2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
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
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"
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
);
22 ESS_SIGNING_CERT
*ossl_ess_signing_cert_new_init(X509
*signcert
,
23 STACK_OF(X509
) *certs
,
26 ESS_CERT_ID
*cid
= NULL
;
30 if ((sc
= ESS_SIGNING_CERT_new()) == NULL
)
32 if (sc
->cert_ids
== NULL
33 && (sc
->cert_ids
= sk_ESS_CERT_ID_new_null()) == NULL
)
36 if ((cid
= ESS_CERT_ID_new_init(signcert
, issuer_needed
)) == NULL
37 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
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
))
48 ESS_SIGNING_CERT_free(sc
);
49 ESS_CERT_ID_free(cid
);
50 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
54 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
)
56 ESS_CERT_ID
*cid
= NULL
;
57 GENERAL_NAME
*name
= NULL
;
58 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
60 /* Call for side-effect of computing hash and caching extensions */
61 if (!ossl_x509v3_cache_extensions(cert
))
64 if ((cid
= ESS_CERT_ID_new()) == NULL
)
66 /* TODO(3.0): fetch sha1 algorithm from providers */
67 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
69 if (!ASN1_OCTET_STRING_set(cid
->hash
, cert_sha1
, SHA_DIGEST_LENGTH
))
72 /* Setting the issuer/serial if requested. */
76 if (cid
->issuer_serial
== NULL
77 && (cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
79 if ((name
= GENERAL_NAME_new()) == NULL
)
81 name
->type
= GEN_DIRNAME
;
82 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
84 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
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
)
94 GENERAL_NAME_free(name
);
95 ESS_CERT_ID_free(cid
);
96 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
100 ESS_SIGNING_CERT_V2
*ossl_ess_signing_cert_v2_new_init(const EVP_MD
*hash_alg
,
102 STACK_OF(X509
) *certs
,
105 ESS_CERT_ID_V2
*cid
= NULL
;
106 ESS_SIGNING_CERT_V2
*sc
;
109 if ((sc
= ESS_SIGNING_CERT_V2_new()) == NULL
)
111 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, signcert
, issuer_needed
)) == NULL
)
113 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
117 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
118 X509
*cert
= sk_X509_value(certs
, i
);
120 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, cert
, 1)) == NULL
)
122 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
129 ESS_SIGNING_CERT_V2_free(sc
);
130 ESS_CERT_ID_V2_free(cid
);
131 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
135 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
136 X509
*cert
, int issuer_needed
)
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
;
144 memset(hash
, 0, sizeof(hash
));
146 if ((cid
= ESS_CERT_ID_V2_new()) == NULL
)
149 if (!EVP_MD_is_a(hash_alg
, SN_sha256
)) {
150 alg
= X509_ALGOR_new();
153 X509_ALGOR_set_md(alg
, hash_alg
);
154 if (alg
->algorithm
== NULL
)
159 cid
->hash_alg
= NULL
;
162 /* TODO(3.0): fetch sha1 algorithm from providers */
163 if (!X509_digest(cert
, hash_alg
, hash
, &hash_len
))
166 if (!ASN1_OCTET_STRING_set(cid
->hash
, hash
, hash_len
))
172 if ((cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
174 if ((name
= GENERAL_NAME_new()) == NULL
)
176 name
->type
= GEN_DIRNAME
;
177 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
179 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
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
)
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
);
196 ESS_SIGNING_CERT
*ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO
*si
)
199 const unsigned char *p
;
201 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificate
);
204 p
= attr
->value
.sequence
->data
;
205 return d2i_ESS_SIGNING_CERT(NULL
, &p
, attr
->value
.sequence
->length
);
208 ESS_SIGNING_CERT_V2
*ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO
*si
)
211 const unsigned char *p
;
213 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificateV2
);
216 p
= attr
->value
.sequence
->data
;
217 return d2i_ESS_SIGNING_CERT_V2(NULL
, &p
, attr
->value
.sequence
->length
);
220 int ossl_ess_signing_cert_add(PKCS7_SIGNER_INFO
*si
, ESS_SIGNING_CERT
*sc
)
222 ASN1_STRING
*seq
= NULL
;
223 unsigned char *p
, *pp
= NULL
;
226 len
= i2d_ESS_SIGNING_CERT(sc
, NULL
);
229 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
230 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
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
);
241 return PKCS7_add_signed_attribute(si
,
242 NID_id_smime_aa_signingCertificate
,
243 V_ASN1_SEQUENCE
, seq
);
245 ASN1_STRING_free(seq
);
251 int ossl_ess_signing_cert_v2_add(PKCS7_SIGNER_INFO
*si
, ESS_SIGNING_CERT_V2
*sc
)
253 ASN1_STRING
*seq
= NULL
;
254 unsigned char *p
, *pp
= NULL
;
255 int len
= i2d_ESS_SIGNING_CERT_V2(sc
, NULL
);
259 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
260 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
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
);
273 return PKCS7_add_signed_attribute(si
,
274 NID_id_smime_aa_signingCertificateV2
,
275 V_ASN1_SEQUENCE
, seq
);
277 ASN1_STRING_free(seq
);
282 static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL
*is
, const X509
*cert
)
284 GENERAL_NAME
*issuer
;
286 if (is
== NULL
|| cert
== NULL
|| sk_GENERAL_NAME_num(is
->issuer
) != 1)
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)
294 return ASN1_INTEGER_cmp(is
->serial
, X509_get0_serialNumber(cert
));
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|.
302 static int find(const ESS_CERT_ID
*cid
, const ESS_CERT_ID_V2
*cid_v2
,
303 int index
, const STACK_OF(X509
) *certs
)
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
;
314 if (cid
== NULL
&& cid_v2
== NULL
) {
315 ERR_raise(ERR_LIB_ESS
, ERR_R_PASSED_INVALID_ARGUMENT
);
320 strcpy(name
, "SHA1");
321 else if (cid_v2
->hash_alg
== NULL
)
322 strcpy(name
, "SHA256");
324 OBJ_obj2txt(name
, sizeof(name
), cid_v2
->hash_alg
->algorithm
, 0);
326 (void)ERR_set_mark();
327 md
= EVP_MD_fetch(NULL
, name
, NULL
);
330 md
= (EVP_MD
*)EVP_get_digestbyname(name
);
333 (void)ERR_clear_last_mark();
334 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_DIGEST_ALG_UNKNOWN
);
337 (void)ERR_pop_to_mark();
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
);
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
);
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)) {
359 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_CERT_ID_WRONG_ORDER
);
366 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_CERT_ID_NOT_FOUND
);
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.
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
)
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
);
386 if (require_signing_cert
&& ss
== NULL
&& ssv2
== NULL
) {
387 ERR_raise(ERR_LIB_CMS
, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE
);
390 if (n_v1
== 0 || n_v2
== 0) {
391 ERR_raise(ERR_LIB_ESS
, ESS_R_EMPTY_ESS_CERT_ID_LIST
);
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)
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)