use rite_sdk::{KeyAlgorithm, KeyUsages, SignAlgorithm, WrapScheme};
use schemars::{JsonSchema, Schema, SchemaGenerator};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct GenerateKeyParams {
#[serde(default = "default_algorithm")]
pub algorithm: KeyAlgorithm,
#[serde(default)]
pub policy: Option<KeyPolicyParams>,
#[serde(default)]
pub slot: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct KeyPolicyParams {
#[serde(default)]
pub persistent: Option<bool>,
#[serde(default)]
pub sensitive: Option<bool>,
#[serde(default)]
pub extractable: Option<bool>,
#[serde(default)]
pub wrap_with_trusted_only: Option<bool>,
#[serde(default)]
pub usages: Option<Vec<KeyUsage>>,
}
impl KeyPolicyParams {
#[must_use]
pub fn resolve_from(&self, defaults: &rite_sdk::KeyPolicy) -> rite_sdk::KeyPolicy {
let usages = self.usages.as_ref().map_or(defaults.usages, |usages| {
usages
.iter()
.fold(KeyUsages::empty(), |all, usage| all | usage.0)
});
rite_sdk::KeyPolicy {
persistent: self.persistent.unwrap_or(defaults.persistent),
sensitive: self.sensitive.unwrap_or(defaults.sensitive),
extractable: self.extractable.unwrap_or(defaults.extractable),
wrap_with_trusted_only: self
.wrap_with_trusted_only
.unwrap_or(defaults.wrap_with_trusted_only),
usages,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(into = "String", try_from = "String")]
pub struct KeyUsage(KeyUsages);
impl KeyUsage {
#[must_use]
pub fn usage(self) -> KeyUsages {
self.0
}
}
impl From<KeyUsage> for String {
fn from(usage: KeyUsage) -> String {
usage.0.describe()
}
}
impl TryFrom<String> for KeyUsage {
type Error = String;
fn try_from(name: String) -> Result<Self, Self::Error> {
KeyUsages::usage_named(&name).map(KeyUsage).ok_or_else(|| {
format!(
"unknown key usage '{name}'. Supported: {}",
KeyUsages::all_names().join(", ")
)
})
}
}
impl JsonSchema for KeyUsage {
fn schema_name() -> std::borrow::Cow<'static, str> {
"KeyUsage".into()
}
fn json_schema(_: &mut SchemaGenerator) -> Schema {
super::schema::names(KeyUsages::all_names().into_iter())
}
}
fn default_algorithm() -> KeyAlgorithm {
KeyAlgorithm::Rsa4096
}
impl Default for GenerateKeyParams {
fn default() -> Self {
Self {
algorithm: default_algorithm(),
policy: None,
slot: None,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct WrapKeyParams {
#[serde(default)]
pub scheme: Option<WrapScheme>,
#[serde(default)]
#[schemars(
regex(pattern = r"^sha256:[0-9a-f]{64}$"),
extend(
"x-message" = "'expect_recipient' must be a fingerprint of the form \
'sha256:<64 lowercase hex digits>'"
)
)]
pub expect_recipient: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct SignDataParams {
#[serde(default)]
pub algorithm: Option<SignAlgorithm>,
#[serde(default)]
pub message: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct VerifySignatureParams {
#[serde(default)]
pub algorithm: Option<SignAlgorithm>,
#[serde(default)]
pub message: Option<String>,
}
const KEY_IDENTITY: &str = r"^(sha256:[0-9a-f]{64}|cmac-aes:[0-9a-f]{6})$";
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct UnwrapKeyParams {
#[serde(default)]
pub algorithm: Option<KeyAlgorithm>,
#[serde(default)]
#[schemars(
regex(pattern = KEY_IDENTITY),
extend("x-message" = EXPECT_KEY_MESSAGE)
)]
pub expect_key: Option<String>,
#[serde(default = "unwrapped_key_label")]
pub label: String,
#[serde(default)]
pub policy: Option<KeyPolicyParams>,
}
const EXPECT_KEY_MESSAGE: &str = "'expect_key' must name the key either as \
'sha256:<64 lowercase hex digits>', the fingerprint of a public key, or as \
'cmac-aes:<6 lowercase hex digits>', the check value of a symmetric key";
fn unwrapped_key_label() -> String {
"unwrapped-key".to_string()
}
impl Default for UnwrapKeyParams {
fn default() -> Self {
Self {
algorithm: None,
expect_key: None,
label: unwrapped_key_label(),
policy: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct ImportKeyParams {
pub algorithm: KeyAlgorithm,
#[serde(default)]
#[schemars(
regex(pattern = KEY_IDENTITY),
extend("x-message" = EXPECT_KEY_MESSAGE)
)]
pub expect_key: Option<String>,
#[serde(default = "imported_key_label")]
pub label: String,
#[serde(default)]
pub policy: Option<KeyPolicyParams>,
}
fn imported_key_label() -> String {
"imported-key".to_string()
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[non_exhaustive]
pub struct EncryptDataParams {
#[serde(default)]
#[schemars(schema_with = "content_schemes")]
pub scheme: Option<WrapScheme>,
}
fn content_schemes(_: &mut SchemaGenerator) -> Schema {
super::schema::names(
WrapScheme::ALL
.iter()
.filter(|scheme| scheme.carries_content())
.map(|scheme| scheme.as_str()),
)
}