rustls/
sign.rs

1use crate::error::TLSError;
2use crate::key;
3use crate::msgs::enums::{SignatureAlgorithm, SignatureScheme};
4
5use ring::{
6    self,
7    signature::{self, EcdsaKeyPair, Ed25519KeyPair, RsaKeyPair},
8};
9use webpki;
10
11use std::mem;
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>, TLSError>;
30
31    /// Reveals which scheme will be used when you call `sign()`.
32    fn get_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<Box<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<Box<dyn SigningKey>>) -> CertifiedKey {
61        CertifiedKey {
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, ()> {
71        self.cert.get(0).ok_or(())
72    }
73
74    /// Steal ownership of the certificate chain.
75    pub fn take_cert(&mut self) -> Vec<key::Certificate> {
76        mem::replace(&mut self.cert, Vec::new())
77    }
78
79    /// Return true if there's an OCSP response.
80    pub fn has_ocsp(&self) -> bool {
81        self.ocsp.is_some()
82    }
83
84    /// Steal ownership of the OCSP response.
85    pub fn take_ocsp(&mut self) -> Option<Vec<u8>> {
86        mem::replace(&mut self.ocsp, None)
87    }
88
89    /// Return true if there's an SCT list.
90    pub fn has_sct_list(&self) -> bool {
91        self.sct_list.is_some()
92    }
93
94    /// Steal ownership of the SCT list.
95    pub fn take_sct_list(&mut self) -> Option<Vec<u8>> {
96        mem::replace(&mut self.sct_list, None)
97    }
98
99    /// Check the certificate chain for validity:
100    /// - it should be non-empty list
101    /// - the first certificate should be parsable as a x509v3,
102    /// - the first certificate should quote the given server name
103    ///   (if provided)
104    ///
105    /// These checks are not security-sensitive.  They are the
106    /// *server* attempting to detect accidental misconfiguration.
107    pub fn cross_check_end_entity_cert(
108        &self,
109        name: Option<webpki::DNSNameRef>,
110    ) -> Result<(), TLSError> {
111        // Always reject an empty certificate chain.
112        let end_entity_cert = self.end_entity_cert().map_err(|()| {
113            TLSError::General("No end-entity certificate in certificate chain".to_string())
114        })?;
115
116        // Reject syntactically-invalid end-entity certificates.
117        let end_entity_cert =
118            webpki::EndEntityCert::from(end_entity_cert.as_ref()).map_err(|_| {
119                TLSError::General(
120                    "End-entity certificate in certificate \
121                                  chain is syntactically invalid"
122                        .to_string(),
123                )
124            })?;
125
126        if let Some(name) = name {
127            // If SNI was offered then the certificate must be valid for
128            // that hostname. Note that this doesn't fully validate that the
129            // certificate is valid; it only validates that the name is one
130            // that the certificate is valid for, if the certificate is
131            // valid.
132            if end_entity_cert
133                .verify_is_valid_for_dns_name(name)
134                .is_err()
135            {
136                return Err(TLSError::General(
137                    "The server certificate is not \
138                                             valid for the given name"
139                        .to_string(),
140                ));
141            }
142        }
143
144        Ok(())
145    }
146}
147
148/// Parse `der` as any supported key encoding/type, returning
149/// the first which works.
150pub fn any_supported_type(der: &key::PrivateKey) -> Result<Box<dyn SigningKey>, ()> {
151    if let Ok(rsa) = RSASigningKey::new(der) {
152        Ok(Box::new(rsa))
153    } else if let Ok(ecdsa) = any_ecdsa_type(der) {
154        Ok(ecdsa)
155    } else {
156        any_eddsa_type(der)
157    }
158}
159
160/// Parse `der` as any ECDSA key type, returning the first which works.
161pub fn any_ecdsa_type(der: &key::PrivateKey) -> Result<Box<dyn SigningKey>, ()> {
162    if let Ok(ecdsa_p256) = ECDSASigningKey::new(
163        der,
164        SignatureScheme::ECDSA_NISTP256_SHA256,
165        &signature::ECDSA_P256_SHA256_ASN1_SIGNING,
166    ) {
167        return Ok(Box::new(ecdsa_p256));
168    }
169
170    if let Ok(ecdsa_p384) = ECDSASigningKey::new(
171        der,
172        SignatureScheme::ECDSA_NISTP384_SHA384,
173        &signature::ECDSA_P384_SHA384_ASN1_SIGNING,
174    ) {
175        return Ok(Box::new(ecdsa_p384));
176    }
177
178    Err(())
179}
180
181/// Parse `der` as any EdDSA key type, returning the first which works.
182pub fn any_eddsa_type(der: &key::PrivateKey) -> Result<Box<dyn SigningKey>, ()> {
183    if let Ok(ed25519) = Ed25519SigningKey::new(der, SignatureScheme::ED25519) {
184        return Ok(Box::new(ed25519));
185    }
186
187    // TODO: Add support for Ed448
188
189    Err(())
190}
191
192/// A `SigningKey` for RSA-PKCS1 or RSA-PSS
193pub struct RSASigningKey {
194    key: Arc<RsaKeyPair>,
195}
196
197static ALL_RSA_SCHEMES: &[SignatureScheme] = &[
198    SignatureScheme::RSA_PSS_SHA512,
199    SignatureScheme::RSA_PSS_SHA384,
200    SignatureScheme::RSA_PSS_SHA256,
201    SignatureScheme::RSA_PKCS1_SHA512,
202    SignatureScheme::RSA_PKCS1_SHA384,
203    SignatureScheme::RSA_PKCS1_SHA256,
204];
205
206impl RSASigningKey {
207    /// Make a new `RSASigningKey` from a DER encoding, in either
208    /// PKCS#1 or PKCS#8 format.
209    pub fn new(der: &key::PrivateKey) -> Result<RSASigningKey, ()> {
210        RsaKeyPair::from_der(&der.0)
211            .or_else(|_| RsaKeyPair::from_pkcs8(&der.0))
212            .map(|s| RSASigningKey { key: Arc::new(s) })
213            .map_err(|_| ())
214    }
215}
216
217impl SigningKey for RSASigningKey {
218    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
219        ALL_RSA_SCHEMES
220            .iter()
221            .filter(|scheme| offered.contains(scheme))
222            .nth(0)
223            .map(|scheme| RSASigner::new(self.key.clone(), *scheme))
224    }
225
226    fn algorithm(&self) -> SignatureAlgorithm {
227        SignatureAlgorithm::RSA
228    }
229}
230
231struct RSASigner {
232    key: Arc<RsaKeyPair>,
233    scheme: SignatureScheme,
234    encoding: &'static dyn signature::RsaEncoding,
235}
236
237impl RSASigner {
238    fn new(key: Arc<RsaKeyPair>, scheme: SignatureScheme) -> Box<dyn Signer> {
239        let encoding: &dyn signature::RsaEncoding = match scheme {
240            SignatureScheme::RSA_PKCS1_SHA256 => &signature::RSA_PKCS1_SHA256,
241            SignatureScheme::RSA_PKCS1_SHA384 => &signature::RSA_PKCS1_SHA384,
242            SignatureScheme::RSA_PKCS1_SHA512 => &signature::RSA_PKCS1_SHA512,
243            SignatureScheme::RSA_PSS_SHA256 => &signature::RSA_PSS_SHA256,
244            SignatureScheme::RSA_PSS_SHA384 => &signature::RSA_PSS_SHA384,
245            SignatureScheme::RSA_PSS_SHA512 => &signature::RSA_PSS_SHA512,
246            _ => unreachable!(),
247        };
248
249        Box::new(RSASigner {
250            key,
251            scheme,
252            encoding,
253        })
254    }
255}
256
257impl Signer for RSASigner {
258    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TLSError> {
259        let mut sig = vec![0; self.key.public_modulus_len()];
260
261        let rng = ring::rand::SystemRandom::new();
262        self.key
263            .sign(self.encoding, &rng, message, &mut sig)
264            .map(|_| sig)
265            .map_err(|_| TLSError::General("signing failed".to_string()))
266    }
267
268    fn get_scheme(&self) -> SignatureScheme {
269        self.scheme
270    }
271}
272
273/// A SigningKey that uses exactly one TLS-level SignatureScheme
274/// and one ring-level signature::SigningAlgorithm.
275///
276/// Compare this to RSASigningKey, which for a particular key is
277/// willing to sign with several algorithms.  This is quite poor
278/// cryptography practice, but is necessary because a given RSA key
279/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
280/// (PSS signatures) -- nobody is willing to obtain certificates for
281/// different protocol versions.
282///
283/// Currently this is only implemented for ECDSA keys.
284struct ECDSASigningKey {
285    key: Arc<EcdsaKeyPair>,
286    scheme: SignatureScheme,
287}
288
289impl ECDSASigningKey {
290    /// Make a new `ECDSASigningKey` from a DER encoding in PKCS#8 format,
291    /// expecting a key usable with precisely the given signature scheme.
292    pub fn new(
293        der: &key::PrivateKey,
294        scheme: SignatureScheme,
295        sigalg: &'static signature::EcdsaSigningAlgorithm,
296    ) -> Result<ECDSASigningKey, ()> {
297        EcdsaKeyPair::from_pkcs8(sigalg, &der.0)
298            .map(|kp| ECDSASigningKey {
299                key: Arc::new(kp),
300                scheme,
301            })
302            .map_err(|_| ())
303    }
304}
305
306impl SigningKey for ECDSASigningKey {
307    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
308        if offered.contains(&self.scheme) {
309            Some(Box::new(ECDSASigner {
310                key: self.key.clone(),
311                scheme: self.scheme,
312            }))
313        } else {
314            None
315        }
316    }
317
318    fn algorithm(&self) -> SignatureAlgorithm {
319        use crate::msgs::handshake::DecomposedSignatureScheme;
320        self.scheme.sign()
321    }
322}
323
324struct ECDSASigner {
325    key: Arc<EcdsaKeyPair>,
326    scheme: SignatureScheme,
327}
328
329impl Signer for ECDSASigner {
330    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TLSError> {
331        let rng = ring::rand::SystemRandom::new();
332        self.key
333            .sign(&rng, message)
334            .map_err(|_| TLSError::General("signing failed".into()))
335            .map(|sig| sig.as_ref().into())
336    }
337
338    fn get_scheme(&self) -> SignatureScheme {
339        self.scheme
340    }
341}
342
343/// A SigningKey that uses exactly one TLS-level SignatureScheme
344/// and one ring-level signature::SigningAlgorithm.
345///
346/// Compare this to RSASigningKey, which for a particular key is
347/// willing to sign with several algorithms.  This is quite poor
348/// cryptography practice, but is necessary because a given RSA key
349/// is expected to work in TLS1.2 (PKCS#1 signatures) and TLS1.3
350/// (PSS signatures) -- nobody is willing to obtain certificates for
351/// different protocol versions.
352///
353/// Currently this is only implemented for Ed25519 keys.
354struct Ed25519SigningKey {
355    key: Arc<Ed25519KeyPair>,
356    scheme: SignatureScheme,
357}
358
359impl Ed25519SigningKey {
360    /// Make a new `Ed25519SigningKey` from a DER encoding in PKCS#8 format,
361    /// expecting a key usable with precisely the given signature scheme.
362    pub fn new(der: &key::PrivateKey, scheme: SignatureScheme) -> Result<Ed25519SigningKey, ()> {
363        Ed25519KeyPair::from_pkcs8_maybe_unchecked(&der.0)
364            .map(|kp| Ed25519SigningKey {
365                key: Arc::new(kp),
366                scheme,
367            })
368            .map_err(|_| ())
369    }
370}
371
372impl SigningKey for Ed25519SigningKey {
373    fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>> {
374        if offered.contains(&self.scheme) {
375            Some(Box::new(Ed25519Signer {
376                key: self.key.clone(),
377                scheme: self.scheme,
378            }))
379        } else {
380            None
381        }
382    }
383
384    fn algorithm(&self) -> SignatureAlgorithm {
385        use crate::msgs::handshake::DecomposedSignatureScheme;
386        self.scheme.sign()
387    }
388}
389
390struct Ed25519Signer {
391    key: Arc<Ed25519KeyPair>,
392    scheme: SignatureScheme,
393}
394
395impl Signer for Ed25519Signer {
396    fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TLSError> {
397        Ok(self.key.sign(message).as_ref().into())
398    }
399
400    fn get_scheme(&self) -> SignatureScheme {
401        self.scheme
402    }
403}
404
405/// The set of schemes we support for signatures and
406/// that are allowed for TLS1.3.
407pub fn supported_sign_tls13() -> &'static [SignatureScheme] {
408    &[
409        SignatureScheme::ECDSA_NISTP384_SHA384,
410        SignatureScheme::ECDSA_NISTP256_SHA256,
411        SignatureScheme::RSA_PSS_SHA512,
412        SignatureScheme::RSA_PSS_SHA384,
413        SignatureScheme::RSA_PSS_SHA256,
414        SignatureScheme::ED25519,
415    ]
416}