1 /* 2 * Copyright 2019-2021 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 <string.h> 11 #include <openssl/x509v3.h> 12 #include <openssl/err.h> 13 #include <openssl/ess.h> 14 #include "internal/sizes.h" 15 #include "crypto/ess.h" 16 #include "crypto/x509.h" 17 18 static ESS_CERT_ID *ESS_CERT_ID_new_init(const X509 *cert, 19 int set_issuer_serial); 20 static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, 21 const X509 *cert, 22 int set_issuer_serial); 23 24 ESS_SIGNING_CERT *OSSL_ESS_signing_cert_new_init(const X509 *signcert, 25 const STACK_OF(X509) *certs, 26 int set_issuer_serial) 27 { 28 ESS_CERT_ID *cid = NULL; 29 ESS_SIGNING_CERT *sc; 30 int i; 31 32 if ((sc = ESS_SIGNING_CERT_new()) == NULL) 33 goto err; 34 if (sc->cert_ids == NULL 35 && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL) 36 goto err; 37 38 if ((cid = ESS_CERT_ID_new_init(signcert, set_issuer_serial)) == NULL 39 || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) 40 goto err; 41 for (i = 0; i < sk_X509_num(certs); ++i) { 42 X509 *cert = sk_X509_value(certs, i); 43 44 if ((cid = ESS_CERT_ID_new_init(cert, 1)) == NULL 45 || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) 46 goto err; 47 } 48 49 return sc; 50 err: 51 ESS_SIGNING_CERT_free(sc); 52 ESS_CERT_ID_free(cid); 53 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); 54 return NULL; 55 } 56 57 static ESS_CERT_ID *ESS_CERT_ID_new_init(const X509 *cert, 58 int set_issuer_serial) 59 { 60 ESS_CERT_ID *cid = NULL; 61 GENERAL_NAME *name = NULL; 62 unsigned char cert_sha1[SHA_DIGEST_LENGTH]; 63 64 if ((cid = ESS_CERT_ID_new()) == NULL) 65 goto err; 66 if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL)) 67 goto err; 68 if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH)) 69 goto err; 70 71 /* Setting the issuer/serial if requested. */ 72 if (!set_issuer_serial) 73 return cid; 74 75 if (cid->issuer_serial == NULL 76 && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) 77 goto err; 78 if ((name = GENERAL_NAME_new()) == NULL) 79 goto err; 80 name->type = GEN_DIRNAME; 81 if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) 82 goto err; 83 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) 84 goto err; 85 name = NULL; /* Ownership is lost. */ 86 ASN1_INTEGER_free(cid->issuer_serial->serial); 87 if ((cid->issuer_serial->serial = 88 ASN1_INTEGER_dup(X509_get0_serialNumber(cert))) == NULL) 89 goto err; 90 91 return cid; 92 err: 93 GENERAL_NAME_free(name); 94 ESS_CERT_ID_free(cid); 95 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); 96 return NULL; 97 } 98 99 ESS_SIGNING_CERT_V2 *OSSL_ESS_signing_cert_v2_new_init(const EVP_MD *hash_alg, 100 const X509 *signcert, 101 const 102 STACK_OF(X509) *certs, 103 int set_issuer_serial) 104 { 105 ESS_CERT_ID_V2 *cid = NULL; 106 ESS_SIGNING_CERT_V2 *sc; 107 int i; 108 109 if ((sc = ESS_SIGNING_CERT_V2_new()) == NULL) 110 goto err; 111 cid = ESS_CERT_ID_V2_new_init(hash_alg, signcert, set_issuer_serial); 112 if (cid == NULL) 113 goto err; 114 if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) 115 goto err; 116 cid = NULL; 117 118 for (i = 0; i < sk_X509_num(certs); ++i) { 119 X509 *cert = sk_X509_value(certs, i); 120 121 if ((cid = ESS_CERT_ID_V2_new_init(hash_alg, cert, 1)) == NULL) 122 goto err; 123 if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid)) 124 goto err; 125 cid = NULL; 126 } 127 128 return sc; 129 err: 130 ESS_SIGNING_CERT_V2_free(sc); 131 ESS_CERT_ID_V2_free(cid); 132 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); 133 return NULL; 134 } 135 136 static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg, 137 const X509 *cert, 138 int set_issuer_serial) 139 { 140 ESS_CERT_ID_V2 *cid; 141 GENERAL_NAME *name = NULL; 142 unsigned char hash[EVP_MAX_MD_SIZE]; 143 unsigned int hash_len = sizeof(hash); 144 X509_ALGOR *alg = NULL; 145 146 memset(hash, 0, sizeof(hash)); 147 148 if ((cid = ESS_CERT_ID_V2_new()) == NULL) 149 goto err; 150 151 if (!EVP_MD_is_a(hash_alg, SN_sha256)) { 152 alg = X509_ALGOR_new(); 153 if (alg == NULL) 154 goto err; 155 X509_ALGOR_set_md(alg, hash_alg); 156 if (alg->algorithm == NULL) 157 goto err; 158 cid->hash_alg = alg; 159 alg = NULL; 160 } else { 161 cid->hash_alg = NULL; 162 } 163 164 if (!X509_digest(cert, hash_alg, hash, &hash_len)) 165 goto err; 166 167 if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len)) 168 goto err; 169 170 if (!set_issuer_serial) 171 return cid; 172 173 if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL) 174 goto err; 175 if ((name = GENERAL_NAME_new()) == NULL) 176 goto err; 177 name->type = GEN_DIRNAME; 178 if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL) 179 goto err; 180 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) 181 goto err; 182 name = NULL; /* Ownership is lost. */ 183 ASN1_INTEGER_free(cid->issuer_serial->serial); 184 cid->issuer_serial->serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert)); 185 if (cid->issuer_serial->serial == NULL) 186 goto err; 187 188 return cid; 189 err: 190 X509_ALGOR_free(alg); 191 GENERAL_NAME_free(name); 192 ESS_CERT_ID_V2_free(cid); 193 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE); 194 return NULL; 195 } 196 197 static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert) 198 { 199 GENERAL_NAME *issuer; 200 201 if (is == NULL || cert == NULL || sk_GENERAL_NAME_num(is->issuer) != 1) 202 return -1; 203 204 issuer = sk_GENERAL_NAME_value(is->issuer, 0); 205 if (issuer->type != GEN_DIRNAME 206 || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)) != 0) 207 return -1; 208 209 return ASN1_INTEGER_cmp(is->serial, X509_get0_serialNumber(cert)); 210 } 211 212 /* 213 * Find the cert in |certs| referenced by |cid| if not NULL, else by |cid_v2|. 214 * The cert must be the first one in |certs| if and only if |index| is 0. 215 * Return 0 on not found, -1 on error, else 1 + the position in |certs|. 216 */ 217 static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2, 218 int index, const STACK_OF(X509) *certs) 219 { 220 const X509 *cert; 221 EVP_MD *md = NULL; 222 char name[OSSL_MAX_NAME_SIZE]; 223 unsigned char cert_digest[EVP_MAX_MD_SIZE]; 224 unsigned int len, cid_hash_len; 225 const ESS_ISSUER_SERIAL *is; 226 int i; 227 int ret = -1; 228 229 if (cid == NULL && cid_v2 == NULL) { 230 ERR_raise(ERR_LIB_ESS, ERR_R_PASSED_INVALID_ARGUMENT); 231 return -1; 232 } 233 234 if (cid != NULL) 235 strcpy(name, "SHA1"); 236 else if (cid_v2->hash_alg == NULL) 237 strcpy(name, "SHA256"); 238 else 239 OBJ_obj2txt(name, sizeof(name), cid_v2->hash_alg->algorithm, 0); 240 241 (void)ERR_set_mark(); 242 md = EVP_MD_fetch(NULL, name, NULL); 243 244 if (md == NULL) 245 md = (EVP_MD *)EVP_get_digestbyname(name); 246 247 if (md == NULL) { 248 (void)ERR_clear_last_mark(); 249 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN); 250 goto end; 251 } 252 (void)ERR_pop_to_mark(); 253 254 for (i = 0; i < sk_X509_num(certs); ++i) { 255 cert = sk_X509_value(certs, i); 256 257 cid_hash_len = cid != NULL ? cid->hash->length : cid_v2->hash->length; 258 if (!X509_digest(cert, md, cert_digest, &len) 259 || cid_hash_len != len) { 260 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR); 261 goto end; 262 } 263 264 if (memcmp(cid != NULL ? cid->hash->data : cid_v2->hash->data, 265 cert_digest, len) == 0) { 266 is = cid != NULL ? cid->issuer_serial : cid_v2->issuer_serial; 267 /* Well, it's not really required to match the serial numbers. */ 268 if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) { 269 if ((i == 0) == (index == 0)) { 270 ret = i + 1; 271 goto end; 272 } 273 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER); 274 goto end; 275 } 276 } 277 } 278 279 ret = 0; 280 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND); 281 end: 282 EVP_MD_free(md); 283 return ret; 284 } 285 286 int OSSL_ESS_check_signing_certs(const ESS_SIGNING_CERT *ss, 287 const ESS_SIGNING_CERT_V2 *ssv2, 288 const STACK_OF(X509) *chain, 289 int require_signing_cert) 290 { 291 int n_v1 = ss == NULL ? -1 : sk_ESS_CERT_ID_num(ss->cert_ids); 292 int n_v2 = ssv2 == NULL ? -1 : sk_ESS_CERT_ID_V2_num(ssv2->cert_ids); 293 int i, ret; 294 295 if (require_signing_cert && ss == NULL && ssv2 == NULL) { 296 ERR_raise(ERR_LIB_CMS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE); 297 return -1; 298 } 299 if (n_v1 == 0 || n_v2 == 0) { 300 ERR_raise(ERR_LIB_ESS, ESS_R_EMPTY_ESS_CERT_ID_LIST); 301 return -1; 302 } 303 /* If both ss and ssv2 exist, as required evaluate them independently. */ 304 for (i = 0; i < n_v1; i++) { 305 ret = find(sk_ESS_CERT_ID_value(ss->cert_ids, i), NULL, i, chain); 306 if (ret <= 0) 307 return ret; 308 } 309 for (i = 0; i < n_v2; i++) { 310 ret = find(NULL, sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i), i, chain); 311 if (ret <= 0) 312 return ret; 313 } 314 return 1; 315 } 316