summaryrefslogtreecommitdiff
path: root/packet-detector/src/tls_util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'packet-detector/src/tls_util.rs')
-rw-r--r--packet-detector/src/tls_util.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/packet-detector/src/tls_util.rs b/packet-detector/src/tls_util.rs
new file mode 100644
index 0000000..456991b
--- /dev/null
+++ b/packet-detector/src/tls_util.rs
@@ -0,0 +1,73 @@
1use rcgen::{DistinguishedName, DnType};
2use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier};
3use rustls::pki_types::{CertificateDer, ServerName, UnixTime};
4use rustls::{DigitallySignedStruct, Error, SignatureScheme};
5use sha2::{Digest, Sha256};
6use x509_parser::prelude::*;
7
8/// SHA256 fingerprint (truncated to 16 bytes by default)
9pub fn fingerprint(cert: &CertificateDer<'_>, full: bool) -> String {
10 let hash = Sha256::digest(cert.as_ref());
11 if full { hex::encode(hash) } else { hex::encode(&hash[..16]) }
12}
13
14pub fn dn(cn: &str, org: &str) -> DistinguishedName {
15 let mut d = DistinguishedName::new();
16 d.push(DnType::CommonName, cn);
17 d.push(DnType::OrganizationName, org);
18 d.push(DnType::CountryName, "US");
19 d
20}
21
22/// Parse certs from PEM
23pub fn parse_pem(pem: &str) -> Result<Vec<CertificateDer<'static>>, std::io::Error> {
24 rustls_pemfile::certs(&mut pem.as_bytes()).collect()
25}
26
27fn schemes() -> Vec<SignatureScheme> {
28 rustls::crypto::ring::default_provider()
29 .signature_verification_algorithms
30 .supported_schemes()
31}
32
33/// Macro to implement the boilerplate verifier methods
34macro_rules! impl_verifier_base {
35 () => {
36 fn verify_tls12_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &DigitallySignedStruct) -> Result<HandshakeSignatureValid, Error> {
37 Ok(HandshakeSignatureValid::assertion())
38 }
39 fn verify_tls13_signature(&self, _: &[u8], _: &CertificateDer<'_>, _: &DigitallySignedStruct) -> Result<HandshakeSignatureValid, Error> {
40 Ok(HandshakeSignatureValid::assertion())
41 }
42 fn supported_verify_schemes(&self) -> Vec<SignatureScheme> {
43 schemes()
44 }
45 };
46}
47
48/// Accepts all certificates, logs info
49#[derive(Debug)]
50pub struct LoggingVerifier;
51
52impl ServerCertVerifier for LoggingVerifier {
53 fn verify_server_cert(&self, cert: &CertificateDer<'_>, intermediates: &[CertificateDer<'_>], _: &ServerName<'_>, _: &[u8], _: UnixTime) -> Result<ServerCertVerified, Error> {
54 println!("\n=== Server Certificate ===");
55 match X509Certificate::from_der(cert.as_ref()) {
56 Ok((_, x)) => {
57 println!("Subject: {}", x.subject());
58 println!("Issuer: {}", x.issuer());
59 println!("SHA256: {}", fingerprint(cert, true));
60 if x.subject() == x.issuer() { println!("Type: Self-Signed"); }
61 }
62 Err(e) => println!("Parse failed: {}", e),
63 }
64 for (i, c) in intermediates.iter().enumerate() {
65 if let Ok((_, x)) = X509Certificate::from_der(c.as_ref()) {
66 println!("Intermediate #{}: {}", i + 1, x.subject());
67 }
68 }
69 println!("Chain length: {}\n", 1 + intermediates.len());
70 Ok(ServerCertVerified::assertion())
71 }
72 impl_verifier_base!();
73}