diff options
Diffstat (limited to 'crypto/x509/x509_req.c')
-rw-r--r-- | crypto/x509/x509_req.c | 100 |
1 files changed, 60 insertions, 40 deletions
diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c index 0434fbbc6b70..4085b587a5e1 100644 --- a/crypto/x509/x509_req.c +++ b/crypto/x509/x509_req.c @@ -28,7 +28,7 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) ret = X509_REQ_new_ex(x->libctx, x->propq); if (ret == NULL) { - ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } @@ -67,7 +67,7 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) return X509_PUBKEY_get(req->req_info.pubkey); } -EVP_PKEY *X509_REQ_get0_pubkey(X509_REQ *req) +EVP_PKEY *X509_REQ_get0_pubkey(const X509_REQ *req) { if (req == NULL) return NULL; @@ -79,28 +79,9 @@ X509_PUBKEY *X509_REQ_get_X509_PUBKEY(X509_REQ *req) return req->req_info.pubkey; } -int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +int X509_REQ_check_private_key(const X509_REQ *req, EVP_PKEY *pkey) { - EVP_PKEY *xk = NULL; - int ok = 0; - - xk = X509_REQ_get_pubkey(x); - switch (EVP_PKEY_eq(xk, k)) { - case 1: - ok = 1; - break; - case 0: - ERR_raise(ERR_LIB_X509, X509_R_KEY_VALUES_MISMATCH); - break; - case -1: - ERR_raise(ERR_LIB_X509, X509_R_KEY_TYPE_MISMATCH); - break; - case -2: - ERR_raise(ERR_LIB_X509, X509_R_UNKNOWN_KEY_TYPE); - } - - EVP_PKEY_free(xk); - return ok; + return ossl_x509_check_private_key(X509_REQ_get0_pubkey(req), pkey); } /* @@ -136,33 +117,47 @@ void X509_REQ_set_extension_nids(int *nids) ext_nids = nids; } -STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) +static STACK_OF(X509_EXTENSION) *get_extensions_by_nid(const X509_REQ *req, + int nid) { X509_ATTRIBUTE *attr; ASN1_TYPE *ext = NULL; - int idx, *pnid; const unsigned char *p; + int idx = X509_REQ_get_attr_by_NID(req, nid, -1); - if (req == NULL || !ext_nids) - return NULL; - for (pnid = ext_nids; *pnid != NID_undef; pnid++) { - idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); - if (idx == -1) - continue; - attr = X509_REQ_get_attr(req, idx); - ext = X509_ATTRIBUTE_get0_type(attr, 0); - break; - } - if (ext == NULL) /* no extensions is not an error */ + if (idx < 0) /* no extensions is not an error */ return sk_X509_EXTENSION_new_null(); - if (ext->type != V_ASN1_SEQUENCE) + attr = X509_REQ_get_attr(req, idx); + ext = X509_ATTRIBUTE_get0_type(attr, 0); + if (ext == NULL || ext->type != V_ASN1_SEQUENCE) { + ERR_raise(ERR_LIB_X509, X509_R_WRONG_TYPE); return NULL; + } p = ext->value.sequence->data; return (STACK_OF(X509_EXTENSION) *) ASN1_item_d2i(NULL, &p, ext->value.sequence->length, ASN1_ITEM_rptr(X509_EXTENSIONS)); } +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(OSSL_FUTURE_CONST X509_REQ *req) +{ + STACK_OF(X509_EXTENSION) *exts = NULL; + int *pnid; + + if (req == NULL || ext_nids == NULL) + return NULL; + for (pnid = ext_nids; *pnid != NID_undef; pnid++) { + exts = get_extensions_by_nid(req, *pnid); + if (exts == NULL) + return NULL; + if (sk_X509_EXTENSION_num(exts) > 0) + return exts; + sk_X509_EXTENSION_free(exts); + } + /* no extensions is not an error */ + return sk_X509_EXTENSION_new_null(); +} + /* * Add a STACK_OF extensions to a certificate request: allow alternative OIDs * in case we want to create a non standard one. @@ -173,14 +168,39 @@ int X509_REQ_add_extensions_nid(X509_REQ *req, int extlen; int rv = 0; unsigned char *ext = NULL; + STACK_OF(X509_EXTENSION) *mod_exts = NULL; + int loc; + + if (sk_X509_EXTENSION_num(exts) <= 0) + return 1; /* adding NULL or empty list of exts is a no-op */ + + loc = X509at_get_attr_by_NID(req->req_info.attributes, nid, -1); + if (loc != -1) { + if ((mod_exts = get_extensions_by_nid(req, nid)) == NULL) + return 0; + if (X509v3_add_extensions(&mod_exts, exts) == NULL) + goto end; + } /* Generate encoding of extensions */ - extlen = ASN1_item_i2d((const ASN1_VALUE *)exts, &ext, - ASN1_ITEM_rptr(X509_EXTENSIONS)); + extlen = ASN1_item_i2d((const ASN1_VALUE *) + (mod_exts == NULL ? exts : mod_exts), + &ext, ASN1_ITEM_rptr(X509_EXTENSIONS)); if (extlen <= 0) - return 0; + goto end; + if (mod_exts != NULL) { + X509_ATTRIBUTE *att = X509at_delete_attr(req->req_info.attributes, loc); + + if (att == NULL) + goto end; + X509_ATTRIBUTE_free(att); + } + rv = X509_REQ_add1_attr_by_NID(req, nid, V_ASN1_SEQUENCE, ext, extlen); OPENSSL_free(ext); + + end: + sk_X509_EXTENSION_pop_free(mod_exts, X509_EXTENSION_free); return rv; } |