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 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
*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 ESSerr(ESS_F_ESS_SIGNING_CERT_NEW_INIT
, 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 (!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 ESSerr(ESS_F_ESS_CERT_ID_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
99 ESS_SIGNING_CERT_V2
*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 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_NEW_INIT
, 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 ESSerr(ESS_F_ESS_CERT_ID_V2_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
195 ESS_SIGNING_CERT
*ESS_SIGNING_CERT_get(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
*ESS_SIGNING_CERT_V2_get(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 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 ESSerr(ESS_F_ESS_SIGNING_CERT_ADD
, 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 ESSerr(ESS_F_ESS_SIGNING_CERT_ADD
, 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 ESS_SIGNING_CERT_V2_add(PKCS7_SIGNER_INFO
*si
,
249 ESS_SIGNING_CERT_V2
*sc
)
251 ASN1_STRING
*seq
= NULL
;
252 unsigned char *p
, *pp
= NULL
;
253 int len
= i2d_ESS_SIGNING_CERT_V2(sc
, NULL
);
255 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
256 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_ADD
, ERR_R_MALLOC_FAILURE
);
261 i2d_ESS_SIGNING_CERT_V2(sc
, &p
);
262 if ((seq
= ASN1_STRING_new()) == NULL
|| !ASN1_STRING_set(seq
, pp
, len
)) {
263 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_ADD
, ERR_R_MALLOC_FAILURE
);
269 return PKCS7_add_signed_attribute(si
,
270 NID_id_smime_aa_signingCertificateV2
,
271 V_ASN1_SEQUENCE
, seq
);
273 ASN1_STRING_free(seq
);
278 static int ess_issuer_serial_cmp(const ESS_ISSUER_SERIAL
*is
, const X509
*cert
)
280 GENERAL_NAME
*issuer
;
282 if (is
== NULL
|| cert
== NULL
|| sk_GENERAL_NAME_num(is
->issuer
) != 1)
285 issuer
= sk_GENERAL_NAME_value(is
->issuer
, 0);
286 if (issuer
->type
!= GEN_DIRNAME
287 || X509_NAME_cmp(issuer
->d
.dirn
, X509_get_issuer_name(cert
)) != 0)
290 return ASN1_INTEGER_cmp(is
->serial
, X509_get0_serialNumber(cert
));
293 /* Returns < 0 if certificate is not found, certificate index otherwise. */
294 int ess_find_cert(const STACK_OF(ESS_CERT_ID
) *cert_ids
, X509
*cert
)
297 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
299 if (cert_ids
== NULL
|| cert
== NULL
)
302 /* Recompute SHA1 hash of certificate if necessary (side effect). */
303 if (!x509v3_cache_extensions(cert
))
306 /* TODO(3.0): fetch sha1 algorithm from providers */
307 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
310 /* Look for cert in the cert_ids vector. */
311 for (i
= 0; i
< sk_ESS_CERT_ID_num(cert_ids
); ++i
) {
312 const ESS_CERT_ID
*cid
= sk_ESS_CERT_ID_value(cert_ids
, i
);
314 if (cid
->hash
->length
== SHA_DIGEST_LENGTH
315 && memcmp(cid
->hash
->data
, cert_sha1
, SHA_DIGEST_LENGTH
) == 0) {
316 const ESS_ISSUER_SERIAL
*is
= cid
->issuer_serial
;
318 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0)
326 /* Returns < 0 if certificate is not found, certificate index otherwise. */
327 int ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2
) *cert_ids
, const X509
*cert
)
330 unsigned char cert_digest
[EVP_MAX_MD_SIZE
];
333 /* Look for cert in the cert_ids vector. */
334 for (i
= 0; i
< sk_ESS_CERT_ID_V2_num(cert_ids
); ++i
) {
335 const ESS_CERT_ID_V2
*cid
= sk_ESS_CERT_ID_V2_value(cert_ids
, i
);
340 if (cid
->hash_alg
!= NULL
)
341 md
= EVP_get_digestbyobj(cid
->hash_alg
->algorithm
);
345 /* TODO(3.0): fetch sha1 algorithm from providers */
346 if (!X509_digest(cert
, md
, cert_digest
, &len
))
349 if (cid
->hash
->length
!= (int)len
)
352 if (memcmp(cid
->hash
->data
, cert_digest
, cid
->hash
->length
) == 0) {
353 const ESS_ISSUER_SERIAL
*is
= cid
->issuer_serial
;
355 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0)