use super::*;
#[non_exhaustive]
#[derive(Serialize, Deserialize, Builder, PartialEq, Clone)]
pub struct OtherPrimeInfo {
#[builder(with = <_>::from_iter)]
#[serde(with = "base64url_uint")]
pub r: Vec<u8>,
#[builder(with = <_>::from_iter)]
#[serde(with = "base64url_uint")]
pub d: Vec<u8>,
#[builder(with = <_>::from_iter)]
#[serde(with = "base64url_uint")]
pub t: Vec<u8>,
}
impl std::fmt::Debug for OtherPrimeInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OtherPrimeInfo").finish_non_exhaustive()
}
}
impl Zeroize for OtherPrimeInfo {
fn zeroize(&mut self) {
self.r.zeroize();
self.d.zeroize();
self.t.zeroize();
}
}
impl Drop for OtherPrimeInfo {
fn drop(&mut self) {
self.zeroize();
}
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Builder, PartialEq, Clone)]
#[builder(derive(Into))]
pub struct RsaKey {
#[serde(flatten)]
#[builder(into)]
pub public: RsaPublicKey,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url_uint",
skip_serializing_if = "Option::is_none",
default
)]
pub d: Option<Vec<u8>>,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url_uint",
skip_serializing_if = "Option::is_none",
default
)]
pub p: Option<Vec<u8>>,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url_uint",
skip_serializing_if = "Option::is_none",
default
)]
pub q: Option<Vec<u8>>,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url_uint",
skip_serializing_if = "Option::is_none",
default
)]
pub dp: Option<Vec<u8>>,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url_uint",
skip_serializing_if = "Option::is_none",
default
)]
pub dq: Option<Vec<u8>>,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url_uint",
skip_serializing_if = "Option::is_none",
default
)]
pub qi: Option<Vec<u8>>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub oth: Option<Vec<OtherPrimeInfo>>,
}
impl std::fmt::Debug for RsaKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("RsaKey")
.field("public", &self.public)
.finish_non_exhaustive()
}
}
impl Zeroize for RsaKey {
fn zeroize(&mut self) {
self.d.zeroize();
self.p.zeroize();
self.q.zeroize();
self.dp.zeroize();
self.dq.zeroize();
self.qi.zeroize();
if let Some(oth) = &mut self.oth {
for info in oth.iter_mut() {
info.zeroize();
}
}
}
}
impl Drop for RsaKey {
fn drop(&mut self) {
self.zeroize();
}
}
impl From<RsaKey> for RsaPublicKey {
fn from(mut key: RsaKey) -> Self {
std::mem::replace(
&mut key.public,
RsaPublicKey {
n: vec![],
e: vec![],
},
)
}
}
impl From<RsaKey> for Key {
fn from(value: RsaKey) -> Self {
Self::Rsa(value)
}
}
impl<S: rsa_key_builder::State> From<RsaKeyBuilder<S>> for Key
where
S: rsa_key_builder::IsComplete,
{
fn from(value: RsaKeyBuilder<S>) -> Self {
Self::Rsa(value.build())
}
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Builder, PartialEq, Clone)]
#[builder(derive(Into))]
pub struct EcKey {
#[serde(flatten)]
#[builder(into)]
pub public: EcPublicKey,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url",
skip_serializing_if = "Option::is_none",
default
)]
pub d: Option<Vec<u8>>,
}
impl std::fmt::Debug for EcKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EcKey")
.field("public", &self.public)
.finish_non_exhaustive()
}
}
impl Zeroize for EcKey {
fn zeroize(&mut self) {
self.d.zeroize();
}
}
impl Drop for EcKey {
fn drop(&mut self) {
self.zeroize();
}
}
impl From<EcKey> for EcPublicKey {
fn from(mut key: EcKey) -> Self {
std::mem::replace(
&mut key.public,
EcPublicKey {
crv: String::new(),
x: vec![],
y: vec![],
},
)
}
}
impl From<EcKey> for Key {
fn from(value: EcKey) -> Self {
Self::Ec(value)
}
}
impl<S: ec_key_builder::State> From<EcKeyBuilder<S>> for Key
where
S: ec_key_builder::IsComplete,
{
fn from(value: EcKeyBuilder<S>) -> Self {
Self::Ec(value.build())
}
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Builder, PartialEq, Clone)]
#[builder(derive(Into))]
pub struct OkpKey {
#[serde(flatten)]
#[builder(into)]
pub public: OkpPublicKey,
#[builder(with = <_>::from_iter)]
#[serde(
with = "option_base64url",
skip_serializing_if = "Option::is_none",
default
)]
pub d: Option<Vec<u8>>,
}
impl std::fmt::Debug for OkpKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OkpKey")
.field("public", &self.public)
.finish_non_exhaustive()
}
}
impl Zeroize for OkpKey {
fn zeroize(&mut self) {
self.d.zeroize();
}
}
impl Drop for OkpKey {
fn drop(&mut self) {
self.zeroize();
}
}
impl From<OkpKey> for OkpPublicKey {
fn from(mut key: OkpKey) -> Self {
std::mem::replace(
&mut key.public,
OkpPublicKey {
crv: String::new(),
x: vec![],
},
)
}
}
impl From<OkpKey> for Key {
fn from(value: OkpKey) -> Self {
Self::Okp(value)
}
}
impl<S: okp_key_builder::State> From<OkpKeyBuilder<S>> for Key
where
S: okp_key_builder::IsComplete,
{
fn from(value: OkpKeyBuilder<S>) -> Self {
Self::Okp(value.build())
}
}
#[non_exhaustive]
#[derive(Serialize, Deserialize, Builder, PartialEq, Clone)]
#[builder(derive(Into))]
pub struct OctKey {
#[builder(with = <_>::from_iter)]
#[serde(with = "base64url")]
pub k: Vec<u8>,
}
impl std::fmt::Debug for OctKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("OctKey").finish_non_exhaustive()
}
}
impl Zeroize for OctKey {
fn zeroize(&mut self) {
self.k.zeroize();
}
}
impl Drop for OctKey {
fn drop(&mut self) {
self.zeroize();
}
}
impl From<OctKey> for Key {
fn from(value: OctKey) -> Self {
Self::Oct(value)
}
}
impl<S: oct_key_builder::State> From<OctKeyBuilder<S>> for Key
where
S: oct_key_builder::IsComplete,
{
fn from(value: OctKeyBuilder<S>) -> Self {
Self::Oct(value.build())
}
}
#[non_exhaustive]
#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
#[serde(tag = "kty")]
pub enum Key {
#[serde(rename = "RSA")]
Rsa(RsaKey),
#[serde(rename = "EC")]
Ec(EcKey),
#[serde(rename = "OKP")]
Okp(OkpKey),
#[serde(rename = "oct")]
Oct(OctKey),
#[serde(skip_serializing, other)]
Unknown,
}
impl Key {
#[must_use]
pub fn public_key(&self) -> Option<PublicKey> {
match self {
Key::Rsa(rsa) => Some(PublicKey::Rsa(rsa.public.clone())),
Key::Ec(ec) => Some(PublicKey::Ec(ec.public.clone())),
Key::Okp(okp) => Some(PublicKey::Okp(okp.public.clone())),
Key::Oct(_) | Key::Unknown => None,
}
}
#[must_use]
pub fn private_key(&self) -> Option<PrivateKey> {
match self {
Key::Rsa(rsa) => rsa.private_key().map(PrivateKey::Rsa),
Key::Ec(ec) => ec.private_key().map(PrivateKey::Ec),
Key::Okp(okp) => okp.private_key().map(PrivateKey::Okp),
Key::Oct(_) | Key::Unknown => None,
}
}
}