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