use crate::encrypt::CoseAlgorithm;
use crate::error::CoseError;
use crate::header_map::HeaderMap;
#[cfg(feature = "openssl")]
use ::openssl::symm::Cipher;
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::str::FromStr;
#[cfg(feature = "openssl")]
mod openssl;
#[cfg(feature = "openssl")]
pub use self::openssl::Openssl;
#[cfg(feature = "key_kms")]
pub mod kms;
#[cfg(feature = "key_openssl_pkey")]
mod openssl_pkey;
#[cfg(feature = "key_tpm")]
pub mod tpm;
pub trait Entropy {
fn rand_bytes(buff: &mut [u8]) -> Result<(), CoseError>;
}
pub trait Encryption {
fn encrypt_aead(
algo: EncryptionAlgorithm,
key: &[u8],
iv: Option<&[u8]>,
aad: &[u8],
data: &[u8],
tag: &mut [u8],
) -> Result<Vec<u8>, CoseError>;
}
pub enum EncryptionAlgorithm {
Aes128Gcm,
Aes192Gcm,
Aes256Gcm,
}
impl From<CoseAlgorithm> for EncryptionAlgorithm {
fn from(algo: CoseAlgorithm) -> EncryptionAlgorithm {
match algo {
CoseAlgorithm::AesGcm96_128_128 => EncryptionAlgorithm::Aes128Gcm,
CoseAlgorithm::AesGcm96_128_192 => EncryptionAlgorithm::Aes192Gcm,
CoseAlgorithm::AesGcm96_128_256 => EncryptionAlgorithm::Aes256Gcm,
}
}
}
#[cfg(feature = "openssl")]
impl From<EncryptionAlgorithm> for Cipher {
fn from(algo: EncryptionAlgorithm) -> Cipher {
match algo {
EncryptionAlgorithm::Aes128Gcm => Cipher::aes_128_gcm(),
EncryptionAlgorithm::Aes192Gcm => Cipher::aes_192_gcm(),
EncryptionAlgorithm::Aes256Gcm => Cipher::aes_256_gcm(),
}
}
}
pub trait Decryption {
fn decrypt_aead(
algo: EncryptionAlgorithm,
key: &[u8],
iv: Option<&[u8]>,
aad: &[u8],
data: &[u8],
tag: &[u8],
) -> Result<Vec<u8>, CoseError>;
}
#[derive(Debug, Copy, Clone)]
pub enum MessageDigest {
Sha256,
Sha384,
Sha512,
}
#[cfg(feature = "openssl")]
impl From<MessageDigest> for ::openssl::hash::MessageDigest {
fn from(digest: MessageDigest) -> Self {
match digest {
MessageDigest::Sha256 => ::openssl::hash::MessageDigest::sha256(),
MessageDigest::Sha384 => ::openssl::hash::MessageDigest::sha384(),
MessageDigest::Sha512 => ::openssl::hash::MessageDigest::sha512(),
}
}
}
pub trait Hash {
fn hash(digest: MessageDigest, data: &[u8]) -> Result<Vec<u8>, CoseError>;
}
pub trait SigningPublicKey {
fn get_parameters(&self) -> Result<(SignatureAlgorithm, MessageDigest), CoseError>;
fn verify(&self, digest: &[u8], signature: &[u8]) -> Result<bool, CoseError>;
}
#[cfg(feature = "openssl")]
fn merge_ec_signature(bytes_r: &[u8], bytes_s: &[u8], key_length: usize) -> Vec<u8> {
assert!(bytes_r.len() <= key_length);
assert!(bytes_s.len() <= key_length);
let mut signature_bytes = vec![0u8; key_length * 2];
let offset_copy = key_length - bytes_r.len();
signature_bytes[offset_copy..offset_copy + bytes_r.len()].copy_from_slice(bytes_r);
let offset_copy = key_length - bytes_s.len() + key_length;
signature_bytes[offset_copy..offset_copy + bytes_s.len()].copy_from_slice(bytes_s);
signature_bytes
}
pub trait SigningPrivateKey: SigningPublicKey {
fn sign(&self, digest: &[u8]) -> Result<Vec<u8>, CoseError>;
}
#[derive(Debug, Copy, Clone, Serialize_repr, Deserialize_repr)]
#[repr(i8)]
pub enum SignatureAlgorithm {
ES256 = -7,
ES384 = -35,
ES512 = -36,
}
impl SignatureAlgorithm {
pub fn key_length(&self) -> usize {
match self {
SignatureAlgorithm::ES256 => 32,
SignatureAlgorithm::ES384 => 48,
SignatureAlgorithm::ES512 => 66,
}
}
pub fn suggested_message_digest(&self) -> MessageDigest {
match self {
SignatureAlgorithm::ES256 => MessageDigest::Sha256,
SignatureAlgorithm::ES384 => MessageDigest::Sha384,
SignatureAlgorithm::ES512 => MessageDigest::Sha512,
}
}
}
impl FromStr for SignatureAlgorithm {
type Err = CoseError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ES256" => Ok(SignatureAlgorithm::ES256),
"ES384" => Ok(SignatureAlgorithm::ES384),
"ES512" => Ok(SignatureAlgorithm::ES512),
name => Err(CoseError::UnsupportedError(format!(
"Algorithm '{}' is not supported",
name
))),
}
}
}
impl ToString for SignatureAlgorithm {
fn to_string(&self) -> String {
match self {
SignatureAlgorithm::ES256 => "ES256",
SignatureAlgorithm::ES384 => "ES384",
SignatureAlgorithm::ES512 => "ES512",
}
.to_string()
}
}
impl From<SignatureAlgorithm> for HeaderMap {
fn from(sig_alg: SignatureAlgorithm) -> Self {
let mut map = HeaderMap::new();
map.insert(1.into(), (sig_alg as i8).into());
map
}
}