wtx 0.52.0

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::{
  collections::Vector,
  crypto::{
    CryptoError, EcdsaP256SigningKeyRing, EcdsaP384SigningKeyRing, Ed25519SigningKeyRing, HashTy,
    RsaPkcs1SigningKeyRing, RsaPssSigningKeyRing, SigningOutput, signing_key::SigningKey,
  },
  rng::CryptoRng,
};
use ring::{
  rand::SystemRandom,
  signature::{
    ECDSA_P256_SHA256_ASN1, ECDSA_P256_SHA256_ASN1_SIGNING, ECDSA_P384_SHA384_ASN1,
    ECDSA_P384_SHA384_ASN1_SIGNING, ED25519, EcdsaKeyPair, Ed25519KeyPair, RsaKeyPair,
    UnparsedPublicKey, VerificationAlgorithm,
  },
};

impl SigningKey for EcdsaP256SigningKeyRing {
  type Signature = ring::signature::Signature;

  #[inline]
  fn from_pkcs8(bytes: &[u8], _: HashTy) -> crate::Result<Self> {
    Ok(Self(
      EcdsaKeyPair::from_pkcs8(&ECDSA_P256_SHA256_ASN1_SIGNING, bytes, &SystemRandom::new())
        .map_err(|_err| CryptoError::SigningKeyError)?,
    ))
  }

  #[inline]
  fn sign<RNG>(&self, msg: &[u8], _: &mut RNG) -> crate::Result<SigningOutput<Self::Signature>>
  where
    RNG: CryptoRng,
  {
    let signature =
      self.0.sign(&SystemRandom::new(), msg).map_err(|_err| CryptoError::SignatureError)?;
    Ok(SigningOutput::new(HashTy::Sha256, signature))
  }

  #[inline]
  fn validate(msg: &[u8], pk: &[u8], so: &SigningOutput<&[u8]>) -> crate::Result<()> {
    validate_signature(&ECDSA_P256_SHA256_ASN1, pk, msg, so.signature())
  }
}

impl SigningKey for EcdsaP384SigningKeyRing {
  type Signature = ring::signature::Signature;

  #[inline]
  fn from_pkcs8(bytes: &[u8], _: HashTy) -> crate::Result<Self> {
    Ok(Self(
      EcdsaKeyPair::from_pkcs8(&ECDSA_P384_SHA384_ASN1_SIGNING, bytes, &SystemRandom::new())
        .map_err(|_err| CryptoError::SigningKeyError)?,
    ))
  }

  #[inline]
  fn sign<RNG>(&self, msg: &[u8], _: &mut RNG) -> crate::Result<SigningOutput<Self::Signature>>
  where
    RNG: CryptoRng,
  {
    let signature =
      self.0.sign(&SystemRandom::new(), msg).map_err(|_err| CryptoError::SignatureError)?;
    Ok(SigningOutput::new(HashTy::Sha384, signature))
  }

  #[inline]
  fn validate(msg: &[u8], pk: &[u8], so: &SigningOutput<&[u8]>) -> crate::Result<()> {
    validate_signature(&ECDSA_P384_SHA384_ASN1, pk, msg, so.signature())
  }
}

impl SigningKey for Ed25519SigningKeyRing {
  type Signature = ring::signature::Signature;

  #[inline]
  fn from_pkcs8(bytes: &[u8], _: HashTy) -> crate::Result<Self> {
    Ok(Self(
      Ed25519KeyPair::from_pkcs8_maybe_unchecked(bytes)
        .map_err(|_err| CryptoError::SigningKeyError)?,
    ))
  }

  #[inline]
  fn sign<RNG>(&self, msg: &[u8], _: &mut RNG) -> crate::Result<SigningOutput<Self::Signature>>
  where
    RNG: CryptoRng,
  {
    Ok(SigningOutput::new(HashTy::Sha512, self.0.sign(msg)))
  }

  #[inline]
  fn validate(msg: &[u8], pk: &[u8], so: &SigningOutput<&[u8]>) -> crate::Result<()> {
    validate_signature(&ED25519, pk, msg, so.signature())
  }
}

impl SigningKey for RsaPkcs1SigningKeyRing {
  type Signature = Vector<u8>;

  #[inline]
  fn from_pkcs8(bytes: &[u8], hash_ty: HashTy) -> crate::Result<Self> {
    Ok(Self((hash_ty, RsaKeyPair::from_pkcs8(bytes).map_err(|_err| CryptoError::SigningKeyError)?)))
  }

  #[inline]
  fn sign<RNG>(&self, msg: &[u8], _: &mut RNG) -> crate::Result<SigningOutput<Self::Signature>>
  where
    RNG: CryptoRng,
  {
    let mut signature = Vector::from_vec(alloc::vec![0; self.0.1.public().modulus_len()]);
    self
      .0
      .1
      .sign(self.0.0.rsa_pkcs1_enc_ring(), &SystemRandom::new(), msg, &mut signature)
      .map_err(|_err| CryptoError::SignatureError)?;
    Ok(SigningOutput::new(self.0.0, signature))
  }

  #[inline]
  fn validate(msg: &[u8], pk: &[u8], so: &SigningOutput<&[u8]>) -> crate::Result<()> {
    validate_signature(so.hash_ty().rsa_pkcs1_params_ring(), pk, msg, so.signature())
  }
}

impl SigningKey for RsaPssSigningKeyRing {
  type Signature = Vector<u8>;

  #[inline]
  fn from_pkcs8(bytes: &[u8], hash_ty: HashTy) -> crate::Result<Self> {
    Ok(Self((hash_ty, RsaKeyPair::from_pkcs8(bytes).map_err(|_err| CryptoError::SigningKeyError)?)))
  }

  #[inline]
  fn sign<RNG>(&self, msg: &[u8], _: &mut RNG) -> crate::Result<SigningOutput<Self::Signature>>
  where
    RNG: CryptoRng,
  {
    let mut signature = Vector::from_vec(alloc::vec![0; self.0.1.public().modulus_len()]);
    self
      .0
      .1
      .sign(self.0.0.rsa_pss_enc_ring(), &SystemRandom::new(), msg, &mut signature)
      .map_err(|_err| CryptoError::SignatureError)?;
    Ok(SigningOutput::new(self.0.0, signature))
  }

  #[inline]
  fn validate(msg: &[u8], pk: &[u8], so: &SigningOutput<&[u8]>) -> crate::Result<()> {
    validate_signature(so.hash_ty().rsa_pss_params_ring(), pk, msg, so.signature())
  }
}

#[inline]
fn validate_signature(
  alg: &'static dyn VerificationAlgorithm,
  pk: &[u8],
  msg: &[u8],
  signature: &[u8],
) -> crate::Result<()> {
  UnparsedPublicKey::new(alg, pk)
    .verify(msg, signature)
    .map_err(|_err| CryptoError::SignatureError.into())
}