Skip to main content

DTGCredential

Struct DTGCredential 

Source
pub struct DTGCredential { /* private fields */ }
Expand description

Defined DTG Credentials

Implementations§

Source§

impl DTGCredential

Source

pub fn new_vmc( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, personhood: bool, ) -> Self

Creates a new community-issued Verifiable Membership Credential (VMC) — the membership grant, the community → member half of a membership edge.

A membership edge is a pair of VMCs, and this is only one of them. The member answers with DTGCredential::new_member_vmc_for, and the edge is not complete until they have: a community can always issue a credential naming somebody as a member, but it cannot produce the acknowledgement without that party’s signature. The pair is what makes an unconsented membership claim unprovable.

The grant MUST NOT carry a digestMultibase — that property is what marks the other direction — and this constructor does not set one.

issuer: The identifier of the VTC or VTN granting membership subject: The member’s identifier, or the member VTC’s own for VTN membership valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until personhood: Whether this VMC can be used as a form of Personhood Credential - Adds PersonhoodCredential to the type array if true

§Give it an id

Chain DTGCredential::with_id on: the member stores the grant under its id, and re-issuing is only recognisable as a renewal rather than a duplicate if there is one.

Source

pub fn new_member_vmc_for( grant: &Value, member: &str, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, ) -> Result<Self, DTGCredentialError>

Creates a new member-issued Verifiable Membership Credential (VMC) — the membership acknowledgement, the member → community half of a membership edge.

The roles of DTGCredential::new_vmc are reversed (the member issues, the community is the subject) and the subject carries a digestMultibase of the grant being acknowledged. That digest is what binds the two halves into one edge: an acknowledgement whose digest matches no valid grant does not complete anything, and the binding forces an order — the grant must exist before this can reference it.

This is the member’s consent artifact. Because the member is its issuer, withdrawing consent needs no cooperation from the community.

§Takes the grant in its wire form, deliberately

grant is the JSON the community sent, not a parsed DTGCredential. The digest has to cover the document the community will recompute it over, and this library does not model every member a credential may carry — credentialStatus, which every VMC issued against a status list carries, is dropped by a parse-then-re-serialise round trip. Building the acknowledgement from a parsed grant would produce a digest that verifies nowhere, and would do it silently.

So: keep the bytes you were given, and pass them here.

member: The member acknowledging — the party whose key will sign this. Refused unless the grant names exactly this identifier as its subject. valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until. Must not be later than the grant’s own validUntil, and must be set if the grant’s is.

§Errors

DTGCredentialError::NotAMembershipGrant if grant is not a JSON object, does not carry MembershipCredential in its type, has no issuer or credentialSubject.id, or already carries a digest — that last is an acknowledgement, and acknowledging one does not form an edge.

It is also DTGCredentialError::NotAMembershipGrant if the grant carries a validUntil that is not an RFC 3339 timestamp.

DTGCredentialError::NotTheGrantSubject if the grant’s credentialSubject.id is not member.

DTGCredentialError::OutlivesGrant if the grant expires and valid_until is later than it, or absent.

DTGCredentialError::InvalidValidityWindow if valid_until is not after valid_from, and DTGCredentialError::JsonTooDeep if the grant is nested more deeply than crate::MAX_JSON_DEPTH.

§Give it an id

Chain DTGCredential::with_id on before signing. A community keys a member’s VMC by id to tell a re-send from a renewal.

§Security

The result is binding evidence, not membership. This constructor does not verify the grant’s proof, so it builds an acknowledgement of a grant nobody signed as readily as of one the community did. Verify the grant first — with verify_grant_with_public_key under the affinidi-signing feature, or against your own resolver — and treat the edge as complete only once both proofs and both windows have verified.

Pass as member the identity whose key will sign the acknowledgement, established independently of the grant. An identifier read out of the grant would make the check compare the grant with itself.

Source

pub fn new_member_vmc( grant: &Value, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, ) -> Result<Self, DTGCredentialError>

👎Deprecated since 0.10.0:

Takes the member from the grant without comparing it to anything, and lets the acknowledgement outlive the grant. Use DTGCredential::new_member_vmc_for, which takes the member you expect and refuses a grant naming anyone else. This constructor will be removed in a future release.

