Skip to content

Commit

Permalink
Add Support To Resolve JWK_JCS-PUB encoded did:key DIDs (#600)
Browse files Browse the repository at this point in the history
  • Loading branch information
ianhamilton87 authored Sep 18, 2024
1 parent 868e073 commit a585e0c
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 1 deletion.
20 changes: 20 additions & 0 deletions crates/jwk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ impl FromStr for JWK {
}
}

impl TryFrom<&[u8]> for JWK {
type Error = serde_json::Error;

fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
serde_json::from_slice(bytes)
}
}

impl TryFrom<serde_json::Value> for JWK {
type Error = serde_json::Error;

Expand Down Expand Up @@ -1319,6 +1327,7 @@ mod tests {
const RSA_DER: &[u8] = include_bytes!("../../../tests/rsa2048-2020-08-25.der");
const RSA_PK_DER: &[u8] = include_bytes!("../../../tests/rsa2048-2020-08-25-pk.der");
const ED25519_JSON: &str = include_str!("../../../tests/ed25519-2020-10-18.json");
const JWK_JCS_JSON: &[u8] = include_bytes!("../../../tests/jwk_jcs-pub.json");

#[test]
fn jwk_to_from_der_rsa() {
Expand All @@ -1330,6 +1339,17 @@ mod tests {
assert_eq!(key.to_public().params, Params::RSA(rsa_params));
}

#[test]
fn jwk_try_from_bytes() {
let actual_jwk: JWK = JWK::try_from(JWK_JCS_JSON).unwrap();
let actual_params: Params = actual_jwk.params;
if let Params::EC(ref ec_params) = actual_params {
assert_eq!(ec_params.curve.as_deref(), Some("P-256"));
} else {
panic!("actual_params is not of type Params::EC");
}
}

#[test]
fn rsa_from_str() {
let _key: JWK = serde_json::from_str(RSA_JSON).unwrap();
Expand Down
41 changes: 40 additions & 1 deletion crates/jwk/src/multicodec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use ssi_multicodec::{MultiEncoded, MultiEncodedBuf};
use ssi_multicodec::{Codec, MultiEncoded, MultiEncodedBuf};
use std::borrow::Cow;

use crate::{Error, Params, JWK};

Expand Down Expand Up @@ -47,6 +48,9 @@ impl JWK {
ssi_multicodec::BLS12_381_G2_PUB => {
crate::bls12381g2_parse(k).map_err(FromMulticodecError::Bls12381G2Pub)
}
ssi_multicodec::JWK_JCS_PUB => {
JWK::from_bytes(k).map_err(FromMulticodecError::JwkJcsPub)
}
_ => Err(FromMulticodecError::UnsupportedCodec(codec)),
}
}
Expand Down Expand Up @@ -123,6 +127,18 @@ impl JWK {
}
}

impl Codec for JWK {
const CODEC: u64 = ssi_multicodec::JWK_JCS_PUB;

fn to_bytes(&self) -> Cow<[u8]> {
Cow::Owned(serde_jcs::to_vec(self).unwrap())
}

fn from_bytes(bytes: &[u8]) -> Result<Self, ssi_multicodec::Error> {
Self::try_from(bytes).map_err(|_| ssi_multicodec::Error::InvalidData)
}
}

#[derive(Debug, thiserror::Error)]
pub enum FromMulticodecError {
#[cfg(feature = "rsa")]
Expand Down Expand Up @@ -165,6 +181,9 @@ pub enum FromMulticodecError {
#[error(transparent)]
Bls12381G2Pub(ssi_bbs::Error),

#[error(transparent)]
JwkJcsPub(ssi_multicodec::Error),

/// Unexpected multibase (multicodec) key prefix multicodec
#[error("Unsupported multicodec key type 0x{0:x}")]
UnsupportedCodec(u64),
Expand All @@ -184,3 +203,23 @@ pub enum ToMulticodecError {
#[error("invalid input key: {0}")]
InvalidInputKey(Error),
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
#[cfg(feature = "secp256r1")]
fn test_multicodec_jwk_jcs_pub() {
let jwk = JWK::generate_p256();
// Note: can't use JWK::to_multicodec() because it's based on the particular key within the JWK
// it will see the P256 key and assign a multicodec of 0x1200.
// For jwk_jcs_pub multicodecs, we can only decode them
let jwk_buf = MultiEncodedBuf::encode(&jwk);
let (codec, data) = jwk_buf.parts();
assert_eq!(codec, ssi_multicodec::JWK_JCS_PUB);
assert_eq!(*data, jwk.to_bytes().into_owned());
let jwk2 = JWK::from_multicodec(&jwk_buf).unwrap();
assert_eq!(jwk, jwk2);
}
}
6 changes: 6 additions & 0 deletions tests/jwk_jcs-pub.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"crv": "P-256",
"kty": "EC",
"x": "g3fsv1xpWPH099LIUn_zJoOF5Ur8xobyzZwX9m_dJ4E",
"y": "9304UAFl55xQMfrnB-zKEjjXEC4OFWSuYnr7W6hdkVA"
}

0 comments on commit a585e0c

Please sign in to comment.