use std::ops::{Deref, DerefMut};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::{iana, CoseMap, Error};
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Key(pub CoseMap);
impl Key {
pub fn new() -> Self {
Key(CoseMap::new())
}
pub fn from_slice(data: &[u8]) -> Result<Self, Error> {
Ok(Key(CoseMap::from_slice(data)?))
}
pub fn to_vec(&self) -> Result<Vec<u8>, Error> {
self.0.to_vec()
}
pub fn kty(&self) -> Result<Option<i64>, Error> {
self.0.get_i64(iana::KeyParameterKty)
}
pub fn set_kty(&mut self, kty: i64) -> &mut Self {
self.0.insert(iana::KeyParameterKty, kty);
self
}
pub fn kid(&self) -> Result<Option<&[u8]>, Error> {
self.0.get_bytes(iana::KeyParameterKid)
}
pub fn set_kid(&mut self, kid: impl Into<Vec<u8>>) -> &mut Self {
self.0.insert(iana::KeyParameterKid, kid.into());
self
}
pub fn alg(&self) -> Result<Option<i64>, Error> {
self.0.get_i64(iana::KeyParameterAlg)
}
pub fn set_alg(&mut self, alg: i64) -> &mut Self {
self.0.insert(iana::KeyParameterAlg, alg);
self
}
pub fn ops(&self) -> Result<Option<Vec<i64>>, Error> {
match self.0.get_array(iana::KeyParameterKeyOps)? {
None => Ok(None),
Some(values) => {
let mut ops = Vec::with_capacity(values.len());
for v in values {
match v {
crate::Value::Integer(i) => ops.push(i64::try_from(*i).map_err(|_| {
Error::UnexpectedType("key_ops integer out of range".into())
})?),
_ => {
return Err(Error::UnexpectedType(
"key_ops must be an array of integers".into(),
))
}
}
}
Ok(Some(ops))
}
}
}
pub fn set_ops(&mut self, ops: &[i64]) -> &mut Self {
let values: Vec<crate::Value> = ops.iter().map(|&op| crate::Value::from(op)).collect();
self.0.insert(iana::KeyParameterKeyOps, values);
self
}
pub fn base_iv(&self) -> Result<Option<&[u8]>, Error> {
self.0.get_bytes(iana::KeyParameterBaseIV)
}
}
impl Deref for Key {
type Target = CoseMap;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Key {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Serialize for Key {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Key {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
CoseMap::deserialize(deserializer).map(Key)
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(transparent)]
pub struct KeySet(pub Vec<Key>);
impl KeySet {
pub fn new() -> Self {
KeySet(Vec::new())
}
pub fn from_slice(data: &[u8]) -> Result<Self, Error> {
Ok(cbor2::from_slice(data)?)
}
pub fn to_vec(&self) -> Result<Vec<u8>, Error> {
Ok(cbor2::to_canonical_vec(self)?)
}
pub fn lookup(&self, kid: &[u8]) -> Option<&Key> {
self.0
.iter()
.find(|k| matches!(k.kid(), Ok(Some(id)) if id == kid))
}
}
impl Deref for KeySet {
type Target = Vec<Key>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for KeySet {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}