Creates a member-issued VMC without checking who the grant names or when it expires.

Identical to DTGCredential::new_member_vmc_for except that the member is taken from the grant with nothing to compare it against, and the grant’s validUntil is not consulted.

Source

pub fn new_vrc( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, ) -> Self

Creates a new Verified Relationship Credential (VRC) issuer: The issuer DID of the credential subject: The DID of the subject of this credential valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until

Source

pub fn new_vic( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, ) -> Self

Creates a new Verified Invitation Credential (VIC) issuer: The issuer DID of the credential subject: The DID of the subject of this credential valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until

Source

pub fn new_vac( issuer: String, subject: String, scope: String, actions: Vec<String>, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

Creates a new Verifiable Authority Credential (VAC) — a chain root.

The issuer is the party governing scope. To derive a narrower VAC from one you already hold, use DTGCredential::attenuate instead: a chain root is a grant made by the governing party, and minting one directly is how a self-issued grant of arbitrary authority gets in.

actions MUST NOT be empty — an empty list confers nothing rather than everything.

§valid_until is required

Not optional, unlike the base structure and unlike every other new_* constructor here. Nothing about the subject’s current standing is consulted when a VAC is verified, so authority that does not expire is authority nobody can withdraw by waiting.

§Errors

DTGCredentialError::InvalidValidityWindow if valid_until is not after valid_from, and DTGCredentialError::EmptyAuthorityActions if actions is empty.

Source

pub fn attenuate( &self, subject: String, actions: Vec<String>, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

Derive a narrower VAC from one this holder already holds.

This is what lets a member equip an agent, a device, or a short-lived session with only the authority that task needs, rather than lending it their own. The derived credential is issued by the holder, not by the party governing the scope, and carries parent — the digest of the credential it narrows — so a verifier can walk back to a root.

Refuses anything that would widen. The checks here mirror crate::authority::verify_chain on purpose: a holder should be unable to build a chain a verifier would reject, so the failure surfaces at issue time rather than at use — but the verifier’s checks remain authoritative, because nothing stops a different implementation constructing the JSON by hand.

  • self must be a VAC.
  • actions must be a subset of what self confers.
  • valid_until must not exceed self’s.
§Binding the derivative to the agent is subject, not a separate field

A VAC is not a bearer credential: crate::authority::verify_chain requires the party presenting the leaf to be its subject. So equipping an agent means naming the agent in subject, and there is nothing further to bind. An earlier version of this method took an audience for that job; it was removed with the property.

§Digests the model

The parent digest is computed with DTGCredential::digest_multibase, which hashes this in-memory credential. That is right for a VAC this process built and signed. For one that arrived from a counterparty, use DTGCredential::attenuate_from_json and give it the bytes you received — the same distinction DTGCredential::new_member_vmc_for draws, and for the same reason.

Source

pub fn attenuate_from_json( parent: &Value, subject: String, actions: Vec<String>, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

Derive a narrower VAC from a parent in its wire form.

Identical to DTGCredential::attenuate except that the parent is the JSON a counterparty sent rather than a parsed credential, so the parent digest covers the document the verifier will recompute it over. Use this whenever the VAC being narrowed came from somewhere else.

§Errors

DTGCredentialError::NotAnAuthorityCredential if parent is not a JSON object carrying AuthorityCredential in its type and a well-formed credentialSubject.authority, and the same widening errors as DTGCredential::attenuate.

Source

pub fn new_vdc( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, scope: Vec<String>, max_depth: Option<u32>, ) -> Result<Self, DTGCredentialError>

Creates a new Verifiable Delegation Credential (VDC) — the delegation grant, the delegator → delegate half of a delegation edge.

Establishes that subject may act in the issuer’s name, for the acts named in scope, until valid_until. Within that scope what the delegate does is attributable to the delegator.

§This is not authority

A VDC never supplies permission the delegator did not itself hold. A verifier substitutes the delegator for the delegate and then asks the permission question it would have asked of the delegator directly — so withdrawing the delegator’s own permission ends the delegate’s ability to act immediately, without revoking anything. See DTGCredential::new_vac for the credential that answers that question.

§The edge is not complete without the acceptance

This is one half. The delegate answers with DTGCredential::new_delegate_vdc_for, and a verifier MUST obtain and verify that half before accepting any party as acting under the delegation: a grant alone establishes what the delegator appointed, not what the delegate agreed to. Same consent rule as a membership edge, and for the same reason — a delegator can always name someone as its delegate, but cannot produce the countersignature.

scope MUST NOT be empty: a VDC cannot express an unbounded appointment by omitting it.

max_depth is the number of further re-delegations permitted below this one. None and Some(0) both prohibit re-delegation — the default is a single hop, and setting it above zero is the delegator’s explicit authorisation, of which there is no other kind.

§valid_until is required

An appointment with no expiry cannot be reasoned about by a verifier that cannot reach the delegator.

§Errors

DTGCredentialError::MalformedDelegation if scope is empty, and DTGCredentialError::InvalidValidityWindow if valid_until is not after valid_from.

Source

pub fn redelegate( &self, subject: String, scope: Vec<String>, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

Derive a further VDC from one this delegate already holds — a re-delegation.

Only permitted where the held VDC sets maxDepth above zero, and only for a subset of the acts it was itself appointed for. The default is a single hop: a delegate that needs a further delegate and is not authorised to re-delegate asks the principal, who issues a fresh root delegation directly — so that the principal always holds the complete register of who may speak in its name.

The derived VDC carries parent, the digest of the VDC it derives from, and a maxDepth one less than its parent’s.

Like DTGCredential::attenuate, this digests the in-memory model; for a grant that arrived from a counterparty, use DTGCredential::redelegate_from_json.

§Errors

DTGCredentialError::MalformedDelegation if self is not a delegation grant, if it does not permit re-delegation, if scope is empty or not a subset of the parent’s, or if valid_until is later than the parent’s. DTGCredentialError::InvalidValidityWindow if valid_until is not after valid_from.

Source

pub fn redelegate_from_json( parent: &Value, subject: String, scope: Vec<String>, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

Derive a further VDC from a parent grant in its wire form.

Identical to DTGCredential::redelegate except that the parent is the JSON the delegator sent, so the parent digest covers the document a verifier will recompute it over.

Source

pub fn new_delegate_vdc_for( grant: &Value, delegate: &str, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

Creates the delegate-issued half of a delegation edge — the acceptance.

The roles of DTGCredential::new_vdc are reversed (the delegate issues, the delegator is the subject) and the subject carries accepts, the digest of the grant being taken on. That digest is what binds the two halves into one edge.

An acceptance carries no scope of its own. What the delegate consented to is the scope of the grant it names, which a verifier holds in any case; restating it would require an equality check across the two credentials that cannot be satisfied under selective disclosure of either.

This is the delegate’s consent artifact, and its accountability for acting in another’s name. Because a delegator cannot produce it, a party holding only the delegate’s key cannot manufacture appointments either.

§Takes the grant in its wire form, deliberately

Same reasoning as DTGCredential::new_member_vmc_for: the digest has to cover the document the delegator will recompute it over. Keep the bytes you were given and pass them here.

§Errors

DTGCredentialError::NotADelegationGrant if grant is not a JSON object carrying DelegationCredential in its type, has no issuer or credentialSubject.id, or already carries accepts — that last is itself an acceptance, and accepting one forms no edge.

It is also DTGCredentialError::NotADelegationGrant if the grant carries a validUntil that is not an RFC 3339 timestamp.

DTGCredentialError::NotTheGrantSubject if the grant’s credentialSubject.id is not delegate.

DTGCredentialError::OutlivesGrant if valid_until is later than the grant’s.

DTGCredentialError::InvalidValidityWindow if valid_until is not after valid_from, and DTGCredentialError::JsonTooDeep if the grant is nested more deeply than crate::MAX_JSON_DEPTH.

§Security

The result is binding evidence, not an appointment. This constructor does not verify the grant’s proof, so it builds an acceptance of a grant nobody signed as readily as of one the delegator did. Verify the grant first — with verify_grant_with_public_key under the affinidi-signing feature, or against your own resolver — and treat the edge as complete only once both proofs and both windows have verified.

Pass as delegate the identity whose key will sign the acceptance, established independently of the grant. An identifier read out of the grant would make the check compare the grant with itself.

Source

pub fn new_delegate_vdc( grant: &Value, valid_from: DateTime<Utc>, valid_until: DateTime<Utc>, ) -> Result<Self, DTGCredentialError>

👎Deprecated since 0.10.0:

Takes the delegate from the grant without comparing it to anything, and lets the acceptance outlive the grant. Use DTGCredential::new_delegate_vdc_for, which takes the delegate you expect and refuses a grant appointing anyone else. This constructor will be removed in a future release.

Creates a delegate-issued acceptance without checking who the grant appoints or when it expires.

Identical to DTGCredential::new_delegate_vdc_for except that the delegate is taken from the grant with nothing to compare it against, and the grant’s validUntil is not consulted.

Source

pub fn new_vpc( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, ) -> Self

Creates a new Verified Persona Credential (VPC) issuer: The issuer DID of the credential subject: The DID of the subject of this credential valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until

Source

pub fn new_vec( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, endorsement: Value, ) -> Self

Creates a new Verified Endorsement Credential (VEC) issuer: The issuer DID of the credential subject: The DID of the subject of this credential valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until endorsement: The endorsement details for this credential

§Security

endorsement is embedded verbatim. The specification does not define its content, so its shape is the issuer’s to choose and this library checks nothing about it but its depth. A VEC says only that its issuer said this: a consumer must verify the proof, and establish that the issuer is one whose endorsements it accepts for this purpose, before relying on any member of it.

Build it from input you control. Nesting past crate::MAX_JSON_DEPTH is refused when the credential is validated, digested or signed rather than here, because this constructor cannot return an error.

Source

pub fn new_vwc_for_session( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, session: &Value, digest: String, witness_context: Option<WitnessContext>, ) -> Result<Self, DTGCredentialError>

Creates a Verifiable Witness Credential (VWC) for a witness/session, citing the session by taskContext and taskDigestMultibase.

This is the constructor for the only VWC-issuing flow the specifications define: the witness, answering witness/session/submit on the party’s session, delivers the VWC in the response. That specification’s Conformance, item 1, requires the VWC’s taskContext to be the id of the witness/session document that opened the session and its taskDigestMultibase to be that document’s task digest. Both are read from session here, so the pair cannot disagree.

  • issuer: the witness’s DID — a member’s identifier, or the DID of a VTA acting according to VTC policy.
  • subject: the DID of the party observed issuing the edge credential that digest names, i.e. that credential’s issuer. One VWC per direction.
  • session: the witness/session document, as received. Its top-level proof, if any, is excluded from the digest, so a signed and an unsigned copy give one value.
  • digest: the witnessed edge credential’s digest, from DTGCredential::digest_multibase or crate::digest_multibase_json. REQUIRED here, unlike DTGCredential::new_vwc: a VWC without it does not say which edge was witnessed.
§Errors
§Security

Pass the session document the witness itself received and answered, not one the party supplies alongside its submission. The digest is load-bearing because the witness signs it: it is how a verifier later tells this session from a counterfeit reusing its id.

Source

pub fn new_vwc( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, task_context: String, digest: Option<String>, witness_context: Option<WitnessContext>, ) -> Self

👎Deprecated since 0.11.0:

A VWC issued through witness/session MUST carry taskDigestMultibase, the task digest of the session document, beside taskContext (witness/session/submit Conformance, item 1), and this constructor cannot set it. Use DTGCredential::new_vwc_for_session.

Creates a new Verified Witness Credential (VWC)

Carries no taskDigestMultibase, so the VWC names its session by id alone. Use DTGCredential::new_vwc_for_session, which reads both halves of the citation from the session document.

issuer: The issuer DID of the credential - a member’s identifier, or the DID of a VTA acting according to VTC policy subject: The DID of the observed party. For a witnessed bi-directional exchange this MUST be the issuer of the VRC that this VWC attests (the VRC referenced by digestMultibase), so that the two VWCs of an exchange are unambiguously bound to their respective directions. The witness should issue one VWC per direction. valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until task_context: Required threadId of the trust task exchange the witnessing occurred in digest: Cryptographic hash of the witnessed edge credential, binding this VWC to the specific edge. Produce it with DTGCredential::digest_multibase on that credential, or crate::digest_multibase_json on the bytes you received. REQUIRED by the specification; Option here because a VWC that predates the requirement still has to deserialize. A VWC without one identifies the observed party and the exchange, but not which edge was witnessed. witness_context: Optional Semantic context for the witness

Source

pub fn new_rcard( issuer: String, subject: String, valid_from: DateTime<Utc>, valid_until: Option<DateTime<Utc>>, card: Value, ) -> Self

👎Deprecated since 0.2.0:

The r-card is a verifiable data structure (VDS), not a DTGCredential subtype. It was removed from the DTG Core Credentials specification in Working Draft 01 and will be defined by the planned DTG Verifiable Data Structures specification. This constructor will be removed in a future release.

Creates a new Verified RCard Credential (VWC) issuer: The issuer DID of the credential subject: The DID of the subject of this credential valid_from: The datetime from which this credential is valid valid_until: Optional: The datetime this credential is valid until card: JSON Value representing a Jcard (RFC 7095) format

Source

pub fn with_id(self, id: impl Into<String>) -> Self

Sets this credential’s own identifier, consuming and returning it so it chains onto any of the new_* constructors above.

id MUST be a single URL per the W3C VC Data Model; urn:uuid:<uuid> is the usual choice for a credential with no dereferenceable home. This crate does not validate it.

let vmc = DTGCredential::new_vmc(
    "did:example:member".to_string(),
    "did:example:community".to_string(),
    Utc::now(),
    None,
    false,
)
.with_id("urn:uuid:2a4e1d90-6e0c-4d3f-9a4a-6d0a8f7c1b52");
assert_eq!(vmc.id(), Some("urn:uuid:2a4e1d90-6e0c-4d3f-9a4a-6d0a8f7c1b52"));
§Set it before signing

A Data Integrity proof covers the credential minus its proof, so id is part of what is signed. Chain this onto the constructor, before DTGCredential::sign — adding an id to an already-signed credential leaves a document whose proof no longer verifies.

Source

pub fn set_id(&mut self, id: impl Into<String>)

Sets this credential’s own identifier in place.

The non-consuming form of DTGCredential::with_id; the same “before signing” caveat applies.

Source

pub fn with_task_citation( self, document: &Value, ) -> Result<Self, DTGCredentialError>

Cites a Trust Task document: sets taskContext to its id and taskDigestMultibase to its task digest, together.

Use it for any credential whose meaning depends on an exchange — a VWC, or a statement a vetting/session produces. Name the innermost exchange that attests what the credential states, by the document that initiated it (Trust Tasks §4.9.1). Setting both halves from one document is the point: the id locates the exchange and the digest binds the credential to it, and a pair taken from two places binds nothing. See crate::task_digest_multibase_json for how the digest is computed.

Replaces a taskContext and taskDigestMultibase already set.

§Set it before signing

Both members are covered by the credential’s proof, as for DTGCredential::with_id.

§Errors

DTGCredentialError::MalformedTaskDocument if document is not an object with a string id; DTGCredentialError::JsonTooDeep if it is nested past crate::MAX_JSON_DEPTH.

Source

pub fn set_task_citation( &mut self, document: &Value, ) -> Result<(), DTGCredentialError>

Cites a Trust Task document in place.

The non-consuming form of DTGCredential::with_task_citation; the same caveats apply. On error, the credential is left unchanged.

Source

pub fn with_credential_status(self, status: Value) -> Self

Attaches the status mechanism through which a verifier determines whether this credential has been revoked.

The entry is opaque to this library: the mechanism is chosen by the governing VTC or VTN, and nothing here selects one or resolves it. BitstringStatusListEntry is the common choice.

let vdc = DTGCredential::new_vdc(
    "did:example:delegator".to_string(),
    "did:example:delegate".to_string(),
    Utc::now(),
    Utc::now() + Duration::days(90),
    vec!["sign:invoices".to_string()],
    None,
)
.unwrap()
.with_credential_status(json!({
    "id": "https://example.com/status/3#94567",
    "type": "BitstringStatusListEntry",
    "statusPurpose": "revocation",
    "statusListIndex": "94567",
    "statusListCredential": "https://example.com/status/3"
}));
assert!(vdc.credential().credential_status.is_some());
§When a VDC needs one

CONDITIONAL, not required. A verifier MUST be able to establish that an appointment is in force without contacting the delegator, and either of two things satisfies that: a validUntil short enough that expiry alone bounds the exposure, or a status entry the verifier can check. A VDC MUST carry one where its validity period exceeds the freshness window the governing VTC or VTN defines for delegations, and MAY omit it otherwise.

That window is governance this library does not know, so it cannot decide for a caller which side of the condition a given VDC falls on — hence a setter rather than a constructor parameter. Prefer short validity and re-issuance wherever the delegator is reachable: a status check is a live lookup that reveals the verification event to whoever hosts the status list. A long-lived appointment made in advance of a delegator’s unavailability is the case this exists for.

§Set it before signing

Same caveat as DTGCredential::with_id — a Data Integrity proof covers the credential minus its proof, so attaching a status entry to an already-signed credential leaves a document whose proof no longer verifies.

§This library does not check it

Neither crate::delegation::verify_chain nor crate::authority::verify_chain resolves a status entry; both verify structure, scope and validity only. Revocation is a live lookup the caller performs.

§Security

The entry is embedded verbatim and nothing about it is checked when it is attached. It tells a verifier where to look, so a verifier must check the credential’s proof before following it, and should apply its own policy to where it leads. Nesting past crate::MAX_JSON_DEPTH is refused when the credential is validated, digested or signed, because this setter cannot return an error.

Source

pub fn set_credential_status(&mut self, status: Value)

Attaches a revocation status mechanism in place.

The non-consuming form of DTGCredential::with_credential_status; the same “before signing” caveat, the same CONDITIONAL rule and the same security notes apply.

Source§

impl DTGCredential

Source

pub fn credential(&self) -> &DTGCommon

get the raw credential

Source

pub fn credential_mut(&mut self) -> &mut DTGCommon

Get the raw credential as mutable

Source

pub fn signed(&self) -> bool

Has this credential been signed?

Source

pub fn type_(&self) -> DTGCredentialType

get the credential type

Source

pub fn id(&self) -> Option<&str>

This credential’s own identifier, if it has one.

None for a credential built by one of the new_* constructors and never given one with DTGCredential::with_id. See DTGCommon::id for why a counterparty may require it.

Source

pub fn issuer(&self) -> &str

Returns the Issuer DID

Source

pub fn subject(&self) -> &str

Returns the Subject DID

Source

pub fn valid_from(&self) -> DateTime<Utc>

Returns the valid_from timestamp

Source

pub fn valid_until(&self) -> Option<DateTime<Utc>>

Returns the valid until timestamp

Source

pub fn task_context(&self) -> Option<&str>

The id naming the trust task exchange this credential cites, if set. See DTGCommon::task_context.

This is always Some for DTGCredentialType::Witness credentials, where the spec makes taskContext REQUIRED.

Source

pub fn task_digest_multibase(&self) -> Option<&str>

The task digest of the Trust Task document taskContext names, if set. See DTGCommon::task_digest_multibase.

Source

pub fn cites_task(&self, document: &Value) -> Result<bool, DTGCredentialError>

Does this credential cite document — the Trust Task document its taskContext names — and is it bound to that document’s content?

Both halves of the citation have to hold:

  1. taskContext equals the document’s id, which locates the exchange;
  2. taskDigestMultibase matches the task digest recomputed from document, which binds the credential to it.

Returns Ok(false) where either fails, and where the credential carries no taskContext or no taskDigestMultibase. The last case is deliberate: Trust Tasks §4.9.3 forbids falling back to comparing ids alone, because an id is a name anyone may reuse on a counterfeit.

§Compares bytes, not strings

The digest is recomputed with the top-level proof removed, so a signed and an unsigned copy of the same document agree, and compared as decoded multihash bytes. A task digest may be base58btc or base64url: two conforming encodings of one digest are different strings, and a string comparison would reject an honest citation.

§What this does not check

That the exchange completed, which needs the outcome evidence of DTG Core Credentials §Outcome Interpretability, and that the document was attributable, which needs its own proof. A task digest attests content, not authenticity. It is load-bearing because it is the credential’s issuer who signed it.

§Errors

DTGCredentialError::InvalidDigest if the carried value is not a well-formed multibase multihash, and DTGCredentialError::UnsupportedDigestAlgorithm if it names a hash this library does not implement. Trust Tasks §4.9.3 requires such a citation to be treated as unverified, never recomputed under another algorithm, so it is reported rather than folded into Ok(false). DTGCredentialError::JsonTooDeep if document is nested past MAX_JSON_DEPTH.

Source

pub fn digest_multibase(&self) -> Result<String, DTGCredentialError>

This credential’s digest, in the encoding a credential that references it carries — a member-issued VMC acknowledging a membership grant, a VWC attesting an edge credential, or the parent of an attenuated VAC.

Per DTG Core Credentials Digest Encoding, that is the SHA-256 hash of the credential’s JSON representation excluding its top-level proof member, canonicalized with the JSON Canonicalization Scheme (JCS, RFC 8785), wrapped in a sha2-256 multihash and encoded base58btc with a multibase z prefix.

§Why proof is excluded

The digest binds to what the credential says, not to a particular signature over it. A referencing credential therefore survives a re-proofing of its referent: a re-signed grant carrying identical claims still satisfies an acknowledgement made against the earlier signature. It also means the digest can be computed before the referent is signed, and is stable whichever of its proofs a holder happens to have.

§Prefer the wire form for a credential you received

This digests the model. DTGCommon::extra carries top-level members this library does not model through a round trip, so for most received credentials the two agree — but a member inside credentialSubject that the subject types do not model is still not represented. Where you still hold the bytes a counterparty sent, digest those with digest_multibase_json.

§Errors

DTGCredentialError::JsonTooDeep if an open JSON member takes the credential past MAX_JSON_DEPTH, checked before the credential is cloned or serialized.

Source

pub fn digest(&self) -> Result<String, DTGCredentialError>

👎Deprecated since 0.7.0:

Working Draft 02 replaced the sha256:<hex> digest with a base58btc multibase multihash under the property name digestMultibase. Use DTGCredential::digest_multibase. This method will be removed in a future release.

This credential’s digest in the superseded sha256:<hex> encoding.

Source

pub fn subject_digest(&self) -> Option<&str>

The digest this credential carries of the credential it references, if it carries one.

Some for a member-issued VMC (which MUST carry one), for a VWC bound to the edge credential it attests, for an attenuated VAC (authority.parent), and for a derived or accepting VDC (delegation.parent / delegation.accepts). None for a community-issued VMC, which MUST omit it, and for a credential that references nothing.

Source

pub fn verify_digest( &self, referenced: &DTGCredential, ) -> Result<bool, DTGCredentialError>

Checks that the digest this credential carries matches the credential it claims to reference.

Answers one question only — whether the hashes agree. It does not check that the two credentials are of the types the reference requires, nor that their issuers and subjects line up. For a membership acknowledgement, DTGCredential::acknowledges checks all of that together and is what a verifier completing an edge should call.

§Compares bytes, not strings

The specification requires a verifier to decode the multibase envelope and the multihash inside it, and to compare the algorithm identifier and the raw digest — never the encoded strings. Two equal digests can be written differently, and a string comparison would report a mismatch where the credentials agree.

Returns Ok(false) if the digests do not match, or if this credential carries no digest, in which case there is nothing to rely on.

§Errors

DTGCredentialError::InvalidDigest if the carried value is not a well-formed digestMultibase — a Working Draft 01 sha256:<hex> value among them — and DTGCredentialError::UnsupportedDigestAlgorithm if it names a hash this library does not implement. Both are reported rather than folded into Ok(false): a digest that cannot be read is not a digest that disagrees.

Source

pub fn acknowledges( &self, grant: &DTGCredential, ) -> Result<bool, DTGCredentialError>

Does this member-issued VMC acknowledge grant, completing that membership edge?

A membership edge is complete only when both VMCs of the pair exist and are valid: the community-issued VMC that grants membership, and the member-issued VMC that acknowledges it. This checks everything that binds the two together:

  1. grant is a MembershipCredential carrying no digest — a community-issued grant
  2. self is a MembershipCredential carrying one — a member-issued acknowledgement
  3. the two name the same pair of parties, in mirrored roles: this credential’s issuer is the grant’s subject, and its subject is the grant’s issuer
  4. the digest matches the grant

Returns Ok(false) where any of those does not hold, rather than distinguishing them: a caller deciding whether an edge is complete has one decision to make, and every failing case answers it the same way.

§What this does not check

Neither credential’s proof, and neither validity window. Both are the caller’s to verify — proof verification needs a resolver this crate does not hold, and whether a window is current is a question about an instant the caller chooses. An edge is complete when both VMCs are valid as well as bound, and this covers only the binding.

§Security

Ok(true) is binding evidence, not membership. A pair binds whether or not anybody signed either half: an acknowledgement can be built against a grant the community never issued, and this accepts the two together. Before treating an edge as complete, verify the grant’s proof against the community’s key and the acknowledgement’s against the member’s — each made by a verification method of that credential’s issuer — and check both windows at the instant you care about. verify_grant_with_public_key, under the affinidi-signing feature, does that for the grant in its wire form.

Source

pub fn accepts(&self, grant: &DTGCredential) -> Result<bool, DTGCredentialError>

Does this delegate-issued VDC accept grant, completing that delegation edge?

A delegation edge is complete only when both VDCs exist and are valid: the delegator’s grant, and the delegate’s acceptance of it. This checks everything that binds the two together:

  1. grant is a DelegationCredential carrying scope and no accepts — a grant
  2. self is a DelegationCredential carrying accepts — an acceptance
  3. the two name the same pair of parties in mirrored roles: this credential’s issuer is the grant’s subject, and its subject is the grant’s issuer
  4. the accepts digest matches the grant

Returns Ok(false) where any of those does not hold, rather than distinguishing them: a caller deciding whether an edge is complete has one decision to make, and every failing case answers it the same way.

§What this does not check

Neither credential’s proof, neither validity window, and neither’s revocation status. Nor does it establish that the delegator may perform the act in question — that is a separate question, asked of the delegator at the time of the act, which a VDC moves but never answers. This covers the binding.

§Security

As with DTGCredential::acknowledges, Ok(true) is binding evidence only. Verify both proofs, each against a verification method of its own credential’s issuer, and both windows, before accepting anybody as acting under the delegation.

Source

pub fn proof_value(&self) -> Option<&str>

Returns the proof value if signed else None

Source

pub fn validate(&self) -> Result<(), DTGCredentialError>

Checks the invariants this library holds a credential to before putting a proof on it.

DTGCredential::sign calls this first, so this library never signs a credential that fails it, and DTGCredential::verify_proof_with_public_key calls it before examining a proof. The new_* constructors that return a plain Self have no way to refuse, so a credential built by one of them is checked here rather than there. If you sign with another backend, call this yourself before you do.

A validFrom in the past is accepted. Backdating is legitimate — re-issuing a credential with the date the original took effect is the usual case — so only the ordering of the two ends is checked, never either end against the clock.

Source

pub async fn sign( &mut self, signing_secret: &Secret, create_time: Option<DateTime<Utc>>, ) -> Result<DataIntegrityProof, DTGCredentialError>

Sign the credential using W3C Data Integrity Proof with JCS EdDSA 2022 signing_secret: The secret key to use to sign the credential create_time: Optional creation time for the proof, defaults to now if None

§Errors

Anything DTGCredential::validate refuses, before any signing is attempted.

Source

pub fn verify_proof_with_public_key( &self, public_key_bytes: &[u8], ) -> Result<(), DTGCredentialError>

Verify the credential if you already know the public key bytes otherwise use the affinidi_tdk:verify_data() method public_key_bytes: The public key bytes to use to verify the credential

§Errors

Anything DTGCredential::validate refuses, before the proof is examined: a credential this library would not have signed does not verify either.

Source

pub fn get_w3c_vc_version(&self) -> W3CVCVersion

Is this credential a W3C VC Version 1.1 or 2.0 credential?

Source

pub fn is_personhood_credential(&self) -> bool

returns true if this credential a personhood credential (PHC)

Trait Implementations§

Source§

impl Clone for DTGCredential

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for DTGCredential

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for DTGCredential

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Serialize for DTGCredential

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl TryFrom<DTGCommon> for DTGCredential

Post deserialize setup of a CredentialSubject and CredntialType

Source§

type Error = DTGCredentialError

The type returned in the event of a conversion error.
Source§

fn try_from(value: DTGCommon) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more