1use der_parser::oid::Oid;
2use nom::HexDisplay;
3use std::cmp::min;
4use std::env;
5use std::io;
6use x509_parser::prelude::*;
7
8fn print_hex_dump(bytes: &[u8], max_len: usize) {
9 let m = min(bytes.len(), max_len);
10 print!("{}", &bytes[..m].to_hex(16));
11 if bytes.len() > max_len {
12 println!("... <continued>");
13 }
14}
15
16fn format_oid(oid: &Oid) -> String {
17 match oid2sn(oid, oid_registry()) {
18 Ok(s) => s.to_owned(),
19 _ => format!("{}", oid),
20 }
21}
22
23fn print_authority_key_identifier(aki: &AuthorityKeyIdentifier, level: usize) {
24 if let Some(id) = &aki.key_identifier {
25 println!("{:indent$}keyid: {:x}", "", id, indent = level);
26 }
27 if aki.authority_cert_issuer.is_some() {
28 unimplemented!();
29 }
30 if let Some(serial) = aki.authority_cert_serial {
31 let s = format_serial(serial);
32 println!("{:indent$}serial: {}", "", &s, indent = level);
33 }
34}
35
36fn print_x509_extension(oid: &Oid, ext: &X509Extension, level: usize) {
37 match ext.parsed_extension() {
38 ParsedExtension::CRLNumber(num) => {
39 println!("{:indent$}X509v3 CRL Number: {}", "", num, indent = level);
40 }
41 ParsedExtension::ReasonCode(code) => {
42 println!(
43 "{:indent$}X509v3 CRL Reason Code: {}",
44 "",
45 code,
46 indent = level
47 );
48 }
49 ParsedExtension::InvalidityDate(date) => {
50 println!("{:indent$}Invalidity Date: {}", "", date, indent = level);
51 }
52 ParsedExtension::AuthorityKeyIdentifier(aki) => {
53 println!(
54 "{:indent$}X509v3 Authority Key Identifier:",
55 "",
56 indent = level
57 );
58 print_authority_key_identifier(aki, level + 2);
59 }
60 x => {
61 print!("{:indent$}{}:", "", format_oid(oid), indent = level);
62 print!(" Critical={}", ext.critical);
63 print!(" len={}", ext.value.len());
64 println!();
65 println!(" {:indent$}{:?}", "", x, indent = level);
66 }
67 }
68}
69
70fn print_x509_digest_algorithm(alg: &AlgorithmIdentifier, level: usize) {
71 println!(
72 "{:indent$}Oid: {}",
73 "",
74 format_oid(&alg.algorithm),
75 indent = level
76 );
77 if let Some(parameter) = &alg.parameters {
78 println!(
79 "{:indent$}Parameter: <PRESENT> {:?}",
80 "",
81 parameter.tag(),
82 indent = level
83 );
84 let bytes = parameter.as_bytes();
85 print_hex_dump(bytes, 32);
86 } else {
87 println!("{:indent$}Parameter: <ABSENT>", "", indent = level);
88 }
89}
90
91fn print_revoked_certificate(revoked: &RevokedCertificate, level: usize) {
92 println!(
93 "{:indent$}Serial number: {}",
94 "",
95 revoked.raw_serial_as_string(),
96 indent = level
97 );
98 println!(
99 "{:indent$}Revocation Date: {}",
100 "",
101 revoked.revocation_date,
102 indent = level + 2
103 );
104 println!("{:indent$}CRL Extensions:", "", indent = level + 2);
105 for ext in revoked.extensions() {
106 print_x509_extension(&ext.oid, ext, level + 4);
107 }
108}
109
110fn print_crl_info(crl: &CertificateRevocationList) {
111 println!(" Version: {}", crl.version().unwrap_or(X509Version(0)));
112 println!(" Signature Algorithm:");
114 print_x509_digest_algorithm(&crl.signature_algorithm, 4);
115 println!(" Issuer: {}", crl.issuer());
116 println!(" Last Update: {}", crl.last_update());
118 println!(
119 " Next Update: {}",
120 crl.next_update()
121 .map_or_else(|| "NONE".to_string(), |d| d.to_string())
122 );
123 println!("{:indent$}CRL Extensions:", "", indent = 2);
124 for ext in crl.extensions() {
125 print_x509_extension(&ext.oid, ext, 4);
126 }
127 println!(" Revoked certificates:");
128 for revoked in crl.iter_revoked_certificates() {
129 print_revoked_certificate(revoked, 4);
130 }
131 println!();
132}
133
134pub fn main() -> io::Result<()> {
135 for file_name in env::args().skip(1) {
136 let tmpdata;
138
139 println!("File: {}", file_name);
140 let data = std::fs::read(file_name.clone()).expect("Unable to read file");
141 let der_data: &[u8] = if (data[0], data[1]) == (0x30, 0x82) {
142 &data
144 } else {
145 let (_, data) = parse_x509_pem(&data).expect("Could not decode the PEM file");
147 tmpdata = data;
148 &tmpdata.contents
149 };
150 let (_, crl) = parse_x509_crl(der_data).expect("Could not decode DER data");
151 print_crl_info(&crl);
152 }
153 Ok(())
154}