2 * Copyright 1995-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 "internal/cryptlib.h"
12 #include <openssl/objects.h>
13 #include <openssl/x509.h>
14 #include "crypto/asn1.h"
15 #include "crypto/evp.h"
16 #include "crypto/x509.h" /* for sk_X509_add1_cert() */
17 #include "pk7_local.h"
19 long PKCS7_ctrl(PKCS7
*p7
, int cmd
, long larg
, char *parg
)
24 nid
= OBJ_obj2nid(p7
->type
);
27 /* NOTE(emilia): does not support detached digested data. */
28 case PKCS7_OP_SET_DETACHED_SIGNATURE
:
29 if (nid
== NID_pkcs7_signed
) {
30 ret
= p7
->detached
= (int)larg
;
31 if (ret
&& PKCS7_type_is_data(p7
->d
.sign
->contents
)) {
32 ASN1_OCTET_STRING
*os
;
33 os
= p7
->d
.sign
->contents
->d
.data
;
34 ASN1_OCTET_STRING_free(os
);
35 p7
->d
.sign
->contents
->d
.data
= NULL
;
38 ERR_raise(ERR_LIB_PKCS7
,
39 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE
);
43 case PKCS7_OP_GET_DETACHED_SIGNATURE
:
44 if (nid
== NID_pkcs7_signed
) {
45 if (p7
->d
.sign
== NULL
|| p7
->d
.sign
->contents
->d
.ptr
== NULL
)
52 ERR_raise(ERR_LIB_PKCS7
,
53 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE
);
59 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_UNKNOWN_OPERATION
);
65 int PKCS7_content_new(PKCS7
*p7
, int type
)
69 if ((ret
= PKCS7_new()) == NULL
)
71 if (!PKCS7_set_type(ret
, type
))
73 if (!PKCS7_set_content(p7
, ret
))
82 int PKCS7_set_content(PKCS7
*p7
, PKCS7
*p7_data
)
86 i
= OBJ_obj2nid(p7
->type
);
88 case NID_pkcs7_signed
:
89 PKCS7_free(p7
->d
.sign
->contents
);
90 p7
->d
.sign
->contents
= p7_data
;
92 case NID_pkcs7_digest
:
93 PKCS7_free(p7
->d
.digest
->contents
);
94 p7
->d
.digest
->contents
= p7_data
;
97 case NID_pkcs7_enveloped
:
98 case NID_pkcs7_signedAndEnveloped
:
99 case NID_pkcs7_encrypted
:
101 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_UNSUPPORTED_CONTENT_TYPE
);
109 int PKCS7_set_type(PKCS7
*p7
, int type
)
114 * PKCS7_content_free(p7);
116 obj
= OBJ_nid2obj(type
); /* will not fail */
119 case NID_pkcs7_signed
:
121 if ((p7
->d
.sign
= PKCS7_SIGNED_new()) == NULL
)
123 if (!ASN1_INTEGER_set(p7
->d
.sign
->version
, 1)) {
124 PKCS7_SIGNED_free(p7
->d
.sign
);
131 if ((p7
->d
.data
= ASN1_OCTET_STRING_new()) == NULL
)
134 case NID_pkcs7_signedAndEnveloped
:
136 if ((p7
->d
.signed_and_enveloped
= PKCS7_SIGN_ENVELOPE_new())
139 if (!ASN1_INTEGER_set(p7
->d
.signed_and_enveloped
->version
, 1))
141 p7
->d
.signed_and_enveloped
->enc_data
->content_type
142 = OBJ_nid2obj(NID_pkcs7_data
);
144 case NID_pkcs7_enveloped
:
146 if ((p7
->d
.enveloped
= PKCS7_ENVELOPE_new())
149 if (!ASN1_INTEGER_set(p7
->d
.enveloped
->version
, 0))
151 p7
->d
.enveloped
->enc_data
->content_type
= OBJ_nid2obj(NID_pkcs7_data
);
153 case NID_pkcs7_encrypted
:
155 if ((p7
->d
.encrypted
= PKCS7_ENCRYPT_new())
158 if (!ASN1_INTEGER_set(p7
->d
.encrypted
->version
, 0))
160 p7
->d
.encrypted
->enc_data
->content_type
= OBJ_nid2obj(NID_pkcs7_data
);
163 case NID_pkcs7_digest
:
165 if ((p7
->d
.digest
= PKCS7_DIGEST_new())
168 if (!ASN1_INTEGER_set(p7
->d
.digest
->version
, 0))
172 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_UNSUPPORTED_CONTENT_TYPE
);
180 int PKCS7_set0_type_other(PKCS7
*p7
, int type
, ASN1_TYPE
*other
)
182 p7
->type
= OBJ_nid2obj(type
);
187 int PKCS7_add_signer(PKCS7
*p7
, PKCS7_SIGNER_INFO
*psi
)
191 STACK_OF(PKCS7_SIGNER_INFO
) *signer_sk
;
192 STACK_OF(X509_ALGOR
) *md_sk
;
194 i
= OBJ_obj2nid(p7
->type
);
196 case NID_pkcs7_signed
:
197 signer_sk
= p7
->d
.sign
->signer_info
;
198 md_sk
= p7
->d
.sign
->md_algs
;
200 case NID_pkcs7_signedAndEnveloped
:
201 signer_sk
= p7
->d
.signed_and_enveloped
->signer_info
;
202 md_sk
= p7
->d
.signed_and_enveloped
->md_algs
;
205 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
209 nid
= OBJ_obj2nid(psi
->digest_alg
->algorithm
);
211 /* If the digest is not currently listed, add it */
213 for (i
= 0; i
< sk_X509_ALGOR_num(md_sk
); i
++) {
214 alg
= sk_X509_ALGOR_value(md_sk
, i
);
215 if (OBJ_obj2nid(alg
->algorithm
) == nid
) {
220 if (!j
) { /* we need to add another algorithm */
221 if ((alg
= X509_ALGOR_new()) == NULL
222 || (alg
->parameter
= ASN1_TYPE_new()) == NULL
) {
223 X509_ALGOR_free(alg
);
224 ERR_raise(ERR_LIB_PKCS7
, ERR_R_MALLOC_FAILURE
);
227 alg
->algorithm
= OBJ_nid2obj(nid
);
228 alg
->parameter
->type
= V_ASN1_NULL
;
229 if (!sk_X509_ALGOR_push(md_sk
, alg
)) {
230 X509_ALGOR_free(alg
);
235 psi
->ctx
= pkcs7_get0_ctx(p7
);
236 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk
, psi
))
241 int PKCS7_add_certificate(PKCS7
*p7
, X509
*x509
)
246 i
= OBJ_obj2nid(p7
->type
);
248 case NID_pkcs7_signed
:
249 sk
= &(p7
->d
.sign
->cert
);
251 case NID_pkcs7_signedAndEnveloped
:
252 sk
= &(p7
->d
.signed_and_enveloped
->cert
);
255 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
259 return X509_add_cert_new(sk
, x509
, X509_ADD_FLAG_UP_REF
);
262 int PKCS7_add_crl(PKCS7
*p7
, X509_CRL
*crl
)
265 STACK_OF(X509_CRL
) **sk
;
267 i
= OBJ_obj2nid(p7
->type
);
269 case NID_pkcs7_signed
:
270 sk
= &(p7
->d
.sign
->crl
);
272 case NID_pkcs7_signedAndEnveloped
:
273 sk
= &(p7
->d
.signed_and_enveloped
->crl
);
276 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
281 *sk
= sk_X509_CRL_new_null();
283 ERR_raise(ERR_LIB_PKCS7
, ERR_R_MALLOC_FAILURE
);
287 X509_CRL_up_ref(crl
);
288 if (!sk_X509_CRL_push(*sk
, crl
)) {
295 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO
*p7i
, X509
*x509
, EVP_PKEY
*pkey
,
300 /* We now need to add another PKCS7_SIGNER_INFO entry */
301 if (!ASN1_INTEGER_set(p7i
->version
, 1))
303 if (!X509_NAME_set(&p7i
->issuer_and_serial
->issuer
,
304 X509_get_issuer_name(x509
)))
308 * because ASN1_INTEGER_set is used to set a 'long' we will do things the
311 ASN1_INTEGER_free(p7i
->issuer_and_serial
->serial
);
312 if (!(p7i
->issuer_and_serial
->serial
=
313 ASN1_INTEGER_dup(X509_get0_serialNumber(x509
))))
317 * TODO(3.0) Adapt for provider-native keys
318 * Meanwhile, we downgrade the key.
321 if (!evp_pkey_downgrade(pkey
)) {
322 ERR_raise(ERR_LIB_PKCS7
,
323 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
327 /* lets keep the pkey around for a while */
328 EVP_PKEY_up_ref(pkey
);
331 /* Set the algorithms */
333 X509_ALGOR_set0(p7i
->digest_alg
, OBJ_nid2obj(EVP_MD_type(dgst
)),
336 if (pkey
->ameth
&& pkey
->ameth
->pkey_ctrl
) {
337 ret
= pkey
->ameth
->pkey_ctrl(pkey
, ASN1_PKEY_CTRL_PKCS7_SIGN
, 0, p7i
);
341 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_SIGNING_CTRL_FAILURE
);
345 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
350 PKCS7_SIGNER_INFO
*PKCS7_add_signature(PKCS7
*p7
, X509
*x509
, EVP_PKEY
*pkey
,
353 PKCS7_SIGNER_INFO
*si
= NULL
;
357 if (EVP_PKEY_get_default_digest_nid(pkey
, &def_nid
) <= 0)
359 dgst
= EVP_get_digestbynid(def_nid
);
361 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_NO_DEFAULT_DIGEST
);
366 if ((si
= PKCS7_SIGNER_INFO_new()) == NULL
)
368 if (!PKCS7_SIGNER_INFO_set(si
, x509
, pkey
, dgst
))
370 if (!PKCS7_add_signer(p7
, si
))
374 PKCS7_SIGNER_INFO_free(si
);
378 static STACK_OF(X509
) *pkcs7_get_signer_certs(const PKCS7
*p7
)
380 if (PKCS7_type_is_signed(p7
))
381 return p7
->d
.sign
->cert
;
382 if (PKCS7_type_is_signedAndEnveloped(p7
))
383 return p7
->d
.signed_and_enveloped
->cert
;
387 static STACK_OF(PKCS7_RECIP_INFO
) *pkcs7_get_recipient_info(const PKCS7
*p7
)
389 if (PKCS7_type_is_signedAndEnveloped(p7
))
390 return p7
->d
.signed_and_enveloped
->recipientinfo
;
391 if (PKCS7_type_is_enveloped(p7
))
392 return p7
->d
.enveloped
->recipientinfo
;
397 * Set up the library context into any loaded structure that needs it.
398 * i.e loaded X509 objects.
400 void pkcs7_resolve_libctx(PKCS7
*p7
)
403 const PKCS7_CTX
*ctx
= pkcs7_get0_ctx(p7
);
404 OSSL_LIB_CTX
*libctx
= pkcs7_ctx_get0_libctx(ctx
);
405 const char *propq
= pkcs7_ctx_get0_propq(ctx
);
406 STACK_OF(PKCS7_RECIP_INFO
) *rinfos
= pkcs7_get_recipient_info(p7
);
407 STACK_OF(PKCS7_SIGNER_INFO
) *sinfos
= PKCS7_get_signer_info(p7
);
408 STACK_OF(X509
) *certs
= pkcs7_get_signer_certs(p7
);
413 for (i
= 0; i
< sk_X509_num(certs
); i
++)
414 x509_set0_libctx(sk_X509_value(certs
, i
), libctx
, propq
);
416 for (i
= 0; i
< sk_PKCS7_RECIP_INFO_num(rinfos
); i
++) {
417 PKCS7_RECIP_INFO
*ri
= sk_PKCS7_RECIP_INFO_value(rinfos
, i
);
419 x509_set0_libctx(ri
->cert
, libctx
, propq
);
422 for (i
= 0; i
< sk_PKCS7_SIGNER_INFO_num(sinfos
); i
++) {
423 PKCS7_SIGNER_INFO
*si
= sk_PKCS7_SIGNER_INFO_value(sinfos
, i
);
430 const PKCS7_CTX
*pkcs7_get0_ctx(const PKCS7
*p7
)
432 return p7
!= NULL
? &p7
->ctx
: NULL
;
435 OSSL_LIB_CTX
*pkcs7_ctx_get0_libctx(const PKCS7_CTX
*ctx
)
437 return ctx
!= NULL
? ctx
->libctx
: NULL
;
439 const char *pkcs7_ctx_get0_propq(const PKCS7_CTX
*ctx
)
441 return ctx
!= NULL
? ctx
->propq
: NULL
;
444 int PKCS7_set_digest(PKCS7
*p7
, const EVP_MD
*md
)
446 if (PKCS7_type_is_digest(p7
)) {
447 if ((p7
->d
.digest
->md
->parameter
= ASN1_TYPE_new()) == NULL
) {
448 ERR_raise(ERR_LIB_PKCS7
, ERR_R_MALLOC_FAILURE
);
451 p7
->d
.digest
->md
->parameter
->type
= V_ASN1_NULL
;
452 p7
->d
.digest
->md
->algorithm
= OBJ_nid2obj(EVP_MD_nid(md
));
456 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
460 STACK_OF(PKCS7_SIGNER_INFO
) *PKCS7_get_signer_info(PKCS7
*p7
)
462 if (p7
== NULL
|| p7
->d
.ptr
== NULL
)
464 if (PKCS7_type_is_signed(p7
)) {
465 return p7
->d
.sign
->signer_info
;
466 } else if (PKCS7_type_is_signedAndEnveloped(p7
)) {
467 return p7
->d
.signed_and_enveloped
->signer_info
;
472 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO
*si
, EVP_PKEY
**pk
,
473 X509_ALGOR
**pdig
, X509_ALGOR
**psig
)
478 *pdig
= si
->digest_alg
;
480 *psig
= si
->digest_enc_alg
;
483 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO
*ri
, X509_ALGOR
**penc
)
486 *penc
= ri
->key_enc_algor
;
489 PKCS7_RECIP_INFO
*PKCS7_add_recipient(PKCS7
*p7
, X509
*x509
)
491 PKCS7_RECIP_INFO
*ri
;
493 if ((ri
= PKCS7_RECIP_INFO_new()) == NULL
)
495 if (!PKCS7_RECIP_INFO_set(ri
, x509
))
497 if (!PKCS7_add_recipient_info(p7
, ri
))
499 ri
->ctx
= pkcs7_get0_ctx(p7
);
502 PKCS7_RECIP_INFO_free(ri
);
506 int PKCS7_add_recipient_info(PKCS7
*p7
, PKCS7_RECIP_INFO
*ri
)
509 STACK_OF(PKCS7_RECIP_INFO
) *sk
;
511 i
= OBJ_obj2nid(p7
->type
);
513 case NID_pkcs7_signedAndEnveloped
:
514 sk
= p7
->d
.signed_and_enveloped
->recipientinfo
;
516 case NID_pkcs7_enveloped
:
517 sk
= p7
->d
.enveloped
->recipientinfo
;
520 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
524 if (!sk_PKCS7_RECIP_INFO_push(sk
, ri
))
529 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO
*p7i
, X509
*x509
)
532 EVP_PKEY
*pkey
= NULL
;
533 if (!ASN1_INTEGER_set(p7i
->version
, 0))
535 if (!X509_NAME_set(&p7i
->issuer_and_serial
->issuer
,
536 X509_get_issuer_name(x509
)))
539 ASN1_INTEGER_free(p7i
->issuer_and_serial
->serial
);
540 if (!(p7i
->issuer_and_serial
->serial
=
541 ASN1_INTEGER_dup(X509_get0_serialNumber(x509
))))
544 pkey
= X509_get0_pubkey(x509
);
546 if (!pkey
|| !pkey
->ameth
|| !pkey
->ameth
->pkey_ctrl
) {
547 ERR_raise(ERR_LIB_PKCS7
,
548 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
552 ret
= pkey
->ameth
->pkey_ctrl(pkey
, ASN1_PKEY_CTRL_PKCS7_ENCRYPT
, 0, p7i
);
554 ERR_raise(ERR_LIB_PKCS7
,
555 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
559 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_ENCRYPTION_CTRL_FAILURE
);
572 X509
*PKCS7_cert_from_signer_info(PKCS7
*p7
, PKCS7_SIGNER_INFO
*si
)
574 if (PKCS7_type_is_signed(p7
))
575 return (X509_find_by_issuer_and_serial(p7
->d
.sign
->cert
,
576 si
->issuer_and_serial
->issuer
,
578 issuer_and_serial
->serial
));
583 int PKCS7_set_cipher(PKCS7
*p7
, const EVP_CIPHER
*cipher
)
586 PKCS7_ENC_CONTENT
*ec
;
588 i
= OBJ_obj2nid(p7
->type
);
590 case NID_pkcs7_signedAndEnveloped
:
591 ec
= p7
->d
.signed_and_enveloped
->enc_data
;
593 case NID_pkcs7_enveloped
:
594 ec
= p7
->d
.enveloped
->enc_data
;
597 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
601 /* Check cipher OID exists and has data in it */
602 i
= EVP_CIPHER_type(cipher
);
603 if (i
== NID_undef
) {
604 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
);
609 ec
->ctx
= pkcs7_get0_ctx(p7
);
613 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
614 int PKCS7_stream(unsigned char ***boundary
, PKCS7
*p7
)
616 ASN1_OCTET_STRING
*os
= NULL
;
618 switch (OBJ_obj2nid(p7
->type
)) {
623 case NID_pkcs7_signedAndEnveloped
:
624 os
= p7
->d
.signed_and_enveloped
->enc_data
->enc_data
;
626 os
= ASN1_OCTET_STRING_new();
627 p7
->d
.signed_and_enveloped
->enc_data
->enc_data
= os
;
631 case NID_pkcs7_enveloped
:
632 os
= p7
->d
.enveloped
->enc_data
->enc_data
;
634 os
= ASN1_OCTET_STRING_new();
635 p7
->d
.enveloped
->enc_data
->enc_data
= os
;
639 case NID_pkcs7_signed
:
640 os
= p7
->d
.sign
->contents
->d
.data
;
651 os
->flags
|= ASN1_STRING_FLAG_NDEF
;
652 *boundary
= &os
->data
;