1#[cfg(feature = "tsa-verify")]
5pub use inner::{verify, verify_with_extra_cert, TsaProvider, VerifiedToken};
6
7#[cfg(feature = "tsa-verify")]
8pub(crate) mod inner {
9 use rasn::prelude::*;
10 use rasn_pkix::Certificate;
11 use sha2::{Digest, Sha256, Sha384, Sha512};
12
13 use crate::error::Error;
14
15 const OID_SIGNED_DATA: &[u32] = &[1, 2, 840, 113549, 1, 7, 2];
18 const OID_TST_INFO: &[u32] = &[1, 2, 840, 113549, 1, 9, 16, 1, 4];
19 const OID_MESSAGE_DIGEST: &[u32] = &[1, 2, 840, 113549, 1, 9, 4];
20 const OID_SHA256: &[u32] = &[2, 16, 840, 1, 101, 3, 4, 2, 1];
21 const OID_SHA384: &[u32] = &[2, 16, 840, 1, 101, 3, 4, 2, 2];
22 const OID_SHA512: &[u32] = &[2, 16, 840, 1, 101, 3, 4, 2, 3];
23 const OID_RSA_SHA256: &[u32] = &[1, 2, 840, 113549, 1, 1, 11];
24 const OID_RSA_SHA384: &[u32] = &[1, 2, 840, 113549, 1, 1, 12];
25 const OID_RSA_SHA512: &[u32] = &[1, 2, 840, 113549, 1, 1, 13];
26 const OID_ECDSA_SHA256: &[u32] = &[1, 2, 840, 10045, 4, 3, 2];
27 const OID_ECDSA_SHA384: &[u32] = &[1, 2, 840, 10045, 4, 3, 3];
28 const OID_ECDSA_SHA512: &[u32] = &[1, 2, 840, 10045, 4, 3, 4];
29 const OID_SUBJECT_KEY_ID: &[u32] = &[2, 5, 29, 14];
30
31 fn oid(parts: &[u32]) -> ObjectIdentifier {
32 ObjectIdentifier::new(parts.to_vec()).expect("static OID is valid")
33 }
34
35 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
38 pub struct AlgorithmIdentifier {
39 pub algorithm: ObjectIdentifier,
40 pub parameters: Option<Any>,
41 }
42
43 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
44 pub struct IssuerAndSerialNumber {
45 pub issuer: Any,
46 pub serial_number: Integer,
47 }
48
49 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
50 #[rasn(choice)]
51 pub enum SignerIdentifier {
52 IssuerAndSerialNumber(IssuerAndSerialNumber),
53 #[rasn(tag(0))]
54 SubjectKeyIdentifier(OctetString),
55 }
56
57 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
58 pub struct Attribute {
59 pub attr_type: ObjectIdentifier,
60 pub attr_values: SetOf<Any>,
61 }
62
63 pub type Attributes = SetOf<Attribute>;
64
65 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
66 pub struct SignerInfo {
67 pub version: Integer,
68 pub sid: SignerIdentifier,
69 pub digest_algorithm: AlgorithmIdentifier,
70 #[rasn(tag(0))]
71 pub signed_attrs: Option<Attributes>,
72 pub signature_algorithm: AlgorithmIdentifier,
73 pub signature: OctetString,
74 }
75
76 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
77 pub struct EncapsulatedContentInfo {
78 pub e_content_type: ObjectIdentifier,
79 #[rasn(tag(explicit(0)))]
80 pub e_content: Option<OctetString>,
81 }
82
83 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
85 pub struct CertificateSet(pub SetOf<Any>);
86
87 #[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, Hash)]
88 pub struct SignedData {
89 pub version: Integer,
90 pub digest_algorithms: SetOf<AlgorithmIdentifier>,
91 pub encap_content_info: EncapsulatedContentInfo,
92 #[rasn(tag(0))]
93 pub certificates: Option<CertificateSet>,
94 pub signer_infos: SetOf<SignerInfo>,
95 }
96
97 #[derive(AsnType, Clone, Debug, Decode, Encode)]
98 pub struct ContentInfo {
99 pub content_type: ObjectIdentifier,
100 #[rasn(tag(explicit(0)))]
101 pub content: Any,
102 }
103
104 #[derive(AsnType, Clone, Debug, Decode, Encode)]
106 pub struct TstAccuracy {
107 pub seconds: Option<Integer>,
108 #[rasn(tag(0))]
109 pub millis: Option<Integer>,
110 #[rasn(tag(1))]
111 pub micros: Option<Integer>,
112 }
113
114 #[derive(AsnType, Clone, Debug, Decode, Encode)]
116 pub struct TstInfo {
117 pub version: Integer,
118 pub policy: ObjectIdentifier,
119 pub message_imprint: MessageImprint,
120 pub serial_number: Integer,
121 pub gen_time: GeneralizedTime,
122 pub accuracy: Option<TstAccuracy>,
124 pub ordering: Option<bool>,
126 pub nonce: Option<Integer>,
127 #[rasn(tag(explicit(0)))]
129 pub tsa: Option<Any>,
130 #[rasn(tag(1))]
131 pub extensions: Option<Any>,
132 }
133
134 #[derive(AsnType, Clone, Debug, Decode, Encode)]
135 pub struct MessageImprint {
136 pub hash_algorithm: AlgorithmIdentifier,
137 pub hashed_message: OctetString,
138 }
139
140 #[derive(Debug, Clone, PartialEq, Eq)]
142 pub enum TsaProvider {
143 FreeTsa,
144 Evidency,
145 Qtsa,
146 }
147
148 #[derive(Debug, Clone)]
149 pub struct VerifiedToken {
150 pub provider: TsaProvider,
151 pub hashed_message: Vec<u8>,
152 pub serial_number: String,
153 pub gen_time_unix: i64,
154 }
155
156 struct TrustAnchor {
157 provider: TsaProvider,
158 chain: &'static [&'static [u8]],
159 }
160
161 fn trust_anchors() -> Vec<TrustAnchor> {
162 vec![
163 TrustAnchor {
164 provider: TsaProvider::FreeTsa,
165 chain: &[
166 include_bytes!("certs/freetsa_root.der"),
167 include_bytes!("certs/freetsa_tsa.der"),
168 ],
169 },
170 TrustAnchor {
171 provider: TsaProvider::Evidency,
172 chain: &[
173 include_bytes!("certs/evidency_prod_root.der"),
174 include_bytes!("certs/evidency_sandbox_root.der"),
175 ],
176 },
177 TrustAnchor {
178 provider: TsaProvider::Qtsa,
179 chain: &[
180 include_bytes!("certs/qtsa_root.der"),
181 include_bytes!("certs/qtsa_intermediate.der"),
182 include_bytes!("certs/qtsa_tsa_g4.der"),
183 include_bytes!("certs/sectigo_usertrust_root.der"),
184 ],
185 },
186 ]
187 }
188
189 pub fn verify(token_der: &[u8], message: &[u8]) -> crate::Result<VerifiedToken> {
191 verify_inner(token_der, message, &[])
192 }
193
194 pub fn verify_with_extra_cert(
196 token_der: &[u8],
197 message: &[u8],
198 extra_cert_der: &[u8],
199 extra_provider: TsaProvider,
200 ) -> crate::Result<VerifiedToken> {
201 verify_inner(token_der, message, &[(extra_cert_der, extra_provider)])
202 }
203
204 fn verify_inner(
205 token_der: &[u8],
206 message: &[u8],
207 extra_trusted: &[(&[u8], TsaProvider)],
208 ) -> crate::Result<VerifiedToken> {
209 let ci: ContentInfo = rasn::der::decode(token_der)
210 .map_err(|e| Error::TsaParse(format!("ContentInfo: {e}")))?;
211
212 if ci.content_type != oid(OID_SIGNED_DATA) {
213 return Err(Error::TsaParse("not a SignedData content type".into()));
214 }
215
216 let sd: SignedData = rasn::der::decode(ci.content.as_bytes())
217 .map_err(|e| Error::TsaParse(format!("SignedData: {e}")))?;
218
219 if sd.encap_content_info.e_content_type != oid(OID_TST_INFO) {
220 return Err(Error::TsaParse("encapContentInfo is not TSTInfo".into()));
221 }
222
223 let e_content = sd
224 .encap_content_info
225 .e_content
226 .as_ref()
227 .ok_or_else(|| Error::TsaParse("missing eContent".into()))?;
228 let tst_der: &[u8] = e_content.as_ref();
229
230 let tst: TstInfo =
231 rasn::der::decode(tst_der).map_err(|e| Error::TsaParse(format!("TSTInfo: {e}")))?;
232
233 verify_message_imprint(&tst, message)?;
234
235 let signer_infos = sd.signer_infos.to_vec();
236 let signer = signer_infos
237 .into_iter()
238 .next()
239 .ok_or_else(|| Error::TsaParse("no SignerInfo in SignedData".into()))?;
240
241 let signer_cert_der = find_signer_cert(&sd, signer, extra_trusted)?;
242 let provider = identify_provider(&signer_cert_der, extra_trusted)?;
243
244 verify_signature(signer, &signer_cert_der, tst_der)?;
245
246 Ok(VerifiedToken {
247 provider,
248 hashed_message: tst.message_imprint.hashed_message.to_vec(),
249 serial_number: format!("{}", tst.serial_number),
250 gen_time_unix: tst.gen_time.timestamp(),
251 })
252 }
253
254 fn verify_message_imprint(tst: &TstInfo, message: &[u8]) -> crate::Result<()> {
255 let alg_oid = &tst.message_imprint.hash_algorithm.algorithm;
256 let expected: Vec<u8> = if *alg_oid == oid(OID_SHA256) {
257 Sha256::digest(message).to_vec()
258 } else if *alg_oid == oid(OID_SHA384) {
259 Sha384::digest(message).to_vec()
260 } else if *alg_oid == oid(OID_SHA512) {
261 Sha512::digest(message).to_vec()
262 } else {
263 return Err(Error::TsaVerification(
264 "unsupported hash algorithm in message imprint".into(),
265 ));
266 };
267
268 if tst.message_imprint.hashed_message.as_ref() != expected.as_slice() {
269 return Err(Error::TsaVerification(
270 "message imprint hash mismatch".into(),
271 ));
272 }
273 Ok(())
274 }
275
276 fn find_signer_cert(
277 sd: &SignedData,
278 signer: &SignerInfo,
279 extra_trusted: &[(&[u8], TsaProvider)],
280 ) -> crate::Result<Vec<u8>> {
281 if let Some(certs) = &sd.certificates {
283 for cert_any in certs.0.to_vec() {
284 let cert_der = cert_any.as_bytes();
285 if signer_matches_cert(signer, cert_der) {
286 return Ok(cert_der.to_vec());
287 }
288 }
289 }
290
291 for anchor in trust_anchors() {
293 for &cert_der in anchor.chain {
294 if signer_matches_cert(signer, cert_der) {
295 return Ok(cert_der.to_vec());
296 }
297 }
298 }
299
300 for (cert_der, _) in extra_trusted {
302 if signer_matches_cert(signer, cert_der) {
303 return Ok(cert_der.to_vec());
304 }
305 }
306
307 Err(Error::TsaParse(
308 "signer certificate not found in token or trust anchors".into(),
309 ))
310 }
311
312 fn signer_matches_cert(signer: &SignerInfo, cert_der: &[u8]) -> bool {
313 let Ok(cert) = rasn::der::decode::<Certificate>(cert_der) else {
314 return false;
315 };
316 match &signer.sid {
317 SignerIdentifier::IssuerAndSerialNumber(isn) => {
318 cert.tbs_certificate.serial_number == isn.serial_number
319 }
320 SignerIdentifier::SubjectKeyIdentifier(skid) => cert
321 .tbs_certificate
322 .extensions
323 .as_ref()
324 .and_then(|exts| exts.iter().find(|e| e.extn_id == oid(OID_SUBJECT_KEY_ID)))
325 .map(|e| e.extn_value.as_ref() == skid.as_ref())
326 .unwrap_or(false),
327 }
328 }
329
330 fn identify_provider(
331 signer_cert_der: &[u8],
332 extra_trusted: &[(&[u8], TsaProvider)],
333 ) -> crate::Result<TsaProvider> {
334 for (cert, provider) in extra_trusted {
335 if *cert == signer_cert_der {
336 return Ok(provider.clone());
337 }
338 }
339 for anchor in trust_anchors() {
340 if anchor.chain.contains(&signer_cert_der) {
341 return Ok(anchor.provider);
342 }
343 }
344 Err(Error::TsaUntrustedProvider)
345 }
346
347 fn verify_signature(
348 signer: &SignerInfo,
349 cert_der: &[u8],
350 e_content_der: &[u8],
351 ) -> crate::Result<()> {
352 let cert: Certificate = rasn::der::decode(cert_der)
353 .map_err(|e| Error::TsaParse(format!("signer cert: {e}")))?;
354
355 let spki_der = rasn::der::encode(&cert.tbs_certificate.subject_public_key_info)
356 .map_err(|e| Error::TsaParse(format!("SPKI encode: {e}")))?;
357
358 let signed_bytes: Vec<u8> = match &signer.signed_attrs {
359 Some(attrs) => {
360 rasn::der::encode(attrs)
362 .map_err(|e| Error::TsaParse(format!("signedAttrs encode: {e}")))?
363 }
364 None => e_content_der.to_vec(),
365 };
366
367 if let Some(attrs) = &signer.signed_attrs {
368 verify_message_digest_attr(attrs, e_content_der, &signer.digest_algorithm)?;
369 }
370
371 let sig_alg = &signer.signature_algorithm.algorithm;
372 let sig_bytes = signer.signature.as_ref();
373
374 if *sig_alg == oid(OID_RSA_SHA256) {
375 verify_rsa_sha256(sig_bytes, &signed_bytes, &spki_der)
376 } else if *sig_alg == oid(OID_RSA_SHA384) {
377 verify_rsa_sha384(sig_bytes, &signed_bytes, &spki_der)
378 } else if *sig_alg == oid(OID_RSA_SHA512) {
379 verify_rsa_sha512(sig_bytes, &signed_bytes, &spki_der)
380 } else if *sig_alg == oid(OID_ECDSA_SHA256) {
381 verify_ecdsa_p256(sig_bytes, &signed_bytes, &spki_der)
382 } else if *sig_alg == oid(OID_ECDSA_SHA384) {
383 verify_ecdsa_p384(sig_bytes, &signed_bytes, &spki_der)
384 } else if *sig_alg == oid(OID_ECDSA_SHA512) {
385 verify_ecdsa_sha512(sig_bytes, &signed_bytes, &spki_der)
386 } else {
387 Err(Error::TsaVerification(format!(
388 "unsupported signature algorithm: {:?}",
389 sig_alg
390 )))
391 }
392 }
393
394 fn verify_message_digest_attr(
395 attrs: &Attributes,
396 e_content_der: &[u8],
397 digest_alg: &AlgorithmIdentifier,
398 ) -> crate::Result<()> {
399 let md_oid = oid(OID_MESSAGE_DIGEST);
400 let attrs_vec = attrs.to_vec();
401 let Some(md_attr) = attrs_vec.into_iter().find(|a| a.attr_type == md_oid) else {
402 return Err(Error::TsaVerification(
403 "messageDigest attribute missing".into(),
404 ));
405 };
406
407 let vals = md_attr.attr_values.to_vec();
408 let Some(md_any) = vals.into_iter().next() else {
409 return Err(Error::TsaVerification("empty messageDigest value".into()));
410 };
411
412 let expected: OctetString = rasn::der::decode(md_any.as_bytes())
413 .map_err(|e| Error::TsaParse(format!("messageDigest: {e}")))?;
414
415 let actual: Vec<u8> = if digest_alg.algorithm == oid(OID_SHA256) {
416 Sha256::digest(e_content_der).to_vec()
417 } else if digest_alg.algorithm == oid(OID_SHA384) {
418 Sha384::digest(e_content_der).to_vec()
419 } else if digest_alg.algorithm == oid(OID_SHA512) {
420 Sha512::digest(e_content_der).to_vec()
421 } else {
422 return Err(Error::TsaVerification(
423 "unsupported digest algorithm".into(),
424 ));
425 };
426
427 if expected.as_ref() != actual.as_slice() {
428 return Err(Error::TsaVerification("messageDigest mismatch".into()));
429 }
430 Ok(())
431 }
432
433 fn verify_rsa_sha256(sig: &[u8], data: &[u8], spki_der: &[u8]) -> crate::Result<()> {
434 use rsa::{pkcs1v15::VerifyingKey, pkcs8::DecodePublicKey, signature::Verifier};
435 let pk = rsa::RsaPublicKey::from_public_key_der(spki_der)
436 .map_err(|e| Error::TsaVerification(format!("RSA key: {e}")))?;
437 let vk: VerifyingKey<Sha256> = VerifyingKey::new(pk);
438 let sig = rsa::pkcs1v15::Signature::try_from(sig)
439 .map_err(|e| Error::TsaVerification(format!("RSA sig: {e}")))?;
440 vk.verify(data, &sig)
441 .map_err(|_| Error::TsaVerification("RSA-SHA256 invalid".into()))
442 }
443
444 fn verify_rsa_sha384(sig: &[u8], data: &[u8], spki_der: &[u8]) -> crate::Result<()> {
445 use rsa::{pkcs1v15::VerifyingKey, pkcs8::DecodePublicKey, signature::Verifier};
446 let pk = rsa::RsaPublicKey::from_public_key_der(spki_der)
447 .map_err(|e| Error::TsaVerification(format!("RSA key: {e}")))?;
448 let vk: VerifyingKey<Sha384> = VerifyingKey::new(pk);
449 let sig = rsa::pkcs1v15::Signature::try_from(sig)
450 .map_err(|e| Error::TsaVerification(format!("RSA sig: {e}")))?;
451 vk.verify(data, &sig)
452 .map_err(|_| Error::TsaVerification("RSA-SHA384 invalid".into()))
453 }
454
455 fn verify_rsa_sha512(sig: &[u8], data: &[u8], spki_der: &[u8]) -> crate::Result<()> {
456 use rsa::{pkcs1v15::VerifyingKey, pkcs8::DecodePublicKey, signature::Verifier};
457 let pk = rsa::RsaPublicKey::from_public_key_der(spki_der)
458 .map_err(|e| Error::TsaVerification(format!("RSA key: {e}")))?;
459 let vk: VerifyingKey<Sha512> = VerifyingKey::new(pk);
460 let sig = rsa::pkcs1v15::Signature::try_from(sig)
461 .map_err(|e| Error::TsaVerification(format!("RSA sig: {e}")))?;
462 vk.verify(data, &sig)
463 .map_err(|_| Error::TsaVerification("RSA-SHA512 invalid".into()))
464 }
465
466 fn verify_ecdsa_p256(sig: &[u8], data: &[u8], spki_der: &[u8]) -> crate::Result<()> {
467 use p256::{
468 ecdsa::{signature::Verifier, DerSignature, VerifyingKey},
469 pkcs8::DecodePublicKey,
470 };
471 let vk = VerifyingKey::from_public_key_der(spki_der)
472 .map_err(|e| Error::TsaVerification(format!("P-256 key: {e}")))?;
473 let sig = DerSignature::try_from(sig)
474 .map_err(|e| Error::TsaVerification(format!("P-256 sig: {e}")))?;
475 vk.verify(data, &sig)
476 .map_err(|_| Error::TsaVerification("ECDSA-P256-SHA256 invalid".into()))
477 }
478
479 fn verify_ecdsa_p384(sig: &[u8], data: &[u8], spki_der: &[u8]) -> crate::Result<()> {
480 use p384::ecdsa::{signature::Verifier, DerSignature, VerifyingKey};
481 use p384::pkcs8::DecodePublicKey;
482 let vk = VerifyingKey::from_public_key_der(spki_der)
483 .map_err(|e| Error::TsaVerification(format!("P-384 key: {e}")))?;
484 let sig = DerSignature::try_from(sig)
485 .map_err(|e| Error::TsaVerification(format!("P-384 sig: {e}")))?;
486 vk.verify(data, &sig)
487 .map_err(|_| Error::TsaVerification("ECDSA-P384-SHA384 invalid".into()))
488 }
489
490 fn verify_ecdsa_sha512(sig: &[u8], data: &[u8], spki_der: &[u8]) -> crate::Result<()> {
492 let prehash = Sha512::digest(data);
493
494 {
495 use p256::pkcs8::DecodePublicKey;
497 if let Ok(vk) = p256::ecdsa::VerifyingKey::from_public_key_der(spki_der) {
498 use p256::ecdsa::signature::hazmat::PrehashVerifier;
499 let raw = p256::ecdsa::Signature::from_der(sig)
500 .map_err(|e| Error::TsaVerification(format!("sig: {e}")))?;
501 return vk
502 .verify_prehash(prehash.as_slice(), &raw)
503 .map_err(|_| Error::TsaVerification("ECDSA-P256-SHA512 invalid".into()));
504 }
505 }
506
507 {
508 use p384::pkcs8::DecodePublicKey;
510 if let Ok(vk) = p384::ecdsa::VerifyingKey::from_public_key_der(spki_der) {
511 use p384::ecdsa::signature::hazmat::PrehashVerifier;
512 let raw = p384::ecdsa::Signature::from_der(sig)
513 .map_err(|e| Error::TsaVerification(format!("sig: {e}")))?;
514 return vk
515 .verify_prehash(prehash.as_slice(), &raw)
516 .map_err(|_| Error::TsaVerification("ECDSA-P384-SHA512 invalid".into()));
517 }
518 }
519
520 Err(Error::TsaVerification(
521 "ECDSA-SHA512: unsupported EC curve (expected P-256 or P-384)".into(),
522 ))
523 }
524
525 #[cfg(test)]
526 pub mod mock {
527 use rasn::prelude::*;
530 use rsa::{
531 pkcs1v15::SigningKey,
532 pkcs8::EncodePublicKey,
533 rand_core::OsRng,
534 signature::{RandomizedSigner, SignatureEncoding},
535 RsaPrivateKey,
536 };
537 use sha2::{Digest, Sha256};
538
539 use super::*;
540
541 const TEST_RSA_BITS: usize = 512;
542
543 const OID_SHA256_OBJ: &[u32] = &[2, 16, 840, 1, 101, 3, 4, 2, 1];
544 const OID_RSA_SHA256_OBJ: &[u32] = &[1, 2, 840, 113549, 1, 1, 11];
545 const OID_SIGNED_DATA_OBJ: &[u32] = &[1, 2, 840, 113549, 1, 7, 2];
546 const OID_TST_INFO_OBJ: &[u32] = &[1, 2, 840, 113549, 1, 9, 16, 1, 4];
547 const OID_MESSAGE_DIGEST_OBJ: &[u32] = &[1, 2, 840, 113549, 1, 9, 4];
548 const OID_MOCK_POLICY: &[u32] = &[1, 3, 6, 1, 4, 1, 0, 1];
549
550 fn o(parts: &[u32]) -> ObjectIdentifier {
551 ObjectIdentifier::new(parts.to_vec()).unwrap()
552 }
553
554 fn sha256_alg() -> AlgorithmIdentifier {
555 AlgorithmIdentifier {
556 algorithm: o(OID_SHA256_OBJ),
557 parameters: None,
558 }
559 }
560
561 fn rsa_sha256_alg() -> AlgorithmIdentifier {
562 AlgorithmIdentifier {
563 algorithm: o(OID_RSA_SHA256_OBJ),
564 parameters: None,
565 }
566 }
567
568 pub fn build(message: &[u8]) -> (Vec<u8>, Vec<u8>) {
570 let sk = RsaPrivateKey::new(&mut OsRng, TEST_RSA_BITS).expect("RSA key gen");
571 let signing_key: SigningKey<Sha256> = SigningKey::new(sk.clone());
572
573 let spki_der = sk.to_public_key().to_public_key_der().unwrap().to_vec();
574
575 let msg_hash = Sha256::digest(message);
577 let tst = TstInfo {
578 version: Integer::from(1u8),
579 policy: o(OID_MOCK_POLICY),
580 message_imprint: MessageImprint {
581 hash_algorithm: sha256_alg(),
582 hashed_message: OctetString::from(msg_hash.to_vec()),
583 },
584 serial_number: Integer::from(42u8),
585 gen_time: chrono::Utc::now().fixed_offset(),
586 accuracy: None,
587 ordering: None,
588 nonce: None,
589 tsa: None,
590 extensions: None,
591 };
592 let tst_der = rasn::der::encode(&tst).unwrap();
593
594 let tst_digest = Sha256::digest(&tst_der);
596 let digest_attr = build_message_digest_attr(&tst_digest);
597 let mut signed_attrs = Attributes::new();
598 signed_attrs.insert(digest_attr);
599 let signed_attrs_der = rasn::der::encode(&signed_attrs).unwrap();
600
601 let sig_bytes: Vec<u8> = signing_key
603 .sign_with_rng(&mut OsRng, &signed_attrs_der)
604 .to_bytes()
605 .to_vec();
606
607 let signer_info = SignerInfo {
609 version: Integer::from(1u8),
610 sid: SignerIdentifier::IssuerAndSerialNumber(IssuerAndSerialNumber {
611 issuer: Any::new(vec![]),
612 serial_number: Integer::from(42u8),
613 }),
614 digest_algorithm: sha256_alg(),
615 signed_attrs: Some(signed_attrs),
616 signature_algorithm: rsa_sha256_alg(),
617 signature: OctetString::from(sig_bytes),
618 };
619
620 let mut certs_set = SetOf::<Any>::new();
622 certs_set.insert(Any::new(spki_der.clone()));
623
624 let mut digest_algs = SetOf::new();
625 digest_algs.insert(sha256_alg());
626 let mut signer_infos = SetOf::new();
627 signer_infos.insert(signer_info);
628
629 let sd = SignedData {
630 version: Integer::from(3u8),
631 digest_algorithms: digest_algs,
632 encap_content_info: EncapsulatedContentInfo {
633 e_content_type: o(OID_TST_INFO_OBJ),
634 e_content: Some(OctetString::from(tst_der)),
635 },
636 certificates: Some(CertificateSet(certs_set)),
637 signer_infos,
638 };
639 let sd_der = rasn::der::encode(&sd).unwrap();
640
641 let ci = ContentInfo {
642 content_type: o(OID_SIGNED_DATA_OBJ),
643 content: Any::new(sd_der),
644 };
645 let token_der = rasn::der::encode(&ci).unwrap();
646
647 (token_der, spki_der)
648 }
649
650 fn build_message_digest_attr(digest: &[u8]) -> Attribute {
651 let val_der = rasn::der::encode(&OctetString::from(digest.to_vec())).unwrap();
652 let mut vals = SetOf::<Any>::new();
653 vals.insert(Any::new(val_der));
654 Attribute {
655 attr_type: o(OID_MESSAGE_DIGEST_OBJ),
656 attr_values: vals,
657 }
658 }
659
660 }
663
664 #[cfg(test)]
665 mod tests {
666 use super::mock;
667 use super::*;
668
669 #[test]
670 fn mock_token_parses_and_imprint_matches() {
671 let message = b"hello from the test suite";
672 let (token_der, _spki_der) = mock::build(message);
673
674 let ci: ContentInfo = rasn::der::decode(&token_der).unwrap();
676 assert_eq!(ci.content_type, oid(OID_SIGNED_DATA));
677
678 let sd: SignedData = rasn::der::decode(ci.content.as_bytes()).unwrap();
679 let tst_der: &[u8] = sd.encap_content_info.e_content.as_ref().unwrap().as_ref();
680 let tst: TstInfo = rasn::der::decode(tst_der).unwrap();
681
682 let expected: Vec<u8> = sha2::Sha256::digest(message).to_vec();
683 assert_eq!(
684 tst.message_imprint.hashed_message.as_ref(),
685 expected.as_slice()
686 );
687 }
688
689 #[test]
690 fn wrong_message_imprint_detected() {
691 let message = b"correct message";
692 let (token_der, _spki_der) = mock::build(message);
693
694 let ci: ContentInfo = rasn::der::decode(&token_der).unwrap();
696 let sd: SignedData = rasn::der::decode(ci.content.as_bytes()).unwrap();
697 let tst_der: &[u8] = sd.encap_content_info.e_content.as_ref().unwrap().as_ref();
698 let tst: TstInfo = rasn::der::decode(tst_der).unwrap();
699
700 let wrong_hash: Vec<u8> = sha2::Sha256::digest(b"wrong message").to_vec();
701 assert_ne!(
702 tst.message_imprint.hashed_message.as_ref(),
703 wrong_hash.as_slice()
704 );
705 }
706 }
707}