From df5f4f723e76bb99fef4aa5bd0b6b30848042503 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 2 May 2021 00:16:39 +0800 Subject: [PATCH] feat: x509 --- Cargo.lock | 141 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/config.rs | 5 ++ src/main.rs | 2 + src/sample_cert.pem | 30 ++++++++ src/simple_thread_pool.rs | 60 ++++++++++++++++ src/x509.rs | 28 ++++++++ 7 files changed, 267 insertions(+) create mode 100644 src/sample_cert.pem create mode 100644 src/simple_thread_pool.rs create mode 100644 src/x509.rs diff --git a/Cargo.lock b/Cargo.lock index c9f72d9..ab3aeb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "rust_util", "serde", "tide", + "x509-parser", ] [[package]] @@ -382,6 +383,18 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitvec" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake3" version = "0.3.7" @@ -646,6 +659,31 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +[[package]] +name = "der-oid-macro" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4cccf60bb98c0fca115a581f894aed0e43fa55bf289fdac5599bec440bb4fd6" +dependencies = [ + "nom", + "num-bigint", + "num-traits", + "syn", +] + +[[package]] +name = "der-parser" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120842c2385dea19347e2f6e31caa5dced5ba8afdfacaac16c59465fdd1168f2" +dependencies = [ + "der-oid-macro", + "nom", + "num-bigint", + "num-traits", + "rusticata-macros", +] + [[package]] name = "deser-hjson" version = "0.1.12" @@ -747,6 +785,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "futures-channel" version = "0.3.14" @@ -1008,6 +1052,19 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lexical-core" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" +dependencies = [ + "arrayvec", + "bitflags", + "cfg-if 1.0.0", + "ryu", + "static_assertions", +] + [[package]] name = "libc" version = "0.2.94" @@ -1036,6 +1093,30 @@ version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec", + "funty", + "lexical-core", + "memchr", + "version_check", +] + +[[package]] +name = "num-bigint" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e0d047c1062aa51e256408c560894e5251f08925980e53cf1aa5bd00eec6512" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-integer" version = "0.1.44" @@ -1065,6 +1146,15 @@ dependencies = [ "libc", ] +[[package]] +name = "oid-registry" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2508c8f170e55be68508b1113956a760a82684f42022f8834fb16ca198621211" +dependencies = [ + "der-parser", +] + [[package]] name = "once_cell" version = "1.7.2" @@ -1239,6 +1329,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + [[package]] name = "rand" version = "0.7.3" @@ -1381,6 +1477,15 @@ dependencies = [ "semver", ] +[[package]] +name = "rusticata-macros" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7390af60e66c44130b4c5ea85f2555b7ace835d73b4b889c704dc3cb4c0468c8" +dependencies = [ + "nom", +] + [[package]] name = "rustls" version = "0.19.1" @@ -1570,6 +1675,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stdweb" version = "0.4.20" @@ -1648,6 +1759,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "term" version = "0.7.0" @@ -2042,3 +2159,27 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + +[[package]] +name = "x509-parser" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64abca276c58f8341ddc13fd4bd6ae75993cc669043f5b34813c90f7dff04771" +dependencies = [ + "base64 0.13.0", + "chrono", + "data-encoding", + "der-parser", + "lazy_static", + "nom", + "oid-registry", + "rusticata-macros", + "rustversion", + "thiserror", +] diff --git a/Cargo.toml b/Cargo.toml index d28d640..485dac7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ tide = "0.16" async-std = { version = "1.8", features = ["attributes"] } serde = { version = "1.0", features = ["derive"] } deser-hjson = "0.1" +x509-parser = "0.9.2" diff --git a/src/config.rs b/src/config.rs index 394b38a..e43fd2e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -79,6 +79,7 @@ pub struct AcmeConfig { pub dir: String, pub auth_timeout: Option, pub csr_timeout: Option, + pub concurrent: Option, // ? } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -103,6 +104,10 @@ impl AcmeConfig { pub fn get_csr_timeout(&self) -> u64 { self.csr_timeout.unwrap_or(5_000) } + + pub fn get_concurrent(&self) -> u32 { + self.concurrent.unwrap_or(0) + } } impl CertConfigItem { diff --git a/src/main.rs b/src/main.rs index 1ba68a2..1ac6996 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,8 @@ extern crate lazy_static; extern crate rust_util; mod config; +mod x509; +mod simple_thread_pool; use rust_util::XResult; use acme_lib::{DirectoryUrl, Directory}; diff --git a/src/sample_cert.pem b/src/sample_cert.pem new file mode 100644 index 0000000..d853b15 --- /dev/null +++ b/src/sample_cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFLzCCBBegAwIBAgISA/crxAcU6d5dXfB8WprCO3F2MA0GCSqGSIb3DQEBCwUA +MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD +EwJSMzAeFw0yMTAzMjExMTA1MzlaFw0yMTA2MTkxMTA1MzlaMBcxFTATBgNVBAMT +DHppZ3N0YWNrLm9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIKS +WNIiChA7I+GKzAQCsP5gNaVuNxGOmfkAzCy9iPPLBaG/bYDATnXQgvKwA+M0uqkD +9g21ZLMadZ0yEEpLuFMWQAgpBXNs3dEaBdKLRywMJEI4NVwFMRy7vFcRqs7tpcvZ +DavIJ7tnwznBykweEn5VSSwxiUDex+uTldA20Ep9FIkTvT2BB6oOaaFiCq7n86AA +kuxHvmvX/6tz+faL8hntWRwPxZA97/dpFobfX0i6P33BPvRAoqpoQQevfA6RiB/j +8TlUr/zeYOTsfBl3E1J6Bm1rAx8n6csj9quY8hFy5/gcJIhCFmSx+YjdvyD/laPo +ZDyEUsWNA3PHV59n0CECAwEAAaOCAlgwggJUMA4GA1UdDwEB/wQEAwIFoDAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4E +FgQUXZjy4SEu/3OoM48AdTCzy892h0gwHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA +5h+vnYsUwsYwVQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vcjMu +by5sZW5jci5vcmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9yZy8w +KQYDVR0RBCIwIIIQd3d3LnppZ3N0YWNrLm9yZ4IMemlnc3RhY2sub3JnMEwGA1Ud +IARFMEMwCAYGZ4EMAQIBMDcGCysGAQQBgt8TAQEBMCgwJgYIKwYBBQUHAgEWGmh0 +dHA6Ly9jcHMubGV0c2VuY3J5cHQub3JnMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDv +AHUAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbHDsoAAAF4VK0xGQAABAMA +RjBEAiBBEcIEe9KGuQJHySF/XYfLjJInOME5uiyU9th2WqZH8QIgAhlfHiehfpIY +EaVLJbCmAccPJHJEj4uYroAxJc9qYVAAdgD2XJQv0XcwIhRUGAgwlFaO400TGTO/ +3wwvIAvMTvFk4wAAAXhUrTFBAAAEAwBHMEUCIFSZOj3WOb+lRMRVxlTpM7bS+J8b +DxI1BgGVRMK1h70gAiEA5AQ3XnYal1fo713SzvT9qErr604Y2j41JLNU7OiaNAsw +DQYJKoZIhvcNAQELBQADggEBAGAQeTCB+Xllw3TgATPtwP/Q2znV80T59P3QuGtQ +O3F9ioBRYTP5JhnOEuWrarSqPLlz8/Z6wcoYN5T53/tEmUdGVMVrteN170Cc99XQ +Gl/Yahy5eK3blCm7jDU3Zpo5JjHexKBFeMrwE3kZii0/T9q8YV+7QbBhfND4IzYv +QyE/Tf3hmb7ETmn8FtN60cPGwmI5KWrknsYmAcdgW6q8c1MUMmsrBYMm3bTdQBL2 +N1/zk8KYO+ZaBeUBNtEvBAS0/4WcDNcgsE9qts9dQekWZydrEb2Txbz45cNfbUpa +3AwcPmNAmvcFqumUoBUKeaSl4gK1FIhgBdeivD+zjEKGaXI= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/simple_thread_pool.rs b/src/simple_thread_pool.rs new file mode 100644 index 0000000..088812d --- /dev/null +++ b/src/simple_thread_pool.rs @@ -0,0 +1,60 @@ +use rust_util::XResult; +use std::thread; +use std::thread::JoinHandle; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::Arc; +use std::time::Duration; + +pub struct SimpleThreadPool { + max_pool_size: u32, + running_pool_size: Arc, +} + +impl SimpleThreadPool { + pub fn new(max_pool_size: u32) -> XResult { + if max_pool_size > 20 { + return simple_error!("Illegal pool size: {}", max_pool_size); + } + Ok(Self { + max_pool_size, + running_pool_size: Arc::new(AtomicU32::new(0)), + }) + } + + pub fn submit(&mut self, f: F) -> Option> where + F: FnOnce() -> (), + F: Send + 'static, + { + let running = self.running_pool_size.fetch_add(1, Ordering::SeqCst); + let running_pool_size_clone = self.running_pool_size.clone(); + if running < self.max_pool_size { + Some(thread::spawn(move || { + f(); + running_pool_size_clone.fetch_sub(1, Ordering::SeqCst); + })) + } else { + f(); + self.running_pool_size.fetch_sub(1, Ordering::SeqCst); + None + } + } +} + +#[test] +fn test_simple_thread_pool() { + let mut stp = SimpleThreadPool::new(2).unwrap(); + let mut handlers = vec![]; + for i in 1..10 { + if let Some(h) = stp.submit(move || { + println!("Task start: {}", i); + thread::sleep(Duration::from_secs(1)); + println!("Task end: {}", i); + }) { + handlers.push(h); + } + } + + for h in handlers { + h.join().unwrap(); + } +} \ No newline at end of file diff --git a/src/x509.rs b/src/x509.rs new file mode 100644 index 0000000..0c8f03c --- /dev/null +++ b/src/x509.rs @@ -0,0 +1,28 @@ +use x509_parser::parse_x509_certificate; +use x509_parser::pem::parse_x509_pem; +use x509_parser::extensions::ParsedExtension; +use x509_parser::der_parser::oid::Oid; + +#[test] +fn test_x509() { + let pem = include_str!("sample_cert.pem"); + let (_, parsed_pem) = parse_x509_pem(pem.as_bytes()).unwrap(); + let (_, cert) = parse_x509_certificate(parsed_pem.contents.as_slice()).unwrap(); + // println!("{:?}", cert); + // println!("{:#?}", cert.subject().iter_common_name()); + cert.subject().iter_common_name().for_each(|c| { + use std::str::FromStr; + if c.attr_type == Oid::from_str("2.5.4.3").unwrap() { + println!("{:?}", c.attr_value.content.as_str().unwrap()); + } + }); + // println!("{:#?}", cert.extensions()); + for (oid, ext) in cert.extensions().iter() { + match ext.parsed_extension() { + ParsedExtension::SubjectAlternativeName(san) => { + println!("{:?}", san); + } + _ => {} + } + } +} \ No newline at end of file