wtx 0.45.0

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::{
  collection::Vector,
  crypto::{
    CryptoError, Ed25519Openssl, Ed25519SignKeyOpenssl, P256Openssl, P256SignKeyOpenssl,
    P384Openssl, P384SignKeyOpenssl, RsaPssRsaeSha256Openssl, RsaPssRsaeSha384Openssl,
    RsaPssSignKeySha256Openssl, RsaPssSignKeySha384Openssl, Signature,
  },
  rng::CryptoRng,
};
use openssl::{
  ec::{EcGroup, EcKey},
  hash::MessageDigest,
  nid::Nid,
  pkey::{PKey, Public},
  rsa::Rsa,
  sign::{RsaPssSaltlen, Signer, Verifier},
};

impl Signature for P256Openssl {
  type SignKey = P256SignKeyOpenssl;
  type SignOutput = [u8; 64];

  #[inline]
  fn sign<RNG>(
    _: &mut RNG,
    sign_key: &mut Self::SignKey,
    msg: &[u8],
  ) -> crate::Result<Self::SignOutput>
  where
    RNG: CryptoRng,
  {
    let mut signer = Signer::new(MessageDigest::sha256(), &sign_key.0)?;
    signer.update(msg)?;
    let mut rslt = [0; 64];
    let _ = signer.sign(&mut rslt)?;
    Ok(rslt)
  }

  #[inline]
  fn validate(pk: &[u8], msg: &[u8], signature: &[u8]) -> crate::Result<()> {
    let pkey = ec_public_key_from_uncompressed(Nid::X9_62_PRIME256V1, pk)?;
    let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey)?;
    verifier.update(msg)?;
    if !verifier.verify(signature)? {
      return Err(CryptoError::SignatureError.into());
    }
    Ok(())
  }
}

impl Signature for P384Openssl {
  type SignKey = P384SignKeyOpenssl;
  type SignOutput = [u8; 96];

  #[inline]
  fn sign<RNG>(
    _: &mut RNG,
    sign_key: &mut Self::SignKey,
    msg: &[u8],
  ) -> crate::Result<Self::SignOutput>
  where
    RNG: CryptoRng,
  {
    let mut signer = Signer::new(MessageDigest::sha384(), &sign_key.0)?;
    signer.update(msg)?;
    let mut rslt = [0; 96];
    let _ = signer.sign(&mut rslt)?;
    Ok(rslt)
  }

  #[inline]
  fn validate(pk: &[u8], msg: &[u8], signature: &[u8]) -> crate::Result<()> {
    let pkey = ec_public_key_from_uncompressed(Nid::SECP384R1, pk)?;
    let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey)?;
    verifier.update(msg)?;
    if !verifier.verify(signature)? {
      return Err(CryptoError::SignatureError.into());
    }
    Ok(())
  }
}

impl Signature for Ed25519Openssl {
  type SignKey = Ed25519SignKeyOpenssl;
  type SignOutput = [u8; 64];

  #[inline]
  fn sign<RNG>(
    _: &mut RNG,
    sign_key: &mut Self::SignKey,
    msg: &[u8],
  ) -> crate::Result<Self::SignOutput>
  where
    RNG: CryptoRng,
  {
    let mut signer = Signer::new_without_digest(&sign_key.0)?;
    signer.update(msg)?;
    signer.sign_to_vec()?.try_into().map_err(|_err| CryptoError::SignatureError.into())
  }

  #[inline]
  fn validate(pk: &[u8], msg: &[u8], signature: &[u8]) -> crate::Result<()> {
    let pkey = PKey::public_key_from_raw_bytes(pk, openssl::pkey::Id::ED25519)?;
    let mut verifier = Verifier::new_without_digest(&pkey)?;
    verifier.update(msg)?;
    if !verifier.verify(signature)? {
      return Err(CryptoError::SignatureError.into());
    }
    Ok(())
  }
}

impl Signature for RsaPssRsaeSha256Openssl {
  type SignKey = RsaPssSignKeySha256Openssl;
  type SignOutput = Vector<u8>;

  #[inline]
  fn sign<RNG>(
    _: &mut RNG,
    sign_key: &mut Self::SignKey,
    msg: &[u8],
  ) -> crate::Result<Self::SignOutput>
  where
    RNG: CryptoRng,
  {
    let mut signer = Signer::new(MessageDigest::sha256(), &sign_key.0)?;
    signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?;
    signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
    signer.update(msg)?;
    Ok(signer.sign_to_vec()?.into())
  }

  #[inline]
  fn validate(pk: &[u8], msg: &[u8], signature: &[u8]) -> crate::Result<()> {
    let rsa = Rsa::public_key_from_der_pkcs1(pk)?;
    let pkey = PKey::from_rsa(rsa)?;
    let mut verifier = Verifier::new(MessageDigest::sha256(), &pkey)?;
    verifier.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?;
    verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
    verifier.update(msg)?;
    if !verifier.verify(signature)? {
      return Err(CryptoError::SignatureError.into());
    }
    Ok(())
  }
}

impl Signature for RsaPssRsaeSha384Openssl {
  type SignKey = RsaPssSignKeySha384Openssl;
  type SignOutput = Vector<u8>;

  #[inline]
  fn sign<RNG>(
    _: &mut RNG,
    sign_key: &mut Self::SignKey,
    msg: &[u8],
  ) -> crate::Result<Self::SignOutput>
  where
    RNG: CryptoRng,
  {
    let mut signer = Signer::new(MessageDigest::sha384(), &sign_key.0)?;
    signer.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?;
    signer.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
    signer.update(msg)?;
    Ok(signer.sign_to_vec()?.into())
  }

  #[inline]
  fn validate(pk: &[u8], msg: &[u8], signature: &[u8]) -> crate::Result<()> {
    let rsa = Rsa::public_key_from_der_pkcs1(pk)?;
    let pkey = PKey::from_rsa(rsa)?;
    let mut verifier = Verifier::new(MessageDigest::sha384(), &pkey)?;
    verifier.set_rsa_padding(openssl::rsa::Padding::PKCS1_PSS)?;
    verifier.set_rsa_pss_saltlen(RsaPssSaltlen::DIGEST_LENGTH)?;
    verifier.update(msg)?;
    verifier.verify(signature)?.then_some(()).ok_or(CryptoError::SignatureError.into())
  }
}

fn ec_public_key_from_uncompressed(nid: Nid, pk: &[u8]) -> crate::Result<PKey<Public>> {
  let group = EcGroup::from_curve_name(nid)?;
  let mut ctx = openssl::bn::BigNumContext::new()?;
  let point = openssl::ec::EcPoint::from_bytes(&group, pk, &mut ctx)?;
  Ok(PKey::from_ec_key(EcKey::from_public_key(&group, &point)?)?)
}