Add sign and verify on bytes (#150)

This commit is contained in:
Charles Lehner 2020-11-17 08:17:40 -05:00 committed by Vincent Prouillet
parent 2178cc7506
commit 4aee8bc382
3 changed files with 26 additions and 13 deletions

View File

@ -29,10 +29,10 @@ pub(crate) fn alg_to_ec_signing(alg: Algorithm) -> &'static signature::EcdsaSign
pub fn sign(
alg: &'static signature::EcdsaSigningAlgorithm,
key: &[u8],
message: &str,
message: &[u8],
) -> Result<String> {
let signing_key = signature::EcdsaKeyPair::from_pkcs8(alg, key)?;
let rng = rand::SystemRandom::new();
let out = signing_key.sign(&rng, message.as_bytes())?;
let out = signing_key.sign(&rng, message)?;
Ok(b64_encode(out.as_ref()))
}

View File

@ -13,8 +13,8 @@ pub(crate) mod rsa;
/// The actual HS signing + encoding
/// Could be in its own file to match RSA/EC but it's 2 lines...
pub(crate) fn sign_hmac(alg: hmac::Algorithm, key: &[u8], message: &str) -> Result<String> {
let digest = hmac::sign(&hmac::Key::new(alg, key), message.as_bytes());
pub(crate) fn sign_hmac(alg: hmac::Algorithm, key: &[u8], message: &[u8]) -> Result<String> {
let digest = hmac::sign(&hmac::Key::new(alg, key), message);
Ok(b64_encode(digest.as_ref()))
}
@ -23,6 +23,11 @@ pub(crate) fn sign_hmac(alg: hmac::Algorithm, key: &[u8], message: &str) -> Resu
///
/// If you just want to encode a JWT, use `encode` instead.
pub fn sign(message: &str, key: &EncodingKey, algorithm: Algorithm) -> Result<String> {
sign_bytes(message.as_bytes(), key, algorithm)
}
/// Same as sign() but for message as bytes
pub fn sign_bytes(message: &[u8], key: &EncodingKey, algorithm: Algorithm) -> Result<String> {
match algorithm {
Algorithm::HS256 => sign_hmac(hmac::HMAC_SHA256, key.inner(), message),
Algorithm::HS384 => sign_hmac(hmac::HMAC_SHA384, key.inner(), message),
@ -47,12 +52,12 @@ pub fn sign(message: &str, key: &EncodingKey, algorithm: Algorithm) -> Result<St
fn verify_ring(
alg: &'static dyn signature::VerificationAlgorithm,
signature: &str,
message: &str,
message: &[u8],
key: &[u8],
) -> Result<bool> {
let signature_bytes = b64_decode(signature)?;
let public_key = signature::UnparsedPublicKey::new(alg, key);
let res = public_key.verify(message.as_bytes(), &signature_bytes);
let res = public_key.verify(message, &signature_bytes);
Ok(res.is_ok())
}
@ -70,11 +75,21 @@ pub fn verify(
message: &str,
key: &DecodingKey,
algorithm: Algorithm,
) -> Result<bool> {
Ok(verify_bytes(signature, message.as_bytes(), key, algorithm)?)
}
/// Same as verify() but for message as bytes
pub fn verify_bytes(
signature: &str,
message: &[u8],
key: &DecodingKey,
algorithm: Algorithm,
) -> Result<bool> {
match algorithm {
Algorithm::HS256 | Algorithm::HS384 | Algorithm::HS512 => {
// we just re-sign the message with the key and compare if they are equal
let signed = sign(message, &EncodingKey::from_secret(key.as_bytes()), algorithm)?;
let signed = sign_bytes(message, &EncodingKey::from_secret(key.as_bytes()), algorithm)?;
Ok(verify_slices_are_equal(signature.as_ref(), signed.as_ref()).is_ok())
}
Algorithm::ES256 | Algorithm::ES384 => verify_ring(

View File

@ -37,15 +37,13 @@ pub(crate) fn alg_to_rsa_signing(alg: Algorithm) -> &'static dyn signature::RsaE
pub(crate) fn sign(
alg: &'static dyn signature::RsaEncoding,
key: &[u8],
message: &str,
message: &[u8],
) -> Result<String> {
let key_pair = signature::RsaKeyPair::from_der(key).map_err(|_| ErrorKind::InvalidRsaKey)?;
let mut signature = vec![0; key_pair.public_modulus_len()];
let rng = rand::SystemRandom::new();
key_pair
.sign(alg, &rng, message.as_bytes(), &mut signature)
.map_err(|_| ErrorKind::InvalidRsaKey)?;
key_pair.sign(alg, &rng, message, &mut signature).map_err(|_| ErrorKind::InvalidRsaKey)?;
Ok(b64_encode(&signature))
}
@ -54,13 +52,13 @@ pub(crate) fn sign(
pub(crate) fn verify_from_components(
alg: &'static signature::RsaParameters,
signature: &str,
message: &str,
message: &[u8],
components: (&str, &str),
) -> Result<bool> {
let signature_bytes = b64_decode(signature)?;
let n = BigUint::from_bytes_be(&b64_decode(components.0)?).to_bytes_be();
let e = BigUint::from_bytes_be(&b64_decode(components.1)?).to_bytes_be();
let pubkey = signature::RsaPublicKeyComponents { n, e };
let res = pubkey.verify(alg, message.as_ref(), &signature_bytes);
let res = pubkey.verify(alg, message, &signature_bytes);
Ok(res.is_ok())
}