Skip to content
This repository was archived by the owner on Dec 12, 2024. It is now read-only.

Commit 487d633

Browse files
Updates (#15)
* updates * cid * consistent api * typo * cycles
1 parent 8f8ea12 commit 487d633

File tree

9 files changed

+165
-117
lines changed

9 files changed

+165
-117
lines changed

cid/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Controlled Identifier Documents
2+
3+
This directory contains an implementation of the [Controlled Identifier Document 1.0](https://w3c.github.io/cid/)
4+
specification.

controller/controller.go renamed to cid/cid.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package controller
1+
package cid
22

33
import (
44
"github.com/lestrrat-go/jwx/v2/jwk"
@@ -25,14 +25,14 @@ type Document struct {
2525
}
2626

2727
type VerificationMethod struct {
28-
ID string `json:"id" validate:"required"`
29-
Type string `json:"type" validate:"required"`
30-
Controller string `json:"controller" validate:"required"`
31-
Revoked string `json:"revoked,omitempty"`
32-
PublicKeyJWK jwk.Key `json:"publicKeyJwk,omitempty"`
33-
SecretKeyJWK jwk.Key `json:"secretKeyJwk,omitempty"`
34-
PublicKeyMultibase string `json:"publicKeyMultibase,omitempty"`
35-
SecretKeyMultibase string `json:"secretKeyMultibase,omitempty"`
28+
ID string `json:"id" validate:"required"`
29+
Type string `json:"type" validate:"required"`
30+
Controller util.SingleOrArray[string] `json:"controller" validate:"required"`
31+
Revoked string `json:"revoked,omitempty"`
32+
PublicKeyJWK jwk.Key `json:"publicKeyJwk,omitempty"`
33+
SecretKeyJWK jwk.Key `json:"secretKeyJwk,omitempty"`
34+
PublicKeyMultibase string `json:"publicKeyMultibase,omitempty"`
35+
SecretKeyMultibase string `json:"secretKeyMultibase,omitempty"`
3636
}
3737

3838
type VerificationMethodMap struct {

controller/README.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

credential/testdata/vp-enveloped-vc-example-1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
"verifiableCredential": [{
88
"@context": "https://www.w3.org/ns/credentials/v2",
99
"type": "EnvelopedVerifiableCredential",
10-
"id": "data:application/vc-ld+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
10+
"id": "data:application/vc+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
1111
}]
1212
}

credential/testdata/vp-enveloped-vp-example-1.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44
"https://www.w3.org/ns/credentials/examples/v2"
55
],
66
"type": "EnvelopedVerifiablePresentation",
7-
"id": "data:application/vp-ld+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
7+
"id": "data:application/vp+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
88
}

crypto_test.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package vc_jose_cose_go
2+
3+
import (
4+
"fmt"
5+
"github.com/TBD54566975/vc-jose-cose-go/cid"
6+
"github.com/TBD54566975/vc-jose-cose-go/util"
7+
"github.com/goccy/go-json"
8+
"github.com/lestrrat-go/jwx/v2/jwa"
9+
"github.com/stretchr/testify/require"
10+
"testing"
11+
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
// TestGenerateKeys is used to generate sample cid document verification methods
16+
func TestGenerateKeys(t *testing.T) {
17+
t.Skip("skipping test as it is not needed except for local testing")
18+
19+
tests := []struct {
20+
name string
21+
curve jwa.EllipticCurveAlgorithm
22+
kid string
23+
}{
24+
{"EC P-256", jwa.P256, "key-1"},
25+
{"EC P-384", jwa.P384, "key-2"},
26+
{"EC P-521", jwa.P521, "key-3"},
27+
{"OKP EdDSA", jwa.Ed25519, "key-4"},
28+
}
29+
30+
for _, tt := range tests {
31+
t.Run(tt.name, func(t *testing.T) {
32+
key, err := util.GenerateJWK(tt.curve)
33+
require.NoError(t, err)
34+
assert.NotNil(t, key)
35+
36+
pubKey, err := key.PublicKey()
37+
require.NoError(t, err)
38+
assert.NotNil(t, pubKey)
39+
40+
id := "https://example.issuer/6c427e8392ab4057b93356fbb9022ecb"
41+
vm := cid.VerificationMethod{
42+
ID: fmt.Sprintf("%s#%s", id, tt.kid),
43+
Type: cid.TypeJSONWebKey,
44+
Controller: util.SingleOrArray[string]{id},
45+
PublicKeyJWK: pubKey,
46+
SecretKeyJWK: key,
47+
}
48+
49+
vmJSONBytes, err := json.Marshal(vm)
50+
require.NoError(t, err)
51+
t.Logf("\n%s\n", string(vmJSONBytes))
52+
})
53+
}
54+
}
55+
56+
func TestKeyToBytes(t *testing.T) {
57+
for _, keyType := range util.GetSupportedKeyTypes() {
58+
t.Run(string(keyType), func(t *testing.T) {
59+
pub, priv, err := util.GenerateKeyByKeyType(keyType)
60+
61+
assert.NoError(t, err)
62+
assert.NotEmpty(t, pub)
63+
assert.NotEmpty(t, priv)
64+
65+
pubKeyBytes, err := util.PubKeyToBytes(pub)
66+
assert.NoError(t, err)
67+
assert.NotEmpty(t, pubKeyBytes)
68+
69+
reconstructedPub, err := util.BytesToPubKey(pubKeyBytes, keyType)
70+
assert.NoError(t, err)
71+
assert.NotEmpty(t, reconstructedPub)
72+
assert.EqualValues(t, pub, reconstructedPub)
73+
74+
privKeyBytes, err := util.PrivKeyToBytes(priv)
75+
assert.NoError(t, err)
76+
assert.NotEmpty(t, privKeyBytes)
77+
78+
reconstructedPriv, err := util.BytesToPrivKey(privKeyBytes, keyType)
79+
assert.NoError(t, err)
80+
assert.NotEmpty(t, reconstructedPriv)
81+
assert.EqualValues(t, priv, reconstructedPriv)
82+
83+
kt, err := util.GetKeyTypeFromPrivateKey(priv)
84+
assert.NoError(t, err)
85+
assert.Equal(t, keyType, kt)
86+
})
87+
}
88+
89+
for _, keyType := range util.GetSupportedKeyTypes() {
90+
t.Run(string(keyType)+" with pointers", func(t *testing.T) {
91+
pub, priv, err := util.GenerateKeyByKeyType(keyType)
92+
93+
assert.NoError(t, err)
94+
assert.NotEmpty(t, pub)
95+
assert.NotEmpty(t, priv)
96+
97+
pubKeyBytes, err := util.PubKeyToBytes(&pub)
98+
assert.NoError(t, err)
99+
assert.NotEmpty(t, pubKeyBytes)
100+
101+
reconstructedPub, err := util.BytesToPubKey(pubKeyBytes, keyType)
102+
assert.NoError(t, err)
103+
assert.NotEmpty(t, reconstructedPub)
104+
assert.EqualValues(t, pub, reconstructedPub)
105+
106+
privKeyBytes, err := util.PrivKeyToBytes(&priv)
107+
assert.NoError(t, err)
108+
assert.NotEmpty(t, privKeyBytes)
109+
110+
reconstructedPriv, err := util.BytesToPrivKey(privKeyBytes, keyType)
111+
assert.NoError(t, err)
112+
assert.NotEmpty(t, reconstructedPriv)
113+
assert.EqualValues(t, priv, reconstructedPriv)
114+
115+
kt, err := util.GetKeyTypeFromPrivateKey(&priv)
116+
assert.NoError(t, err)
117+
assert.Equal(t, keyType, kt)
118+
})
119+
}
120+
}
121+
122+
func TestSECP256k1Conversions(t *testing.T) {
123+
pk, sk, err := util.GenerateSECP256k1Key()
124+
assert.NoError(t, err)
125+
126+
ecdsaPK := pk.ToECDSA()
127+
ecdsaSK := sk.ToECDSA()
128+
129+
gotPK := util.SECP256k1ECDSAPubKeyToSECP256k1(*ecdsaPK)
130+
gotSK := util.SECP256k1ECDSASPrivKeyToSECP256k1(*ecdsaSK)
131+
132+
assert.Equal(t, pk, gotPK)
133+
assert.Equal(t, sk, gotSK)
134+
}

jose/jose.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,18 @@ func VerifyVerifiableCredential(jwt string, key jwk.Key) (*credential.Verifiable
114114
}
115115

116116
// SignVerifiablePresentation dynamically signs a VerifiablePresentation based on the key type.
117-
func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Key) (string, error) {
117+
func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Key) (*string, error) {
118118
if vp.IsEmpty() {
119-
return "", errors.New("VerifiablePresentation is empty")
119+
return nil, errors.New("VerifiablePresentation is empty")
120120
}
121121
if key == nil {
122-
return "", errors.New("key is required")
122+
return nil, errors.New("key is required")
123123
}
124124
if key.KeyID() == "" {
125-
return "", errors.New("key ID is required")
125+
return nil, errors.New("key ID is required")
126126
}
127127
if key.Algorithm().String() == "" {
128-
return "", errors.New("key algorithm is required")
128+
return nil, errors.New("key algorithm is required")
129129
}
130130

131131
var alg jwa.SignatureAlgorithm
@@ -134,7 +134,7 @@ func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Ke
134134
case jwa.EC:
135135
crv, ok := key.Get("crv")
136136
if !ok || crv == nil {
137-
return "", fmt.Errorf("invalid or missing 'crv' parameter")
137+
return nil, fmt.Errorf("invalid or missing 'crv' parameter")
138138
}
139139
crvAlg := crv.(jwa.EllipticCurveAlgorithm)
140140
switch crvAlg {
@@ -145,22 +145,22 @@ func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Ke
145145
case jwa.P521:
146146
alg = jwa.ES512
147147
default:
148-
return "", fmt.Errorf("unsupported curve: %s", crvAlg.String())
148+
return nil, fmt.Errorf("unsupported curve: %s", crvAlg.String())
149149
}
150150
case jwa.OKP:
151151
alg = jwa.EdDSA
152152
default:
153-
return "", fmt.Errorf("unsupported key type: %s", kty)
153+
return nil, fmt.Errorf("unsupported key type: %s", kty)
154154
}
155155

156156
// Convert the VerifiablePresentation to a map for manipulation
157157
vpMap := make(map[string]any)
158158
vpBytes, err := json.Marshal(vp)
159159
if err != nil {
160-
return "", err
160+
return nil, err
161161
}
162162
if err = json.Unmarshal(vpBytes, &vpMap); err != nil {
163-
return "", err
163+
return nil, err
164164
}
165165

166166
// Add standard claims
@@ -179,7 +179,7 @@ func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Ke
179179
// Marshal the claims to JSON
180180
payload, err := json.Marshal(vpMap)
181181
if err != nil {
182-
return "", err
182+
return nil, err
183183
}
184184

185185
// Add protected header values
@@ -192,17 +192,18 @@ func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Ke
192192
}
193193
for k, v := range headers {
194194
if err = jwsHeaders.Set(k, v); err != nil {
195-
return "", err
195+
return nil, err
196196
}
197197
}
198198

199199
// Sign the payload
200200
signed, err := jws.Sign(payload, jws.WithKey(alg, key, jws.WithProtectedHeaders(jwsHeaders)))
201201
if err != nil {
202-
return "", err
202+
return nil, err
203203
}
204204

205-
return string(signed), nil
205+
result := string(signed)
206+
return &result, nil
206207
}
207208

208209
// VerifyVerifiablePresentation verifies a VerifiablePresentation JWT using the provided key.

jose/jose_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func Test_Sign_Verify_VerifiablePresentation(t *testing.T) {
7979
assert.NotEmpty(t, jwt)
8080

8181
// Verify the VP
82-
verifiedVP, err := VerifyVerifiablePresentation(jwt, key)
82+
verifiedVP, err := VerifyVerifiablePresentation(*jwt, key)
8383
require.NoError(t, err)
8484
assert.Equal(t, vp.ID, verifiedVP.ID)
8585
assert.Equal(t, vp.Holder.ID(), verifiedVP.Holder.ID())

util/crypto_test.go

Lines changed: 0 additions & 87 deletions
This file was deleted.

0 commit comments

Comments
 (0)