Skip to content

Commit 1a3b8a6

Browse files
Restore previous semantics of authorityKeyIdentifier=keyid
when the function X509V3_set_issuer_pkey is not used, since that would break code written for 1.1.1 and before, where e.g. X509V3_EXT_conf(NULL, &ctx, "authorityKeyIdentifier", "keyid,issuer"); was guaranteed to never fail and always generate a valid extension, and not an empty AKID. But due to the change, which happened between 1.1.1 and 3.0 that is no longer the case. Code written for 3.0 must use X509V3_set_issuer_pkey and detect the possible empty extensions, or use keyid:always and be prepared that it may be impossible to create this extension.
1 parent 5c10213 commit 1a3b8a6

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

crypto/x509/v3_akid.c

Lines changed: 23 additions & 24 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 self_signed = 0;
111111
AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
112112

113113
if (akeyid == NULL)
@@ -145,50 +145,51 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
145145
ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
146146
goto err;
147147
}
148-
same_issuer = ctx->subject_cert == ctx->issuer_cert;
149-
ERR_set_mark();
150-
if (ctx->issuer_pkey != NULL)
151-
ss = X509_check_private_key(ctx->subject_cert, ctx->issuer_pkey);
152-
else
153-
ss = same_issuer;
154-
ERR_pop_to_mark();
148+
149+
if (ctx->subject_cert != NULL && ctx->issuer_pkey != NULL) {
150+
ERR_set_mark();
151+
self_signed = X509_check_private_key(ctx->subject_cert,
152+
ctx->issuer_pkey);
153+
ERR_pop_to_mark();
154+
}
155155

156156
/* unless forced with "always", AKID is suppressed for self-signed certs */
157-
if (keyid == 2 || (keyid == 1 && !ss)) {
157+
if (keyid == 2 || (keyid == 1 && !self_signed)) {
158158
/*
159159
* prefer any pre-existing subject key identifier of the issuer cert
160-
* except issuer cert is same as subject cert and is not self-signed
160+
* except issuer cert is same as subject cert and private key is given
161161
*/
162-
i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
163-
if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
164-
&& !(same_issuer && !ss))
165-
ikeyid = X509V3_EXT_d2i(ext);
166-
if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) {
162+
if (ctx->subject_cert == issuer_cert && ctx->issuer_pkey != NULL) {
167163
/* generate fallback AKID, emulating s2i_skey_id(..., "hash") */
168164
X509_PUBKEY *pubkey = NULL;
169165

170166
if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey))
171167
ikeyid = ossl_x509_pubkey_hash(pubkey);
172168
X509_PUBKEY_free(pubkey);
169+
} else {
170+
i = X509_get_ext_by_NID(issuer_cert,
171+
NID_subject_key_identifier, -1);
172+
if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL) {
173+
ikeyid = X509V3_EXT_d2i(ext);
174+
if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ {
175+
ASN1_OCTET_STRING_free(ikeyid);
176+
ikeyid = NULL;
177+
}
178+
}
173179
}
174-
if ((keyid == 2 || issuer == 0)
175-
&& (ikeyid == NULL
176-
|| ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */) {
180+
if (keyid == 2 && ikeyid == NULL) {
177181
ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
178182
goto err;
179183
}
180184
}
181185

182-
if (issuer == 2 || (issuer == 1 && ikeyid == NULL)) {
186+
if (issuer == 2 || (issuer == 1 && ikeyid == NULL && !self_signed)) {
183187
isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert));
184188
serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert));
185189
if (isname == NULL || serial == NULL) {
186190
ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
187191
goto err;
188192
}
189-
}
190-
191-
if (isname != NULL) {
192193
if ((gens = sk_GENERAL_NAME_new_null()) == NULL
193194
|| (gen = GENERAL_NAME_new()) == NULL
194195
|| !sk_GENERAL_NAME_push(gens, gen)) {
@@ -200,8 +201,6 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
200201
}
201202

202203
akeyid->issuer = gens;
203-
gen = NULL;
204-
gens = NULL;
205204
akeyid->serial = serial;
206205
akeyid->keyid = ikeyid;
207206

doc/man5/x509v3_config.pod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,16 @@ or both of them, separated by C<,>.
195195
Either or both can have the option B<always>,
196196
indicated by putting a colon C<:> between the value and this option.
197197
For self-signed certificates the AKID is suppressed unless B<always> is present.
198+
In order to find out, if the certificate is about to be self-signed, the
199+
private key as given by B<X509V3_set_issuer_pkey> is compared to the
200+
public key in the subject_certificate.
201+
When there is no private key available, the AKID will not be suppressed.
198202
By default the B<x509>, B<req>, and B<ca> apps behave as if
199203
"none" was given for self-signed certificates and "keyid, issuer" otherwise.
200204

201205
If B<keyid> is present, an attempt is made to
202206
copy the subject key identifier (SKID) from the issuer certificate except if
203-
the issuer certificate is the same as the current one and it is not self-signed.
207+
the issuer certificate does not have the subject key identifier extension.
204208
The hash of the public key related to the signing key is taken as fallback
205209
if the issuer certificate is the same as the current certificate.
206210
If B<always> is present but no value can be obtained, an error is returned.

0 commit comments

Comments
 (0)