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/. */
6 use byteorder::{BigEndian, NativeEndian, ReadBytesExt, WriteBytesExt};
7 use std::convert::TryInto;
9 use crate::error::{Error, ErrorType};
10 use crate::error_here;
12 /// Accessing fields of packed structs is unsafe (it may be undefined behavior if the field isn't
13 /// aligned). Since we're implementing a PKCS#11 module, we already have to trust the caller not to
14 /// give us bad data, so normally we would deal with this by adding an unsafe block. If we do that,
15 /// though, the compiler complains that the unsafe block is unnecessary. Thus, we use this macro to
16 /// annotate the unsafe block to silence the compiler.
18 macro_rules! unsafe_packed_field_access {
20 #[allow(unused_unsafe)]
21 let tmp = unsafe { $e };
26 // The following ENCODED_OID_BYTES_* consist of the encoded bytes of an ASN.1
27 // OBJECT IDENTIFIER specifying the indicated OID (in other words, the full
28 // tag, length, and value).
29 #[cfg(any(target_os = "macos", target_os = "ios"))]
30 pub const ENCODED_OID_BYTES_SECP256R1: &[u8] =
31 &[0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07];
32 #[cfg(any(target_os = "macos", target_os = "ios"))]
33 pub const ENCODED_OID_BYTES_SECP384R1: &[u8] = &[0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22];
34 #[cfg(any(target_os = "macos", target_os = "ios"))]
35 pub const ENCODED_OID_BYTES_SECP521R1: &[u8] = &[0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23];
37 // The following OID_BYTES_* consist of the contents of the bytes of an ASN.1
38 // OBJECT IDENTIFIER specifying the indicated OID (in other words, just the
39 // value, and not the tag or length).
40 #[cfg(any(target_os = "macos", target_os = "ios"))]
41 pub const OID_BYTES_SHA_256: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01];
42 #[cfg(any(target_os = "macos", target_os = "ios"))]
43 pub const OID_BYTES_SHA_384: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02];
44 #[cfg(any(target_os = "macos", target_os = "ios"))]
45 pub const OID_BYTES_SHA_512: &[u8] = &[0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03];
46 #[cfg(any(target_os = "macos", target_os = "ios"))]
47 pub const OID_BYTES_SHA_1: &[u8] = &[0x2b, 0x0e, 0x03, 0x02, 0x1a];
49 // This is a helper function to take a value and lay it out in memory how
50 // PKCS#11 is expecting it.
51 pub fn serialize_uint<T: TryInto<u64>>(value: T) -> Result<Vec<u8>, Error> {
52 let value_size = std::mem::size_of::<T>();
53 let mut value_buf = Vec::with_capacity(value_size);
54 let value_as_u64 = value
56 .map_err(|_| error_here!(ErrorType::ValueTooLarge))?;
58 .write_uint::<NativeEndian>(value_as_u64, value_size)
59 .map_err(|_| error_here!(ErrorType::LibraryFailure))?;
63 /// Given a slice of DER bytes representing an RSA public key, extracts the bytes of the modulus
64 /// as an unsigned integer. Also verifies that the public exponent is present (again as an
65 /// unsigned integer). Finally verifies that reading these values consumes the entirety of the
67 /// RSAPublicKey ::= SEQUENCE {
68 /// modulus INTEGER, -- n
69 /// publicExponent INTEGER -- e
71 pub fn read_rsa_modulus(public_key: &[u8]) -> Result<Vec<u8>, Error> {
72 let mut sequence = Sequence::new(public_key)?;
73 let modulus_value = sequence.read_unsigned_integer()?;
74 let _exponent = sequence.read_unsigned_integer()?;
75 if !sequence.at_end() {
76 return Err(error_here!(ErrorType::ExtraInput));
78 Ok(modulus_value.to_vec())
81 /// Given a slice of DER bytes representing a DigestInfo, extracts the bytes of
82 /// the OID of the hash algorithm and the digest.
83 /// DigestInfo ::= SEQUENCE {
84 /// digestAlgorithm DigestAlgorithmIdentifier,
87 /// DigestAlgorithmIdentifier ::= AlgorithmIdentifier
89 /// AlgorithmIdentifier ::= SEQUENCE {
90 /// algorithm OBJECT IDENTIFIER,
91 /// parameters ANY DEFINED BY algorithm OPTIONAL }
93 /// Digest ::= OCTET STRING
94 pub fn read_digest_info(digest_info: &[u8]) -> Result<(&[u8], &[u8]), Error> {
95 let mut sequence = Sequence::new(digest_info)?;
96 let mut algorithm = sequence.read_sequence()?;
97 let oid = algorithm.read_oid()?;
98 algorithm.read_null()?;
99 if !algorithm.at_end() {
100 return Err(error_here!(ErrorType::ExtraInput));
102 let digest = sequence.read_octet_string()?;
103 if !sequence.at_end() {
104 return Err(error_here!(ErrorType::ExtraInput));
109 /// Given a slice of DER bytes representing an ECDSA signature, extracts the bytes of `r` and `s`
110 /// as unsigned integers. Also verifies that this consumes the entirety of the slice.
111 /// Ecdsa-Sig-Value ::= SEQUENCE {
114 #[cfg(any(target_os = "macos", target_os = "ios"))]
115 pub fn read_ec_sig_point(signature: &[u8]) -> Result<(&[u8], &[u8]), Error> {
116 let mut sequence = Sequence::new(signature)?;
117 let r = sequence.read_unsigned_integer()?;
118 let s = sequence.read_unsigned_integer()?;
119 if !sequence.at_end() {
120 return Err(error_here!(ErrorType::ExtraInput));
125 /// Given a slice of DER bytes representing an X.509 certificate, extracts the encoded serial
126 /// number, issuer, and subject. Does not verify that the remainder of the certificate is in any
128 /// Certificate ::= SEQUENCE {
129 /// tbsCertificate TBSCertificate,
130 /// signatureAlgorithm AlgorithmIdentifier,
131 /// signatureValue BIT STRING }
133 /// TBSCertificate ::= SEQUENCE {
134 /// version [0] EXPLICIT Version DEFAULT v1,
135 /// serialNumber CertificateSerialNumber,
136 /// signature AlgorithmIdentifier,
138 /// validity Validity,
142 /// CertificateSerialNumber ::= INTEGER
144 /// Name ::= CHOICE { -- only one possibility for now --
145 /// rdnSequence RDNSequence }
147 /// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
149 /// Validity ::= SEQUENCE {
152 #[allow(clippy::type_complexity)]
153 pub fn read_encoded_certificate_identifiers(
155 ) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>), Error> {
156 let mut certificate_sequence = Sequence::new(certificate)?;
157 let mut tbs_certificate_sequence = certificate_sequence.read_sequence()?;
158 let _version = tbs_certificate_sequence.read_tagged_value(0)?;
159 let serial_number = tbs_certificate_sequence.read_encoded_sequence_component(INTEGER)?;
160 let _signature = tbs_certificate_sequence.read_sequence()?;
162 tbs_certificate_sequence.read_encoded_sequence_component(SEQUENCE | CONSTRUCTED)?;
163 let _validity = tbs_certificate_sequence.read_sequence()?;
165 tbs_certificate_sequence.read_encoded_sequence_component(SEQUENCE | CONSTRUCTED)?;
166 Ok((serial_number, issuer, subject))
169 /// Helper macro for reading some bytes from a slice while checking the slice is long enough.
170 /// Returns a pair consisting of a slice of the bytes read and a slice of the rest of the bytes
171 /// from the original slice.
172 macro_rules! try_read_bytes {
173 ($data:ident, $len:expr) => {{
174 if $data.len() < $len {
175 return Err(error_here!(ErrorType::TruncatedInput));
181 /// ASN.1 tag identifying an integer.
182 const INTEGER: u8 = 0x02;
183 /// ASN.1 tag identifying an octet string.
184 const OCTET_STRING: u8 = 0x04;
185 /// ASN.1 tag identifying a null value.
186 const NULL: u8 = 0x05;
187 /// ASN.1 tag identifying an object identifier (OID).
188 const OBJECT_IDENTIFIER: u8 = 0x06;
189 /// ASN.1 tag identifying a sequence.
190 const SEQUENCE: u8 = 0x10;
191 /// ASN.1 tag modifier identifying an item as constructed.
192 const CONSTRUCTED: u8 = 0x20;
193 /// ASN.1 tag modifier identifying an item as context-specific.
194 const CONTEXT_SPECIFIC: u8 = 0x80;
196 /// A helper struct for reading items from a DER SEQUENCE (in this case, all sequences are
197 /// assumed to be CONSTRUCTED).
198 struct Sequence<'a> {
199 /// The contents of the SEQUENCE.
203 impl<'a> Sequence<'a> {
204 fn new(input: &'a [u8]) -> Result<Sequence<'a>, Error> {
205 let mut der = Der::new(input);
206 let (_, _, sequence_bytes) = der.read_tlv(SEQUENCE | CONSTRUCTED)?;
207 // We're assuming we want to consume the entire input for now.
209 return Err(error_here!(ErrorType::ExtraInput));
212 contents: Der::new(sequence_bytes),
216 // TODO: we're not exhaustively validating this integer
217 fn read_unsigned_integer(&mut self) -> Result<&'a [u8], Error> {
218 let (_, _, bytes) = self.contents.read_tlv(INTEGER)?;
219 if bytes.is_empty() {
220 return Err(error_here!(ErrorType::InvalidInput));
222 // There may be a leading zero (we should also check that the first bit
223 // of the rest of the integer is set).
224 if bytes[0] == 0 && bytes.len() > 1 {
225 let (_, integer) = bytes.split_at(1);
232 fn read_octet_string(&mut self) -> Result<&'a [u8], Error> {
233 let (_, _, bytes) = self.contents.read_tlv(OCTET_STRING)?;
237 fn read_oid(&mut self) -> Result<&'a [u8], Error> {
238 let (_, _, bytes) = self.contents.read_tlv(OBJECT_IDENTIFIER)?;
242 fn read_null(&mut self) -> Result<(), Error> {
243 let (_, _, bytes) = self.contents.read_tlv(NULL)?;
244 if bytes.is_empty() {
247 Err(error_here!(ErrorType::InvalidInput))
251 fn read_sequence(&mut self) -> Result<Sequence<'a>, Error> {
252 let (_, _, sequence_bytes) = self.contents.read_tlv(SEQUENCE | CONSTRUCTED)?;
254 contents: Der::new(sequence_bytes),
258 fn read_tagged_value(&mut self, tag: u8) -> Result<&'a [u8], Error> {
259 let (_, _, tagged_value_bytes) = self
261 .read_tlv(CONTEXT_SPECIFIC | CONSTRUCTED | tag)?;
262 Ok(tagged_value_bytes)
265 fn read_encoded_sequence_component(&mut self, tag: u8) -> Result<Vec<u8>, Error> {
266 let (tag, length, value) = self.contents.read_tlv(tag)?;
267 let mut encoded_component_bytes = length;
268 encoded_component_bytes.insert(0, tag);
269 encoded_component_bytes.extend_from_slice(value);
270 Ok(encoded_component_bytes)
273 fn at_end(&self) -> bool {
274 self.contents.at_end()
278 /// A helper struct for reading DER data. The contents are treated like a cursor, so its position
279 /// is updated as data is read.
285 fn new(contents: &'a [u8]) -> Der<'a> {
289 // In theory, a caller could encounter an error and try another operation, in which case we may
290 // be in an inconsistent state. As long as this implementation isn't exposed to code that would
291 // use it incorrectly (i.e. it stays in this module and we only expose a stateless API), it
293 /// Given an expected tag, reads the next (tag, lengh, value) from the contents. Most
294 /// consumers will only be interested in the value, but some may want the entire encoded
295 /// contents, in which case the returned tuple can be concatenated.
296 fn read_tlv(&mut self, tag: u8) -> Result<(u8, Vec<u8>, &'a [u8]), Error> {
297 let contents = self.contents;
298 let (tag_read, rest) = try_read_bytes!(contents, 1);
299 if tag_read[0] != tag {
300 return Err(error_here!(ErrorType::InvalidInput));
302 let mut accumulated_length_bytes = Vec::with_capacity(4);
303 let (length1, rest) = try_read_bytes!(rest, 1);
304 accumulated_length_bytes.extend_from_slice(length1);
305 let (length, to_read_from) = if length1[0] < 0x80 {
306 (length1[0] as usize, rest)
307 } else if length1[0] == 0x81 {
308 let (length, rest) = try_read_bytes!(rest, 1);
309 accumulated_length_bytes.extend_from_slice(length);
310 if length[0] < 0x80 {
311 return Err(error_here!(ErrorType::InvalidInput));
313 (length[0] as usize, rest)
314 } else if length1[0] == 0x82 {
315 let (mut lengths, rest) = try_read_bytes!(rest, 2);
316 accumulated_length_bytes.extend_from_slice(lengths);
318 .read_u16::<BigEndian>()
319 .map_err(|_| error_here!(ErrorType::LibraryFailure))?;
321 return Err(error_here!(ErrorType::InvalidInput));
323 (length as usize, rest)
325 return Err(error_here!(ErrorType::UnsupportedInput));
327 let (contents, rest) = try_read_bytes!(to_read_from, length);
328 self.contents = rest;
329 Ok((tag, accumulated_length_bytes, contents))
332 fn at_end(&self) -> bool {
333 self.contents.is_empty()
342 fn der_test_empty_input() {
343 let input = Vec::new();
344 let mut der = Der::new(&input);
345 assert!(der.read_tlv(INTEGER).is_err());
349 fn der_test_no_length() {
350 let input = vec![INTEGER];
351 let mut der = Der::new(&input);
352 assert!(der.read_tlv(INTEGER).is_err());
356 fn der_test_empty_sequence() {
357 let input = vec![SEQUENCE, 0];
358 let mut der = Der::new(&input);
359 let read_result = der.read_tlv(SEQUENCE);
360 assert!(read_result.is_ok());
361 let (tag, length, sequence_bytes) = read_result.unwrap();
362 assert_eq!(tag, SEQUENCE);
363 assert_eq!(length, vec![0]);
364 assert_eq!(sequence_bytes.len(), 0);
365 assert!(der.at_end());
369 fn der_test_not_at_end() {
370 let input = vec![SEQUENCE, 0, 1];
371 let mut der = Der::new(&input);
372 let read_result = der.read_tlv(SEQUENCE);
373 assert!(read_result.is_ok());
374 let (tag, length, sequence_bytes) = read_result.unwrap();
375 assert_eq!(tag, SEQUENCE);
376 assert_eq!(length, vec![0]);
377 assert_eq!(sequence_bytes.len(), 0);
378 assert!(!der.at_end());
382 fn der_test_wrong_tag() {
383 let input = vec![SEQUENCE, 0];
384 let mut der = Der::new(&input);
385 assert!(der.read_tlv(INTEGER).is_err());
389 fn der_test_truncated_two_byte_length() {
390 let input = vec![SEQUENCE, 0x81];
391 let mut der = Der::new(&input);
392 assert!(der.read_tlv(SEQUENCE).is_err());
396 fn der_test_truncated_three_byte_length() {
397 let input = vec![SEQUENCE, 0x82, 1];
398 let mut der = Der::new(&input);
399 assert!(der.read_tlv(SEQUENCE).is_err());
403 fn der_test_truncated_data() {
404 let input = vec![SEQUENCE, 20, 1];
405 let mut der = Der::new(&input);
406 assert!(der.read_tlv(SEQUENCE).is_err());
410 fn der_test_sequence() {
412 SEQUENCE, 20, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0,
414 let mut der = Der::new(&input);
415 let result = der.read_tlv(SEQUENCE);
416 assert!(result.is_ok());
417 let (tag, length, value) = result.unwrap();
418 assert_eq!(tag, SEQUENCE);
419 assert_eq!(length, vec![20]);
422 [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0]
424 assert!(der.at_end());
428 fn der_test_not_shortest_two_byte_length_encoding() {
429 let input = vec![SEQUENCE, 0x81, 1, 1];
430 let mut der = Der::new(&input);
431 assert!(der.read_tlv(SEQUENCE).is_err());
435 fn der_test_not_shortest_three_byte_length_encoding() {
436 let input = vec![SEQUENCE, 0x82, 0, 1, 1];
437 let mut der = Der::new(&input);
438 assert!(der.read_tlv(SEQUENCE).is_err());
442 fn der_test_indefinite_length_unsupported() {
443 let input = vec![SEQUENCE, 0x80, 1, 2, 3, 0x00, 0x00];
444 let mut der = Der::new(&input);
445 assert!(der.read_tlv(SEQUENCE).is_err());
449 fn der_test_input_too_long() {
450 // This isn't valid DER (the contents of the SEQUENCE are truncated), but it demonstrates
451 // that we don't try to read too much if we're given a long length (and also that we don't
452 // support lengths 2^16 and up).
453 let input = vec![SEQUENCE, 0x83, 0x01, 0x00, 0x01, 1, 1, 1, 1];
454 let mut der = Der::new(&input);
455 assert!(der.read_tlv(SEQUENCE).is_err());
459 fn empty_input_fails() {
460 let empty = Vec::new();
461 assert!(read_rsa_modulus(&empty).is_err());
462 #[cfg(any(target_os = "macos", target_os = "ios"))]
463 assert!(read_ec_sig_point(&empty).is_err());
464 assert!(read_encoded_certificate_identifiers(&empty).is_err());
468 fn empty_sequence_fails() {
469 let empty = vec![SEQUENCE | CONSTRUCTED];
470 assert!(read_rsa_modulus(&empty).is_err());
471 #[cfg(any(target_os = "macos", target_os = "ios"))]
472 assert!(read_ec_sig_point(&empty).is_err());
473 assert!(read_encoded_certificate_identifiers(&empty).is_err());
477 fn test_read_rsa_modulus() {
478 let rsa_key = include_bytes!("../test/rsa.bin");
479 let result = read_rsa_modulus(rsa_key);
480 assert!(result.is_ok());
481 let modulus = result.unwrap();
482 assert_eq!(modulus, include_bytes!("../test/modulus.bin").to_vec());
486 fn test_read_certificate_identifiers() {
487 let certificate = include_bytes!("../test/certificate.bin");
488 let result = read_encoded_certificate_identifiers(certificate);
489 assert!(result.is_ok());
490 let (serial_number, issuer, subject) = result.unwrap();
494 0x02, 0x14, 0x3f, 0xed, 0x7b, 0x43, 0x47, 0x8a, 0x53, 0x42, 0x5b, 0x0d, 0x50, 0xe1,
495 0x37, 0x88, 0x2a, 0x20, 0x3f, 0x31, 0x17, 0x20
501 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x54,
502 0x65, 0x73, 0x74, 0x20, 0x43, 0x41
508 0x30, 0x1a, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x54,
509 0x65, 0x73, 0x74, 0x20, 0x45, 0x6e, 0x64, 0x2d, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79
515 #[cfg(target_os = "windows")]
516 fn test_read_digest() {
519 // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256
521 // OCTET STRING 1A7FCDB9A5F649F954885CFE145F3E93F0D1FA72BE980CC6EC82C70E1407C7D2
523 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x1, 0x65, 0x03, 0x04, 0x02,
524 0x01, 0x05, 0x00, 0x04, 0x20, 0x1a, 0x7f, 0xcd, 0xb9, 0xa5, 0xf6, 0x49, 0xf9, 0x54,
525 0x88, 0x5c, 0xfe, 0x14, 0x5f, 0x3e, 0x93, 0xf0, 0xd1, 0xfa, 0x72, 0xbe, 0x98, 0x0c,
526 0xc6, 0xec, 0x82, 0xc7, 0x0e, 0x14, 0x07, 0xc7, 0xd2,
528 let result = read_digest(&digest_info);
529 assert!(result.is_ok());
530 let digest = result.unwrap();
534 0x1a, 0x7f, 0xcd, 0xb9, 0xa5, 0xf6, 0x49, 0xf9, 0x54, 0x88, 0x5c, 0xfe, 0x14, 0x5f,
535 0x3e, 0x93, 0xf0, 0xd1, 0xfa, 0x72, 0xbe, 0x98, 0x0c, 0xc6, 0xec, 0x82, 0xc7, 0x0e,
536 0x14, 0x07, 0xc7, 0xd2