use generic_array::GenericArray;
use rand::{rngs::OsRng, CryptoRng, RngCore};
use rusty_paseto::core::PasetoError;
#[cfg(feature = "v3")]
use rusty_paseto::core::V3;
#[cfg(feature = "v4")]
use rusty_paseto::core::V4;
use crate::{Key, KeyType, Local, Public, Secret, Version};
#[cfg(feature = "v3")]
impl Key<V3, Secret> {
pub fn from_sec1_pem(s: &str) -> Result<Self, PasetoError> {
let sk = p384::SecretKey::from_sec1_pem(s).map_err(|_| PasetoError::Cryption)?;
Ok(Self { key: sk.to_bytes() })
}
pub fn from_bytes(s: &[u8]) -> Result<Self, PasetoError> {
let sk = p384::SecretKey::from_slice(s).map_err(|_| PasetoError::Cryption)?;
Ok(Self { key: sk.to_bytes() })
}
pub fn public_key(&self) -> Key<V3, Public> {
use p384::{EncodedPoint, SecretKey};
let sk = SecretKey::from_bytes(&self.key).unwrap();
let pk: EncodedPoint = sk.public_key().into();
let pk = pk.compress();
let pk = pk.as_bytes();
Key {
key: *GenericArray::from_slice(pk),
}
}
}
#[cfg(feature = "v3")]
impl Key<V3, Public> {
pub fn from_public_key_pem(s: &str) -> Result<Self, PasetoError> {
use p384::{pkcs8::DecodePublicKey, EncodedPoint};
let pk = p384::PublicKey::from_public_key_pem(s).map_err(|_| PasetoError::Cryption)?;
let pk: EncodedPoint = pk.into();
let pk = pk.compress();
let pk = pk.as_bytes();
Ok(Self {
key: *GenericArray::from_slice(pk),
})
}
pub fn from_sec1_bytes(s: &[u8]) -> Result<Self, PasetoError> {
let pk = p384::PublicKey::from_sec1_bytes(s).map_err(|_| PasetoError::Cryption)?;
let pk: p384::EncodedPoint = pk.into();
let pk = pk.compress();
let pk = pk.as_bytes();
Ok(Self {
key: *GenericArray::from_slice(pk),
})
}
}
#[cfg(feature = "v4")]
impl Key<V4, Secret> {
pub fn from_keypair_bytes(key: &[u8]) -> Result<Self, PasetoError> {
use ed25519_dalek::SigningKey;
let key: [u8; 64] = key.try_into().map_err(|_| PasetoError::InvalidKey)?;
match SigningKey::from_keypair_bytes(&key) {
Ok(_) => {}
Err(_) => return Err(PasetoError::InvalidKey),
};
Ok(Key { key: key.into() })
}
pub fn from_secret_key(key: [u8; 32]) -> Self {
Self {
key: ed25519_dalek::SigningKey::from_bytes(&key)
.to_keypair_bytes()
.into(),
}
}
pub fn public_key(&self) -> Key<V4, Public> {
use generic_array::sequence::Split;
let (_sk, pk): (GenericArray<u8, generic_array::typenum::U32>, _) = self.key.split();
Key { key: pk }
}
}
#[cfg(feature = "v4")]
impl Key<V4, Public> {
pub fn from_public_key(key: &[u8]) -> Result<Self, PasetoError> {
let key = key.try_into().map_err(|_| PasetoError::InvalidKey)?;
let _ =
ed25519_dalek::VerifyingKey::from_bytes(&key).map_err(|_| PasetoError::InvalidKey)?;
Ok(Self { key: key.into() })
}
}
#[cfg(feature = "v3")]
impl Key<V3, Local> {
pub fn from_bytes(key: [u8; 32]) -> Self {
Self { key: key.into() }
}
pub fn to_bytes(&self) -> [u8; 32] {
self.key.into()
}
}
#[cfg(feature = "v4")]
impl Key<V4, Local> {
pub fn from_bytes(key: [u8; 32]) -> Self {
Self { key: key.into() }
}
pub fn to_bytes(&self) -> [u8; 32] {
self.key.into()
}
}
impl<V: Version, K: KeyType<V>> AsRef<[u8]> for Key<V, K> {
fn as_ref(&self) -> &[u8] {
&self.key
}
}
impl<V: Version> Key<V, Local> {
pub fn new_os_random() -> Self {
Self::new_random(&mut OsRng)
}
pub fn new_random(rng: &mut (impl RngCore + CryptoRng)) -> Self {
let mut key = GenericArray::<u8, V::Local>::default();
rng.fill_bytes(&mut key);
Self { key }
}
}
#[cfg(feature = "v4")]
impl Key<V4, Secret> {
pub fn new_os_random() -> Self {
Self::new_random(&mut OsRng)
}
pub fn new_random(rng: &mut (impl RngCore + CryptoRng)) -> Self {
let mut key = [0; 32];
rng.fill_bytes(&mut key);
Self {
key: ed25519_dalek::SigningKey::from_bytes(&key)
.to_keypair_bytes()
.into(),
}
}
}
#[cfg(feature = "v3")]
impl Key<V3, Secret> {
pub fn new_os_random() -> Self {
Self::new_random(&mut OsRng)
}
pub fn new_random(rng: &mut (impl RngCore + CryptoRng)) -> Self {
Self {
key: p384::SecretKey::random(rng).to_bytes(),
}
}
}
#[cfg(feature = "v4")]
impl From<Key<V4, Local>>
for rusty_paseto::core::PasetoSymmetricKey<V4, rusty_paseto::core::Local>
{
fn from(key: Key<V4, Local>) -> Self {
let key: [u8; 32] = key.key.into();
let key: rusty_paseto::core::Key<32> = key.into();
key.into()
}
}
#[cfg(feature = "v3")]
impl From<Key<V3, Local>>
for rusty_paseto::core::PasetoSymmetricKey<V3, rusty_paseto::core::Local>
{
fn from(key: Key<V3, Local>) -> Self {
let key: [u8; 32] = key.key.into();
let key: rusty_paseto::core::Key<32> = key.into();
key.into()
}
}
#[cfg(feature = "v4")]
impl From<Key<V4, Public>> for rusty_paseto::core::Key<32> {
fn from(key: Key<V4, Public>) -> Self {
let key: [u8; 32] = key.key.into();
key.into()
}
}
#[cfg(feature = "v4")]
impl From<Key<V4, Secret>> for rusty_paseto::core::Key<64> {
fn from(key: Key<V4, Secret>) -> Self {
let key: [u8; 64] = key.key.into();
key.into()
}
}
#[cfg(feature = "v3")]
impl From<Key<V3, Public>> for rusty_paseto::core::Key<49> {
fn from(key: Key<V3, Public>) -> Self {
let key: [u8; 49] = key.key.into();
key.into()
}
}
#[cfg(feature = "v3")]
impl From<Key<V3, Secret>> for rusty_paseto::core::Key<48> {
fn from(key: Key<V3, Secret>) -> Self {
let key: [u8; 48] = key.key.into();
key.into()
}
}