summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>2020-12-24 11:25:47 +0100
committerDr. David von Oheimb <dev@ddvo.net>2021-01-13 11:53:15 +0100
commit41e597a01d95540f52e8bc4d69f88c3d93a093ce (patch)
tree5ae2b3b3691b635e55d704f8874bacfce6c34911 /crypto
parentea9fd333d19096d654cb252a2f6785ca03bfcbc1 (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.c42
-rw-r--r--crypto/x509/v3_alt.c6
-rw-r--r--crypto/x509/v3_conf.c34
-rw-r--r--crypto/x509/v3_skey.c63
-rw-r--r--crypto/x509/v3_utf8.c1
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"
/*