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

Commit

Permalink
Updates (#15)
Browse files Browse the repository at this point in the history
* updates

* cid

* consistent api

* typo

* cycles
  • Loading branch information
decentralgabe authored Dec 10, 2024
1 parent 8f8ea12 commit 487d633
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 117 deletions.
4 changes: 4 additions & 0 deletions cid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Controlled Identifier Documents

This directory contains an implementation of the [Controlled Identifier Document 1.0](https://w3c.github.io/cid/)
specification.
18 changes: 9 additions & 9 deletions controller/controller.go → cid/cid.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package controller
package cid

import (
"github.com/lestrrat-go/jwx/v2/jwk"
Expand All @@ -25,14 +25,14 @@ type Document struct {
}

type VerificationMethod struct {
ID string `json:"id" validate:"required"`
Type string `json:"type" validate:"required"`
Controller string `json:"controller" validate:"required"`
Revoked string `json:"revoked,omitempty"`
PublicKeyJWK jwk.Key `json:"publicKeyJwk,omitempty"`
SecretKeyJWK jwk.Key `json:"secretKeyJwk,omitempty"`
PublicKeyMultibase string `json:"publicKeyMultibase,omitempty"`
SecretKeyMultibase string `json:"secretKeyMultibase,omitempty"`
ID string `json:"id" validate:"required"`
Type string `json:"type" validate:"required"`
Controller util.SingleOrArray[string] `json:"controller" validate:"required"`
Revoked string `json:"revoked,omitempty"`
PublicKeyJWK jwk.Key `json:"publicKeyJwk,omitempty"`
SecretKeyJWK jwk.Key `json:"secretKeyJwk,omitempty"`
PublicKeyMultibase string `json:"publicKeyMultibase,omitempty"`
SecretKeyMultibase string `json:"secretKeyMultibase,omitempty"`
}

type VerificationMethodMap struct {
Expand Down
4 changes: 0 additions & 4 deletions controller/README.md

This file was deleted.

2 changes: 1 addition & 1 deletion credential/testdata/vp-enveloped-vc-example-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
"verifiableCredential": [{
"@context": "https://www.w3.org/ns/credentials/v2",
"type": "EnvelopedVerifiableCredential",
"id": "data:application/vc-ld+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
"id": "data:application/vc+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
}]
}
2 changes: 1 addition & 1 deletion credential/testdata/vp-enveloped-vp-example-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"https://www.w3.org/ns/credentials/examples/v2"
],
"type": "EnvelopedVerifiablePresentation",
"id": "data:application/vp-ld+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
"id": "data:application/vp+jwt,eyJraWQiOiJFeEhrQk1XOWZtYmt2VjI2Nm1ScHVQMnNVWV9OX0VXSU4xbGFwVXpPOHJvIiwiYWxnIjoiRVMzODQifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvZXhhbXBsZXMvdjIiXSwiaWQiOiJodHRwOi8vdW5pdmVyc2l0eS5leGFtcGxlL2NyZWRlbnRpYWxzLzE4NzIiLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRXhhbXBsZUFsdW1uaUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly91bml2ZXJzaXR5LmV4YW1wbGUvaXNzdWVycy81NjUwNDkiLCJ2YWxpZEZyb20iOiIyMDEwLTAxLTAxVDE5OjIzOjI0WiIsImNyZWRlbnRpYWxTY2hlbWEiOnsiaWQiOiJodHRwczovL2V4YW1wbGUub3JnL2V4YW1wbGVzL2RlZ3JlZS5qc29uIiwidHlwZSI6Ikpzb25TY2hlbWEifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZToxMjMiLCJkZWdyZWUiOnsidHlwZSI6IkJhY2hlbG9yRGVncmVlIiwibmFtZSI6IkJhY2hlbG9yIG9mIFNjaWVuY2UgYW5kIEFydHMifX19.d2k4O3FytQJf83kLh-HsXuPvh6yeOlhJELVo5TF71gu7elslQyOf2ZItAXrtbXF4Kz9WivNdztOayz4VUQ0Mwa8yCDZkP9B2pH-9S_tcAFxeoeJ6Z4XnFuL_DOfkR1fP"
}
134 changes: 134 additions & 0 deletions crypto_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package vc_jose_cose_go

Check warning on line 1 in crypto_test.go

View workflow job for this annotation

GitHub Actions / lint

var-naming: don't use an underscore in package name (revive)

import (
"fmt"

Check failure on line 4 in crypto_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `goimports`-ed (goimports)
"github.com/TBD54566975/vc-jose-cose-go/cid"
"github.com/TBD54566975/vc-jose-cose-go/util"
"github.com/goccy/go-json"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/stretchr/testify/require"
"testing"

"github.com/stretchr/testify/assert"
)

// TestGenerateKeys is used to generate sample cid document verification methods
func TestGenerateKeys(t *testing.T) {
t.Skip("skipping test as it is not needed except for local testing")

tests := []struct {
name string
curve jwa.EllipticCurveAlgorithm
kid string
}{
{"EC P-256", jwa.P256, "key-1"},
{"EC P-384", jwa.P384, "key-2"},
{"EC P-521", jwa.P521, "key-3"},
{"OKP EdDSA", jwa.Ed25519, "key-4"},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
key, err := util.GenerateJWK(tt.curve)
require.NoError(t, err)
assert.NotNil(t, key)

pubKey, err := key.PublicKey()
require.NoError(t, err)
assert.NotNil(t, pubKey)

id := "https://example.issuer/6c427e8392ab4057b93356fbb9022ecb"
vm := cid.VerificationMethod{
ID: fmt.Sprintf("%s#%s", id, tt.kid),
Type: cid.TypeJSONWebKey,
Controller: util.SingleOrArray[string]{id},
PublicKeyJWK: pubKey,
SecretKeyJWK: key,
}

vmJSONBytes, err := json.Marshal(vm)
require.NoError(t, err)
t.Logf("\n%s\n", string(vmJSONBytes))
})
}
}

