Skip to main content

ferritls_rustls/
sign.rs

1//! 签名适配:`SigningKey` / `Signer` / `KeyProvider`。
2//!
3//! rustls 0.23 的签名 trait 位于 `rustls::sign`(不在 `rustls::crypto`
4//! 下);`Signer::sign` 的输入是**未哈希**消息,与 ferritls-core 的
5//! 约定一致。
6
7use std::sync::Arc;
8
9use rustls::pki_types::PrivateKeyDer;
10use rustls::sign::{Signer, SigningKey};
11use rustls::{Error as RustlsError, SignatureAlgorithm, SignatureScheme};
12
13use ferritls_core::sign::{ecdsa, ed25519, rsa};
14
15/// P-256/SHA-256 签名密钥。
16pub struct EcdsaP256Key(ecdsa::p256::SigningKey);
17
18/// P-384/SHA-384 签名密钥。
19pub struct EcdsaP384Key(ecdsa::p384::SigningKey);
20
21/// Ed25519 签名密钥(非批准)。
22pub struct Ed25519Key(ed25519::SigningKey);
23
24/// RSA 签名密钥(PSS 与 PKCS#1 v1.5,按对端 offer 选择)。
25pub struct RsaKey(rsa::SigningKey);
26
27impl std::fmt::Debug for EcdsaP256Key {
28    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29        f.write_str("EcdsaP256Key")
30    }
31}
32
33impl std::fmt::Debug for EcdsaP384Key {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        f.write_str("EcdsaP384Key")
36    }
37}
38
39impl std::fmt::Debug for Ed25519Key {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        f.write_str("Ed25519Key")
42    }
43}
44
45impl std::fmt::Debug for RsaKey {
46    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47        f.write_str("RsaKey")
48    }
49}
50
51impl EcdsaP256Key {
52    /// 由 32 字节标量构造。
53    pub fn new(d: &[u8; 32]) -> Self {
54        Self(ecdsa::p256::SigningKey::from_seed(*d))
55    }
56}
57
58impl EcdsaP384Key {
59    /// 由 48 字节标量构造。
60    pub fn new(d: &[u8; 48]) -> Self {
61        Self(ecdsa::p384::SigningKey::from_seed(*d))
62    }
63}
64
65impl Ed25519Key {
66    /// 由 32 字节种子构造。
67    pub fn new(seed: &[u8; 32]) -> Self {
68        Self(ed25519::SigningKey::from_seed(*seed))
69    }
70}
71
72impl RsaKey {
73    /// 由 PKCS#1 RSAPrivateKey DER 构造(含结构一致性校验)。
74    pub fn from_pkcs1_der(der: &[u8]) -> Result<Self, RustlsError> {
75        rsa::SigningKey::from_pkcs1_der(der)
76            .map(Self)
77            .map_err(|_| RustlsError::General("invalid RSA private key".into()))
78    }
79
80    /// 由 PKCS#8 PrivateKeyInfo DER 构造。
81    pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, RustlsError> {
82        rsa::SigningKey::from_pkcs8_der(der)
83            .map(Self)
84            .map_err(|_| RustlsError::General("invalid RSA private key".into()))
85    }
86}
87
88impl SigningKey for EcdsaP256Key {
89    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
90        if offered.contains(&SignatureScheme::ECDSA_NISTP256_SHA256) {
91            Some(Box::new(EcdsaP256Signer(self.0.clone())))
92        } else {
93            None
94        }
95    }
96
97    fn algorithm(&self) -> SignatureAlgorithm {
98        SignatureAlgorithm::ECDSA
99    }
100}
101
102impl SigningKey for EcdsaP384Key {
103    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
104        if offered.contains(&SignatureScheme::ECDSA_NISTP384_SHA384) {
105            Some(Box::new(EcdsaP384Signer(self.0.clone())))
106        } else {
107            None
108        }
109    }
110
111    fn algorithm(&self) -> SignatureAlgorithm {
112        SignatureAlgorithm::ECDSA
113    }
114}
115
116impl SigningKey for Ed25519Key {
117    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
118        if offered.contains(&SignatureScheme::ED25519) {
119            Some(Box::new(Ed25519Signer(self.0.clone())))
120        } else {
121            None
122        }
123    }
124
125    fn algorithm(&self) -> SignatureAlgorithm {
126        SignatureAlgorithm::ED25519
127    }
128}
129
130impl SigningKey for RsaKey {
131    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
132        // 优先级:TLS 1.3 首选 PSS(SHA-256/384/512),随后 v1.5
133        const PREFERRED: [SignatureScheme; 6] = [
134            SignatureScheme::RSA_PSS_SHA256,
135            SignatureScheme::RSA_PSS_SHA384,
136            SignatureScheme::RSA_PSS_SHA512,
137            SignatureScheme::RSA_PKCS1_SHA256,
138            SignatureScheme::RSA_PKCS1_SHA384,
139            SignatureScheme::RSA_PKCS1_SHA512,
140        ];
141        PREFERRED.iter().find_map(|s| {
142            if offered.contains(s) {
143                Some(Box::new(RsaSigner {
144                    scheme: *s,
145                    key: self.0.clone(),
146                }) as Box<dyn Signer>)
147            } else {
148                None
149            }
150        })
151    }
152
153    fn algorithm(&self) -> SignatureAlgorithm {
154        SignatureAlgorithm::RSA
155    }
156}
157
158/// ECDSA P-256/SHA-256 签名器(`choose_scheme` 的产物)。
159pub struct EcdsaP256Signer(ecdsa::p256::SigningKey);
160
161/// ECDSA P-384/SHA-384 签名器。
162pub struct EcdsaP384Signer(ecdsa::p384::SigningKey);
163
164/// Ed25519 签名器。
165pub struct Ed25519Signer(ed25519::SigningKey);
166
167/// RSA(PSS / PKCS#1 × SHA-2 按 scheme 变化)签名器。
168pub struct RsaSigner {
169    /// 目标签名方案。
170    pub scheme: SignatureScheme,
171    key: rsa::SigningKey,
172}
173
174impl std::fmt::Debug for EcdsaP256Signer {
175    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
176        f.write_str("EcdsaP256Signer")
177    }
178}
179
180impl std::fmt::Debug for EcdsaP384Signer {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        f.write_str("EcdsaP384Signer")
183    }
184}
185
186impl std::fmt::Debug for Ed25519Signer {
187    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188        f.write_str("Ed25519Signer")
189    }
190}
191
192impl std::fmt::Debug for RsaSigner {
193    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194        f.write_str("RsaSigner")
195    }
196}
197
198fn map_sign_err(_: ferritls_core::Error) -> RustlsError {
199    RustlsError::General("signing failed".into())
200}
201
202impl Signer for EcdsaP256Signer {
203    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, RustlsError> {
204        self.0.sign(message).map_err(map_sign_err)
205    }
206
207    fn scheme(&self) -> SignatureScheme {
208        SignatureScheme::ECDSA_NISTP256_SHA256
209    }
210}
211
212impl Signer for EcdsaP384Signer {
213    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, RustlsError> {
214        self.0.sign(message).map_err(map_sign_err)
215    }
216
217    fn scheme(&self) -> SignatureScheme {
218        SignatureScheme::ECDSA_NISTP384_SHA384
219    }
220}
221
222impl Signer for Ed25519Signer {
223    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, RustlsError> {
224        Ok(self.0.sign(message).to_vec())
225    }
226
227    fn scheme(&self) -> SignatureScheme {
228        SignatureScheme::ED25519
229    }
230}
231
232impl Signer for RsaSigner {
233    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, RustlsError> {
234        let bits = match self.scheme {
235            SignatureScheme::RSA_PSS_SHA256 | SignatureScheme::RSA_PKCS1_SHA256 => 256,
236            SignatureScheme::RSA_PSS_SHA384 | SignatureScheme::RSA_PKCS1_SHA384 => 384,
237            SignatureScheme::RSA_PSS_SHA512 | SignatureScheme::RSA_PKCS1_SHA512 => 512,
238            _ => return Err(RustlsError::General("unsupported RSA scheme".into())),
239        };
240        let pss = matches!(
241            self.scheme,
242            SignatureScheme::RSA_PSS_SHA256
243                | SignatureScheme::RSA_PSS_SHA384
244                | SignatureScheme::RSA_PSS_SHA512
245        );
246        let result = if pss {
247            self.key.sign_pss(bits, message)
248        } else {
249            self.key.sign_pkcs1v15(bits, message)
250        };
251        result.map_err(map_sign_err)
252    }
253
254    fn scheme(&self) -> SignatureScheme {
255        self.scheme
256    }
257}
258
259/// rustls `CryptoProvider::key_provider` 字段的实现:把
260/// `PrivateKeyDer`(PKCS#8/SEC1/PKCS#1)分派到对应签名密钥类型。
261#[derive(Debug)]
262pub struct KeyLoader;
263
264impl KeyLoader {
265    /// PKCS#8 通用分派(对 `any_supported_type` 与本 trait 共用)。
266    pub fn from_pkcs8(der: &[u8]) -> Result<Arc<dyn SigningKey>, RustlsError> {
267        let parsed = ferritls_core::der::parse_pkcs8_private_key(der)
268            .map_err(|_| RustlsError::General("invalid private key".into()))?;
269        match parsed {
270            ferritls_core::der::ParsedPrivateKey::P256 { scalar, .. } => {
271                Ok(Arc::new(EcdsaP256Key::new(&scalar)))
272            }
273            ferritls_core::der::ParsedPrivateKey::P384 { scalar, .. } => {
274                Ok(Arc::new(EcdsaP384Key::new(&scalar)))
275            }
276            ferritls_core::der::ParsedPrivateKey::RsaPkcs1(pkcs1) => {
277                RsaKey::from_pkcs1_der(&pkcs1).map(|k| Arc::new(k) as Arc<dyn SigningKey>)
278            }
279            ferritls_core::der::ParsedPrivateKey::Ed25519(seed) => Ok(Arc::new(Ed25519Key::new(
280                seed.as_slice().try_into().expect("32-byte seed"),
281            ))),
282        }
283    }
284}
285
286impl rustls::crypto::KeyProvider for KeyLoader {
287    fn load_private_key(
288        &self,
289        key_der: PrivateKeyDer<'static>,
290    ) -> Result<Arc<dyn SigningKey>, RustlsError> {
291        any_supported_type(&key_der)
292    }
293
294    fn fips(&self) -> bool {
295        // 认证前恒 false(lib.rs“fips() 语义”)。
296        false
297    }
298}
299
300/// 兼容任意支持类型的密钥加载(ECDSA → Ed25519 → RSA 依次尝试)。
301pub fn any_supported_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, RustlsError> {
302    let der_bytes = der.secret_der();
303    // PKCS#8 优先(四种算法统一入口)
304    if let Ok(key) = KeyLoader::from_pkcs8(der_bytes) {
305        return Ok(key);
306    }
307    // PKCS#1 RSA
308    if let Ok(key) = RsaKey::from_pkcs1_der(der_bytes) {
309        return Ok(Arc::new(key));
310    }
311    Err(RustlsError::General(
312        "unsupported private key format or algorithm".into(),
313    ))
314}
315
316/// 仅接受 ECDSA(P-256/P-384)密钥。
317pub fn any_ecdsa_type(der: &PrivateKeyDer<'_>) -> Result<Arc<dyn SigningKey>, RustlsError> {
318    let der_bytes = der.secret_der();
319    if let Ok(key) = KeyLoader::from_pkcs8(der_bytes) {
320        let alg = key.algorithm();
321        if alg == SignatureAlgorithm::ECDSA {
322            return Ok(key);
323        }
324    }
325    Err(RustlsError::General("not an ECDSA key".into()))
326}
327
328/// `KeyProvider` 单例(填入 `CryptoProvider::key_provider`)。
329pub static KEY_LOADER: &dyn rustls::crypto::KeyProvider = &KeyLoader;