From 4eab16be0319187fef363bd724c39c38874813bb Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sat, 18 Nov 2023 19:56:33 -0500 Subject: [PATCH 01/10] Remove unused fields in X509_LOOKUP and X509_LOOKUP_METHOD Change-Id: I8d1d3578e0e05757744b905689939708a9353e8d Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64131 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit df67e20de66fd95fd94b4d2837034a264f347c2c) --- crypto/x509/by_dir.c | 3 --- crypto/x509/by_file.c | 3 --- crypto/x509/internal.h | 5 ----- crypto/x509/x509_lu.c | 20 ++------------------ 4 files changed, 2 insertions(+), 29 deletions(-) diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index 204fd28d2b..413f1661c9 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -93,11 +93,8 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, X509_OBJECT *ret); static X509_LOOKUP_METHOD x509_dir_lookup = { - "Load certs from files in a directory", new_dir, // new free_dir, // free - NULL, // init - NULL, // shutdown dir_ctrl, // ctrl get_cert_by_subject, // get_by_subject }; diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 2c83137b1e..a461246166 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -66,11 +66,8 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); static X509_LOOKUP_METHOD x509_file_lookup = { - "Load file into cache", NULL, // new NULL, // free - NULL, // init - NULL, // shutdown by_file_ctrl, // ctrl NULL, // get_by_subject }; diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 0fa48b1788..2b6627d36d 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h @@ -279,11 +279,8 @@ struct x509_object_st { // This is a static that defines the function interface struct x509_lookup_method_st { - const char *name; int (*new_item)(X509_LOOKUP *ctx); void (*free)(X509_LOOKUP *ctx); - int (*init)(X509_LOOKUP *ctx); - int (*shutdown)(X509_LOOKUP *ctx); int (*ctrl)(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret); int (*get_by_subject)(X509_LOOKUP *ctx, int type, X509_NAME *name, @@ -323,8 +320,6 @@ struct x509_store_st { // This is the functions plus an instance of the local variables. struct x509_lookup_st { - int init; // have we been started - int skip; // don't use us. X509_LOOKUP_METHOD *method; // the functions void *method_data; // method data diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index d8dac39eaf..bc063e7254 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -77,7 +77,6 @@ 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)); @@ -97,23 +96,12 @@ void X509_LOOKUP_free(X509_LOOKUP *ctx) { if (ctx == NULL) { return; } - if ((ctx->method != NULL) && (ctx->method->free != NULL)) { + if (ctx->method != NULL && ctx->method->free != NULL) { (*ctx->method->free)(ctx); } OPENSSL_free(ctx); } -static int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) { - if (ctx->method == NULL) { - return 0; - } - if (ctx->method->shutdown != NULL) { - return ctx->method->shutdown(ctx); - } else { - return 1; - } -} - int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, char **ret) { if (ctx->method == NULL) { @@ -128,10 +116,7 @@ int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, 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) { + if (ctx->method == NULL || ctx->method->get_by_subject == NULL) { return 0; } // Note |get_by_subject| leaves |ret| in an inconsistent state. It has @@ -240,7 +225,6 @@ void X509_STORE_free(X509_STORE *vfy) { sk = vfy->get_cert_methods; for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { lu = sk_X509_LOOKUP_value(sk, j); - X509_LOOKUP_shutdown(lu); X509_LOOKUP_free(lu); } sk_X509_LOOKUP_free(sk); From da613958e8e9eb2fba163da2a030298b51153c6e Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Wed, 29 Nov 2023 10:48:37 -0500 Subject: [PATCH 02/10] Move X509_INFO back into x509.h and document Although this is only used by , one existing caller expects the free functions to be defined in . It's not really worth it to put it in the other header, so just move it back. Change-Id: I7e719d51110b567296fcd797f72d13aa41de73af Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64287 Commit-Queue: David Benjamin Commit-Queue: Bob Beck Auto-Submit: David Benjamin Reviewed-by: Bob Beck (cherry picked from commit 38c4bf10ce77ccabf50a61fb42edbad488ecffd8) --- include/openssl/pem.h | 52 +++++++++++++++--------------------------- include/openssl/x509.h | 30 +++++++++++++++++++++++- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/include/openssl/pem.h b/include/openssl/pem.h index 0c060d4d9c..2266b0ebc0 100644 --- a/include/openssl/pem.h +++ b/include/openssl/pem.h @@ -353,28 +353,27 @@ 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); - +// PEM_X509_INFO_read_bio reads PEM blocks from |bp| and decodes any +// certificates, CRLs, and private keys found. It returns a +// |STACK_OF(X509_INFO)| structure containing the results, or NULL on error. +// +// If |sk| is NULL, the result on success will be a newly-allocated +// |STACK_OF(X509_INFO)| structure which should be released with +// |sk_X509_INFO_pop_free| and |X509_INFO_free| when done. +// +// If |sk| is non-NULL, it appends the results to |sk| instead and returns |sk| +// on success. In this case, the caller retains ownership of |sk| in both +// success and failure. OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio( BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +// PEM_X509_INFO_read behaves like |PEM_X509_INFO_read_bio| but reads from a +// |FILE|. +OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, + STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, + void *u); + OPENSSL_EXPORT int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, long *len); OPENSSL_EXPORT int PEM_write(FILE *fp, const char *name, const char *hdr, @@ -385,10 +384,6 @@ OPENSSL_EXPORT int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, void *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *callback, void *u); -OPENSSL_EXPORT STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, - STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, - void *u); // PEM_def_callback treats |userdata| as a string and copies it into |buf|, // assuming its |size| is sufficient. Returns the length of the string, or 0 @@ -480,17 +475,6 @@ 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 a12c825085..49b8180654 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2595,6 +2595,32 @@ OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, EVP_MD_CTX *ctx); +// X.509 information. +// +// |X509_INFO| is the return type for |PEM_X509_INFO_read_bio|, defined in +// . It is used to store a certificate, CRL, or private key. This +// type is defined in this header for OpenSSL compatibility. + +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); + + // Deprecated functions. // X509_get_notBefore returns |x509|'s notBefore time. Note this function is not @@ -3389,9 +3415,11 @@ 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_OBJECT, X509_OBJECT_free) +BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) +BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) +BORINGSSL_MAKE_DELETER(X509_OBJECT, X509_OBJECT_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 d0c25d154621528a50fcf2e01095460d6459da8c Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 19 Nov 2023 10:04:06 -0500 Subject: [PATCH 03/10] Remove a pile of unused X509_STORE callbacks Other than the verify callback, these are practically unused. The one exception is that gRPC have used a couple of the CRL functions, though in somewhat questionable ways. Keep those for now, but we need to work with them to fix their code. There's also a bit of mess around check_issued, largely due to further rust-openssl misunderstandings. Update-Note: Removed a bunch of unused X509_STORE callback functions. We can restore them if someone was using them. Change-Id: I9c47581784c56a4c3b762e603a20ad7d5d612c65 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64133 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 998f511b9856281a6d8ec9617bf5a526740a88be) --- crypto/x509/internal.h | 34 ++++++++----------- crypto/x509/x509_lu.c | 70 +++----------------------------------- crypto/x509/x509_vfy.c | 76 ++++++++---------------------------------- include/openssl/x509.h | 46 ------------------------- 4 files changed, 31 insertions(+), 195 deletions(-) diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 2b6627d36d..080b69b342 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h @@ -301,18 +301,10 @@ struct x509_store_st { X509_VERIFY_PARAM *param; // Callbacks for various operations - X509_STORE_CTX_verify_fn verify; // called to verify a certificate X509_STORE_CTX_verify_cb verify_cb; // error callback X509_STORE_CTX_get_issuer_fn get_issuer; // get issuers cert from ctx - X509_STORE_CTX_check_issued_fn check_issued; // check issued - X509_STORE_CTX_check_revocation_fn - check_revocation; // Check revocation status of chain - X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL - X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity - X509_STORE_CTX_cert_crl_fn cert_crl; // Check certificate against CRL - X509_STORE_CTX_lookup_certs_fn lookup_certs; - X509_STORE_CTX_lookup_crls_fn lookup_crls; - X509_STORE_CTX_cleanup_fn cleanup; + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity CRYPTO_refcount_t references; } /* X509_STORE */; @@ -341,19 +333,10 @@ struct x509_store_ctx_st { void *other_ctx; // Other info for use with get_issuer() // Callbacks for various operations - X509_STORE_CTX_verify_fn verify; // called to verify a certificate X509_STORE_CTX_verify_cb verify_cb; // error callback X509_STORE_CTX_get_issuer_fn get_issuer; // get issuers cert from ctx - X509_STORE_CTX_check_issued_fn check_issued; // check issued - X509_STORE_CTX_check_revocation_fn - check_revocation; // Check revocation status of chain - X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL - X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity - X509_STORE_CTX_cert_crl_fn cert_crl; // Check certificate against CRL - X509_STORE_CTX_check_policy_fn check_policy; - X509_STORE_CTX_lookup_certs_fn lookup_certs; - X509_STORE_CTX_lookup_crls_fn lookup_crls; - X509_STORE_CTX_cleanup_fn cleanup; + X509_STORE_CTX_get_crl_fn get_crl; // retrieve CRL + X509_STORE_CTX_check_crl_fn check_crl; // Check CRL validity // The following is built up int valid; // if 0, rebuild chain @@ -437,6 +420,15 @@ int X509_policy_check(const STACK_OF(X509) *certs, const STACK_OF(ASN1_OBJECT) *user_policies, unsigned long flags, X509 **out_current_cert); +// x509_check_issued_with_callback calls |X509_check_issued|, but allows the +// verify callback to override the result. It returns one on success and zero on +// error. +// +// TODO(davidben): Reduce the scope of the verify callback and remove this. The +// callback only runs with |X509_V_FLAG_CB_ISSUER_CHECK|, which is only used by +// one internal project and rust-openssl, who use it by mistake. +int x509_check_issued_with_callback(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + #if defined(__cplusplus) } // extern C diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index bc063e7254..3bf05461eb 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -609,7 +609,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { return 0; } // If certificate matches all OK - if (ctx->check_issued(ctx, x, obj.data.x509)) { + if (x509_check_issued_with_callback(ctx, x, obj.data.x509)) { if (x509_check_cert_time(ctx, obj.data.x509, /*suppress_error*/1)) { *issuer = obj.data.x509; return 1; @@ -617,7 +617,8 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { } X509_OBJECT_free_contents(&obj); - // Else find index of first cert accepted by 'check_issued' + // Else find index of first cert accepted by + // |x509_check_issued_with_callback|. ret = 0; CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); @@ -633,7 +634,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) { if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) { break; } - if (ctx->check_issued(ctx, x, pobj->data.x509)) { + if (x509_check_issued_with_callback(ctx, x, pobj->data.x509)) { *issuer = pobj->data.x509; ret = 1; // Break the loop with a match if the time check is valid, otherwise @@ -676,14 +677,6 @@ int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) { X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) { return ctx->param; } -void X509_STORE_set_verify(X509_STORE *ctx, X509_STORE_CTX_verify_fn verify) { - ctx->verify = verify; -} - -X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx) { - return ctx->verify; -} - void X509_STORE_set_verify_cb(X509_STORE *ctx, X509_STORE_CTX_verify_cb verify_cb) { ctx->verify_cb = verify_cb; @@ -702,25 +695,6 @@ X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx) { return ctx->get_issuer; } -void X509_STORE_set_check_issued(X509_STORE *ctx, - X509_STORE_CTX_check_issued_fn check_issued) { - ctx->check_issued = check_issued; -} - -X509_STORE_CTX_check_issued_fn X509_STORE_get_check_issued(X509_STORE *ctx) { - return ctx->check_issued; -} - -void X509_STORE_set_check_revocation( - X509_STORE *ctx, X509_STORE_CTX_check_revocation_fn check_revocation) { - ctx->check_revocation = check_revocation; -} - -X509_STORE_CTX_check_revocation_fn X509_STORE_get_check_revocation( - X509_STORE *ctx) { - return ctx->check_revocation; -} - void X509_STORE_set_get_crl(X509_STORE *ctx, X509_STORE_CTX_get_crl_fn get_crl) { ctx->get_crl = get_crl; @@ -739,40 +713,4 @@ X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx) { return ctx->check_crl; } -void X509_STORE_set_cert_crl(X509_STORE *ctx, - X509_STORE_CTX_cert_crl_fn cert_crl) { - ctx->cert_crl = cert_crl; -} - -X509_STORE_CTX_cert_crl_fn X509_STORE_get_cert_crl(X509_STORE *ctx) { - return ctx->cert_crl; -} - -void X509_STORE_set_lookup_certs(X509_STORE *ctx, - X509_STORE_CTX_lookup_certs_fn lookup_certs) { - ctx->lookup_certs = lookup_certs; -} - -X509_STORE_CTX_lookup_certs_fn X509_STORE_get_lookup_certs(X509_STORE *ctx) { - return ctx->lookup_certs; -} - -void X509_STORE_set_lookup_crls(X509_STORE *ctx, - X509_STORE_CTX_lookup_crls_fn lookup_crls) { - ctx->lookup_crls = lookup_crls; -} - -X509_STORE_CTX_lookup_crls_fn X509_STORE_get_lookup_crls(X509_STORE *ctx) { - return ctx->lookup_crls; -} - -void X509_STORE_set_cleanup(X509_STORE *ctx, - X509_STORE_CTX_cleanup_fn ctx_cleanup) { - ctx->cleanup = ctx_cleanup; -} - -X509_STORE_CTX_cleanup_fn X509_STORE_get_cleanup(X509_STORE *ctx) { - return ctx->cleanup; -} - X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) { return ctx->ctx; } diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 5ad35f3a37..ad93aae4bb 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -102,7 +102,6 @@ static CRYPTO_EX_DATA_CLASS g_ex_data_class = #define CRL_SCORE_AKID 0x004 static int null_callback(int ok, X509_STORE_CTX *e); -static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); static int check_chain_extensions(X509_STORE_CTX *ctx); static int check_name_constraints(X509_STORE_CTX *ctx); @@ -118,6 +117,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x); static int crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, int *pcrl_score); static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score); +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); static int internal_verify(X509_STORE_CTX *ctx); @@ -141,7 +141,7 @@ static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) { X509 *xtmp = NULL; size_t i; // Lookup all certs with matching subject name - certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); + certs = X509_STORE_get1_certs(ctx, X509_get_subject_name(x)); if (certs == NULL) { return NULL; } @@ -400,7 +400,8 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { // self signed certificate in which case we've indicated an error already // and set bad_chain == 1 if (trust != X509_TRUST_TRUSTED && !bad_chain) { - if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { + if (chain_ss == NULL || + !x509_check_issued_with_callback(ctx, x, chain_ss)) { if (ctx->last_untrusted >= num) { ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; } else { @@ -443,18 +444,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { // Check revocation status: we do this after copying parameters because // they may be needed for CRL signature verification. - - ok = ctx->check_revocation(ctx); + ok = check_revocation(ctx); if (!ok) { goto end; } // At this point, we have a chain and need to verify it - if (ctx->verify != NULL) { - ok = ctx->verify(ctx); - } else { - ok = internal_verify(ctx); - } + ok = internal_verify(ctx); if (!ok) { goto end; } @@ -468,7 +464,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx) { // If we get this far evaluate policies if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) { - ok = ctx->check_policy(ctx); + ok = check_policy(ctx); } end: @@ -496,7 +492,7 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) { X509 *issuer, *candidate = NULL; for (i = 0; i < sk_X509_num(sk); i++) { issuer = sk_X509_value(sk, i); - if (ctx->check_issued(ctx, x, issuer)) { + if (x509_check_issued_with_callback(ctx, x, issuer)) { candidate = issuer; if (x509_check_cert_time(ctx, candidate, /*suppress_error*/1)) { break; @@ -508,7 +504,8 @@ static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) { // Given a possible certificate and issuer check them -static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) { +int x509_check_issued_with_callback(X509_STORE_CTX *ctx, X509 *x, + X509 *issuer) { int ret; ret = X509_check_issued(issuer, x); if (ret == X509_V_OK) { @@ -839,7 +836,7 @@ static int check_cert(X509_STORE_CTX *ctx) { goto err; } - ok = ctx->cert_crl(ctx, crl, x); + ok = cert_crl(ctx, crl, x); if (!ok) { goto err; } @@ -1164,7 +1161,7 @@ static int get_crl(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509 *x) { } // Lookup CRLs from store - skcrl = ctx->lookup_crls(ctx, nm); + skcrl = X509_STORE_get1_crls(ctx, nm); // If no CRLs found and a near match from get_crl_sk use that if (!skcrl && crl) { @@ -1207,7 +1204,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) { } else { issuer = sk_X509_value(ctx->chain, chnum); // If not self signed, can't check signature - if (!ctx->check_issued(ctx, issuer, issuer)) { + if (!x509_check_issued_with_callback(ctx, issuer, issuer)) { ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; ok = ctx->verify_cb(0, ctx); if (!ok) { @@ -1404,7 +1401,7 @@ static int internal_verify(X509_STORE_CTX *ctx) { n--; xi = sk_X509_value(ctx->chain, n); - if (ctx->check_issued(ctx, xi, xi)) { + if (x509_check_issued_with_callback(ctx, xi, xi)) { xs = xi; } else { if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { @@ -1693,7 +1690,6 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, // Inherit callbacks and flags from X509_STORE. ctx->verify_cb = store->verify_cb; - ctx->cleanup = store->cleanup; if (!X509_VERIFY_PARAM_inherit(ctx->param, store->param) || !X509_VERIFY_PARAM_inherit(ctx->param, @@ -1701,12 +1697,6 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, goto err; } - if (store->check_issued) { - ctx->check_issued = store->check_issued; - } else { - ctx->check_issued = check_issued; - } - if (store->get_issuer) { ctx->get_issuer = store->get_issuer; } else { @@ -1719,18 +1709,6 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->verify_cb = null_callback; } - if (store->verify) { - ctx->verify = store->verify; - } else { - ctx->verify = internal_verify; - } - - if (store->check_revocation) { - ctx->check_revocation = store->check_revocation; - } else { - ctx->check_revocation = check_revocation; - } - if (store->get_crl) { ctx->get_crl = store->get_crl; } else { @@ -1743,26 +1721,6 @@ int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, ctx->check_crl = check_crl; } - if (store->cert_crl) { - ctx->cert_crl = store->cert_crl; - } else { - ctx->cert_crl = cert_crl; - } - - if (store->lookup_certs) { - ctx->lookup_certs = store->lookup_certs; - } else { - ctx->lookup_certs = X509_STORE_get1_certs; - } - - if (store->lookup_crls) { - ctx->lookup_crls = store->lookup_crls; - } else { - ctx->lookup_crls = X509_STORE_get1_crls; - } - - ctx->check_policy = check_policy; - return 1; err: @@ -1789,12 +1747,6 @@ void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) { } void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) { - // We need to be idempotent because, unfortunately, |X509_STORE_CTX_free| - // also calls this function. - if (ctx->cleanup != NULL) { - ctx->cleanup(ctx); - ctx->cleanup = NULL; - } X509_VERIFY_PARAM_free(ctx->param); ctx->param = NULL; sk_X509_pop_free(ctx->chain, X509_free); diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 49b8180654..43398001f3 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -2884,23 +2884,11 @@ DEFINE_STACK_OF(X509_OBJECT) DEFINE_STACK_OF(X509_VERIFY_PARAM) typedef int (*X509_STORE_CTX_verify_cb)(int, X509_STORE_CTX *); -typedef int (*X509_STORE_CTX_verify_fn)(X509_STORE_CTX *); typedef int (*X509_STORE_CTX_get_issuer_fn)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); -typedef int (*X509_STORE_CTX_check_issued_fn)(X509_STORE_CTX *ctx, X509 *x, - X509 *issuer); -typedef int (*X509_STORE_CTX_check_revocation_fn)(X509_STORE_CTX *ctx); typedef int (*X509_STORE_CTX_get_crl_fn)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); typedef int (*X509_STORE_CTX_check_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl); -typedef int (*X509_STORE_CTX_cert_crl_fn)(X509_STORE_CTX *ctx, X509_CRL *crl, - X509 *x); -typedef int (*X509_STORE_CTX_check_policy_fn)(X509_STORE_CTX *ctx); -typedef STACK_OF(X509) *(*X509_STORE_CTX_lookup_certs_fn)(X509_STORE_CTX *ctx, - X509_NAME *nm); -typedef STACK_OF(X509_CRL) *(*X509_STORE_CTX_lookup_crls_fn)( - X509_STORE_CTX *ctx, X509_NAME *nm); -typedef int (*X509_STORE_CTX_cleanup_fn)(X509_STORE_CTX *ctx); OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth); @@ -3122,14 +3110,6 @@ OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_verify(X509_STORE *ctx, - X509_STORE_CTX_verify_fn verify); -#define X509_STORE_set_verify_func(ctx, func) \ - X509_STORE_set_verify((ctx), (func)) -OPENSSL_EXPORT void X509_STORE_CTX_set_verify(X509_STORE_CTX *ctx, - X509_STORE_CTX_verify_fn verify); -OPENSSL_EXPORT X509_STORE_CTX_verify_fn X509_STORE_get_verify(X509_STORE *ctx); - // X509_STORE_set_verify_cb acts like |X509_STORE_CTX_set_verify_cb| but sets // the verify callback for any |X509_STORE_CTX| created from this |X509_STORE| // @@ -3144,14 +3124,6 @@ OPENSSL_EXPORT void X509_STORE_set_get_issuer( X509_STORE *ctx, X509_STORE_CTX_get_issuer_fn get_issuer); OPENSSL_EXPORT X509_STORE_CTX_get_issuer_fn X509_STORE_get_get_issuer(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_check_issued( - X509_STORE *ctx, X509_STORE_CTX_check_issued_fn check_issued); -OPENSSL_EXPORT X509_STORE_CTX_check_issued_fn -X509_STORE_get_check_issued(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_check_revocation( - X509_STORE *ctx, X509_STORE_CTX_check_revocation_fn check_revocation); -OPENSSL_EXPORT X509_STORE_CTX_check_revocation_fn -X509_STORE_get_check_revocation(X509_STORE *ctx); OPENSSL_EXPORT void X509_STORE_set_get_crl(X509_STORE *ctx, X509_STORE_CTX_get_crl_fn get_crl); OPENSSL_EXPORT X509_STORE_CTX_get_crl_fn @@ -3160,24 +3132,6 @@ OPENSSL_EXPORT void X509_STORE_set_check_crl( X509_STORE *ctx, X509_STORE_CTX_check_crl_fn check_crl); OPENSSL_EXPORT X509_STORE_CTX_check_crl_fn X509_STORE_get_check_crl(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_cert_crl( - X509_STORE *ctx, X509_STORE_CTX_cert_crl_fn cert_crl); -OPENSSL_EXPORT X509_STORE_CTX_cert_crl_fn -X509_STORE_get_cert_crl(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_lookup_certs( - X509_STORE *ctx, X509_STORE_CTX_lookup_certs_fn lookup_certs); -OPENSSL_EXPORT X509_STORE_CTX_lookup_certs_fn -X509_STORE_get_lookup_certs(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_lookup_crls( - X509_STORE *ctx, X509_STORE_CTX_lookup_crls_fn lookup_crls); -#define X509_STORE_set_lookup_crls_cb(ctx, func) \ - X509_STORE_set_lookup_crls((ctx), (func)) -OPENSSL_EXPORT X509_STORE_CTX_lookup_crls_fn -X509_STORE_get_lookup_crls(X509_STORE *ctx); -OPENSSL_EXPORT void X509_STORE_set_cleanup(X509_STORE *ctx, - X509_STORE_CTX_cleanup_fn cleanup); -OPENSSL_EXPORT X509_STORE_CTX_cleanup_fn -X509_STORE_get_cleanup(X509_STORE *ctx); OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); From 0e0b2347ea9a06b10df6e7930f8b2d137f15be8d Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 19 Nov 2023 10:20:04 -0500 Subject: [PATCH 04/10] Document some X509_VERIFY_PARAM and X509_STORE functions There are quite a lot of these, and I haven't organized them into sections yet or anything, but get some easy ones. While I'm here, also do the check_private_key functions. They're pretty easy. Bug: 426 Change-Id: I1a5217d27908255833c350893bc3180ced82b0d0 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64134 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 2ba7634b9e2b33875e2a40dec9e04abffe061f2c) --- crypto/x509/x509_req.c | 2 +- crypto/x509/x509_vfy.c | 2 +- include/openssl/x509.h | 128 ++++++++++++++++++++++++++++++++--------- 3 files changed, 104 insertions(+), 28 deletions(-) diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c index b40e641fcb..de11723506 100644 --- a/crypto/x509/x509_req.c +++ b/crypto/x509/x509_req.c @@ -92,7 +92,7 @@ EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req) { return (X509_PUBKEY_get0(req->req_info->pubkey)); } -int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) { +int X509_REQ_check_private_key(X509_REQ *x, const EVP_PKEY *k) { EVP_PKEY *xk = NULL; int ok = 0; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index ad93aae4bb..7bba05c7bb 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -1764,7 +1764,7 @@ void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) { } void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, unsigned long flags, - int64_t t) { + int64_t t) { X509_VERIFY_PARAM_set_time_posix(ctx->param, t); } diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 43398001f3..1f20ce8d4a 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -214,6 +214,10 @@ OPENSSL_EXPORT EVP_PKEY *X509_get_pubkey(X509 *x509); // internal invariants in |x509|. OPENSSL_EXPORT ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x509); +// X509_check_private_key returns one if |x509|'s public key matches |pkey| and +// zero otherwise. +OPENSSL_EXPORT int X509_check_private_key(X509 *x509, const EVP_PKEY *pkey); + // X509_get0_uids sets |*out_issuer_uid| to a non-owning pointer to the // issuerUID field of |x509|, or NULL if |x509| has no issuerUID. It similarly // outputs |x509|'s subjectUID field to |*out_subject_uid|. @@ -990,6 +994,11 @@ OPENSSL_EXPORT EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); // reference to |req|. The caller must not free the result after use. OPENSSL_EXPORT EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req); +// X509_REQ_check_private_key returns one if |req|'s public key matches |pkey| +// and zero otherwise. +OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *req, + const EVP_PKEY *pkey); + // X509_REQ_get_attr_count returns the number of attributes in |req|. OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req); @@ -2709,6 +2718,15 @@ OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx( // longer call it. OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); +// X509_STORE_CTX_cleanup resets |ctx| to the empty state. +// +// This function is a remnant of when |X509_STORE_CTX| was stack-allocated and +// should not be used. If releasing |ctx|, call |X509_STORE_CTX_free|. If +// reusing |ctx| for a new verification, release the old one and create a new +// one. +OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + + // Private structures. struct X509_algor_st { @@ -2802,10 +2820,6 @@ OPENSSL_EXPORT const char *X509_get_default_private_dir(void); OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); -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 unsigned long X509_issuer_name_hash(X509 *a); OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); @@ -3071,8 +3085,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_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| OPENSSL_EXPORT X509_CRL *X509_OBJECT_get0_X509_CRL(const X509_OBJECT *a); @@ -3086,17 +3098,24 @@ OPENSSL_EXPORT int X509_OBJECT_set1_X509(X509_OBJECT *a, X509 *obj); // responsible for managing freeing |obj| when appropriate. OPENSSL_EXPORT int X509_OBJECT_set1_X509_CRL(X509_OBJECT *a, X509_CRL *obj); -OPENSSL_EXPORT X509_STORE *X509_STORE_new(void); // X509_STORE_lock takes a write lock on |v|. return 1 on success, 0 on failure. // // Avoid operations on the X509_STORE or a X509_STORE_CTX containing it while // it is locked; many |X509_STORE_*| functions take this lock internally which // will cause a deadlock when called on a locked store. OPENSSL_EXPORT int X509_STORE_lock(X509_STORE *v); + // X509_STORE_unlock releases a lock on |v|. return 1 on success, 0 on failure OPENSSL_EXPORT int X509_STORE_unlock(X509_STORE *v); + +// X509_STORE_new returns a newly-allocated |X509_STORE|, or NULL on error. +OPENSSL_EXPORT X509_STORE *X509_STORE_new(void); + +// X509_STORE_up_ref adds one to the reference count of |store| and returns one. OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store); -OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v); + +// X509_STORE_free releases memory associated with |store|. +OPENSSL_EXPORT void X509_STORE_free(X509_STORE *store); OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st); OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, @@ -3108,7 +3127,13 @@ OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *ctx, int trust); OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); -OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); + +// X509_STORE_get0_param returns |store|'s default verification parameters. This +// object is mutable and may be modified by the caller. +// +// TODO(crbug.com/boringssl/441): Discuss the semantics of this notion of +// "default". +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *store); // X509_STORE_set_verify_cb acts like |X509_STORE_CTX_set_verify_cb| but sets // the verify callback for any |X509_STORE_CTX| created from this |X509_STORE| @@ -3138,7 +3163,9 @@ 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); +// X509_STORE_CTX_free releases memory associated with |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); @@ -3156,9 +3183,11 @@ OPENSSL_EXPORT void X509_STORE_CTX_set0_trusted_stack(X509_STORE_CTX *ctx, OPENSSL_EXPORT void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); -OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); - +// X509_STORE_CTX_get0_store returns the |X509_STORE| that |ctx| uses. OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); + +// X509_STORE_CTX_get0_cert returns the leaf certificate that |ctx| is +// verifying. OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx); OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, @@ -3216,8 +3245,15 @@ OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int trust); OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); + +// X509_STORE_CTX_set_time configures certificate verification to use |t| +// instead of the current time. |flags| is ignored and should be zero. OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, time_t t); + +// X509_STORE_CTX_set_time_posix configures certificate verification to use |t| +// instead of the current time. |t| is interpreted as a POSIX timestamp in +// seconds. |flags| is ignored and should be zero. OPENSSL_EXPORT void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, unsigned long flags, int64_t t); @@ -3243,10 +3279,20 @@ OPENSSL_EXPORT void X509_STORE_CTX_set_time_posix(X509_STORE_CTX *ctx, OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb( X509_STORE_CTX *ctx, int (*verify_cb)(int ok, X509_STORE_CTX *ctx)); +// X509_STORE_CTX_get0_param returns |ctx|'s verification parameters. This +// object is mutable and may be modified by the caller. OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param( X509_STORE_CTX *ctx); + +// X509_STORE_CTX_set0_param returns |ctx|'s verification parameters to |param| +// and takes ownership of |param|. After this function returns, the caller +// should not free |param|. +// +// TODO(crbug.com/boringssl/441): The bug notes some odd interactions with +// the different notions of default. Discuss this. OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); + OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); @@ -3264,8 +3310,13 @@ OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *vs, int type, // X509_VERIFY_PARAM functions +// X509_VERIFY_PARAM_new returns a newly-allocated |X509_VERIFY_PARAM|, or NULL +// on error. OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); + +// X509_VERIFY_PARAM_free releases memory associated with |param|. OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); + OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from); OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, @@ -3284,20 +3335,36 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); + +// X509_VERIFY_PARAM_set_time configures certificate verification to use |t| +// instead of the current time. OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); + +// X509_VERIFY_PARAM_set_time_posix configures certificate verification to use +// |t| instead of the current time. |t| is interpreted as a POSIX timestamp in +// seconds. OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time_posix(X509_VERIFY_PARAM *param, int64_t t); + +// X509_VERIFY_PARAM_add0_policy adds |policy| to the user-initial-policy-set +// (see Section 6.1.1 of RFC 5280). On success, it takes ownership of +// |policy| and returns one. Otherwise, it returns zero and the caller retains +// owneship of |policy|. OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, ASN1_OBJECT *policy); + +// X509_VERIFY_PARAM_set1_policies sets the user-initial-policy-set (see +// Section 6.1.1 of RFC 5280) to a copy of |policies|. It returns one on success +// and zero on error. OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies( X509_VERIFY_PARAM *param, const STACK_OF(ASN1_OBJECT) *policies); - -// X509_VERIFY_PARAM_set1_host sets the expected DNS hostname to |name| and -// clears any previously specified hostname. If |name| is NULL or empty, the -// list of hostnames is cleared and name checks are not performed on the peer -// certificate. +// X509_VERIFY_PARAM_set1_host configures |param| to check for the DNS name +// specified by |name| and clears any previously specified hostname. If |name| +// is NULL or empty, the list of hostnames is cleared and name checks are not +// performed on the peer certificate. It returns one on success and zero on +// error. // |namelen| should be set to the length of |name|. It may be zero if |name| is // NUL-terminated, but this is only maintained for backwards compatibility with // OpenSSL. @@ -3305,24 +3372,28 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const char *name, size_t namelen); -// X509_VERIFY_PARAM_add1_host adds |name| as an additional DNS hostname -// reference identifier that can match the peer's certificate. -// Any previous names set via |X509_VERIFY_PARAM_set1_host| or +// X509_VERIFY_PARAM_add1_host |name| to the list of names checked by +// |param|. If any configured DNS name matches the certificate, verification +// succeeds. Any previous names set via |X509_VERIFY_PARAM_set1_host| or // |X509_VERIFY_PARAM_add1_host| are retained, no change is made if |name| is // NULL or empty. When multiple names are configured, the peer is considered -// verified when any name matches. +// verified when any name matches. It returns one on success and zero on error. // |namelen| should be set to the length of |name|. It may be zero if |name| is // NUL-terminated, but this is only maintained for backwards compatibility with // OpenSSL. OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, const char *name, - size_t namelen); + size_t name_len); + +// X509_VERIFY_PARAM_set_hostflags sets the name-checking flags on |param| to +// |flags|. |flags| should be a combination of |X509_CHECK_FLAG_*| constants. OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, unsigned int flags); + OPENSSL_EXPORT char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); -// X509_VERIFY_PARAM_set1_email sets the expected RFC822 email address to -// |email|. +// X509_VERIFY_PARAM_set1_email configures |param| to check for the email +// address specified by |email|. It returns one on success and zero on error. // |emaillen| should be set to the length of |email|. It may be zero if |email| // is NUL-terminated, but this is only maintained for backwards compatibility // with OpenSSL. @@ -3330,13 +3401,18 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, const char *email, size_t emaillen); -// X509_VERIFY_PARAM_set1_ip sets the expected IP address to |ip|. |iplen| MUST -// be set to the length of |ip|. +// X509_VERIFY_PARAM_set1_ip configures |param| to check for the IP address +// specified by |ip|. It returns one on success and zero on error. The IP +// address is specified in its binary representation. |ip_len| must be 4 for an +// IPv4 address and 16 for an IPv6 address. +// NOTE:|iplen| MUST be set to the length of |ip|. OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, const unsigned char *ip, size_t iplen); -// X509_VERIFY_PARAM_set1_ip_asc sets the expected IP address to |ipasc|. +// X509_VERIFY_PARAM_set1_ip_asc decodes |ipasc| as the ASCII representation of +// an IPv4 or IPv6 address, and configures |param| to check for it. It returns +// one on success and zero on error. // |ipasc| MUST be a NUL-terminal ASCII string: dotted decimal quad for IPv4 and // colon-separated hexadecimal for IPv6. The condensed "::" notation is // supported for IPv6 addresses. From 1380642ee5a6e6218cc4896874cc2234f12af115 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Wed, 29 Nov 2023 15:32:33 -0500 Subject: [PATCH 05/10] Add CRYPTO_{addc,subc}_* functions to crypto/internal.h I'm getting tired of having to rederive the best way to convince the compiler to emit addc and subb functions. Do it once and use the Clang builtins when available, because compilers seem to generally be terrible at this. (See https://github.com/llvm/llvm-project/issues/73847.) The immediate trigger was the FIPS 186-2 PRF, which completely doesn't matter, but reminded me of this mess. As far as naming and calling conventions go, I just mimicked the Clang ones. In doing so, also use the Clang builtins when available, which helps Clang x86_64 no-asm builds a bit: Before: Did 704 ECDH P-384 operations in 1018920us (690.9 ops/sec) Did 1353 ECDSA P-384 signing operations in 1077927us (1255.2 ops/sec) Did 1190 ECDSA P-384 verify operations in 1020788us (1165.8 ops/sec) Did 784 RSA 2048 signing operations in 1058644us (740.6 ops/sec) Did 34000 RSA 2048 verify (same key) operations in 1011854us (33601.7 ops/sec) Did 30000 RSA 2048 verify (fresh key) operations in 1005974us (29821.8 ops/sec) Did 7799 RSA 2048 private key parse operations in 1061203us (7349.2 ops/sec) Did 130 RSA 4096 signing operations in 1082617us (120.1 ops/sec) Did 10472 RSA 4096 verify (same key) operations in 1082857us (9670.7 ops/sec) Did 9086 RSA 4096 verify (fresh key) operations in 1039164us (8743.6 ops/sec) Did 2574 RSA 4096 private key parse operations in 1078946us (2385.7 ops/sec) After: Did 775 ECDH P-384 operations in 1008465us (768.5 ops/sec) Did 1474 ECDSA P-384 signing operations in 1062096us (1387.8 ops/sec) Did 1485 ECDSA P-384 verify operations in 1086574us (1366.7 ops/sec) Did 812 RSA 2048 signing operations in 1043705us (778.0 ops/sec) Did 36000 RSA 2048 verify (same key) operations in 1005643us (35798.0 ops/sec) Did 33000 RSA 2048 verify (fresh key) operations in 1028256us (32093.2 ops/sec) Did 10087 RSA 2048 private key parse operations in 1018067us (9908.0 ops/sec) Did 132 RSA 4096 signing operations in 1033049us (127.8 ops/sec) Did 11000 RSA 4096 verify (same key) operations in 1070502us (10275.6 ops/sec) Did 9812 RSA 4096 verify (fresh key) operations in 1047618us (9366.0 ops/sec) Did 3245 RSA 4096 private key parse operations in 1083247us (2995.6 ops/sec) But this is also a no-asm build, so we don't really care. Builds with assembly, broadly, do not use these codepaths. The exception is the generic ECC code on 32-bit Arm, which has a few mod-add functions, and we don't have 32-bit Arm bn_add_words assembly: Before: Did 168 ECDH P-384 operations in 1003229us (167.5 ops/sec) Did 330 ECDSA P-384 signing operations in 1076600us (306.5 ops/sec) Did 319 ECDSA P-384 verify operations in 1080750us (295.2 ops/sec) After: Did 195 ECDH P-384 operations in 1026458us (190.0 ops/sec) Did 350 ECDSA P-384 signing operations in 1005392us (348.1 ops/sec) Did 341 ECDSA P-384 verify operations in 1008486us (338.1 ops/sec) Change-Id: Ia3fa51e59398224b9c39180e1d856bb412aa1246 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64309 Reviewed-by: Adam Langley Commit-Queue: David Benjamin (cherry picked from commit 70ca6bc24be103dabd68e448cd3af29b929b771d) --- crypto/fipsmodule/bn/add.c | 10 +-- crypto/fipsmodule/bn/generic.c | 51 +++------------ crypto/fipsmodule/bn/mul.c | 8 +-- crypto/internal.h | 110 +++++++++++++++++++++++++++++++++ 4 files changed, 124 insertions(+), 55 deletions(-) diff --git a/crypto/fipsmodule/bn/add.c b/crypto/fipsmodule/bn/add.c index 38a845062e..1a8785e520 100644 --- a/crypto/fipsmodule/bn/add.c +++ b/crypto/fipsmodule/bn/add.c @@ -117,10 +117,7 @@ int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { BN_ULONG carry = bn_add_words(r->d, a->d, b->d, min); for (int i = min; i < max; i++) { - // |r| and |a| may alias, so use a temporary. - BN_ULONG tmp = carry + a->d[i]; - carry = tmp < a->d[i]; - r->d[i] = tmp; + r->d[i] = CRYPTO_addc_w(a->d[i], 0, carry, &carry); } r->d[max] = carry; @@ -241,10 +238,7 @@ int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { BN_ULONG borrow = bn_sub_words(r->d, a->d, b->d, b_width); for (int i = b_width; i < a->width; i++) { - // |r| and |a| may alias, so use a temporary. - BN_ULONG tmp = a->d[i]; - r->d[i] = a->d[i] - borrow; - borrow = tmp < r->d[i]; + r->d[i] = CRYPTO_subc_w(a->d[i], 0, borrow, &borrow); } if (borrow) { diff --git a/crypto/fipsmodule/bn/generic.c b/crypto/fipsmodule/bn/generic.c index e4f4518e94..247398fddb 100644 --- a/crypto/fipsmodule/bn/generic.c +++ b/crypto/fipsmodule/bn/generic.c @@ -567,37 +567,6 @@ void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { #if !defined(BN_ADD_ASM) -// bn_add_with_carry returns |x + y + carry|, and sets |*out_carry| to the -// carry bit. |carry| must be zero or one. -static inline BN_ULONG bn_add_with_carry(BN_ULONG x, BN_ULONG y, BN_ULONG carry, - BN_ULONG *out_carry) { - assert(carry == 0 || carry == 1); -#if defined(BN_ULLONG) - BN_ULLONG ret = carry; - ret += (BN_ULLONG)x + y; - *out_carry = (BN_ULONG)(ret >> BN_BITS2); - return (BN_ULONG)ret; -#else - x += carry; - carry = x < carry; - BN_ULONG ret = x + y; - carry += ret < x; - *out_carry = carry; - return ret; -#endif -} - -// bn_sub_with_borrow returns |x - y - borrow|, and sets |*out_borrow| to the -// borrow bit. |borrow| must be zero or one. -static inline BN_ULONG bn_sub_with_borrow(BN_ULONG x, BN_ULONG y, - BN_ULONG borrow, - BN_ULONG *out_borrow) { - assert(borrow == 0 || borrow == 1); - BN_ULONG ret = x - y - borrow; - *out_borrow = (x < y) | ((x == y) & borrow); - return ret; -} - BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, size_t n) { if (n == 0) { @@ -606,17 +575,17 @@ BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, BN_ULONG carry = 0; while (n & ~3) { - r[0] = bn_add_with_carry(a[0], b[0], carry, &carry); - r[1] = bn_add_with_carry(a[1], b[1], carry, &carry); - r[2] = bn_add_with_carry(a[2], b[2], carry, &carry); - r[3] = bn_add_with_carry(a[3], b[3], carry, &carry); + r[0] = CRYPTO_addc_w(a[0], b[0], carry, &carry); + r[1] = CRYPTO_addc_w(a[1], b[1], carry, &carry); + r[2] = CRYPTO_addc_w(a[2], b[2], carry, &carry); + r[3] = CRYPTO_addc_w(a[3], b[3], carry, &carry); a += 4; b += 4; r += 4; n -= 4; } while (n) { - r[0] = bn_add_with_carry(a[0], b[0], carry, &carry); + r[0] = CRYPTO_addc_w(a[0], b[0], carry, &carry); a++; b++; r++; @@ -633,17 +602,17 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, BN_ULONG borrow = 0; while (n & ~3) { - r[0] = bn_sub_with_borrow(a[0], b[0], borrow, &borrow); - r[1] = bn_sub_with_borrow(a[1], b[1], borrow, &borrow); - r[2] = bn_sub_with_borrow(a[2], b[2], borrow, &borrow); - r[3] = bn_sub_with_borrow(a[3], b[3], borrow, &borrow); + r[0] = CRYPTO_subc_w(a[0], b[0], borrow, &borrow); + r[1] = CRYPTO_subc_w(a[1], b[1], borrow, &borrow); + r[2] = CRYPTO_subc_w(a[2], b[2], borrow, &borrow); + r[3] = CRYPTO_subc_w(a[3], b[3], borrow, &borrow); a += 4; b += 4; r += 4; n -= 4; } while (n) { - r[0] = bn_sub_with_borrow(a[0], b[0], borrow, &borrow); + r[0] = CRYPTO_subc_w(a[0], b[0], borrow, &borrow); a++; b++; r++; diff --git a/crypto/fipsmodule/bn/mul.c b/crypto/fipsmodule/bn/mul.c index 4075ab8b95..df529c66ce 100644 --- a/crypto/fipsmodule/bn/mul.c +++ b/crypto/fipsmodule/bn/mul.c @@ -144,17 +144,13 @@ static BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, // in |a| were zeros. dl = -dl; for (int i = 0; i < dl; i++) { - r[i] = 0u - b[i] - borrow; - borrow |= r[i] != 0; + r[i] = CRYPTO_subc_w(0, b[i], borrow, &borrow); } } else { // |b| is shorter than |a|. Complete the subtraction as if the excess words // in |b| were zeros. for (int i = 0; i < dl; i++) { - // |r| and |a| may alias, so use a temporary. - BN_ULONG tmp = a[i]; - r[i] = a[i] - borrow; - borrow = tmp < r[i]; + r[i] = CRYPTO_subc_w(a[i], 0, borrow, &borrow); } } diff --git a/crypto/internal.h b/crypto/internal.h index ff03b812f2..89e352d358 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -210,6 +210,12 @@ typedef __uint128_t uint128_t; #define OPENSSL_ATTR_PURE #endif +#if defined(__has_builtin) +#define OPENSSL_HAS_BUILTIN(x) __has_builtin(x) +#else +#define OPENSSL_HAS_BUILTIN(x) 0 +#endif + // Pointer utility functions. @@ -1078,6 +1084,110 @@ static inline uint64_t CRYPTO_rotr_u64(uint64_t value, int shift) { } +// Arithmetic functions. + +// CRYPTO_addc_* returns |x + y + carry|, and sets |*out_carry| to the carry +// bit. |carry| must be zero or one. +#if OPENSSL_HAS_BUILTIN(__builtin_addc) + +#define CRYPTO_GENERIC_ADDC(x, y, carry, out_carry) \ + (_Generic((x), \ + unsigned: __builtin_addc, \ + unsigned long: __builtin_addcl, \ + unsigned long long: __builtin_addcll))((x), (y), (carry), (out_carry)) + +static inline uint32_t CRYPTO_addc_u32(uint32_t x, uint32_t y, uint32_t carry, + uint32_t *out_carry) { + assert(carry <= 1); + return CRYPTO_GENERIC_ADDC(x, y, carry, out_carry); +} + +static inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry, + uint64_t *out_carry) { + assert(carry <= 1); + return CRYPTO_GENERIC_ADDC(x, y, carry, out_carry); +} + +#else + +static inline uint32_t CRYPTO_addc_u32(uint32_t x, uint32_t y, uint32_t carry, + uint32_t *out_carry) { + assert(carry <= 1); + uint64_t ret = carry; + ret += (uint64_t)x + y; + *out_carry = (uint32_t)(ret >> 32); + return (uint32_t)ret; +} + +static inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry, + uint64_t *out_carry) { + assert(carry <= 1); +#if defined(BORINGSSL_HAS_UINT128) + uint128_t ret = carry; + ret += (uint128_t)x + y; + *out_carry = (uint64_t)(ret >> 64); + return (uint64_t)ret; +#else + x += carry; + carry = x < carry; + uint64_t ret = x + y; + carry += ret < x; + *out_carry = carry; + return ret; +#endif +} +#endif + +// CRYPTO_subc_* returns |x - y - borrow|, and sets |*out_borrow| to the borrow +// bit. |borrow| must be zero or one. +#if OPENSSL_HAS_BUILTIN(__builtin_subc) + +#define CRYPTO_GENERIC_SUBC(x, y, borrow, out_borrow) \ + (_Generic((x), \ + unsigned: __builtin_subc, \ + unsigned long: __builtin_subcl, \ + unsigned long long: __builtin_subcll))((x), (y), (borrow), (out_borrow)) + +static inline uint32_t CRYPTO_subc_u32(uint32_t x, uint32_t y, uint32_t borrow, + uint32_t *out_borrow) { + assert(borrow <= 1); + return CRYPTO_GENERIC_SUBC(x, y, borrow, out_borrow); +} + +static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, + uint64_t *out_borrow) { + assert(borrow <= 1); + return CRYPTO_GENERIC_SUBC(x, y, borrow, out_borrow); +} + +#else + +static inline uint32_t CRYPTO_subc_u32(uint32_t x, uint32_t y, uint32_t borrow, + uint32_t *out_borrow) { + assert(borrow <= 1); + uint32_t ret = x - y - borrow; + *out_borrow = (x < y) | ((x == y) & borrow); + return ret; +} + +static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, + uint64_t *out_borrow) { + assert(borrow <= 1); + uint64_t ret = x - y - borrow; + *out_borrow = (x < y) | ((x == y) & borrow); + return ret; +} +#endif + +#if defined(OPENSSL_64_BIT) +#define CRYPTO_addc_w CRYPTO_addc_u64 +#define CRYPTO_subc_w CRYPTO_subc_u64 +#else +#define CRYPTO_addc_w CRYPTO_addc_u32 +#define CRYPTO_subc_w CRYPTO_subc_u32 +#endif + + // FIPS functions. #if defined(AWSLC_FIPS) From 1dee03276302672650d0e3442aace459b4700969 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Wed, 29 Nov 2023 16:38:01 -0500 Subject: [PATCH 06/10] Add a value barrier in p224_select_point Clang seems to be undoing the constant-time code here. This is another constant-time table lookup, so this is more of the usual problem. Found with the valgrind-based tooling. I didn't switch this to constant_time_conditional_memxor since we still haven't figured out https://crbug.com/boringssl/655, but we definitely need some kind of abstraction for this pattern. Change-Id: Ic11873b23cde31375ac1a326ed09ac1ca53ec913 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64310 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 4b9dd97dd7d2d8b0b34cfc9af446efa9b61118ee) Commit was changed to use OPENSSL_STATIC_ASSERT and crypto_word_t_is_too_small in AWS-LC. --- crypto/fipsmodule/ec/p224-64.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crypto/fipsmodule/ec/p224-64.c b/crypto/fipsmodule/ec/p224-64.c index f21093d2cf..6a550498ef 100644 --- a/crypto/fipsmodule/ec/p224-64.c +++ b/crypto/fipsmodule/ec/p224-64.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -836,12 +837,12 @@ static void p224_select_point(const uint64_t idx, size_t size, for (size_t i = 0; i < size; i++) { const p224_limb *inlimbs = &pre_comp[i][0][0]; - uint64_t mask = i ^ idx; - mask |= mask >> 4; - mask |= mask >> 2; - mask |= mask >> 1; - mask &= 1; - mask--; + OPENSSL_STATIC_ASSERT(sizeof(uint64_t) <= sizeof(crypto_word_t), + crypto_word_t_is_too_small); + OPENSSL_STATIC_ASSERT(sizeof(size_t) <= sizeof(crypto_word_t), + crypto_word_t_is_too_small); + // Without a value barrier, Clang adds a branch here. + uint64_t mask = value_barrier_w(constant_time_eq_w(i, idx)); for (size_t j = 0; j < 4 * 3; j++) { outlimbs[j] |= inlimbs[j] & mask; } From 124c480030a678e235687b11985ce1bda42dfcd2 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Sun, 19 Nov 2023 10:28:36 -0500 Subject: [PATCH 07/10] Remove X509_VERIFY_PARAM names The getter and setter are never used, largely because named parameters don't do anything. The field only exists for X509_VERIFY_PARAM_lookup, where we have to cast away const because the library expects to have to free the string. Just replace X509_VERIFY_PARAM_lookup with a handful of strcmp calls. As part of this, merge the pkcs7 and smime_sign entries. They were identical. Update-Note: Removed some unused functions. Change-Id: If4eaad52b50d28b83335f6b545af81063e0756d7 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64135 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 790f96bdb549d4dd81a88f0a1fd2fe466b712d97) --- crypto/x509/internal.h | 1 - crypto/x509/x509_vpm.c | 124 ++++++++++++++++++----------------------- include/openssl/x509.h | 6 +- 3 files changed, 56 insertions(+), 75 deletions(-) diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 080b69b342..1fb5b7d580 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h @@ -247,7 +247,6 @@ struct X509_crl_st { } /* X509_CRL */; struct X509_VERIFY_PARAM_st { - char *name; int64_t check_time; // POSIX time to use unsigned long inh_flags; // Inheritance flags unsigned long flags; // Various verify flags diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 7ef3cd8ed7..73d7d87860 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -131,7 +131,6 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param) { if (!param) { return; } - param->name = NULL; param->purpose = 0; param->trust = 0; // param->inh_flags = X509_VP_FLAG_DEFAULT; @@ -385,17 +384,6 @@ static int int_x509_param_set1_ip(unsigned char **pdest, size_t *pdestlen, return 1; } -int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) { - if (param->name) { - OPENSSL_free(param->name); - } - param->name = OPENSSL_strdup(name); - if (param->name) { - return 1; - } - return 0; -} - int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) { param->flags |= flags; if (flags & X509_V_FLAG_POLICY_MASK) { @@ -538,68 +526,64 @@ int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) { return param->depth; } -const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) { - return param->name; -} - #define vpm_empty_id NULL, 0U, NULL, NULL, 0, NULL, 0, 0 -// Default verify parameters: these are used for various applications and can -// be overridden by the user specified table. NB: the 'name' field *must* be -// in alphabetical order because it will be searched using OBJ_search. - -static const X509_VERIFY_PARAM default_table[] = { - {(char *)"default", // X509 default parameters - 0, // Check time - 0, // internal flags - X509_V_FLAG_TRUSTED_FIRST, // flags - 0, // purpose - 0, // trust - 100, // depth - NULL, // policies - vpm_empty_id}, - {(char *)"pkcs7", // S/MIME sign parameters - 0, // Check time - 0, // internal flags - 0, // flags - X509_PURPOSE_SMIME_SIGN, // purpose - X509_TRUST_EMAIL, // trust - -1, // depth - NULL, // policies - vpm_empty_id}, - {(char *)"smime_sign", // S/MIME sign parameters - 0, // Check time - 0, // internal flags - 0, // flags - X509_PURPOSE_SMIME_SIGN, // purpose - X509_TRUST_EMAIL, // trust - -1, // depth - NULL, // policies - vpm_empty_id}, - {(char *)"ssl_client", // SSL/TLS client parameters - 0, // Check time - 0, // internal flags - 0, // flags - X509_PURPOSE_SSL_CLIENT, // purpose - X509_TRUST_SSL_CLIENT, // trust - -1, // depth - NULL, // policies - vpm_empty_id}, - {(char *)"ssl_server", // SSL/TLS server parameters - 0, // Check time - 0, // internal flags - 0, // flags - X509_PURPOSE_SSL_SERVER, // purpose - X509_TRUST_SSL_SERVER, // trust - -1, // depth - NULL, // policies - vpm_empty_id}}; +static const X509_VERIFY_PARAM kDefaultParam = { + /*check_time=*/0, + /*inh_flags=*/0, + /*flags=*/X509_V_FLAG_TRUSTED_FIRST, + /*purpose=*/0, + /*trust=*/0, + /*depth=*/100, + /*policies=*/NULL, + vpm_empty_id}; + +static const X509_VERIFY_PARAM kSMIMESignParam = { + /*check_time=*/0, + /*inh_flags=*/0, + /*flags=*/0, + /*purpose=*/X509_PURPOSE_SMIME_SIGN, + /*trust=*/X509_TRUST_EMAIL, + /*depth=*/-1, + /*policies=*/NULL, + vpm_empty_id}; + +static const X509_VERIFY_PARAM kSSLClientParam = { + /*check_time=*/0, + /*inh_flags=*/0, + /*flags=*/0, + /*purpose=*/X509_PURPOSE_SSL_CLIENT, + /*trust=*/X509_TRUST_SSL_CLIENT, + /*depth=*/-1, + /*policies=*/NULL, + vpm_empty_id}; + +static const X509_VERIFY_PARAM kSSLServerParam = { + /*check_time=*/0, + /*inh_flags=*/0, + /*flags=*/0, + /*purpose=*/X509_PURPOSE_SSL_SERVER, + /*trust=*/X509_TRUST_SSL_SERVER, + /*depth=*/-1, + /*policies=*/NULL, + vpm_empty_id}; const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(default_table); i++) { - if (strcmp(default_table[i].name, name) == 0) { - return &default_table[i]; - } + if (strcmp(name, "default") == 0) { + return &kDefaultParam; + } + if (strcmp(name, "pkcs7") == 0) { + // PKCS#7 and S/MIME signing use the same defaults. + return &kSMIMESignParam; + } + if (strcmp(name, "smime_sign") == 0) { + return &kSMIMESignParam; + } + if (strcmp(name, "ssl_client") == 0) { + return &kSSLClientParam; + } + if (strcmp(name, "ssl_server") == 0) { + return &kSSLServerParam; } return NULL; } diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 1f20ce8d4a..fac1b4545b 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -3321,8 +3321,6 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from); OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, const X509_VERIFY_PARAM *from); -OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, - const char *name); OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, @@ -3420,9 +3418,9 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc); OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); -OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name( - const X509_VERIFY_PARAM *param); +// X509_VERIFY_PARAM_lookup returns a pre-defined |X509_VERIFY_PARAM| named by +// |name|, or NULL if no such name is defined. OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup( const char *name); From 32f0de91cadba5780f27457137daa94928ee47fb Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 20 Nov 2023 23:53:04 -0500 Subject: [PATCH 08/10] Simplify X509_VERIFY_PARAM_new and X509_VERIFY_PARAM_free Although new and free share a zero function, most of the function is irrelevant to both (either because we're about to free the object or have allocated it with zalloc), or only one of them. While I'm here, remove some unnecessary NULL checks guarding free functions. Change-Id: I9906ebc16c931f51b6341958bcf0a10426a1211b Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64136 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 9d479673ccd027eaee60e4c382ed4a463d471a96) --- crypto/x509/x509_vpm.c | 52 +++++++++--------------------------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 73d7d87860..67c0d2f274 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -74,8 +74,6 @@ static void str_free(char *s) { OPENSSL_free(s); } -#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) - static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode, const char *name, size_t namelen) { char *copy; @@ -94,7 +92,7 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode, } if (mode == SET_HOST && param->hosts) { - string_stack_free(param->hosts); + sk_OPENSSL_STRING_pop_free(param->hosts, str_free); param->hosts = NULL; } // OpenSSL returns 1 when trying to set or add an empty name. This is also a @@ -127,47 +125,15 @@ static int int_x509_param_set_hosts(X509_VERIFY_PARAM *param, int mode, return 1; } -static void x509_verify_param_zero(X509_VERIFY_PARAM *param) { - if (!param) { - return; - } - param->purpose = 0; - param->trust = 0; - // param->inh_flags = X509_VP_FLAG_DEFAULT; - param->inh_flags = 0; - param->flags = 0; - param->depth = -1; - if (param->policies) { - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - param->policies = NULL; - } - if (param->hosts) { - string_stack_free(param->hosts); - param->hosts = NULL; - } - if (param->peername) { - OPENSSL_free(param->peername); - param->peername = NULL; - } - if (param->email) { - OPENSSL_free(param->email); - param->email = NULL; - param->emaillen = 0; - } - if (param->ip) { - OPENSSL_free(param->ip); - param->ip = NULL; - param->iplen = 0; - } - param->poison = 0; -} - X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) { X509_VERIFY_PARAM *param = OPENSSL_zalloc(sizeof(X509_VERIFY_PARAM)); if (!param) { return NULL; } - x509_verify_param_zero(param); + param->depth = -1; + // TODO(crbug.com/boringssl/441): This line was commented out. Figure out what + // this was for: + // param->inh_flags = X509_VP_FLAG_DEFAULT; return param; } @@ -175,7 +141,11 @@ void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) { if (param == NULL) { return; } - x509_verify_param_zero(param); + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + sk_OPENSSL_STRING_pop_free(param->hosts, str_free); + OPENSSL_free(param->peername); + OPENSSL_free(param->email); + OPENSSL_free(param->ip); OPENSSL_free(param); } @@ -278,7 +248,7 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, // Copy the host flags if and only if we're copying the host list if (test_x509_verify_param_copy(hosts, NULL)) { if (dest->hosts) { - string_stack_free(dest->hosts); + sk_OPENSSL_STRING_pop_free(dest->hosts, str_free); dest->hosts = NULL; } if (src->hosts) { From ae49b31c492861c0c8236b91808bfd7c6debd454 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 20 Nov 2023 23:41:55 -0500 Subject: [PATCH 09/10] Merge crypto/x509v3 into crypto/x509 The public headers are not yet merged. That will be doen in the subsequent CL. This required teaching make_errors.go that x509v3 are found elsewhere, also to skip irrelevant OPENSSL_DECLARE_ERROR_REASON calls. Change-Id: Ic40de51f9a5325acd60262c614924dc3407b800c Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64137 Commit-Queue: David Benjamin Reviewed-by: Bob Beck (cherry picked from commit 861cb31975b68abd0b6ed7d0dd37213b17385bab) --- crypto/CMakeLists.txt | 76 +++++------ crypto/x509/asn1_gen.c | 1 - crypto/{x509v3 => x509}/ext_dat.h | 0 crypto/x509/internal.h | 113 ++++++++++++++++ crypto/x509/policy.c | 1 - crypto/{x509v3 => x509}/tab_test.cc | 0 crypto/{x509v3 => x509}/v3_akey.c | 0 crypto/{x509v3 => x509}/v3_akeya.c | 0 crypto/{x509v3 => x509}/v3_alt.c | 1 - crypto/{x509v3 => x509}/v3_bcons.c | 0 crypto/{x509v3 => x509}/v3_bitst.c | 0 crypto/{x509v3 => x509}/v3_conf.c | 1 - crypto/{x509v3 => x509}/v3_cpols.c | 0 crypto/{x509v3 => x509}/v3_crld.c | 1 - crypto/{x509v3 => x509}/v3_enum.c | 0 crypto/{x509v3 => x509}/v3_extku.c | 0 crypto/{x509v3 => x509}/v3_genn.c | 0 crypto/{x509v3 => x509}/v3_ia5.c | 0 crypto/{x509v3 => x509}/v3_info.c | 0 crypto/{x509v3 => x509}/v3_int.c | 0 crypto/{x509v3 => x509}/v3_lib.c | 3 +- crypto/{x509v3 => x509}/v3_ncons.c | 2 +- crypto/{x509v3 => x509}/v3_ocsp.c | 0 crypto/{x509v3 => x509}/v3_pcons.c | 0 crypto/{x509v3 => x509}/v3_pmaps.c | 0 crypto/{x509v3 => x509}/v3_prn.c | 0 crypto/{x509v3 => x509}/v3_purp.c | 1 - crypto/{x509v3 => x509}/v3_skey.c | 1 - crypto/{x509v3 => x509}/v3_utl.c | 0 crypto/x509/x509_cmp.c | 1 - crypto/x509/x509_set.c | 1 - crypto/x509/x509_test.cc | 1 - crypto/x509/x509_trs.c | 1 - crypto/x509/x509_vfy.c | 1 - crypto/x509/x509_vpm.c | 1 - crypto/x509v3/internal.h | 195 ---------------------------- fuzz/cert.cc | 2 +- util/make_errors.go | 16 ++- 38 files changed, 166 insertions(+), 254 deletions(-) rename crypto/{x509v3 => x509}/ext_dat.h (100%) rename crypto/{x509v3 => x509}/tab_test.cc (100%) rename crypto/{x509v3 => x509}/v3_akey.c (100%) rename crypto/{x509v3 => x509}/v3_akeya.c (100%) rename crypto/{x509v3 => x509}/v3_alt.c (99%) rename crypto/{x509v3 => x509}/v3_bcons.c (100%) rename crypto/{x509v3 => x509}/v3_bitst.c (100%) rename crypto/{x509v3 => x509}/v3_conf.c (99%) rename crypto/{x509v3 => x509}/v3_cpols.c (100%) rename crypto/{x509v3 => x509}/v3_crld.c (99%) rename crypto/{x509v3 => x509}/v3_enum.c (100%) rename crypto/{x509v3 => x509}/v3_extku.c (100%) rename crypto/{x509v3 => x509}/v3_genn.c (100%) rename crypto/{x509v3 => x509}/v3_ia5.c (100%) rename crypto/{x509v3 => x509}/v3_info.c (100%) rename crypto/{x509v3 => x509}/v3_int.c (100%) rename crypto/{x509v3 => x509}/v3_lib.c (99%) rename crypto/{x509v3 => x509}/v3_ncons.c (99%) rename crypto/{x509v3 => x509}/v3_ocsp.c (100%) rename crypto/{x509v3 => x509}/v3_pcons.c (100%) rename crypto/{x509v3 => x509}/v3_pmaps.c (100%) rename crypto/{x509v3 => x509}/v3_prn.c (100%) rename crypto/{x509v3 => x509}/v3_purp.c (99%) rename crypto/{x509v3 => x509}/v3_skey.c (99%) rename crypto/{x509v3 => x509}/v3_utl.c (100%) delete mode 100644 crypto/x509v3/internal.h diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index cc9c695748..f58199170a 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -460,7 +460,42 @@ add_library( x509/t_req.c x509/t_x509.c x509/t_x509a.c - x509/x509.c + x509/v3_akey.c + x509/v3_akeya.c + x509/v3_alt.c + x509/v3_bcons.c + x509/v3_bitst.c + x509/v3_conf.c + x509/v3_cpols.c + x509/v3_crld.c + x509/v3_enum.c + x509/v3_extku.c + x509/v3_genn.c + x509/v3_ia5.c + x509/v3_info.c + x509/v3_int.c + x509/v3_lib.c + x509/v3_ncons.c + x509/v3_ocsp.c + x509/v3_pcons.c + x509/v3_pmaps.c + x509/v3_prn.c + x509/v3_purp.c + x509/v3_skey.c + x509/v3_utl.c + x509/x_algor.c + x509/x_all.c + x509/x_attrib.c + x509/x_crl.c + x509/x_exten.c + x509/x_name.c + x509/x_pubkey.c + x509/x_req.c + x509/x_sig.c + x509/x_spki.c + x509/x_val.c + x509/x_x509.c + x509/x_x509a.c x509/x509_att.c x509/x509_cmp.c x509/x509_d2.c @@ -475,46 +510,11 @@ add_library( x509/x509_v3.c x509/x509_vfy.c x509/x509_vpm.c + x509/x509.c x509/x509cset.c x509/x509name.c x509/x509rset.c x509/x509spki.c - x509/x_algor.c - x509/x_all.c - x509/x_attrib.c - x509/x_crl.c - x509/x_exten.c - x509/x_name.c - x509/x_pubkey.c - x509/x_req.c - x509/x_sig.c - x509/x_spki.c - x509/x_val.c - x509/x_x509.c - x509/x_x509a.c - x509v3/v3_akey.c - x509v3/v3_akeya.c - x509v3/v3_alt.c - x509v3/v3_bcons.c - x509v3/v3_bitst.c - x509v3/v3_conf.c - x509v3/v3_cpols.c - x509v3/v3_crld.c - x509v3/v3_enum.c - x509v3/v3_extku.c - x509v3/v3_genn.c - x509v3/v3_ia5.c - x509v3/v3_info.c - x509v3/v3_int.c - x509v3/v3_lib.c - x509v3/v3_ncons.c - x509v3/v3_ocsp.c - x509v3/v3_pcons.c - x509v3/v3_pmaps.c - x509v3/v3_prn.c - x509v3/v3_purp.c - x509v3/v3_skey.c - x509v3/v3_utl.c decrepit/bio/base64_bio.c decrepit/blowfish/blowfish.c decrepit/cast/cast.c @@ -765,9 +765,9 @@ if(BUILD_TESTING) test/file_test_gtest.cc thread_test.cc trust_token/trust_token_test.cc + x509/tab_test.cc x509/x509_test.cc x509/x509_time_test.cc - x509v3/tab_test.cc decrepit/blowfish/blowfish_test.cc decrepit/cast/cast_test.cc decrepit/cfb/cfb_test.cc diff --git a/crypto/x509/asn1_gen.c b/crypto/x509/asn1_gen.c index 321f63bec0..b75a5feb9a 100644 --- a/crypto/x509/asn1_gen.c +++ b/crypto/x509/asn1_gen.c @@ -69,7 +69,6 @@ #include "../conf/internal.h" #include "../internal.h" -#include "../x509v3/internal.h" #include "internal.h" diff --git a/crypto/x509v3/ext_dat.h b/crypto/x509/ext_dat.h similarity index 100% rename from crypto/x509v3/ext_dat.h rename to crypto/x509/ext_dat.h diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 1fb5b7d580..43f4966612 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h @@ -62,6 +62,7 @@ #include #include #include +#include #include "../asn1/internal.h" @@ -428,6 +429,118 @@ int X509_policy_check(const STACK_OF(X509) *certs, // one internal project and rust-openssl, who use it by mistake. int x509_check_issued_with_callback(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); +// x509v3_bytes_to_hex encodes |len| bytes from |in| to hex and returns a +// newly-allocated NUL-terminated string containing the result, or NULL on +// allocation error. +// +// This function was historically named |hex_to_string| in OpenSSL. Despite the +// name, |hex_to_string| converted to hex. +OPENSSL_EXPORT char *x509v3_bytes_to_hex(const uint8_t *in, size_t len); + +// x509v3_hex_string_to_bytes decodes |str| in hex and returns a newly-allocated +// array containing the result, or NULL on error. On success, it sets |*len| to +// the length of the result. Colon separators between bytes in the input are +// allowed and ignored. +// +// This function was historically named |string_to_hex| in OpenSSL. Despite the +// name, |string_to_hex| converted from hex. +unsigned char *x509v3_hex_to_bytes(const char *str, size_t *len); + +// x509v3_conf_name_matches returns one if |name| is equal to |cmp| or begins +// with |cmp| followed by '.', and zero otherwise. +int x509v3_conf_name_matches(const char *name, const char *cmp); + +// x509v3_looks_like_dns_name returns one if |in| looks like a DNS name and zero +// otherwise. +OPENSSL_EXPORT int x509v3_looks_like_dns_name(const unsigned char *in, + size_t len); + +// x509v3_cache_extensions fills in a number of fields relating to X.509 +// extensions in |x|. It returns one on success and zero if some extensions were +// invalid. +OPENSSL_EXPORT int x509v3_cache_extensions(X509 *x); + +// x509v3_a2i_ipadd decodes |ipasc| as an IPv4 or IPv6 address. IPv6 addresses +// use colon-separated syntax while IPv4 addresses use dotted decimal syntax. If +// it decodes an IPv4 address, it writes the result to the first four bytes of +// |ipout| and returns four. If it decodes an IPv6 address, it writes the result +// to all 16 bytes of |ipout| and returns 16. Otherwise, it returns zero. +int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc); + +// A |BIT_STRING_BITNAME| is used to contain a list of bit names. +typedef struct { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +// x509V3_add_value_asn1_string appends a |CONF_VALUE| with the specified name +// and value to |*extlist|. if |*extlist| is NULL, it sets |*extlist| to a +// newly-allocated |STACK_OF(CONF_VALUE)| first. It returns one on success and +// zero on error. +int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_NAME_from_section adds attributes to |nm| by interpreting the +// key/value pairs in |dn_sk|. It returns one on success and zero on error. +// |chtype|, which should be one of |MBSTRING_*| constants, determines the +// character encoding used to interpret values. +int X509V3_NAME_from_section(X509_NAME *nm, const STACK_OF(CONF_VALUE) *dn_sk, + int chtype); + +// X509V3_bool_from_string decodes |str| as a boolean. On success, it returns +// one and sets |*out_bool| to resulting value. Otherwise, it returns zero. +int X509V3_bool_from_string(const char *str, ASN1_BOOLEAN *out_bool); + +// X509V3_get_value_bool decodes |value| as a boolean. On success, it returns +// one and sets |*out_bool| to the resulting value. Otherwise, it returns zero. +int X509V3_get_value_bool(const CONF_VALUE *value, ASN1_BOOLEAN *out_bool); + +// X509V3_get_value_int decodes |value| as an integer. On success, it returns +// one and sets |*aint| to the resulting value. Otherwise, it returns zero. If +// |*aint| was non-NULL at the start of the function, it frees the previous +// value before writing a new one. +int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); + +// X509V3_get_section behaves like |NCONF_get_section| but queries |ctx|'s +// config database. +const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx, + const char *section); + +// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to +// |*extlist|. It returns one on success and zero on error. If |*extlist| is +// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| +// containing the result. Either |name| or |value| may be NULL to omit the +// field. +// +// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the +// function returns. +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value +// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); + +// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string +// representation of |aint|. Note this string representation may be decimal or +// hexadecimal, depending on the size of |aint|. +int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); + +#define X509V3_conf_err(val) \ + ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ + ",value:", (val)->value); + +// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero +// value otherwise. Note this function does not provide a comparison suitable +// for sorting. +// +// This function is exported for testing. +OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, + const GENERAL_NAME *b); + #if defined(__cplusplus) } // extern C diff --git a/crypto/x509/policy.c b/crypto/x509/policy.c index 6390fe8795..96aa9b572b 100644 --- a/crypto/x509/policy.c +++ b/crypto/x509/policy.c @@ -22,7 +22,6 @@ #include #include "../internal.h" -#include "../x509v3/internal.h" #include "internal.h" diff --git a/crypto/x509v3/tab_test.cc b/crypto/x509/tab_test.cc similarity index 100% rename from crypto/x509v3/tab_test.cc rename to crypto/x509/tab_test.cc diff --git a/crypto/x509v3/v3_akey.c b/crypto/x509/v3_akey.c similarity index 100% rename from crypto/x509v3/v3_akey.c rename to crypto/x509/v3_akey.c diff --git a/crypto/x509v3/v3_akeya.c b/crypto/x509/v3_akeya.c similarity index 100% rename from crypto/x509v3/v3_akeya.c rename to crypto/x509/v3_akeya.c diff --git a/crypto/x509v3/v3_alt.c b/crypto/x509/v3_alt.c similarity index 99% rename from crypto/x509v3/v3_alt.c rename to crypto/x509/v3_alt.c index e3c15f5b99..1d80d71318 100644 --- a/crypto/x509v3/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -63,7 +63,6 @@ #include #include -#include "../x509/internal.h" #include "internal.h" diff --git a/crypto/x509v3/v3_bcons.c b/crypto/x509/v3_bcons.c similarity index 100% rename from crypto/x509v3/v3_bcons.c rename to crypto/x509/v3_bcons.c diff --git a/crypto/x509v3/v3_bitst.c b/crypto/x509/v3_bitst.c similarity index 100% rename from crypto/x509v3/v3_bitst.c rename to crypto/x509/v3_bitst.c diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509/v3_conf.c similarity index 99% rename from crypto/x509v3/v3_conf.c rename to crypto/x509/v3_conf.c index d42523820c..a7eb9f0334 100644 --- a/crypto/x509v3/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -69,7 +69,6 @@ #include #include "../internal.h" -#include "../x509/internal.h" #include "internal.h" static int v3_check_critical(const char **value); diff --git a/crypto/x509v3/v3_cpols.c b/crypto/x509/v3_cpols.c similarity index 100% rename from crypto/x509v3/v3_cpols.c rename to crypto/x509/v3_cpols.c diff --git a/crypto/x509v3/v3_crld.c b/crypto/x509/v3_crld.c similarity index 99% rename from crypto/x509v3/v3_crld.c rename to crypto/x509/v3_crld.c index 4162c3538f..dcb03f9f73 100644 --- a/crypto/x509v3/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -65,7 +65,6 @@ #include #include -#include "../x509/internal.h" #include "internal.h" diff --git a/crypto/x509v3/v3_enum.c b/crypto/x509/v3_enum.c similarity index 100% rename from crypto/x509v3/v3_enum.c rename to crypto/x509/v3_enum.c diff --git a/crypto/x509v3/v3_extku.c b/crypto/x509/v3_extku.c similarity index 100% rename from crypto/x509v3/v3_extku.c rename to crypto/x509/v3_extku.c diff --git a/crypto/x509v3/v3_genn.c b/crypto/x509/v3_genn.c similarity index 100% rename from crypto/x509v3/v3_genn.c rename to crypto/x509/v3_genn.c diff --git a/crypto/x509v3/v3_ia5.c b/crypto/x509/v3_ia5.c similarity index 100% rename from crypto/x509v3/v3_ia5.c rename to crypto/x509/v3_ia5.c diff --git a/crypto/x509v3/v3_info.c b/crypto/x509/v3_info.c similarity index 100% rename from crypto/x509v3/v3_info.c rename to crypto/x509/v3_info.c diff --git a/crypto/x509v3/v3_int.c b/crypto/x509/v3_int.c similarity index 100% rename from crypto/x509v3/v3_int.c rename to crypto/x509/v3_int.c diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509/v3_lib.c similarity index 99% rename from crypto/x509v3/v3_lib.c rename to crypto/x509/v3_lib.c index f31bd36527..23dffe73f5 100644 --- a/crypto/x509v3/v3_lib.c +++ b/crypto/x509/v3_lib.c @@ -66,9 +66,10 @@ #include #include -#include "../x509/internal.h" +#include "internal.h" #include "ext_dat.h" + static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; static int ext_stack_cmp(const X509V3_EXT_METHOD *const *a, diff --git a/crypto/x509v3/v3_ncons.c b/crypto/x509/v3_ncons.c similarity index 99% rename from crypto/x509v3/v3_ncons.c rename to crypto/x509/v3_ncons.c index ac9559f5c6..037084e9a6 100644 --- a/crypto/x509v3/v3_ncons.c +++ b/crypto/x509/v3_ncons.c @@ -65,7 +65,7 @@ #include #include "../internal.h" -#include "../x509/internal.h" +#include "internal.h" static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, diff --git a/crypto/x509v3/v3_ocsp.c b/crypto/x509/v3_ocsp.c similarity index 100% rename from crypto/x509v3/v3_ocsp.c rename to crypto/x509/v3_ocsp.c diff --git a/crypto/x509v3/v3_pcons.c b/crypto/x509/v3_pcons.c similarity index 100% rename from crypto/x509v3/v3_pcons.c rename to crypto/x509/v3_pcons.c diff --git a/crypto/x509v3/v3_pmaps.c b/crypto/x509/v3_pmaps.c similarity index 100% rename from crypto/x509v3/v3_pmaps.c rename to crypto/x509/v3_pmaps.c diff --git a/crypto/x509v3/v3_prn.c b/crypto/x509/v3_prn.c similarity index 100% rename from crypto/x509v3/v3_prn.c rename to crypto/x509/v3_prn.c diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509/v3_purp.c similarity index 99% rename from crypto/x509v3/v3_purp.c rename to crypto/x509/v3_purp.c index 2aa21119a7..f6c4dfd8e5 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -66,7 +66,6 @@ #include #include "../internal.h" -#include "../x509/internal.h" #include "internal.h" #define V1_ROOT (EXFLAG_V1 | EXFLAG_SS) diff --git a/crypto/x509v3/v3_skey.c b/crypto/x509/v3_skey.c similarity index 99% rename from crypto/x509v3/v3_skey.c rename to crypto/x509/v3_skey.c index caa7fe50a0..eff6d545f4 100644 --- a/crypto/x509v3/v3_skey.c +++ b/crypto/x509/v3_skey.c @@ -64,7 +64,6 @@ #include #include -#include "../x509/internal.h" #include "internal.h" diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509/v3_utl.c similarity index 100% rename from crypto/x509v3/v3_utl.c rename to crypto/x509/v3_utl.c diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 52d6ac33ae..df036dc8b6 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -66,7 +66,6 @@ #include #include "../internal.h" -#include "../x509v3/internal.h" #include "internal.h" diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c index 33307896f3..5c593eb865 100644 --- a/crypto/x509/x509_set.c +++ b/crypto/x509/x509_set.c @@ -60,7 +60,6 @@ #include #include -#include "../x509v3/internal.h" #include "internal.h" #include "openssl/x509v3.h" diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index ea861db1c5..cb3ba972ec 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -38,7 +38,6 @@ #include "../evp_extra/internal.h" #include "../internal.h" #include "../test/test_util.h" -#include "../x509v3/internal.h" #if defined(OPENSSL_THREADS) #include diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index 5f315a7028..6aa40830bc 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -59,7 +59,6 @@ #include #include -#include "../x509v3/internal.h" #include "internal.h" diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 7bba05c7bb..227f2cf95d 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -68,7 +68,6 @@ #include #include "../internal.h" -#include "../x509v3/internal.h" #include "internal.h" static CRYPTO_EX_DATA_CLASS g_ex_data_class = diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 67c0d2f274..52d564b674 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -63,7 +63,6 @@ #include #include "../internal.h" -#include "../x509v3/internal.h" #include "internal.h" diff --git a/crypto/x509v3/internal.h b/crypto/x509v3/internal.h deleted file mode 100644 index 2ae6bce215..0000000000 --- a/crypto/x509v3/internal.h +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * 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 above 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 acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED 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 OpenSSL PROJECT OR - * ITS 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. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef OPENSSL_HEADER_X509V3_INTERNAL_H -#define OPENSSL_HEADER_X509V3_INTERNAL_H - -#include - -#include -#include -#include - -// TODO(davidben): Merge x509 and x509v3. This include is needed because some -// internal typedefs are shared between the two, but the two modules depend on -// each other circularly. -#include "../x509/internal.h" - -#if defined(__cplusplus) -extern "C" { -#endif - - -// x509v3_bytes_to_hex encodes |len| bytes from |in| to hex and returns a -// newly-allocated NUL-terminated string containing the result, or NULL on -// allocation error. -// -// This function was historically named |hex_to_string| in OpenSSL. Despite the -// name, |hex_to_string| converted to hex. -OPENSSL_EXPORT char *x509v3_bytes_to_hex(const uint8_t *in, size_t len); - -// x509v3_hex_string_to_bytes decodes |str| in hex and returns a newly-allocated -// array containing the result, or NULL on error. On success, it sets |*len| to -// the length of the result. Colon separators between bytes in the input are -// allowed and ignored. -// -// This function was historically named |string_to_hex| in OpenSSL. Despite the -// name, |string_to_hex| converted from hex. -unsigned char *x509v3_hex_to_bytes(const char *str, size_t *len); - -// x509v3_conf_name_matches returns one if |name| is equal to |cmp| or begins -// with |cmp| followed by '.', and zero otherwise. -int x509v3_conf_name_matches(const char *name, const char *cmp); - -// x509v3_looks_like_dns_name returns one if |in| looks like a DNS name and zero -// otherwise. -OPENSSL_EXPORT int x509v3_looks_like_dns_name(const unsigned char *in, - size_t len); - -// x509v3_cache_extensions fills in a number of fields relating to X.509 -// extensions in |x|. It returns one on success and zero if some extensions were -// invalid. -OPENSSL_EXPORT int x509v3_cache_extensions(X509 *x); - -// x509v3_a2i_ipadd decodes |ipasc| as an IPv4 or IPv6 address. IPv6 addresses -// use colon-separated syntax while IPv4 addresses use dotted decimal syntax. If -// it decodes an IPv4 address, it writes the result to the first four bytes of -// |ipout| and returns four. If it decodes an IPv6 address, it writes the result -// to all 16 bytes of |ipout| and returns 16. Otherwise, it returns zero. -int x509v3_a2i_ipadd(unsigned char ipout[16], const char *ipasc); - -// A |BIT_STRING_BITNAME| is used to contain a list of bit names. -typedef struct { - int bitnum; - const char *lname; - const char *sname; -} BIT_STRING_BITNAME; - -// x509V3_add_value_asn1_string appends a |CONF_VALUE| with the specified name -// and value to |*extlist|. if |*extlist| is NULL, it sets |*extlist| to a -// newly-allocated |STACK_OF(CONF_VALUE)| first. It returns one on success and -// zero on error. -int x509V3_add_value_asn1_string(const char *name, const ASN1_STRING *value, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_NAME_from_section adds attributes to |nm| by interpreting the -// key/value pairs in |dn_sk|. It returns one on success and zero on error. -// |chtype|, which should be one of |MBSTRING_*| constants, determines the -// character encoding used to interpret values. -int X509V3_NAME_from_section(X509_NAME *nm, const STACK_OF(CONF_VALUE) *dn_sk, - int chtype); - -// X509V3_bool_from_string decodes |str| as a boolean. On success, it returns -// one and sets |*out_bool| to resulting value. Otherwise, it returns zero. -int X509V3_bool_from_string(const char *str, ASN1_BOOLEAN *out_bool); - -// X509V3_get_value_bool decodes |value| as a boolean. On success, it returns -// one and sets |*out_bool| to the resulting value. Otherwise, it returns zero. -int X509V3_get_value_bool(const CONF_VALUE *value, ASN1_BOOLEAN *out_bool); - -// X509V3_get_value_int decodes |value| as an integer. On success, it returns -// one and sets |*aint| to the resulting value. Otherwise, it returns zero. If -// |*aint| was non-NULL at the start of the function, it frees the previous -// value before writing a new one. -int X509V3_get_value_int(const CONF_VALUE *value, ASN1_INTEGER **aint); - -// X509V3_get_section behaves like |NCONF_get_section| but queries |ctx|'s -// config database. -const STACK_OF(CONF_VALUE) *X509V3_get_section(const X509V3_CTX *ctx, - const char *section); - -// X509V3_add_value appends a |CONF_VALUE| containing |name| and |value| to -// |*extlist|. It returns one on success and zero on error. If |*extlist| is -// NULL, it sets |*extlist| to a newly-allocated |STACK_OF(CONF_VALUE)| -// containing the result. Either |name| or |value| may be NULL to omit the -// field. -// -// On failure, if |*extlist| was NULL, |*extlist| will remain NULL when the -// function returns. -int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_bool behaves like |X509V3_add_value| but stores the value -// "TRUE" if |asn1_bool| is non-zero and "FALSE" otherwise. -int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); - -// X509V3_add_value_bool behaves like |X509V3_add_value| but stores a string -// representation of |aint|. Note this string representation may be decimal or -// hexadecimal, depending on the size of |aint|. -int X509V3_add_value_int(const char *name, const ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist); - -#define X509V3_conf_err(val) \ - ERR_add_error_data(6, "section:", (val)->section, ",name:", (val)->name, \ - ",value:", (val)->value); - -// GENERAL_NAME_cmp returns zero if |a| and |b| are equal and a non-zero -// value otherwise. Note this function does not provide a comparison suitable -// for sorting. -// -// This function is exported for testing. -OPENSSL_EXPORT int GENERAL_NAME_cmp(const GENERAL_NAME *a, - const GENERAL_NAME *b); - - -#if defined(__cplusplus) -} // extern C -#endif - -#endif // OPENSSL_HEADER_X509V3_INTERNAL_H diff --git a/fuzz/cert.cc b/fuzz/cert.cc index 548109e55a..e433450c34 100644 --- a/fuzz/cert.cc +++ b/fuzz/cert.cc @@ -16,7 +16,7 @@ #include #include -#include "../crypto/x509v3/internal.h" +#include "../crypto/x509/internal.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { X509 *x509 = d2i_X509(NULL, &buf, len); diff --git a/util/make_errors.go b/util/make_errors.go index 04ace22e0a..fd36b07f16 100644 --- a/util/make_errors.go +++ b/util/make_errors.go @@ -59,6 +59,10 @@ func getLibraryInfo(lib string) libraryInfo { info.sourceDirs = append(info.sourceDirs, filepath.Join("crypto", "hpke")) } + if lib == "x509v3" { + info.sourceDirs = append(info.sourceDirs, filepath.Join("crypto", "x509")) + } + return info } @@ -324,7 +328,7 @@ func assignNewValues(assignments map[string]int, reserved int) { } } -func handleDeclareMacro(line, join, macroName string, m map[string]int) { +func handleDeclareMacro(line, prefix, join, macroName string, m map[string]int) { if i := strings.Index(line, macroName); i >= 0 { contents := line[i+len(macroName):] if i := strings.Index(contents, ")"); i >= 0 { @@ -336,9 +340,11 @@ func handleDeclareMacro(line, join, macroName string, m map[string]int) { if len(args) != 2 { panic("Bad macro line: " + line) } - token := args[0] + join + args[1] - if _, ok := m[token]; !ok { - m[token] = -1 + if args[0] == prefix { + token := args[0] + join + args[1] + if _, ok := m[token]; !ok { + m[token] = -1 + } } } } @@ -357,7 +363,7 @@ func addReasons(reasons map[string]int, filename, prefix string) error { for scanner.Scan() { line := scanner.Text() - handleDeclareMacro(line, "_R_", "OPENSSL_DECLARE_ERROR_REASON(", reasons) + handleDeclareMacro(line, prefix, "_R_", "OPENSSL_DECLARE_ERROR_REASON(", reasons) for len(line) > 0 { i := strings.Index(line, prefix+"_") From cdc51f07e69157ed105ce55769faf61216a7a213 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Mon, 20 Nov 2023 23:59:49 -0500 Subject: [PATCH 10/10] Merge into The headers moved from x509v3 to x509 was redone to avoid unintentionally taking changes we've skipped and keep AWS-LC specific changes. Change-Id: I53147d1f96d1f99909f5c8bda00cefb088677a0e Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/64138 Reviewed-by: Bob Beck Commit-Queue: David Benjamin (cherry picked from commit 58906eab928fe849a55cb846fcd84fb8b64773ed) --- crypto/decrepit/x509/x509_decrepit.c | 2 +- crypto/x509/asn1_gen.c | 1 - crypto/x509/internal.h | 1 - crypto/x509/policy.c | 1 - crypto/x509/t_crl.c | 2 +- crypto/x509/t_req.c | 1 - crypto/x509/t_x509.c | 1 - crypto/x509/tab_test.cc | 2 +- crypto/x509/v3_akey.c | 2 +- crypto/x509/v3_akeya.c | 2 +- crypto/x509/v3_alt.c | 2 +- crypto/x509/v3_bcons.c | 2 +- crypto/x509/v3_bitst.c | 2 +- crypto/x509/v3_conf.c | 1 - crypto/x509/v3_cpols.c | 2 +- crypto/x509/v3_crld.c | 2 +- crypto/x509/v3_enum.c | 2 +- crypto/x509/v3_extku.c | 2 +- crypto/x509/v3_genn.c | 2 +- crypto/x509/v3_ia5.c | 2 +- crypto/x509/v3_info.c | 2 +- crypto/x509/v3_int.c | 2 +- crypto/x509/v3_lib.c | 2 +- crypto/x509/v3_ncons.c | 2 +- crypto/x509/v3_ocsp.c | 2 +- crypto/x509/v3_pcons.c | 2 +- crypto/x509/v3_pmaps.c | 2 +- crypto/x509/v3_prn.c | 2 +- crypto/x509/v3_purp.c | 2 +- crypto/x509/v3_skey.c | 2 +- crypto/x509/v3_utl.c | 2 +- crypto/x509/x509_cmp.c | 1 - crypto/x509/x509_ext.c | 1 - crypto/x509/x509_lu.c | 1 - crypto/x509/x509_test.cc | 1 - crypto/x509/x509_trs.c | 2 +- crypto/x509/x509_v3.c | 1 - crypto/x509/x509_vfy.c | 1 - crypto/x509/x509_vpm.c | 1 - crypto/x509/x_crl.c | 1 - crypto/x509/x_x509.c | 1 - fuzz/conf.cc | 1 - include/openssl/x509.h | 962 +++++++++++++++++++++- include/openssl/x509v3.h | 1124 +------------------------- include/openssl/x509v3_errors.h | 124 +++ ssl/ssl_test.cc | 1 - ssl/ssl_x509.cc | 1 - util/make_errors.go | 1 + 48 files changed, 1127 insertions(+), 1154 deletions(-) create mode 100644 include/openssl/x509v3_errors.h diff --git a/crypto/decrepit/x509/x509_decrepit.c b/crypto/decrepit/x509/x509_decrepit.c index 9f845595b6..2fd91a7b15 100644 --- a/crypto/decrepit/x509/x509_decrepit.c +++ b/crypto/decrepit/x509/x509_decrepit.c @@ -12,7 +12,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include #include diff --git a/crypto/x509/asn1_gen.c b/crypto/x509/asn1_gen.c index b75a5feb9a..73a5cc3f0c 100644 --- a/crypto/x509/asn1_gen.c +++ b/crypto/x509/asn1_gen.c @@ -65,7 +65,6 @@ #include #include #include -#include #include "../conf/internal.h" #include "../internal.h" diff --git a/crypto/x509/internal.h b/crypto/x509/internal.h index 43f4966612..282aff79d9 100644 --- a/crypto/x509/internal.h +++ b/crypto/x509/internal.h @@ -62,7 +62,6 @@ #include #include #include -#include #include "../asn1/internal.h" diff --git a/crypto/x509/policy.c b/crypto/x509/policy.c index 96aa9b572b..52039b639f 100644 --- a/crypto/x509/policy.c +++ b/crypto/x509/policy.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/t_crl.c b/crypto/x509/t_crl.c index 1957e3175b..fcb36acdfc 100644 --- a/crypto/x509/t_crl.c +++ b/crypto/x509/t_crl.c @@ -61,7 +61,7 @@ #include #include #include -#include + int X509_CRL_print_fp(FILE *fp, X509_CRL *x) { BIO *b = BIO_new_fp(fp, BIO_NOCLOSE); diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c index e9287d5f3d..3cfab193f3 100644 --- a/crypto/x509/t_req.c +++ b/crypto/x509/t_req.c @@ -62,7 +62,6 @@ #include #include #include -#include #include "internal.h" diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c index 1d71576ccd..9596b65e5a 100644 --- a/crypto/x509/t_x509.c +++ b/crypto/x509/t_x509.c @@ -64,7 +64,6 @@ #include #include #include -#include #include "internal.h" diff --git a/crypto/x509/tab_test.cc b/crypto/x509/tab_test.cc index b5b662fdae..be17b7ad1d 100644 --- a/crypto/x509/tab_test.cc +++ b/crypto/x509/tab_test.cc @@ -60,7 +60,7 @@ #include -#include +#include #include "../internal.h" #include "ext_dat.h" diff --git a/crypto/x509/v3_akey.c b/crypto/x509/v3_akey.c index 2af596af0b..740058dd4b 100644 --- a/crypto/x509/v3_akey.c +++ b/crypto/x509/v3_akey.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_akeya.c b/crypto/x509/v3_akeya.c index f18f4e339e..4a05aae630 100644 --- a/crypto/x509/v3_akeya.c +++ b/crypto/x509/v3_akeya.c @@ -59,7 +59,7 @@ #include #include #include -#include +#include ASN1_SEQUENCE(AUTHORITY_KEYID) = { diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c index 1d80d71318..f61645a77a 100644 --- a/crypto/x509/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_bcons.c b/crypto/x509/v3_bcons.c index e614b8ec69..0808012132 100644 --- a/crypto/x509/v3_bcons.c +++ b/crypto/x509/v3_bcons.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_bitst.c b/crypto/x509/v3_bitst.c index 1201738b55..01245024c6 100644 --- a/crypto/x509/v3_bitst.c +++ b/crypto/x509/v3_bitst.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c index a7eb9f0334..e086c195d7 100644 --- a/crypto/x509/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -66,7 +66,6 @@ #include #include #include -#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c index e66e260b00..746527b269 100644 --- a/crypto/x509/v3_cpols.c +++ b/crypto/x509/v3_cpols.c @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_crld.c b/crypto/x509/v3_crld.c index dcb03f9f73..371fa8d0f1 100644 --- a/crypto/x509/v3_crld.c +++ b/crypto/x509/v3_crld.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_enum.c b/crypto/x509/v3_enum.c index 3143a98d35..3efbca52be 100644 --- a/crypto/x509/v3_enum.c +++ b/crypto/x509/v3_enum.c @@ -58,7 +58,7 @@ #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_extku.c b/crypto/x509/v3_extku.c index d678ac781d..d2a438d403 100644 --- a/crypto/x509/v3_extku.c +++ b/crypto/x509/v3_extku.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_genn.c b/crypto/x509/v3_genn.c index 609c5dae4f..42cd787906 100644 --- a/crypto/x509/v3_genn.c +++ b/crypto/x509/v3_genn.c @@ -59,7 +59,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_ia5.c b/crypto/x509/v3_ia5.c index e0f9e6bfda..d28b85a426 100644 --- a/crypto/x509/v3_ia5.c +++ b/crypto/x509/v3_ia5.c @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include "../internal.h" diff --git a/crypto/x509/v3_info.c b/crypto/x509/v3_info.c index 5e14b76587..eb190de280 100644 --- a/crypto/x509/v3_info.c +++ b/crypto/x509/v3_info.c @@ -65,7 +65,7 @@ #include #include #include -#include +#include static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret); diff --git a/crypto/x509/v3_int.c b/crypto/x509/v3_int.c index 0ca2b5ec25..4f1b3434cb 100644 --- a/crypto/x509/v3_int.c +++ b/crypto/x509/v3_int.c @@ -57,7 +57,7 @@ #include #include -#include +#include static char *i2s_ASN1_INTEGER_cb(const X509V3_EXT_METHOD *method, void *ext) { diff --git a/crypto/x509/v3_lib.c b/crypto/x509/v3_lib.c index 23dffe73f5..7ada228e96 100644 --- a/crypto/x509/v3_lib.c +++ b/crypto/x509/v3_lib.c @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_ncons.c b/crypto/x509/v3_ncons.c index 037084e9a6..31ef58d0d6 100644 --- a/crypto/x509/v3_ncons.c +++ b/crypto/x509/v3_ncons.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/v3_ocsp.c b/crypto/x509/v3_ocsp.c index bb87e5b8f6..60571cb33c 100644 --- a/crypto/x509/v3_ocsp.c +++ b/crypto/x509/v3_ocsp.c @@ -9,7 +9,7 @@ #include -#include +#include #include #include diff --git a/crypto/x509/v3_pcons.c b/crypto/x509/v3_pcons.c index 7b70a4e431..0ab5bad54c 100644 --- a/crypto/x509/v3_pcons.c +++ b/crypto/x509/v3_pcons.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_pmaps.c b/crypto/x509/v3_pmaps.c index cd8efd6d2d..25be453bb9 100644 --- a/crypto/x509/v3_pmaps.c +++ b/crypto/x509/v3_pmaps.c @@ -60,7 +60,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_prn.c b/crypto/x509/v3_prn.c index 6811f40164..f37ae0f42d 100644 --- a/crypto/x509/v3_prn.c +++ b/crypto/x509/v3_prn.c @@ -61,7 +61,7 @@ #include #include #include -#include +#include // Extension printing routines diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index f6c4dfd8e5..26f24a3e4f 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -63,7 +63,7 @@ #include #include #include -#include +#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/v3_skey.c b/crypto/x509/v3_skey.c index eff6d545f4..3d181cec31 100644 --- a/crypto/x509/v3_skey.c +++ b/crypto/x509/v3_skey.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c index f75f171f73..dbeabd0f9b 100644 --- a/crypto/x509/v3_utl.c +++ b/crypto/x509/v3_utl.c @@ -67,7 +67,7 @@ #include #include #include -#include +#include #include "../conf/internal.h" #include "../internal.h" diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index df036dc8b6..d598d6f98b 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -63,7 +63,6 @@ #include #include #include -#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/x509_ext.c b/crypto/x509/x509_ext.c index a8f561d445..e8e79dc78b 100644 --- a/crypto/x509/x509_ext.c +++ b/crypto/x509/x509_ext.c @@ -59,7 +59,6 @@ #include #include #include -#include #include "internal.h" diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index 3bf05461eb..d679493f70 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -60,7 +60,6 @@ #include #include #include -#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc index cb3ba972ec..4e59751114 100644 --- a/crypto/x509/x509_test.cc +++ b/crypto/x509/x509_test.cc @@ -32,7 +32,6 @@ #include #include #include -#include #include "internal.h" #include "../evp_extra/internal.h" diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index 6aa40830bc..d8ab1dc229 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -57,7 +57,7 @@ #include #include #include -#include +#include #include "internal.h" diff --git a/crypto/x509/x509_v3.c b/crypto/x509/x509_v3.c index 0f506c9d19..5001a00a27 100644 --- a/crypto/x509/x509_v3.c +++ b/crypto/x509/x509_v3.c @@ -60,7 +60,6 @@ #include #include #include -#include #include "internal.h" diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 227f2cf95d..aac51c3026 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -65,7 +65,6 @@ #include #include #include -#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 52d564b674..48a71ea637 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -60,7 +60,6 @@ #include #include #include -#include #include "../internal.h" #include "internal.h" diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c index fe78c0c6ed..fd0752d5fd 100644 --- a/crypto/x509/x_crl.c +++ b/crypto/x509/x_crl.c @@ -63,7 +63,6 @@ #include #include #include -#include #include diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index 963d9afd6f..c8e1178a87 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -65,7 +65,6 @@ #include #include #include -#include #include "../asn1/internal.h" #include "../internal.h" diff --git a/fuzz/conf.cc b/fuzz/conf.cc index 9b810e1029..f2bd21b66b 100644 --- a/fuzz/conf.cc +++ b/fuzz/conf.cc @@ -15,7 +15,6 @@ #include #include #include -#include #include diff --git a/include/openssl/x509.h b/include/openssl/x509.h index fac1b4545b..a04be3de3b 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h @@ -63,16 +63,21 @@ #ifndef OPENSSL_HEADER_X509_H #define OPENSSL_HEADER_X509_H -#include #include + +#include + +#include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -80,7 +85,7 @@ #include #include #include -#include +#include // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -3424,6 +3429,948 @@ OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup( const char *name); +// Forward reference +struct v3_ext_method; +struct v3_ext_ctx; + +// Useful typedefs + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE)(void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V)(const X509V3_EXT_METHOD *method, + void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const X509V3_EXT_METHOD *method, void *ext); +typedef void *(*X509V3_EXT_S2I)(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str); +typedef int (*X509V3_EXT_I2R)(const X509V3_EXT_METHOD *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, const char *str); + +// V3 extension structure + +struct v3_ext_method { + int ext_nid; + int ext_flags; + + // it determines how values of this extension are allocated, released, parsed, + // and marshalled. This must be non-NULL. + ASN1_ITEM_EXP *it; + + // The following functions are ignored in favor of |it|. They are retained in + // the struct only for source compatibility with existing struct definitions. + // + // Only OCSP nonce extensions currently rely on these functions with AWS-LC. + // This is to maintain backwards compatibility with how OCSP nonce extensions + // are handled in OpenSSL. This can't be easily removed because OpenSSL + // considers the OCSP nonce to be "special". + // |X509V3_EXT_add| enforces |it| to be non-NULL, so external users are not + // allowed to use the following functions. + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; + + // The following pair is used for string extensions + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; + + // The following pair is used for multi-valued extensions + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; + + // The following are used for raw extensions + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + + void *usr_data; // Any extension specific data +}; + +DEFINE_STACK_OF(X509V3_EXT_METHOD) + +// ext_flags values + +#define X509V3_EXT_CTX_DEP 0x2 +#define X509V3_EXT_MULTILINE 0x4 + +struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +}; + + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +#define GEN_OTHERNAME 0 +#define GEN_EMAIL 1 +#define GEN_DNS 2 +#define GEN_X400 3 +#define GEN_DIRNAME 4 +#define GEN_EDIPARTY 5 +#define GEN_URI 6 +#define GEN_IPADD 7 +#define GEN_RID 8 + + int type; + union { + char *ptr; + OTHERNAME *otherName; // otherName + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_STRING *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + + // Old names + ASN1_OCTET_STRING *ip; // iPAddress + X509_NAME *dirn; // dirn + ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier + ASN1_OBJECT *rid; // registeredID + } d; +} GENERAL_NAME; + +DEFINE_STACK_OF(GENERAL_NAME) + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +DEFINE_STACK_OF(GENERAL_NAMES) + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; + // If relativename then this contains the full distribution point name + X509_NAME *dpname; +} DIST_POINT_NAME; +// CRLDP_ALL_REASONS is an alias for all existing reasons +#define CRLDP_ALL_REASONS 0x807f + +#define CRL_REASON_NONE (-1) +#define CRL_REASON_UNSPECIFIED 0 +#define CRL_REASON_KEY_COMPROMISE 1 +#define CRL_REASON_CA_COMPROMISE 2 +#define CRL_REASON_AFFILIATION_CHANGED 3 +#define CRL_REASON_SUPERSEDED 4 +#define CRL_REASON_CESSATION_OF_OPERATION 5 +#define CRL_REASON_CERTIFICATE_HOLD 6 +#define CRL_REASON_REMOVE_FROM_CRL 8 +#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +#define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DEFINE_STACK_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DEFINE_STACK_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DEFINE_STACK_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DEFINE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BOOLEAN onlyuser; + ASN1_BOOLEAN onlyCA; + ASN1_BIT_STRING *onlysomereasons; + ASN1_BOOLEAN indirectCRL; + ASN1_BOOLEAN onlyattr; +}; + +// X509_PURPOSE stuff + +#define EXFLAG_BCONS 0x1 +#define EXFLAG_KUSAGE 0x2 +#define EXFLAG_XKUSAGE 0x4 +#define EXFLAG_NSCERT 0x8 + +#define EXFLAG_CA 0x10 +// EXFLAG_SI indicates the certificate is self-issued, i.e. its subject and +// issuer names match. +#define EXFLAG_SI 0x20 +#define EXFLAG_V1 0x40 +#define EXFLAG_INVALID 0x80 +#define EXFLAG_SET 0x100 +#define EXFLAG_CRITICAL 0x200 +// EXFLAG_SS indicates the certificate is likely self-signed. That is, if it is +// self-issued, its authority key identifer (if any) matches itself, and its key +// usage extension (if any) allows certificate signatures. The signature itself +// is not checked in computing this bit. +#define EXFLAG_SS 0x2000 + +#define KU_DIGITAL_SIGNATURE 0x0080 +#define KU_NON_REPUDIATION 0x0040 +#define KU_KEY_ENCIPHERMENT 0x0020 +#define KU_DATA_ENCIPHERMENT 0x0010 +#define KU_KEY_AGREEMENT 0x0008 +#define KU_KEY_CERT_SIGN 0x0004 +#define KU_CRL_SIGN 0x0002 +#define KU_ENCIPHER_ONLY 0x0001 +#define KU_DECIPHER_ONLY 0x8000 + +#define NS_SSL_CLIENT 0x80 +#define NS_SSL_SERVER 0x40 +#define NS_SMIME 0x20 +#define NS_OBJSIGN 0x10 +#define NS_SSL_CA 0x04 +#define NS_SMIME_CA 0x02 +#define NS_OBJSIGN_CA 0x01 +#define NS_ANY_CA (NS_SSL_CA | NS_SMIME_CA | NS_OBJSIGN_CA) + +#define XKU_SSL_SERVER 0x1 +#define XKU_SSL_CLIENT 0x2 +#define XKU_SMIME 0x4 +#define XKU_CODE_SIGN 0x8 +#define XKU_SGC 0x10 +#define XKU_OCSP_SIGN 0x20 +#define XKU_TIMESTAMP 0x40 +#define XKU_DVCS 0x80 +#define XKU_ANYEKU 0x100 + +#define X509_PURPOSE_DYNAMIC 0x1 +#define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; // Default trust ID + int flags; + int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +#define X509_PURPOSE_SSL_CLIENT 1 +#define X509_PURPOSE_SSL_SERVER 2 +#define X509_PURPOSE_NS_SSL_SERVER 3 +#define X509_PURPOSE_SMIME_SIGN 4 +#define X509_PURPOSE_SMIME_ENCRYPT 5 +#define X509_PURPOSE_CRL_SIGN 6 +#define X509_PURPOSE_ANY 7 +#define X509_PURPOSE_OCSP_HELPER 8 +#define X509_PURPOSE_TIMESTAMP_SIGN 9 + +#define X509_PURPOSE_MIN 1 +#define X509_PURPOSE_MAX 9 + +DEFINE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) + +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); + +// i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it +// appends the value to |ret| and returns |ret| on success or NULL on error. If +// it returns NULL, the caller is still responsible for freeing |ret|. If |ret| +// is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| containing the +// result. |method| is ignored. +// +// Do not use this function. This is an internal implementation detail of the +// human-readable print functions. If extracting a SAN list from a certificate, +// look at |gen| directly. +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME( + const X509V3_EXT_METHOD *method, const GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); + +// GENERAL_NAME_print prints a human-readable representation of |gen| to |out|. +// It returns one on success and zero on error. +// +// TODO(davidben): Actually, it just returns one and doesn't check for I/O or +// allocation errors. But it should return zero on error. +OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen); + +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +// i2v_GENERAL_NAMES serializes |gen| as a list of |CONF_VALUE|s. If |ret| is +// non-NULL, it appends the values to |ret| and returns |ret| on success or NULL +// on error. If it returns NULL, the caller is still responsible for freeing +// |ret|. If |ret| is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| +// containing the results. |method| is ignored. +// +// Do not use this function. This is an internal implementation detail of the +// human-readable print functions. If extracting a SAN list from a certificate, +// look at |gen| directly. +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES( + const X509V3_EXT_METHOD *method, const GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES( + const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS_const(OTHERNAME) +DECLARE_ASN1_FUNCTIONS_const(EDIPARTYNAME) +OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, + void *value); +OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); +OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, + ASN1_TYPE *value); +OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, + ASN1_OBJECT **poid, + ASN1_TYPE **pvalue); + +// i2s_ASN1_OCTET_STRING returns a human-readable representation of |oct| as a +// newly-allocated, NUL-terminated string, or NULL on error. |method| is +// ignored. The caller must release the result with |OPENSSL_free| when done. +OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *oct); + +OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING( + const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str); + +DECLARE_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE) +OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_FUNCTIONS_const(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS_const(POLICYINFO) +DECLARE_ASN1_FUNCTIONS_const(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS_const(USERNOTICE) +DECLARE_ASN1_FUNCTIONS_const(NOTICEREF) + +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, + X509_NAME *iname); + +OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +// TODO(https://crbug.com/boringssl/407): This is not const because it contains +// an |X509_NAME|. +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, int gen_type, + const char *value, int is_nc); + +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + const X509V3_CTX *ctx, + const CONF_VALUE *cnf); +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex( + GENERAL_NAME *out, const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, + const CONF_VALUE *cnf, int is_nc); +OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); + + +// Deprecated config-based extension creation. +// +// The following functions allow specifying X.509 extensions using OpenSSL's +// config file syntax, from the OpenSSL command-line tool. They are retained, +// for now, for compatibility with legacy software but may be removed in the +// future. Construct the extensions using the typed C APIs instead. +// +// Callers should especially avoid these functions if passing in non-constant +// values. They use ad-hoc, string-based formats which are prone to injection +// vulnerabilities. For a CA, this means using them risks misissuance. +// +// These functions are not safe to use with untrusted inputs. The string formats +// may implicitly reference context information and, in OpenSSL (though not +// BoringSSL), one even allows reading arbitrary files. Many formats can also +// produce far larger outputs than their inputs, so untrusted inputs may lead to +// denial-of-service attacks. Finally, the parsers see much less testing and +// review than most of the library and may have bugs including memory leaks or +// crashes. + +// v3_ext_ctx, aka |X509V3_CTX|, contains additional context information for +// constructing extensions. Some string formats reference additional values in +// these objects. It must be initialized with |X509V3_set_ctx| or +// |X509V3_set_ctx_test| before use. +struct v3_ext_ctx { + int flags; + const X509 *issuer_cert; + const X509 *subject_cert; + const X509_REQ *subject_req; + const X509_CRL *crl; + const CONF *db; +}; + +#define X509V3_CTX_TEST 0x1 + +// X509V3_set_ctx initializes |ctx| with the specified objects. Some string +// formats will reference fields in these objects. Each object may be NULL to +// omit it, in which case those formats cannot be used. |flags| should be zero, +// unless called via |X509V3_set_ctx_test|. +// +// |issuer|, |subject|, |req|, and |crl|, if non-NULL, must outlive |ctx|. +OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, + const X509 *subject, const X509_REQ *req, + const X509_CRL *crl, int flags); + +// X509V3_set_ctx_test calls |X509V3_set_ctx| without any reference objects and +// mocks out some features that use them. The resulting extensions may be +// incomplete and should be discarded. This can be used to partially validate +// syntax. +// +// TODO(davidben): Can we remove this? +#define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, X509V3_CTX_TEST) + +// X509V3_set_nconf sets |ctx| to use |conf| as the config database. |ctx| must +// have previously been initialized by |X509V3_set_ctx| or +// |X509V3_set_ctx_test|. Some string formats will reference sections in |conf|. +// |conf| may be NULL, in which case these formats cannot be used. If non-NULL, +// |conf| must outlive |ctx|. +OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf); + +// X509V3_set_ctx_nodb calls |X509V3_set_nconf| with no config database. +#define X509V3_set_ctx_nodb(ctx) X509V3_set_nconf(ctx, NULL) + +// X509V3_EXT_nconf constructs an extension of type specified by |name|, and +// value specified by |value|. It returns a newly-allocated |X509_EXTENSION| +// object on success, or NULL on error. |conf| and |ctx| specify additional +// information referenced by some formats. Either |conf| or |ctx| may be NULL, +// in which case features which use it will be disabled. +// +// If non-NULL, |ctx| must be initialized with |X509V3_set_ctx| or +// |X509V3_set_ctx_test|. +// +// Both |conf| and |ctx| provide a |CONF| object. When |ctx| is non-NULL, most +// features use the |ctx| copy, configured with |X509V3_set_ctx|, but some use +// |conf|. Callers should ensure the two match to avoid surprisingly behavior. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, + const X509V3_CTX *ctx, + const char *name, + const char *value); + +// X509V3_EXT_nconf_nid behaves like |X509V3_EXT_nconf|, except the extension +// type is specified as a NID. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(const CONF *conf, + const X509V3_CTX *ctx, + int ext_nid, + const char *value); + +// X509V3_EXT_conf_nid calls |X509V3_EXT_nconf_nid|. |conf| must be NULL. +// +// TODO(davidben): This and |X509V3_EXT_conf| are the only exposed instance of +// |LHASH| in our public headers. cryptography.io wraps this function so we +// cannot replace the type with a dummy struct. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + const X509V3_CTX *ctx, + int ext_nid, + const char *value); + +// X509V3_EXT_conf calls |X509V3_EXT_nconf|. |conf| must be NULL. +// +// NOTE: This is only provided for compatibility. See |X509V3_EXT_nconf| +// instead. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, + const char *name, + const char *value); + + +// X509V3_EXT_add_nconf_sk looks up the section named |section| in |conf|. For +// each |CONF_VALUE| in the section, it constructs an extension as in +// |X509V3_EXT_nconf|, taking |name| and |value| from the |CONF_VALUE|. Each new +// extension is appended to |*sk|. If |*sk| is non-NULL, and at least one +// extension is added, it sets |*sk| to a newly-allocated +// |STACK_OF(X509_EXTENSION)|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(const CONF *conf, + const X509V3_CTX *ctx, + const char *section, + STACK_OF(X509_EXTENSION) **sk); + +// X509V3_EXT_add_nconf adds extensions to |cert| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, + const char *section, X509 *cert); + +// X509V3_EXT_REQ_add_nconf adds extensions to |req| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(const CONF *conf, + const X509V3_CTX *ctx, + const char *section, X509_REQ *req); + +// X509V3_EXT_CRL_add_nconf adds extensions to |crl| as in +// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. +OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(const CONF *conf, + const X509V3_CTX *ctx, + const char *section, X509_CRL *crl); + + +OPENSSL_EXPORT char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, + const ASN1_INTEGER *aint); +OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, + const char *value); +OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *meth, + const ASN1_ENUMERATED *aint); + +// X509V3_EXT_add registers |ext| as a custom extension for the extension type +// |ext->ext_nid|. |ext| must be valid for the remainder of the address space's +// lifetime. It returns one on success and zero on error. +// +// WARNING: This function modifies global state. If other code in the same +// address space also registers an extension with type |ext->ext_nid|, the two +// registrations will conflict. Which registration takes effect is undefined. If +// the two registrations use incompatible in-memory representations, code +// expecting the other registration will then cast a type to the wrong type, +// resulting in a potentially exploitable memory error. This conflict can also +// occur if BoringSSL later adds support for |ext->ext_nid|, with a different +// in-memory representation than the one expected by |ext|. +// +// This function, additionally, is not thread-safe and cannot be called +// concurrently with any other BoringSSL function. +// +// As a result, it is impossible to safely use this function. Registering a +// custom extension has no impact on certificate verification so, instead, +// callers should simply handle the custom extension with the byte-based +// |X509_EXTENSION| APIs directly. Registering |ext| with the library has little +// practical value. +OPENSSL_EXPORT OPENSSL_DEPRECATED int X509V3_EXT_add(X509V3_EXT_METHOD *ext); + +// X509V3_EXT_add_list calls |X509V3_EXT_add| on |&extlist[0]|, |&extlist[1]|, +// and so on, until some |extlist[i]->ext_nid| is -1. It returns one on success +// and zero on error. +// +// WARNING: Do not use this function. See |X509V3_EXT_add|. +OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); + +// X509V3_EXT_add_alias registers a custom extension with NID |nid_to|. The +// corresponding ASN.1 type is copied from |nid_from|. It returns one on success +// and zero on error. +// +// WARNING: Do not use this function. See |X509V3_EXT_add|. +OPENSSL_EXPORT OPENSSL_DEPRECATED int X509V3_EXT_add_alias(int nid_to, + int nid_from); + +// X509V3_EXT_cleanup removes all custom extensions registered with +// |X509V3_EXT_add*|. +// +// WARNING: This function modifies global state and will impact custom +// extensions registered by any code in the same address space. It, +// additionally, is not thread-safe and cannot be called concurrently with any +// other BoringSSL function. +// +// Instead of calling this function, allow memory from custom extensions to be +// released on process exit, along with other global program state. +OPENSSL_EXPORT void X509V3_EXT_cleanup(void); + +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get( + const X509_EXTENSION *ext); +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +OPENSSL_EXPORT int X509V3_add_standard_extensions(void); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); + +// X509V3_EXT_d2i decodes |ext| and returns a pointer to a newly-allocated +// structure, with type dependent on the type of the extension. It returns NULL +// if |ext| is an unsupported extension or if there was a syntax error in the +// extension. The caller should cast the return value to the expected type and +// free the structure when done. +// +// WARNING: Casting the return value to the wrong type is a potentially +// exploitable memory error, so callers must not use this function before +// checking |ext| is of a known type. +OPENSSL_EXPORT void *X509V3_EXT_d2i(const X509_EXTENSION *ext); + +// X509V3_get_d2i finds and decodes the extension in |extensions| of type |nid|. +// If found, it decodes it and returns a newly-allocated structure, with type +// dependent on |nid|. If the extension is not found or on error, it returns +// NULL. The caller may distinguish these cases using the |out_critical| value. +// +// If |out_critical| is not NULL, this function sets |*out_critical| to one if +// the extension is found and critical, zero if it is found and not critical, -1 +// if it is not found, and -2 if there is an invalid duplicate extension. Note +// this function may set |*out_critical| to one or zero and still return NULL if +// the extension is found but has a syntax error. +// +// If |out_idx| is not NULL, this function looks for the first occurrence of the +// extension after |*out_idx|. It then sets |*out_idx| to the index of the +// extension, or -1 if not found. If |out_idx| is non-NULL, duplicate extensions +// are not treated as an error. Callers, however, should not rely on this +// behavior as it may be removed in the future. Duplicate extensions are +// forbidden in RFC 5280. +// +// WARNING: This function is difficult to use correctly. Callers should pass a +// non-NULL |out_critical| and check both the return value and |*out_critical| +// to handle errors. If the return value is NULL and |*out_critical| is not -1, +// there was an error. Otherwise, the function succeeded and but may return NULL +// for a missing extension. Callers should pass NULL to |out_idx| so that +// duplicate extensions are handled correctly. +// +// Additionally, casting the return value to the wrong type is a potentially +// exploitable memory error, so callers must ensure the cast and |nid| match. +OPENSSL_EXPORT void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *extensions, + int nid, int *out_critical, int *out_idx); + +// X509V3_EXT_free casts |ext_data| into the type that corresponds to |nid| and +// releases memory associated with it. It returns one on success and zero if +// |nid| is not a known extension. +// +// WARNING: Casting |ext_data| to the wrong type is a potentially exploitable +// memory error, so callers must ensure |ext_data|'s type matches |nid|. +// +// TODO(davidben): OpenSSL upstream no longer exposes this function. Remove it? +OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data); + +// X509V3_EXT_i2d casts |ext_struc| into the type that corresponds to +// |ext_nid|, serializes it, and returns a newly-allocated |X509_EXTENSION| +// object containing the serialization, or NULL on error. The |X509_EXTENSION| +// has OID |ext_nid| and is critical if |crit| is one. +// +// WARNING: Casting |ext_struc| to the wrong type is a potentially exploitable +// memory error, so callers must ensure |ext_struct|'s type matches |ext_nid|. +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, + void *ext_struc); + +// The following constants control the behavior of |X509V3_add1_i2d| and related +// functions. + +// X509V3_ADD_OP_MASK can be ANDed with the flags to determine how duplicate +// extensions are processed. +#define X509V3_ADD_OP_MASK 0xfL + +// X509V3_ADD_DEFAULT causes the function to fail if the extension was already +// present. +#define X509V3_ADD_DEFAULT 0L + +// X509V3_ADD_APPEND causes the function to unconditionally appended the new +// extension to to the extensions list, even if there is a duplicate. +#define X509V3_ADD_APPEND 1L + +// X509V3_ADD_REPLACE causes the function to replace the existing extension, or +// append if it is not present. +#define X509V3_ADD_REPLACE 2L + +// X509V3_ADD_REPLACE_EXISTING causes the function to replace the existing extension and +// fail if it is not present. +#define X509V3_ADD_REPLACE_EXISTING 3L + +// X509V3_ADD_KEEP_EXISTING causes the function to succeed without replacing the +// extension if already present. +#define X509V3_ADD_KEEP_EXISTING 4L + +// X509V3_ADD_DELETE causes the function to remove the matching extension. No +// new extension is added. If there is no matching extension, the function +// fails. The |value| parameter is ignored in this mode. +#define X509V3_ADD_DELETE 5L + +// X509V3_ADD_SILENT may be ORed into one of the values above to indicate the +// function should not add to the error queue on duplicate or missing extension. +// The function will continue to return zero in those cases, and it will +// continue to return -1 and add to the error queue on other errors. +#define X509V3_ADD_SILENT 0x10 + +// X509V3_add1_i2d casts |value| to the type that corresponds to |nid|, +// serializes it, and appends it to the extension list in |*x|. If |*x| is NULL, +// it will set |*x| to a newly-allocated |STACK_OF(X509_EXTENSION)| as needed. +// The |crit| parameter determines whether the new extension is critical. +// |flags| may be some combination of the |X509V3_ADD_*| constants to control +// the function's behavior on duplicate extension. +// +// This function returns one on success, zero if the operation failed due to a +// missing or duplicate extension, and -1 on other errors. +// +// WARNING: Casting |value| to the wrong type is a potentially exploitable +// memory error, so callers must ensure |value|'s type matches |nid|. +OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, + void *value, int crit, unsigned long flags); + +#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) + +// X509V3_EXT_DEFAULT causes unknown extensions or syntax errors to return +// failure. +#define X509V3_EXT_DEFAULT 0 +// X509V3_EXT_ERROR_UNKNOWN causes unknown extensions or syntax errors to print +// as "" or "", respectively. +#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +// X509V3_EXT_PARSE_UNKNOWN is deprecated and behaves like +// |X509V3_EXT_DUMP_UNKNOWN|. +#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +// X509V3_EXT_DUMP_UNKNOWN causes unknown extensions to be displayed as a +// hexdump. +#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, + const STACK_OF(CONF_VALUE) *val, + int indent, int ml); +OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, const X509_EXTENSION *ext, + unsigned long flag, int indent); +OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, const X509_EXTENSION *ext, + int flag, int indent); + +// X509V3_extensions_print prints |title|, followed by a human-readable +// representation of |exts| to |out|. It returns one on success and zero on +// error. The output is indented by |indent| spaces. |flag| is one of the +// |X509V3_EXT_*| constants and controls printing of unknown extensions and +// syntax errors. +OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, + const STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +OPENSSL_EXPORT int X509_check_ca(X509 *x); +OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); +OPENSSL_EXPORT int X509_supported_extension(const X509_EXTENSION *ex); +OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); +OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); +OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); + +OPENSSL_EXPORT uint32_t X509_get_extension_flags(X509 *x); +OPENSSL_EXPORT uint32_t X509_get_key_usage(X509 *x); +OPENSSL_EXPORT uint32_t X509_get_extended_key_usage(X509 *x); + +// X509_get0_subject_key_id returns |x509|'s subject key identifier, if present. +// (See RFC 5280, section 4.2.1.2.) It returns NULL if the extension is not +// present or if some extension in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509); + +// X509_get0_authority_key_id returns keyIdentifier of |x509|'s authority key +// identifier, if the extension and field are present. (See RFC 5280, +// section 4.2.1.1.) It returns NULL if the extension is not present, if it is +// present but lacks a keyIdentifier field, or if some extension in |x509| was +// invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509); + +// X509_get0_authority_issuer returns the authorityCertIssuer of |x509|'s +// authority key identifier, if the extension and field are present. (See +// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present, +// if it is present but lacks a authorityCertIssuer field, or if some extension +// in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509); + +// X509_get0_authority_serial returns the authorityCertSerialNumber of |x509|'s +// authority key identifier, if the extension and field are present. (See +// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present, +// if it is present but lacks a authorityCertSerialNumber field, or if some +// extension in |x509| was invalid. +// +// Note that decoding an |X509| object will not check for invalid extensions. To +// detect the error case, call |X509_get_extensions_flags| and check the +// |EXFLAG_INVALID| bit. +OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509); + +OPENSSL_EXPORT int X509_PURPOSE_get_count(void); +OPENSSL_EXPORT X509_PURPOSE *X509_PURPOSE_get0(int idx); +OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname); +OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); +OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, + const X509 *, int), + const char *name, const char *sname, + void *arg); +OPENSSL_EXPORT char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); +OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); +OPENSSL_EXPORT int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); +OPENSSL_EXPORT void X509_PURPOSE_cleanup(void); +OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *); + +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); + + +// 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 AWS-LC, this behavior is +// always enabled. This only applies to |X509_check_host| in OpenSSL. +#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 + +// 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 + +// 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 + +// 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 +// X509_check_host will calculate the length using strlen. It is encouraged to +// always pass in the length of |chk| and rely on higher level parsing to ensure +// strlen is not called on a string that does not contain a null terminator. +// If a match is found X509_check_host returns 1, if |peername| is not null +// it is updated to point to the matching name in |x|. +OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); + +// X509_check_email checks if the email address in |x| matches |chk| string up +// to |chklen|. If |chklen| is 0 X509_check_email will calculate the length +// using strlen. It is encouraged to always pass in the length of |chk| and rely +// on higher level parsing to ensure strlen is not called on a string that does +// not contain a null terminator. If the certificate matches X509_check_email +// returns 1. +OPENSSL_EXPORT int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); + +// X509_check_ip checks if the IPv4 or IPv6 address in |x| matches |chk| up +// to |chklen|. X509_check_ip does not attempt to determine the length of |chk| +// if 0 is passed in for |chklen|. If the certificate matches X509_check_ip +// returns 1. +OPENSSL_EXPORT int X509_check_ip(X509 *x, const unsigned char *chk, + size_t chklen, unsigned int flags); +OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, + unsigned int flags); + +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); + #if defined(__cplusplus) } // extern C @@ -3434,7 +4381,18 @@ extern "C++" { BSSL_NAMESPACE_BEGIN +BORINGSSL_MAKE_DELETER(ACCESS_DESCRIPTION, ACCESS_DESCRIPTION_free) +BORINGSSL_MAKE_DELETER(AUTHORITY_KEYID, AUTHORITY_KEYID_free) +BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free) +// TODO(davidben): Move this to conf.h and rename to CONF_VALUE_free. +BORINGSSL_MAKE_DELETER(CONF_VALUE, X509V3_conf_free) +BORINGSSL_MAKE_DELETER(DIST_POINT, DIST_POINT_free) +BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free) +BORINGSSL_MAKE_DELETER(GENERAL_SUBTREE, GENERAL_SUBTREE_free) +BORINGSSL_MAKE_DELETER(NAME_CONSTRAINTS, NAME_CONSTRAINTS_free) BORINGSSL_MAKE_DELETER(NETSCAPE_SPKI, NETSCAPE_SPKI_free) +BORINGSSL_MAKE_DELETER(POLICY_MAPPING, POLICY_MAPPING_free) +BORINGSSL_MAKE_DELETER(POLICYINFO, POLICYINFO_free) BORINGSSL_MAKE_DELETER(RSA_PSS_PARAMS, RSA_PSS_PARAMS_free) BORINGSSL_MAKE_DELETER(X509, X509_free) BORINGSSL_MAKE_UP_REF(X509, X509_up_ref) diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 0dc1fe3dce..c8e52be185 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -1,1109 +1,17 @@ -/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project 1999. */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * 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 above 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 acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED 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 OpenSSL PROJECT OR - * ITS 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. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). */ - -#ifndef OPENSSL_HEADER_X509V3_H -#define OPENSSL_HEADER_X509V3_H - -#include -#include -#include +/* Copyright (c) 2023, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This header is provided in order to make compiling against code that expects +// OpenSSL easier. #include - -#if defined(__cplusplus) -extern "C" { -#endif - - -// Legacy X.509 library. -// -// This header is part of OpenSSL's X.509 implementation. It is retained for -// compatibility but otherwise underdocumented and not actively maintained. In -// the future, a replacement library will be available. Meanwhile, minimize -// dependencies on this header where possible. - - -// Forward reference -struct v3_ext_method; -struct v3_ext_ctx; - -// Useful typedefs - -typedef struct v3_ext_method X509V3_EXT_METHOD; - -typedef void *(*X509V3_EXT_NEW)(void); -typedef void (*X509V3_EXT_FREE)(void *); -typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); -typedef int (*X509V3_EXT_I2D)(void *, unsigned char **); -typedef STACK_OF(CONF_VALUE) *(*X509V3_EXT_I2V)(const X509V3_EXT_METHOD *method, - void *ext, - STACK_OF(CONF_VALUE) *extlist); -typedef void *(*X509V3_EXT_V2I)(const X509V3_EXT_METHOD *method, - const X509V3_CTX *ctx, - const STACK_OF(CONF_VALUE) *values); -typedef char *(*X509V3_EXT_I2S)(const X509V3_EXT_METHOD *method, void *ext); -typedef void *(*X509V3_EXT_S2I)(const X509V3_EXT_METHOD *method, - const X509V3_CTX *ctx, const char *str); -typedef int (*X509V3_EXT_I2R)(const X509V3_EXT_METHOD *method, void *ext, - BIO *out, int indent); -typedef void *(*X509V3_EXT_R2I)(const X509V3_EXT_METHOD *method, - const X509V3_CTX *ctx, const char *str); - -// V3 extension structure - -struct v3_ext_method { - int ext_nid; - int ext_flags; - - // it determines how values of this extension are allocated, released, parsed, - // and marshalled. This must be non-NULL. - ASN1_ITEM_EXP *it; - - // The following functions are ignored in favor of |it|. They are retained in - // the struct only for source compatibility with existing struct definitions. - // - // Only OCSP nonce extensions currently rely on these functions with AWS-LC. - // This is to maintain backwards compatibility with how OCSP nonce extensions - // are handled in OpenSSL. This can't be easily removed because OpenSSL - // considers the OCSP nonce to be "special". - // |X509V3_EXT_add| enforces |it| to be non-NULL, so external users are not - // allowed to use the following functions. - X509V3_EXT_NEW ext_new; - X509V3_EXT_FREE ext_free; - X509V3_EXT_D2I d2i; - X509V3_EXT_I2D i2d; - - // The following pair is used for string extensions - X509V3_EXT_I2S i2s; - X509V3_EXT_S2I s2i; - - // The following pair is used for multi-valued extensions - X509V3_EXT_I2V i2v; - X509V3_EXT_V2I v2i; - - // The following are used for raw extensions - X509V3_EXT_I2R i2r; - X509V3_EXT_R2I r2i; - - void *usr_data; // Any extension specific data -}; - -DEFINE_STACK_OF(X509V3_EXT_METHOD) - -// ext_flags values -#define X509V3_EXT_CTX_DEP 0x2 -#define X509V3_EXT_MULTILINE 0x4 - -struct BASIC_CONSTRAINTS_st { - int ca; - ASN1_INTEGER *pathlen; -}; - - -typedef struct otherName_st { - ASN1_OBJECT *type_id; - ASN1_TYPE *value; -} OTHERNAME; - -typedef struct EDIPartyName_st { - ASN1_STRING *nameAssigner; - ASN1_STRING *partyName; -} EDIPARTYNAME; - -typedef struct GENERAL_NAME_st { -#define GEN_OTHERNAME 0 -#define GEN_EMAIL 1 -#define GEN_DNS 2 -#define GEN_X400 3 -#define GEN_DIRNAME 4 -#define GEN_EDIPARTY 5 -#define GEN_URI 6 -#define GEN_IPADD 7 -#define GEN_RID 8 - - int type; - union { - char *ptr; - OTHERNAME *otherName; // otherName - ASN1_IA5STRING *rfc822Name; - ASN1_IA5STRING *dNSName; - ASN1_STRING *x400Address; - X509_NAME *directoryName; - EDIPARTYNAME *ediPartyName; - ASN1_IA5STRING *uniformResourceIdentifier; - ASN1_OCTET_STRING *iPAddress; - ASN1_OBJECT *registeredID; - - // Old names - ASN1_OCTET_STRING *ip; // iPAddress - X509_NAME *dirn; // dirn - ASN1_IA5STRING *ia5; // rfc822Name, dNSName, uniformResourceIdentifier - ASN1_OBJECT *rid; // registeredID - } d; -} GENERAL_NAME; - -DEFINE_STACK_OF(GENERAL_NAME) - -typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; - -DEFINE_STACK_OF(GENERAL_NAMES) - -typedef struct ACCESS_DESCRIPTION_st { - ASN1_OBJECT *method; - GENERAL_NAME *location; -} ACCESS_DESCRIPTION; - -DEFINE_STACK_OF(ACCESS_DESCRIPTION) - -typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; - -typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; - -typedef struct DIST_POINT_NAME_st { - int type; - union { - GENERAL_NAMES *fullname; - STACK_OF(X509_NAME_ENTRY) *relativename; - } name; - // If relativename then this contains the full distribution point name - X509_NAME *dpname; -} DIST_POINT_NAME; -// All existing reasons -#define CRLDP_ALL_REASONS 0x807f - -#define CRL_REASON_NONE (-1) -#define CRL_REASON_UNSPECIFIED 0 -#define CRL_REASON_KEY_COMPROMISE 1 -#define CRL_REASON_CA_COMPROMISE 2 -#define CRL_REASON_AFFILIATION_CHANGED 3 -#define CRL_REASON_SUPERSEDED 4 -#define CRL_REASON_CESSATION_OF_OPERATION 5 -#define CRL_REASON_CERTIFICATE_HOLD 6 -#define CRL_REASON_REMOVE_FROM_CRL 8 -#define CRL_REASON_PRIVILEGE_WITHDRAWN 9 -#define CRL_REASON_AA_COMPROMISE 10 - -struct DIST_POINT_st { - DIST_POINT_NAME *distpoint; - ASN1_BIT_STRING *reasons; - GENERAL_NAMES *CRLissuer; -}; - -typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; - -DEFINE_STACK_OF(DIST_POINT) - -struct AUTHORITY_KEYID_st { - ASN1_OCTET_STRING *keyid; - GENERAL_NAMES *issuer; - ASN1_INTEGER *serial; -}; - -typedef struct NOTICEREF_st { - ASN1_STRING *organization; - STACK_OF(ASN1_INTEGER) *noticenos; -} NOTICEREF; - -typedef struct USERNOTICE_st { - NOTICEREF *noticeref; - ASN1_STRING *exptext; -} USERNOTICE; - -typedef struct POLICYQUALINFO_st { - ASN1_OBJECT *pqualid; - union { - ASN1_IA5STRING *cpsuri; - USERNOTICE *usernotice; - ASN1_TYPE *other; - } d; -} POLICYQUALINFO; - -DEFINE_STACK_OF(POLICYQUALINFO) - -typedef struct POLICYINFO_st { - ASN1_OBJECT *policyid; - STACK_OF(POLICYQUALINFO) *qualifiers; -} POLICYINFO; - -typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; - -DEFINE_STACK_OF(POLICYINFO) - -typedef struct POLICY_MAPPING_st { - ASN1_OBJECT *issuerDomainPolicy; - ASN1_OBJECT *subjectDomainPolicy; -} POLICY_MAPPING; - -DEFINE_STACK_OF(POLICY_MAPPING) - -typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; - -typedef struct GENERAL_SUBTREE_st { - GENERAL_NAME *base; - ASN1_INTEGER *minimum; - ASN1_INTEGER *maximum; -} GENERAL_SUBTREE; - -DEFINE_STACK_OF(GENERAL_SUBTREE) - -struct NAME_CONSTRAINTS_st { - STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; - STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; -}; - -typedef struct POLICY_CONSTRAINTS_st { - ASN1_INTEGER *requireExplicitPolicy; - ASN1_INTEGER *inhibitPolicyMapping; -} POLICY_CONSTRAINTS; - -struct ISSUING_DIST_POINT_st { - DIST_POINT_NAME *distpoint; - ASN1_BOOLEAN onlyuser; - ASN1_BOOLEAN onlyCA; - ASN1_BIT_STRING *onlysomereasons; - ASN1_BOOLEAN indirectCRL; - ASN1_BOOLEAN onlyattr; -}; - -// X509_PURPOSE stuff - -#define EXFLAG_BCONS 0x1 -#define EXFLAG_KUSAGE 0x2 -#define EXFLAG_XKUSAGE 0x4 -#define EXFLAG_NSCERT 0x8 - -#define EXFLAG_CA 0x10 -// Really self issued not necessarily self signed -#define EXFLAG_SI 0x20 -#define EXFLAG_V1 0x40 -#define EXFLAG_INVALID 0x80 -#define EXFLAG_SET 0x100 -#define EXFLAG_CRITICAL 0x200 - -// Self signed -#define EXFLAG_SS 0x2000 - -#define KU_DIGITAL_SIGNATURE 0x0080 -#define KU_NON_REPUDIATION 0x0040 -#define KU_KEY_ENCIPHERMENT 0x0020 -#define KU_DATA_ENCIPHERMENT 0x0010 -#define KU_KEY_AGREEMENT 0x0008 -#define KU_KEY_CERT_SIGN 0x0004 -#define KU_CRL_SIGN 0x0002 -#define KU_ENCIPHER_ONLY 0x0001 -#define KU_DECIPHER_ONLY 0x8000 - -#define NS_SSL_CLIENT 0x80 -#define NS_SSL_SERVER 0x40 -#define NS_SMIME 0x20 -#define NS_OBJSIGN 0x10 -#define NS_SSL_CA 0x04 -#define NS_SMIME_CA 0x02 -#define NS_OBJSIGN_CA 0x01 -#define NS_ANY_CA (NS_SSL_CA | NS_SMIME_CA | NS_OBJSIGN_CA) - -#define XKU_SSL_SERVER 0x1 -#define XKU_SSL_CLIENT 0x2 -#define XKU_SMIME 0x4 -#define XKU_CODE_SIGN 0x8 -#define XKU_SGC 0x10 -#define XKU_OCSP_SIGN 0x20 -#define XKU_TIMESTAMP 0x40 -#define XKU_DVCS 0x80 -#define XKU_ANYEKU 0x100 - -#define X509_PURPOSE_DYNAMIC 0x1 -#define X509_PURPOSE_DYNAMIC_NAME 0x2 - -typedef struct x509_purpose_st { - int purpose; - int trust; // Default trust ID - int flags; - int (*check_purpose)(const struct x509_purpose_st *, const X509 *, int); - char *name; - char *sname; - void *usr_data; -} X509_PURPOSE; - -#define X509_PURPOSE_SSL_CLIENT 1 -#define X509_PURPOSE_SSL_SERVER 2 -#define X509_PURPOSE_NS_SSL_SERVER 3 -#define X509_PURPOSE_SMIME_SIGN 4 -#define X509_PURPOSE_SMIME_ENCRYPT 5 -#define X509_PURPOSE_CRL_SIGN 6 -#define X509_PURPOSE_ANY 7 -#define X509_PURPOSE_OCSP_HELPER 8 -#define X509_PURPOSE_TIMESTAMP_SIGN 9 - -#define X509_PURPOSE_MIN 1 -#define X509_PURPOSE_MAX 9 - -DEFINE_STACK_OF(X509_PURPOSE) - -DECLARE_ASN1_FUNCTIONS_const(BASIC_CONSTRAINTS) - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) -OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); - -// i2v_GENERAL_NAME serializes |gen| as a |CONF_VALUE|. If |ret| is non-NULL, it -// appends the value to |ret| and returns |ret| on success or NULL on error. If -// it returns NULL, the caller is still responsible for freeing |ret|. If |ret| -// is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| containing the -// result. |method| is ignored. -// -// Do not use this function. This is an internal implementation detail of the -// human-readable print functions. If extracting a SAN list from a certificate, -// look at |gen| directly. -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME( - const X509V3_EXT_METHOD *method, const GENERAL_NAME *gen, - STACK_OF(CONF_VALUE) *ret); - -// GENERAL_NAME_print prints a human-readable representation of |gen| to |out|. -// It returns one on success and zero on error. -// -// TODO(davidben): Actually, it just returns one and doesn't check for I/O or -// allocation errors. But it should return zero on error. -OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, const GENERAL_NAME *gen); - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) - -// i2v_GENERAL_NAMES serializes |gen| as a list of |CONF_VALUE|s. If |ret| is -// non-NULL, it appends the values to |ret| and returns |ret| on success or NULL -// on error. If it returns NULL, the caller is still responsible for freeing -// |ret|. If |ret| is NULL, it returns a newly-allocated |STACK_OF(CONF_VALUE)| -// containing the results. |method| is ignored. -// -// Do not use this function. This is an internal implementation detail of the -// human-readable print functions. If extracting a SAN list from a certificate, -// look at |gen| directly. -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES( - const X509V3_EXT_METHOD *method, const GENERAL_NAMES *gen, - STACK_OF(CONF_VALUE) *extlist); -OPENSSL_EXPORT GENERAL_NAMES *v2i_GENERAL_NAMES( - const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, - const STACK_OF(CONF_VALUE) *nval); - -DECLARE_ASN1_FUNCTIONS_const(OTHERNAME) -DECLARE_ASN1_FUNCTIONS_const(EDIPARTYNAME) -OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, - void *value); -OPENSSL_EXPORT void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype); -OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, - ASN1_OBJECT *oid, - ASN1_TYPE *value); -OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen, - ASN1_OBJECT **poid, - ASN1_TYPE **pvalue); - -// i2s_ASN1_OCTET_STRING returns a human-readable representation of |oct| as a -// newly-allocated, NUL-terminated string, or NULL on error. |method| is -// ignored. The caller must release the result with |OPENSSL_free| when done. -OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(const X509V3_EXT_METHOD *method, - const ASN1_OCTET_STRING *oct); - -OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING( - const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str); - -DECLARE_ASN1_FUNCTIONS_const(EXTENDED_KEY_USAGE) -OPENSSL_EXPORT int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a); - -DECLARE_ASN1_FUNCTIONS_const(CERTIFICATEPOLICIES) -DECLARE_ASN1_FUNCTIONS_const(POLICYINFO) -DECLARE_ASN1_FUNCTIONS_const(POLICYQUALINFO) -DECLARE_ASN1_FUNCTIONS_const(USERNOTICE) -DECLARE_ASN1_FUNCTIONS_const(NOTICEREF) - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(DIST_POINT) -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) - -OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, - X509_NAME *iname); - -OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) - -DECLARE_ASN1_ITEM(POLICY_MAPPING) -DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) -DECLARE_ASN1_ITEM(POLICY_MAPPINGS) - -DECLARE_ASN1_ITEM(GENERAL_SUBTREE) -DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) - -DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) -DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) - -DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) -DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) - -OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - const X509V3_CTX *ctx, int gen_type, - const char *value, int is_nc); - -OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, - const X509V3_CTX *ctx, - const CONF_VALUE *cnf); -OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex( - GENERAL_NAME *out, const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, - const CONF_VALUE *cnf, int is_nc); -OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); - - -// Deprecated config-based extension creation. -// -// The following functions allow specifying X.509 extensions using OpenSSL's -// config file syntax, from the OpenSSL command-line tool. They are retained, -// for now, for compatibility with legacy software but may be removed in the -// future. Construct the extensions using the typed C APIs instead. -// -// Callers should especially avoid these functions if passing in non-constant -// values. They use ad-hoc, string-based formats which are prone to injection -// vulnerabilities. For a CA, this means using them risks misissuance. -// -// These functions are not safe to use with untrusted inputs. The string formats -// may implicitly reference context information and, in OpenSSL (though not -// BoringSSL), one even allows reading arbitrary files. Many formats can also -// produce far larger outputs than their inputs, so untrusted inputs may lead to -// denial-of-service attacks. Finally, the parsers see much less testing and -// review than most of the library and may have bugs including memory leaks or -// crashes. - -// v3_ext_ctx, aka |X509V3_CTX|, contains additional context information for -// constructing extensions. Some string formats reference additional values in -// these objects. It must be initialized with |X509V3_set_ctx| or -// |X509V3_set_ctx_test| before use. -struct v3_ext_ctx { - int flags; - const X509 *issuer_cert; - const X509 *subject_cert; - const X509_REQ *subject_req; - const X509_CRL *crl; - const CONF *db; -}; - -#define X509V3_CTX_TEST 0x1 - -// X509V3_set_ctx initializes |ctx| with the specified objects. Some string -// formats will reference fields in these objects. Each object may be NULL to -// omit it, in which case those formats cannot be used. |flags| should be zero, -// unless called via |X509V3_set_ctx_test|. -// -// |issuer|, |subject|, |req|, and |crl|, if non-NULL, must outlive |ctx|. -OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, const X509 *issuer, - const X509 *subject, const X509_REQ *req, - const X509_CRL *crl, int flags); - -// X509V3_set_ctx_test calls |X509V3_set_ctx| without any reference objects and -// mocks out some features that use them. The resulting extensions may be -// incomplete and should be discarded. This can be used to partially validate -// syntax. -// -// TODO(davidben): Can we remove this? -#define X509V3_set_ctx_test(ctx) \ - X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, X509V3_CTX_TEST) - -// X509V3_set_nconf sets |ctx| to use |conf| as the config database. |ctx| must -// have previously been initialized by |X509V3_set_ctx| or -// |X509V3_set_ctx_test|. Some string formats will reference sections in |conf|. -// |conf| may be NULL, in which case these formats cannot be used. If non-NULL, -// |conf| must outlive |ctx|. -OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, const CONF *conf); - -// X509V3_set_ctx_nodb calls |X509V3_set_nconf| with no config database. -#define X509V3_set_ctx_nodb(ctx) X509V3_set_nconf(ctx, NULL) - -// X509V3_EXT_nconf constructs an extension of type specified by |name|, and -// value specified by |value|. It returns a newly-allocated |X509_EXTENSION| -// object on success, or NULL on error. |conf| and |ctx| specify additional -// information referenced by some formats. Either |conf| or |ctx| may be NULL, -// in which case features which use it will be disabled. -// -// If non-NULL, |ctx| must be initialized with |X509V3_set_ctx| or -// |X509V3_set_ctx_test|. -// -// Both |conf| and |ctx| provide a |CONF| object. When |ctx| is non-NULL, most -// features use the |ctx| copy, configured with |X509V3_set_ctx|, but some use -// |conf|. Callers should ensure the two match to avoid surprisingly behavior. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(const CONF *conf, - const X509V3_CTX *ctx, - const char *name, - const char *value); - -// X509V3_EXT_nconf_nid behaves like |X509V3_EXT_nconf|, except the extension -// type is specified as a NID. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(const CONF *conf, - const X509V3_CTX *ctx, - int ext_nid, - const char *value); - -// X509V3_EXT_conf_nid calls |X509V3_EXT_nconf_nid|. |conf| must be NULL. -// -// TODO(davidben): This and |X509V3_EXT_conf| are the only exposed instance of -// |LHASH| in our public headers. cryptography.io wraps this function so we -// cannot replace the type with a dummy struct. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, - const X509V3_CTX *ctx, - int ext_nid, - const char *value); - -// X509V3_EXT_conf calls |X509V3_EXT_nconf|. |conf| must be NULL. -// -// NOTE: This is only provided for compatibility. See |X509V3_EXT_nconf| -// instead. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, - X509V3_CTX *ctx, - const char *name, - const char *value); - - -// X509V3_EXT_add_nconf_sk looks up the section named |section| in |conf|. For -// each |CONF_VALUE| in the section, it constructs an extension as in -// |X509V3_EXT_nconf|, taking |name| and |value| from the |CONF_VALUE|. Each new -// extension is appended to |*sk|. If |*sk| is non-NULL, and at least one -// extension is added, it sets |*sk| to a newly-allocated -// |STACK_OF(X509_EXTENSION)|. It returns one on success and zero on error. -OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(const CONF *conf, - const X509V3_CTX *ctx, - const char *section, - STACK_OF(X509_EXTENSION) **sk); - -// X509V3_EXT_add_nconf adds extensions to |cert| as in -// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. -OPENSSL_EXPORT int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, - const char *section, X509 *cert); - -// X509V3_EXT_REQ_add_nconf adds extensions to |req| as in -// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. -OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(const CONF *conf, - const X509V3_CTX *ctx, - const char *section, X509_REQ *req); - -// X509V3_EXT_CRL_add_nconf adds extensions to |crl| as in -// |X509V3_EXT_add_nconf_sk|. It returns one on success and zero on error. -OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(const CONF *conf, - const X509V3_CTX *ctx, - const char *section, X509_CRL *crl); - - -OPENSSL_EXPORT char *i2s_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, - const ASN1_INTEGER *aint); -OPENSSL_EXPORT ASN1_INTEGER *s2i_ASN1_INTEGER(const X509V3_EXT_METHOD *meth, - const char *value); -OPENSSL_EXPORT char *i2s_ASN1_ENUMERATED(const X509V3_EXT_METHOD *meth, - const ASN1_ENUMERATED *aint); - -// X509V3_EXT_add registers |ext| as a custom extension for the extension type -// |ext->ext_nid|. |ext| must be valid for the remainder of the address space's -// lifetime. It returns one on success and zero on error. -// -// WARNING: This function modifies global state. If other code in the same -// address space also registers an extension with type |ext->ext_nid|, the two -// registrations will conflict. Which registration takes effect is undefined. If -// the two registrations use incompatible in-memory representations, code -// expecting the other registration will then cast a type to the wrong type, -// resulting in a potentially exploitable memory error. This conflict can also -// occur if BoringSSL later adds support for |ext->ext_nid|, with a different -// in-memory representation than the one expected by |ext|. -// -// This function, additionally, is not thread-safe and cannot be called -// concurrently with any other BoringSSL function. -// -// As a result, it is impossible to safely use this function. Registering a -// custom extension has no impact on certificate verification so, instead, -// callers should simply handle the custom extension with the byte-based -// |X509_EXTENSION| APIs directly. Registering |ext| with the library has little -// practical value. -OPENSSL_EXPORT OPENSSL_DEPRECATED int X509V3_EXT_add(X509V3_EXT_METHOD *ext); - -// X509V3_EXT_add_list calls |X509V3_EXT_add| on |&extlist[0]|, |&extlist[1]|, -// and so on, until some |extlist[i]->ext_nid| is -1. It returns one on success -// and zero on error. -// -// WARNING: Do not use this function. See |X509V3_EXT_add|. -OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); - -// X509V3_EXT_add_alias registers a custom extension with NID |nid_to|. The -// corresponding ASN.1 type is copied from |nid_from|. It returns one on success -// and zero on error. -// -// WARNING: Do not use this function. See |X509V3_EXT_add|. -OPENSSL_EXPORT OPENSSL_DEPRECATED int X509V3_EXT_add_alias(int nid_to, - int nid_from); - -// X509V3_EXT_cleanup removes all custom extensions registered with -// |X509V3_EXT_add*|. -// -// WARNING: This function modifies global state and will impact custom -// extensions registered by any code in the same address space. It, -// additionally, is not thread-safe and cannot be called concurrently with any -// other BoringSSL function. -// -// Instead of calling this function, allow memory from custom extensions to be -// released on process exit, along with other global program state. -OPENSSL_EXPORT void X509V3_EXT_cleanup(void); - -OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get( - const X509_EXTENSION *ext); -OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); -OPENSSL_EXPORT int X509V3_add_standard_extensions(void); -OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); - -// X509V3_EXT_d2i decodes |ext| and returns a pointer to a newly-allocated -// structure, with type dependent on the type of the extension. It returns NULL -// if |ext| is an unsupported extension or if there was a syntax error in the -// extension. The caller should cast the return value to the expected type and -// free the structure when done. -// -// WARNING: Casting the return value to the wrong type is a potentially -// exploitable memory error, so callers must not use this function before -// checking |ext| is of a known type. -OPENSSL_EXPORT void *X509V3_EXT_d2i(const X509_EXTENSION *ext); - -// X509V3_get_d2i finds and decodes the extension in |extensions| of type |nid|. -// If found, it decodes it and returns a newly-allocated structure, with type -// dependent on |nid|. If the extension is not found or on error, it returns -// NULL. The caller may distinguish these cases using the |out_critical| value. -// -// If |out_critical| is not NULL, this function sets |*out_critical| to one if -// the extension is found and critical, zero if it is found and not critical, -1 -// if it is not found, and -2 if there is an invalid duplicate extension. Note -// this function may set |*out_critical| to one or zero and still return NULL if -// the extension is found but has a syntax error. -// -// If |out_idx| is not NULL, this function looks for the first occurrence of the -// extension after |*out_idx|. It then sets |*out_idx| to the index of the -// extension, or -1 if not found. If |out_idx| is non-NULL, duplicate extensions -// are not treated as an error. Callers, however, should not rely on this -// behavior as it may be removed in the future. Duplicate extensions are -// forbidden in RFC 5280. -// -// WARNING: This function is difficult to use correctly. Callers should pass a -// non-NULL |out_critical| and check both the return value and |*out_critical| -// to handle errors. If the return value is NULL and |*out_critical| is not -1, -// there was an error. Otherwise, the function succeeded and but may return NULL -// for a missing extension. Callers should pass NULL to |out_idx| so that -// duplicate extensions are handled correctly. -// -// Additionally, casting the return value to the wrong type is a potentially -// exploitable memory error, so callers must ensure the cast and |nid| match. -OPENSSL_EXPORT void *X509V3_get_d2i(const STACK_OF(X509_EXTENSION) *extensions, - int nid, int *out_critical, int *out_idx); - -// X509V3_EXT_free casts |ext_data| into the type that corresponds to |nid| and -// releases memory associated with it. It returns one on success and zero if -// |nid| is not a known extension. -// -// WARNING: Casting |ext_data| to the wrong type is a potentially exploitable -// memory error, so callers must ensure |ext_data|'s type matches |nid|. -// -// TODO(davidben): OpenSSL upstream no longer exposes this function. Remove it? -OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data); - -// X509V3_EXT_i2d casts |ext_struc| into the type that corresponds to -// |ext_nid|, serializes it, and returns a newly-allocated |X509_EXTENSION| -// object containing the serialization, or NULL on error. The |X509_EXTENSION| -// has OID |ext_nid| and is critical if |crit| is one. -// -// WARNING: Casting |ext_struc| to the wrong type is a potentially exploitable -// memory error, so callers must ensure |ext_struct|'s type matches |ext_nid|. -OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, - void *ext_struc); - -// The following constants control the behavior of |X509V3_add1_i2d| and related -// functions. - -// X509V3_ADD_OP_MASK can be ANDed with the flags to determine how duplicate -// extensions are processed. -#define X509V3_ADD_OP_MASK 0xfL - -// X509V3_ADD_DEFAULT causes the function to fail if the extension was already -// present. -#define X509V3_ADD_DEFAULT 0L - -// X509V3_ADD_APPEND causes the function to unconditionally appended the new -// extension to to the extensions list, even if there is a duplicate. -#define X509V3_ADD_APPEND 1L - -// X509V3_ADD_REPLACE causes the function to replace the existing extension, or -// append if it is not present. -#define X509V3_ADD_REPLACE 2L - -// X509V3_ADD_REPLACE causes the function to replace the existing extension and -// fail if it is not present. -#define X509V3_ADD_REPLACE_EXISTING 3L - -// X509V3_ADD_KEEP_EXISTING causes the function to succeed without replacing the -// extension if already present. -#define X509V3_ADD_KEEP_EXISTING 4L - -// X509V3_ADD_DELETE causes the function to remove the matching extension. No -// new extension is added. If there is no matching extension, the function -// fails. The |value| parameter is ignored in this mode. -#define X509V3_ADD_DELETE 5L - -// X509V3_ADD_SILENT may be ORed into one of the values above to indicate the -// function should not add to the error queue on duplicate or missing extension. -// The function will continue to return zero in those cases, and it will -// continue to return -1 and add to the error queue on other errors. -#define X509V3_ADD_SILENT 0x10 - -// X509V3_add1_i2d casts |value| to the type that corresponds to |nid|, -// serializes it, and appends it to the extension list in |*x|. If |*x| is NULL, -// it will set |*x| to a newly-allocated |STACK_OF(X509_EXTENSION)| as needed. -// The |crit| parameter determines whether the new extension is critical. -// |flags| may be some combination of the |X509V3_ADD_*| constants to control -// the function's behavior on duplicate extension. -// -// This function returns one on success, zero if the operation failed due to a -// missing or duplicate extension, and -1 on other errors. -// -// WARNING: Casting |value| to the wrong type is a potentially exploitable -// memory error, so callers must ensure |value|'s type matches |nid|. -OPENSSL_EXPORT int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, - void *value, int crit, unsigned long flags); - -#define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) - -// X509V3_EXT_DEFAULT causes unknown extensions or syntax errors to return -// failure. -#define X509V3_EXT_DEFAULT 0 -// X509V3_EXT_ERROR_UNKNOWN causes unknown extensions or syntax errors to print -// as "" or "", respectively. -#define X509V3_EXT_ERROR_UNKNOWN (1L << 16) -// X509V3_EXT_PARSE_UNKNOWN is deprecated and behaves like -// |X509V3_EXT_DUMP_UNKNOWN|. -#define X509V3_EXT_PARSE_UNKNOWN (2L << 16) -// X509V3_EXT_DUMP_UNKNOWN causes unknown extensions to be displayed as a -// hexdump. -#define X509V3_EXT_DUMP_UNKNOWN (3L << 16) - -OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, - const STACK_OF(CONF_VALUE) *val, - int indent, int ml); -OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, const X509_EXTENSION *ext, - unsigned long flag, int indent); -OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, const X509_EXTENSION *ext, - int flag, int indent); - -// X509V3_extensions_print prints |title|, followed by a human-readable -// representation of |exts| to |out|. It returns one on success and zero on -// error. The output is indented by |indent| spaces. |flag| is one of the -// |X509V3_EXT_*| constants and controls printing of unknown extensions and -// syntax errors. -OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, - const STACK_OF(X509_EXTENSION) *exts, - unsigned long flag, int indent); - -OPENSSL_EXPORT int X509_check_ca(X509 *x); -OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); -OPENSSL_EXPORT int X509_supported_extension(const X509_EXTENSION *ex); -OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); -OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); -OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); - -OPENSSL_EXPORT uint32_t X509_get_extension_flags(X509 *x); -OPENSSL_EXPORT uint32_t X509_get_key_usage(X509 *x); -OPENSSL_EXPORT uint32_t X509_get_extended_key_usage(X509 *x); - -// X509_get0_subject_key_id returns |x509|'s subject key identifier, if present. -// (See RFC 5280, section 4.2.1.2.) It returns NULL if the extension is not -// present or if some extension in |x509| was invalid. -// -// Note that decoding an |X509| object will not check for invalid extensions. To -// detect the error case, call |X509_get_extensions_flags| and check the -// |EXFLAG_INVALID| bit. -OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x509); - -// X509_get0_authority_key_id returns keyIdentifier of |x509|'s authority key -// identifier, if the extension and field are present. (See RFC 5280, -// section 4.2.1.1.) It returns NULL if the extension is not present, if it is -// present but lacks a keyIdentifier field, or if some extension in |x509| was -// invalid. -// -// Note that decoding an |X509| object will not check for invalid extensions. To -// detect the error case, call |X509_get_extensions_flags| and check the -// |EXFLAG_INVALID| bit. -OPENSSL_EXPORT const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x509); - -// X509_get0_authority_issuer returns the authorityCertIssuer of |x509|'s -// authority key identifier, if the extension and field are present. (See -// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present, -// if it is present but lacks a authorityCertIssuer field, or if some extension -// in |x509| was invalid. -// -// Note that decoding an |X509| object will not check for invalid extensions. To -// detect the error case, call |X509_get_extensions_flags| and check the -// |EXFLAG_INVALID| bit. -OPENSSL_EXPORT const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x509); - -// X509_get0_authority_serial returns the authorityCertSerialNumber of |x509|'s -// authority key identifier, if the extension and field are present. (See -// RFC 5280, section 4.2.1.1.) It returns NULL if the extension is not present, -// if it is present but lacks a authorityCertSerialNumber field, or if some -// extension in |x509| was invalid. -// -// Note that decoding an |X509| object will not check for invalid extensions. To -// detect the error case, call |X509_get_extensions_flags| and check the -// |EXFLAG_INVALID| bit. -OPENSSL_EXPORT const ASN1_INTEGER *X509_get0_authority_serial(X509 *x509); - -OPENSSL_EXPORT int X509_PURPOSE_get_count(void); -OPENSSL_EXPORT X509_PURPOSE *X509_PURPOSE_get0(int idx); -OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(const char *sname); -OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); -OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags, - int (*ck)(const X509_PURPOSE *, - const X509 *, int), - const char *name, const char *sname, - void *arg); -OPENSSL_EXPORT char *X509_PURPOSE_get0_name(const X509_PURPOSE *xp); -OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(const X509_PURPOSE *xp); -OPENSSL_EXPORT int X509_PURPOSE_get_trust(const X509_PURPOSE *xp); -OPENSSL_EXPORT void X509_PURPOSE_cleanup(void); -OPENSSL_EXPORT int X509_PURPOSE_get_id(const X509_PURPOSE *); - -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); - - -// 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 AWS-LC, this behavior is -// always enabled. This only applies to |X509_check_host| in OpenSSL. -#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0 - -// 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 - -// 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 - -// 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 -// X509_check_host will calculate the length using strlen. It is encouraged to -// always pass in the length of |chk| and rely on higher level parsing to ensure -// strlen is not called on a string that does not contain a null terminator. -// If a match is found X509_check_host returns 1, if |peername| is not null -// it is updated to point to the matching name in |x|. -OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen, - unsigned int flags, char **peername); - -// X509_check_email checks if the email address in |x| matches |chk| string up -// to |chklen|. If |chklen| is 0 X509_check_email will calculate the length -// using strlen. It is encouraged to always pass in the length of |chk| and rely -// on higher level parsing to ensure strlen is not called on a string that does -// not contain a null terminator. If the certificate matches X509_check_email -// returns 1. -OPENSSL_EXPORT int X509_check_email(X509 *x, const char *chk, size_t chklen, - unsigned int flags); - -// X509_check_ip checks if the IPv4 or IPv6 address in |x| matches |chk| up -// to |chklen|. X509_check_ip does not attempt to determine the length of |chk| -// if 0 is passed in for |chklen|. If the certificate matches X509_check_ip -// returns 1. -OPENSSL_EXPORT int X509_check_ip(X509 *x, const unsigned char *chk, - size_t chklen, unsigned int flags); -OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, - unsigned int flags); - -OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); -OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); - -// BEGIN ERROR CODES -// The following lines are auto generated by the script mkerr.pl. Any changes -// made after this point may be overwritten when the script is next run. - - -#if defined(__cplusplus) -} // extern C - -extern "C++" { - -BSSL_NAMESPACE_BEGIN - -BORINGSSL_MAKE_DELETER(ACCESS_DESCRIPTION, ACCESS_DESCRIPTION_free) -BORINGSSL_MAKE_DELETER(AUTHORITY_KEYID, AUTHORITY_KEYID_free) -BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free) -// TODO(davidben): Move this to conf.h and rename to CONF_VALUE_free. -BORINGSSL_MAKE_DELETER(CONF_VALUE, X509V3_conf_free) -BORINGSSL_MAKE_DELETER(DIST_POINT, DIST_POINT_free) -BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free) -BORINGSSL_MAKE_DELETER(GENERAL_SUBTREE, GENERAL_SUBTREE_free) -BORINGSSL_MAKE_DELETER(NAME_CONSTRAINTS, NAME_CONSTRAINTS_free) -BORINGSSL_MAKE_DELETER(POLICY_MAPPING, POLICY_MAPPING_free) -BORINGSSL_MAKE_DELETER(POLICYINFO, POLICYINFO_free) - -BSSL_NAMESPACE_END - -} // extern C++ -#endif - -#define X509V3_R_BAD_IP_ADDRESS 100 -#define X509V3_R_BAD_OBJECT 101 -#define X509V3_R_BN_DEC2BN_ERROR 102 -#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 103 -#define X509V3_R_CANNOT_FIND_FREE_FUNCTION 104 -#define X509V3_R_DIRNAME_ERROR 105 -#define X509V3_R_DISTPOINT_ALREADY_SET 106 -#define X509V3_R_DUPLICATE_ZONE_ID 107 -#define X509V3_R_ERROR_CONVERTING_ZONE 108 -#define X509V3_R_ERROR_CREATING_EXTENSION 109 -#define X509V3_R_ERROR_IN_EXTENSION 110 -#define X509V3_R_EXPECTED_A_SECTION_NAME 111 -#define X509V3_R_EXTENSION_EXISTS 112 -#define X509V3_R_EXTENSION_NAME_ERROR 113 -#define X509V3_R_EXTENSION_NOT_FOUND 114 -#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 115 -#define X509V3_R_EXTENSION_VALUE_ERROR 116 -#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 117 -#define X509V3_R_ILLEGAL_HEX_DIGIT 118 -#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 119 -#define X509V3_R_INVALID_BOOLEAN_STRING 120 -#define X509V3_R_INVALID_EXTENSION_STRING 121 -#define X509V3_R_INVALID_MULTIPLE_RDNS 122 -#define X509V3_R_INVALID_NAME 123 -#define X509V3_R_INVALID_NULL_ARGUMENT 124 -#define X509V3_R_INVALID_NULL_NAME 125 -#define X509V3_R_INVALID_NULL_VALUE 126 -#define X509V3_R_INVALID_NUMBER 127 -#define X509V3_R_INVALID_NUMBERS 128 -#define X509V3_R_INVALID_OBJECT_IDENTIFIER 129 -#define X509V3_R_INVALID_OPTION 130 -#define X509V3_R_INVALID_POLICY_IDENTIFIER 131 -#define X509V3_R_INVALID_PROXY_POLICY_SETTING 132 -#define X509V3_R_INVALID_PURPOSE 133 -#define X509V3_R_INVALID_SECTION 134 -#define X509V3_R_INVALID_SYNTAX 135 -#define X509V3_R_ISSUER_DECODE_ERROR 136 -#define X509V3_R_MISSING_VALUE 137 -#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 138 -#define X509V3_R_NO_CONFIG_DATABASE 139 -#define X509V3_R_NO_ISSUER_CERTIFICATE 140 -#define X509V3_R_NO_ISSUER_DETAILS 141 -#define X509V3_R_NO_POLICY_IDENTIFIER 142 -#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 143 -#define X509V3_R_NO_PUBLIC_KEY 144 -#define X509V3_R_NO_SUBJECT_DETAILS 145 -#define X509V3_R_ODD_NUMBER_OF_DIGITS 146 -#define X509V3_R_OPERATION_NOT_DEFINED 147 -#define X509V3_R_OTHERNAME_ERROR 148 -#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 149 -#define X509V3_R_POLICY_PATH_LENGTH 150 -#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 151 -#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 152 -#define X509V3_R_SECTION_NOT_FOUND 153 -#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 154 -#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 155 -#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 156 -#define X509V3_R_UNKNOWN_EXTENSION 157 -#define X509V3_R_UNKNOWN_EXTENSION_NAME 158 -#define X509V3_R_UNKNOWN_OPTION 159 -#define X509V3_R_UNSUPPORTED_OPTION 160 -#define X509V3_R_UNSUPPORTED_TYPE 161 -#define X509V3_R_USER_TOO_LONG 162 -#define X509V3_R_INVALID_VALUE 163 -#define X509V3_R_TRAILING_DATA_IN_EXTENSION 164 - -#endif // OPENSSL_HEADER_X509V3_H diff --git a/include/openssl/x509v3_errors.h b/include/openssl/x509v3_errors.h new file mode 100644 index 0000000000..293d268d54 --- /dev/null +++ b/include/openssl/x509v3_errors.h @@ -0,0 +1,124 @@ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project 1999. */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * 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 above 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 acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED 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 OpenSSL PROJECT OR + * ITS 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. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_X509V3_ERRORS_H +#define OPENSSL_HEADER_X509V3_ERRORS_H + +#define X509V3_R_BAD_IP_ADDRESS 100 +#define X509V3_R_BAD_OBJECT 101 +#define X509V3_R_BN_DEC2BN_ERROR 102 +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 103 +#define X509V3_R_CANNOT_FIND_FREE_FUNCTION 104 +#define X509V3_R_DIRNAME_ERROR 105 +#define X509V3_R_DISTPOINT_ALREADY_SET 106 +#define X509V3_R_DUPLICATE_ZONE_ID 107 +#define X509V3_R_ERROR_CONVERTING_ZONE 108 +#define X509V3_R_ERROR_CREATING_EXTENSION 109 +#define X509V3_R_ERROR_IN_EXTENSION 110 +#define X509V3_R_EXPECTED_A_SECTION_NAME 111 +#define X509V3_R_EXTENSION_EXISTS 112 +#define X509V3_R_EXTENSION_NAME_ERROR 113 +#define X509V3_R_EXTENSION_NOT_FOUND 114 +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 115 +#define X509V3_R_EXTENSION_VALUE_ERROR 116 +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 117 +#define X509V3_R_ILLEGAL_HEX_DIGIT 118 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 119 +#define X509V3_R_INVALID_BOOLEAN_STRING 120 +#define X509V3_R_INVALID_EXTENSION_STRING 121 +#define X509V3_R_INVALID_MULTIPLE_RDNS 122 +#define X509V3_R_INVALID_NAME 123 +#define X509V3_R_INVALID_NULL_ARGUMENT 124 +#define X509V3_R_INVALID_NULL_NAME 125 +#define X509V3_R_INVALID_NULL_VALUE 126 +#define X509V3_R_INVALID_NUMBER 127 +#define X509V3_R_INVALID_NUMBERS 128 +#define X509V3_R_INVALID_OBJECT_IDENTIFIER 129 +#define X509V3_R_INVALID_OPTION 130 +#define X509V3_R_INVALID_POLICY_IDENTIFIER 131 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 132 +#define X509V3_R_INVALID_PURPOSE 133 +#define X509V3_R_INVALID_SECTION 134 +#define X509V3_R_INVALID_SYNTAX 135 +#define X509V3_R_ISSUER_DECODE_ERROR 136 +#define X509V3_R_MISSING_VALUE 137 +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 138 +#define X509V3_R_NO_CONFIG_DATABASE 139 +#define X509V3_R_NO_ISSUER_CERTIFICATE 140 +#define X509V3_R_NO_ISSUER_DETAILS 141 +#define X509V3_R_NO_POLICY_IDENTIFIER 142 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 143 +#define X509V3_R_NO_PUBLIC_KEY 144 +#define X509V3_R_NO_SUBJECT_DETAILS 145 +#define X509V3_R_ODD_NUMBER_OF_DIGITS 146 +#define X509V3_R_OPERATION_NOT_DEFINED 147 +#define X509V3_R_OTHERNAME_ERROR 148 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 149 +#define X509V3_R_POLICY_PATH_LENGTH 150 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 151 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 152 +#define X509V3_R_SECTION_NOT_FOUND 153 +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 154 +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 155 +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 156 +#define X509V3_R_UNKNOWN_EXTENSION 157 +#define X509V3_R_UNKNOWN_EXTENSION_NAME 158 +#define X509V3_R_UNKNOWN_OPTION 159 +#define X509V3_R_UNSUPPORTED_OPTION 160 +#define X509V3_R_UNSUPPORTED_TYPE 161 +#define X509V3_R_USER_TOO_LONG 162 +#define X509V3_R_INVALID_VALUE 163 +#define X509V3_R_TRAILING_DATA_IN_EXTENSION 164 + +#endif // OPENSSL_HEADER_X509V3_ERRORS_H diff --git a/ssl/ssl_test.cc b/ssl/ssl_test.cc index a449744cde..c8335de560 100644 --- a/ssl/ssl_test.cc +++ b/ssl/ssl_test.cc @@ -42,7 +42,6 @@ #include #include #include -#include #include "../crypto/internal.h" #include "../crypto/test/test_util.h" diff --git a/ssl/ssl_x509.cc b/ssl/ssl_x509.cc index 8af55a8636..5388a475ee 100644 --- a/ssl/ssl_x509.cc +++ b/ssl/ssl_x509.cc @@ -148,7 +148,6 @@ #include #include #include -#include #include "../crypto/internal.h" #include "internal.h" diff --git a/util/make_errors.go b/util/make_errors.go index fd36b07f16..0ec0fd1726 100644 --- a/util/make_errors.go +++ b/util/make_errors.go @@ -60,6 +60,7 @@ func getLibraryInfo(lib string) libraryInfo { } if lib == "x509v3" { + info.headerName = "x509v3_errors.h" info.sourceDirs = append(info.sourceDirs, filepath.Join("crypto", "x509")) }