Skip to content

Commit

Permalink
Merge pull-request #499
Browse files Browse the repository at this point in the history
  • Loading branch information
r-n-o committed Jan 2, 2025
2 parents 434b39b + ff69616 commit 0ae2f77
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 1 deletion.
31 changes: 31 additions & 0 deletions src/qos_p256/src/encrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,13 @@ impl P256EncryptPublic {

/// Deserialize from a SEC1 encoded point, not compressed.
pub fn from_bytes(bytes: &[u8]) -> Result<Self, P256Error> {
if bytes.len() > PUB_KEY_LEN_UNCOMPRESSED as usize {
return Err(P256Error::EncodedPublicKeyTooLong);
}
if bytes.len() < PUB_KEY_LEN_UNCOMPRESSED as usize {
return Err(P256Error::EncodedPublicKeyTooShort);
}

Ok(Self {
public: PublicKey::from_sec1_bytes(bytes)
.map_err(|_| P256Error::FailedToReadPublicKey)?,
Expand Down Expand Up @@ -551,6 +558,30 @@ mod test_asymmetric {
assert_eq!(decrypted, plaintext);
}

#[test]
fn encoded_public_keys_bytes_are_validated() {
let too_short = vec![0u8; 64];
let too_long = vec![0u8; 66];

// Uncompressed public key with a compressed prefix (0x02)
let bad_prefix = qos_hex::decode("02bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();
let just_right = qos_hex::decode("04bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();

assert!(matches!(
P256EncryptPublic::from_bytes(&too_short),
Err(P256Error::EncodedPublicKeyTooShort)
));
assert!(matches!(
P256EncryptPublic::from_bytes(&too_long),
Err(P256Error::EncodedPublicKeyTooLong)
));
assert!(matches!(
P256EncryptPublic::from_bytes(&bad_prefix),
Err(P256Error::FailedToReadPublicKey),
));
assert!(matches!(P256EncryptPublic::from_bytes(&just_right), Ok(_),));
}

#[test]
fn private_key_roundtrip_bytes() {
let pair = P256EncryptPair::generate();
Expand Down
33 changes: 32 additions & 1 deletion src/qos_p256/src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use p256::ecdsa::{
use rand_core::OsRng;
use zeroize::ZeroizeOnDrop;

use crate::P256Error;
use crate::{P256Error, PUB_KEY_LEN_UNCOMPRESSED};

/// Sign private key pair.
#[derive(ZeroizeOnDrop)]
Expand Down Expand Up @@ -86,6 +86,13 @@ impl P256SignPublic {

/// Deserialize from a SEC1 encoded point, not compressed.
pub fn from_bytes(bytes: &[u8]) -> Result<Self, P256Error> {
if bytes.len() > PUB_KEY_LEN_UNCOMPRESSED as usize {
return Err(P256Error::EncodedPublicKeyTooLong);
}
if bytes.len() < PUB_KEY_LEN_UNCOMPRESSED as usize {
return Err(P256Error::EncodedPublicKeyTooShort);
}

Ok(Self {
public: VerifyingKey::from_sec1_bytes(bytes)
.map_err(|_| P256Error::FailedToReadPublicKey)?,
Expand Down Expand Up @@ -157,4 +164,28 @@ mod tests {

assert_eq!(raw_secret1, raw_secret2);
}

#[test]
fn encoded_public_keys_bytes_are_validated() {
let too_short = vec![0u8; 64];
let too_long = vec![0u8; 66];

// Uncompressed public key with a compressed prefix (0x02)
let bad_prefix = qos_hex::decode("02bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();
let just_right = qos_hex::decode("04bf772379de68fed2e81a47a141210c827c31fadc5b24ed3dafa84a9d19896172cb1b53ee6ecb38ca5c4be4d664b63f034886b764ad520c301fe542dfdf4002e4").unwrap();

assert!(matches!(
P256SignPublic::from_bytes(&too_short),
Err(P256Error::EncodedPublicKeyTooShort)
));
assert!(matches!(
P256SignPublic::from_bytes(&too_long),
Err(P256Error::EncodedPublicKeyTooLong)
));
assert!(matches!(
P256SignPublic::from_bytes(&bad_prefix),
Err(P256Error::FailedToReadPublicKey),
));
assert!(matches!(P256SignPublic::from_bytes(&just_right), Ok(_),));
}
}

0 comments on commit 0ae2f77

Please sign in to comment.