• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Signed Certificate Timestamp list extension as defined in the
2 //! [Certificate Transparency RFC 6962].
3 //!
4 //! [Certificate Transparency RFC 6962]: https://datatracker.ietf.org/doc/html/rfc6962
5 
6 #![cfg(feature = "sct")]
7 
8 use alloc::{format, vec::Vec};
9 use const_oid::{AssociatedOid, ObjectIdentifier};
10 use der::asn1::OctetString;
11 use tls_codec::{
12     DeserializeBytes, SerializeBytes, TlsByteVecU16, TlsDeserializeBytes, TlsSerializeBytes,
13     TlsSize,
14 };
15 
16 /// A signed certificate timestamp list (SCT list) as defined in [RFC 6962 Section 3.3].
17 ///
18 /// ```text
19 /// SignedCertificateTimestampList ::= OCTET STRING
20 /// ```
21 ///
22 /// [RFC 6962 Section 3.3]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.3
23 #[derive(Debug, PartialEq)]
24 pub struct SignedCertificateTimestampList(OctetString);
25 
26 //TODO: Remove this and use const-oid's rfc6962::CT_PRECERT_SCTS once a const-oid version
27 // containing it is published
28 const CT_PRECERT_SCTS: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2");
29 
30 impl AssociatedOid for SignedCertificateTimestampList {
31     const OID: ObjectIdentifier = CT_PRECERT_SCTS;
32 }
33 
34 impl_newtype!(SignedCertificateTimestampList, OctetString);
35 impl_extension!(SignedCertificateTimestampList, critical = false);
36 
37 /// Errors that are thrown by this module.
38 #[derive(PartialEq, Debug)]
39 pub enum Error {
40     /// [Errors][der::Error] from the `der` crate.
41     Der(der::Error),
42     /// [Errors][tls_codec::Error] from the `tls_codec` crate.
43     Tls(tls_codec::Error),
44 }
45 
46 impl From<der::Error> for Error {
from(value: der::Error) -> Self47     fn from(value: der::Error) -> Self {
48         Error::Der(value)
49     }
50 }
51 
52 impl From<tls_codec::Error> for Error {
from(value: tls_codec::Error) -> Self53     fn from(value: tls_codec::Error) -> Self {
54         Error::Tls(value)
55     }
56 }
57 
58 impl SignedCertificateTimestampList {
59     /// Creates a new [`SignedCertificateTimestampList`] from a slice of [`SerializedSct`]s.
new(serialized_scts: &[SerializedSct]) -> Result<Self, Error>60     pub fn new(serialized_scts: &[SerializedSct]) -> Result<Self, Error> {
61         let mut result: Vec<u8> = Vec::new();
62         for timestamp in serialized_scts {
63             let buffer = timestamp.tls_serialize()?;
64             result.extend(buffer);
65         }
66         let tls_vec = TlsByteVecU16::new(result);
67         let buffer = tls_vec.tls_serialize()?;
68         Ok(SignedCertificateTimestampList(OctetString::new(buffer)?))
69     }
70 
71     /// Parses the encoded [SerializedSct]s and returns a [Vec] containing them.
72     ///
73     /// Returns an [error][Error] if a [SerializedSct] can't be
74     /// deserialized or if there are trailing bytes after all [SerializedSct]s
75     /// are deserialized.
parse_timestamps(&self) -> Result<Vec<SerializedSct>, Error>76     pub fn parse_timestamps(&self) -> Result<Vec<SerializedSct>, Error> {
77         let (tls_vec, rest) = TlsByteVecU16::tls_deserialize_bytes(self.0.as_bytes())?;
78         if !rest.is_empty() {
79             return Err(tls_codec::Error::TrailingData)?;
80         }
81         let mut bytes = tls_vec.as_slice();
82         let mut result = Vec::new();
83         while !bytes.is_empty() {
84             let (serialized_sct, rest) = SerializedSct::tls_deserialize_bytes(bytes)?;
85             result.push(serialized_sct);
86             bytes = rest;
87         }
88         Ok(result)
89     }
90 }
91 
92 /// A byte string that contains a serialized [SignedCertificateTimestamp] as
93 /// defined in [RFC 6962 section 3.3].
94 ///
95 /// [RFC 6962 section 3.3]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.3
96 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
97 pub struct SerializedSct {
98     data: TlsByteVecU16,
99 }
100 
101 impl SerializedSct {
102     /// Creates a new [SerializedSct] from a [SignedCertificateTimestamp].
103     ///
104     /// Returns [tls_codec Error][tls_codec::Error] if the given [SignedCertificateTimestamp]
105     /// can't be serialized.
new(timestamp: SignedCertificateTimestamp) -> Result<Self, tls_codec::Error>106     pub fn new(timestamp: SignedCertificateTimestamp) -> Result<Self, tls_codec::Error> {
107         let buffer = timestamp.tls_serialize()?;
108         Ok(SerializedSct {
109             data: TlsByteVecU16::from_slice(&buffer),
110         })
111     }
112 
113     /// Parses a [SignedCertificateTimestamp] from a this [SerializedSct].
114     ///
115     /// Returns an [error][Error] if a [SignedCertificateTimestamp] can't be
116     /// deserialized or if there are trailing bytes after a
117     /// [SignedCertificateTimestamp] has been deserialized.
parse_timestamp(&self) -> Result<SignedCertificateTimestamp, Error>118     pub fn parse_timestamp(&self) -> Result<SignedCertificateTimestamp, Error> {
119         let (sct, rest) = SignedCertificateTimestamp::tls_deserialize_bytes(self.data.as_slice())?;
120         if !rest.is_empty() {
121             return Err(tls_codec::Error::TrailingData)?;
122         }
123         Ok(sct)
124     }
125 }
126 
127 /// A signed certificate timestamp (SCT) as defined in [RFC 6962 section 3.2].
128 ///
129 /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2
130 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
131 pub struct SignedCertificateTimestamp {
132     /// The version of the protocol to which the SCT conforms.
133     /// Currently, it is always v1.
134     pub version: Version,
135     /// The SHA-256 hash of the log's public key, calculated over
136     /// the DER encoding of the key represented as [SubjectPublicKeyInfo][spki::SubjectPublicKeyInfo].
137     pub log_id: LogId,
138     /// the current NTP Time measured since the `UNIX_EPOCH`
139     /// (January 1, 1970, 00:00), ignoring leap seconds, in milliseconds.
140     pub timestamp: u64,
141     /// The future extensions to protocol version v1.
142     /// Currently, no extensions are specified.
143     pub extensions: TlsByteVecU16,
144     /// A digital signature over many fields including
145     /// version, timestamp, extensions and others. See [RFC 6962 section 3.2]
146     /// for a complete list.
147     ///
148     /// [RFC 6962 section 3.2]:https://datatracker.ietf.org/doc/html/rfc6962#section-3.2
149     pub signature: DigitallySigned,
150 }
151 
152 impl SignedCertificateTimestamp {
153     /// Creates a [DateTime][der::DateTime] from the timestamp field since the `UNIX_EPOCH`.
154     ///
155     /// Returns an error if timestamp is outside the supported date range.
timestamp(&self) -> Result<der::DateTime, der::Error>156     pub fn timestamp(&self) -> Result<der::DateTime, der::Error> {
157         der::DateTime::from_unix_duration(core::time::Duration::from_millis(self.timestamp))
158     }
159 }
160 
161 /// The version of the protocol to which the SCT conforms
162 /// as defined in [RFC 6962 section 3.2]. Currently, it is always v1.
163 ///
164 /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2
165 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
166 #[repr(u8)]
167 pub enum Version {
168     /// Version 1.
169     V1 = 0,
170 }
171 
172 /// The SHA-256 hash of the log's public key, calculated over
173 /// the DER encoding of the key represented as [SubjectPublicKeyInfo][spki::SubjectPublicKeyInfo]
174 /// as defined in [RFC 6962 section 3.2].
175 ///
176 /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2
177 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
178 pub struct LogId {
179     /// Hash of the log's public key.
180     pub key_id: [u8; 32],
181 }
182 
183 /// Digital signature as defined in [RFC 5246 section 4.7].
184 ///
185 /// [RFC 5246 section 4.7]: https://datatracker.ietf.org/doc/html/rfc5246#section-4.7
186 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
187 pub struct DigitallySigned {
188     /// [SignatureAndHashAlgorithm] as defined in [RFC 5246 section 7.4.1.4.1].
189     ///
190     /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1
191     pub algorithm: SignatureAndHashAlgorithm,
192     /// Digital signature over some contents using the [SignatureAndHashAlgorithm].
193     pub signature: TlsByteVecU16,
194 }
195 
196 /// A combination of signature and hashing algorithms as defined in [RFC 5246 section 7.4.1.4.1].
197 ///
198 /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1
199 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
200 pub struct SignatureAndHashAlgorithm {
201     /// The hashing algorithm.
202     pub hash: HashAlgorithm,
203     /// The signature algorithm.
204     pub signature: SignatureAlgorithm,
205 }
206 
207 /// Signature algorithm as defined in [RFC 5246 section 7.4.1.4.1].
208 ///
209 /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1
210 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
211 #[repr(u8)]
212 pub enum SignatureAlgorithm {
213     /// Anonymous signature algorithm.
214     Anonymous = 0,
215     /// RSA signature algorithm.
216     Rsa = 1,
217     /// DSA signature algorithm.
218     Dsa = 2,
219     /// ECDSA signature algorithm.
220     Ecdsa = 3,
221     /// ED25519 signature algorithm.
222     Ed25519 = 7,
223     /// ED448 signature algorithm.
224     Ed448 = 8,
225 }
226 
227 /// Hashing algorithm as defined in [RFC 5246 section 7.4.1.4.1].
228 ///
229 /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1
230 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)]
231 #[repr(u8)]
232 pub enum HashAlgorithm {
233     /// No algorithm.
234     None = 0,
235     /// MD5 algorithm.
236     Md5 = 1,
237     /// SHA1 algorithm.
238     Sha1 = 2,
239     /// SHA224 algorithm.
240     Sha224 = 3,
241     /// SHA256 algorithm.
242     Sha256 = 4,
243     /// SHA384 algorithm.
244     Sha384 = 5,
245     /// SHA512 algorithm.
246     Sha512 = 6,
247     /// Intrinsic algorithm.
248     Intrinsic = 8,
249 }
250 
251 #[cfg(test)]
252 mod tests {
253     use der::{asn1::OctetString, Decode, Encode};
254     use tls_codec::{DeserializeBytes, SerializeBytes, TlsByteVecU16};
255 
256     use crate::ext::pkix::sct::LogId;
257 
258     use super::{
259         DigitallySigned, HashAlgorithm, SerializedSct, SignatureAlgorithm,
260         SignatureAndHashAlgorithm, SignedCertificateTimestamp, SignedCertificateTimestampList,
261         Version,
262     };
263 
run_deserialization_test<'a, T: DeserializeBytes + PartialEq + core::fmt::Debug>( bytes: &'a [u8], expected_result: Result<(T, &[u8]), tls_codec::Error>, ) -> Result<(T, &'a [u8]), tls_codec::Error>264     fn run_deserialization_test<'a, T: DeserializeBytes + PartialEq + core::fmt::Debug>(
265         bytes: &'a [u8],
266         expected_result: Result<(T, &[u8]), tls_codec::Error>,
267     ) -> Result<(T, &'a [u8]), tls_codec::Error> {
268         let actual_result = T::tls_deserialize_bytes(bytes);
269         assert_eq!(actual_result, expected_result);
270         actual_result
271     }
272 
run_serialization_test<T: SerializeBytes>(value: T, expected_bytes: &[u8])273     fn run_serialization_test<T: SerializeBytes>(value: T, expected_bytes: &[u8]) {
274         let result = value.tls_serialize().expect("failed to serialize value");
275         assert_eq!(expected_bytes, &result);
276     }
277 
278     #[test]
test_hash_algorithm_deserialization()279     fn test_hash_algorithm_deserialization() {
280         let bytes = [0, 1, 2, 3, 4, 5, 6, 8];
281 
282         let result = run_deserialization_test(
283             &bytes,
284             Ok((HashAlgorithm::None, [1, 2, 3, 4, 5, 6, 8].as_slice())),
285         );
286         let result = run_deserialization_test(
287             result.expect("run_deserialization_test failed").1,
288             Ok((HashAlgorithm::Md5, [2, 3, 4, 5, 6, 8].as_slice())),
289         );
290         let result = run_deserialization_test(
291             result.expect("run_deserialization_test failed").1,
292             Ok((HashAlgorithm::Sha1, [3, 4, 5, 6, 8].as_slice())),
293         );
294         let result = run_deserialization_test(
295             result.expect("run_deserialization_test failed").1,
296             Ok((HashAlgorithm::Sha224, [4, 5, 6, 8].as_slice())),
297         );
298         let result = run_deserialization_test(
299             result.expect("run_deserialization_test failed").1,
300             Ok((HashAlgorithm::Sha256, [5, 6, 8].as_slice())),
301         );
302         let result = run_deserialization_test(
303             result.expect("run_deserialization_test failed").1,
304             Ok((HashAlgorithm::Sha384, [6, 8].as_slice())),
305         );
306         let result = run_deserialization_test(
307             result.expect("run_deserialization_test failed").1,
308             Ok((HashAlgorithm::Sha512, [8].as_slice())),
309         );
310         let result = run_deserialization_test(
311             result.expect("run_deserialization_test failed").1,
312             Ok((HashAlgorithm::Intrinsic, [].as_slice())),
313         );
314         let _ = run_deserialization_test::<HashAlgorithm>(
315             result.expect("run_deserialization_test failed").1,
316             Err(tls_codec::Error::EndOfStream),
317         );
318         let _ =
319             run_deserialization_test::<HashAlgorithm>(&[7], Err(tls_codec::Error::UnknownValue(7)));
320         let _ =
321             run_deserialization_test::<HashAlgorithm>(&[9], Err(tls_codec::Error::UnknownValue(9)));
322     }
323 
324     #[test]
test_hash_algorithm_serialization()325     fn test_hash_algorithm_serialization() {
326         run_serialization_test(HashAlgorithm::None, &[0]);
327         run_serialization_test(HashAlgorithm::Md5, &[1]);
328         run_serialization_test(HashAlgorithm::Sha1, &[2]);
329         run_serialization_test(HashAlgorithm::Sha224, &[3]);
330         run_serialization_test(HashAlgorithm::Sha256, &[4]);
331         run_serialization_test(HashAlgorithm::Sha384, &[5]);
332         run_serialization_test(HashAlgorithm::Sha512, &[6]);
333         run_serialization_test(HashAlgorithm::Intrinsic, &[8]);
334     }
335 
336     #[test]
test_signature_algorithm_deserialization()337     fn test_signature_algorithm_deserialization() {
338         let bytes = [0, 1, 2, 3, 7, 8];
339 
340         let result = run_deserialization_test(
341             &bytes,
342             Ok((SignatureAlgorithm::Anonymous, [1, 2, 3, 7, 8].as_slice())),
343         );
344         let result = run_deserialization_test(
345             result.expect("run_deserialization_test failed").1,
346             Ok((SignatureAlgorithm::Rsa, [2, 3, 7, 8].as_slice())),
347         );
348         let result = run_deserialization_test(
349             result.expect("run_deserialization_test failed").1,
350             Ok((SignatureAlgorithm::Dsa, [3, 7, 8].as_slice())),
351         );
352         let result = run_deserialization_test(
353             result.expect("run_deserialization_test failed").1,
354             Ok((SignatureAlgorithm::Ecdsa, [7, 8].as_slice())),
355         );
356         let result = run_deserialization_test(
357             result.expect("run_deserialization_test failed").1,
358             Ok((SignatureAlgorithm::Ed25519, [8].as_slice())),
359         );
360         let result = run_deserialization_test(
361             result.expect("run_deserialization_test failed").1,
362             Ok((SignatureAlgorithm::Ed448, [].as_slice())),
363         );
364         let _ = run_deserialization_test::<SignatureAlgorithm>(
365             result.expect("run_deserialization_test failed").1,
366             Err(tls_codec::Error::EndOfStream),
367         );
368         let _ = run_deserialization_test::<SignatureAlgorithm>(
369             &[4],
370             Err(tls_codec::Error::UnknownValue(4)),
371         );
372         let _ = run_deserialization_test::<SignatureAlgorithm>(
373             &[5],
374             Err(tls_codec::Error::UnknownValue(5)),
375         );
376         let _ = run_deserialization_test::<SignatureAlgorithm>(
377             &[6],
378             Err(tls_codec::Error::UnknownValue(6)),
379         );
380         let _ = run_deserialization_test::<SignatureAlgorithm>(
381             &[9],
382             Err(tls_codec::Error::UnknownValue(9)),
383         );
384     }
385 
386     #[test]
test_signature_algorithm_serialization()387     fn test_signature_algorithm_serialization() {
388         run_serialization_test(SignatureAlgorithm::Anonymous, &[0]);
389         run_serialization_test(SignatureAlgorithm::Rsa, &[1]);
390         run_serialization_test(SignatureAlgorithm::Dsa, &[2]);
391         run_serialization_test(SignatureAlgorithm::Ecdsa, &[3]);
392         run_serialization_test(SignatureAlgorithm::Ed25519, &[7]);
393         run_serialization_test(SignatureAlgorithm::Ed448, &[8]);
394     }
395 
396     #[test]
test_signature_and_hash_algorithm_deserialization()397     fn test_signature_and_hash_algorithm_deserialization() {
398         let bytes = [4, 3, 2, 1];
399 
400         let result = run_deserialization_test(
401             &bytes,
402             Ok((
403                 SignatureAndHashAlgorithm {
404                     hash: HashAlgorithm::Sha256,
405                     signature: SignatureAlgorithm::Ecdsa,
406                 },
407                 [2, 1].as_slice(),
408             )),
409         );
410 
411         let _ = run_deserialization_test(
412             result.expect("run_deserialization_test failed").1,
413             Ok((
414                 SignatureAndHashAlgorithm {
415                     hash: HashAlgorithm::Sha1,
416                     signature: SignatureAlgorithm::Rsa,
417                 },
418                 [].as_slice(),
419             )),
420         );
421     }
422 
423     #[test]
test_signature_and_hash_algorithm_serialization()424     fn test_signature_and_hash_algorithm_serialization() {
425         run_serialization_test(
426             SignatureAndHashAlgorithm {
427                 hash: HashAlgorithm::Sha1,
428                 signature: SignatureAlgorithm::Rsa,
429             },
430             &[2, 1],
431         );
432         run_serialization_test(
433             SignatureAndHashAlgorithm {
434                 hash: HashAlgorithm::Sha256,
435                 signature: SignatureAlgorithm::Ecdsa,
436             },
437             &[4, 3],
438         );
439     }
440 
441     #[test]
test_digitally_signed_deserialization()442     fn test_digitally_signed_deserialization() {
443         let bytes = [4, 3, 0, 3, 2, 1, 0, 2, 1, 0, 1, 9];
444 
445         let result = run_deserialization_test(
446             &bytes,
447             Ok((
448                 DigitallySigned {
449                     algorithm: SignatureAndHashAlgorithm {
450                         hash: HashAlgorithm::Sha256,
451                         signature: SignatureAlgorithm::Ecdsa,
452                     },
453                     signature: TlsByteVecU16::from_slice(&[2, 1, 0]),
454                 },
455                 [2, 1, 0, 1, 9].as_slice(),
456             )),
457         );
458 
459         let _ = run_deserialization_test(
460             result.expect("run_deserialization_test failed").1,
461             Ok((
462                 DigitallySigned {
463                     algorithm: SignatureAndHashAlgorithm {
464                         hash: HashAlgorithm::Sha1,
465                         signature: SignatureAlgorithm::Rsa,
466                     },
467                     signature: TlsByteVecU16::from_slice(&[9]),
468                 },
469                 [].as_slice(),
470             )),
471         );
472     }
473 
474     #[test]
test_digitally_signed_serialization()475     fn test_digitally_signed_serialization() {
476         run_serialization_test(
477             DigitallySigned {
478                 algorithm: SignatureAndHashAlgorithm {
479                     hash: HashAlgorithm::Sha256,
480                     signature: SignatureAlgorithm::Ecdsa,
481                 },
482                 signature: TlsByteVecU16::from_slice(&[0, 1, 2]),
483             },
484             &[4, 3, 0, 3, 0, 1, 2],
485         );
486         run_serialization_test(
487             DigitallySigned {
488                 algorithm: SignatureAndHashAlgorithm {
489                     hash: HashAlgorithm::Sha1,
490                     signature: SignatureAlgorithm::Rsa,
491                 },
492                 signature: TlsByteVecU16::from_slice(&[0, 1, 2]),
493             },
494             &[2, 1, 0, 3, 0, 1, 2],
495         );
496     }
497 
498     #[test]
test_version_deserialization()499     fn test_version_deserialization() {
500         let bytes = [0, 0];
501 
502         let result = run_deserialization_test(&bytes, Ok((Version::V1, [0].as_slice())));
503 
504         let _ = run_deserialization_test(
505             result.expect("run_deserialization_test failed").1,
506             Ok((Version::V1, [].as_slice())),
507         );
508         let _ = run_deserialization_test::<Version>(&[1], Err(tls_codec::Error::UnknownValue(1)));
509     }
510 
511     #[test]
test_version_serialization()512     fn test_version_serialization() {
513         run_serialization_test(Version::V1, &[0]);
514     }
515 
516     #[test]
test_log_id_deserialization()517     fn test_log_id_deserialization() {
518         let bytes = [42; 36];
519 
520         let _ =
521             run_deserialization_test(&bytes, Ok((LogId { key_id: [42; 32] }, [42; 4].as_slice())));
522     }
523 
524     #[test]
test_log_id_serialization()525     fn test_log_id_serialization() {
526         run_serialization_test(LogId { key_id: [3; 32] }, &[3; 32]);
527     }
528 
529     const TLS_SCT_EXAMPLE: [u8; 119] = [
530         0, 122, 50, 140, 84, 216, 183, 45, 182, 32, 234, 56, 224, 82, 30, 233, 132, 22, 112, 50,
531         19, 133, 77, 59, 210, 43, 193, 58, 87, 163, 82, 235, 82, 0, 0, 1, 135, 224, 74, 186, 106,
532         0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 170, 82, 81, 162, 157, 234, 14, 189, 167, 13, 247,
533         211, 97, 112, 248, 172, 149, 125, 58, 18, 238, 60, 150, 157, 124, 245, 188, 138, 102, 212,
534         244, 187, 2, 33, 0, 209, 79, 31, 63, 208, 79, 240, 233, 193, 187, 28, 33, 190, 95, 130, 66,
535         183, 222, 187, 42, 22, 83, 0, 119, 226, 246, 19, 197, 47, 237, 198, 149,
536     ];
537 
538     #[test]
test_sct_deserialization()539     fn test_sct_deserialization() {
540         let _ = run_deserialization_test(
541             &TLS_SCT_EXAMPLE,
542             Ok((
543                 SignedCertificateTimestamp {
544                     version: Version::V1,
545                     log_id: LogId {
546                         key_id: TLS_SCT_EXAMPLE[1..33]
547                             .try_into()
548                             .expect("failed to convert to u8 array"),
549                     },
550                     timestamp: u64::from_be_bytes(
551                         TLS_SCT_EXAMPLE[33..41]
552                             .try_into()
553                             .expect("failed to convert to u8 array"),
554                     ),
555                     extensions: TlsByteVecU16::from_slice(&[]),
556                     signature: DigitallySigned {
557                         algorithm: SignatureAndHashAlgorithm {
558                             hash: HashAlgorithm::Sha256,
559                             signature: SignatureAlgorithm::Ecdsa,
560                         },
561                         signature: TlsByteVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]),
562                     },
563                 },
564                 &[],
565             )),
566         );
567     }
568 
569     #[test]
test_sct_serialization()570     fn test_sct_serialization() {
571         run_serialization_test(
572             SignedCertificateTimestamp {
573                 version: Version::V1,
574                 log_id: LogId {
575                     key_id: TLS_SCT_EXAMPLE[1..33]
576                         .try_into()
577                         .expect("failed to convert to u8 array"),
578                 },
579                 timestamp: u64::from_be_bytes(
580                     TLS_SCT_EXAMPLE[33..41]
581                         .try_into()
582                         .expect("failed to convert to u8 array"),
583                 ),
584                 extensions: TlsByteVecU16::from_slice(&[]),
585                 signature: DigitallySigned {
586                     algorithm: SignatureAndHashAlgorithm {
587                         hash: HashAlgorithm::Sha256,
588                         signature: SignatureAlgorithm::Ecdsa,
589                     },
590                     signature: TlsByteVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]),
591                 },
592             },
593             &TLS_SCT_EXAMPLE,
594         );
595     }
596 
597     const SCT_EXAMPLE: [u8; 245] = [
598         4, 129, 242, 0, 240, 0, 119, 0, 122, 50, 140, 84, 216, 183, 45, 182, 32, 234, 56, 224, 82,
599         30, 233, 132, 22, 112, 50, 19, 133, 77, 59, 210, 43, 193, 58, 87, 163, 82, 235, 82, 0, 0,
600         1, 135, 224, 74, 186, 106, 0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 170, 82, 81, 162, 157, 234,
601         14, 189, 167, 13, 247, 211, 97, 112, 248, 172, 149, 125, 58, 18, 238, 60, 150, 157, 124,
602         245, 188, 138, 102, 212, 244, 187, 2, 33, 0, 209, 79, 31, 63, 208, 79, 240, 233, 193, 187,
603         28, 33, 190, 95, 130, 66, 183, 222, 187, 42, 22, 83, 0, 119, 226, 246, 19, 197, 47, 237,
604         198, 149, 0, 117, 0, 173, 247, 190, 250, 124, 255, 16, 200, 139, 157, 61, 156, 30, 62, 24,
605         106, 180, 103, 41, 93, 207, 177, 12, 36, 202, 133, 134, 52, 235, 220, 130, 138, 0, 0, 1,
606         135, 224, 74, 186, 164, 0, 0, 4, 3, 0, 70, 48, 68, 2, 32, 29, 110, 144, 37, 157, 227, 170,
607         70, 67, 16, 68, 195, 212, 168, 246, 37, 94, 69, 210, 136, 42, 113, 217, 230, 34, 152, 253,
608         116, 13, 174, 232, 191, 2, 32, 16, 25, 200, 223, 59, 176, 40, 145, 76, 85, 242, 133, 130,
609         212, 61, 216, 83, 238, 115, 130, 82, 240, 196, 162, 249, 54, 199, 120, 175, 72, 223, 14,
610     ];
611 
612     #[test]
test_sct_list_deserialization()613     fn test_sct_list_deserialization() {
614         fn run_test(
615             bytes: &[u8],
616             expected_result: Result<SignedCertificateTimestampList, der::Error>,
617         ) -> Result<SignedCertificateTimestampList, der::Error> {
618             let actual_result = SignedCertificateTimestampList::from_der(bytes);
619             assert_eq!(actual_result, expected_result);
620             actual_result
621         }
622 
623         let result = run_test(
624             &SCT_EXAMPLE,
625             Ok(SignedCertificateTimestampList(
626                 OctetString::new(&SCT_EXAMPLE[3..]).expect("failed to convert to u8 array"),
627             )),
628         );
629         let scts = result
630             .expect("run_test failed")
631             .parse_timestamps()
632             .expect("parse_timestamps failed");
633         assert_eq!(
634             scts[0].parse_timestamp(),
635             Ok(SignedCertificateTimestamp {
636                 version: Version::V1,
637                 log_id: LogId {
638                     key_id: SCT_EXAMPLE[8..40]
639                         .try_into()
640                         .expect("failed to convert to u8 array"),
641                 },
642                 timestamp: u64::from_be_bytes(
643                     SCT_EXAMPLE[40..48]
644                         .try_into()
645                         .expect("failed to convert to u8 array")
646                 ),
647                 extensions: TlsByteVecU16::from_slice(&[]),
648                 signature: DigitallySigned {
649                     algorithm: SignatureAndHashAlgorithm {
650                         hash: HashAlgorithm::Sha256,
651                         signature: SignatureAlgorithm::Ecdsa,
652                     },
653                     signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[54..126]),
654                 },
655             })
656         );
657         assert_eq!(
658             scts[1].parse_timestamp(),
659             Ok(SignedCertificateTimestamp {
660                 version: Version::V1,
661                 log_id: LogId {
662                     key_id: SCT_EXAMPLE[129..161]
663                         .try_into()
664                         .expect("failed to convert to u8 array"),
665                 },
666                 timestamp: u64::from_be_bytes(
667                     SCT_EXAMPLE[161..169]
668                         .try_into()
669                         .expect("failed to convert to u8 array")
670                 ),
671                 extensions: TlsByteVecU16::from_slice(&[]),
672                 signature: DigitallySigned {
673                     algorithm: SignatureAndHashAlgorithm {
674                         hash: HashAlgorithm::Sha256,
675                         signature: SignatureAlgorithm::Ecdsa,
676                     },
677                     signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[175..]),
678                 },
679             })
680         );
681     }
682 
683     #[test]
test_sct_list_serialization()684     fn test_sct_list_serialization() {
685         let serialized_sct1 = SerializedSct::new(SignedCertificateTimestamp {
686             version: Version::V1,
687             log_id: LogId {
688                 key_id: SCT_EXAMPLE[8..40]
689                     .try_into()
690                     .expect("failed to convert to u8 array"),
691             },
692             timestamp: u64::from_be_bytes(
693                 SCT_EXAMPLE[40..48]
694                     .try_into()
695                     .expect("failed to convert to u8 array"),
696             ),
697             extensions: TlsByteVecU16::from_slice(&[]),
698             signature: DigitallySigned {
699                 algorithm: SignatureAndHashAlgorithm {
700                     hash: HashAlgorithm::Sha256,
701                     signature: SignatureAlgorithm::Ecdsa,
702                 },
703                 signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[54..126]),
704             },
705         })
706         .expect("failed to create SerializedSct");
707         let serialized_sct2 = SerializedSct::new(SignedCertificateTimestamp {
708             version: Version::V1,
709             log_id: LogId {
710                 key_id: SCT_EXAMPLE[129..161]
711                     .try_into()
712                     .expect("failed to convert to u8 array"),
713             },
714             timestamp: u64::from_be_bytes(
715                 SCT_EXAMPLE[161..169]
716                     .try_into()
717                     .expect("failed to convert to u8 array"),
718             ),
719             extensions: TlsByteVecU16::from_slice(&[]),
720             signature: DigitallySigned {
721                 algorithm: SignatureAndHashAlgorithm {
722                     hash: HashAlgorithm::Sha256,
723                     signature: SignatureAlgorithm::Ecdsa,
724                 },
725                 signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[175..]),
726             },
727         })
728         .expect("failed to create SerializedSct");
729         let list = SignedCertificateTimestampList::new(&[serialized_sct1, serialized_sct2])
730             .expect("failed to create SignedCertificateTimestampList");
731         let der = list.to_der().expect("failed to convert to der");
732         assert_eq!(der.as_slice(), SCT_EXAMPLE.as_slice());
733     }
734 }
735