diff --git a/.github/workflows/dsa.yml b/.github/workflows/dsa.yml index 953f7302..2503d308 100644 --- a/.github/workflows/dsa.yml +++ b/.github/workflows/dsa.yml @@ -24,7 +24,7 @@ jobs: - thumbv7em-none-eabi - wasm32-unknown-unknown toolchain: - - 1.61.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v3 @@ -43,7 +43,7 @@ jobs: - macos-latest - windows-latest toolchain: - - 1.61.0 # MSRV + - 1.65.0 # MSRV - stable runs-on: ${{ matrix.platform }} steps: diff --git a/Cargo.lock b/Cargo.lock index 34f31221..20f3c0da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -198,7 +198,7 @@ dependencies = [ "digest 0.10.6", "num-bigint-dig", "num-traits", - "pkcs8 0.9.0", + "pkcs8 0.10.0", "rand 0.8.5", "rand_chacha 0.3.1", "rfc6979", diff --git a/dsa/Cargo.toml b/dsa/Cargo.toml index 584b50ed..69f8f6cc 100644 --- a/dsa/Cargo.toml +++ b/dsa/Cargo.toml @@ -12,20 +12,20 @@ readme = "README.md" repository = "https://github.com/RustCrypto/signatures/tree/master/dsa" categories = ["cryptography", "no-std"] keywords = ["crypto", "nist", "signature"] -rust-version = "1.61" +rust-version = "1.65" [dependencies] digest = "0.10" num-bigint = { package = "num-bigint-dig", version = "0.8", default-features = false, features = ["prime", "rand", "zeroize"] } num-traits = { version = "0.2", default-features = false } -pkcs8 = { version = "0.9", default-features = false, features = ["alloc"] } +pkcs8 = { version = "0.10", default-features = false, features = ["alloc"] } rfc6979 = { version = "0.4", path = "../rfc6979" } sha2 = { version = "0.10", default-features = false } signature = { version = "2.0, <2.1", default-features = false, features = ["alloc", "digest", "rand_core"] } zeroize = { version = "1.5", default-features = false } [dev-dependencies] -pkcs8 = { version = "0.9", default-features = false, features = ["pem"] } +pkcs8 = { version = "0.10", default-features = false, features = ["pem"] } rand = "0.8" rand_chacha = "0.3" sha1 = "0.10" diff --git a/dsa/README.md b/dsa/README.md index 56c81ed6..2893e13f 100644 --- a/dsa/README.md +++ b/dsa/README.md @@ -30,7 +30,7 @@ USE AT YOUR OWN RISK! ## Minimum Supported Rust Version -This crate requires **Rust 1.61** at a minimum. +This crate requires **Rust 1.65** at a minimum. We may change the MSRV in the future, but it will be accompanied by a minor version bump. @@ -59,7 +59,7 @@ dual licensed as above, without any additional terms or conditions. [build-image]: https://github.com/RustCrypto/signatures/actions/workflows/dsa.yml/badge.svg [build-link]: https://github.com/RustCrypto/signatures/actions/workflows/dsa.yml [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.61+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures diff --git a/dsa/src/components.rs b/dsa/src/components.rs index 8e07b4ee..b2450e2f 100644 --- a/dsa/src/components.rs +++ b/dsa/src/components.rs @@ -5,7 +5,10 @@ use crate::{size::KeySize, two}; use num_bigint::BigUint; use num_traits::Zero; -use pkcs8::der::{self, asn1::UIntRef, DecodeValue, Encode, Header, Reader, Sequence, Tag}; +use pkcs8::der::{ + self, asn1::UintRef, DecodeValue, Encode, EncodeValue, Header, Length, Reader, Sequence, Tag, + Writer, +}; use signature::rand_core::CryptoRngCore; /// The common components of an DSA keypair @@ -61,9 +64,9 @@ impl Components { impl<'a> DecodeValue<'a> for Components { fn decode_value>(reader: &mut R, _header: Header) -> der::Result { - let p = reader.decode::>()?; - let q = reader.decode::>()?; - let g = reader.decode::>()?; + let p = reader.decode::>()?; + let q = reader.decode::>()?; + let g = reader.decode::>()?; let p = BigUint::from_bytes_be(p.as_bytes()); let q = BigUint::from_bytes_be(q.as_bytes()); @@ -73,19 +76,19 @@ impl<'a> DecodeValue<'a> for Components { } } -impl<'a> Sequence<'a> for Components { - fn fields(&self, encoder: F) -> der::Result - where - F: FnOnce(&[&dyn Encode]) -> der::Result, - { - let p_bytes = self.p.to_bytes_be(); - let q_bytes = self.q.to_bytes_be(); - let g_bytes = self.g.to_bytes_be(); - - let p = UIntRef::new(&p_bytes)?; - let q = UIntRef::new(&q_bytes)?; - let g = UIntRef::new(&g_bytes)?; +impl EncodeValue for Components { + fn value_len(&self) -> der::Result { + UintRef::new(&self.p.to_bytes_be())?.encoded_len()? + + UintRef::new(&self.q.to_bytes_be())?.encoded_len()? + + UintRef::new(&self.g.to_bytes_be())?.encoded_len()? + } - encoder(&[&p, &q, &g]) + fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { + UintRef::new(&self.p.to_bytes_be())?.encode(writer)?; + UintRef::new(&self.q.to_bytes_be())?.encode(writer)?; + UintRef::new(&self.g.to_bytes_be())?.encode(writer)?; + Ok(()) } } + +impl<'a> Sequence<'a> for Components {} diff --git a/dsa/src/lib.rs b/dsa/src/lib.rs index 16e4abfd..3a0fa78b 100644 --- a/dsa/src/lib.rs +++ b/dsa/src/lib.rs @@ -69,7 +69,10 @@ pub const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.2.840.10040.4. use alloc::{boxed::Box, vec::Vec}; use num_traits::Zero; -use pkcs8::der::{self, asn1::UIntRef, Decode, Encode, Reader, Sequence}; +use pkcs8::der::{ + self, asn1::UintRef, Decode, DecodeValue, Encode, EncodeValue, Header, Length, Reader, + Sequence, Writer, +}; use signature::SignatureEncoding; /// Container of the DSA signature @@ -106,11 +109,11 @@ impl Signature { } } -impl<'a> Decode<'a> for Signature { - fn decode>(reader: &mut R) -> der::Result { - reader.sequence(|sequence| { - let r = UIntRef::decode(sequence)?; - let s = UIntRef::decode(sequence)?; +impl<'a> DecodeValue<'a> for Signature { + fn decode_value>(reader: &mut R, header: Header) -> der::Result { + reader.read_nested(header.length, |reader| { + let r = UintRef::decode(reader)?; + let s = UintRef::decode(reader)?; let r = BigUint::from_bytes_be(r.as_bytes()); let s = BigUint::from_bytes_be(s.as_bytes()); @@ -120,6 +123,19 @@ impl<'a> Decode<'a> for Signature { } } +impl EncodeValue for Signature { + fn value_len(&self) -> der::Result { + UintRef::new(&self.r.to_bytes_be())?.encoded_len()? + + UintRef::new(&self.s.to_bytes_be())?.encoded_len()? + } + + fn encode_value(&self, writer: &mut impl Writer) -> der::Result<()> { + UintRef::new(&self.r.to_bytes_be())?.encode(writer)?; + UintRef::new(&self.s.to_bytes_be())?.encode(writer)?; + Ok(()) + } +} + impl From for Box<[u8]> { fn from(sig: Signature) -> Box<[u8]> { sig.to_bytes() @@ -138,20 +154,7 @@ impl PartialOrd for Signature { } } -impl<'a> Sequence<'a> for Signature { - fn fields(&self, encoder: F) -> der::Result - where - F: FnOnce(&[&dyn der::Encode]) -> der::Result, - { - let r_bytes = self.r.to_bytes_be(); - let s_bytes = self.s.to_bytes_be(); - - let r = UIntRef::new(&r_bytes)?; - let s = UIntRef::new(&s_bytes)?; - - encoder(&[&r, &s]) - } -} +impl<'a> Sequence<'a> for Signature {} impl SignatureEncoding for Signature { type Repr = Box<[u8]>; @@ -161,7 +164,7 @@ impl SignatureEncoding for Signature { } fn to_vec(&self) -> Vec { - Encode::to_vec(self).expect("DER encoding error") + self.to_der().expect("DER encoding error") } } diff --git a/dsa/src/signing_key.rs b/dsa/src/signing_key.rs index f77342c6..d471aae5 100644 --- a/dsa/src/signing_key.rs +++ b/dsa/src/signing_key.rs @@ -11,8 +11,8 @@ use digest::{core_api::BlockSizeUser, Digest, FixedOutputReset}; use num_bigint::BigUint; use num_traits::Zero; use pkcs8::{ - der::{asn1::UIntRef, AnyRef, Decode, Encode}, - AlgorithmIdentifier, DecodePrivateKey, EncodePrivateKey, PrivateKeyInfo, SecretDocument, + der::{asn1::UintRef, AnyRef, Decode, Encode}, + AlgorithmIdentifierRef, EncodePrivateKey, PrivateKeyInfo, SecretDocument, }; use signature::{ hazmat::{PrehashSigner, RandomizedPrehashSigner}, @@ -158,16 +158,16 @@ where impl EncodePrivateKey for SigningKey { fn to_pkcs8_der(&self) -> pkcs8::Result { - let parameters = self.verifying_key().components().to_vec()?; + let parameters = self.verifying_key().components().to_der()?; let parameters = AnyRef::from_der(¶meters)?; - let algorithm = AlgorithmIdentifier { + let algorithm = AlgorithmIdentifierRef { oid: OID, parameters: Some(parameters), }; let mut x_bytes = self.x().to_bytes_be(); - let x = UIntRef::new(&x_bytes)?; - let mut signing_key = x.to_vec()?; + let x = UintRef::new(&x_bytes)?; + let mut signing_key = x.to_der()?; let signing_key_info = PrivateKeyInfo::new(algorithm, &signing_key); let secret_document = signing_key_info.try_into()?; @@ -186,13 +186,13 @@ impl<'a> TryFrom> for SigningKey { value.algorithm.assert_algorithm_oid(OID)?; let parameters = value.algorithm.parameters_any()?; - let components: Components = parameters.decode_into()?; + let components = parameters.decode_as::()?; - let x = UIntRef::from_der(value.private_key)?; + let x = UintRef::from_der(value.private_key)?; let x = BigUint::from_bytes_be(x.as_bytes()); let y = if let Some(y_bytes) = value.public_key { - let y = UIntRef::from_der(y_bytes)?; + let y = UintRef::from_der(y_bytes)?; BigUint::from_bytes_be(y.as_bytes()) } else { crate::generate::public_component(&components, &x) @@ -205,8 +205,6 @@ impl<'a> TryFrom> for SigningKey { } } -impl DecodePrivateKey for SigningKey {} - impl Debug for SigningKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("SigningKey") diff --git a/dsa/src/verifying_key.rs b/dsa/src/verifying_key.rs index 289af83e..e44bebf4 100644 --- a/dsa/src/verifying_key.rs +++ b/dsa/src/verifying_key.rs @@ -8,8 +8,11 @@ use digest::Digest; use num_bigint::{BigUint, ModInverse}; use num_traits::One; use pkcs8::{ - der::{asn1::UIntRef, AnyRef, Decode, Encode}, - spki, AlgorithmIdentifier, DecodePublicKey, EncodePublicKey, SubjectPublicKeyInfo, + der::{ + asn1::{BitStringRef, UintRef}, + AnyRef, Decode, Encode, + }, + spki, AlgorithmIdentifierRef, EncodePublicKey, SubjectPublicKeyInfoRef, }; use signature::{hazmat::PrehashVerifier, DigestVerifier, Verifier}; @@ -114,39 +117,41 @@ where impl EncodePublicKey for VerifyingKey { fn to_public_key_der(&self) -> spki::Result { - let parameters = self.components.to_vec()?; + let parameters = self.components.to_der()?; let parameters = AnyRef::from_der(¶meters)?; - let algorithm = AlgorithmIdentifier { + let algorithm = AlgorithmIdentifierRef { oid: OID, parameters: Some(parameters), }; let y_bytes = self.y.to_bytes_be(); - let y = UIntRef::new(&y_bytes)?; - let public_key = y.to_vec()?; + let y = UintRef::new(&y_bytes)?; + let public_key = y.to_der()?; - SubjectPublicKeyInfo { + SubjectPublicKeyInfoRef { algorithm, - subject_public_key: &public_key, + subject_public_key: BitStringRef::new(0, &public_key)?, } .try_into() } } -impl<'a> TryFrom> for VerifyingKey { +impl<'a> TryFrom> for VerifyingKey { type Error = spki::Error; - fn try_from(value: SubjectPublicKeyInfo<'a>) -> Result { + fn try_from(value: SubjectPublicKeyInfoRef<'a>) -> Result { value.algorithm.assert_algorithm_oid(OID)?; let parameters = value.algorithm.parameters_any()?; - let components = parameters.decode_into()?; - - let y = UIntRef::from_der(value.subject_public_key)?; - let y = BigUint::from_bytes_be(y.as_bytes()); - - Self::from_components(components, y).map_err(|_| spki::Error::KeyMalformed) + let components = parameters.decode_as()?; + let y = UintRef::from_der( + value + .subject_public_key + .as_bytes() + .ok_or(spki::Error::KeyMalformed)?, + )?; + + Self::from_components(components, BigUint::from_bytes_be(y.as_bytes())) + .map_err(|_| spki::Error::KeyMalformed) } } - -impl DecodePublicKey for VerifyingKey {} diff --git a/dsa/tests/components.rs b/dsa/tests/components.rs index 7a4f186a..22888346 100644 --- a/dsa/tests/components.rs +++ b/dsa/tests/components.rs @@ -16,7 +16,7 @@ fn decode_encode_openssl_components() { Components::from_der(raw_components).expect("Failed to parse DER into component structure"); let reencoded_components = components - .to_vec() + .to_der() .expect("Failed to encode components to DER"); assert_eq!(raw_components, reencoded_components); diff --git a/dsa/tests/signature.rs b/dsa/tests/signature.rs index c36f02b6..33922298 100644 --- a/dsa/tests/signature.rs +++ b/dsa/tests/signature.rs @@ -52,7 +52,7 @@ fn decode_encode_signature() { let signature_openssl = Signature::from_der(MESSAGE_SIGNATURE_OPENSSL_ASN1).expect("Failed to decode signature"); let encoded_signature_openssl = signature_openssl - .to_vec() + .to_der() .expect("Failed to encode signature"); assert_eq!(MESSAGE_SIGNATURE_OPENSSL_ASN1, encoded_signature_openssl); @@ -60,7 +60,7 @@ fn decode_encode_signature() { let signature_crate = Signature::from_der(MESSAGE_SIGNATURE_CRATE_ASN1).expect("Failed to decode signature"); let encoded_signature_crate = signature_crate - .to_vec() + .to_der() .expect("Failed to encode signature"); assert_eq!(MESSAGE_SIGNATURE_CRATE_ASN1, encoded_signature_crate);