func TestKeyToBytes(t *testing.T) {
for _, keyType := range util.GetSupportedKeyTypes() {
t.Run(string(keyType), func(t *testing.T) {
pub, priv, err := util.GenerateKeyByKeyType(keyType)

assert.NoError(t, err)
assert.NotEmpty(t, pub)
assert.NotEmpty(t, priv)

pubKeyBytes, err := util.PubKeyToBytes(pub)
assert.NoError(t, err)
assert.NotEmpty(t, pubKeyBytes)

reconstructedPub, err := util.BytesToPubKey(pubKeyBytes, keyType)
assert.NoError(t, err)
assert.NotEmpty(t, reconstructedPub)
assert.EqualValues(t, pub, reconstructedPub)

privKeyBytes, err := util.PrivKeyToBytes(priv)
assert.NoError(t, err)
assert.NotEmpty(t, privKeyBytes)

reconstructedPriv, err := util.BytesToPrivKey(privKeyBytes, keyType)
assert.NoError(t, err)
assert.NotEmpty(t, reconstructedPriv)
assert.EqualValues(t, priv, reconstructedPriv)

kt, err := util.GetKeyTypeFromPrivateKey(priv)
assert.NoError(t, err)
assert.Equal(t, keyType, kt)
})
}

for _, keyType := range util.GetSupportedKeyTypes() {
t.Run(string(keyType)+" with pointers", func(t *testing.T) {
pub, priv, err := util.GenerateKeyByKeyType(keyType)

assert.NoError(t, err)
assert.NotEmpty(t, pub)
assert.NotEmpty(t, priv)

pubKeyBytes, err := util.PubKeyToBytes(&pub)
assert.NoError(t, err)
assert.NotEmpty(t, pubKeyBytes)

reconstructedPub, err := util.BytesToPubKey(pubKeyBytes, keyType)
assert.NoError(t, err)
assert.NotEmpty(t, reconstructedPub)
assert.EqualValues(t, pub, reconstructedPub)

privKeyBytes, err := util.PrivKeyToBytes(&priv)
assert.NoError(t, err)
assert.NotEmpty(t, privKeyBytes)

reconstructedPriv, err := util.BytesToPrivKey(privKeyBytes, keyType)
assert.NoError(t, err)
assert.NotEmpty(t, reconstructedPriv)
assert.EqualValues(t, priv, reconstructedPriv)

kt, err := util.GetKeyTypeFromPrivateKey(&priv)
assert.NoError(t, err)
assert.Equal(t, keyType, kt)
})
}
}

