1*b077aed3SPierre Pronchery /*
2*b077aed3SPierre Pronchery * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
3*b077aed3SPierre Pronchery *
4*b077aed3SPierre Pronchery * Licensed under the Apache License 2.0 (the "License"). You may not use
5*b077aed3SPierre Pronchery * this file except in compliance with the License. You can obtain a copy
6*b077aed3SPierre Pronchery * in the file LICENSE in the source distribution or at
7*b077aed3SPierre Pronchery * https://www.openssl.org/source/license.html
8*b077aed3SPierre Pronchery */
9*b077aed3SPierre Pronchery
10*b077aed3SPierre Pronchery #include <stdio.h>
11*b077aed3SPierre Pronchery #include "internal/cryptlib.h"
12*b077aed3SPierre Pronchery #include <openssl/conf.h>
13*b077aed3SPierre Pronchery #include <openssl/asn1.h>
14*b077aed3SPierre Pronchery #include <openssl/asn1t.h>
15*b077aed3SPierre Pronchery #include <openssl/x509v3.h>
16*b077aed3SPierre Pronchery #include "crypto/x509.h"
17*b077aed3SPierre Pronchery #include "ext_dat.h"
18*b077aed3SPierre Pronchery
19*b077aed3SPierre Pronchery static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
20*b077aed3SPierre Pronchery AUTHORITY_KEYID *akeyid,
21*b077aed3SPierre Pronchery STACK_OF(CONF_VALUE)
22*b077aed3SPierre Pronchery *extlist);
23*b077aed3SPierre Pronchery static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
24*b077aed3SPierre Pronchery X509V3_CTX *ctx,
25*b077aed3SPierre Pronchery STACK_OF(CONF_VALUE) *values);
26*b077aed3SPierre Pronchery
27*b077aed3SPierre Pronchery const X509V3_EXT_METHOD ossl_v3_akey_id = {
28*b077aed3SPierre Pronchery NID_authority_key_identifier,
29*b077aed3SPierre Pronchery X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
30*b077aed3SPierre Pronchery 0, 0, 0, 0,
31*b077aed3SPierre Pronchery 0, 0,
32*b077aed3SPierre Pronchery (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID,
33*b077aed3SPierre Pronchery (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
34*b077aed3SPierre Pronchery 0, 0,
35*b077aed3SPierre Pronchery NULL
36*b077aed3SPierre Pronchery };
37*b077aed3SPierre Pronchery
STACK_OF(CONF_VALUE)38*b077aed3SPierre Pronchery static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
39*b077aed3SPierre Pronchery AUTHORITY_KEYID *akeyid,
40*b077aed3SPierre Pronchery STACK_OF(CONF_VALUE)
41*b077aed3SPierre Pronchery *extlist)
42*b077aed3SPierre Pronchery {
43*b077aed3SPierre Pronchery char *tmp = NULL;
44*b077aed3SPierre Pronchery STACK_OF(CONF_VALUE) *origextlist = extlist, *tmpextlist;
45*b077aed3SPierre Pronchery
46*b077aed3SPierre Pronchery if (akeyid->keyid) {
47*b077aed3SPierre Pronchery tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length);
48*b077aed3SPierre Pronchery if (tmp == NULL) {
49*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
50*b077aed3SPierre Pronchery return NULL;
51*b077aed3SPierre Pronchery }
52*b077aed3SPierre Pronchery if (!X509V3_add_value((akeyid->issuer || akeyid->serial) ? "keyid" : NULL,
53*b077aed3SPierre Pronchery tmp, &extlist)) {
54*b077aed3SPierre Pronchery OPENSSL_free(tmp);
55*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB);
56*b077aed3SPierre Pronchery goto err;
57*b077aed3SPierre Pronchery }
58*b077aed3SPierre Pronchery OPENSSL_free(tmp);
59*b077aed3SPierre Pronchery }
60*b077aed3SPierre Pronchery if (akeyid->issuer) {
61*b077aed3SPierre Pronchery tmpextlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
62*b077aed3SPierre Pronchery if (tmpextlist == NULL) {
63*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB);
64*b077aed3SPierre Pronchery goto err;
65*b077aed3SPierre Pronchery }
66*b077aed3SPierre Pronchery extlist = tmpextlist;
67*b077aed3SPierre Pronchery }
68*b077aed3SPierre Pronchery if (akeyid->serial) {
69*b077aed3SPierre Pronchery tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length);
70*b077aed3SPierre Pronchery if (tmp == NULL) {
71*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
72*b077aed3SPierre Pronchery goto err;
73*b077aed3SPierre Pronchery }
74*b077aed3SPierre Pronchery if (!X509V3_add_value("serial", tmp, &extlist)) {
75*b077aed3SPierre Pronchery OPENSSL_free(tmp);
76*b077aed3SPierre Pronchery goto err;
77*b077aed3SPierre Pronchery }
78*b077aed3SPierre Pronchery OPENSSL_free(tmp);
79*b077aed3SPierre Pronchery }
80*b077aed3SPierre Pronchery return extlist;
81*b077aed3SPierre Pronchery err:
82*b077aed3SPierre Pronchery if (origextlist == NULL)
83*b077aed3SPierre Pronchery sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free);
84*b077aed3SPierre Pronchery return NULL;
85*b077aed3SPierre Pronchery }
86*b077aed3SPierre Pronchery
87*b077aed3SPierre Pronchery /*-
88*b077aed3SPierre Pronchery * Currently two options:
89*b077aed3SPierre Pronchery * keyid: use the issuers subject keyid, the value 'always' means its is
90*b077aed3SPierre Pronchery * an error if the issuer certificate doesn't have a key id.
91*b077aed3SPierre Pronchery * issuer: use the issuers cert issuer and serial number. The default is
92*b077aed3SPierre Pronchery * to only use this if keyid is not present. With the option 'always'
93*b077aed3SPierre Pronchery * this is always included.
94*b077aed3SPierre Pronchery */
95*b077aed3SPierre Pronchery
v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* values)96*b077aed3SPierre Pronchery static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
97*b077aed3SPierre Pronchery X509V3_CTX *ctx,
98*b077aed3SPierre Pronchery STACK_OF(CONF_VALUE) *values)
99*b077aed3SPierre Pronchery {
100*b077aed3SPierre Pronchery char keyid = 0, issuer = 0;
101*b077aed3SPierre Pronchery int i, n = sk_CONF_VALUE_num(values);
102*b077aed3SPierre Pronchery CONF_VALUE *cnf;
103*b077aed3SPierre Pronchery ASN1_OCTET_STRING *ikeyid = NULL;
104*b077aed3SPierre Pronchery X509_NAME *isname = NULL;
105*b077aed3SPierre Pronchery GENERAL_NAMES *gens = NULL;
106*b077aed3SPierre Pronchery GENERAL_NAME *gen = NULL;
107*b077aed3SPierre Pronchery ASN1_INTEGER *serial = NULL;
108*b077aed3SPierre Pronchery X509_EXTENSION *ext;
109*b077aed3SPierre Pronchery X509 *issuer_cert;
110*b077aed3SPierre Pronchery int same_issuer, ss;
111*b077aed3SPierre Pronchery AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
112*b077aed3SPierre Pronchery
113*b077aed3SPierre Pronchery if (akeyid == NULL)
114*b077aed3SPierre Pronchery goto err;
115*b077aed3SPierre Pronchery
116*b077aed3SPierre Pronchery if (n == 1 && strcmp(sk_CONF_VALUE_value(values, 0)->name, "none") == 0) {
117*b077aed3SPierre Pronchery return akeyid;
118*b077aed3SPierre Pronchery }
119*b077aed3SPierre Pronchery
120*b077aed3SPierre Pronchery for (i = 0; i < n; i++) {
121*b077aed3SPierre Pronchery cnf = sk_CONF_VALUE_value(values, i);
122*b077aed3SPierre Pronchery if (strcmp(cnf->name, "keyid") == 0) {
123*b077aed3SPierre Pronchery keyid = 1;
124*b077aed3SPierre Pronchery if (cnf->value && strcmp(cnf->value, "always") == 0)
125*b077aed3SPierre Pronchery keyid = 2;
126*b077aed3SPierre Pronchery } else if (strcmp(cnf->name, "issuer") == 0) {
127*b077aed3SPierre Pronchery issuer = 1;
128*b077aed3SPierre Pronchery if (cnf->value && strcmp(cnf->value, "always") == 0)
129*b077aed3SPierre Pronchery issuer = 2;
130*b077aed3SPierre Pronchery } else {
131*b077aed3SPierre Pronchery ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION,
132*b077aed3SPierre Pronchery "name=%s", cnf->name);
133*b077aed3SPierre Pronchery goto err;
134*b077aed3SPierre Pronchery }
135*b077aed3SPierre Pronchery }
136*b077aed3SPierre Pronchery
137*b077aed3SPierre Pronchery if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0)
138*b077aed3SPierre Pronchery return akeyid;
139*b077aed3SPierre Pronchery
140*b077aed3SPierre Pronchery if (ctx == NULL) {
141*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
142*b077aed3SPierre Pronchery goto err;
143*b077aed3SPierre Pronchery }
144*b077aed3SPierre Pronchery if ((issuer_cert = ctx->issuer_cert) == NULL) {
145*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
146*b077aed3SPierre Pronchery goto err;
147*b077aed3SPierre Pronchery }
148*b077aed3SPierre Pronchery same_issuer = ctx->subject_cert == ctx->issuer_cert;
149*b077aed3SPierre Pronchery ERR_set_mark();
150*b077aed3SPierre Pronchery if (ctx->issuer_pkey != NULL)
151*b077aed3SPierre Pronchery ss = X509_check_private_key(ctx->subject_cert, ctx->issuer_pkey);
152*b077aed3SPierre Pronchery else
153*b077aed3SPierre Pronchery ss = same_issuer;
154*b077aed3SPierre Pronchery ERR_pop_to_mark();
155*b077aed3SPierre Pronchery
156*b077aed3SPierre Pronchery /* unless forced with "always", AKID is suppressed for self-signed certs */
157*b077aed3SPierre Pronchery if (keyid == 2 || (keyid == 1 && !ss)) {
158*b077aed3SPierre Pronchery /*
159*b077aed3SPierre Pronchery * prefer any pre-existing subject key identifier of the issuer cert
160*b077aed3SPierre Pronchery * except issuer cert is same as subject cert and is not self-signed
161*b077aed3SPierre Pronchery */
162*b077aed3SPierre Pronchery i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
163*b077aed3SPierre Pronchery if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
164*b077aed3SPierre Pronchery && !(same_issuer && !ss))
165*b077aed3SPierre Pronchery ikeyid = X509V3_EXT_d2i(ext);
166*b077aed3SPierre Pronchery if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) {
167*b077aed3SPierre Pronchery /* generate fallback AKID, emulating s2i_skey_id(..., "hash") */
168*b077aed3SPierre Pronchery X509_PUBKEY *pubkey = NULL;
169*b077aed3SPierre Pronchery
170*b077aed3SPierre Pronchery if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey))
171*b077aed3SPierre Pronchery ikeyid = ossl_x509_pubkey_hash(pubkey);
172*b077aed3SPierre Pronchery X509_PUBKEY_free(pubkey);
173*b077aed3SPierre Pronchery }
174*b077aed3SPierre Pronchery if ((keyid == 2 || issuer == 0)
175*b077aed3SPierre Pronchery && (ikeyid == NULL
176*b077aed3SPierre Pronchery || ASN1_STRING_length(ikeyid) <= 2) /* indicating "none" */) {
177*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
178*b077aed3SPierre Pronchery goto err;
179*b077aed3SPierre Pronchery }
180*b077aed3SPierre Pronchery }
181*b077aed3SPierre Pronchery
182*b077aed3SPierre Pronchery if (issuer == 2 || (issuer == 1 && ikeyid == NULL)) {
183*b077aed3SPierre Pronchery isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert));
184*b077aed3SPierre Pronchery serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert));
185*b077aed3SPierre Pronchery if (isname == NULL || serial == NULL) {
186*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
187*b077aed3SPierre Pronchery goto err;
188*b077aed3SPierre Pronchery }
189*b077aed3SPierre Pronchery }
190*b077aed3SPierre Pronchery
191*b077aed3SPierre Pronchery if (isname != NULL) {
192*b077aed3SPierre Pronchery if ((gens = sk_GENERAL_NAME_new_null()) == NULL
193*b077aed3SPierre Pronchery || (gen = GENERAL_NAME_new()) == NULL
194*b077aed3SPierre Pronchery || !sk_GENERAL_NAME_push(gens, gen)) {
195*b077aed3SPierre Pronchery ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
196*b077aed3SPierre Pronchery goto err;
197*b077aed3SPierre Pronchery }
198*b077aed3SPierre Pronchery gen->type = GEN_DIRNAME;
199*b077aed3SPierre Pronchery gen->d.dirn = isname;
200*b077aed3SPierre Pronchery }
201*b077aed3SPierre Pronchery
202*b077aed3SPierre Pronchery akeyid->issuer = gens;
203*b077aed3SPierre Pronchery gen = NULL;
204*b077aed3SPierre Pronchery gens = NULL;
205*b077aed3SPierre Pronchery akeyid->serial = serial;
206*b077aed3SPierre Pronchery akeyid->keyid = ikeyid;
207*b077aed3SPierre Pronchery
208*b077aed3SPierre Pronchery return akeyid;
209*b077aed3SPierre Pronchery
210*b077aed3SPierre Pronchery err:
211*b077aed3SPierre Pronchery sk_GENERAL_NAME_free(gens);
212*b077aed3SPierre Pronchery GENERAL_NAME_free(gen);
213*b077aed3SPierre Pronchery X509_NAME_free(isname);
214*b077aed3SPierre Pronchery ASN1_INTEGER_free(serial);
215*b077aed3SPierre Pronchery ASN1_OCTET_STRING_free(ikeyid);
216*b077aed3SPierre Pronchery AUTHORITY_KEYID_free(akeyid);
217*b077aed3SPierre Pronchery return NULL;
218*b077aed3SPierre Pronchery }
219