parse_certificate/
parse_certificate.rs1use std::str::FromStr;
13use synta::{BitStringRef, Decoder, Element, Encoding, ObjectIdentifier, Sequence};
14
15fn main() {
16 println!("=== X.509 Certificate Structure Parser ===\n");
17
18 let cert_data = create_example_certificate();
21
22 println!("Certificate size: {} bytes", cert_data.len());
23 println!(
24 "First 32 bytes: {:02X?}...\n",
25 &cert_data[..32.min(cert_data.len())]
26 );
27
28 match parse_certificate(&cert_data) {
30 Ok(()) => println!("\nCertificate parsed successfully!"),
31 Err(e) => println!("\nError parsing certificate: {:?}", e),
32 }
33}
34
35fn parse_certificate(data: &[u8]) -> synta::Result<()> {
36 let mut decoder = Decoder::new(data, Encoding::Der);
44 let cert: Sequence = decoder.decode()?;
45 let cert_elements = cert.into_elements()?;
46
47 println!(
48 "Certificate is a SEQUENCE with {} elements",
49 cert_elements.len()
50 );
51
52 if cert_elements.len() < 3 {
53 println!("Warning: Expected at least 3 elements (tbsCertificate, signatureAlgorithm, signatureValue)");
54 return Ok(());
55 }
56
57 if let Element::Sequence(tbs) = &cert_elements[0] {
59 println!("\n1. TBSCertificate (To-Be-Signed Certificate):");
60 let tbs_els = tbs.clone().into_elements()?;
61 println!(" {} elements", tbs_els.len());
62 parse_tbs_certificate(&tbs_els);
63 }
64
65 if let Element::Sequence(sig_alg) = &cert_elements[1] {
67 println!("\n2. Signature Algorithm:");
68 parse_algorithm_identifier(sig_alg);
69 }
70
71 match &cert_elements[2] {
73 Element::BitString(sig) => {
74 println!("\n3. Signature Value:");
75 println!(
76 " {} bytes (unused bits: {})",
77 sig.as_bytes().len(),
78 sig.unused_bits()
79 );
80 }
81 _ => println!("\n3. Signature Value: Unexpected type"),
82 }
83
84 Ok(())
85}
86
87fn parse_tbs_certificate(tbs_elements: &[Element<'_>]) {
88 for (i, element) in tbs_elements.iter().enumerate() {
90 match element {
91 Element::Integer(version) if i == 0 => {
92 println!(" - Version/Field {}: {:?} bytes", i, version.as_bytes());
94 }
95 Element::Integer(serial) => {
96 println!(" - Serial Number: {} bytes", serial.as_bytes().len());
97 }
98 Element::Sequence(seq) => {
99 let len = seq.iter().count();
100 println!(" - SEQUENCE at position {}: {} elements", i, len);
101 }
102 _ => {}
103 }
104 }
105}
106
107fn parse_algorithm_identifier(alg: &Sequence<'_>) {
108 if let Some(Ok(Element::ObjectIdentifier(oid))) = alg.iter().next() {
114 println!(" Algorithm OID: {}", oid);
115
116 let oid_str = oid.to_string();
118 let name = match oid_str.as_str() {
119 "1.2.840.113549.1.1.1" => "RSA Encryption",
120 "1.2.840.113549.1.1.5" => "SHA-1 with RSA",
121 "1.2.840.113549.1.1.11" => "SHA-256 with RSA",
122 "1.2.840.10045.4.3.2" => "ECDSA with SHA-256",
123 _ => "Unknown",
124 };
125 println!(" Algorithm: {}", name);
126 }
127
128 if alg.iter().count() > 1 {
129 println!(" Has parameters: yes");
130 }
131}
132
133fn create_example_certificate() -> Vec<u8> {
134 use synta::Integer;
138 use synta::ToDer;
139
140 let mut tbs = Sequence::new();
142 tbs.push(Element::Integer(Integer::from(2))); tbs.push(Element::Integer(Integer::from(123456))); let mut sig_alg = Sequence::new();
147 sig_alg.push(Element::ObjectIdentifier(
148 ObjectIdentifier::from_str("1.2.840.113549.1.1.11").unwrap(),
149 )); let signature_data = vec![0xDE, 0xAD, 0xBE, 0xEF];
153 let signature = BitStringRef::new(&signature_data, 0).unwrap();
154
155 let mut cert = Sequence::new();
157 cert.push(Element::Sequence(tbs));
158 cert.push(Element::Sequence(sig_alg));
159 cert.push(Element::BitString(signature));
160
161 cert.to_der().unwrap()
163}