forked from hyperledger-archives/aries-framework-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
didconnection.go
137 lines (110 loc) · 3.85 KB
/
didconnection.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
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package did
import (
"encoding/json"
"errors"
"fmt"
"github.com/btcsuite/btcutil/base58"
"github.com/Universal-Health-Chain/aries-framework-go/pkg/didcomm/common/service"
diddoc "github.com/Universal-Health-Chain/aries-framework-go/pkg/doc/did"
"github.com/Universal-Health-Chain/aries-framework-go/pkg/framework/aries/api/vdr"
"github.com/Universal-Health-Chain/aries-framework-go/pkg/storage"
)
// StoreName DID connection store name.
const StoreName = "didconnection"
// ErrNotFound signals that the entry for the given DID and key is not present in the store.
var ErrNotFound = errors.New("did not found under given key")
// ConnectionStore stores DIDs indexed by key.
type ConnectionStore struct {
store storage.Store
vdr vdr.Registry
}
type didRecord struct {
DID string `json:"did,omitempty"`
// TODO add type below to distinguish Legacy vs new Packer
// envelopeType string
}
type connectionProvider interface {
StorageProvider() storage.Provider
VDRegistry() vdr.Registry
}
// NewConnectionStore returns a new did lookup ConnectionStore.
func NewConnectionStore(ctx connectionProvider) (*ConnectionStore, error) {
store, err := ctx.StorageProvider().OpenStore(StoreName)
if err != nil {
return nil, err
}
return &ConnectionStore{store: store, vdr: ctx.VDRegistry()}, nil
}
// saveDID saves a DID, indexed using the given public key.
func (c *ConnectionStore) saveDID(did, key string) error {
data := didRecord{
DID: did,
}
bytes, err := json.Marshal(data)
if err != nil {
return err
}
return c.store.Put(key, bytes)
}
// SaveDID saves a DID, indexed using the given public keys.
func (c *ConnectionStore) SaveDID(did string, keys ...string) error {
for _, key := range keys {
err := c.saveDID(did, key)
if err != nil {
return fmt.Errorf("saving DID in did map: %w", err)
}
}
return nil
}
// SaveDIDFromDoc saves a map from a did doc's keys to the did.
func (c *ConnectionStore) SaveDIDFromDoc(doc *diddoc.Doc) error {
var keys []string
for i := range doc.VerificationMethod {
// TODO fix hardcode base58 https://github.com/hyperledger/aries-framework-go/issues/1207
// keeping these keys base58 encoded as long as legacyPacker exists
keys = append(keys, base58.Encode(doc.VerificationMethod[i].Value))
}
// assumption doc.KeyAgreement exists when separate encryption keys and verifications keys are used for this DID
// eg: used by Authcrypt/Anoncrypt Packer (not Legacy Packer)
for i := range doc.KeyAgreement {
// add proper crypto keys (as opposed to verification keys as doc.VerificationMethod above)
keys = append(keys, doc.KeyAgreement[i].VerificationMethod.ID[1:])
}
// save recipientKeys from didcomm-enabled service entries
// an error is returned only if the doc does not have a valid didcomm service entry, so we ignore it
svc, err := service.CreateDestination(doc)
if err == nil {
keys = append(keys, svc.RecipientKeys...)
}
return c.SaveDID(doc.ID, keys...)
}
// SaveDIDByResolving resolves a DID using the VDR then saves the map from keys -> did
// keys: fallback keys in case the DID can't be resolved
func (c *ConnectionStore) SaveDIDByResolving(did string, keys ...string) error {
docResolution, err := c.vdr.Resolve(did)
if errors.Is(err, vdr.ErrNotFound) {
return c.SaveDID(did, keys...)
} else if err != nil {
return fmt.Errorf("failed to read from vdr store : %w", err)
}
return c.SaveDIDFromDoc(docResolution.DIDDocument)
}
// GetDID gets the DID stored under the given key.
func (c *ConnectionStore) GetDID(key string) (string, error) {
bytes, err := c.store.Get(key)
if errors.Is(err, storage.ErrDataNotFound) {
return "", ErrNotFound
} else if err != nil {
return "", err
}
var record didRecord
err = json.Unmarshal(bytes, &record)
if err != nil {
return "", err
}
return record.DID, nil
}