Skip to content

Commit

Permalink
Adds support for ECDSA signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
baloo authored and dralley committed Nov 10, 2024
1 parent d1fd61a commit 8a50048
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added

- Added support for ecdsa signatures

## 0.16.0

### Added
Expand Down
16 changes: 16 additions & 0 deletions src/rpm/headers/signature_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,22 @@ impl SignatureHeaderBuilder<WithDigest> {
phantom: Default::default(),
}
}

pub fn add_ecdsa_signature(
mut self,
sig_header_only: &[u8],
) -> SignatureHeaderBuilder<WithSignature> {
let offset = 0i32; // filled externally later on
self.entries.push(IndexEntry::new(
IndexSignatureTag::RPMSIGTAG_DSA,
offset,
IndexData::Bin(sig_header_only.to_vec()),
));
SignatureHeaderBuilder::<WithSignature> {
entries: self.entries,
phantom: Default::default(),
}
}
}

#[cfg(test)]
Expand Down
3 changes: 3 additions & 0 deletions src/rpm/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ impl Package {
crate::signature::AlgorithmType::EdDSA => {
sig_header_builder.add_eddsa_signature(&header_signature)
}
crate::signature::AlgorithmType::ECDSA => {
sig_header_builder.add_ecdsa_signature(&header_signature)
}
};

self.metadata.signature = sig_header_builder.build();
Expand Down
10 changes: 10 additions & 0 deletions src/rpm/signature/pgp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ impl From<traits::AlgorithmType> for ::pgp::crypto::public_key::PublicKeyAlgorit
match value {
traits::AlgorithmType::RSA => PublicKeyAlgorithm::RSA,
traits::AlgorithmType::EdDSA => PublicKeyAlgorithm::EdDSALegacy,
traits::AlgorithmType::ECDSA => PublicKeyAlgorithm::ECDSA,
}
}
}
Expand Down Expand Up @@ -100,6 +101,11 @@ where
algorithm: AlgorithmType::EdDSA,
key_passphrase: None,
}),
PublicKeyAlgorithm::ECDSA => Ok(Self {
secret_key: inner,
algorithm: AlgorithmType::ECDSA,
key_passphrase: None,
}),
algorithm => Err(Error::UnsupportedPGPKeyType(algorithm)),
}
}
Expand Down Expand Up @@ -263,6 +269,10 @@ impl Verifier {
public_key,
algorithm: AlgorithmType::EdDSA,
}),
PublicKeyAlgorithm::ECDSA => Ok(Self {
public_key,
algorithm: AlgorithmType::ECDSA,
}),
a => Err(Error::UnsupportedPGPKeyType(a)),
}
}
Expand Down
1 change: 1 addition & 0 deletions src/rpm/signature/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::io;
#[derive(Clone, Copy, Debug)]
pub enum AlgorithmType {
RSA,
ECDSA,
EdDSA,
}

Expand Down
10 changes: 10 additions & 0 deletions test_assets/fixture_packages/signing_keys/public_nistp256.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----

mFIEZy0/HRMIKoZIzj0DAQcCAwTV3+oPJaeeZrD7lMsdwnV2xD3ZpVuM7QRqERgz
cCOy/mkwdWySiWLe746qxGE015wJ/F/tP5nsDgZJg9A4ofwYtBlBbGljZSA8YWxp
Y2VAZXhhbXBsZS5jb20+iJAEExMIADgWIQSv7E04DLxEn5XutuCNvq52nKsG6gUC
Zy0/HQIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRCNvq52nKsG6nwsAP91
H80ltwaC07b+T1vpU+WNN1gKIAKTCXEgbYmHJmmAogEAprfD7g4va0CVkgNxNJlM
GrBALsDsXGFrcQi45tDKRUI=
=GgQq
-----END PGP PUBLIC KEY BLOCK-----
11 changes: 11 additions & 0 deletions test_assets/fixture_packages/signing_keys/secret_nistp256.asc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----

lHcEZy0/HRMIKoZIzj0DAQcCAwTV3+oPJaeeZrD7lMsdwnV2xD3ZpVuM7QRqERgz
cCOy/mkwdWySiWLe746qxGE015wJ/F/tP5nsDgZJg9A4ofwYAAD7B9vjV/l8xtDV
tJsRCL51KjMg7TH3hzfI8j7MQZYu+m4SE7QZQWxpY2UgPGFsaWNlQGV4YW1wbGUu
Y29tPoiQBBMTCAA4FiEEr+xNOAy8RJ+V7rbgjb6udpyrBuoFAmctPx0CGwMFCwkI
BwIGFQoJCAsCBBYCAwECHgECF4AACgkQjb6udpyrBup8LAD/dR/NJbcGgtO2/k9b
6VPljTdYCiACkwlxIG2JhyZpgKIBAKa3w+4OL2tAlZIDcTSZTBqwQC7A7Fxha3EI
uObQykVC
=mSPj
-----END PGP PRIVATE KEY BLOCK-----
16 changes: 16 additions & 0 deletions tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,19 @@ pub fn eddsa_public_key() -> Vec<u8> {
pub fn load_eddsa_keys() -> (Vec<u8>, Vec<u8>) {
(eddsa_private_key(), eddsa_public_key())
}

pub fn ecdsa_private_key() -> Vec<u8> {
let private_key =
cargo_manifest_dir().join("test_assets/fixture_packages/signing_keys/secret_nistp256.asc");
std::fs::read(private_key).unwrap()
}

pub fn ecdsa_public_key() -> Vec<u8> {
let public_key =
cargo_manifest_dir().join("test_assets/fixture_packages/signing_keys/public_nistp256.asc");
std::fs::read(public_key).unwrap()
}

pub fn load_ecdsa_keys() -> (Vec<u8>, Vec<u8>) {
(ecdsa_private_key(), ecdsa_public_key())
}
22 changes: 22 additions & 0 deletions tests/signatures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ fn test_rpm_file_signatures_resign() -> Result<(), Box<dyn std::error::Error>> {
None,
&verification_key,
"eddsa_resigned_pkg.rpm",
)?;

// test ECDSA
let (signing_key, verification_key) = common::load_ecdsa_keys();
resign_and_verify_with_keys(
pkg_path.as_ref(),
&signing_key,
None,
&verification_key,
"ecdsa_resigned_pkg.rpm",
)
}

Expand All @@ -59,6 +69,10 @@ fn parse_externally_signed_rpm_and_verify() -> Result<(), Box<dyn std::error::Er
let (signing_key, verification_key) = common::load_eddsa_keys();
build_parse_sign_and_verify(&signing_key, &verification_key, "eddsa_signed_pkg.rpm")?;

// test ECDSA
let (signing_key, verification_key) = common::load_ecdsa_keys();
build_parse_sign_and_verify(&signing_key, &verification_key, "ecdsa_signed_pkg.rpm")?;

Ok(())
}

Expand All @@ -83,6 +97,14 @@ fn test_verify_unsigned_package() -> Result<(), Box<dyn std::error::Error>> {
Err(rpm::Error::NoSignatureFound)
));

// test ECDSA
let verification_key = common::ecdsa_public_key();
let verifier = Verifier::load_from_asc_bytes(verification_key.as_ref())?;
assert!(matches!(
pkg.verify_signature(verifier),
Err(rpm::Error::NoSignatureFound)
));

Ok(())
}

Expand Down

0 comments on commit 8a50048

Please sign in to comment.