Skip to content

Commit 6bc6cc1

Browse files
committed
dsa: Update sanity checks
1 parent 1c33224 commit 6bc6cc1

File tree

3 files changed

+26
-10
lines changed

3 files changed

+26
-10
lines changed

dsa/src/components.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use num_traits::One;
77
use pkcs8::der::{self, asn1::UIntRef, DecodeValue, Encode, Header, Reader, Sequence};
88
use rand::{CryptoRng, RngCore};
99

10+
use crate::two;
11+
1012
/// The common components of an DSA keypair
1113
///
1214
/// (the prime p, quotient q and generator g)
@@ -63,11 +65,10 @@ impl Components {
6365
/// Check whether the components are valid
6466
#[must_use]
6567
pub fn is_valid(&self) -> bool {
66-
if *self.p() <= BigUint::one() || *self.q() <= BigUint::one() {
67-
return false;
68-
}
69-
70-
true
68+
*self.p() >= two()
69+
&& *self.q() >= two()
70+
&& *self.g() >= BigUint::one()
71+
&& self.g() < self.p()
7172
}
7273
}
7374

dsa/src/privatekey.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{Components, PublicKey, Signature, DSA_OID};
66
use core::cmp::min;
77
use digest::Digest;
88
use num_bigint::BigUint;
9+
use num_traits::One;
910
use pkcs8::{
1011
der::{asn1::UIntRef, AnyRef, Decode, Encode},
1112
AlgorithmIdentifier, DecodePrivateKey, EncodePrivateKey, PrivateKeyInfo, SecretDocument,
@@ -61,7 +62,11 @@ impl PrivateKey {
6162
/// Check whether the private key is valid
6263
#[must_use]
6364
pub fn is_valid(&self) -> bool {
64-
self.public_key().components().is_valid()
65+
if !self.public_key().is_valid() {
66+
return false;
67+
}
68+
69+
*self.x() >= BigUint::one() && self.x() < self.public_key().components().q()
6570
}
6671

6772
/// Sign data with the private key
@@ -120,7 +125,11 @@ impl<'a> TryFrom<PrivateKeyInfo<'a>> for PrivateKey {
120125
value.algorithm.assert_algorithm_oid(DSA_OID)?;
121126

122127
let parameters = value.algorithm.parameters_any()?;
123-
let components = parameters.decode_into()?;
128+
let components: Components = parameters.decode_into()?;
129+
130+
if !components.is_valid() {
131+
return Err(pkcs8::Error::KeyMalformed);
132+
}
124133

125134
let x = UIntRef::from_der(value.private_key)?;
126135
let x = BigUint::from_bytes_be(x.as_bytes());
@@ -133,7 +142,13 @@ impl<'a> TryFrom<PrivateKeyInfo<'a>> for PrivateKey {
133142
};
134143

135144
let public_key = PublicKey::from_components(components, y);
136-
Ok(PrivateKey::from_components(public_key, x))
145+
let private_key = PrivateKey::from_components(public_key, x);
146+
147+
if !private_key.is_valid() {
148+
return Err(pkcs8::Error::KeyMalformed);
149+
}
150+
151+
Ok(private_key)
137152
}
138153
}
139154

dsa/src/publickey.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! Module containing the definition of the public key container
33
//!
44
5-
use crate::{Components, Signature, DSA_OID};
5+
use crate::{two, Components, Signature, DSA_OID};
66
use core::cmp::min;
77
use digest::Digest;
88
use num_bigint::{BigUint, ModInverse};
@@ -52,7 +52,7 @@ impl PublicKey {
5252
return false;
5353
}
5454

55-
self.y().modpow(components.q(), components.p()) == BigUint::one()
55+
*self.y() >= two() && self.y().modpow(components.q(), components.p()) == BigUint::one()
5656
}
5757

5858
/// Verify if the signature matches the provided hash

0 commit comments

Comments
 (0)