1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use ring::{rand, signature};
use crate::crypto::algorithm::AlgorithmID;
use crate::crypto::SecretOrKey;
use crate::error::{Error, ErrorDetails};
use crate::raw::*;
impl From<AlgorithmID> for &signature::EcdsaSigningAlgorithm {
fn from(alg: AlgorithmID) -> Self {
match alg {
AlgorithmID::ES256 => &signature::ECDSA_P256_SHA256_FIXED_SIGNING,
AlgorithmID::ES384 => &signature::ECDSA_P384_SHA384_FIXED_SIGNING,
_ => unreachable!("Tried to get EC alg for a non-EC algorithm"),
}
}
}
pub fn sign(
_algorithm: AlgorithmID,
secret_or_key: &SecretOrKey,
message: &str,
) -> Result<String, Error> {
match secret_or_key {
SecretOrKey::EcdsaKeyPair(signing_key) => {
let rng = rand::SystemRandom::new();
let out = signing_key.sign(&rng, message.as_bytes()).map_err(|e| {
Error::InvalidInput(ErrorDetails::map(
"Failed to sign JWT with ECDSA",
Box::new(e),
))
})?;
Ok(b64_encode(out.as_ref()))
}
_ => Err(Error::InvalidInput(ErrorDetails::new(
"Missing ECDSA private key for signing",
))),
}
}
pub fn verify(
algorithm: AlgorithmID,
secret_or_key: &SecretOrKey,
message: &str,
signature: &str,
) -> Result<(), Error> {
let ring_alg = algorithm.into();
match secret_or_key {
SecretOrKey::EcdsaUnparsedKey(key) => {
let public_key = signature::UnparsedPublicKey::new(ring_alg, key);
let signature_bytes = b64_decode(signature)?;
public_key
.verify(message.as_bytes(), &signature_bytes)
.map_err(|_| Error::InvalidSignature())
}
_ => Err(Error::InvalidInput(ErrorDetails::new(
"Missing ECDSA public key for signing",
))),
}
}