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