ssh_key/private/
opaque.rsuse crate::{
public::{OpaquePublicKey, OpaquePublicKeyBytes},
Algorithm, Error, Result,
};
use alloc::vec::Vec;
use core::fmt;
use encoding::{CheckedSum, Decode, Encode, Reader, Writer};
use subtle::{Choice, ConstantTimeEq};
#[derive(Clone)]
pub struct OpaquePrivateKeyBytes(Vec<u8>);
#[derive(Clone)]
pub struct OpaqueKeypair {
pub private: OpaquePrivateKeyBytes,
pub public: OpaquePublicKey,
}
pub struct OpaqueKeypairBytes {
pub private: OpaquePrivateKeyBytes,
pub public: OpaquePublicKeyBytes,
}
impl OpaqueKeypair {
pub fn new(private_key: Vec<u8>, public: OpaquePublicKey) -> Self {
Self {
private: OpaquePrivateKeyBytes(private_key),
public,
}
}
pub fn algorithm(&self) -> Algorithm {
self.public.algorithm()
}
pub(super) fn decode_as(reader: &mut impl Reader, algorithm: Algorithm) -> Result<Self> {
let key = OpaqueKeypairBytes::decode(reader)?;
let public = OpaquePublicKey {
algorithm,
key: key.public,
};
Ok(Self {
public,
private: key.private,
})
}
}
impl Decode for OpaquePrivateKeyBytes {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
let len = usize::decode(reader)?;
let mut bytes = vec![0; len];
reader.read(&mut bytes)?;
Ok(Self(bytes))
}
}
impl Decode for OpaqueKeypairBytes {
type Error = Error;
fn decode(reader: &mut impl Reader) -> Result<Self> {
let public = OpaquePublicKeyBytes::decode(reader)?;
let private = OpaquePrivateKeyBytes::decode(reader)?;
Ok(Self { public, private })
}
}
impl Encode for OpaqueKeypair {
fn encoded_len(&self) -> encoding::Result<usize> {
[self.public.encoded_len()?, self.private.encoded_len()?].checked_sum()
}
fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
self.public.encode(writer)?;
self.private.encode(writer)?;
Ok(())
}
}
impl ConstantTimeEq for OpaqueKeypair {
fn ct_eq(&self, other: &Self) -> Choice {
Choice::from((self.public == other.public) as u8) & self.private.ct_eq(&other.private)
}
}
impl Encode for OpaquePrivateKeyBytes {
fn encoded_len(&self) -> encoding::Result<usize> {
self.0.encoded_len()
}
fn encode(&self, writer: &mut impl Writer) -> encoding::Result<()> {
self.0.encode(writer)
}
}
impl From<&OpaqueKeypair> for OpaquePublicKey {
fn from(keypair: &OpaqueKeypair) -> OpaquePublicKey {
keypair.public.clone()
}
}
impl fmt::Debug for OpaqueKeypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OpaqueKeypair")
.field("public", &self.public)
.finish_non_exhaustive()
}
}
impl ConstantTimeEq for OpaquePrivateKeyBytes {
fn ct_eq(&self, other: &Self) -> Choice {
self.as_ref().ct_eq(other.as_ref())
}
}
impl AsRef<[u8]> for OpaquePrivateKeyBytes {
fn as_ref(&self) -> &[u8] {
&self.0
}
}