Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for ECDSA signatures #246

Merged
merged 1 commit into from
Nov 10, 2024
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: 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
Loading