Documentation ¶
Overview ¶
Package verifiable implements Verifiable Credential and Presentation data model (https://www.w3.org/TR/vc-data-model). It provides the data structures and functions which allow to process the Verifiable documents on different sides and levels. For example, an Issuer can create verifiable.Credential structure and issue it to a Holder in JWS form. The Holder can decode received Credential and make sure the signature is valid. The Holder can present the Credential to the Verifier or combine one or more Credentials into a Verifiable Presentation. The Verifier can decode and verify the received Credentials and Presentations.
Index ¶
- func CachingJSONLDLoader() *ld.CachingDocumentLoader
- func CreateCustomCredential(vcData []byte, producers []CustomCredentialProducer, opts ...CredentialOpt) (interface{}, error)
- type Credential
- type CredentialDecoder
- type CredentialOpt
- func WithBaseContextExtendedValidation(customContexts, customTypes []string) CredentialOpt
- func WithBaseContextValidation() CredentialOpt
- func WithCredentialSchemaLoader(loader *CredentialSchemaLoader) CredentialOpt
- func WithEmbeddedSignatureSuites(suites ...verifierSignatureSuite) CredentialOpt
- func WithJSONLDDocumentLoader(documentLoader ld.DocumentLoader) CredentialOpt
- func WithJSONLDValidation() CredentialOpt
- func WithNoCustomSchemaCheck() CredentialOpt
- func WithPublicKeyFetcher(fetcher PublicKeyFetcher) CredentialOpt
- func WithStrictValidation() CredentialOpt
- type CredentialSchemaLoader
- type CredentialSchemaLoaderBuilder
- func (b *CredentialSchemaLoaderBuilder) Build() *CredentialSchemaLoader
- func (b *CredentialSchemaLoaderBuilder) SetCache(cache SchemaCache) *CredentialSchemaLoaderBuilder
- func (b *CredentialSchemaLoaderBuilder) SetJSONLoader(loader gojsonschema.JSONLoader) *CredentialSchemaLoaderBuilder
- func (b *CredentialSchemaLoaderBuilder) SetSchemaDownloadClient(client *http.Client) *CredentialSchemaLoaderBuilder
- type CredentialTemplate
- type CustomCredentialProducer
- type CustomFields
- type Evidence
- type ExpirableSchemaCache
- type Issuer
- type JWSAlgorithm
- type JWTCredClaims
- type JWTCredClaimsUnmarshaller
- type JWTPresClaims
- type JWTPresClaimsUnmarshaller
- type LinkedDataProofContext
- type MarshalledCredential
- type Presentation
- func (vp *Presentation) AddLinkedDataProof(context *LinkedDataProofContext) error
- func (vp *Presentation) Credentials() []interface{}
- func (vp *Presentation) JWTClaims(audience []string, minimizeVP bool) (*JWTPresClaims, error)
- func (vp *Presentation) MarshalJSON() ([]byte, error)
- func (vp *Presentation) MarshalledCredentials() ([]MarshalledCredential, error)
- func (vp *Presentation) SetCredentials(creds ...interface{}) error
- type PresentationOpt
- type Proof
- type PublicKeyFetcher
- type SchemaCache
- type Subject
- type TypedID
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CachingJSONLDLoader ¶ added in v0.1.1
func CachingJSONLDLoader() *ld.CachingDocumentLoader
CachingJSONLDLoader creates JSON_LD CachingDocumentLoader with preloaded base JSON-LD document.
func CreateCustomCredential ¶ added in v0.1.1
func CreateCustomCredential( vcData []byte, producers []CustomCredentialProducer, opts ...CredentialOpt) (interface{}, error)
CreateCustomCredential creates custom extended credentials from bytes which could be marshalled JSON or serialized JWT. It decodes input bytes to the base Verifiable Credential using NewCredential(). It then checks all producers to find the appropriate which is capable of building extended Credential data model. If none of producers accept the credential, the base credential is returned.
Types ¶
type Credential ¶
type Credential struct { Context []string CustomContext []interface{} ID string Types []string Subject Subject Issuer Issuer Issued *time.Time Expired *time.Time Proofs []Proof Status *TypedID Schemas []TypedID Evidence *Evidence TermsOfUse []TypedID RefreshService []TypedID CustomFields CustomFields }
Credential Verifiable Credential definition
Example (Embedding) ¶
package main import ( "crypto/ed25519" "encoding/json" "fmt" "time" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) type UniversityDegree struct { Type string `json:"type,omitempty"` University string `json:"university,omitempty"` } type UniversityDegreeSubject struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Spouse string `json:"spouse,omitempty"` Degree UniversityDegree `json:"degree,omitempty"` } type UniversityDegreeCredential struct { *verifiable.Credential ReferenceNumber int `json:"referenceNumber,omitempty"` } func (udc *UniversityDegreeCredential) MarshalJSON() ([]byte, error) { c := udc.Credential cp := *c cp.CustomFields = map[string]interface{}{ "referenceNumber": udc.ReferenceNumber, } return json.Marshal(&cp) } //nolint:gochecknoglobals var ( privIssuerKey = ed25519.PrivateKey{56, 237, 176, 143, 247, 162, 167, 111, 85, 161, 158, 14, 243, 173, 144, 51, 157, 109, 155, 228, 77, 170, 238, 85, 220, 144, 158, 51, 14, 40, 153, 141, 193, 179, 12, 234, 125, 193, 60, 56, 198, 150, 80, 93, 30, 58, 14, 152, 205, 6, 50, 98, 125, 212, 65, 17, 15, 11, 230, 3, 226, 187, 7, 89} issued = time.Date(2010, time.January, 1, 19, 23, 24, 0, time.UTC) expired = time.Date(2020, time.January, 1, 19, 23, 24, 0, time.UTC) ) func main() { vc := &UniversityDegreeCredential{ Credential: &verifiable.Credential{ Context: []string{ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"}, ID: "http://example.edu/credentials/1872", Types: []string{ "VerifiableCredential", "UniversityDegreeCredential"}, Subject: UniversityDegreeSubject{ ID: "did:example:ebfeb1f712ebc6f1c276e12ec21", Name: "Jayden Doe", Spouse: "did:example:c276e12ec21ebfeb1f712ebc6f1", Degree: UniversityDegree{ Type: "BachelorDegree", University: "MIT", }, }, Issuer: verifiable.Issuer{ ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", Name: "Example University", }, Issued: &issued, Expired: &expired, Schemas: []verifiable.TypedID{}, }, ReferenceNumber: 83294847, } // Marshal to JSON to verify the result of decoding. vcBytes, err := json.Marshal(vc) if err != nil { fmt.Println("failed to marshal VC to JSON") } fmt.Println(string(vcBytes)) // Marshal to JWS. jwtClaims, err := vc.JWTClaims(true) if err != nil { fmt.Println(fmt.Errorf("failed to marshal JWT claims of VC: %w", err)) } jws, err := jwtClaims.MarshalJWS(verifiable.EdDSA, privIssuerKey, "") if err != nil { fmt.Println(fmt.Errorf("failed to sign VC inside JWT: %w", err)) } fmt.Println(jws) // Decode JWS and make sure it's coincide with JSON. _, vcBytesFromJWS, err := verifiable.NewCredential( []byte(jws), verifiable.WithPublicKeyFetcher(verifiable.SingleKey(privIssuerKey.Public()))) if err != nil { fmt.Println(fmt.Errorf("failed to encode VC from JWS: %w", err)) } fmt.Println(string(vcBytesFromJWS)) // todo missing referenceNumber here (https://github.com/hyperledger/aries-framework-go/issues/847) }
Output: {"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"credentialSchema":[],"credentialSubject":{"degree":{"type":"BachelorDegree","university":"MIT"},"id":"did:example:ebfeb1f712ebc6f1c276e12ec21","name":"Jayden Doe","spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1"},"expirationDate":"2020-01-01T19:23:24Z","id":"http://example.edu/credentials/1872","issuanceDate":"2010-01-01T19:23:24Z","issuer":{"id":"did:example:76e12ec712ebc6f1c221ebfeb1f","name":"Example University"},"referenceNumber":83294847,"type":["VerifiableCredential","UniversityDegreeCredential"]} eyJhbGciOiJFZERTQSIsImtpZCI6IiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzc5MDY2MDQsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiXSwiY3JlZGVudGlhbFNjaGVtYSI6W10sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImRlZ3JlZSI6eyJ0eXBlIjoiQmFjaGVsb3JEZWdyZWUiLCJ1bml2ZXJzaXR5IjoiTUlUIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiaXNzdWVyIjp7Im5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ.AHn2A2q5DL1heX3_izq_2yrsBDhoZ6BGGKhoRvhfMnMUuuOnBOdekdTg-dfUMJgipXRql_6WzBUIj4wTFehXCw {"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"credentialSchema":[],"credentialSubject":{"degree":{"type":"BachelorDegree","university":"MIT"},"id":"did:example:ebfeb1f712ebc6f1c276e12ec21","name":"Jayden Doe","spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1"},"expirationDate":"2020-01-01T19:23:24Z","id":"http://example.edu/credentials/1872","issuanceDate":"2010-01-01T19:23:24Z","issuer":{"id":"did:example:76e12ec712ebc6f1c221ebfeb1f","name":"Example University"},"type":["VerifiableCredential","UniversityDegreeCredential"]}
Example (ExtraFields) ¶
package main import ( "crypto/ed25519" "encoding/json" "fmt" "time" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) type UniversityDegree struct { Type string `json:"type,omitempty"` University string `json:"university,omitempty"` } type UniversityDegreeSubject struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Spouse string `json:"spouse,omitempty"` Degree UniversityDegree `json:"degree,omitempty"` } //nolint:gochecknoglobals var ( privIssuerKey = ed25519.PrivateKey{56, 237, 176, 143, 247, 162, 167, 111, 85, 161, 158, 14, 243, 173, 144, 51, 157, 109, 155, 228, 77, 170, 238, 85, 220, 144, 158, 51, 14, 40, 153, 141, 193, 179, 12, 234, 125, 193, 60, 56, 198, 150, 80, 93, 30, 58, 14, 152, 205, 6, 50, 98, 125, 212, 65, 17, 15, 11, 230, 3, 226, 187, 7, 89} issued = time.Date(2010, time.January, 1, 19, 23, 24, 0, time.UTC) expired = time.Date(2020, time.January, 1, 19, 23, 24, 0, time.UTC) ) func main() { vc := &verifiable.Credential{ Context: []string{ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"}, ID: "http://example.edu/credentials/1872", Types: []string{ "VerifiableCredential", "UniversityDegreeCredential"}, Subject: UniversityDegreeSubject{ ID: "did:example:ebfeb1f712ebc6f1c276e12ec21", Name: "Jayden Doe", Spouse: "did:example:c276e12ec21ebfeb1f712ebc6f1", Degree: UniversityDegree{ Type: "BachelorDegree", University: "MIT", }, }, Issuer: verifiable.Issuer{ ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", Name: "Example University", }, Issued: &issued, Expired: &expired, Schemas: []verifiable.TypedID{}, CustomFields: map[string]interface{}{ "referenceNumber": 83294847, }, } // Marshal to JSON. vcBytes, err := json.Marshal(vc) if err != nil { fmt.Println("failed to marshal VC to JSON") } fmt.Println(string(vcBytes)) // Marshal to JWS. jwtClaims, err := vc.JWTClaims(true) if err != nil { fmt.Println(fmt.Errorf("failed to marshal JWT claims of VC: %w", err)) } jws, err := jwtClaims.MarshalJWS(verifiable.EdDSA, privIssuerKey, "") if err != nil { fmt.Println(fmt.Errorf("failed to sign VC inside JWT: %w", err)) } fmt.Println(jws) // Decode JWS and make sure it's coincide with JSON. _, vcBytesFromJWS, err := verifiable.NewCredential( []byte(jws), verifiable.WithPublicKeyFetcher(verifiable.SingleKey(privIssuerKey.Public()))) if err != nil { fmt.Println(fmt.Errorf("failed to encode VC from JWS: %w", err)) } fmt.Println(string(vcBytesFromJWS)) }
Output: {"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"credentialSchema":[],"credentialSubject":{"degree":{"type":"BachelorDegree","university":"MIT"},"id":"did:example:ebfeb1f712ebc6f1c276e12ec21","name":"Jayden Doe","spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1"},"expirationDate":"2020-01-01T19:23:24Z","id":"http://example.edu/credentials/1872","issuanceDate":"2010-01-01T19:23:24Z","issuer":{"id":"did:example:76e12ec712ebc6f1c221ebfeb1f","name":"Example University"},"referenceNumber":83294847,"type":["VerifiableCredential","UniversityDegreeCredential"]} eyJhbGciOiJFZERTQSIsImtpZCI6IiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzc5MDY2MDQsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiXSwiY3JlZGVudGlhbFNjaGVtYSI6W10sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImRlZ3JlZSI6eyJ0eXBlIjoiQmFjaGVsb3JEZWdyZWUiLCJ1bml2ZXJzaXR5IjoiTUlUIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiaXNzdWVyIjp7Im5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwicmVmZXJlbmNlTnVtYmVyIjo4LjMyOTQ4NDdlKzA3LCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXX19.auzCDgrk2TOK9BQFZHVI4p5bX1EI3CEfFNjXneC0r5fV5JE9jHY7WAIuRgKoFhNnadLKHdIekED_NrnlOEa0BA {"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"credentialSchema":[],"credentialSubject":{"degree":{"type":"BachelorDegree","university":"MIT"},"id":"did:example:ebfeb1f712ebc6f1c276e12ec21","name":"Jayden Doe","spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1"},"expirationDate":"2020-01-01T19:23:24Z","id":"http://example.edu/credentials/1872","issuanceDate":"2010-01-01T19:23:24Z","issuer":{"id":"did:example:76e12ec712ebc6f1c221ebfeb1f","name":"Example University"},"referenceNumber":83294847,"type":["VerifiableCredential","UniversityDegreeCredential"]}
func NewCredential ¶
func NewCredential(vcData []byte, opts ...CredentialOpt) (*Credential, []byte, error)
NewCredential decodes Verifiable Credential from bytes which could be marshalled JSON or serialized JWT. It also applies miscellaneous options like settings of schema validation. It returns decoded Credential and its marshalled JSON. For JSON bytes input, the output marshalled JSON is the same value. For serialized JWT input, the output is the result of decoding `vc` claim from JWT. The output Credential and marshalled JSON can be used for extensions of the base data model by checking CustomFields of Credential and/or unmarshalling the JSON to custom date structure.
Example ¶
package main import ( "crypto/ed25519" "fmt" "time" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) type UniversityDegree struct { Type string `json:"type,omitempty"` University string `json:"university,omitempty"` } type UniversityDegreeSubject struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Spouse string `json:"spouse,omitempty"` Degree UniversityDegree `json:"degree,omitempty"` } //nolint:gochecknoglobals var ( privIssuerKey = ed25519.PrivateKey{56, 237, 176, 143, 247, 162, 167, 111, 85, 161, 158, 14, 243, 173, 144, 51, 157, 109, 155, 228, 77, 170, 238, 85, 220, 144, 158, 51, 14, 40, 153, 141, 193, 179, 12, 234, 125, 193, 60, 56, 198, 150, 80, 93, 30, 58, 14, 152, 205, 6, 50, 98, 125, 212, 65, 17, 15, 11, 230, 3, 226, 187, 7, 89} issued = time.Date(2010, time.January, 1, 19, 23, 24, 0, time.UTC) expired = time.Date(2020, time.January, 1, 19, 23, 24, 0, time.UTC) ) func main() { // Issuer is about to issue the university degree credential for the Holder vcEncoded := &verifiable.Credential{ Context: []string{ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"}, ID: "http://example.edu/credentials/1872", Types: []string{ "VerifiableCredential", "UniversityDegreeCredential"}, Subject: UniversityDegreeSubject{ ID: "did:example:ebfeb1f712ebc6f1c276e12ec21", Name: "Jayden Doe", Spouse: "did:example:c276e12ec21ebfeb1f712ebc6f1", Degree: UniversityDegree{ Type: "BachelorDegree", University: "MIT", }, }, Issuer: verifiable.Issuer{ ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", Name: "Example University", }, Issued: &issued, Expired: &expired, Schemas: []verifiable.TypedID{}, CustomFields: map[string]interface{}{ "referenceNumber": 83294847, }, } // ... in JWS form. jwtClaims, err := vcEncoded.JWTClaims(true) if err != nil { fmt.Println(fmt.Errorf("failed to marshal JWT claims of VC: %w", err)) } jws, err := jwtClaims.MarshalJWS(verifiable.EdDSA, privIssuerKey, "") if err != nil { fmt.Println(fmt.Errorf("failed to sign VC inside JWT: %w", err)) } // The Holder receives JWS and decodes it. _, vcDecodedBytes, err := verifiable.NewCredential( []byte(jws), verifiable.WithPublicKeyFetcher(verifiable.SingleKey(privIssuerKey.Public()))) if err != nil { fmt.Println(fmt.Errorf("failed to decode VC JWS: %w", err)) } fmt.Println(string(vcDecodedBytes)) // The Holder then e.g. can save the credential to her personal verifiable credential wallet. }
Output: {"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"credentialSchema":[],"credentialSubject":{"degree":{"type":"BachelorDegree","university":"MIT"},"id":"did:example:ebfeb1f712ebc6f1c276e12ec21","name":"Jayden Doe","spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1"},"expirationDate":"2020-01-01T19:23:24Z","id":"http://example.edu/credentials/1872","issuanceDate":"2010-01-01T19:23:24Z","issuer":{"id":"did:example:76e12ec712ebc6f1c221ebfeb1f","name":"Example University"},"referenceNumber":83294847,"type":["VerifiableCredential","UniversityDegreeCredential"]}
func (*Credential) AddLinkedDataProof ¶ added in v0.1.1
func (vc *Credential) AddLinkedDataProof(context *LinkedDataProofContext) error
AddLinkedDataProof appends proof to the Verifiable Credential.
Example ¶
package main import ( "crypto/ed25519" "encoding/json" "fmt" "time" "github.com/hyperledger/aries-framework-go/pkg/doc/signature/ed25519signature2018" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) //nolint:gochecknoglobals var ( privIssuerKey = ed25519.PrivateKey{56, 237, 176, 143, 247, 162, 167, 111, 85, 161, 158, 14, 243, 173, 144, 51, 157, 109, 155, 228, 77, 170, 238, 85, 220, 144, 158, 51, 14, 40, 153, 141, 193, 179, 12, 234, 125, 193, 60, 56, 198, 150, 80, 93, 30, 58, 14, 152, 205, 6, 50, 98, 125, 212, 65, 17, 15, 11, 230, 3, 226, 187, 7, 89} issued = time.Date(2010, time.January, 1, 19, 23, 24, 0, time.UTC) ) func main() { vcJSON := ` { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2009-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "referenceNumber": 83294849, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] } ` vc, _, err := verifiable.NewCredential([]byte(vcJSON)) if err != nil { fmt.Println(fmt.Errorf("failed to decode VC JSON: %w", err)) } err = vc.AddLinkedDataProof(&verifiable.LinkedDataProofContext{ Created: &issued, Creator: "Example University", SignatureType: "Ed25519Signature2018", Suite: ed25519signature2018.New(), PrivateKey: privIssuerKey, }) if err != nil { fmt.Println(fmt.Errorf("failed to add linked data proof: %w", err)) } vcJSONWithProof, err := json.MarshalIndent(vc, "", "\t") if err != nil { fmt.Println(fmt.Errorf("failed to marshal VC to JSON: %w", err)) } fmt.Println(string(vcJSONWithProof)) }
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2009-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "proof": { "created": "2010-01-01T19:23:24Z", "creator": "Example University", "domain": "", "nonce": "", "proofValue": "IHtZUp8KQ0l_HMIpbjgPakSgCKZ0rimcwv0o8yi4YBxcdgk7khAwW0aeX2AkBLWZaL_ce142h1zOqdjI-tQLBg", "type": "Ed25519Signature2018" }, "referenceNumber": 83294849, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] }
func (*Credential) JWTClaims ¶
func (vc *Credential) JWTClaims(minimizeVC bool) (*JWTCredClaims, error)
JWTClaims converts Verifiable Credential into JWT Credential claims, which can be than serialized e.g. into JWS.
Example ¶
package main import ( "crypto/ed25519" "fmt" "time" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) //nolint:gochecknoglobals var privIssuerKey = ed25519.PrivateKey{56, 237, 176, 143, 247, 162, 167, 111, 85, 161, 158, 14, 243, 173, 144, 51, 157, 109, 155, 228, 77, 170, 238, 85, 220, 144, 158, 51, 14, 40, 153, 141, 193, 179, 12, 234, 125, 193, 60, 56, 198, 150, 80, 93, 30, 58, 14, 152, 205, 6, 50, 98, 125, 212, 65, 17, 15, 11, 230, 3, 226, 187, 7, 89} func main() { // The Holder kept the credential serialized to JSON in her personal verifiable credential wallet. vcStrFromWallet := ` { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2010-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "referenceNumber": 83294847, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] } ` // The Holder wants to send the credential to the Verifier in JWS. vc, _, err := verifiable.NewCredential([]byte(vcStrFromWallet)) if err != nil { fmt.Println(fmt.Errorf("failed to decode VC JSON: %w", err)) } jwtClaims, err := vc.JWTClaims(true) if err != nil { fmt.Println(fmt.Errorf("failed to marshal JWT claims of VC: %w", err)) } jws, err := jwtClaims.MarshalJWS(verifiable.EdDSA, privIssuerKey, "") if err != nil { fmt.Println(fmt.Errorf("failed to sign VC inside JWT: %w", err)) } // The Holder passes JWS to Verifier fmt.Println(jws) //nolint
Output:
func (*Credential) MarshalJSON ¶
func (vc *Credential) MarshalJSON() ([]byte, error)
MarshalJSON converts Verifiable Credential to JSON bytes
func (*Credential) Presentation ¶ added in v0.1.1
func (vc *Credential) Presentation() (*Presentation, error)
Presentation encloses credential into presentation.
Example ¶
package main import ( "crypto/ed25519" "fmt" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) // Private key generated by ed25519.GenerateKey(rand.Reader) // //nolint:gochecknoglobals var privHolderKey = ed25519.PrivateKey{137, 207, 34, 115, 168, 80, 44, 145, 236, 206, 165, 152, 211, 195, 240, 205, 232, 37, 216, 101, 58, 133, 198, 107, 232, 119, 30, 80, 176, 137, 10, 251, 109, 144, 158, 93, 189, 195, 0, 24, 15, 29, 166, 185, 169, 69, 246, 25, 182, 179, 115, 54, 107, 4, 123, 30, 5, 88, 175, 94, 109, 15, 34, 113} func main() { // A Holder loads the credential from verifiable credential wallet in order to send to Verifier. // She embedded the credential into presentation and sends it to the Verifier in JWS form. vcStrFromWallet := ` { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2010-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "referenceNumber": 83294847, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] } ` vc, _, err := verifiable.NewCredential([]byte(vcStrFromWallet)) if err != nil { fmt.Println(fmt.Errorf("failed to decode VC JSON: %w", err)) } vp, err := vc.Presentation() if err != nil { fmt.Println(fmt.Errorf("failed to build VP from VC: %w", err)) } vp.ID = "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5" vp.Holder = "did:example:ebfeb1f712ebc6f1c276e12ec21" aud := []string{"did:example:4a57546973436f6f6c4a4a57573"} jwtClaims, err := vp.JWTClaims(aud, true) if err != nil { fmt.Println(fmt.Errorf("failed to create JWT claims of VP: %w", err)) } jws, err := jwtClaims.MarshalJWS(verifiable.EdDSA, privHolderKey, "") if err != nil { fmt.Println(fmt.Errorf("failed to sign VP inside JWT: %w", err)) } fmt.Println(jws) //nolint
Output:
type CredentialDecoder ¶
type CredentialDecoder func(dataJSON []byte, vc *Credential) error
CredentialDecoder makes a custom decoding of Verifiable Credential in JSON form to existent instance of Credential.
type CredentialOpt ¶
type CredentialOpt func(opts *credentialOpts)
CredentialOpt is the Verifiable Credential decoding option
func WithBaseContextExtendedValidation ¶ added in v0.1.1
func WithBaseContextExtendedValidation(customContexts, customTypes []string) CredentialOpt
WithBaseContextExtendedValidation validates that fields that are specified in base context are as specified. Additional fields are allowed
func WithBaseContextValidation ¶ added in v0.1.1
func WithBaseContextValidation() CredentialOpt
WithBaseContextValidation validates that only the fields and values (when applicable) are present in the document. No extra fields are allowed (outside of credentialSubject).
func WithCredentialSchemaLoader ¶ added in v0.1.1
func WithCredentialSchemaLoader(loader *CredentialSchemaLoader) CredentialOpt
WithCredentialSchemaLoader option is used to define custom credentials schema loader. If not defined, the default one is created with default HTTP client to download the schema and no caching of the schemas.
func WithEmbeddedSignatureSuites ¶ added in v0.1.1
func WithEmbeddedSignatureSuites(suites ...verifierSignatureSuite) CredentialOpt
WithEmbeddedSignatureSuites defines the suites which are used to check embedded linked data proof of VC.
func WithJSONLDDocumentLoader ¶ added in v0.1.1
func WithJSONLDDocumentLoader(documentLoader ld.DocumentLoader) CredentialOpt
WithJSONLDDocumentLoader defines custom JSON-LD document loader. If not defined, when decoding VC a new document loader will be created using CachingJSONLDLoader() if JSON-LD validation is made.
func WithJSONLDValidation ¶ added in v0.1.1
func WithJSONLDValidation() CredentialOpt
WithJSONLDValidation uses the JSON LD parser for validation.
func WithNoCustomSchemaCheck ¶
func WithNoCustomSchemaCheck() CredentialOpt
WithNoCustomSchemaCheck option is for disabling of Credential Schemas download if defined in Verifiable Credential. Instead, the Verifiable Credential is checked against default Schema.
func WithPublicKeyFetcher ¶
func WithPublicKeyFetcher(fetcher PublicKeyFetcher) CredentialOpt
WithPublicKeyFetcher set public key fetcher used when decoding from JWS.
func WithStrictValidation ¶ added in v0.1.1
func WithStrictValidation() CredentialOpt
WithStrictValidation enabled strict validation of VC.
In case of JSON Schema validation, additionalProperties=true is set on the schema.
In case of JSON-LD validation, the comparison of JSON-LD VC document after compaction with original VC one is made. In case when any field (root one or inside credentialSubject) not defined in any JSON-LD schema is present the validation exception is raised.
type CredentialSchemaLoader ¶ added in v0.1.1
type CredentialSchemaLoader struct {
// contains filtered or unexported fields
}
CredentialSchemaLoader defines expirable cache.
type CredentialSchemaLoaderBuilder ¶ added in v0.1.1
type CredentialSchemaLoaderBuilder struct {
// contains filtered or unexported fields
}
CredentialSchemaLoaderBuilder defines a builder of CredentialSchemaLoader.
func NewCredentialSchemaLoaderBuilder ¶ added in v0.1.1
func NewCredentialSchemaLoaderBuilder() *CredentialSchemaLoaderBuilder
NewCredentialSchemaLoaderBuilder creates a new instance of CredentialSchemaLoaderBuilder.
func (*CredentialSchemaLoaderBuilder) Build ¶ added in v0.1.1
func (b *CredentialSchemaLoaderBuilder) Build() *CredentialSchemaLoader
Build constructed CredentialSchemaLoader. It creates default HTTP client and JSON schema loader if not defined.
func (*CredentialSchemaLoaderBuilder) SetCache ¶ added in v0.1.1
func (b *CredentialSchemaLoaderBuilder) SetCache(cache SchemaCache) *CredentialSchemaLoaderBuilder
SetCache defines SchemaCache.
func (*CredentialSchemaLoaderBuilder) SetJSONLoader ¶ added in v0.1.1
func (b *CredentialSchemaLoaderBuilder) SetJSONLoader(loader gojsonschema.JSONLoader) *CredentialSchemaLoaderBuilder
SetJSONLoader defines gojsonschema.JSONLoader
func (*CredentialSchemaLoaderBuilder) SetSchemaDownloadClient ¶ added in v0.1.1
func (b *CredentialSchemaLoaderBuilder) SetSchemaDownloadClient(client *http.Client) *CredentialSchemaLoaderBuilder
SetSchemaDownloadClient sets HTTP client to be used to download the schema.
type CredentialTemplate ¶
type CredentialTemplate func() *Credential
CredentialTemplate defines a factory method to create new Credential template.
type CustomCredentialProducer ¶ added in v0.1.1
type CustomCredentialProducer interface { // Accept checks if producer is capable of building extended Credential data model. Accept(vc *Credential) bool // Apply creates custom credential using base credential and its JSON bytes. Apply(vc *Credential, dataJSON []byte) (interface{}, error) }
CustomCredentialProducer is a factory for Credentials with extended data model.
type CustomFields ¶ added in v0.1.1
type CustomFields map[string]interface{}
CustomFields is a map of extra fields of struct build when unmarshalling JSON which are not mapped to the struct fields.
type ExpirableSchemaCache ¶ added in v0.1.1
type ExpirableSchemaCache struct {
// contains filtered or unexported fields
}
ExpirableSchemaCache is an implementation of SchemaCache based fastcache.Cache with expirable elements.
func NewExpirableSchemaCache ¶ added in v0.1.1
func NewExpirableSchemaCache(size int, expiration time.Duration) *ExpirableSchemaCache
NewExpirableSchemaCache creates new instance of ExpirableSchemaCache.
func (*ExpirableSchemaCache) Get ¶ added in v0.1.1
func (sc *ExpirableSchemaCache) Get(k string) ([]byte, bool)
Get element from the cache. If element is present, it checks if the element is expired. If yes, it clears the element from the cache and indicates that the key is not found.
func (*ExpirableSchemaCache) Put ¶ added in v0.1.1
func (sc *ExpirableSchemaCache) Put(k string, v []byte)
Put element to the cache. It also adds a mark of when the element will expire.
type JWSAlgorithm ¶
type JWSAlgorithm int
JWSAlgorithm defines JWT signature algorithms of Verifiable Credential
const ( // RS256 JWT Algorithm RS256 JWSAlgorithm = iota // EdDSA JWT Algorithm EdDSA )
type JWTCredClaims ¶
JWTCredClaims is JWT Claims extension by Verifiable Credential (with custom "vc" claim).
func (*JWTCredClaims) MarshalJWS ¶
func (jcc *JWTCredClaims) MarshalJWS(signatureAlg JWSAlgorithm, privateKey interface{}, keyID string) (string, error)
MarshalJWS serializes JWT into signed form (JWS) todo refactor, do not pass privateKey (https://github.com/hyperledger/aries-framework-go/issues/339)
func (*JWTCredClaims) MarshalUnsecuredJWT ¶
func (jcc *JWTCredClaims) MarshalUnsecuredJWT() (string, error)
MarshalUnsecuredJWT serialized JWT into unsecured JWT.
type JWTCredClaimsUnmarshaller ¶
type JWTCredClaimsUnmarshaller func(vcJWTBytes []byte) (*JWTCredClaims, error)
JWTCredClaimsUnmarshaller unmarshals verifiable credential bytes into JWT claims with extra "vc" claim.
type JWTPresClaims ¶
JWTPresClaims is JWT Claims extension by Verifiable Presentation (with custom "vp" claim).
func (*JWTPresClaims) MarshalJWS ¶
func (jpc *JWTPresClaims) MarshalJWS(signatureAlg JWSAlgorithm, privateKey interface{}, keyID string) (string, error)
MarshalJWS serializes JWT presentation claims into signed form (JWS) todo refactor, do not pass privateKey (https://github.com/hyperledger/aries-framework-go/issues/339)
func (*JWTPresClaims) MarshalUnsecuredJWT ¶
func (jpc *JWTPresClaims) MarshalUnsecuredJWT() (string, error)
MarshalUnsecuredJWT serializes JWT presentation claims into unsecured JWT.
type JWTPresClaimsUnmarshaller ¶
type JWTPresClaimsUnmarshaller func(vpJWTBytes []byte) (*JWTPresClaims, error)
JWTPresClaimsUnmarshaller parses JWT of certain type to JWT Claims containing "vp" (Presentation) claim.
type LinkedDataProofContext ¶ added in v0.1.1
type LinkedDataProofContext struct { SignatureType string // required Suite signerSignatureSuite // required PrivateKey []byte // required Creator string // required Created *time.Time // optional }
LinkedDataProofContext holds options needed to build a Linked Data Proof. todo refactor, do not pass privateKey (https://github.com/hyperledger/aries-framework-go/issues/339)
type MarshalledCredential ¶ added in v0.1.1
type MarshalledCredential []byte
MarshalledCredential defines marshalled Verifiable Credential enclosed into Presentation. MarshalledCredential can be passed to verifiable.NewCredential().
type Presentation ¶
type Presentation struct { Context []string CustomContext []interface{} ID string Type []string Holder string Proofs []Proof RefreshService *TypedID // contains filtered or unexported fields }
Presentation Verifiable Presentation base data model definition
func NewPresentation ¶
func NewPresentation(vpData []byte, opts ...PresentationOpt) (*Presentation, error)
NewPresentation creates an instance of Verifiable Presentation by reading a JSON document from bytes. It also applies miscellaneous options like custom decoders or settings of schema validation.
Example ¶
package main import ( "crypto/ed25519" "encoding/json" "fmt" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) // Private key generated by ed25519.GenerateKey(rand.Reader) // //nolint:gochecknoglobals var privHolderKey = ed25519.PrivateKey{137, 207, 34, 115, 168, 80, 44, 145, 236, 206, 165, 152, 211, 195, 240, 205, 232, 37, 216, 101, 58, 133, 198, 107, 232, 119, 30, 80, 176, 137, 10, 251, 109, 144, 158, 93, 189, 195, 0, 24, 15, 29, 166, 185, 169, 69, 246, 25, 182, 179, 115, 54, 107, 4, 123, 30, 5, 88, 175, 94, 109, 15, 34, 113} func main() { // A Holder sends to the Verifier a verifiable presentation in JWS form. vpJWS := "eyJhbGciOiJFZERTQSIsImtpZCI6IiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJkaWQ6ZXhhbXBsZTo0YTU3NTQ2OTczNDM2ZjZmNmM0YTRhNTc1NzMiLCJpc3MiOiJkaWQ6ZXhhbXBsZTplYmZlYjFmNzEyZWJjNmYxYzI3NmUxMmVjMjEiLCJqdGkiOiJ1cm46dXVpZDozOTc4MzQ0Zi04NTk2LTRjM2EtYTk3OC04ZmNhYmEzOTAzYzUiLCJ2cCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl0sInZlcmlmaWFibGVDcmVkZW50aWFsIjpbeyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImNyZWRlbnRpYWxTY2hlbWEiOltdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwidW5pdmVyc2l0eSI6Ik1JVCJ9LCJpZCI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsIm5hbWUiOiJKYXlkZW4gRG9lIiwic3BvdXNlIjoiZGlkOmV4YW1wbGU6YzI3NmUxMmVjMjFlYmZlYjFmNzEyZWJjNmYxIn0sImV4cGlyYXRpb25EYXRlIjoiMjAyMC0wMS0wMVQxOToyMzoyNFoiLCJpZCI6Imh0dHA6Ly9leGFtcGxlLmVkdS9jcmVkZW50aWFscy8xODcyIiwiaXNzdWFuY2VEYXRlIjoiMjAxMC0wMS0wMVQxOToyMzoyNFoiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6ZXhhbXBsZTo3NmUxMmVjNzEyZWJjNmYxYzIyMWViZmViMWYiLCJuYW1lIjoiRXhhbXBsZSBVbml2ZXJzaXR5In0sInJlZmVyZW5jZU51bWJlciI6ODMyOTQ4NDcsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVbml2ZXJzaXR5RGVncmVlQ3JlZGVudGlhbCJdfV19fQ.F6-OoI27Q5d82ZR32uXxAXYH15QxhzrwCTZIJnwF7ABhXXUA73PmxxnFuXr-5keXpCzXPxtzHsRv0AKUWW_iAA" //nolint:lll // Holder received and decodes it. vp, err := verifiable.NewPresentation( []byte(vpJWS), verifiable.WithPresPublicKeyFetcher(verifiable.SingleKey(privHolderKey.Public()))) if err != nil { fmt.Println(fmt.Errorf("failed to decode VP JWS: %w", err)) } // Marshal the VP to JSON to verify the result of decoding. vpBytes, err := json.Marshal(vp) if err != nil { fmt.Println(fmt.Errorf("failed to marshal VP to JSON: %w", err)) } fmt.Println(string(vpBytes)) }
Output: {"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"id":"urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5","type":["VerifiablePresentation","UniversityDegreeCredential"],"verifiableCredential":[{"@context":["https://www.w3.org/2018/credentials/v1","https://www.w3.org/2018/credentials/examples/v1"],"credentialSchema":[],"credentialSubject":{"degree":{"type":"BachelorDegree","university":"MIT"},"id":"did:example:ebfeb1f712ebc6f1c276e12ec21","name":"Jayden Doe","spouse":"did:example:c276e12ec21ebfeb1f712ebc6f1"},"expirationDate":"2020-01-01T19:23:24Z","id":"http://example.edu/credentials/1872","issuanceDate":"2010-01-01T19:23:24Z","issuer":{"id":"did:example:76e12ec712ebc6f1c221ebfeb1f","name":"Example University"},"referenceNumber":83294847,"type":["VerifiableCredential","UniversityDegreeCredential"]}],"holder":"did:example:ebfeb1f712ebc6f1c276e12ec21"}
func (*Presentation) AddLinkedDataProof ¶ added in v0.1.1
func (vp *Presentation) AddLinkedDataProof(context *LinkedDataProofContext) error
AddLinkedDataProof appends proof to the Verifiable Presentation.
func (*Presentation) Credentials ¶
func (vp *Presentation) Credentials() []interface{}
Credentials returns current credentials of presentation.
func (*Presentation) JWTClaims ¶
func (vp *Presentation) JWTClaims(audience []string, minimizeVP bool) (*JWTPresClaims, error)
JWTClaims converts Verifiable Presentation into JWT Presentation claims, which can be than serialized e.g. into JWS.
Example ¶
package main import ( "crypto/ed25519" "fmt" "github.com/hyperledger/aries-framework-go/pkg/doc/verifiable" ) // Private key generated by ed25519.GenerateKey(rand.Reader) // //nolint:gochecknoglobals var privHolderKey = ed25519.PrivateKey{137, 207, 34, 115, 168, 80, 44, 145, 236, 206, 165, 152, 211, 195, 240, 205, 232, 37, 216, 101, 58, 133, 198, 107, 232, 119, 30, 80, 176, 137, 10, 251, 109, 144, 158, 93, 189, 195, 0, 24, 15, 29, 166, 185, 169, 69, 246, 25, 182, 179, 115, 54, 107, 4, 123, 30, 5, 88, 175, 94, 109, 15, 34, 113} func main() { // The Holder kept the presentation serialized to JSON in her personal verifiable credential wallet. vpStrFromWallet := ` { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c5", "type": [ "VerifiablePresentation", "UniversityDegreeCredential" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2010-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "referenceNumber": 83294847, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] } ], "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21" } ` // The Holder wants to send the presentation to the Verifier in JWS. vp, err := verifiable.NewPresentation([]byte(vpStrFromWallet)) if err != nil { fmt.Println(fmt.Errorf("failed to decode VP JSON: %w", err)) } aud := []string{"did:example:4a57546973436f6f6c4a4a57573"} jwtClaims, err := vp.JWTClaims(aud, true) if err != nil { fmt.Println(fmt.Errorf("failed to create JWT claims of VP: %w", err)) } jws, err := jwtClaims.MarshalJWS(verifiable.EdDSA, privHolderKey, "") if err != nil { fmt.Println(fmt.Errorf("failed to sign VP inside JWT: %w", err)) } fmt.Println(jws) //nolint
Output:
func (*Presentation) MarshalJSON ¶
func (vp *Presentation) MarshalJSON() ([]byte, error)
MarshalJSON converts Verifiable Presentation to JSON bytes.
Example ¶
vp := &verifiable.Presentation{ Context: []string{ "https://www.w3.org/2018/credentials/v1"}, ID: "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c", Type: []string{"VerifiablePresentation"}, Holder: "did:example:ebfeb1f712ebc6f1c276e12ec21", } vc := &verifiable.Credential{ Context: []string{ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"}, ID: "http://example.edu/credentials/1872", Types: []string{ "VerifiableCredential", "UniversityDegreeCredential"}, Subject: UniversityDegreeSubject{ ID: "did:example:ebfeb1f712ebc6f1c276e12ec21", Name: "Jayden Doe", Spouse: "did:example:c276e12ec21ebfeb1f712ebc6f1", Degree: UniversityDegree{ Type: "BachelorDegree", University: "MIT", }, }, Issuer: verifiable.Issuer{ ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", Name: "Example University", }, Issued: &issued, Expired: &expired, Schemas: []verifiable.TypedID{}, CustomFields: map[string]interface{}{ "referenceNumber": 83294847, }, } err := vp.SetCredentials(vc) if err != nil { fmt.Println(fmt.Errorf("failed to set credentials of VP: %w", err)) } // json.MarshalIndent() calls Presentation.MarshalJSON() vpJSON, err := json.MarshalIndent(vp, "", "\t") if err != nil { fmt.Println(fmt.Errorf("failed to marshal VP to JSON: %w", err)) } fmt.Println(string(vpJSON))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1" ], "id": "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c", "type": [ "VerifiablePresentation" ], "verifiableCredential": [ { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2010-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "referenceNumber": 83294847, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] } ], "holder": "did:example:ebfeb1f712ebc6f1c276e12ec21" }
func (*Presentation) MarshalledCredentials ¶ added in v0.1.1
func (vp *Presentation) MarshalledCredentials() ([]MarshalledCredential, error)
MarshalledCredentials provides marshalled credentials enclosed into Presentation in raw byte array format. They can be used to decode Credentials into struct.
Example ¶
vp := &verifiable.Presentation{ Context: []string{ "https://www.w3.org/2018/credentials/v1"}, ID: "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c", Type: []string{"VerifiablePresentation"}, Holder: "did:example:ebfeb1f712ebc6f1c276e12ec21", } vc := verifiable.Credential{ Context: []string{ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"}, ID: "http://example.edu/credentials/1872", Types: []string{ "VerifiableCredential", "UniversityDegreeCredential"}, Subject: UniversityDegreeSubject{ ID: "did:example:ebfeb1f712ebc6f1c276e12ec21", Name: "Jayden Doe", Spouse: "did:example:c276e12ec21ebfeb1f712ebc6f1", Degree: UniversityDegree{ Type: "BachelorDegree", University: "MIT", }, }, Issuer: verifiable.Issuer{ ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", Name: "Example University", }, Issued: &issued, Expired: &expired, Schemas: []verifiable.TypedID{}, } // Put JWS form of VC into VP. vcJWTClaims, err := vc.JWTClaims(true) if err != nil { fmt.Println(fmt.Errorf("failed to set credentials of VP: %w", err)) } vcJWS, err := vcJWTClaims.MarshalJWS(verifiable.EdDSA, privIssuerKey, "i-kid") if err != nil { fmt.Println(fmt.Errorf("failed to sign VC JWT: %w", err)) } err = vp.SetCredentials(vcJWS) if err != nil { fmt.Println(fmt.Errorf("failed to set credentials of VP: %w", err)) } // Marshal VP to JWS as well. vpJWTClaims, err := vp.JWTClaims(nil, true) if err != nil { fmt.Println(fmt.Errorf("failed to create JWT claims of VP: %w", err)) } vpJWS, err := vpJWTClaims.MarshalJWS(verifiable.EdDSA, privHolderKey, "h-kid") if err != nil { fmt.Println(fmt.Errorf("failed to sign VP inside JWT: %w", err)) } // Decode VP from JWS. // Note that VC-s inside will be decoded as well. If they are JWS, their signature is verified // and thus we need to make sure the public key fetcher can access the vp, err = verifiable.NewPresentation( []byte(vpJWS), verifiable.WithPresPublicKeyFetcher(func(issuerID, keyID string) (interface{}, error) { switch issuerID { case "did:example:76e12ec712ebc6f1c221ebfeb1f": return privIssuerKey.Public(), nil case "did:example:ebfeb1f712ebc6f1c276e12ec21": return privHolderKey.Public(), nil default: return nil, fmt.Errorf("unexpected key: %s", keyID) } })) if err != nil { fmt.Println(fmt.Errorf("failed to decode VP JWS: %w", err)) } // Get credentials in binary form. vpCreds, err := vp.MarshalledCredentials() if err != nil { fmt.Println(fmt.Errorf("failed to get marshalled credentials from decoded presentation: %w", err)) } if len(vpCreds) != 1 { fmt.Println("Expected 1 credential inside presentation") } // Decoded credential. Note that no public key fetcher is passed as the VC was already decoded (and proof verified) // when VP was decoded. vcDecoded, _, err := verifiable.NewCredential(vpCreds[0]) if err != nil { fmt.Println(fmt.Errorf("failed to decode VC: %w", err)) } vcDecodedJSON, err := json.MarshalIndent(vcDecoded, "", "\t") if err != nil { fmt.Println(fmt.Errorf("failed to marshal VP to JSON: %w", err)) } fmt.Println(string(vcDecodedJSON))
Output: { "@context": [ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1" ], "credentialSchema": [], "credentialSubject": { "degree": { "type": "BachelorDegree", "university": "MIT" }, "id": "did:example:ebfeb1f712ebc6f1c276e12ec21", "name": "Jayden Doe", "spouse": "did:example:c276e12ec21ebfeb1f712ebc6f1" }, "expirationDate": "2020-01-01T19:23:24Z", "id": "http://example.edu/credentials/1872", "issuanceDate": "2010-01-01T19:23:24Z", "issuer": { "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", "name": "Example University" }, "type": [ "VerifiableCredential", "UniversityDegreeCredential" ] }
func (*Presentation) SetCredentials ¶ added in v0.1.1
func (vp *Presentation) SetCredentials(creds ...interface{}) error
SetCredentials defines credentials of presentation. The credential could be string/byte (probably serialized JWT) or Credential structure.
Example ¶
// Holder wants to send 2 credentials to Verifier vp := &verifiable.Presentation{ Context: []string{ "https://www.w3.org/2018/credentials/v1"}, ID: "urn:uuid:3978344f-8596-4c3a-a978-8fcaba3903c", Type: []string{"VerifiablePresentation"}, Holder: "did:example:ebfeb1f712ebc6f1c276e12ec21", } // The first VC is created on fly (or just decoded using NewCredential). vc := &verifiable.Credential{ Context: []string{ "https://www.w3.org/2018/credentials/v1", "https://www.w3.org/2018/credentials/examples/v1"}, ID: "http://example.edu/credentials/1872", Types: []string{ "VerifiableCredential", "UniversityDegreeCredential"}, Subject: UniversityDegreeSubject{ ID: "did:example:ebfeb1f712ebc6f1c276e12ec21", Name: "Jayden Doe", Spouse: "did:example:c276e12ec21ebfeb1f712ebc6f1", Degree: UniversityDegree{ Type: "BachelorDegree", University: "MIT", }, }, Issuer: verifiable.Issuer{ ID: "did:example:76e12ec712ebc6f1c221ebfeb1f", Name: "Example University", }, Issued: &issued, Expired: &expired, Schemas: []verifiable.TypedID{}, CustomFields: map[string]interface{}{ "referenceNumber": 83294847, }, } // The second VC is provided in JWS form (e.g. kept in the wallet in that form). vcJWS := "eyJhbGciOiJFZERTQSIsImtpZCI6IiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1Nzc5MDY2MDQsImlhdCI6MTI2MjM3MzgwNCwiaXNzIjoiZGlkOmV4YW1wbGU6NzZlMTJlYzcxMmViYzZmMWMyMjFlYmZlYjFmIiwianRpIjoiaHR0cDovL2V4YW1wbGUuZWR1L2NyZWRlbnRpYWxzLzE4NzIiLCJuYmYiOjEyNjIzNzM4MDQsInN1YiI6ImRpZDpleGFtcGxlOmViZmViMWY3MTJlYmM2ZjFjMjc2ZTEyZWMyMSIsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjEiXSwiY3JlZGVudGlhbFNjaGVtYSI6W10sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImRlZ3JlZSI6eyJ0eXBlIjoiQmFjaGVsb3JEZWdyZWUiLCJ1bml2ZXJzaXR5IjoiTUlUIn0sImlkIjoiZGlkOmV4YW1wbGU6ZWJmZWIxZjcxMmViYzZmMWMyNzZlMTJlYzIxIiwibmFtZSI6IkpheWRlbiBEb2UiLCJzcG91c2UiOiJkaWQ6ZXhhbXBsZTpjMjc2ZTEyZWMyMWViZmViMWY3MTJlYmM2ZjEifSwiaXNzdWVyIjp7Im5hbWUiOiJFeGFtcGxlIFVuaXZlcnNpdHkifSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWVDcmVkZW50aWFsIl19fQ.AHn2A2q5DL1heX3_izq_2yrsBDhoZ6BGGKhoRvhfMnMUuuOnBOdekdTg-dfUMJgipXRql_6WzBUIj4wTFehXCw" // nolint:lll err := vp.SetCredentials(vc, vcJWS) if err != nil { fmt.Println(fmt.Errorf("failed to set credentials of VP: %w", err)) }
Output:
type PresentationOpt ¶
type PresentationOpt func(opts *presentationOpts)
PresentationOpt is the Verifiable Presentation decoding option
func WithPresEmbeddedSignatureSuites ¶ added in v0.1.1
func WithPresEmbeddedSignatureSuites(suites ...verifierSignatureSuite) PresentationOpt
WithPresEmbeddedSignatureSuites defines the suites which are used to check embedded linked data proof of VP.
func WithPresPublicKeyFetcher ¶
func WithPresPublicKeyFetcher(fetcher PublicKeyFetcher) PresentationOpt
WithPresPublicKeyFetcher indicates that Verifiable Presentation should be decoded from JWS using the public key fetcher.
type Proof ¶
type Proof map[string]interface{}
Proof defines embedded proof of Verifiable Credential
type PublicKeyFetcher ¶
PublicKeyFetcher fetches public key for JWT signing verification based on Issuer ID (possibly DID) and Key ID. If not defined, JWT encoding is not tested.
func SingleKey ¶
func SingleKey(pubKey interface{}) PublicKeyFetcher
SingleKey defines the case when only one verification key is used and we don't need to pick the one.
type SchemaCache ¶ added in v0.1.1
type SchemaCache interface { // Put element to the cache. Put(k string, v []byte) // Get element from the cache, returns false at second return value if element is not present. Get(k string) ([]byte, bool) }
SchemaCache defines a cache of credential schemas.
type TypedID ¶
type TypedID struct { ID string `json:"id,omitempty"` Type string `json:"type,omitempty"` CustomFields `json:"-"` }
TypedID defines a flexible structure with id and name fields and arbitrary extra fields kept in CustomFields.
func (TypedID) MarshalJSON ¶
MarshalJSON defines custom marshalling of TypedID to JSON.
func (*TypedID) UnmarshalJSON ¶
UnmarshalJSON defines custom unmarshalling of TypedID from JSON.
Source Files ¶
- cache.go
- common.go
- credential.go
- credential_jws.go
- credential_jwt.go
- credential_jwt_unsecured.go
- credential_ldp.go
- embedded_proof.go
- json.go
- jsonld.go
- jws.go
- jwt_unsecured.go
- linked_data_proof.go
- presentation.go
- presentation_jws.go
- presentation_jwt.go
- presentation_jwt_unsecured.go
- presentation_ldp.go