Skip to main content

uselesskey_rustls/srp/
pki.rs

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