Skip to content

Commit 0ae2f77

Browse files
committed
Merge pull-request #499
2 parents 434b39b + ff69616 commit 0ae2f77

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

src/qos_p256/src/encrypt.rs

+31
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ impl P256EncryptPublic {
220220

221221
/// Deserialize from a SEC1 encoded point, not compressed.
222222
pub fn from_bytes(bytes: &[u8]) -> Result<Self, P256Error> {
223+
if bytes.len() > PUB_KEY_LEN_UNCOMPRESSED as usize {
224+
return Err(P256Error::EncodedPublicKeyTooLong);
225+
}
226+
if bytes.len() < PUB_KEY_LEN_UNCOMPRESSED as usize {
227+
return Err(P256Error::EncodedPublicKeyTooShort);
228+
}
229+
223230
Ok(Self {
224231
public: PublicKey::from_sec1_bytes(bytes)
225232
.map_err(|_| P256Error::FailedToReadPublicKey)?,
@@ -551,6 +558,30 @@ mod test_asymmetric {
551558
assert_eq!(decrypted, plaintext);
552559
}
553560

561+
#[test]
562+
fn encoded_public_keys_bytes_are_validated() {
563+
let too_short = vec![0u8; 64];
564+
let too_long = vec![0u8; 66];
565+
566+
// Uncompressed public key with a compressed prefix (0x02)
567+
let bad_prefix = qos_hex::decode("02bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();
568+
let just_right = qos_hex::decode("04bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();
569+
570+
assert!(matches!(
571+
P256EncryptPublic::from_bytes(&too_short),
572+
Err(P256Error::EncodedPublicKeyTooShort)
573+
));
574+
assert!(matches!(
575+
P256EncryptPublic::from_bytes(&too_long),
576+
Err(P256Error::EncodedPublicKeyTooLong)
577+
));
578+
assert!(matches!(
579+
P256EncryptPublic::from_bytes(&bad_prefix),
580+
Err(P256Error::FailedToReadPublicKey),
581+
));
582+
assert!(matches!(P256EncryptPublic::from_bytes(&just_right), Ok(_),));
583+
}
584+
554585
#[test]
555586
fn private_key_roundtrip_bytes() {
556587
let pair = P256EncryptPair::generate();

src/qos_p256/src/sign.rs

+32-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use p256::ecdsa::{
77
use rand_core::OsRng;
88
use zeroize::ZeroizeOnDrop;
99

10-
use crate::P256Error;
10+
use crate::{P256Error, PUB_KEY_LEN_UNCOMPRESSED};
1111

1212
/// Sign private key pair.
1313
#[derive(ZeroizeOnDrop)]
@@ -86,6 +86,13 @@ impl P256SignPublic {
8686

8787
/// Deserialize from a SEC1 encoded point, not compressed.
8888
pub fn from_bytes(bytes: &[u8]) -> Result<Self, P256Error> {
89+
if bytes.len() > PUB_KEY_LEN_UNCOMPRESSED as usize {
90+
return Err(P256Error::EncodedPublicKeyTooLong);
91+
}
92+
if bytes.len() < PUB_KEY_LEN_UNCOMPRESSED as usize {
93+
return Err(P256Error::EncodedPublicKeyTooShort);
94+
}
95+
8996
Ok(Self {
9097
public: VerifyingKey::from_sec1_bytes(bytes)
9198
.map_err(|_| P256Error::FailedToReadPublicKey)?,
@@ -157,4 +164,28 @@ mod tests {
157164

158165
assert_eq!(raw_secret1, raw_secret2);
159166
}
167+
168+
#[test]
169+
fn encoded_public_keys_bytes_are_validated() {
170+
let too_short = vec![0u8; 64];
171+
let too_long = vec![0u8; 66];
172+
173+
// Uncompressed public key with a compressed prefix (0x02)
174+
let bad_prefix = qos_hex::decode("02bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();
175+
let just_right = qos_hex::decode("04bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();
176+
177+
assert!(matches!(
178+
P256SignPublic::from_bytes(&too_short),
179+
Err(P256Error::EncodedPublicKeyTooShort)
180+
));
181+
assert!(matches!(
182+
P256SignPublic::from_bytes(&too_long),
183+
Err(P256Error::EncodedPublicKeyTooLong)
184+
));
185+
assert!(matches!(
186+
P256SignPublic::from_bytes(&bad_prefix),
187+
Err(P256Error::FailedToReadPublicKey),
188+
));
189+
assert!(matches!(P256SignPublic::from_bytes(&just_right), Ok(_),));
190+
}
160191
}

0 commit comments

Comments
 (0)