1use crate::cert::CertificateChoices;
4use crate::revocation::RevocationInfoChoices;
5use crate::signed_data::EncapsulatedContentInfo;
6use crate::signed_data::{CertificateSet, SignedData, SignerInfos};
7use core::cmp::Ordering;
8use der::asn1::SetOfVec;
9use der::Encode;
10use der::{asn1::ObjectIdentifier, Any, AnyRef, Enumerated, Sequence, ValueOrd};
11use x509_cert::{Certificate, PkiPath};
12
13#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Enumerated)]
21#[asn1(type = "INTEGER")]
22#[repr(u8)]
23#[allow(missing_docs)]
24pub enum CmsVersion {
25 V0 = 0,
26 V1 = 1,
27 V2 = 2,
28 V3 = 3,
29 V4 = 4,
30 V5 = 5,
31}
32
33impl ValueOrd for CmsVersion {
34 fn value_cmp(&self, other: &Self) -> der::Result<Ordering> {
35 (*self as u8).value_cmp(&(*other as u8))
36 }
37}
38
39#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
51#[allow(missing_docs)]
52pub struct ContentInfo {
53 pub content_type: ObjectIdentifier,
54 #[asn1(context_specific = "0", tag_mode = "EXPLICIT")]
55 pub content: Any,
56}
57
58impl TryFrom<Certificate> for ContentInfo {
60 type Error = der::Error;
61
62 fn try_from(cert: Certificate) -> der::Result<Self> {
63 let mut certs = CertificateSet(Default::default());
64 certs.0.insert(CertificateChoices::Certificate(cert))?;
65
66 let sd = SignedData {
68 version: CmsVersion::V1,
69 digest_algorithms: SetOfVec::default(),
70 encap_content_info: EncapsulatedContentInfo {
71 econtent_type: const_oid::db::rfc5911::ID_DATA,
72 econtent: None,
73 },
74 certificates: Some(certs),
75 crls: Some(RevocationInfoChoices(Default::default())),
76 signer_infos: SignerInfos(Default::default()),
77 };
78
79 let signed_data = sd.to_der()?;
80 let content = AnyRef::try_from(signed_data.as_slice())?;
81
82 Ok(ContentInfo {
83 content_type: const_oid::db::rfc5911::ID_SIGNED_DATA,
84 content: Any::from(content),
85 })
86 }
87}
88
89impl TryFrom<PkiPath> for ContentInfo {
91 type Error = der::Error;
92
93 fn try_from(pki_path: PkiPath) -> der::Result<Self> {
94 let mut certs = CertificateSet(Default::default());
95 for cert in pki_path {
96 certs.0.insert(CertificateChoices::Certificate(cert))?;
97 }
98
99 let sd = SignedData {
101 version: CmsVersion::V1,
102 digest_algorithms: SetOfVec::default(),
103 encap_content_info: EncapsulatedContentInfo {
104 econtent_type: const_oid::db::rfc5911::ID_DATA,
105 econtent: None,
106 },
107 certificates: Some(certs),
108 crls: Some(RevocationInfoChoices(Default::default())),
109 signer_infos: SignerInfos(Default::default()),
110 };
111
112 let signed_data = sd.to_der()?;
113 let content = AnyRef::try_from(signed_data.as_slice())?;
114
115 Ok(ContentInfo {
116 content_type: const_oid::db::rfc5911::ID_SIGNED_DATA,
117 content: Any::from(content),
118 })
119 }
120}