pub(crate) mod enc_sk_ctx;
pub(crate) mod plaintext_ctx;
pub(crate) mod sk_ctx;
pub(crate) mod trusted_ctx;
pub(crate) mod unverified_ctx;
use crate::{
asn1::Asn1DecodeWrapperAux,
codec::{Decode as _, DecodeWrapper, Pem},
collections::{ShortBoxSliceU16, Vector},
misc::SecretContext,
rng::CryptoRng,
tls::{SignatureScheme, TlsMode},
x509::{KeyTy, Pkcs8},
};
use core::fmt::Debug;
pub trait TlsCtx: Debug {
const TY: TlsMode;
}
pub trait TlsCtxSk: TlsCtx {
type Signature: AsRef<[u8]>;
fn sign<RNG>(
&self,
buffer: &mut Vector<u8>,
msg: &[u8],
rng: &mut RNG,
sc: SignatureScheme,
) -> crate::Result<Self::Signature>
where
RNG: CryptoRng;
}
pub trait TlsCtxSkLoader: Sized + TlsCtxSk {
type SkInputDer<'data>: TlsCtxSkInput<TlsCtxSk = Self>;
type SkInputPem<'data>: TlsCtxSkInput<TlsCtxSk = Self>;
fn from_ders<'data, RNG>(
input: impl IntoIterator<Item = Self::SkInputDer<'data>>,
rng: &mut RNG,
) -> crate::Result<Self>
where
RNG: CryptoRng;
fn from_pems<'data, RNG>(
input: impl IntoIterator<Item = Self::SkInputPem<'data>>,
rng: &mut RNG,
) -> crate::Result<Self>
where
RNG: CryptoRng;
}
pub trait TlsCtxSkInput {
type TlsCtxSk: TlsCtxSk;
}
impl TlsCtxSkInput for &[u8] {
type TlsCtxSk = sk_ctx::SkCtx;
}
impl TlsCtxSkInput for ShortBoxSliceU16<u8> {
type TlsCtxSk = sk_ctx::SkCtx;
}
impl TlsCtxSkInput for (SecretContext, &mut [u8]) {
type TlsCtxSk = enc_sk_ctx::EncSkCtx;
}
#[inline]
fn secret_key_from_pem(pem_bytes: &[u8]) -> crate::Result<(ShortBoxSliceU16<u8>, KeyTy)> {
let mut buffer = Vector::new();
let pem = Pem::<_, 1>::decode(&mut DecodeWrapper::new(pem_bytes, &mut buffer))?;
let rslt = pem.data.into_inner()?;
buffer.truncate(rslt[0].1.end);
let key_ty = secret_key_ty(&buffer)?;
Ok((buffer.try_into()?, key_ty))
}
#[inline]
fn secret_key_ty(der: &[u8]) -> crate::Result<KeyTy> {
let mut dw = DecodeWrapper::new(der, Asn1DecodeWrapperAux::default());
KeyTy::try_from(&Pkcs8::<&[u8]>::decode(&mut dw)?)
}