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"
16 DEFINE_STACK_OF(ESS_CERT_ID
)
17 DEFINE_STACK_OF(ESS_CERT_ID_V2
)
18 DEFINE_STACK_OF(GENERAL_NAME
)
21 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
);
22 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
23 X509
*cert
, int issuer_needed
);
25 ESS_SIGNING_CERT
*ESS_SIGNING_CERT_new_init(X509
*signcert
,
26 STACK_OF(X509
) *certs
,
29 ESS_CERT_ID
*cid
= NULL
;
33 if ((sc
= ESS_SIGNING_CERT_new()) == NULL
)
35 if (sc
->cert_ids
== NULL
36 && (sc
->cert_ids
= sk_ESS_CERT_ID_new_null()) == NULL
)
39 if ((cid
= ESS_CERT_ID_new_init(signcert
, issuer_needed
)) == NULL
40 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
42 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
43 X509
*cert
= sk_X509_value(certs
, i
);
44 if ((cid
= ESS_CERT_ID_new_init(cert
, 1)) == NULL
45 || !sk_ESS_CERT_ID_push(sc
->cert_ids
, cid
))
51 ESS_SIGNING_CERT_free(sc
);
52 ESS_CERT_ID_free(cid
);
53 ESSerr(ESS_F_ESS_SIGNING_CERT_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
57 static ESS_CERT_ID
*ESS_CERT_ID_new_init(X509
*cert
, int issuer_needed
)
59 ESS_CERT_ID
*cid
= NULL
;
60 GENERAL_NAME
*name
= NULL
;
61 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
63 /* Call for side-effect of computing hash and caching extensions */
64 if (!X509v3_cache_extensions(cert
, NULL
, NULL
))
67 if ((cid
= ESS_CERT_ID_new()) == NULL
)
69 /* TODO(3.0): fetch sha1 algorithm from providers */
70 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
72 if (!ASN1_OCTET_STRING_set(cid
->hash
, cert_sha1
, SHA_DIGEST_LENGTH
))
75 /* Setting the issuer/serial if requested. */
79 if (cid
->issuer_serial
== NULL
80 && (cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
82 if ((name
= GENERAL_NAME_new()) == NULL
)
84 name
->type
= GEN_DIRNAME
;
85 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
87 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
89 name
= NULL
; /* Ownership is lost. */
90 ASN1_INTEGER_free(cid
->issuer_serial
->serial
);
91 if ((cid
->issuer_serial
->serial
=
92 ASN1_INTEGER_dup(X509_get0_serialNumber(cert
))) == NULL
)
97 GENERAL_NAME_free(name
);
98 ESS_CERT_ID_free(cid
);
99 ESSerr(ESS_F_ESS_CERT_ID_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
103 ESS_SIGNING_CERT_V2
*ESS_SIGNING_CERT_V2_new_init(const EVP_MD
*hash_alg
,
105 STACK_OF(X509
) *certs
,
108 ESS_CERT_ID_V2
*cid
= NULL
;
109 ESS_SIGNING_CERT_V2
*sc
;
112 if ((sc
= ESS_SIGNING_CERT_V2_new()) == NULL
)
114 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, signcert
, issuer_needed
)) == NULL
)
116 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
120 for (i
= 0; i
< sk_X509_num(certs
); ++i
) {
121 X509
*cert
= sk_X509_value(certs
, i
);
123 if ((cid
= ESS_CERT_ID_V2_new_init(hash_alg
, cert
, 1)) == NULL
)
125 if (!sk_ESS_CERT_ID_V2_push(sc
->cert_ids
, cid
))
132 ESS_SIGNING_CERT_V2_free(sc
);
133 ESS_CERT_ID_V2_free(cid
);
134 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
138 static ESS_CERT_ID_V2
*ESS_CERT_ID_V2_new_init(const EVP_MD
*hash_alg
,
139 X509
*cert
, int issuer_needed
)
142 GENERAL_NAME
*name
= NULL
;
143 unsigned char hash
[EVP_MAX_MD_SIZE
];
144 unsigned int hash_len
= sizeof(hash
);
145 X509_ALGOR
*alg
= NULL
;
147 memset(hash
, 0, sizeof(hash
));
149 if ((cid
= ESS_CERT_ID_V2_new()) == NULL
)
152 if (hash_alg
!= EVP_sha256()) {
153 alg
= X509_ALGOR_new();
156 X509_ALGOR_set_md(alg
, hash_alg
);
157 if (alg
->algorithm
== NULL
)
162 cid
->hash_alg
= NULL
;
165 /* TODO(3.0): fetch sha1 algorithm from providers */
166 if (!X509_digest(cert
, hash_alg
, hash
, &hash_len
))
169 if (!ASN1_OCTET_STRING_set(cid
->hash
, hash
, hash_len
))
175 if ((cid
->issuer_serial
= ESS_ISSUER_SERIAL_new()) == NULL
)
177 if ((name
= GENERAL_NAME_new()) == NULL
)
179 name
->type
= GEN_DIRNAME
;
180 if ((name
->d
.dirn
= X509_NAME_dup(X509_get_issuer_name(cert
))) == NULL
)
182 if (!sk_GENERAL_NAME_push(cid
->issuer_serial
->issuer
, name
))
184 name
= NULL
; /* Ownership is lost. */
185 ASN1_INTEGER_free(cid
->issuer_serial
->serial
);
186 cid
->issuer_serial
->serial
= ASN1_INTEGER_dup(X509_get0_serialNumber(cert
));
187 if (cid
->issuer_serial
->serial
== NULL
)
192 X509_ALGOR_free(alg
);
193 GENERAL_NAME_free(name
);
194 ESS_CERT_ID_V2_free(cid
);
195 ESSerr(ESS_F_ESS_CERT_ID_V2_NEW_INIT
, ERR_R_MALLOC_FAILURE
);
199 ESS_SIGNING_CERT
*ESS_SIGNING_CERT_get(PKCS7_SIGNER_INFO
*si
)
202 const unsigned char *p
;
204 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificate
);
207 p
= attr
->value
.sequence
->data
;
208 return d2i_ESS_SIGNING_CERT(NULL
, &p
, attr
->value
.sequence
->length
);
211 ESS_SIGNING_CERT_V2
*ESS_SIGNING_CERT_V2_get(PKCS7_SIGNER_INFO
*si
)
214 const unsigned char *p
;
216 attr
= PKCS7_get_signed_attribute(si
, NID_id_smime_aa_signingCertificateV2
);
219 p
= attr
->value
.sequence
->data
;
220 return d2i_ESS_SIGNING_CERT_V2(NULL
, &p
, attr
->value
.sequence
->length
);
223 int ESS_SIGNING_CERT_add(PKCS7_SIGNER_INFO
*si
, ESS_SIGNING_CERT
*sc
)
225 ASN1_STRING
*seq
= NULL
;
226 unsigned char *p
, *pp
= NULL
;
229 len
= i2d_ESS_SIGNING_CERT(sc
, NULL
);
230 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
231 ESSerr(ESS_F_ESS_SIGNING_CERT_ADD
, ERR_R_MALLOC_FAILURE
);
235 i2d_ESS_SIGNING_CERT(sc
, &p
);
236 if ((seq
= ASN1_STRING_new()) == NULL
|| !ASN1_STRING_set(seq
, pp
, len
)) {
237 ESSerr(ESS_F_ESS_SIGNING_CERT_ADD
, ERR_R_MALLOC_FAILURE
);
242 return PKCS7_add_signed_attribute(si
,
243 NID_id_smime_aa_signingCertificate
,
244 V_ASN1_SEQUENCE
, seq
);
246 ASN1_STRING_free(seq
);
252 int ESS_SIGNING_CERT_V2_add(PKCS7_SIGNER_INFO
*si
,
253 ESS_SIGNING_CERT_V2
*sc
)
255 ASN1_STRING
*seq
= NULL
;
256 unsigned char *p
, *pp
= NULL
;
257 int len
= i2d_ESS_SIGNING_CERT_V2(sc
, NULL
);
259 if ((pp
= OPENSSL_malloc(len
)) == NULL
) {
260 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_ADD
, 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 ESSerr(ESS_F_ESS_SIGNING_CERT_V2_ADD
, 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
));
297 /* Returns < 0 if certificate is not found, certificate index otherwise. */
298 int ess_find_cert(const STACK_OF(ESS_CERT_ID
) *cert_ids
, X509
*cert
)
301 unsigned char cert_sha1
[SHA_DIGEST_LENGTH
];
303 if (cert_ids
== NULL
|| cert
== NULL
)
306 /* Recompute SHA1 hash of certificate if necessary (side effect). */
307 if (!X509v3_cache_extensions(cert
, NULL
, NULL
))
310 /* TODO(3.0): fetch sha1 algorithm from providers */
311 if (!X509_digest(cert
, EVP_sha1(), cert_sha1
, NULL
))
314 /* Look for cert in the cert_ids vector. */
315 for (i
= 0; i
< sk_ESS_CERT_ID_num(cert_ids
); ++i
) {
316 const ESS_CERT_ID
*cid
= sk_ESS_CERT_ID_value(cert_ids
, i
);
318 if (cid
->hash
->length
== SHA_DIGEST_LENGTH
319 && memcmp(cid
->hash
->data
, cert_sha1
, SHA_DIGEST_LENGTH
) == 0) {
320 const ESS_ISSUER_SERIAL
*is
= cid
->issuer_serial
;
322 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0)
330 /* Returns < 0 if certificate is not found, certificate index otherwise. */
331 int ess_find_cert_v2(const STACK_OF(ESS_CERT_ID_V2
) *cert_ids
, const X509
*cert
)
334 unsigned char cert_digest
[EVP_MAX_MD_SIZE
];
337 /* Look for cert in the cert_ids vector. */
338 for (i
= 0; i
< sk_ESS_CERT_ID_V2_num(cert_ids
); ++i
) {
339 const ESS_CERT_ID_V2
*cid
= sk_ESS_CERT_ID_V2_value(cert_ids
, i
);
344 if (cid
->hash_alg
!= NULL
)
345 md
= EVP_get_digestbyobj(cid
->hash_alg
->algorithm
);
349 /* TODO(3.0): fetch sha1 algorithm from providers */
350 if (!X509_digest(cert
, md
, cert_digest
, &len
))
353 if (cid
->hash
->length
!= (int)len
)
356 if (memcmp(cid
->hash
->data
, cert_digest
, cid
->hash
->length
) == 0) {
357 const ESS_ISSUER_SERIAL
*is
= cid
->issuer_serial
;
359 if (is
== NULL
|| ess_issuer_serial_cmp(is
, cert
) == 0)