forked from hyperledger-archives/aries-framework-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinked_data_proof.go
144 lines (117 loc) · 4.41 KB
/
linked_data_proof.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package verifiable
import (
"encoding/json"
"fmt"
"strings"
"time"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/jsonld"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/proof"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/signer"
"github.com/hyperledger/aries-framework-go/pkg/doc/signature/verifier"
)
const (
resolveIDParts = 2
)
type keyResolverAdapter struct {
pubKeyFetcher PublicKeyFetcher
}
func (k *keyResolverAdapter) Resolve(id string) (*verifier.PublicKey, error) {
// id will contain didID#keyID
idSplit := strings.Split(id, "#")
if len(idSplit) != resolveIDParts {
return nil, fmt.Errorf("wrong id %s to resolve", idSplit)
}
// idSplit[0] is didID
// idSplit[1] is keyID
pubKey, err := k.pubKeyFetcher(idSplit[0], fmt.Sprintf("#%s", idSplit[1]))
if err != nil {
return nil, err
}
return pubKey, nil
}
// SignatureRepresentation is a signature value holder type (e.g. "proofValue" or "jws").
type SignatureRepresentation int
const (
// SignatureProofValue uses "proofValue" field in a Proof to put/read a digital signature.
SignatureProofValue SignatureRepresentation = iota
// SignatureJWS uses "jws" field in a Proof as an element for representation of detached JSON Web Signatures.
SignatureJWS
)
// LinkedDataProofContext holds options needed to build a Linked Data Proof.
type LinkedDataProofContext struct {
SignatureType string // required
Suite signer.SignatureSuite // required
SignatureRepresentation SignatureRepresentation // required
Created *time.Time // optional
VerificationMethod string // optional
Challenge string // optional
Domain string // optional
Purpose string // optional
// CapabilityChain must be an array. Each element is either a string or an object.
CapabilityChain []interface{}
}
func checkLinkedDataProof(jsonldBytes []byte, suites []verifier.SignatureSuite,
pubKeyFetcher PublicKeyFetcher, jsonldOpts *jsonldCredentialOpts) error {
documentVerifier, err := verifier.New(&keyResolverAdapter{pubKeyFetcher}, suites...)
if err != nil {
return fmt.Errorf("create new signature verifier: %w", err)
}
processorOpts := mapJSONLDProcessorOpts(jsonldOpts)
err = documentVerifier.Verify(jsonldBytes, processorOpts...)
if err != nil {
return fmt.Errorf("check linked data proof: %w", err)
}
return nil
}
func mapJSONLDProcessorOpts(jsonldOpts *jsonldCredentialOpts) []jsonld.ProcessorOpts {
var processorOpts []jsonld.ProcessorOpts
if jsonldOpts.jsonldDocumentLoader != nil {
processorOpts = append(processorOpts, jsonld.WithDocumentLoader(jsonldOpts.jsonldDocumentLoader))
}
if jsonldOpts.jsonldOnlyValidRDF {
processorOpts = append(processorOpts, jsonld.WithRemoveAllInvalidRDF())
} else {
processorOpts = append(processorOpts, jsonld.WithValidateRDF())
}
return processorOpts
}
type rawProof struct {
Proof json.RawMessage `json:"proof,omitempty"`
}
// addLinkedDataProof adds a new proof to the JSON-LD document (VC or VP). It returns a slice
// of the proofs which were already present appended with a newly created proof.
func addLinkedDataProof(context *LinkedDataProofContext, jsonldBytes []byte,
opts ...jsonld.ProcessorOpts) ([]Proof, error) {
documentSigner := signer.New(context.Suite)
vcWithNewProofBytes, err := documentSigner.Sign(mapContext(context), jsonldBytes, opts...)
if err != nil {
return nil, fmt.Errorf("add linked data proof: %w", err)
}
// Get a proof from json-ld document.
var rProof rawProof
err = json.Unmarshal(vcWithNewProofBytes, &rProof)
if err != nil {
return nil, err
}
proofs, err := parseProof(rProof.Proof)
if err != nil {
return nil, err
}
return proofs, nil
}
func mapContext(context *LinkedDataProofContext) *signer.Context {
return &signer.Context{
SignatureType: context.SignatureType,
SignatureRepresentation: proof.SignatureRepresentation(context.SignatureRepresentation),
Created: context.Created,
VerificationMethod: context.VerificationMethod,
Challenge: context.Challenge,
Domain: context.Domain,
Purpose: context.Purpose,
CapabilityChain: context.CapabilityChain,
}
}