From 5ba5db1a29ef54dc3ee2efbc5bdb3d95b77fc928 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 14 Jul 2023 16:30:43 -0400 Subject: [PATCH] Support Android's "baremetal" target This corresponds to the libcrypto_baremetal build target in Android, which is an embedded-style platform that uses a subset of the bionic libc. It will also, eventually, use getentropy for its PRNG. As part of this, generalize the OPENSSL_TRUSTY exclusion for file BIOs to OPENSSL_NO_FILESYSTEM. Upstream OpenSSL uses OPENSSL_NO_STDIO, but that excludes all of FILE entirely. We already require FILE in quite a few places (urandom.c, self_test.c) for writing to stderr, and FILE is part of C standard library. So, let's tentatively say that we require you have FILE and stderr. Instead, OPENSSL_NO_FILESYSTEM is saying you don't have fopen. You're still required to have the three std{in,out,err} FILEs, and given a FILE, you need to allow the standard operations on it. (Possibly in forms that always fail.) To keep us honest, whenever a function is excluded, I've dropped it from the header too, and followed callers up the chain. I have not attempted to make the tests work when these are excluded. Later CLs in this series will do the same for NO_SOCK and NO_POSIX_IO. This was a little tedious, but not too bad. (I assume we'll end up changing our minds on this a lot. For now, let's try this.) I haven't yet restored OPENSSL_RAND_TRUSTY or removed the OPENSSL_TRUSTY ifdef on file.c. Having a separate CL makes it a bit easier to revert if something goes wrong. This depends on https://android-review.googlesource.com/c/platform/bionic/+/2659335, which fixes the header bionic uses for getentropy. Bug: 629, b:291102972 Change-Id: Idd839cd3fa4253128de54bd1be7da261dbcdeb7c Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/61726 Auto-Submit: David Benjamin Reviewed-by: Bob Beck Commit-Queue: Bob Beck --- crypto/bio/file.c | 8 ++++++++ crypto/conf/conf.c | 10 ++++------ crypto/x509/by_dir.c | 4 ++-- crypto/x509/by_file.c | 4 ++-- crypto/x509/x509_d2.c | 5 +++-- decrepit/ssl/ssl_decrepit.c | 5 +++-- include/openssl/bio.h | 4 ++++ include/openssl/conf.h | 2 ++ include/openssl/ssl.h | 10 ++++++++++ include/openssl/target.h | 21 ++++++++++++++++++--- include/openssl/x509.h | 6 ++++-- ssl/ssl_file.cc | 10 ++++++---- ssl/ssl_x509.cc | 2 ++ 13 files changed, 68 insertions(+), 23 deletions(-) diff --git a/crypto/bio/file.c b/crypto/bio/file.c index d0281c854..f0801ba9e 100644 --- a/crypto/bio/file.c +++ b/crypto/bio/file.c @@ -73,6 +73,8 @@ #include +// TODO(crbug.com/boringssl/629): Remove this in favor of the more fine-grained +// OPENSSL_NO_FILESYSTEM ifdef. #if !defined(OPENSSL_TRUSTY) #include @@ -89,6 +91,7 @@ #define BIO_FP_WRITE 0x04 #define BIO_FP_APPEND 0x08 +#if !defined(OPENSSL_NO_FILESYSTEM) BIO *BIO_new_file(const char *filename, const char *mode) { BIO *ret; FILE *file; @@ -114,6 +117,7 @@ BIO *BIO_new_file(const char *filename, const char *mode) { return ret; } +#endif // !OPENSSL_NO_FILESYSTEM BIO *BIO_new_fp(FILE *stream, int close_flag) { BIO *ret = BIO_new(BIO_s_file()); @@ -193,6 +197,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { b->ptr = ptr; b->init = 1; break; +#if !defined(OPENSSL_NO_FILESYSTEM) case BIO_C_SET_FILENAME: file_free(b); b->shutdown = (int)num & BIO_CLOSE; @@ -225,6 +230,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { b->ptr = fp; b->init = 1; break; +#endif // !OPENSSL_NO_FILESYSTEM case BIO_C_GET_FILE_PTR: // the ptr parameter is actually a FILE ** in this case. if (ptr != NULL) { @@ -284,6 +290,7 @@ int BIO_set_fp(BIO *bio, FILE *file, int close_flag) { return (int)BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *)file); } +#if !defined(OPENSSL_NO_FILESYSTEM) int BIO_read_filename(BIO *bio, const char *filename) { return (int)BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, (char *)filename); @@ -304,6 +311,7 @@ int BIO_rw_filename(BIO *bio, const char *filename) { BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename); } +#endif // !OPENSSL_NO_FILESYSTEM long BIO_tell(BIO *bio) { return BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL); } diff --git a/crypto/conf/conf.c b/crypto/conf/conf.c index 6b9833d97..18bec19aa 100644 --- a/crypto/conf/conf.c +++ b/crypto/conf/conf.c @@ -387,7 +387,7 @@ static void clear_comments(CONF *conf, char *p) { } } -static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) { +int NCONF_load_bio(CONF *conf, BIO *in, long *out_error_line) { static const size_t CONFBUFSIZE = 512; int bufnum = 0, i, ii; BUF_MEM *buff = NULL; @@ -585,6 +585,7 @@ err: return 0; } +#if !defined(OPENSSL_NO_FILESYSTEM) int NCONF_load(CONF *conf, const char *filename, long *out_error_line) { BIO *in = BIO_new_file(filename, "rb"); int ret; @@ -594,15 +595,12 @@ int NCONF_load(CONF *conf, const char *filename, long *out_error_line) { return 0; } - ret = def_load_bio(conf, in, out_error_line); + ret = NCONF_load_bio(conf, in, out_error_line); BIO_free(in); return ret; } - -int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line) { - return def_load_bio(conf, bio, out_error_line); -} +#endif // !OPENSSL_NO_FILESYSTEM int CONF_parse_list(const char *list, char sep, int remove_whitespace, int (*list_cb)(const char *elem, size_t len, void *usr), diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index a34496f86..95a69bf0d 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -64,7 +64,7 @@ #include #include -#if !defined(OPENSSL_TRUSTY) +#if !defined(OPENSSL_NO_FILESYSTEM) #include "../internal.h" #include "internal.h" @@ -403,4 +403,4 @@ finish: return ok; } -#endif // OPENSSL_TRUSTY +#endif // OPENSSL_NO_FILESYSTEM diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 7c056f081..33bd97819 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -62,7 +62,7 @@ #include "internal.h" -#ifndef OPENSSL_NO_STDIO +#if !defined(OPENSSL_NO_FILESYSTEM) static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); @@ -279,4 +279,4 @@ err: return count; } -#endif // OPENSSL_NO_STDIO +#endif // !OPENSSL_NO_FILESYSTEM diff --git a/crypto/x509/x509_d2.c b/crypto/x509/x509_d2.c index 748bd88ac..7db1d2f34 100644 --- a/crypto/x509/x509_d2.c +++ b/crypto/x509/x509_d2.c @@ -57,7 +57,8 @@ #include #include -#ifndef OPENSSL_NO_STDIO +#if !defined(OPENSSL_NO_FILESYSTEM) + int X509_STORE_set_default_paths(X509_STORE *ctx) { X509_LOOKUP *lookup; @@ -107,4 +108,4 @@ int X509_STORE_load_locations(X509_STORE *ctx, const char *file, return 1; } -#endif +#endif // !OPENSSL_NO_FILESYSTEM diff --git a/decrepit/ssl/ssl_decrepit.c b/decrepit/ssl/ssl_decrepit.c index a155c0f46..c6df9a11e 100644 --- a/decrepit/ssl/ssl_decrepit.c +++ b/decrepit/ssl/ssl_decrepit.c @@ -110,7 +110,8 @@ #include -#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL) +#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_PNACL) && \ + !defined(OPENSSL_NO_FILESYSTEM) #include #include @@ -162,4 +163,4 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, return ret; } -#endif // !WINDOWS && !PNACL +#endif // !WINDOWS && !PNACL && !OPENSSL_NO_FILESYSTEM diff --git a/include/openssl/bio.h b/include/openssl/bio.h index 707a4b155..ce139cccf 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -470,9 +470,11 @@ OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd); // BIO_s_file returns a BIO_METHOD that wraps a |FILE|. OPENSSL_EXPORT const BIO_METHOD *BIO_s_file(void); +#if !defined(OPENSSL_NO_FILESYSTEM) // BIO_new_file creates a file BIO by opening |filename| with the given mode. // See the |fopen| manual page for details of the mode argument. OPENSSL_EXPORT BIO *BIO_new_file(const char *filename, const char *mode); +#endif // BIO_new_fp creates a new file BIO that wraps the given |FILE|. If // |close_flag| is |BIO_CLOSE|, then |fclose| will be called on |stream| when @@ -488,6 +490,7 @@ OPENSSL_EXPORT int BIO_get_fp(BIO *bio, FILE **out_file); // success and zero otherwise. OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag); +#if !defined(OPENSSL_NO_FILESYSTEM) // BIO_read_filename opens |filename| for reading and sets the result as the // |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| // will be closed when |bio| is freed. @@ -507,6 +510,7 @@ OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename); // as the |FILE| for |bio|. It returns one on success and zero otherwise. The // |FILE| will be closed when |bio| is freed. OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename); +#endif // OPENSSL_NO_FILESYSTEM // BIO_tell returns the file offset of |bio|, or a negative number on error or // if |bio| does not support the operation. diff --git a/include/openssl/conf.h b/include/openssl/conf.h index c9027c1db..f217e980f 100644 --- a/include/openssl/conf.h +++ b/include/openssl/conf.h @@ -99,12 +99,14 @@ OPENSSL_EXPORT CONF *NCONF_new(void *method); // NCONF_free frees all the data owned by |conf| and then |conf| itself. OPENSSL_EXPORT void NCONF_free(CONF *conf); +#if !defined(OPENSSL_NO_FILESYSTEM) // NCONF_load parses the file named |filename| and adds the values found to // |conf|. It returns one on success and zero on error. In the event of an // error, if |out_error_line| is not NULL, |*out_error_line| is set to the // number of the line that contained the error. OPENSSL_EXPORT int NCONF_load(CONF *conf, const char *filename, long *out_error_line); +#endif // NCONF_load_bio acts like |NCONF_load| but reads from |bio| rather than from // a named file. diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index ffbf51eb2..4aba1051a 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1195,6 +1195,7 @@ OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, #define SSL_FILETYPE_PEM 1 #define SSL_FILETYPE_ASN1 2 +#if !defined(OPENSSL_NO_FILESYSTEM) OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); @@ -1217,6 +1218,7 @@ OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file, // success and zero on failure. OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +#endif // !OPENSSL_NO_FILESYSTEM // SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based // convenience functions called on |ctx|. @@ -2651,6 +2653,7 @@ OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); // SSL_CTX_get_cert_store returns |ctx|'s certificate store. OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); +#if !defined(OPENSSL_NO_FILESYSTEM) // SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust // anchors into |ctx|'s store. It returns one on success and zero on failure. OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); @@ -2667,6 +2670,7 @@ OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, const char *ca_dir); +#endif // !OPENSSL_NO_FILESYSTEM // SSL_get_verify_result returns the result of certificate verification. It is // either |X509_V_OK| or a |X509_V_ERR_*| value. @@ -2828,20 +2832,24 @@ OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509); // ownership of |x509|. OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509); +#if !defined(OPENSSL_NO_FILESYSTEM) // SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from // it. It returns a newly-allocated stack of the certificate subjects or NULL // on error. Duplicates in |file| are ignored. OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +#endif // SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on // success or NULL on allocation error. OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list); +#if !defined(OPENSSL_NO_FILESYSTEM) // SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file| // but appends the result to |out|. It returns one on success or zero on // error. OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, const char *file); +#endif // SSL_add_bio_cert_subjects_to_stack behaves like // |SSL_add_file_cert_subjects_to_stack| but reads from |bio|. @@ -5110,12 +5118,14 @@ OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); // |ec_key|'s curve. The remainder of |ec_key| is ignored. OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); +#if !defined(OPENSSL_NO_FILESYSTEM) // SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls // |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success // or zero on error. This function is only available from the libdecrepit // library. OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, const char *dir); +#endif // SSL_CTX_enable_tls_channel_id calls |SSL_CTX_set_tls_channel_id_enabled|. OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx); diff --git a/include/openssl/target.h b/include/openssl/target.h index 92eaf75c7..f830c14ce 100644 --- a/include/openssl/target.h +++ b/include/openssl/target.h @@ -70,10 +70,13 @@ #define OPENSSL_WINDOWS #endif -// Trusty isn't Linux but currently defines __linux__. As a workaround, we -// exclude it here. +// Trusty and Android baremetal aren't't Linux but currently define __linux__. +// As a workaround, we exclude them here. +// // TODO(b/169780122): Remove this workaround once Trusty no longer defines it. -#if defined(__linux__) && !defined(__TRUSTY__) +// TODO(b/291101350): Remove this workaround once Android baremetal no longer +// defines it. +#if defined(__linux__) && !defined(__TRUSTY__) && !defined(ANDROID_BAREMETAL) #define OPENSSL_LINUX #endif @@ -88,6 +91,7 @@ // platforms must introduce their own defines. #if defined(__TRUSTY__) #define OPENSSL_TRUSTY +#define OPENSSL_NO_FILESYSTEM #define OPENSSL_NO_POSIX_IO #define OPENSSL_NO_SOCK #define OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED @@ -97,6 +101,17 @@ // other platform is not supported. Other embedded platforms must introduce // their own defines. #if defined(OPENSSL_NANOLIBC) +#define OPENSSL_NO_FILESYSTEM +#define OPENSSL_NO_POSIX_IO +#define OPENSSL_NO_SOCK +#define OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED +#endif + +// Android baremetal is an embedded target that uses a subset of bionic. +// Defining this on any other platform is not supported. Other embedded +// platforms must introduce their own defines. +#if defined(ANDROID_BAREMETAL) +#define OPENSSL_NO_FILESYSTEM #define OPENSSL_NO_POSIX_IO #define OPENSSL_NO_SOCK #define OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED diff --git a/include/openssl/x509.h b/include/openssl/x509.h index c80b14e5a..7ce29180f 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2852,8 +2852,10 @@ OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); +#if !defined(OPENSSL_NO_FILESYSTEM) OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_file(void); +#endif OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); @@ -2864,7 +2866,7 @@ OPENSSL_EXPORT int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, OPENSSL_EXPORT int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); -#ifndef OPENSSL_NO_STDIO +#if !defined(OPENSSL_NO_FILESYSTEM) OPENSSL_EXPORT int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); OPENSSL_EXPORT int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, @@ -2880,7 +2882,7 @@ OPENSSL_EXPORT int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, X509_OBJECT *ret); OPENSSL_EXPORT int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); -#ifndef OPENSSL_NO_STDIO +#if !defined(OPENSSL_NO_FILESYSTEM) OPENSSL_EXPORT int X509_STORE_load_locations(X509_STORE *ctx, const char *file, const char *dir); OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); diff --git a/ssl/ssl_file.cc b/ssl/ssl_file.cc index 9e06ec893..0071153ce 100644 --- a/ssl/ssl_file.cc +++ b/ssl/ssl_file.cc @@ -199,6 +199,11 @@ static int add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio, return 1; } +int SSL_add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio) { + return add_bio_cert_subjects_to_stack(out, bio, /*allow_empty=*/true); +} + +#if !defined(OPENSSL_NO_FILESYSTEM) STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) { bssl::UniquePtr in(BIO_new_file(file, "r")); if (in == nullptr) { @@ -222,10 +227,6 @@ int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, return SSL_add_bio_cert_subjects_to_stack(out, in.get()); } -int SSL_add_bio_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, BIO *bio) { - return add_bio_cert_subjects_to_stack(out, bio, /*allow_empty=*/true); -} - int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { int reason_code; BIO *in; @@ -544,6 +545,7 @@ end: BIO_free(in); return ret; } +#endif // !OPENSSL_NO_FILESYSTEM void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) { ctx->default_passwd_callback = cb; diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc index e4b3775b3..5514cf203 100644 --- a/ssl/ssl_x509.cc +++ b/ssl/ssl_x509.cc @@ -695,6 +695,7 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { X509_VERIFY_PARAM_set_depth(ctx->param, depth); } +#if !defined(OPENSSL_NO_FILESYSTEM) int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { check_ssl_ctx_x509_method(ctx); return X509_STORE_set_default_paths(ctx->cert_store); @@ -705,6 +706,7 @@ int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, check_ssl_ctx_x509_method(ctx); return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir); } +#endif // !OPENSSL_NO_FILESYSTEM long SSL_get_verify_result(const SSL *ssl) { check_ssl_x509_method(ssl);