rustls-rustcrypto 0.0.2-alpha

Pure Rust cryptography provider for the Rustls TLS library using algorithm implementations from the RustCrypto organization
Documentation
use der::Decode;
use digest::Digest;
use paste::paste;
use pki_types::{AlgorithmIdentifier, InvalidSignature, SignatureVerificationAlgorithm};
use signature::hazmat::PrehashVerifier;
use webpki::alg_id;

macro_rules! impl_generic_ecdsa_verifer {
    (
        $name:ident,
        $public_key_algo:expr,
        $signature_alg_id:expr,
        $verifying_key:ty,
        $signature:ty,
        $hash:ty
    ) => {
        paste! {
            #[allow(non_camel_case_types)]
            #[derive(Debug)]
            struct [<EcdsaVerifier_ $name>];

            impl SignatureVerificationAlgorithm for [<EcdsaVerifier_ $name>] {
                fn public_key_alg_id(&self) -> AlgorithmIdentifier {
                    $public_key_algo
                }

                fn signature_alg_id(&self) -> AlgorithmIdentifier {
                    $signature_alg_id
                }

                fn verify_signature(
                    &self,
                    public_key: &[u8],
                    message: &[u8],
                    signature: &[u8],
                ) -> Result<(), InvalidSignature> {
                    let signature = <$signature>::from_der(signature).map_err(|_| InvalidSignature)?;
                    let verifying_key = <$verifying_key>::from_sec1_bytes(public_key).map_err(|_| InvalidSignature)?;
                    let digest = &<$hash>::digest(&message);
                    verifying_key
                        .verify_prehash(digest, &signature)
                        .map_err(|_| InvalidSignature)
                }
            }

            pub const $name: &dyn SignatureVerificationAlgorithm = &[<EcdsaVerifier_ $name>];
        }
    };
}

impl_generic_ecdsa_verifer! {ECDSA_P256_SHA256, alg_id::ECDSA_P256, alg_id::ECDSA_SHA256, p256::ecdsa::VerifyingKey, p256::ecdsa::DerSignature, sha2::Sha256}
impl_generic_ecdsa_verifer! {ECDSA_P256_SHA384, alg_id::ECDSA_P256, alg_id::ECDSA_SHA384, p256::ecdsa::VerifyingKey, p256::ecdsa::DerSignature, sha2::Sha384}
impl_generic_ecdsa_verifer! {ECDSA_P384_SHA256, alg_id::ECDSA_P384, alg_id::ECDSA_SHA256, p384::ecdsa::VerifyingKey, p384::ecdsa::DerSignature, sha2::Sha256}
impl_generic_ecdsa_verifer! {ECDSA_P384_SHA384, alg_id::ECDSA_P384, alg_id::ECDSA_SHA384, p384::ecdsa::VerifyingKey, p384::ecdsa::DerSignature, sha2::Sha384}