Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ zkryptium = "0.2.2" # BBS
log = "0.4.21"
async-std = "1.9"
async-trait = "0.1.68"
thiserror = "1.0.40"
thiserror = "2.0"
chrono = "0.4.24"
iref = "3.2.2"
static-iref = "3.0"
Expand Down
1 change: 1 addition & 0 deletions crates/claims/crates/data-integrity/core/src/hashing.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(deprecated)] // TODO upgrade `digest` crate when possible.
use digest::{
consts::{U32, U48},
generic_array::{ArrayLength, GenericArray},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl StandardCryptographicSuite for EcdsaSecp256k1RecoverySignature2020 {

type ProofOptions = ();

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ impl StandardCryptographicSuite for AleoSignature2021 {

type ProofOptions = ();

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl StandardCryptographicSuite for Eip712Signature2021 {

type ProofOptions = ();

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl StandardCryptographicSuite for EthereumPersonalSignature2021 {

type ProofOptions = ();

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl StandardCryptographicSuite for EthereumPersonalSignature2021v0_1 {

type ProofOptions = ();

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl StandardCryptographicSuite for SolanaSignature2021 {

type ProofOptions = ();

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ impl Options {
}

impl RecoverPublicJwk for Options {
fn public_jwk(&self) -> Cow<JWK> {
fn public_jwk(&self) -> Cow<'_, JWK> {
Cow::Borrowed(&self.public_key_jwk)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl StandardCryptographicSuite for Ed25519BLAKE2BDigestSize20Base58CheckEncoded

type ProofOptions = Options;

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl StandardCryptographicSuite for P256BLAKE2BDigestSize20Base58CheckEncodedSig

type ProofOptions = Options;

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl StandardCryptographicSuite for TezosJcsSignature2021 {

type ProofOptions = Options;

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl StandardCryptographicSuite for TezosSignature2021 {

type ProofOptions = Options;

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::Other(Self::NAME)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl StandardCryptographicSuite for Bbs2023 {

type SignatureAlgorithm = Bbs2023SignatureAlgorithm;

fn type_(&self) -> TypeRef {
fn type_(&self) -> TypeRef<'_> {
TypeRef::DataIntegrityProof(CryptosuiteStr::new("bbs-2023").unwrap())
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ pub struct JsonCredential {
}

impl JsonLdObject for JsonCredential {
fn json_ld_context(&self) -> Option<Cow<ssi_json_ld::syntax::Context>> {
fn json_ld_context(&self) -> Option<Cow<'_, ssi_json_ld::syntax::Context>> {
Some(Cow::Borrowed(&self.context))
}
}

impl JsonLdNodeObject for JsonCredential {
fn json_ld_type(&self) -> JsonLdTypes {
fn json_ld_type(&self) -> JsonLdTypes<'_> {
JsonLdTypes::new(&[], Cow::Borrowed(&self.types))
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/crates/jws/src/compact/url_safe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl<'a> PartialEq<&'a Jws> for String {
/// don't know if it is URL-safe.
/// Use [`JwsVec`](crate::JwsVec) if you don't have any expectations about the
/// encoding.
#[derive(Clone, serde::Serialize)]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize)]
#[serde(transparent)]
pub struct JwsBuf(String);

Expand Down
1 change: 1 addition & 0 deletions crates/claims/crates/jws/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,7 @@ pub fn recover(algorithm: Algorithm, data: &[u8], signature: &[u8]) -> Result<JW
let rec_id =
k256::ecdsa::RecoveryId::try_from(signature[64]).map_err(ssi_jwk::Error::from)?;
let hash = ssi_crypto::hashes::sha256::sha256(data);
#[allow(deprecated)] // TODO upgrade `digest` crate when possible.
let digest = k256::elliptic_curve::FieldBytes::<k256::Secp256k1>::from_slice(&hash);
let recovered_key = VerifyingKey::recover_from_prehash(digest, &sig, rec_id)
.map_err(ssi_jwk::Error::from)?;
Expand Down
46 changes: 44 additions & 2 deletions crates/claims/crates/jws/src/signature.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ssi_claims_core::SignatureError;
use ssi_jwk::{Algorithm, JWK};
use std::borrow::Cow;
use std::{borrow::Cow, rc::Rc, sync::Arc};

use crate::{DecodedJws, DecodedSigningBytes, Header, JwsBuf, JwsSignature};

Expand Down Expand Up @@ -134,7 +134,7 @@ pub trait JwsSigner {
}
}

impl<T: JwsSigner> JwsSigner for &T {
impl<T: ?Sized + JwsSigner> JwsSigner for &T {
async fn fetch_info(&self) -> Result<JwsSignerInfo, SignatureError> {
T::fetch_info(*self).await
}
Expand All @@ -148,6 +148,48 @@ impl<T: JwsSigner> JwsSigner for &T {
}
}

impl<T: JwsSigner> JwsSigner for Box<T> {
async fn fetch_info(&self) -> Result<JwsSignerInfo, SignatureError> {
T::fetch_info(self).await
}

async fn sign_bytes(&self, signing_bytes: &[u8]) -> Result<Vec<u8>, SignatureError> {
T::sign_bytes(self, signing_bytes).await
}

async fn sign(&self, payload: impl JwsPayload) -> Result<JwsBuf, SignatureError> {
T::sign(self, payload).await
}
}

impl<T: JwsSigner> JwsSigner for Rc<T> {
async fn fetch_info(&self) -> Result<JwsSignerInfo, SignatureError> {
T::fetch_info(self).await
}

async fn sign_bytes(&self, signing_bytes: &[u8]) -> Result<Vec<u8>, SignatureError> {
T::sign_bytes(self, signing_bytes).await
}

async fn sign(&self, payload: impl JwsPayload) -> Result<JwsBuf, SignatureError> {
T::sign(self, payload).await
}
}

impl<T: JwsSigner> JwsSigner for Arc<T> {
async fn fetch_info(&self) -> Result<JwsSignerInfo, SignatureError> {
T::fetch_info(self).await
}

async fn sign_bytes(&self, signing_bytes: &[u8]) -> Result<Vec<u8>, SignatureError> {
T::sign_bytes(self, signing_bytes).await
}

async fn sign(&self, payload: impl JwsPayload) -> Result<JwsBuf, SignatureError> {
T::sign(self, payload).await
}
}

impl<T: JwsSigner + Clone> JwsSigner for Cow<'_, T> {
async fn fetch_info(&self) -> Result<JwsSignerInfo, SignatureError> {
T::fetch_info(self.as_ref()).await
Expand Down
2 changes: 1 addition & 1 deletion crates/claims/crates/jwt/src/claims/matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ mod tests {
}
}

fn try_get<C: Claim>(&self) -> Result<Option<Cow<C>>, InvalidClaimValue> {
fn try_get<C: Claim>(&self) -> Result<Option<Cow<'_, C>>, InvalidClaimValue> {
match_claim_type! {
match C {
CustomClaim => {
Expand Down
4 changes: 4 additions & 0 deletions crates/claims/crates/jwt/src/claims/mixed/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ impl JWTClaimsBuilder {
})
}
}

pub fn build(self) -> Result<JWTClaims, InvalidJWTClaims> {
self.with_private_claims(AnyClaims::default())
}
}

#[derive(Debug, thiserror::Error)]
Expand Down
73 changes: 72 additions & 1 deletion crates/claims/crates/jwt/src/claims/registered.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::{Claim, InvalidClaimValue, JWTClaims};
use crate::{CastClaim, ClaimSet, InfallibleClaimSet, NumericDate, StringOrURI};
use ssi_claims_core::{ClaimsValidity, DateTimeProvider, ValidateClaims};
use chrono::{DateTime, Utc};
use ssi_claims_core::{ClaimsValidity, DateTimeProvider, InvalidClaims, ValidateClaims};
use ssi_core::OneOrMany;
use ssi_jws::JwsPayload;
use std::{borrow::Cow, collections::BTreeMap};
Expand Down Expand Up @@ -409,3 +410,73 @@ registered_claims! {

"vp": VerifiablePresentation(json_syntax::Value)
}

pub enum JwtClaimValidationFailed {
Premature {
now: DateTime<Utc>,
valid_from: DateTime<Utc>,
},
Expired {
now: DateTime<Utc>,
valid_until: DateTime<Utc>,
},
}

impl From<JwtClaimValidationFailed> for InvalidClaims {
fn from(value: JwtClaimValidationFailed) -> Self {
match value {
JwtClaimValidationFailed::Premature { now, valid_from } => {
Self::Premature { now, valid_from }
}
JwtClaimValidationFailed::Expired { now, valid_until } => {
Self::Expired { now, valid_until }
}
}
}
}

impl ExpirationTime {
pub fn verify(&self, now: DateTime<Utc>) -> Result<(), JwtClaimValidationFailed> {
let exp: DateTime<Utc> = self.0.into();
if exp > now {
Ok(())
} else {
Err(JwtClaimValidationFailed::Expired {
now,
valid_until: exp,
})
}
}
}

impl NotBefore {
pub fn verify(&self, now: DateTime<Utc>) -> Result<(), JwtClaimValidationFailed> {
let nbf: DateTime<Utc> = self.0.into();
if nbf <= now {
Ok(())
} else {
Err(JwtClaimValidationFailed::Premature {
now,
valid_from: nbf,
})
}
}
}

impl IssuedAt {
pub fn now() -> Self {
Self(Utc::now().try_into().unwrap())
}

pub fn verify(&self, now: DateTime<Utc>) -> Result<(), JwtClaimValidationFailed> {
let iat: DateTime<Utc> = self.0.into();
if iat <= now {
Ok(())
} else {
Err(JwtClaimValidationFailed::Premature {
now,
valid_from: iat,
})
}
}
}
24 changes: 20 additions & 4 deletions crates/claims/crates/sd-jwt/src/digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize};
use sha2::Digest;
use ssi_jwt::Claim;

use crate::{disclosure::Disclosure, DecodeError, SD_ALG_CLAIM_NAME};
use crate::{DecodeError, SD_ALG_CLAIM_NAME};

/// Elements of the _sd_alg claim
#[non_exhaustive]
Expand All @@ -25,15 +25,29 @@ impl SdAlg {
}
}

/// Hash the given disclosure.
pub fn hash(&self, disclosure: &Disclosure) -> String {
/// Hash the given bytes.
pub fn hash(&self, bytes: impl AsRef<[u8]>) -> String {
match self {
Self::Sha256 => {
let digest = sha2::Sha256::digest(disclosure.as_bytes());
let digest = sha2::Sha256::digest(bytes.as_ref());
BASE64_URL_SAFE_NO_PAD.encode(digest)
}
}
}

/// Verifies the given hash.
#[allow(deprecated)] // TODO bump the `digest` crate whenever possible.
pub fn verify(&self, bytes: impl AsRef<[u8]>, hash: &str) -> bool {
match self {
Self::Sha256 => {
let Ok(rdigest) = BASE64_URL_SAFE_NO_PAD.decode(hash) else {
return false;
};
let digest = sha2::Sha256::digest(bytes.as_ref());
digest.as_slice() == rdigest
}
}
}
}

impl Claim for SdAlg {
Expand Down Expand Up @@ -89,6 +103,8 @@ impl<'de> Deserialize<'de> for SdAlg {
mod tests {
use super::*;

use crate::Disclosure;

#[test]
fn test_disclosure_hashing() {
assert_eq!(
Expand Down
Loading