]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/ess/ess_lib.c
Prefer fetch over legacy get_digestby/get_cipherby
[thirdparty/openssl.git] / crypto / ess / ess_lib.c
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(X509 *cert, int issuer_needed);
19 static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg,
20 X509 *cert, int issuer_needed);
21
22 ESS_SIGNING_CERT *ossl_ess_signing_cert_new_init(X509 *signcert,
23 STACK_OF(X509) *certs,
24 int issuer_needed)
25 {
26 ESS_CERT_ID *cid = NULL;
27 ESS_SIGNING_CERT *sc;
28 int i;
29
30 if ((sc = ESS_SIGNING_CERT_new()) == NULL)
31 goto err;
32 if (sc->cert_ids == NULL
33 && (sc->cert_ids = sk_ESS_CERT_ID_new_null()) == NULL)
34 goto err;
35
36 if ((cid = ESS_CERT_ID_new_init(signcert, issuer_needed)) == NULL
37 || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
38 goto err;
39 for (i = 0; i < sk_X509_num(certs); ++i) {
40 X509 *cert = sk_X509_value(certs, i);
41 if ((cid = ESS_CERT_ID_new_init(cert, 1)) == NULL
42 || !sk_ESS_CERT_ID_push(sc->cert_ids, cid))
43 goto err;
44 }
45
46 return sc;
47 err:
48 ESS_SIGNING_CERT_free(sc);
49 ESS_CERT_ID_free(cid);
50 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
51 return NULL;
52 }
53
54 static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed)
55 {
56 ESS_CERT_ID *cid = NULL;
57 GENERAL_NAME *name = NULL;
58 unsigned char cert_sha1[SHA_DIGEST_LENGTH];
59
60 /* Call for side-effect of computing hash and caching extensions */
61 if (!ossl_x509v3_cache_extensions(cert))
62 return NULL;
63
64 if ((cid = ESS_CERT_ID_new()) == NULL)
65 goto err;
66 /* TODO(3.0): fetch sha1 algorithm from providers */
67 if (!X509_digest(cert, EVP_sha1(), cert_sha1, NULL))
68 goto err;
69 if (!ASN1_OCTET_STRING_set(cid->hash, cert_sha1, SHA_DIGEST_LENGTH))
70 goto err;
71
72 /* Setting the issuer/serial if requested. */
73 if (!issuer_needed)
74 return cid;
75
76 if (cid->issuer_serial == NULL
77 && (cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
78 goto err;
79 if ((name = GENERAL_NAME_new()) == NULL)
80 goto err;
81 name->type = GEN_DIRNAME;
82 if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
83 goto err;
84 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
85 goto err;
86 name = NULL; /* Ownership is lost. */
87 ASN1_INTEGER_free(cid->issuer_serial->serial);
88 if ((cid->issuer_serial->serial =
89 ASN1_INTEGER_dup(X509_get0_serialNumber(cert))) == NULL)
90 goto err;
91
92 return cid;
93 err:
94 GENERAL_NAME_free(name);
95 ESS_CERT_ID_free(cid);
96 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
97 return NULL;
98 }
99
100 ESS_SIGNING_CERT_V2 *ossl_ess_signing_cert_v2_new_init(const EVP_MD *hash_alg,
101 X509 *signcert,
102 STACK_OF(X509) *certs,
103 int issuer_needed)
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 if ((cid = ESS_CERT_ID_V2_new_init(hash_alg, signcert, issuer_needed)) == NULL)
112 goto err;
113 if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
114 goto err;
115 cid = NULL;
116
117 for (i = 0; i < sk_X509_num(certs); ++i) {
118 X509 *cert = sk_X509_value(certs, i);
119
120 if ((cid = ESS_CERT_ID_V2_new_init(hash_alg, cert, 1)) == NULL)
121 goto err;
122 if (!sk_ESS_CERT_ID_V2_push(sc->cert_ids, cid))
123 goto err;
124 cid = NULL;
125 }
126
127 return sc;
128 err:
129 ESS_SIGNING_CERT_V2_free(sc);
130 ESS_CERT_ID_V2_free(cid);
131 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
132 return NULL;
133 }
134
135 static ESS_CERT_ID_V2 *ESS_CERT_ID_V2_new_init(const EVP_MD *hash_alg,
136 X509 *cert, int issuer_needed)
137 {
138 ESS_CERT_ID_V2 *cid;
139 GENERAL_NAME *name = NULL;
140 unsigned char hash[EVP_MAX_MD_SIZE];
141 unsigned int hash_len = sizeof(hash);
142 X509_ALGOR *alg = NULL;
143
144 memset(hash, 0, sizeof(hash));
145
146 if ((cid = ESS_CERT_ID_V2_new()) == NULL)
147 goto err;
148
149 if (!EVP_MD_is_a(hash_alg, SN_sha256)) {
150 alg = X509_ALGOR_new();
151 if (alg == NULL)
152 goto err;
153 X509_ALGOR_set_md(alg, hash_alg);
154 if (alg->algorithm == NULL)
155 goto err;
156 cid->hash_alg = alg;
157 alg = NULL;
158 } else {
159 cid->hash_alg = NULL;
160 }
161
162 /* TODO(3.0): fetch sha1 algorithm from providers */
163 if (!X509_digest(cert, hash_alg, hash, &hash_len))
164 goto err;
165
166 if (!ASN1_OCTET_STRING_set(cid->hash, hash, hash_len))
167 goto err;
168
169 if (!issuer_needed)
170 return cid;
171
172 if ((cid->issuer_serial = ESS_ISSUER_SERIAL_new()) == NULL)
173 goto err;
174 if ((name = GENERAL_NAME_new()) == NULL)
175 goto err;
176 name->type = GEN_DIRNAME;
177 if ((name->d.dirn = X509_NAME_dup(X509_get_issuer_name(cert))) == NULL)
178 goto err;
179 if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name))
180 goto err;
181 name = NULL; /* Ownership is lost. */
182 ASN1_INTEGER_free(cid->issuer_serial->serial);
183 cid->issuer_serial->serial = ASN1_INTEGER_dup(X509_get0_serialNumber(cert));
184 if (cid->issuer_serial->serial == NULL)
185 goto err;
186
187 return cid;
188 err:
189 X509_ALGOR_free(alg);
190 GENERAL_NAME_free(name);
191 ESS_CERT_ID_V2_free(cid);
192 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
193 return NULL;
194 }
195
196 ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si)
197 {
198 ASN1_TYPE *attr;
199 const unsigned char *p;
200
201 attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate);
202 if (attr == NULL)
203 return NULL;
204 p = attr->value.sequence->data;
205 return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length);
206 }
207
208 ESS_SIGNING_CERT_V2 *ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO *si)
209 {
210 ASN1_TYPE *attr;
211 const unsigned char *p;
212
213 attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2);
214 if (attr == NULL)
215 return NULL;
216 p = attr->value.sequence->data;
217 return d2i_ESS_SIGNING_CERT_V2(NULL, &p, attr->value.sequence->length);
218 }
219
220 int ossl_ess_signing_cert_add(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc)
221 {
222 ASN1_STRING *seq = NULL;
223 unsigned char *p, *pp = NULL;
224 int len;
225
226 len = i2d_ESS_SIGNING_CERT(sc, NULL);
227 if (len <= 0)
228 goto err;
229 if ((pp = OPENSSL_malloc(len)) == NULL) {
230 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
231 goto err;
232 }
233 p = pp;
234 i2d_ESS_SIGNING_CERT(sc, &p);
235 if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
236 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
237 goto err;
238 }
239 OPENSSL_free(pp);
240 pp = NULL;
241 return PKCS7_add_signed_attribute(si,
242 NID_id_smime_aa_signingCertificate,
243 V_ASN1_SEQUENCE, seq);
244 err:
245 ASN1_STRING_free(seq);
246 OPENSSL_free(pp);
247
248 return 0;
249 }
250
251 int ossl_ess_signing_cert_v2_add(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT_V2 *sc)
252 {
253 ASN1_STRING *seq = NULL;
254 unsigned char *p, *pp = NULL;
255 int len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);
256
257 if (len <= 0)
258 goto err;
259 if ((pp = OPENSSL_malloc(len)) == NULL) {
260 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
261 goto err;
262 }
263
264 p = pp;
265 i2d_ESS_SIGNING_CERT_V2(sc, &p);
266 if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) {
267 ERR_raise(ERR_LIB_ESS, ERR_R_MALLOC_FAILURE);
268 goto err;
269 }
270
271 OPENSSL_free(pp);
272 pp = NULL;
273 return PKCS7_add_signed_attribute(si,
274 NID_id_smime_aa_signingCertificateV2,
275 V_ASN1_SEQUENCE, seq);
276 err:
277 ASN1_STRING_free(seq);
278 OPENSSL_free(pp);
279 return 0;
280 }
281
282 static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL *is, const X509 *cert)
283 {
284 GENERAL_NAME *issuer;
285
286 if (is == NULL || cert == NULL || sk_GENERAL_NAME_num(is->issuer) != 1)
287 return -1;
288
289 issuer = sk_GENERAL_NAME_value(is->issuer, 0);
290 if (issuer->type != GEN_DIRNAME
291 || X509_NAME_cmp(issuer->d.dirn, X509_get_issuer_name(cert)) != 0)
292 return -1;
293
294 return ASN1_INTEGER_cmp(is->serial, X509_get0_serialNumber(cert));
295 }
296
297 /*
298 * Find cert referenced by |cid| (if not NULL, else |cidv2|) in |certs|.
299 * If the cid{,v2} index is 0, the cert must be in the first in |certs| list.
300 * Return 0 on not found, -1 on error, else 1 + the position in |certs|.
301 */
302 static int find(const ESS_CERT_ID *cid, const ESS_CERT_ID_V2 *cid_v2,
303 int index, const STACK_OF(X509) *certs)
304 {
305 const X509 *cert;
306 EVP_MD *md = NULL;
307 char name[OSSL_MAX_NAME_SIZE];
308 unsigned char cert_digest[EVP_MAX_MD_SIZE];
309 unsigned int len, cid_hash_len;
310 const ESS_ISSUER_SERIAL *is;
311 int i;
312 int ret = -1;
313
314 if (cid == NULL && cid_v2 == NULL) {
315 ERR_raise(ERR_LIB_ESS, ERR_R_PASSED_INVALID_ARGUMENT);
316 return -1;
317 }
318
319 if (cid != NULL)
320 strcpy(name, "SHA1");
321 else if (cid_v2->hash_alg == NULL)
322 strcpy(name, "SHA256");
323 else
324 OBJ_obj2txt(name, sizeof(name), cid_v2->hash_alg->algorithm, 0);
325
326 (void)ERR_set_mark();
327 md = EVP_MD_fetch(NULL, name, NULL);
328
329 if (md == NULL)
330 md = (EVP_MD *)EVP_get_digestbyname(name);
331
332 if (md == NULL) {
333 (void)ERR_clear_last_mark();
334 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_DIGEST_ALG_UNKNOWN);
335 goto end;
336 }
337 (void)ERR_pop_to_mark();
338
339 /* Look for cert with cid in the certs. */
340 for (i = 0; i < sk_X509_num(certs); ++i) {
341 cert = sk_X509_value(certs, i);
342
343 cid_hash_len = cid != NULL ? cid->hash->length : cid_v2->hash->length;
344 if (!X509_digest(cert, md, cert_digest, &len)
345 || cid_hash_len != len) {
346 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_DIGEST_ERROR);
347 goto end;
348 }
349
350 if (memcmp(cid != NULL ? cid->hash->data : cid_v2->hash->data,
351 cert_digest, len) == 0) {
352 is = cid != NULL ? cid->issuer_serial : cid_v2->issuer_serial;
353 /* Well, it's not really required to match the serial numbers. */
354 if (is == NULL || ess_issuer_serial_cmp(is, cert) == 0) {
355 if ((i == 0) == (index == 0)) {
356 ret = i + 1;
357 goto end;
358 }
359 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_WRONG_ORDER);
360 goto end;
361 }
362 }
363 }
364
365 ret = 0;
366 ERR_raise(ERR_LIB_ESS, ESS_R_ESS_CERT_ID_NOT_FOUND);
367 end:
368 EVP_MD_free(md);
369 return ret;
370 }
371
372 /*
373 * If ESSCertID and/or ESSCertIDv2 exist, which must be non-empty if given,
374 * check if their first ID entry matches the signer cert first in chain
375 * and each further ID entry matches any further cert in the chain.
376 */
377 int ossl_ess_check_signing_certs(const ESS_SIGNING_CERT *ss,
378 const ESS_SIGNING_CERT_V2 *ssv2,
379 const STACK_OF(X509) *chain,
380 int require_signing_cert)
381 {
382 int n_v1 = ss == NULL ? -1 : sk_ESS_CERT_ID_num(ss->cert_ids);
383 int n_v2 = ssv2 == NULL ? -1 : sk_ESS_CERT_ID_V2_num(ssv2->cert_ids);
384 int i;
385
386 if (require_signing_cert && ss == NULL && ssv2 == NULL) {
387 ERR_raise(ERR_LIB_CMS, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE);
388 return 0;
389 }
390 if (n_v1 == 0 || n_v2 == 0) {
391 ERR_raise(ERR_LIB_ESS, ESS_R_EMPTY_ESS_CERT_ID_LIST);
392 return 0;
393 }
394 /* If both ss and ssv2 exist, as required evaluate them independently. */
395 for (i = 0; i < n_v1; i++)
396 if (find(sk_ESS_CERT_ID_value(ss->cert_ids, i), NULL, i, chain) <= 0)
397 return 0;
398 for (i = 0; i < n_v2; i++)
399 if (find(NULL, sk_ESS_CERT_ID_V2_value(ssv2->cert_ids, i), i, chain) <= 0)
400 return 0;
401 return 1;
402 }