1use crate::crypto::asn1::DerElement;
2use crate::crypto::x509::SigningKey;
3use crate::error::PdfResult;
4use chrono::Utc;
5use rsa::pkcs1v15::SigningKey as RsaSigningKey;
6use rsa::signature::{SignatureEncoding, Signer as RsaSignerTrait};
7use sha2::Sha256;
8
9pub fn generate_pkcs7_detached(key: &SigningKey, byte_range_sha256: &[u8]) -> PdfResult<Vec<u8>> {
11 let id_data = vec![1, 2, 840, 113549, 1, 7, 1];
12 let id_signed_data = vec![1, 2, 840, 113549, 1, 7, 2];
13 let id_sha256 = vec![2, 16, 840, 1, 101, 3, 4, 2, 1];
14 let rsa_encryption = vec![1, 2, 840, 113549, 1, 1, 1];
15 let id_content_type = vec![1, 2, 840, 113549, 1, 9, 3];
16 let id_message_digest = vec![1, 2, 840, 113549, 1, 9, 4];
17 let id_signing_time = vec![1, 2, 840, 113549, 1, 9, 5];
18
19 let attr_content_type = DerElement::Sequence(vec![
22 DerElement::ObjectIdentifier(id_content_type),
23 DerElement::Set(vec![DerElement::ObjectIdentifier(id_data.clone())]),
24 ]);
25
26 let attr_message_digest = DerElement::Sequence(vec![
28 DerElement::ObjectIdentifier(id_message_digest),
29 DerElement::Set(vec![DerElement::OctetString(byte_range_sha256.to_vec())]),
30 ]);
31
32 let now = Utc::now();
34 let time_str = now.format("%y%m%d%H%M%SZ").to_string();
35 let attr_signing_time = DerElement::Sequence(vec![
36 DerElement::ObjectIdentifier(id_signing_time),
37 DerElement::Set(vec![DerElement::UtcTime(time_str)]),
38 ]);
39
40 let mut raw_attrs = vec![attr_content_type, attr_message_digest, attr_signing_time];
42 raw_attrs.sort_by_key(|a| a.to_der());
43
44 let signed_attrs_set = DerElement::Set(raw_attrs.clone());
45 let signed_attrs_der = signed_attrs_set.to_der();
46
47 let signer = RsaSigningKey::<Sha256>::new(key.private_key.clone());
49 let signature = signer.sign(&signed_attrs_der);
50
51 let issuer_seq = DerElement::Sequence(vec![DerElement::Set(vec![DerElement::Sequence(vec![
53 DerElement::ObjectIdentifier(vec![2, 5, 4, 3]),
54 DerElement::Utf8String("Techwasti Infotech".to_string()),
55 ])])]);
56
57 let issuer_and_serial = DerElement::Sequence(vec![
58 issuer_seq,
59 DerElement::integer_from_bytes(&key.serial_number),
60 ]);
61
62 let auth_attrs_tagged =
65 DerElement::ContextSpecific(0, Box::new(DerElement::Set(raw_attrs)), true);
66
67 let signer_info = DerElement::Sequence(vec![
68 DerElement::integer_from_u64(1), issuer_and_serial,
70 DerElement::Sequence(vec![
71 DerElement::ObjectIdentifier(id_sha256.clone()),
72 DerElement::Null,
73 ]),
74 auth_attrs_tagged,
75 DerElement::Sequence(vec![
76 DerElement::ObjectIdentifier(rsa_encryption),
77 DerElement::Null,
78 ]),
79 DerElement::OctetString(signature.to_vec()),
80 ]);
81
82 let encap_content_info = DerElement::Sequence(vec![DerElement::ObjectIdentifier(id_data)]);
84
85 let cert_tagged = DerElement::ContextSpecific(
88 0,
89 Box::new(DerElement::OctetString(key.certificate_der.clone())),
90 true,
91 );
92
93 let signed_data = DerElement::Sequence(vec![
95 DerElement::integer_from_u64(1), DerElement::Set(vec![DerElement::Sequence(vec![
97 DerElement::ObjectIdentifier(id_sha256),
98 DerElement::Null,
99 ])]),
100 encap_content_info,
101 cert_tagged,
102 DerElement::Set(vec![signer_info]),
103 ]);
104
105 let content_info = DerElement::Sequence(vec![
107 DerElement::ObjectIdentifier(id_signed_data),
108 DerElement::ContextSpecific(0, Box::new(signed_data), true),
109 ]);
110
111 Ok(content_info.to_der())
112}