use num_derive::FromPrimitive;
mod response_status;
pub mod utils;
pub mod common;
pub mod request;
pub mod response;
#[cfg(feature = "fuzz")]
use arbitrary::Arbitrary;
pub use request::Request;
pub use response::Response;
pub use response_status::{ResponseStatus, Result};
use std::convert::TryFrom;
use std::fmt;
#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
#[derive(FromPrimitive, PartialEq, Eq, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum ProviderId {
Core = 0,
MbedCrypto = 1,
Pkcs11 = 2,
Tpm = 3,
TrustedService = 4,
CryptoAuthLib = 5,
}
impl fmt::Display for ProviderId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ProviderId::Core => write!(f, "Core provider"),
ProviderId::MbedCrypto => write!(f, "Mbed Crypto provider"),
ProviderId::Pkcs11 => write!(f, "PKCS #11 provider"),
ProviderId::Tpm => write!(f, "TPM provider"),
ProviderId::TrustedService => write!(f, "Trusted Service provider"),
ProviderId::CryptoAuthLib => write!(f, "CryptoAuthentication Library provider"),
}
}
}
impl TryFrom<u8> for ProviderId {
type Error = ResponseStatus;
fn try_from(provider_id: u8) -> ::std::result::Result<Self, Self::Error> {
match num::FromPrimitive::from_u8(provider_id) {
Some(provider_id) => Ok(provider_id),
None => Err(ResponseStatus::ProviderDoesNotExist),
}
}
}
#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
#[derive(FromPrimitive, Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u8)]
pub enum BodyType {
Protobuf = 0,
}
#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
#[derive(FromPrimitive, Copy, Clone, PartialEq, Debug, Hash, Eq)]
#[repr(u32)]
pub enum Opcode {
Ping = 0x0001,
PsaGenerateKey = 0x0002,
PsaDestroyKey = 0x0003,
PsaSignHash = 0x0004,
PsaVerifyHash = 0x0005,
PsaImportKey = 0x0006,
PsaExportPublicKey = 0x0007,
ListProviders = 0x0008,
ListOpcodes = 0x0009,
PsaAsymmetricEncrypt = 0x000A,
PsaAsymmetricDecrypt = 0x000B,
PsaExportKey = 0x000C,
PsaGenerateRandom = 0x000D,
ListAuthenticators = 0x000E,
PsaHashCompute = 0x000F,
PsaHashCompare = 0x0010,
PsaAeadEncrypt = 0x0011,
PsaAeadDecrypt = 0x0012,
PsaRawKeyAgreement = 0x0013,
PsaCipherEncrypt = 0x0014,
PsaCipherDecrypt = 0x0015,
PsaSignMessage = 0x0018,
PsaVerifyMessage = 0x0019,
ListKeys = 0x001A,
ListClients = 0x001B,
DeleteClient = 0x001C,
AttestKey = 0x001E,
PrepareKeyAttestation = 0x001F,
CanDoCrypto = 0x0020,
}
impl Opcode {
pub fn is_core(&self) -> bool {
match self {
Opcode::Ping
| Opcode::ListProviders
| Opcode::ListOpcodes
| Opcode::ListAuthenticators
| Opcode::ListKeys
| Opcode::ListClients
| Opcode::DeleteClient => true,
Opcode::PsaGenerateKey
| Opcode::PsaDestroyKey
| Opcode::PsaSignHash
| Opcode::PsaVerifyHash
| Opcode::PsaSignMessage
| Opcode::PsaVerifyMessage
| Opcode::PsaImportKey
| Opcode::PsaExportPublicKey
| Opcode::PsaAsymmetricEncrypt
| Opcode::PsaAsymmetricDecrypt
| Opcode::PsaExportKey
| Opcode::PsaGenerateRandom
| Opcode::PsaHashCompute
| Opcode::PsaHashCompare
| Opcode::PsaAeadEncrypt
| Opcode::PsaAeadDecrypt
| Opcode::PsaCipherEncrypt
| Opcode::PsaCipherDecrypt
| Opcode::PsaRawKeyAgreement
| Opcode::CanDoCrypto
| Opcode::AttestKey
| Opcode::PrepareKeyAttestation => false,
}
}
pub fn is_admin(&self) -> bool {
match self {
Opcode::ListClients | Opcode::DeleteClient => true,
Opcode::Ping
| Opcode::ListProviders
| Opcode::ListOpcodes
| Opcode::ListAuthenticators
| Opcode::ListKeys
| Opcode::PsaGenerateKey
| Opcode::PsaDestroyKey
| Opcode::PsaSignHash
| Opcode::PsaVerifyHash
| Opcode::PsaSignMessage
| Opcode::PsaVerifyMessage
| Opcode::PsaImportKey
| Opcode::PsaExportPublicKey
| Opcode::PsaAsymmetricEncrypt
| Opcode::PsaAsymmetricDecrypt
| Opcode::PsaExportKey
| Opcode::PsaGenerateRandom
| Opcode::PsaHashCompute
| Opcode::PsaHashCompare
| Opcode::PsaAeadEncrypt
| Opcode::PsaAeadDecrypt
| Opcode::PsaCipherEncrypt
| Opcode::PsaCipherDecrypt
| Opcode::PsaRawKeyAgreement
| Opcode::CanDoCrypto
| Opcode::AttestKey
| Opcode::PrepareKeyAttestation => false,
}
}
pub fn is_crypto(&self) -> bool {
!self.is_core()
}
}
#[cfg_attr(feature = "fuzz", derive(Arbitrary))]
#[derive(FromPrimitive, PartialEq, Eq, Hash, Copy, Clone, Debug)]
#[repr(u8)]
pub enum AuthType {
NoAuth = 0,
Direct = 1,
Jwt = 2,
UnixPeerCredentials = 3,
JwtSvid = 4,
}
impl fmt::Display for AuthType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AuthType::NoAuth => write!(f, "No authentication"),
AuthType::Direct => write!(f, "Direct authentication"),
AuthType::Jwt => write!(f, "JSON Web Tokens authentication"),
AuthType::UnixPeerCredentials => write!(f, "Unix Peer Credentials authentication"),
AuthType::JwtSvid => {
write!(f, "JWT SPIFFE Verifiable Identity Document authentication")
}
}
}
}
#[test]
fn check_opcode_nature() {
assert!(Opcode::ListKeys.is_core());
assert!(!Opcode::ListKeys.is_crypto());
assert!(Opcode::PsaGenerateKey.is_crypto());
assert!(Opcode::ListClients.is_admin());
assert!(!Opcode::PsaGenerateKey.is_admin());
}