1 #[cfg(test)]
2 mod crypto_test;
3
4 pub mod crypto_cbc;
5 pub mod crypto_ccm;
6 pub mod crypto_gcm;
7 pub mod padding;
8
9 use crate::curve::named_curve::*;
10 use crate::error::*;
11 use crate::record_layer::record_layer_header::*;
12 use crate::signature_hash_algorithm::{HashAlgorithm, SignatureAlgorithm, SignatureHashAlgorithm};
13
14 use der_parser::{oid, oid::Oid};
15 use rcgen::KeyPair;
16 use ring::rand::SystemRandom;
17 use ring::signature::{EcdsaKeyPair, Ed25519KeyPair, RsaKeyPair};
18 use std::convert::TryFrom;
19 use std::sync::Arc;
20
21 /// A X.509 certificate(s) used to authenticate a DTLS connection.
22 #[derive(Clone, PartialEq, Debug)]
23 pub struct Certificate {
24 /// DER-encoded certificates.
25 pub certificate: Vec<rustls::Certificate>,
26 /// Private key.
27 pub private_key: CryptoPrivateKey,
28 }
29
30 impl Certificate {
31 /// Generate a self-signed certificate.
32 ///
33 /// See [`rcgen::generate_simple_self_signed`].
generate_self_signed(subject_alt_names: impl Into<Vec<String>>) -> Result<Self>34 pub fn generate_self_signed(subject_alt_names: impl Into<Vec<String>>) -> Result<Self> {
35 let cert = rcgen::generate_simple_self_signed(subject_alt_names)?;
36 let key_pair = cert.get_key_pair();
37
38 Ok(Certificate {
39 certificate: vec![rustls::Certificate(cert.serialize_der()?)],
40 private_key: CryptoPrivateKey::try_from(key_pair)?,
41 })
42 }
43
44 /// Generate a self-signed certificate with the given algorithm.
45 ///
46 /// See [`rcgen::Certificate::from_params`].
generate_self_signed_with_alg( subject_alt_names: impl Into<Vec<String>>, alg: &'static rcgen::SignatureAlgorithm, ) -> Result<Self>47 pub fn generate_self_signed_with_alg(
48 subject_alt_names: impl Into<Vec<String>>,
49 alg: &'static rcgen::SignatureAlgorithm,
50 ) -> Result<Self> {
51 let mut params = rcgen::CertificateParams::new(subject_alt_names);
52 params.alg = alg;
53 let cert = rcgen::Certificate::from_params(params)?;
54 let key_pair = cert.get_key_pair();
55
56 Ok(Certificate {
57 certificate: vec![rustls::Certificate(cert.serialize_der()?)],
58 private_key: CryptoPrivateKey::try_from(key_pair)?,
59 })
60 }
61
62 /// Parses a certificate from the ASCII PEM format.
63 #[cfg(feature = "pem")]
from_pem(pem_str: &str) -> Result<Self>64 pub fn from_pem(pem_str: &str) -> Result<Self> {
65 let mut pems = pem::parse_many(pem_str).map_err(|e| Error::InvalidPEM(e.to_string()))?;
66 if pems.len() < 2 {
67 return Err(Error::InvalidPEM(format!(
68 "expected at least two PEM blocks, got {}",
69 pems.len()
70 )));
71 }
72 if pems[0].tag != "PRIVATE_KEY" {
73 return Err(Error::InvalidPEM(format!(
74 "invalid tag (expected: 'PRIVATE_KEY', got: '{}')",
75 pems[0].tag
76 )));
77 }
78
79 let keypair = rcgen::KeyPair::from_der(&pems[0].contents)
80 .map_err(|e| Error::InvalidPEM(format!("can't decode keypair: {e}")))?;
81
82 let mut rustls_certs = Vec::new();
83 for p in pems.drain(1..) {
84 if p.tag != "CERTIFICATE" {
85 return Err(Error::InvalidPEM(format!(
86 "invalid tag (expected: 'CERTIFICATE', got: '{}')",
87 p.tag
88 )));
89 }
90 rustls_certs.push(rustls::Certificate(p.contents));
91 }
92
93 Ok(Certificate {
94 certificate: rustls_certs,
95 private_key: CryptoPrivateKey::try_from(&keypair)?,
96 })
97 }
98
99 /// Serializes the certificate (including the private key) in PKCS#8 format in PEM.
100 #[cfg(feature = "pem")]
serialize_pem(&self) -> String101 pub fn serialize_pem(&self) -> String {
102 let mut data = vec![pem::Pem {
103 tag: "PRIVATE_KEY".to_string(),
104 contents: self.private_key.serialized_der.clone(),
105 }];
106 for rustls_cert in &self.certificate {
107 data.push(pem::Pem {
108 tag: "CERTIFICATE".to_string(),
109 contents: rustls_cert.0.clone(),
110 });
111 }
112 pem::encode_many(&data)
113 }
114 }
115
value_key_message( client_random: &[u8], server_random: &[u8], public_key: &[u8], named_curve: NamedCurve, ) -> Vec<u8>116 pub(crate) fn value_key_message(
117 client_random: &[u8],
118 server_random: &[u8],
119 public_key: &[u8],
120 named_curve: NamedCurve,
121 ) -> Vec<u8> {
122 let mut server_ecdh_params = vec![0u8; 4];
123 server_ecdh_params[0] = 3; // named curve
124 server_ecdh_params[1..3].copy_from_slice(&(named_curve as u16).to_be_bytes());
125 server_ecdh_params[3] = public_key.len() as u8;
126
127 let mut plaintext = vec![];
128 plaintext.extend_from_slice(client_random);
129 plaintext.extend_from_slice(server_random);
130 plaintext.extend_from_slice(&server_ecdh_params);
131 plaintext.extend_from_slice(public_key);
132
133 plaintext
134 }
135
136 /// Either ED25519, ECDSA or RSA keypair.
137 #[derive(Debug)]
138 pub enum CryptoPrivateKeyKind {
139 Ed25519(Ed25519KeyPair),
140 Ecdsa256(EcdsaKeyPair),
141 Rsa256(RsaKeyPair),
142 }
143
144 /// Private key.
145 #[derive(Debug)]
146 pub struct CryptoPrivateKey {
147 /// Keypair.
148 pub kind: CryptoPrivateKeyKind,
149 /// DER-encoded keypair.
150 pub serialized_der: Vec<u8>,
151 }
152
153 impl PartialEq for CryptoPrivateKey {
eq(&self, other: &Self) -> bool154 fn eq(&self, other: &Self) -> bool {
155 if self.serialized_der != other.serialized_der {
156 return false;
157 }
158
159 matches!(
160 (&self.kind, &other.kind),
161 (
162 CryptoPrivateKeyKind::Rsa256(_),
163 CryptoPrivateKeyKind::Rsa256(_)
164 ) | (
165 CryptoPrivateKeyKind::Ecdsa256(_),
166 CryptoPrivateKeyKind::Ecdsa256(_)
167 ) | (
168 CryptoPrivateKeyKind::Ed25519(_),
169 CryptoPrivateKeyKind::Ed25519(_)
170 )
171 )
172 }
173 }
174
175 impl Clone for CryptoPrivateKey {
clone(&self) -> Self176 fn clone(&self) -> Self {
177 match self.kind {
178 CryptoPrivateKeyKind::Ed25519(_) => CryptoPrivateKey {
179 kind: CryptoPrivateKeyKind::Ed25519(
180 Ed25519KeyPair::from_pkcs8(&self.serialized_der).unwrap(),
181 ),
182 serialized_der: self.serialized_der.clone(),
183 },
184 CryptoPrivateKeyKind::Ecdsa256(_) => CryptoPrivateKey {
185 kind: CryptoPrivateKeyKind::Ecdsa256(
186 EcdsaKeyPair::from_pkcs8(
187 &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING,
188 &self.serialized_der,
189 )
190 .unwrap(),
191 ),
192 serialized_der: self.serialized_der.clone(),
193 },
194 CryptoPrivateKeyKind::Rsa256(_) => CryptoPrivateKey {
195 kind: CryptoPrivateKeyKind::Rsa256(
196 RsaKeyPair::from_pkcs8(&self.serialized_der).unwrap(),
197 ),
198 serialized_der: self.serialized_der.clone(),
199 },
200 }
201 }
202 }
203
204 impl TryFrom<&KeyPair> for CryptoPrivateKey {
205 type Error = Error;
206
try_from(key_pair: &KeyPair) -> Result<Self>207 fn try_from(key_pair: &KeyPair) -> Result<Self> {
208 let serialized_der = key_pair.serialize_der();
209 if key_pair.is_compatible(&rcgen::PKCS_ED25519) {
210 Ok(CryptoPrivateKey {
211 kind: CryptoPrivateKeyKind::Ed25519(
212 Ed25519KeyPair::from_pkcs8(&serialized_der)
213 .map_err(|e| Error::Other(e.to_string()))?,
214 ),
215 serialized_der,
216 })
217 } else if key_pair.is_compatible(&rcgen::PKCS_ECDSA_P256_SHA256) {
218 Ok(CryptoPrivateKey {
219 kind: CryptoPrivateKeyKind::Ecdsa256(
220 EcdsaKeyPair::from_pkcs8(
221 &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING,
222 &serialized_der,
223 )
224 .map_err(|e| Error::Other(e.to_string()))?,
225 ),
226 serialized_der,
227 })
228 } else if key_pair.is_compatible(&rcgen::PKCS_RSA_SHA256) {
229 Ok(CryptoPrivateKey {
230 kind: CryptoPrivateKeyKind::Rsa256(
231 RsaKeyPair::from_pkcs8(&serialized_der)
232 .map_err(|e| Error::Other(e.to_string()))?,
233 ),
234 serialized_der,
235 })
236 } else {
237 Err(Error::Other("Unsupported key_pair".to_owned()))
238 }
239 }
240 }
241
242 impl CryptoPrivateKey {
from_key_pair(key_pair: &KeyPair) -> Result<Self>243 pub fn from_key_pair(key_pair: &KeyPair) -> Result<Self> {
244 let serialized_der = key_pair.serialize_der();
245 if key_pair.is_compatible(&rcgen::PKCS_ED25519) {
246 Ok(CryptoPrivateKey {
247 kind: CryptoPrivateKeyKind::Ed25519(
248 Ed25519KeyPair::from_pkcs8(&serialized_der)
249 .map_err(|e| Error::Other(e.to_string()))?,
250 ),
251 serialized_der,
252 })
253 } else if key_pair.is_compatible(&rcgen::PKCS_ECDSA_P256_SHA256) {
254 Ok(CryptoPrivateKey {
255 kind: CryptoPrivateKeyKind::Ecdsa256(
256 EcdsaKeyPair::from_pkcs8(
257 &ring::signature::ECDSA_P256_SHA256_ASN1_SIGNING,
258 &serialized_der,
259 )
260 .map_err(|e| Error::Other(e.to_string()))?,
261 ),
262 serialized_der,
263 })
264 } else if key_pair.is_compatible(&rcgen::PKCS_RSA_SHA256) {
265 Ok(CryptoPrivateKey {
266 kind: CryptoPrivateKeyKind::Rsa256(
267 RsaKeyPair::from_pkcs8(&serialized_der)
268 .map_err(|e| Error::Other(e.to_string()))?,
269 ),
270 serialized_der,
271 })
272 } else {
273 Err(Error::Other("Unsupported key_pair".to_owned()))
274 }
275 }
276 }
277
278 // If the client provided a "signature_algorithms" extension, then all
279 // certificates provided by the server MUST be signed by a
280 // hash/signature algorithm pair that appears in that extension
281 //
282 // https://tools.ietf.org/html/rfc5246#section-7.4.2
generate_key_signature( client_random: &[u8], server_random: &[u8], public_key: &[u8], named_curve: NamedCurve, private_key: &CryptoPrivateKey, ) -> Result<Vec<u8>>283 pub(crate) fn generate_key_signature(
284 client_random: &[u8],
285 server_random: &[u8],
286 public_key: &[u8],
287 named_curve: NamedCurve,
288 private_key: &CryptoPrivateKey, /*, hash_algorithm: HashAlgorithm*/
289 ) -> Result<Vec<u8>> {
290 let msg = value_key_message(client_random, server_random, public_key, named_curve);
291 let signature = match &private_key.kind {
292 CryptoPrivateKeyKind::Ed25519(kp) => kp.sign(&msg).as_ref().to_vec(),
293 CryptoPrivateKeyKind::Ecdsa256(kp) => {
294 let system_random = SystemRandom::new();
295 kp.sign(&system_random, &msg)
296 .map_err(|e| Error::Other(e.to_string()))?
297 .as_ref()
298 .to_vec()
299 }
300 CryptoPrivateKeyKind::Rsa256(kp) => {
301 let system_random = SystemRandom::new();
302 let mut signature = vec![0; kp.public_modulus_len()];
303 kp.sign(
304 &ring::signature::RSA_PKCS1_SHA256,
305 &system_random,
306 &msg,
307 &mut signature,
308 )
309 .map_err(|e| Error::Other(e.to_string()))?;
310
311 signature
312 }
313 };
314
315 Ok(signature)
316 }
317
318 // add OID_ED25519 which is not defined in x509_parser
319 pub const OID_ED25519: Oid<'static> = oid!(1.3.101 .112);
320 pub const OID_ECDSA: Oid<'static> = oid!(1.2.840 .10045 .2 .1);
321
verify_signature( message: &[u8], hash_algorithm: &SignatureHashAlgorithm, remote_key_signature: &[u8], raw_certificates: &[Vec<u8>], insecure_verification: bool, ) -> Result<()>322 fn verify_signature(
323 message: &[u8],
324 hash_algorithm: &SignatureHashAlgorithm,
325 remote_key_signature: &[u8],
326 raw_certificates: &[Vec<u8>],
327 insecure_verification: bool,
328 ) -> Result<()> {
329 if raw_certificates.is_empty() {
330 return Err(Error::ErrLengthMismatch);
331 }
332
333 let (_, certificate) = x509_parser::parse_x509_certificate(&raw_certificates[0])
334 .map_err(|e| Error::Other(e.to_string()))?;
335
336 let verify_alg: &dyn ring::signature::VerificationAlgorithm = match hash_algorithm.signature {
337 SignatureAlgorithm::Ed25519 => &ring::signature::ED25519,
338 SignatureAlgorithm::Ecdsa if hash_algorithm.hash == HashAlgorithm::Sha256 => {
339 &ring::signature::ECDSA_P256_SHA256_ASN1
340 }
341 SignatureAlgorithm::Ecdsa if hash_algorithm.hash == HashAlgorithm::Sha384 => {
342 &ring::signature::ECDSA_P384_SHA384_ASN1
343 }
344 SignatureAlgorithm::Rsa if hash_algorithm.hash == HashAlgorithm::Sha1 => {
345 &ring::signature::RSA_PKCS1_1024_8192_SHA1_FOR_LEGACY_USE_ONLY
346 }
347 SignatureAlgorithm::Rsa if (hash_algorithm.hash == HashAlgorithm::Sha256) => {
348 if remote_key_signature.len() < 256 && insecure_verification {
349 &ring::signature::RSA_PKCS1_1024_8192_SHA256_FOR_LEGACY_USE_ONLY
350 } else {
351 &ring::signature::RSA_PKCS1_2048_8192_SHA256
352 }
353 }
354 SignatureAlgorithm::Rsa if hash_algorithm.hash == HashAlgorithm::Sha384 => {
355 &ring::signature::RSA_PKCS1_2048_8192_SHA384
356 }
357 SignatureAlgorithm::Rsa if hash_algorithm.hash == HashAlgorithm::Sha512 => {
358 if remote_key_signature.len() < 256 && insecure_verification {
359 &ring::signature::RSA_PKCS1_1024_8192_SHA512_FOR_LEGACY_USE_ONLY
360 } else {
361 &ring::signature::RSA_PKCS1_2048_8192_SHA512
362 }
363 }
364 _ => return Err(Error::ErrKeySignatureVerifyUnimplemented),
365 };
366
367 log::trace!("Picked an algorithm {:?}", verify_alg);
368
369 let public_key = ring::signature::UnparsedPublicKey::new(
370 verify_alg,
371 certificate
372 .tbs_certificate
373 .subject_pki
374 .subject_public_key
375 .data,
376 );
377
378 public_key
379 .verify(message, remote_key_signature)
380 .map_err(|e| Error::Other(e.to_string()))?;
381
382 Ok(())
383 }
384
verify_key_signature( message: &[u8], hash_algorithm: &SignatureHashAlgorithm, remote_key_signature: &[u8], raw_certificates: &[Vec<u8>], insecure_verification: bool, ) -> Result<()>385 pub(crate) fn verify_key_signature(
386 message: &[u8],
387 hash_algorithm: &SignatureHashAlgorithm,
388 remote_key_signature: &[u8],
389 raw_certificates: &[Vec<u8>],
390 insecure_verification: bool,
391 ) -> Result<()> {
392 verify_signature(
393 message,
394 hash_algorithm,
395 remote_key_signature,
396 raw_certificates,
397 insecure_verification,
398 )
399 }
400
401 // If the server has sent a CertificateRequest message, the client MUST send the Certificate
402 // message. The ClientKeyExchange message is now sent, and the content
403 // of that message will depend on the public key algorithm selected
404 // between the ClientHello and the ServerHello. If the client has sent
405 // a certificate with signing ability, a digitally-signed
406 // CertificateVerify message is sent to explicitly verify possession of
407 // the private key in the certificate.
408 // https://tools.ietf.org/html/rfc5246#section-7.3
generate_certificate_verify( handshake_bodies: &[u8], private_key: &CryptoPrivateKey, ) -> Result<Vec<u8>>409 pub(crate) fn generate_certificate_verify(
410 handshake_bodies: &[u8],
411 private_key: &CryptoPrivateKey, /*, hashAlgorithm hashAlgorithm*/
412 ) -> Result<Vec<u8>> {
413 let signature = match &private_key.kind {
414 CryptoPrivateKeyKind::Ed25519(kp) => kp.sign(handshake_bodies).as_ref().to_vec(),
415 CryptoPrivateKeyKind::Ecdsa256(kp) => {
416 let system_random = SystemRandom::new();
417 kp.sign(&system_random, handshake_bodies)
418 .map_err(|e| Error::Other(e.to_string()))?
419 .as_ref()
420 .to_vec()
421 }
422 CryptoPrivateKeyKind::Rsa256(kp) => {
423 let system_random = SystemRandom::new();
424 let mut signature = vec![0; kp.public_modulus_len()];
425 kp.sign(
426 &ring::signature::RSA_PKCS1_SHA256,
427 &system_random,
428 handshake_bodies,
429 &mut signature,
430 )
431 .map_err(|e| Error::Other(e.to_string()))?;
432
433 signature
434 }
435 };
436
437 Ok(signature)
438 }
439
verify_certificate_verify( handshake_bodies: &[u8], hash_algorithm: &SignatureHashAlgorithm, remote_key_signature: &[u8], raw_certificates: &[Vec<u8>], insecure_verification: bool, ) -> Result<()>440 pub(crate) fn verify_certificate_verify(
441 handshake_bodies: &[u8],
442 hash_algorithm: &SignatureHashAlgorithm,
443 remote_key_signature: &[u8],
444 raw_certificates: &[Vec<u8>],
445 insecure_verification: bool,
446 ) -> Result<()> {
447 verify_signature(
448 handshake_bodies,
449 hash_algorithm,
450 remote_key_signature,
451 raw_certificates,
452 insecure_verification,
453 )
454 }
455
load_certs(raw_certificates: &[Vec<u8>]) -> Result<Vec<rustls::Certificate>>456 pub(crate) fn load_certs(raw_certificates: &[Vec<u8>]) -> Result<Vec<rustls::Certificate>> {
457 if raw_certificates.is_empty() {
458 return Err(Error::ErrLengthMismatch);
459 }
460
461 let mut certs = vec![];
462 for raw_cert in raw_certificates {
463 let cert = rustls::Certificate(raw_cert.to_vec());
464 certs.push(cert);
465 }
466
467 Ok(certs)
468 }
469
verify_client_cert( raw_certificates: &[Vec<u8>], cert_verifier: &Arc<dyn rustls::ClientCertVerifier>, ) -> Result<Vec<rustls::Certificate>>470 pub(crate) fn verify_client_cert(
471 raw_certificates: &[Vec<u8>],
472 cert_verifier: &Arc<dyn rustls::ClientCertVerifier>,
473 ) -> Result<Vec<rustls::Certificate>> {
474 let chains = load_certs(raw_certificates)?;
475
476 match cert_verifier.verify_client_cert(&chains, None) {
477 Ok(_) => {}
478 Err(err) => return Err(Error::Other(err.to_string())),
479 };
480
481 Ok(chains)
482 }
483
verify_server_cert( raw_certificates: &[Vec<u8>], cert_verifier: &Arc<dyn rustls::ServerCertVerifier>, roots: &rustls::RootCertStore, server_name: &str, ) -> Result<Vec<rustls::Certificate>>484 pub(crate) fn verify_server_cert(
485 raw_certificates: &[Vec<u8>],
486 cert_verifier: &Arc<dyn rustls::ServerCertVerifier>,
487 roots: &rustls::RootCertStore,
488 server_name: &str,
489 ) -> Result<Vec<rustls::Certificate>> {
490 let chains = load_certs(raw_certificates)?;
491 let dns_name = match webpki::DNSNameRef::try_from_ascii_str(server_name) {
492 Ok(dns_name) => dns_name,
493 Err(err) => return Err(Error::Other(err.to_string())),
494 };
495
496 match cert_verifier.verify_server_cert(roots, &chains, dns_name, &[]) {
497 Ok(_) => {}
498 Err(err) => return Err(Error::Other(err.to_string())),
499 };
500
501 Ok(chains)
502 }
503
generate_aead_additional_data(h: &RecordLayerHeader, payload_len: usize) -> Vec<u8>504 pub(crate) fn generate_aead_additional_data(h: &RecordLayerHeader, payload_len: usize) -> Vec<u8> {
505 let mut additional_data = vec![0u8; 13];
506 // SequenceNumber MUST be set first
507 // we only want uint48, clobbering an extra 2 (using uint64, rust doesn't have uint48)
508 additional_data[..8].copy_from_slice(&h.sequence_number.to_be_bytes());
509 additional_data[..2].copy_from_slice(&h.epoch.to_be_bytes());
510 additional_data[8] = h.content_type as u8;
511 additional_data[9] = h.protocol_version.major;
512 additional_data[10] = h.protocol_version.minor;
513 additional_data[11..].copy_from_slice(&(payload_len as u16).to_be_bytes());
514
515 additional_data
516 }
517
518 #[cfg(test)]
519 mod test {
520 #[cfg(feature = "pem")]
521 use super::*;
522
523 #[cfg(feature = "pem")]
524 #[test]
test_certificate_serialize_pem_and_from_pem() -> Result<()>525 fn test_certificate_serialize_pem_and_from_pem() -> Result<()> {
526 let cert = Certificate::generate_self_signed(vec!["webrtc.rs".to_owned()])?;
527
528 let pem = cert.serialize_pem();
529 let loaded_cert = Certificate::from_pem(&pem)?;
530
531 assert_eq!(loaded_cert, cert);
532
533 Ok(())
534 }
535 }
536