use azure_core::{
base64,
error::{Error, ErrorKind},
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::{Map, Value};
use std::fmt::{Debug, Display};
use time::OffsetDateTime;
#[derive(Debug, Deserialize)]
pub struct KeyVaultKey {
#[serde(flatten)]
pub properties: KeyProperties,
pub key: JsonWebKey,
}
#[derive(Debug, Deserialize)]
pub struct KeyProperties {
pub attributes: KeyAttributes,
pub managed: Option<bool>,
pub tags: Option<Map<String, Value>>,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct KeyAttributes {
#[serde(
rename = "created",
with = "azure_core::date::timestamp::option",
default
)]
pub created_on: Option<OffsetDateTime>,
pub enabled: Option<bool>,
#[serde(rename = "exp", with = "azure_core::date::timestamp::option", default)]
pub expires_on: Option<OffsetDateTime>,
#[serde(rename = "nbf", with = "azure_core::date::timestamp::option", default)]
pub not_before: Option<OffsetDateTime>,
pub recoverable_days: Option<u8>,
pub recovery_level: Option<String>,
#[serde(
rename = "updated",
with = "azure_core::date::timestamp::option",
default
)]
pub updated_on: Option<OffsetDateTime>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct JsonWebKey {
#[serde(rename = "crv")]
pub curve_name: Option<String>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub d: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub dp: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub dq: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub e: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub k: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
#[serde(rename = "key_hsm")]
pub t: Option<Vec<u8>>,
pub key_ops: Option<Vec<String>>,
#[serde(rename = "kid")]
pub id: Option<String>,
#[serde(rename = "kty")]
pub key_type: String,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub n: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub p: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub q: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub qi: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub x: Option<Vec<u8>>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
#[serde(default)]
pub y: Option<Vec<u8>>,
}
fn ser_base64<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let base_64 = base64::encode_url_safe(bytes);
serializer.serialize_str(&base_64)
}
fn ser_base64_opt<S>(bytes: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if let Some(bytes) = bytes {
let base_64 = base64::encode_url_safe(bytes);
serializer.serialize_str(&base_64)
} else {
serializer.serialize_none()
}
}
fn deser_base64<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
let s: String = String::deserialize(deserializer)?;
let res = base64::decode_url_safe(s).map_err(serde::de::Error::custom)?;
Ok(res)
}
fn deser_base64_opt<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s: Option<&str> = Option::deserialize(deserializer)?;
let res = match s {
Some(s) => Some(base64::decode_url_safe(s).map_err(serde::de::Error::custom)?),
None => None,
};
Ok(res)
}
#[derive(Debug, Deserialize)]
pub struct SignResult {
#[serde(
rename = "value",
serialize_with = "ser_base64",
deserialize_with = "deser_base64"
)]
pub signature: Vec<u8>,
#[serde(skip)]
pub algorithm: SignatureAlgorithm,
#[serde(rename = "kid")]
pub key_id: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(untagged)]
pub enum SignatureAlgorithm {
ES256, ES256K, ES384, ES512, PS256, PS384, PS512, RS256, RS384, RS512, Custom(String),
}
impl Default for SignatureAlgorithm {
fn default() -> Self {
SignatureAlgorithm::Custom("".to_string())
}
}
impl Display for SignatureAlgorithm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(self, f)
}
}
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub enum EncryptionAlgorithm {
#[default]
#[serde(rename = "A128CBC")]
A128Cbc,
#[serde(rename = "A128CBCPAD")]
A128CbcPad,
#[serde(rename = "A128GCM")]
A128Gcm,
#[serde(rename = "A192CBC")]
A192Cbc,
#[serde(rename = "A192CBCPAD")]
A192CbcPad,
#[serde(rename = "A192GCM")]
A192Gcm,
#[serde(rename = "A256CBC")]
A256Cbc,
#[serde(rename = "A256CBCPAD")]
A256CbcPad,
#[serde(rename = "A256GCM")]
A256Gcm,
#[serde(rename = "RSA-OAEP")]
RsaOaep,
#[serde(rename = "RSA-OAEP-256")]
RsaOaep256,
#[serde(rename = "RSA1_5")]
Rsa15,
}
impl Display for EncryptionAlgorithm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Debug::fmt(self, f)
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DecryptParameters {
pub decrypt_parameters_encryption: CryptographParamtersEncryption,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub ciphertext: Vec<u8>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum CryptographParamtersEncryption {
Rsa(RsaEncryptionParameters),
AesGcm(AesGcmEncryptionParameters),
AesCbc(AesCbcEncryptionParameters),
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct EncryptParameters {
pub encrypt_parameters_encryption: CryptographParamtersEncryption,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub plaintext: Vec<u8>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RsaEncryptionParameters {
pub algorithm: EncryptionAlgorithm,
}
impl RsaEncryptionParameters {
pub fn new(algorithm: EncryptionAlgorithm) -> Result<Self, Error> {
match algorithm {
EncryptionAlgorithm::Rsa15
| EncryptionAlgorithm::RsaOaep
| EncryptionAlgorithm::RsaOaep256 => Ok(Self { algorithm }),
_ => Err(Error::with_message(ErrorKind::Other, || {
format!("unexpected encryption algorithm: {algorithm}")
})),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AesGcmEncryptionParameters {
pub algorithm: EncryptionAlgorithm,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub iv: Vec<u8>,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub authentication_tag: Vec<u8>,
#[serde(
serialize_with = "ser_base64_opt",
deserialize_with = "deser_base64_opt"
)]
pub additional_authenticated_data: Option<Vec<u8>>,
}
impl AesGcmEncryptionParameters {
pub fn new(
algorithm: EncryptionAlgorithm,
iv: Vec<u8>,
authentication_tag: Vec<u8>,
additional_authenticated_data: Option<Vec<u8>>,
) -> Result<Self, Error> {
match algorithm {
EncryptionAlgorithm::A128Gcm
| EncryptionAlgorithm::A192Gcm
| EncryptionAlgorithm::A256Gcm => Ok(Self {
algorithm,
iv,
authentication_tag,
additional_authenticated_data,
}),
_ => Err(Error::with_message(ErrorKind::Other, || {
format!("unexpected encryption algorithm: {algorithm}")
})),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AesCbcEncryptionParameters {
pub algorithm: EncryptionAlgorithm,
#[serde(serialize_with = "ser_base64", deserialize_with = "deser_base64")]
pub iv: Vec<u8>,
}
impl AesCbcEncryptionParameters {
pub fn new(algorithm: EncryptionAlgorithm, iv: Vec<u8>) -> Result<Self, Error> {
match algorithm {
EncryptionAlgorithm::A128Cbc
| EncryptionAlgorithm::A192Cbc
| EncryptionAlgorithm::A256Cbc
| EncryptionAlgorithm::A128CbcPad
| EncryptionAlgorithm::A192CbcPad
| EncryptionAlgorithm::A256CbcPad => Ok(Self { algorithm, iv }),
_ => Err(Error::with_message(ErrorKind::Other, || {
format!("unexpected encryption algorithm: {algorithm}")
})),
}
}
}
#[derive(Debug, Deserialize)]
pub struct DecryptResult {
#[serde(skip)]
pub algorithm: EncryptionAlgorithm,
#[serde(rename = "kid")]
pub key_id: String,
#[serde(
rename = "value",
serialize_with = "ser_base64",
deserialize_with = "deser_base64"
)]
pub result: Vec<u8>,
}
#[derive(Debug, Deserialize)]
pub struct EncryptResult {
#[serde(skip)]
pub algorithm: EncryptionAlgorithm,
#[serde(rename = "kid")]
pub key_id: String,
#[serde(
rename = "value",
serialize_with = "ser_base64",
deserialize_with = "deser_base64"
)]
pub result: Vec<u8>,
}
#[derive(Debug, Deserialize)]
pub struct GetRandomBytesResult {
#[serde(rename = "value", deserialize_with = "deser_base64")]
pub result: Vec<u8>,
}