2 * Copyright 1995-2023 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 "internal/cryptlib.h"
12 #include <openssl/objects.h>
13 #include <openssl/x509.h>
14 #include <openssl/pkcs7.h>
15 #include "crypto/asn1.h"
16 #include "crypto/evp.h"
17 #include "crypto/x509.h" /* for sk_X509_add1_cert() */
18 #include "pk7_local.h"
20 long PKCS7_ctrl(PKCS7
*p7
, int cmd
, long larg
, char *parg
)
25 nid
= OBJ_obj2nid(p7
->type
);
28 /* NOTE(emilia): does not support detached digested data. */
29 case PKCS7_OP_SET_DETACHED_SIGNATURE
:
30 if (nid
== NID_pkcs7_signed
) {
31 ret
= p7
->detached
= (int)larg
;
32 if (ret
&& PKCS7_type_is_data(p7
->d
.sign
->contents
)) {
33 ASN1_OCTET_STRING
*os
;
34 os
= p7
->d
.sign
->contents
->d
.data
;
35 ASN1_OCTET_STRING_free(os
);
36 p7
->d
.sign
->contents
->d
.data
= NULL
;
39 ERR_raise(ERR_LIB_PKCS7
,
40 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE
);
44 case PKCS7_OP_GET_DETACHED_SIGNATURE
:
45 if (nid
== NID_pkcs7_signed
) {
46 if (p7
->d
.sign
== NULL
|| p7
->d
.sign
->contents
->d
.ptr
== NULL
)
53 ERR_raise(ERR_LIB_PKCS7
,
54 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE
);
60 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_UNKNOWN_OPERATION
);
66 int PKCS7_content_new(PKCS7
*p7
, int type
)
70 if ((ret
= PKCS7_new()) == NULL
)
72 if (!PKCS7_set_type(ret
, type
))
74 if (!PKCS7_set_content(p7
, ret
))
83 int PKCS7_set_content(PKCS7
*p7
, PKCS7
*p7_data
)
87 i
= OBJ_obj2nid(p7
->type
);
89 case NID_pkcs7_signed
:
90 PKCS7_free(p7
->d
.sign
->contents
);
91 p7
->d
.sign
->contents
= p7_data
;
93 case NID_pkcs7_digest
:
94 PKCS7_free(p7
->d
.digest
->contents
);
95 p7
->d
.digest
->contents
= p7_data
;
98 case NID_pkcs7_enveloped
:
99 case NID_pkcs7_signedAndEnveloped
:
100 case NID_pkcs7_encrypted
:
102 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_UNSUPPORTED_CONTENT_TYPE
);
110 int PKCS7_set_type(PKCS7
*p7
, int type
)
115 * PKCS7_content_free(p7);
117 obj
= OBJ_nid2obj(type
); /* will not fail */
120 case NID_pkcs7_signed
:
122 if ((p7
->d
.sign
= PKCS7_SIGNED_new()) == NULL
)
124 if (!ASN1_INTEGER_set(p7
->d
.sign
->version
, 1)) {
125 PKCS7_SIGNED_free(p7
->d
.sign
);
132 if ((p7
->d
.data
= ASN1_OCTET_STRING_new()) == NULL
)
135 case NID_pkcs7_signedAndEnveloped
:
137 if ((p7
->d
.signed_and_enveloped
= PKCS7_SIGN_ENVELOPE_new())
140 if (!ASN1_INTEGER_set(p7
->d
.signed_and_enveloped
->version
, 1))
142 p7
->d
.signed_and_enveloped
->enc_data
->content_type
143 = OBJ_nid2obj(NID_pkcs7_data
);
145 case NID_pkcs7_enveloped
:
147 if ((p7
->d
.enveloped
= PKCS7_ENVELOPE_new())
150 if (!ASN1_INTEGER_set(p7
->d
.enveloped
->version
, 0))
152 p7
->d
.enveloped
->enc_data
->content_type
= OBJ_nid2obj(NID_pkcs7_data
);
154 case NID_pkcs7_encrypted
:
156 if ((p7
->d
.encrypted
= PKCS7_ENCRYPT_new())
159 if (!ASN1_INTEGER_set(p7
->d
.encrypted
->version
, 0))
161 p7
->d
.encrypted
->enc_data
->content_type
= OBJ_nid2obj(NID_pkcs7_data
);
164 case NID_pkcs7_digest
:
166 if ((p7
->d
.digest
= PKCS7_DIGEST_new())
169 if (!ASN1_INTEGER_set(p7
->d
.digest
->version
, 0))
173 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_UNSUPPORTED_CONTENT_TYPE
);
181 int PKCS7_set0_type_other(PKCS7
*p7
, int type
, ASN1_TYPE
*other
)
183 p7
->type
= OBJ_nid2obj(type
);
188 int PKCS7_add_signer(PKCS7
*p7
, PKCS7_SIGNER_INFO
*psi
)
193 STACK_OF(PKCS7_SIGNER_INFO
) *signer_sk
;
194 STACK_OF(X509_ALGOR
) *md_sk
;
196 i
= OBJ_obj2nid(p7
->type
);
198 case NID_pkcs7_signed
:
199 signer_sk
= p7
->d
.sign
->signer_info
;
200 md_sk
= p7
->d
.sign
->md_algs
;
202 case NID_pkcs7_signedAndEnveloped
:
203 signer_sk
= p7
->d
.signed_and_enveloped
->signer_info
;
204 md_sk
= p7
->d
.signed_and_enveloped
->md_algs
;
207 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
211 obj
= psi
->digest_alg
->algorithm
;
212 /* If the digest is not currently listed, add it */
214 for (i
= 0; i
< sk_X509_ALGOR_num(md_sk
); i
++) {
215 alg
= sk_X509_ALGOR_value(md_sk
, i
);
216 if (OBJ_cmp(obj
, alg
->algorithm
) == 0) {
221 if (!j
) { /* we need to add another algorithm */
224 if ((alg
= X509_ALGOR_new()) == NULL
225 || (alg
->parameter
= ASN1_TYPE_new()) == NULL
) {
226 X509_ALGOR_free(alg
);
227 ERR_raise(ERR_LIB_PKCS7
, ERR_R_ASN1_LIB
);
231 * If there is a constant copy of the ASN1 OBJECT in libcrypto, then
232 * use that. Otherwise, use a dynamically duplicated copy
234 if ((nid
= OBJ_obj2nid(obj
)) != NID_undef
)
235 alg
->algorithm
= OBJ_nid2obj(nid
);
237 alg
->algorithm
= OBJ_dup(obj
);
238 alg
->parameter
->type
= V_ASN1_NULL
;
239 if (alg
->algorithm
== NULL
|| !sk_X509_ALGOR_push(md_sk
, alg
)) {
240 X509_ALGOR_free(alg
);
245 psi
->ctx
= ossl_pkcs7_get0_ctx(p7
);
246 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk
, psi
))
251 int PKCS7_add_certificate(PKCS7
*p7
, X509
*x509
)
256 i
= OBJ_obj2nid(p7
->type
);
258 case NID_pkcs7_signed
:
259 sk
= &(p7
->d
.sign
->cert
);
261 case NID_pkcs7_signedAndEnveloped
:
262 sk
= &(p7
->d
.signed_and_enveloped
->cert
);
265 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
269 return ossl_x509_add_cert_new(sk
, x509
, X509_ADD_FLAG_UP_REF
);
272 int PKCS7_add_crl(PKCS7
*p7
, X509_CRL
*crl
)
275 STACK_OF(X509_CRL
) **sk
;
277 i
= OBJ_obj2nid(p7
->type
);
279 case NID_pkcs7_signed
:
280 sk
= &(p7
->d
.sign
->crl
);
282 case NID_pkcs7_signedAndEnveloped
:
283 sk
= &(p7
->d
.signed_and_enveloped
->crl
);
286 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
291 *sk
= sk_X509_CRL_new_null();
293 ERR_raise(ERR_LIB_PKCS7
, ERR_R_CRYPTO_LIB
);
297 X509_CRL_up_ref(crl
);
298 if (!sk_X509_CRL_push(*sk
, crl
)) {
305 static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO
*si
,
310 X509_ALGOR
*alg1
, *alg2
;
311 EVP_PKEY
*pkey
= si
->pkey
;
313 PKCS7_SIGNER_INFO_get0_algs(si
, NULL
, &alg1
, &alg2
);
314 if (alg1
== NULL
|| alg1
->algorithm
== NULL
)
316 hnid
= OBJ_obj2nid(alg1
->algorithm
);
317 if (hnid
== NID_undef
)
319 if (!OBJ_find_sigid_by_algs(&snid
, hnid
, EVP_PKEY_get_id(pkey
)))
321 return X509_ALGOR_set0(alg2
, OBJ_nid2obj(snid
), V_ASN1_UNDEF
, NULL
);
326 static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO
*si
, int verify
)
329 X509_ALGOR
*alg
= NULL
;
331 PKCS7_SIGNER_INFO_get0_algs(si
, NULL
, NULL
, &alg
);
333 return X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaEncryption
),
339 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO
*p7i
, X509
*x509
, EVP_PKEY
*pkey
,
344 /* We now need to add another PKCS7_SIGNER_INFO entry */
345 if (!ASN1_INTEGER_set(p7i
->version
, 1))
347 if (!X509_NAME_set(&p7i
->issuer_and_serial
->issuer
,
348 X509_get_issuer_name(x509
)))
352 * because ASN1_INTEGER_set is used to set a 'long' we will do things the
355 ASN1_INTEGER_free(p7i
->issuer_and_serial
->serial
);
356 if (!(p7i
->issuer_and_serial
->serial
=
357 ASN1_INTEGER_dup(X509_get0_serialNumber(x509
))))
360 /* lets keep the pkey around for a while */
361 EVP_PKEY_up_ref(pkey
);
364 /* Set the algorithms */
366 if (!X509_ALGOR_set0(p7i
->digest_alg
, OBJ_nid2obj(EVP_MD_get_type(dgst
)),
370 if (EVP_PKEY_is_a(pkey
, "EC") || EVP_PKEY_is_a(pkey
, "DSA"))
371 return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i
, 0);
372 if (EVP_PKEY_is_a(pkey
, "RSA"))
373 return pkcs7_rsa_sign_verify_setup(p7i
, 0);
375 if (pkey
->ameth
!= NULL
&& pkey
->ameth
->pkey_ctrl
!= NULL
) {
376 ret
= pkey
->ameth
->pkey_ctrl(pkey
, ASN1_PKEY_CTRL_PKCS7_SIGN
, 0, p7i
);
380 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_SIGNING_CTRL_FAILURE
);
384 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
388 PKCS7_SIGNER_INFO
*PKCS7_add_signature(PKCS7
*p7
, X509
*x509
, EVP_PKEY
*pkey
,
391 PKCS7_SIGNER_INFO
*si
= NULL
;
395 if (EVP_PKEY_get_default_digest_nid(pkey
, &def_nid
) <= 0)
397 dgst
= EVP_get_digestbynid(def_nid
);
399 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_NO_DEFAULT_DIGEST
);
404 if ((si
= PKCS7_SIGNER_INFO_new()) == NULL
)
406 if (PKCS7_SIGNER_INFO_set(si
, x509
, pkey
, dgst
) <= 0)
408 if (!PKCS7_add_signer(p7
, si
))
412 PKCS7_SIGNER_INFO_free(si
);
416 static STACK_OF(X509
) *pkcs7_get_signer_certs(const PKCS7
*p7
)
418 if (p7
->d
.ptr
== NULL
)
420 if (PKCS7_type_is_signed(p7
))
421 return p7
->d
.sign
->cert
;
422 if (PKCS7_type_is_signedAndEnveloped(p7
))
423 return p7
->d
.signed_and_enveloped
->cert
;
427 static STACK_OF(PKCS7_RECIP_INFO
) *pkcs7_get_recipient_info(const PKCS7
*p7
)
429 if (p7
->d
.ptr
== NULL
)
431 if (PKCS7_type_is_signedAndEnveloped(p7
))
432 return p7
->d
.signed_and_enveloped
->recipientinfo
;
433 if (PKCS7_type_is_enveloped(p7
))
434 return p7
->d
.enveloped
->recipientinfo
;
439 * Set up the library context into any loaded structure that needs it.
440 * i.e loaded X509 objects.
442 void ossl_pkcs7_resolve_libctx(PKCS7
*p7
)
445 const PKCS7_CTX
*ctx
= ossl_pkcs7_get0_ctx(p7
);
446 OSSL_LIB_CTX
*libctx
= ossl_pkcs7_ctx_get0_libctx(ctx
);
447 const char *propq
= ossl_pkcs7_ctx_get0_propq(ctx
);
448 STACK_OF(PKCS7_RECIP_INFO
) *rinfos
;
449 STACK_OF(PKCS7_SIGNER_INFO
) *sinfos
;
450 STACK_OF(X509
) *certs
;
452 if (ctx
== NULL
|| p7
->d
.ptr
== NULL
)
455 rinfos
= pkcs7_get_recipient_info(p7
);
456 sinfos
= PKCS7_get_signer_info(p7
);
457 certs
= pkcs7_get_signer_certs(p7
);
459 for (i
= 0; i
< sk_X509_num(certs
); i
++)
460 ossl_x509_set0_libctx(sk_X509_value(certs
, i
), libctx
, propq
);
462 for (i
= 0; i
< sk_PKCS7_RECIP_INFO_num(rinfos
); i
++) {
463 PKCS7_RECIP_INFO
*ri
= sk_PKCS7_RECIP_INFO_value(rinfos
, i
);
465 ossl_x509_set0_libctx(ri
->cert
, libctx
, propq
);
468 for (i
= 0; i
< sk_PKCS7_SIGNER_INFO_num(sinfos
); i
++) {
469 PKCS7_SIGNER_INFO
*si
= sk_PKCS7_SIGNER_INFO_value(sinfos
, i
);
476 const PKCS7_CTX
*ossl_pkcs7_get0_ctx(const PKCS7
*p7
)
478 return p7
!= NULL
? &p7
->ctx
: NULL
;
481 void ossl_pkcs7_set0_libctx(PKCS7
*p7
, OSSL_LIB_CTX
*ctx
)
483 p7
->ctx
.libctx
= ctx
;
486 int ossl_pkcs7_set1_propq(PKCS7
*p7
, const char *propq
)
488 if (p7
->ctx
.propq
!= NULL
) {
489 OPENSSL_free(p7
->ctx
.propq
);
490 p7
->ctx
.propq
= NULL
;
493 p7
->ctx
.propq
= OPENSSL_strdup(propq
);
494 if (p7
->ctx
.propq
== NULL
)
500 int ossl_pkcs7_ctx_propagate(const PKCS7
*from
, PKCS7
*to
)
502 ossl_pkcs7_set0_libctx(to
, from
->ctx
.libctx
);
503 if (!ossl_pkcs7_set1_propq(to
, from
->ctx
.propq
))
506 ossl_pkcs7_resolve_libctx(to
);
510 OSSL_LIB_CTX
*ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX
*ctx
)
512 return ctx
!= NULL
? ctx
->libctx
: NULL
;
514 const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX
*ctx
)
516 return ctx
!= NULL
? ctx
->propq
: NULL
;
519 int PKCS7_set_digest(PKCS7
*p7
, const EVP_MD
*md
)
521 if (PKCS7_type_is_digest(p7
)) {
522 if ((p7
->d
.digest
->md
->parameter
= ASN1_TYPE_new()) == NULL
) {
523 ERR_raise(ERR_LIB_PKCS7
, ERR_R_ASN1_LIB
);
526 p7
->d
.digest
->md
->parameter
->type
= V_ASN1_NULL
;
527 p7
->d
.digest
->md
->algorithm
= OBJ_nid2obj(EVP_MD_nid(md
));
531 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
535 STACK_OF(PKCS7_SIGNER_INFO
) *PKCS7_get_signer_info(PKCS7
*p7
)
537 if (p7
== NULL
|| p7
->d
.ptr
== NULL
)
539 if (PKCS7_type_is_signed(p7
)) {
540 return p7
->d
.sign
->signer_info
;
541 } else if (PKCS7_type_is_signedAndEnveloped(p7
)) {
542 return p7
->d
.signed_and_enveloped
->signer_info
;
547 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO
*si
, EVP_PKEY
**pk
,
548 X509_ALGOR
**pdig
, X509_ALGOR
**psig
)
553 *pdig
= si
->digest_alg
;
555 *psig
= si
->digest_enc_alg
;
558 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO
*ri
, X509_ALGOR
**penc
)
561 *penc
= ri
->key_enc_algor
;
564 PKCS7_RECIP_INFO
*PKCS7_add_recipient(PKCS7
*p7
, X509
*x509
)
566 PKCS7_RECIP_INFO
*ri
;
568 if ((ri
= PKCS7_RECIP_INFO_new()) == NULL
)
570 if (PKCS7_RECIP_INFO_set(ri
, x509
) <= 0)
572 if (!PKCS7_add_recipient_info(p7
, ri
))
574 ri
->ctx
= ossl_pkcs7_get0_ctx(p7
);
577 PKCS7_RECIP_INFO_free(ri
);
581 int PKCS7_add_recipient_info(PKCS7
*p7
, PKCS7_RECIP_INFO
*ri
)
584 STACK_OF(PKCS7_RECIP_INFO
) *sk
;
586 i
= OBJ_obj2nid(p7
->type
);
588 case NID_pkcs7_signedAndEnveloped
:
589 sk
= p7
->d
.signed_and_enveloped
->recipientinfo
;
591 case NID_pkcs7_enveloped
:
592 sk
= p7
->d
.enveloped
->recipientinfo
;
595 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
599 if (!sk_PKCS7_RECIP_INFO_push(sk
, ri
))
604 static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO
*ri
, int decrypt
)
606 X509_ALGOR
*alg
= NULL
;
609 PKCS7_RECIP_INFO_get0_alg(ri
, &alg
);
611 return X509_ALGOR_set0(alg
, OBJ_nid2obj(NID_rsaEncryption
),
617 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO
*p7i
, X509
*x509
)
620 EVP_PKEY
*pkey
= NULL
;
621 if (!ASN1_INTEGER_set(p7i
->version
, 0))
623 if (!X509_NAME_set(&p7i
->issuer_and_serial
->issuer
,
624 X509_get_issuer_name(x509
)))
627 ASN1_INTEGER_free(p7i
->issuer_and_serial
->serial
);
628 if (!(p7i
->issuer_and_serial
->serial
=
629 ASN1_INTEGER_dup(X509_get0_serialNumber(x509
))))
632 pkey
= X509_get0_pubkey(x509
);
636 if (EVP_PKEY_is_a(pkey
, "RSA-PSS"))
638 if (EVP_PKEY_is_a(pkey
, "RSA")) {
639 if (pkcs7_rsa_encrypt_decrypt_setup(p7i
, 0) <= 0)
644 if (pkey
->ameth
== NULL
|| pkey
->ameth
->pkey_ctrl
== NULL
) {
645 ERR_raise(ERR_LIB_PKCS7
,
646 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
650 ret
= pkey
->ameth
->pkey_ctrl(pkey
, ASN1_PKEY_CTRL_PKCS7_ENCRYPT
, 0, p7i
);
652 ERR_raise(ERR_LIB_PKCS7
,
653 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
657 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_ENCRYPTION_CTRL_FAILURE
);
670 X509
*PKCS7_cert_from_signer_info(PKCS7
*p7
, PKCS7_SIGNER_INFO
*si
)
672 if (PKCS7_type_is_signed(p7
))
673 return (X509_find_by_issuer_and_serial(p7
->d
.sign
->cert
,
674 si
->issuer_and_serial
->issuer
,
676 issuer_and_serial
->serial
));
681 int PKCS7_set_cipher(PKCS7
*p7
, const EVP_CIPHER
*cipher
)
684 PKCS7_ENC_CONTENT
*ec
;
686 i
= OBJ_obj2nid(p7
->type
);
688 case NID_pkcs7_signedAndEnveloped
:
689 ec
= p7
->d
.signed_and_enveloped
->enc_data
;
691 case NID_pkcs7_enveloped
:
692 ec
= p7
->d
.enveloped
->enc_data
;
695 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
699 /* Check cipher OID exists and has data in it */
700 i
= EVP_CIPHER_get_type(cipher
);
701 if (i
== NID_undef
) {
702 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
);
707 ec
->ctx
= ossl_pkcs7_get0_ctx(p7
);
711 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
712 int PKCS7_stream(unsigned char ***boundary
, PKCS7
*p7
)
714 ASN1_OCTET_STRING
*os
= NULL
;
716 switch (OBJ_obj2nid(p7
->type
)) {
721 case NID_pkcs7_signedAndEnveloped
:
722 os
= p7
->d
.signed_and_enveloped
->enc_data
->enc_data
;
724 os
= ASN1_OCTET_STRING_new();
725 p7
->d
.signed_and_enveloped
->enc_data
->enc_data
= os
;
729 case NID_pkcs7_enveloped
:
730 os
= p7
->d
.enveloped
->enc_data
->enc_data
;
732 os
= ASN1_OCTET_STRING_new();
733 p7
->d
.enveloped
->enc_data
->enc_data
= os
;
737 case NID_pkcs7_signed
:
738 os
= p7
->d
.sign
->contents
->d
.data
;
749 os
->flags
|= ASN1_STRING_FLAG_NDEF
;
750 *boundary
= &os
->data
;