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