rustls_rustcrypto/sign/
eddsa.rs

1#[cfg(feature = "alloc")]
2use alloc::{boxed::Box, format, string::ToString, sync::Arc};
3use core::marker::PhantomData;
4
5use pkcs8::DecodePrivateKey;
6use pki_types::PrivateKeyDer;
7use rustls::sign::{Signer, SigningKey};
8use rustls::{SignatureAlgorithm, SignatureScheme};
9use sec1::DecodeEcPrivateKey;
10
11#[derive(Debug)]
12pub struct Ed25519SigningKey {
13    key: Arc<ed25519_dalek::SigningKey>,
14    scheme: SignatureScheme,
15}
16
17impl TryFrom<&PrivateKeyDer<'_>> for Ed25519SigningKey {
18    type Error = rustls::Error;
19
20    fn try_from(value: &PrivateKeyDer<'_>) -> Result<Self, Self::Error> {
21        let pkey = match value {
22            PrivateKeyDer::Pkcs8(der) => {
23                ed25519_dalek::SigningKey::from_pkcs8_der(der.secret_pkcs8_der())
24                    .map_err(|e| format!("failed to decrypt private key: {e}"))
25            }
26            PrivateKeyDer::Sec1(sec1) => {
27                ed25519_dalek::SigningKey::from_sec1_der(sec1.secret_sec1_der())
28                    .map_err(|e| format!("failed to decrypt private key: {e}"))
29            }
30            PrivateKeyDer::Pkcs1(_) => Err("ED25519 does not support PKCS#1 key".to_string()),
31            _ => Err("not supported".into()),
32        };
33        pkey.map(|kp| Self {
34            key: Arc::new(kp),
35            scheme: SignatureScheme::ED25519,
36        })
37        .map_err(rustls::Error::General)
38    }
39}
40
41impl SigningKey for Ed25519SigningKey {
42    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
43        if offered.contains(&self.scheme) {
44            Some(Box::new(super::GenericSigner {
45                _marker: PhantomData,
46                key: self.key.clone(),
47                scheme: self.scheme,
48            }))
49        } else {
50            None
51        }
52    }
53
54    fn algorithm(&self) -> SignatureAlgorithm {
55        SignatureAlgorithm::ED25519
56    }
57}