1use {
6 crate::{
7 rfc3447::RsaPrivateKey, rfc5958::OneAsymmetricKey, EcdsaCurve, KeyAlgorithm,
8 SignatureAlgorithm, X509CertificateError as Error,
9 },
10 bcder::decode::Constructed,
11 bytes::Bytes,
12 der::SecretDocument,
13 ring::{
14 rand::SystemRandom,
15 signature::{self as ringsig, KeyPair},
16 },
17 signature::{SignatureEncoding as SignatureTrait, Signer},
18 zeroize::Zeroizing,
19};
20
21pub trait Sign {
23 #[deprecated(since = "0.13.0", note = "use the signature::Signer trait instead")]
31 fn sign(&self, message: &[u8]) -> Result<(Vec<u8>, SignatureAlgorithm), Error>;
32
33 fn key_algorithm(&self) -> Option<KeyAlgorithm>;
37
38 fn public_key_data(&self) -> Bytes;
43
44 fn signature_algorithm(&self) -> Result<SignatureAlgorithm, Error>;
49
50 fn private_key_data(&self) -> Option<Zeroizing<Vec<u8>>>;
52
53 fn rsa_primes(&self) -> Result<Option<(Zeroizing<Vec<u8>>, Zeroizing<Vec<u8>>)>, Error>;
55}
56
57pub trait KeyInfoSigner: Signer<Signature> + Sign {}
59
60#[derive(Clone, Debug)]
61pub struct Signature(Vec<u8>);
62
63impl From<Vec<u8>> for Signature {
64 fn from(v: Vec<u8>) -> Self {
65 Self(v)
66 }
67}
68
69impl From<Signature> for Vec<u8> {
70 fn from(v: Signature) -> Vec<u8> {
71 v.0
72 }
73}
74
75impl From<Signature> for Bytes {
76 fn from(v: Signature) -> Self {
77 Self::copy_from_slice(&v.0)
78 }
79}
80
81impl AsRef<[u8]> for Signature {
82 fn as_ref(&self) -> &[u8] {
83 &self.0
84 }
85}
86
87impl SignatureTrait for Signature {
88 type Repr = Vec<u8>;
89}
90
91impl TryFrom<&[u8]> for Signature {
92 type Error = ();
93
94 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
95 Ok(Self(value.to_vec()))
96 }
97}
98
99#[derive(Debug)]
101pub struct EcdsaKeyPair {
102 pkcs8_der: SecretDocument,
103 ring_pair: ringsig::EcdsaKeyPair,
104 curve: EcdsaCurve,
105 private_key: Zeroizing<Vec<u8>>,
106}
107
108#[derive(Debug)]
110pub struct Ed25519KeyPair {
111 pkcs8_der: SecretDocument,
112 ring_pair: ringsig::Ed25519KeyPair,
113}
114
115#[derive(Debug)]
117pub struct RsaKeyPair {
118 pkcs8_der: SecretDocument,
119 ring_pair: ringsig::RsaKeyPair,
120 private_key: Zeroizing<Vec<u8>>,
121}
122
123#[derive(Debug)]
128pub enum InMemorySigningKeyPair {
129 Ecdsa(Box<EcdsaKeyPair>),
131
132 Ed25519(Box<Ed25519KeyPair>),
134
135 Rsa(Box<RsaKeyPair>),
137}
138
139impl Signer<Signature> for InMemorySigningKeyPair {
140 fn try_sign(&self, msg: &[u8]) -> Result<Signature, signature::Error> {
141 match self {
142 Self::Rsa(kp) => {
143 let mut signature = vec![0; kp.ring_pair.public().modulus_len()];
144
145 kp.ring_pair
146 .sign(
147 &ringsig::RSA_PKCS1_SHA256,
148 &ring::rand::SystemRandom::new(),
149 msg,
150 &mut signature,
151 )
152 .map_err(|_| signature::Error::new())?;
153
154 Ok(signature.into())
155 }
156 Self::Ecdsa(kp) => {
157 let signature = kp
158 .ring_pair
159 .sign(&ring::rand::SystemRandom::new(), msg)
160 .map_err(|_| signature::Error::new())?;
161
162 Ok(Signature::from(signature.as_ref().to_vec()))
163 }
164 Self::Ed25519(kp) => {
165 let signature = kp.ring_pair.sign(msg);
166
167 Ok(Signature::from(signature.as_ref().to_vec()))
168 }
169 }
170 }
171}
172
173impl Sign for InMemorySigningKeyPair {
174 fn sign(&self, message: &[u8]) -> Result<(Vec<u8>, SignatureAlgorithm), Error> {
180 let algorithm = self.signature_algorithm()?;
181
182 Ok((self.try_sign(message)?.into(), algorithm))
183 }
184
185 fn key_algorithm(&self) -> Option<KeyAlgorithm> {
186 Some(match self {
187 Self::Rsa(_) => KeyAlgorithm::Rsa,
188 Self::Ed25519(_) => KeyAlgorithm::Ed25519,
189 Self::Ecdsa(kp) => KeyAlgorithm::Ecdsa(kp.curve),
190 })
191 }
192
193 fn public_key_data(&self) -> Bytes {
194 match self {
195 Self::Rsa(kp) => Bytes::copy_from_slice(kp.ring_pair.public_key().as_ref()),
196 Self::Ecdsa(kp) => Bytes::copy_from_slice(kp.ring_pair.public_key().as_ref()),
197 Self::Ed25519(kp) => Bytes::copy_from_slice(kp.ring_pair.public_key().as_ref()),
198 }
199 }
200
201 fn signature_algorithm(&self) -> Result<SignatureAlgorithm, Error> {
202 Ok(match self {
203 Self::Rsa(_) => SignatureAlgorithm::RsaSha256,
204 Self::Ecdsa(kp) => {
205 match kp.curve {
209 EcdsaCurve::Secp256r1 => SignatureAlgorithm::EcdsaSha256,
210 EcdsaCurve::Secp384r1 => SignatureAlgorithm::EcdsaSha384,
211 }
212 }
213 Self::Ed25519(_) => SignatureAlgorithm::Ed25519,
214 })
215 }
216
217 fn private_key_data(&self) -> Option<Zeroizing<Vec<u8>>> {
218 match self {
219 Self::Rsa(kp) => Some(kp.private_key.clone()),
220 Self::Ecdsa(kp) => Some(kp.private_key.clone()),
221 Self::Ed25519(_) => None,
222 }
223 }
224
225 fn rsa_primes(&self) -> Result<Option<(Zeroizing<Vec<u8>>, Zeroizing<Vec<u8>>)>, Error> {
226 match self {
227 Self::Rsa(kp) => {
228 let key = Constructed::decode(kp.private_key.as_ref(), bcder::Mode::Der, |cons| {
229 RsaPrivateKey::take_from(cons)
230 })?;
231
232 Ok(Some((
233 Zeroizing::new(key.p.as_slice().to_vec()),
234 Zeroizing::new(key.q.as_slice().to_vec()),
235 )))
236 }
237 Self::Ecdsa(_) => Ok(None),
238 Self::Ed25519(_) => Ok(None),
239 }
240 }
241}
242
243impl KeyInfoSigner for InMemorySigningKeyPair {}
244
245impl InMemorySigningKeyPair {
246 pub fn from_pkcs8_der(data: impl AsRef<[u8]>) -> Result<Self, Error> {
250 let pkcs8_der = SecretDocument::try_from(data.as_ref())?;
251
252 let key = Constructed::decode(data.as_ref(), bcder::Mode::Der, |cons| {
254 OneAsymmetricKey::take_from(cons)
255 })?;
256
257 let algorithm = KeyAlgorithm::try_from(&key.private_key_algorithm)?;
258
259 match algorithm {
262 KeyAlgorithm::Rsa => {
263 let pair = ringsig::RsaKeyPair::from_pkcs8(data.as_ref())?;
264
265 Ok(Self::Rsa(Box::new(RsaKeyPair {
266 pkcs8_der,
267 ring_pair: pair,
268 private_key: Zeroizing::new(key.private_key.into_bytes().to_vec()),
269 })))
270 }
271 KeyAlgorithm::Ecdsa(curve) => {
272 let pair = ringsig::EcdsaKeyPair::from_pkcs8(
273 curve.into(),
274 data.as_ref(),
275 &SystemRandom::new(),
276 )?;
277
278 Ok(Self::Ecdsa(Box::new(EcdsaKeyPair {
279 pkcs8_der,
280 ring_pair: pair,
281 curve,
282 private_key: Zeroizing::new(data.as_ref().to_vec()),
283 })))
284 }
285 KeyAlgorithm::Ed25519 => Ok(Self::Ed25519(Box::new(Ed25519KeyPair {
286 pkcs8_der,
287 ring_pair: ringsig::Ed25519KeyPair::from_pkcs8(data.as_ref())?,
288 }))),
289 }
290 }
291
292 pub fn from_pkcs8_pem(data: impl AsRef<[u8]>) -> Result<Self, Error> {
297 let der = pem::parse(data.as_ref()).map_err(Error::PemDecode)?;
298
299 Self::from_pkcs8_der(der.contents())
300 }
301
302 pub fn generate_random(key_algorithm: KeyAlgorithm) -> Result<Self, Error> {
308 let rng = SystemRandom::new();
309
310 let document = match key_algorithm {
311 KeyAlgorithm::Ed25519 => ringsig::Ed25519KeyPair::generate_pkcs8(&rng)
312 .map_err(|_| Error::KeyPairGenerationError),
313 KeyAlgorithm::Ecdsa(curve) => ringsig::EcdsaKeyPair::generate_pkcs8(curve.into(), &rng)
314 .map_err(|_| Error::KeyPairGenerationError),
315 KeyAlgorithm::Rsa => Err(Error::RsaKeyGenerationNotSupported),
316 }?;
317
318 Self::from_pkcs8_der(document.as_ref())
319 }
320
321 pub fn verification_algorithm(
328 &self,
329 ) -> Result<&'static dyn ringsig::VerificationAlgorithm, Error> {
330 Ok(self.signature_algorithm()?
331 .resolve_verification_algorithm(self.key_algorithm().expect("key algorithm should be known for InMemorySigningKeyPair")).expect(
332 "illegal combination of key algorithm in signature algorithm: this should not occur"
333 ))
334 }
335
336 pub fn to_pkcs8_one_asymmetric_key_der(&self) -> Zeroizing<Vec<u8>> {
338 match self {
339 Self::Ecdsa(kp) => kp.pkcs8_der.to_bytes(),
340 Self::Ed25519(kp) => kp.pkcs8_der.to_bytes(),
341 Self::Rsa(kp) => kp.pkcs8_der.to_bytes(),
342 }
343 }
344}
345
346impl From<&InMemorySigningKeyPair> for KeyAlgorithm {
347 fn from(key: &InMemorySigningKeyPair) -> Self {
348 match key {
349 InMemorySigningKeyPair::Rsa(_) => KeyAlgorithm::Rsa,
350 InMemorySigningKeyPair::Ecdsa(kp) => KeyAlgorithm::Ecdsa(kp.curve),
351 InMemorySigningKeyPair::Ed25519(_) => KeyAlgorithm::Ed25519,
352 }
353 }
354}
355
356#[cfg(test)]
357mod test {
358 use {super::*, crate::rfc5280, crate::testutil::*, ringsig::UnparsedPublicKey};
359
360 #[test]
361 fn generate_random_ecdsa() {
362 for curve in EcdsaCurve::all() {
363 InMemorySigningKeyPair::generate_random(KeyAlgorithm::Ecdsa(*curve)).unwrap();
364 }
365 }
366
367 #[test]
368 fn generate_random_ed25519() {
369 InMemorySigningKeyPair::generate_random(KeyAlgorithm::Ed25519).unwrap();
370 }
371
372 #[test]
373 fn generate_random_rsa() {
374 assert!(InMemorySigningKeyPair::generate_random(KeyAlgorithm::Rsa).is_err());
375 }
376
377 #[test]
378 fn signing_key_from_ecdsa_pkcs8() {
379 let rng = ring::rand::SystemRandom::new();
380
381 for alg in &[
382 &ringsig::ECDSA_P256_SHA256_ASN1_SIGNING,
383 &ringsig::ECDSA_P384_SHA384_ASN1_SIGNING,
384 ] {
385 let doc = ringsig::EcdsaKeyPair::generate_pkcs8(alg, &rng).unwrap();
386
387 let signing_key = InMemorySigningKeyPair::from_pkcs8_der(doc.as_ref()).unwrap();
388 assert!(matches!(signing_key, InMemorySigningKeyPair::Ecdsa(_,)));
389
390 let pem_data = pem::Pem::new("PRIVATE KEY", doc.as_ref()).to_string();
391
392 let signing_key = InMemorySigningKeyPair::from_pkcs8_pem(pem_data.as_bytes()).unwrap();
393 assert!(matches!(signing_key, InMemorySigningKeyPair::Ecdsa(_)));
394
395 let key_pair_asn1 = Constructed::decode(doc.as_ref(), bcder::Mode::Der, |cons| {
396 OneAsymmetricKey::take_from(cons)
397 })
398 .unwrap();
399 assert_eq!(
400 key_pair_asn1.private_key_algorithm.algorithm,
401 KeyAlgorithm::Ecdsa(EcdsaCurve::Secp256r1).into()
403 );
404
405 let expected = if *alg == &ringsig::ECDSA_P256_SHA256_ASN1_SIGNING {
406 EcdsaCurve::Secp256r1
407 } else if *alg == &ringsig::ECDSA_P384_SHA384_ASN1_SIGNING {
408 EcdsaCurve::Secp384r1
409 } else {
410 panic!("unhandled test case");
411 };
412
413 assert!(key_pair_asn1.private_key_algorithm.parameters.is_some());
414 let oid = key_pair_asn1
415 .private_key_algorithm
416 .parameters
417 .unwrap()
418 .decode_oid()
419 .unwrap();
420
421 assert_eq!(EcdsaCurve::try_from(&oid).unwrap(), expected);
422 }
423 }
424
425 #[test]
426 fn signing_key_from_ed25519_pkcs8() {
427 let rng = ring::rand::SystemRandom::new();
428
429 let doc = ringsig::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
430
431 let signing_key = InMemorySigningKeyPair::from_pkcs8_der(doc.as_ref()).unwrap();
432 assert!(matches!(signing_key, InMemorySigningKeyPair::Ed25519(_)));
433
434 let pem_data = pem::Pem::new("PRIVATE KEY", doc.as_ref()).to_string();
435
436 let signing_key = InMemorySigningKeyPair::from_pkcs8_pem(pem_data.as_bytes()).unwrap();
437 assert!(matches!(signing_key, InMemorySigningKeyPair::Ed25519(_)));
438
439 let key_pair_asn1 = Constructed::decode(doc.as_ref(), bcder::Mode::Der, |cons| {
440 OneAsymmetricKey::take_from(cons)
441 })
442 .unwrap();
443 assert_eq!(
444 key_pair_asn1.private_key_algorithm.algorithm,
445 SignatureAlgorithm::Ed25519.into()
446 );
447 assert!(key_pair_asn1.private_key_algorithm.parameters.is_none());
448 }
449
450 #[test]
451 fn ecdsa_self_signed_certificate_verification() {
452 for curve in EcdsaCurve::all() {
453 let (cert, _) = self_signed_ecdsa_key_pair(Some(*curve));
454 cert.verify_signed_by_certificate(&cert).unwrap();
455
456 let raw: &rfc5280::Certificate = cert.as_ref();
457
458 let tbs_signature_algorithm =
459 SignatureAlgorithm::try_from(&raw.tbs_certificate.signature).unwrap();
460 let expected = match curve {
461 EcdsaCurve::Secp256r1 => SignatureAlgorithm::EcdsaSha256,
462 EcdsaCurve::Secp384r1 => SignatureAlgorithm::EcdsaSha384,
463 };
464 assert_eq!(tbs_signature_algorithm, expected);
465
466 let spki = &raw.tbs_certificate.subject_public_key_info;
467
468 assert_eq!(
470 spki.algorithm.algorithm,
471 crate::algorithm::OID_EC_PUBLIC_KEY
472 );
473 let expected = match curve {
475 EcdsaCurve::Secp256r1 => crate::algorithm::OID_EC_SECP256R1,
476 EcdsaCurve::Secp384r1 => crate::algorithm::OID_EC_SECP384R1,
477 };
478 assert!(spki.algorithm.parameters.is_some());
479 assert_eq!(
480 spki.algorithm
481 .parameters
482 .as_ref()
483 .unwrap()
484 .decode_oid()
485 .unwrap(),
486 expected
487 );
488
489 let cert_algorithm = SignatureAlgorithm::try_from(&raw.signature_algorithm).unwrap();
491 assert_eq!(cert_algorithm, tbs_signature_algorithm);
492 }
493 }
494
495 #[test]
496 fn ed25519_self_signed_certificate_verification() {
497 let (cert, _) = self_signed_ed25519_key_pair();
498 cert.verify_signed_by_certificate(&cert).unwrap();
499 }
500
501 #[test]
502 fn rsa_signing_roundtrip() {
503 let key = rsa_private_key();
504 let cert = rsa_cert();
505 let message = b"hello, world";
506
507 let signature = Signer::try_sign(&key, message).unwrap();
508
509 let public_key = UnparsedPublicKey::new(
510 key.verification_algorithm().unwrap(),
511 cert.public_key_data(),
512 );
513
514 public_key.verify(message, signature.as_ref()).unwrap();
515 }
516}