1#![forbid(unsafe_code)]
2
3#![cfg_attr(feature = "rsa", doc = "```")]
23#![cfg_attr(not(feature = "rsa"), doc = "```ignore")]
24#[cfg(feature = "rsa")]
40pub trait RingRsaKeyPairExt {
41 fn rsa_key_pair_ring(&self) -> ring::rsa::KeyPair;
43}
44
45#[cfg(feature = "rsa")]
46impl RingRsaKeyPairExt for uselesskey_rsa::RsaKeyPair {
47 fn rsa_key_pair_ring(&self) -> ring::rsa::KeyPair {
48 ring::rsa::KeyPair::from_pkcs8(self.private_key_pkcs8_der()).expect("valid RSA PKCS#8 DER")
49 }
50}
51
52#[cfg(feature = "ecdsa")]
57use ring::signature::{
58 ECDSA_P256_SHA256_ASN1_SIGNING, ECDSA_P384_SHA384_ASN1_SIGNING,
59 EcdsaKeyPair as RingEcdsaKeyPair, EcdsaSigningAlgorithm,
60};
61
62#[cfg(feature = "ecdsa")]
64pub trait RingEcdsaKeyPairExt {
65 fn ecdsa_key_pair_ring(&self) -> RingEcdsaKeyPair;
70}
71
72#[cfg(feature = "ecdsa")]
73impl RingEcdsaKeyPairExt for uselesskey_ecdsa::EcdsaKeyPair {
74 fn ecdsa_key_pair_ring(&self) -> RingEcdsaKeyPair {
75 let alg: &'static EcdsaSigningAlgorithm = match self.spec() {
76 uselesskey_ecdsa::EcdsaSpec::Es256 => &ECDSA_P256_SHA256_ASN1_SIGNING,
77 uselesskey_ecdsa::EcdsaSpec::Es384 => &ECDSA_P384_SHA384_ASN1_SIGNING,
78 };
79 RingEcdsaKeyPair::from_pkcs8(
80 alg,
81 self.private_key_pkcs8_der(),
82 &ring::rand::SystemRandom::new(),
83 )
84 .expect("valid ECDSA PKCS#8 DER")
85 }
86}
87
88#[cfg(feature = "ed25519")]
94pub trait RingEd25519KeyPairExt {
95 fn ed25519_key_pair_ring(&self) -> ring::signature::Ed25519KeyPair;
97}
98
99#[cfg(feature = "ed25519")]
100impl RingEd25519KeyPairExt for uselesskey_ed25519::Ed25519KeyPair {
101 fn ed25519_key_pair_ring(&self) -> ring::signature::Ed25519KeyPair {
102 ring::signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(self.private_key_pkcs8_der())
103 .expect("valid Ed25519 PKCS#8 DER")
104 }
105}
106
107#[cfg(test)]
112mod tests {
113 use std::sync::OnceLock;
114 use uselesskey_core::{Factory, Seed};
115
116 static FX: OnceLock<Factory> = OnceLock::new();
117
118 fn fx() -> Factory {
119 FX.get_or_init(|| {
120 let seed = Seed::from_env_value("uselesskey-ring-inline-test-seed-v1")
121 .expect("test seed should always parse");
122 Factory::deterministic(seed)
123 })
124 .clone()
125 }
126
127 #[cfg(feature = "rsa")]
128 mod rsa_tests {
129 use crate::RingRsaKeyPairExt;
130 use ring::signature;
131 use uselesskey_rsa::{RsaFactoryExt, RsaSpec};
132
133 #[test]
134 fn test_rsa_sign_verify() {
135 let fx = super::fx();
136 let rsa = fx.rsa("test", RsaSpec::rs256());
137 let ring_kp = rsa.rsa_key_pair_ring();
138
139 let msg = b"test message";
140 let rng = ring::rand::SystemRandom::new();
141 let mut sig = vec![0u8; ring_kp.public().modulus_len()];
142 ring_kp
143 .sign(&signature::RSA_PKCS1_SHA256, &rng, msg, &mut sig)
144 .expect("sign");
145
146 let public_key_bytes = ring_kp.public().as_ref();
147 let public_key = signature::UnparsedPublicKey::new(
148 &signature::RSA_PKCS1_2048_8192_SHA256,
149 public_key_bytes,
150 );
151 public_key.verify(msg, &sig).expect("verify");
152 }
153 }
154
155 #[cfg(feature = "rsa")]
156 mod rsa_deterministic_tests {
157 use crate::RingRsaKeyPairExt;
158 use ring::signature;
159 use uselesskey_core::{Factory, Seed};
160 use uselesskey_rsa::{RsaFactoryExt, RsaSpec};
161
162 #[test]
163 fn test_rsa_deterministic_sign_verify() {
164 let seed = Seed::from_env_value("test-seed").unwrap();
165 let fx = Factory::deterministic(seed);
166 let rsa = fx.rsa("det-test", RsaSpec::rs256());
167 let ring_kp = rsa.rsa_key_pair_ring();
168
169 let msg = b"deterministic message";
170 let rng = ring::rand::SystemRandom::new();
171 let mut sig = vec![0u8; ring_kp.public().modulus_len()];
172 ring_kp
173 .sign(&signature::RSA_PKCS1_SHA256, &rng, msg, &mut sig)
174 .expect("sign");
175
176 let public_key_bytes = ring_kp.public().as_ref();
177 let public_key = signature::UnparsedPublicKey::new(
178 &signature::RSA_PKCS1_2048_8192_SHA256,
179 public_key_bytes,
180 );
181 public_key.verify(msg, &sig).expect("verify");
182 }
183 }
184
185 #[cfg(feature = "ecdsa")]
186 mod ecdsa_tests {
187 use crate::RingEcdsaKeyPairExt;
188 use ring::signature::{self, KeyPair};
189 use uselesskey_core::Factory;
190 use uselesskey_ecdsa::{EcdsaFactoryExt, EcdsaSpec};
191
192 #[test]
193 fn test_ecdsa_p256_sign_verify() {
194 let fx = Factory::random();
195 let ecdsa = fx.ecdsa("test", EcdsaSpec::es256());
196 let ring_kp = ecdsa.ecdsa_key_pair_ring();
197
198 let msg = b"test message";
199 let rng = ring::rand::SystemRandom::new();
200 let sig = ring_kp.sign(&rng, msg).expect("sign");
201
202 let public_key_bytes = ring_kp.public_key().as_ref();
203 let public_key = signature::UnparsedPublicKey::new(
204 &signature::ECDSA_P256_SHA256_ASN1,
205 public_key_bytes,
206 );
207 public_key.verify(msg, sig.as_ref()).expect("verify");
208 }
209
210 #[test]
211 fn test_ecdsa_p384_sign_verify() {
212 let fx = Factory::random();
213 let ecdsa = fx.ecdsa("test", EcdsaSpec::es384());
214 let ring_kp = ecdsa.ecdsa_key_pair_ring();
215
216 let msg = b"test message";
217 let rng = ring::rand::SystemRandom::new();
218 let sig = ring_kp.sign(&rng, msg).expect("sign");
219
220 let public_key_bytes = ring_kp.public_key().as_ref();
221 let public_key = signature::UnparsedPublicKey::new(
222 &signature::ECDSA_P384_SHA384_ASN1,
223 public_key_bytes,
224 );
225 public_key.verify(msg, sig.as_ref()).expect("verify");
226 }
227 }
228
229 #[cfg(feature = "ed25519")]
230 mod ed25519_tests {
231 use crate::RingEd25519KeyPairExt;
232 use ring::signature::{self, KeyPair};
233 use uselesskey_core::Factory;
234 use uselesskey_ed25519::{Ed25519FactoryExt, Ed25519Spec};
235
236 #[test]
237 fn test_ed25519_sign_verify() {
238 let fx = Factory::random();
239 let ed = fx.ed25519("test", Ed25519Spec::new());
240 let ring_kp = ed.ed25519_key_pair_ring();
241
242 let msg = b"test message";
243 let sig = ring_kp.sign(msg);
244
245 let public_key_bytes = ring_kp.public_key().as_ref();
246 let public_key =
247 signature::UnparsedPublicKey::new(&signature::ED25519, public_key_bytes);
248 public_key.verify(msg, sig.as_ref()).expect("verify");
249 }
250 }
251}