Coverage Report

Created: 2025-06-13 06:57

/src/openssl/crypto/x509/v3_akid.c
Line
Count
Source (jump to first uncovered line)
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_OCTET_STRING(NULL, akeyid->serial);
70
0
        if (tmp == NULL) {
71
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
72
0
            goto err;
73
0
        }
74
0
        if (!X509V3_add_value("serial", tmp, &extlist)) {
75
0
            OPENSSL_free(tmp);
76
0
            goto err;
77
0
        }
78
0
        OPENSSL_free(tmp);
79
0
    }
80
0
    return extlist;
81
0
 err:
82
0
    if (origextlist == NULL)
83
0
        sk_CONF_VALUE_pop_free(extlist, X509V3_conf_free);
84
0
    return NULL;
85
0
}
86
87
/*-
88
 * Three explicit tags may be given, where 'keyid' and 'issuer' may be combined:
89
 * 'none': do not add any authority key identifier.
90
 * 'keyid': use the issuer's subject keyid; the option 'always' means its is
91
 * an error if the issuer certificate doesn't have a subject key id.
92
 * 'issuer': use the issuer's cert issuer and serial number. The default is
93
 * to only use this if 'keyid' is not present. With the option 'always'
94
 * this is always included.
95
 */
96
static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
97
                                            X509V3_CTX *ctx,
98
                                            STACK_OF(CONF_VALUE) *values)
99
0
{
100
0
    char keyid = 0, issuer = 0;
101
0
    int i, n = sk_CONF_VALUE_num(values);
102
0
    CONF_VALUE *cnf;
103
0
    ASN1_OCTET_STRING *ikeyid = NULL;
104
0
    X509_NAME *isname = NULL;
105
0
    GENERAL_NAMES *gens = NULL;
106
0
    GENERAL_NAME *gen = NULL;
107
0
    ASN1_INTEGER *serial = NULL;
108
0
    X509_EXTENSION *ext;
109
0
    X509 *issuer_cert;
110
0
    int same_issuer, ss;
111
0
    AUTHORITY_KEYID *akeyid = AUTHORITY_KEYID_new();
112
113
0
    if (akeyid == NULL)
114
0
        goto err;
115
116
0
    if (n == 1 && strcmp(sk_CONF_VALUE_value(values, 0)->name, "none") == 0) {
117
0
        return akeyid;
118
0
    }
119
120
0
    for (i = 0; i < n; i++) {
121
0
        cnf = sk_CONF_VALUE_value(values, i);
122
0
        if (cnf->value != NULL && strcmp(cnf->value, "always") != 0) {
123
0
            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_OPTION,
124
0
                           "name=%s option=%s", cnf->name, cnf->value);
125
0
            goto err;
126
0
        }
127
0
        if (strcmp(cnf->name, "keyid") == 0 && keyid == 0) {
128
0
            keyid = 1;
129
0
            if (cnf->value != NULL)
130
0
                keyid = 2;
131
0
        } else if (strcmp(cnf->name, "issuer") == 0 && issuer == 0) {
132
0
            issuer = 1;
133
0
            if (cnf->value != NULL)
134
0
                issuer = 2;
135
0
        } else if (strcmp(cnf->name, "none") == 0
136
0
                   || strcmp(cnf->name, "keyid") == 0
137
0
                   || strcmp(cnf->name, "issuer") == 0) {
138
0
            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_VALUE,
139
0
                           "name=%s", cnf->name);
140
0
            goto err;
141
0
        } else {
142
0
            ERR_raise_data(ERR_LIB_X509V3, X509V3_R_UNKNOWN_VALUE,
143
0
                           "name=%s", cnf->name);
144
0
            goto err;
145
0
        }
146
0
    }
147
148
0
    if (ctx != NULL && (ctx->flags & X509V3_CTX_TEST) != 0)
149
0
        return akeyid;
150
151
0
    if (ctx == NULL) {
152
0
        ERR_raise(ERR_LIB_X509V3, ERR_R_PASSED_NULL_PARAMETER);
153
0
        goto err;
154
0
    }
155
0
    if ((issuer_cert = ctx->issuer_cert) == NULL) {
156
0
        ERR_raise(ERR_LIB_X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
157
0
        goto err;
158
0
    }
159
0
    same_issuer = ctx->subject_cert == ctx->issuer_cert;
160
0
    ERR_set_mark();
161
0
    if (ctx->issuer_pkey != NULL)
162
0
        ss = X509_check_private_key(ctx->subject_cert, ctx->issuer_pkey);
163
0
    else
164
0
        ss = same_issuer;
165
0
    ERR_pop_to_mark();
166
167
    /* unless forced with "always", AKID is suppressed for self-signed certs */
168
0
    if (keyid == 2 || (keyid == 1 && !ss)) {
169
        /*
170
         * 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
172
         */
173
0
        i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1);
174
0
        if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL
175
0
            && !(same_issuer && !ss)) {
176
0
            ikeyid = X509V3_EXT_d2i(ext);
177
0
            if (ASN1_STRING_length(ikeyid) == 0) /* indicating "none" */ {
178
0
                ASN1_OCTET_STRING_free(ikeyid);
179
0
                ikeyid = NULL;
180
0
            }
181
0
        }
182
0
        if (ikeyid == NULL && same_issuer && ctx->issuer_pkey != NULL) {
183
            /* generate fallback AKID, emulating s2i_skey_id(..., "hash") */
184
0
            X509_PUBKEY *pubkey = NULL;
185
186
0
            if (X509_PUBKEY_set(&pubkey, ctx->issuer_pkey))
187
0
                ikeyid = ossl_x509_pubkey_hash(pubkey);
188
0
            X509_PUBKEY_free(pubkey);
189
0
        }
190
0
        if (keyid == 2 && ikeyid == NULL) {
191
0
            ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
192
0
            goto err;
193
0
        }
194
0
    }
195
196
0
    if (issuer == 2 || (issuer == 1 && !ss && ikeyid == NULL)) {
197
0
        isname = X509_NAME_dup(X509_get_issuer_name(issuer_cert));
198
0
        serial = ASN1_INTEGER_dup(X509_get0_serialNumber(issuer_cert));
199
0
        if (isname == NULL || serial == NULL) {
200
0
            ERR_raise(ERR_LIB_X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
201
0
            goto err;
202
0
        }
203
0
    }
204
205
0
    if (isname != NULL) {
206
0
        if ((gens = sk_GENERAL_NAME_new_null()) == NULL
207
0
            || (gen = GENERAL_NAME_new()) == NULL) {
208
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
209
0
            goto err;
210
0
        }
211
0
        if (!sk_GENERAL_NAME_push(gens, gen)) {
212
0
            ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB);
213
0
            goto err;
214
0
        }
215
0
        gen->type = GEN_DIRNAME;
216
0
        gen->d.dirn = isname;
217
0
    }
218
219
0
    akeyid->issuer = gens;
220
0
    gen = NULL;
221
0
    gens = NULL;
222
0
    akeyid->serial = serial;
223
0
    akeyid->keyid = ikeyid;
224
225
0
    return akeyid;
226
227
0
 err:
228
0
    sk_GENERAL_NAME_free(gens);
229
0
    GENERAL_NAME_free(gen);
230
0
    X509_NAME_free(isname);
231
0
    ASN1_INTEGER_free(serial);
232
0
    ASN1_OCTET_STRING_free(ikeyid);
233
0
    AUTHORITY_KEYID_free(akeyid);
234
0
    return NULL;
235
0
}