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
14pub trait SigningKey: Send + Sync {
16 fn choose_scheme(&self, offered: &[SignatureScheme]) -> Option<Box<dyn Signer>>;
21
22 fn algorithm(&self) -> SignatureAlgorithm;
24}
25
26pub trait Signer: Send + Sync {
28 fn sign(&self, message: &[u8]) -> Result<Vec<u8>, TLSError>;
30
31 fn get_scheme(&self) -> SignatureScheme;
33}
34
35#[derive(Clone)]
38pub struct CertifiedKey {
39 pub cert: Vec<key::Certificate>,
41
42 pub key: Arc<Box<dyn SigningKey>>,
44
45 pub ocsp: Option<Vec<u8>>,
48
49 pub sct_list: Option<Vec<u8>>,
53}
54
55impl CertifiedKey {
56 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 pub fn end_entity_cert(&self) -> Result<&key::Certificate, ()> {
71 self.cert.get(0).ok_or(())
72 }
73
74 pub fn take_cert(&mut self) -> Vec<key::Certificate> {
76 mem::replace(&mut self.cert, Vec::new())
77 }
78
79 pub fn has_ocsp(&self) -> bool {
81 self.ocsp.is_some()
82 }
83
84 pub fn take_ocsp(&mut self) -> Option<Vec<u8>> {
86 mem::replace(&mut self.ocsp, None)
87 }
88
89 pub fn has_sct_list(&self) -> bool {
91 self.sct_list.is_some()
92 }
93
94 pub fn take_sct_list(&mut self) -> Option<Vec<u8>> {
96 mem::replace(&mut self.sct_list, None)
97 }
98
99 pub fn cross_check_end_entity_cert(
108 &self,
109 name: Option<webpki::DNSNameRef>,
110 ) -> Result<(), TLSError> {
111 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 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 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
148pub 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
160pub 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
181pub 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 Err(())
190}
191
192pub 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 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
273struct ECDSASigningKey {
285 key: Arc<EcdsaKeyPair>,
286 scheme: SignatureScheme,
287}
288
289impl ECDSASigningKey {
290 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
343struct Ed25519SigningKey {
355 key: Arc<Ed25519KeyPair>,
356 scheme: SignatureScheme,
357}
358
359impl Ed25519SigningKey {
360 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
405pub 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}