Use X509_get0_pubkey to simplify things slightly
Also X509_REQ_check_private_key didn't handle unknown key type case.
Clean those up and align with X509_check_private_key.
Change-Id: I7b16f85662943e4b226221a01e1092cf62afc643
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/65051
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/x509/t_req.c b/crypto/x509/t_req.c
index 3cfab19..bc41b45 100644
--- a/crypto/x509/t_req.c
+++ b/crypto/x509/t_req.c
@@ -80,7 +80,6 @@
int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags,
unsigned long cflag) {
long l;
- EVP_PKEY *pkey;
STACK_OF(X509_ATTRIBUTE) *sk;
char mlch = ' ';
@@ -127,13 +126,12 @@
goto err;
}
- pkey = X509_REQ_get_pubkey(x);
+ const EVP_PKEY *pkey = X509_REQ_get0_pubkey(x);
if (pkey == NULL) {
BIO_printf(bio, "%12sUnable to load Public Key\n", "");
ERR_print_errors(bio);
} else {
EVP_PKEY_print_public(bio, pkey, 16, NULL);
- EVP_PKEY_free(pkey);
}
}
diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c
index 9596b65..9046928 100644
--- a/crypto/x509/t_x509.c
+++ b/crypto/x509/t_x509.c
@@ -212,13 +212,12 @@
return 0;
}
- EVP_PKEY *pkey = X509_get_pubkey(x);
+ const EVP_PKEY *pkey = X509_get0_pubkey(x);
if (pkey == NULL) {
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
ERR_print_errors(bp);
} else {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
- EVP_PKEY_free(pkey);
}
}
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 9574c9b..87518ff 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -218,6 +218,13 @@
return NULL;
}
+EVP_PKEY *X509_get0_pubkey(const X509 *x) {
+ if (x == NULL) {
+ return NULL;
+ }
+ return X509_PUBKEY_get0(x->cert_info->key);
+}
+
EVP_PKEY *X509_get_pubkey(const X509 *x) {
if (x == NULL) {
return NULL;
@@ -232,36 +239,29 @@
return x->cert_info->key->public_key;
}
-int X509_check_private_key(X509 *x, const EVP_PKEY *k) {
- EVP_PKEY *xk;
- int ret;
-
- xk = X509_get_pubkey(x);
-
- if (xk) {
- ret = EVP_PKEY_cmp(xk, k);
- } else {
- ret = -2;
+int X509_check_private_key(const X509 *x, const EVP_PKEY *k) {
+ const EVP_PKEY *xk = X509_get0_pubkey(x);
+ if (xk == NULL) {
+ return 0;
}
- switch (ret) {
- case 1:
- break;
- case 0:
- OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
- break;
- case -1:
- OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
- break;
- case -2:
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
- }
- if (xk) {
- EVP_PKEY_free(xk);
- }
+ int ret = EVP_PKEY_cmp(xk, k);
if (ret > 0) {
return 1;
}
+
+ switch (ret) {
+ case 0:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
+ return 0;
+ case -1:
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
+ return 0;
+ case -2:
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+ return 0;
+ }
+
return 0;
}
diff --git a/crypto/x509/x509_req.c b/crypto/x509/x509_req.c
index 3c192ff..c7ea009 100644
--- a/crypto/x509/x509_req.c
+++ b/crypto/x509/x509_req.c
@@ -77,37 +77,47 @@
}
EVP_PKEY *X509_REQ_get_pubkey(const X509_REQ *req) {
- if ((req == NULL) || (req->req_info == NULL)) {
+ if (req == NULL) {
return NULL;
}
- return (X509_PUBKEY_get(req->req_info->pubkey));
+ return X509_PUBKEY_get(req->req_info->pubkey);
}
-int X509_REQ_check_private_key(X509_REQ *x, const EVP_PKEY *k) {
- EVP_PKEY *xk = NULL;
- int ok = 0;
+EVP_PKEY *X509_REQ_get0_pubkey(const X509_REQ *req) {
+ if (req == NULL) {
+ return NULL;
+ }
+ return X509_PUBKEY_get0(req->req_info->pubkey);
+}
- xk = X509_REQ_get_pubkey(x);
- switch (EVP_PKEY_cmp(xk, k)) {
- case 1:
- ok = 1;
- break;
+int X509_REQ_check_private_key(const X509_REQ *x, const EVP_PKEY *k) {
+ const EVP_PKEY *xk = X509_REQ_get0_pubkey(x);
+ if (xk == NULL) {
+ return 0;
+ }
+
+ int ret = EVP_PKEY_cmp(xk, k);
+ if (ret > 0) {
+ return 1;
+ }
+
+ switch (ret) {
case 0:
OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
- break;
+ return 0;
case -1:
OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
- break;
+ return 0;
case -2:
if (EVP_PKEY_id(k) == EVP_PKEY_EC) {
OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
- break;
+ } else {
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
}
- OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
+ return 0;
}
- EVP_PKEY_free(xk);
- return ok;
+ return 0;
}
int X509_REQ_extension_nid(int req_nid) {
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index 6bf366b..15121d2 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -1171,8 +1171,6 @@
// Check CRL validity
static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) {
X509 *issuer = NULL;
- EVP_PKEY *ikey = NULL;
- int ok = 0;
int cnum = ctx->error_depth;
int chnum = (int)sk_X509_num(ctx->chain) - 1;
// if we have an alternative CRL issuer cert use that
@@ -1189,9 +1187,8 @@
// If not self signed, can't check signature
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) {
- goto err;
+ if (!ctx->verify_cb(0, ctx)) {
+ return 0;
}
}
}
@@ -1201,61 +1198,50 @@
if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
!(issuer->ex_kusage & X509v3_KU_CRL_SIGN)) {
ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) {
- goto err;
+ if (!ctx->verify_cb(0, ctx)) {
+ return 0;
}
}
if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) {
- goto err;
+ if (!ctx->verify_cb(0, ctx)) {
+ return 0;
}
}
if (crl->idp_flags & IDP_INVALID) {
ctx->error = X509_V_ERR_INVALID_EXTENSION;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) {
- goto err;
+ if (!ctx->verify_cb(0, ctx)) {
+ return 0;
}
}
if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
- ok = check_crl_time(ctx, crl, 1);
- if (!ok) {
- goto err;
+ if (!check_crl_time(ctx, crl, 1)) {
+ return 0;
}
}
// Attempt to get issuer certificate public key
- ikey = X509_get_pubkey(issuer);
-
+ EVP_PKEY *ikey = X509_get0_pubkey(issuer);
if (!ikey) {
ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) {
- goto err;
+ if (!ctx->verify_cb(0, ctx)) {
+ return 0;
}
} else {
// Verify CRL signature
if (X509_CRL_verify(crl, ikey) <= 0) {
ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
- ok = ctx->verify_cb(0, ctx);
- if (!ok) {
- goto err;
+ if (!ctx->verify_cb(0, ctx)) {
+ return 0;
}
}
}
}
- ok = 1;
-
-err:
- EVP_PKEY_free(ikey);
- return ok;
+ return 1;
}
// Check certificate against CRL
@@ -1365,7 +1351,6 @@
static int internal_verify(X509_STORE_CTX *ctx) {
int ok = 0;
X509 *xs, *xi;
- EVP_PKEY *pkey = NULL;
int n = (int)sk_X509_num(ctx->chain);
ctx->error_depth = n - 1;
@@ -1399,7 +1384,8 @@
// explicitly asked for. It doesn't add any security and just wastes
// time.
if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
- if ((pkey = X509_get_pubkey(xi)) == NULL) {
+ EVP_PKEY *pkey = X509_get0_pubkey(xi);
+ if (pkey == NULL) {
ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
ctx->current_cert = xi;
ok = ctx->verify_cb(0, ctx);
@@ -1411,12 +1397,9 @@
ctx->current_cert = xs;
ok = ctx->verify_cb(0, ctx);
if (!ok) {
- EVP_PKEY_free(pkey);
goto end;
}
}
- EVP_PKEY_free(pkey);
- pkey = NULL;
}
check_cert:
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 697f193..72bca77 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -219,7 +219,8 @@
// 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);
+OPENSSL_EXPORT int X509_check_private_key(const 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
@@ -1128,7 +1129,7 @@
// 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,
+OPENSSL_EXPORT int X509_REQ_check_private_key(const X509_REQ *req,
const EVP_PKEY *pkey);
// X509_REQ_get_attr_count returns the number of attributes in |req|.