Coverage Report

Created: 2026-03-09 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/x509/v3_akid.c
Line
Count
Source
1
/*
2
 * Copyright 1999-2022 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <stdio.h>
11
#include "internal/cryptlib.h"
12
#include <openssl/conf.h>
13
#include <openssl/asn1.h>
14
#include <openssl/asn1t.h>
15
#include <openssl/x509v3.h>
16
#include "crypto/x509.h"
17
#include "ext_dat.h"
18
19
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
20
    AUTHORITY_KEYID *akeyid,
21
    STACK_OF(CONF_VALUE)
22
        *extlist);
23
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
24
    X509V3_CTX *ctx,
25
    STACK_OF(CONF_VALUE) *values);
26
27
const X509V3_EXT_METHOD ossl_v3_akey_id = {
28
    NID_authority_key_identifier,
29
    X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID),
30
    0, 0, 0, 0,
31
    0, 0,
32
    (X509V3_EXT_I2V)i2v_AUTHORITY_KEYID,
33
    (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID,
34
    0, 0,
35
    NULL
36
};
37
38
static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
39
    AUTHORITY_KEYID *akeyid,
40
    STACK_OF(CONF_VALUE)
41
        *extlist)
42
0
{
43
0
    char *tmp = NULL;
44
0
    STACK_OF(CONF_VALUE) *origextlist = extlist, *tmpextlist;
45
46
0
    if (akeyid->keyid) {
47
0
        tmp = i2s_ASN1_OCTET_STRING(NULL, akeyid->keyid);
48
0
        if (tmp == NULL) {
49
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
50
0
            return NULL;
51
0
        }
52
0
        if (!X509V3_add_value((akeyid->issuer || akeyid->serial) ? "keyid" : NULL,
53
0
                tmp, &extlist)) {
54
0
            OPENSSL_free(tmp);
55
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB);
56
0
            goto err;
57
0
        }
58
0
        OPENSSL_free(tmp);
59
0
    }
60
0
    if (akeyid->issuer) {
61
0
        tmpextlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist);
62
0
        if (tmpextlist == NULL) {
63
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_X509_LIB);
64
0
            goto err;
65
0
        }
66
0
        extlist = tmpextlist;
67
0
    }
68
0
    if (akeyid->serial) {
69
0
        tmp = i2s_ASN1_INTEGER(NULL, akeyid->serial);
70
71
0
        if (tmp == NULL) {
72
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
73
0
            goto err;
74
0
        }
75
0
        if (!X509V3_add_value("serial", tmp, &extlist)) {
76
0
            OPENSSL_free(tmp);
77
0
            goto err;
78
0
        }
79
0
        OPENSSL_free(tmp);
80
0
    }
81
0
    return extlist;
82
0
err:
83
0
    if (origextlist == NULL)
84
0
        sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free);
85
0
    return NULL;
86
0
}
87
88
enum qualifier {
89
    NEVER,
90
    NONSS,
91
    MAYBE,
92
    GOTTO,
93
};
94
95
/*-
96
 * Three explicit tags may be given, where 'keyid' and 'issuer' may be combined:
97
 * 'none': do not add any authority key identifier.
98
 * 'keyid': use the issuer's subject keyid; the option 'always' means its is
99
 * an error if the issuer certificate doesn't have a subject key id.
100
 * 'issuer': use the issuer's cert issuer and serial number. The default is
101
 * to only use this if 'keyid' is not present. With the option 'always'
102
 * this is always included.
103
 */
104
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
105
    X509V3_CTX *ctx,
106
    STACK_OF(CONF_VALUE) *values)
107
0
{
108
0
    int i, n = sk_CONF_VALUE_num(values);
109
0
    CONF_VALUE *cnf;
110
0
    ASN1_OCTET_STRING *ikeyid = NULL;
111
0
    X509_NAME *isname = NULL;
112
0
    GENERAL_NAMES *gens = NULL;
113
0
    GENERAL_NAME *gen = NULL;
114
0
    ASN1_INTEGER *serial = NULL;
115
0
    const X509_EXTENSION *ext;
116
0
    X509 *issuer_cert;
117
0
    int same_issuer, ss;
118
0
    AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
119
0
    enum qualifier keyid = NEVER, issuer = NEVER;
120
121
0
    if (akeyid == NULL)
122
0
        goto err;
123
124
0
    if (n == 1 && strcmp(sk_CONF_VALUE_value(values, 0)->name, "none") == 0)
125
0
        return akeyid;
126
127
0
    for (i = 0; i < n; i++) {
128
0
        enum qualifier q = MAYBE;
129
130
0
        cnf = sk_CONF_VALUE_value(values, i);
131
0
        if (cnf->value != NULL && *cnf->value != '\0') {
132
0
            if (strcmp(cnf->value, "always") == 0) {
133
0
                q = GOTTO;
134
0
            } else if (strcmp(cnf->value, "nonss") == 0) {
135
0
                q = NONSS;
136
0
            } else {
137
0
                ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION,
138
0
                    "name=%s option=%s", cnf->name, cnf->value);
139
0
                goto err;
140
0
            }
141
0
        }
142
0
        if (strcmp(cnf->name, "keyid") == 0 && keyid == NEVER) {
143
0
            keyid = q;
144
0
        } else if (strcmp(cnf->name, "issuer") == 0 && issuer == 0) {
145
0
            issuer = q;
146
0
        } else if (strcmp(cnf->name, "none") == 0
147
0
            || strcmp(cnf->name, "keyid") == 0
148
0
            || strcmp(cnf->name, "issuer") == 0) {
149
0
            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_VALUE,
150
0
                "name=%s", cnf->name);
151
0
            goto err;
152
0
        } else {
153
0
            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_VALUE,
154
0
                "name=%s", cnf->name);
