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