From 9cc4f2b114aa69ba6ec68dfeb8a03f56e430a279 Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Fri, 5 Apr 2024 11:18:10 -0700 Subject: [PATCH 01/25] Clarify documentation around SSL_MODE_NO_AUTO_CHAIN (#1509) Clarify what auto-chaining is and the documentation around it. This was taken from our internal porting guide which had a better paragraph describing what this was. --- include/openssl/ssl.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 7fb69fb5fa..e53d0870cb 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -839,13 +839,20 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl); // SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain // before sending certificates to the peer. This flag is set (and the feature // disabled) by default. -// OpenSSL does not set this flag by default. This might cause issues for -// services migrating to AWS-LC, if the service was relying on the default -// behavior. We highly recommend not to disable this flag, but if a consumer -// had been relying on this default behavior, they can temporarily revert -// locally with |SSL_[CTX_]clear_mode|. However, it is still expected of the -// AWS-LC consumer to structure their code to not rely on certificate -// auto-chaining in general. +// By default, OpenSSL automatically builds a certificate chain on the fly if +// there is no certificate chain explicitly provided. This feature is called +// Auto-Chaining. Auto-Chaining can be turned off in OpenSSL by setting the +// |SSL_MODE_NO_AUTO_CHAIN| flag for the SSL connection. AWS-LC has this flag +// turned on (auto-chaining off) by default. This forces the certificate chain +// to be explicit, and no longer results in unexpected certificate chains being +// sent back to clients. This may cause issues for services migrating to AWS-LC, +// if the service had been reliant on the default behavior. Services should +// restructure their certificate chains to not use the default auto-chaining +// behavior from OpenSSL when porting to AWS-LC. We highly recommend not to +// re-enable Auto-Chaining, but if a consumer had been relying on this default +// behavior, they can temporarily revert back with |SSL_[CTX_]clear_mode|. +// However, it is generally expected of AWS-LC consumers to structure their +// certificate chains to not rely on auto-chaining. #define SSL_MODE_NO_AUTO_CHAIN 0x00000008L // SSL_MODE_ENABLE_FALSE_START allows clients to send application data before From d3ad9d359e3440aadc686d67ffcfc2871ed9529e Mon Sep 17 00:00:00 2001 From: dkostic <25055813+dkostic@users.noreply.github.com> Date: Fri, 5 Apr 2024 11:20:39 -0700 Subject: [PATCH 02/25] RSA key pair-wise consistency test with approved APIs (#1518) This commit reverts a change done in: c8bdf891e4d2c276ba0c27efc78b219a56606c6a, where the RSA PWCT was implemented using RSA_sign/verify API. According to our FIPS lab we ought to use the approved EVP_DigestSign/Verify API, which is what we do in this commmit. --- crypto/fipsmodule/rsa/rsa.c | 72 ++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 17 deletions(-) diff --git a/crypto/fipsmodule/rsa/rsa.c b/crypto/fipsmodule/rsa/rsa.c index 82f463c2a0..c7efbad9ca 100644 --- a/crypto/fipsmodule/rsa/rsa.c +++ b/crypto/fipsmodule/rsa/rsa.c @@ -1142,6 +1142,59 @@ int RSA_check_key(const RSA *key) { return ret; } +// Performs Pair-Wise Consistency Test (PWCT) with the given RSA key +// by signing and verifying a message. This is required for RSA_check_fips +// function further below. According to our FIPS lab we have to do the test +// with EVP_DigestSign/Verify API. +static int rsa_key_fips_pairwise_consistency_test_signing(RSA *key) { + int ret = 0; + + uint8_t msg[1] = {0}; + size_t msg_len = 1; + uint8_t *sig_der = NULL; + size_t sig_len = 0; + + EVP_PKEY *evp_pkey = NULL; + EVP_MD_CTX md_ctx; + const EVP_MD *md = EVP_sha256(); + + evp_pkey = EVP_PKEY_new(); + if (!evp_pkey || !EVP_PKEY_set1_RSA(evp_pkey, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto end; + } + + // Initialize the context and grab the expected signature length. + EVP_MD_CTX_init(&md_ctx); + if (!EVP_DigestSignInit(&md_ctx, NULL, md, NULL, evp_pkey) || + !EVP_DigestSign(&md_ctx, NULL, &sig_len, msg, msg_len)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto end; + } + + sig_der = OPENSSL_malloc(sig_len); + if (!sig_der || + !EVP_DigestSign(&md_ctx, sig_der, &sig_len, msg, msg_len)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto end; + } + if (boringssl_fips_break_test("RSA_PWCT")) { + msg[0] = ~msg[0]; + } + if (!EVP_DigestVerifyInit(&md_ctx, NULL, md, NULL, evp_pkey) || + !EVP_DigestVerify(&md_ctx, sig_der, sig_len, msg, msg_len)) { + goto end; + } + + ret = 1; + +end: + EVP_PKEY_free(evp_pkey); + EVP_MD_CTX_cleanse(&md_ctx); + OPENSSL_free(sig_der); + return ret; +} + // This is the product of the 132 smallest odd primes, from 3 to 751, // as defined in SP 800-89 5.3.3. static const BN_ULONG kSmallFactorsLimbs[] = { @@ -1242,23 +1295,8 @@ int RSA_check_fips(RSA *key) { // encryption, so either pair-wise consistency self-test is acceptable. We // perform a signing test. The same guidance can be found in FIPS 140-3 IG // in Section 7.10.3.3, sub-section Additional comments. - uint8_t data[32] = {0}; - unsigned sig_len = RSA_size(key); - sig = OPENSSL_malloc(sig_len); - if (sig == NULL) { - OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); - goto end; - } - - if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) { - OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); - goto end; - } - if (boringssl_fips_break_test("RSA_PWCT")) { - data[0] = ~data[0]; - } - if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) { - OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + if (!rsa_key_fips_pairwise_consistency_test_signing(key)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); goto end; } From f1ae63657daab6dcdbfecac8f5c07097c321085e Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 12 Nov 2023 19:21:55 -0500 Subject: [PATCH 03/25] Document X509_PUBKEY functions Bug: 426 Change-Id: I29d4e1d5a5c319ba7bedab197efaf0427a8115af Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63943 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 4e400359bcffad4cd6fe4d7db5c83c1eb085cd34) --- include/openssl/x509.h | 118 ++++++++++++++++++++++++++--------------- 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 5f7ea65dec..ec097801a0 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -1387,6 +1387,80 @@ OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt( ossl_ssize_t len); +// Public keys. +// +// X.509 encodes public keys as SubjectPublicKeyInfo (RFC 5280), sometimes +// referred to as SPKI. These are represented in this library by |X509_PUBKEY|. + +// X509_PUBKEY is an |ASN1_ITEM| whose ASN.1 type is SubjectPublicKeyInfo and C +// type is |X509_PUBKEY*|. +DECLARE_ASN1_ITEM(X509_PUBKEY) + +// X509_PUBKEY_new returns a newly-allocated, empty |X509_PUBKEY| object, or +// NULL on error. +OPENSSL_EXPORT X509_PUBKEY *X509_PUBKEY_new(void); + +// X509_PUBKEY_free releases memory associated with |key|. +OPENSSL_EXPORT void X509_PUBKEY_free(X509_PUBKEY *key); + +// d2i_X509_PUBKEY parses up to |len| bytes from |*inp| as a DER-encoded +// SubjectPublicKeyInfo, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **out, + const uint8_t **inp, long len); + +// i2d_X509_PUBKEY marshals |key| as a DER-encoded SubjectPublicKeyInfo, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_PUBKEY(const X509_PUBKEY *key, uint8_t **outp); + +// X509_PUBKEY_set serializes |pkey| into a newly-allocated |X509_PUBKEY| +// structure. On success, it frees |*x| if non-NULL, then sets |*x| to the new +// object, and returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); + +// X509_PUBKEY_get decodes the public key in |key| and returns an |EVP_PKEY| on +// success, or NULL on error or unrecognized algorithm. The caller must release +// the result with |EVP_PKEY_free| when done. The |EVP_PKEY| is cached in |key|, +// so callers must not mutate the result. +OPENSSL_EXPORT EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); + +// X509_PUBKEY_set0_param sets |pub| to a key with AlgorithmIdentifier +// determined by |obj|, |param_type|, and |param_value|, and an encoded +// public key of |key|. On success, it gives |pub| ownership of all the other +// parameters and returns one. Otherwise, it returns zero. |key| must have been +// allocated by |OPENSSL_malloc|. |obj| and, if applicable, |param_value| must +// not be freed after a successful call, and must have been allocated in a +// manner compatible with |ASN1_OBJECT_free| or |ASN1_STRING_free|. +// +// |obj|, |param_type|, and |param_value| are interpreted as in +// |X509_ALGOR_set0|. See |X509_ALGOR_set0| for details. +OPENSSL_EXPORT int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, + int param_type, void *param_value, + uint8_t *key, int key_len); + +// X509_PUBKEY_get0_param outputs fields of |pub| and returns one. If |out_obj| +// is not NULL, it sets |*out_obj| to AlgorithmIdentifier's OID. If |out_key| +// is not NULL, it sets |*out_key| and |*out_key_len| to the encoded public key. +// If |out_alg| is not NULL, it sets |*out_alg| to the AlgorithmIdentifier. +// +// All pointers outputted by this function are internal to |pub| and must not be +// freed by the caller. Additionally, although some outputs are non-const, +// callers must not mutate the resulting objects. +// +// Note: X.509 SubjectPublicKeyInfo structures store the encoded public key as a +// BIT STRING. |*out_key| and |*out_key_len| will silently pad the key with zero +// bits if |pub| did not contain a whole number of bytes. Use +// |X509_PUBKEY_get0_public_key| to preserve this information. +OPENSSL_EXPORT int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, + const uint8_t **out_key, + int *out_key_len, + X509_ALGOR **out_alg, + X509_PUBKEY *pub); + +// X509_PUBKEY_get0_public_key returns |pub|'s encoded public key. +OPENSSL_EXPORT const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key( + const X509_PUBKEY *pub); + + // Extensions. // // X.509 certificates and CRLs may contain a list of extensions (RFC 5280). @@ -2529,19 +2603,6 @@ OPENSSL_EXPORT const char *X509_get_default_cert_dir_env(void); OPENSSL_EXPORT const char *X509_get_default_cert_file_env(void); OPENSSL_EXPORT const char *X509_get_default_private_dir(void); -DECLARE_ASN1_FUNCTIONS_const(X509_PUBKEY) - -// X509_PUBKEY_set serializes |pkey| into a newly-allocated |X509_PUBKEY| -// structure. On success, it frees |*x|, sets |*x| to the new object, and -// returns one. Otherwise, it returns zero. -OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); - -// X509_PUBKEY_get decodes the public key in |key| and returns an |EVP_PKEY| on -// success, or NULL on error. The caller must release the result with -// |EVP_PKEY_free| when done. The |EVP_PKEY| is cached in |key|, so callers must -// not mutate the result. -OPENSSL_EXPORT EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); - DECLARE_ASN1_FUNCTIONS_const(X509_SIG) @@ -2638,37 +2699,6 @@ OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); // Use |EVP_marshal_private_key| instead. OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey); -// X509_PUBKEY_set0_param sets |pub| to a key with AlgorithmIdentifier -// determined by |obj|, |param_type|, and |param_value|, and an encoded -// public key of |key|. On success, it takes ownership of all its parameters and -// returns one. Otherwise, it returns zero. |key| must have been allocated by -// |OPENSSL_malloc|. -// -// |obj|, |param_type|, and |param_value| are interpreted as in -// |X509_ALGOR_set0|. See |X509_ALGOR_set0| for details. -OPENSSL_EXPORT int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, - int param_type, void *param_value, - uint8_t *key, int key_len); - -// X509_PUBKEY_get0_param outputs fields of |pub| and returns one. If |out_obj| -// is not NULL, it sets |*out_obj| to AlgorithmIdentifier's OID. If |out_key| -// is not NULL, it sets |*out_key| and |*out_key_len| to the encoded public key. -// If |out_alg| is not NULL, it sets |*out_alg| to the AlgorithmIdentifier. -// -// Note: X.509 SubjectPublicKeyInfo structures store the encoded public key as a -// BIT STRING. |*out_key| and |*out_key_len| will silently pad the key with zero -// bits if |pub| did not contain a whole number of bytes. Use -// |X509_PUBKEY_get0_public_key| to preserve this information. -OPENSSL_EXPORT int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, - const uint8_t **out_key, - int *out_key_len, - X509_ALGOR **out_alg, - X509_PUBKEY *pub); - -// X509_PUBKEY_get0_public_key returns |pub|'s encoded public key. -OPENSSL_EXPORT const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key( - const X509_PUBKEY *pub); - OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags); OPENSSL_EXPORT int X509_TRUST_get_count(void); OPENSSL_EXPORT X509_TRUST *X509_TRUST_get0(int idx); From 141e4254d6ae1fda4e0f2f745d1b5b33aa4eb724 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 12 Nov 2023 19:42:41 -0500 Subject: [PATCH 04/25] Document PKCS8_PRIV_KEY_INFO and X509_SIG Bug: 426 Change-Id: Ie96fd593817cbbfc11f78bb5608fcc9eb0b8d773 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63944 Commit-Queue: David Benjamin Reviewed-by: Bob Beck (cherry picked from commit 2a63b90f103ab601cb81e347c0f0ad767e40e019) --- include/openssl/x509.h | 115 ++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 31 deletions(-) diff --git a/include/openssl/x509.h b/include/openssl/x509.h index ec097801a0..4d34d7c956 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -1982,6 +1982,90 @@ OPENSSL_EXPORT RSA_PSS_PARAMS *d2i_RSA_PSS_PARAMS(RSA_PSS_PARAMS **out, OPENSSL_EXPORT int i2d_RSA_PSS_PARAMS(const RSA_PSS_PARAMS *in, uint8_t **outp); +// PKCS#8 private keys. +// +// The |PKCS8_PRIV_KEY_INFO| type represents a PKCS#8 PrivateKeyInfo (RFC 5208) +// structure. This is analogous to SubjectPublicKeyInfo and uses the same +// AlgorithmIdentifiers, but carries private keys and is not part of X.509 +// itself. +// +// TODO(davidben): Do these functions really belong in this header? + +// PKCS8_PRIV_KEY_INFO is an |ASN1_ITEM| whose ASN.1 type is PrivateKeyInfo and +// C type is |PKCS8_PRIV_KEY_INFO*|. +DECLARE_ASN1_ITEM(PKCS8_PRIV_KEY_INFO) + +// PKCS8_PRIV_KEY_INFO_new returns a newly-allocated, empty +// |PKCS8_PRIV_KEY_INFO| object, or NULL on error. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_PRIV_KEY_INFO_new(void); + +// PKCS8_PRIV_KEY_INFO_free releases memory associated with |key|. +OPENSSL_EXPORT void PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *key); + +// d2i_PKCS8_PRIV_KEY_INFO parses up to |len| bytes from |*inp| as a DER-encoded +// PrivateKeyInfo, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO( + PKCS8_PRIV_KEY_INFO **out, const uint8_t **inp, long len); + +// i2d_PKCS8_PRIV_KEY_INFO marshals |key| as a DER-encoded PrivateKeyInfo, as +// described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO(const PKCS8_PRIV_KEY_INFO *key, + uint8_t **outp); + +// EVP_PKCS82PKEY returns |p8| as a newly-allocated |EVP_PKEY|, or NULL if the +// key was unsupported or could not be decoded. The caller must release the +// result with |EVP_PKEY_free| when done. +// +// Use |EVP_parse_private_key| instead. +OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); + +// EVP_PKEY2PKCS8 encodes |pkey| as a PKCS#8 PrivateKeyInfo (RFC 5208), +// represented as a newly-allocated |PKCS8_PRIV_KEY_INFO|, or NULL on error. The +// caller must release the result with |PKCS8_PRIV_KEY_INFO_free| when done. +// +// Use |EVP_marshal_private_key| instead. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey); + + +// Algorithm and octet string pairs. +// +// The |X509_SIG| type represents an ASN.1 SEQUENCE type of an +// AlgorithmIdentifier and an OCTET STRING. Although named |X509_SIG|, there is +// no type in X.509 which matches this format. The two common types which do are +// DigestInfo (RFC 2315 and RFC 8017), and EncryptedPrivateKeyInfo (RFC 5208). + +// X509_SIG is an |ASN1_ITEM| whose ASN.1 type is the SEQUENCE described above +// and C type is |X509_SIG*|. +DECLARE_ASN1_ITEM(X509_SIG) + +// X509_SIG_new returns a newly-allocated, empty |X509_SIG| object, or NULL on +// error. +OPENSSL_EXPORT X509_SIG *X509_SIG_new(void); + +// X509_SIG_free releases memory associated with |key|. +OPENSSL_EXPORT void X509_SIG_free(X509_SIG *key); + +// d2i_X509_SIG parses up to |len| bytes from |*inp| as a DER-encoded algorithm +// and octet string pair, as described in |d2i_SAMPLE|. +OPENSSL_EXPORT X509_SIG *d2i_X509_SIG(X509_SIG **out, const uint8_t **inp, + long len); + +// i2d_X509_SIG marshals |sig| as a DER-encoded algorithm +// and octet string pair, as described in |i2d_SAMPLE|. +OPENSSL_EXPORT int i2d_X509_SIG(const X509_SIG *sig, uint8_t **outp); + +// X509_SIG_get0 sets |*out_alg| and |*out_digest| to non-owning pointers to +// |sig|'s algorithm and digest fields, respectively. Either |out_alg| and +// |out_digest| may be NULL to skip those fields. +OPENSSL_EXPORT void X509_SIG_get0(const X509_SIG *sig, + const X509_ALGOR **out_alg, + const ASN1_OCTET_STRING **out_digest); + +// X509_SIG_getm behaves like |X509_SIG_get0| but returns mutable pointers. +OPENSSL_EXPORT void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg, + ASN1_OCTET_STRING **out_digest); + + // Printing functions. // // The following functions output human-readable representations of @@ -2580,17 +2664,6 @@ struct X509_info_st { DEFINE_STACK_OF(X509_INFO) -// X509_SIG_get0 sets |*out_alg| and |*out_digest| to non-owning pointers to -// |sig|'s algorithm and digest fields, respectively. Either |out_alg| and -// |out_digest| may be NULL to skip those fields. -OPENSSL_EXPORT void X509_SIG_get0(const X509_SIG *sig, - const X509_ALGOR **out_alg, - const ASN1_OCTET_STRING **out_digest); - -// X509_SIG_getm behaves like |X509_SIG_get0| but returns mutable pointers. -OPENSSL_EXPORT void X509_SIG_getm(X509_SIG *sig, X509_ALGOR **out_alg, - ASN1_OCTET_STRING **out_digest); - // X509_verify_cert_error_string returns |err| as a human-readable string, where // |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns // a default description. @@ -2603,8 +2676,6 @@ OPENSSL_EXPORT const char *X509_get_default_cert_dir_env(void); OPENSSL_EXPORT const char *X509_get_default_cert_file_env(void); OPENSSL_EXPORT const char *X509_get_default_private_dir(void); -DECLARE_ASN1_FUNCTIONS_const(X509_SIG) - OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); @@ -2681,24 +2752,6 @@ OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); // depended on. OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); -// PKCS#8 utilities - -DECLARE_ASN1_FUNCTIONS_const(PKCS8_PRIV_KEY_INFO) - -// EVP_PKCS82PKEY returns |p8| as a newly-allocated |EVP_PKEY|, or NULL if the -// key was unsupported or could not be decoded. If non-NULL, the caller must -// release the result with |EVP_PKEY_free| when done. -// -// Use |EVP_parse_private_key| instead. -OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8); - -// EVP_PKEY2PKCS8 encodes |pkey| as a PKCS#8 PrivateKeyInfo (RFC 5208), -// represented as a newly-allocated |PKCS8_PRIV_KEY_INFO|, or NULL on error. The -// caller must release the result with |PKCS8_PRIV_KEY_INFO_free| when done. -// -// Use |EVP_marshal_private_key| instead. -OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey); - OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags); OPENSSL_EXPORT int X509_TRUST_get_count(void); OPENSSL_EXPORT X509_TRUST *X509_TRUST_get0(int idx); From 64c6a0d98ecfe351779e925975d8915a3cf4d104 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 12 Nov 2023 19:56:19 -0500 Subject: [PATCH 05/25] Document X509_NAME comparison functions Warts and all. Bug: 426 Change-Id: I45c7ae59b65055b560df6019a98269b3a28fd24f Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63945 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit a697bcb71dc1b822e681fc3defb61786f6c26c2e) --- include/openssl/x509.h | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 4d34d7c956..145705d54c 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -1198,6 +1198,19 @@ OPENSSL_EXPORT int i2d_X509_NAME(X509_NAME *in, uint8_t **outp); // mutated. OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *name); +// X509_NAME_cmp compares |a| and |b|'s canonicalized forms. It returns zero if +// they are equal, one if |a| sorts after |b|, -1 if |b| sorts after |a|, and -2 +// on error. +// +// TODO(https://crbug.com/boringssl/407): This function is const, but it is not +// always thread-safe, notably if |name| was mutated. +// +// TODO(https://crbug.com/boringssl/355): The -2 return is very inconvenient to +// pass to a sorting function. Can we make this infallible? In the meantime, +// prefer to use this function only for equality checks rather than comparisons. +// Although even the library itself passes this to a sorting function. +OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); + // X509_NAME_get0_der sets |*out_der| and |*out_der_len| // // Avoid this function and prefer |i2d_X509_NAME|. It is one of the reasons @@ -2453,6 +2466,21 @@ OPENSSL_EXPORT ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, // current time. OPENSSL_EXPORT ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec); +// X509_issuer_name_cmp behaves like |X509_NAME_cmp|, but compares |a| and |b|'s +// issuer names. +OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); + +// X509_subject_name_cmp behaves like |X509_NAME_cmp|, but compares |a| and +// |b|'s subject names. +OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); + +// X509_CRL_cmp behaves like |X509_NAME_cmp|, but compares |a| and |b|'s +// issuer names. +// +// WARNING: This function is misnamed. It does not compare other parts of the +// CRL, only the issuer fields using |X509_NAME_cmp|. +OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); + // ex_data functions. // @@ -2710,21 +2738,17 @@ OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); -OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); OPENSSL_EXPORT unsigned long X509_issuer_name_hash(X509 *a); -OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); OPENSSL_EXPORT unsigned long X509_issuer_name_hash_old(X509 *a); OPENSSL_EXPORT unsigned long X509_subject_name_hash_old(X509 *x); OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); -OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); OPENSSL_EXPORT unsigned long X509_NAME_hash(X509_NAME *x); OPENSSL_EXPORT unsigned long X509_NAME_hash_old(X509_NAME *x); -OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); // X509_verify_cert attempts to discover and validate a certificate chain based From c2343a5fc03546a983ccc7de4ebec2ebba628ff6 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 13 Nov 2023 09:04:43 -0500 Subject: [PATCH 06/25] Document ASN1_ITEM-based signing, etc. APIs These probably shouldn't be public API, but ah well. Bug: 426 Change-Id: I4c5a81c70d3b2d5866ef494ac2a6710a662103c8 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/63947 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 5bef6ec18376dc684d0cf336ee7d455afdc2c395) --- include/openssl/x509.h | 97 +++++++++++++++++++++++++++++++++--------- 1 file changed, 76 insertions(+), 21 deletions(-) diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 145705d54c..e3dea69274 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -392,6 +392,9 @@ OPENSSL_EXPORT int X509_sign(X509 *x509, EVP_PKEY *pkey, const EVP_MD *md); // zero on error. The signature algorithm and parameters come from |ctx|, which // must have been initialized with |EVP_DigestSignInit|. The caller should // configure the corresponding |EVP_PKEY_CTX| before calling this function. +// +// On success or failure, this function mutates |ctx| and resets it to the empty +// state. Caller should not rely on its contents after the function returns. OPENSSL_EXPORT int X509_sign_ctx(X509 *x509, EVP_MD_CTX *ctx); // i2d_re_X509_tbs serializes the TBSCertificate portion of |x509|, as described @@ -748,6 +751,9 @@ OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *crl, EVP_PKEY *pkey, // zero on error. The signature algorithm and parameters come from |ctx|, which // must have been initialized with |EVP_DigestSignInit|. The caller should // configure the corresponding |EVP_PKEY_CTX| before calling this function. +// +// On success or failure, this function mutates |ctx| and resets it to the empty +// state. Caller should not rely on its contents after the function returns. OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *crl, EVP_MD_CTX *ctx); // i2d_re_X509_CRL_tbs serializes the TBSCertList portion of |crl|, as described @@ -1113,6 +1119,9 @@ OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *req, EVP_PKEY *pkey, // zero on error. The signature algorithm and parameters come from |ctx|, which // must have been initialized with |EVP_DigestSignInit|. The caller should // configure the corresponding |EVP_PKEY_CTX| before calling this function. +// +// On success or failure, this function mutates |ctx| and resets it to the empty +// state. Caller should not rely on its contents after the function returns. OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *req, EVP_MD_CTX *ctx); // i2d_re_X509_REQ_tbs serializes the CertificationRequestInfo (see RFC 2986) @@ -2502,6 +2511,73 @@ OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, OPENSSL_EXPORT void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +// Hashing and signing ASN.1 structures. + +// ASN1_digest serializes |data| with |i2d| and then hashes the result with +// |type|. On success, it returns one, writes the digest to |md|, and sets +// |*len| to the digest length if non-NULL. On error, it returns zero. +// +// |EVP_MD_CTX_size| bytes are written, which is at most |EVP_MAX_MD_SIZE|. The +// buffer must have sufficient space for this output. +OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +// ASN1_item_digest serializes |data| with |it| and then hashes the result with +// |type|. On success, it returns one, writes the digest to |md|, and sets +// |*len| to the digest length if non-NULL. On error, it returns zero. +// +// |EVP_MD_CTX_size| bytes are written, which is at most |EVP_MAX_MD_SIZE|. The +// buffer must have sufficient space for this output. +// +// WARNING: |data| must be a pointer with the same type as |it|'s corresponding +// C type. Using the wrong type is a potentially exploitable memory error. +OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, + void *data, unsigned char *md, + unsigned int *len); + +// ASN1_item_verify serializes |data| with |it| and then verifies |signature| is +// a valid signature for the result with |algor1| and |pkey|. It returns one on +// success and zero on error. The signature and algorithm are interpreted as in +// X.509. +// +// WARNING: |data| must be a pointer with the same type as |it|'s corresponding +// C type. Using the wrong type is a potentially exploitable memory error. +OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, + const X509_ALGOR *algor1, + const ASN1_BIT_STRING *signature, + void *data, EVP_PKEY *pkey); + +// ASN1_item_sign serializes |data| with |it| and then signs the result with +// the private key |pkey|. It returns the length of the signature on success and +// zero on error. On success, it writes the signature to |signature| and the +// signature algorithm to each of |algor1| and |algor2|. Either of |algor1| or +// |algor2| may be NULL to ignore them. This function uses digest algorithm +// |md|, or |pkey|'s default if NULL. Other signing parameters use |pkey|'s +// defaults. To customize them, use |ASN1_item_sign_ctx|. +// +// WARNING: |data| must be a pointer with the same type as |it|'s corresponding +// C type. Using the wrong type is a potentially exploitable memory error. +OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); + +// ASN1_item_sign_ctx behaves like |ASN1_item_sign| except the signature is +// signed with |ctx|, |ctx|, which must have been initialized with +// |EVP_DigestSignInit|. The caller should configure the corresponding +// |EVP_PKEY_CTX| with any additional parameters before calling this function. +// +// On success or failure, this function mutates |ctx| and resets it to the empty +// state. Caller should not rely on its contents after the function returns. +// +// WARNING: |data| must be a pointer with the same type as |it|'s corresponding +// C type. Using the wrong type is a potentially exploitable memory error. +OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, + EVP_MD_CTX *ctx); + + // Deprecated functions. // X509_get_notBefore returns |x509|'s notBefore time. Note this function is not @@ -2713,27 +2789,6 @@ OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); OPENSSL_EXPORT X509_INFO *X509_INFO_new(void); OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); -OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, - unsigned char *md, unsigned int *len); - -OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, - void *data, unsigned char *md, - unsigned int *len); - -OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, - const X509_ALGOR *algor1, - const ASN1_BIT_STRING *signature, - void *data, EVP_PKEY *pkey); - -OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *data, - EVP_PKEY *pkey, const EVP_MD *type); -OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, - EVP_MD_CTX *ctx); - OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); From a70973cf5cff2a2d096c3db080f06fef17f5bce4 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 13 Nov 2023 17:26:54 -0500 Subject: [PATCH 07/25] Trim X509_INFO and move to crypto/pem X509_INFO only exists to be a return value to PEM_X509_INFO_read. There is no use in letting callers create these objects, since they cannot do anything with it. Only X509_INFO_free is needed. Also cut a ton of unused fields from X509_PKEY. Change-Id: I322589f04883903e1fe5c23c3966ecf631e85b7f Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64127 Commit-Queue: Bob Beck Auto-Submit: David Benjamin Commit-Queue: David Benjamin Reviewed-by: Bob Beck (cherry picked from commit fcd464ce97d96fd0278ad3082a8429022ae2c4d7) --- crypto/CMakeLists.txt | 2 - crypto/pem/pem_info.c | 31 ++++++++++++ crypto/x509/x_info.c | 94 ----------------------------------- crypto/x509/x_pkey.c | 110 ----------------------------------------- include/openssl/pem.h | 32 +++++++++++- include/openssl/x509.h | 39 --------------- 6 files changed, 62 insertions(+), 246 deletions(-) delete mode 100644 crypto/x509/x_pkey.c diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 26b93b2dcf..f158992347 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -484,9 +484,7 @@ add_library( x509/x_attrib.c x509/x_crl.c x509/x_exten.c - x509/x_info.c x509/x_name.c - x509/x_pkey.c x509/x_pubkey.c x509/x_req.c x509/x_sig.c diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c index c097013d40..db8275b3ae 100644 --- a/crypto/pem/pem_info.c +++ b/crypto/pem/pem_info.c @@ -69,6 +69,37 @@ #include #include + +static X509_PKEY *X509_PKEY_new(void) { + return OPENSSL_zalloc(sizeof(X509_PKEY)); +} + +static void X509_PKEY_free(X509_PKEY *x) { + if (x == NULL) { + return; + } + + EVP_PKEY_free(x->dec_pkey); + OPENSSL_free(x); +} + +static X509_INFO *X509_INFO_new(void) { + return OPENSSL_zalloc(sizeof(X509_INFO)); +} + +void X509_INFO_free(X509_INFO *x) { + if (x == NULL) { + return; + } + + X509_free(x->x509); + X509_CRL_free(x->crl); + X509_PKEY_free(x->x_pkey); + OPENSSL_free(x->enc_data); + OPENSSL_free(x); +} + + STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u) { BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); diff --git a/crypto/x509/x_info.c b/crypto/x509/x_info.c index e4e2e73f2a..e69de29bb2 100644 --- a/crypto/x509/x_info.c +++ b/crypto/x509/x_info.c @@ -1,94 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include - -#include -#include -#include -#include -#include - -X509_INFO *X509_INFO_new(void) { - X509_INFO *ret = NULL; - - ret = (X509_INFO *)OPENSSL_zalloc(sizeof(X509_INFO)); - if (ret == NULL) { - return NULL; - } - - return ret; -} - -void X509_INFO_free(X509_INFO *x) { - if (x == NULL) { - return; - } - - if (x->x509 != NULL) { - X509_free(x->x509); - } - if (x->crl != NULL) { - X509_CRL_free(x->crl); - } - if (x->x_pkey != NULL) { - X509_PKEY_free(x->x_pkey); - } - if (x->enc_data != NULL) { - OPENSSL_free(x->enc_data); - } - OPENSSL_free(x); -} diff --git a/crypto/x509/x_pkey.c b/crypto/x509/x_pkey.c deleted file mode 100644 index 33a9aa91d2..0000000000 --- a/crypto/x509/x_pkey.c +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] */ - -#include - -#include - -#include -#include -#include -#include - -#include "../internal.h" - - -X509_PKEY *X509_PKEY_new(void) { - X509_PKEY *ret = OPENSSL_zalloc(sizeof(X509_PKEY)); - if (ret == NULL) { - goto err; - } - - ret->enc_algor = X509_ALGOR_new(); - if (ret->enc_algor == NULL) { - goto err; - } - ret->enc_pkey = ASN1_OCTET_STRING_new(); - if (ret->enc_pkey == NULL) { - goto err; - } - return ret; - -err: - if (ret != NULL) { - X509_PKEY_free(ret); - } - return NULL; -} - -void X509_PKEY_free(X509_PKEY *x) { - if (x == NULL) { - return; - } - - if (x->enc_algor != NULL) { - X509_ALGOR_free(x->enc_algor); - } - if (x->enc_pkey != NULL) { - ASN1_OCTET_STRING_free(x->enc_pkey); - } - if (x->dec_pkey != NULL) { - EVP_PKEY_free(x->dec_pkey); - } - if ((x->key_data != NULL) && (x->key_free)) { - OPENSSL_free(x->key_data); - } - OPENSSL_free(x); -} diff --git a/include/openssl/pem.h b/include/openssl/pem.h index b0a1174c76..0c060d4d9c 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -353,6 +353,25 @@ OPENSSL_EXPORT int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); +struct private_key_st { + EVP_PKEY *dec_pkey; +} /* X509_PKEY */; + +struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; +} /* X509_INFO */; + +DEFINE_STACK_OF(X509_INFO) + +// X509_INFO_free releases memory associated with |info|. +OPENSSL_EXPORT void X509_INFO_free(X509_INFO *info); + OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio( BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); @@ -460,7 +479,18 @@ OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, #ifdef __cplusplus -} +} // extern "C" + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { +BSSL_NAMESPACE_BEGIN + +BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) + +BSSL_NAMESPACE_END +} // extern "C++" +#endif // !BORINGSSL_NO_CXX + #endif #define PEM_R_BAD_BASE64_DECODE 100 diff --git a/include/openssl/x509.h b/include/openssl/x509.h index e3dea69274..72140eb7f6 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2737,37 +2737,6 @@ DEFINE_STACK_OF(X509_TRUST) DECLARE_STACK_OF(GENERAL_NAMES) -struct private_key_st { - int version; - // The PKCS#8 data types - X509_ALGOR *enc_algor; - ASN1_OCTET_STRING *enc_pkey; // encrypted pub key - - // When decrypted, the following will not be NULL - EVP_PKEY *dec_pkey; - - // used to encrypt and decrypt - int key_length; - char *key_data; - int key_free; // true if we should auto free key_data - - // expanded version of 'enc_algor' - EVP_CIPHER_INFO cipher; -} /* X509_PKEY */; - -struct X509_info_st { - X509 *x509; - X509_CRL *crl; - X509_PKEY *x_pkey; - - EVP_CIPHER_INFO enc_cipher; - int enc_len; - char *enc_data; - -} /* X509_INFO */; - -DEFINE_STACK_OF(X509_INFO) - // X509_verify_cert_error_string returns |err| as a human-readable string, where // |err| should be one of the |X509_V_*| values. If |err| is unknown, it returns // a default description. @@ -2783,12 +2752,6 @@ OPENSSL_EXPORT const char *X509_get_default_private_dir(void); OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); -OPENSSL_EXPORT X509_PKEY *X509_PKEY_new(void); -OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); - -OPENSSL_EXPORT X509_INFO *X509_INFO_new(void); -OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); - OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); @@ -3400,12 +3363,10 @@ BORINGSSL_MAKE_DELETER(X509_ATTRIBUTE, X509_ATTRIBUTE_free) BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free) BORINGSSL_MAKE_UP_REF(X509_CRL, X509_CRL_up_ref) BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free) -BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) BORINGSSL_MAKE_DELETER(X509_OBJECT, X509_OBJECT_free) BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) -BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free) BORINGSSL_MAKE_DELETER(X509_PUBKEY, X509_PUBKEY_free) BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free) BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free) From 6a68be8bbbeed46350aaf06c8c42c9334ea72476 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 18 Nov 2023 17:57:01 -0500 Subject: [PATCH 08/25] Remove X509_STORE_CTX_zero This was never used externally. It's a remnant of when we supported stack-allocated X509_STOREs, but now its opaque. Change-Id: Idb997237ca81f4c35795cfc8c9d2ee222629e1ce Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64128 Auto-Submit: David Benjamin Reviewed-by: Bob Beck Commit-Queue: Bob Beck (cherry picked from commit 698aa894c96412d4df20e2bb031d9eb9c9d5919a) --- crypto/x509/x509_vfy.c | 21 ++++++++------------- include/openssl/x509.h | 1 - 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 2213a139dd..86697e03b0 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1659,18 +1659,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, } X509_STORE_CTX *X509_STORE_CTX_new(void) { - X509_STORE_CTX *ctx; - ctx = (X509_STORE_CTX *)OPENSSL_zalloc(sizeof(X509_STORE_CTX)); - if (!ctx) { - return NULL; - } - // NO-OP: struct already zeroed - //X509_STORE_CTX_zero(ctx); - return ctx; -} - -void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) { - OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + return OPENSSL_zalloc(sizeof(X509_STORE_CTX)); } void X509_STORE_CTX_free(X509_STORE_CTX *ctx) { @@ -1683,7 +1672,13 @@ void X509_STORE_CTX_free(X509_STORE_CTX *ctx) { int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { - X509_STORE_CTX_zero(ctx); + // TODO(davidben): This is a remnant of when |X509_STORE_CTX| was a + // stack-allocatable function. Now that it is heap-allocated, we don't need to + // worry about uninitialized memory in |ctx|. Move the memset to + // |X509_STORE_CTX_cleanup| and call |X509_STORE_CTX_cleanup| here so callers + // don't leak memory when re-initializing a previously initialized + // |X509_STORE_CTX|. + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); ctx->ctx = store; ctx->cert = x509; ctx->untrusted = chain; diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 72140eb7f6..1400ee750f 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -3123,7 +3123,6 @@ OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); -OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx); OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain); From ff66362f6a32ed12536c557856c85a6a79d8edc0 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Tue, 21 Nov 2023 12:01:38 -0500 Subject: [PATCH 09/25] Fix leak if X509_STORE_CTX_init is called on a previously initialized context This wasn't possible when X509_STORE_CTX was stack-allocated because X509_STORE_CTX_init needed to account for an uninitialized struct. But now it is always initialized, so we can avoid this footgun. This also matches what OpenSSL does nowadays. Change-Id: I266be58204b8cd374fa4896c1c66a35ffaa762ea Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64141 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 1685bd140f6eeb6939c73756be70c888dde32c5e) --- crypto/x509/x509_test.cc | 12 ++++++++++++ crypto/x509/x509_vfy.c | 11 +++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index e7d925baf2..2fd4a6ac1c 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -3888,6 +3888,18 @@ TEST(X509Test, NullStore) { EXPECT_FALSE(X509_STORE_CTX_init(ctx.get(), nullptr, leaf.get(), nullptr)); } +TEST(X509Test, StoreCtxReuse) { + bssl::UniquePtr leaf(CertFromPEM(kLeafPEM)); + ASSERT_TRUE(leaf); + bssl::UniquePtr store(X509_STORE_new()); + ASSERT_TRUE(store); + bssl::UniquePtr ctx(X509_STORE_CTX_new()); + ASSERT_TRUE(ctx); + ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr)); + // Re-initializing |ctx| should not leak memory. + ASSERT_TRUE(X509_STORE_CTX_init(ctx.get(), store.get(), leaf.get(), nullptr)); +} + TEST(X509Test, BasicConstraints) { const uint32_t kFlagMask = EXFLAG_CA | EXFLAG_BCONS | EXFLAG_INVALID; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 86697e03b0..5ad35f3a37 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1672,13 +1672,8 @@ void X509_STORE_CTX_free(X509_STORE_CTX *ctx) { int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, STACK_OF(X509) *chain) { - // TODO(davidben): This is a remnant of when |X509_STORE_CTX| was a - // stack-allocatable function. Now that it is heap-allocated, we don't need to - // worry about uninitialized memory in |ctx|. Move the memset to - // |X509_STORE_CTX_cleanup| and call |X509_STORE_CTX_cleanup| here so callers - // don't leak memory when re-initializing a previously initialized - // |X509_STORE_CTX|. - OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + X509_STORE_CTX_cleanup(ctx); + ctx->ctx = store; ctx->cert = x509; ctx->untrusted = chain; @@ -1805,7 +1800,7 @@ void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) { sk_X509_pop_free(ctx->chain, X509_free); ctx->chain = NULL; CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data)); - OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); } void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) { From 526543f4e4044f34b2d57eb6bdf0e49d5b45b054 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 18 Nov 2023 19:31:24 -0500 Subject: [PATCH 10/25] Add X509_OBJECT_new and X509_OBJECT_free This is a bit of a mess. The immediate motivation here is that there is no legitimate reason to ever call X509_OBJECT_free_contents outside of the library. Unsurprisingly, this means rust-openssl uses it. rust-openssl uses it because they want to be able to free X509_OBJECTs. Add OpenSSL 1.1.x's X509_OBJECT_free, which is what they should be using it instead. As it turns out, they don't *actually* need to free X509_OBJECTs. This is just some design mistake that cause them to need free functions for types they never free. On top of that, the only reason rust-openssl references X509_OBJECT is for X509_STORE_get0_objects, but their use of that API is a Rust safety violation anyway. It's all a mess. As for whether freeing it ever makes sense, the question is whether X509_STORE_get_by_subject needs to be a public API. In so far as it is public, callers would need to create empty X509_OBJECTs as an output, now that X509_OBJECT is opaque. There are also other users of X509_STORE_get0_objects that might benefit from an X509_STORE_get1_objects, in which case X509_OBJECT_free will be useful. For now just to unblock fixing the more immediate rust-openssl mistake (rather than the underlying mistake), add the APIs that X509_STORE_get_by_subject callers would need if they existed. There's quite a bit to clean up around X509_OBJECT, but start by adding these APIs. As part of this, since rust-openssl prevents us from removing X509_OBJECT_free_contents, deprecate it and fix it to leave the X509_OBJECT in a self-consistent state. (This is moot because rust-openssl will never call it, but still.) Change-Id: I78708f2d2464eb9a18844fef0d62cb0a727b9f47 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64129 Reviewed-by: Bob Beck Auto-Submit: David Benjamin Commit-Queue: David Benjamin (cherry picked from commit c2b7df5850398dc7c73146c07f6eed95dd363a48) --- crypto/x509/x509_lu.c | 39 ++++++++++++--------------------------- include/openssl/x509.h | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index bcad1043d8..024c3e7a4c 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -217,21 +217,6 @@ int X509_STORE_up_ref(X509_STORE *store) { return 1; } -static void cleanup(X509_OBJECT *a) { - if (a == NULL) { - return; - } - if (a->type == X509_LU_X509) { - X509_free(a->data.x509); - } else if (a->type == X509_LU_CRL) { - X509_CRL_free(a->data.crl); - } else { - // abort(); - } - - OPENSSL_free(a); -} - void X509_STORE_free(X509_STORE *vfy) { size_t j; STACK_OF(X509_LOOKUP) *sk; @@ -254,7 +239,7 @@ void X509_STORE_free(X509_STORE *vfy) { X509_LOOKUP_free(lu); } sk_X509_LOOKUP_free(sk); - sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + sk_X509_OBJECT_pop_free(vfy->objs, X509_OBJECT_free); if (vfy->param) { X509_VERIFY_PARAM_free(vfy->param); @@ -328,7 +313,7 @@ static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) { return 0; } - X509_OBJECT *const obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + X509_OBJECT *const obj = X509_OBJECT_new(); if (obj == NULL) { return 0; } @@ -354,8 +339,7 @@ static int x509_store_add(X509_STORE *ctx, void *x, int is_crl) { CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); if (!added) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); + X509_OBJECT_free(obj); } return ret; @@ -370,11 +354,15 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) { } X509_OBJECT *X509_OBJECT_new(void) { - X509_OBJECT *ret = OPENSSL_zalloc(sizeof(X509_OBJECT)); - if (ret == NULL) { - return NULL; + return OPENSSL_zalloc(sizeof(X509_OBJECT)); +} + +void X509_OBJECT_free(X509_OBJECT *obj) { + if (obj == NULL) { + return; } - return ret; + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); } int X509_OBJECT_up_ref_count(X509_OBJECT *a) { @@ -398,11 +386,8 @@ void X509_OBJECT_free_contents(X509_OBJECT *a) { X509_CRL_free(a->data.crl); break; } -} -void X509_OBJECT_free(X509_OBJECT *a) { - X509_OBJECT_free_contents(a); - OPENSSL_free(a); + OPENSSL_memset(a, 0, sizeof(X509_OBJECT)); } int X509_OBJECT_get_type(const X509_OBJECT *a) { return a->type; } diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 1400ee750f..9ebe5d4189 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2824,6 +2824,7 @@ The X509_STORE then calls a function to actually verify the certificate chain. */ +#define X509_LU_NONE 0 #define X509_LU_X509 1 #define X509_LU_CRL 2 #define X509_LU_PKEY 3 @@ -3021,6 +3022,22 @@ OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject( STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); + +// X509_OBJECT_new returns a newly-allocated, empty |X509_OBJECT| or NULL on +// error. +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_new(void); + +// X509_OBJECT_free releases memory associated with |obj|. +OPENSSL_EXPORT void X509_OBJECT_free(X509_OBJECT *obj); + +// X509_OBJECT_get_type returns the type of |obj|, which will be one of the +// |X509_LU_*| constants. +OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *obj); + +// X509_OBJECT_get0_X509 returns |obj| as a certificate, or NULL if |obj| is not +// a certificate. +OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *obj); + OPENSSL_EXPORT int X509_OBJECT_up_ref_count(X509_OBJECT *a); OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *a); OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); From 18e6bf5145e7a28619cd09a218b25518c4332d77 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 18 Nov 2023 19:48:21 -0500 Subject: [PATCH 11/25] Unexport various unused X509_OBJECT and X509_LOOKUP functions. Some things of note: - Anyone calling X509_OBJECT_up_ref_count is breaking X509_OBJECT's internal invariants, or relying on someone else handing back an X509_OBJECT with broken invariants. - X509_LOOKUP_by_subject hands back an X509_OBJECT with broken internal invariants. Fortunately, it is never called, so unexport it as a the first step to cleaning this up. Change-Id: Ia67693f802671cf857bf51aec6e20f27d1525212 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64130 Auto-Submit: David Benjamin Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit d9b81bb43a24b3adb6e8a616a4828e1bad89c486) --- crypto/x509/x509_lu.c | 53 ++++++++++++++++++++++------------------ crypto/x509/x509_test.cc | 11 ++------- include/openssl/x509.h | 23 ++++++----------- 3 files changed, 38 insertions(+), 49 deletions(-) diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 024c3e7a4c..d8dac39eaf 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -65,10 +65,22 @@ #include "../internal.h" #include "internal.h" -X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) { - X509_LOOKUP *ret; - ret = (X509_LOOKUP *)OPENSSL_zalloc(sizeof(X509_LOOKUP)); +static int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +static X509_OBJECT *X509_OBJECT_retrieve_by_subject( + STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); +static X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +static int X509_OBJECT_up_ref_count(X509_OBJECT *a); + +static X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +static int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +static int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +static X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) { + X509_LOOKUP *ret = OPENSSL_zalloc(sizeof(X509_LOOKUP)); if (ret == NULL) { return NULL; } @@ -91,18 +103,7 @@ void X509_LOOKUP_free(X509_LOOKUP *ctx) { OPENSSL_free(ctx); } -int X509_LOOKUP_init(X509_LOOKUP *ctx) { - if (ctx->method == NULL) { - return 0; - } - if (ctx->method->init != NULL) { - return ctx->method->init(ctx); - } else { - return 1; - } -} - -int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) { +static int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) { if (ctx->method == NULL) { return 0; } @@ -125,14 +126,18 @@ int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, } } -int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, - X509_OBJECT *ret) { +static int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret) { if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) { return 0; } if (ctx->skip) { return 0; } + // Note |get_by_subject| leaves |ret| in an inconsistent state. It has + // pointers to an |X509| or |X509_CRL|, but has not bumped the refcount yet. + // For now, the caller is expected to fix this, but ideally we'd fix the + // |X509_LOOKUP| convention itself. return ctx->method->get_by_subject(ctx, type, name, ret) > 0; } @@ -365,7 +370,7 @@ void X509_OBJECT_free(X509_OBJECT *obj) { OPENSSL_free(obj); } -int X509_OBJECT_up_ref_count(X509_OBJECT *a) { +static int X509_OBJECT_up_ref_count(X509_OBJECT *a) { switch (a->type) { case X509_LU_X509: X509_up_ref(a->data.x509); @@ -473,13 +478,13 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, return (int)idx; } -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name) { +static int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) { return x509_object_idx_cnt(h, type, name, NULL); } -X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name) { +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name) { int idx; idx = X509_OBJECT_idx_by_subject(h, type, name); if (idx == -1) { @@ -574,8 +579,8 @@ STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) { return sk; } -X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, - X509_OBJECT *x) { +static X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x) { sk_X509_OBJECT_sort(h); size_t idx; if (!sk_X509_OBJECT_find_awslc(h, &idx, x)) { diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index 2fd4a6ac1c..2d4bb95e85 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -1851,7 +1851,7 @@ TEST(X509Test, MatchFoundSetsPeername) { char *peername = nullptr; EXPECT_NE(1, X509_check_host(leaf.get(), kWrongHostname, strlen(kWrongHostname), 0, &peername)); ASSERT_EQ(nullptr, peername); - + EXPECT_EQ(1, X509_check_host(leaf.get(), kHostname, strlen(kHostname), 0, &peername)); EXPECT_STREQ(peername, kHostname); OPENSSL_free(peername); @@ -5086,15 +5086,8 @@ TEST(X509Test, AddDuplicates) { ASSERT_TRUE(X509_STORE_lock(store.get())); // Sleep after taking the lock to cause contention. Sleep longer than the // adder half of threads to ensure we hold the lock while they contend - // for it. |X509_OBJECT_retrieve_by_subject| is called because it doesn't - // take a lock on the store, thus avoiding deadlock. + // for it. std::this_thread::sleep_for(std::chrono::microseconds(11 + (sleep_buf[0] % 5))); - EXPECT_TRUE(X509_OBJECT_retrieve_by_subject( - store->objs, X509_LU_X509, X509_get_subject_name(a.get()) - )); - EXPECT_TRUE(X509_OBJECT_retrieve_by_subject( - store->objs, X509_LU_X509, X509_get_subject_name(b.get()) - )); ASSERT_TRUE(X509_STORE_unlock(store.get())); }); } diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 9ebe5d4189..9e3091a4cf 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2658,6 +2658,13 @@ OPENSSL_EXPORT int X509_NAME_get_text_by_NID(const X509_NAME *name, int nid, OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx( X509_STORE_CTX *ctx); +// X509_LOOKUP_free releases memory associated with |ctx|. This function should +// never be used outside the library. No function in the public API hands +// ownership of an |X509_LOOKUP| to the caller. +// +// TODO(davidben): Unexport this function after rust-openssl is fixed to no +// longer call it. +OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); // Private structures. @@ -3016,13 +3023,6 @@ OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_new(void); // X509_OBJECT_free frees an |X509_OBJECT| from the heap. OPENSSL_EXPORT void X509_OBJECT_free(X509_OBJECT *a); -OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, - int type, X509_NAME *name); -OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject( - STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name); -OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, - X509_OBJECT *x); - // X509_OBJECT_new returns a newly-allocated, empty |X509_OBJECT| or NULL on // error. OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_new(void); @@ -3038,7 +3038,6 @@ OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *obj); // a certificate. OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *obj); -OPENSSL_EXPORT int X509_OBJECT_up_ref_count(X509_OBJECT *a); OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *a); OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); // X509_OBJECT_get0_X509_CRL returns the |X509_CRL| associated with |a| @@ -3182,13 +3181,6 @@ OPENSSL_EXPORT int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); -OPENSSL_EXPORT X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); -OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); -OPENSSL_EXPORT int X509_LOOKUP_init(X509_LOOKUP *ctx); -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); - 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); @@ -3379,7 +3371,6 @@ BORINGSSL_MAKE_DELETER(X509_ATTRIBUTE, X509_ATTRIBUTE_free) BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free) BORINGSSL_MAKE_UP_REF(X509_CRL, X509_CRL_up_ref) BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free) -BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) BORINGSSL_MAKE_DELETER(X509_OBJECT, X509_OBJECT_free) BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) From 0afd2a8ab9ae310264e5089380fa42835d351f80 Mon Sep 17 00:00:00 2001 From: dkostic <25055813+dkostic@users.noreply.github.com> Date: Tue, 9 Apr 2024 11:08:03 -0700 Subject: [PATCH 12/25] Add NULL checks to EVP_MD_CTX_cleanse/cleanup (#1519) Add NULL checks to EVP_MD_CTX_cleanse/cleanup. --- crypto/fipsmodule/digest/digest.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/digest/digest.c b/crypto/fipsmodule/digest/digest.c index 0ba7427e11..8e279ca58f 100644 --- a/crypto/fipsmodule/digest/digest.c +++ b/crypto/fipsmodule/digest/digest.c @@ -98,12 +98,15 @@ EVP_MD_CTX *EVP_MD_CTX_new(void) { EVP_MD_CTX *EVP_MD_CTX_create(void) { return EVP_MD_CTX_new(); } int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { + if (ctx == NULL) { + return 1; + } + OPENSSL_free(ctx->md_data); assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); // |pctx| should be freed by the user of |EVP_MD_CTX| if - // |EVP_MD_CTX_FLAG_KEEP_PKEY_CTX| is set. Everything other than the external - // |pctx| that |ctx->pctx| was pointing to is cleaned up when the flag is set. + // |EVP_MD_CTX_FLAG_KEEP_PKEY_CTX| is set. Everything other than the external |pctx| that |ctx->pctx| was pointing to is cleaned up when the flag is set. if (ctx->pctx_ops && !(ctx->flags & EVP_MD_CTX_FLAG_KEEP_PKEY_CTX)) { ctx->pctx_ops->free(ctx->pctx); } @@ -114,6 +117,9 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { } void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx) { + if (ctx == NULL || ctx->md_data == NULL || ctx->digest == NULL) { + return; + } OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); EVP_MD_CTX_cleanup(ctx); } From 388f7605e72c34c2b2a7dfddcb118cd687641a18 Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Wed, 10 Apr 2024 14:25:46 -0400 Subject: [PATCH 13/25] CI for compiling w/ Clang on Windows (#1520) --- .../workflows/{mingw.yml => windows-alt.yml} | 30 ++++++++++++++++++- tool/bssl_bm.h | 4 ++- 2 files changed, 32 insertions(+), 2 deletions(-) rename .github/workflows/{mingw.yml => windows-alt.yml} (59%) diff --git a/.github/workflows/mingw.yml b/.github/workflows/windows-alt.yml similarity index 59% rename from .github/workflows/mingw.yml rename to .github/workflows/windows-alt.yml index 8d7075ed60..3390603c5f 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/windows-alt.yml @@ -1,4 +1,4 @@ -name: MinGW +name: Windows Alternative Compilers on: pull_request: branches: [ '*' ] @@ -40,3 +40,31 @@ jobs: run: cmake --build ./build --target all - name: Run tests run: cmake --build ./build --target run_tests + clang: + if: github.repository == 'aws/aws-lc' + runs-on: windows-latest + steps: + - name: Install NASM + uses: ilammy/setup-nasm@v1.5.1 + - name: Checkout + uses: actions/checkout@v4 + - name: Install LLVM and Clang + uses: KyleMayes/install-llvm-action@v2 + id: clang + with: + version: 16 + env: true + - name: Setup CMake + uses: threeal/cmake-action@v1.3.0 + with: + generator: Ninja + c-compiler: "C:/Program Files/LLVM/bin/clang.exe" + cxx-compiler: "C:/Program Files/LLVM/bin/clang++.exe" + options: | + CMAKE_SYSTEM_NAME=Windows \ + CMAKE_SYSTEM_PROCESSOR=x86_64 \ + CMAKE_BUILD_TOOL=ninja.exe \ + - name: Build Project + run: cmake --build ./build --target all + - name: Run tests + run: cmake --build ./build --target run_tests diff --git a/tool/bssl_bm.h b/tool/bssl_bm.h index 247e36886e..2671b162f6 100644 --- a/tool/bssl_bm.h +++ b/tool/bssl_bm.h @@ -30,8 +30,10 @@ #if defined(INTERNAL_TOOL) #include <../crypto/ec_extra/internal.h> #include <../crypto/trust_token/internal.h> +#if defined(FIPS_ENTROPY_SOURCE_JITTER_CPU) #include "../third_party/jitterentropy/jitterentropy.h" -#endif +#endif // FIPS_ENTROPY_SOURCE_JITTER_CPU +#endif // INTERNAL_TOOL #define BM_NAMESPACE bssl #define BM_ECDSA_size(key) ECDSA_size(key) From dd247e288de4b17825a92620232d9266e6341009 Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Wed, 10 Apr 2024 11:59:12 -0700 Subject: [PATCH 14/25] add support for X509_get_signature_info (#1504) MySQL 8.2/8.3 depends on`X509_get_signature_info`. This symbol originated from an OpenSSL 1.1.1 commit (openssl/openssl@786dd2c) implementing support for "custom signature parameters". The commit mainly allows the user to set and retrieve information about the signature type. There's also a custom ASN1 method handler that OpenSSL implemented in this commit. We don't support custom `EVP_PKEY` ASN1 methods and setting your own signature information doesn't make much sense without the custom methods, so I've only implemented support for retrieving the signature type. MySQL only depends on retrieving the signature info, so this fits our use case. Note: `CryptoAlg-2393` was cut to track missing RSA PSS support in libssl, which was uncovered in the postgres CI. --- crypto/err/x509.errordata | 1 + crypto/x509/internal.h | 20 ++- crypto/x509/x509_set.c | 76 ++++++++++ crypto/x509/x509_test.cc | 31 +++++ crypto/x509v3/v3_purp.c | 7 +- generated-src/err_data.c | 130 +++++++++--------- include/openssl/base.h | 1 + include/openssl/x509.h | 23 +++- .../postgres_patch/aws-lc-postgres.patch | 33 +++++ .../integration/run_postgres_integration.sh | 5 + 10 files changed, 256 insertions(+), 71 deletions(-) create mode 100644 tests/ci/integration/postgres_patch/aws-lc-postgres.patch diff --git a/crypto/err/x509.errordata b/crypto/err/x509.errordata index e30d667bd7..ab886f6700 100644 --- a/crypto/err/x509.errordata +++ b/crypto/err/x509.errordata @@ -39,6 +39,7 @@ X509,137,SIGNATURE_ALGORITHM_MISMATCH X509,128,UNKNOWN_KEY_TYPE X509,129,UNKNOWN_NID X509,130,UNKNOWN_PURPOSE_ID +X509,145,UNKNOWN_SIGID_ALGS X509,131,UNKNOWN_TRUST_ID X509,132,UNSUPPORTED_ALGORITHM X509,133,WRONG_LOOKUP_TYPE diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 5de3ed8daa..0fa48b1788 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h @@ -139,10 +139,21 @@ typedef struct { // an |X509_NAME|. DECLARE_ASN1_FUNCTIONS(X509_CINF) +struct x509_sig_info_st { + // NID of message digest. + int digest_nid; + // NID of public key algorithm. + int pubkey_nid; + // Security bits. + int sec_bits; + uint32_t flags; +} /* X509_SIG_INFO */; + struct x509_st { X509_CINF *cert_info; X509_ALGOR *sig_alg; ASN1_BIT_STRING *signature; + X509_SIG_INFO sig_info; CRYPTO_refcount_t references; CRYPTO_EX_DATA ex_data; // These contain copies of various extension values @@ -350,9 +361,9 @@ struct x509_store_ctx_st { X509_STORE_CTX_cleanup_fn cleanup; // The following is built up - int valid; // if 0, rebuild chain - int last_untrusted; // index of last untrusted cert - STACK_OF(X509) *chain; // chain of X509s - built up and trusted + int valid; // if 0, rebuild chain + int last_untrusted; // index of last untrusted cert + STACK_OF(X509) *chain; // chain of X509s - built up and trusted // When something goes wrong, this is why int error_depth; @@ -415,6 +426,9 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey); +// x509_init_signature_info initializes the signature info for |x509|. +int x509_init_signature_info(X509 *x509); + // Path-building functions. diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c index bfc3ae0152..33307896f3 100644 --- a/crypto/x509/x509_set.c +++ b/crypto/x509/x509_set.c @@ -60,7 +60,9 @@ #include #include +#include "../x509v3/internal.h" #include "internal.h" +#include "openssl/x509v3.h" long X509_get_version(const X509 *x509) { @@ -238,3 +240,77 @@ const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) { X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509) { return x509->cert_info->key; } + +static int X509_SIG_INFO_get(const X509_SIG_INFO *sig_info, int *digest_nid, + int *pubkey_nid, int *sec_bits, uint32_t *flags) { + if (sig_info == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (digest_nid != NULL) { + *digest_nid = sig_info->digest_nid; + } + if (pubkey_nid != NULL) { + *pubkey_nid = sig_info->pubkey_nid; + } + if (sec_bits != NULL) { + *sec_bits = sig_info->sec_bits; + } + if (flags != NULL) { + *flags = sig_info->flags; + } + return (sig_info->flags & X509_SIG_INFO_VALID) != 0; +} + +int X509_get_signature_info(X509 *x509, int *digest_nid, int *pubkey_nid, + int *sec_bits, uint32_t *flags) { + if (x509 == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + // The return value of |x509v3_cache_extensions| is not checked because + // |X509_get_signature_info|'s function contract does not encapsulate failures + // if any invalid extensions do exist. + x509v3_cache_extensions(x509); + return X509_SIG_INFO_get(&x509->sig_info, digest_nid, pubkey_nid, sec_bits, + flags); +} + +int x509_init_signature_info(X509 *x509) { + int pubkey_nid, digest_nid; + const EVP_MD *md; + + x509->sig_info.digest_nid = NID_undef; + x509->sig_info.pubkey_nid = NID_undef; + x509->sig_info.sec_bits = -1; + x509->sig_info.flags = 0; + if (!OBJ_find_sigid_algs(OBJ_obj2nid(x509->sig_alg->algorithm), &digest_nid, + &pubkey_nid) || + pubkey_nid == NID_undef) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_SIGID_ALGS); + return 0; + } + x509->sig_info.pubkey_nid = pubkey_nid; + x509->sig_info.digest_nid = digest_nid; + x509->sig_info.flags |= X509_SIG_INFO_VALID; + + md = EVP_get_digestbynid(digest_nid); + if (md == NULL) { + // Some valid signature algorithms have an undefined digest. See + // crypto/obj/obj_xref.c. + return 1; + } + // Security bits: half number of bits in digest. + x509->sig_info.sec_bits = (int)EVP_MD_size(md) * 4; + + switch (digest_nid) { + case NID_sha1: + case NID_sha256: + case NID_sha384: + case NID_sha512: + x509->sig_info.flags |= X509_SIG_INFO_TLS; + } + return 1; +} diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index 2d4bb95e85..ea861db1c5 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -7062,3 +7062,34 @@ TEST(X509Test, GetTextByOBJ) { } } } + +TEST(X509Test, GetSigInfo) { + bssl::UniquePtr cert(CertFromPEM(kLeafPEM)); + ASSERT_TRUE(cert); + + int digest_nid, pubkey_nid, sec_bits; + uint32_t flags; + EXPECT_TRUE(X509_get_signature_info(cert.get(), &digest_nid, &pubkey_nid, + &sec_bits, &flags)); + + EXPECT_EQ(digest_nid, NID_sha256); + EXPECT_EQ(pubkey_nid, NID_rsaEncryption); + EXPECT_EQ(sec_bits, (int)EVP_MD_size(EVP_sha256()) * 4); + EXPECT_TRUE(flags & (X509_SIG_INFO_VALID | X509_SIG_INFO_TLS)); + + cert = CertFromPEM(kEd25519Cert); + EXPECT_TRUE(X509_get_signature_info(cert.get(), &digest_nid, &pubkey_nid, + &sec_bits, &flags)); + EXPECT_EQ(digest_nid, NID_undef); + EXPECT_EQ(pubkey_nid, NID_ED25519); + EXPECT_EQ(sec_bits, -1); + EXPECT_TRUE(flags & X509_SIG_INFO_VALID); + + cert = CertFromPEM(kExampleRsassaPssCert); + EXPECT_TRUE(X509_get_signature_info(cert.get(), &digest_nid, &pubkey_nid, + &sec_bits, &flags)); + EXPECT_EQ(digest_nid, NID_undef); + EXPECT_EQ(pubkey_nid, NID_rsaEncryption); + EXPECT_EQ(sec_bits, -1); + EXPECT_TRUE(flags & X509_SIG_INFO_VALID); +} diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index 1696225f53..2aa21119a7 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -132,7 +132,9 @@ static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) { // As much as I'd like to make X509_check_purpose use a "const" X509* I // really can't because it does recalculate hashes and do other non-const -// things. +// things. If |id| is -1 it just calls |x509v3_cache_extensions| for its +// side-effect. +// Returns 1 on success, 0 if x does not allow purpose, -1 on (internal) error. int X509_check_purpose(X509 *x, int id, int ca) { int idx; const X509_PURPOSE *pt; @@ -550,6 +552,9 @@ int x509v3_cache_extensions(X509 *x) { break; } } + if (!x509_init_signature_info(x)) { + x->ex_flags |= EXFLAG_INVALID; + } x->ex_flags |= EXFLAG_SET; CRYPTO_MUTEX_unlock_write(&x->lock); diff --git a/generated-src/err_data.c b/generated-src/err_data.c index 672078671c..957d14637c 100644 --- a/generated-src/err_data.c +++ b/generated-src/err_data.c @@ -233,9 +233,9 @@ const uint32_t kOpenSSLReasonValues[] = { 0x2c403998, 0x2c4093a9, 0x2c4139a9, - 0x2c41b9bc, + 0x2c41b9cf, 0x2c42136f, - 0x2c42b9cd, + 0x2c42b9e0, 0x2c43076d, 0x2c43b8b3, 0x2c4437fb, @@ -247,6 +247,7 @@ const uint32_t kOpenSSLReasonValues[] = { 0x2c4738ea, 0x2c47b923, 0x2c48380d, + 0x2c48b9bc, 0x30320000, 0x30328015, 0x3033001f, @@ -705,71 +706,71 @@ const uint32_t kOpenSSLReasonValues[] = { 0x4c4197bc, 0x4c421925, 0x4c429704, - 0x503239df, - 0x5032b9ee, - 0x503339f9, - 0x5033ba09, - 0x50343a22, - 0x5034ba3c, - 0x50353a4a, - 0x5035ba60, - 0x50363a72, - 0x5036ba88, - 0x50373aa1, - 0x5037bab4, - 0x50383acc, - 0x5038badd, - 0x50393af2, - 0x5039bb06, - 0x503a3b26, - 0x503abb3c, - 0x503b3b54, - 0x503bbb66, - 0x503c3b82, - 0x503cbb99, - 0x503d3bb2, - 0x503dbbc8, - 0x503e3bd5, - 0x503ebbeb, - 0x503f3bfd, + 0x503239f2, + 0x5032ba01, + 0x50333a0c, + 0x5033ba1c, + 0x50343a35, + 0x5034ba4f, + 0x50353a5d, + 0x5035ba73, + 0x50363a85, + 0x5036ba9b, + 0x50373ab4, + 0x5037bac7, + 0x50383adf, + 0x5038baf0, + 0x50393b05, + 0x5039bb19, + 0x503a3b39, + 0x503abb4f, + 0x503b3b67, + 0x503bbb79, + 0x503c3b95, + 0x503cbbac, + 0x503d3bc5, + 0x503dbbdb, + 0x503e3be8, + 0x503ebbfe, + 0x503f3c10, 0x503f83b3, - 0x50403c10, - 0x5040bc20, - 0x50413c3a, - 0x5041bc49, - 0x50423c63, - 0x5042bc80, - 0x50433c90, - 0x5043bca0, - 0x50443cbd, + 0x50403c23, + 0x5040bc33, + 0x50413c4d, + 0x5041bc5c, + 0x50423c76, + 0x5042bc93, + 0x50433ca3, + 0x5043bcb3, + 0x50443cd0, 0x50448469, - 0x50453cd1, - 0x5045bcef, - 0x50463d02, - 0x5046bd18, - 0x50473d2a, - 0x5047bd3f, - 0x50483d65, - 0x5048bd73, - 0x50493d86, - 0x5049bd9b, - 0x504a3db1, - 0x504abdc1, - 0x504b3de1, - 0x504bbdf4, - 0x504c3e17, - 0x504cbe45, - 0x504d3e72, - 0x504dbe8f, - 0x504e3eaa, - 0x504ebec6, - 0x504f3ed8, - 0x504fbeef, - 0x50503efe, + 0x50453ce4, + 0x5045bd02, + 0x50463d15, + 0x5046bd2b, + 0x50473d3d, + 0x5047bd52, + 0x50483d78, + 0x5048bd86, + 0x50493d99, + 0x5049bdae, + 0x504a3dc4, + 0x504abdd4, + 0x504b3df4, + 0x504bbe07, + 0x504c3e2a, + 0x504cbe58, + 0x504d3e85, + 0x504dbea2, + 0x504e3ebd, + 0x504ebed9, + 0x504f3eeb, + 0x504fbf02, + 0x50503f11, 0x50508729, - 0x50513f11, - 0x5051bcaf, - 0x50523e57, + 0x50513f24, + 0x5051bcc2, + 0x50523e6a, 0x583210b7, 0x5c3293b5, 0x5c3313ce, @@ -1534,6 +1535,7 @@ const char kOpenSSLReasonStringData[] = "SIGNATURE_ALGORITHM_MISMATCH\0" "UNKNOWN_KEY_TYPE\0" "UNKNOWN_PURPOSE_ID\0" + "UNKNOWN_SIGID_ALGS\0" "UNKNOWN_TRUST_ID\0" "WRONG_LOOKUP_TYPE\0" "BAD_IP_ADDRESS\0" diff --git a/include/openssl/base.h b/include/openssl/base.h index b643bfea39..6c5d0afb93 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -300,6 +300,7 @@ typedef struct X509_name_entry_st X509_NAME_ENTRY; typedef struct X509_name_st X509_NAME; typedef struct X509_pubkey_st X509_PUBKEY; typedef struct X509_req_st X509_REQ; +typedef struct x509_sig_info_st X509_SIG_INFO; typedef struct X509_sig_st X509_SIG; typedef struct bignum_ctx BN_CTX; typedef struct bignum_st BIGNUM; diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 9e3091a4cf..99ae0187b3 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -275,6 +275,22 @@ OPENSSL_EXPORT void *X509_get_ext_d2i(const X509 *x509, int nid, // but they will be rejected when verifying. OPENSSL_EXPORT const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x509); +// X509_SIG_INFO_* are flags for |X509_get_signature_info|. +// X509_SIG_INFO_VALID means that the signature info is valid. +#define X509_SIG_INFO_VALID 0x1 +// X509_SIG_INFO_TLS means that the signature is suitable for TLS use. +#define X509_SIG_INFO_TLS 0x2 + +// X509_get_signature_info retrieves information about the signature of |x509|. +// The NID of the signing digest is written to |digest_nid|, the public key +// algorithm to |pubkey_nid|, the effective security bits to |sec_bits|, and +// flag details to |flags|. Parameters other than |x509| can be set to NULL if +// the information is not required. It is an error to pass a null pointer to +// |x509|. +OPENSSL_EXPORT int X509_get_signature_info(X509 *x509, int *digest_nid, + int *pubkey_nid, int *sec_bits, + uint32_t *flags); + // X509_get0_signature sets |*out_sig| and |*out_alg| to the signature and // signature algorithm of |x509|, respectively. Either output pointer may be // NULL to ignore the value. @@ -2279,7 +2295,8 @@ OPENSSL_EXPORT int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase); // This function outputs a legacy format that does not correctly handle string // encodings and other cases. Prefer |X509_NAME_print_ex| if printing a name for // debugging purposes. -OPENSSL_EXPORT char *X509_NAME_oneline(const X509_NAME *name, char *buf, int size); +OPENSSL_EXPORT char *X509_NAME_oneline(const X509_NAME *name, char *buf, + int size); // X509_NAME_print_ex_fp behaves like |X509_NAME_print_ex| but writes to |fp|. OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, const X509_NAME *nm, @@ -3259,8 +3276,7 @@ OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, // may be |X509_LU_X509| or |X509_LU_CRL|, and the subject name from the store // in |vs|. If found and |ret| is not NULL, it increments the reference count // and stores the object in |ret|. -OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, - int type, +OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, X509_OBJECT *ret); @@ -3433,5 +3449,6 @@ BSSL_NAMESPACE_END #define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 142 #define X509_R_NO_CRL_FOUND 143 #define X509_R_INVALID_POLICY_EXTENSION 144 +#define X509_R_UNKNOWN_SIGID_ALGS 145 #endif // OPENSSL_HEADER_X509_H diff --git a/tests/ci/integration/postgres_patch/aws-lc-postgres.patch b/tests/ci/integration/postgres_patch/aws-lc-postgres.patch new file mode 100644 index 0000000000..6ba8b59473 --- /dev/null +++ b/tests/ci/integration/postgres_patch/aws-lc-postgres.patch @@ -0,0 +1,33 @@ +diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl +index dd93224124..44f570c8e2 100644 +--- a/src/test/ssl/t/002_scram.pl ++++ b/src/test/ssl/t/002_scram.pl +@@ -155,14 +155,18 @@ $node->connect_ok( + # Now test with a server certificate that uses the RSA-PSS algorithm. + # This checks that the certificate can be loaded and that channel binding + # works. (see bug #17760) +-if ($supports_rsapss_certs) +-{ +- switch_server_cert($node, certfile => 'server-rsapss'); +- $node->connect_ok( +- "$common_connstr user=ssltestuser channel_binding=require", +- "SCRAM with SSL and channel_binding=require, server certificate uses 'rsassaPss'", +- log_like => [ +- qr/connection authenticated: identity="ssltestuser" method=scram-sha-256/ +- ]); +-} ++# ++# AWS-LC does not support RSA-PSS certificates in libssl. If there is a relevant ++# feature request for this, cut an issue to our public repository. ++# ++# if ($supports_rsapss_certs) ++# { ++# switch_server_cert($node, certfile => 'server-rsapss'); ++# $node->connect_ok( ++# "$common_connstr user=ssltestuser channel_binding=require", ++# "SCRAM with SSL and channel_binding=require, server certificate uses 'rsassaPss'", ++# log_like => [ ++# qr/connection authenticated: identity="ssltestuser" method=scram-sha-256/ ++# ]); ++# } + done_testing(); diff --git a/tests/ci/integration/run_postgres_integration.sh b/tests/ci/integration/run_postgres_integration.sh index 20aa6f7603..506208bf48 100755 --- a/tests/ci/integration/run_postgres_integration.sh +++ b/tests/ci/integration/run_postgres_integration.sh @@ -17,6 +17,7 @@ source tests/ci/common_posix_setup.sh SCRATCH_FOLDER=${SRC_ROOT}/"POSTGRES_BUILD_ROOT" POSTGRES_SRC_FOLDER="${SCRATCH_FOLDER}/postgres" POSTGRES_BUILD_FOLDER="${SCRATCH_FOLDER}/postgres/build" +POSTGRES_PATCH_FOLDER="${SRC_ROOT}/tests/ci/integration/postgres_patch" AWS_LC_BUILD_FOLDER="${SCRATCH_FOLDER}/aws-lc-build" AWS_LC_INSTALL_FOLDER="${POSTGRES_SRC_FOLDER}/aws-lc-install" @@ -47,6 +48,10 @@ function postgres_patch() { for i in "${!POSTGRES_ERROR_STRING[@]}"; do find ./ -type f -name "001_ssltests.pl" | xargs sed -i -e "s|${POSTGRES_ERROR_STRING[$i]}|${AWS_LC_EXPECTED_ERROR_STRING[$i]}|g" done + for patchfile in $(find -L "${POSTGRES_PATCH_FOLDER}" -type f -name '*.patch'); do + echo "Apply patch $patchfile..." + patch -p1 --quiet -i "$patchfile" + done } # Get latest postgres version. From 3fa0916e1b7effaf164d7ee35550c16484a8d481 Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Wed, 10 Apr 2024 15:14:44 -0700 Subject: [PATCH 15/25] allow empty lists in SSL_CTX_set_ciphersuites (#1511) MySQL deprecated the usage of weaker ciphers in their test suite. This brought an additional gap to light, where OpenSSL allows the setting of empty strings in the Ciphersuite string configuration. This is known behavior since 1.1.1 and still exists today. I've reconfigured the behavior for `SSL_[CTX]_set_cipher_list` which is our OpenSSL compat layer, but kept the same behavior for `SSL_[CTX]_set_strict_cipher_list`. --- include/openssl/ssl.h | 9 +++++++-- ssl/ssl_cipher.cc | 8 +++++--- ssl/ssl_test.cc | 20 +++++++++++++------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index e53d0870cb..7fbe0c4dab 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1691,7 +1691,10 @@ OPENSSL_EXPORT int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, // |str| as a cipher string. It returns one on success and zero on failure. // // Prefer to use |SSL_CTX_set_strict_cipher_list|. This function tolerates -// garbage inputs, unless an empty cipher list results. +// garbage inputs, unless an empty cipher list results. However, an empty +// string which also results in an empty cipher list, is allowed. This +// behavior is strongly advised against and only meant for OpenSSL +// compatibility. // // Note: this API only sets the TLSv1.2 and below ciphers. // Use |SSL_CTX_set_ciphersuites| to configure TLS 1.3 specific ciphers. @@ -1711,7 +1714,9 @@ OPENSSL_EXPORT int SSL_CTX_set_ciphersuites(SSL_CTX *ctx, const char *str); // a cipher string. It returns one on success and zero on failure. // // Prefer to use |SSL_set_strict_cipher_list|. This function tolerates garbage -// inputs, unless an empty cipher list results. +// inputs, unless an empty cipher list results. However, an empty string which +// also results in an empty cipher list, is allowed. This behavior is strongly +// advised against and only meant for OpenSSL compatibility. OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str); // SSL_CTX_get_ciphers returns the cipher list for |ctx|, in order of diff --git a/ssl/ssl_cipher.cc b/ssl/ssl_cipher.cc index 3ab1abbdfb..099e80710d 100644 --- a/ssl/ssl_cipher.cc +++ b/ssl/ssl_cipher.cc @@ -1358,9 +1358,11 @@ bool ssl_create_cipher_list(UniquePtr *out_cipher_list, *out_cipher_list = std::move(pref_list); - // Configuring an empty cipher list is an error but still updates the - // output. - if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers.get()) == 0) { + // Configuring an empty cipher list is an error when |strict| is true, but + // still updates the output. When otherwise, OpenSSL explicitly allows an + // empty list. + if ((strict || (*rule_str != '\0')) && + sk_SSL_CIPHER_num((*out_cipher_list)->ciphers.get()) == 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH); return false; } diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index fc4d2adadd..0febdf09ac 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc @@ -549,8 +549,6 @@ static const char *kBadRules[] = { "[+RSA]", // Unknown directive. "@BOGUS", - // Empty cipher lists error at SSL_CTX_set_cipher_list. - "", "BOGUS", // COMPLEMENTOFDEFAULT is empty. "COMPLEMENTOFDEFAULT", @@ -5758,12 +5756,20 @@ TEST(SSLTest, EmptyCipherList) { // Initially, the cipher list is not empty. EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get()))); - // Configuring the empty cipher list fails. - EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), "")); - ERR_clear_error(); + // Configuring the empty cipher list with |SSL_CTX_set_cipher_list| + // succeeds. + EXPECT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), "")); + // The cipher list is updated to empty. + EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get()))); + + // Configuring the empty cipher list with |SSL_CTX_set_ciphersuites| + // also succeeds. + EXPECT_TRUE(SSL_CTX_set_ciphersuites(ctx.get(), "")); + EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get()))); - // Configuring the empty cipher list fails. - EXPECT_FALSE(SSL_CTX_set_ciphersuites(ctx.get(), "")); + // Configuring the empty cipher list with |SSL_CTX_set_strict_cipher_list| + // fails. + EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), "")); ERR_clear_error(); // But the cipher list is still updated to empty. From a8e1537dda80a2fc94a40bd2bb9f2996e9ec8740 Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Thu, 11 Apr 2024 12:43:36 -0400 Subject: [PATCH 16/25] aws-lc-rs CI step must use CMake to build (#1523) --- .github/workflows/aws-lc-rs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/aws-lc-rs.yml b/.github/workflows/aws-lc-rs.yml index 1c56e44244..f9021dbf9e 100644 --- a/.github/workflows/aws-lc-rs.yml +++ b/.github/workflows/aws-lc-rs.yml @@ -9,6 +9,7 @@ concurrency: cancel-in-progress: true env: GOPROXY: https://proxy.golang.org,direct + AWS_LC_SYS_CMAKE_BUILDER: 1 jobs: standard: runs-on: ubuntu-latest From 6284822a2e30d9a8497ba7e07bf3f506808912f2 Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Thu, 11 Apr 2024 14:19:05 -0400 Subject: [PATCH 17/25] Bump to v1.24.0 (#1522) ### Description of changes: * Bump version to v1.24.0 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- crypto/fipsmodule/service_indicator/service_indicator_test.cc | 4 ++-- include/openssl/base.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crypto/fipsmodule/service_indicator/service_indicator_test.cc b/crypto/fipsmodule/service_indicator/service_indicator_test.cc index 853d699509..ce0313efca 100644 --- a/crypto/fipsmodule/service_indicator/service_indicator_test.cc +++ b/crypto/fipsmodule/service_indicator/service_indicator_test.cc @@ -4280,7 +4280,7 @@ TEST(ServiceIndicatorTest, DRBG) { // Since this is running in FIPS mode it should end in FIPS // Update this when the AWS-LC version number is modified TEST(ServiceIndicatorTest, AWSLCVersionString) { - ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.23.0"); + ASSERT_STREQ(awslc_version_string(), "AWS-LC FIPS 1.24.0"); } #else @@ -4323,6 +4323,6 @@ TEST(ServiceIndicatorTest, BasicTest) { // Since this is not running in FIPS mode it shouldn't end in FIPS // Update this when the AWS-LC version number is modified TEST(ServiceIndicatorTest, AWSLCVersionString) { - ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.23.0"); + ASSERT_STREQ(awslc_version_string(), "AWS-LC 1.24.0"); } #endif // AWSLC_FIPS diff --git a/include/openssl/base.h b/include/openssl/base.h index 6c5d0afb93..ff6ec8d70d 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -122,7 +122,7 @@ extern "C" { // ServiceIndicatorTest.AWSLCVersionString // Note: there are two versions of this test. Only one test is compiled // depending on FIPS mode. -#define AWSLC_VERSION_NUMBER_STRING "1.23.0" +#define AWSLC_VERSION_NUMBER_STRING "1.24.0" #if defined(BORINGSSL_SHARED_LIBRARY) From b6daf74a7cc9a914df4a935af808790361ff30b9 Mon Sep 17 00:00:00 2001 From: Will Childs-Klein Date: Thu, 11 Apr 2024 17:39:11 -0400 Subject: [PATCH 18/25] Fix python CI patches (#1524) This is in light of upstream [PR 117234#][1] being merged. [1]: https://github.com/python/cpython/pull/117234 --- .../python_patch/3.12/aws-lc-cpython.patch | 17 ----------------- .../python_patch/main/aws-lc-cpython.patch | 17 ----------------- 2 files changed, 34 deletions(-) diff --git a/tests/ci/integration/python_patch/3.12/aws-lc-cpython.patch b/tests/ci/integration/python_patch/3.12/aws-lc-cpython.patch index 061eb0120d..1d2ce20da1 100644 --- a/tests/ci/integration/python_patch/3.12/aws-lc-cpython.patch +++ b/tests/ci/integration/python_patch/3.12/aws-lc-cpython.patch @@ -106,23 +106,6 @@ index a8faa1d..8abe8fd 100644 # The _tkinter module. # -diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c -index af6d1b2..4b060b3 100644 ---- a/Modules/_hashopenssl.c -+++ b/Modules/_hashopenssl.c -@@ -130,8 +130,12 @@ static const py_hashentry_t py_hashes[] = { - PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128), - PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256), - /* blake2 digest */ -+#if defined(NID_blake2s256) - PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256), -+#endif -+#if defined(NID_blake2b512) - PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512), -+#endif - PY_HASH_ENTRY(NULL, NULL, NULL, 0), - }; - diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 5f1425a..d546ce7 100644 --- a/Modules/_ssl.c diff --git a/tests/ci/integration/python_patch/main/aws-lc-cpython.patch b/tests/ci/integration/python_patch/main/aws-lc-cpython.patch index 1a7228c009..4103cd67d3 100644 --- a/tests/ci/integration/python_patch/main/aws-lc-cpython.patch +++ b/tests/ci/integration/python_patch/main/aws-lc-cpython.patch @@ -105,23 +105,6 @@ index cd1cf24..53bcc4c 100644 # The _tkinter module. # -diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c -index 0e230f3..390d6e0 100644 ---- a/Modules/_hashopenssl.c -+++ b/Modules/_hashopenssl.c -@@ -130,8 +130,12 @@ static const py_hashentry_t py_hashes[] = { - PY_HASH_ENTRY(Py_hash_shake_128, NULL, SN_shake128, NID_shake128), - PY_HASH_ENTRY(Py_hash_shake_256, NULL, SN_shake256, NID_shake256), - /* blake2 digest */ -+#if defined(NID_blake2s256) - PY_HASH_ENTRY(Py_hash_blake2s, "blake2s256", SN_blake2s256, NID_blake2s256), -+#endif -+#if defined(NID_blake2b512) - PY_HASH_ENTRY(Py_hash_blake2b, "blake2b512", SN_blake2b512, NID_blake2b512), -+#endif - PY_HASH_ENTRY(NULL, NULL, NULL, 0), - }; - diff --git a/Modules/_ssl.c b/Modules/_ssl.c index d00f407..7049f79 100644 --- a/Modules/_ssl.c From 746d06505b3a3827cf61959ca0c3d87c3f21accc Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Fri, 12 Apr 2024 15:00:13 -0700 Subject: [PATCH 19/25] Document no-op functions and flags in AWS-LC (#1473) Update porting guide for AWS-LC. This is the second phase which includes updated function documentation. Originally, this was to include links to the corresponding functions/sections in the new tables as well, but we can't actually provide correct links until we have the correct commit hash in main. A third phase will link the tables to the corresponding section. We also marked no-op and older functions with `OPENSSL_DEPRECATED`. This mechanism helps alert AWS-LC consumers that there are no-op or deprecated functions being used and there is certain functionality not implemented around the functions they are consuming. --- crypto/rand_extra/rand_extra.c | 2 + include/openssl/asn1.h | 35 +- include/openssl/bio.h | 13 +- include/openssl/cipher.h | 31 +- include/openssl/conf.h | 30 +- include/openssl/dh.h | 7 +- include/openssl/digest.h | 53 +-- include/openssl/ec.h | 60 ++-- include/openssl/ec_key.h | 11 +- include/openssl/evp.h | 113 ++++--- include/openssl/ex_data.h | 4 +- include/openssl/pkcs7.h | 55 +++- include/openssl/rand.h | 44 ++- include/openssl/ssl.h | 579 ++++++++++++++++++++------------- include/openssl/thread.h | 53 +-- include/openssl/x509.h | 6 +- include/openssl/x509v3.h | 43 ++- tool/speed.cc | 7 +- 18 files changed, 729 insertions(+), 417 deletions(-) diff --git a/crypto/rand_extra/rand_extra.c b/crypto/rand_extra/rand_extra.c index 9cbf0be5bb..48176e7bf9 100644 --- a/crypto/rand_extra/rand_extra.c +++ b/crypto/rand_extra/rand_extra.c @@ -54,6 +54,7 @@ int RAND_status(void) { return 1; } +OPENSSL_BEGIN_ALLOW_DEPRECATED static const struct rand_meth_st kSSLeayMethod = { RAND_seed, RAND_bytes, @@ -72,6 +73,7 @@ RAND_METHOD *RAND_OpenSSL(void) { } const RAND_METHOD *RAND_get_rand_method(void) { return RAND_SSLeay(); } +OPENSSL_END_ALLOW_DEPRECATED int RAND_set_rand_method(const RAND_METHOD *method) { return 1; } diff --git a/include/openssl/asn1.h b/include/openssl/asn1.h index 1cc72e2470..581b87369b 100644 --- a/include/openssl/asn1.h +++ b/include/openssl/asn1.h @@ -1438,8 +1438,8 @@ OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); // ASN1_TIME conversion functions. // // |struct| |tm| represents a calendar date: year, month, day... it is not -// necessarily a valid day, e.g. month 13. |time_t| is a typedef for the system's -// type that represents the seconds since the UNIX epoch. Posix time is +// necessarily a valid day, e.g. month 13. |time_t| is a typedef for the +// system's type that represents the seconds since the UNIX epoch. Posix time is // a signed 64-bit integer which also represents the seconds since the UNIX // epoch. @@ -1923,18 +1923,6 @@ OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); // Deprecated functions. -// ASN1_STRING_set_default_mask does nothing. -OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask); - -// ASN1_STRING_set_default_mask_asc returns one. -OPENSSL_EXPORT int ASN1_STRING_set_default_mask_asc(const char *p); - -// ASN1_STRING_get_default_mask returns |B_ASN1_UTF8STRING|. -OPENSSL_EXPORT unsigned long ASN1_STRING_get_default_mask(void); - -// ASN1_STRING_TABLE_cleanup does nothing. -OPENSSL_EXPORT void ASN1_STRING_TABLE_cleanup(void); - // M_ASN1_* are legacy aliases for various |ASN1_STRING| functions. Use the // functions themselves. #define M_ASN1_STRING_length(x) ASN1_STRING_length(x) @@ -2054,6 +2042,25 @@ OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a); OPENSSL_EXPORT long ASN1_ENUMERATED_get(const ASN1_ENUMERATED *a); +// General No-op Functions [Deprecated]. + +// ASN1_STRING_set_default_mask does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void ASN1_STRING_set_default_mask( + unsigned long mask); + +// ASN1_STRING_set_default_mask_asc returns one. +OPENSSL_EXPORT OPENSSL_DEPRECATED int ASN1_STRING_set_default_mask_asc( + const char *p); + +// ASN1_STRING_get_default_mask returns |B_ASN1_UTF8STRING|. This is +// the value AWS-LC uses by default and is not configurable. +OPENSSL_EXPORT OPENSSL_DEPRECATED unsigned long ASN1_STRING_get_default_mask( + void); + +// ASN1_STRING_TABLE_cleanup does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void ASN1_STRING_TABLE_cleanup(void); + + #if defined(__cplusplus) } // extern C diff --git a/include/openssl/bio.h b/include/openssl/bio.h index d140b9b029..1451c131d6 100644 --- a/include/openssl/bio.h +++ b/include/openssl/bio.h @@ -862,9 +862,6 @@ OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void); OPENSSL_EXPORT void BIO_set_retry_special(BIO *bio); -// BIO_set_write_buffer_size returns zero. -OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size); - // BIO_set_shutdown sets a method-specific "shutdown" bit on |bio|. OPENSSL_EXPORT void BIO_set_shutdown(BIO *bio, int shutdown); @@ -879,6 +876,16 @@ OPENSSL_EXPORT int BIO_meth_set_puts(BIO_METHOD *method, // BIO_meth_get_puts returns |puts| function of |method|. OPENSSL_EXPORT int (*BIO_meth_get_puts(const BIO_METHOD *method)) (BIO *, const char *); + +// General No-op Functions [Deprecated]. + +// BIO_set_write_buffer_size returns zero. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and +// depends on this. +OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size); + + // Private functions #define BIO_FLAGS_READ 0x01 diff --git a/include/openssl/cipher.h b/include/openssl/cipher.h index c24e15f089..de74f5ecf7 100644 --- a/include/openssl/cipher.h +++ b/include/openssl/cipher.h @@ -355,8 +355,8 @@ OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, #define EVP_CIPH_XTS_MODE 0x7 #define EVP_CIPH_CCM_MODE 0x8 -// Buffer length in bits not bytes: CFB1 mode only. -# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +// EVP_CIPH_FLAG_LENGTH_BITS buffers length in bits not bytes: CFB1 mode only. +#define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 // The following values are never returned from |EVP_CIPHER_mode| and are // included only to make it easier to compile code with BoringSSL. #define EVP_CIPH_OCB_MODE 0x9 @@ -409,7 +409,8 @@ OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, // the named cipher algorithm. They are imported from OpenSSL to provide AES CBC // HMAC SHA stitch implementation. These methods are TLS specific. // -// WARNING: these APIs usage can get wrong easily. Below functions include details. +// WARNING: these APIs usage can get wrong easily. Below functions include +// details. // |aesni_cbc_hmac_sha1_cipher| and |aesni_cbc_hmac_sha256_cipher|. @@ -470,9 +471,6 @@ OPENSSL_EXPORT int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, uint8_t *out, OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len); -// EVP_add_cipher_alias does nothing and returns one. -OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b); - // EVP_get_cipherbyname returns an |EVP_CIPHER| given a human readable name in // |name|, or NULL if the name is unknown. Note using this function links almost // every cipher implemented by BoringSSL into the binary, not just the ones the @@ -557,13 +555,22 @@ OPENSSL_EXPORT OPENSSL_DEPRECATED const EVP_CIPHER *EVP_cast5_ecb(void); // EVP_cast5_cbc is CAST5 in CBC mode and is deprecated. OPENSSL_EXPORT OPENSSL_DEPRECATED const EVP_CIPHER *EVP_cast5_cbc(void); -// The following flags do nothing and are included only to make it easier to -// compile code with AWS-LC. + +// General No-op Functions [Deprecated]. + +// EVP_CIPHER_CTX_set_flags does nothing. We strongly discourage doing +// any additional configurations when consuming |EVP_CIPHER_CTX|. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EVP_CIPHER_CTX_set_flags( + const EVP_CIPHER_CTX *ctx, uint32_t flags); + +// The following flags are related to |EVP_CIPHER_CTX_set_flags|. They +// do nothing and are included only to make it easier to compile code +// with AWS-LC. #define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0 -// EVP_CIPHER_CTX_set_flags does nothing. -OPENSSL_EXPORT void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, - uint32_t flags); +// EVP_add_cipher_alias does nothing and returns one. +OPENSSL_EXPORT OPENSSL_DEPRECATED int EVP_add_cipher_alias(const char *a, + const char *b); // Private functions. @@ -612,7 +619,7 @@ struct evp_cipher_ctx_st { const EVP_CIPHER *cipher; // app_data is a pointer to opaque, user data. - void *app_data; // application stuff + void *app_data; // application stuff // cipher_data points to the |cipher| specific state. void *cipher_data; diff --git a/include/openssl/conf.h b/include/openssl/conf.h index 04b7af34f9..e02f76939d 100644 --- a/include/openssl/conf.h +++ b/include/openssl/conf.h @@ -59,8 +59,8 @@ #include -#include #include +#include #if defined(__cplusplus) extern "C" { @@ -124,33 +124,39 @@ OPENSSL_EXPORT const char *NCONF_get_string(const CONF *conf, const char *name); -// Deprecated functions +// General No-op Functions [Deprecated]. +// +// AWS-LC has no support for loading config files to configure AWS-LC, so +// the following functions have been deprecated as no-ops. // These defines do nothing but are provided to make old code easier to // compile. #define CONF_MFLAGS_DEFAULT_SECTION 0 #define CONF_MFLAGS_IGNORE_MISSING_FILE 0 -// CONF_modules_load_file returns one. BoringSSL is defined to have no config +// CONF_modules_load_file returns one. AWS-LC is defined to have no config // file options, thus loading from |filename| always succeeds by doing nothing. -OPENSSL_EXPORT int CONF_modules_load_file(const char *filename, - const char *appname, - unsigned long flags); +OPENSSL_EXPORT OPENSSL_DEPRECATED int CONF_modules_load_file( + const char *filename, const char *appname, unsigned long flags); // CONF_modules_free does nothing. -OPENSSL_EXPORT void CONF_modules_free(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CONF_modules_free(void); // CONF_modules_unload does nothing. -OPENSSL_EXPORT void CONF_modules_unload(int all); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CONF_modules_unload(int all); // CONF_modules_finish does nothing. -OPENSSL_EXPORT void CONF_modules_finish(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CONF_modules_finish(void); -// OPENSSL_config does nothing. +// OPENSSL_config does nothing. This has been deprecated since OpenSSL 1.1.0. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and +// depends on this. OPENSSL_EXPORT void OPENSSL_config(const char *config_name); -// OPENSSL_no_config does nothing. -OPENSSL_EXPORT void OPENSSL_no_config(void); +// OPENSSL_no_config does nothing. This has been deprecated since OpenSSL +// 1.1.0. +OPENSSL_EXPORT OPENSSL_DEPRECATED void OPENSSL_no_config(void); #if defined(__cplusplus) diff --git a/include/openssl/dh.h b/include/openssl/dh.h index c0bed49f5b..4910ee53fb 100644 --- a/include/openssl/dh.h +++ b/include/openssl/dh.h @@ -348,15 +348,20 @@ OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, // This function has been deprecated with no replacement. OPENSSL_EXPORT DH *DH_get_2048_256(void); + +// General No-op Functions [Deprecated]. + // DH_clear_flags does nothing and is included to simplify compiling code that // expects it. -OPENSSL_EXPORT void DH_clear_flags(DH *dh, int flags); +OPENSSL_EXPORT OPENSSL_DEPRECATED void DH_clear_flags(DH *dh, int flags); // DH_FLAG_CACHE_MONT_P is not supported by AWS-LC and is included to simplify // compiling code that expects it. This flag controls if the DH APIs should // cache the montgomery form of the prime to speed up multiplication at the cost // of increasing memory storage. AWS-LC always does this and does not support // turning this option off. +// +// NOTE: This is also on by default in OpenSSL. #define DH_FLAG_CACHE_MONT_P 0 diff --git a/include/openssl/digest.h b/include/openssl/digest.h index d98bd197e7..2dcd47b110 100644 --- a/include/openssl/digest.h +++ b/include/openssl/digest.h @@ -267,21 +267,10 @@ OPENSSL_EXPORT int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md); // Deprecated functions. - -// EVP_MD_unstable_sha3_enable is a no-op as SHA3 is always enabled. -OPENSSL_EXPORT void EVP_MD_unstable_sha3_enable(bool enable); - -// EVP_MD_unstable_sha3_is_enabled always returns true as SHA3 is always enabled. -OPENSSL_EXPORT bool EVP_MD_unstable_sha3_is_enabled(void); - // EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of // |in|. It returns one on success and zero on error. OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); -// EVP_add_digest does nothing and returns one. It exists only for -// compatibility with OpenSSL. -OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest); - // EVP_get_digestbyname returns an |EVP_MD| given a human readable name in // |name|, or NULL if the name is unknown. OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *); @@ -300,15 +289,6 @@ OPENSSL_EXPORT int EVP_DigestFinalXOF(EVP_MD_CTX *ctx, uint8_t *out, // EVP_MD_meth_get_flags calls |EVP_MD_flags|. OPENSSL_EXPORT uint32_t EVP_MD_meth_get_flags(const EVP_MD *md); -// EVP_MD_CTX_set_flags does nothing. -OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); - -// EVP_MD_CTX_FLAG_NON_FIPS_ALLOW is meaningless. In OpenSSL it permits non-FIPS -// algorithms in FIPS mode. But BoringSSL FIPS mode doesn't prohibit algorithms -// (it's up the the caller to use the FIPS module in a fashion compliant with -// their needs). Thus this exists only to allow code to compile. -#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0 - // EVP_MD_nid calls |EVP_MD_type|. OPENSSL_EXPORT int EVP_MD_nid(const EVP_MD *md); @@ -325,9 +305,10 @@ OPENSSL_EXPORT int EVP_MD_nid(const EVP_MD *md); // associated. // // |EVP_MD_CTX_set_pkey_ctx| will overwrite any |EVP_PKEY_CTX| object associated -// to |ctx|. If it was not associated through a previous |EVP_MD_CTX_set_pkey_ctx| -// call, it will be freed first. -OPENSSL_EXPORT void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx); +// to |ctx|. If it was not associated through a previous +// |EVP_MD_CTX_set_pkey_ctx| call, it will be freed first. +OPENSSL_EXPORT void EVP_MD_CTX_set_pkey_ctx(EVP_MD_CTX *ctx, + EVP_PKEY_CTX *pctx); struct evp_md_pctx_ops; @@ -363,6 +344,32 @@ struct env_md_ctx_st { } /* EVP_MD_CTX */; +// General No-op Functions [Deprecated]. + +// EVP_MD_unstable_sha3_enable is a no-op as SHA3 is always enabled. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EVP_MD_unstable_sha3_enable(bool enable); + +// EVP_MD_unstable_sha3_is_enabled always returns true as SHA3 is always +// enabled. +OPENSSL_EXPORT OPENSSL_DEPRECATED bool EVP_MD_unstable_sha3_is_enabled(void); + +// EVP_MD_CTX_set_flags does nothing. We strongly discourage doing any +// additional configurations when consuming |EVP_MD_CTX|. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, + int flags); + +// EVP_MD_CTX_FLAG_NON_FIPS_ALLOW is meaningless. In OpenSSL it permits non-FIPS +// algorithms in FIPS mode. But BoringSSL FIPS mode doesn't prohibit algorithms +// (it's up the the caller to use the FIPS module in a fashion compliant with +// their needs). Thus this exists only to allow code to compile. +#define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0 + +// EVP_add_digest does nothing and returns one. It exists only for +// compatibility with OpenSSL, which requires manually loading supported digests +// when certain options are turned on. +OPENSSL_EXPORT OPENSSL_DEPRECATED int EVP_add_digest(const EVP_MD *digest); + + #if defined(__cplusplus) } // extern C diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 24772edb9f..e52d3de9fc 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -410,26 +410,6 @@ OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, #define OPENSSL_EC_EXPLICIT_CURVE 0 #define OPENSSL_EC_NAMED_CURVE 1 -// EC_GROUP_set_asn1_flag does nothing. -OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); - -// EC_GROUP_get_asn1_flag returns |OPENSSL_EC_NAMED_CURVE|. -OPENSSL_EXPORT int EC_GROUP_get_asn1_flag(const EC_GROUP *group); - -typedef struct ec_method_st EC_METHOD; - -// EC_GROUP_method_of returns a dummy non-NULL pointer. -OPENSSL_EXPORT const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); - -// EC_METHOD_get_field_type returns NID_X9_62_prime_field. -OPENSSL_EXPORT int EC_METHOD_get_field_type(const EC_METHOD *meth); - -// EC_GROUP_set_point_conversion_form aborts the process if |form| is not -// |POINT_CONVERSION_UNCOMPRESSED| or |POINT_CONVERSION_COMPRESSED|, and -// otherwise does nothing. -OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form( - EC_GROUP *group, point_conversion_form_t form); - // EC_builtin_curve describes a supported elliptic curve. typedef struct { int nid; @@ -448,6 +428,46 @@ OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, OPENSSL_EXPORT void EC_POINT_clear_free(EC_POINT *point); +// General No-op Functions [Deprecated]. + +// EC_GROUP_set_asn1_flag does nothing. AWS-LC only supports +// |OPENSSL_EC_NAMED_CURVE|. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EC_GROUP_set_asn1_flag(EC_GROUP *group, + int flag); + +// EC_GROUP_get_asn1_flag returns |OPENSSL_EC_NAMED_CURVE|. This is the only +// type AWS-LC supports. +OPENSSL_EXPORT OPENSSL_DEPRECATED int EC_GROUP_get_asn1_flag( + const EC_GROUP *group); + +// EC_GROUP_set_point_conversion_form aborts the process if |form| is not +// |POINT_CONVERSION_UNCOMPRESSED| or |POINT_CONVERSION_COMPRESSED|, and +// otherwise does nothing. +// AWS-LC always uses |POINT_CONVERSION_UNCOMPRESSED|. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EC_GROUP_set_point_conversion_form( + EC_GROUP *group, point_conversion_form_t form); + + +// EC_METHOD No-ops [Deprecated]. +// +// |EC_METHOD| is a low level implementation detail of the EC module, but +// it’s exposed in traditionally public API. This should be an internal only +// concept. Users should switch to a different suitable constructor like +// |EC_GROUP_new_curve_GFp|, |EC_GROUP_new_curve_GF2m|, or +// |EC_GROUP_new_by_curve_name|. The |EC_METHOD| APIs have also been +// deprecated in OpenSSL 3.0. + +typedef struct ec_method_st EC_METHOD; + +// EC_GROUP_method_of returns a dummy non-NULL pointer. +OPENSSL_EXPORT OPENSSL_DEPRECATED const EC_METHOD *EC_GROUP_method_of( + const EC_GROUP *group); + +// EC_METHOD_get_field_type returns NID_X9_62_prime_field. +OPENSSL_EXPORT OPENSSL_DEPRECATED int EC_METHOD_get_field_type( + const EC_METHOD *meth); + + #if defined(__cplusplus) } // extern C #endif diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index d676f982ff..b273a75475 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -311,9 +311,6 @@ struct ecdsa_method_st { // Deprecated functions. -// EC_KEY_set_asn1_flag does nothing. -OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag); - // d2i_ECPrivateKey parses a DER-encoded ECPrivateKey structure (RFC 5915) from // |len| bytes at |*inp|, as described in |d2i_SAMPLE|. On input, if |*out_key| // is non-NULL and has a group configured, the parameters field may be omitted @@ -358,6 +355,14 @@ OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); +// General No-op Functions [Deprecated]. + +// EC_KEY_set_asn1_flag does nothing. AWS-LC only supports +// |OPENSSL_EC_NAMED_CURVE|. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EC_KEY_set_asn1_flag(EC_KEY *key, + int flag); + + #if defined(__cplusplus) } // extern C diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 6d787b1f4f..01587c1392 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -179,7 +179,6 @@ OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey); #define EVP_PKEY_NONE NID_undef #define EVP_PKEY_RSA NID_rsaEncryption #define EVP_PKEY_RSA_PSS NID_rsassaPss -#define EVP_PKEY_DSA NID_dsa #define EVP_PKEY_EC NID_X9_62_id_ecPublicKey #define EVP_PKEY_ED25519 NID_ED25519 #define EVP_PKEY_X25519 NID_X25519 @@ -929,10 +928,6 @@ OPENSSL_EXPORT int EVP_PKEY_kem_check_key(EVP_PKEY *key); // Deprecated functions. -// EVP_PKEY_DH is defined for compatibility, but it is impossible to create an -// |EVP_PKEY| of that type. -#define EVP_PKEY_DH NID_dhKeyAgreement - // EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID // 2.5.8.1.1), but is no longer accepted. #define EVP_PKEY_RSA2 NID_rsa @@ -945,11 +940,6 @@ OPENSSL_EXPORT int EVP_PKEY_kem_check_key(EVP_PKEY *key); // Ed448 and attempts to create keys will fail. #define EVP_PKEY_ED448 NID_ED448 -// EVP_PKEY_get0 returns NULL. This function is provided for compatibility with -// OpenSSL but does not return anything. Use the typed |EVP_PKEY_get0_*| -// functions instead. -OPENSSL_EXPORT void *EVP_PKEY_get0(const EVP_PKEY *pkey); - // EVP_MD_get_pkey_type returns the NID of the public key signing algorithm // associated with |md| and RSA. This does not return all potential signing // algorithms that could work with |md| and should not be used. @@ -958,21 +948,6 @@ OPENSSL_EXPORT int EVP_MD_get_pkey_type(const EVP_MD *md); // EVP_MD_pkey_type calls |EVP_MD_get_pkey_type|. OPENSSL_EXPORT int EVP_MD_pkey_type(const EVP_MD *md); -// OpenSSL_add_all_algorithms does nothing. -OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void); - -// OPENSSL_add_all_algorithms_conf does nothing. -OPENSSL_EXPORT void OPENSSL_add_all_algorithms_conf(void); - -// OpenSSL_add_all_ciphers does nothing. -OPENSSL_EXPORT void OpenSSL_add_all_ciphers(void); - -// OpenSSL_add_all_digests does nothing. -OPENSSL_EXPORT void OpenSSL_add_all_digests(void); - -// EVP_cleanup does nothing. -OPENSSL_EXPORT void EVP_cleanup(void); - OPENSSL_EXPORT void EVP_CIPHER_do_all_sorted( void (*callback)(const EVP_CIPHER *cipher, const char *name, const char *unused, void *arg), @@ -1041,12 +1016,6 @@ OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, OPENSSL_EXPORT EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp, long len); -// EVP_PKEY_get0_DH returns NULL. -OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); - -// EVP_PKEY_get1_DH returns NULL. -OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey); - // EVP_PKEY_CTX_set_ec_param_enc returns one if |encoding| is // |OPENSSL_EC_NAMED_CURVE| or zero with an error otherwise. OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, @@ -1151,14 +1120,6 @@ OPENSSL_EXPORT int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp); OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len); -// EVP_PKEY_CTX_set_dsa_paramgen_bits returns zero. -OPENSSL_EXPORT int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, - int nbits); - -// EVP_PKEY_CTX_set_dsa_paramgen_q_bits returns zero. -OPENSSL_EXPORT int EVP_PKEY_CTX_set_dsa_paramgen_q_bits(EVP_PKEY_CTX *ctx, - int qbits); - // EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of // the given type. If successful, it returns one. If the |type| argument // is one of |EVP_PKEY_RSA|, |EVP_PKEY_DSA|, or |EVP_PKEY_EC| values it calls @@ -1178,6 +1139,80 @@ OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine, const uint8_t *mac_key, size_t mac_key_len); + +// General No-op Functions [Deprecated]. + +// EVP_PKEY_get0 returns NULL. This function is provided for compatibility with +// OpenSSL but does not return anything. Use the typed |EVP_PKEY_get0_*| +// functions instead. +// +// Note: In OpenSSL, the returned type will be different depending on the type +// of |EVP_PKEY| consumed. This leads to misuage very easily and has been +// deprecated as a no-op to avoid so. +OPENSSL_EXPORT OPENSSL_DEPRECATED void *EVP_PKEY_get0(const EVP_PKEY *pkey); + +// OpenSSL_add_all_algorithms does nothing. This has been deprecated since +// OpenSSL 1.1.0. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and +// depends on this. +OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void); + +// OPENSSL_add_all_algorithms_conf does nothing. This has been deprecated since +// OpenSSL 1.1.0. +OPENSSL_EXPORT OPENSSL_DEPRECATED void OPENSSL_add_all_algorithms_conf(void); + +// OpenSSL_add_all_ciphers does nothing. This has been deprecated since OpenSSL +// 1.1.0. +OPENSSL_EXPORT OPENSSL_DEPRECATED void OpenSSL_add_all_ciphers(void); + +// OpenSSL_add_all_digests does nothing. This has been deprecated since OpenSSL +// 1.1.0. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. tpm2-tss defines -Werror and +// depends on this. +OPENSSL_EXPORT void OpenSSL_add_all_digests(void); + +// EVP_cleanup does nothing. This has been deprecated since OpenSSL 1.1.0. +OPENSSL_EXPORT OPENSSL_DEPRECATED void EVP_cleanup(void); + + +// EVP_PKEY_DSA No-ops [Deprecated]. +// +// |EVP_PKEY_DSA| is deprecated. It is currently still possible to parse DER +// into a DSA |EVP_PKEY|, but signing or verifying with those objects will not +// work. + +#define EVP_PKEY_DSA NID_dsa + +// EVP_PKEY_CTX_set_dsa_paramgen_bits returns zero. +OPENSSL_EXPORT OPENSSL_DEPRECATED int EVP_PKEY_CTX_set_dsa_paramgen_bits( + EVP_PKEY_CTX *ctx, int nbits); + +// EVP_PKEY_CTX_set_dsa_paramgen_q_bits returns zero. +OPENSSL_EXPORT OPENSSL_DEPRECATED int EVP_PKEY_CTX_set_dsa_paramgen_q_bits( + EVP_PKEY_CTX *ctx, int qbits); + + +// EVP_PKEY_DH No-ops [Deprecated]. +// +// |EVP_PKEY_DH| is deprecated. It is not possible to create a DH |EVP_PKEY| in +// AWS-LC. The following symbols are also no-ops due to the deprecation. + +// EVP_PKEY_DH is defined for compatibility, but it is impossible to create an +// |EVP_PKEY| of that type. +#define EVP_PKEY_DH NID_dhKeyAgreement + +// EVP_PKEY_get0_DH returns NULL. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. curl defines -Werror and +// depends on this. +OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); + +// EVP_PKEY_get1_DH returns NULL. +OPENSSL_EXPORT OPENSSL_DEPRECATED DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey); + + // Preprocessor compatibility section (hidden). // // Historically, a number of APIs were implemented in OpenSSL as macros and diff --git a/include/openssl/ex_data.h b/include/openssl/ex_data.h index 8f2f98b0af..7d03f1766a 100644 --- a/include/openssl/ex_data.h +++ b/include/openssl/ex_data.h @@ -175,10 +175,10 @@ typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, int index, long argl, void *argp); -// Deprecated functions. +// General No-op Functions [Deprecated]. // CRYPTO_cleanup_all_ex_data does nothing. -OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_cleanup_all_ex_data(void); // CRYPTO_EX_dup is a legacy callback function type which is ignored. typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h index 85f2a4ecc9..8244b184f4 100644 --- a/include/openssl/pkcs7.h +++ b/include/openssl/pkcs7.h @@ -58,8 +58,8 @@ OPENSSL_EXPORT int PKCS7_bundle_raw_certificates( // PKCS7_bundle_certificates behaves like |PKCS7_bundle_raw_certificates| but // takes |X509| objects as input. -OPENSSL_EXPORT int PKCS7_bundle_certificates( - CBB *out, const STACK_OF(X509) *certs); +OPENSSL_EXPORT int PKCS7_bundle_certificates(CBB *out, + const STACK_OF(X509) *certs); // PKCS7_get_CRLs parses a PKCS#7, SignedData structure from |cbs| and appends // the included CRLs to |out_crls|. It returns one on success and zero on error. @@ -143,8 +143,7 @@ typedef struct { // d2i_PKCS7 parses a BER-encoded, PKCS#7 signed data ContentInfo structure from // |len| bytes at |*inp|, as described in |d2i_SAMPLE|. -OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, - size_t len); +OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, size_t len); // d2i_PKCS7_bio behaves like |d2i_PKCS7| but reads the input from |bio|. If // the length of the object is indefinite the full contents of |bio| are read. @@ -183,21 +182,51 @@ OPENSSL_EXPORT int PKCS7_type_is_signed(const PKCS7 *p7); // PKCS7_type_is_signedAndEnveloped returns zero. OPENSSL_EXPORT int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7); + +// PKCS7_sign [Deprecated] +// +// Only |PKCS7_DETACHED| and a combination of +// "PKCS7_DETACHED|PKCS7_BINARY|PKCS7_NOATTR|PKCS7_PARTIAL" is supported. +// See |PKCS7_sign| for more details. + // PKCS7_DETACHED indicates that the PKCS#7 file specifies its data externally. #define PKCS7_DETACHED 0x40 -// The following flags cause |PKCS7_sign| to fail. +// PKCS7_BINARY disables the default translation to MIME canonical format (as +// required by the S/MIME specifications). +// Must be used as "PKCS7_DETACHED|PKCS7_BINARY|PKCS7_NOATTR|PKCS7_PARTIAL". +#define PKCS7_BINARY 0x80 + +// PKCS7_NOATTR disables usage of authenticatedAttributes. +// Must be used as "PKCS7_DETACHED|PKCS7_BINARY|PKCS7_NOATTR|PKCS7_PARTIAL". +#define PKCS7_NOATTR 0x100 + +// PKCS7_PARTIAL outputs a partial PKCS7 structure which additional signers and +// capabilities can be added before finalization. +// Must be used as "PKCS7_DETACHED|PKCS7_BINARY|PKCS7_NOATTR|PKCS7_PARTIAL". +#define PKCS7_PARTIAL 0x4000 + +// PKCS7_TEXT prepends MIME headers for type text/plain to the data. Using this +// will fail |PKCS7_sign|. #define PKCS7_TEXT 0x1 + +// PKCS7_NOCERTS excludes the signer's certificate and the extra certs defined +// from the PKCS7 structure. Using this will fail |PKCS7_sign|. #define PKCS7_NOCERTS 0x2 + +// PKCS7_NOSMIMECAP omits SMIMECapabilities. Using this will fail |PKCS7_sign|. +#define PKCS7_NOSMIMECAP 0x200 + +// PKCS7_STREAM returns a PKCS7 structure just initialized to perform the +// signing operation. Signing is not performed yet. Using this will fail +// |PKCS7_sign|. +#define PKCS7_STREAM 0x1000 + +// The following flags are used with |PKCS7_verify| (not implemented). #define PKCS7_NOSIGS 0x4 #define PKCS7_NOCHAIN 0x8 #define PKCS7_NOINTERN 0x10 #define PKCS7_NOVERIFY 0x20 -#define PKCS7_BINARY 0x80 -#define PKCS7_NOATTR 0x100 -#define PKCS7_NOSMIMECAP 0x200 -#define PKCS7_STREAM 0x1000 -#define PKCS7_PARTIAL 0x4000 // PKCS7_sign can operate in two modes to provide some backwards compatibility: // @@ -215,8 +244,10 @@ OPENSSL_EXPORT int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7); // // Note this function only implements a subset of the corresponding OpenSSL // function. It is provided for backwards compatibility only. -OPENSSL_EXPORT PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, BIO *data, int flags); +OPENSSL_EXPORT OPENSSL_DEPRECATED PKCS7 *PKCS7_sign(X509 *sign_cert, + EVP_PKEY *pkey, + STACK_OF(X509) *certs, + BIO *data, int flags); #if defined(__cplusplus) diff --git a/include/openssl/rand.h b/include/openssl/rand.h index 6dabc60ec7..d317da6016 100644 --- a/include/openssl/rand.h +++ b/include/openssl/rand.h @@ -75,44 +75,58 @@ OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len); // descriptors etc are opened. OPENSSL_EXPORT void RAND_seed(const void *buf, int num); + +// General No-op Functions [Deprecated]. +// +// OpenSSL historically allowed applications to do various operations to gather +// entropy and mix them into the entropy pool. AWS-LC sources entropy for the +// consuming application and the following functions have been deprecated as +// no-ops. Consumers should call |RAND_bytes| directly. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED| to the ones that are missing. +// curl and tpm2-tss defines -Wnerror and depend on them. + // RAND_load_file returns a nonnegative number. -OPENSSL_EXPORT int RAND_load_file(const char *path, long num); +OPENSSL_EXPORT OPENSSL_DEPRECATED int RAND_load_file(const char *path, + long num); // RAND_write_file does nothing and returns negative 1. -OPENSSL_EXPORT int RAND_write_file(const char *file); +OPENSSL_EXPORT OPENSSL_DEPRECATED int RAND_write_file(const char *file); // RAND_file_name returns NULL. -OPENSSL_EXPORT const char *RAND_file_name(char *buf, size_t num); +OPENSSL_EXPORT OPENSSL_DEPRECATED const char *RAND_file_name(char *buf, + size_t num); // RAND_add does nothing. -OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy); +OPENSSL_EXPORT OPENSSL_DEPRECATED void RAND_add(const void *buf, int num, + double entropy); // RAND_egd returns 255. -OPENSSL_EXPORT int RAND_egd(const char *); +OPENSSL_EXPORT OPENSSL_DEPRECATED int RAND_egd(const char *); // RAND_poll returns one. -OPENSSL_EXPORT int RAND_poll(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED int RAND_poll(void); // RAND_status returns one. OPENSSL_EXPORT int RAND_status(void); // RAND_cleanup does nothing. -OPENSSL_EXPORT void RAND_cleanup(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED void RAND_cleanup(void); // rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it // exists only to be the return type of |RAND_SSLeay|. It's // external so that variables of this type can be initialized. struct rand_meth_st { - void (*seed) (const void *buf, int num); - int (*bytes) (uint8_t *buf, size_t num); - void (*cleanup) (void); - void (*add) (const void *buf, int num, double entropy); - int (*pseudorand) (uint8_t *buf, size_t num); - int (*status) (void); + void (*seed)(const void *buf, int num); + int (*bytes)(uint8_t *buf, size_t num); + void (*cleanup)(void); + void (*add)(const void *buf, int num, double entropy); + int (*pseudorand)(uint8_t *buf, size_t num); + int (*status)(void); }; // RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. -OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED RAND_METHOD *RAND_SSLeay(void); // RAND_OpenSSL returns a pointer to a dummy |RAND_METHOD|. OPENSSL_EXPORT RAND_METHOD *RAND_OpenSSL(void); @@ -124,7 +138,7 @@ OPENSSL_EXPORT const RAND_METHOD *RAND_get_rand_method(void); OPENSSL_EXPORT int RAND_set_rand_method(const RAND_METHOD *); // RAND_keep_random_devices_open does nothing. -OPENSSL_EXPORT void RAND_keep_random_devices_open(int a); +OPENSSL_EXPORT OPENSSL_DEPRECATED void RAND_keep_random_devices_open(int a); #if defined(__cplusplus) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 7fbe0c4dab..84091c07df 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -482,9 +482,9 @@ OPENSSL_EXPORT int SSL_write_ex(SSL *s, const void *buf, size_t num, // keys for this connection will be updated and the peer will be informed of the // change. // If |request_type| is set to |SSL_KEY_UPDATE_REQUESTED|, then the sending keys -// for this connection will be updated and the peer will be informed of the change -// along with a request for the peer to additionally update its sending keys. -// RFC: https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3 +// for this connection will be updated and the peer will be informed of the +// change along with a request for the peer to additionally update its sending +// keys. RFC: https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.3 // // Note that this function does not _send_ the message itself. The next call to // |SSL_write| will cause the message to be sent. |SSL_write| may be called with @@ -1780,8 +1780,8 @@ OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl); // SSL_get0_verified_chain returns the verified certificate chain of the peer // including the peer's end entity certificate. It must be called after a // session has been successfully established. If peer verification was not -// successful (as indicated by |SSL_get_verify_result| not returning |X509_V_OK|) -// the result will be null. If a verification callback was set with +// successful (as indicated by |SSL_get_verify_result| not returning +// |X509_V_OK|) the result will be null. If a verification callback was set with // |SSL_CTX_set_cert_verify_callback| or |SSL_set_custom_verify| // this function's behavior is undefined. OPENSSL_EXPORT STACK_OF(X509) *SSL_get0_verified_chain(const SSL *ssl); @@ -3078,6 +3078,10 @@ OPENSSL_EXPORT int SSL_set_verify_algorithm_prefs(SSL *ssl, // SSL_set_hostflags calls |X509_VERIFY_PARAM_set_hostflags| on the // |X509_VERIFY_PARAM| associated with this |SSL*|. The |flags| argument // should be one of the |X509_CHECK_*| constants. +// +// |X509_V_FLAG_X509_STRICT| is always ON by default and +// |X509_V_FLAG_ALLOW_PROXY_CERTS| is always OFF. Both are non-configurable. +// See |x509.h| for more details. OPENSSL_EXPORT void SSL_set_hostflags(SSL *ssl, unsigned flags); @@ -4041,7 +4045,8 @@ enum ssl_early_data_reason_t BORINGSSL_ENUM_INT { ssl_early_data_alps_mismatch = 14, // The value of the largest entry. ssl_early_data_unsupported_with_custom_extension = 15, - ssl_early_data_reason_max_value = ssl_early_data_unsupported_with_custom_extension, + ssl_early_data_reason_max_value = + ssl_early_data_unsupported_with_custom_extension, }; // SSL_get_early_data_reason returns details why 0-RTT was accepted or rejected @@ -4775,7 +4780,10 @@ OPENSSL_EXPORT int SSL_was_key_usage_invalid(const SSL *ssl); // OSSL_HANDSHAKE_STATE enumerates possible TLS states returned from // |SSL_get_state| and |SSL_state|. TLS_ST_* are aliases for |SSL_ST_*| for // OpenSSL 1.1.0 compatibility. -typedef enum {TLS_ST_OK = SSL_ST_OK, TLS_ST_BEFORE = SSL_ST_INIT} OSSL_HANDSHAKE_STATE; +typedef enum { + TLS_ST_OK = SSL_ST_OK, + TLS_ST_BEFORE = SSL_ST_INIT +} OSSL_HANDSHAKE_STATE; // SSL_CB_* are possible values for the |type| parameter in the info // callback and the bitmasks that make them up. @@ -4931,6 +4939,54 @@ OPENSSL_EXPORT int SSL_used_hello_retry_request(const SSL *ssl); OPENSSL_EXPORT void SSL_set_jdk11_workaround(SSL *ssl, int enable); +// SSL Stat Counters. + +// SSL_CTX_sess_connect returns the number of started SSL/TLS handshakes in +// client mode. +OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_good returns the number of successfully established +// SSL/TLS sessions in client mode. +OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_renegotiate returns the number of started renegotiations +// in client mode. +OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept returns the number of started SSL/TLS handshakes in +// server mode. +OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_renegotiate returns zero. AWS-LC does not support server +// side renegotiations. +OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_good returns the number of successfully established +// SSL/TLS sessions in server mode. +OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_hits returns the number of successfully reused sessions, from +// both session cache and session tickets. +OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_cb_hits returns the number of successfully retrieved sessions +// from the external session cache in server mode. +OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_misses returns the number of sessions proposed by clients that +// were not found in the internal session cache in server mode. +OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx); + +// SSL_CTX_sess_timeouts returns the number of sessions proposed by clients and +// either found in the internal or external session cache in server mode, but +// that were invalid due to timeout. +OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx); + +// SSL_CTX_sess_cache_full returns the number of sessions that were removed +// because the maximum session cache size was exceeded. +OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx); + + // Deprecated functions. // SSL_library_init calls |CRYPTO_library_init| and returns one. @@ -4950,27 +5006,6 @@ OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, // SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); -typedef void COMP_METHOD; -typedef struct ssl_comp_st SSL_COMP; - -// SSL_COMP_get_compression_methods returns NULL. -OPENSSL_EXPORT STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); - -// SSL_COMP_add_compression_method returns one. -OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); - -// SSL_COMP_get_name returns NULL. -OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp); - -// SSL_COMP_get0_name returns the |name| member of |comp|. -OPENSSL_EXPORT const char *SSL_COMP_get0_name(const SSL_COMP *comp); - -// SSL_COMP_get_id returns the |id| member of |comp|. -OPENSSL_EXPORT int SSL_COMP_get_id(const SSL_COMP *comp); - -// SSL_COMP_free_compression_methods does nothing. -OPENSSL_EXPORT void SSL_COMP_free_compression_methods(void); - // SSLv23_method calls |TLS_method|. OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); @@ -5010,78 +5045,12 @@ OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); // Free |ssl| and create a new one instead. OPENSSL_EXPORT int SSL_clear(SSL *ssl); -// SSL_CTX_set_tmp_rsa_callback does nothing. -OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback( - SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); - -// SSL_set_tmp_rsa_callback does nothing. -OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl, - RSA *(*cb)(SSL *ssl, int is_export, - int keylength)); - -// SSL_CTX_sess_connect returns the number of started SSL/TLS handshakes in -// client mode. -OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx); - -// SSL_CTX_sess_connect_good returns the number of successfully established -// SSL/TLS sessions in client mode. -OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx); - -// SSL_CTX_sess_connect_renegotiate returns the number of started renegotiations -// in client mode. -OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx); - -// SSL_CTX_sess_accept returns the number of started SSL/TLS handshakes in -// server mode. -OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx); - -// SSL_CTX_sess_accept_renegotiate returns zero. AWS-LC does not support server -// side renegotiations. -OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx); - -// SSL_CTX_sess_accept_good returns the number of successfully established -// SSL/TLS sessions in server mode. -OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx); - -// SSL_CTX_sess_hits returns the number of successfully reused sessions, from -// both session cache and session tickets. -OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx); - -// SSL_CTX_sess_cb_hits returns the number of successfully retrieved sessions -// from the external session cache in server mode. -OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx); - -// SSL_CTX_sess_misses returns the number of sessions proposed by clients that -// were not found in the internal session cache in server mode. -OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx); - -// SSL_CTX_sess_timeouts returns the number of sessions proposed by clients and -// either found in the internal or external session cache in server mode, but -// that were invalid due to timeout. -OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx); - -// SSL_CTX_sess_cache_full returns the number of sessions that were removed -// because the maximum session cache size was exceeded. -OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx); - // SSL_cutthrough_complete calls |SSL_in_false_start|. OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *ssl); // SSL_num_renegotiations calls |SSL_total_renegotiations|. OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl); -// SSL_CTX_need_tmp_RSA returns zero. -OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx); - -// SSL_need_tmp_RSA returns zero. -OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl); - -// SSL_CTX_set_tmp_rsa returns one. -OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa); - -// SSL_set_tmp_rsa returns one. -OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa); - // SSL_CTX_get_read_ahead returns zero. OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx); @@ -5094,18 +5063,6 @@ OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl); // SSL_set_read_ahead returns one. OPENSSL_EXPORT int SSL_set_read_ahead(SSL *ssl, int yes); -// SSL_set_state does nothing. -OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state); - -// SSL_get_shared_ciphers writes an empty string to |buf| and returns a -// pointer to |buf|, or NULL if |len| is less than or equal to zero. -OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); - -// SSL_get_shared_sigalgs returns zero. -OPENSSL_EXPORT int SSL_get_shared_sigalgs(SSL *ssl, int idx, int *psign, - int *phash, int *psignandhash, - uint8_t *rsig, uint8_t *rhash); - // SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. #define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START @@ -5130,12 +5087,6 @@ OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session); // frees |*out| and sets |*out| to the new |SSL_SESSION|. OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out); -// ERR_load_SSL_strings does nothing. -OPENSSL_EXPORT void ERR_load_SSL_strings(void); - -// SSL_load_error_strings does nothing. -OPENSSL_EXPORT void SSL_load_error_strings(void); - // SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns // zero on success and one on failure. // @@ -5151,33 +5102,6 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, // convention. Use |SSL_set_srtp_profiles| instead. OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); -// SSL_get_current_compression returns NULL. -OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl); - -// SSL_get_current_expansion returns NULL. -OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl); - -// SSL_get_server_tmp_key returns zero. -OPENSSL_EXPORT int SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key); - -// SSL_CTX_set_tmp_dh returns 1. -OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); - -// SSL_set_tmp_dh returns 1. -OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh); - -// SSL_CTX_set_tmp_dh_callback does nothing. -OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback( - SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength)); - -// SSL_set_tmp_dh_callback does nothing. -OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl, - DH *(*cb)(SSL *ssl, int is_export, - int keylength)); - -// SSL_CTX_set_dh_auto does nothing and returns 0 for error. -OPENSSL_EXPORT long SSL_CTX_set_dh_auto(SSL_CTX *ctx, int onoff); - // SSL_CTX_set1_sigalgs takes |num_values| ints and interprets them as pairs // where the first is the nid of a hash function and the second is an // |EVP_PKEY_*| value. It configures the signature algorithm preferences for @@ -5226,41 +5150,6 @@ OPENSSL_EXPORT int SSL_CTX_set1_sigalgs_list(SSL_CTX *ctx, const char *str); // more convenient to codesearch for specific algorithm values. OPENSSL_EXPORT int SSL_set1_sigalgs_list(SSL *ssl, const char *str); -// SSL_CTX_get_security_level returns 0. This is only to maintain compatibility -// with OpenSSL and no security assumptions should be based on the number this -// function returns. -// -// Per OpenSSL's definition of Level 0, 1, and 2: -// -// Level 0: -// Everything is permitted. This retains compatibility with previous versions of -// OpenSSL. -// -// Level 1 -// The security level corresponds to a minimum of 80 bits of security. Any -// parameters offering below 80 bits of security are excluded. As a result RSA, -// DSA and DH keys shorter than 1024 bits and ECC keys shorter than 160 bits are -// prohibited. All export cipher suites are prohibited since they all offer less -// than 80 bits of security. SSL version 2 is prohibited. Any cipher suite using -// MD5 for the MAC is also prohibited. -// -// Level 2 -// Security level set to 112 bits of security. As a result RSA, DSA and DH keys -// shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited. In -// addition to the level 1 exclusions any cipher suite using RC4 is also -// prohibited. SSL version 3 is also not allowed. Compression is disabled. -// -// AWS-LC's libssl doesn't support SSLv2 or SSLv3, and we have no support for MD5 -// or RC4 related cipher suites. However, we don't directly prohibit 512 bit RSA -// keys like Level 1 in OpenSSL states. Since this function is only retained for -// OpenSSL compatibility, we set the returned value to 0. This may change if -// we're asked to support actual Security level setting in AWS-LC. -OPENSSL_EXPORT int SSL_CTX_get_security_level(const SSL_CTX *ctx); - -// SSL_CTX_set_security_level does nothing. See documentation in -// |SSL_CTX_get_security_level| about implied security levels for AWS-LC. -OPENSSL_EXPORT void SSL_CTX_set_security_level(const SSL_CTX *ctx, int level); - // SSL_SESSION_print prints the contents of |sess| to |bp|. OPENSSL_EXPORT int SSL_SESSION_print(BIO *bp, const SSL_SESSION *sess); @@ -5289,48 +5178,6 @@ OPENSSL_EXPORT int SSL_SESSION_print(BIO *bp, const SSL_SESSION *sess); #define SSL_set_timeout(session, timeout) \ SSL_SESSION_set_timeout((session), (timeout)) -struct ssl_comp_st { - int id; - const char *name; - char *method; -}; - -DEFINE_STACK_OF(SSL_COMP) - -// The following flags do nothing and are included only to make it easier to -// compile code with BoringSSL. -#define SSL_MODE_AUTO_RETRY 0 -#define SSL_MODE_RELEASE_BUFFERS 0 -#define SSL_MODE_SEND_CLIENTHELLO_TIME 0 -#define SSL_MODE_SEND_SERVERHELLO_TIME 0 -#define SSL_OP_ALL 0 -#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 -#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 -#define SSL_OP_EPHEMERAL_RSA 0 -#define SSL_OP_LEGACY_SERVER_CONNECT 0 -#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 -#define SSL_OP_MICROSOFT_SESS_ID_BUG 0 -#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 -#define SSL_OP_NETSCAPE_CA_DN_BUG 0 -#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0 -#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 -#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 -#define SSL_OP_NO_COMPRESSION 0 -#define SSL_OP_NO_RENEGOTIATION 0 // ssl_renegotiate_never is the default -#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 -#define SSL_OP_NO_SSLv2 0 -#define SSL_OP_NO_SSLv3 0 -#define SSL_OP_PKCS1_CHECK_1 0 -#define SSL_OP_PKCS1_CHECK_2 0 -#define SSL_OP_SINGLE_DH_USE 0 -#define SSL_OP_SINGLE_ECDH_USE 0 -#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 -#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 -#define SSL_OP_TLS_BLOCK_PADDING_BUG 0 -#define SSL_OP_TLS_D5_BUG 0 -#define SSL_OP_TLS_ROLLBACK_BUG 0 -#define SSL_VERIFY_CLIENT_ONCE 0 - // SSL_cache_hit calls |SSL_session_reused|. OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl); @@ -5514,12 +5361,6 @@ OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void); // other than one on error. OPENSSL_EXPORT long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership); -// SSL_CTX_set_ecdh_auto returns one. -#define SSL_CTX_set_ecdh_auto(ctx, onoff) 1 - -// SSL_set_ecdh_auto returns one. -#define SSL_set_ecdh_auto(ssl, onoff) 1 - // SSL_get_session returns a non-owning pointer to |ssl|'s session. For // historical reasons, which session it returns depends on |ssl|'s state. // @@ -5614,7 +5455,9 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_cb(SSL_CTX *ctx, void *arg)); // SSL_CTX_get_tlsext_status_cb returns the legacy OpenSSL OCSP callback if set. -OPENSSL_EXPORT int SSL_CTX_get_tlsext_status_cb(SSL_CTX *ctx, int (**callback)(SSL *, void *)); +OPENSSL_EXPORT int SSL_CTX_get_tlsext_status_cb(SSL_CTX *ctx, + int (**callback)(SSL *, + void *)); // SSL_CTX_set_tlsext_status_arg sets additional data for // |SSL_CTX_set_tlsext_status_cb|'s callback and returns one. @@ -5643,7 +5486,8 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_status_arg(SSL_CTX *ctx, void *arg); #define SSL_CURVE_SECP384R1 SSL_GROUP_SECP384R1 #define SSL_CURVE_SECP521R1 SSL_GROUP_SECP521R1 #define SSL_CURVE_X25519 SSL_GROUP_X25519 -#define SSL_CURVE_SECP256R1_KYBER768_DRAFT00 SSL_GROUP_SECP256R1_KYBER768_DRAFT00 +#define SSL_CURVE_SECP256R1_KYBER768_DRAFT00 \ + SSL_GROUP_SECP256R1_KYBER768_DRAFT00 #define SSL_CURVE_X25519_KYBER768_DRAFT00 SSL_GROUP_X25519_KYBER768_DRAFT00 // SSL_get_curve_id calls |SSL_get_group_id|. @@ -5670,6 +5514,293 @@ OPENSSL_EXPORT int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves); OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); +// No-op Configuration Flags +// +// The following flags do nothing and are included only to make it easier to +// compile code with AWS-LC. Flags defined within this section are not +// configurable and the state of AWS-LC does not change when used. + +// SSL_MODE_AUTO_RETRY is ON by default in AWS-LC and OpenSSL. This will let +// the application automatically retry if the transport is blocking. +// Read/write operations will only return after the handshake and successful +// completion. +#define SSL_MODE_AUTO_RETRY 0 + +// SSL_MODE_RELEASE_BUFFERS is ON by default in AWS-LC. When a read/write +// buffer is no longer needed for a given SSL, the memory holding it is +// released. +#define SSL_MODE_RELEASE_BUFFERS 0 + +// SSL_MODE_SEND_CLIENTHELLO_TIME is OFF by default in AWS-LC. Turning this ON +// in OpenSSL sends the current time in the Random fields of the ClientHello +// records is sent. +#define SSL_MODE_SEND_CLIENTHELLO_TIME 0 + +// SSL_MODE_SEND_SERVERHELLO_TIME is ON by default in AWS-LC. The current time +// in the Random fields of the ServerHello records is sent. +#define SSL_MODE_SEND_SERVERHELLO_TIME 0 + +// SSL_OP_ALL is OFF by default in AWS-LC. Turning this ON in OpenSSL enables +// all the less harmless bug workarounds that OpenSSL has had historically. +// +// See https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_options.html +// for more details. +#define SSL_OP_ALL 0 + +// SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION is OFF by default in AWS-LC. +// Turning this ON in OpenSSL allows legacy insecure renegotiation for +// unpatched clients and servers and is intentionally not supported in AWS-LC. +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 + +// SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS is ON by default in AWS-LC. This +// disables a countermeasure against a SSL 3.0/TLS 1.0 protocol vulnerability +// affecting CBC ciphers, which cannot be handled by some broken SSL +// implementations. +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 + +// SSL_OP_LEGACY_SERVER_CONNECT is OFF by default in AWS-LC. Turning this ON in +// OpenSSL allows legacy insecure renegotiation between OpenSSL and unpatched +// servers "only" and is intentionally not supported in AWS-LC. +#define SSL_OP_LEGACY_SERVER_CONNECT 0 + +// SSL_OP_NO_COMPRESSION is ON by default in AWS-LC. AWS-LC intentionally does +// not support TLS record compressions. +#define SSL_OP_NO_COMPRESSION 0 + +// SSL_OP_NO_RENEGOTIATION is ON by default in AWS-LC. This disables all +// renegotiation in TLSv1.2 and earlier. +// To enable renegotiation, use |SSL_set_renegotiate_mode|. +#define SSL_OP_NO_RENEGOTIATION 0 // ssl_renegotiate_never is the default + +// SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is ON by default in AWS-LC. +// This always starts a new session when performing renegotiation as a server +// (i.e., session resumption requests are only accepted in the initial +// handshake). +// There is no support for renegototiation for a server in AWS-LC +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 + +// SSL_OP_NO_SSLv2 is ON by default in AWS-LC. There is no support for SSLv2 in +// AWS-LC +#define SSL_OP_NO_SSLv2 0 + +// SSL_OP_NO_SSLv2 is ON by default in AWS-LC. There is no support for SSLv3 in +// AWS-LC +#define SSL_OP_NO_SSLv3 0 + +// SSL_OP_TLS_ROLLBACK_BUG is OFF by default in AWS-LC. Turning this ON in +// OpenSSL disables version rollback attack detection and is intentionally not +// supported in AWS-LC. +#define SSL_OP_TLS_ROLLBACK_BUG 0 + +// SSL_VERIFY_CLIENT_ONCE is OFF by default in AWS-LC. Turning this ON in +// OpenSSL only requests a client certificate on the initial TLS handshake and +// is intentionally not supported in AWS-LC. +#define SSL_VERIFY_CLIENT_ONCE 0 + +// The following have no effect in both AWS-LC and OpenSSL. +#define SSL_OP_EPHEMERAL_RSA 0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 +#define SSL_OP_PKCS1_CHECK_1 0 +#define SSL_OP_PKCS1_CHECK_2 0 +#define SSL_OP_SINGLE_DH_USE 0 +#define SSL_OP_SINGLE_ECDH_USE 0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0 +#define SSL_OP_TLS_D5_BUG 0 + + +// |SSL_COMP| and |COMP_METHOD| No-ops [Deprecated]. +// +// Support for SSL compression has been completely removed and the following +// functions are only provided as no-ops for easier compatibility. + +typedef void COMP_METHOD; +typedef struct ssl_comp_st SSL_COMP; + +// SSL_COMP_get_compression_methods returns NULL. +OPENSSL_EXPORT OPENSSL_DEPRECATED STACK_OF(SSL_COMP) * +SSL_COMP_get_compression_methods(void); + +// SSL_COMP_add_compression_method returns one. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_COMP_add_compression_method( + int id, COMP_METHOD *cm); + +// SSL_COMP_get_name returns NULL. +OPENSSL_EXPORT OPENSSL_DEPRECATED const char *SSL_COMP_get_name( + const COMP_METHOD *comp); + +// SSL_COMP_get0_name returns the |name| member of |comp|. +OPENSSL_EXPORT OPENSSL_DEPRECATED const char *SSL_COMP_get0_name( + const SSL_COMP *comp); + +// SSL_COMP_get_id returns the |id| member of |comp|. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_COMP_get_id(const SSL_COMP *comp); + +// SSL_COMP_free_compression_methods does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_COMP_free_compression_methods(void); + +// SSL_get_current_compression returns NULL. +OPENSSL_EXPORT OPENSSL_DEPRECATED const COMP_METHOD * +SSL_get_current_compression(SSL *ssl); + +// SSL_get_current_expansion returns NULL. +OPENSSL_EXPORT OPENSSL_DEPRECATED const COMP_METHOD *SSL_get_current_expansion( + SSL *ssl); + +struct ssl_comp_st { + int id; + const char *name; + char *method; +}; + +DEFINE_STACK_OF(SSL_COMP) + + +// FFDH Ciphersuite No-ops [Deprecated]. +// +// AWS-LC does not support the use of FFDH cipher suites in libssl. The +// following functions are only provided as no-ops for easier compatibility. + +// SSL_get_server_tmp_key returns zero. This was deprecated as part of the +// removal of |EVP_PKEY_DH|. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_get_server_tmp_key( + SSL *ssl, EVP_PKEY **out_key); + +// SSL_CTX_set_tmp_dh returns 1. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and +// depends on this. +OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); + +// SSL_set_tmp_dh returns 1. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_set_tmp_dh(SSL *ssl, const DH *dh); + +// SSL_CTX_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_CTX_set_tmp_dh_callback( + SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_set_tmp_dh_callback( + SSL *ssl, DH *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_CTX_set_dh_auto does nothing and returns 0 for error. +OPENSSL_EXPORT OPENSSL_DEPRECATED long SSL_CTX_set_dh_auto(SSL_CTX *ctx, + int onoff); + + +// Security Levels No-ops [Deprecated]. +// +// OpenSSL has the option to set “security levels”. Security levels can be +// defined either at compile time with "-DOPENSSL_TLS_SECURITY_LEVEL=level" or +// at runtime with |SSL_CTX_set_security_level|. AWS-LC does not support this +// and the security level APIs are no-ops within AWS-LC. AWS-LC intentionally +// limits the knobs a consumer can tweak in regards to security. + +// SSL_CTX_get_security_level returns 0. This is only to maintain compatibility +// with OpenSSL and no security assumptions should be based on the number this +// function returns. +// +// Per OpenSSL's definition of Level 0, 1, and 2: +// +// Level 0: +// Everything is permitted. This retains compatibility with previous versions of +// OpenSSL. +// +// Level 1 +// The security level corresponds to a minimum of 80 bits of security. Any +// parameters offering below 80 bits of security are excluded. As a result RSA, +// DSA and DH keys shorter than 1024 bits and ECC keys shorter than 160 bits are +// prohibited. All export cipher suites are prohibited since they all offer less +// than 80 bits of security. SSL version 2 is prohibited. Any cipher suite using +// MD5 for the MAC is also prohibited. +// +// Level 2 +// Security level set to 112 bits of security. As a result RSA, DSA and DH keys +// shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited. In +// addition to the level 1 exclusions any cipher suite using RC4 is also +// prohibited. SSL version 3 is also not allowed. Compression is disabled. +// +// AWS-LC's libssl doesn't support SSLv2 or SSLv3 and we have no support for MD5 +// or RC4 related cipher suites. However, we don't directly prohibit 512 bit RSA +// keys like Level 1 in OpenSSL states. Since this function is only retained for +// OpenSSL compatibility, we set the returned value to 0. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_CTX_get_security_level( + const SSL_CTX *ctx); + +// SSL_CTX_set_security_level does nothing. See documentation in +// |SSL_CTX_get_security_level| about implied security levels for AWS-LC. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_CTX_set_security_level( + const SSL_CTX *ctx, int level); + + +// General No-op Functions [Deprecated]. + +// SSL_set_state does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_set_state(SSL *ssl, int state); + +// SSL_get_shared_ciphers writes an empty string to |buf| and returns a +// pointer to |buf|, or NULL if |len| is less than or equal to zero. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and +// depends on this. +OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +// SSL_get_shared_sigalgs returns zero. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_get_shared_sigalgs( + SSL *ssl, int idx, int *psign, int *phash, int *psignandhash, uint8_t *rsig, + uint8_t *rhash); + +// SSL_CTX_set_ecdh_auto returns one. This is also a no-op in OpenSSL. +#define SSL_CTX_set_ecdh_auto(ctx, onoff) 1 + +// SSL_set_ecdh_auto returns one. This is also a no-op in OpenSSL. +#define SSL_set_ecdh_auto(ssl, onoff) 1 + +// ERR_load_SSL_strings does nothing in AWS-LC and OpenSSL. +OPENSSL_EXPORT OPENSSL_DEPRECATED void ERR_load_SSL_strings(void); + +// SSL_load_error_strings does nothing in AWS-LC and OpenSSL. +// +// TODO (CryptoAlg-2398): Add |OPENSSL_DEPRECATED|. nginx defines -Werror and +// depends on this. +OPENSSL_EXPORT void SSL_load_error_strings(void); + + +// SSL TMP_RSA No-ops [Deprecated]. +// +// Support for these methods was intentionally removed due to them being the +// center of the FREAK attack. These functions are also no-ops in OpenSSL. +// FREAK Attack: https://freakattack.com/ + +// SSL_CTX_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_CTX_set_tmp_rsa_callback( + SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT OPENSSL_DEPRECATED void SSL_set_tmp_rsa_callback( + SSL *ssl, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_CTX_need_tmp_RSA returns zero. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx); + +// SSL_need_tmp_RSA returns zero. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_need_tmp_RSA(const SSL *ssl); + +// SSL_CTX_set_tmp_rsa returns one. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, + const RSA *rsa); + +// SSL_set_tmp_rsa returns one. +OPENSSL_EXPORT OPENSSL_DEPRECATED int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa); + + // Nodejs compatibility section (hidden). // // These defines exist for node.js, with the hope that we can eliminate the diff --git a/include/openssl/thread.h b/include/openssl/thread.h index e6108902fc..eab2a4f485 100644 --- a/include/openssl/thread.h +++ b/include/openssl/thread.h @@ -89,7 +89,7 @@ typedef pthread_rwlock_t CRYPTO_MUTEX; // by thread_pthread.c. typedef union crypto_mutex_st { double alignment; - uint8_t padding[3*sizeof(int) + 5*sizeof(unsigned) + 16 + 8]; + uint8_t padding[3 * sizeof(int) + 5 * sizeof(unsigned) + 16 + 8]; } CRYPTO_MUTEX; #endif @@ -116,7 +116,7 @@ OPENSSL_EXPORT int AWSLC_thread_local_clear(void); // calls to |AWSLC_thread_local_clear|. OPENSSL_EXPORT int AWSLC_thread_local_shutdown(void); -// Deprecated functions. +// General No-op Functions [Deprecated]. // // Historically, OpenSSL required callers to provide locking callbacks. // BoringSSL is thread-safe by default, but some old code calls these functions @@ -132,40 +132,43 @@ OPENSSL_EXPORT int AWSLC_thread_local_shutdown(void); // CRYPTO_num_locks returns one. (This is non-zero that callers who allocate // sizeof(lock) times this value don't get zero and then fail because malloc(0) // returned NULL.) -OPENSSL_EXPORT int CRYPTO_num_locks(void); +OPENSSL_EXPORT OPENSSL_DEPRECATED int CRYPTO_num_locks(void); // CRYPTO_set_locking_callback does nothing. -OPENSSL_EXPORT void CRYPTO_set_locking_callback( +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_set_locking_callback( void (*func)(int mode, int lock_num, const char *file, int line)); // CRYPTO_set_add_lock_callback does nothing. -OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)( +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_set_add_lock_callback(int (*func)( int *num, int amount, int lock_num, const char *file, int line)); // CRYPTO_get_locking_callback returns NULL. -OPENSSL_EXPORT void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, - const char *file, - int line); +OPENSSL_EXPORT OPENSSL_DEPRECATED void (*CRYPTO_get_locking_callback(void))( + int mode, int lock_num, const char *file, int line); // CRYPTO_get_lock_name returns a fixed, dummy string. -OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num); +OPENSSL_EXPORT OPENSSL_DEPRECATED const char *CRYPTO_get_lock_name( + int lock_num); // CRYPTO_THREADID_set_callback returns one. -OPENSSL_EXPORT int CRYPTO_THREADID_set_callback( +OPENSSL_EXPORT OPENSSL_DEPRECATED int CRYPTO_THREADID_set_callback( void (*threadid_func)(CRYPTO_THREADID *threadid)); // CRYPTO_THREADID_set_numeric does nothing. -OPENSSL_EXPORT void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, - unsigned long val); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_THREADID_set_numeric( + CRYPTO_THREADID *id, unsigned long val); // CRYPTO_THREADID_set_pointer does nothing. -OPENSSL_EXPORT void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_THREADID_set_pointer( + CRYPTO_THREADID *id, void *ptr); // CRYPTO_THREADID_current does nothing. -OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_THREADID_current( + CRYPTO_THREADID *id); // CRYPTO_set_id_callback does nothing. -OPENSSL_EXPORT void CRYPTO_set_id_callback(unsigned long (*func)(void)); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_set_id_callback( + unsigned long (*func)(void)); typedef struct { int references; @@ -173,30 +176,32 @@ typedef struct { } CRYPTO_dynlock; // CRYPTO_set_dynlock_create_callback does nothing. -OPENSSL_EXPORT void CRYPTO_set_dynlock_create_callback( +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_set_dynlock_create_callback( struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line)); // CRYPTO_set_dynlock_lock_callback does nothing. -OPENSSL_EXPORT void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( - int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_set_dynlock_lock_callback( + void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, + const char *file, int line)); // CRYPTO_set_dynlock_destroy_callback does nothing. -OPENSSL_EXPORT void CRYPTO_set_dynlock_destroy_callback( +OPENSSL_EXPORT OPENSSL_DEPRECATED void CRYPTO_set_dynlock_destroy_callback( void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line)); // CRYPTO_get_dynlock_create_callback returns NULL. -OPENSSL_EXPORT struct CRYPTO_dynlock_value *( +OPENSSL_EXPORT OPENSSL_DEPRECATED struct CRYPTO_dynlock_value *( *CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); // CRYPTO_get_dynlock_lock_callback returns NULL. -OPENSSL_EXPORT void (*CRYPTO_get_dynlock_lock_callback(void))( - int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); +OPENSSL_EXPORT OPENSSL_DEPRECATED void (*CRYPTO_get_dynlock_lock_callback( + void))(int mode, struct CRYPTO_dynlock_value *l, const char *file, + int line); // CRYPTO_get_dynlock_destroy_callback returns NULL. -OPENSSL_EXPORT void (*CRYPTO_get_dynlock_destroy_callback(void))( - struct CRYPTO_dynlock_value *l, const char *file, int line); +OPENSSL_EXPORT OPENSSL_DEPRECATED void (*CRYPTO_get_dynlock_destroy_callback( + void))(struct CRYPTO_dynlock_value *l, const char *file, int line); #if defined(__cplusplus) diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 99ae0187b3..a12c825085 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2980,10 +2980,11 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); // X509_V_FLAG_IGNORE_CRITICAL ignores unhandled critical extensions. #define X509_V_FLAG_IGNORE_CRITICAL 0x10 // X509_V_FLAG_X509_STRICT does nothing as its functionality has been enabled by -// default. +// default. In OpenSSL, enabling this disables workarounds for some broken +// certificates and makes the verification strictly apply X509 rules. #define X509_V_FLAG_X509_STRICT 0x00 // X509_V_FLAG_ALLOW_PROXY_CERTS does nothing as proxy certificate support has -// been removed. +// been removed. Proxy certificate support has been removed from AWS-LC. #define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 // X509_V_FLAG_POLICY_CHECK enables policy checking. #define X509_V_FLAG_POLICY_CHECK 0x80 @@ -3006,6 +3007,7 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); #define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 // X509_V_FLAG_TRUSTED_FIRST flag causes chain construction to look for issuers // in the trust store before looking at the untrusted certificates provided. +// This is ON by default in both AWS-LC and OpenSSL. #define X509_V_FLAG_TRUSTED_FIRST 0x8000 // X509_V_FLAG_PARTIAL_CHAIN allows partial chains if at least one certificate diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 22533b0da5..0dc1fe3dce 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -940,22 +940,45 @@ OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); -// Flags for X509_check_* functions -// Deprecated: this flag does nothing -#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0 -// Disable wildcard matching for dnsName fields and common name. + +// X509_check_* functions +// +// See https://www.openssl.org/docs/manmaster/man3/X509_check_host.html +// for more details. + +// X509_CHECK_FLAG_NO_WILDCARDS disables wildcard matching for dnsName fields +// and common name. This only applies to |X509_check_host|. #define X509_CHECK_FLAG_NO_WILDCARDS 0x2 + +// X509_CHECK_FLAG_NEVER_CHECK_SUBJECT skips the subject common name fallback +// if subjectAltNames is missing. +#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 + // X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS does nothing, but is necessary in -// OpenSSL to enable standard wildcard matching. In BoringSSL, this behavior is -// always enabled. +// OpenSSL to enable standard wildcard matching. In AWS-LC, this behavior is +// always enabled. This only applies to |X509_check_host| in OpenSSL. #define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 -// Deprecated: this flag does nothing + +// X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT is deprecated and does nothing. +// Enabling this in OpenSSL considers the subject DN even if the certificate +// contains at least one subject alternative name of the right type; the +// default is to ignore the subject DN when at least one corresponding subject +// alternative names is present. +#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0 + +// X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS is deprecated and does nothing. +// This only applies to |X509_check_host|. When used in OpenSSL, it allows a +// "*" that constitutes the complete label of a DNS name (e.g. +// "*.example.com") to match more than one label in |chk|. #define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0 -// Deprecated: this flag does nothing + +// X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS is deprecated and does nothing. +// This only applies to |X509_check_host|. When used in OpenSSL, it +// restricts name values which start with ".", that would otherwise match +// any sub-domain in the peer certificate, to only match direct child +// sub-domains. #define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0 -// Skip the subject common name fallback if subjectAltNames is missing. -#define X509_CHECK_FLAG_NEVER_CHECK_SUBJECT 0x20 // X509_check_host checks if |x| has a Common Name or Subject Alternate name // that matches the |chk| string up to |chklen|. If |chklen| is 0 diff --git a/tool/speed.cc b/tool/speed.cc index 5a26220722..18a8282bd3 100644 --- a/tool/speed.cc +++ b/tool/speed.cc @@ -2558,7 +2558,12 @@ static bool parseStringVectorToIntegerVector( } bool Speed(const std::vector &args) { -#if AWSLC_API_VERSION > 16 +#if AWSLC_API_VERSION > 27 + OPENSSL_BEGIN_ALLOW_DEPRECATED + // We started marking this as deprecated. + EVP_MD_unstable_sha3_enable(true); + OPENSSL_END_ALLOW_DEPRECATED +#elif AWSLC_API_VERSION > 16 // For mainline AWS-LC this is a no-op, however if speed.cc built with an old // branch of AWS-LC SHA3 might be disabled by default and fail the benchmark. EVP_MD_unstable_sha3_enable(true); From 572c75befa9628bb057c94a81232011578cd14c5 Mon Sep 17 00:00:00 2001 From: Andrew Hopkins Date: Fri, 12 Apr 2024 15:19:23 -0700 Subject: [PATCH 20/25] Use larger ARM hosts for long CodeBuild jobs (#1529) --- .../ci/cdk/cdk/codebuild/github_ci_integration_omnibus.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ci/cdk/cdk/codebuild/github_ci_integration_omnibus.yaml b/tests/ci/cdk/cdk/codebuild/github_ci_integration_omnibus.yaml index a8dcdddd11..ce8bbc583b 100644 --- a/tests/ci/cdk/cdk/codebuild/github_ci_integration_omnibus.yaml +++ b/tests/ci/cdk/cdk/codebuild/github_ci_integration_omnibus.yaml @@ -63,7 +63,7 @@ batch: env: type: ARM_CONTAINER privileged-mode: false - compute-type: BUILD_GENERAL1_LARGE + compute-type: BUILD_GENERAL1_2XLARGE image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-aarch:amazonlinux-2023_clang-15x_sanitizer_latest variables: AWS_LC_CI_TARGET: "tests/ci/integration/run_openssh_integration.sh" @@ -74,7 +74,7 @@ batch: env: type: ARM_CONTAINER privileged-mode: false - compute-type: BUILD_GENERAL1_LARGE + compute-type: BUILD_GENERAL1_2XLARGE image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-aarch:amazonlinux-2023_clang-15x_sanitizer_latest variables: AWS_LC_CI_TARGET: "tests/ci/integration/run_openssh_integration.sh" @@ -116,7 +116,7 @@ batch: env: type: ARM_CONTAINER privileged-mode: false - compute-type: BUILD_GENERAL1_LARGE + compute-type: BUILD_GENERAL1_2XLARGE image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-aarch:ubuntu-22.04_gcc-12x_latest variables: AWS_LC_CI_TARGET: "tests/ci/integration/run_mysql_integration.sh" From 04eb6b4bea12746c97b30510c6f5cc07a75cdc72 Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:28:19 -0400 Subject: [PATCH 21/25] Align GitHub workflow/job run conditions (#1532) ### Description of changes: * Align our GitHub workflows/jobs so that they all run on the same conditions. * Avoid costly CI runs when on non-"aws" repos. * The "General CI Tests sanity-test-run" and "Code Coverage codecov-ci" jobs will still run on any repo that has GitHub actions enabled. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. --- .github/workflows/abidiff.yml | 3 +++ .github/workflows/actions-ci.yml | 11 +++++++++-- .github/workflows/aws-lc-rs.yml | 1 + .github/workflows/cmake.yml | 6 +++--- .github/workflows/codecov-ci.yml | 2 +- .github/workflows/cross-test.yml | 9 ++++++++- .github/workflows/integrations.yml | 11 +++++++++++ .github/workflows/windows-alt.yml | 9 ++++----- 8 files changed, 40 insertions(+), 12 deletions(-) diff --git a/.github/workflows/abidiff.yml b/.github/workflows/abidiff.yml index 532892288f..68af3272b1 100644 --- a/.github/workflows/abidiff.yml +++ b/.github/workflows/abidiff.yml @@ -1,5 +1,7 @@ name: ABI Diff on: + push: + branches: [ '*' ] pull_request: branches: [ '*' ] concurrency: @@ -10,6 +12,7 @@ env: GOPROXY: https://proxy.golang.org,direct jobs: libs: + if: github.repository_owner == 'aws' name: libcrypto and libssl runs-on: ubuntu-latest steps: diff --git a/.github/workflows/actions-ci.yml b/.github/workflows/actions-ci.yml index 65ec960518..8afda4f526 100644 --- a/.github/workflows/actions-ci.yml +++ b/.github/workflows/actions-ci.yml @@ -1,12 +1,12 @@ name: General CI Tests on: + push: + branches: [ '*' ] pull_request: branches: [ '*' ] - concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true - env: GOPROXY: https://proxy.golang.org,direct SDE_MIRROR_URL: "https://downloadmirror.intel.com/813591/sde-external-9.33.0-2024-01-07-win.tar.xz" @@ -30,6 +30,7 @@ jobs: ninja -C test_build_dir run_tests macOS-x86: + if: github.repository_owner == 'aws' needs: [sanity-test-run] runs-on: macos-latest steps: @@ -39,6 +40,7 @@ jobs: ./tests/ci/run_posix_tests.sh macOS-x86-FIPS: + if: github.repository_owner == 'aws' needs: [sanity-test-run] runs-on: macos-latest steps: @@ -48,6 +50,7 @@ jobs: ./tests/ci/run_fips_tests.sh macOS-ARM: + if: github.repository_owner == 'aws' needs: [sanity-test-run] runs-on: macos-latest-xlarge steps: @@ -60,6 +63,7 @@ jobs: ./tests/ci/run_posix_tests.sh macOS-ARM-FIPS: + if: github.repository_owner == 'aws' needs: [sanity-test-run] runs-on: macos-latest-xlarge steps: @@ -73,6 +77,7 @@ jobs: MSVC-2019: + if: github.repository_owner == 'aws' needs: [sanity-test-run] runs-on: aws-lc_windows-2019_8-core steps: @@ -87,6 +92,7 @@ jobs: .\tests\ci\run_windows_tests.bat "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 MSVC-2022: + if: github.repository_owner == 'aws' needs: [sanity-test-run] runs-on: aws-lc_windows-latest_8-core steps: @@ -101,6 +107,7 @@ jobs: .\tests\ci\run_windows_tests.bat "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 MSVC-SDE-64-bit: + if: github.repository_owner == 'aws' needs: [sanity-test-run] # TODO: Update this to run on windows-2022. windows-2022 (Windows 11) has phased out support for older processors. # https://learn.microsoft.com/en-us/windows-hardware/design/minimum/supported/windows-11-supported-intel-processors diff --git a/.github/workflows/aws-lc-rs.yml b/.github/workflows/aws-lc-rs.yml index f9021dbf9e..5d91d0dedc 100644 --- a/.github/workflows/aws-lc-rs.yml +++ b/.github/workflows/aws-lc-rs.yml @@ -12,6 +12,7 @@ env: AWS_LC_SYS_CMAKE_BUILDER: 1 jobs: standard: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index c8595bc313..5ab96862f3 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -1,10 +1,9 @@ name: CMake Compatability on: - pull_request: - branches: [ '*' ] push: branches: [ '*' ] - + pull_request: + branches: [ '*' ] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true @@ -13,6 +12,7 @@ env: GOPROXY: https://proxy.golang.org,direct jobs: cmake: + if: github.repository_owner == 'aws' name: CMake ${{ matrix.cmake.version}} build with ${{ matrix.generator}} FIPS=${{ matrix.fips }} strategy: matrix: diff --git a/.github/workflows/codecov-ci.yml b/.github/workflows/codecov-ci.yml index 8e0d34b39a..d9fb2e9419 100644 --- a/.github/workflows/codecov-ci.yml +++ b/.github/workflows/codecov-ci.yml @@ -5,7 +5,7 @@ on: pull_request: branches: [ '*' ] concurrency: - group: code-cov-${{ github.workflow }}-${{ github.event.pull_request.number }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: codecov-ci: diff --git a/.github/workflows/cross-test.yml b/.github/workflows/cross-test.yml index fde99b84cc..15ff4371d4 100644 --- a/.github/workflows/cross-test.yml +++ b/.github/workflows/cross-test.yml @@ -5,10 +5,11 @@ on: pull_request: branches: [ '*' ] concurrency: - group: ppc64be-${{ github.workflow }}-${{ github.event.pull_request.number }} + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: ppc64-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu @@ -19,6 +20,7 @@ jobs: - name: PPC64 Build/Test run: tests/ci/run_cross_tests.sh ppc64 powerpc64-unknown-linux-gnu "-DCMAKE_BUILD_TYPE=Release" "-DCMAKE_BUILD_TYPE=Release -DFIPS=1 -DBUILD_SHARED_LIBS=1" ppc32-non-fips-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu @@ -29,6 +31,7 @@ jobs: - name: PPC32 Build/Test run: tests/ci/run_cross_tests.sh ppc powerpc-unknown-linux-gnu "-DCMAKE_BUILD_TYPE=Release" ppc32-fips-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu @@ -39,6 +42,7 @@ jobs: - name: PPC32 Build/Test run: tests/ci/run_cross_tests.sh ppc powerpc-unknown-linux-gnu "-DCMAKE_BUILD_TYPE=Release -DFIPS=1 -DBUILD_SHARED_LIBS=1" ppc64le-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu @@ -49,6 +53,7 @@ jobs: - name: PPC64LE Build/Test run: tests/ci/run_cross_tests.sh ppc64le powerpc64le-unknown-linux-gnu "-DCMAKE_BUILD_TYPE=Release" "-DCMAKE_BUILD_TYPE=Release -DFIPS=1 -DBUILD_SHARED_LIBS=1" riscv64-non-fips-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu @@ -66,6 +71,7 @@ jobs: CFLAGS: "-Wno-string-compare" run: tests/ci/run_cross_tests.sh riscv riscv64-unknown-linux-gnu "-DCMAKE_BUILD_TYPE=Release" armv6-non-fips-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu @@ -89,6 +95,7 @@ jobs: # - name: armv6 Build/Test # run: tests/ci/run_cross_tests.sh loongarch64 loongarch64-unknown-linux-gnu "-DCMAKE_BUILD_TYPE=Release" s390x-non-fips-build-test: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install qemu diff --git a/.github/workflows/integrations.yml b/.github/workflows/integrations.yml index d439b99535..e967d09b6e 100644 --- a/.github/workflows/integrations.yml +++ b/.github/workflows/integrations.yml @@ -11,6 +11,7 @@ env: CC: gcc jobs: haproxy: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -22,6 +23,7 @@ jobs: run: | ./tests/ci/integration/run_haproxy_integration.sh tpm2-tss: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -32,6 +34,7 @@ jobs: run: | ./tests/ci/integration/run_tpm2_tss_integration.sh grpc: + if: github.repository_owner == 'aws' env: DEBIAN_FRONTEND: noninteractive TZ: Etc/UTC @@ -49,6 +52,7 @@ jobs: run: | ./tests/ci/integration/run_grpc_integration.sh tcpdump: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -60,6 +64,7 @@ jobs: run: | ./tests/ci/integration/run_tcpdump_integration.sh trousers: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -71,6 +76,7 @@ jobs: run: | ./tests/ci/integration/run_trousers_integration.sh ntp: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -82,6 +88,7 @@ jobs: run: | ./tests/ci/integration/run_ntp_integration.sh socat: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -92,6 +99,7 @@ jobs: run: | ./tests/ci/integration/run_socat_integration.sh python-main: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -103,6 +111,7 @@ jobs: run: | ./tests/ci/integration/run_python_integration.sh main python-releases: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -114,6 +123,7 @@ jobs: run: | ./tests/ci/integration/run_python_integration.sh 3.10 3.11 3.12 bind9: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies @@ -125,6 +135,7 @@ jobs: run: | ./tests/ci/integration/run_bind9_integration.sh strongswan: + if: github.repository_owner == 'aws' runs-on: ubuntu-latest steps: - name: Install OS Dependencies diff --git a/.github/workflows/windows-alt.yml b/.github/workflows/windows-alt.yml index 3390603c5f..0c23b32bc3 100644 --- a/.github/workflows/windows-alt.yml +++ b/.github/workflows/windows-alt.yml @@ -1,16 +1,15 @@ name: Windows Alternative Compilers on: - pull_request: - branches: [ '*' ] push: branches: [ '*' ] - + pull_request: + branches: [ '*' ] concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number }} cancel-in-progress: true jobs: mingw: - if: github.repository == 'aws/aws-lc' + if: github.repository_owner == 'aws' runs-on: windows-latest steps: - name: Install NASM @@ -41,7 +40,7 @@ jobs: - name: Run tests run: cmake --build ./build --target run_tests clang: - if: github.repository == 'aws/aws-lc' + if: github.repository_owner == 'aws' runs-on: windows-latest steps: - name: Install NASM From 2d45531bc09952373a4f1aaa744a509371739504 Mon Sep 17 00:00:00 2001 From: William Bo Yang Date: Mon, 15 Apr 2024 23:44:19 +0300 Subject: [PATCH 22/25] Add macho parser for use by C inject_hash (#1435) Adds a macho file parser and tests in anticipation of usage in an upcoming C language replacement for `inject_hash.go` --- CMakeLists.txt | 11 + util/fipstools/CMakeLists.txt | 2 + .../inject_hash/macho_parser/common.h | 17 ++ .../inject_hash/macho_parser/macho_parser.c | 219 ++++++++++++++ .../inject_hash/macho_parser/macho_parser.h | 45 +++ .../macho_parser/tests/CMakeLists.txt | 15 + .../macho_parser/tests/macho_tests.cc | 66 +++++ .../macho_parser/tests/macho_tests.h | 278 ++++++++++++++++++ 8 files changed, 653 insertions(+) create mode 100644 util/fipstools/inject_hash/macho_parser/common.h create mode 100644 util/fipstools/inject_hash/macho_parser/macho_parser.c create mode 100644 util/fipstools/inject_hash/macho_parser/macho_parser.h create mode 100644 util/fipstools/inject_hash/macho_parser/tests/CMakeLists.txt create mode 100644 util/fipstools/inject_hash/macho_parser/tests/macho_tests.cc create mode 100644 util/fipstools/inject_hash/macho_parser/tests/macho_tests.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5d5e868527..eed22f14e3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1027,6 +1027,17 @@ if(BUILD_TESTING) add_custom_target(fips_specific_tests_if_any) endif() + # Add macho parser tests if FIPS and on MacOS + if(FIPS AND APPLE) + add_custom_target( + macho_parser_tests + COMMAND ./util/fipstools/inject_hash/macho_parser/tests/test_macho_parser + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS test_macho_parser + ) + add_dependencies(fips_specific_tests_if_any macho_parser_tests) + endif() + # Read util/go_tests.txt into a CMake variable. file(READ util/go_tests.txt GO_TESTS) foreach(fips_specific_test ${GO_FIPS_TESTS}) diff --git a/util/fipstools/CMakeLists.txt b/util/fipstools/CMakeLists.txt index 79b7f044a7..6a0d83efba 100644 --- a/util/fipstools/CMakeLists.txt +++ b/util/fipstools/CMakeLists.txt @@ -6,4 +6,6 @@ if(FIPS AND BUILD_TESTING) ) target_link_libraries(test_fips crypto) target_include_directories(test_fips BEFORE PRIVATE ${PROJECT_BINARY_DIR}/symbol_prefix_include) + + add_subdirectory(inject_hash/macho_parser/tests) endif() diff --git a/util/fipstools/inject_hash/macho_parser/common.h b/util/fipstools/inject_hash/macho_parser/common.h new file mode 100644 index 0000000000..d1d81fbaaa --- /dev/null +++ b/util/fipstools/inject_hash/macho_parser/common.h @@ -0,0 +1,17 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include + +#define LOG_ERROR(...) do { \ + fprintf(stderr, "File: %s, Line: %d, ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ +} while(0) + +#endif diff --git a/util/fipstools/inject_hash/macho_parser/macho_parser.c b/util/fipstools/inject_hash/macho_parser/macho_parser.c new file mode 100644 index 0000000000..b24c343403 --- /dev/null +++ b/util/fipstools/inject_hash/macho_parser/macho_parser.c @@ -0,0 +1,219 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include + +#include "common.h" +#include "macho_parser.h" + +#define TEXT_INDEX 0 +#define CONST_INDEX 1 +#define SYMTABLE_INDEX 2 +#define STRTABLE_INDEX 3 + +// Documentation for the Mach-O structs can be found in macho-o/loader.h and mach-o/nlist.h +int read_macho_file(const char *filename, machofile *macho) { + FILE *file = NULL; + struct load_command *load_commands = NULL; + uint32_t bytes_read; + int ret = 0; + + file = fopen(filename, "rb"); + if (file == NULL) { + LOG_ERROR("Error opening file %s", filename); + goto end; + } + + bytes_read = fread(&macho->macho_header, 1, sizeof(struct mach_header_64), file); + if (bytes_read != sizeof(struct mach_header_64)) { + LOG_ERROR("Error reading macho_header from file %s", filename); + goto end; + } + if (macho->macho_header.magic != MH_MAGIC_64) { + LOG_ERROR("File is not a 64-bit Mach-O file"); + goto end; + } + + load_commands = malloc(macho->macho_header.sizeofcmds); + if (load_commands == NULL) { + LOG_ERROR("Error allocating memory for load_commands"); + goto end; + } + bytes_read = fread(load_commands, 1, macho->macho_header.sizeofcmds, file); + if (bytes_read != macho->macho_header.sizeofcmds) { + LOG_ERROR("Error reading load commands from file %s", filename); + goto end; + } + + // We're only looking for __text, __const in the __TEXT segment, and the string & symbol tables + macho->num_sections = 4; + macho->sections = malloc(macho->num_sections * sizeof(section_info)); + if (macho->sections == NULL) { + LOG_ERROR("Error allocating memory for macho sections"); + } + + int text_found = 0; + int const_found = 0; + int symtab_found = 0; + + // mach-o/loader.h explains that cmdsize (and by extension sizeofcmds) must be a multiple of 8 on 64-bit systems. struct load_command will always be 8 bytes. + for (size_t i = 0; i < macho->macho_header.sizeofcmds / sizeof(struct load_command); i += load_commands[i].cmdsize / sizeof(struct load_command)) { + if (load_commands[i].cmd == LC_SEGMENT_64) { + struct segment_command_64 *segment = (struct segment_command_64 *)&load_commands[i]; + if (strcmp(segment->segname, "__TEXT") == 0) { + struct section_64 *sections = (struct section_64 *)&segment[1]; + for (size_t j = 0; j < segment->nsects; j++) { + if (strcmp(sections[j].sectname, "__text") == 0) { + if (text_found == 1) { + LOG_ERROR("Duplicate __text section found"); + goto end; + } + macho->sections[TEXT_INDEX].offset = sections[j].offset; + macho->sections[TEXT_INDEX].size = sections[j].size; + strcpy(macho->sections[TEXT_INDEX].name, sections[j].sectname); + text_found = 1; + } else if (strcmp(sections[j].sectname, "__const") == 0) { + if (const_found == 1) { + LOG_ERROR("Duplicate __const section found"); + goto end; + } + macho->sections[CONST_INDEX].offset = sections[j].offset; + macho->sections[CONST_INDEX].size = sections[j].size; + strcpy(macho->sections[CONST_INDEX].name, sections[j].sectname); + const_found = 1; + } + } + } + } else if (load_commands[i].cmd == LC_SYMTAB) { + if (symtab_found == 1) { + LOG_ERROR("Duplicate symbol and string tables found"); + goto end; + } + struct symtab_command *symtab = (struct symtab_command *)&load_commands[i]; + macho->sections[SYMTABLE_INDEX].offset = symtab->symoff; + macho->sections[SYMTABLE_INDEX].size = symtab->nsyms * sizeof(struct nlist_64); + strcpy(macho->sections[SYMTABLE_INDEX].name, "__symbol_table"); + macho->sections[STRTABLE_INDEX].offset = symtab->stroff; + macho->sections[STRTABLE_INDEX].size = symtab->strsize; + strcpy(macho->sections[STRTABLE_INDEX].name, "__string_table"); + symtab_found = 1; + } + } + + ret = 1; +end: + free(load_commands); + if (file != NULL) { + fclose(file); + } + return ret; +} + +void free_macho_file(machofile *macho) { + free(macho->sections); + free(macho); + macho = NULL; +} + +uint8_t* get_macho_section_data(const char *filename, machofile *macho, const char *section_name, size_t *size, uint32_t *offset) { + FILE *file = NULL; + uint8_t *ret = NULL; + uint32_t bytes_read; + + file = fopen(filename, "rb"); + if (file == NULL) { + LOG_ERROR("Error opening file %s", filename); + goto end; + } + + int section_index; + if (strcmp(section_name, "__text") == 0) { + section_index = TEXT_INDEX; + } else if (strcmp(section_name, "__const") == 0) { + section_index = CONST_INDEX; + } else if (strcmp(section_name, "__symbol_table") == 0) { + section_index = SYMTABLE_INDEX; + } else if (strcmp(section_name, "__string_table") == 0) { + section_index = STRTABLE_INDEX; + } else { + LOG_ERROR("Getting invalid macho section data %s", section_name); + goto end; + } + + uint8_t *section_data = malloc(macho->sections[section_index].size); + if (section_data == NULL) { + LOG_ERROR("Error allocating memory for section data"); + goto end; + } + + if (fseek(file, macho->sections[section_index].offset, SEEK_SET) != 0) { + free(section_data); + LOG_ERROR("Failed to seek in file %s", filename); + goto end; + } + bytes_read = fread(section_data, 1, macho->sections[section_index].size, file); + if (bytes_read != macho->sections[section_index].size) { + free(section_data); + LOG_ERROR("Error reading section data from file %s", filename); + goto end; + } + + if (size != NULL) { + *size = macho->sections[section_index].size; + } + if (offset != NULL) { + *offset = macho->sections[section_index].offset; + } + + ret = section_data; + +end: + if (file != NULL) { + fclose(file); + } + return ret; +} + +uint32_t find_macho_symbol_index(uint8_t *symbol_table_data, size_t symbol_table_size, uint8_t *string_table_data, size_t string_table_size, const char *symbol_name, uint32_t *base) { + char* string_table = NULL; + uint32_t ret = 0; + + if (symbol_table_data == NULL || string_table_data == NULL) { + LOG_ERROR("Symbol and string table pointers cannot be null to find the symbol index"); + goto end; + } + + string_table = malloc(string_table_size); + if (string_table == NULL) { + LOG_ERROR("Error allocating memory for string table"); + goto end; + } + memcpy(string_table, string_table_data, string_table_size); + + int found = 0; + size_t index = 0; + for (size_t i = 0; i < symbol_table_size / sizeof(struct nlist_64); i++) { + struct nlist_64 *symbol = (struct nlist_64 *)(symbol_table_data + i * sizeof(struct nlist_64)); + if (strcmp(symbol_name, &string_table[symbol->n_un.n_strx]) == 0) { + if (found == 0) { + index = symbol->n_value; + found = 1; + } else { + LOG_ERROR("Duplicate symbol %s found", symbol_name); + goto end; + } + } + } + if (found == 0) { + LOG_ERROR("Requested symbol %s not found", symbol_name); + goto end; + } + if (base != NULL) { + index = index - *base; + } + ret = index; + +end: + free(string_table); + return ret; +} diff --git a/util/fipstools/inject_hash/macho_parser/macho_parser.h b/util/fipstools/inject_hash/macho_parser/macho_parser.h new file mode 100644 index 0000000000..a11463fc87 --- /dev/null +++ b/util/fipstools/inject_hash/macho_parser/macho_parser.h @@ -0,0 +1,45 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#ifndef MACHO_PARSER_H +#define MACHO_PARSER_H +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include + +typedef struct { + char name[16]; + size_t size; + uint32_t offset; +} section_info; + +typedef struct { + struct mach_header_64 macho_header; + section_info *sections; + uint32_t num_sections; +} machofile; + +// read_macho_file reads a Mach-O file [in] and populates a machofile struct [out] with its contents. +// It returns 0 on failure, 1 on success. +int read_macho_file(const char *filename, machofile *macho); + +// free_macho_file frees the memory allocated to a machofile struct [in] +void free_macho_file(machofile *macho); + +// get_macho_section_data retrieves data from a specific section [in] the provided Mach-O file [in]. +// In addition to returning a pointer to the retrieved data, or NULL if it doesn't find said section, +// it also populates the size [out] & offset [out] pointers provided they are not NULL. +uint8_t* get_macho_section_data(const char* filename, machofile *macho, const char *section_name, size_t *size, uint32_t *offset); + +// find_macho_symbol_index finds the index of a symbol [in] in the Mach-O file's [in] symbol table. +// It returns the index on success, and 0 on failure. +uint32_t find_macho_symbol_index(uint8_t *symbol_table_data, size_t symbol_table_size, uint8_t *string_table_data, size_t string_table_size, const char *symbol_name, uint32_t *base); + +#ifdef __cplusplus +} // extern "C" +#endif +#endif diff --git a/util/fipstools/inject_hash/macho_parser/tests/CMakeLists.txt b/util/fipstools/inject_hash/macho_parser/tests/CMakeLists.txt new file mode 100644 index 0000000000..59ffa32a58 --- /dev/null +++ b/util/fipstools/inject_hash/macho_parser/tests/CMakeLists.txt @@ -0,0 +1,15 @@ +if(FIPS AND APPLE) + add_executable( + test_macho_parser + + macho_tests.cc + ../macho_parser.c + ) + + target_link_libraries( + test_macho_parser + + test_support_lib + boringssl_gtest_main + ) +endif() diff --git a/util/fipstools/inject_hash/macho_parser/tests/macho_tests.cc b/util/fipstools/inject_hash/macho_parser/tests/macho_tests.cc new file mode 100644 index 0000000000..38c921ba12 --- /dev/null +++ b/util/fipstools/inject_hash/macho_parser/tests/macho_tests.cc @@ -0,0 +1,66 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include + +#include "../common.h" +#include "macho_tests.h" + +#define TEST_FILE "test_macho" + +machofile *MachoTestFixture::expected_macho; +struct nlist_64 *MachoTestFixture::expected_symtab; +uint32_t MachoTestFixture::expected_symbol1_ind; +uint32_t MachoTestFixture::expected_symbol2_ind; + +constexpr char MachoTestFixture::expected_strtab[EXPECTED_STRTAB_SIZE]; +constexpr int MachoTestFixture::text_data[TEXT_DATA_SIZE]; +constexpr char MachoTestFixture::const_data[CONST_DATA_SIZE]; + +TEST_F(MachoTestFixture, TestReadMachoFile) { + machofile test_macho_file; + if (!read_macho_file(TEST_FILE, &test_macho_file)) { + LOG_ERROR("Failed to read macho_file"); + } + + EXPECT_TRUE(memcmp(&test_macho_file.macho_header, &expected_macho->macho_header, sizeof(struct mach_header_64)) == 0); + EXPECT_EQ(test_macho_file.num_sections, expected_macho->num_sections); + EXPECT_TRUE(memcmp(test_macho_file.sections, expected_macho->sections, test_macho_file.num_sections * sizeof(section_info)) == 0); +} + +TEST_F(MachoTestFixture, TestGetMachoSectionData) { + std::unique_ptr text_section(nullptr); + std::unique_ptr const_section(nullptr); + std::unique_ptr symbol_table(nullptr); + std::unique_ptr string_table(nullptr); + + size_t text_section_size; + size_t const_section_size; + size_t symbol_table_size; + size_t string_table_size; + + text_section.reset(get_macho_section_data(TEST_FILE, expected_macho, "__text", &text_section_size, NULL)); + const_section.reset(get_macho_section_data(TEST_FILE, expected_macho, "__const", &const_section_size, NULL)); + symbol_table.reset(get_macho_section_data(TEST_FILE, expected_macho, "__symbol_table", &symbol_table_size, NULL)); + string_table.reset(get_macho_section_data(TEST_FILE, expected_macho, "__string_table", &string_table_size, NULL)); + + ASSERT_TRUE(memcmp(text_section.get(), text_data, text_section_size) == 0); + ASSERT_TRUE(memcmp(const_section.get(), const_data, const_section_size) == 0); + ASSERT_TRUE(memcmp(symbol_table.get(), expected_symtab, symbol_table_size) == 0); + ASSERT_TRUE(memcmp(string_table.get(), expected_strtab, string_table_size) == 0); +} + +TEST_F(MachoTestFixture, TestFindMachoSymbolIndex) { + std::unique_ptr symbol_table(nullptr); + std::unique_ptr string_table(nullptr); + + size_t symbol_table_size; + size_t string_table_size; + + symbol_table.reset(get_macho_section_data(TEST_FILE, expected_macho, "__symbol_table", &symbol_table_size, NULL)); + string_table.reset(get_macho_section_data(TEST_FILE, expected_macho, "__string_table", &string_table_size, NULL)); + + uint32_t symbol1_index = find_macho_symbol_index(symbol_table.get(), symbol_table_size, string_table.get(), string_table_size, "symbol1", NULL); + + ASSERT_EQ(symbol1_index, expected_symbol1_ind); +} diff --git a/util/fipstools/inject_hash/macho_parser/tests/macho_tests.h b/util/fipstools/inject_hash/macho_parser/tests/macho_tests.h new file mode 100644 index 0000000000..33783f60a5 --- /dev/null +++ b/util/fipstools/inject_hash/macho_parser/tests/macho_tests.h @@ -0,0 +1,278 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC + +#include + +#include "../macho_parser.h" + +#define TEST_FILE "test_macho" +#define EXPECTED_STRTAB_SIZE 32 +#define TEXT_DATA_SIZE 1 +#define CONST_DATA_SIZE 3 +#define NUM_SYMS 2 + +class MachoTestFixture : public ::testing::Test { +protected: + static machofile *expected_macho; + static struct nlist_64 *expected_symtab; + static constexpr char expected_strtab[] = "__text\0__const\0symbol1\0symbol2\0"; + static constexpr int text_data[] = { 0xC3 }; + static constexpr char const_data[] = "hi"; + static uint32_t expected_symbol1_ind; + static uint32_t expected_symbol2_ind; + + static uint32_t FindSymbolIndex(const char *strtab, const char *symbol_name) { + const char *symbol = strtab; + uint32_t index = 0; + + while (*symbol != '\0') { + if (strcmp(symbol, symbol_name) == 0) { + return index; + } + + index += strlen(symbol) + 1; + symbol += strlen(symbol) + 1; + } + + return UINT32_MAX; + } + + static void SetUpTestSuite() { + bool fail = true; + section_info *expected_text_section = NULL; + section_info *expected_const_section = NULL; + section_info *expected_symbol_table = NULL; + section_info *expected_string_table = NULL; + section_info *expected_sections = NULL; + + struct nlist_64 symbol1; + struct nlist_64 symbol2; + + static FILE *file = fopen(TEST_FILE, "wb"); + if (file == NULL) { + LOG_ERROR("Error with fopen() on %s file", TEST_FILE); + } + + uint32_t header_sizeofcmds = sizeof(struct segment_command_64) + 2 * sizeof(struct section_64) + sizeof(struct symtab_command); + uint32_t header_ncmds = 2; + struct mach_header_64 test_header = { + .magic = MH_MAGIC_64, + .ncmds = header_ncmds, + .sizeofcmds = header_sizeofcmds, + }; + + uint32_t text_segment_cmdsize = sizeof(struct segment_command_64) + 2 * sizeof(struct section_64); + uint32_t text_segment_nsects = 2; + struct segment_command_64 test_text_segment = { + .cmd = LC_SEGMENT_64, + .cmdsize = text_segment_cmdsize, + .segname = "__TEXT", + .nsects = text_segment_nsects, + }; + + uint32_t text_section_offset = sizeof(struct mach_header_64) + sizeof(struct segment_command_64) + 2 * sizeof(struct section_64) + sizeof(struct symtab_command); + uint64_t text_section_size = TEXT_DATA_SIZE; // {0xC3} + struct section_64 test_text_section = { + .sectname = "__text", + .size = text_section_size, + .offset = text_section_offset, + }; + + uint32_t const_section_offset = text_section_offset + text_section_size; + uint64_t const_section_size = CONST_DATA_SIZE; // "hi" + struct section_64 test_const_section = { + .sectname = "__const", + .size = const_section_size, + .offset = const_section_offset, + }; + + uint32_t symtab_command_symoff = const_section_offset + const_section_size; + uint32_t symtab_command_stroff = symtab_command_symoff + NUM_SYMS * sizeof(struct nlist_64); + uint32_t symtab_command_strsize = 32; + struct symtab_command test_symtab_command = { + .cmd = LC_SYMTAB, + .cmdsize = sizeof(struct symtab_command), + .symoff = symtab_command_symoff, + .nsyms = NUM_SYMS, + .stroff = symtab_command_stroff, + .strsize = symtab_command_strsize, + }; + + if (fwrite(&test_header, sizeof(struct mach_header_64), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + if (fwrite(&test_text_segment, sizeof(struct segment_command_64), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + if (fwrite(&test_text_section, sizeof(struct section_64), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + if (fwrite(&test_const_section, sizeof(struct section_64), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + if (fwrite(&test_symtab_command, sizeof(struct symtab_command), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + + if (fseek(file, test_text_section.offset, SEEK_SET) != 0) { + LOG_ERROR("Failed to seek in file %s", TEST_FILE); + goto end; + } + if (fwrite(text_data, sizeof(text_data), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + + if (fseek(file, test_const_section.offset, SEEK_SET) != 0) { + LOG_ERROR("Failed to seek in file %s", TEST_FILE); + goto end; + } + if (fwrite(const_data, sizeof(const_data), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + + expected_symbol1_ind = FindSymbolIndex(expected_strtab, "symbol1"); + if (expected_symbol1_ind == UINT32_MAX) { + LOG_ERROR("symbol1 not found in expected string table"); + goto end; + } + symbol1 = { + .n_un = {.n_strx = expected_symbol1_ind}, + .n_type = 0, + .n_sect = 1, + .n_desc = 0, + .n_value = expected_symbol1_ind, + }; + + expected_symbol2_ind = FindSymbolIndex(expected_strtab, "symbol2"); + if (expected_symbol2_ind == UINT32_MAX) { + LOG_ERROR("symbol2 not found in expected string table"); + goto end; + } + symbol2 = { + .n_un = {.n_strx = expected_symbol2_ind}, + .n_type = 0, + .n_sect = 2, + .n_desc = 0, + .n_value = expected_symbol2_ind, + }; + + if (fseek(file, symtab_command_symoff, SEEK_SET) != 0) { + LOG_ERROR("Failed to seek in file %s", TEST_FILE); + goto end; + } + if (fwrite(&symbol1, sizeof(struct nlist_64), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + if (fwrite(&symbol2, sizeof(struct nlist_64), 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + + if (fseek(file, symtab_command_stroff, SEEK_SET) != 0) { + LOG_ERROR("Failed to seek in file %s", TEST_FILE); + goto end; + } + if (fwrite(expected_strtab, symtab_command_strsize, 1, file) != 1) { + LOG_ERROR("Error occurred while writing to file %s", TEST_FILE); + goto end; + } + + if (fclose(file) != 0) { + LOG_ERROR("Error closing file\n"); + goto end; + } + + // We use calloc for the below four calls to ensure that the untouched parts are zeroized, + // as we will later memcmp the data to what we've read from the file. + expected_text_section = (section_info*) calloc(1, sizeof(section_info)); + if (expected_text_section == NULL) { + LOG_ERROR(" Error allocating memory for expected text section"); + goto end; + } + strcpy(expected_text_section->name, "__text"); + expected_text_section->size = text_section_size; + expected_text_section->offset = text_section_offset; + + expected_const_section = (section_info*) calloc(1, sizeof(section_info)); + if (expected_const_section == NULL) { + LOG_ERROR(" Error allocating memory for expected const section"); + goto end; + } + strcpy(expected_const_section->name, "__const"); + expected_const_section->size = const_section_size; + expected_const_section->offset = const_section_offset; + + expected_symbol_table = (section_info*) calloc(1, sizeof(section_info)); + if (expected_symbol_table == NULL) { + LOG_ERROR(" Error allocating memory for expected symbol table"); + goto end; + } + strcpy(expected_symbol_table->name, "__symbol_table"); + expected_symbol_table->size = NUM_SYMS * sizeof(struct nlist_64); + expected_symbol_table->offset = symtab_command_symoff; + + expected_string_table = (section_info*) calloc(1, sizeof(section_info)); + if (expected_string_table == NULL) { + LOG_ERROR(" Error allocating memory for expected string table"); + goto end; + } + strcpy(expected_string_table->name, "__string_table"); + expected_string_table->size = symtab_command_strsize; + expected_string_table->offset = symtab_command_stroff; + + expected_sections = (section_info*) malloc(sizeof(section_info) * 4); + if (expected_sections == NULL) { + LOG_ERROR("Error allocating memory for expected sections"); + goto end; + } + memcpy(&expected_sections[0], expected_text_section, sizeof(section_info)); + memcpy(&expected_sections[1], expected_const_section, sizeof(section_info)); + memcpy(&expected_sections[2], expected_symbol_table, sizeof(section_info)); + memcpy(&expected_sections[3], expected_string_table, sizeof(section_info)); + + expected_macho = (machofile*) malloc(sizeof(machofile)); + if (expected_macho == NULL) { + LOG_ERROR("Error allocating memory for expected macho file struct"); + goto end; + } + expected_macho->macho_header = test_header; + expected_macho->num_sections = 4; + expected_macho->sections = expected_sections; + + expected_symtab = (struct nlist_64*) malloc(NUM_SYMS * sizeof(struct nlist_64)); + if (expected_symtab == NULL) { + LOG_ERROR("Error allocating memory for expected symbol table struct"); + goto end; + } + expected_symtab[0] = symbol1; + expected_symtab[1] = symbol2; + + fail = false; +end: + if (fail) { + free(expected_sections); + free(expected_macho); + free(expected_symtab); + } + free(expected_text_section); + free(expected_const_section); + free(expected_symbol_table); + free(expected_string_table); + } + + static void TearDownTestSuite() { + free_macho_file(expected_macho); + free(expected_symtab); + if (remove(TEST_FILE) != 0) { + LOG_ERROR("Error deleting %s", TEST_FILE); + } + } +}; From b3472ef16fe272ed9b331a466ff67432e1a1b3a9 Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Mon, 15 Apr 2024 14:25:55 -0700 Subject: [PATCH 23/25] Add non-fips/fips ci for gcc-10 on ubuntu (#1525) This change adds a new CI dimension for gcc-10 with non-fips/fips on ubuntu. --- .../github_ci_linux_x86_omnibus.yaml | 20 +++++++++++++++++++ .../docker_images/linux-x86/build_images.sh | 1 + .../ci/docker_images/linux-x86/push_images.sh | 1 + .../linux-x86/ubuntu-22.04_gcc-10x/Dockerfile | 20 +++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-10x/Dockerfile diff --git a/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml b/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml index 918ed91309..2aaddf0fc5 100644 --- a/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml +++ b/tests/ci/cdk/cdk/codebuild/github_ci_linux_x86_omnibus.yaml @@ -125,6 +125,26 @@ batch: variables: AWS_LC_CI_TARGET: "tests/ci/run_tests_with_sde_asan.sh" + - identifier: ubuntu2204_gcc10x_x86_64 + buildspec: ./tests/ci/codebuild/common/run_simple_target.yml + env: + type: LINUX_CONTAINER + privileged-mode: true + compute-type: BUILD_GENERAL1_LARGE + image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-x86:ubuntu-22.04_gcc-10x_latest + variables: + AWS_LC_CI_TARGET: "tests/ci/run_posix_tests.sh" + + - identifier: ubuntu2204_gcc10x_x86_64_fips + buildspec: ./tests/ci/codebuild/common/run_simple_target.yml + env: + type: LINUX_CONTAINER + privileged-mode: true + compute-type: BUILD_GENERAL1_LARGE + image: 620771051181.dkr.ecr.us-west-2.amazonaws.com/aws-lc-docker-images-linux-x86:ubuntu-22.04_gcc-10x_latest + variables: + AWS_LC_CI_TARGET: "tests/ci/run_fips_tests.sh" + - identifier: ubuntu2204_gcc11x_x86_64 buildspec: ./tests/ci/codebuild/common/run_simple_target.yml env: diff --git a/tests/ci/docker_images/linux-x86/build_images.sh b/tests/ci/docker_images/linux-x86/build_images.sh index ff845b856d..9c72313f17 100755 --- a/tests/ci/docker_images/linux-x86/build_images.sh +++ b/tests/ci/docker_images/linux-x86/build_images.sh @@ -26,6 +26,7 @@ docker build -t ubuntu-20.04:android -f ubuntu-20.04_android/Dockerfile ../ docker build -t ubuntu-20.04:clang-7x-bm-framework ubuntu-20.04_clang-7x-bm-framework docker build -t ubuntu-22.04:base -f ubuntu-22.04_base/Dockerfile ../dependencies docker build -t ubuntu-22.04:clang-14x-sde ubuntu-22.04_clang-14x-sde +docker build -t ubuntu-22.04:gcc-10x ubuntu-22.04_gcc-10x docker build -t ubuntu-22.04:gcc-11x ubuntu-22.04_gcc-11x docker build -t ubuntu-22.04:gcc-12x ubuntu-22.04_gcc-12x docker build -t amazonlinux-2:base -f amazonlinux-2_base/Dockerfile ../dependencies diff --git a/tests/ci/docker_images/linux-x86/push_images.sh b/tests/ci/docker_images/linux-x86/push_images.sh index dd97e66f82..53a68be89d 100755 --- a/tests/ci/docker_images/linux-x86/push_images.sh +++ b/tests/ci/docker_images/linux-x86/push_images.sh @@ -29,6 +29,7 @@ tag_and_push_img 'ubuntu-20.04:clang-10x_formal-verification-saw-aarch64' "${ECS tag_and_push_img 'ubuntu-20.04:gcc-7x' "${ECS_REPO}:ubuntu-20.04_gcc-7x" tag_and_push_img 'ubuntu-20.04:gcc-8x' "${ECS_REPO}:ubuntu-20.04_gcc-8x" tag_and_push_img 'ubuntu-22.04:clang-14x-sde' "${ECS_REPO}:ubuntu-22.04_clang-14x-sde" +tag_and_push_img 'ubuntu-22.04:gcc-10x' "${ECS_REPO}:ubuntu-22.04_gcc-10x" tag_and_push_img 'ubuntu-22.04:gcc-11x' "${ECS_REPO}:ubuntu-22.04_gcc-11x" tag_and_push_img 'ubuntu-22.04:gcc-12x' "${ECS_REPO}:ubuntu-22.04_gcc-12x" tag_and_push_img 'ubuntu-22.04:clang-14x_formal-verification-nsym-aarch64' "${ECS_REPO}:ubuntu-22.04_clang-14x_formal-verification-nsym-aarch64" diff --git a/tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-10x/Dockerfile b/tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-10x/Dockerfile new file mode 100644 index 0000000000..341b783983 --- /dev/null +++ b/tests/ci/docker_images/linux-x86/ubuntu-22.04_gcc-10x/Dockerfile @@ -0,0 +1,20 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 OR ISC + +FROM ubuntu-22.04:base + +SHELL ["/bin/bash", "-c"] + +RUN set -ex && \ + apt-get update && \ + apt-get -y --no-install-recommends upgrade && \ + apt-get -y --no-install-recommends install \ + gcc-10 g++-10 && \ + apt-get autoremove --purge -y && \ + apt-get clean && \ + apt-get autoclean && \ + rm -rf /var/lib/apt/lists/* && \ + rm -rf /tmp/* + +ENV CC=gcc-10 +ENV CXX=g++-10 From 4566f1d1cb665018042827ff5303532194098f9e Mon Sep 17 00:00:00 2001 From: Samuel Chiang Date: Mon, 15 Apr 2024 14:31:24 -0700 Subject: [PATCH 24/25] Bump mysql integration CI to 8.3 (#1508) MySQL 8.2/8.3 changed some of the build behavior with OpenSSL. According to the documentation, `-DWITH_SSL={path_name}` is a viable option, but it only seems to work with Visual Studio and MacOS due to the usage of `${CMAKE_CFG_INTDIR}`. `${CMAKE_CFG_INTDIR}` is undefined on single build configs like regular Make and Ninja, so our build fails when using the option. Another option was documented in mysql: > Another permitted way to do the same thing is to set WITH_SSL to system and set the CMAKE_PREFIX_PATH option to path_name.) Using this gets around our CI build issues with mysql 8.3. --- tests/ci/integration/run_mysql_integration.sh | 46 +++++++++++-------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/tests/ci/integration/run_mysql_integration.sh b/tests/ci/integration/run_mysql_integration.sh index 9256a31d96..41e6e6fd9e 100755 --- a/tests/ci/integration/run_mysql_integration.sh +++ b/tests/ci/integration/run_mysql_integration.sh @@ -4,7 +4,7 @@ source tests/ci/common_posix_setup.sh -MYSQL_VERSION_TAG="mysql-8.1.0" +MYSQL_VERSION_TAG="mysql-8.3.0" # This directory is specific to the docker image used. Use -DDOWNLOAD_BOOST=1 -DWITH_BOOST= # with mySQL to download a compatible boost version locally. BOOST_INSTALL_FOLDER=/home/dependencies/boost @@ -36,7 +36,8 @@ rm -rf "${SCRATCH_FOLDER:?}"/* cd ${SCRATCH_FOLDER} function mysql_patch_reminder() { - LATEST_MYSQL_VERSION_TAG=mysql-`curl https://api.github.com/repos/mysql/mysql-server/tags | jq '.[].name' |grep '\-8.0' |sed -e 's/"mysql-cluster-\(.*\)"/\1/' |sort | tail -n 1` + # Check latest MySQL version. MySQL often updates with large changes depending on OpenSSL all at once, so we pin to a specific version. + LATEST_MYSQL_VERSION_TAG=`git describe --tags --abbrev=0` if [[ "${LATEST_MYSQL_VERSION_TAG}" != "${MYSQL_VERSION_TAG}" ]]; then aws cloudwatch put-metric-data --namespace AWS-LC --metric-name MySQLVersionMismatch --value 1 else @@ -45,7 +46,7 @@ function mysql_patch_reminder() { } function mysql_build() { - cmake ${MYSQL_SRC_FOLDER} -GNinja -DWITH_BOOST=${BOOST_INSTALL_FOLDER} -DWITH_SSL=${AWS_LC_INSTALL_FOLDER} "-B${MYSQL_BUILD_FOLDER}" -DCMAKE_BUILD_TYPE=RelWithDebInfo + cmake ${MYSQL_SRC_FOLDER} -GNinja -DWITH_SSL=system -DCMAKE_PREFIX_PATH=${AWS_LC_INSTALL_FOLDER} "-B${MYSQL_BUILD_FOLDER}" -DCMAKE_BUILD_TYPE=RelWithDebInfo time ninja -C ${MYSQL_BUILD_FOLDER} ls -R ${MYSQL_BUILD_FOLDER} } @@ -56,9 +57,8 @@ function mysql_run_tests() { # # Tests marked with Bug#0000 are tests that have are known to fail in containerized environments. These tests aren't exactly relevant # to testing AWS-LC functionality. - # Tests marked with Bug#0001 use DHE cipher suites for the connection. AWS-LC has no intention of supporting DHE cipher suites. - # Tests marked with Bug#0002 use stateful session resumption, otherwise known as session caching. It is known that AWS-LC does not - # currently support this. + # Tests marked with Bug#0001 use stateful session resumption, otherwise known as session caching. It is known that AWS-LC does not + # currently support this with TLS 1.3. echo "main.mysqlpump_bugs : Bug#0000 Can't create/open a file ~/dump.sql' main.restart_server : Bug#0000 mysqld is not managed by supervisor process main.udf_bug35242734 : Bug#0000 mysqld is not managed by supervisor process @@ -77,16 +77,9 @@ main.persisted_variables_bugs_fast : Bug#0000 Unsure main.mysqldump : Bug#0000 contains nonaggregated column main.func_math : Bug#0000 should have failed with errno 1690 main.derived_condition_pushdown : Bug#0000 Fails with OpenSSL as well. Not relevant to AWS-LC. -main.grant_alter_user_qa : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.grant_user_lock_qa : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.openssl_1 : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.ssl : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.ssl_cipher : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.ssl_dynamic : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.ssl-sha512 : Bug#0001 Uses DHE cipher suites in test, which AWS-LC does not support. -main.client_ssl_data_print : Bug#0002 AWS-LC does not support Stateful session resumption (Session Caching). -main.ssl_cache : Bug#0002 AWS-LC does not support Stateful session resumption (Session Caching). -main.ssl_cache_tls13 : Bug#0002 AWS-LC does not support Stateful session resumption (Session Caching). +main.client_ssl_data_print : Bug#0001 AWS-LC does not support Stateful session resumption (Session Caching). +main.ssl_cache : Bug#0001 AWS-LC does not support Stateful session resumption (Session Caching). +main.ssl_cache_tls13 : Bug#0001 AWS-LC does not support Stateful session resumption (Session Caching). "> skiplist ./mtr --suite=main --force --parallel=auto --skip-test-list=${MYSQL_BUILD_FOLDER}/mysql-test/skiplist --retry-failure=3 --retry=3 --report-unstable-tests popd @@ -118,16 +111,29 @@ function mysql_patch_tests() { done } -# Get latest MySQL version. MySQL often updates with large changes depending on OpenSSL all at once, so we pin to a specific version. -mysql_patch_reminder -git clone https://github.com/mysql/mysql-server.git ${MYSQL_SRC_FOLDER} -b ${MYSQL_VERSION_TAG} --depth 1 +git clone https://github.com/mysql/mysql-server.git ${MYSQL_SRC_FOLDER} --depth 1 --no-single-branch mkdir -p ${AWS_LC_BUILD_FOLDER} ${AWS_LC_INSTALL_FOLDER} ${MYSQL_BUILD_FOLDER} ls -aws_lc_build "$SRC_ROOT" "$AWS_LC_BUILD_FOLDER" "$AWS_LC_INSTALL_FOLDER" -DBUILD_TESTING=OFF -DBUILD_TOOL=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=0 +aws_lc_build "$SRC_ROOT" "$AWS_LC_BUILD_FOLDER" "$AWS_LC_INSTALL_FOLDER" -DBUILD_TESTING=OFF -DBUILD_TOOL=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=1 + pushd ${MYSQL_SRC_FOLDER} + +mysql_patch_reminder +git checkout ${MYSQL_VERSION_TAG} + mysql_patch_tests mysql_patch_error_strings + mysql_build mysql_run_tests popd + +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlclient.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlclient.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libssl.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlharness_tls.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlharness_tls.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libssl.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlrouter_routing.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlrouter_routing.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libssl.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlrouter_http.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libcrypto.so" || exit 1 +ldd "${MYSQL_BUILD_FOLDER}/lib/libmysqlrouter_http.so" | grep "${AWS_LC_INSTALL_FOLDER}/lib/libssl.so" || exit 1 From 86ae10bb1e6d6783dba3969addee525fbf2af3fc Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Mon, 15 Apr 2024 18:55:34 -0400 Subject: [PATCH 25/25] Remove guard for big-endian support (#1531) --- CMakeLists.txt | 7 ------- tests/ci/run_cross_tests.sh | 1 - tests/docker_images/linux-ppc/ubuntu-x-tools/ppc.cmake | 1 - tests/docker_images/linux-ppc64/ubuntu-x-tools/ppc64.cmake | 1 - tests/docker_images/linux-s390x/ubuntu-x-tools/s390x.cmake | 1 - 5 files changed, 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eed22f14e3..b3ec8ac10a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -722,13 +722,6 @@ if(MALLOC_FAILURE_TESTING) endif() TEST_BIG_ENDIAN(BIG_ENDIAN) -if(BIG_ENDIAN) - if(ENABLE_EXPERIMENTAL_BIG_ENDIAN_SUPPORT) - message(STATUS "Continuing with experimental support on big endian platform") - else() - message(FATAL_ERROR "Big Endian is not supported.") - endif() -endif() if(OPENSSL_NO_SSE2_FOR_TESTING) add_definitions(-DOPENSSL_NO_SSE2_FOR_TESTING) diff --git a/tests/ci/run_cross_tests.sh b/tests/ci/run_cross_tests.sh index 99066f3fed..648c6df57a 100755 --- a/tests/ci/run_cross_tests.sh +++ b/tests/ci/run_cross_tests.sh @@ -47,7 +47,6 @@ set(CMAKE_CXX_COMPILER ${SCRATCH_FOLDER}/${TARGET_PLATFORM}/bin/${TARGET_PLATFOR set(CMAKE_SYSROOT ${SCRATCH_FOLDER}/${TARGET_PLATFORM}/${TARGET_PLATFORM}/sysroot) set(CMAKE_SYSTEM_INCLUDE_PATH ${SCRATCH_FOLDER}/${TARGET_PLATFORM}/${TARGET_PLATFORM}/sysroot/usr/include) -set(ENABLE_EXPERIMENTAL_BIG_ENDIAN_SUPPORT true) set(CMAKE_GENERATOR Ninja) EOF diff --git a/tests/docker_images/linux-ppc/ubuntu-x-tools/ppc.cmake b/tests/docker_images/linux-ppc/ubuntu-x-tools/ppc.cmake index 015db6c94c..f83e7ddcec 100644 --- a/tests/docker_images/linux-ppc/ubuntu-x-tools/ppc.cmake +++ b/tests/docker_images/linux-ppc/ubuntu-x-tools/ppc.cmake @@ -9,4 +9,3 @@ set(CMAKE_CXX_COMPILER /powerpc-unknown-linux-gnu/bin/powerpc-unknown-linux-gnu- # Specify the sysroot for the target system set(CMAKE_SYSROOT /powerpc-unknown-linux-gnu/powerpc-unknown-linux-gnu/sysroot) set(CMAKE_GENERATOR Ninja) -set(ENABLE_EXPERIMENTAL_BIG_ENDIAN_SUPPORT true) diff --git a/tests/docker_images/linux-ppc64/ubuntu-x-tools/ppc64.cmake b/tests/docker_images/linux-ppc64/ubuntu-x-tools/ppc64.cmake index a0f1067aa9..9cde392e8f 100644 --- a/tests/docker_images/linux-ppc64/ubuntu-x-tools/ppc64.cmake +++ b/tests/docker_images/linux-ppc64/ubuntu-x-tools/ppc64.cmake @@ -9,4 +9,3 @@ set(CMAKE_CXX_COMPILER /powerpc64-unknown-linux-gnu/bin/powerpc64-unknown-linux- # Specify the sysroot for the target system set(CMAKE_SYSROOT /powerpc64-unknown-linux-gnu/powerpc64-unknown-linux-gnu/sysroot/) set(CMAKE_GENERATOR Ninja) -set(ENABLE_EXPERIMENTAL_BIG_ENDIAN_SUPPORT true) diff --git a/tests/docker_images/linux-s390x/ubuntu-x-tools/s390x.cmake b/tests/docker_images/linux-s390x/ubuntu-x-tools/s390x.cmake index d112e55b41..733d0d163e 100644 --- a/tests/docker_images/linux-s390x/ubuntu-x-tools/s390x.cmake +++ b/tests/docker_images/linux-s390x/ubuntu-x-tools/s390x.cmake @@ -9,4 +9,3 @@ set(CMAKE_CXX_COMPILER /s390x-ibm-linux-gnu/bin/s390x-ibm-linux-gnu-g++) # Specify the sysroot for the target system set(CMAKE_SYSROOT /s390x-ibm-linux-gnu/s390x-ibm-linux-gnu/sysroot) set(CMAKE_GENERATOR Ninja) -set(ENABLE_EXPERIMENTAL_BIG_ENDIAN_SUPPORT true)