diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cf9ede..2f9006e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 8.0.0 (unreleased) + +- Add EdDSA algorithm +- `sign`/`verify` now takes a `&[u8]` instead of `&str` to be more flexible + ## 7.2.0 (2020-06-30) - Add `dangerous_insecure_decode` to replace `dangerous_unsafe_decode`, which is now deprecated diff --git a/src/crypto/eddsa.rs b/src/crypto/eddsa.rs index 7a47ed2..d0b6f9d 100644 --- a/src/crypto/eddsa.rs +++ b/src/crypto/eddsa.rs @@ -16,8 +16,8 @@ pub(crate) fn alg_to_ec_verification(alg: Algorithm) -> &'static signature::EdDS /// The actual EdDSA signing + encoding /// The key needs to be in PKCS8 format -pub fn sign(key: &[u8], message: &str) -> Result { +pub fn sign(key: &[u8], message: &[u8]) -> Result { let signing_key = signature::Ed25519KeyPair::from_pkcs8_maybe_unchecked(key)?; - let out = signing_key.sign(message.as_bytes()); + let out = signing_key.sign(message); Ok(b64_encode(out.as_ref())) } diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs index 93432b7..1be9ee7 100644 --- a/src/crypto/mod.rs +++ b/src/crypto/mod.rs @@ -22,12 +22,7 @@ pub(crate) fn sign_hmac(alg: hmac::Algorithm, key: &[u8], message: &[u8]) -> Res /// the base64 url safe encoded of the result. /// /// If you just want to encode a JWT, use `encode` instead. -pub fn sign(message: &str, key: &EncodingKey, algorithm: Algorithm) -> Result { - 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 { +pub fn sign(message: &[u8], key: &EncodingKey, algorithm: Algorithm) -> Result { match algorithm { Algorithm::HS256 => sign_hmac(hmac::HMAC_SHA256, key.inner(), message), Algorithm::HS384 => sign_hmac(hmac::HMAC_SHA384, key.inner(), message), @@ -71,16 +66,6 @@ fn verify_ring( /// /// `message` is base64(header) + "." + base64(claims) pub fn verify( - signature: &str, - message: &str, - key: &DecodingKey, - algorithm: Algorithm, -) -> Result { - 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, @@ -89,7 +74,7 @@ pub fn verify_bytes( 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_bytes(message, &EncodingKey::from_secret(key.as_bytes()), algorithm)?; + let signed = sign(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( diff --git a/src/decoding.rs b/src/decoding.rs index 33462cf..110fdcd 100644 --- a/src/decoding.rs +++ b/src/decoding.rs @@ -186,7 +186,7 @@ pub fn decode( return Err(new_error(ErrorKind::InvalidAlgorithm)); } - if !verify(signature, message, key, header.alg)? { + if !verify(signature, message.as_bytes(), key, header.alg)? { return Err(new_error(ErrorKind::InvalidSignature)); } diff --git a/src/encoding.rs b/src/encoding.rs index cfb96e6..9a4b62c 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -117,7 +117,7 @@ pub fn encode(header: &Header, claims: &T, key: &EncodingKey) -> R let encoded_header = b64_encode_part(&header)?; let encoded_claims = b64_encode_part(&claims)?; let message = [encoded_header.as_ref(), encoded_claims.as_ref()].join("."); - let signature = crypto::sign(&*message, key, header.alg)?; + let signature = crypto::sign(&*message.as_bytes(), key, header.alg)?; Ok([message, signature].join(".")) } diff --git a/tests/ecdsa/mod.rs b/tests/ecdsa/mod.rs index 2362409..40e97df 100644 --- a/tests/ecdsa/mod.rs +++ b/tests/ecdsa/mod.rs @@ -18,9 +18,9 @@ fn round_trip_sign_verification_pk8() { let pubkey = include_bytes!("public_ecdsa_key.pk8"); let encrypted = - sign("hello world", &EncodingKey::from_ec_der(privkey), Algorithm::ES256).unwrap(); + sign("hello world".as_bytes(), &EncodingKey::from_ec_der(privkey), Algorithm::ES256).unwrap(); let is_valid = - verify(&encrypted, "hello world", &DecodingKey::from_ec_der(pubkey), Algorithm::ES256) + verify(&encrypted, "hello world".as_bytes(), &DecodingKey::from_ec_der(pubkey), Algorithm::ES256) .unwrap(); assert!(is_valid); } @@ -30,11 +30,11 @@ fn round_trip_sign_verification_pem() { let privkey_pem = include_bytes!("private_ecdsa_key.pem"); let pubkey_pem = include_bytes!("public_ecdsa_key.pem"); let encrypted = - sign("hello world", &EncodingKey::from_ec_pem(privkey_pem).unwrap(), Algorithm::ES256) + sign("hello world".as_bytes(), &EncodingKey::from_ec_pem(privkey_pem).unwrap(), Algorithm::ES256) .unwrap(); let is_valid = verify( &encrypted, - "hello world", + "hello world".as_bytes(), &DecodingKey::from_ec_pem(pubkey_pem).unwrap(), Algorithm::ES256, ) diff --git a/tests/eddsa/mod.rs b/tests/eddsa/mod.rs index 98cf532..c67f0c2 100644 --- a/tests/eddsa/mod.rs +++ b/tests/eddsa/mod.rs @@ -18,9 +18,9 @@ fn round_trip_sign_verification_pk8() { let pubkey = include_bytes!("public_ed25519_key.pk8"); let encrypted = - sign("hello world", &EncodingKey::from_ed_der(privkey), Algorithm::EdDSA).unwrap(); + sign("hello world".as_bytes(), &EncodingKey::from_ed_der(privkey), Algorithm::EdDSA).unwrap(); let is_valid = - verify(&encrypted, "hello world", &DecodingKey::from_ed_der(pubkey), Algorithm::EdDSA) + verify(&encrypted, "hello world".as_bytes(), &DecodingKey::from_ed_der(pubkey), Algorithm::EdDSA) .unwrap(); assert!(is_valid); } @@ -30,11 +30,11 @@ fn round_trip_sign_verification_pem() { let privkey_pem = include_bytes!("private_ed25519_key.pem"); let pubkey_pem = include_bytes!("public_ed25519_key.pem"); let encrypted = - sign("hello world", &EncodingKey::from_ed_pem(privkey_pem).unwrap(), Algorithm::EdDSA) + sign("hello world".as_bytes(), &EncodingKey::from_ed_pem(privkey_pem).unwrap(), Algorithm::EdDSA) .unwrap(); let is_valid = verify( &encrypted, - "hello world", + "hello world".as_bytes(), &DecodingKey::from_ed_pem(pubkey_pem).unwrap(), Algorithm::EdDSA, ) diff --git a/tests/hmac.rs b/tests/hmac.rs index aba469d..1a25cdf 100644 --- a/tests/hmac.rs +++ b/tests/hmac.rs @@ -17,7 +17,7 @@ pub struct Claims { #[test] fn sign_hs256() { let result = - sign("hello world", &EncodingKey::from_secret(b"secret"), Algorithm::HS256).unwrap(); + sign("hello world".as_bytes(), &EncodingKey::from_secret(b"secret"), Algorithm::HS256).unwrap(); let expected = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo"; assert_eq!(result, expected); } @@ -26,7 +26,7 @@ fn sign_hs256() { fn verify_hs256() { let sig = "c0zGLzKEFWj0VxWuufTXiRMk5tlI5MbGDAYhzaxIYjo"; let valid = - verify(sig, "hello world", &DecodingKey::from_secret(b"secret"), Algorithm::HS256).unwrap(); + verify(sig, "hello world".as_bytes(), &DecodingKey::from_secret(b"secret"), Algorithm::HS256).unwrap(); assert!(valid); } diff --git a/tests/rsa/mod.rs b/tests/rsa/mod.rs index 60a2b71..dfd28f0 100644 --- a/tests/rsa/mod.rs +++ b/tests/rsa/mod.rs @@ -28,9 +28,9 @@ fn round_trip_sign_verification_pem_pkcs1() { for &alg in RSA_ALGORITHMS { let encrypted = - sign("hello world", &EncodingKey::from_rsa_pem(privkey_pem).unwrap(), alg).unwrap(); + sign("hello world".as_bytes(), &EncodingKey::from_rsa_pem(privkey_pem).unwrap(), alg).unwrap(); let is_valid = - verify(&encrypted, "hello world", &DecodingKey::from_rsa_pem(pubkey_pem).unwrap(), alg) + verify(&encrypted, "hello world".as_bytes(), &DecodingKey::from_rsa_pem(pubkey_pem).unwrap(), alg) .unwrap(); assert!(is_valid); } @@ -43,9 +43,9 @@ fn round_trip_sign_verification_pem_pkcs8() { for &alg in RSA_ALGORITHMS { let encrypted = - sign("hello world", &EncodingKey::from_rsa_pem(privkey_pem).unwrap(), alg).unwrap(); + sign("hello world".as_bytes(), &EncodingKey::from_rsa_pem(privkey_pem).unwrap(), alg).unwrap(); let is_valid = - verify(&encrypted, "hello world", &DecodingKey::from_rsa_pem(pubkey_pem).unwrap(), alg) + verify(&encrypted, "hello world".as_bytes(), &DecodingKey::from_rsa_pem(pubkey_pem).unwrap(), alg) .unwrap(); assert!(is_valid); } @@ -57,9 +57,9 @@ fn round_trip_sign_verification_der() { let pubkey_der = include_bytes!("public_rsa_key.der"); for &alg in RSA_ALGORITHMS { - let encrypted = sign("hello world", &EncodingKey::from_rsa_der(privkey_der), alg).unwrap(); + let encrypted = sign("hello world".as_bytes(), &EncodingKey::from_rsa_der(privkey_der), alg).unwrap(); let is_valid = - verify(&encrypted, "hello world", &DecodingKey::from_rsa_der(pubkey_der), alg).unwrap(); + verify(&encrypted, "hello world".as_bytes(), &DecodingKey::from_rsa_der(pubkey_der), alg).unwrap(); assert!(is_valid); } }