jsonwebtoken/crypto/
ecdsa.rs

1use ring::{rand, signature};
2
3use crate::algorithms::Algorithm;
4use crate::errors::Result;
5use crate::serialization::b64_encode;
6
7/// Only used internally when validating EC, to map from our enum to the Ring EcdsaVerificationAlgorithm structs.
8pub(crate) fn alg_to_ec_verification(
9    alg: Algorithm,
10) -> &'static signature::EcdsaVerificationAlgorithm {
11    match alg {
12        Algorithm::ES256 => &signature::ECDSA_P256_SHA256_FIXED,
13        Algorithm::ES384 => &signature::ECDSA_P384_SHA384_FIXED,
14        _ => unreachable!("Tried to get EC alg for a non-EC algorithm"),
15    }
16}
17
18/// Only used internally when signing EC, to map from our enum to the Ring EcdsaVerificationAlgorithm structs.
19pub(crate) fn alg_to_ec_signing(alg: Algorithm) -> &'static signature::EcdsaSigningAlgorithm {
20    match alg {
21        Algorithm::ES256 => &signature::ECDSA_P256_SHA256_FIXED_SIGNING,
22        Algorithm::ES384 => &signature::ECDSA_P384_SHA384_FIXED_SIGNING,
23        _ => unreachable!("Tried to get EC alg for a non-EC algorithm"),
24    }
25}
26
27/// The actual ECDSA signing + encoding
28/// The key needs to be in PKCS8 format
29pub fn sign(
30    alg: &'static signature::EcdsaSigningAlgorithm,
31    key: &[u8],
32    message: &[u8],
33) -> Result<String> {
34    let rng = rand::SystemRandom::new();
35    let signing_key = signature::EcdsaKeyPair::from_pkcs8(alg, key, &rng)?;
36    let out = signing_key.sign(&rng, message)?;
37    Ok(b64_encode(out))
38}