lib.rs (33894B)
1 /* -*- Mode: rust; rust-indent-offset: 4 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 pub mod error; 7 8 use byteorder::{BigEndian, ReadBytesExt}; 9 10 use crate::error::{Error, ErrorType}; 11 12 // The following OID_BYTES_* consist of the contents of the bytes of an ASN.1 13 // OBJECT IDENTIFIER specifying the indicated OID (in other words, just the 14 // value, and not the tag or length). 15 pub const OID_BYTES_SHA_256: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01]; 16 pub const OID_BYTES_SHA_384: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02]; 17 pub const OID_BYTES_SHA_512: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03]; 18 pub const OID_BYTES_SHA_1: &[u8] = &[0x2b, 0x0e, 0x03, 0x02, 0x1a]; 19 20 const OID_BYTES_RSA_ENCRYPTION: &[u8] = &[0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01]; 21 const OID_BYTES_EC_PUBLIC_KEY: &[u8] = &[0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01]; 22 const OID_BYTES_SECP256R1: &[u8] = &[0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]; 23 24 /// Given a slice of DER bytes representing an RSA public key, extracts the bytes of the modulus 25 /// as an unsigned integer. Also verifies that the public exponent is present (again as an 26 /// unsigned integer). Finally verifies that reading these values consumes the entirety of the 27 /// slice. 28 /// RSAPublicKey ::= SEQUENCE { 29 /// modulus INTEGER, -- n 30 /// publicExponent INTEGER -- e 31 /// } 32 pub fn read_rsa_modulus(public_key: &[u8]) -> Result<Vec<u8>, Error> { 33 let mut sequence = Sequence::new(public_key)?; 34 let modulus_value = sequence.read_unsigned_integer()?; 35 let _exponent = sequence.read_unsigned_integer()?; 36 if !sequence.at_end() { 37 return Err(error_here!(ErrorType::ExtraInput)); 38 } 39 Ok(modulus_value.to_vec()) 40 } 41 42 /// Given a slice of DER bytes representing a SubjectPublicKeyInfo, extracts 43 /// the bytes of the parameters of the algorithm. Does not verify that all 44 /// input is consumed. 45 /// PublicKeyInfo ::= SEQUENCE { 46 /// algorithm AlgorithmIdentifier, 47 /// PublicKey BIT STRING 48 /// } 49 /// 50 /// AlgorithmIdentifier ::= SEQUENCE { 51 /// algorithm OBJECT IDENTIFIER, 52 /// parameters ANY DEFINED BY algorithm OPTIONAL 53 /// } 54 pub fn read_spki_algorithm_parameters(spki: &[u8]) -> Result<Vec<u8>, Error> { 55 let mut public_key_info = Sequence::new(spki)?; 56 let mut algorithm_identifier = public_key_info.read_sequence()?; 57 let _algorithm = algorithm_identifier.read_oid()?; 58 Ok(algorithm_identifier.read_rest().to_vec()) 59 } 60 61 /// Given a slice of DER bytes representing a DigestInfo, extracts the bytes of 62 /// the OID of the hash algorithm and the digest. 63 /// DigestInfo ::= SEQUENCE { 64 /// digestAlgorithm DigestAlgorithmIdentifier, 65 /// digest Digest } 66 /// 67 /// DigestAlgorithmIdentifier ::= AlgorithmIdentifier 68 /// 69 /// AlgorithmIdentifier ::= SEQUENCE { 70 /// algorithm OBJECT IDENTIFIER, 71 /// parameters ANY DEFINED BY algorithm OPTIONAL } 72 /// 73 /// Digest ::= OCTET STRING 74 pub fn read_digest_info(digest_info: &[u8]) -> Result<(&[u8], &[u8]), Error> { 75 let mut sequence = Sequence::new(digest_info)?; 76 let mut algorithm = sequence.read_sequence()?; 77 let oid = algorithm.read_oid()?; 78 algorithm.read_null()?; 79 if !algorithm.at_end() { 80 return Err(error_here!(ErrorType::ExtraInput)); 81 } 82 let digest = sequence.read_octet_string()?; 83 if !sequence.at_end() { 84 return Err(error_here!(ErrorType::ExtraInput)); 85 } 86 Ok((oid, digest)) 87 } 88 89 /// Converts a slice of DER bytes representing an ECDSA signature to the concatenation of the bytes 90 /// of `r` and `s`, each 0-padded to `coordinate_width`. Also verifies that this consumes the 91 /// entirety of the slice. 92 /// Ecdsa-Sig-Value ::= SEQUENCE { 93 /// r INTEGER, 94 /// s INTEGER } 95 pub fn der_ec_sig_to_raw(encoded: &[u8], coordinate_width: usize) -> Result<Vec<u8>, Error> { 96 let (r, s) = read_ec_sig_point(encoded)?; 97 if r.len() > coordinate_width || s.len() > coordinate_width { 98 return Err(error_here!(ErrorType::InvalidInput)); 99 } 100 let mut raw_signature = Vec::with_capacity(2 * coordinate_width); 101 raw_signature.resize(coordinate_width - r.len(), 0); 102 raw_signature.extend_from_slice(r); 103 raw_signature.resize((2 * coordinate_width) - s.len(), 0); 104 raw_signature.extend_from_slice(s); 105 Ok(raw_signature) 106 } 107 108 /// Given a slice of DER bytes representing an ECDSA signature, extracts the bytes of `r` and `s` 109 /// as unsigned integers. Also verifies that this consumes the entirety of the slice. 110 /// Ecdsa-Sig-Value ::= SEQUENCE { 111 /// r INTEGER, 112 /// s INTEGER } 113 fn read_ec_sig_point(signature: &[u8]) -> Result<(&[u8], &[u8]), Error> { 114 let mut sequence = Sequence::new(signature)?; 115 let r = sequence.read_unsigned_integer()?; 116 let s = sequence.read_unsigned_integer()?; 117 if !sequence.at_end() { 118 return Err(error_here!(ErrorType::ExtraInput)); 119 } 120 Ok((r, s)) 121 } 122 123 /// Given a slice of DER bytes representing an X.509 certificate, extracts the encoded serial 124 /// number, issuer, and subject. Does not verify that the remainder of the certificate is in any 125 /// way well-formed. 126 /// Certificate ::= SEQUENCE { 127 /// tbsCertificate TBSCertificate, 128 /// signatureAlgorithm AlgorithmIdentifier, 129 /// signatureValue BIT STRING } 130 /// 131 /// TBSCertificate ::= SEQUENCE { 132 /// version [0] EXPLICIT Version DEFAULT v1, 133 /// serialNumber CertificateSerialNumber, 134 /// signature AlgorithmIdentifier, 135 /// issuer Name, 136 /// validity Validity, 137 /// subject Name, 138 /// ... 139 /// 140 /// CertificateSerialNumber ::= INTEGER 141 /// 142 /// Name ::= CHOICE { -- only one possibility for now -- 143 /// rdnSequence RDNSequence } 144 /// 145 /// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName 146 /// 147 /// Validity ::= SEQUENCE { 148 /// notBefore Time, 149 /// notAfter Time } 150 #[allow(clippy::type_complexity)] 151 pub fn read_encoded_certificate_identifiers( 152 certificate: &[u8], 153 ) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>), Error> { 154 let mut certificate_sequence = Sequence::new(certificate)?; 155 let mut tbs_certificate_sequence = certificate_sequence.read_sequence()?; 156 let _version = tbs_certificate_sequence.read_optional_tagged_value(0)?; 157 let serial_number = tbs_certificate_sequence.read_encoded_sequence_component(INTEGER)?; 158 let _signature = tbs_certificate_sequence.read_sequence()?; 159 let issuer = 160 tbs_certificate_sequence.read_encoded_sequence_component(SEQUENCE | CONSTRUCTED)?; 161 let _validity = tbs_certificate_sequence.read_sequence()?; 162 let subject = 163 tbs_certificate_sequence.read_encoded_sequence_component(SEQUENCE | CONSTRUCTED)?; 164 Ok((serial_number, issuer, subject)) 165 } 166 167 pub struct RSAPrivateKey { 168 pub modulus: Vec<u8>, 169 pub private_exponent: Vec<u8>, 170 } 171 172 pub struct ECPrivateKey { 173 pub private_key: Vec<u8>, 174 } 175 176 pub enum PrivateKeyInfo { 177 RSA(RSAPrivateKey), 178 EC(ECPrivateKey), 179 } 180 181 /// PrivateKeyInfo ::= SEQUENCE { 182 /// version Version, 183 /// privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, 184 /// privateKey PrivateKey, 185 /// attributes [0] IMPLICIT Attributes OPTIONAL } 186 /// 187 /// Version ::= INTEGER 188 /// 189 /// PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier 190 /// 191 /// PrivateKey ::= OCTET STRING 192 /// 193 /// Attributes ::= SET OF Attribute 194 /// 195 /// RSAPrivateKey ::= SEQUENCE { 196 /// version Version, 197 /// modulus INTEGER, -- n 198 /// publicExponent INTEGER, -- e 199 /// privateExponent INTEGER, -- d 200 /// prime1 INTEGER, -- p 201 /// prime2 INTEGER, -- q 202 /// exponent1 INTEGER, -- d mod (p-1) 203 /// exponent2 INTEGER, -- d mod (q-1) 204 /// coefficient INTEGER, -- (inverse of q) mod p 205 /// otherPrimeInfos OtherPrimeInfos OPTIONAL 206 /// } 207 /// 208 /// ECPrivateKey ::= SEQUENCE { 209 /// version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 210 /// privateKey OCTET STRING, 211 /// parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 212 /// publicKey [1] BIT STRING OPTIONAL 213 /// } 214 pub fn read_private_key_info(private_key_info: &[u8]) -> Result<PrivateKeyInfo, Error> { 215 let mut private_key_info = Sequence::new(private_key_info)?; 216 let _version = private_key_info.read_unsigned_integer()?; 217 let mut algorithm_identifier = private_key_info.read_sequence()?; 218 let algorithm = algorithm_identifier.read_oid()?; 219 let private_key_bytes = private_key_info.read_octet_string()?; 220 let mut private_key = Sequence::new(private_key_bytes)?; 221 if algorithm == OID_BYTES_RSA_ENCRYPTION { 222 let _version = private_key.read_unsigned_integer()?; 223 let modulus = private_key.read_unsigned_integer()?; 224 let _public_exponent = private_key.read_unsigned_integer()?; 225 let private_exponent = private_key.read_unsigned_integer()?; 226 return Ok(PrivateKeyInfo::RSA(RSAPrivateKey { 227 modulus: modulus.to_vec(), 228 private_exponent: private_exponent.to_vec(), 229 })); 230 } 231 if algorithm == OID_BYTES_EC_PUBLIC_KEY { 232 let algorithm_parameters = algorithm_identifier.read_oid()?; 233 // Currently, only secp256r1 is supported. 234 if algorithm_parameters != OID_BYTES_SECP256R1 { 235 return Err(error_here!(ErrorType::UnsupportedInput)); 236 } 237 let _version = private_key.read_unsigned_integer()?; 238 let private_key_bytes = private_key.read_octet_string()?; 239 return Ok(PrivateKeyInfo::EC(ECPrivateKey { 240 private_key: private_key_bytes.to_vec(), 241 })); 242 } 243 Err(error_here!(ErrorType::UnsupportedInput)) 244 } 245 246 /// Helper macro for reading some bytes from a slice while checking the slice is long enough. 247 /// Returns a pair consisting of a slice of the bytes read and a slice of the rest of the bytes 248 /// from the original slice. 249 macro_rules! try_read_bytes { 250 ($data:ident, $len:expr) => {{ 251 if $data.len() < $len { 252 return Err(error_here!(ErrorType::TruncatedInput)); 253 } 254 $data.split_at($len) 255 }}; 256 } 257 258 /// ASN.1 tag identifying an integer. 259 const INTEGER: u8 = 0x02; 260 /// ASN.1 tag identifying an octet string. 261 const OCTET_STRING: u8 = 0x04; 262 /// ASN.1 tag identifying a null value. 263 const NULL: u8 = 0x05; 264 /// ASN.1 tag identifying an object identifier (OID). 265 const OBJECT_IDENTIFIER: u8 = 0x06; 266 /// ASN.1 tag identifying a sequence. 267 const SEQUENCE: u8 = 0x10; 268 /// ASN.1 tag modifier identifying an item as constructed. 269 const CONSTRUCTED: u8 = 0x20; 270 /// ASN.1 tag modifier identifying an item as context-specific. 271 const CONTEXT_SPECIFIC: u8 = 0x80; 272 273 /// A helper struct for reading items from a DER SEQUENCE (in this case, all sequences are 274 /// assumed to be CONSTRUCTED). 275 struct Sequence<'a> { 276 /// The contents of the SEQUENCE. 277 contents: Der<'a>, 278 } 279 280 impl<'a> Sequence<'a> { 281 fn new(input: &'a [u8]) -> Result<Sequence<'a>, Error> { 282 let mut der = Der::new(input); 283 let (_, _, sequence_bytes) = der.read_tlv(SEQUENCE | CONSTRUCTED)?; 284 // We're assuming we want to consume the entire input for now. 285 if !der.at_end() { 286 return Err(error_here!(ErrorType::ExtraInput)); 287 } 288 Ok(Sequence { 289 contents: Der::new(sequence_bytes), 290 }) 291 } 292 293 // TODO: we're not exhaustively validating this integer 294 fn read_unsigned_integer(&mut self) -> Result<&'a [u8], Error> { 295 let (_, _, bytes) = self.contents.read_tlv(INTEGER)?; 296 if bytes.is_empty() { 297 return Err(error_here!(ErrorType::InvalidInput)); 298 } 299 // There may be a leading zero (we should also check that the first bit 300 // of the rest of the integer is set). 301 if bytes[0] == 0 && bytes.len() > 1 { 302 let (_, integer) = bytes.split_at(1); 303 Ok(integer) 304 } else { 305 Ok(bytes) 306 } 307 } 308 309 fn read_octet_string(&mut self) -> Result<&'a [u8], Error> { 310 let (_, _, bytes) = self.contents.read_tlv(OCTET_STRING)?; 311 Ok(bytes) 312 } 313 314 fn read_oid(&mut self) -> Result<&'a [u8], Error> { 315 let (_, _, bytes) = self.contents.read_tlv(OBJECT_IDENTIFIER)?; 316 Ok(bytes) 317 } 318 319 fn read_null(&mut self) -> Result<(), Error> { 320 let (_, _, bytes) = self.contents.read_tlv(NULL)?; 321 if bytes.is_empty() { 322 Ok(()) 323 } else { 324 Err(error_here!(ErrorType::InvalidInput)) 325 } 326 } 327 328 fn read_sequence(&mut self) -> Result<Sequence<'a>, Error> { 329 let (_, _, sequence_bytes) = self.contents.read_tlv(SEQUENCE | CONSTRUCTED)?; 330 Ok(Sequence { 331 contents: Der::new(sequence_bytes), 332 }) 333 } 334 335 fn read_optional_tagged_value(&mut self, tag: u8) -> Result<Option<&'a [u8]>, Error> { 336 let expected = CONTEXT_SPECIFIC | CONSTRUCTED | tag; 337 if self.contents.peek(expected) { 338 let (_, _, tagged_value_bytes) = self.contents.read_tlv(expected)?; 339 Ok(Some(tagged_value_bytes)) 340 } else { 341 Ok(None) 342 } 343 } 344 345 fn read_encoded_sequence_component(&mut self, tag: u8) -> Result<Vec<u8>, Error> { 346 let (tag, length, value) = self.contents.read_tlv(tag)?; 347 let mut encoded_component_bytes = length; 348 encoded_component_bytes.insert(0, tag); 349 encoded_component_bytes.extend_from_slice(value); 350 Ok(encoded_component_bytes) 351 } 352 353 fn at_end(&self) -> bool { 354 self.contents.at_end() 355 } 356 357 fn read_rest(&mut self) -> &[u8] { 358 self.contents.read_rest() 359 } 360 } 361 362 /// A helper struct for reading DER data. The contents are treated like a cursor, so its position 363 /// is updated as data is read. 364 struct Der<'a> { 365 contents: &'a [u8], 366 } 367 368 impl<'a> Der<'a> { 369 fn new(contents: &'a [u8]) -> Der<'a> { 370 Der { contents } 371 } 372 373 // In theory, a caller could encounter an error and try another operation, in which case we may 374 // be in an inconsistent state. As long as this implementation isn't exposed to code that would 375 // use it incorrectly (i.e. it stays in this module and we only expose a stateless API), it 376 // should be safe. 377 /// Given an expected tag, reads the next (tag, lengh, value) from the contents. Most 378 /// consumers will only be interested in the value, but some may want the entire encoded 379 /// contents, in which case the returned tuple can be concatenated. 380 fn read_tlv(&mut self, tag: u8) -> Result<(u8, Vec<u8>, &'a [u8]), Error> { 381 let contents = self.contents; 382 let (tag_read, rest) = try_read_bytes!(contents, 1); 383 if tag_read[0] != tag { 384 return Err(error_here!(ErrorType::InvalidInput)); 385 } 386 let mut accumulated_length_bytes = Vec::with_capacity(4); 387 let (length1, rest) = try_read_bytes!(rest, 1); 388 accumulated_length_bytes.extend_from_slice(length1); 389 let (length, to_read_from) = if length1[0] < 0x80 { 390 (length1[0] as usize, rest) 391 } else if length1[0] == 0x81 { 392 let (length, rest) = try_read_bytes!(rest, 1); 393 accumulated_length_bytes.extend_from_slice(length); 394 if length[0] < 0x80 { 395 return Err(error_here!(ErrorType::InvalidInput)); 396 } 397 (length[0] as usize, rest) 398 } else if length1[0] == 0x82 { 399 let (mut lengths, rest) = try_read_bytes!(rest, 2); 400 accumulated_length_bytes.extend_from_slice(lengths); 401 let length = lengths 402 .read_u16::<BigEndian>() 403 .map_err(|_| error_here!(ErrorType::LibraryFailure))?; 404 if length < 256 { 405 return Err(error_here!(ErrorType::InvalidInput)); 406 } 407 (length as usize, rest) 408 } else { 409 return Err(error_here!(ErrorType::UnsupportedInput)); 410 }; 411 let (contents, rest) = try_read_bytes!(to_read_from, length); 412 self.contents = rest; 413 Ok((tag, accumulated_length_bytes, contents)) 414 } 415 416 fn at_end(&self) -> bool { 417 self.contents.is_empty() 418 } 419 420 fn peek(&self, expected: u8) -> bool { 421 Some(&expected) == self.contents.first() 422 } 423 424 fn read_rest(&mut self) -> &'a [u8] { 425 let contents = self.contents; 426 self.contents = &[]; 427 contents 428 } 429 } 430 431 #[cfg(test)] 432 mod tests { 433 use super::*; 434 435 #[test] 436 fn der_test_empty_input() { 437 let input = Vec::new(); 438 let mut der = Der::new(&input); 439 assert!(der.read_tlv(INTEGER).is_err()); 440 } 441 442 #[test] 443 fn der_test_no_length() { 444 let input = vec![INTEGER]; 445 let mut der = Der::new(&input); 446 assert!(der.read_tlv(INTEGER).is_err()); 447 } 448 449 #[test] 450 fn der_test_empty_sequence() { 451 let input = vec![SEQUENCE, 0]; 452 let mut der = Der::new(&input); 453 let read_result = der.read_tlv(SEQUENCE); 454 assert!(read_result.is_ok()); 455 let (tag, length, sequence_bytes) = read_result.unwrap(); 456 assert_eq!(tag, SEQUENCE); 457 assert_eq!(length, vec![0]); 458 assert_eq!(sequence_bytes.len(), 0); 459 assert!(der.at_end()); 460 } 461 462 #[test] 463 fn der_test_not_at_end() { 464 let input = vec![SEQUENCE, 0, 1]; 465 let mut der = Der::new(&input); 466 let read_result = der.read_tlv(SEQUENCE); 467 assert!(read_result.is_ok()); 468 let (tag, length, sequence_bytes) = read_result.unwrap(); 469 assert_eq!(tag, SEQUENCE); 470 assert_eq!(length, vec![0]); 471 assert_eq!(sequence_bytes.len(), 0); 472 assert!(!der.at_end()); 473 } 474 475 #[test] 476 fn der_test_wrong_tag() { 477 let input = vec![SEQUENCE, 0]; 478 let mut der = Der::new(&input); 479 assert!(der.read_tlv(INTEGER).is_err()); 480 } 481 482 #[test] 483 fn der_test_truncated_two_byte_length() { 484 let input = vec![SEQUENCE, 0x81]; 485 let mut der = Der::new(&input); 486 assert!(der.read_tlv(SEQUENCE).is_err()); 487 } 488 489 #[test] 490 fn der_test_truncated_three_byte_length() { 491 let input = vec![SEQUENCE, 0x82, 1]; 492 let mut der = Der::new(&input); 493 assert!(der.read_tlv(SEQUENCE).is_err()); 494 } 495 496 #[test] 497 fn der_test_truncated_data() { 498 let input = vec![SEQUENCE, 20, 1]; 499 let mut der = Der::new(&input); 500 assert!(der.read_tlv(SEQUENCE).is_err()); 501 } 502 503 #[test] 504 fn der_test_sequence() { 505 let input = vec![ 506 SEQUENCE, 20, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0, 507 ]; 508 let mut der = Der::new(&input); 509 let result = der.read_tlv(SEQUENCE); 510 assert!(result.is_ok()); 511 let (tag, length, value) = result.unwrap(); 512 assert_eq!(tag, SEQUENCE); 513 assert_eq!(length, vec![20]); 514 assert_eq!( 515 value, 516 [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0] 517 ); 518 assert!(der.at_end()); 519 } 520 521 #[test] 522 fn der_test_not_shortest_two_byte_length_encoding() { 523 let input = vec![SEQUENCE, 0x81, 1, 1]; 524 let mut der = Der::new(&input); 525 assert!(der.read_tlv(SEQUENCE).is_err()); 526 } 527 528 #[test] 529 fn der_test_not_shortest_three_byte_length_encoding() { 530 let input = vec![SEQUENCE, 0x82, 0, 1, 1]; 531 let mut der = Der::new(&input); 532 assert!(der.read_tlv(SEQUENCE).is_err()); 533 } 534 535 #[test] 536 fn der_test_indefinite_length_unsupported() { 537 let input = vec![SEQUENCE, 0x80, 1, 2, 3, 0x00, 0x00]; 538 let mut der = Der::new(&input); 539 assert!(der.read_tlv(SEQUENCE).is_err()); 540 } 541 542 #[test] 543 fn der_test_input_too_long() { 544 // This isn't valid DER (the contents of the SEQUENCE are truncated), but it demonstrates 545 // that we don't try to read too much if we're given a long length (and also that we don't 546 // support lengths 2^16 and up). 547 let input = vec![SEQUENCE, 0x83, 0x01, 0x00, 0x01, 1, 1, 1, 1]; 548 let mut der = Der::new(&input); 549 assert!(der.read_tlv(SEQUENCE).is_err()); 550 } 551 552 #[test] 553 fn empty_input_fails() { 554 let empty = Vec::new(); 555 assert!(read_rsa_modulus(&empty).is_err()); 556 assert!(read_ec_sig_point(&empty).is_err()); 557 assert!(read_encoded_certificate_identifiers(&empty).is_err()); 558 } 559 560 #[test] 561 fn empty_sequence_fails() { 562 let empty = vec![SEQUENCE | CONSTRUCTED]; 563 assert!(read_rsa_modulus(&empty).is_err()); 564 assert!(read_ec_sig_point(&empty).is_err()); 565 assert!(read_encoded_certificate_identifiers(&empty).is_err()); 566 } 567 568 #[test] 569 fn test_der_ec_sig_to_raw() { 570 let ec_sig_point = vec![ 571 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 572 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 573 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0x85, 0xfb, 0xb4, 574 0x75, 0x5d, 0xb5, 0x1c, 0x5f, 0x97, 0x52, 0x27, 0xd9, 0x71, 0x14, 0xc0, 0xbc, 0x67, 575 0x10, 0x4f, 0x72, 0x2e, 0x37, 0xb2, 0x78, 0x54, 0xfd, 0xd0, 0x9d, 0x51, 0xd4, 0x9f, 576 0xf2, 577 ]; 578 let result = der_ec_sig_to_raw(&ec_sig_point, 32); 579 assert!(result.is_ok()); 580 let expected = vec![ 581 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 582 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 583 0x80, 0x0a, 0x70, 0xe6, 0x85, 0xfb, 0xb4, 0x75, 0x5d, 0xb5, 0x1c, 0x5f, 0x97, 0x52, 584 0x27, 0xd9, 0x71, 0x14, 0xc0, 0xbc, 0x67, 0x10, 0x4f, 0x72, 0x2e, 0x37, 0xb2, 0x78, 585 0x54, 0xfd, 0xd0, 0x9d, 0x51, 0xd4, 0x9f, 0xf2, 586 ]; 587 assert_eq!(result.unwrap(), expected); 588 } 589 590 #[test] 591 fn test_der_ec_sig_to_raw_long() { 592 let ec_sig = vec![ 593 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 594 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 595 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0x85, 0xfb, 0xb4, 596 0x75, 0x5d, 0xb5, 0x1c, 0x5f, 0x97, 0x52, 0x27, 0xd9, 0x71, 0x14, 0xc0, 0xbc, 0x67, 597 0x10, 0x4f, 0x72, 0x2e, 0x37, 0xb2, 0x78, 0x54, 0xfd, 0xd0, 0x9d, 0x51, 0xd4, 0x9f, 598 0xf2, 599 ]; 600 let result = der_ec_sig_to_raw(&ec_sig, 16); 601 assert!(result.is_err()); 602 } 603 604 #[test] 605 fn test_der_ec_sig_to_raw_short() { 606 let ec_sig_point = vec![ 607 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 608 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 609 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0x85, 0xfb, 0xb4, 610 0x75, 0x5d, 0xb5, 0x1c, 0x5f, 0x97, 0x52, 0x27, 0xd9, 0x71, 0x14, 0xc0, 0xbc, 0x67, 611 0x10, 0x4f, 0x72, 0x2e, 0x37, 0xb2, 0x78, 0x54, 0xfd, 0xd0, 0x9d, 0x51, 0xd4, 0x9f, 612 0xf2, 613 ]; 614 let result = der_ec_sig_to_raw(&ec_sig_point, 48); 615 assert!(result.is_ok()); 616 let expected = vec![ 617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 618 0x00, 0x00, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 619 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 620 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xfb, 0xb4, 0x75, 0x5d, 0xb5, 622 0x1c, 0x5f, 0x97, 0x52, 0x27, 0xd9, 0x71, 0x14, 0xc0, 0xbc, 0x67, 0x10, 0x4f, 0x72, 623 0x2e, 0x37, 0xb2, 0x78, 0x54, 0xfd, 0xd0, 0x9d, 0x51, 0xd4, 0x9f, 0xf2, 624 ]; 625 assert_eq!(result.unwrap(), expected); 626 } 627 628 #[test] 629 fn test_read_rsa_modulus() { 630 let rsa_key = include_bytes!("../test/rsa.bin"); 631 let result = read_rsa_modulus(rsa_key); 632 assert!(result.is_ok()); 633 let modulus = result.unwrap(); 634 assert_eq!(modulus, include_bytes!("../test/modulus.bin").to_vec()); 635 } 636 637 #[test] 638 fn test_read_certificate_identifiers() { 639 let certificate = include_bytes!("../test/certificate.bin"); 640 let result = read_encoded_certificate_identifiers(certificate); 641 assert!(result.is_ok()); 642 let (serial_number, issuer, subject) = result.unwrap(); 643 assert_eq!( 644 serial_number, 645 &[ 646 0x02, 0x14, 0x3f, 0xed, 0x7b, 0x43, 0x47, 0x8a, 0x53, 0x42, 0x5b, 0x0d, 0x50, 0xe1, 647 0x37, 0x88, 0x2a, 0x20, 0x3f, 0x31, 0x17, 0x20 648 ] 649 ); 650 assert_eq!( 651 issuer, 652 &[ 653 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x54, 654 0x65, 0x73, 0x74, 0x20, 0x43, 0x41 655 ] 656 ); 657 assert_eq!( 658 subject, 659 &[ 660 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x54, 661 0x65, 0x73, 0x74, 0x20, 0x45, 0x6e, 0x64, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79 662 ] 663 ); 664 } 665 666 #[test] 667 fn test_read_v1_certificate_identifiers() { 668 let certificate = include_bytes!("../test/v1certificate.bin"); 669 let result = read_encoded_certificate_identifiers(certificate); 670 assert!(result.is_ok()); 671 let (serial_number, issuer, subject) = result.unwrap(); 672 assert_eq!( 673 serial_number, 674 &[ 675 0x02, 0x14, 0x51, 0x6b, 0x24, 0xaa, 0xf2, 0x7f, 0x56, 0x13, 0x5f, 0xc3, 0x8b, 0x5c, 676 0xa7, 0x00, 0x83, 0xa8, 0xee, 0xca, 0xad, 0xa0 677 ] 678 ); 679 assert_eq!( 680 issuer, 681 &[ 682 0x30, 0x12, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x07, 0x54, 683 0x65, 0x73, 0x74, 0x20, 0x43, 0x41 684 ] 685 ); 686 assert_eq!( 687 subject, 688 &[ 689 0x30, 0x12, 0x31, 0x10, 0x30, 0x0E, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0C, 0x07, 0x56, 690 0x31, 0x20, 0x43, 0x65, 0x72, 0x74 691 ] 692 ); 693 } 694 695 #[test] 696 fn test_read_digest() { 697 // SEQUENCE 698 // SEQUENCE 699 // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 700 // NULL 701 // OCTET STRING 1A7FCDB9A5F649F954885CFE145F3E93F0D1FA72BE980CC6EC82C70E1407C7D2 702 let digest_info = [ 703 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x1, 0x65, 0x03, 0x04, 0x02, 704 0x01, 0x05, 0x00, 0x04, 0x20, 0x1a, 0x7f, 0xcd, 0xb9, 0xa5, 0xf6, 0x49, 0xf9, 0x54, 705 0x88, 0x5c, 0xfe, 0x14, 0x5f, 0x3e, 0x93, 0xf0, 0xd1, 0xfa, 0x72, 0xbe, 0x98, 0x0c, 706 0xc6, 0xec, 0x82, 0xc7, 0x0e, 0x14, 0x07, 0xc7, 0xd2, 707 ]; 708 let result = read_digest_info(&digest_info); 709 assert!(result.is_ok()); 710 let (oid, digest) = result.unwrap(); 711 assert_eq!(oid, &[0x60, 0x86, 0x48, 0x1, 0x65, 0x03, 0x04, 0x02, 0x01]); 712 assert_eq!( 713 digest, 714 &[ 715 0x1a, 0x7f, 0xcd, 0xb9, 0xa5, 0xf6, 0x49, 0xf9, 0x54, 0x88, 0x5c, 0xfe, 0x14, 0x5f, 716 0x3e, 0x93, 0xf0, 0xd1, 0xfa, 0x72, 0xbe, 0x98, 0x0c, 0xc6, 0xec, 0x82, 0xc7, 0x0e, 717 0x14, 0x07, 0xc7, 0xd2 718 ] 719 ); 720 } 721 722 #[test] 723 fn test_read_spki_algorithm_parameters() { 724 let spki = [ 725 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 726 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 727 0xbf, 0xbb, 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 728 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79, 729 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, 730 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 731 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 732 ]; 733 let result = read_spki_algorithm_parameters(&spki); 734 assert!(result.is_ok()); 735 let parameters = result.unwrap(); 736 const ENCODED_OID_BYTES_SECP256R1: &[u8] = 737 &[0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]; 738 assert_eq!(¶meters, ENCODED_OID_BYTES_SECP256R1); 739 } 740 741 #[test] 742 fn test_read_private_key_info_rsa() { 743 let private_key_info_rsa = include_bytes!("../test/private-key-info-rsa.bin"); 744 let result = read_private_key_info(private_key_info_rsa); 745 assert!(result.is_ok()); 746 let private_key = result.unwrap(); 747 assert!(matches!(private_key, PrivateKeyInfo::RSA(_))); 748 let PrivateKeyInfo::RSA(private_key_rsa) = private_key else { 749 unreachable!() 750 }; 751 let expected_modulus = [ 752 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, 0x6e, 0xb6, 0x88, 0x06, 753 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 754 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 755 0x06, 0x9b, 0x6e, 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 756 0x71, 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, 757 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, 0x20, 0xc3, 758 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, 0x15, 0x82, 0x0f, 0xf1, 759 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 760 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 761 0x88, 0x61, 0x79, 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 762 0x1f, 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, 763 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, 0x1c, 0x6c, 764 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, 0x75, 0x31, 0xa3, 0x0c, 765 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 766 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 767 0x61, 0x1d, 0xee, 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 768 0x24, 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, 769 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, 0xda, 0x18, 770 0x0a, 0x35, 0xed, 0x8d, 771 ]; 772 assert_eq!(private_key_rsa.modulus, expected_modulus); 773 let expected_private_exponent = [ 774 0x9e, 0xcb, 0xce, 0x38, 0x61, 0xa4, 0x54, 0xec, 0xb1, 0xe0, 0xfe, 0x8f, 0x85, 0xdd, 775 0x43, 0xc9, 0x2f, 0x58, 0x25, 0xce, 0x2e, 0x99, 0x78, 0x84, 0xd0, 0xe1, 0xa9, 0x49, 776 0xda, 0xa2, 0xc5, 0xac, 0x55, 0x9b, 0x24, 0x04, 0x50, 0xe5, 0xac, 0x9f, 0xe0, 0xc3, 777 0xe3, 0x1c, 0x0e, 0xef, 0xa6, 0x52, 0x5a, 0x65, 0xf0, 0xc2, 0x21, 0x94, 0x00, 0x4e, 778 0xe1, 0xab, 0x46, 0x3d, 0xde, 0x9e, 0xe8, 0x22, 0x87, 0xcc, 0x93, 0xe7, 0x46, 0xa9, 779 0x19, 0x29, 0xc5, 0xe6, 0xac, 0x3d, 0x88, 0x75, 0x3f, 0x6c, 0x25, 0xba, 0x59, 0x79, 780 0xe7, 0x3e, 0x5d, 0x8f, 0xb2, 0x39, 0x11, 0x1a, 0x3c, 0xda, 0xb8, 0xa4, 0xb0, 0xcd, 781 0xf5, 0xf9, 0xca, 0xb0, 0x5f, 0x12, 0x33, 0xa3, 0x83, 0x35, 0xc6, 0x4b, 0x55, 0x60, 782 0x52, 0x5e, 0x7e, 0x3b, 0x92, 0xad, 0x7c, 0x75, 0x04, 0xcf, 0x1d, 0xc7, 0xcb, 0x00, 783 0x57, 0x88, 0xaf, 0xcb, 0xe1, 0xe8, 0xf9, 0x5d, 0xf7, 0x40, 0x2a, 0x15, 0x15, 0x30, 784 0xd5, 0x80, 0x83, 0x46, 0x86, 0x4e, 0xb3, 0x70, 0xaa, 0x79, 0x95, 0x6a, 0x58, 0x78, 785 0x62, 0xcb, 0x53, 0x37, 0x91, 0x30, 0x7f, 0x70, 0xd9, 0x1c, 0x96, 0xd2, 0x2d, 0x00, 786 0x1a, 0x69, 0x00, 0x9b, 0x92, 0x3c, 0x68, 0x33, 0x88, 0xc9, 0xf3, 0x6c, 0xb9, 0xb5, 787 0xeb, 0xe6, 0x43, 0x02, 0x04, 0x1c, 0x78, 0xd9, 0x08, 0x20, 0x6b, 0x87, 0x00, 0x9c, 788 0xb8, 0xca, 0xba, 0xca, 0xd3, 0xdb, 0xdb, 0x27, 0x92, 0xfb, 0x91, 0x1b, 0x2c, 0xf4, 789 0xdb, 0x66, 0x03, 0x58, 0x5b, 0xe9, 0xae, 0x0c, 0xa3, 0xb8, 0xe6, 0x41, 0x7a, 0xa0, 790 0x4b, 0x06, 0xe4, 0x70, 0xea, 0x1a, 0x3b, 0x58, 0x1c, 0xa0, 0x3a, 0x67, 0x81, 0xc9, 791 0x31, 0x5b, 0x62, 0xb3, 0x0e, 0x60, 0x11, 0xf2, 0x24, 0x72, 0x59, 0x46, 0xee, 0xc5, 792 0x7c, 0x6d, 0x94, 0x41, 793 ]; 794 assert_eq!(private_key_rsa.private_exponent, expected_private_exponent); 795 } 796 797 #[test] 798 fn test_read_private_key_info_ecdsa() { 799 let private_key_info_ecdsa = include_bytes!("../test/private-key-info-ecdsa.bin"); 800 let result = read_private_key_info(private_key_info_ecdsa); 801 assert!(result.is_ok()); 802 let private_key = result.unwrap(); 803 assert!(matches!(private_key, PrivateKeyInfo::EC(_))); 804 let PrivateKeyInfo::EC(private_key_ec) = private_key else { 805 unreachable!() 806 }; 807 let expected_private_key = [ 808 0x21, 0x91, 0x40, 0x3d, 0x57, 0x10, 0xbf, 0x15, 0xa2, 0x65, 0x81, 0x8c, 0xd4, 0x2e, 809 0xd6, 0xfe, 0xdf, 0x09, 0xad, 0xd9, 0x2d, 0x78, 0xb1, 0x8e, 0x7a, 0x1e, 0x9f, 0xeb, 810 0x95, 0x52, 0x47, 0x02, 811 ]; 812 assert_eq!(private_key_ec.private_key, expected_private_key); 813 } 814 }