use crate::{
errcode::{Kind, Origin},
hex_encoding, Error,
};
use cfg_if::cfg_if;
use core::fmt;
use minicbor::{Decode, Encode};
use serde::{Deserialize, Serialize};
use zeroize::Zeroize;
#[cfg(feature = "tag")]
use crate::TypeTag;
pub const CURVE25519_SECRET_LENGTH_U32: u32 = 32;
pub const CURVE25519_SECRET_LENGTH_USIZE: usize = 32;
pub const CURVE25519_PUBLIC_LENGTH_U32: u32 = 32;
pub const CURVE25519_PUBLIC_LENGTH_USIZE: usize = 32;
pub const AES256_SECRET_LENGTH_U32: u32 = 32;
pub const AES256_SECRET_LENGTH_USIZE: usize = 32;
pub const AES128_SECRET_LENGTH_U32: u32 = 16;
pub const AES128_SECRET_LENGTH_USIZE: usize = 16;
cfg_if! {
if #[cfg(not(feature = "alloc"))] {
pub type SecretKeyVec = heapless::Vec<u8, 32>;
pub type PublicKeyVec = heapless::Vec<u8, 65>;
pub type SmallBuffer<T> = heapless::Vec<T, 4>;
pub type Buffer<T> = heapless::Vec<T, 512>;
pub type KeyId = heapless::String<64>;
pub type SignatureVec = heapless::Vec<u8, 112>;
impl From<&str> for KeyId {
fn from(s: &str) -> Self {
heapless::String::from(s)
}
}
}
else {
use alloc::vec::Vec;
use alloc::string::String;
pub type SecretKeyVec = Vec<u8>;
pub type PublicKeyVec = Vec<u8>;
pub type SmallBuffer<T> = Vec<T>;
pub type Buffer<T> = Vec<T>;
pub type KeyId = String;
pub type SignatureVec = Vec<u8>;
}
}
#[derive(Serialize, Deserialize, Clone, Zeroize, Encode, Decode)]
#[zeroize(drop)]
#[cbor(transparent)]
pub struct SecretKey(
#[serde(with = "hex_encoding")]
#[n(0)]
SecretKeyVec,
);
impl SecretKey {
pub fn new(data: SecretKeyVec) -> Self {
Self(data)
}
}
impl fmt::Debug for SecretKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.pad("<secret key omitted>")
}
}
impl Eq for SecretKey {}
impl PartialEq for SecretKey {
fn eq(&self, o: &Self) -> bool {
subtle::ConstantTimeEq::ct_eq(&self.0[..], &o.0[..]).into()
}
}
impl AsRef<[u8]> for SecretKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
#[derive(Encode, Decode, Serialize, Deserialize, Clone, Debug, Zeroize)]
#[zeroize(drop)]
#[rustfmt::skip]
#[cbor(map)]
pub struct PublicKey {
#[cfg(feature = "tag")]
#[serde(skip)]
#[n(0)] tag: TypeTag<8922437>,
#[b(1)] data: PublicKeyVec,
#[n(2)] stype: SecretType,
}
impl Eq for PublicKey {}
impl PartialEq for PublicKey {
fn eq(&self, o: &Self) -> bool {
let choice = subtle::ConstantTimeEq::ct_eq(&self.data[..], &o.data[..]);
choice.into() && self.stype == o.stype
}
}
impl PublicKey {
pub fn data(&self) -> &[u8] {
&self.data
}
pub fn stype(&self) -> SecretType {
self.stype
}
}
impl PublicKey {
pub fn new(data: PublicKeyVec, stype: SecretType) -> Self {
PublicKey {
#[cfg(feature = "tag")]
tag: TypeTag,
data,
stype,
}
}
}
impl fmt::Display for PublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?} {}", self.stype(), hex::encode(self.data()))
}
}
#[derive(Serialize, Deserialize, Clone, Debug, Zeroize)]
pub struct Signature(SignatureVec);
impl Signature {
pub fn new(data: SignatureVec) -> Self {
Self(data)
}
}
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Eq for Signature {}
impl PartialEq for Signature {
fn eq(&self, o: &Self) -> bool {
subtle::ConstantTimeEq::ct_eq(&self.0[..], &o.0[..]).into()
}
}
impl From<Signature> for SignatureVec {
fn from(sig: Signature) -> Self {
sig.0
}
}
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Encode, Decode, Eq, PartialEq, Zeroize)]
#[rustfmt::skip]
#[cbor(index_only)]
pub enum SecretType {
#[n(1)] Buffer,
#[n(2)] Aes,
#[n(3)] X25519,
#[n(4)] Ed25519,
#[n(5)] NistP256
}
#[derive(Serialize, Deserialize, Copy, Clone, Encode, Decode, Debug, Eq, PartialEq)]
#[rustfmt::skip]
#[cbor(index_only)]
pub enum SecretPersistence {
#[n(1)] Ephemeral,
#[n(2)] Persistent,
}
#[derive(Serialize, Deserialize, Copy, Encode, Decode, Clone, Debug, Eq, PartialEq)]
#[rustfmt::skip]
pub struct SecretAttributes {
#[n(1)] stype: SecretType,
#[n(2)] persistence: SecretPersistence,
#[n(3)] length: u32,
}
impl SecretAttributes {
pub fn stype(&self) -> SecretType {
self.stype
}
pub fn persistence(&self) -> SecretPersistence {
self.persistence
}
pub fn length(&self) -> u32 {
self.length
}
}
impl SecretAttributes {
pub fn new(stype: SecretType, persistence: SecretPersistence, length: u32) -> Self {
SecretAttributes {
stype,
persistence,
length,
}
}
}
impl fmt::Display for SecretAttributes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{:?}({:?}) len:{}",
self.stype(),
self.persistence(),
self.length()
)
}
}
#[derive(Clone, Debug, Zeroize)]
#[zeroize(drop)]
pub struct KeyPair {
secret: KeyId,
public: PublicKey,
}
impl KeyPair {
pub fn secret(&self) -> &KeyId {
&self.secret
}
pub fn public(&self) -> &PublicKey {
&self.public
}
}
impl KeyPair {
pub fn new(secret: KeyId, public: PublicKey) -> Self {
Self { secret, public }
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct VaultEntry {
key_attributes: SecretAttributes,
secret: Secret,
}
#[derive(Debug, Eq, PartialEq, Clone, Serialize, Deserialize, Encode, Decode)]
#[rustfmt::skip]
pub enum Secret {
#[n(0)] Key(#[n(0)] SecretKey),
#[n(1)] Aws(#[n(1)] KeyId)
}
impl Secret {
pub fn cast_as_key(&self) -> &SecretKey {
self.try_as_key().expect("`Secret` holds a key")
}
pub fn try_as_key(&self) -> Result<&SecretKey, Error> {
if let Secret::Key(k) = self {
Ok(k)
} else {
Err(Error::new(
Origin::Other,
Kind::Misuse,
"`Secret` does not hold a key",
))
}
}
}
impl VaultEntry {
pub fn key_attributes(&self) -> SecretAttributes {
self.key_attributes
}
pub fn secret(&self) -> &Secret {
&self.secret
}
}
impl VaultEntry {
pub fn new(key_attributes: SecretAttributes, secret: Secret) -> Self {
VaultEntry {
key_attributes,
secret,
}
}
pub fn new_key(key_attributes: SecretAttributes, key: SecretKey) -> Self {
VaultEntry {
key_attributes,
secret: Secret::Key(key),
}
}
pub fn new_aws(key_attributes: SecretAttributes, kid: KeyId) -> Self {
VaultEntry {
key_attributes,
secret: Secret::Aws(kid),
}
}
}