155
0
            goto err;
156
0
        }
157
0
    }
158
159
0
    if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0)
160
0
        return akeyid;
161
162
0
    if (ctx == NULL) {
163
0
        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
164
0
        goto err;
165
0
    }
166
0
    if ((issuer_cert = ctx->issuer_cert) == NULL) {
167
0
        ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
168
0
        goto err;
169
0
    }
170
0
    same_issuer = ctx->subject_cert == ctx->issuer_cert;
171
0
    ERR_set_mark();
172
0
    if (ctx->issuer_pkey != NULL)
173
0
        ss = X509_check_private_key(ctx->subject_cert, ctx->issuer_pkey);
174
0
    else
175
0
        ss = same_issuer;
176
0
    ERR_pop_to_mark();
177
178
0
    if (keyid > NONSS || (keyid == NONSS && !ss)) {
179
        /*
180
         * The subject key identifier of the issuer cert is acceptable unless
181
         * the issuer cert is same as subject cert, but the subject will not
182
         * not be self-signed (i.e. will be signed with a different key).
183
         */
184
0
        i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
185
0
        if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
186
0
            && !(same_issuer && !ss)) {
187
0
            ikeyid = X509V3_EXT_d2i(ext);
188
            /* Ignore empty keyids in the issuer cert */
189
0
            if (ASN1_STRING_length(ikeyid) == 0) {
190
0
                ASN1_OCTET_STRING_free(ikeyid);
191
0
                ikeyid = NULL;
192
0
            }
193
0
        }
194
        /*
195
         * If we have that other key in hand, synthesise a fallback AKID,
196
         * emulating s2i_skey_id(..., "hash").
197
         *
198
         * When creating self-signed certificates, we do not synthesise
199
         * best-effort keyids, instead the keyid needs be set first.  The
200
         * X509V3_EXT_add_nconf_sk() function makes every effort to process the
201
         * SKID before the AKID, but some callers may specify extensions
202
         * piecemeal.  We don't want to mispredict it being set later and end
203
         * up with a "dangling" AKID keyid.
204
         */
205
0
        if (ikeyid == NULL && same_issuer && !ss && ctx->issuer_pkey != NULL) {
206
0
            X509_PUBKEY *pubkey = NULL;
207
208
0
            if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey))
209
0
                ikeyid = ossl_x509_pubkey_hash(pubkey);
210
0
            X509_PUBKEY_free(pubkey);
211
0
        }
212
0
        if (keyid == GOTTO && ikeyid == NULL) {
213
0
            ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
214
0
            goto err;
215
0
        }
216
0
    }
217
218
    /*
219
     * When the same object is specified as both the issuer and subject
220
     * certificate, but with a different (forced) issuer public key (so not
221
     * self-signed), we don't have access to the true issuer certificate's
222
     * serial number, so can't create an isser+serial AKID.
223
     */
224
0
    if (!same_issuer || ss) {
225
0
        if (issuer == GOTTO
226
0
            || (ikeyid == NULL
227
0
                && (issuer == MAYBE
228
0
                    || (issuer == NONSS && !ss)))) {
229
0
            isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert));
230
0
            serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert));
231
0
        }
232
0
    }
233
    /* "always" fails unless both issuer and serial are available */
234
0
    if (issuer == GOTTO && (isname == NULL || serial == NULL)) {
235
0
        ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
236
0
        goto err;
237
0
    }
238
239
0
    if (isname != NULL) {
240
0
        if ((gens = sk_GENERAL_NAME_new_null()) == NULL
241
0
            || (gen = GENERAL_NAME_new()) == NULL) {
242
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
243
0
            goto err;
244
0
        }
245
0
        if (!sk_GENERAL_NAME_push(gens, gen)) {
246
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB);
247
0
            goto err;
248
0
        }
249
0
        gen->type = GEN_DIRNAME;
250
0
        gen->d.dirn = isname;
251
0
    }
252
253
0
    akeyid->issuer = gens;
254
0
    gen = NULL;
255
0
    gens = NULL;
256
0
    akeyid->serial = serial;
257
0
    akeyid->keyid = ikeyid;
258
259
0
    return akeyid;
260
261
0
err:
262
0
    sk_GENERAL_NAME_free(gens);
263
0
    GENERAL_NAME_free(gen);
264
0
    X509_NAME_free(isname);
265
0
    ASN1_INTEGER_free(serial);
266
0
    ASN1_OCTET_STRING_free(ikeyid);
267
0
    AUTHORITY_KEYID_free(akeyid);
268
    return NULL;
269
0
}