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 STACK_OF(PKCS7_RECIP_INFO
) *rinfos
= pkcs7_get_recipient_info(p7
);
405 STACK_OF(PKCS7_SIGNER_INFO
) *sinfos
= PKCS7_get_signer_info(p7
);
406 STACK_OF(X509
) *certs
= pkcs7_get_signer_certs(p7
);
411 for (i
= 0; i
< sk_X509_num(certs
); i
++)
412 x509_set0_libctx(sk_X509_value(certs
, i
), ctx
->libctx
, ctx
->propq
);
414 for (i
= 0; i
< sk_PKCS7_RECIP_INFO_num(rinfos
); i
++) {
415 PKCS7_RECIP_INFO
*ri
= sk_PKCS7_RECIP_INFO_value(rinfos
, i
);
417 x509_set0_libctx(ri
->cert
, ctx
->libctx
, ctx
->propq
);
420 for (i
= 0; i
< sk_PKCS7_SIGNER_INFO_num(sinfos
); i
++) {
421 PKCS7_SIGNER_INFO
*si
= sk_PKCS7_SIGNER_INFO_value(sinfos
, i
);
428 const PKCS7_CTX
*pkcs7_get0_ctx(const PKCS7
*p7
)
430 return p7
!= NULL
? &p7
->ctx
: NULL
;
433 OSSL_LIB_CTX
*pkcs7_ctx_get0_libctx(const PKCS7_CTX
*ctx
)
435 return ctx
!= NULL
? ctx
->libctx
: NULL
;
437 const char *pkcs7_ctx_get0_propq(const PKCS7_CTX
*ctx
)
439 return ctx
!= NULL
? ctx
->propq
: NULL
;
442 int PKCS7_set_digest(PKCS7
*p7
, const EVP_MD
*md
)
444 if (PKCS7_type_is_digest(p7
)) {
445 if ((p7
->d
.digest
->md
->parameter
= ASN1_TYPE_new()) == NULL
) {
446 ERR_raise(ERR_LIB_PKCS7
, ERR_R_MALLOC_FAILURE
);
449 p7
->d
.digest
->md
->parameter
->type
= V_ASN1_NULL
;
450 p7
->d
.digest
->md
->algorithm
= OBJ_nid2obj(EVP_MD_nid(md
));
454 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
458 STACK_OF(PKCS7_SIGNER_INFO
) *PKCS7_get_signer_info(PKCS7
*p7
)
460 if (p7
== NULL
|| p7
->d
.ptr
== NULL
)
462 if (PKCS7_type_is_signed(p7
)) {
463 return p7
->d
.sign
->signer_info
;
464 } else if (PKCS7_type_is_signedAndEnveloped(p7
)) {
465 return p7
->d
.signed_and_enveloped
->signer_info
;
470 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO
*si
, EVP_PKEY
**pk
,
471 X509_ALGOR
**pdig
, X509_ALGOR
**psig
)
476 *pdig
= si
->digest_alg
;
478 *psig
= si
->digest_enc_alg
;
481 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO
*ri
, X509_ALGOR
**penc
)
484 *penc
= ri
->key_enc_algor
;
487 PKCS7_RECIP_INFO
*PKCS7_add_recipient(PKCS7
*p7
, X509
*x509
)
489 PKCS7_RECIP_INFO
*ri
;
491 if ((ri
= PKCS7_RECIP_INFO_new()) == NULL
)
493 if (!PKCS7_RECIP_INFO_set(ri
, x509
))
495 if (!PKCS7_add_recipient_info(p7
, ri
))
497 ri
->ctx
= pkcs7_get0_ctx(p7
);
500 PKCS7_RECIP_INFO_free(ri
);
504 int PKCS7_add_recipient_info(PKCS7
*p7
, PKCS7_RECIP_INFO
*ri
)
507 STACK_OF(PKCS7_RECIP_INFO
) *sk
;
509 i
= OBJ_obj2nid(p7
->type
);
511 case NID_pkcs7_signedAndEnveloped
:
512 sk
= p7
->d
.signed_and_enveloped
->recipientinfo
;
514 case NID_pkcs7_enveloped
:
515 sk
= p7
->d
.enveloped
->recipientinfo
;
518 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
522 if (!sk_PKCS7_RECIP_INFO_push(sk
, ri
))
527 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO
*p7i
, X509
*x509
)
530 EVP_PKEY
*pkey
= NULL
;
531 if (!ASN1_INTEGER_set(p7i
->version
, 0))
533 if (!X509_NAME_set(&p7i
->issuer_and_serial
->issuer
,
534 X509_get_issuer_name(x509
)))
537 ASN1_INTEGER_free(p7i
->issuer_and_serial
->serial
);
538 if (!(p7i
->issuer_and_serial
->serial
=
539 ASN1_INTEGER_dup(X509_get0_serialNumber(x509
))))
542 pkey
= X509_get0_pubkey(x509
);
544 if (!pkey
|| !pkey
->ameth
|| !pkey
->ameth
->pkey_ctrl
) {
545 ERR_raise(ERR_LIB_PKCS7
,
546 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
550 ret
= pkey
->ameth
->pkey_ctrl(pkey
, ASN1_PKEY_CTRL_PKCS7_ENCRYPT
, 0, p7i
);
552 ERR_raise(ERR_LIB_PKCS7
,
553 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE
);
557 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_ENCRYPTION_CTRL_FAILURE
);
570 X509
*PKCS7_cert_from_signer_info(PKCS7
*p7
, PKCS7_SIGNER_INFO
*si
)
572 if (PKCS7_type_is_signed(p7
))
573 return (X509_find_by_issuer_and_serial(p7
->d
.sign
->cert
,
574 si
->issuer_and_serial
->issuer
,
576 issuer_and_serial
->serial
));
581 int PKCS7_set_cipher(PKCS7
*p7
, const EVP_CIPHER
*cipher
)
584 PKCS7_ENC_CONTENT
*ec
;
586 i
= OBJ_obj2nid(p7
->type
);
588 case NID_pkcs7_signedAndEnveloped
:
589 ec
= p7
->d
.signed_and_enveloped
->enc_data
;
591 case NID_pkcs7_enveloped
:
592 ec
= p7
->d
.enveloped
->enc_data
;
595 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_WRONG_CONTENT_TYPE
);
599 /* Check cipher OID exists and has data in it */
600 i
= EVP_CIPHER_type(cipher
);
601 if (i
== NID_undef
) {
602 ERR_raise(ERR_LIB_PKCS7
, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER
);
607 ec
->ctx
= pkcs7_get0_ctx(p7
);
611 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
612 int PKCS7_stream(unsigned char ***boundary
, PKCS7
*p7
)
614 ASN1_OCTET_STRING
*os
= NULL
;
616 switch (OBJ_obj2nid(p7
->type
)) {
621 case NID_pkcs7_signedAndEnveloped
:
622 os
= p7
->d
.signed_and_enveloped
->enc_data
->enc_data
;
624 os
= ASN1_OCTET_STRING_new();
625 p7
->d
.signed_and_enveloped
->enc_data
->enc_data
= os
;
629 case NID_pkcs7_enveloped
:
630 os
= p7
->d
.enveloped
->enc_data
->enc_data
;
632 os
= ASN1_OCTET_STRING_new();
633 p7
->d
.enveloped
->enc_data
->enc_data
= os
;
637 case NID_pkcs7_signed
:
638 os
= p7
->d
.sign
->contents
->d
.data
;
649 os
->flags
|= ASN1_STRING_FLAG_NDEF
;
650 *boundary
= &os
->data
;