tlspuffin/tls/rustls/
sign.rs

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