1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 1995-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/evp.h> 13e1051a39Sopenharmony_ci#include <openssl/asn1t.h> 14e1051a39Sopenharmony_ci#include <openssl/x509.h> 15e1051a39Sopenharmony_ci#include <openssl/x509v3.h> 16e1051a39Sopenharmony_ci#include "crypto/x509.h" 17e1051a39Sopenharmony_ci 18e1051a39Sopenharmony_ciASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { 19e1051a39Sopenharmony_ci ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), 20e1051a39Sopenharmony_ci ASN1_EMBED(X509_CINF, serialNumber, ASN1_INTEGER), 21e1051a39Sopenharmony_ci ASN1_EMBED(X509_CINF, signature, X509_ALGOR), 22e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), 23e1051a39Sopenharmony_ci ASN1_EMBED(X509_CINF, validity, X509_VAL), 24e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_CINF, subject, X509_NAME), 25e1051a39Sopenharmony_ci ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), 26e1051a39Sopenharmony_ci ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), 27e1051a39Sopenharmony_ci ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), 28e1051a39Sopenharmony_ci ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) 29e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) 30e1051a39Sopenharmony_ci 31e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509_CINF) 32e1051a39Sopenharmony_ci/* X509 top level structure needs a bit of customisation */ 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_ciextern void ossl_policy_cache_free(X509_POLICY_CACHE *cache); 35e1051a39Sopenharmony_ci 36e1051a39Sopenharmony_cistatic int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, 37e1051a39Sopenharmony_ci void *exarg) 38e1051a39Sopenharmony_ci{ 39e1051a39Sopenharmony_ci X509 *ret = (X509 *)*pval; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci switch (operation) { 42e1051a39Sopenharmony_ci 43e1051a39Sopenharmony_ci case ASN1_OP_D2I_PRE: 44e1051a39Sopenharmony_ci CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); 45e1051a39Sopenharmony_ci X509_CERT_AUX_free(ret->aux); 46e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(ret->skid); 47e1051a39Sopenharmony_ci AUTHORITY_KEYID_free(ret->akid); 48e1051a39Sopenharmony_ci CRL_DIST_POINTS_free(ret->crldp); 49e1051a39Sopenharmony_ci ossl_policy_cache_free(ret->policy_cache); 50e1051a39Sopenharmony_ci GENERAL_NAMES_free(ret->altname); 51e1051a39Sopenharmony_ci NAME_CONSTRAINTS_free(ret->nc); 52e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_RFC3779 53e1051a39Sopenharmony_ci sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); 54e1051a39Sopenharmony_ci ASIdentifiers_free(ret->rfc3779_asid); 55e1051a39Sopenharmony_ci#endif 56e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(ret->distinguishing_id); 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_ci /* fall thru */ 59e1051a39Sopenharmony_ci 60e1051a39Sopenharmony_ci case ASN1_OP_NEW_POST: 61e1051a39Sopenharmony_ci ret->ex_cached = 0; 62e1051a39Sopenharmony_ci ret->ex_kusage = 0; 63e1051a39Sopenharmony_ci ret->ex_xkusage = 0; 64e1051a39Sopenharmony_ci ret->ex_nscert = 0; 65e1051a39Sopenharmony_ci ret->ex_flags = 0; 66e1051a39Sopenharmony_ci ret->ex_pathlen = -1; 67e1051a39Sopenharmony_ci ret->ex_pcpathlen = -1; 68e1051a39Sopenharmony_ci ret->skid = NULL; 69e1051a39Sopenharmony_ci ret->akid = NULL; 70e1051a39Sopenharmony_ci ret->policy_cache = NULL; 71e1051a39Sopenharmony_ci ret->altname = NULL; 72e1051a39Sopenharmony_ci ret->nc = NULL; 73e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_RFC3779 74e1051a39Sopenharmony_ci ret->rfc3779_addr = NULL; 75e1051a39Sopenharmony_ci ret->rfc3779_asid = NULL; 76e1051a39Sopenharmony_ci#endif 77e1051a39Sopenharmony_ci ret->distinguishing_id = NULL; 78e1051a39Sopenharmony_ci ret->aux = NULL; 79e1051a39Sopenharmony_ci ret->crldp = NULL; 80e1051a39Sopenharmony_ci if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data)) 81e1051a39Sopenharmony_ci return 0; 82e1051a39Sopenharmony_ci break; 83e1051a39Sopenharmony_ci 84e1051a39Sopenharmony_ci case ASN1_OP_FREE_POST: 85e1051a39Sopenharmony_ci CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); 86e1051a39Sopenharmony_ci X509_CERT_AUX_free(ret->aux); 87e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(ret->skid); 88e1051a39Sopenharmony_ci AUTHORITY_KEYID_free(ret->akid); 89e1051a39Sopenharmony_ci CRL_DIST_POINTS_free(ret->crldp); 90e1051a39Sopenharmony_ci ossl_policy_cache_free(ret->policy_cache); 91e1051a39Sopenharmony_ci GENERAL_NAMES_free(ret->altname); 92e1051a39Sopenharmony_ci NAME_CONSTRAINTS_free(ret->nc); 93e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_RFC3779 94e1051a39Sopenharmony_ci sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); 95e1051a39Sopenharmony_ci ASIdentifiers_free(ret->rfc3779_asid); 96e1051a39Sopenharmony_ci#endif 97e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(ret->distinguishing_id); 98e1051a39Sopenharmony_ci OPENSSL_free(ret->propq); 99e1051a39Sopenharmony_ci break; 100e1051a39Sopenharmony_ci 101e1051a39Sopenharmony_ci case ASN1_OP_DUP_POST: 102e1051a39Sopenharmony_ci { 103e1051a39Sopenharmony_ci X509 *old = exarg; 104e1051a39Sopenharmony_ci 105e1051a39Sopenharmony_ci if (!ossl_x509_set0_libctx(ret, old->libctx, old->propq)) 106e1051a39Sopenharmony_ci return 0; 107e1051a39Sopenharmony_ci } 108e1051a39Sopenharmony_ci break; 109e1051a39Sopenharmony_ci case ASN1_OP_GET0_LIBCTX: 110e1051a39Sopenharmony_ci { 111e1051a39Sopenharmony_ci OSSL_LIB_CTX **libctx = exarg; 112e1051a39Sopenharmony_ci 113e1051a39Sopenharmony_ci *libctx = ret->libctx; 114e1051a39Sopenharmony_ci } 115e1051a39Sopenharmony_ci break; 116e1051a39Sopenharmony_ci 117e1051a39Sopenharmony_ci case ASN1_OP_GET0_PROPQ: 118e1051a39Sopenharmony_ci { 119e1051a39Sopenharmony_ci const char **propq = exarg; 120e1051a39Sopenharmony_ci 121e1051a39Sopenharmony_ci *propq = ret->propq; 122e1051a39Sopenharmony_ci } 123e1051a39Sopenharmony_ci break; 124e1051a39Sopenharmony_ci 125e1051a39Sopenharmony_ci default: 126e1051a39Sopenharmony_ci break; 127e1051a39Sopenharmony_ci } 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci return 1; 130e1051a39Sopenharmony_ci} 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ciASN1_SEQUENCE_ref(X509, x509_cb) = { 133e1051a39Sopenharmony_ci ASN1_EMBED(X509, cert_info, X509_CINF), 134e1051a39Sopenharmony_ci ASN1_EMBED(X509, sig_alg, X509_ALGOR), 135e1051a39Sopenharmony_ci ASN1_EMBED(X509, signature, ASN1_BIT_STRING) 136e1051a39Sopenharmony_ci} ASN1_SEQUENCE_END_ref(X509, X509) 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ciIMPLEMENT_ASN1_FUNCTIONS(X509) 139e1051a39Sopenharmony_ciIMPLEMENT_ASN1_DUP_FUNCTION(X509) 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci/* 142e1051a39Sopenharmony_ci * This should only be used if the X509 object was embedded inside another 143e1051a39Sopenharmony_ci * asn1 object and it needs a libctx to operate. 144e1051a39Sopenharmony_ci * Use X509_new_ex() instead if possible. 145e1051a39Sopenharmony_ci */ 146e1051a39Sopenharmony_ciint ossl_x509_set0_libctx(X509 *x, OSSL_LIB_CTX *libctx, const char *propq) 147e1051a39Sopenharmony_ci{ 148e1051a39Sopenharmony_ci if (x != NULL) { 149e1051a39Sopenharmony_ci x->libctx = libctx; 150e1051a39Sopenharmony_ci OPENSSL_free(x->propq); 151e1051a39Sopenharmony_ci x->propq = NULL; 152e1051a39Sopenharmony_ci if (propq != NULL) { 153e1051a39Sopenharmony_ci x->propq = OPENSSL_strdup(propq); 154e1051a39Sopenharmony_ci if (x->propq == NULL) 155e1051a39Sopenharmony_ci return 0; 156e1051a39Sopenharmony_ci } 157e1051a39Sopenharmony_ci } 158e1051a39Sopenharmony_ci return 1; 159e1051a39Sopenharmony_ci} 160e1051a39Sopenharmony_ci 161e1051a39Sopenharmony_ciX509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci X509 *cert = NULL; 164e1051a39Sopenharmony_ci 165e1051a39Sopenharmony_ci cert = (X509 *)ASN1_item_new_ex(X509_it(), libctx, propq); 166e1051a39Sopenharmony_ci if (!ossl_x509_set0_libctx(cert, libctx, propq)) { 167e1051a39Sopenharmony_ci X509_free(cert); 168e1051a39Sopenharmony_ci cert = NULL; 169e1051a39Sopenharmony_ci } 170e1051a39Sopenharmony_ci return cert; 171e1051a39Sopenharmony_ci} 172e1051a39Sopenharmony_ci 173e1051a39Sopenharmony_ciint X509_set_ex_data(X509 *r, int idx, void *arg) 174e1051a39Sopenharmony_ci{ 175e1051a39Sopenharmony_ci return CRYPTO_set_ex_data(&r->ex_data, idx, arg); 176e1051a39Sopenharmony_ci} 177e1051a39Sopenharmony_ci 178e1051a39Sopenharmony_civoid *X509_get_ex_data(const X509 *r, int idx) 179e1051a39Sopenharmony_ci{ 180e1051a39Sopenharmony_ci return CRYPTO_get_ex_data(&r->ex_data, idx); 181e1051a39Sopenharmony_ci} 182e1051a39Sopenharmony_ci 183e1051a39Sopenharmony_ci/* 184e1051a39Sopenharmony_ci * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with 185e1051a39Sopenharmony_ci * extra info tagged on the end. Since these functions set how a certificate 186e1051a39Sopenharmony_ci * is trusted they should only be used when the certificate comes from a 187e1051a39Sopenharmony_ci * reliable source such as local storage. 188e1051a39Sopenharmony_ci */ 189e1051a39Sopenharmony_ci 190e1051a39Sopenharmony_ciX509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) 191e1051a39Sopenharmony_ci{ 192e1051a39Sopenharmony_ci const unsigned char *q; 193e1051a39Sopenharmony_ci X509 *ret; 194e1051a39Sopenharmony_ci int freeret = 0; 195e1051a39Sopenharmony_ci 196e1051a39Sopenharmony_ci /* Save start position */ 197e1051a39Sopenharmony_ci q = *pp; 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci if (a == NULL || *a == NULL) 200e1051a39Sopenharmony_ci freeret = 1; 201e1051a39Sopenharmony_ci ret = d2i_X509(a, &q, length); 202e1051a39Sopenharmony_ci /* If certificate unreadable then forget it */ 203e1051a39Sopenharmony_ci if (ret == NULL) 204e1051a39Sopenharmony_ci return NULL; 205e1051a39Sopenharmony_ci /* update length */ 206e1051a39Sopenharmony_ci length -= q - *pp; 207e1051a39Sopenharmony_ci if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) 208e1051a39Sopenharmony_ci goto err; 209e1051a39Sopenharmony_ci *pp = q; 210e1051a39Sopenharmony_ci return ret; 211e1051a39Sopenharmony_ci err: 212e1051a39Sopenharmony_ci if (freeret) { 213e1051a39Sopenharmony_ci X509_free(ret); 214e1051a39Sopenharmony_ci if (a) 215e1051a39Sopenharmony_ci *a = NULL; 216e1051a39Sopenharmony_ci } 217e1051a39Sopenharmony_ci return NULL; 218e1051a39Sopenharmony_ci} 219e1051a39Sopenharmony_ci 220e1051a39Sopenharmony_ci/* 221e1051a39Sopenharmony_ci * Serialize trusted certificate to *pp or just return the required buffer 222e1051a39Sopenharmony_ci * length if pp == NULL. We ultimately want to avoid modifying *pp in the 223e1051a39Sopenharmony_ci * error path, but that depends on similar hygiene in lower-level functions. 224e1051a39Sopenharmony_ci * Here we avoid compounding the problem. 225e1051a39Sopenharmony_ci */ 226e1051a39Sopenharmony_cistatic int i2d_x509_aux_internal(const X509 *a, unsigned char **pp) 227e1051a39Sopenharmony_ci{ 228e1051a39Sopenharmony_ci int length, tmplen; 229e1051a39Sopenharmony_ci unsigned char *start = pp != NULL ? *pp : NULL; 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ci /* 232e1051a39Sopenharmony_ci * This might perturb *pp on error, but fixing that belongs in i2d_X509() 233e1051a39Sopenharmony_ci * not here. It should be that if a == NULL length is zero, but we check 234e1051a39Sopenharmony_ci * both just in case. 235e1051a39Sopenharmony_ci */ 236e1051a39Sopenharmony_ci length = i2d_X509(a, pp); 237e1051a39Sopenharmony_ci if (length <= 0 || a == NULL) 238e1051a39Sopenharmony_ci return length; 239e1051a39Sopenharmony_ci 240e1051a39Sopenharmony_ci tmplen = i2d_X509_CERT_AUX(a->aux, pp); 241e1051a39Sopenharmony_ci if (tmplen < 0) { 242e1051a39Sopenharmony_ci if (start != NULL) 243e1051a39Sopenharmony_ci *pp = start; 244e1051a39Sopenharmony_ci return tmplen; 245e1051a39Sopenharmony_ci } 246e1051a39Sopenharmony_ci length += tmplen; 247e1051a39Sopenharmony_ci 248e1051a39Sopenharmony_ci return length; 249e1051a39Sopenharmony_ci} 250e1051a39Sopenharmony_ci 251e1051a39Sopenharmony_ci/* 252e1051a39Sopenharmony_ci * Serialize trusted certificate to *pp, or just return the required buffer 253e1051a39Sopenharmony_ci * length if pp == NULL. 254e1051a39Sopenharmony_ci * 255e1051a39Sopenharmony_ci * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since 256e1051a39Sopenharmony_ci * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do 257e1051a39Sopenharmony_ci * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the 258e1051a39Sopenharmony_ci * allocated buffer. 259e1051a39Sopenharmony_ci */ 260e1051a39Sopenharmony_ciint i2d_X509_AUX(const X509 *a, unsigned char **pp) 261e1051a39Sopenharmony_ci{ 262e1051a39Sopenharmony_ci int length; 263e1051a39Sopenharmony_ci unsigned char *tmp; 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci /* Buffer provided by caller */ 266e1051a39Sopenharmony_ci if (pp == NULL || *pp != NULL) 267e1051a39Sopenharmony_ci return i2d_x509_aux_internal(a, pp); 268e1051a39Sopenharmony_ci 269e1051a39Sopenharmony_ci /* Obtain the combined length */ 270e1051a39Sopenharmony_ci if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) 271e1051a39Sopenharmony_ci return length; 272e1051a39Sopenharmony_ci 273e1051a39Sopenharmony_ci /* Allocate requisite combined storage */ 274e1051a39Sopenharmony_ci *pp = tmp = OPENSSL_malloc(length); 275e1051a39Sopenharmony_ci if (tmp == NULL) { 276e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_X509, ERR_R_MALLOC_FAILURE); 277e1051a39Sopenharmony_ci return -1; 278e1051a39Sopenharmony_ci } 279e1051a39Sopenharmony_ci 280e1051a39Sopenharmony_ci /* Encode, but keep *pp at the originally malloced pointer */ 281e1051a39Sopenharmony_ci length = i2d_x509_aux_internal(a, &tmp); 282e1051a39Sopenharmony_ci if (length <= 0) { 283e1051a39Sopenharmony_ci OPENSSL_free(*pp); 284e1051a39Sopenharmony_ci *pp = NULL; 285e1051a39Sopenharmony_ci } 286e1051a39Sopenharmony_ci return length; 287e1051a39Sopenharmony_ci} 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ciint i2d_re_X509_tbs(X509 *x, unsigned char **pp) 290e1051a39Sopenharmony_ci{ 291e1051a39Sopenharmony_ci x->cert_info.enc.modified = 1; 292e1051a39Sopenharmony_ci return i2d_X509_CINF(&x->cert_info, pp); 293e1051a39Sopenharmony_ci} 294e1051a39Sopenharmony_ci 295e1051a39Sopenharmony_civoid X509_get0_signature(const ASN1_BIT_STRING **psig, 296e1051a39Sopenharmony_ci const X509_ALGOR **palg, const X509 *x) 297e1051a39Sopenharmony_ci{ 298e1051a39Sopenharmony_ci if (psig) 299e1051a39Sopenharmony_ci *psig = &x->signature; 300e1051a39Sopenharmony_ci if (palg) 301e1051a39Sopenharmony_ci *palg = &x->sig_alg; 302e1051a39Sopenharmony_ci} 303e1051a39Sopenharmony_ci 304e1051a39Sopenharmony_ciint X509_get_signature_nid(const X509 *x) 305e1051a39Sopenharmony_ci{ 306e1051a39Sopenharmony_ci return OBJ_obj2nid(x->sig_alg.algorithm); 307e1051a39Sopenharmony_ci} 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_civoid X509_set0_distinguishing_id(X509 *x, ASN1_OCTET_STRING *d_id) 310e1051a39Sopenharmony_ci{ 311e1051a39Sopenharmony_ci ASN1_OCTET_STRING_free(x->distinguishing_id); 312e1051a39Sopenharmony_ci x->distinguishing_id = d_id; 313e1051a39Sopenharmony_ci} 314e1051a39Sopenharmony_ci 315e1051a39Sopenharmony_ciASN1_OCTET_STRING *X509_get0_distinguishing_id(X509 *x) 316e1051a39Sopenharmony_ci{ 317e1051a39Sopenharmony_ci return x->distinguishing_id; 318e1051a39Sopenharmony_ci} 319