aboutsummaryrefslogtreecommitdiff
path: root/crypto/x509/x509_req.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/x509/x509_req.c')
-rw-r--r--crypto/x509/x509_req.c100
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;
}