Skip to content

Commit 2388e31

Browse files
AlfioEmanueleFrestarobin-nitrokey
authored andcommitted
Add Deserialize trait to PublicKey
1 parent 0fd493a commit 2388e31

File tree

2 files changed

+51
-10
lines changed

2 files changed

+51
-10
lines changed

src/lib.rs

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,8 @@ impl Expected for Crv {
140140
}
141141
}
142142

143-
// `Deserialize` can't be derived on untagged enum,
144-
// would need to "sniff" for correct (Kty, Alg, Crv) triple
145-
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
143+
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
144+
#[serde(try_from = "RawPublicKey")]
146145
#[serde(untagged)]
147146
pub enum PublicKey {
148147
P256Key(P256PublicKey),
@@ -175,6 +174,44 @@ impl From<TotpPublicKey> for PublicKey {
175174
}
176175
}
177176

177+
impl TryFrom<RawPublicKey> for PublicKey {
178+
type Error = serde::de::value::Error;
179+
180+
fn try_from(raw: RawPublicKey) -> Result<Self, Self::Error> {
181+
match raw {
182+
RawPublicKey {
183+
kty: Some(Kty::Ec2),
184+
alg: Some(Alg::Es256),
185+
crv: Some(Crv::P256),
186+
x: Some(x),
187+
y: Some(y),
188+
} => Ok(PublicKey::P256Key(P256PublicKey { x, y })),
189+
RawPublicKey {
190+
kty: Some(Kty::Ec2),
191+
alg: Some(Alg::EcdhEsHkdf256),
192+
crv: Some(Crv::P256),
193+
x: Some(x),
194+
y: Some(y),
195+
} => Ok(PublicKey::EcdhEsHkdf256Key(EcdhEsHkdf256PublicKey { x, y })),
196+
RawPublicKey {
197+
kty: Some(Kty::Okp),
198+
alg: Some(Alg::EdDsa),
199+
crv: Some(Crv::Ed25519),
200+
x: Some(x),
201+
y: None,
202+
} => Ok(PublicKey::Ed25519Key(Ed25519PublicKey { x })),
203+
RawPublicKey {
204+
kty: Some(Kty::Symmetric),
205+
alg: Some(Alg::Totp),
206+
crv: None,
207+
x: None,
208+
y: None,
209+
} => Ok(PublicKey::TotpKey(TotpPublicKey {})),
210+
_ => Err(serde::de::Error::custom("invalid key data")),
211+
}
212+
}
213+
}
214+
178215
#[derive(Clone, Debug, Default)]
179216
struct RawPublicKey {
180217
kty: Option<Kty>,

tests/cose.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use core::fmt::Debug;
22

33
use cbor_smol::{cbor_deserialize, cbor_serialize_bytes};
44
use ciborium::Value;
5-
use cosey::{EcdhEsHkdf256PublicKey, Ed25519PublicKey, P256PublicKey};
5+
use cosey::{EcdhEsHkdf256PublicKey, Ed25519PublicKey, P256PublicKey, PublicKey};
66
use heapless_bytes::Bytes;
77
use itertools::Itertools as _;
88
use quickcheck::{Arbitrary, Gen};
@@ -150,25 +150,29 @@ fn de_p256() {
150150
let x = Bytes::from_slice(&[0xff; 32]).unwrap();
151151
let y = Bytes::from_slice(&[0xff; 32]).unwrap();
152152
let key = P256PublicKey { x, y };
153-
test_de("a5010203262001215820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff225820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", key);
153+
let data = "a5010203262001215820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff225820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
154+
test_de(data, key.clone());
155+
test_de(data, PublicKey::P256Key(key));
154156
}
155157

156158
#[test]
157159
fn de_ecdh() {
158160
let x = Bytes::from_slice(&[0xff; 32]).unwrap();
159161
let y = Bytes::from_slice(&[0xff; 32]).unwrap();
160162
let key = EcdhEsHkdf256PublicKey { x, y };
161-
test_de("a501020338182001215820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff225820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", key);
163+
let data = "a501020338182001215820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff225820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
164+
test_de(data, key.clone());
165+
test_de(data, PublicKey::EcdhEsHkdf256Key(key));
162166
}
163167

164168
#[test]
165169
fn de_ed25519() {
166170
let x = Bytes::from_slice(&[0xff; 32]).unwrap();
167171
let key = Ed25519PublicKey { x };
168-
test_de(
169-
"a4010103272006215820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
170-
key,
171-
);
172+
let data =
173+
"a4010103272006215820ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
174+
test_de(data, key.clone());
175+
test_de(data, PublicKey::Ed25519Key(key));
172176
}
173177

174178
quickcheck::quickcheck! {

0 commit comments

Comments
 (0)