diff --git a/Cargo.toml b/Cargo.toml index d039b38..e738aa6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ categories = [ base64ct = { version = "1.6", features = ["std"] } bytes = { version = "1.5" } chrono = { version = "0.4", features = ["serde"] } +der = { version = "0.7.8", optional = true } digest = { version = "0.10" } ecdsa = { version = "0.16", features = ["signing", "der"], optional = true } hmac = { version = "0.12", optional = true } @@ -56,6 +57,7 @@ p256 = ["dep:p256", "ecdsa"] p384 = ["dep:p384", "ecdsa"] p521 = ["dep:p521", "ecdsa"] spki = ["dep:spki"] +der = ["dep:der"] [[example]] name = "acme-new-account" diff --git a/src/algorithms/sig.rs b/src/algorithms/sig.rs index dbf2240..c7040e7 100644 --- a/src/algorithms/sig.rs +++ b/src/algorithms/sig.rs @@ -70,3 +70,40 @@ impl spki::SignatureBitStringEncoding for SignatureBytes { spki::der::asn1::BitString::from_bytes(self.0.as_ref()) } } + +#[cfg(feature = "der")] +impl<'c> der::Decode<'c> for SignatureBytes { + fn decode>(reader: &mut R) -> der::Result { + use der::Encode; + + let header = reader.peek_header()?; + header.tag.assert_eq(der::Tag::Sequence)?; + + let len = (header.encoded_len()? + header.length)?; + let mut buf = Vec::with_capacity(usize::try_from(len)?); + let slice = buf + .get_mut(..usize::try_from(len)?) + .ok_or_else(|| reader.error(der::Tag::Sequence.length_error().kind()))?; + + reader.read_into(slice)?; + Ok(Self::from(buf)) + } +} + +#[cfg(feature = "der")] +impl der::Tagged for SignatureBytes { + fn tag(&self) -> der::Tag { + der::Tag::Sequence + } +} + +#[cfg(feature = "der")] +impl der::Encode for SignatureBytes { + fn encoded_len(&self) -> der::Result { + der::Length::try_from(self.0.len()) + } + + fn encode(&self, writer: &mut impl der::Writer) -> der::Result<()> { + writer.write(self.0.as_ref()) + } +}