Skip to content

Commit

Permalink
Add signing_key::Error
Browse files Browse the repository at this point in the history
  • Loading branch information
bouzuya committed Apr 14, 2024
1 parent 909f75b commit 1a7af29
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 49 deletions.
11 changes: 5 additions & 6 deletions src/html_form_data.rs
Expand Up @@ -18,8 +18,6 @@ pub(crate) enum ErrorKind {
AccessibleAtOutOfRange,
#[error("bound token authorizer: {0}")]
BoundTokenAuthorizer(#[source] crate::signing_key::BoundTokenError),
#[error("bound token sign: {0}")]
BoundTokenSign(#[source] crate::signing_key::BoundTokenError),
#[error("bucket not found")]
BucketNotFound,
#[error("expiration before accessible_at")]
Expand All @@ -30,10 +28,8 @@ pub(crate) enum ErrorKind {
KeyNotFound,
#[error("policy document serialization")]
PolicyDocumentSerialization,
#[error("service account private key parsing")]
ServiceAccountPrivateKeyParsing,
#[error(transparent)]
Sign(crate::private::signed_url::Error),
Signing(crate::signing_key::Error),
#[error("x-goog-algorithm not supported")]
XGoogAlgorithmNotSupported,
#[error("x-goog-credential invalid")]
Expand Down Expand Up @@ -559,7 +555,10 @@ impl HtmlFormDataBuilder {
policy.as_bytes(),
);
let message = encoded_policy.as_str();
let message_digest = signing_key.sign(*use_sign_blob, message.as_bytes()).await?;
let message_digest = signing_key
.sign(*use_sign_blob, message.as_bytes())
.await
.map_err(ErrorKind::Signing)?;
let x_goog_signature = hex_encode(&message_digest);
Ok((
Some(encoded_policy),
Expand Down
2 changes: 1 addition & 1 deletion src/private.rs
Expand Up @@ -22,6 +22,6 @@ pub(crate) use self::http_verb::HttpVerb;
pub(crate) use self::location::Location;
pub(crate) use self::request_type::RequestType;
pub(crate) use self::service::Service;
pub(crate) use self::signed_url::{hex_encode, sign, SignedUrl};
pub(crate) use self::signed_url::{hex_encode, SignedUrl};
pub(crate) use self::signing_algorithm::SigningAlgorithm;
pub(crate) use self::string_to_sign::StringToSign;
28 changes: 2 additions & 26 deletions src/private/signed_url.rs
@@ -1,4 +1,4 @@
use std::{collections::BTreeSet, vec};
use std::collections::BTreeSet;

use crate::SigningKey;

Expand Down Expand Up @@ -38,7 +38,7 @@ impl SignedUrl {
) -> Result<Self, Error> {
// FIXME: handle error
let service_account_client_email = signing_key.authorizer().await.unwrap();
let x_goog_algorithm = SigningAlgorithm::Goog4RsaSha256;
let x_goog_algorithm = signing_key.x_goog_algorithm();
add_signed_url_required_query_string_parameters(
&mut request,
service_account_client_email.as_str(),
Expand Down Expand Up @@ -132,30 +132,6 @@ pub(crate) fn hex_encode(message_digest: &[u8]) -> String {
})
}

pub(crate) fn sign(
algorithm: SigningAlgorithm,
key: &[u8],
message: &[u8],
) -> Result<Vec<u8>, Error> {
match algorithm {
SigningAlgorithm::Goog4RsaSha256 => {
let key_pair =
ring::signature::RsaKeyPair::from_pkcs8(key).map_err(ErrorKind::KeyRejected)?;
let mut signature = vec![0; key_pair.public().modulus_len()];
key_pair
.sign(
&ring::signature::RSA_PKCS1_SHA256,
&ring::rand::SystemRandom::new(),
message,
&mut signature,
)
.map_err(ErrorKind::Sign)?;
Ok(signature)
}
_ => unimplemented!(),
}
}

#[cfg(test)]
mod tests {
use crate::private::{utils::UnixTimestamp, Date, Location, RequestType, Service};
Expand Down
48 changes: 32 additions & 16 deletions src/signing_key.rs
Expand Up @@ -5,6 +5,22 @@ use std::{

use crate::private::SigningAlgorithm;

#[derive(Debug, thiserror::Error)]
#[error(transparent)]
pub struct Error(#[from] ErrorKind);

#[derive(Debug, thiserror::Error)]
enum ErrorKind {
#[error("bound token signing error: {0}")]
BoundTokenSigning(#[source] BoundTokenError),
#[error("service account private key pem parsing error: {0}")]
ServiceAccountPrivateKeyPemParsing(#[source] pem::PemError),
#[error("service account private key pkcs8 parsing error: {0}")]
ServiceAccountPrivateKeyPkcs8Parsing(ring::error::KeyRejected),
#[error("service account signing error: {0}")]
ServiceAccountSigning(ring::error::Unspecified),
}

#[derive(Clone)]
pub struct SigningKey(KeyInner);

Expand Down Expand Up @@ -38,18 +54,14 @@ impl SigningKey {
})
}

pub(crate) async fn sign(
&self,
use_sign_blob: bool,
message: &[u8],
) -> Result<Vec<u8>, crate::html_form_data::Error> {
pub(crate) async fn sign(&self, use_sign_blob: bool, message: &[u8]) -> Result<Vec<u8>, Error> {
match &self.0 {
KeyInner::BoundToken(bound_token) => {
if use_sign_blob {
Ok(bound_token
.sign(message)
.await
.map_err(crate::html_form_data::ErrorKind::BoundTokenSign)?)
.map_err(ErrorKind::BoundTokenSigning)?)
} else {
todo!()
}
Expand All @@ -59,17 +71,21 @@ impl SigningKey {
if use_sign_blob {
todo!()
} else {
let pkcs8 = pem::parse(private_key.as_bytes()).map_err(|_| {
crate::html_form_data::ErrorKind::ServiceAccountPrivateKeyParsing
})?;
let pkcs8 = pem::parse(private_key.as_bytes())
.map_err(ErrorKind::ServiceAccountPrivateKeyPemParsing)?;
let signing_key = pkcs8.contents();
let message_digest = crate::private::sign(
crate::private::SigningAlgorithm::Goog4RsaSha256,
signing_key,
message,
)
.map_err(crate::html_form_data::ErrorKind::Sign)?;
Ok(message_digest)
let key_pair = ring::signature::RsaKeyPair::from_pkcs8(signing_key)
.map_err(ErrorKind::ServiceAccountPrivateKeyPkcs8Parsing)?;
let mut signature = vec![0; key_pair.public().modulus_len()];
key_pair
.sign(
&ring::signature::RSA_PKCS1_SHA256,
&ring::rand::SystemRandom::new(),
message,
&mut signature,
)
.map_err(ErrorKind::ServiceAccountSigning)?;
Ok(signature)
}
}
}
Expand Down

0 comments on commit 1a7af29

Please sign in to comment.