Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix W3C Bitstring status list statusMessage.status property de/serialization. #605

Merged
merged 2 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/claims/crates/jws/src/compact/bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,11 +176,11 @@ impl CompactJWS {
/// Any type that providing a `JWKResolver` through the `ResolverProvider`
/// trait will be fine. Notable implementors are:
/// - [`VerificationParameters`](ssi_claims_core::VerificationParameters):
/// A good default providing many other common verification parameters that
/// are not necessary here.
/// A good default providing many other common verification parameters that
/// are not necessary here.
/// - [`JWK`](ssi_jwk::JWK): allows you to put a JWK as `params`, which
/// will resolve into itself. Can be useful if you don't need key resolution
/// because you know in advance what key was used to sign the JWS.
/// will resolve into itself. Can be useful if you don't need key resolution
/// because you know in advance what key was used to sign the JWS.
///
/// # Passing the parameters by reference
///
Expand Down
11 changes: 4 additions & 7 deletions crates/claims/crates/jws/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ pub use signature::*;
mod verification;
pub use verification::*;

#[cfg(feature = "linked-data")]
mod linked_data;

/// Decoded JWS.
#[derive(Clone, PartialEq, Eq)]
pub struct JWS<T = Vec<u8>> {
Expand Down Expand Up @@ -202,11 +199,11 @@ impl<T> DecodedJWS<T> {
/// a `JWKResolver` through the `ResolverProvider` trait.
/// Notable implementors are:
/// - [`VerificationParameters`](ssi_claims_core::VerificationParameters):
/// A good default providing many other common verification parameters that
/// are not necessary here.
/// A good default providing many other common verification parameters that
/// are not necessary here.
/// - [`JWK`]: allows you to put a JWK as `params`, which
/// will resolve into itself. Can be useful if you don't need key resolution
/// because you know in advance what key was used to sign the JWS.
/// will resolve into itself. Can be useful if you don't need key resolution
/// because you know in advance what key was used to sign the JWS.
///
/// # Passing the parameters by reference
///
Expand Down
118 changes: 0 additions & 118 deletions crates/claims/crates/jws/src/linked_data.rs

This file was deleted.

4 changes: 2 additions & 2 deletions crates/claims/crates/vc/examples/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use ssi_verification_methods::{
};
use static_iref::{iri, uri};
use std::{borrow::Cow, collections::HashMap, sync::Arc};
use xsd_types::DateTime;
use xsd_types::{DateTime, DateTimeStamp};

#[derive(Clone, linked_data::Serialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -159,7 +159,7 @@ async fn main() {
// Signature options, defining the crypto suite, signature date,
// signing key and proof purpose.
let proof_options = ProofOptions::new(
DateTime::now(),
DateTimeStamp::now(),
iri!("https://example.com/controller#key").to_owned().into(),
ProofPurpose::Assertion,
(),
Expand Down
31 changes: 30 additions & 1 deletion crates/status/src/impl/bitstring_status_list/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! W3C Bitstring Status List v1.0
//! W3C Bitstring Status List v1.0 (Working Draft 06 April 2024)
//!
//! A privacy-preserving, space-efficient, and high-performance mechanism for
//! publishing status information such as suspension or revocation of Verifiable
Expand All @@ -17,10 +17,17 @@ pub use syntax::*;

#[derive(Debug, Serialize, Deserialize)]
pub struct StatusMessage {
#[serde(with = "prefixed_hexadecimal")]
pub status: u8,
pub message: String,
}

impl StatusMessage {
pub fn new(status: u8, message: String) -> Self {
Self { status, message }
}
}

#[derive(Debug, thiserror::Error)]
#[error("invalid status size `{0}`")]
pub struct InvalidStatusSize(u8);
Expand Down Expand Up @@ -545,6 +552,28 @@ impl StatusMap for StatusList {
}
}

mod prefixed_hexadecimal {
use serde::{Deserialize, Deserializer, Serialize, Serializer};

pub fn serialize<S>(value: &u8, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
format!("{value:#x}").serialize(serializer)
}

pub fn deserialize<'de, D>(deserializer: D) -> Result<u8, D::Error>
where
D: Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
let number = string
.strip_prefix("0x")
.ok_or_else(|| serde::de::Error::custom("missing `0x` prefix"))?;
u8::from_str_radix(number, 16).map_err(serde::de::Error::custom)
}
}

#[cfg(test)]
mod tests {
use rand::{rngs::StdRng, RngCore, SeedableRng};
Expand Down
4 changes: 4 additions & 0 deletions crates/status/src/impl/bitstring_status_list/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ impl EncodedList {
/// 16MB.
pub const DEFAULT_LIMIT: u64 = 16 * 1024 * 1024;

pub fn new(value: String) -> Self {
Self(value)
}

pub fn encode(bytes: &[u8]) -> Self {
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(bytes).unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,53 @@ impl BitstringStatusList {
Ok(StatusList::from_bytes(self.status_size, bytes, self.ttl))
}
}

#[cfg(test)]
mod tests {
use super::BitstringStatusList;
use crate::bitstring_status_list::{EncodedList, StatusMessage, StatusPurpose, TimeToLive};

const STATUS_LIST: &str = r#"{
"id": "https://example.com/status/3#list",
"type": "BitstringStatusList",
"ttl": 500,
"statusPurpose": "message",
"statusReference": "https://example.org/status-dictionary/",
"statusSize": 2,
"statusMessage": [
{"status":"0x0", "message":"valid"},
{"status":"0x1", "message":"invalid"},
{"status":"0x2", "message":"pending_review"}
],
"encodedList": "uH4sIAAAAAAAAA-3BMQEAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA"
}"#;

#[test]
fn deserialize() {
serde_json::from_str::<BitstringStatusList>(STATUS_LIST).unwrap();
}

#[test]
fn serialize() {
let expected: serde_json::Value = serde_json::from_str(STATUS_LIST).unwrap();

let status_list = BitstringStatusList {
id: Some("https://example.com/status/3#list".parse().unwrap()),
ttl: TimeToLive(500),
status_purpose: StatusPurpose::Message,
status_reference: Some("https://example.org/status-dictionary/".parse().unwrap()),
status_size: 2.try_into().unwrap(),
status_message: vec![
StatusMessage::new(0, "valid".to_owned()),
StatusMessage::new(1, "invalid".to_owned()),
StatusMessage::new(2, "pending_review".to_owned()),
],
encoded_list: EncodedList::new(
"uH4sIAAAAAAAAA-3BMQEAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAIC3AYbSVKsAQAAA".to_owned(),
),
};

let value = serde_json::to_value(status_list).unwrap();
assert_eq!(value, expected);
}
}