Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/dsa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -43,7 +43,7 @@ jobs:
- macos-latest
- windows-latest
toolchain:
- 1.61.0 # MSRV
- 1.65.0 # MSRV
- stable
runs-on: ${{ matrix.platform }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions dsa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions dsa/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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

Expand Down
37 changes: 20 additions & 17 deletions dsa/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -61,9 +64,9 @@ impl Components {

impl<'a> DecodeValue<'a> for Components {
fn decode_value<R: Reader<'a>>(reader: &mut R, _header: Header) -> der::Result<Self> {
let p = reader.decode::<UIntRef<'_>>()?;
let q = reader.decode::<UIntRef<'_>>()?;
let g = reader.decode::<UIntRef<'_>>()?;
let p = reader.decode::<UintRef<'_>>()?;
let q = reader.decode::<UintRef<'_>>()?;
let g = reader.decode::<UintRef<'_>>()?;

let p = BigUint::from_bytes_be(p.as_bytes());
let q = BigUint::from_bytes_be(q.as_bytes());
Expand All @@ -73,19 +76,19 @@ impl<'a> DecodeValue<'a> for Components {
}
}

impl<'a> Sequence<'a> for Components {
fn fields<F, T>(&self, encoder: F) -> der::Result<T>
where
F: FnOnce(&[&dyn Encode]) -> der::Result<T>,
{
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<Length> {
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 {}
45 changes: 24 additions & 21 deletions dsa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -106,11 +109,11 @@ impl Signature {
}
}

impl<'a> Decode<'a> for Signature {
fn decode<R: Reader<'a>>(reader: &mut R) -> der::Result<Self> {
reader.sequence(|sequence| {
let r = UIntRef::decode(sequence)?;
let s = UIntRef::decode(sequence)?;
impl<'a> DecodeValue<'a> for Signature {
fn decode_value<R: Reader<'a>>(reader: &mut R, header: Header) -> der::Result<Self> {
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());
Expand All @@ -120,6 +123,19 @@ impl<'a> Decode<'a> for Signature {
}
}

impl EncodeValue for Signature {
fn value_len(&self) -> der::Result<Length> {
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<Signature> for Box<[u8]> {
fn from(sig: Signature) -> Box<[u8]> {
sig.to_bytes()
Expand All @@ -138,20 +154,7 @@ impl PartialOrd for Signature {
}
}

impl<'a> Sequence<'a> for Signature {
fn fields<F, T>(&self, encoder: F) -> der::Result<T>
where
F: FnOnce(&[&dyn der::Encode]) -> der::Result<T>,
{
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]>;
Expand All @@ -161,7 +164,7 @@ impl SignatureEncoding for Signature {
}

fn to_vec(&self) -> Vec<u8> {
Encode::to_vec(self).expect("DER encoding error")
self.to_der().expect("DER encoding error")
}
}

Expand Down
20 changes: 9 additions & 11 deletions dsa/src/signing_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -158,16 +158,16 @@ where

impl EncodePrivateKey for SigningKey {
fn to_pkcs8_der(&self) -> pkcs8::Result<SecretDocument> {
let parameters = self.verifying_key().components().to_vec()?;
let parameters = self.verifying_key().components().to_der()?;
let parameters = AnyRef::from_der(&parameters)?;
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()?;
Expand All @@ -186,13 +186,13 @@ impl<'a> TryFrom<PrivateKeyInfo<'a>> 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::<Components>()?;

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)
Expand All @@ -205,8 +205,6 @@ impl<'a> TryFrom<PrivateKeyInfo<'a>> for SigningKey {
}
}

impl DecodePrivateKey for SigningKey {}

impl Debug for SigningKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SigningKey")
Expand Down
41 changes: 23 additions & 18 deletions dsa/src/verifying_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -114,39 +117,41 @@ where

impl EncodePublicKey for VerifyingKey {
fn to_public_key_der(&self) -> spki::Result<spki::Document> {
let parameters = self.components.to_vec()?;
let parameters = self.components.to_der()?;
let parameters = AnyRef::from_der(&parameters)?;
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<SubjectPublicKeyInfo<'a>> for VerifyingKey {
impl<'a> TryFrom<SubjectPublicKeyInfoRef<'a>> for VerifyingKey {
type Error = spki::Error;

fn try_from(value: SubjectPublicKeyInfo<'a>) -> Result<Self, Self::Error> {
fn try_from(value: SubjectPublicKeyInfoRef<'a>) -> Result<Self, Self::Error> {
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 {}
2 changes: 1 addition & 1 deletion dsa/tests/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions dsa/tests/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ 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);

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);
Expand Down