func TestSECP256k1Conversions(t *testing.T) {
pk, sk, err := util.GenerateSECP256k1Key()
assert.NoError(t, err)

ecdsaPK := pk.ToECDSA()
ecdsaSK := sk.ToECDSA()

gotPK := util.SECP256k1ECDSAPubKeyToSECP256k1(*ecdsaPK)
gotSK := util.SECP256k1ECDSASPrivKeyToSECP256k1(*ecdsaSK)

assert.Equal(t, pk, gotPK)
assert.Equal(t, sk, gotSK)
}
29 changes: 15 additions & 14 deletions jose/jose.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,18 +114,18 @@ func VerifyVerifiableCredential(jwt string, key jwk.Key) (*credential.Verifiable
}

// SignVerifiablePresentation dynamically signs a VerifiablePresentation based on the key type.
func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Key) (string, error) {
func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Key) (*string, error) {
if vp.IsEmpty() {
return "", errors.New("VerifiablePresentation is empty")
return nil, errors.New("VerifiablePresentation is empty")
}
if key == nil {
return "", errors.New("key is required")
return nil, errors.New("key is required")
}
if key.KeyID() == "" {
return "", errors.New("key ID is required")
return nil, errors.New("key ID is required")
}
if key.Algorithm().String() == "" {
return "", errors.New("key algorithm is required")
return nil, errors.New("key algorithm is required")
}

var alg jwa.SignatureAlgorithm
Expand All @@ -134,7 +134,7 @@ func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Ke
case jwa.EC:
crv, ok := key.Get("crv")
if !ok || crv == nil {
return "", fmt.Errorf("invalid or missing 'crv' parameter")
return nil, fmt.Errorf("invalid or missing 'crv' parameter")
}
crvAlg := crv.(jwa.EllipticCurveAlgorithm)
switch crvAlg {
Expand All @@ -145,22 +145,22 @@ func SignVerifiablePresentation(vp credential.VerifiablePresentation, key jwk.Ke
case jwa.P521:
alg = jwa.ES512
default:
return "", fmt.Errorf("unsupported curve: %s", crvAlg.String())
return nil, fmt.Errorf("unsupported curve: %s", crvAlg.String())
}
case jwa.OKP:
alg = jwa.EdDSA
default:
return "", fmt.Errorf("unsupported key type: %s", kty)
return nil, fmt.Errorf("unsupported key type: %s", kty)
}

// Convert the VerifiablePresentation to a map for manipulation
vpMap := make(map[string]any)
vpBytes, err := json.Marshal(vp)
if err != nil {
return "", err
return nil, err
}
if err = json.Unmarshal(vpBytes, &vpMap); err != nil {
return "", err
return nil, err
}

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

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

// Sign the payload
signed, err := jws.Sign(payload, jws.WithKey(alg, key, jws.WithProtectedHeaders(jwsHeaders)))
if err != nil {
return "", err
return nil, err
}

return string(signed), nil
result := string(signed)
return &result, nil
}

// VerifyVerifiablePresentation verifies a VerifiablePresentation JWT using the provided key.
Expand Down
2 changes: 1 addition & 1 deletion jose/jose_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func Test_Sign_Verify_VerifiablePresentation(t *testing.T) {
assert.NotEmpty(t, jwt)

// Verify the VP
verifiedVP, err := VerifyVerifiablePresentation(jwt, key)
verifiedVP, err := VerifyVerifiablePresentation(*jwt, key)
require.NoError(t, err)
assert.Equal(t, vp.ID, verifiedVP.ID)
assert.Equal(t, vp.Holder.ID(), verifiedVP.Holder.ID())
Expand Down
87 changes: 0 additions & 87 deletions util/crypto_test.go

This file was deleted.

0 comments on commit 487d633

Please sign in to comment.