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