Skip to main content

uselesskey_core_rustls_pki/
lib.rs

1//! rustls-pki-types adapter traits for uselesskey fixtures.
2//!
3//! This crate is intentionally focused on PKI conversion only:
4//! converting fixture outputs into `rustls_pki_types` key and certificate types.
5
6#![forbid(unsafe_code)]
7#![warn(missing_docs)]
8
9use rustls_pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
10
11/// Extension trait to convert uselesskey fixtures into `PrivateKeyDer`.
12///
13/// Implemented for types that have a PKCS#8 DER private key.
14pub trait RustlsPrivateKeyExt {
15    /// Convert the private key to a `PrivateKeyDer<'static>` (PKCS#8 variant).
16    fn private_key_der_rustls(&self) -> PrivateKeyDer<'static>;
17}
18
19/// Extension trait to convert uselesskey X.509 fixtures into `CertificateDer`.
20///
21/// Implemented for types that represent a single certificate.
22pub trait RustlsCertExt {
23    /// Convert the certificate to a `CertificateDer<'static>`.
24    fn certificate_der_rustls(&self) -> CertificateDer<'static>;
25}
26
27/// Extension trait for X.509 certificate chains.
28///
29/// Provides the full chain in rustls format.
30#[cfg(feature = "x509")]
31pub trait RustlsChainExt {
32    /// Get the certificate chain as a `Vec<CertificateDer>` (leaf + intermediate, no root).
33    ///
34    /// This is the format expected by `rustls::ServerConfig`.
35    fn chain_der_rustls(&self) -> Vec<CertificateDer<'static>>;
36
37    /// Get the root CA certificate as a `CertificateDer`.
38    ///
39    /// Use this to add to a `RootCertStore` for client-side verification.
40    fn root_certificate_der_rustls(&self) -> CertificateDer<'static>;
41}
42
43#[cfg(feature = "x509")]
44impl RustlsPrivateKeyExt for uselesskey_x509::X509Cert {
45    fn private_key_der_rustls(&self) -> PrivateKeyDer<'static> {
46        PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
47            self.private_key_pkcs8_der().to_vec(),
48        ))
49    }
50}
51
52#[cfg(feature = "x509")]
53impl RustlsCertExt for uselesskey_x509::X509Cert {
54    fn certificate_der_rustls(&self) -> CertificateDer<'static> {
55        CertificateDer::from(self.cert_der().to_vec())
56    }
57}
58
59#[cfg(feature = "x509")]
60impl RustlsPrivateKeyExt for uselesskey_x509::X509Chain {
61    fn private_key_der_rustls(&self) -> PrivateKeyDer<'static> {
62        PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
63            self.leaf_private_key_pkcs8_der().to_vec(),
64        ))
65    }
66}
67
68#[cfg(feature = "x509")]
69impl RustlsCertExt for uselesskey_x509::X509Chain {
70    fn certificate_der_rustls(&self) -> CertificateDer<'static> {
71        CertificateDer::from(self.leaf_cert_der().to_vec())
72    }
73}
74
75#[cfg(feature = "x509")]
76impl RustlsChainExt for uselesskey_x509::X509Chain {
77    fn chain_der_rustls(&self) -> Vec<CertificateDer<'static>> {
78        vec![
79            CertificateDer::from(self.leaf_cert_der().to_vec()),
80            CertificateDer::from(self.intermediate_cert_der().to_vec()),
81        ]
82    }
83
84    fn root_certificate_der_rustls(&self) -> CertificateDer<'static> {
85        CertificateDer::from(self.root_cert_der().to_vec())
86    }
87}
88
89#[cfg(feature = "rsa")]
90impl RustlsPrivateKeyExt for uselesskey_rsa::RsaKeyPair {
91    fn private_key_der_rustls(&self) -> PrivateKeyDer<'static> {
92        PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
93            self.private_key_pkcs8_der().to_vec(),
94        ))
95    }
96}
97
98#[cfg(feature = "ecdsa")]
99impl RustlsPrivateKeyExt for uselesskey_ecdsa::EcdsaKeyPair {
100    fn private_key_der_rustls(&self) -> PrivateKeyDer<'static> {
101        PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
102            self.private_key_pkcs8_der().to_vec(),
103        ))
104    }
105}
106
107#[cfg(feature = "ed25519")]
108impl RustlsPrivateKeyExt for uselesskey_ed25519::Ed25519KeyPair {
109    fn private_key_der_rustls(&self) -> PrivateKeyDer<'static> {
110        PrivateKeyDer::Pkcs8(PrivatePkcs8KeyDer::from(
111            self.private_key_pkcs8_der().to_vec(),
112        ))
113    }
114}
115
116#[cfg(test)]
117mod tests {
118    #[cfg(feature = "x509")]
119    mod x509_tests {
120        use crate::{RustlsCertExt, RustlsChainExt, RustlsPrivateKeyExt};
121        use uselesskey_x509::{ChainSpec, X509FactoryExt, X509Spec};
122
123        #[test]
124        fn test_self_signed_private_key() {
125            let fx = uselesskey_core::Factory::random();
126            let cert = fx.x509_self_signed("test", X509Spec::self_signed("test.example.com"));
127
128            let key = cert.private_key_der_rustls();
129            assert_eq!(key.secret_der(), cert.private_key_pkcs8_der());
130        }
131
132        #[test]
133        fn test_self_signed_certificate() {
134            let fx = uselesskey_core::Factory::random();
135            let cert = fx.x509_self_signed("test", X509Spec::self_signed("test.example.com"));
136
137            let cert_der = cert.certificate_der_rustls();
138            assert_eq!(cert_der.as_ref(), cert.cert_der());
139        }
140
141        #[test]
142        fn test_chain_private_key() {
143            let fx = uselesskey_core::Factory::random();
144            let chain = fx.x509_chain("test", ChainSpec::new("test.example.com"));
145
146            let key = chain.private_key_der_rustls();
147            assert_eq!(key.secret_der(), chain.leaf_private_key_pkcs8_der());
148        }
149
150        #[test]
151        fn test_chain_certificate() {
152            let fx = uselesskey_core::Factory::random();
153            let chain = fx.x509_chain("test", ChainSpec::new("test.example.com"));
154
155            let cert_der = chain.certificate_der_rustls();
156            assert_eq!(cert_der.as_ref(), chain.leaf_cert_der());
157        }
158
159        #[test]
160        fn test_chain_der_rustls() {
161            let fx = uselesskey_core::Factory::random();
162            let chain = fx.x509_chain("test", ChainSpec::new("test.example.com"));
163
164            let chain_certs = chain.chain_der_rustls();
165            assert_eq!(chain_certs.len(), 2);
166            assert_eq!(chain_certs[0].as_ref(), chain.leaf_cert_der());
167            assert_eq!(chain_certs[1].as_ref(), chain.intermediate_cert_der());
168        }
169
170        #[test]
171        fn test_root_certificate() {
172            let fx = uselesskey_core::Factory::random();
173            let chain = fx.x509_chain("test", ChainSpec::new("test.example.com"));
174
175            let root = chain.root_certificate_der_rustls();
176            assert_eq!(root.as_ref(), chain.root_cert_der());
177        }
178    }
179
180    #[cfg(feature = "rsa")]
181    mod rsa_tests {
182        use crate::RustlsPrivateKeyExt;
183        use uselesskey_rsa::{RsaFactoryExt, RsaSpec};
184
185        #[test]
186        fn test_rsa_private_key() {
187            let fx = uselesskey_core::Factory::random();
188            let keypair = fx.rsa("test", RsaSpec::rs256());
189
190            let key = keypair.private_key_der_rustls();
191            assert_eq!(key.secret_der(), keypair.private_key_pkcs8_der());
192        }
193    }
194
195    #[cfg(feature = "ecdsa")]
196    mod ecdsa_tests {
197        use crate::RustlsPrivateKeyExt;
198        use uselesskey_ecdsa::{EcdsaFactoryExt, EcdsaSpec};
199
200        #[test]
201        fn test_ecdsa_es256_private_key() {
202            let fx = uselesskey_core::Factory::random();
203            let keypair = fx.ecdsa("test", EcdsaSpec::es256());
204
205            let key = keypair.private_key_der_rustls();
206            assert_eq!(key.secret_der(), keypair.private_key_pkcs8_der());
207        }
208
209        #[test]
210        fn test_ecdsa_es384_private_key() {
211            let fx = uselesskey_core::Factory::random();
212            let keypair = fx.ecdsa("test", EcdsaSpec::es384());
213
214            let key = keypair.private_key_der_rustls();
215            assert_eq!(key.secret_der(), keypair.private_key_pkcs8_der());
216        }
217    }
218
219    #[cfg(feature = "ed25519")]
220    mod ed25519_tests {
221        use crate::RustlsPrivateKeyExt;
222        use uselesskey_ed25519::{Ed25519FactoryExt, Ed25519Spec};
223
224        #[test]
225        fn test_ed25519_private_key() {
226            let fx = uselesskey_core::Factory::random();
227            let keypair = fx.ed25519("test", Ed25519Spec::new());
228
229            let key = keypair.private_key_der_rustls();
230            assert_eq!(key.secret_der(), keypair.private_key_pkcs8_der());
231        }
232    }
233}