Skip to content

Commit

Permalink
Require credentialSubject to be non-empty (#409)
Browse files Browse the repository at this point in the history
- Require credentialSubject to be non-empty
- Use blank node instead of empty credentialSubject for existing
  RDF-based credential test vectors
- Reissue vc-poly-eip712sig with non-empty credentialSubject
  • Loading branch information
clehner committed Mar 29, 2022
1 parent 4c30f1a commit ab332d1
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 71 deletions.
4 changes: 3 additions & 1 deletion did-ethr/tests/vc.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"type": [
"VerifiableCredential"
],
"credentialSubject": {},
"credentialSubject": {
"id": "_:1"
},
"issuer": "did:ethr:0xdebee5349ba59faa2b9831f108a0f712d8ab26bb",
"issuanceDate": "2021-06-16T21:16:03.362Z",
"proof": {
Expand Down
4 changes: 3 additions & 1 deletion did-pkh/tests/vc-eth-eip712vm.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"type": [
"VerifiableCredential"
],
"credentialSubject": {},
"credentialSubject": {
"id": "_:1"
},
"issuer": "did:pkh:eth:0xdebee5349ba59faa2b9831f108a0f712d8ab26bb",
"issuanceDate": "2021-06-16T20:55:45.850Z",
"proof": {
Expand Down
4 changes: 3 additions & 1 deletion did-pkh/tests/vc-eth-epsig.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"type": [
"VerifiableCredential"
],
"credentialSubject": {},
"credentialSubject": {
"id": "_:1"
},
"issuer": "did:pkh:eth:0xdebee5349ba59faa2b9831f108a0f712d8ab26bb",
"issuanceDate": "2021-06-15T19:10:36.479Z",
"proof": {
Expand Down
135 changes: 71 additions & 64 deletions did-pkh/tests/vc-poly-eip712sig.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -2,81 +2,88 @@
"@context": [
"https://www.w3.org/2018/credentials/v1"
],
"credentialSubject": {},
"issuanceDate": "2021-06-15T19:10:36.479Z",
"issuer": "did:pkh:poly:0x4e90e8a8191c1c23a24a598c3ab4fb47ce926ff5",
"type": [
"VerifiableCredential"
],
"credentialSubject": {
"id": "did:pkh:eip155:137:0x3a692a1a163657a0f53bc5c9f1d284b3ce2f4941"
},
"issuer": "did:pkh:eip155:137:0x3a692a1a163657a0f53bc5c9f1d284b3ce2f4941",
"issuanceDate": "2022-03-21T20:16:09.281Z",
"proof": {
"@context": "https://demo.spruceid.com/ld/eip712sig-2021/v0.1.jsonld",
"created": "2021-08-11T18:27:11.735Z",
"@context": "https://w3id.org/security/suites/eip712sig-2021/v1",
"type": "EthereumEip712Signature2021",
"proofPurpose": "assertionMethod",
"proofValue": "0x1902d56716f6ef4c79935e0ac85acc6fdf21c4df1711183a037e3b3a0193e5ca149e42764ff7f9990c6b9c2b11f57d5d7f3e48be0fd80d477480d57f959c89c11b",
"verificationMethod": "did:pkh:eip155:137:0x3a692a1a163657a0f53bc5c9f1d284b3ce2f4941#blockchainAccountId",
"created": "2022-03-21T20:16:09.284Z",
"eip712Domain": {
"domain": {
"name": "Polygon Example Credential"
},
"messageSchema": {
"CredentialSubject": [],
"types": {
"CredentialSubject": [
{
"name": "id",
"type": "string"
}
],
"EIP712Domain": [
{
"name": "name",
"type": "string"
}
{
"name": "name",
"type": "string"
}
],
"Proof": [
{
"name": "@context",
"type": "string"
},
{
"name": "verificationMethod",
"type": "string"
},
{
"name": "created",
"type": "string"
},
{
"name": "proofPurpose",
"type": "string"
},
{
"name": "type",
"type": "string"
}
{
"name": "@context",
"type": "string"
},
{
"name": "verificationMethod",
"type": "string"
},
{
"name": "created",
"type": "string"
},
{
"name": "proofPurpose",
"type": "string"
},
{
"name": "type",
"type": "string"
}
],
"VerifiableCredential": [
{
"name": "@context",
"type": "string[]"
},
{
"name": "type",
"type": "string[]"
},
{
"name": "issuer",
"type": "string"
},
{
"name": "issuanceDate",
"type": "string"
},
{
"name": "credentialSubject",
"type": "CredentialSubject"
},
{
"name": "proof",
"type": "Proof"
}
{
"name": "@context",
"type": "string[]"
},
{
"name": "type",
"type": "string[]"
},
{
"name": "issuer",
"type": "string"
},
{
"name": "issuanceDate",
"type": "string"
},
{
"name": "credentialSubject",
"type": "CredentialSubject"
},
{
"name": "proof",
"type": "Proof"
}
]
},
"primaryType": "VerifiableCredential"
},
"proofPurpose": "assertionMethod",
"proofValue": "0xfb9a723fea057f3a7bbfde5097b8b6dd2922017a4f46f51c8999d7420ef08a9f138f1bfc2ea6678751d2bb3870ae2b90b0a57149835bb06edc34f1fc863771991c",
"type": "EthereumEip712Signature2021",
"verificationMethod": "did:pkh:poly:0x4e90e8a8191c1c23a24a598c3ab4fb47ce926ff5#Recovery2020"
},
"type": [
"VerifiableCredential"
]
}
}
}
4 changes: 3 additions & 1 deletion did-pkh/tests/vc-poly-epsig.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"@context": [
"https://www.w3.org/2018/credentials/v1"
],
"credentialSubject": {},
"credentialSubject": {
"id": "_:1"
},
"issuanceDate": "2021-06-15T19:10:36.479Z",
"issuer": "did:pkh:poly:0x4e90e8a8191c1c23a24a598c3ab4fb47ce926ff5",
"proof": {
Expand Down
7 changes: 7 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ pub enum Error {
MissingProof,
/// Missing issuance date
MissingIssuanceDate,
/// Credential subject must be non-empty
///
/// [Verifiable credential subject](crate::vc::CredentialSubject) arity must be positive
/// and value must be non-empty, per [VC
/// Data Model](https://www.w3.org/TR/vc-data-model/#credential-subject).
EmptyCredentialSubject,
/// Missing type VerifiableCredential
MissingTypeVerifiableCredential,
/// Missing type VerifiablePresentation
Expand Down Expand Up @@ -411,6 +417,7 @@ impl fmt::Display for Error {
Error::MissingPrime => write!(f, "Missing prime factor in RSA key"),
Error::MissingKeyParameters => write!(f, "JWT key parameters not found"),
Error::MissingProof => write!(f, "Missing proof property"),
Error::EmptyCredentialSubject => write!(f, "Credential subject must be non-empty"),
Error::MissingIssuanceDate => write!(f, "Missing issuance date"),
Error::MissingTypeVerifiableCredential => {
write!(f, "Missing type VerifiableCredential")
Expand Down
36 changes: 34 additions & 2 deletions src/vc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,22 @@ pub struct CredentialSubject {
pub property_set: Option<Map<String, Value>>,
}

impl CredentialSubject {
/// Check if the credential subject is empty
///
/// An empty credential subject (containing no properties, not even an id property) is
/// considered invalid, as the VC Data Model defines the value of the
/// [credentialSubject](https://www.w3.org/TR/vc-data-model/#credential-subject) property as
/// "a set of objects that contain one or more properties [...]"
pub fn is_empty(&self) -> bool {
self.id.is_none()
&& match self.property_set {
Some(ref ps) => ps.is_empty(),
None => true,
}
}
}

#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum Issuer {
Expand Down Expand Up @@ -1178,6 +1194,18 @@ impl Credential {
if self.issuer.is_none() {
return Err(Error::MissingIssuer);
}
if self.credential_subject.is_empty() {
// https://www.w3.org/TR/vc-data-model/#credential-subject
// VC-Data-Model "defines a credentialSubject property for the expression of claims
// about one or more subjects."
// Therefore, zero credentialSubject values is considered invalid.
return Err(Error::EmptyCredentialSubject);
}
for subject in &self.credential_subject {
if subject.is_empty() {
return Err(Error::EmptyCredentialSubject);
}
}
if self.issuance_date.is_none() {
return Err(Error::MissingIssuanceDate);
}
Expand Down Expand Up @@ -3021,7 +3049,9 @@ _:c14n0 <https://w3id.org/security#verificationMethod> <https://example.org/foo/
"type": ["VerifiableCredential"],
"issuer": "did:example:foo",
"issuanceDate": "2021-08-25T18:38:54Z",
"credentialSubject": {},
"credentialSubject": {
"id": "did:example:foo"
},
"credentialStatus": {
"id": "_:1",
"type": "RevocationList2020Status",
Expand All @@ -3038,7 +3068,9 @@ _:c14n0 <https://w3id.org/security#verificationMethod> <https://example.org/foo/
"type": ["VerifiableCredential"],
"issuer": "did:example:foo",
"issuanceDate": "2021-08-25T20:15:45Z",
"credentialSubject": {},
"credentialSubject": {
"id": "did:example:foo"
},
"credentialStatus": {
"id": "_:1",
"type": "RevocationList2020Status",
Expand Down
4 changes: 3 additions & 1 deletion tests/lds-aleo2021-vc0.jsonld
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"type": [
"VerifiableCredential"
],
"credentialSubject": {},
"credentialSubject": {
"id": "_:1"
},
"issuer": "did:example:aleovm2021",
"issuanceDate": "2021-11-23T20:08:36Z",
"proof": [
Expand Down

0 comments on commit ab332d1

Please sign in to comment.