|  | 
|  | 1 | +use jsonwebtoken::{ | 
|  | 2 | +    Algorithm, DecodingKey, EncodingKey, Header, Validation, | 
|  | 3 | +    crypto::{CryptoProvider, JwkUtils, JwtSigner, JwtVerifier}, | 
|  | 4 | +    decode, encode, | 
|  | 5 | +    errors::Error, | 
|  | 6 | +}; | 
|  | 7 | +use serde::{Deserialize, Serialize}; | 
|  | 8 | +use signature::{Signer, Verifier}; | 
|  | 9 | + | 
|  | 10 | +fn new_signer(algorithm: &Algorithm, key: &EncodingKey) -> Result<Box<dyn JwtSigner>, Error> { | 
|  | 11 | +    let jwt_signer = match algorithm { | 
|  | 12 | +        Algorithm::EdDSA => Box::new(CustomEdDSASigner::new(key)?) as Box<dyn JwtSigner>, | 
|  | 13 | +        _ => unimplemented!(), | 
|  | 14 | +    }; | 
|  | 15 | + | 
|  | 16 | +    Ok(jwt_signer) | 
|  | 17 | +} | 
|  | 18 | + | 
|  | 19 | +fn new_verifier(algorithm: &Algorithm, key: &DecodingKey) -> Result<Box<dyn JwtVerifier>, Error> { | 
|  | 20 | +    let jwt_verifier = match algorithm { | 
|  | 21 | +        Algorithm::EdDSA => Box::new(CustomEdDSAVerifier::new(key)?) as Box<dyn JwtVerifier>, | 
|  | 22 | +        _ => unimplemented!(), | 
|  | 23 | +    }; | 
|  | 24 | + | 
|  | 25 | +    Ok(jwt_verifier) | 
|  | 26 | +} | 
|  | 27 | + | 
|  | 28 | +pub struct CustomEdDSASigner; | 
|  | 29 | + | 
|  | 30 | +impl CustomEdDSASigner { | 
|  | 31 | +    fn new(_: &EncodingKey) -> Result<Self, Error> { | 
|  | 32 | +        Ok(CustomEdDSASigner) | 
|  | 33 | +    } | 
|  | 34 | +} | 
|  | 35 | + | 
|  | 36 | +// WARNING: This is obviously not secure at all and should NEVER be done in practice! | 
|  | 37 | +impl Signer<Vec<u8>> for CustomEdDSASigner { | 
|  | 38 | +    fn try_sign(&self, _: &[u8]) -> Result<Vec<u8>, signature::Error> { | 
|  | 39 | +        Ok(vec![0; 16]) | 
|  | 40 | +    } | 
|  | 41 | +} | 
|  | 42 | + | 
|  | 43 | +impl JwtSigner for CustomEdDSASigner { | 
|  | 44 | +    fn algorithm(&self) -> Algorithm { | 
|  | 45 | +        Algorithm::EdDSA | 
|  | 46 | +    } | 
|  | 47 | +} | 
|  | 48 | + | 
|  | 49 | +pub struct CustomEdDSAVerifier; | 
|  | 50 | + | 
|  | 51 | +impl CustomEdDSAVerifier { | 
|  | 52 | +    fn new(_: &DecodingKey) -> Result<Self, Error> { | 
|  | 53 | +        Ok(CustomEdDSAVerifier) | 
|  | 54 | +    } | 
|  | 55 | +} | 
|  | 56 | + | 
|  | 57 | +impl Verifier<Vec<u8>> for CustomEdDSAVerifier { | 
|  | 58 | +    fn verify(&self, _: &[u8], signature: &Vec<u8>) -> Result<(), signature::Error> { | 
|  | 59 | +        if signature == &vec![0; 16] { Ok(()) } else { Err(signature::Error::new()) } | 
|  | 60 | +    } | 
|  | 61 | +} | 
|  | 62 | + | 
|  | 63 | +impl JwtVerifier for CustomEdDSAVerifier { | 
|  | 64 | +    fn algorithm(&self) -> Algorithm { | 
|  | 65 | +        Algorithm::EdDSA | 
|  | 66 | +    } | 
|  | 67 | +} | 
|  | 68 | + | 
|  | 69 | +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] | 
|  | 70 | +pub struct Claims { | 
|  | 71 | +    sub: String, | 
|  | 72 | +    exp: u64, | 
|  | 73 | +} | 
|  | 74 | + | 
|  | 75 | +fn main() { | 
|  | 76 | +    // create and install our custom provider | 
|  | 77 | +    let my_crypto_provider = CryptoProvider { | 
|  | 78 | +        signer_factory: new_signer, | 
|  | 79 | +        verifier_factory: new_verifier, | 
|  | 80 | +        // the default impl uses dummy functions that panic, but we don't need them here | 
|  | 81 | +        jwk_utils: JwkUtils::default(), | 
|  | 82 | +    }; | 
|  | 83 | +    my_crypto_provider.install_default().unwrap(); | 
|  | 84 | + | 
|  | 85 | +    // for an actual EdDSA implementation, this would be some private key | 
|  | 86 | +    let key = b"secret"; | 
|  | 87 | +    let my_claims = Claims { sub: "me".to_owned(), exp: 10000000000 }; | 
|  | 88 | + | 
|  | 89 | +    // our crypto provider only supports EdDSA | 
|  | 90 | +    let header = Header::new(Algorithm::EdDSA); | 
|  | 91 | + | 
|  | 92 | +    let token = match encode(&header, &my_claims, &EncodingKey::from_ed_der(key)) { | 
|  | 93 | +        Ok(t) => t, | 
|  | 94 | +        Err(_) => panic!(), // in practice you would return an error | 
|  | 95 | +    }; | 
|  | 96 | + | 
|  | 97 | +    let claims = match decode::<Claims>( | 
|  | 98 | +        token, | 
|  | 99 | +        &DecodingKey::from_ed_der(key), | 
|  | 100 | +        &Validation::new(Algorithm::EdDSA), | 
|  | 101 | +    ) { | 
|  | 102 | +        Ok(c) => c.claims, | 
|  | 103 | +        Err(_) => panic!(), | 
|  | 104 | +    }; | 
|  | 105 | + | 
|  | 106 | +    assert_eq!(my_claims, claims); | 
|  | 107 | +} | 
0 commit comments