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 "crypto/ess.h"
15 #include "crypto/x509.h"
17 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
);
18 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
19 X509
*cert
, int issuer_needed
);
21 ESS_SIGNING_CERT
*ossl_ess_signing_cert_new_init(X509
*signcert
,
22 STACK_OF(X509
) *certs
,
25 ESS_CERT_ID
*cid
= NULL
;
29 if ((sc
= ESS_SIGNING_CERT_new()) == NULL
)
31 if (sc
->cert_ids
== NULL
32 && (sc
->cert_ids
= sk_ESS_CERT_ID_new_null()) == NULL
)
35 if ((cid
= ESS_CERT_ID_new_init(signcert
, issuer_needed
)) == NULL
36 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
38 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
39 X509
*cert
= sk_X509_value(certs
, i
);
40 if ((cid
= ESS_CERT_ID_new_init(cert
, 1)) == NULL
41 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
47 ESS_SIGNING_CERT_free(sc
);
48 ESS_CERT_ID_free(cid
);
49 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
53 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
)
55 ESS_CERT_ID
*cid
= NULL
;
56 GENERAL_NAME
*name
= NULL
;
57 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
59 /* Call for side-effect of computing hash and caching extensions */
60 if (!ossl_x509v3_cache_extensions(cert
))
63 if ((cid
= ESS_CERT_ID_new()) == NULL
)
65 /* TODO(3.0): fetch sha1 algorithm from providers */
66 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
68 if (!ASN1_OCTET_STRING_set(cid
->hash
, cert_sha1
, SHA_DIGEST_LENGTH
))
71 /* Setting the issuer/serial if requested. */
75 if (cid
->issuer_serial
== NULL
76 && (cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
78 if ((name
= GENERAL_NAME_new()) == NULL
)
80 name
->type
= GEN_DIRNAME
;
81 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
83 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
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
)
93 GENERAL_NAME_free(name
);
94 ESS_CERT_ID_free(cid
);
95 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
99 ESS_SIGNING_CERT_V2
*ossl_ess_signing_cert_v2_new_init(const EVP_MD
*hash_alg
,
101 STACK_OF(X509
) *certs
,
104 ESS_CERT_ID_V2
*cid
= NULL
;
105 ESS_SIGNING_CERT_V2
*sc
;
108 if ((sc
= ESS_SIGNING_CERT_V2_new()) == NULL
)
110 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, signcert
, issuer_needed
)) == NULL
)
112 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
116 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
117 X509
*cert
= sk_X509_value(certs
, i
);
119 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, cert
, 1)) == NULL
)
121 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
128 ESS_SIGNING_CERT_V2_free(sc
);
129 ESS_CERT_ID_V2_free(cid
);
130 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
134 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
135 X509
*cert
, int issuer_needed
)
138 GENERAL_NAME
*name
= NULL
;
139 unsigned char hash
[EVP_MAX_MD_SIZE
];
140 unsigned int hash_len
= sizeof(hash
);
141 X509_ALGOR
*alg
= NULL
;
143 memset(hash
, 0, sizeof(hash
));
145 if ((cid
= ESS_CERT_ID_V2_new()) == NULL
)
148 if (hash_alg
!= EVP_sha256()) {
149 alg
= X509_ALGOR_new();
152 X509_ALGOR_set_md(alg
, hash_alg
);
153 if (alg
->algorithm
== NULL
)
158 cid
->hash_alg
= NULL
;
161 /* TODO(3.0): fetch sha1 algorithm from providers */
162 if (!X509_digest(cert
, hash_alg
, hash
, &hash_len
))
165 if (!ASN1_OCTET_STRING_set(cid
->hash
, hash
, hash_len
))
171 if ((cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
173 if ((name
= GENERAL_NAME_new()) == NULL
)
175 name
->type
= GEN_DIRNAME
;
176 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
178 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
180 name
= NULL
; /* Ownership is lost. */
181 ASN1_INTEGER_free(cid
->issuer_serial
->serial
);
182 cid
->issuer_serial
->serial
= ASN1_INTEGER_dup(X509_get0_serialNumber(cert
));
183 if (cid
->issuer_serial
->serial
== NULL
)
188 X509_ALGOR_free(alg
);
189 GENERAL_NAME_free(name
);
190 ESS_CERT_ID_V2_free(cid
);
191 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
195 ESS_SIGNING_CERT
*ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO
*si
)
198 const unsigned char *p
;
200 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificate
);
203 p
= attr
->value
.sequence
->data
;
204 return d2i_ESS_SIGNING_CERT(NULL
, &p
, attr
->value
.sequence
->length
);
207 ESS_SIGNING_CERT_V2
*ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO
*si
)
210 const unsigned char *p
;
212 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificateV2
);
215 p
= attr
->value
.sequence
->data
;
216 return d2i_ESS_SIGNING_CERT_V2(NULL
, &p
, attr
->value
.sequence
->length
);
219 int ossl_ess_signing_cert_add(PKCS7_SIGNER_INFO
*si
, ESS_SIGNING_CERT
*sc
)
221 ASN1_STRING
*seq
= NULL
;
222 unsigned char *p
, *pp
= NULL
;
225 len
= i2d_ESS_SIGNING_CERT(sc
, NULL
);
226 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
227 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
231 i2d_ESS_SIGNING_CERT(sc
, &p
);
232 if ((seq
= ASN1_STRING_new()) == NULL
|| !ASN1_STRING_set(seq
, pp
, len
)) {
233 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
238 return PKCS7_add_signed_attribute(si
,
239 NID_id_smime_aa_signingCertificate
,
240 V_ASN1_SEQUENCE
, seq
);
242 ASN1_STRING_free(seq
);
248 int ossl_ess_signing_cert_v2_add(PKCS7_SIGNER_INFO
*si
, ESS_SIGNING_CERT_V2
*sc
)
250 ASN1_STRING
*seq
= NULL
;
251 unsigned char *p
, *pp
= NULL
;
252 int len
= i2d_ESS_SIGNING_CERT_V2(sc
, NULL
);
254 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
255 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
260 i2d_ESS_SIGNING_CERT_V2(sc
, &p
);
261 if ((seq
= ASN1_STRING_new()) == NULL
|| !ASN1_STRING_set(seq
, pp
, len
)) {
262 ERR_raise(ERR_LIB_ESS
, ERR_R_MALLOC_FAILURE
);
268 return PKCS7_add_signed_attribute(si
,
269 NID_id_smime_aa_signingCertificateV2
,
270 V_ASN1_SEQUENCE
, seq
);
272 ASN1_STRING_free(seq
);
277 static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL
*is
, const X509
*cert
)
279 GENERAL_NAME
*issuer
;
281 if (is
== NULL
|| cert
== NULL
|| sk_GENERAL_NAME_num(is
->issuer
) != 1)
284 issuer
= sk_GENERAL_NAME_value(is
->issuer
, 0);
285 if (issuer
->type
!= GEN_DIRNAME
286 || X509_NAME_cmp(issuer
->d
.dirn
, X509_get_issuer_name(cert
)) != 0)
289 return ASN1_INTEGER_cmp(is
->serial
, X509_get0_serialNumber(cert
));
293 * Find cert referenced by |cid| (if not NULL, else |cidv2|) in |certs|.
294 * If the cid{,v2} index is 0, the cert must be in the first in |certs| list.
295 * Return 0 on not found, -1 on error, else 1 + the position in |certs|.
297 static int find(const ESS_CERT_ID
*cid
, const ESS_CERT_ID_V2
*cid_v2
,
298 int index
, const STACK_OF(X509
) *certs
)
302 unsigned char cert_digest
[EVP_MAX_MD_SIZE
];
303 unsigned int len
, cid_hash_len
;
304 const ESS_ISSUER_SERIAL
*is
;
307 if (cid
== NULL
&& cid_v2
== NULL
) {
308 ERR_raise(ERR_LIB_ESS
, ERR_R_PASSED_INVALID_ARGUMENT
);
312 /* Look for cert with cid in the certs. */
313 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
314 cert
= sk_X509_value(certs
, i
);
319 md
= cid_v2
->hash_alg
== NULL
? EVP_sha256() :
320 EVP_get_digestbyobj(cid_v2
->hash_alg
->algorithm
);
322 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_DIGEST_ALG_UNKNOWN
);
326 cid_hash_len
= cid
!= NULL
? cid
->hash
->length
: cid_v2
->hash
->length
;
327 if (!X509_digest(cert
, md
, cert_digest
, &len
)
328 || cid_hash_len
!= len
) {
329 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_CERT_DIGEST_ERROR
);
333 if (memcmp(cid
!= NULL
? cid
->hash
->data
: cid_v2
->hash
->data
,
334 cert_digest
, len
) == 0) {
335 is
= cid
!= NULL
? cid
->issuer_serial
: cid_v2
->issuer_serial
;
336 /* Well, it's not really required to match the serial numbers. */
337 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0) {
338 if ((i
== 0) == (index
== 0))
340 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_CERT_ID_WRONG_ORDER
);
346 ERR_raise(ERR_LIB_ESS
, ESS_R_ESS_CERT_ID_NOT_FOUND
);
351 * If ESSCertID and/or ESSCertIDv2 exist, which must be non-empty if given,
352 * check if their first ID entry matches the signer cert first in chain
353 * and each further ID entry matches any further cert in the chain.
355 int ossl_ess_check_signing_certs(const ESS_SIGNING_CERT
*ss
,
356 const ESS_SIGNING_CERT_V2
*ssv2
,
357 const STACK_OF(X509
) *chain
,
358 int require_signing_cert
)
360 int n_v1
= ss
== NULL
? -1 : sk_ESS_CERT_ID_num(ss
->cert_ids
);
361 int n_v2
= ssv2
== NULL
? -1 : sk_ESS_CERT_ID_V2_num(ssv2
->cert_ids
);
364 if (require_signing_cert
&& ss
== NULL
&& ssv2
== NULL
) {
365 ERR_raise(ERR_LIB_CMS
, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE
);
368 if (n_v1
== 0 || n_v2
== 0) {
369 ERR_raise(ERR_LIB_ESS
, ESS_R_EMPTY_ESS_CERT_ID_LIST
);
372 /* If both ss and ssv2 exist, as required evaluate them independently. */
373 for (i
= 0; i
< n_v1
; i
++)
374 if (find(sk_ESS_CERT_ID_value(ss
->cert_ids
, i
), NULL
, i
, chain
) <= 0)
376 for (i
= 0; i
< n_v2
; i
++)
377 if (find(NULL
, sk_ESS_CERT_ID_V2_value(ssv2
->cert_ids
, i
), i
, chain
) <= 0)