Skip to content

Commit

Permalink
Make Error Send + Sync (fixes rpm-rs#191)
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Dec 3, 2023
1 parent f6081b6 commit 9a8fd27
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 36 deletions.
54 changes: 46 additions & 8 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
use std::io;
use std::{io, str::Utf8Error};

use thiserror::Error;

use crate::{DigestAlgorithm, TimestampError};

#[derive(Error, Debug)]
#[error(transparent)]
pub struct KeyLoadError {
kind: KeyLoadErrorKind,
}

impl KeyLoadError {
pub(crate) fn new<K>(kind: K) -> Self
where
KeyLoadErrorKind: From<K>,
{
Self { kind: kind.into() }
}
}

#[derive(Error, Debug)]
pub(crate) enum KeyLoadErrorKind {
#[error("Failed to parse bytes as utf8 for ascii armored parsing")]
Utf8Error(
#[from]
#[source]
Utf8Error,
),
#[error("Failed to parse bytes as ascii armored key")]
SecretKey(
#[from]
#[source]
pgp::errors::Error,
),
}

#[derive(Error, Debug)]
#[non_exhaustive]
pub enum Error {
Expand Down Expand Up @@ -57,17 +88,19 @@ pub enum Error {
NoSignatureFound,

#[error("error creating signature: {0}")]
SignError(Box<dyn std::error::Error>),
SignError(#[source] pgp::errors::Error),

#[error("error parsing key - {details}. underlying error was: {source}")]
KeyLoadError {
source: Box<dyn std::error::Error>,
details: &'static str,
},
#[error("error parsing key")]
KeyLoadError(
#[source]
#[from]
KeyLoadError,
),

#[error("error verifying signature with key {key_ref}: {source}")]
VerificationError {
source: Box<dyn std::error::Error>,
#[source]
source: pgp::errors::Error,
key_ref: String,
},

Expand Down Expand Up @@ -110,3 +143,8 @@ impl From<TimestampError> for Error {
Error::TimestampConv(error)
}
}

const _: () = {
const fn assert_send_sync<T: Send + Sync>() {}
assert_send_sync::<Error>();
};
41 changes: 13 additions & 28 deletions src/rpm/signature/pgp.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{traits, AlgorithmType};
use crate::errors::Error;
use crate::errors::{Error, KeyLoadError};
use crate::Timestamp;

use std::io;
Expand Down Expand Up @@ -63,12 +63,11 @@ impl traits::Signing for Signer {
let passwd_fn = || self.key_passphrase.clone().unwrap_or_default();
let signature_packet = sig_cfg
.sign(&self.secret_key, passwd_fn, data)
.map_err(|e| Error::SignError(Box::new(e)))?;
.map_err(Error::SignError)?;

let mut signature_bytes = Vec::with_capacity(1024);
let mut cursor = io::Cursor::new(&mut signature_bytes);
pgp::packet::write_packet(&mut cursor, &signature_packet)
.map_err(|e| Error::SignError(Box::new(e)))?;
pgp::packet::write_packet(&mut cursor, &signature_packet).map_err(Error::SignError)?;

Ok(signature_bytes)
}
Expand All @@ -82,19 +81,12 @@ impl Signer {
/// load the private key for signing
pub fn load_from_asc_bytes(input: &[u8]) -> Result<Self, Error> {
// only asc loading is supported right now
let input = std::str::from_utf8(input).map_err(|e| Error::KeyLoadError {
source: Box::new(e),
details: "Failed to parse bytes as utf8 for ascii armored parsing",
})?;
let input = std::str::from_utf8(input).map_err(KeyLoadError::new)?;
Self::load_from_asc(input)
}

pub fn load_from_asc(input: &str) -> Result<Self, Error> {
let (secret_key, _) =
SignedSecretKey::from_string(input).map_err(|e| Error::KeyLoadError {
source: Box::new(e),
details: "Failed to parse bytes as ascii armored key",
})?;
let (secret_key, _) = SignedSecretKey::from_string(input).map_err(KeyLoadError::new)?;
match secret_key.algorithm() {
PublicKeyAlgorithm::RSA => Ok(Self {
secret_key,
Expand Down Expand Up @@ -159,9 +151,9 @@ impl traits::Verifying for Verifier {
log::trace!("Signature has issuer ref: {:?}", key_id);

if self.public_key.key_id() == *key_id {
return signature.verify(&self.public_key, data).map_err(|e| {
return signature.verify(&self.public_key, data).map_err(|source| {
Error::VerificationError {
source: Box::new(e),
source,
key_ref: format!("{:?}", key_id),
}
});
Expand Down Expand Up @@ -193,10 +185,10 @@ impl traits::Verifying for Verifier {
);
return Ok(());
}
Err(e) => {
Err(source) => {
log::trace!("Subkey verification failed");
result = Err(Error::VerificationError {
source: Box::new(e),
source,
key_ref: format!("{:?}", sub_key.key_id()),
})
}
Expand All @@ -216,8 +208,8 @@ impl traits::Verifying for Verifier {
);
signature
.verify(&self.public_key, data)
.map_err(|e| Error::VerificationError {
source: Box::new(e),
.map_err(|source| Error::VerificationError {
source,
key_ref: format!("{:?}", self.public_key.key_id()),
})
}
Expand All @@ -231,19 +223,12 @@ impl traits::Verifying for Verifier {
impl Verifier {
pub fn load_from_asc_bytes(input: &[u8]) -> Result<Self, Error> {
// only asc loading is supported right now
let input = std::str::from_utf8(input).map_err(|e| Error::KeyLoadError {
source: Box::new(e),
details: "Failed to parse bytes as utf8 for ascii armored parsing",
})?;
let input = std::str::from_utf8(input).map_err(KeyLoadError::new)?;
Self::load_from_asc(input)
}

pub fn load_from_asc(input: &str) -> Result<Self, Error> {
let (public_key, _) =
SignedPublicKey::from_string(input).map_err(|e| Error::KeyLoadError {
source: Box::new(e),
details: "Failed to parse bytes as ascii armored key",
})?;
let (public_key, _) = SignedPublicKey::from_string(input).map_err(KeyLoadError::new)?;

match public_key.algorithm() {
PublicKeyAlgorithm::RSA => Ok(Self {
Expand Down

0 comments on commit 9a8fd27

Please sign in to comment.