ribbit_client/
signature.rs1use crate::error::Result;
6use tracing::{debug, trace};
7
8pub fn parse_signature(signature_bytes: &[u8]) -> Result<SignatureInfo> {
17 trace!("Parsing {} bytes of signature data", signature_bytes.len());
18
19 if signature_bytes.len() < 20 {
21 return Err(crate::error::Error::Asn1Error(
22 "Signature too short".to_string(),
23 ));
24 }
25
26 let tlv = asn1::parse_single::<asn1::Tlv>(signature_bytes)
28 .map_err(|e| crate::error::Error::Asn1Error(format!("Failed to parse ASN.1: {e:?}")))?;
29
30 let tag = tlv.tag();
31 let len = tlv.data().len();
32 trace!("ASN.1 tag: {tag:?}, length: {len}");
33
34 let mut algorithm = "Unknown".to_string();
36 let mut signer_count = 0;
37 let mut certificate_count = 0;
38
39 let data = tlv.data();
42 if data.len() > 20 {
43 if data[0] == 0x06 && data[1] == 0x09 {
45 let oid_bytes = &data[2..11];
46 if oid_bytes == [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02] {
47 debug!("Found PKCS#7 signedData OID");
48
49 if let Some(sha256_pos) = find_pattern(
51 data,
52 &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01],
53 ) {
54 algorithm = "SHA-256".to_string();
55 debug!("Found SHA-256 algorithm at position {}", sha256_pos);
56 }
57
58 let mut pos = 0;
60 while pos < data.len() - 4 {
61 if data[pos] == 0x30 && data[pos + 1] == 0x82 {
62 let len = ((data[pos + 2] as usize) << 8) | (data[pos + 3] as usize);
64 if len > 300 && len < 2000 {
65 certificate_count += 1;
66 }
67 pos += 4 + len;
68 } else {
69 pos += 1;
70 }
71 }
72
73 signer_count = 1; }
76 }
77 }
78
79 let signature_info = SignatureInfo {
80 format: "PKCS#7/CMS".to_string(),
81 size: signature_bytes.len(),
82 algorithm,
83 signer_count,
84 certificate_count,
85 };
86
87 debug!("Parsed signature: {:?}", signature_info);
88 Ok(signature_info)
89}
90
91fn find_pattern(data: &[u8], pattern: &[u8]) -> Option<usize> {
93 data.windows(pattern.len())
94 .position(|window| window == pattern)
95}
96
97#[derive(Debug, Clone)]
99pub struct SignatureInfo {
100 pub format: String,
102 pub size: usize,
104 pub algorithm: String,
106 pub signer_count: usize,
108 pub certificate_count: usize,
110}