Skip to content

Commit fa08e7a

Browse files
Restore previous semantics of authorityKeyIdentifier=keyid
Also self-signed certificates should always have an AKID, not only for "keyid:always" but also for "keyid", and just silently fall back to not having an AKID if the signer does not have an SKID extension, as this was previously. Fixes openssl#29001
1 parent 36efd09 commit fa08e7a

File tree

2 files changed

+18
-26
lines changed

2 files changed

+18
-26
lines changed

crypto/x509/v3_akid.c

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
107107
ASN1_INTEGER *serial = NULL;
108108
X509_EXTENSION *ext;
109109
X509 *issuer_cert;
110-
int same_issuer, ss;
110+
int same_issuer;
111111
AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
112112

113113
if (akeyid == NULL)
@@ -156,44 +156,38 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
156156
ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
157157
goto err;
158158
}
159-
same_issuer = ctx->subject_cert == ctx->issuer_cert;
160-
ERR_set_mark();
161-
if (ctx->issuer_pkey != NULL)
162-
ss = X509_check_private_key(ctx->subject_cert, ctx->issuer_pkey);
163-
else
164-
ss = same_issuer;
165-
ERR_pop_to_mark();
159+
same_issuer = ctx->subject_cert == issuer_cert;
166160

167161
/* unless forced with "always", AKID is suppressed for self-signed certs */
168-
if (keyid == 2 || (keyid == 1 && !ss)) {
162+
if (keyid != 0) {
169163
/*
170164
* prefer any pre-existing subject key identifier of the issuer cert
171-
* except issuer cert is same as subject cert and is not self-signed
165+
* except issuer cert is same as subject cert and private key is given
172166
*/
173-
i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
174-
if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
175-
&& !(same_issuer && !ss)) {
176-
ikeyid = X509V3_EXT_d2i(ext);
177-
if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ {
178-
ASN1_OCTET_STRING_free(ikeyid);
179-
ikeyid = NULL;
180-
}
181-
}
182-
if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) {
167+
if (same_issuer && ctx->issuer_pkey != NULL) {
183168
/* generate fallback AKID, emulating s2i_skey_id(..., "hash") */
184169
X509_PUBKEY *pubkey = NULL;
185170

186171
if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey))
187172
ikeyid = ossl_x509_pubkey_hash(pubkey);
188173
X509_PUBKEY_free(pubkey);
174+
} else {
175+
i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
176+
if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL) {
177+
ikeyid = X509V3_EXT_d2i(ext);
178+
if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ {
179+
ASN1_OCTET_STRING_free(ikeyid);
180+
ikeyid = NULL;
181+
}
182+
}
189183
}
190184
if (keyid == 2 && ikeyid == NULL) {
191185
ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
192186
goto err;
193187
}
194188
}
195189

196-
if (issuer == 2 || (issuer == 1 && !ss && ikeyid == NULL)) {
190+
if (issuer == 2 || (issuer == 1 && !same_issuer && ikeyid == NULL)) {
197191
isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert));
198192
serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert));
199193
if (isname == NULL || serial == NULL) {
@@ -217,8 +211,6 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
217211
}
218212

219213
akeyid->issuer = gens;
220-
gen = NULL;
221-
gens = NULL;
222214
akeyid->serial = serial;
223215
akeyid->keyid = ikeyid;
224216

test/recipes/25-test_req.t

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ has_AKID($cert, 0); # forced no AKID
612612

613613
$cert = "self-signed_v3_CA_explicit_AKID.pem";
614614
generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid");
615-
has_AKID($cert, 0); # for self-signed cert, AKID suppressed and not forced
615+
has_AKID($cert, 1); # for self-signed cert, AKID present but not forced
616616

617617
$cert = "self-signed_v3_CA_forced_AKID.pem";
618618
generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid:always");
@@ -629,11 +629,11 @@ cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 1); # f
629629

630630
$cert = "self-signed_v3_CA_nonforced_keyid_issuer_AKID.pem";
631631
generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid, issuer");
632-
has_AKID($cert, 0); # AKID not present because not forced and cert self-signed
632+
has_AKID($cert, 1); # AKID present but not forced
633633

634634
$cert = "self-signed_v3_CA_keyid_forced_issuer_AKID.pem";
635635
generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid, issuer:always");
636-
cert_contains($cert, "Authority Key Identifier: DirName:/CN=CA serial:", 1); # issuer AKID forced, with keyid not forced
636+
cert_contains($cert, "Authority Key Identifier: keyid:.* DirName:/CN=CA serial:", 1); # issuer AKID forced, with keyid not forced
637637

638638
$cert = "self-signed_v3_CA_forced_keyid_issuer_AKID.pem";
639639
generate_cert($cert, @v3_ca, "-addext", "authorityKeyIdentifier = keyid:always, issuer");

0 commit comments

Comments
 (0)