diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2020-12-24 11:25:47 +0100 |
---|---|---|
committer | Dr. David von Oheimb <dev@ddvo.net> | 2021-01-13 11:53:15 +0100 |
commit | 41e597a01d95540f52e8bc4d69f88c3d93a093ce (patch) | |
tree | 5ae2b3b3691b635e55d704f8874bacfce6c34911 /crypto | |
parent | ea9fd333d19096d654cb252a2f6785ca03bfcbc1 (diff) |
Add X509V3_set_issuer_pkey, needed for AKID of self-issued not self-signed cert
Also clean up some related auxiliary functions and documentation
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13658)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/x509/v3_akey.c | 42 | ||||
-rw-r--r-- | crypto/x509/v3_alt.c | 6 | ||||
-rw-r--r-- | crypto/x509/v3_conf.c | 34 | ||||
-rw-r--r-- | crypto/x509/v3_skey.c | 63 | ||||
-rw-r--r-- | crypto/x509/v3_utf8.c | 1 |
5 files changed, 91 insertions, 55 deletions
diff --git a/crypto/x509/v3_akey.c b/crypto/x509/v3_akey.c index 2e90d495c5..d0d20c4455 100644 --- a/crypto/x509/v3_akey.c +++ b/crypto/x509/v3_akey.c @@ -13,6 +13,7 @@ #include <openssl/asn1.h> #include <openssl/asn1t.h> #include <openssl/x509v3.h> +#include "crypto/x509.h" #include "ext_dat.h" static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, @@ -86,7 +87,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, GENERAL_NAME *gen = NULL; ASN1_INTEGER *serial = NULL; X509_EXTENSION *ext; - X509 *cert; + X509 *issuer_cert; AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new(); if (akeyid == NULL) @@ -113,36 +114,49 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, } } - if (!ctx || !ctx->issuer_cert) { - if (ctx && (ctx->flags == CTX_TEST)) - return akeyid; + if (ctx != NULL && (ctx->flags & CTX_TEST) != 0) + return akeyid; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if ((issuer_cert = ctx->issuer_cert) == NULL) { ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); goto err; } - cert = ctx->issuer_cert; - if (keyid) { - i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); - if ((i >= 0) && (ext = X509_get_ext(cert, i))) + if (keyid != 0) { + /* prefer any pre-existing subject key identifier of the issuer cert */ + i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1); + if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL) ikeyid = X509V3_EXT_d2i(ext); + if (ikeyid == NULL && ctx->issuer_pkey != NULL) { /* fallback */ + /* generate AKID from scratch, emulating s2i_skey_id(..., "hash") */ + X509_PUBKEY *pubkey = NULL; + + if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey)) + ikeyid = x509_pubkey_hash(pubkey); + X509_PUBKEY_free(pubkey); + } if ((keyid == 2 || issuer == 0) && (ikeyid == NULL - || ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */ ) { + || ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */) { ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); goto err; } } - if ((issuer && !ikeyid) || (issuer == 2)) { - isname = X509_NAME_dup(X509_get_issuer_name(cert)); - serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert)); - if (!isname || !serial) { + if (issuer == 2 || (issuer == 1 && ikeyid == NULL)) { + isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert)); + serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert)); + if (isname == NULL || serial == NULL) { ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); goto err; } } - if (isname) { + if (isname != NULL) { if ((gens = sk_GENERAL_NAME_new_null()) == NULL || (gen = GENERAL_NAME_new()) == NULL || !sk_GENERAL_NAME_push(gens, gen)) { diff --git a/crypto/x509/v3_alt.c b/crypto/x509/v3_alt.c index 2344c554fa..d2e3ec138b 100644 --- a/crypto/x509/v3_alt.c +++ b/crypto/x509/v3_alt.c @@ -325,7 +325,7 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) X509_EXTENSION *ext; int i, num; - if (ctx && (ctx->flags == CTX_TEST)) + if (ctx != NULL && (ctx->flags & CTX_TEST) != 0) return 1; if (!ctx || !ctx->issuer_cert) { ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_DETAILS); @@ -410,12 +410,12 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) GENERAL_NAME *gen = NULL; int i = -1; - if (ctx != NULL && ctx->flags == CTX_TEST) + if (ctx != NULL && (ctx->flags & CTX_TEST) != 0) return 1; if (ctx == NULL || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS); - goto err; + return 0; } /* Find the subject name */ if (ctx->subject_cert) diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c index 1f424325a0..f8a2e3fe27 100644 --- a/crypto/x509/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -437,6 +437,10 @@ static X509V3_CONF_METHOD nconf_method = { void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) { + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return; + } ctx->db_meth = &nconf_method; ctx->db = conf; } @@ -444,11 +448,33 @@ void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, X509_CRL *crl, int flags) { + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return; + } + ctx->flags = flags; ctx->issuer_cert = issuer; ctx->subject_cert = subj; - ctx->crl = crl; ctx->subject_req = req; - ctx->flags = flags; + ctx->crl = crl; + ctx->db_meth = NULL; + ctx->db = NULL; + ctx->issuer_pkey = NULL; +} + +/* For API backward compatibility, this is separate from X509V3_set_ctx() */ +int X509V3_set_issuer_pkey(X509V3_CTX *ctx, EVP_PKEY *pkey) +{ + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ctx->subject_cert == NULL && pkey != NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + ctx->issuer_pkey = pkey; + return 1; } /* Old conf compatibility functions */ @@ -489,6 +515,10 @@ static X509V3_CONF_METHOD conf_lhash_method = { void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) { + if (ctx == NULL) { + ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER); + return; + } ctx->db_meth = &conf_lhash_method; ctx->db = lhash; } diff --git a/crypto/x509/v3_skey.c b/crypto/x509/v3_skey.c index 6122596081..8d13dc248a 100644 --- a/crypto/x509/v3_skey.c +++ b/crypto/x509/v3_skey.c @@ -52,56 +52,49 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, } -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) +ASN1_OCTET_STRING *x509_pubkey_hash(X509_PUBKEY *pubkey) { ASN1_OCTET_STRING *oct; - X509_PUBKEY *pubkey; const unsigned char *pk; int pklen; unsigned char pkey_dig[EVP_MAX_MD_SIZE]; unsigned int diglen; - if (strcmp(str, "none") == 0) - return ASN1_OCTET_STRING_new(); /* dummy */ - - if (strcmp(str, "hash") != 0) - return s2i_ASN1_OCTET_STRING(method, ctx, str); - - if ((oct = ASN1_OCTET_STRING_new()) == NULL) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); + if (pubkey == NULL) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY); return NULL; } + if ((oct = ASN1_OCTET_STRING_new()) == NULL) + return NULL; - if (ctx && (ctx->flags == CTX_TEST)) + X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey); + /* TODO(3.0) - explicitly fetch the digest */ + if (EVP_Digest(pk, pklen, pkey_dig, &diglen, EVP_sha1(), NULL) + && ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) return oct; - if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { - ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - pubkey = ctx->subject_req != NULL ? - ctx->subject_req->req_info.pubkey : - ctx->subject_cert->cert_info.key; - if (pubkey == NULL) { - ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_PUBLIC_KEY); - goto err; - } + ASN1_OCTET_STRING_free(oct); + return NULL; +} - X509_PUBKEY_get0_param(NULL, &pk, &pklen, NULL, pubkey); +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + if (strcmp(str, "none") == 0) + return ASN1_OCTET_STRING_new(); /* dummy */ - if (!EVP_Digest(pk, pklen, pkey_dig, &diglen, EVP_sha1(), NULL)) - goto err; + if (strcmp(str, "hash") != 0) + return s2i_ASN1_OCTET_STRING(method, ctx /* not used */, str); - if (!ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { - ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE); - goto err; + if (ctx != NULL && (ctx->flags & CTX_TEST) != 0) + return ASN1_OCTET_STRING_new(); + if (ctx == NULL + || (ctx->subject_cert == NULL && ctx->subject_req == NULL)) { + ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_SUBJECT_DETAILS); + return NULL; } - return oct; - - err: - ASN1_OCTET_STRING_free(oct); - return NULL; + return x509_pubkey_hash(ctx->subject_req != NULL ? + ctx->subject_req->req_info.pubkey : + ctx->subject_cert->cert_info.key); } diff --git a/crypto/x509/v3_utf8.c b/crypto/x509/v3_utf8.c index d37ac73246..465e0a39a3 100644 --- a/crypto/x509/v3_utf8.c +++ b/crypto/x509/v3_utf8.c @@ -12,7 +12,6 @@ #include <openssl/asn1.h> #include <openssl/conf.h> #include <openssl/x509v3.h> -#include <crypto/x509v3.h> #include "ext_dat.h" /* |