Skip to content

Commit

Permalink
Extract some duplicated code.
Browse files Browse the repository at this point in the history
  • Loading branch information
radumarias committed Aug 5, 2024
1 parent a9fdf0f commit 5cffb26
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 159 deletions.
1 change: 1 addition & 0 deletions src/cose.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod key;
pub mod mac0;
mod serialize;
pub mod sign1;

use coset::iana;
Expand Down
38 changes: 21 additions & 17 deletions src/cose/key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,14 @@ impl<'de> Deserialize<'de> for CoseKey {
impl TryFrom<CoseKey> for EncodedPoint {
type Error = Error;
fn try_from(value: CoseKey) -> Result<EncodedPoint, Self::Error> {
let x = get_x(&value)?.as_bytes().ok_or(Error::EC2MissingX)?;
let x = get_coord(&value, Element::X)?
.as_bytes()
.ok_or(Error::EC2MissingX)?;
match value.0.kty {
KeyType::Assigned(kty) => match kty {
iana::KeyType::EC2 => {
let x_generic_array = GenericArray::from_slice(x.as_ref());
match get_y(&value)? {
match get_coord(&value, Element::Y)? {
Value::Bytes(y) => {
let y_generic_array = GenericArray::from_slice(y.as_ref());
Ok(EncodedPoint::from_affine_coordinates(
Expand Down Expand Up @@ -208,13 +210,13 @@ impl From<CoseKey> for CborValue {
/// If X or Y is missing.
fn from(key: CoseKey) -> CborValue {
let mut map = BTreeMap::new();
let x = get_x(&key)
let x = get_coord(&key, Element::X)
.unwrap()
.as_bytes()
.ok_or(Error::EC2MissingX)
.unwrap()
.clone();
let y = get_y(&key)
let y = get_coord(&key, Element::Y)
.unwrap()
.as_bytes()
.ok_or(Error::EC2MissingY)
Expand Down Expand Up @@ -366,24 +368,26 @@ fn into_curve(str: String) -> Result<EllipticCurve, Error> {
})
}

fn get_x(key: &CoseKey) -> Result<&Value, Error> {
for (key, value) in &key.0.params {
match key {
Label::Int(p) if *p == iana::Ec2KeyParameter::X as i64 => return Ok(value),
_ => continue,
}
}
Err(Error::EC2MissingX)
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
enum Element {
X,
Y,
}

fn get_y(key: &CoseKey) -> Result<&Value, Error> {
fn get_coord(key: &CoseKey, element: Element) -> Result<&Value, Error> {
for (key, value) in &key.0.params {
match key {
Label::Int(p) if *p == iana::Ec2KeyParameter::Y as i64 => return Ok(value),
_ => continue,
match element {
Element::X => match key {
Label::Int(p) if *p == iana::Ec2KeyParameter::X as i64 => return Ok(value),
_ => continue,
},
Element::Y => match key {
Label::Int(p) if *p == iana::Ec2KeyParameter::Y as i64 => return Ok(value),
_ => continue,
},
}
}
Err(Error::EC2MissingY)
Err(Error::EC2MissingX)
}

fn get_crv(key: &CoseKey) -> Result<EllipticCurve, Error> {
Expand Down
81 changes: 10 additions & 71 deletions src/cose/mac0.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::cose::SignatureAlgorithm;
use crate::cose::{serialize, SignatureAlgorithm};
use ::hmac::Hmac;
use coset::cbor::Value;
use coset::cwt::ClaimsSet;
Expand All @@ -7,9 +7,7 @@ use coset::{
RegisteredLabelWithPrivate,
};
use digest::{Mac, MacError};
use serde::ser::{SerializeMap, SerializeSeq};
use serde::{ser, Deserialize, Deserializer, Serialize};
use serde_cbor::tags::Tagged;
use sha2::Sha256;

/// Prepared `COSE_Mac0` for remote signing.
Expand Down Expand Up @@ -254,74 +252,15 @@ impl ser::Serialize for CoseMac0 {
.clone()
.to_cbor_value()
.map_err(ser::Error::custom)?;
if self.tagged {
return Tagged::new(Some(iana::CborTag::CoseMac0 as u64), value).serialize(serializer);
}
match value {
Value::Bytes(x) => serializer.serialize_bytes(&x),
Value::Bool(x) => serializer.serialize_bool(x),
Value::Text(x) => serializer.serialize_str(x.as_str()),
Value::Null => serializer.serialize_unit(),

Value::Tag(tag, ref v) => Tagged::new(Some(tag), v).serialize(serializer),

Value::Float(x) => {
let y = x as f32;
if (y as f64).to_bits() == x.to_bits() {
serializer.serialize_f32(y)
} else {
serializer.serialize_f64(x)
}
}

#[allow(clippy::unnecessary_fallible_conversions)]
Value::Integer(x) => {
if let Ok(x) = u8::try_from(x) {
serializer.serialize_u8(x)
} else if let Ok(x) = i8::try_from(x) {
serializer.serialize_i8(x)
} else if let Ok(x) = u16::try_from(x) {
serializer.serialize_u16(x)
} else if let Ok(x) = i16::try_from(x) {
serializer.serialize_i16(x)
} else if let Ok(x) = u32::try_from(x) {
serializer.serialize_u32(x)
} else if let Ok(x) = i32::try_from(x) {
serializer.serialize_i32(x)
} else if let Ok(x) = u64::try_from(x) {
serializer.serialize_u64(x)
} else if let Ok(x) = i64::try_from(x) {
serializer.serialize_i64(x)
} else if let Ok(x) = u128::try_from(x) {
serializer.serialize_u128(x)
} else if let Ok(x) = i128::try_from(x) {
serializer.serialize_i128(x)
} else {
unreachable!()
}
}

Value::Array(x) => {
let mut map = serializer.serialize_seq(Some(x.len()))?;

for v in x {
map.serialize_element(&v)?;
}

map.end()
}

Value::Map(x) => {
let mut map = serializer.serialize_map(Some(x.len()))?;

for (k, v) in x {
map.serialize_entry(&k, &v)?;
}

map.end()
}
_ => unimplemented!(),
}
serialize::serialize(
value,
if self.tagged {
Some(iana::CborTag::CoseMac0 as u64)
} else {
None
},
serializer,
)
}
}

Expand Down
81 changes: 10 additions & 71 deletions src/cose/sign1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ use coset::{
iana, sig_structure_data, AsCborValue, CborSerializable, CoseError, RegisteredLabelWithPrivate,
SignatureContext,
};
use serde::ser::{SerializeMap, SerializeSeq};
use serde::{ser, Deserialize, Deserializer, Serialize};
use serde_cbor::tags::Tagged;
use signature::Verifier;

use crate::cose::SignatureAlgorithm;
use crate::cose::{serialize, SignatureAlgorithm};

/// Prepared `COSE_Sign1` for remote signing.
///
Expand Down Expand Up @@ -268,74 +266,15 @@ impl ser::Serialize for CoseSign1 {
.clone()
.to_cbor_value()
.map_err(ser::Error::custom)?;
if self.tagged {
return Tagged::new(Some(iana::CborTag::CoseSign1 as u64), value).serialize(serializer);
}
match value {
Value::Bytes(x) => serializer.serialize_bytes(&x),
Value::Bool(x) => serializer.serialize_bool(x),
Value::Text(x) => serializer.serialize_str(x.as_str()),
Value::Null => serializer.serialize_unit(),

Value::Tag(tag, ref v) => Tagged::new(Some(tag), v).serialize(serializer),

Value::Float(x) => {
let y = x as f32;
if (y as f64).to_bits() == x.to_bits() {
serializer.serialize_f32(y)
} else {
serializer.serialize_f64(x)
}
}

#[allow(clippy::unnecessary_fallible_conversions)]
Value::Integer(x) => {
if let Ok(x) = u8::try_from(x) {
serializer.serialize_u8(x)
} else if let Ok(x) = i8::try_from(x) {
serializer.serialize_i8(x)
} else if let Ok(x) = u16::try_from(x) {
serializer.serialize_u16(x)
} else if let Ok(x) = i16::try_from(x) {
serializer.serialize_i16(x)
} else if let Ok(x) = u32::try_from(x) {
serializer.serialize_u32(x)
} else if let Ok(x) = i32::try_from(x) {
serializer.serialize_i32(x)
} else if let Ok(x) = u64::try_from(x) {
serializer.serialize_u64(x)
} else if let Ok(x) = i64::try_from(x) {
serializer.serialize_i64(x)
} else if let Ok(x) = u128::try_from(x) {
serializer.serialize_u128(x)
} else if let Ok(x) = i128::try_from(x) {
serializer.serialize_i128(x)
} else {
unreachable!()
}
}

Value::Array(x) => {
let mut map = serializer.serialize_seq(Some(x.len()))?;

for v in x {
map.serialize_element(&v)?;
}

map.end()
}

Value::Map(x) => {
let mut map = serializer.serialize_map(Some(x.len()))?;

for (k, v) in x {
map.serialize_entry(&k, &v)?;
}

map.end()
}
_ => unimplemented!(),
}
serialize::serialize(
value,
if self.tagged {
Some(iana::CborTag::CoseSign1 as u64)
} else {
None
},
serializer,
)
}
}

Expand Down

0 comments on commit 5cffb26

Please sign in to comment.