1#[cfg(test)]
11mod crypto_test;
12
13pub mod crypto_cbc;
15pub mod crypto_ccm;
17pub mod crypto_chacha20;
19pub mod crypto_gcm;
21pub mod padding;
23
24use std::convert::TryFrom;
25use std::sync::Arc;
26
27use der_parser::oid;
28use der_parser::oid::Oid;
29
30use rustls::client::danger::ServerCertVerifier;
31use rustls::pki_types::{CertificateDer, ServerName};
32use rustls::server::danger::ClientCertVerifier;
33
34use rcgen::{CertifiedKey, KeyPair, generate_simple_self_signed};
35use ring::rand::SystemRandom;
36use ring::signature::{EcdsaKeyPair, Ed25519KeyPair};
37
38use crate::curve::named_curve::*;
39use crate::record_layer::record_layer_header::*;
40use crate::signature_hash_algorithm::{HashAlgorithm, SignatureAlgorithm, SignatureHashAlgorithm};
41use shared::error::*;
42
43#[derive(Clone, PartialEq, Debug)]
45pub struct Certificate {
46 pub certificate: Vec<CertificateDer<'static>>,
48 pub private_key: CryptoPrivateKey,
50}
51
52impl Certificate {
53 pub fn generate_self_signed(subject_alt_names: impl Into<Vec<String>>) -> Result<Self> {
57 let CertifiedKey { cert, signing_key } = generate_simple_self_signed(subject_alt_names)?;
58 Ok(Certificate {
59 certificate: vec![cert.der().to_owned()],
60 private_key: CryptoPrivateKey::try_from(&signing_key)?,
61 })
62 }
63
64 pub fn generate_self_signed_with_alg(
68 subject_alt_names: impl Into<Vec<String>>,
69 alg: &'static rcgen::SignatureAlgorithm,
70 ) -> Result<Self> {
71 let params = rcgen::CertificateParams::new(subject_alt_names).unwrap();
72 let key_pair = rcgen::KeyPair::generate_for(alg).unwrap();
73 let cert = params.self_signed(&key_pair).unwrap();
74
75 Ok(Certificate {
76 certificate: vec![cert.der().to_owned()],
77 private_key: CryptoPrivateKey::try_from(&key_pair)?,
78 })
79 }
80
81 #[cfg(feature = "pem")]
83 pub fn from_pem(pem_str: &str) -> Result<Self> {
84 let mut pems = pem::parse_many(pem_str).map_err(|e| Error::InvalidPEM(e.to_string()))?;
85 if pems.len() < 2 {
86 return Err(Error::InvalidPEM(format!(
87 "expected at least two PEM blocks, got {}",
88 pems.len()
89 )));
90 }
91 if pems[0].tag() != "PRIVATE_KEY" {
92 return Err(Error::InvalidPEM(format!(
93 "invalid tag (expected: 'PRIVATE_KEY', got: '{}')",
94 pems[0].tag()
95 )));
96 }
97
98 let keypair = KeyPair::try_from(pems[0].contents())
99 .map_err(|e| Error::InvalidPEM(format!("can't decode keypair: {e}")))?;
100
101 let mut rustls_certs = Vec::new();
102 for p in pems.drain(1..) {
103 if p.tag() != "CERTIFICATE" {
104 return Err(Error::InvalidPEM(format!(
105 "invalid tag (expected: 'CERTIFICATE', got: '{}')",
106 p.tag()
107 )));
108 }
109 rustls_certs.push(CertificateDer::from(p.contents().to_vec()));
110 }
111
112 Ok(Certificate {
113 certificate: rustls_certs,
114 private_key: CryptoPrivateKey::try_from(&keypair)?,
115 })
116 }
117
118 #[cfg(feature = "pem")]
120 pub fn serialize_pem(&self) -> String {
121 let mut data = vec![pem::Pem::new(
122 "PRIVATE_KEY".to_string(),
123 self.private_key.serialized_der.clone(),
124 )];
125 for rustls_cert in &self.certificate {
126 data.push(pem::Pem::new(
127 "CERTIFICATE".to_string(),
128 rustls_cert.as_ref(),
129 ));
130 }
131 pem::encode_many(&data)
132 }
133}
134
135pub(crate) fn value_key_message(
136 client_random: &[u8],
137 server_random: &[u8],
138 public_key: &[u8],
139 named_curve: NamedCurve,
140) -> Vec<u8> {
141 let mut server_ecdh_params = vec![0u8; 4];
142 server_ecdh_params[0] = 3; server_ecdh_params[1..3].copy_from_slice(&(named_curve as u16).to_be_bytes());
144 server_ecdh_params[3] = public_key.len() as u8;
145
146 let mut plaintext = vec![];
147 plaintext.extend_from_slice(client_random);
148 plaintext.extend_from_slice(server_random);
149 plaintext.extend_from_slice(&server_ecdh_params);
150 plaintext.extend_from_slice(public_key);
151
152 plaintext
153}
154
155pub trait CustomSigner: Send + Sync + std::fmt::Debug {
161 fn sign(&self, message: &[u8]) -> std::result::Result<Vec<u8>, String>;
163
164 fn clone_box(&self) -> Box<dyn CustomSigner>;
166}
167
168#[derive(Debug)]
170pub enum CryptoPrivateKeyKind {
171 Ed25519(Ed25519KeyPair),
173 Ecdsa256(EcdsaKeyPair),
175 Rsa256(ring::rsa::KeyPair),
177 Custom(Box<dyn CustomSigner>),
181}
182
183#[derive(Debug)]
185pub struct CryptoPrivateKey {
186 pub kind: CryptoPrivateKeyKind,
188 pub serialized_der: Vec<u8>,
190}
191
192impl PartialEq for CryptoPrivateKey {
193 fn eq(&self, other: &Self) -> bool {
194 if self.serialized_der != other.serialized_der {
195 return false;
196 }
197
198 matches!(
199 (&self.kind, &other.kind),
200 (
201 CryptoPrivateKeyKind::Rsa256(_),
202 CryptoPrivateKeyKind::Rsa256(_)
203 ) | (
204 CryptoPrivateKeyKind::Ecdsa256(_),
205 CryptoPrivateKeyKind::Ecdsa256(_)
206 ) | (
207 CryptoPrivateKeyKind::Ed25519(_),
208 CryptoPrivateKeyKind::Ed25519(_)
209 ) | (
210 CryptoPrivateKeyKind::Custom(_),
211 CryptoPrivateKeyKind::Custom(_)
212 )
213 )
214 }
215}
216
217impl Clone for CryptoPrivateKey {
218 fn clone(&self) -> Self {
219 match self.kind {
220 CryptoPrivateKeyKind::Ed25519(_) => CryptoPrivateKey {
221 kind: CryptoPrivateKeyKind::Ed25519(
222 Ed25519KeyPair::from_pkcs8_maybe_unchecked(&self.serialized_der).unwrap(),
223 ),
224 serialized_der: self.serialized_der.clone(),
225 },
226 CryptoPrivateKeyKind::Ecdsa256(_) => CryptoPrivateKey {
227 kind: CryptoPrivateKeyKind::Ecdsa256(
228 EcdsaKeyPair::from_pkcs8(
229 &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING,
230 &self.serialized_der,
231 #[cfg(feature = "ring")]
232 &SystemRandom::new(),
233 )
234 .unwrap(),
235 ),
236 serialized_der: self.serialized_der.clone(),
237 },
238 CryptoPrivateKeyKind::Rsa256(_) => CryptoPrivateKey {
239 kind: CryptoPrivateKeyKind::Rsa256(
240 ring::rsa::KeyPair::from_pkcs8(&self.serialized_der).unwrap(),
241 ),
242 serialized_der: self.serialized_der.clone(),
243 },
244 CryptoPrivateKeyKind::Custom(ref signer) => CryptoPrivateKey {
245 kind: CryptoPrivateKeyKind::Custom(signer.clone_box()),
246 serialized_der: self.serialized_der.clone(),
247 },
248 }
249 }
250}
251
252impl TryFrom<&KeyPair> for CryptoPrivateKey {
253 type Error = Error;
254
255 fn try_from(key_pair: &KeyPair) -> Result<Self> {
256 Self::from_key_pair(key_pair)
257 }
258}
259
260impl CryptoPrivateKey {
261 pub fn from_key_pair(key_pair: &KeyPair) -> Result<Self> {
267 let serialized_der = key_pair.serialize_der();
268 if key_pair.is_compatible(&rcgen::PKCS_ED25519) {
269 Ok(CryptoPrivateKey {
270 kind: CryptoPrivateKeyKind::Ed25519(
271 Ed25519KeyPair::from_pkcs8_maybe_unchecked(&serialized_der)
272 .map_err(|e| Error::Other(e.to_string()))?,
273 ),
274 serialized_der,
275 })
276 } else if key_pair.is_compatible(&rcgen::PKCS_ECDSA_P256_SHA256) {
277 Ok(CryptoPrivateKey {
278 kind: CryptoPrivateKeyKind::Ecdsa256(
279 EcdsaKeyPair::from_pkcs8(
280 &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING,
281 &serialized_der,
282 #[cfg(feature = "ring")]
283 &SystemRandom::new(),
284 )
285 .map_err(|e| Error::Other(e.to_string()))?,
286 ),
287 serialized_der,
288 })
289 } else if key_pair.is_compatible(&rcgen::PKCS_RSA_SHA256) {
290 Ok(CryptoPrivateKey {
291 kind: CryptoPrivateKeyKind::Rsa256(
292 ring::rsa::KeyPair::from_pkcs8(&serialized_der)
293 .map_err(|e| Error::Other(e.to_string()))?,
294 ),
295 serialized_der,
296 })
297 } else {
298 Err(Error::Other("Unsupported key_pair".to_owned()))
299 }
300 }
301}
302
303pub(crate) fn generate_key_signature(
309 client_random: &[u8],
310 server_random: &[u8],
311 public_key: &[u8],
312 named_curve: NamedCurve,
313 private_key: &CryptoPrivateKey, ) -> Result<Vec<u8>> {
315 let msg = value_key_message(client_random, server_random, public_key, named_curve);
316 let signature = match &private_key.kind {
317 CryptoPrivateKeyKind::Ed25519(kp) => kp.sign(&msg).as_ref().to_vec(),
318 CryptoPrivateKeyKind::Ecdsa256(kp) => {
319 let system_random = SystemRandom::new();
320 kp.sign(&system_random, &msg)
321 .map_err(|e| Error::Other(e.to_string()))?
322 .as_ref()
323 .to_vec()
324 }
325 CryptoPrivateKeyKind::Rsa256(kp) => {
326 let system_random = SystemRandom::new();
327 #[cfg(feature = "ring")]
328 let mut signature = vec![0; kp.public().modulus_len()];
329 #[cfg(feature = "aws-lc-rs")]
330 let mut signature = vec![0; kp.public_modulus_len()];
331 kp.sign(
332 &ring::signature::RSA_PKCS1_SHA256,
333 &system_random,
334 &msg,
335 &mut signature,
336 )
337 .map_err(|e| Error::Other(e.to_string()))?;
338
339 signature
340 }
341 CryptoPrivateKeyKind::Custom(signer) => signer.sign(&msg).map_err(Error::Other)?,
342 };
343
344 Ok(signature)
345}
346
347pub const OID_ED25519: Oid<'static> = oid!(1.3.101.112);
350pub const OID_ECDSA: Oid<'static> = oid!(1.2.840.10045.2.1);
352
353fn verify_signature(
354 message: &[u8],
355 hash_algorithm: &SignatureHashAlgorithm,
356 remote_key_signature: &[u8],
357 raw_certificates: &[Vec<u8>],
358 insecure_verification: bool,
359) -> Result<()> {
360 if raw_certificates.is_empty() {
361 return Err(Error::ErrLengthMismatch);
362 }
363
364 let (_, certificate) = x509_parser::parse_x509_certificate(&raw_certificates[0])
365 .map_err(|e| Error::Other(e.to_string()))?;
366
367 let verify_alg: &dyn ring::signature::VerificationAlgorithm = match hash_algorithm.signature {
368 SignatureAlgorithm::Ed25519 => &ring::signature::ED25519,
369 SignatureAlgorithm::Ecdsa if hash_algorithm.hash == HashAlgorithm::Sha256 => {
370 &ring::signature::ECDSA_P256_SHA256_ASN1
371 }
372 SignatureAlgorithm::Ecdsa if hash_algorithm.hash == HashAlgorithm::Sha384 => {
373 &ring::signature::ECDSA_P384_SHA384_ASN1
374 }
375 SignatureAlgorithm::Rsa if hash_algorithm.hash == HashAlgorithm::Sha1 => {
376 &ring::signature::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY
377 }
378 SignatureAlgorithm::Rsa if (hash_algorithm.hash == HashAlgorithm::Sha256) => {
379 if remote_key_signature.len() < 256 && insecure_verification {
380 &ring::signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY
381 } else {
382 &ring::signature::RSA_PKCS1_2048_8192_SHA256
383 }
384 }
385 SignatureAlgorithm::Rsa if hash_algorithm.hash == HashAlgorithm::Sha384 => {
386 &ring::signature::RSA_PKCS1_2048_8192_SHA384
387 }
388 SignatureAlgorithm::Rsa if hash_algorithm.hash == HashAlgorithm::Sha512 => {
389 if remote_key_signature.len() < 256 && insecure_verification {
390 &ring::signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY
391 } else {
392 &ring::signature::RSA_PKCS1_2048_8192_SHA512
393 }
394 }
395 _ => return Err(Error::ErrKeySignatureVerifyUnimplemented),
396 };
397
398 log::trace!("Picked an algorithm {verify_alg:?}");
399
400 let public_key = ring::signature::UnparsedPublicKey::new(
401 verify_alg,
402 certificate
403 .tbs_certificate
404 .subject_pki
405 .subject_public_key
406 .data,
407 );
408
409 public_key
410 .verify(message, remote_key_signature)
411 .map_err(|e| Error::Other(e.to_string()))?;
412
413 Ok(())
414}
415
416pub(crate) fn verify_key_signature(
417 message: &[u8],
418 hash_algorithm: &SignatureHashAlgorithm,
419 remote_key_signature: &[u8],
420 raw_certificates: &[Vec<u8>],
421 insecure_verification: bool,
422) -> Result<()> {
423 verify_signature(
424 message,
425 hash_algorithm,
426 remote_key_signature,
427 raw_certificates,
428 insecure_verification,
429 )
430}
431
432pub(crate) fn generate_certificate_verify(
441 handshake_bodies: &[u8],
442 private_key: &CryptoPrivateKey, ) -> Result<Vec<u8>> {
444 let signature = match &private_key.kind {
445 CryptoPrivateKeyKind::Ed25519(kp) => kp.sign(handshake_bodies).as_ref().to_vec(),
446 CryptoPrivateKeyKind::Ecdsa256(kp) => {
447 let system_random = SystemRandom::new();
448 kp.sign(&system_random, handshake_bodies)
449 .map_err(|e| Error::Other(e.to_string()))?
450 .as_ref()
451 .to_vec()
452 }
453 CryptoPrivateKeyKind::Rsa256(kp) => {
454 let system_random = SystemRandom::new();
455 #[cfg(feature = "ring")]
456 let mut signature = vec![0; kp.public().modulus_len()];
457 #[cfg(feature = "aws-lc-rs")]
458 let mut signature = vec![0; kp.public_modulus_len()];
459 kp.sign(
460 &ring::signature::RSA_PKCS1_SHA256,
461 &system_random,
462 handshake_bodies,
463 &mut signature,
464 )
465 .map_err(|e| Error::Other(e.to_string()))?;
466
467 signature
468 }
469 CryptoPrivateKeyKind::Custom(signer) => {
470 signer.sign(handshake_bodies).map_err(Error::Other)?
471 }
472 };
473
474 Ok(signature)
475}
476
477pub(crate) fn verify_certificate_verify(
478 handshake_bodies: &[u8],
479 hash_algorithm: &SignatureHashAlgorithm,
480 remote_key_signature: &[u8],
481 raw_certificates: &[Vec<u8>],
482 insecure_verification: bool,
483) -> Result<()> {
484 verify_signature(
485 handshake_bodies,
486 hash_algorithm,
487 remote_key_signature,
488 raw_certificates,
489 insecure_verification,
490 )
491}
492
493pub(crate) fn load_certs(raw_certificates: &[Vec<u8>]) -> Result<Vec<CertificateDer<'static>>> {
494 if raw_certificates.is_empty() {
495 return Err(Error::ErrLengthMismatch);
496 }
497
498 let mut certs = vec![];
499 for raw_cert in raw_certificates {
500 let cert = CertificateDer::from(raw_cert.to_vec());
501 certs.push(cert);
502 }
503
504 Ok(certs)
505}
506
507pub(crate) fn verify_client_cert(
508 raw_certificates: &[Vec<u8>],
509 cert_verifier: &Arc<dyn ClientCertVerifier>,
510) -> Result<Vec<CertificateDer<'static>>> {
511 let chains = load_certs(raw_certificates)?;
512
513 let (end_entity, intermediates) = chains
514 .split_first()
515 .ok_or(Error::ErrClientCertificateRequired)?;
516
517 match cert_verifier.verify_client_cert(
518 end_entity,
519 intermediates,
520 rustls::pki_types::UnixTime::now(),
521 ) {
522 Ok(_) => {}
523 Err(err) => return Err(Error::Other(err.to_string())),
524 };
525
526 Ok(chains)
527}
528
529pub(crate) fn verify_server_cert(
530 raw_certificates: &[Vec<u8>],
531 cert_verifier: &Arc<dyn ServerCertVerifier>,
532 server_name: &str,
533) -> Result<Vec<CertificateDer<'static>>> {
534 let chains = load_certs(raw_certificates)?;
535 let server_name = match ServerName::try_from(server_name) {
536 Ok(server_name) => server_name,
537 Err(err) => return Err(Error::Other(err.to_string())),
538 };
539
540 let (end_entity, intermediates) = chains
541 .split_first()
542 .ok_or(Error::ErrServerMustHaveCertificate)?;
543 match cert_verifier.verify_server_cert(
544 end_entity,
545 intermediates,
546 &server_name,
547 &[],
548 rustls::pki_types::UnixTime::now(),
549 ) {
550 Ok(_) => {}
551 Err(err) => return Err(Error::Other(err.to_string())),
552 };
553
554 Ok(chains)
555}
556
557pub(crate) fn generate_aead_additional_data(h: &RecordLayerHeader, payload_len: usize) -> [u8; 13] {
558 let mut additional_data = [0u8; 13];
559 additional_data[..8].copy_from_slice(&h.sequence_number.to_be_bytes());
562 additional_data[..2].copy_from_slice(&h.epoch.to_be_bytes());
563 additional_data[8] = h.content_type as u8;
564 additional_data[9] = h.protocol_version.major;
565 additional_data[10] = h.protocol_version.minor;
566 additional_data[11..].copy_from_slice(&(payload_len as u16).to_be_bytes());
567
568 additional_data
569}
570
571#[cfg(test)]
572mod test {
573 #[cfg(feature = "pem")]
574 use super::*;
575
576 #[cfg(feature = "pem")]
577 #[test]
578 fn test_certificate_serialize_pem_and_from_pem() -> Result<()> {
579 let cert = Certificate::generate_self_signed(vec!["webrtc.rs".to_owned()])?;
580
581 let pem = cert.serialize_pem();
582 let loaded_cert = Certificate::from_pem(&pem)?;
583
584 assert_eq!(loaded_cert, cert);
585
586 Ok(())
587 }
588}