2 * Copyright 2019-2020 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 DEFINE_STACK_OF(ESS_CERT_ID
)
18 DEFINE_STACK_OF(ESS_CERT_ID_V2
)
19 DEFINE_STACK_OF(GENERAL_NAME
)
22 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
);
23 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
24 X509
*cert
, int issuer_needed
);
26 ESS_SIGNING_CERT
*ESS_SIGNING_CERT_new_init(X509
*signcert
,
27 STACK_OF(X509
) *certs
,
30 ESS_CERT_ID
*cid
= NULL
;
34 if ((sc
= ESS_SIGNING_CERT_new()) == NULL
)
36 if (sc
->cert_ids
== NULL
37 && (sc
->cert_ids
= sk_ESS_CERT_ID_new_null()) == NULL
)
40 if ((cid
= ESS_CERT_ID_new_init(signcert
, issuer_needed
)) == NULL
41 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
43 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
44 X509
*cert
= sk_X509_value(certs
, i
);
45 if ((cid
= ESS_CERT_ID_new_init(cert
, 1)) == NULL
46 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
52 ESS_SIGNING_CERT_free(sc
);
53 ESS_CERT_ID_free(cid
);
54 ESSerr(ESS_F_ESS_SIGNING_CERT_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
58 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
)
60 ESS_CERT_ID
*cid
= NULL
;
61 GENERAL_NAME
*name
= NULL
;
62 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
64 /* Call for side-effect of computing hash and caching extensions */
65 if (!x509v3_cache_extensions(cert
))
68 if ((cid
= ESS_CERT_ID_new()) == NULL
)
70 /* TODO(3.0): fetch sha1 algorithm from providers */
71 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
73 if (!ASN1_OCTET_STRING_set(cid
->hash
, cert_sha1
, SHA_DIGEST_LENGTH
))
76 /* Setting the issuer/serial if requested. */
80 if (cid
->issuer_serial
== NULL
81 && (cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
83 if ((name
= GENERAL_NAME_new()) == NULL
)
85 name
->type
= GEN_DIRNAME
;
86 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
88 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
90 name
= NULL
; /* Ownership is lost. */
91 ASN1_INTEGER_free(cid
->issuer_serial
->serial
);
92 if ((cid
->issuer_serial
->serial
=
93 ASN1_INTEGER_dup(X509_get0_serialNumber(cert
))) == NULL
)
98 GENERAL_NAME_free(name
);
99 ESS_CERT_ID_free(cid
);
100 ESSerr(ESS_F_ESS_CERT_ID_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
104 ESS_SIGNING_CERT_V2
*ESS_SIGNING_CERT_V2_new_init(const EVP_MD
*hash_alg
,
106 STACK_OF(X509
) *certs
,
109 ESS_CERT_ID_V2
*cid
= NULL
;
110 ESS_SIGNING_CERT_V2
*sc
;
113 if ((sc
= ESS_SIGNING_CERT_V2_new()) == NULL
)
115 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, signcert
, issuer_needed
)) == NULL
)
117 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
121 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
122 X509
*cert
= sk_X509_value(certs
, i
);
124 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, cert
, 1)) == NULL
)
126 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
133 ESS_SIGNING_CERT_V2_free(sc
);
134 ESS_CERT_ID_V2_free(cid
);
135 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
139 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
140 X509
*cert
, int issuer_needed
)
143 GENERAL_NAME
*name
= NULL
;
144 unsigned char hash
[EVP_MAX_MD_SIZE
];
145 unsigned int hash_len
= sizeof(hash
);
146 X509_ALGOR
*alg
= NULL
;
148 memset(hash
, 0, sizeof(hash
));
150 if ((cid
= ESS_CERT_ID_V2_new()) == NULL
)
153 if (hash_alg
!= EVP_sha256()) {
154 alg
= X509_ALGOR_new();
157 X509_ALGOR_set_md(alg
, hash_alg
);
158 if (alg
->algorithm
== NULL
)
163 cid
->hash_alg
= NULL
;
166 /* TODO(3.0): fetch sha1 algorithm from providers */
167 if (!X509_digest(cert
, hash_alg
, hash
, &hash_len
))
170 if (!ASN1_OCTET_STRING_set(cid
->hash
, hash
, hash_len
))
176 if ((cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
178 if ((name
= GENERAL_NAME_new()) == NULL
)
180 name
->type
= GEN_DIRNAME
;
181 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
183 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
185 name
= NULL
; /* Ownership is lost. */
186 ASN1_INTEGER_free(cid
->issuer_serial
->serial
);
187 cid
->issuer_serial
->serial
= ASN1_INTEGER_dup(X509_get0_serialNumber(cert
));
188 if (cid
->issuer_serial
->serial
== NULL
)
193 X509_ALGOR_free(alg
);
194 GENERAL_NAME_free(name
);
195 ESS_CERT_ID_V2_free(cid
);
196 ESSerr(ESS_F_ESS_CERT_ID_V2_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
200 ESS_SIGNING_CERT
*ESS_SIGNING_CERT_get(PKCS7_SIGNER_INFO
*si
)
203 const unsigned char *p
;
205 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificate
);
208 p
= attr
->value
.sequence
->data
;
209 return d2i_ESS_SIGNING_CERT(NULL
, &p
, attr
->value
.sequence
->length
);
212 ESS_SIGNING_CERT_V2
*ESS_SIGNING_CERT_V2_get(PKCS7_SIGNER_INFO
*si
)
215 const unsigned char *p
;
217 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificateV2
);
220 p
= attr
->value
.sequence
->data
;
221 return d2i_ESS_SIGNING_CERT_V2(NULL
, &p
, attr
->value
.sequence
->length
);
224 int ESS_SIGNING_CERT_add(PKCS7_SIGNER_INFO
*si
, ESS_SIGNING_CERT
*sc
)
226 ASN1_STRING
*seq
= NULL
;
227 unsigned char *p
, *pp
= NULL
;
230 len
= i2d_ESS_SIGNING_CERT(sc
, NULL
);
231 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
232 ESSerr(ESS_F_ESS_SIGNING_CERT_ADD
, ERR_R_MALLOC_FAILURE
);
236 i2d_ESS_SIGNING_CERT(sc
, &p
);
237 if ((seq
= ASN1_STRING_new()) == NULL
|| !ASN1_STRING_set(seq
, pp
, len
)) {
238 ESSerr(ESS_F_ESS_SIGNING_CERT_ADD
, ERR_R_MALLOC_FAILURE
);
243 return PKCS7_add_signed_attribute(si
,
244 NID_id_smime_aa_signingCertificate
,
245 V_ASN1_SEQUENCE
, seq
);
247 ASN1_STRING_free(seq
);
253 int ESS_SIGNING_CERT_V2_add(PKCS7_SIGNER_INFO
*si
,
254 ESS_SIGNING_CERT_V2
*sc
)
256 ASN1_STRING
*seq
= NULL
;
257 unsigned char *p
, *pp
= NULL
;
258 int len
= i2d_ESS_SIGNING_CERT_V2(sc
, NULL
);
260 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
261 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_ADD
, ERR_R_MALLOC_FAILURE
);
266 i2d_ESS_SIGNING_CERT_V2(sc
, &p
);
267 if ((seq
= ASN1_STRING_new()) == NULL
|| !ASN1_STRING_set(seq
, pp
, len
)) {
268 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_ADD
, ERR_R_MALLOC_FAILURE
);
274 return PKCS7_add_signed_attribute(si
,
275 NID_id_smime_aa_signingCertificateV2
,
276 V_ASN1_SEQUENCE
, seq
);
278 ASN1_STRING_free(seq
);
283 static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL
*is
, const X509
*cert
)
285 GENERAL_NAME
*issuer
;
287 if (is
== NULL
|| cert
== NULL
|| sk_GENERAL_NAME_num(is
->issuer
) != 1)
290 issuer
= sk_GENERAL_NAME_value(is
->issuer
, 0);
291 if (issuer
->type
!= GEN_DIRNAME
292 || X509_NAME_cmp(issuer
->d
.dirn
, X509_get_issuer_name(cert
)) != 0)
295 return ASN1_INTEGER_cmp(is
->serial
, X509_get0_serialNumber(cert
));
298 /* Returns < 0 if certificate is not found, certificate index otherwise. */
299 int ess_find_cert(const STACK_OF(ESS_CERT_ID
) *cert_ids
, X509
*cert
)
302 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
304 if (cert_ids
== NULL
|| cert
== NULL
)
307 /* Recompute SHA1 hash of certificate if necessary (side effect). */
308 if (!x509v3_cache_extensions(cert
))
311 /* TODO(3.0): fetch sha1 algorithm from providers */
312 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
315 /* Look for cert in the cert_ids vector. */
316 for (i
= 0; i
< sk_ESS_CERT_ID_num(cert_ids
); ++i
) {
317 const ESS_CERT_ID
*cid
= sk_ESS_CERT_ID_value(cert_ids
, i
);
319 if (cid
->hash
->length
== SHA_DIGEST_LENGTH
320 && memcmp(cid
->hash
->data
, cert_sha1
, SHA_DIGEST_LENGTH
) == 0) {
321 const ESS_ISSUER_SERIAL
*is
= cid
->issuer_serial
;
323 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0)
331 /* Returns < 0 if certificate is not found, certificate index otherwise. */
332 int ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2
) *cert_ids
, const X509
*cert
)
335 unsigned char cert_digest
[EVP_MAX_MD_SIZE
];
338 /* Look for cert in the cert_ids vector. */
339 for (i
= 0; i
< sk_ESS_CERT_ID_V2_num(cert_ids
); ++i
) {
340 const ESS_CERT_ID_V2
*cid
= sk_ESS_CERT_ID_V2_value(cert_ids
, i
);
345 if (cid
->hash_alg
!= NULL
)
346 md
= EVP_get_digestbyobj(cid
->hash_alg
->algorithm
);
350 /* TODO(3.0): fetch sha1 algorithm from providers */
351 if (!X509_digest(cert
, md
, cert_digest
, &len
))
354 if (cid
->hash
->length
!= (int)len
)
357 if (memcmp(cid
->hash
->data
, cert_digest
, cid
->hash
->length
) == 0) {
358 const ESS_ISSUER_SERIAL
*is
= cid
->issuer_serial
;
360 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0)