rustls/
sign.rs

1use crate::enums::{SignatureAlgorithm, SignatureScheme};
2use crate::error::Error;
3use crate::key;
4use crate::x509::{wrap_in_asn1_len, wrap_in_sequence};
5
6use ring::io::der;
7use ring::rand::{SecureRandom, SystemRandom};
8use ring::signature::{self, EcdsaKeyPair, Ed25519KeyPair, RsaKeyPair};
9
10use std::error::Error as StdError;
11use std::fmt;
12use std::sync::Arc;
13
14/// An abstract signing key.
15pub trait SigningKey: Send + Sync {
16    /// Choose a `SignatureScheme` from those offered.
17    ///
18    /// Expresses the choice by returning something that implements `Signer`,
19    /// using the chosen scheme.
20    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>>;
21
22    /// What kind of key we have.
23    fn algorithm(&self) -> SignatureAlgorithm;
24}
25
26/// A thing that can sign a message.
27pub trait Signer: Send + Sync {
28    /// Signs `message` using the selected scheme.
29    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error>;
30
31    /// Reveals which scheme will be used when you call `sign()`.
32    fn scheme(&self) -> SignatureScheme;
33}
34
35/// A packaged-together certificate chain, matching `SigningKey` and
36/// optional stapled OCSP response and/or SCT list.
37#[derive(Clone)]
38pub struct CertifiedKey {
39    /// The certificate chain.
40    pub cert: Vec<key::Certificate>,
41
42    /// The certified key.
43    pub key: Arc<dyn SigningKey>,
44
45    /// An optional OCSP response from the certificate issuer,
46    /// attesting to its continued validity.
47    pub ocsp: Option<Vec<u8>>,
48
49    /// An optional collection of SCTs from CT logs, proving the
50    /// certificate is included on those logs.  This must be
51    /// a `SignedCertificateTimestampList` encoding; see RFC6962.
52    pub sct_list: Option<Vec<u8>>,
53}
54
55impl CertifiedKey {
56    /// Make a new CertifiedKey, with the given chain and key.
57    ///
58    /// The cert chain must not be empty. The first certificate in the chain
59    /// must be the end-entity certificate.
60    pub fn new(cert: Vec<key::Certificate>, key: Arc<dyn SigningKey>) -> Self {
61        Self {
62            cert,
63            key,
64            ocsp: None,
65            sct_list: None,
66        }
67    }
68
69    /// The end-entity certificate.
70    pub fn end_entity_cert(&self) -> Result<&key::Certificate, SignError> {
71        self.cert.first().ok_or(SignError(()))
72    }
73}
74
75/// Parse `der` as any supported key encoding/type, returning
76/// the first which works.
77pub fn any_supported_type(der: &key::PrivateKey) -> Result<Arc<dyn SigningKey>, SignError> {
78    if let Ok(rsa) = RsaSigningKey::new(der) {
79        Ok(Arc::new(rsa))
80    } else if let Ok(ecdsa) = any_ecdsa_type(der) {
81        Ok(ecdsa)
82    } else {
83        any_eddsa_type(der)
84    }
85}
86
87/// Parse `der` as any ECDSA key type, returning the first which works.
88///
89/// Both SEC1 (PEM section starting with 'BEGIN EC PRIVATE KEY') and PKCS8
90/// (PEM section starting with 'BEGIN PRIVATE KEY') encodings are supported.
91pub fn any_ecdsa_type(der: &key::PrivateKey) -> Result<Arc<dyn SigningKey>, SignError> {
92    if let Ok(ecdsa_p256) = EcdsaSigningKey::new(
93        der,
94        SignatureScheme::ECDSA_NISTP256_SHA256,
95        &signature::ECDSA_P256_SHA256_ASN1_SIGNING,
96    ) {
97        return Ok(Arc::new(ecdsa_p256));
98    }
99
100    if let Ok(ecdsa_p384) = EcdsaSigningKey::new(
101        der,
102        SignatureScheme::ECDSA_NISTP384_SHA384,
103        &signature::ECDSA_P384_SHA384_ASN1_SIGNING,
104    ) {
105        return Ok(Arc::new(ecdsa_p384));
106    }
107
108    Err(SignError(()))
109}
110
111/// Parse `der` as any EdDSA key type, returning the first which works.
112pub fn any_eddsa_type(der: &key::PrivateKey) -> Result<Arc<dyn SigningKey>, SignError> {
113    if let Ok(ed25519) = Ed25519SigningKey::new(der, SignatureScheme::ED25519) {
114        return Ok(Arc::new(ed25519));
115    }
116
117    // TODO: Add support for Ed448
118
119    Err(SignError(()))
120}
121
122/// A `SigningKey` for RSA-PKCS1 or RSA-PSS.
123///
124/// This is used by the test suite, so it must be `pub`, but it isn't part of
125/// the public, stable, API.
126#[doc(hidden)]
127pub struct RsaSigningKey {
128    key: Arc<RsaKeyPair>,
129}
130
131static ALL_RSA_SCHEMES: &[SignatureScheme] = &[
132    SignatureScheme::RSA_PSS_SHA512,
133    SignatureScheme::RSA_PSS_SHA384,
134    SignatureScheme::RSA_PSS_SHA256,
135    SignatureScheme::RSA_PKCS1_SHA512,
136    SignatureScheme::RSA_PKCS1_SHA384,
137    SignatureScheme::RSA_PKCS1_SHA256,
138];
139
140impl RsaSigningKey {
141    /// Make a new `RsaSigningKey` from a DER encoding, in either
142    /// PKCS#1 or PKCS#8 format.
143    pub fn new(der: &key::PrivateKey) -> Result<Self, SignError> {
144        RsaKeyPair::from_der(&der.0)
145            .or_else(|_| RsaKeyPair::from_pkcs8(&der.0))
146            .map(|s| Self { key: Arc::new(s) })
147            .map_err(|_| SignError(()))
148    }
149}
150
151impl SigningKey for RsaSigningKey {
152    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
153        ALL_RSA_SCHEMES
154            .iter()
155            .find(|scheme| offered.contains(scheme))
156            .map(|scheme| RsaSigner::new(Arc::clone(&self.key), *scheme))
157    }
158
159    fn algorithm(&self) -> SignatureAlgorithm {
160        SignatureAlgorithm::RSA
161    }
162}
163
164struct RsaSigner {
165    key: Arc<RsaKeyPair>,
166    scheme: SignatureScheme,
167    encoding: &'static dyn signature::RsaEncoding,
168}
169
170impl RsaSigner {
171    fn new(key: Arc<RsaKeyPair>, scheme: SignatureScheme) -> Box<dyn Signer> {
172        let encoding: &dyn signature::RsaEncoding = match scheme {
173            SignatureScheme::RSA_PKCS1_SHA256 => &signature::RSA_PKCS1_SHA256,
174            SignatureScheme::RSA_PKCS1_SHA384 => &signature::RSA_PKCS1_SHA384,
175            SignatureScheme::RSA_PKCS1_SHA512 => &signature::RSA_PKCS1_SHA512,
176            SignatureScheme::RSA_PSS_SHA256 => &signature::RSA_PSS_SHA256,
177            SignatureScheme::RSA_PSS_SHA384 => &signature::RSA_PSS_SHA384,
178            SignatureScheme::RSA_PSS_SHA512 => &signature::RSA_PSS_SHA512,
179            _ => unreachable!(),
180        };
181
182        Box::new(Self {
183            key,
184            scheme,
185            encoding,
186        })
187    }
188}
189
190impl Signer for RsaSigner {
191    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
192        let mut sig = vec![0; self.key.public().modulus_len()];
193
194        let rng = SystemRandom::new();
195        self.key
196            .sign(self.encoding, &rng, message, &mut sig)
197            .map(|_| sig)
198            .map_err(|_| Error::General("signing failed".to_string()))
199    }
200
201    fn scheme(&self) -> SignatureScheme {
202        self.scheme
203    }
204}
205
206/// A SigningKey that uses exactly one TLS-level SignatureScheme
207/// and one ring-level signature::SigningAlgorithm.
208///
209/// Compare this to RsaSigningKey, which for a particular key is
210/// willing to sign with several algorithms.  This is quite poor
211/// cryptography practice, but is necessary because a given RSA key
212/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
213/// (PSS signatures) -- nobody is willing to obtain certificates for
214/// different protocol versions.
215///
216/// Currently this is only implemented for ECDSA keys.
217struct EcdsaSigningKey {
218    key: Arc<EcdsaKeyPair>,
219    scheme: SignatureScheme,
220}
221
222impl EcdsaSigningKey {
223    /// Make a new `ECDSASigningKey` from a DER encoding in PKCS#8 or SEC1
224    /// format, expecting a key usable with precisely the given signature
225    /// scheme.
226    fn new(
227        der: &key::PrivateKey,
228        scheme: SignatureScheme,
229        sigalg: &'static signature::EcdsaSigningAlgorithm,
230    ) -> Result<Self, ()> {
231        let rng = SystemRandom::new();
232        EcdsaKeyPair::from_pkcs8(sigalg, &der.0, &rng)
233            .map_err(|_| ())
234            .or_else(|_| Self::convert_sec1_to_pkcs8(scheme, sigalg, &der.0, &rng))
235            .map(|kp| Self {
236                key: Arc::new(kp),
237                scheme,
238            })
239    }
240
241    /// Convert a SEC1 encoding to PKCS8, and ask ring to parse it.  This
242    /// can be removed once https://github.com/briansmith/ring/pull/1456
243    /// (or equivalent) is landed.
244    fn convert_sec1_to_pkcs8(
245        scheme: SignatureScheme,
246        sigalg: &'static signature::EcdsaSigningAlgorithm,
247        maybe_sec1_der: &[u8],
248        rng: &dyn SecureRandom,
249    ) -> Result<EcdsaKeyPair, ()> {
250        let pkcs8_prefix = match scheme {
251            SignatureScheme::ECDSA_NISTP256_SHA256 => &PKCS8_PREFIX_ECDSA_NISTP256,
252            SignatureScheme::ECDSA_NISTP384_SHA384 => &PKCS8_PREFIX_ECDSA_NISTP384,
253            _ => unreachable!(), // all callers are in this file
254        };
255
256        // wrap sec1 encoding in an OCTET STRING
257        let mut sec1_wrap = Vec::with_capacity(maybe_sec1_der.len() + 8);
258        sec1_wrap.extend_from_slice(maybe_sec1_der);
259        wrap_in_asn1_len(&mut sec1_wrap);
260        sec1_wrap.insert(0, der::Tag::OctetString as u8);
261
262        let mut pkcs8 = Vec::with_capacity(pkcs8_prefix.len() + sec1_wrap.len() + 4);
263        pkcs8.extend_from_slice(pkcs8_prefix);
264        pkcs8.extend_from_slice(&sec1_wrap);
265        wrap_in_sequence(&mut pkcs8);
266
267        EcdsaKeyPair::from_pkcs8(sigalg, &pkcs8, rng).map_err(|_| ())
268    }
269}
270
271// This is (line-by-line):
272// - INTEGER Version = 0
273// - SEQUENCE (privateKeyAlgorithm)
274//   - id-ecPublicKey OID
275//   - prime256v1 OID
276const PKCS8_PREFIX_ECDSA_NISTP256: &[u8] = b"\x02\x01\x00\
277      \x30\x13\
278      \x06\x07\x2a\x86\x48\xce\x3d\x02\x01\
279      \x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07";
280
281// This is (line-by-line):
282// - INTEGER Version = 0
283// - SEQUENCE (privateKeyAlgorithm)
284//   - id-ecPublicKey OID
285//   - secp384r1 OID
286const PKCS8_PREFIX_ECDSA_NISTP384: &[u8] = b"\x02\x01\x00\
287     \x30\x10\
288     \x06\x07\x2a\x86\x48\xce\x3d\x02\x01\
289     \x06\x05\x2b\x81\x04\x00\x22";
290
291impl SigningKey for EcdsaSigningKey {
292    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
293        if offered.contains(&self.scheme) {
294            Some(Box::new(EcdsaSigner {
295                key: Arc::clone(&self.key),
296                scheme: self.scheme,
297            }))
298        } else {
299            None
300        }
301    }
302
303    fn algorithm(&self) -> SignatureAlgorithm {
304        self.scheme.sign()
305    }
306}
307
308struct EcdsaSigner {
309    key: Arc<EcdsaKeyPair>,
310    scheme: SignatureScheme,
311}
312
313impl Signer for EcdsaSigner {
314    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
315        let rng = SystemRandom::new();
316        self.key
317            .sign(&rng, message)
318            .map_err(|_| Error::General("signing failed".into()))
319            .map(|sig| sig.as_ref().into())
320    }
321
322    fn scheme(&self) -> SignatureScheme {
323        self.scheme
324    }
325}
326
327/// A SigningKey that uses exactly one TLS-level SignatureScheme
328/// and one ring-level signature::SigningAlgorithm.
329///
330/// Compare this to RsaSigningKey, which for a particular key is
331/// willing to sign with several algorithms.  This is quite poor
332/// cryptography practice, but is necessary because a given RSA key
333/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
334/// (PSS signatures) -- nobody is willing to obtain certificates for
335/// different protocol versions.
336///
337/// Currently this is only implemented for Ed25519 keys.
338struct Ed25519SigningKey {
339    key: Arc<Ed25519KeyPair>,
340    scheme: SignatureScheme,
341}
342
343impl Ed25519SigningKey {
344    /// Make a new `Ed25519SigningKey` from a DER encoding in PKCS#8 format,
345    /// expecting a key usable with precisely the given signature scheme.
346    fn new(der: &key::PrivateKey, scheme: SignatureScheme) -> Result<Self, SignError> {
347        Ed25519KeyPair::from_pkcs8_maybe_unchecked(&der.0)
348            .map(|kp| Self {
349                key: Arc::new(kp),
350                scheme,
351            })
352            .map_err(|_| SignError(()))
353    }
354}
355
356impl SigningKey for Ed25519SigningKey {
357    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
358        if offered.contains(&self.scheme) {
359            Some(Box::new(Ed25519Signer {
360                key: Arc::clone(&self.key),
361                scheme: self.scheme,
362            }))
363        } else {
364            None
365        }
366    }
367
368    fn algorithm(&self) -> SignatureAlgorithm {
369        self.scheme.sign()
370    }
371}
372
373struct Ed25519Signer {
374    key: Arc<Ed25519KeyPair>,
375    scheme: SignatureScheme,
376}
377
378impl Signer for Ed25519Signer {
379    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, Error> {
380        Ok(self.key.sign(message).as_ref().into())
381    }
382
383    fn scheme(&self) -> SignatureScheme {
384        self.scheme
385    }
386}
387
388/// The set of schemes we support for signatures and
389/// that are allowed for TLS1.3.
390pub fn supported_sign_tls13() -> &'static [SignatureScheme] {
391    &[
392        SignatureScheme::ECDSA_NISTP384_SHA384,
393        SignatureScheme::ECDSA_NISTP256_SHA256,
394        SignatureScheme::RSA_PSS_SHA512,
395        SignatureScheme::RSA_PSS_SHA384,
396        SignatureScheme::RSA_PSS_SHA256,
397        SignatureScheme::ED25519,
398    ]
399}
400
401/// Errors while signing
402#[derive(Debug)]
403pub struct SignError(());
404
405impl fmt::Display for SignError {
406    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
407        f.write_str("sign error")
408    }
409}
410
411impl StdError for SignError {}
412
413#[test]
414fn can_load_ecdsa_nistp256_pkcs8() {
415    let key = key::PrivateKey(include_bytes!("testdata/nistp256key.pkcs8.der").to_vec());
416    assert!(any_supported_type(&key).is_ok());
417    assert!(any_ecdsa_type(&key).is_ok());
418    assert!(any_eddsa_type(&key).is_err());
419}
420
421#[test]
422fn can_load_ecdsa_nistp256_sec1() {
423    let key = key::PrivateKey(include_bytes!("testdata/nistp256key.der").to_vec());
424    assert!(any_supported_type(&key).is_ok());
425    assert!(any_ecdsa_type(&key).is_ok());
426    assert!(any_eddsa_type(&key).is_err());
427}
428
429#[test]
430fn can_load_ecdsa_nistp384_pkcs8() {
431    let key = key::PrivateKey(include_bytes!("testdata/nistp384key.pkcs8.der").to_vec());
432    assert!(any_supported_type(&key).is_ok());
433    assert!(any_ecdsa_type(&key).is_ok());
434    assert!(any_eddsa_type(&key).is_err());
435}
436
437#[test]
438fn can_load_ecdsa_nistp384_sec1() {
439    let key = key::PrivateKey(include_bytes!("testdata/nistp384key.der").to_vec());
440    assert!(any_supported_type(&key).is_ok());
441    assert!(any_ecdsa_type(&key).is_ok());
442    assert!(any_eddsa_type(&key).is_err());
443}
444
445#[test]
446fn can_load_eddsa_pkcs8() {
447    let key = key::PrivateKey(include_bytes!("testdata/eddsakey.der").to_vec());
448    assert!(any_supported_type(&key).is_ok());
449    assert!(any_eddsa_type(&key).is_ok());
450    assert!(any_ecdsa_type(&key).is_err());
451}
452
453#[test]
454fn can_load_rsa2048_pkcs8() {
455    let key = key::PrivateKey(include_bytes!("testdata/rsa2048key.pkcs8.der").to_vec());
456    assert!(any_supported_type(&key).is_ok());
457    assert!(any_eddsa_type(&key).is_err());
458    assert!(any_ecdsa_type(&key).is_err());
459}
460
461#[test]
462fn can_load_rsa2048_pkcs1() {
463    let key = key::PrivateKey(include_bytes!("testdata/rsa2048key.pkcs1.der").to_vec());
464    assert!(any_supported_type(&key).is_ok());
465    assert!(any_eddsa_type(&key).is_err());
466    assert!(any_ecdsa_type(&key).is_err());
467}