From 0a33b684e0a0a8c98f505f3a2d20e91593bb1eeb Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 21 Jun 2023 19:02:36 +0530 Subject: [PATCH 01/58] add a few failing tests --- tls_codec/tests/decode_bytes.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tls_codec/tests/decode_bytes.rs diff --git a/tls_codec/tests/decode_bytes.rs b/tls_codec/tests/decode_bytes.rs new file mode 100644 index 000000000..06e341517 --- /dev/null +++ b/tls_codec/tests/decode_bytes.rs @@ -0,0 +1,28 @@ +use tls_codec::{DeserializeBytes, TlsByteVecU16, TlsByteVecU32, TlsByteVecU8}; + +#[test] +fn deserialize_tls_byte_vec_u8() { + let bytes = [3, 2, 1, 0]; + let (result, rest) = TlsByteVecU8::tls_deserialize(&bytes).unwrap(); + let expected_result = [2, 1, 0]; + assert_eq!(result.as_slice(), expected_result); + assert_eq!(rest, []); +} + +#[test] +fn deserialize_tls_byte_vec_u16() { + let bytes = [0, 3, 2, 1, 0]; + let (result, rest) = TlsByteVecU16::tls_deserialize(&bytes).unwrap(); + let expected_result = [2, 1, 0]; + assert_eq!(result.as_slice(), expected_result); + assert_eq!(rest, []); +} + +#[test] +fn deserialize_tls_byte_vec_u32() { + let bytes = [0, 0, 0, 3, 2, 1, 0]; + let (result, rest) = TlsByteVecU32::tls_deserialize(&bytes).unwrap(); + let expected_result = [2, 1, 0]; + assert_eq!(result.as_slice(), expected_result); + assert_eq!(rest, []); +} From 75b498a12a62b0a947c10cfc73d945ba7e52b7af Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 13:44:06 +0530 Subject: [PATCH 02/58] Fix a bug in TlsByteVecUX deserialization The DeserializeBytes impl of TlsByteVecUX did not skip the length prefix bytes. --- tls_codec/src/tls_vec.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index da0c9f0a0..f29f04477 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -74,7 +74,9 @@ macro_rules! impl_byte_deserialize { u16::MAX ))); } - let vec = bytes.get(..len).ok_or(Error::EndOfStream)?; + let vec = bytes + .get($len_len..len + $len_len) + .ok_or(Error::EndOfStream)?; let result = Self { vec: vec.to_vec() }; Ok((result, &remainder.get(len..).ok_or(Error::EndOfStream)?)) } From 598079c16bb77681df822e18270fd9be3e7468cf Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 14:44:51 +0530 Subject: [PATCH 03/58] impl SerializeBytes for TlsByteVecUX types --- tls_codec/src/tls_vec.rs | 58 +++++++++++++++++++++++++++++++-- tls_codec/tests/encode_bytes.rs | 29 ++++++++++++++++- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index da0c9f0a0..5432187cb 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -13,7 +13,7 @@ use serde::ser::SerializeStruct; use std::io::{Read, Write}; use zeroize::Zeroize; -use crate::{Deserialize, DeserializeBytes, Error, Serialize, Size}; +use crate::{Deserialize, DeserializeBytes, Error, Serialize, SerializeBytes, Size}; macro_rules! impl_size { ($self:ident, $size:ty, $name:ident, $len_len:literal) => { @@ -78,6 +78,46 @@ macro_rules! impl_byte_deserialize { let result = Self { vec: vec.to_vec() }; Ok((result, &remainder.get(len..).ok_or(Error::EndOfStream)?)) } + + fn serialize_bytes_bytes(&$self) -> Result, Error> { + let tls_serialized_len = $self.tls_serialized_len(); + let byte_length = tls_serialized_len - $len_len; + + let ll = $len_len; + std::println!("serialize_bytes_bytes: tls_serialized_len: {tls_serialized_len}, $len_len: {ll}, byte_length: {byte_length}"); + + let max_len = <$size>::MAX as usize; + debug_assert!( + byte_length <= max_len, + "Vector length can't be encoded in the vector length a {} >= {}", + byte_length, + max_len + ); + if byte_length > max_len { + return Err(Error::InvalidVectorLength); + } + + let mut vec = Vec::::with_capacity(tls_serialized_len); + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), &mut vec)?; + + let bytes = $self.as_slice(); + vec.extend_from_slice(bytes); + written += bytes.len(); + + debug_assert_eq!( + written, tls_serialized_len, + "{} bytes should have been serialized but {} were written", + tls_serialized_len, written + ); + if written != tls_serialized_len { + return Err(Error::EncodingError(format!( + "{} bytes should have been serialized but {} were written", + tls_serialized_len, written + ))); + } + + Ok(vec) + } }; } @@ -130,6 +170,9 @@ macro_rules! impl_serialize { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; + let ll = $len_len; + std::println!("serialize: tls_serialized_len: {tls_serialized_len}, $len_len: {ll}, byte_length: {byte_length}"); + let max_len = <$size>::MAX as usize; debug_assert!( byte_length <= max_len, @@ -141,7 +184,7 @@ macro_rules! impl_serialize { return Err(Error::InvalidVectorLength); } - let mut written = (byte_length as $size).tls_serialize(writer)?; + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; // Now serialize the elements for e in $self.as_slice().iter() { @@ -174,6 +217,9 @@ macro_rules! impl_byte_serialize { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; + let ll = $len_len; + std::println!("serialize_bytes: tls_serialized_len: {tls_serialized_len}, $len_len: {ll}, byte_length: {byte_length}"); + let max_len = <$size>::MAX as usize; debug_assert!( byte_length <= max_len, @@ -185,7 +231,7 @@ macro_rules! impl_byte_serialize { return Err(Error::InvalidVectorLength); } - let mut written = (byte_length as $size).tls_serialize(writer)?; + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; // Now serialize the elements written += writer.write($self.as_slice())?; @@ -293,6 +339,12 @@ macro_rules! impl_tls_vec_codec_bytes { Self::deserialize_bytes_bytes(bytes) } } + + impl SerializeBytes for $name { + fn tls_serialize(&self) -> Result, Error> { + self.serialize_bytes_bytes() + } + } }; } diff --git a/tls_codec/tests/encode_bytes.rs b/tls_codec/tests/encode_bytes.rs index 20830b5e0..f9b30224b 100644 --- a/tls_codec/tests/encode_bytes.rs +++ b/tls_codec/tests/encode_bytes.rs @@ -1,4 +1,4 @@ -use tls_codec::SerializeBytes; +use tls_codec::{SerializeBytes, TlsByteVecU16, TlsByteVecU32, TlsByteVecU8}; #[test] fn serialize_primitives() { @@ -40,3 +40,30 @@ fn serialize_var_len_boundaries() { let serialized = v.tls_serialize().expect("Error encoding vector"); assert_eq!(&serialized[0..5], &[0x80, 0, 0x40, 0, 99]); } + +#[test] +fn serialize_tls_byte_vec_u8() { + let byte_vec = TlsByteVecU8::from_slice(&[1, 2, 3]); + let actual_result = byte_vec + .tls_serialize() + .expect("Error encoding byte vector"); + assert_eq!(actual_result, vec![3, 1, 2, 3]); +} + +#[test] +fn serialize_tls_byte_vec_u16() { + let byte_vec = TlsByteVecU16::from_slice(&[1, 2, 3]); + let actual_result = byte_vec + .tls_serialize() + .expect("Error encoding byte vector"); + assert_eq!(actual_result, vec![0, 3, 1, 2, 3]); +} + +#[test] +fn serialize_tls_byte_vec_u32() { + let byte_vec = TlsByteVecU32::from_slice(&[1, 2, 3]); + let actual_result = byte_vec + .tls_serialize() + .expect("Error encoding byte vector"); + assert_eq!(actual_result, vec![0, 0, 0, 3, 1, 2, 3]); +} From 51297a894a0013e3dc19f8cacaeea65772fe19d3 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 15:29:33 +0530 Subject: [PATCH 04/58] remove println statments --- tls_codec/src/tls_vec.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index 5432187cb..3d123e161 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -83,9 +83,6 @@ macro_rules! impl_byte_deserialize { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; - let ll = $len_len; - std::println!("serialize_bytes_bytes: tls_serialized_len: {tls_serialized_len}, $len_len: {ll}, byte_length: {byte_length}"); - let max_len = <$size>::MAX as usize; debug_assert!( byte_length <= max_len, @@ -170,9 +167,6 @@ macro_rules! impl_serialize { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; - let ll = $len_len; - std::println!("serialize: tls_serialized_len: {tls_serialized_len}, $len_len: {ll}, byte_length: {byte_length}"); - let max_len = <$size>::MAX as usize; debug_assert!( byte_length <= max_len, @@ -217,9 +211,6 @@ macro_rules! impl_byte_serialize { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; - let ll = $len_len; - std::println!("serialize_bytes: tls_serialized_len: {tls_serialized_len}, $len_len: {ll}, byte_length: {byte_length}"); - let max_len = <$size>::MAX as usize; debug_assert!( byte_length <= max_len, From 10398c775208f8fc9f6f52df15b59e54112aa2c1 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 16:11:58 +0530 Subject: [PATCH 05/58] use fully qualified name for Serialize trait --- tls_codec/src/tls_vec.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index 3d123e161..e0935d8dd 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -95,7 +95,7 @@ macro_rules! impl_byte_deserialize { } let mut vec = Vec::::with_capacity(tls_serialized_len); - let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), &mut vec)?; + let mut written = <$size as $crate::Serialize>::tls_serialize(&(byte_length as $size), &mut vec)?; let bytes = $self.as_slice(); vec.extend_from_slice(bytes); @@ -178,7 +178,7 @@ macro_rules! impl_serialize { return Err(Error::InvalidVectorLength); } - let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; + let mut written = <$size as $crate::Serialize>::tls_serialize(&(byte_length as $size), writer)?; // Now serialize the elements for e in $self.as_slice().iter() { @@ -222,7 +222,7 @@ macro_rules! impl_byte_serialize { return Err(Error::InvalidVectorLength); } - let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; + let mut written = <$size as $crate::Serialize>::tls_serialize(&(byte_length as $size), writer)?; // Now serialize the elements written += writer.write($self.as_slice())?; From 14ce591b1b3408fa8d06acae4b5b662b1ecdc0ab Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 16:41:19 +0530 Subject: [PATCH 06/58] Revert "use fully qualified name for Serialize trait" This reverts commit 73e6f26f66b8d404dd0c4587999e3e39a71ac040. --- tls_codec/src/tls_vec.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index e0935d8dd..3d123e161 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -95,7 +95,7 @@ macro_rules! impl_byte_deserialize { } let mut vec = Vec::::with_capacity(tls_serialized_len); - let mut written = <$size as $crate::Serialize>::tls_serialize(&(byte_length as $size), &mut vec)?; + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), &mut vec)?; let bytes = $self.as_slice(); vec.extend_from_slice(bytes); @@ -178,7 +178,7 @@ macro_rules! impl_serialize { return Err(Error::InvalidVectorLength); } - let mut written = <$size as $crate::Serialize>::tls_serialize(&(byte_length as $size), writer)?; + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; // Now serialize the elements for e in $self.as_slice().iter() { @@ -222,7 +222,7 @@ macro_rules! impl_byte_serialize { return Err(Error::InvalidVectorLength); } - let mut written = <$size as $crate::Serialize>::tls_serialize(&(byte_length as $size), writer)?; + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; // Now serialize the elements written += writer.write($self.as_slice())?; From 0c23e290ec33796017a724175f66e3f52e7a777a Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 16:44:21 +0530 Subject: [PATCH 07/58] do not use Serialize trait in impl of SerializeBytes --- tls_codec/src/tls_vec.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index 3d123e161..f1ddc2eb3 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -95,7 +95,9 @@ macro_rules! impl_byte_deserialize { } let mut vec = Vec::::with_capacity(tls_serialized_len); - let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), &mut vec)?; + let length_vec = <$size as SerializeBytes>::tls_serialize(&(byte_length as $size))?; + let mut written = length_vec.len(); + vec.extend_from_slice(&length_vec); let bytes = $self.as_slice(); vec.extend_from_slice(bytes); From f80288b08cf4189bf272f606e70fe53846b7e7db Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 20:28:51 +0530 Subject: [PATCH 08/58] support no_std for tls_codec_derive --- tls_codec/Cargo.toml | 2 +- tls_codec/derive/Cargo.toml | 4 ++++ tls_codec/derive/src/lib.rs | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tls_codec/Cargo.toml b/tls_codec/Cargo.toml index 8f66ca057..bce671748 100644 --- a/tls_codec/Cargo.toml +++ b/tls_codec/Cargo.toml @@ -31,7 +31,7 @@ arbitrary = [ "std", "dep:arbitrary" ] derive = [ "std", "tls_codec_derive" ] serde = [ "std", "dep:serde" ] mls = [] # In MLS variable length vectors are limited compared to QUIC. -std = [] +std = [ "tls_codec_derive?/std" ] [[bench]] name = "tls_vec" diff --git a/tls_codec/derive/Cargo.toml b/tls_codec/derive/Cargo.toml index 42771f553..de63660ed 100644 --- a/tls_codec/derive/Cargo.toml +++ b/tls_codec/derive/Cargo.toml @@ -21,3 +21,7 @@ proc-macro2 = "1.0" [dev-dependencies] tls_codec = { path = "../" } trybuild = "1" + +[features] +default = [ "std" ] +std = [] \ No newline at end of file diff --git a/tls_codec/derive/src/lib.rs b/tls_codec/derive/src/lib.rs index 4dfffa4e0..dbb48b617 100644 --- a/tls_codec/derive/src/lib.rs +++ b/tls_codec/derive/src/lib.rs @@ -698,7 +698,7 @@ fn impl_tls_size(parsed_ast: TlsStruct) -> TokenStream2 { let field_len = match self { #(#field_arms)* }; - std::mem::size_of::<#repr>() + field_len + core::mem::size_of::<#repr>() + field_len } } @@ -740,6 +740,7 @@ fn impl_serialize(parsed_ast: TlsStruct, svariant: SerializeVariant) -> TokenStr SerializeVariant::Write => { quote! { impl #impl_generics tls_codec::Serialize for #ident #ty_generics #where_clause { + #[cfg(feature = "std")] fn tls_serialize(&self, writer: &mut W) -> core::result::Result { let mut written = 0usize; #( @@ -760,6 +761,7 @@ fn impl_serialize(parsed_ast: TlsStruct, svariant: SerializeVariant) -> TokenStr } impl #impl_generics tls_codec::Serialize for &#ident #ty_generics #where_clause { + #[cfg(feature = "std")] fn tls_serialize(&self, writer: &mut W) -> core::result::Result { tls_codec::Serialize::tls_serialize(*self, writer) } @@ -850,6 +852,7 @@ fn impl_serialize(parsed_ast: TlsStruct, svariant: SerializeVariant) -> TokenStr SerializeVariant::Write => { quote! { impl #impl_generics tls_codec::Serialize for #ident #ty_generics #where_clause { + #[cfg(feature = "std")] fn tls_serialize(&self, writer: &mut W) -> core::result::Result { #discriminant_constants match self { @@ -859,6 +862,7 @@ fn impl_serialize(parsed_ast: TlsStruct, svariant: SerializeVariant) -> TokenStr } impl #impl_generics tls_codec::Serialize for &#ident #ty_generics #where_clause { + #[cfg(feature = "std")] fn tls_serialize(&self, writer: &mut W) -> core::result::Result { tls_codec::Serialize::tls_serialize(*self, writer) } @@ -909,6 +913,7 @@ fn impl_deserialize(parsed_ast: TlsStruct) -> TokenStream2 { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); quote! { impl #impl_generics tls_codec::Deserialize for #ident #ty_generics #where_clause { + #[cfg(feature = "std")] fn tls_deserialize(bytes: &mut R) -> core::result::Result { Ok(Self { #(#members: #prefixes::tls_deserialize(bytes)?,)* @@ -948,6 +953,7 @@ fn impl_deserialize(parsed_ast: TlsStruct) -> TokenStream2 { quote! { impl #impl_generics tls_codec::Deserialize for #ident #ty_generics #where_clause { #[allow(non_upper_case_globals)] + #[cfg(feature = "std")] fn tls_deserialize(bytes: &mut R) -> core::result::Result { #discriminant_constants let discriminant = <#repr as tls_codec::Deserialize>::tls_deserialize(bytes)?; From 1c70c7c018ba6562cd6fc602fe63012168f6c19b Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 21:11:50 +0530 Subject: [PATCH 09/58] remove std feature from derive feature --- tls_codec/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tls_codec/Cargo.toml b/tls_codec/Cargo.toml index bce671748..6e30fe3bb 100644 --- a/tls_codec/Cargo.toml +++ b/tls_codec/Cargo.toml @@ -28,7 +28,7 @@ regex = "1.8" [features] default = [ "std" ] arbitrary = [ "std", "dep:arbitrary" ] -derive = [ "std", "tls_codec_derive" ] +derive = [ "tls_codec_derive" ] serde = [ "std", "dep:serde" ] mls = [] # In MLS variable length vectors are limited compared to QUIC. std = [ "tls_codec_derive?/std" ] From 2bc61c62969781497cfea5560721350b6b5c8a1a Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Mon, 12 Jun 2023 19:39:18 +0530 Subject: [PATCH 10/58] SCT feature WIP --- x509-cert/Cargo.toml | 3 ++ x509-cert/src/ext/pkix.rs | 5 ++ x509-cert/src/ext/pkix/sct.rs | 92 +++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 x509-cert/src/ext/pkix/sct.rs diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 8a78260cf..3f59ab711 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -23,6 +23,8 @@ spki = { version = "0.7.2", features = ["alloc"] } arbitrary = { version = "1.3", features = ["derive"], optional = true } sha1 = { version = "0.10.0", optional = true } signature = { version = "2.1.0", features = ["rand_core"], optional = true } +# tls_codec = { version = "0.3.0", features = ["derive"], optional = true } +tls_codec = { version = "0.3.0", features = ["derive"] } [dev-dependencies] hex-literal = "0.4" @@ -43,6 +45,7 @@ arbitrary = ["dep:arbitrary", "std", "der/arbitrary", "spki/arbitrary"] builder = ["std", "sha1/default", "signature"] hazmat = [] pem = ["der/pem", "spki/pem"] +# sct = ["dep:tls_codec"] [package.metadata.docs.rs] all-features = true diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index 95a5e2b5d..c39610fb7 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -9,6 +9,8 @@ mod access; mod authkeyid; mod keyusage; mod policymap; +// #[cfg(feature = "sct")] +mod sct; use crate::attr::AttributeTypeAndValue; @@ -24,6 +26,9 @@ pub use crl::{ pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod}; pub use policymap::{PolicyMapping, PolicyMappings}; +// #[cfg(feature = "sct")] +pub use sct::SctList; + pub use const_oid::db::rfc5280::{ ID_CE_INHIBIT_ANY_POLICY, ID_CE_ISSUER_ALT_NAME, ID_CE_SUBJECT_ALT_NAME, ID_CE_SUBJECT_DIRECTORY_ATTRIBUTES, ID_CE_SUBJECT_KEY_IDENTIFIER, diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs new file mode 100644 index 000000000..c182df389 --- /dev/null +++ b/x509-cert/src/ext/pkix/sct.rs @@ -0,0 +1,92 @@ +use const_oid::{db::rfc6962, AssociatedOid, ObjectIdentifier}; +use der::asn1::OctetString; +use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize}; + +// TODO: Review what should be pub +// TODO: Update docs +// TODO: Review naming + +// TODO: Remove this constant when const_oid version is updated which includes this PR: +// https://github.com/RustCrypto/formats/pull/1094 +// TODO: Do not publish this as pub, this is for testing only +/// OID for signed certificate timestamps extension +// pub const CT_PRECERT_SCTS: ObjectIdentifier = +// ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); + +pub struct SctList(OctetString); + +impl AssociatedOid for SctList { + const OID: ObjectIdentifier = rfc6962::CT_PRECERT_SCTS; +} + +impl_newtype!(SctList, OctetString); +impl_extension!(SctList, critical = false); + +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[repr(u8)] +pub enum HashAlgo { + /// No algorithm + None = 0, + /// MD5 algorithm + Md5 = 1, + /// SHA1 algorithm + Sha1 = 2, + /// SHA224 algorithm + Sha224 = 3, + /// SHA256 algorithm + Sha256 = 4, + /// SHA384 algorithm + Sha384 = 5, + /// SHA512 algorithm + Sha512 = 6, + /// Intrinsic algorithm + Intrinsic = 8, +} + +#[cfg(test)] +mod tests { + use tls_codec::DeserializeBytes; + + use super::HashAlgo; + + #[test] + fn test_hash_algo_deserialization() { + let bytes = [0, 1, 2, 3, 4, 5, 6, 8]; + + let hash_algo = HashAlgo::tls_deserialize(&bytes); + assert_eq!( + hash_algo, + Ok((HashAlgo::None, [1, 2, 3, 4, 5, 6, 8].as_slice())) + ); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!( + hash_algo, + Ok((HashAlgo::Md5, [2, 3, 4, 5, 6, 8].as_slice())) + ); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Ok((HashAlgo::Sha1, [3, 4, 5, 6, 8].as_slice()))); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Ok((HashAlgo::Sha224, [4, 5, 6, 8].as_slice()))); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Ok((HashAlgo::Sha256, [5, 6, 8].as_slice()))); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Ok((HashAlgo::Sha384, [6, 8].as_slice()))); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Ok((HashAlgo::Sha512, [8].as_slice()))); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Ok((HashAlgo::Intrinsic, [].as_slice()))); + + let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); + assert_eq!(hash_algo, Err(tls_codec::Error::EndOfStream)); + + let hash_algo = HashAlgo::tls_deserialize(&[7]); + assert_eq!(hash_algo, Err(tls_codec::Error::UnknownValue(7))); + } +} From 08ba77fdaeed32c5f1b5b3b5608cbdf082faf626 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Mon, 12 Jun 2023 20:53:00 +0530 Subject: [PATCH 11/58] add more tests --- x509-cert/src/ext/pkix/sct.rs | 99 ++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 36 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index c182df389..c315042b5 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -24,7 +24,7 @@ impl_extension!(SctList, critical = false); #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] -pub enum HashAlgo { +pub enum HashAlgorithm { /// No algorithm None = 0, /// MD5 algorithm @@ -45,48 +45,75 @@ pub enum HashAlgo { #[cfg(test)] mod tests { - use tls_codec::DeserializeBytes; + use alloc::vec::Vec; + use tls_codec::{DeserializeBytes, Error, Serialize, Size}; - use super::HashAlgo; + use super::HashAlgorithm; #[test] - fn test_hash_algo_deserialization() { + fn test_hash_algorithm_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(HashAlgorithm, &[u8]), Error>, + ) -> Result<(HashAlgorithm, &'a [u8]), Error> { + let actual_result = HashAlgorithm::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } let bytes = [0, 1, 2, 3, 4, 5, 6, 8]; - let hash_algo = HashAlgo::tls_deserialize(&bytes); - assert_eq!( - hash_algo, - Ok((HashAlgo::None, [1, 2, 3, 4, 5, 6, 8].as_slice())) + let result = run_test( + &bytes, + Ok((HashAlgorithm::None, [1, 2, 3, 4, 5, 6, 8].as_slice())), ); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!( - hash_algo, - Ok((HashAlgo::Md5, [2, 3, 4, 5, 6, 8].as_slice())) + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Md5, [2, 3, 4, 5, 6, 8].as_slice())), ); + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Sha1, [3, 4, 5, 6, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Sha224, [4, 5, 6, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Sha256, [5, 6, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Sha384, [6, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Sha512, [8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((HashAlgorithm::Intrinsic, [].as_slice())), + ); + let _ = run_test(&result.unwrap().1, Err(Error::EndOfStream)); + let _ = run_test(&[7], Err(Error::UnknownValue(7))); + } - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Ok((HashAlgo::Sha1, [3, 4, 5, 6, 8].as_slice()))); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Ok((HashAlgo::Sha224, [4, 5, 6, 8].as_slice()))); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Ok((HashAlgo::Sha256, [5, 6, 8].as_slice()))); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Ok((HashAlgo::Sha384, [6, 8].as_slice()))); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Ok((HashAlgo::Sha512, [8].as_slice()))); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Ok((HashAlgo::Intrinsic, [].as_slice()))); - - let hash_algo = HashAlgo::tls_deserialize(&hash_algo.unwrap().1); - assert_eq!(hash_algo, Err(tls_codec::Error::EndOfStream)); - - let hash_algo = HashAlgo::tls_deserialize(&[7]); - assert_eq!(hash_algo, Err(tls_codec::Error::UnknownValue(7))); + #[test] + fn test_hash_algorithm_serialization() { + fn run_test(hash_algorithm: HashAlgorithm, expected_int: u8) { + let mut buffer = Vec::with_capacity(hash_algorithm.tls_serialized_len()); + let result = hash_algorithm.tls_serialize(&mut buffer); + assert_eq!([expected_int], buffer[..1]); + assert_eq!(result, Ok(1)); + } + + run_test(HashAlgorithm::None, 0); + run_test(HashAlgorithm::Md5, 1); + run_test(HashAlgorithm::Sha1, 2); + run_test(HashAlgorithm::Sha224, 3); + run_test(HashAlgorithm::Sha256, 4); + run_test(HashAlgorithm::Sha384, 5); + run_test(HashAlgorithm::Sha512, 6); + run_test(HashAlgorithm::Intrinsic, 8); } } From d2515180b1277118dcc70bb406f9501ae32cadf6 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Mon, 12 Jun 2023 21:04:14 +0530 Subject: [PATCH 12/58] add signature algo & tests --- x509-cert/src/ext/pkix/sct.rs | 80 ++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index c315042b5..64360f13c 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -22,6 +22,23 @@ impl AssociatedOid for SctList { impl_newtype!(SctList, OctetString); impl_extension!(SctList, critical = false); +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[repr(u8)] +pub enum SignatureAlgorithm { + /// Anonymous signature algorithm + Anonymous = 0, + /// RSA signature algorithm + Rsa = 1, + /// DSA signature algorithm + Dsa = 2, + /// ECDSA signature algorithm + Ecdsa = 3, + /// ED25519 signature algorithm + Ed25519 = 7, + /// ED448 signature algorithm + Ed448 = 8, +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum HashAlgorithm { @@ -48,7 +65,7 @@ mod tests { use alloc::vec::Vec; use tls_codec::{DeserializeBytes, Error, Serialize, Size}; - use super::HashAlgorithm; + use super::{HashAlgorithm, SignatureAlgorithm}; #[test] fn test_hash_algorithm_deserialization() { @@ -96,6 +113,7 @@ mod tests { ); let _ = run_test(&result.unwrap().1, Err(Error::EndOfStream)); let _ = run_test(&[7], Err(Error::UnknownValue(7))); + let _ = run_test(&[9], Err(Error::UnknownValue(9))); } #[test] @@ -116,4 +134,64 @@ mod tests { run_test(HashAlgorithm::Sha512, 6); run_test(HashAlgorithm::Intrinsic, 8); } + + #[test] + fn test_signature_algorithm_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(SignatureAlgorithm, &[u8]), Error>, + ) -> Result<(SignatureAlgorithm, &'a [u8]), Error> { + let actual_result = SignatureAlgorithm::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + let bytes = [0, 1, 2, 3, 7, 8]; + + let result = run_test( + &bytes, + Ok((SignatureAlgorithm::Anonymous, [1, 2, 3, 7, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((SignatureAlgorithm::Rsa, [2, 3, 7, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((SignatureAlgorithm::Dsa, [3, 7, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((SignatureAlgorithm::Ecdsa, [7, 8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((SignatureAlgorithm::Ed25519, [8].as_slice())), + ); + let result = run_test( + &result.unwrap().1, + Ok((SignatureAlgorithm::Ed448, [].as_slice())), + ); + let _ = run_test(&result.unwrap().1, Err(Error::EndOfStream)); + let _ = run_test(&[4], Err(Error::UnknownValue(4))); + let _ = run_test(&[5], Err(Error::UnknownValue(5))); + let _ = run_test(&[6], Err(Error::UnknownValue(6))); + let _ = run_test(&[9], Err(Error::UnknownValue(9))); + } + + #[test] + fn test_signature_algorithm_serialization() { + fn run_test(signature_algorithm: SignatureAlgorithm, expected_int: u8) { + let mut buffer = Vec::with_capacity(signature_algorithm.tls_serialized_len()); + let result = signature_algorithm.tls_serialize(&mut buffer); + assert_eq!([expected_int], buffer[..1]); + assert_eq!(result, Ok(1)); + } + + run_test(SignatureAlgorithm::Anonymous, 0); + run_test(SignatureAlgorithm::Rsa, 1); + run_test(SignatureAlgorithm::Dsa, 2); + run_test(SignatureAlgorithm::Ecdsa, 3); + run_test(SignatureAlgorithm::Ed25519, 7); + run_test(SignatureAlgorithm::Ed448, 8); + } } From 191b78f3de22c43f832de36a6d56ba578441813f Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 13 Jun 2023 00:10:46 +0530 Subject: [PATCH 13/58] add SignatureAndHashAlgorithm struct --- x509-cert/src/ext/pkix/sct.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 64360f13c..76306a7d8 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,5 +1,8 @@ use const_oid::{db::rfc6962, AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString; +//TODO: Remove this explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms +//once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged +use std::format; use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize}; // TODO: Review what should be pub @@ -22,6 +25,12 @@ impl AssociatedOid for SctList { impl_newtype!(SctList, OctetString); impl_extension!(SctList, critical = false); +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +pub struct SignatureAndHashAlgorithm { + signature: SignatureAlgorithm, + hash: HashAlgorithm, +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum SignatureAlgorithm { From fb3960ef7336475d3dc285fdca34fa1d2e741028 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 13 Jun 2023 18:17:46 +0530 Subject: [PATCH 14/58] WIP --- Cargo.lock | 28 ++++++++++------------------ const-oid/Cargo.toml | 2 +- x509-cert/Cargo.toml | 11 ++++++----- x509-cert/src/ext/pkix.rs | 3 +-- x509-cert/src/ext/pkix/sct.rs | 14 ++++++++++++-- 5 files changed, 30 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8d09dfd5..68fecda6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,7 +244,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" name = "cmpv2" version = "0.2.0" dependencies = [ - "const-oid 0.9.2", + "const-oid", "crmf", "der", "hex-literal", @@ -256,7 +256,7 @@ dependencies = [ name = "cms" version = "0.2.1" dependencies = [ - "const-oid 0.9.2", + "const-oid", "der", "ecdsa", "hex-literal", @@ -275,15 +275,6 @@ dependencies = [ [[package]] name = "const-oid" version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" -dependencies = [ - "arbitrary", -] - -[[package]] -name = "const-oid" -version = "0.10.0-pre" dependencies = [ "arbitrary", "hex-literal", @@ -339,7 +330,7 @@ name = "crmf" version = "0.2.0" dependencies = [ "cms", - "const-oid 0.9.2", + "const-oid", "der", "spki", "x509-cert", @@ -415,7 +406,7 @@ name = "der" version = "0.7.7" dependencies = [ "arbitrary", - "const-oid 0.9.2", + "const-oid", "der_derive", "flagset", "hex-literal", @@ -462,7 +453,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid 0.9.2", + "const-oid", "crypto-common", "subtle", ] @@ -999,7 +990,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" name = "pkcs1" version = "0.7.5" dependencies = [ - "const-oid 0.9.2", + "const-oid", "der", "hex-literal", "pkcs8", @@ -1271,7 +1262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ "byteorder", - "const-oid 0.9.2", + "const-oid", "digest", "num-bigint-dig", "num-integer", @@ -1931,7 +1922,7 @@ name = "x509-cert" version = "0.2.3" dependencies = [ "arbitrary", - "const-oid 0.9.2", + "const-oid", "der", "ecdsa", "hex-literal", @@ -1944,6 +1935,7 @@ dependencies = [ "signature", "spki", "tempfile", + "tls_codec", "x509-cert-test-support", ] @@ -1960,7 +1952,7 @@ dependencies = [ name = "x509-ocsp" version = "0.2.0-pre" dependencies = [ - "const-oid 0.9.2", + "const-oid", "der", "hex-literal", "spki", diff --git a/const-oid/Cargo.toml b/const-oid/Cargo.toml index 8651739d8..0ce6f9514 100644 --- a/const-oid/Cargo.toml +++ b/const-oid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "const-oid" -version = "0.10.0-pre" +version = "0.9.2" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = """ diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 3f59ab711..3465379c1 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -23,8 +23,8 @@ spki = { version = "0.7.2", features = ["alloc"] } arbitrary = { version = "1.3", features = ["derive"], optional = true } sha1 = { version = "0.10.0", optional = true } signature = { version = "2.1.0", features = ["rand_core"], optional = true } -# tls_codec = { version = "0.3.0", features = ["derive"], optional = true } -tls_codec = { version = "0.3.0", features = ["derive"] } +tls_codec = { version = "0.3.0", features = ["derive"], optional = true } +# tls_codec = { version = "0.3.0", features = ["derive", "std"] } [dev-dependencies] hex-literal = "0.4" @@ -38,14 +38,15 @@ tempfile = "3.5.0" x509-cert-test-support = { path = "./test-support" } [features] -default = ["pem", "std"] -std = ["const-oid/std", "der/std", "spki/std"] +# default = ["pem", "std"] +default = ["pem", "std", "sct"] +std = ["const-oid/std", "der/std", "spki/std", "tls_codec?/std"] arbitrary = ["dep:arbitrary", "std", "der/arbitrary", "spki/arbitrary"] builder = ["std", "sha1/default", "signature"] hazmat = [] pem = ["der/pem", "spki/pem"] -# sct = ["dep:tls_codec"] +sct = ["dep:tls_codec"] [package.metadata.docs.rs] all-features = true diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index c39610fb7..51163d327 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -9,7 +9,6 @@ mod access; mod authkeyid; mod keyusage; mod policymap; -// #[cfg(feature = "sct")] mod sct; use crate::attr::AttributeTypeAndValue; @@ -26,7 +25,7 @@ pub use crl::{ pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod}; pub use policymap::{PolicyMapping, PolicyMappings}; -// #[cfg(feature = "sct")] +#[cfg(feature = "sct")] pub use sct::SctList; pub use const_oid::db::rfc5280::{ diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 76306a7d8..4d9c30be8 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,8 +1,10 @@ +#![cfg(feature = "sct")] use const_oid::{db::rfc6962, AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString; -//TODO: Remove this explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms +//TODO: Remove use::alloc::format explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms //once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged -use std::format; +// use std::format; +use alloc::{format, vec::Vec}; use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize}; // TODO: Review what should be pub @@ -25,6 +27,14 @@ impl AssociatedOid for SctList { impl_newtype!(SctList, OctetString); impl_extension!(SctList, critical = false); +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +pub struct DigitallySigned { + /// [SignatureAndHashAlgorithm] of the struct + pub algorithm: SignatureAndHashAlgorithm, + /// Signature of the struct + pub signature: Vec, +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignatureAndHashAlgorithm { signature: SignatureAlgorithm, From a72b1becf18e4f64dce91c39a3239722f016b4d4 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 13 Jun 2023 18:46:09 +0530 Subject: [PATCH 15/58] add more test --- x509-cert/src/ext/pkix/sct.rs | 39 +++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 4d9c30be8..67f545abc 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -37,8 +37,8 @@ pub struct DigitallySigned { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignatureAndHashAlgorithm { - signature: SignatureAlgorithm, hash: HashAlgorithm, + signature: SignatureAlgorithm, } #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] @@ -84,7 +84,7 @@ mod tests { use alloc::vec::Vec; use tls_codec::{DeserializeBytes, Error, Serialize, Size}; - use super::{HashAlgorithm, SignatureAlgorithm}; + use super::{HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm}; #[test] fn test_hash_algorithm_deserialization() { @@ -213,4 +213,39 @@ mod tests { run_test(SignatureAlgorithm::Ed25519, 7); run_test(SignatureAlgorithm::Ed448, 8); } + + #[test] + fn test_signature_and_hash_algorithm_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(SignatureAndHashAlgorithm, &[u8]), Error>, + ) -> Result<(SignatureAndHashAlgorithm, &'a [u8]), Error> { + let actual_result = SignatureAndHashAlgorithm::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + let bytes = [4, 3, 2, 1]; + + let result = run_test( + &bytes, + Ok(( + SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + [2, 1].as_slice(), + )), + ); + + let _ = run_test( + &result.unwrap().1, + Ok(( + SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha1, + signature: SignatureAlgorithm::Rsa, + }, + [].as_slice(), + )), + ); + } } From e5d18b15327a63c6c09a893ff885784bede63dfd Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 13 Jun 2023 18:51:02 +0530 Subject: [PATCH 16/58] add another test --- x509-cert/src/ext/pkix/sct.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 67f545abc..abb695f61 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -248,4 +248,18 @@ mod tests { )), ); } + + #[test] + fn test_signature_and_hash_algorithm_serialization() { + fn run_test(algorithm: SignatureAndHashAlgorithm, expected_hash_int: u8, expected_signature_int: u8) { + let mut buffer = Vec::with_capacity(algorithm.tls_serialized_len()); + let result = algorithm.tls_serialize(&mut buffer); + assert_eq!(expected_hash_int, buffer[0]); + assert_eq!(expected_signature_int, buffer[1]); + assert_eq!(result, Ok(2)); + } + + run_test(SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa }, 2, 1); + run_test(SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa }, 4, 3); + } } From 8cb976e9fca5a78144bdf0b1f003c187da4216b8 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 13 Jun 2023 20:22:33 +0530 Subject: [PATCH 17/58] add DigitallySigned deserialize test --- x509-cert/src/ext/pkix/sct.rs | 55 +++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index abb695f61..497ed3902 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -4,8 +4,8 @@ use der::asn1::OctetString; //TODO: Remove use::alloc::format explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms //once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged // use std::format; -use alloc::{format, vec::Vec}; -use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize}; +use alloc::format; +use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16}; // TODO: Review what should be pub // TODO: Update docs @@ -32,7 +32,7 @@ pub struct DigitallySigned { /// [SignatureAndHashAlgorithm] of the struct pub algorithm: SignatureAndHashAlgorithm, /// Signature of the struct - pub signature: Vec, + pub signature: TlsVecU16, } #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] @@ -82,9 +82,9 @@ pub enum HashAlgorithm { #[cfg(test)] mod tests { use alloc::vec::Vec; - use tls_codec::{DeserializeBytes, Error, Serialize, Size}; + use tls_codec::{DeserializeBytes, Error, Serialize, Size, TlsVecU16}; - use super::{HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm}; + use super::{HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, DigitallySigned}; #[test] fn test_hash_algorithm_deserialization() { @@ -262,4 +262,49 @@ mod tests { run_test(SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa }, 2, 1); run_test(SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa }, 4, 3); } + + #[test] + fn test_digitally_signed_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(DigitallySigned, &[u8]), Error>, + ) -> Result<(DigitallySigned, &'a [u8]), Error> { + let actual_result = DigitallySigned::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + let bytes = [4, 3, 0, 3, 2, 1, 0, 2, 1, 0, 1, 9]; + + let result = run_test( + &bytes, + Ok(( + DigitallySigned { + algorithm: + SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::::from_slice(&[2, 1, 0]) + }, + + [2, 1, 0, 1, 9].as_slice(), + )), + ); + + let _ = run_test( + &result.unwrap().1, + Ok(( + DigitallySigned { + algorithm: + SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha1, + signature: SignatureAlgorithm::Rsa, + }, + signature: TlsVecU16::::from_slice(&[9]) + }, + + [].as_slice(), + )), + ); + } } From a2d39e6306c86749b1efb6551eaff6889508a121 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 13 Jun 2023 20:33:49 +0530 Subject: [PATCH 18/58] add DigitallySigned serialization test --- x509-cert/src/ext/pkix/sct.rs | 69 +++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 12 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 497ed3902..f0162ea71 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -84,7 +84,7 @@ mod tests { use alloc::vec::Vec; use tls_codec::{DeserializeBytes, Error, Serialize, Size, TlsVecU16}; - use super::{HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, DigitallySigned}; + use super::{DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm}; #[test] fn test_hash_algorithm_deserialization() { @@ -251,7 +251,11 @@ mod tests { #[test] fn test_signature_and_hash_algorithm_serialization() { - fn run_test(algorithm: SignatureAndHashAlgorithm, expected_hash_int: u8, expected_signature_int: u8) { + fn run_test( + algorithm: SignatureAndHashAlgorithm, + expected_hash_int: u8, + expected_signature_int: u8, + ) { let mut buffer = Vec::with_capacity(algorithm.tls_serialized_len()); let result = algorithm.tls_serialize(&mut buffer); assert_eq!(expected_hash_int, buffer[0]); @@ -259,8 +263,22 @@ mod tests { assert_eq!(result, Ok(2)); } - run_test(SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa }, 2, 1); - run_test(SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa }, 4, 3); + run_test( + SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha1, + signature: SignatureAlgorithm::Rsa, + }, + 2, + 1, + ); + run_test( + SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + 4, + 3, + ); } #[test] @@ -279,14 +297,12 @@ mod tests { &bytes, Ok(( DigitallySigned { - algorithm: - SignatureAndHashAlgorithm { + algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::::from_slice(&[2, 1, 0]) + signature: TlsVecU16::::from_slice(&[2, 1, 0]), }, - [2, 1, 0, 1, 9].as_slice(), )), ); @@ -295,16 +311,45 @@ mod tests { &result.unwrap().1, Ok(( DigitallySigned { - algorithm: - SignatureAndHashAlgorithm { + algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa, }, - signature: TlsVecU16::::from_slice(&[9]) + signature: TlsVecU16::::from_slice(&[9]), }, - [].as_slice(), )), ); } + + #[test] + fn test_digitally_signed_serialization() { + fn run_test(digitally_signed: DigitallySigned, expected_bytes: &[u8]) { + let mut buffer = Vec::with_capacity(digitally_signed.tls_serialized_len()); + let result = digitally_signed.tls_serialize(&mut buffer); + assert_eq!(expected_bytes, &buffer); + assert_eq!(result, Ok(expected_bytes.len())); + } + + run_test( + DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::::from_slice(&[0, 1, 2]), + }, + &[4, 3, 0, 3, 0, 1, 2], + ); + run_test( + DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha1, + signature: SignatureAlgorithm::Rsa, + }, + signature: TlsVecU16::::from_slice(&[0, 1, 2]), + }, + &[2, 1, 0, 3, 0, 1, 2], + ); + } } From d8c3bbb7c160aef960aaf32129edbd3d2702291f Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 12:26:21 +0530 Subject: [PATCH 19/58] add version and its tests --- x509-cert/src/ext/pkix/sct.rs | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index f0162ea71..ecc6e6c41 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -27,6 +27,12 @@ impl AssociatedOid for SctList { impl_newtype!(SctList, OctetString); impl_extension!(SctList, critical = false); +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[repr(u8)] +pub enum Version { + V1 = 0, +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct DigitallySigned { /// [SignatureAndHashAlgorithm] of the struct @@ -84,7 +90,9 @@ mod tests { use alloc::vec::Vec; use tls_codec::{DeserializeBytes, Error, Serialize, Size, TlsVecU16}; - use super::{DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm}; + use super::{ + DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, Version, + }; #[test] fn test_hash_algorithm_deserialization() { @@ -352,4 +360,34 @@ mod tests { &[2, 1, 0, 3, 0, 1, 2], ); } + + #[test] + fn test_version_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(Version, &[u8]), Error>, + ) -> Result<(Version, &'a [u8]), Error> { + let actual_result = Version::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + let bytes = [0, 0]; + + let result = run_test(&bytes, Ok((Version::V1, [0].as_slice()))); + + let _ = run_test(&result.unwrap().1, Ok((Version::V1, [].as_slice()))); + let _ = run_test(&[1], Err(Error::UnknownValue(1))); + } + + #[test] + fn test_version_serialization() { + fn run_test(version: Version, expected_bytes: &[u8]) { + let mut buffer = Vec::with_capacity(version.tls_serialized_len()); + let result = version.tls_serialize(&mut buffer); + assert_eq!(expected_bytes, &buffer); + assert_eq!(result, Ok(expected_bytes.len())); + } + + run_test(Version::V1, &[0]); + } } From 95cd04b9a564aabf4b3222289e2b9f515b4fbe99 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 12:32:27 +0530 Subject: [PATCH 20/58] add LogId and tests --- x509-cert/src/ext/pkix/sct.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index ecc6e6c41..65ffea995 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -33,6 +33,11 @@ pub enum Version { V1 = 0, } +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +pub struct LogId { + key_id: [u8; 32], +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct DigitallySigned { /// [SignatureAndHashAlgorithm] of the struct @@ -90,6 +95,8 @@ mod tests { use alloc::vec::Vec; use tls_codec::{DeserializeBytes, Error, Serialize, Size, TlsVecU16}; + use crate::ext::pkix::sct::LogId; + use super::{ DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, Version, }; @@ -390,4 +397,31 @@ mod tests { run_test(Version::V1, &[0]); } + + #[test] + fn test_log_id_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(LogId, &[u8]), Error>, + ) -> Result<(LogId, &'a [u8]), Error> { + let actual_result = LogId::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + let bytes = [42; 36]; + + let _ = run_test(&bytes, Ok((LogId { key_id: [42; 32] }, [42; 4].as_slice()))); + } + + #[test] + fn test_log_id_serialization() { + fn run_test(log_id: LogId, expected_bytes: &[u8]) { + let mut buffer = Vec::with_capacity(log_id.tls_serialized_len()); + let result = log_id.tls_serialize(&mut buffer); + assert_eq!(expected_bytes, &buffer); + assert_eq!(result, Ok(expected_bytes.len())); + } + + run_test(LogId { key_id: [3; 32] }, &[3; 32]); + } } From 40e80895696cceedc4f5f9b93fc48188e4cc5a79 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 13:16:15 +0530 Subject: [PATCH 21/58] add SignedCertificateTimestamp --- x509-cert/src/ext/pkix/sct.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 65ffea995..7cb8ac723 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -27,6 +27,15 @@ impl AssociatedOid for SctList { impl_newtype!(SctList, OctetString); impl_extension!(SctList, critical = false); +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +pub struct SignedCertificateTimestamp { + version: Version, + log_id: LogId, + timestamp: u64, + extensions: TlsVecU16, + sign: DigitallySigned, +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum Version { From 86f43e61d44d51381b95b3652907ea7dbb14c1a3 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 14:02:06 +0530 Subject: [PATCH 22/58] add SignedCertificateTimestamp tests --- x509-cert/src/ext/pkix/sct.rs | 76 ++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 7cb8ac723..261ea17f9 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,4 +1,5 @@ #![cfg(feature = "sct")] + use const_oid::{db::rfc6962, AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString; //TODO: Remove use::alloc::format explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms @@ -107,7 +108,8 @@ mod tests { use crate::ext::pkix::sct::LogId; use super::{ - DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, Version, + DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, + SignedCertificateTimestamp, Version, }; #[test] @@ -433,4 +435,76 @@ mod tests { run_test(LogId { key_id: [3; 32] }, &[3; 32]); } + + const SCT_EXAMPLE: [u8; 119] = [ + 0, 122, 50, 140, 84, 216, 183, 45, 182, 32, 234, 56, 224, 82, 30, 233, 132, 22, 112, 50, + 19, 133, 77, 59, 210, 43, 193, 58, 87, 163, 82, 235, 82, 0, 0, 1, 135, 224, 74, 186, 106, + 0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 170, 82, 81, 162, 157, 234, 14, 189, 167, 13, 247, + 211, 97, 112, 248, 172, 149, 125, 58, 18, 238, 60, 150, 157, 124, 245, 188, 138, 102, 212, + 244, 187, 2, 33, 0, 209, 79, 31, 63, 208, 79, 240, 233, 193, 187, 28, 33, 190, 95, 130, 66, + 183, 222, 187, 42, 22, 83, 0, 119, 226, 246, 19, 197, 47, 237, 198, 149, + ]; + + #[test] + fn test_sct_deserialization() { + fn run_test<'a>( + bytes: &'a [u8], + expected_result: Result<(SignedCertificateTimestamp, &[u8]), Error>, + ) -> Result<(SignedCertificateTimestamp, &'a [u8]), Error> { + let actual_result = SignedCertificateTimestamp::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + + let _ = run_test( + &SCT_EXAMPLE, + Ok(( + SignedCertificateTimestamp { + version: Version::V1, + log_id: LogId { + key_id: SCT_EXAMPLE[1..33].try_into().unwrap(), + }, + timestamp: u64::from_be_bytes(SCT_EXAMPLE[33..41].try_into().unwrap()), + extensions: TlsVecU16::from_slice(&[]), + sign: DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::from_slice(&SCT_EXAMPLE[47..]), + }, + }, + &[], + )), + ); + } + + #[test] + fn test_sct_serialization() { + fn run_test(sct: SignedCertificateTimestamp, expected_bytes: &[u8]) { + let mut buffer = Vec::with_capacity(sct.tls_serialized_len()); + let result = sct.tls_serialize(&mut buffer); + assert_eq!(expected_bytes, &buffer); + assert_eq!(result, Ok(expected_bytes.len())); + } + + run_test( + SignedCertificateTimestamp { + version: Version::V1, + log_id: LogId { + key_id: SCT_EXAMPLE[1..33].try_into().unwrap(), + }, + timestamp: u64::from_be_bytes(SCT_EXAMPLE[33..41].try_into().unwrap()), + extensions: TlsVecU16::from_slice(&[]), + sign: DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::from_slice(&SCT_EXAMPLE[47..]), + }, + }, + &SCT_EXAMPLE, + ); + } } From f39230587f615f821760d88c319c19311084576a Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 14:05:02 +0530 Subject: [PATCH 23/58] rename SctList to SignedCertificateTimestampList --- x509-cert/src/ext/pkix.rs | 2 +- x509-cert/src/ext/pkix/sct.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index 51163d327..fbf3dd2d7 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -26,7 +26,7 @@ pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod} pub use policymap::{PolicyMapping, PolicyMappings}; #[cfg(feature = "sct")] -pub use sct::SctList; +pub use sct::SignedCertificateTimestampList; pub use const_oid::db::rfc5280::{ ID_CE_INHIBIT_ANY_POLICY, ID_CE_ISSUER_ALT_NAME, ID_CE_SUBJECT_ALT_NAME, diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 261ea17f9..9095936e3 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -19,14 +19,14 @@ use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16}; // pub const CT_PRECERT_SCTS: ObjectIdentifier = // ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); -pub struct SctList(OctetString); +pub struct SignedCertificateTimestampList(OctetString); -impl AssociatedOid for SctList { +impl AssociatedOid for SignedCertificateTimestampList { const OID: ObjectIdentifier = rfc6962::CT_PRECERT_SCTS; } -impl_newtype!(SctList, OctetString); -impl_extension!(SctList, critical = false); +impl_newtype!(SignedCertificateTimestampList, OctetString); +impl_extension!(SignedCertificateTimestampList, critical = false); #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignedCertificateTimestamp { From a52c4f635073497df582088a601b45073c022b56 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 17:11:12 +0530 Subject: [PATCH 24/58] add SignedCertificateTimestampList as tests --- x509-cert/src/ext/pkix/sct.rs | 197 ++++++++++++++++++++++++++++------ 1 file changed, 162 insertions(+), 35 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 9095936e3..58c53159f 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -5,8 +5,8 @@ use der::asn1::OctetString; //TODO: Remove use::alloc::format explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms //once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged // use std::format; -use alloc::format; -use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16}; +use alloc::{format, vec::Vec}; +use tls_codec::{DeserializeBytes, TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16}; // TODO: Review what should be pub // TODO: Update docs @@ -19,6 +19,7 @@ use tls_codec::{TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16}; // pub const CT_PRECERT_SCTS: ObjectIdentifier = // ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); +#[derive(Debug, PartialEq)] pub struct SignedCertificateTimestampList(OctetString); impl AssociatedOid for SignedCertificateTimestampList { @@ -28,6 +29,57 @@ impl AssociatedOid for SignedCertificateTimestampList { impl_newtype!(SignedCertificateTimestampList, OctetString); impl_extension!(SignedCertificateTimestampList, critical = false); +#[derive(PartialEq, Debug)] +pub enum Error { + Der(der::Error), + Tls(tls_codec::Error), +} + +impl From for Error { + fn from(value: der::Error) -> Self { + Error::Der(value) + } +} + +impl From for Error { + fn from(value: tls_codec::Error) -> Self { + Error::Tls(value) + } +} + +impl SignedCertificateTimestampList { + /// Parses the encoded [SerializedSct]s and returns a Vec containing them + pub fn serialized_signed_certificate_timestamps(&self) -> Result, Error> { + let (tls_vec, rest) = TlsVecU16::::tls_deserialize(self.0.as_bytes())?; + if !rest.is_empty() { + return Err(tls_codec::Error::TrailingData)?; + } + let mut bytes = tls_vec.as_slice(); + let mut result = Vec::new(); + while !bytes.is_empty() { + let (serialized_sct, rest) = SerializedSct::tls_deserialize(&bytes)?; + result.push(serialized_sct); + bytes = rest; + } + Ok(result) + } +} + +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +pub struct SerializedSct { + data: TlsVecU16, +} + +impl SerializedSct { + pub fn signed_certificate_timestamp(&self) -> Result { + let (sct, rest) = SignedCertificateTimestamp::tls_deserialize(self.data.as_slice())?; + if !rest.is_empty() { + return Err(tls_codec::Error::TrailingData)?; + } + Ok(sct) + } +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignedCertificateTimestamp { version: Version, @@ -103,21 +155,22 @@ pub enum HashAlgorithm { #[cfg(test)] mod tests { use alloc::vec::Vec; - use tls_codec::{DeserializeBytes, Error, Serialize, Size, TlsVecU16}; + use der::{asn1::OctetString, Decode}; + use tls_codec::{DeserializeBytes, Serialize, Size, TlsVecU16}; use crate::ext::pkix::sct::LogId; use super::{ DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, - SignedCertificateTimestamp, Version, + SignedCertificateTimestamp, SignedCertificateTimestampList, Version, }; #[test] fn test_hash_algorithm_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(HashAlgorithm, &[u8]), Error>, - ) -> Result<(HashAlgorithm, &'a [u8]), Error> { + expected_result: Result<(HashAlgorithm, &[u8]), tls_codec::Error>, + ) -> Result<(HashAlgorithm, &'a [u8]), tls_codec::Error> { let actual_result = HashAlgorithm::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result @@ -156,9 +209,9 @@ mod tests { &result.unwrap().1, Ok((HashAlgorithm::Intrinsic, [].as_slice())), ); - let _ = run_test(&result.unwrap().1, Err(Error::EndOfStream)); - let _ = run_test(&[7], Err(Error::UnknownValue(7))); - let _ = run_test(&[9], Err(Error::UnknownValue(9))); + let _ = run_test(&result.unwrap().1, Err(tls_codec::Error::EndOfStream)); + let _ = run_test(&[7], Err(tls_codec::Error::UnknownValue(7))); + let _ = run_test(&[9], Err(tls_codec::Error::UnknownValue(9))); } #[test] @@ -184,8 +237,8 @@ mod tests { fn test_signature_algorithm_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(SignatureAlgorithm, &[u8]), Error>, - ) -> Result<(SignatureAlgorithm, &'a [u8]), Error> { + expected_result: Result<(SignatureAlgorithm, &[u8]), tls_codec::Error>, + ) -> Result<(SignatureAlgorithm, &'a [u8]), tls_codec::Error> { let actual_result = SignatureAlgorithm::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result @@ -216,11 +269,11 @@ mod tests { &result.unwrap().1, Ok((SignatureAlgorithm::Ed448, [].as_slice())), ); - let _ = run_test(&result.unwrap().1, Err(Error::EndOfStream)); - let _ = run_test(&[4], Err(Error::UnknownValue(4))); - let _ = run_test(&[5], Err(Error::UnknownValue(5))); - let _ = run_test(&[6], Err(Error::UnknownValue(6))); - let _ = run_test(&[9], Err(Error::UnknownValue(9))); + let _ = run_test(&result.unwrap().1, Err(tls_codec::Error::EndOfStream)); + let _ = run_test(&[4], Err(tls_codec::Error::UnknownValue(4))); + let _ = run_test(&[5], Err(tls_codec::Error::UnknownValue(5))); + let _ = run_test(&[6], Err(tls_codec::Error::UnknownValue(6))); + let _ = run_test(&[9], Err(tls_codec::Error::UnknownValue(9))); } #[test] @@ -244,8 +297,8 @@ mod tests { fn test_signature_and_hash_algorithm_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(SignatureAndHashAlgorithm, &[u8]), Error>, - ) -> Result<(SignatureAndHashAlgorithm, &'a [u8]), Error> { + expected_result: Result<(SignatureAndHashAlgorithm, &[u8]), tls_codec::Error>, + ) -> Result<(SignatureAndHashAlgorithm, &'a [u8]), tls_codec::Error> { let actual_result = SignatureAndHashAlgorithm::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result @@ -311,8 +364,8 @@ mod tests { fn test_digitally_signed_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(DigitallySigned, &[u8]), Error>, - ) -> Result<(DigitallySigned, &'a [u8]), Error> { + expected_result: Result<(DigitallySigned, &[u8]), tls_codec::Error>, + ) -> Result<(DigitallySigned, &'a [u8]), tls_codec::Error> { let actual_result = DigitallySigned::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result @@ -383,8 +436,8 @@ mod tests { fn test_version_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(Version, &[u8]), Error>, - ) -> Result<(Version, &'a [u8]), Error> { + expected_result: Result<(Version, &[u8]), tls_codec::Error>, + ) -> Result<(Version, &'a [u8]), tls_codec::Error> { let actual_result = Version::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result @@ -394,7 +447,7 @@ mod tests { let result = run_test(&bytes, Ok((Version::V1, [0].as_slice()))); let _ = run_test(&result.unwrap().1, Ok((Version::V1, [].as_slice()))); - let _ = run_test(&[1], Err(Error::UnknownValue(1))); + let _ = run_test(&[1], Err(tls_codec::Error::UnknownValue(1))); } #[test] @@ -413,8 +466,8 @@ mod tests { fn test_log_id_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(LogId, &[u8]), Error>, - ) -> Result<(LogId, &'a [u8]), Error> { + expected_result: Result<(LogId, &[u8]), tls_codec::Error>, + ) -> Result<(LogId, &'a [u8]), tls_codec::Error> { let actual_result = LogId::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result @@ -436,7 +489,7 @@ mod tests { run_test(LogId { key_id: [3; 32] }, &[3; 32]); } - const SCT_EXAMPLE: [u8; 119] = [ + const TLS_SCT_EXAMPLE: [u8; 119] = [ 0, 122, 50, 140, 84, 216, 183, 45, 182, 32, 234, 56, 224, 82, 30, 233, 132, 22, 112, 50, 19, 133, 77, 59, 210, 43, 193, 58, 87, 163, 82, 235, 82, 0, 0, 1, 135, 224, 74, 186, 106, 0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 170, 82, 81, 162, 157, 234, 14, 189, 167, 13, 247, @@ -449,29 +502,29 @@ mod tests { fn test_sct_deserialization() { fn run_test<'a>( bytes: &'a [u8], - expected_result: Result<(SignedCertificateTimestamp, &[u8]), Error>, - ) -> Result<(SignedCertificateTimestamp, &'a [u8]), Error> { + expected_result: Result<(SignedCertificateTimestamp, &[u8]), tls_codec::Error>, + ) -> Result<(SignedCertificateTimestamp, &'a [u8]), tls_codec::Error> { let actual_result = SignedCertificateTimestamp::tls_deserialize(&bytes); assert_eq!(actual_result, expected_result); actual_result } let _ = run_test( - &SCT_EXAMPLE, + &TLS_SCT_EXAMPLE, Ok(( SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: SCT_EXAMPLE[1..33].try_into().unwrap(), + key_id: TLS_SCT_EXAMPLE[1..33].try_into().unwrap(), }, - timestamp: u64::from_be_bytes(SCT_EXAMPLE[33..41].try_into().unwrap()), + timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), sign: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&SCT_EXAMPLE[47..]), + signature: TlsVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]), }, }, &[], @@ -492,19 +545,93 @@ mod tests { SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: SCT_EXAMPLE[1..33].try_into().unwrap(), + key_id: TLS_SCT_EXAMPLE[1..33].try_into().unwrap(), }, - timestamp: u64::from_be_bytes(SCT_EXAMPLE[33..41].try_into().unwrap()), + timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), sign: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&SCT_EXAMPLE[47..]), + signature: TlsVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]), }, }, + &TLS_SCT_EXAMPLE, + ); + } + + const SCT_EXAMPLE: [u8; 245] = [ + 4, 129, 242, 0, 240, 0, 119, 0, 122, 50, 140, 84, 216, 183, 45, 182, 32, 234, 56, 224, 82, + 30, 233, 132, 22, 112, 50, 19, 133, 77, 59, 210, 43, 193, 58, 87, 163, 82, 235, 82, 0, 0, + 1, 135, 224, 74, 186, 106, 0, 0, 4, 3, 0, 72, 48, 70, 2, 33, 0, 170, 82, 81, 162, 157, 234, + 14, 189, 167, 13, 247, 211, 97, 112, 248, 172, 149, 125, 58, 18, 238, 60, 150, 157, 124, + 245, 188, 138, 102, 212, 244, 187, 2, 33, 0, 209, 79, 31, 63, 208, 79, 240, 233, 193, 187, + 28, 33, 190, 95, 130, 66, 183, 222, 187, 42, 22, 83, 0, 119, 226, 246, 19, 197, 47, 237, + 198, 149, 0, 117, 0, 173, 247, 190, 250, 124, 255, 16, 200, 139, 157, 61, 156, 30, 62, 24, + 106, 180, 103, 41, 93, 207, 177, 12, 36, 202, 133, 134, 52, 235, 220, 130, 138, 0, 0, 1, + 135, 224, 74, 186, 164, 0, 0, 4, 3, 0, 70, 48, 68, 2, 32, 29, 110, 144, 37, 157, 227, 170, + 70, 67, 16, 68, 195, 212, 168, 246, 37, 94, 69, 210, 136, 42, 113, 217, 230, 34, 152, 253, + 116, 13, 174, 232, 191, 2, 32, 16, 25, 200, 223, 59, 176, 40, 145, 76, 85, 242, 133, 130, + 212, 61, 216, 83, 238, 115, 130, 82, 240, 196, 162, 249, 54, 199, 120, 175, 72, 223, 14, + ]; + + #[test] + fn test_sct_list_deserialization() { + fn run_test( + bytes: &[u8], + expected_result: Result, + ) -> Result { + let actual_result = SignedCertificateTimestampList::from_der(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + + let result = run_test( &SCT_EXAMPLE, + Ok(SignedCertificateTimestampList( + OctetString::new(&SCT_EXAMPLE[3..]).unwrap(), + )), + ); + let scts = result + .unwrap() + .serialized_signed_certificate_timestamps() + .unwrap(); + assert_eq!( + scts[0].signed_certificate_timestamp(), + Ok(SignedCertificateTimestamp { + version: Version::V1, + log_id: LogId { + key_id: SCT_EXAMPLE[8..40].try_into().unwrap(), + }, + timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), + extensions: TlsVecU16::from_slice(&[]), + sign: DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::from_slice(&SCT_EXAMPLE[54..126]), + }, + }) + ); + assert_eq!( + scts[1].signed_certificate_timestamp(), + Ok(SignedCertificateTimestamp { + version: Version::V1, + log_id: LogId { + key_id: SCT_EXAMPLE[129..161].try_into().unwrap(), + }, + timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), + extensions: TlsVecU16::from_slice(&[]), + sign: DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::from_slice(&SCT_EXAMPLE[175..]), + }, + }) ); } } From 9d4d95c56c9ca0b748ca4e01805522c3df8b3a69 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 18:36:28 +0530 Subject: [PATCH 25/58] add SignedCertificateTimestampList serialization and tests --- x509-cert/src/ext/pkix/sct.rs | 89 ++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 58c53159f..d44d05193 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -6,7 +6,9 @@ use der::asn1::OctetString; //once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged // use std::format; use alloc::{format, vec::Vec}; -use tls_codec::{DeserializeBytes, TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16}; +use tls_codec::{ + DeserializeBytes, Serialize, Size, TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16, +}; // TODO: Review what should be pub // TODO: Update docs @@ -48,8 +50,24 @@ impl From for Error { } impl SignedCertificateTimestampList { + /// Creates a new [SignedCertificateTimestamp] from a slice of [SerializedSct]s + pub fn new(serialized_scts: &[SerializedSct]) -> Result { + let mut result: Vec = Vec::new(); + for timestamp in serialized_scts { + let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); + let bytes_written = timestamp.tls_serialize(&mut buffer)?; + assert!(bytes_written == timestamp.tls_serialized_len()); + result.extend(buffer); + } + let tls_vec = TlsVecU16::::new(result); + let mut buffer: Vec = Vec::with_capacity(tls_vec.tls_serialized_len()); + let bytes_written = tls_vec.tls_serialize(&mut buffer)?; + assert!(bytes_written == tls_vec.tls_serialized_len()); + Ok(SignedCertificateTimestampList(OctetString::new(buffer)?)) + } + /// Parses the encoded [SerializedSct]s and returns a Vec containing them - pub fn serialized_signed_certificate_timestamps(&self) -> Result, Error> { + pub fn parse_timestamps(&self) -> Result, Error> { let (tls_vec, rest) = TlsVecU16::::tls_deserialize(self.0.as_bytes())?; if !rest.is_empty() { return Err(tls_codec::Error::TrailingData)?; @@ -71,7 +89,16 @@ pub struct SerializedSct { } impl SerializedSct { - pub fn signed_certificate_timestamp(&self) -> Result { + pub fn new(timestamp: SignedCertificateTimestamp) -> Result { + let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); + let bytes_written = timestamp.tls_serialize(&mut buffer)?; + assert!(bytes_written == timestamp.tls_serialized_len()); + Ok(SerializedSct { + data: TlsVecU16::from_slice(&buffer), + }) + } + + pub fn parse_timestamp(&self) -> Result { let (sct, rest) = SignedCertificateTimestamp::tls_deserialize(self.data.as_slice())?; if !rest.is_empty() { return Err(tls_codec::Error::TrailingData)?; @@ -155,14 +182,15 @@ pub enum HashAlgorithm { #[cfg(test)] mod tests { use alloc::vec::Vec; - use der::{asn1::OctetString, Decode}; + use der::{asn1::OctetString, Decode, Encode}; use tls_codec::{DeserializeBytes, Serialize, Size, TlsVecU16}; use crate::ext::pkix::sct::LogId; use super::{ - DigitallySigned, HashAlgorithm, SignatureAlgorithm, SignatureAndHashAlgorithm, - SignedCertificateTimestamp, SignedCertificateTimestampList, Version, + DigitallySigned, HashAlgorithm, SerializedSct, SignatureAlgorithm, + SignatureAndHashAlgorithm, SignedCertificateTimestamp, SignedCertificateTimestampList, + Version, }; #[test] @@ -593,12 +621,9 @@ mod tests { OctetString::new(&SCT_EXAMPLE[3..]).unwrap(), )), ); - let scts = result - .unwrap() - .serialized_signed_certificate_timestamps() - .unwrap(); + let scts = result.unwrap().parse_timestamps().unwrap(); assert_eq!( - scts[0].signed_certificate_timestamp(), + scts[0].parse_timestamp(), Ok(SignedCertificateTimestamp { version: Version::V1, log_id: LogId { @@ -616,7 +641,7 @@ mod tests { }) ); assert_eq!( - scts[1].signed_certificate_timestamp(), + scts[1].parse_timestamp(), Ok(SignedCertificateTimestamp { version: Version::V1, log_id: LogId { @@ -634,4 +659,44 @@ mod tests { }) ); } + + #[test] + fn test_sct_list_serialization() { + let serialized_sct1 = SerializedSct::new(SignedCertificateTimestamp { + version: Version::V1, + log_id: LogId { + key_id: SCT_EXAMPLE[8..40].try_into().unwrap(), + }, + timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), + extensions: TlsVecU16::from_slice(&[]), + sign: DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::from_slice(&SCT_EXAMPLE[54..126]), + }, + }) + .unwrap(); + let serialized_sct2 = SerializedSct::new(SignedCertificateTimestamp { + version: Version::V1, + log_id: LogId { + key_id: SCT_EXAMPLE[129..161].try_into().unwrap(), + }, + timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), + extensions: TlsVecU16::from_slice(&[]), + sign: DigitallySigned { + algorithm: SignatureAndHashAlgorithm { + hash: HashAlgorithm::Sha256, + signature: SignatureAlgorithm::Ecdsa, + }, + signature: TlsVecU16::from_slice(&SCT_EXAMPLE[175..]), + }, + }) + .unwrap(); + let list = + SignedCertificateTimestampList::new(&[serialized_sct1, serialized_sct2]).unwrap(); + let der = list.to_der().unwrap(); + assert_eq!(der.as_slice(), SCT_EXAMPLE.as_slice()); + } } From 195f26e6eb937dceb2eaae212190ad14d33b6fb1 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 18:58:54 +0530 Subject: [PATCH 26/58] remove duplicate code in tests --- x509-cert/src/ext/pkix/sct.rs | 149 ++++++++++++++-------------------- 1 file changed, 61 insertions(+), 88 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index d44d05193..be2db5de3 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -193,53 +193,59 @@ mod tests { Version, }; + fn 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> { + let actual_result = T::tls_deserialize(&bytes); + assert_eq!(actual_result, expected_result); + actual_result + } + #[test] fn test_hash_algorithm_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(HashAlgorithm, &[u8]), tls_codec::Error>, - ) -> Result<(HashAlgorithm, &'a [u8]), tls_codec::Error> { - let actual_result = HashAlgorithm::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } let bytes = [0, 1, 2, 3, 4, 5, 6, 8]; - let result = run_test( + let result = run_deserialization_test( &bytes, Ok((HashAlgorithm::None, [1, 2, 3, 4, 5, 6, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Md5, [2, 3, 4, 5, 6, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Sha1, [3, 4, 5, 6, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Sha224, [4, 5, 6, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Sha256, [5, 6, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Sha384, [6, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Sha512, [8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((HashAlgorithm::Intrinsic, [].as_slice())), ); - let _ = run_test(&result.unwrap().1, Err(tls_codec::Error::EndOfStream)); - let _ = run_test(&[7], Err(tls_codec::Error::UnknownValue(7))); - let _ = run_test(&[9], Err(tls_codec::Error::UnknownValue(9))); + let _ = run_deserialization_test::( + &result.unwrap().1, + Err(tls_codec::Error::EndOfStream), + ); + let _ = + run_deserialization_test::(&[7], Err(tls_codec::Error::UnknownValue(7))); + let _ = + run_deserialization_test::(&[9], Err(tls_codec::Error::UnknownValue(9))); } #[test] @@ -263,45 +269,52 @@ mod tests { #[test] fn test_signature_algorithm_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(SignatureAlgorithm, &[u8]), tls_codec::Error>, - ) -> Result<(SignatureAlgorithm, &'a [u8]), tls_codec::Error> { - let actual_result = SignatureAlgorithm::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } let bytes = [0, 1, 2, 3, 7, 8]; - let result = run_test( + let result = run_deserialization_test( &bytes, Ok((SignatureAlgorithm::Anonymous, [1, 2, 3, 7, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((SignatureAlgorithm::Rsa, [2, 3, 7, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((SignatureAlgorithm::Dsa, [3, 7, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((SignatureAlgorithm::Ecdsa, [7, 8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((SignatureAlgorithm::Ed25519, [8].as_slice())), ); - let result = run_test( + let result = run_deserialization_test( &result.unwrap().1, Ok((SignatureAlgorithm::Ed448, [].as_slice())), ); - let _ = run_test(&result.unwrap().1, Err(tls_codec::Error::EndOfStream)); - let _ = run_test(&[4], Err(tls_codec::Error::UnknownValue(4))); - let _ = run_test(&[5], Err(tls_codec::Error::UnknownValue(5))); - let _ = run_test(&[6], Err(tls_codec::Error::UnknownValue(6))); - let _ = run_test(&[9], Err(tls_codec::Error::UnknownValue(9))); + let _ = run_deserialization_test::( + &result.unwrap().1, + Err(tls_codec::Error::EndOfStream), + ); + let _ = run_deserialization_test::( + &[4], + Err(tls_codec::Error::UnknownValue(4)), + ); + let _ = run_deserialization_test::( + &[5], + Err(tls_codec::Error::UnknownValue(5)), + ); + let _ = run_deserialization_test::( + &[6], + Err(tls_codec::Error::UnknownValue(6)), + ); + let _ = run_deserialization_test::( + &[9], + Err(tls_codec::Error::UnknownValue(9)), + ); } #[test] @@ -323,17 +336,9 @@ mod tests { #[test] fn test_signature_and_hash_algorithm_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(SignatureAndHashAlgorithm, &[u8]), tls_codec::Error>, - ) -> Result<(SignatureAndHashAlgorithm, &'a [u8]), tls_codec::Error> { - let actual_result = SignatureAndHashAlgorithm::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } let bytes = [4, 3, 2, 1]; - let result = run_test( + let result = run_deserialization_test( &bytes, Ok(( SignatureAndHashAlgorithm { @@ -344,7 +349,7 @@ mod tests { )), ); - let _ = run_test( + let _ = run_deserialization_test( &result.unwrap().1, Ok(( SignatureAndHashAlgorithm { @@ -390,17 +395,9 @@ mod tests { #[test] fn test_digitally_signed_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(DigitallySigned, &[u8]), tls_codec::Error>, - ) -> Result<(DigitallySigned, &'a [u8]), tls_codec::Error> { - let actual_result = DigitallySigned::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } let bytes = [4, 3, 0, 3, 2, 1, 0, 2, 1, 0, 1, 9]; - let result = run_test( + let result = run_deserialization_test( &bytes, Ok(( DigitallySigned { @@ -414,7 +411,7 @@ mod tests { )), ); - let _ = run_test( + let _ = run_deserialization_test( &result.unwrap().1, Ok(( DigitallySigned { @@ -462,20 +459,12 @@ mod tests { #[test] fn test_version_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(Version, &[u8]), tls_codec::Error>, - ) -> Result<(Version, &'a [u8]), tls_codec::Error> { - let actual_result = Version::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } let bytes = [0, 0]; - let result = run_test(&bytes, Ok((Version::V1, [0].as_slice()))); + let result = run_deserialization_test(&bytes, Ok((Version::V1, [0].as_slice()))); - let _ = run_test(&result.unwrap().1, Ok((Version::V1, [].as_slice()))); - let _ = run_test(&[1], Err(tls_codec::Error::UnknownValue(1))); + let _ = run_deserialization_test(&result.unwrap().1, Ok((Version::V1, [].as_slice()))); + let _ = run_deserialization_test::(&[1], Err(tls_codec::Error::UnknownValue(1))); } #[test] @@ -492,17 +481,10 @@ mod tests { #[test] fn test_log_id_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(LogId, &[u8]), tls_codec::Error>, - ) -> Result<(LogId, &'a [u8]), tls_codec::Error> { - let actual_result = LogId::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } let bytes = [42; 36]; - let _ = run_test(&bytes, Ok((LogId { key_id: [42; 32] }, [42; 4].as_slice()))); + let _ = + run_deserialization_test(&bytes, Ok((LogId { key_id: [42; 32] }, [42; 4].as_slice()))); } #[test] @@ -528,16 +510,7 @@ mod tests { #[test] fn test_sct_deserialization() { - fn run_test<'a>( - bytes: &'a [u8], - expected_result: Result<(SignedCertificateTimestamp, &[u8]), tls_codec::Error>, - ) -> Result<(SignedCertificateTimestamp, &'a [u8]), tls_codec::Error> { - let actual_result = SignedCertificateTimestamp::tls_deserialize(&bytes); - assert_eq!(actual_result, expected_result); - actual_result - } - - let _ = run_test( + let _ = run_deserialization_test( &TLS_SCT_EXAMPLE, Ok(( SignedCertificateTimestamp { From a4705e4631c27c64c2d79661c1cc1be855b7c64c Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 19:10:32 +0530 Subject: [PATCH 27/58] remove more duplicate code in tests --- x509-cert/src/ext/pkix/sct.rs | 111 ++++++++++------------------------ 1 file changed, 31 insertions(+), 80 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index be2db5de3..cc8092d71 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -183,7 +183,7 @@ pub enum HashAlgorithm { mod tests { use alloc::vec::Vec; use der::{asn1::OctetString, Decode, Encode}; - use tls_codec::{DeserializeBytes, Serialize, Size, TlsVecU16}; + use tls_codec::{DeserializeBytes, Serialize, TlsVecU16}; use crate::ext::pkix::sct::LogId; @@ -202,6 +202,13 @@ mod tests { actual_result } + fn run_serialization_test(value: T, expected_bytes: &[u8]) { + let mut buffer = Vec::with_capacity(value.tls_serialized_len()); + let result = value.tls_serialize(&mut buffer); + assert_eq!(expected_bytes, &buffer); + assert_eq!(result, Ok(expected_bytes.len())); + } + #[test] fn test_hash_algorithm_deserialization() { let bytes = [0, 1, 2, 3, 4, 5, 6, 8]; @@ -250,21 +257,14 @@ mod tests { #[test] fn test_hash_algorithm_serialization() { - fn run_test(hash_algorithm: HashAlgorithm, expected_int: u8) { - let mut buffer = Vec::with_capacity(hash_algorithm.tls_serialized_len()); - let result = hash_algorithm.tls_serialize(&mut buffer); - assert_eq!([expected_int], buffer[..1]); - assert_eq!(result, Ok(1)); - } - - run_test(HashAlgorithm::None, 0); - run_test(HashAlgorithm::Md5, 1); - run_test(HashAlgorithm::Sha1, 2); - run_test(HashAlgorithm::Sha224, 3); - run_test(HashAlgorithm::Sha256, 4); - run_test(HashAlgorithm::Sha384, 5); - run_test(HashAlgorithm::Sha512, 6); - run_test(HashAlgorithm::Intrinsic, 8); + run_serialization_test(HashAlgorithm::None, &[0]); + run_serialization_test(HashAlgorithm::Md5, &[1]); + run_serialization_test(HashAlgorithm::Sha1, &[2]); + run_serialization_test(HashAlgorithm::Sha224, &[3]); + run_serialization_test(HashAlgorithm::Sha256, &[4]); + run_serialization_test(HashAlgorithm::Sha384, &[5]); + run_serialization_test(HashAlgorithm::Sha512, &[6]); + run_serialization_test(HashAlgorithm::Intrinsic, &[8]); } #[test] @@ -319,19 +319,12 @@ mod tests { #[test] fn test_signature_algorithm_serialization() { - fn run_test(signature_algorithm: SignatureAlgorithm, expected_int: u8) { - let mut buffer = Vec::with_capacity(signature_algorithm.tls_serialized_len()); - let result = signature_algorithm.tls_serialize(&mut buffer); - assert_eq!([expected_int], buffer[..1]); - assert_eq!(result, Ok(1)); - } - - run_test(SignatureAlgorithm::Anonymous, 0); - run_test(SignatureAlgorithm::Rsa, 1); - run_test(SignatureAlgorithm::Dsa, 2); - run_test(SignatureAlgorithm::Ecdsa, 3); - run_test(SignatureAlgorithm::Ed25519, 7); - run_test(SignatureAlgorithm::Ed448, 8); + run_serialization_test(SignatureAlgorithm::Anonymous, &[0]); + run_serialization_test(SignatureAlgorithm::Rsa, &[1]); + run_serialization_test(SignatureAlgorithm::Dsa, &[2]); + run_serialization_test(SignatureAlgorithm::Ecdsa, &[3]); + run_serialization_test(SignatureAlgorithm::Ed25519, &[7]); + run_serialization_test(SignatureAlgorithm::Ed448, &[8]); } #[test] @@ -363,33 +356,19 @@ mod tests { #[test] fn test_signature_and_hash_algorithm_serialization() { - fn run_test( - algorithm: SignatureAndHashAlgorithm, - expected_hash_int: u8, - expected_signature_int: u8, - ) { - let mut buffer = Vec::with_capacity(algorithm.tls_serialized_len()); - let result = algorithm.tls_serialize(&mut buffer); - assert_eq!(expected_hash_int, buffer[0]); - assert_eq!(expected_signature_int, buffer[1]); - assert_eq!(result, Ok(2)); - } - - run_test( + run_serialization_test( SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa, }, - 2, - 1, + &[2, 1], ); - run_test( + run_serialization_test( SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - 4, - 3, + &[4, 3], ); } @@ -428,14 +407,7 @@ mod tests { #[test] fn test_digitally_signed_serialization() { - fn run_test(digitally_signed: DigitallySigned, expected_bytes: &[u8]) { - let mut buffer = Vec::with_capacity(digitally_signed.tls_serialized_len()); - let result = digitally_signed.tls_serialize(&mut buffer); - assert_eq!(expected_bytes, &buffer); - assert_eq!(result, Ok(expected_bytes.len())); - } - - run_test( + run_serialization_test( DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, @@ -445,7 +417,7 @@ mod tests { }, &[4, 3, 0, 3, 0, 1, 2], ); - run_test( + run_serialization_test( DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, @@ -469,14 +441,7 @@ mod tests { #[test] fn test_version_serialization() { - fn run_test(version: Version, expected_bytes: &[u8]) { - let mut buffer = Vec::with_capacity(version.tls_serialized_len()); - let result = version.tls_serialize(&mut buffer); - assert_eq!(expected_bytes, &buffer); - assert_eq!(result, Ok(expected_bytes.len())); - } - - run_test(Version::V1, &[0]); + run_serialization_test(Version::V1, &[0]); } #[test] @@ -489,14 +454,7 @@ mod tests { #[test] fn test_log_id_serialization() { - fn run_test(log_id: LogId, expected_bytes: &[u8]) { - let mut buffer = Vec::with_capacity(log_id.tls_serialized_len()); - let result = log_id.tls_serialize(&mut buffer); - assert_eq!(expected_bytes, &buffer); - assert_eq!(result, Ok(expected_bytes.len())); - } - - run_test(LogId { key_id: [3; 32] }, &[3; 32]); + run_serialization_test(LogId { key_id: [3; 32] }, &[3; 32]); } const TLS_SCT_EXAMPLE: [u8; 119] = [ @@ -535,14 +493,7 @@ mod tests { #[test] fn test_sct_serialization() { - fn run_test(sct: SignedCertificateTimestamp, expected_bytes: &[u8]) { - let mut buffer = Vec::with_capacity(sct.tls_serialized_len()); - let result = sct.tls_serialize(&mut buffer); - assert_eq!(expected_bytes, &buffer); - assert_eq!(result, Ok(expected_bytes.len())); - } - - run_test( + run_serialization_test( SignedCertificateTimestamp { version: Version::V1, log_id: LogId { From 9b6919f22afa4090f0b3e5d3dcc2bd7cd1c6c901 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 19:11:51 +0530 Subject: [PATCH 28/58] convert some asserts into assert_eq --- x509-cert/src/ext/pkix/sct.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index cc8092d71..5d999ed09 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -56,13 +56,13 @@ impl SignedCertificateTimestampList { for timestamp in serialized_scts { let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); let bytes_written = timestamp.tls_serialize(&mut buffer)?; - assert!(bytes_written == timestamp.tls_serialized_len()); + assert_eq!(bytes_written, timestamp.tls_serialized_len()); result.extend(buffer); } let tls_vec = TlsVecU16::::new(result); let mut buffer: Vec = Vec::with_capacity(tls_vec.tls_serialized_len()); let bytes_written = tls_vec.tls_serialize(&mut buffer)?; - assert!(bytes_written == tls_vec.tls_serialized_len()); + assert_eq!(bytes_written, tls_vec.tls_serialized_len()); Ok(SignedCertificateTimestampList(OctetString::new(buffer)?)) } @@ -92,7 +92,7 @@ impl SerializedSct { pub fn new(timestamp: SignedCertificateTimestamp) -> Result { let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); let bytes_written = timestamp.tls_serialize(&mut buffer)?; - assert!(bytes_written == timestamp.tls_serialized_len()); + assert_eq!(bytes_written, timestamp.tls_serialized_len()); Ok(SerializedSct { data: TlsVecU16::from_slice(&buffer), }) From 0f6e73ddf73bffb0f4f6152cba4645b9dd550329 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 14 Jun 2023 19:38:17 +0530 Subject: [PATCH 29/58] Fix clippy warning --- x509-cert/src/ext/pkix/sct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 5d999ed09..55d17c775 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -75,7 +75,7 @@ impl SignedCertificateTimestampList { let mut bytes = tls_vec.as_slice(); let mut result = Vec::new(); while !bytes.is_empty() { - let (serialized_sct, rest) = SerializedSct::tls_deserialize(&bytes)?; + let (serialized_sct, rest) = SerializedSct::tls_deserialize(bytes)?; result.push(serialized_sct); bytes = rest; } From 5f7a6e44c9f11f3cd415f1394b1d4083e39482c6 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Thu, 15 Jun 2023 21:17:16 +0530 Subject: [PATCH 30/58] made some fields public --- x509-cert/src/ext/pkix.rs | 2 +- x509-cert/src/ext/pkix/sct.rs | 31 +++++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index fbf3dd2d7..86dd46368 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -26,7 +26,7 @@ pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod} pub use policymap::{PolicyMapping, PolicyMappings}; #[cfg(feature = "sct")] -pub use sct::SignedCertificateTimestampList; +pub use sct::{SerializedSct, SignedCertificateTimestamp, SignedCertificateTimestampList}; pub use const_oid::db::rfc5280::{ ID_CE_INHIBIT_ANY_POLICY, ID_CE_ISSUER_ALT_NAME, ID_CE_SUBJECT_ALT_NAME, diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 55d17c775..906891e93 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,6 +1,6 @@ #![cfg(feature = "sct")] -use const_oid::{db::rfc6962, AssociatedOid, ObjectIdentifier}; +use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString; //TODO: Remove use::alloc::format explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms //once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged @@ -24,8 +24,11 @@ use tls_codec::{ #[derive(Debug, PartialEq)] pub struct SignedCertificateTimestampList(OctetString); +pub const CT_PRECERT_SCTS: ObjectIdentifier = + ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); + impl AssociatedOid for SignedCertificateTimestampList { - const OID: ObjectIdentifier = rfc6962::CT_PRECERT_SCTS; + const OID: ObjectIdentifier = CT_PRECERT_SCTS; } impl_newtype!(SignedCertificateTimestampList, OctetString); @@ -109,11 +112,11 @@ impl SerializedSct { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignedCertificateTimestamp { - version: Version, - log_id: LogId, - timestamp: u64, - extensions: TlsVecU16, - sign: DigitallySigned, + pub version: Version, + pub log_id: LogId, + pub timestamp: u64, + pub extensions: TlsVecU16, + pub signature: DigitallySigned, } #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] @@ -124,7 +127,7 @@ pub enum Version { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct LogId { - key_id: [u8; 32], + pub key_id: [u8; 32], } #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] @@ -478,7 +481,7 @@ mod tests { }, timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), - sign: DigitallySigned { + signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, @@ -501,7 +504,7 @@ mod tests { }, timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), - sign: DigitallySigned { + signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, @@ -555,7 +558,7 @@ mod tests { }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), - sign: DigitallySigned { + signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, @@ -573,7 +576,7 @@ mod tests { }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), - sign: DigitallySigned { + signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, @@ -593,7 +596,7 @@ mod tests { }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), - sign: DigitallySigned { + signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, @@ -609,7 +612,7 @@ mod tests { }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), extensions: TlsVecU16::from_slice(&[]), - sign: DigitallySigned { + signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, From 648683d8d317565e930df11151b78dce67966e84 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 16 Jun 2023 12:12:04 +0530 Subject: [PATCH 31/58] make more items pub --- x509-cert/Cargo.toml | 2 +- x509-cert/src/ext/pkix.rs | 5 ++++- x509-cert/src/ext/pkix/sct.rs | 10 ++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 3465379c1..367adb210 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -23,7 +23,7 @@ spki = { version = "0.7.2", features = ["alloc"] } arbitrary = { version = "1.3", features = ["derive"], optional = true } sha1 = { version = "0.10.0", optional = true } signature = { version = "2.1.0", features = ["rand_core"], optional = true } -tls_codec = { version = "0.3.0", features = ["derive"], optional = true } +tls_codec = { path = "../tls_codec", features = ["derive"], optional = true } # tls_codec = { version = "0.3.0", features = ["derive", "std"] } [dev-dependencies] diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index 86dd46368..9cc30d8bc 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -26,7 +26,10 @@ pub use keyusage::{ExtendedKeyUsage, KeyUsage, KeyUsages, PrivateKeyUsagePeriod} pub use policymap::{PolicyMapping, PolicyMappings}; #[cfg(feature = "sct")] -pub use sct::{SerializedSct, SignedCertificateTimestamp, SignedCertificateTimestampList}; +pub use sct::{ + HashAlgorithm, SerializedSct, SignatureAlgorithm, SignatureAndHashAlgorithm, + SignedCertificateTimestamp, SignedCertificateTimestampList, Version, +}; pub use const_oid::db::rfc5280::{ ID_CE_INHIBIT_ANY_POLICY, ID_CE_ISSUER_ALT_NAME, ID_CE_SUBJECT_ALT_NAME, diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 906891e93..da8edfbc7 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -119,6 +119,12 @@ pub struct SignedCertificateTimestamp { pub signature: DigitallySigned, } +impl SignedCertificateTimestamp { + pub fn timestamp(&self) -> Result { + der::DateTime::from_unix_duration(core::time::Duration::from_millis(self.timestamp)) + } +} + #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum Version { @@ -140,8 +146,8 @@ pub struct DigitallySigned { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignatureAndHashAlgorithm { - hash: HashAlgorithm, - signature: SignatureAlgorithm, + pub hash: HashAlgorithm, + pub signature: SignatureAlgorithm, } #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] From 8883433e1e19e6d7803d870f74c973a49f61e894 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Fri, 16 Jun 2023 19:08:56 +0530 Subject: [PATCH 32/58] Remove old TODOs --- x509-cert/src/ext/pkix/sct.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index da8edfbc7..1e1f54249 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,11 +1,8 @@ #![cfg(feature = "sct")] +use alloc::{format, vec::Vec}; use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString; -//TODO: Remove use::alloc::format explicit use required by the #[derive(TlsSerialize)] on SignagureAndHashAlgorithms -//once the PR: https://github.com/RustCrypto/formats/pull/1103 is merged -// use std::format; -use alloc::{format, vec::Vec}; use tls_codec::{ DeserializeBytes, Serialize, Size, TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16, }; @@ -14,18 +11,12 @@ use tls_codec::{ // TODO: Update docs // TODO: Review naming -// TODO: Remove this constant when const_oid version is updated which includes this PR: -// https://github.com/RustCrypto/formats/pull/1094 -// TODO: Do not publish this as pub, this is for testing only -/// OID for signed certificate timestamps extension -// pub const CT_PRECERT_SCTS: ObjectIdentifier = -// ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); - #[derive(Debug, PartialEq)] pub struct SignedCertificateTimestampList(OctetString); -pub const CT_PRECERT_SCTS: ObjectIdentifier = - ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); +//TODO: Remove this and use const-oid's rfc6962::CT_PRECERT_SCTS once a const-oid version +// containing it is published +const CT_PRECERT_SCTS: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.6.1.4.1.11129.2.4.2"); impl AssociatedOid for SignedCertificateTimestampList { const OID: ObjectIdentifier = CT_PRECERT_SCTS; From f2d4d24e5607d70eba07cf3d754530803d94cfc3 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sat, 17 Jun 2023 12:01:53 +0530 Subject: [PATCH 33/58] document sct items --- x509-cert/src/ext/pkix.rs | 3 +- x509-cert/src/ext/pkix/sct.rs | 78 +++++++++++++++++++++++++++++++++-- 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index 9cc30d8bc..d249d2499 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -9,6 +9,7 @@ mod access; mod authkeyid; mod keyusage; mod policymap; +#[cfg(feature = "sct")] mod sct; use crate::attr::AttributeTypeAndValue; @@ -27,7 +28,7 @@ pub use policymap::{PolicyMapping, PolicyMappings}; #[cfg(feature = "sct")] pub use sct::{ - HashAlgorithm, SerializedSct, SignatureAlgorithm, SignatureAndHashAlgorithm, + Error, HashAlgorithm, SerializedSct, SignatureAlgorithm, SignatureAndHashAlgorithm, SignedCertificateTimestamp, SignedCertificateTimestampList, Version, }; diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 1e1f54249..590e0314f 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -11,6 +11,13 @@ use tls_codec::{ // TODO: Update docs // TODO: Review naming +/// A signed certificate timestamp list (SCT list) as defined in [RFC 6962 Section 3.3]. +/// +/// ```text +/// SignedCertificateTimestampList ::= OCTET STRING +/// ``` +/// +/// [RFC 6962 Section 3.3]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.3 #[derive(Debug, PartialEq)] pub struct SignedCertificateTimestampList(OctetString); @@ -25,9 +32,12 @@ impl AssociatedOid for SignedCertificateTimestampList { impl_newtype!(SignedCertificateTimestampList, OctetString); impl_extension!(SignedCertificateTimestampList, critical = false); +/// Errors that are thrown by this module. #[derive(PartialEq, Debug)] pub enum Error { + /// [Errors][der::Error] from the `der` crate. Der(der::Error), + /// [Errors][tls_codec::Error] from the `tls_codec` crate. Tls(tls_codec::Error), } @@ -60,7 +70,11 @@ impl SignedCertificateTimestampList { Ok(SignedCertificateTimestampList(OctetString::new(buffer)?)) } - /// Parses the encoded [SerializedSct]s and returns a Vec containing them + /// Parses the encoded [SerializedSct]s and returns a [Vec][alloc::vec::Vec] containing them. + /// + /// Returns an [error][Error] if a [SerializedSct] can't be + /// deserialized or if there are trailing bytes after all [SerializedSct]s + /// are deserialized. pub fn parse_timestamps(&self) -> Result, Error> { let (tls_vec, rest) = TlsVecU16::::tls_deserialize(self.0.as_bytes())?; if !rest.is_empty() { @@ -77,12 +91,20 @@ impl SignedCertificateTimestampList { } } +/// A byte string that contains a serialized [SignedCertificateTimestamp] as +/// defined in [RFC 6962 section 3.3]. +/// +/// [RFC 6962 section 3.3]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.3 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SerializedSct { data: TlsVecU16, } impl SerializedSct { + /// Creates a new [SerializedSct] from a [SignedCertificateTimestamp]. + /// + /// Returns [tls_codec Error][tls_codec::Error] if the given [SignedCertificateTimestamp] + /// can't be serialized. pub fn new(timestamp: SignedCertificateTimestamp) -> Result { let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); let bytes_written = timestamp.tls_serialize(&mut buffer)?; @@ -92,6 +114,11 @@ impl SerializedSct { }) } + /// Parses a [SignedCertificateTimestamp] from a this [SerializedSct]. + /// + /// Returns an [error][Error] if a [SignedCertificateTimestamp] can't be + /// deserialized or if there are trailing bytes after a + /// [SignedCertificateTimestamp] has been deserialized. pub fn parse_timestamp(&self) -> Result { let (sct, rest) = SignedCertificateTimestamp::tls_deserialize(self.data.as_slice())?; if !rest.is_empty() { @@ -101,46 +128,88 @@ impl SerializedSct { } } +/// A signed certificate timestamp (SCT) as defined in [RFC 6962 section 3.2]. +/// +/// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignedCertificateTimestamp { + /// The version of the protocol to which the SCT conforms. + /// Currently, it is always v1. pub version: Version, + /// The SHA-256 hash of the log's public key, calculated over + /// the DER encoding of the key represented as [SubjectPublicKeyInfo][spki::SubjectPublicKeyInfo]. pub log_id: LogId, + /// the current NTP Time measured since the `UNIX_EPOCH` + /// (January 1, 1970, 00:00), ignoring leap seconds, in milliseconds. pub timestamp: u64, + /// The future extensions to protocol version v1. + /// Currently, no extensions are specified. pub extensions: TlsVecU16, + /// A digital signature over many fields including + /// version, timestamp, extensions and others. See [RFC 6962 section 3.2] + /// for a complete list. + /// + /// [RFC 6962 section 3.2]:https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 pub signature: DigitallySigned, } impl SignedCertificateTimestamp { + /// Creates a [DateTime][der::DateTime] from the timestamp field since the `UNIX_EPOCH`. + /// + /// Returns an error if timestamp is outside the supported date range. pub fn timestamp(&self) -> Result { der::DateTime::from_unix_duration(core::time::Duration::from_millis(self.timestamp)) } } +/// The version of the protocol to which the SCT conforms +/// as defined in [RFC 6962 section 3.2]. Currently, it is always v1. +/// +/// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum Version { + /// Version 1 V1 = 0, } +/// The SHA-256 hash of the log's public key, calculated over +/// the DER encoding of the key represented as SubjectPublicKeyInfo +/// as defined in [RFC 6962 section 3.2] +/// +/// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct LogId { pub key_id: [u8; 32], } +/// Digital signature as defined in [RFC 5246 section 4.7]. +/// +/// [RFC 5246 section 4.7]: https://datatracker.ietf.org/doc/html/rfc5246#section-4.7 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct DigitallySigned { - /// [SignatureAndHashAlgorithm] of the struct + /// [SignatureAndHashAlgorithm] as defined in [RFC 5246 section 7.4.1.4.1]. + /// + /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 pub algorithm: SignatureAndHashAlgorithm, - /// Signature of the struct + /// Digital signature over some contents using the [SignatureAndHashAlgorithm]. pub signature: TlsVecU16, } +/// A combination of signature and hashing algorithms as defined in [RFC 5246 section 7.4.1.4.1]. +/// +/// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignatureAndHashAlgorithm { + /// The hashing algorithm pub hash: HashAlgorithm, + /// The signature algorithm pub signature: SignatureAlgorithm, } +/// Signature algorithm as defined in [RFC 5246 section 7.4.1.4.1]. +/// +/// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum SignatureAlgorithm { @@ -158,6 +227,9 @@ pub enum SignatureAlgorithm { Ed448 = 8, } +/// Hashing algorithm as defined in [RFC 5246 section 7.4.1.4.1]. +/// +/// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum HashAlgorithm { From ef2e51bc2b57d5c6bbc49f6a2d4fef61cb2cdec9 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sat, 17 Jun 2023 12:11:58 +0530 Subject: [PATCH 34/58] make sct module public --- x509-cert/src/ext/pkix.rs | 2 +- x509-cert/src/ext/pkix/sct.rs | 45 +++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/x509-cert/src/ext/pkix.rs b/x509-cert/src/ext/pkix.rs index d249d2499..2c7a4ffe7 100644 --- a/x509-cert/src/ext/pkix.rs +++ b/x509-cert/src/ext/pkix.rs @@ -10,7 +10,7 @@ mod authkeyid; mod keyusage; mod policymap; #[cfg(feature = "sct")] -mod sct; +pub mod sct; use crate::attr::AttributeTypeAndValue; diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 590e0314f..7a23165c5 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,4 +1,8 @@ #![cfg(feature = "sct")] +//! Signed Certificate Timestamp list extension as defined in the +//! [Certificate Transparency RFC 6962]. +//! +//! [Certificate Transparency RFC 6962]: https://datatracker.ietf.org/doc/html/rfc6962 use alloc::{format, vec::Vec}; use const_oid::{AssociatedOid, ObjectIdentifier}; @@ -54,7 +58,7 @@ impl From for Error { } impl SignedCertificateTimestampList { - /// Creates a new [SignedCertificateTimestamp] from a slice of [SerializedSct]s + /// Creates a new [SignedCertificateTimestamp] from a slice of [SerializedSct]s. pub fn new(serialized_scts: &[SerializedSct]) -> Result { let mut result: Vec = Vec::new(); for timestamp in serialized_scts { @@ -169,17 +173,18 @@ impl SignedCertificateTimestamp { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum Version { - /// Version 1 + /// Version 1. V1 = 0, } /// The SHA-256 hash of the log's public key, calculated over -/// the DER encoding of the key represented as SubjectPublicKeyInfo -/// as defined in [RFC 6962 section 3.2] +/// the DER encoding of the key represented as [SubjectPublicKeyInfo][spki::SubjectPublicKeyInfo] +/// as defined in [RFC 6962 section 3.2]. /// /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct LogId { + /// Hash of the log's public key. pub key_id: [u8; 32], } @@ -201,9 +206,9 @@ pub struct DigitallySigned { /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] pub struct SignatureAndHashAlgorithm { - /// The hashing algorithm + /// The hashing algorithm. pub hash: HashAlgorithm, - /// The signature algorithm + /// The signature algorithm. pub signature: SignatureAlgorithm, } @@ -213,17 +218,17 @@ pub struct SignatureAndHashAlgorithm { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum SignatureAlgorithm { - /// Anonymous signature algorithm + /// Anonymous signature algorithm. Anonymous = 0, - /// RSA signature algorithm + /// RSA signature algorithm. Rsa = 1, - /// DSA signature algorithm + /// DSA signature algorithm. Dsa = 2, - /// ECDSA signature algorithm + /// ECDSA signature algorithm. Ecdsa = 3, - /// ED25519 signature algorithm + /// ED25519 signature algorithm. Ed25519 = 7, - /// ED448 signature algorithm + /// ED448 signature algorithm. Ed448 = 8, } @@ -233,21 +238,21 @@ pub enum SignatureAlgorithm { #[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] pub enum HashAlgorithm { - /// No algorithm + /// No algorithm. None = 0, - /// MD5 algorithm + /// MD5 algorithm. Md5 = 1, - /// SHA1 algorithm + /// SHA1 algorithm. Sha1 = 2, - /// SHA224 algorithm + /// SHA224 algorithm. Sha224 = 3, - /// SHA256 algorithm + /// SHA256 algorithm. Sha256 = 4, - /// SHA384 algorithm + /// SHA384 algorithm. Sha384 = 5, - /// SHA512 algorithm + /// SHA512 algorithm. Sha512 = 6, - /// Intrinsic algorithm + /// Intrinsic algorithm. Intrinsic = 8, } From b4dc05ca84ad20ba88ba3b437a5c71dbffcd9ce6 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 15:19:29 +0530 Subject: [PATCH 35/58] Use SerializeBytes --- x509-cert/Cargo.toml | 2 +- x509-cert/src/ext/pkix/sct.rs | 86 ++++++++++++++++------------------- 2 files changed, 40 insertions(+), 48 deletions(-) diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 367adb210..4678d8bd4 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.65" [dependencies] -const-oid = { version = "0.9.3", features = ["db"] } +const-oid = { version = "0.9.2", features = ["db"] } der = { version = "0.7.6", features = ["alloc", "derive", "flagset", "oid"] } spki = { version = "0.7.2", features = ["alloc"] } diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 7a23165c5..34d058e12 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -8,7 +8,8 @@ use alloc::{format, vec::Vec}; use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString; use tls_codec::{ - DeserializeBytes, Serialize, Size, TlsDeserializeBytes, TlsSerialize, TlsSize, TlsVecU16, + DeserializeBytes, SerializeBytes, TlsByteVecU16, TlsDeserializeBytes, TlsSerializeBytes, + TlsSize, }; // TODO: Review what should be pub @@ -62,15 +63,11 @@ impl SignedCertificateTimestampList { pub fn new(serialized_scts: &[SerializedSct]) -> Result { let mut result: Vec = Vec::new(); for timestamp in serialized_scts { - let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); - let bytes_written = timestamp.tls_serialize(&mut buffer)?; - assert_eq!(bytes_written, timestamp.tls_serialized_len()); + let buffer = timestamp.tls_serialize()?; result.extend(buffer); } - let tls_vec = TlsVecU16::::new(result); - let mut buffer: Vec = Vec::with_capacity(tls_vec.tls_serialized_len()); - let bytes_written = tls_vec.tls_serialize(&mut buffer)?; - assert_eq!(bytes_written, tls_vec.tls_serialized_len()); + let tls_vec = TlsByteVecU16::new(result); + let buffer = tls_vec.tls_serialize()?; Ok(SignedCertificateTimestampList(OctetString::new(buffer)?)) } @@ -80,7 +77,7 @@ impl SignedCertificateTimestampList { /// deserialized or if there are trailing bytes after all [SerializedSct]s /// are deserialized. pub fn parse_timestamps(&self) -> Result, Error> { - let (tls_vec, rest) = TlsVecU16::::tls_deserialize(self.0.as_bytes())?; + let (tls_vec, rest) = TlsByteVecU16::tls_deserialize(self.0.as_bytes())?; if !rest.is_empty() { return Err(tls_codec::Error::TrailingData)?; } @@ -99,9 +96,9 @@ impl SignedCertificateTimestampList { /// defined in [RFC 6962 section 3.3]. /// /// [RFC 6962 section 3.3]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.3 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] pub struct SerializedSct { - data: TlsVecU16, + data: TlsByteVecU16, } impl SerializedSct { @@ -110,11 +107,9 @@ impl SerializedSct { /// Returns [tls_codec Error][tls_codec::Error] if the given [SignedCertificateTimestamp] /// can't be serialized. pub fn new(timestamp: SignedCertificateTimestamp) -> Result { - let mut buffer: Vec = Vec::with_capacity(timestamp.tls_serialized_len()); - let bytes_written = timestamp.tls_serialize(&mut buffer)?; - assert_eq!(bytes_written, timestamp.tls_serialized_len()); + let buffer = timestamp.tls_serialize()?; Ok(SerializedSct { - data: TlsVecU16::from_slice(&buffer), + data: TlsByteVecU16::from_slice(&buffer), }) } @@ -135,7 +130,7 @@ impl SerializedSct { /// A signed certificate timestamp (SCT) as defined in [RFC 6962 section 3.2]. /// /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] pub struct SignedCertificateTimestamp { /// The version of the protocol to which the SCT conforms. /// Currently, it is always v1. @@ -148,7 +143,7 @@ pub struct SignedCertificateTimestamp { pub timestamp: u64, /// The future extensions to protocol version v1. /// Currently, no extensions are specified. - pub extensions: TlsVecU16, + pub extensions: TlsByteVecU16, /// A digital signature over many fields including /// version, timestamp, extensions and others. See [RFC 6962 section 3.2] /// for a complete list. @@ -170,7 +165,7 @@ impl SignedCertificateTimestamp { /// as defined in [RFC 6962 section 3.2]. Currently, it is always v1. /// /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] #[repr(u8)] pub enum Version { /// Version 1. @@ -182,7 +177,7 @@ pub enum Version { /// as defined in [RFC 6962 section 3.2]. /// /// [RFC 6962 section 3.2]: https://datatracker.ietf.org/doc/html/rfc6962#section-3.2 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] pub struct LogId { /// Hash of the log's public key. pub key_id: [u8; 32], @@ -191,20 +186,20 @@ pub struct LogId { /// Digital signature as defined in [RFC 5246 section 4.7]. /// /// [RFC 5246 section 4.7]: https://datatracker.ietf.org/doc/html/rfc5246#section-4.7 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] pub struct DigitallySigned { /// [SignatureAndHashAlgorithm] as defined in [RFC 5246 section 7.4.1.4.1]. /// /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 pub algorithm: SignatureAndHashAlgorithm, /// Digital signature over some contents using the [SignatureAndHashAlgorithm]. - pub signature: TlsVecU16, + pub signature: TlsByteVecU16, } /// A combination of signature and hashing algorithms as defined in [RFC 5246 section 7.4.1.4.1]. /// /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] pub struct SignatureAndHashAlgorithm { /// The hashing algorithm. pub hash: HashAlgorithm, @@ -215,7 +210,7 @@ pub struct SignatureAndHashAlgorithm { /// Signature algorithm as defined in [RFC 5246 section 7.4.1.4.1]. /// /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] #[repr(u8)] pub enum SignatureAlgorithm { /// Anonymous signature algorithm. @@ -235,7 +230,7 @@ pub enum SignatureAlgorithm { /// Hashing algorithm as defined in [RFC 5246 section 7.4.1.4.1]. /// /// [RFC 5246 section 7.4.1.4.1]: https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.4.1 -#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(PartialEq, Debug, TlsDeserializeBytes, TlsSerializeBytes, TlsSize)] #[repr(u8)] pub enum HashAlgorithm { /// No algorithm. @@ -258,9 +253,8 @@ pub enum HashAlgorithm { #[cfg(test)] mod tests { - use alloc::vec::Vec; use der::{asn1::OctetString, Decode, Encode}; - use tls_codec::{DeserializeBytes, Serialize, TlsVecU16}; + use tls_codec::{DeserializeBytes, SerializeBytes, TlsByteVecU16}; use crate::ext::pkix::sct::LogId; @@ -279,11 +273,9 @@ mod tests { actual_result } - fn run_serialization_test(value: T, expected_bytes: &[u8]) { - let mut buffer = Vec::with_capacity(value.tls_serialized_len()); - let result = value.tls_serialize(&mut buffer); - assert_eq!(expected_bytes, &buffer); - assert_eq!(result, Ok(expected_bytes.len())); + fn run_serialization_test(value: T, expected_bytes: &[u8]) { + let result = value.tls_serialize().unwrap(); + assert_eq!(expected_bytes, &result); } #[test] @@ -461,7 +453,7 @@ mod tests { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::::from_slice(&[2, 1, 0]), + signature: TlsByteVecU16::from_slice(&[2, 1, 0]), }, [2, 1, 0, 1, 9].as_slice(), )), @@ -475,7 +467,7 @@ mod tests { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa, }, - signature: TlsVecU16::::from_slice(&[9]), + signature: TlsByteVecU16::from_slice(&[9]), }, [].as_slice(), )), @@ -490,7 +482,7 @@ mod tests { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::::from_slice(&[0, 1, 2]), + signature: TlsByteVecU16::from_slice(&[0, 1, 2]), }, &[4, 3, 0, 3, 0, 1, 2], ); @@ -500,7 +492,7 @@ mod tests { hash: HashAlgorithm::Sha1, signature: SignatureAlgorithm::Rsa, }, - signature: TlsVecU16::::from_slice(&[0, 1, 2]), + signature: TlsByteVecU16::from_slice(&[0, 1, 2]), }, &[2, 1, 0, 3, 0, 1, 2], ); @@ -554,13 +546,13 @@ mod tests { key_id: TLS_SCT_EXAMPLE[1..33].try_into().unwrap(), }, timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), - extensions: TlsVecU16::from_slice(&[]), + extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]), + signature: TlsByteVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]), }, }, &[], @@ -577,13 +569,13 @@ mod tests { key_id: TLS_SCT_EXAMPLE[1..33].try_into().unwrap(), }, timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), - extensions: TlsVecU16::from_slice(&[]), + extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]), + signature: TlsByteVecU16::from_slice(&TLS_SCT_EXAMPLE[47..]), }, }, &TLS_SCT_EXAMPLE, @@ -631,13 +623,13 @@ mod tests { key_id: SCT_EXAMPLE[8..40].try_into().unwrap(), }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), - extensions: TlsVecU16::from_slice(&[]), + extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&SCT_EXAMPLE[54..126]), + signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[54..126]), }, }) ); @@ -649,13 +641,13 @@ mod tests { key_id: SCT_EXAMPLE[129..161].try_into().unwrap(), }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), - extensions: TlsVecU16::from_slice(&[]), + extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&SCT_EXAMPLE[175..]), + signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[175..]), }, }) ); @@ -669,13 +661,13 @@ mod tests { key_id: SCT_EXAMPLE[8..40].try_into().unwrap(), }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), - extensions: TlsVecU16::from_slice(&[]), + extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&SCT_EXAMPLE[54..126]), + signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[54..126]), }, }) .unwrap(); @@ -685,13 +677,13 @@ mod tests { key_id: SCT_EXAMPLE[129..161].try_into().unwrap(), }, timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), - extensions: TlsVecU16::from_slice(&[]), + extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha256, signature: SignatureAlgorithm::Ecdsa, }, - signature: TlsVecU16::from_slice(&SCT_EXAMPLE[175..]), + signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[175..]), }, }) .unwrap(); From ec31dae83a46e88c911044d5c29bc38cb67c4cac Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 18:46:02 +0530 Subject: [PATCH 36/58] revert changes in Cargo.{lock, toml} --- Cargo.lock | 30 +++++++++++++++++++----------- const-oid/Cargo.toml | 2 +- x509-cert/Cargo.toml | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68fecda6b..d0dca64de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -244,7 +244,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" name = "cmpv2" version = "0.2.0" dependencies = [ - "const-oid", + "const-oid 0.9.2", "crmf", "der", "hex-literal", @@ -256,7 +256,7 @@ dependencies = [ name = "cms" version = "0.2.1" dependencies = [ - "const-oid", + "const-oid 0.9.2", "der", "ecdsa", "hex-literal", @@ -275,6 +275,15 @@ dependencies = [ [[package]] name = "const-oid" version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +dependencies = [ + "arbitrary", +] + +[[package]] +name = "const-oid" +version = "0.10.0-pre" dependencies = [ "arbitrary", "hex-literal", @@ -330,7 +339,7 @@ name = "crmf" version = "0.2.0" dependencies = [ "cms", - "const-oid", + "const-oid 0.9.2", "der", "spki", "x509-cert", @@ -406,7 +415,7 @@ name = "der" version = "0.7.7" dependencies = [ "arbitrary", - "const-oid", + "const-oid 0.9.2", "der_derive", "flagset", "hex-literal", @@ -453,7 +462,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", - "const-oid", + "const-oid 0.9.2", "crypto-common", "subtle", ] @@ -990,7 +999,7 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" name = "pkcs1" version = "0.7.5" dependencies = [ - "const-oid", + "const-oid 0.9.2", "der", "hex-literal", "pkcs8", @@ -1262,7 +1271,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ "byteorder", - "const-oid", + "const-oid 0.9.2", "digest", "num-bigint-dig", "num-integer", @@ -1922,7 +1931,7 @@ name = "x509-cert" version = "0.2.3" dependencies = [ "arbitrary", - "const-oid", + "const-oid 0.9.2", "der", "ecdsa", "hex-literal", @@ -1935,7 +1944,6 @@ dependencies = [ "signature", "spki", "tempfile", - "tls_codec", "x509-cert-test-support", ] @@ -1952,7 +1960,7 @@ dependencies = [ name = "x509-ocsp" version = "0.2.0-pre" dependencies = [ - "const-oid", + "const-oid 0.9.2", "der", "hex-literal", "spki", @@ -1987,4 +1995,4 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.22", -] +] \ No newline at end of file diff --git a/const-oid/Cargo.toml b/const-oid/Cargo.toml index 0ce6f9514..8651739d8 100644 --- a/const-oid/Cargo.toml +++ b/const-oid/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "const-oid" -version = "0.9.2" +version = "0.10.0-pre" authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = """ diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 4678d8bd4..367adb210 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" rust-version = "1.65" [dependencies] -const-oid = { version = "0.9.2", features = ["db"] } +const-oid = { version = "0.9.3", features = ["db"] } der = { version = "0.7.6", features = ["alloc", "derive", "flagset", "oid"] } spki = { version = "0.7.2", features = ["alloc"] } From f777a408a1639c10a103cbde3e2d52c58be5d048 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 18:47:56 +0530 Subject: [PATCH 37/58] Fix trailing whitespace --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index d0dca64de..d8d09dfd5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1995,4 +1995,4 @@ dependencies = [ "proc-macro2", "quote", "syn 2.0.22", -] \ No newline at end of file +] From b3b4696f4669654a54e9c09fb53e30fdd5fa5115 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 19:04:09 +0530 Subject: [PATCH 38/58] Correct default features --- x509-cert/Cargo.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 367adb210..8210acab6 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -23,8 +23,10 @@ spki = { version = "0.7.2", features = ["alloc"] } arbitrary = { version = "1.3", features = ["derive"], optional = true } sha1 = { version = "0.10.0", optional = true } signature = { version = "2.1.0", features = ["rand_core"], optional = true } +# TODO: Use next version of tls_codec when a verion containing the following PR is published: +# https://github.com/RustCrypto/formats/pull/1132 +# https://github.com/RustCrypto/formats/pull/1133 tls_codec = { path = "../tls_codec", features = ["derive"], optional = true } -# tls_codec = { version = "0.3.0", features = ["derive", "std"] } [dev-dependencies] hex-literal = "0.4" @@ -38,8 +40,7 @@ tempfile = "3.5.0" x509-cert-test-support = { path = "./test-support" } [features] -# default = ["pem", "std"] -default = ["pem", "std", "sct"] +default = ["pem", "std"] std = ["const-oid/std", "der/std", "spki/std", "tls_codec?/std"] arbitrary = ["dep:arbitrary", "std", "der/arbitrary", "spki/arbitrary"] From 15050dd320bf4316eb1017d2517c98bf2ee9b66e Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 2 Jul 2023 21:14:29 +0530 Subject: [PATCH 39/58] disable default features for tls_codec --- x509-cert/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 8210acab6..963f14147 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -26,7 +26,7 @@ signature = { version = "2.1.0", features = ["rand_core"], optional = true } # TODO: Use next version of tls_codec when a verion containing the following PR is published: # https://github.com/RustCrypto/formats/pull/1132 # https://github.com/RustCrypto/formats/pull/1133 -tls_codec = { path = "../tls_codec", features = ["derive"], optional = true } +tls_codec = { path = "../tls_codec", default-features = false, features = ["derive"], optional = true } [dev-dependencies] hex-literal = "0.4" From 92e9a69ddfd08c1f0ed5547ffe594fc3e32f6830 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Mon, 3 Jul 2023 09:02:56 +0530 Subject: [PATCH 40/58] remove unnecessary TODOs --- x509-cert/src/ext/pkix/sct.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 34d058e12..6865884e4 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -12,10 +12,6 @@ use tls_codec::{ TlsSize, }; -// TODO: Review what should be pub -// TODO: Update docs -// TODO: Review naming - /// A signed certificate timestamp list (SCT list) as defined in [RFC 6962 Section 3.3]. /// /// ```text From 5bea0d9c7d9198f39d51a630856406d80bbcf85f Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 16:01:16 +0530 Subject: [PATCH 41/58] remove duplicate code --- tls_codec/src/tls_vec.rs | 119 ++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 69 deletions(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index f1ddc2eb3..37bbb1a2f 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -78,45 +78,6 @@ macro_rules! impl_byte_deserialize { let result = Self { vec: vec.to_vec() }; Ok((result, &remainder.get(len..).ok_or(Error::EndOfStream)?)) } - - fn serialize_bytes_bytes(&$self) -> Result, Error> { - let tls_serialized_len = $self.tls_serialized_len(); - let byte_length = tls_serialized_len - $len_len; - - let max_len = <$size>::MAX as usize; - debug_assert!( - byte_length <= max_len, - "Vector length can't be encoded in the vector length a {} >= {}", - byte_length, - max_len - ); - if byte_length > max_len { - return Err(Error::InvalidVectorLength); - } - - let mut vec = Vec::::with_capacity(tls_serialized_len); - let length_vec = <$size as SerializeBytes>::tls_serialize(&(byte_length as $size))?; - let mut written = length_vec.len(); - vec.extend_from_slice(&length_vec); - - let bytes = $self.as_slice(); - vec.extend_from_slice(bytes); - written += bytes.len(); - - debug_assert_eq!( - written, tls_serialized_len, - "{} bytes should have been serialized but {} were written", - tls_serialized_len, written - ); - if written != tls_serialized_len { - return Err(Error::EncodingError(format!( - "{} bytes should have been serialized but {} were written", - tls_serialized_len, written - ))); - } - - Ok(vec) - } }; } @@ -166,19 +127,7 @@ macro_rules! impl_serialize { fn serialize(&$self, writer: &mut W) -> Result { // Get the byte length of the content, make sure it's not too // large and write it out. - let tls_serialized_len = $self.tls_serialized_len(); - let byte_length = tls_serialized_len - $len_len; - - let max_len = <$size>::MAX as usize; - debug_assert!( - byte_length <= max_len, - "Vector length can't be encoded in the vector length a {} >= {}", - byte_length, - max_len - ); - if byte_length > max_len { - return Err(Error::InvalidVectorLength); - } + let (tls_serialized_len, byte_length) = $self.get_content_lengths()?; let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; @@ -187,17 +136,7 @@ macro_rules! impl_serialize { written += e.tls_serialize(writer)?; } - debug_assert_eq!( - written, tls_serialized_len, - "{} bytes should have been serialized but {} were written", - tls_serialized_len, written - ); - if written != tls_serialized_len { - return Err(Error::EncodingError(format!( - "{} bytes should have been serialized but {} were written", - tls_serialized_len, written - ))); - } + $self.assert_written_bytes(tls_serialized_len, written)?; Ok(written) } }; @@ -210,6 +149,22 @@ macro_rules! impl_byte_serialize { fn serialize_bytes(&$self, writer: &mut W) -> Result { // Get the byte length of the content, make sure it's not too // large and write it out. + let (tls_serialized_len, byte_length) = $self.get_content_lengths()?; + + let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; + + // Now serialize the elements + written += writer.write($self.as_slice())?; + + $self.assert_written_bytes(tls_serialized_len, written)?; + Ok(written) + } + }; +} +macro_rules! impl_serialize_common { + ($self:ident, $size:ty, $name:ident, $len_len:literal $(,#[$attr:meta])?) => { + $(#[$attr])? + fn get_content_lengths(&$self) -> Result<(usize, usize), Error> { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; @@ -223,12 +178,11 @@ macro_rules! impl_byte_serialize { if byte_length > max_len { return Err(Error::InvalidVectorLength); } + Ok((tls_serialized_len, byte_length)) + } - let mut written = <$size as Serialize>::tls_serialize(&(byte_length as $size), writer)?; - - // Now serialize the elements - written += writer.write($self.as_slice())?; - + $(#[$attr])? + fn assert_written_bytes(&$self, tls_serialized_len: usize, written: usize) -> Result<(), Error> { debug_assert_eq!( written, tls_serialized_len, "{} bytes should have been serialized but {} were written", @@ -240,7 +194,28 @@ macro_rules! impl_byte_serialize { tls_serialized_len, written ))); } - Ok(written) + Ok(()) + } + }; +} + +macro_rules! impl_serialize_bytes_bytes { + ($self:ident, $size:ty, $name:ident, $len_len:literal) => { + fn serialize_bytes_bytes(&$self) -> Result, Error> { + let (tls_serialized_len, byte_length) = $self.get_content_lengths()?; + + let mut vec = Vec::::with_capacity(tls_serialized_len); + let length_vec = <$size as SerializeBytes>::tls_serialize(&(byte_length as $size))?; + let mut written = length_vec.len(); + vec.extend_from_slice(&length_vec); + + let bytes = $self.as_slice(); + vec.extend_from_slice(bytes); + written += bytes.len(); + + $self.assert_written_bytes(tls_serialized_len, written)?; + + Ok(vec) } }; } @@ -834,6 +809,7 @@ macro_rules! impl_secret_tls_vec { impl_tls_vec_codec_generic!($size, $name, $len_len, Zeroize); impl $name { + impl_serialize_common!(self, $size, $name, $len_len, #[cfg(feature = "std")]); impl_serialize!(self, $size, $name, $len_len); } @@ -870,6 +846,7 @@ macro_rules! impl_public_tls_vec { impl_tls_vec_codec_generic!($size, $name, $len_len); impl $name { + impl_serialize_common!(self, $size, $name, $len_len, #[cfg(feature = "std")]); impl_serialize!(self, $size, $name, $len_len); } @@ -893,7 +870,9 @@ macro_rules! impl_tls_byte_vec { impl $name { // This implements serialize and size for all versions + impl_serialize_common!(self, $size, $name, $len_len); impl_byte_serialize!(self, $size, $name, $len_len); + impl_serialize_bytes_bytes!(self, $size, $name, $len_len); impl_byte_size!(self, $size, $name, $len_len); impl_byte_deserialize!(self, $size, $name, $len_len); } @@ -930,6 +909,7 @@ macro_rules! impl_tls_byte_slice { } impl<'a> $name<'a> { + impl_serialize_common!(self, $size, $name, $len_len, #[cfg(feature = "std")]); impl_byte_serialize!(self, $size, $name, $len_len); impl_byte_size!(self, $size, $name, $len_len); } @@ -985,6 +965,7 @@ macro_rules! impl_tls_slice { } impl<'a, T: Serialize> $name<'a, T> { + impl_serialize_common!(self, $size, $name, $len_len, #[cfg(feature = "std")]); impl_serialize!(self, $size, $name, $len_len); } From a8cd76e4ecc203f176af0acbeca490f560a67352 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 16:05:52 +0530 Subject: [PATCH 42/58] rename meta-variable --- tls_codec/src/tls_vec.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tls_codec/src/tls_vec.rs b/tls_codec/src/tls_vec.rs index 37bbb1a2f..c9a989a9e 100644 --- a/tls_codec/src/tls_vec.rs +++ b/tls_codec/src/tls_vec.rs @@ -162,8 +162,8 @@ macro_rules! impl_byte_serialize { }; } macro_rules! impl_serialize_common { - ($self:ident, $size:ty, $name:ident, $len_len:literal $(,#[$attr:meta])?) => { - $(#[$attr])? + ($self:ident, $size:ty, $name:ident, $len_len:literal $(,#[$std_enabled:meta])?) => { + $(#[$std_enabled])? fn get_content_lengths(&$self) -> Result<(usize, usize), Error> { let tls_serialized_len = $self.tls_serialized_len(); let byte_length = tls_serialized_len - $len_len; @@ -181,7 +181,7 @@ macro_rules! impl_serialize_common { Ok((tls_serialized_len, byte_length)) } - $(#[$attr])? + $(#[$std_enabled])? fn assert_written_bytes(&$self, tls_serialized_len: usize, written: usize) -> Result<(), Error> { debug_assert_eq!( written, tls_serialized_len, From 640fa2ae8037d577f295904ee6a60514a329a54a Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 17:08:34 +0530 Subject: [PATCH 43/58] fix tests --- tls_codec/derive/tests/decode.rs | 143 ++++++++++++++++++++++--------- tls_codec/derive/tests/encode.rs | 71 ++++++++++++--- 2 files changed, 158 insertions(+), 56 deletions(-) diff --git a/tls_codec/derive/tests/decode.rs b/tls_codec/derive/tests/decode.rs index 7717b8c12..f26310bc0 100644 --- a/tls_codec/derive/tests/decode.rs +++ b/tls_codec/derive/tests/decode.rs @@ -1,11 +1,14 @@ -use tls_codec::{ - Deserialize, Error, Serialize, Size, TlsSliceU16, TlsVecU16, TlsVecU32, TlsVecU8, VLBytes, -}; -use tls_codec_derive::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize}; - -#[derive( - TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, Clone, Copy, TlsSize, TlsSerialize, -)] +use tls_codec::{TlsVecU16, TlsVecU32, TlsVecU8, VLBytes}; +use tls_codec_derive::{TlsDeserializeBytes, TlsSize}; + +#[cfg(feature = "std")] +use tls_codec::{Deserialize, Error, Serialize, Size, TlsSliceU16}; + +#[cfg(feature = "std")] +use tls_codec_derive::{TlsDeserialize, TlsSerialize}; + +#[derive(TlsDeserializeBytes, Debug, PartialEq, Clone, Copy, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] #[repr(u16)] pub enum ExtensionType { Reserved = 0, @@ -23,31 +26,35 @@ impl Default for ExtensionType { } } -#[derive( - TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, TlsSerialize, TlsSize, Clone, Default, -)] +#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize, Clone, Default)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] pub struct ExtensionStruct { extension_type: ExtensionType, extension_data: TlsVecU32, } -#[derive(TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, TlsSize, TlsSerialize)] +#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] pub struct ExtensionTypeVec { data: TlsVecU8, } -#[derive(TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, TlsSize, TlsSerialize)] +#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] pub struct ArrayWrap { data: [u8; 8], } -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] pub struct TupleStruct1(ExtensionStruct); -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] pub struct TupleStruct(ExtensionStruct, u8); #[test] +#[cfg(feature = "std")] fn tuple_struct() { let ext = ExtensionStruct { extension_type: ExtensionType::KeyId, @@ -89,6 +96,7 @@ fn tuple_struct() { } #[test] +#[cfg(feature = "std")] fn simple_enum() { let b = &[0u8, 5] as &[u8]; let mut b_reader = b; @@ -116,6 +124,7 @@ fn simple_enum() { } #[test] +#[cfg(feature = "std")] fn deserialize_tls_vec() { let long_vector = vec![ExtensionStruct::default(); 3000]; let serialized_long_vec = TlsSliceU16(&long_vector).tls_serialize_detached().unwrap(); @@ -138,6 +147,7 @@ fn deserialize_tls_vec() { } #[test] +#[cfg(feature = "std")] fn byte_arrays() { let x = [0u8, 1, 2, 3]; let serialized = x.tls_serialize_detached().unwrap(); @@ -156,6 +166,7 @@ fn byte_arrays() { } #[test] +#[cfg(feature = "std")] fn simple_struct() { let mut b = &[0u8, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5] as &[u8]; let extension = ExtensionStruct { @@ -178,50 +189,60 @@ fn simple_struct() { assert_eq!(extension, deserialized); } -#[derive(TlsDeserialize, TlsDeserializeBytes, Clone, TlsSize, PartialEq)] +#[derive(TlsDeserializeBytes, Clone, TlsSize, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsDeserialize))] struct DeserializeOnlyStruct(u16); // KAT from MLS -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] #[repr(u8)] enum ProtocolVersion { Reserved = 0, Mls10 = 1, } -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct CipherSuite(u16); -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct HPKEPublicKey(TlsVecU16); -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct CredentialType(u16); -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct SignatureScheme(u16); -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct BasicCredential { identity: TlsVecU16, signature_scheme: SignatureScheme, signature_key: TlsVecU16, } -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct Credential { credential_type: CredentialType, credential: BasicCredential, } -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct Extension { extension_type: ExtensionType, extension_data: TlsVecU32, } -#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct KeyPackage { version: ProtocolVersion, cipher_suite: CipherSuite, @@ -232,6 +253,7 @@ struct KeyPackage { } #[test] +#[cfg(feature = "std")] fn kat_mls_key_package() { let key_package_bytes = &[ 0x01u8, 0x00, 0x01, 0x00, 0x20, 0xF2, 0xBC, 0xD8, 0x95, 0x19, 0xDD, 0x1D, 0x06, 0x9F, 0x8B, @@ -260,7 +282,8 @@ fn kat_mls_key_package() { ); } -#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct Custom { #[tls_codec(with = "custom")] values: Vec, @@ -268,23 +291,30 @@ struct Custom { } mod custom { + use tls_codec::{Size, TlsByteSliceU32}; + + #[cfg(feature = "std")] use std::io::{Read, Write}; - use tls_codec::{Deserialize, Serialize, Size, TlsByteSliceU32, TlsByteVecU32}; + #[cfg(feature = "std")] + use tls_codec::{Deserialize, Serialize, TlsByteVecU32}; pub fn tls_serialized_len(v: &[u8]) -> usize { TlsByteSliceU32(v).tls_serialized_len() } + #[cfg(feature = "std")] pub fn tls_serialize(v: &[u8], writer: &mut W) -> Result { TlsByteSliceU32(v).tls_serialize(writer) } + #[cfg(feature = "std")] pub fn tls_deserialize(bytes: &mut R) -> Result, tls_codec::Error> { Ok(TlsByteVecU32::tls_deserialize(bytes)?.into_vec()) } } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] struct CustomBytes { #[tls_codec(with = "custom_bytes")] values: Vec, @@ -292,13 +322,18 @@ struct CustomBytes { } mod custom_bytes { + use tls_codec::{DeserializeBytes, Size, TlsByteSliceU32, TlsByteVecU32}; + + #[cfg(feature = "std")] use std::io::Write; - use tls_codec::{DeserializeBytes, Serialize, Size, TlsByteSliceU32, TlsByteVecU32}; + #[cfg(feature = "std")] + use tls_codec::Serialize; pub fn tls_serialized_len(v: &[u8]) -> usize { TlsByteSliceU32(v).tls_serialized_len() } + #[cfg(feature = "std")] pub fn tls_serialize(v: &[u8], writer: &mut W) -> Result { TlsByteSliceU32(v).tls_serialize(writer) } @@ -307,9 +342,11 @@ mod custom_bytes { let (vec, remainder) = TlsByteVecU32::tls_deserialize(bytes)?; Ok((vec.into_vec(), remainder)) } + // pub fn tls_deserialize(bytes: &mut R) -> Result<(Vec, &R), tls_codec::Error> {} } #[test] +#[cfg(feature = "std")] fn custom() { let x = Custom { values: vec![0, 1, 2], @@ -320,13 +357,15 @@ fn custom() { assert_eq!(x, deserialized); } -#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] #[repr(u8)] enum EnumWithTupleVariant { A(u8, u32), } #[test] +#[cfg(feature = "std")] fn enum_with_tuple_variant() { let x = EnumWithTupleVariant::A(3, 4); let serialized = x.tls_serialize_detached().unwrap(); @@ -334,13 +373,15 @@ fn enum_with_tuple_variant() { assert_eq!(deserialized, x); } -#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] #[repr(u8)] enum EnumWithStructVariant { A { foo: u8, bar: u32 }, } #[test] +#[cfg(feature = "std")] fn enum_with_struct_variant() { let x = EnumWithStructVariant::A { foo: 3, bar: 4 }; let serialized = x.tls_serialize_detached().unwrap(); @@ -348,7 +389,8 @@ fn enum_with_struct_variant() { assert_eq!(deserialized, x); } -#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] #[repr(u16)] enum EnumWithDataAndDiscriminant { #[tls_codec(discriminant = 3)] @@ -357,6 +399,7 @@ enum EnumWithDataAndDiscriminant { } #[test] +#[cfg(feature = "std")] fn enum_with_data_and_discriminant() { for x in [ EnumWithDataAndDiscriminant::A(4), @@ -382,7 +425,8 @@ mod discriminant { } } -#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] #[repr(u16)] enum EnumWithDataAndConstDiscriminant { #[tls_codec(discriminant = "discriminant::test::constant::TEST_CONST")] @@ -394,6 +438,7 @@ enum EnumWithDataAndConstDiscriminant { } #[test] +#[cfg(feature = "std")] fn enum_with_data_and_const_discriminant() { for x in [ EnumWithDataAndConstDiscriminant::A(4), @@ -407,13 +452,15 @@ fn enum_with_data_and_const_discriminant() { } } -#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] +#[cfg(feature = "std")] +#[derive(Debug, PartialEq, TlsSize, TlsSerialize, TlsDeserialize)] #[repr(u8)] enum EnumWithCustomSerializedField { A(#[tls_codec(with = "custom")] Vec), } #[test] +#[cfg(feature = "std")] fn enum_with_custom_serialized_field() { let x = EnumWithCustomSerializedField::A(vec![1, 2, 3]); let serialized = x.tls_serialize_detached().unwrap(); @@ -421,24 +468,28 @@ fn enum_with_custom_serialized_field() { assert_eq!(deserialized, x); } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] #[repr(u8)] enum EnumWithCustomSerializedFieldBytes { A(#[tls_codec(with = "custom_bytes")] Vec), } // Variable length vectors -#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct MyContainer { value: Vec, } -#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] +#[derive(Debug, PartialEq, TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct MyByteContainer { value: VLBytes, } #[test] +#[cfg(feature = "std")] fn simple_variable_length_struct() { let val = MyContainer { value: vec![1, 2, 3, 4, 5, 6, 7, 8, 9], @@ -456,6 +507,7 @@ fn simple_variable_length_struct() { } #[test] +#[cfg(feature = "std")] fn that_skip_attribute_on_struct_works() { fn test(test: &[u8], expected: T) where @@ -469,7 +521,8 @@ fn that_skip_attribute_on_struct_works() { assert_eq!(expected, got); } - #[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSize)] + #[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsDeserialize))] struct StructWithSkip1 { #[tls_codec(skip)] a: u8, @@ -477,7 +530,8 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsDeserialize, TlsSize)] + #[derive(Debug, PartialEq, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsDeserialize))] struct StructWithSkip2 { a: u8, #[tls_codec(skip)] @@ -485,7 +539,8 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsDeserialize, TlsSize)] + #[derive(Debug, PartialEq, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsDeserialize))] struct StructWithSkip3 { a: u8, b: u8, @@ -499,8 +554,10 @@ fn that_skip_attribute_on_struct_works() { } #[test] +#[cfg(feature = "std")] fn generic_struct() { - #[derive(PartialEq, Eq, Debug, TlsSize, TlsSerialize, TlsDeserialize)] + #[derive(PartialEq, Eq, Debug, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] struct GenericStruct where T: Size + Serialize + Deserialize, @@ -518,7 +575,8 @@ fn generic_struct() { assert_eq!(deserialized, insta); } -#[derive(TlsDeserialize, TlsSerialize, TlsSize)] +#[cfg(feature = "std")] +#[derive(TlsSerialize, TlsDeserialize, TlsSize)] #[repr(u16)] enum TypeWithUnknowns { First = 1, @@ -526,6 +584,7 @@ enum TypeWithUnknowns { } #[test] +#[cfg(feature = "std")] fn type_with_unknowns() { let incoming = [0x00u8, 0x03]; // This must be parsed into TypeWithUnknowns into an unknown let deserialized = TypeWithUnknowns::tls_deserialize_exact(incoming); diff --git a/tls_codec/derive/tests/encode.rs b/tls_codec/derive/tests/encode.rs index e4047678e..926ce0220 100644 --- a/tls_codec/derive/tests/encode.rs +++ b/tls_codec/derive/tests/encode.rs @@ -1,7 +1,14 @@ -use tls_codec::{SecretTlsVecU16, Serialize, Size, TlsSliceU16, TlsVecU16, TlsVecU32}; -use tls_codec_derive::{TlsSerialize, TlsSize}; +use tls_codec::{SecretTlsVecU16, Serialize, TlsSliceU16, TlsVecU16, TlsVecU32}; +use tls_codec_derive::TlsSize; -#[derive(TlsSerialize, TlsSize, Debug)] +#[cfg(feature = "std")] +use tls_codec::Size; + +#[cfg(feature = "std")] +use tls_codec_derive::TlsSerialize; + +#[derive(TlsSize, Debug)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] #[repr(u16)] pub enum ExtensionType { Reserved = 0, @@ -13,32 +20,38 @@ pub enum ExtensionType { SomethingElse = 500, } -#[derive(TlsSerialize, TlsSize, Debug)] +#[derive(TlsSize, Debug)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] pub struct ExtensionStruct { extension_type: ExtensionType, extension_data: TlsVecU32, additional_data: Option>, } -#[derive(TlsSerialize, TlsSize, Debug)] +#[derive(TlsSize, Debug)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] pub struct TupleStruct(ExtensionStruct, u8); -#[derive(TlsSerialize, TlsSize, Debug)] +#[derive(TlsSize, Debug)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] pub struct StructWithLifetime<'a> { value: &'a TlsVecU16, } -#[derive(TlsSerialize, TlsSize, Debug, Clone)] +#[derive(TlsSize, Debug, Clone)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] struct SomeValue { val: TlsVecU16, } -#[derive(TlsSerialize, TlsSize)] +#[derive(TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] pub struct StructWithDoubleLifetime<'a, 'b> { value: &'a TlsSliceU16<'a, &'b SomeValue>, } #[test] +#[cfg(feature = "std")] fn lifetime_struct() { let value: TlsVecU16 = vec![7u8; 33].into(); let s = StructWithLifetime { value: &value }; @@ -60,6 +73,7 @@ fn lifetime_struct() { } #[test] +#[cfg(feature = "std")] fn simple_enum() { let serialized = ExtensionType::KeyId.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 3], serialized); @@ -70,6 +84,7 @@ fn simple_enum() { } #[test] +#[cfg(feature = "std")] fn simple_struct() { let extension = ExtensionStruct { extension_type: ExtensionType::KeyId, @@ -81,6 +96,7 @@ fn simple_struct() { } #[test] +#[cfg(feature = "std")] fn tuple_struct() { let ext = ExtensionStruct { extension_type: ExtensionType::KeyId, @@ -100,6 +116,7 @@ fn byte_arrays() { } #[test] +#[cfg(feature = "std")] fn lifetimes() { let x = vec![1, 2, 3, 4].into(); let s = StructWithLifetime { value: &x }; @@ -113,7 +130,8 @@ fn lifetimes() { assert_eq!(vec![0, 4, 1, 2, 3, 4], serialized); } -#[derive(TlsSerialize, TlsSize)] +#[derive(TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] struct Custom { #[tls_codec(with = "custom")] values: Vec, @@ -121,19 +139,26 @@ struct Custom { } mod custom { + use tls_codec::{Size, TlsByteSliceU32}; + + #[cfg(feature = "std")] use std::io::Write; - use tls_codec::{Serialize, Size, TlsByteSliceU32}; + + #[cfg(feature = "std")] + use tls_codec::Serialize; pub fn tls_serialized_len(v: &[u8]) -> usize { TlsByteSliceU32(v).tls_serialized_len() } + #[cfg(feature = "std")] pub fn tls_serialize(v: &[u8], writer: &mut W) -> Result { TlsByteSliceU32(v).tls_serialize(writer) } } #[test] +#[cfg(feature = "std")] fn custom() { let x = Custom { values: vec![0, 1, 2], @@ -143,7 +168,8 @@ fn custom() { assert_eq!(vec![0, 0, 0, 3, 0, 1, 2, 3], serialized); } -#[derive(TlsSerialize, TlsSize)] +#[derive(TlsSize)] +#[cfg_attr(feature = "std", derive(TlsSerialize))] struct OptionalMemberRef<'a> { optional_member: Option<&'a u32>, ref_optional_member: &'a Option<&'a u32>, @@ -151,6 +177,7 @@ struct OptionalMemberRef<'a> { } #[test] +#[cfg(feature = "std")] fn optional_member() { let m = 6; let v = vec![1, 2, 3]; @@ -163,6 +190,7 @@ fn optional_member() { assert_eq!(vec![1, 0, 0, 0, 6, 0, 0, 6, 0, 1, 0, 2, 0, 3], serialized); } +#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithTupleVariant { @@ -170,12 +198,14 @@ enum EnumWithTupleVariant { } #[test] +#[cfg(feature = "std")] fn enum_with_tuple_variant() { let x = EnumWithTupleVariant::A(3, 4); let serialized = x.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 3, 0, 0, 0, 4], serialized); } +#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithStructVariant { @@ -183,12 +213,14 @@ enum EnumWithStructVariant { } #[test] +#[cfg(feature = "std")] fn enum_with_struct_variant() { let x = EnumWithStructVariant::A { foo: 3, bar: 4 }; let serialized = x.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 3, 0, 0, 0, 4], serialized); } +#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u16)] enum EnumWithDataAndDiscriminant { @@ -198,6 +230,7 @@ enum EnumWithDataAndDiscriminant { } #[test] +#[cfg(feature = "std")] fn enum_with_data_and_discriminant() { let x = EnumWithDataAndDiscriminant::A(4); let serialized = x.tls_serialize_detached().unwrap(); @@ -205,12 +238,14 @@ fn enum_with_data_and_discriminant() { } #[test] +#[cfg(feature = "std")] fn discriminant_is_incremented_implicitly() { let x = EnumWithDataAndDiscriminant::B; let serialized = x.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 4], serialized); } +#[cfg(feature = "std")] mod discriminant { pub mod test { pub mod constant { @@ -224,6 +259,7 @@ mod discriminant { } } +#[cfg(feature = "std")] #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] #[repr(u16)] enum EnumWithDataAndConstDiscriminant { @@ -236,6 +272,7 @@ enum EnumWithDataAndConstDiscriminant { } #[test] +#[cfg(feature = "std")] fn enum_with_data_and_const_discriminant() { let serialized = EnumWithDataAndConstDiscriminant::A(4) .tls_serialize_detached() @@ -251,6 +288,7 @@ fn enum_with_data_and_const_discriminant() { assert_eq!(vec![0, 12], serialized); } +#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithCustomSerializedField { @@ -258,6 +296,7 @@ enum EnumWithCustomSerializedField { } #[test] +#[cfg(feature = "std")] fn enum_with_custom_serialized_field() { let x = EnumWithCustomSerializedField::A(vec![1, 2, 3]); let serialized = x.tls_serialize_detached().unwrap(); @@ -265,6 +304,7 @@ fn enum_with_custom_serialized_field() { } #[test] +#[cfg(feature = "std")] fn that_skip_attribute_on_struct_works() { fn test(test: T, expected: &[u8]) where @@ -277,7 +317,8 @@ fn that_skip_attribute_on_struct_works() { assert_eq!(test.tls_serialize_detached().unwrap(), expected); } - #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] + #[derive(Debug, PartialEq, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsSerialize))] struct StructWithSkip1 { #[tls_codec(skip)] a: u8, @@ -285,7 +326,8 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] + #[derive(Debug, PartialEq, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsSerialize))] struct StructWithSkip2 { a: u8, #[tls_codec(skip)] @@ -293,7 +335,8 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] + #[derive(Debug, PartialEq, TlsSize)] + #[cfg_attr(feature = "std", derive(TlsSerialize))] struct StructWithSkip3 { a: u8, b: u8, From d602da3bb59c19703faf6294260abb3d294d0662 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 17:15:50 +0530 Subject: [PATCH 44/58] test all features for tls_codec_derive --- .github/workflows/tls_codec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tls_codec.yml b/.github/workflows/tls_codec.yml index f66ea38b2..87e59bb17 100644 --- a/.github/workflows/tls_codec.yml +++ b/.github/workflows/tls_codec.yml @@ -70,4 +70,4 @@ jobs: - run: ${{ matrix.deps }} - uses: RustCrypto/actions/cargo-hack-install@master - run: cargo hack test --feature-powerset - - run: cargo hack test -p tls_codec_derive --test encode\* --test decode\* + - run: cargo hack test -p tls_codec_derive --feature-powerset --test encode\* --test decode\* From c5b2e6112bb3acfdae12e9abbc725e23d4e0975b Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 18:32:04 +0530 Subject: [PATCH 45/58] Revert "fix tests" This reverts commit 640fa2ae8037d577f295904ee6a60514a329a54a. --- tls_codec/derive/tests/decode.rs | 143 +++++++++---------------------- tls_codec/derive/tests/encode.rs | 71 +++------------ 2 files changed, 56 insertions(+), 158 deletions(-) diff --git a/tls_codec/derive/tests/decode.rs b/tls_codec/derive/tests/decode.rs index f26310bc0..7717b8c12 100644 --- a/tls_codec/derive/tests/decode.rs +++ b/tls_codec/derive/tests/decode.rs @@ -1,14 +1,11 @@ -use tls_codec::{TlsVecU16, TlsVecU32, TlsVecU8, VLBytes}; -use tls_codec_derive::{TlsDeserializeBytes, TlsSize}; - -#[cfg(feature = "std")] -use tls_codec::{Deserialize, Error, Serialize, Size, TlsSliceU16}; - -#[cfg(feature = "std")] -use tls_codec_derive::{TlsDeserialize, TlsSerialize}; - -#[derive(TlsDeserializeBytes, Debug, PartialEq, Clone, Copy, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +use tls_codec::{ + Deserialize, Error, Serialize, Size, TlsSliceU16, TlsVecU16, TlsVecU32, TlsVecU8, VLBytes, +}; +use tls_codec_derive::{TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize}; + +#[derive( + TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, Clone, Copy, TlsSize, TlsSerialize, +)] #[repr(u16)] pub enum ExtensionType { Reserved = 0, @@ -26,35 +23,31 @@ impl Default for ExtensionType { } } -#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize, Clone, Default)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive( + TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, TlsSerialize, TlsSize, Clone, Default, +)] pub struct ExtensionStruct { extension_type: ExtensionType, extension_data: TlsVecU32, } -#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, TlsSize, TlsSerialize)] pub struct ExtensionTypeVec { data: TlsVecU8, } -#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsDeserialize, TlsDeserializeBytes, Debug, PartialEq, TlsSize, TlsSerialize)] pub struct ArrayWrap { data: [u8; 8], } -#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] pub struct TupleStruct1(ExtensionStruct); -#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] pub struct TupleStruct(ExtensionStruct, u8); #[test] -#[cfg(feature = "std")] fn tuple_struct() { let ext = ExtensionStruct { extension_type: ExtensionType::KeyId, @@ -96,7 +89,6 @@ fn tuple_struct() { } #[test] -#[cfg(feature = "std")] fn simple_enum() { let b = &[0u8, 5] as &[u8]; let mut b_reader = b; @@ -124,7 +116,6 @@ fn simple_enum() { } #[test] -#[cfg(feature = "std")] fn deserialize_tls_vec() { let long_vector = vec![ExtensionStruct::default(); 3000]; let serialized_long_vec = TlsSliceU16(&long_vector).tls_serialize_detached().unwrap(); @@ -147,7 +138,6 @@ fn deserialize_tls_vec() { } #[test] -#[cfg(feature = "std")] fn byte_arrays() { let x = [0u8, 1, 2, 3]; let serialized = x.tls_serialize_detached().unwrap(); @@ -166,7 +156,6 @@ fn byte_arrays() { } #[test] -#[cfg(feature = "std")] fn simple_struct() { let mut b = &[0u8, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5] as &[u8]; let extension = ExtensionStruct { @@ -189,60 +178,50 @@ fn simple_struct() { assert_eq!(extension, deserialized); } -#[derive(TlsDeserializeBytes, Clone, TlsSize, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsDeserialize))] +#[derive(TlsDeserialize, TlsDeserializeBytes, Clone, TlsSize, PartialEq)] struct DeserializeOnlyStruct(u16); // KAT from MLS -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] #[repr(u8)] enum ProtocolVersion { Reserved = 0, Mls10 = 1, } -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct CipherSuite(u16); -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct HPKEPublicKey(TlsVecU16); -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct CredentialType(u16); -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct SignatureScheme(u16); -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct BasicCredential { identity: TlsVecU16, signature_scheme: SignatureScheme, signature_key: TlsVecU16, } -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct Credential { credential_type: CredentialType, credential: BasicCredential, } -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct Extension { extension_type: ExtensionType, extension_data: TlsVecU32, } -#[derive(TlsDeserializeBytes, TlsSize, Clone, PartialEq)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(TlsSerialize, TlsDeserialize, TlsDeserializeBytes, TlsSize, Clone, PartialEq)] struct KeyPackage { version: ProtocolVersion, cipher_suite: CipherSuite, @@ -253,7 +232,6 @@ struct KeyPackage { } #[test] -#[cfg(feature = "std")] fn kat_mls_key_package() { let key_package_bytes = &[ 0x01u8, 0x00, 0x01, 0x00, 0x20, 0xF2, 0xBC, 0xD8, 0x95, 0x19, 0xDD, 0x1D, 0x06, 0x9F, 0x8B, @@ -282,8 +260,7 @@ fn kat_mls_key_package() { ); } -#[derive(Debug, PartialEq, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] struct Custom { #[tls_codec(with = "custom")] values: Vec, @@ -291,30 +268,23 @@ struct Custom { } mod custom { - use tls_codec::{Size, TlsByteSliceU32}; - - #[cfg(feature = "std")] use std::io::{Read, Write}; - #[cfg(feature = "std")] - use tls_codec::{Deserialize, Serialize, TlsByteVecU32}; + use tls_codec::{Deserialize, Serialize, Size, TlsByteSliceU32, TlsByteVecU32}; pub fn tls_serialized_len(v: &[u8]) -> usize { TlsByteSliceU32(v).tls_serialized_len() } - #[cfg(feature = "std")] pub fn tls_serialize(v: &[u8], writer: &mut W) -> Result { TlsByteSliceU32(v).tls_serialize(writer) } - #[cfg(feature = "std")] pub fn tls_deserialize(bytes: &mut R) -> Result, tls_codec::Error> { Ok(TlsByteVecU32::tls_deserialize(bytes)?.into_vec()) } } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSerialize, TlsSize)] struct CustomBytes { #[tls_codec(with = "custom_bytes")] values: Vec, @@ -322,18 +292,13 @@ struct CustomBytes { } mod custom_bytes { - use tls_codec::{DeserializeBytes, Size, TlsByteSliceU32, TlsByteVecU32}; - - #[cfg(feature = "std")] use std::io::Write; - #[cfg(feature = "std")] - use tls_codec::Serialize; + use tls_codec::{DeserializeBytes, Serialize, Size, TlsByteSliceU32, TlsByteVecU32}; pub fn tls_serialized_len(v: &[u8]) -> usize { TlsByteSliceU32(v).tls_serialized_len() } - #[cfg(feature = "std")] pub fn tls_serialize(v: &[u8], writer: &mut W) -> Result { TlsByteSliceU32(v).tls_serialize(writer) } @@ -342,11 +307,9 @@ mod custom_bytes { let (vec, remainder) = TlsByteVecU32::tls_deserialize(bytes)?; Ok((vec.into_vec(), remainder)) } - // pub fn tls_deserialize(bytes: &mut R) -> Result<(Vec, &R), tls_codec::Error> {} } #[test] -#[cfg(feature = "std")] fn custom() { let x = Custom { values: vec![0, 1, 2], @@ -357,15 +320,13 @@ fn custom() { assert_eq!(x, deserialized); } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithTupleVariant { A(u8, u32), } #[test] -#[cfg(feature = "std")] fn enum_with_tuple_variant() { let x = EnumWithTupleVariant::A(3, 4); let serialized = x.tls_serialize_detached().unwrap(); @@ -373,15 +334,13 @@ fn enum_with_tuple_variant() { assert_eq!(deserialized, x); } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithStructVariant { A { foo: u8, bar: u32 }, } #[test] -#[cfg(feature = "std")] fn enum_with_struct_variant() { let x = EnumWithStructVariant::A { foo: 3, bar: 4 }; let serialized = x.tls_serialize_detached().unwrap(); @@ -389,8 +348,7 @@ fn enum_with_struct_variant() { assert_eq!(deserialized, x); } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u16)] enum EnumWithDataAndDiscriminant { #[tls_codec(discriminant = 3)] @@ -399,7 +357,6 @@ enum EnumWithDataAndDiscriminant { } #[test] -#[cfg(feature = "std")] fn enum_with_data_and_discriminant() { for x in [ EnumWithDataAndDiscriminant::A(4), @@ -425,8 +382,7 @@ mod discriminant { } } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u16)] enum EnumWithDataAndConstDiscriminant { #[tls_codec(discriminant = "discriminant::test::constant::TEST_CONST")] @@ -438,7 +394,6 @@ enum EnumWithDataAndConstDiscriminant { } #[test] -#[cfg(feature = "std")] fn enum_with_data_and_const_discriminant() { for x in [ EnumWithDataAndConstDiscriminant::A(4), @@ -452,15 +407,13 @@ fn enum_with_data_and_const_discriminant() { } } -#[cfg(feature = "std")] -#[derive(Debug, PartialEq, TlsSize, TlsSerialize, TlsDeserialize)] +#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithCustomSerializedField { A(#[tls_codec(with = "custom")] Vec), } #[test] -#[cfg(feature = "std")] fn enum_with_custom_serialized_field() { let x = EnumWithCustomSerializedField::A(vec![1, 2, 3]); let serialized = x.tls_serialize_detached().unwrap(); @@ -468,28 +421,24 @@ fn enum_with_custom_serialized_field() { assert_eq!(deserialized, x); } -#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithCustomSerializedFieldBytes { A(#[tls_codec(with = "custom_bytes")] Vec), } // Variable length vectors -#[derive(Debug, PartialEq, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] struct MyContainer { value: Vec, } -#[derive(Debug, PartialEq, TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] +#[derive(Debug, PartialEq, TlsDeserialize, TlsSerialize, TlsSize)] struct MyByteContainer { value: VLBytes, } #[test] -#[cfg(feature = "std")] fn simple_variable_length_struct() { let val = MyContainer { value: vec![1, 2, 3, 4, 5, 6, 7, 8, 9], @@ -507,7 +456,6 @@ fn simple_variable_length_struct() { } #[test] -#[cfg(feature = "std")] fn that_skip_attribute_on_struct_works() { fn test(test: &[u8], expected: T) where @@ -521,8 +469,7 @@ fn that_skip_attribute_on_struct_works() { assert_eq!(expected, got); } - #[derive(Debug, PartialEq, TlsDeserializeBytes, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsDeserialize))] + #[derive(Debug, PartialEq, TlsDeserialize, TlsDeserializeBytes, TlsSize)] struct StructWithSkip1 { #[tls_codec(skip)] a: u8, @@ -530,8 +477,7 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsDeserialize))] + #[derive(Debug, PartialEq, TlsDeserialize, TlsSize)] struct StructWithSkip2 { a: u8, #[tls_codec(skip)] @@ -539,8 +485,7 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsDeserialize))] + #[derive(Debug, PartialEq, TlsDeserialize, TlsSize)] struct StructWithSkip3 { a: u8, b: u8, @@ -554,10 +499,8 @@ fn that_skip_attribute_on_struct_works() { } #[test] -#[cfg(feature = "std")] fn generic_struct() { - #[derive(PartialEq, Eq, Debug, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsSerialize, TlsDeserialize))] + #[derive(PartialEq, Eq, Debug, TlsSize, TlsSerialize, TlsDeserialize)] struct GenericStruct where T: Size + Serialize + Deserialize, @@ -575,8 +518,7 @@ fn generic_struct() { assert_eq!(deserialized, insta); } -#[cfg(feature = "std")] -#[derive(TlsSerialize, TlsDeserialize, TlsSize)] +#[derive(TlsDeserialize, TlsSerialize, TlsSize)] #[repr(u16)] enum TypeWithUnknowns { First = 1, @@ -584,7 +526,6 @@ enum TypeWithUnknowns { } #[test] -#[cfg(feature = "std")] fn type_with_unknowns() { let incoming = [0x00u8, 0x03]; // This must be parsed into TypeWithUnknowns into an unknown let deserialized = TypeWithUnknowns::tls_deserialize_exact(incoming); diff --git a/tls_codec/derive/tests/encode.rs b/tls_codec/derive/tests/encode.rs index 926ce0220..e4047678e 100644 --- a/tls_codec/derive/tests/encode.rs +++ b/tls_codec/derive/tests/encode.rs @@ -1,14 +1,7 @@ -use tls_codec::{SecretTlsVecU16, Serialize, TlsSliceU16, TlsVecU16, TlsVecU32}; -use tls_codec_derive::TlsSize; +use tls_codec::{SecretTlsVecU16, Serialize, Size, TlsSliceU16, TlsVecU16, TlsVecU32}; +use tls_codec_derive::{TlsSerialize, TlsSize}; -#[cfg(feature = "std")] -use tls_codec::Size; - -#[cfg(feature = "std")] -use tls_codec_derive::TlsSerialize; - -#[derive(TlsSize, Debug)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize, Debug)] #[repr(u16)] pub enum ExtensionType { Reserved = 0, @@ -20,38 +13,32 @@ pub enum ExtensionType { SomethingElse = 500, } -#[derive(TlsSize, Debug)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize, Debug)] pub struct ExtensionStruct { extension_type: ExtensionType, extension_data: TlsVecU32, additional_data: Option>, } -#[derive(TlsSize, Debug)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize, Debug)] pub struct TupleStruct(ExtensionStruct, u8); -#[derive(TlsSize, Debug)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize, Debug)] pub struct StructWithLifetime<'a> { value: &'a TlsVecU16, } -#[derive(TlsSize, Debug, Clone)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize, Debug, Clone)] struct SomeValue { val: TlsVecU16, } -#[derive(TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize)] pub struct StructWithDoubleLifetime<'a, 'b> { value: &'a TlsSliceU16<'a, &'b SomeValue>, } #[test] -#[cfg(feature = "std")] fn lifetime_struct() { let value: TlsVecU16 = vec![7u8; 33].into(); let s = StructWithLifetime { value: &value }; @@ -73,7 +60,6 @@ fn lifetime_struct() { } #[test] -#[cfg(feature = "std")] fn simple_enum() { let serialized = ExtensionType::KeyId.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 3], serialized); @@ -84,7 +70,6 @@ fn simple_enum() { } #[test] -#[cfg(feature = "std")] fn simple_struct() { let extension = ExtensionStruct { extension_type: ExtensionType::KeyId, @@ -96,7 +81,6 @@ fn simple_struct() { } #[test] -#[cfg(feature = "std")] fn tuple_struct() { let ext = ExtensionStruct { extension_type: ExtensionType::KeyId, @@ -116,7 +100,6 @@ fn byte_arrays() { } #[test] -#[cfg(feature = "std")] fn lifetimes() { let x = vec![1, 2, 3, 4].into(); let s = StructWithLifetime { value: &x }; @@ -130,8 +113,7 @@ fn lifetimes() { assert_eq!(vec![0, 4, 1, 2, 3, 4], serialized); } -#[derive(TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize)] struct Custom { #[tls_codec(with = "custom")] values: Vec, @@ -139,26 +121,19 @@ struct Custom { } mod custom { - use tls_codec::{Size, TlsByteSliceU32}; - - #[cfg(feature = "std")] use std::io::Write; - - #[cfg(feature = "std")] - use tls_codec::Serialize; + use tls_codec::{Serialize, Size, TlsByteSliceU32}; pub fn tls_serialized_len(v: &[u8]) -> usize { TlsByteSliceU32(v).tls_serialized_len() } - #[cfg(feature = "std")] pub fn tls_serialize(v: &[u8], writer: &mut W) -> Result { TlsByteSliceU32(v).tls_serialize(writer) } } #[test] -#[cfg(feature = "std")] fn custom() { let x = Custom { values: vec![0, 1, 2], @@ -168,8 +143,7 @@ fn custom() { assert_eq!(vec![0, 0, 0, 3, 0, 1, 2, 3], serialized); } -#[derive(TlsSize)] -#[cfg_attr(feature = "std", derive(TlsSerialize))] +#[derive(TlsSerialize, TlsSize)] struct OptionalMemberRef<'a> { optional_member: Option<&'a u32>, ref_optional_member: &'a Option<&'a u32>, @@ -177,7 +151,6 @@ struct OptionalMemberRef<'a> { } #[test] -#[cfg(feature = "std")] fn optional_member() { let m = 6; let v = vec![1, 2, 3]; @@ -190,7 +163,6 @@ fn optional_member() { assert_eq!(vec![1, 0, 0, 0, 6, 0, 0, 6, 0, 1, 0, 2, 0, 3], serialized); } -#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithTupleVariant { @@ -198,14 +170,12 @@ enum EnumWithTupleVariant { } #[test] -#[cfg(feature = "std")] fn enum_with_tuple_variant() { let x = EnumWithTupleVariant::A(3, 4); let serialized = x.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 3, 0, 0, 0, 4], serialized); } -#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithStructVariant { @@ -213,14 +183,12 @@ enum EnumWithStructVariant { } #[test] -#[cfg(feature = "std")] fn enum_with_struct_variant() { let x = EnumWithStructVariant::A { foo: 3, bar: 4 }; let serialized = x.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 3, 0, 0, 0, 4], serialized); } -#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u16)] enum EnumWithDataAndDiscriminant { @@ -230,7 +198,6 @@ enum EnumWithDataAndDiscriminant { } #[test] -#[cfg(feature = "std")] fn enum_with_data_and_discriminant() { let x = EnumWithDataAndDiscriminant::A(4); let serialized = x.tls_serialize_detached().unwrap(); @@ -238,14 +205,12 @@ fn enum_with_data_and_discriminant() { } #[test] -#[cfg(feature = "std")] fn discriminant_is_incremented_implicitly() { let x = EnumWithDataAndDiscriminant::B; let serialized = x.tls_serialize_detached().unwrap(); assert_eq!(vec![0, 4], serialized); } -#[cfg(feature = "std")] mod discriminant { pub mod test { pub mod constant { @@ -259,7 +224,6 @@ mod discriminant { } } -#[cfg(feature = "std")] #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] #[repr(u16)] enum EnumWithDataAndConstDiscriminant { @@ -272,7 +236,6 @@ enum EnumWithDataAndConstDiscriminant { } #[test] -#[cfg(feature = "std")] fn enum_with_data_and_const_discriminant() { let serialized = EnumWithDataAndConstDiscriminant::A(4) .tls_serialize_detached() @@ -288,7 +251,6 @@ fn enum_with_data_and_const_discriminant() { assert_eq!(vec![0, 12], serialized); } -#[cfg(feature = "std")] #[derive(TlsSerialize, TlsSize)] #[repr(u8)] enum EnumWithCustomSerializedField { @@ -296,7 +258,6 @@ enum EnumWithCustomSerializedField { } #[test] -#[cfg(feature = "std")] fn enum_with_custom_serialized_field() { let x = EnumWithCustomSerializedField::A(vec![1, 2, 3]); let serialized = x.tls_serialize_detached().unwrap(); @@ -304,7 +265,6 @@ fn enum_with_custom_serialized_field() { } #[test] -#[cfg(feature = "std")] fn that_skip_attribute_on_struct_works() { fn test(test: T, expected: &[u8]) where @@ -317,8 +277,7 @@ fn that_skip_attribute_on_struct_works() { assert_eq!(test.tls_serialize_detached().unwrap(), expected); } - #[derive(Debug, PartialEq, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsSerialize))] + #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] struct StructWithSkip1 { #[tls_codec(skip)] a: u8, @@ -326,8 +285,7 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsSerialize))] + #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] struct StructWithSkip2 { a: u8, #[tls_codec(skip)] @@ -335,8 +293,7 @@ fn that_skip_attribute_on_struct_works() { c: u8, } - #[derive(Debug, PartialEq, TlsSize)] - #[cfg_attr(feature = "std", derive(TlsSerialize))] + #[derive(Debug, PartialEq, TlsSerialize, TlsSize)] struct StructWithSkip3 { a: u8, b: u8, From da63de873fd55688b22b51419e16b0127af51bd1 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 18:36:39 +0530 Subject: [PATCH 46/58] run encode/decode tests only when std feature is enabled --- tls_codec/derive/tests/decode.rs | 1 + tls_codec/derive/tests/encode.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/tls_codec/derive/tests/decode.rs b/tls_codec/derive/tests/decode.rs index 7717b8c12..107624e23 100644 --- a/tls_codec/derive/tests/decode.rs +++ b/tls_codec/derive/tests/decode.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "std")] use tls_codec::{ Deserialize, Error, Serialize, Size, TlsSliceU16, TlsVecU16, TlsVecU32, TlsVecU8, VLBytes, }; diff --git a/tls_codec/derive/tests/encode.rs b/tls_codec/derive/tests/encode.rs index e4047678e..84b760c91 100644 --- a/tls_codec/derive/tests/encode.rs +++ b/tls_codec/derive/tests/encode.rs @@ -1,3 +1,4 @@ +#![cfg(feature = "std")] use tls_codec::{SecretTlsVecU16, Serialize, Size, TlsSliceU16, TlsVecU16, TlsVecU32}; use tls_codec_derive::{TlsSerialize, TlsSize}; From a0e0de3cec3432d355f62b58e039e999d17f3a91 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 19:00:55 +0530 Subject: [PATCH 47/58] add DeserializeBytes tests --- tls_codec/derive/tests/decode_bytes.rs | 94 ++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tls_codec/derive/tests/decode_bytes.rs diff --git a/tls_codec/derive/tests/decode_bytes.rs b/tls_codec/derive/tests/decode_bytes.rs new file mode 100644 index 000000000..0b76e8252 --- /dev/null +++ b/tls_codec/derive/tests/decode_bytes.rs @@ -0,0 +1,94 @@ +use tls_codec::{TlsVecU16, TlsVecU32, TlsVecU8}; +use tls_codec_derive::{TlsDeserializeBytes, TlsSize}; + +#[derive(TlsDeserializeBytes, Debug, PartialEq, Clone, Copy, TlsSize)] +#[repr(u16)] +pub enum ExtensionType { + Reserved = 0, + Capabilities = 1, + Lifetime = 2, + KeyId = 3, + ParentHash = 4, + RatchetTree = 5, + SomethingElse = 500, +} + +impl Default for ExtensionType { + fn default() -> Self { + Self::Reserved + } +} + +#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize, Clone, Default)] +pub struct ExtensionStruct { + extension_type: ExtensionType, + extension_data: TlsVecU32, +} + +#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] +pub struct ExtensionTypeVec { + data: TlsVecU8, +} + +#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] +pub struct ArrayWrap { + data: [u8; 8], +} + +#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +pub struct TupleStruct1(ExtensionStruct); + +#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +pub struct TupleStruct(ExtensionStruct, u8); + +#[test] +fn tuple_struct() { + let ext = ExtensionStruct { + extension_type: ExtensionType::KeyId, + extension_data: TlsVecU32::from_slice(&[1, 2, 3, 4, 5]), + }; + let t1 = TupleStruct1(ext.clone()); + let serialized_t1 = vec![0, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5]; //t1.tls_serialize_detached().unwrap(); + println!("{:?}", serialized_t1); + let (deserialized_bytes_t1, _remainder) = + ::tls_deserialize(serialized_t1.as_slice()) + .unwrap(); + assert_eq!(t1, deserialized_bytes_t1); +} + +#[test] +fn simple_enum() { + let b = &[0u8, 5] as &[u8]; + let (deserialized_bytes, _remainder) = + ::tls_deserialize(b).unwrap(); + assert_eq!(ExtensionType::RatchetTree, deserialized_bytes); + + let mut b = &[0u8, 5, 1, 244, 0, 1] as &[u8]; + let variants = [ + ExtensionType::RatchetTree, + ExtensionType::SomethingElse, + ExtensionType::Capabilities, + ]; + for variant in variants.iter() { + let (deserialized_bytes, remainder) = + ::tls_deserialize(b).unwrap(); + b = remainder; + assert_eq!(variant, &deserialized_bytes); + } +} + +#[test] +fn deserialize_tls_vec() { + let long_vector = vec![ExtensionStruct::default(); 4]; + let serialized_long_vec = [ + 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + let (deserialized_long_vec_bytes, _remainder): (Vec, &[u8]) = + as tls_codec::DeserializeBytes>::tls_deserialize( + serialized_long_vec.as_slice(), + ) + .map(|(v, r)| (v.into(), r)) + .unwrap(); + assert_eq!(long_vector.len(), deserialized_long_vec_bytes.len()); + assert_eq!(long_vector, deserialized_long_vec_bytes); +} From 710378c4685914e8c8adf72351e69142033677b1 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 19:10:45 +0530 Subject: [PATCH 48/58] add one more tuple_struct test --- tls_codec/derive/tests/decode_bytes.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tls_codec/derive/tests/decode_bytes.rs b/tls_codec/derive/tests/decode_bytes.rs index 0b76e8252..c9ee9316a 100644 --- a/tls_codec/derive/tests/decode_bytes.rs +++ b/tls_codec/derive/tests/decode_bytes.rs @@ -48,12 +48,19 @@ fn tuple_struct() { extension_data: TlsVecU32::from_slice(&[1, 2, 3, 4, 5]), }; let t1 = TupleStruct1(ext.clone()); - let serialized_t1 = vec![0, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5]; //t1.tls_serialize_detached().unwrap(); + let serialized_t1 = vec![0, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5]; println!("{:?}", serialized_t1); let (deserialized_bytes_t1, _remainder) = ::tls_deserialize(serialized_t1.as_slice()) .unwrap(); assert_eq!(t1, deserialized_bytes_t1); + + let t2 = TupleStruct(ext, 5); + let serialized_t2 = vec![0, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5, 5]; + let (deserialized_bytes_t2, _remainder) = + ::tls_deserialize(serialized_t2.as_slice()) + .unwrap(); + assert_eq!(t2, deserialized_bytes_t2); } #[test] From 5217fdc54eb9eca84c6461fa50fe3ecaf3bc0821 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 19:33:37 +0530 Subject: [PATCH 49/58] add another test --- tls_codec/derive/tests/decode_bytes.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tls_codec/derive/tests/decode_bytes.rs b/tls_codec/derive/tests/decode_bytes.rs index c9ee9316a..852f4d38d 100644 --- a/tls_codec/derive/tests/decode_bytes.rs +++ b/tls_codec/derive/tests/decode_bytes.rs @@ -99,3 +99,27 @@ fn deserialize_tls_vec() { assert_eq!(long_vector.len(), deserialized_long_vec_bytes.len()); assert_eq!(long_vector, deserialized_long_vec_bytes); } + +#[test] +fn byte_arrays() { + let x = [0u8, 1, 2, 3]; + let serialized = [0, 1, 2, 3]; + assert_eq!(x.to_vec(), serialized); + + let (deserialized, rest) = + <[u8; 4] as tls_codec::DeserializeBytes>::tls_deserialize(&mut serialized.as_slice()) + .unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); + + let x = [0u8, 1, 2, 3, 7, 6, 5, 4]; + let w = ArrayWrap { data: x }; + let serialized = [0, 1, 2, 3, 7, 6, 5, 4]; + assert_eq!(x.to_vec(), serialized); + + let (deserialized, rest) = + ::tls_deserialize(&mut serialized.as_slice()) + .unwrap(); + assert_eq!(deserialized, w); + assert_eq!(rest, []); +} From 2f7b38bcbb47b1b1becfa318793b55b043104246 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 4 Jul 2023 20:00:41 +0530 Subject: [PATCH 50/58] add proper DeserializeBytes tests --- tls_codec/derive/tests/decode_bytes.rs | 353 +++++++++++++++++++------ 1 file changed, 275 insertions(+), 78 deletions(-) diff --git a/tls_codec/derive/tests/decode_bytes.rs b/tls_codec/derive/tests/decode_bytes.rs index 852f4d38d..4a3267f01 100644 --- a/tls_codec/derive/tests/decode_bytes.rs +++ b/tls_codec/derive/tests/decode_bytes.rs @@ -1,7 +1,7 @@ -use tls_codec::{TlsVecU16, TlsVecU32, TlsVecU8}; -use tls_codec_derive::{TlsDeserializeBytes, TlsSize}; +use tls_codec::{DeserializeBytes, SerializeBytes, Size}; +use tls_codec_derive::{TlsDeserializeBytes, TlsSerializeBytes, TlsSize}; -#[derive(TlsDeserializeBytes, Debug, PartialEq, Clone, Copy, TlsSize)] +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, PartialEq, Debug)] #[repr(u16)] pub enum ExtensionType { Reserved = 0, @@ -13,113 +13,310 @@ pub enum ExtensionType { SomethingElse = 500, } -impl Default for ExtensionType { - fn default() -> Self { - Self::Reserved - } -} - -#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize, Clone, Default)] +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] pub struct ExtensionStruct { extension_type: ExtensionType, - extension_data: TlsVecU32, + extension_data: Vec, + additional_data: Option>, } -#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] -pub struct ExtensionTypeVec { - data: TlsVecU8, -} +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +pub struct TupleStruct(ExtensionStruct, u8); -#[derive(TlsDeserializeBytes, Debug, PartialEq, TlsSize)] -pub struct ArrayWrap { - data: [u8; 8], +#[derive(TlsSerializeBytes, TlsSize, Debug, Clone)] +struct SomeValue { + val: Vec, } -#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] -pub struct TupleStruct1(ExtensionStruct); +#[test] +fn simple_enum() { + let serialized = ExtensionType::KeyId.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, ExtensionType::KeyId); + assert_eq!(rest, []); + let serialized = ExtensionType::SomethingElse.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, ExtensionType::SomethingElse); + assert_eq!(rest, []); +} -#[derive(TlsDeserializeBytes, TlsSize, Debug, PartialEq)] -pub struct TupleStruct(ExtensionStruct, u8); +#[test] +fn simple_struct() { + let extension = ExtensionStruct { + extension_type: ExtensionType::KeyId, + extension_data: vec![1, 2, 3, 4, 5], + additional_data: None, + }; + let serialized = extension.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, extension); + assert_eq!(rest, []); +} #[test] fn tuple_struct() { let ext = ExtensionStruct { extension_type: ExtensionType::KeyId, - extension_data: TlsVecU32::from_slice(&[1, 2, 3, 4, 5]), + extension_data: vec![1, 2, 3, 4, 5], + additional_data: None, }; - let t1 = TupleStruct1(ext.clone()); - let serialized_t1 = vec![0, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5]; - println!("{:?}", serialized_t1); - let (deserialized_bytes_t1, _remainder) = - ::tls_deserialize(serialized_t1.as_slice()) - .unwrap(); - assert_eq!(t1, deserialized_bytes_t1); - - let t2 = TupleStruct(ext, 5); - let serialized_t2 = vec![0, 3, 0, 0, 0, 5, 1, 2, 3, 4, 5, 5]; - let (deserialized_bytes_t2, _remainder) = - ::tls_deserialize(serialized_t2.as_slice()) - .unwrap(); - assert_eq!(t2, deserialized_bytes_t2); + let x = TupleStruct(ext, 6); + let serialized = x.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); } #[test] -fn simple_enum() { - let b = &[0u8, 5] as &[u8]; - let (deserialized_bytes, _remainder) = - ::tls_deserialize(b).unwrap(); - assert_eq!(ExtensionType::RatchetTree, deserialized_bytes); - - let mut b = &[0u8, 5, 1, 244, 0, 1] as &[u8]; - let variants = [ - ExtensionType::RatchetTree, - ExtensionType::SomethingElse, - ExtensionType::Capabilities, - ]; - for variant in variants.iter() { - let (deserialized_bytes, remainder) = - ::tls_deserialize(b).unwrap(); - b = remainder; - assert_eq!(variant, &deserialized_bytes); +fn byte_arrays() { + let x = [0u8, 1, 2, 3]; + let serialized = x.tls_serialize().unwrap(); + let (deserialized, rest) = <[u8; 4] as DeserializeBytes>::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} + +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +struct Custom { + #[tls_codec(with = "custom")] + values: Vec, + a: u8, +} + +mod custom { + use tls_codec::{DeserializeBytes, SerializeBytes, Size}; + + pub fn tls_serialized_len(v: &[u8]) -> usize { + v.tls_serialized_len() + } + + pub fn tls_serialize(v: &[u8]) -> Result, tls_codec::Error> { + v.tls_serialize() + } + + pub fn tls_deserialize( + bytes: &[u8], + ) -> Result<(T, &[u8]), tls_codec::Error> { + ::tls_deserialize(bytes) } } #[test] -fn deserialize_tls_vec() { - let long_vector = vec![ExtensionStruct::default(); 4]; - let serialized_long_vec = [ - 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - let (deserialized_long_vec_bytes, _remainder): (Vec, &[u8]) = - as tls_codec::DeserializeBytes>::tls_deserialize( - serialized_long_vec.as_slice(), - ) - .map(|(v, r)| (v.into(), r)) - .unwrap(); - assert_eq!(long_vector.len(), deserialized_long_vec_bytes.len()); - assert_eq!(long_vector, deserialized_long_vec_bytes); +fn custom() { + let x = Custom { + values: vec![0, 1, 2], + a: 3, + }; + let serialized = x.tls_serialize().unwrap(); + assert_eq!(vec![3, 0, 1, 2, 3], serialized); + let (deserialized, rest) = ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} + +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[repr(u8)] +enum EnumWithTupleVariant { + A(u8, u32), } #[test] -fn byte_arrays() { - let x = [0u8, 1, 2, 3]; - let serialized = [0, 1, 2, 3]; - assert_eq!(x.to_vec(), serialized); +fn enum_with_tuple_variant() { + let x = EnumWithTupleVariant::A(3, 4); + let serialized = x.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[repr(u8)] +enum EnumWithStructVariant { + A { foo: u8, bar: u32 }, +} + +#[test] +fn enum_with_struct_variant() { + let x = EnumWithStructVariant::A { foo: 3, bar: 4 }; + let serialized = x.tls_serialize().unwrap(); let (deserialized, rest) = - <[u8; 4] as tls_codec::DeserializeBytes>::tls_deserialize(&mut serialized.as_slice()) + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} + +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[repr(u16)] +enum EnumWithDataAndDiscriminant { + #[tls_codec(discriminant = 3)] + A(u8), + B, +} + +#[test] +fn enum_with_data_and_discriminant() { + let x = EnumWithDataAndDiscriminant::A(4); + let serialized = x.tls_serialize().unwrap(); + + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} + +#[test] +fn discriminant_is_incremented_implicitly() { + let x = EnumWithDataAndDiscriminant::B; + let serialized = x.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} + +mod discriminant { + pub mod test { + pub mod constant { + pub const TEST_CONST: u8 = 3; + } + pub mod enum_val { + pub enum Test { + Potato = 0x0004, + } + } + } +} + +#[derive(Debug, PartialEq, TlsSerializeBytes, TlsDeserializeBytes, TlsSize)] +#[repr(u16)] +enum EnumWithDataAndConstDiscriminant { + #[tls_codec(discriminant = "discriminant::test::constant::TEST_CONST")] + A(u8), + #[tls_codec(discriminant = "discriminant::test::enum_val::Test::Potato")] + B, + #[tls_codec(discriminant = 12)] + C, +} + +#[test] +fn enum_with_data_and_const_discriminant() { + let x = EnumWithDataAndConstDiscriminant::A(4); + let serialized = x.tls_serialize().unwrap(); + assert_eq!(vec![0, 3, 4], serialized); + let (deserialized, rest) = + ::tls_deserialize(&serialized) .unwrap(); assert_eq!(deserialized, x); assert_eq!(rest, []); - let x = [0u8, 1, 2, 3, 7, 6, 5, 4]; - let w = ArrayWrap { data: x }; - let serialized = [0, 1, 2, 3, 7, 6, 5, 4]; - assert_eq!(x.to_vec(), serialized); + let x = EnumWithDataAndConstDiscriminant::B; + let serialized = x.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized) + .unwrap(); + assert_eq!(deserialized, x); + assert_eq!(rest, []); + let x = EnumWithDataAndConstDiscriminant::C; + let serialized = x.tls_serialize().unwrap(); let (deserialized, rest) = - ::tls_deserialize(&mut serialized.as_slice()) + ::tls_deserialize(&serialized) .unwrap(); - assert_eq!(deserialized, w); + assert_eq!(deserialized, x); + assert_eq!(rest, []); +} + +#[derive(TlsSerializeBytes, TlsDeserializeBytes, TlsSize, Debug, PartialEq)] +#[repr(u8)] +enum EnumWithCustomSerializedField { + A(#[tls_codec(with = "custom")] Vec), +} + +#[test] +fn enum_with_custom_serialized_field() { + let x = EnumWithCustomSerializedField::A(vec![1, 2, 3]); + let serialized = x.tls_serialize().unwrap(); + let (deserialized, rest) = + ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, x); assert_eq!(rest, []); } + +#[test] +fn that_skip_attribute_on_struct_works() { + fn test(test: T, expected: T) + where + T: std::fmt::Debug + PartialEq + SerializeBytes + Size, + { + let serialized = test.tls_serialize().unwrap(); + let (deserialized, rest) = ::tls_deserialize(&serialized).unwrap(); + assert_eq!(deserialized, expected); + assert_eq!(rest, []); + } + + #[derive(Debug, PartialEq, TlsSerializeBytes, TlsDeserializeBytes, TlsSize)] + struct StructWithSkip1 { + #[tls_codec(skip)] + a: u8, + b: u8, + c: u8, + } + + #[derive(Debug, PartialEq, TlsSerializeBytes, TlsDeserializeBytes, TlsSize)] + struct StructWithSkip2 { + a: u8, + #[tls_codec(skip)] + b: u8, + c: u8, + } + + #[derive(Debug, PartialEq, TlsSerializeBytes, TlsDeserializeBytes, TlsSize)] + struct StructWithSkip3 { + a: u8, + b: u8, + #[tls_codec(skip)] + c: u8, + } + + test( + StructWithSkip1 { + a: 123, + b: 13, + c: 42, + }, + StructWithSkip1 { + a: Default::default(), + b: 13, + c: 42, + }, + ); + test( + StructWithSkip2 { + a: 123, + b: 13, + c: 42, + }, + StructWithSkip2 { + a: 123, + b: Default::default(), + c: 42, + }, + ); + test( + StructWithSkip3 { + a: 123, + b: 13, + c: 42, + }, + StructWithSkip3 { + a: 123, + b: 13, + c: Default::default(), + }, + ); +} From 993ca90887f4f64db107bc05b3ed8656a86c95f4 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Sun, 20 Aug 2023 17:20:21 +0530 Subject: [PATCH 51/58] update Cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 515643d1c..9deac7e6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1932,6 +1932,7 @@ dependencies = [ "signature", "spki", "tempfile", + "tls_codec", "x509-cert-test-support", ] From 41eae916a0d22daefaa4f9cdef2c76d43565773e Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 22 Nov 2023 14:27:28 +0530 Subject: [PATCH 52/58] use tls_codec version 0.4.0 --- Cargo.lock | 31 ++++++++++++++++++++++++++----- x509-cert/Cargo.toml | 7 +++---- x509-cert/src/ext/pkix/sct.rs | 2 +- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9deac7e6a..bdace1857 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1622,7 +1622,17 @@ dependencies = [ "criterion", "regex", "serde", - "tls_codec_derive", + "tls_codec_derive 0.3.0", + "zeroize", +] + +[[package]] +name = "tls_codec" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38a1d5fcfa859f0ec2b5e111dc903890bd7dac7f34713232bf9aa4fd7cad7b2" +dependencies = [ + "tls_codec_derive 0.4.0", "zeroize", ] @@ -1633,10 +1643,21 @@ dependencies = [ "proc-macro2", "quote", "syn", - "tls_codec", + "tls_codec 0.3.1", "trybuild", ] +[[package]] +name = "tls_codec_derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8e00e3e7a54e0f1c8834ce72ed49c8487fbd3f801d8cfe1a0ad0640382f8e15" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.7.6" @@ -1932,7 +1953,7 @@ dependencies = [ "signature", "spki", "tempfile", - "tls_codec", + "tls_codec 0.4.0", "x509-cert-test-support", ] @@ -1969,9 +1990,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 1d49cfee5..6c4e6313f 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -23,10 +23,9 @@ spki = { version = "0.7.2", features = ["alloc"] } arbitrary = { version = "1.3", features = ["derive"], optional = true } sha1 = { version = "0.10.0", optional = true } signature = { version = "2.1.0", features = ["rand_core"], optional = true } -# TODO: Use next version of tls_codec when a verion containing the following PR is published: -# https://github.com/RustCrypto/formats/pull/1132 -# https://github.com/RustCrypto/formats/pull/1133 -tls_codec = { path = "../tls_codec", default-features = false, features = ["derive"], optional = true } +tls_codec = { version = "0.4.0", default-features = false, features = [ + "derive", +], optional = true } [dev-dependencies] hex-literal = "0.4" diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 6865884e4..41c844eef 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -73,7 +73,7 @@ impl SignedCertificateTimestampList { /// deserialized or if there are trailing bytes after all [SerializedSct]s /// are deserialized. pub fn parse_timestamps(&self) -> Result, Error> { - let (tls_vec, rest) = TlsByteVecU16::tls_deserialize(self.0.as_bytes())?; + let (tls_vec, rest) = TlsByteVecU16::tls_deserialize_bytes(self.0.as_bytes())?; if !rest.is_empty() { return Err(tls_codec::Error::TrailingData)?; } From d4f9af82b20fdd363e4eccc1c3d7566f1948ff0c Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 22 Nov 2023 14:34:55 +0530 Subject: [PATCH 53/58] use tls_deserialize_bytes instead of tls_deserialize --- x509-cert/src/ext/pkix/sct.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 41c844eef..63e749384 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -80,7 +80,7 @@ impl SignedCertificateTimestampList { let mut bytes = tls_vec.as_slice(); let mut result = Vec::new(); while !bytes.is_empty() { - let (serialized_sct, rest) = SerializedSct::tls_deserialize(bytes)?; + let (serialized_sct, rest) = SerializedSct::tls_deserialize_bytes(bytes)?; result.push(serialized_sct); bytes = rest; } @@ -115,7 +115,7 @@ impl SerializedSct { /// deserialized or if there are trailing bytes after a /// [SignedCertificateTimestamp] has been deserialized. pub fn parse_timestamp(&self) -> Result { - let (sct, rest) = SignedCertificateTimestamp::tls_deserialize(self.data.as_slice())?; + let (sct, rest) = SignedCertificateTimestamp::tls_deserialize_bytes(self.data.as_slice())?; if !rest.is_empty() { return Err(tls_codec::Error::TrailingData)?; } @@ -264,7 +264,7 @@ mod tests { bytes: &'a [u8], expected_result: Result<(T, &[u8]), tls_codec::Error>, ) -> Result<(T, &'a [u8]), tls_codec::Error> { - let actual_result = T::tls_deserialize(&bytes); + let actual_result = T::tls_deserialize_bytes(&bytes); assert_eq!(actual_result, expected_result); actual_result } From 7dcceec0cbbd764a332ba47c23c67e6194f68489 Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 22 Nov 2023 15:49:46 +0530 Subject: [PATCH 54/58] fix clippy errors --- x509-cert/src/ext/pkix/sct.rs | 120 +++++++++++++++++++++++----------- 1 file changed, 81 insertions(+), 39 deletions(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 63e749384..676e6828a 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -264,13 +264,13 @@ mod tests { bytes: &'a [u8], expected_result: Result<(T, &[u8]), tls_codec::Error>, ) -> Result<(T, &'a [u8]), tls_codec::Error> { - let actual_result = T::tls_deserialize_bytes(&bytes); + let actual_result = T::tls_deserialize_bytes(bytes); assert_eq!(actual_result, expected_result); actual_result } fn run_serialization_test(value: T, expected_bytes: &[u8]) { - let result = value.tls_serialize().unwrap(); + let result = value.tls_serialize().expect("failed to serialize value"); assert_eq!(expected_bytes, &result); } @@ -283,35 +283,35 @@ mod tests { Ok((HashAlgorithm::None, [1, 2, 3, 4, 5, 6, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Md5, [2, 3, 4, 5, 6, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Sha1, [3, 4, 5, 6, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Sha224, [4, 5, 6, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Sha256, [5, 6, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Sha384, [6, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Sha512, [8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((HashAlgorithm::Intrinsic, [].as_slice())), ); let _ = run_deserialization_test::( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Err(tls_codec::Error::EndOfStream), ); let _ = @@ -341,27 +341,27 @@ mod tests { Ok((SignatureAlgorithm::Anonymous, [1, 2, 3, 7, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((SignatureAlgorithm::Rsa, [2, 3, 7, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((SignatureAlgorithm::Dsa, [3, 7, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((SignatureAlgorithm::Ecdsa, [7, 8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((SignatureAlgorithm::Ed25519, [8].as_slice())), ); let result = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok((SignatureAlgorithm::Ed448, [].as_slice())), ); let _ = run_deserialization_test::( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Err(tls_codec::Error::EndOfStream), ); let _ = run_deserialization_test::( @@ -408,7 +408,7 @@ mod tests { ); let _ = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok(( SignatureAndHashAlgorithm { hash: HashAlgorithm::Sha1, @@ -456,7 +456,7 @@ mod tests { ); let _ = run_deserialization_test( - &result.unwrap().1, + result.expect("run_deserialization_test failed").1, Ok(( DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -500,7 +500,10 @@ mod tests { let result = run_deserialization_test(&bytes, Ok((Version::V1, [0].as_slice()))); - let _ = run_deserialization_test(&result.unwrap().1, Ok((Version::V1, [].as_slice()))); + let _ = run_deserialization_test( + result.expect("run_deserialization_test failed").1, + Ok((Version::V1, [].as_slice())), + ); let _ = run_deserialization_test::(&[1], Err(tls_codec::Error::UnknownValue(1))); } @@ -539,9 +542,15 @@ mod tests { SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: TLS_SCT_EXAMPLE[1..33].try_into().unwrap(), + key_id: TLS_SCT_EXAMPLE[1..33] + .try_into() + .expect("failed to convert to u8 array"), }, - timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), + timestamp: u64::from_be_bytes( + TLS_SCT_EXAMPLE[33..41] + .try_into() + .expect("failed to convert to u8 array"), + ), extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -562,9 +571,15 @@ mod tests { SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: TLS_SCT_EXAMPLE[1..33].try_into().unwrap(), + key_id: TLS_SCT_EXAMPLE[1..33] + .try_into() + .expect("failed to convert to u8 array"), }, - timestamp: u64::from_be_bytes(TLS_SCT_EXAMPLE[33..41].try_into().unwrap()), + timestamp: u64::from_be_bytes( + TLS_SCT_EXAMPLE[33..41] + .try_into() + .expect("failed to convert to u8 array"), + ), extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -599,7 +614,7 @@ mod tests { bytes: &[u8], expected_result: Result, ) -> Result { - let actual_result = SignedCertificateTimestampList::from_der(&bytes); + let actual_result = SignedCertificateTimestampList::from_der(bytes); assert_eq!(actual_result, expected_result); actual_result } @@ -607,18 +622,27 @@ mod tests { let result = run_test( &SCT_EXAMPLE, Ok(SignedCertificateTimestampList( - OctetString::new(&SCT_EXAMPLE[3..]).unwrap(), + OctetString::new(&SCT_EXAMPLE[3..]).expect("failed to convert to u8 array"), )), ); - let scts = result.unwrap().parse_timestamps().unwrap(); + let scts = result + .expect("run_test failed") + .parse_timestamps() + .expect("parse_timestamps failed"); assert_eq!( scts[0].parse_timestamp(), Ok(SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: SCT_EXAMPLE[8..40].try_into().unwrap(), + key_id: SCT_EXAMPLE[8..40] + .try_into() + .expect("failed to convert to u8 array"), }, - timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), + timestamp: u64::from_be_bytes( + SCT_EXAMPLE[40..48] + .try_into() + .expect("failed to convert to u8 array") + ), extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -634,9 +658,15 @@ mod tests { Ok(SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: SCT_EXAMPLE[129..161].try_into().unwrap(), + key_id: SCT_EXAMPLE[129..161] + .try_into() + .expect("failed to convert to u8 array"), }, - timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), + timestamp: u64::from_be_bytes( + SCT_EXAMPLE[161..169] + .try_into() + .expect("failed to convert to u8 array") + ), extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -654,9 +684,15 @@ mod tests { let serialized_sct1 = SerializedSct::new(SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: SCT_EXAMPLE[8..40].try_into().unwrap(), + key_id: SCT_EXAMPLE[8..40] + .try_into() + .expect("failed to convert to u8 array"), }, - timestamp: u64::from_be_bytes(SCT_EXAMPLE[40..48].try_into().unwrap()), + timestamp: u64::from_be_bytes( + SCT_EXAMPLE[40..48] + .try_into() + .expect("failed to convert to u8 array"), + ), extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -666,13 +702,19 @@ mod tests { signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[54..126]), }, }) - .unwrap(); + .expect("failed to create SerializedSct"); let serialized_sct2 = SerializedSct::new(SignedCertificateTimestamp { version: Version::V1, log_id: LogId { - key_id: SCT_EXAMPLE[129..161].try_into().unwrap(), + key_id: SCT_EXAMPLE[129..161] + .try_into() + .expect("failed to convert to u8 array"), }, - timestamp: u64::from_be_bytes(SCT_EXAMPLE[161..169].try_into().unwrap()), + timestamp: u64::from_be_bytes( + SCT_EXAMPLE[161..169] + .try_into() + .expect("failed to convert to u8 array"), + ), extensions: TlsByteVecU16::from_slice(&[]), signature: DigitallySigned { algorithm: SignatureAndHashAlgorithm { @@ -682,10 +724,10 @@ mod tests { signature: TlsByteVecU16::from_slice(&SCT_EXAMPLE[175..]), }, }) - .unwrap(); - let list = - SignedCertificateTimestampList::new(&[serialized_sct1, serialized_sct2]).unwrap(); - let der = list.to_der().unwrap(); + .expect("failed to create SerializedSct"); + let list = SignedCertificateTimestampList::new(&[serialized_sct1, serialized_sct2]) + .expect("failed to create SignedCertificateTimestampList"); + let der = list.to_der().expect("failed to convert to der"); assert_eq!(der.as_slice(), SCT_EXAMPLE.as_slice()); } } From 5a79efe3a71541792fc48fd0b162261bc57e00ea Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Wed, 22 Nov 2023 15:50:49 +0530 Subject: [PATCH 55/58] fix cargo doc error --- x509-cert/src/ext/pkix/sct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 676e6828a..7fba942cd 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -67,7 +67,7 @@ impl SignedCertificateTimestampList { Ok(SignedCertificateTimestampList(OctetString::new(buffer)?)) } - /// Parses the encoded [SerializedSct]s and returns a [Vec][alloc::vec::Vec] containing them. + /// Parses the encoded [SerializedSct]s and returns a [Vec] containing them. /// /// Returns an [error][Error] if a [SerializedSct] can't be /// deserialized or if there are trailing bytes after all [SerializedSct]s From e3aa60f580465a7e2142ceea12d9f536be4d8cfd Mon Sep 17 00:00:00 2001 From: Raminder Singh Date: Tue, 19 Dec 2023 07:27:45 +0530 Subject: [PATCH 56/58] Update x509-cert/src/ext/pkix/sct.rs Co-authored-by: Arthur Gautier --- x509-cert/src/ext/pkix/sct.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index 7fba942cd..c948f3942 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -55,7 +55,7 @@ impl From for Error { } impl SignedCertificateTimestampList { - /// Creates a new [SignedCertificateTimestamp] from a slice of [SerializedSct]s. + /// Creates a new [`SignedCertificateTimestampList`] from a slice of [`SerializedSct`]s. pub fn new(serialized_scts: &[SerializedSct]) -> Result { let mut result: Vec = Vec::new(); for timestamp in serialized_scts { From cdb6a9d991c8df91b16e906e13cf33761d684ade Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Dec 2023 06:45:06 -0700 Subject: [PATCH 57/58] Update x509-cert/Cargo.toml --- x509-cert/Cargo.toml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/x509-cert/Cargo.toml b/x509-cert/Cargo.toml index 6c4e6313f..613eb9294 100644 --- a/x509-cert/Cargo.toml +++ b/x509-cert/Cargo.toml @@ -23,9 +23,7 @@ spki = { version = "0.7.2", features = ["alloc"] } arbitrary = { version = "1.3", features = ["derive"], optional = true } sha1 = { version = "0.10.0", optional = true } signature = { version = "2.1.0", features = ["rand_core"], optional = true } -tls_codec = { version = "0.4.0", default-features = false, features = [ - "derive", -], optional = true } +tls_codec = { version = "0.4.0", default-features = false, features = ["derive"], optional = true } [dev-dependencies] hex-literal = "0.4" From f829498b3dda5ef133b051a1ea7043c5d37d31f7 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Tue, 19 Dec 2023 06:46:01 -0700 Subject: [PATCH 58/58] Update x509-cert/src/ext/pkix/sct.rs --- x509-cert/src/ext/pkix/sct.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x509-cert/src/ext/pkix/sct.rs b/x509-cert/src/ext/pkix/sct.rs index c948f3942..32539a562 100644 --- a/x509-cert/src/ext/pkix/sct.rs +++ b/x509-cert/src/ext/pkix/sct.rs @@ -1,9 +1,10 @@ -#![cfg(feature = "sct")] //! Signed Certificate Timestamp list extension as defined in the //! [Certificate Transparency RFC 6962]. //! //! [Certificate Transparency RFC 6962]: https://datatracker.ietf.org/doc/html/rfc6962 +#![cfg(feature = "sct")] + use alloc::{format, vec::Vec}; use const_oid::{AssociatedOid, ObjectIdentifier}; use der::asn1::OctetString;