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

Commit

Permalink
feat: change KMS interface for Data Integrity (#3621)
Browse files Browse the repository at this point in the history
Signed-off-by: Mykhailo Sizov <[email protected]>
  • Loading branch information
mishasizov-SK authored Aug 22, 2023
1 parent cce322d commit 25cbbcb
Show file tree
Hide file tree
Showing 8 changed files with 45 additions and 41 deletions.
2 changes: 1 addition & 1 deletion component/kmscrypto/kms/localkms/localkms.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ func (l *LocalKMS) CreateAndExportPubKeyBytes(kt kmsapi.KeyType, opts ...kmsapi.
// Note: The key handle created is not stored in the KMS, it's only useful to execute the crypto primitive
// associated with it.
func (l *LocalKMS) PubKeyBytesToHandle(pubKey []byte, kt kmsapi.KeyType, opts ...kmsapi.KeyOpts) (interface{}, error) {
return publicKeyBytesToHandle(pubKey, kt, opts...)
return PublicKeyBytesToHandle(pubKey, kt, opts...)
}

// ImportPrivateKey will import privKey into the KMS storage for the given keyType then returns the new key id and
Expand Down
18 changes: 9 additions & 9 deletions component/kmscrypto/kms/localkms/pubkey_export_import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func TestPubKeyExportAndRead(t *testing.T) {
t.Run(tt.tcName, func(t *testing.T) {
exportedKeyBytes, origKH := exportRawPublicKeyBytes(t, tt.keyTemplate, false)

kh, err := publicKeyBytesToHandle(exportedKeyBytes, tt.keyType)
kh, err := PublicKeyBytesToHandle(exportedKeyBytes, tt.keyType)
require.NoError(t, err)
require.NotEmpty(t, kh)

Expand Down Expand Up @@ -179,49 +179,49 @@ func exportRawPublicKeyBytes(t *testing.T, keyTemplate *tinkpb.KeyTemplate, expe

func TestNegativeCases(t *testing.T) {
t.Run("test publicKeyBytesToHandle with empty pubKey", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{}, kms.ECDSAP256TypeIEEEP1363)
kh, err := PublicKeyBytesToHandle([]byte{}, kms.ECDSAP256TypeIEEEP1363)
require.EqualError(t, err, "pubKey is empty")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with empty KeyType", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, "")
kh, err := PublicKeyBytesToHandle([]byte{1}, "")
require.EqualError(t, err, "error getting marshalled proto key: invalid key type")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP256TypeDER", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, kms.ECDSAP256TypeDER)
kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP256TypeDER)
require.EqualError(t, err, "error getting marshalled proto key: asn1: syntax error: truncated tag or length")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP256TypeIEEEP1363", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, kms.ECDSAP256TypeIEEEP1363)
kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP256TypeIEEEP1363)
require.EqualError(t, err, "error getting marshalled proto key: failed to unamrshal public ecdsa key")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP384TypeDER", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, kms.ECDSAP384TypeDER)
kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP384TypeDER)
require.EqualError(t, err, "error getting marshalled proto key: asn1: syntax error: truncated tag or length")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP384TypeIEEEP1363", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, kms.ECDSAP384TypeIEEEP1363)
kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP384TypeIEEEP1363)
require.EqualError(t, err, "error getting marshalled proto key: failed to unamrshal public ecdsa key")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP521TypeDER", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, kms.ECDSAP521TypeDER)
kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP521TypeDER)
require.EqualError(t, err, "error getting marshalled proto key: asn1: syntax error: truncated tag or length")
require.Empty(t, kh)
})

t.Run("test publicKeyBytesToHandle with bad pubKey and ECDSAP521TypeIEEEP1363", func(t *testing.T) {
kh, err := publicKeyBytesToHandle([]byte{1}, kms.ECDSAP521TypeIEEEP1363)
kh, err := PublicKeyBytesToHandle([]byte{1}, kms.ECDSAP521TypeIEEEP1363)
require.EqualError(t, err, "error getting marshalled proto key: failed to unamrshal public ecdsa key")
require.Empty(t, kh)
})
Expand Down
6 changes: 5 additions & 1 deletion component/kmscrypto/kms/localkms/pubkey_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ import (
secp256k1subtle "github.com/hyperledger/aries-framework-go/component/kmscrypto/crypto/tinkcrypto/primitive/secp256k1/subtle"
)

func publicKeyBytesToHandle(pubKey []byte, kt kms.KeyType, opts ...kms.KeyOpts) (*keyset.Handle, error) {
// PublicKeyBytesToHandle will create and return a key handle for pubKey of type kt
// it returns an error if it failed creating the key handle
// Note: The key handle created is not stored in the KMS, it's only useful to execute the crypto primitive
// associated with it.
func PublicKeyBytesToHandle(pubKey []byte, kt kms.KeyType, opts ...kms.KeyOpts) (*keyset.Handle, error) {
if len(pubKey) == 0 {
return nil, fmt.Errorf("pubKey is empty")
}
Expand Down
23 changes: 11 additions & 12 deletions component/models/dataintegrity/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,18 @@ const (
func TestIntegration(t *testing.T) {
suiteOpts := suiteOptions(t)

storeProv := mockstorage.NewMockStoreProvider()

kmsProv, err := mockkms.NewProviderForKMS(storeProv, &noop.NoLock{})
require.NoError(t, err)

kms, err := localkms.New("local-lock://custom/master/key/", kmsProv)
require.NoError(t, err)

signerInit := ecdsa2019.NewSignerInitializer(&ecdsa2019.SignerInitializerOptions{
LDDocumentLoader: suiteOpts.LDDocumentLoader,
Signer: suiteOpts.Signer,
KMS: suiteOpts.KMS,
KMS: kms,
})

verifierInit := ecdsa2019.NewVerifierInitializer(&ecdsa2019.VerifierInitializerOptions{
Expand All @@ -55,13 +63,13 @@ func TestIntegration(t *testing.T) {
KMS: suiteOpts.KMS,
})

_, p256Bytes, err := suiteOpts.KMS.CreateAndExportPubKeyBytes(kmsapi.ECDSAP256IEEEP1363)
_, p256Bytes, err := kms.CreateAndExportPubKeyBytes(kmsapi.ECDSAP256IEEEP1363)
require.NoError(t, err)

p256JWK, err := jwkkid.BuildJWK(p256Bytes, kmsapi.ECDSAP256IEEEP1363)
require.NoError(t, err)

_, p384Bytes, err := suiteOpts.KMS.CreateAndExportPubKeyBytes(kmsapi.ECDSAP384IEEEP1363)
_, p384Bytes, err := kms.CreateAndExportPubKeyBytes(kmsapi.ECDSAP384IEEEP1363)
require.NoError(t, err)

p384JWK, err := jwkkid.BuildJWK(p384Bytes, kmsapi.ECDSAP384IEEEP1363)
Expand Down Expand Up @@ -188,22 +196,13 @@ func suiteOptions(t *testing.T) *ecdsa2019.Options {
docLoader, err := documentloader.NewDocumentLoader(createMockProvider())
require.NoError(t, err)

storeProv := mockstorage.NewMockStoreProvider()

kmsProv, err := mockkms.NewProviderForKMS(storeProv, &noop.NoLock{})
require.NoError(t, err)

kms, err := localkms.New("local-lock://custom/master/key/", kmsProv)
require.NoError(t, err)

cr, err := tinkcrypto.New()
require.NoError(t, err)

return &ecdsa2019.Options{
LDDocumentLoader: docLoader,
Signer: cr,
Verifier: cr,
KMS: kms,
}
}

Expand Down
9 changes: 9 additions & 0 deletions component/models/dataintegrity/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ const (
DataIntegrityProof = "DataIntegrityProof"
)

// KeyManager manages keys and their storage for the aries framework.
type KeyManager interface {
// Get key handle for the given keyID
// Returns:
// - handle instance (to private key)
// - error if failure
Get(keyID string) (interface{}, error)
}

// VerificationMethod implements the data integrity verification method model:
// https://www.w3.org/TR/vc-data-integrity/#verification-methods
type VerificationMethod = did.VerificationMethod
Expand Down
15 changes: 8 additions & 7 deletions component/models/dataintegrity/suite/ecdsa2019/ecdsa2019.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
kmsapi "github.com/hyperledger/aries-framework-go/spi/kms"

"github.com/hyperledger/aries-framework-go/component/kmscrypto/doc/jose/jwk"
"github.com/hyperledger/aries-framework-go/component/kmscrypto/kms/localkms"
"github.com/hyperledger/aries-framework-go/component/models/dataintegrity/models"
"github.com/hyperledger/aries-framework-go/component/models/dataintegrity/suite"
"github.com/hyperledger/aries-framework-go/component/models/ld/processor"
Expand Down Expand Up @@ -57,15 +58,15 @@ type Suite struct {
ldLoader ld.DocumentLoader
signer Signer
verifier Verifier
kms kmsapi.KeyManager
kms models.KeyManager
}

// Options provides initialization options for Suite.
type Options struct {
LDDocumentLoader ld.DocumentLoader
Signer Signer
Verifier Verifier
KMS kmsapi.KeyManager
KMS models.KeyManager
}

// SuiteInitializer is the initializer for Suite.
Expand Down Expand Up @@ -122,7 +123,7 @@ func NewSignerInitializer(options *SignerInitializerOptions) suite.SignerInitial
type VerifierInitializerOptions struct {
LDDocumentLoader ld.DocumentLoader
Verifier Verifier
KMS kmsapi.KeyManager
KMS models.KeyManager
}

// NewVerifierInitializer returns a suite.VerifierInitializer that initializes an
Expand Down Expand Up @@ -231,7 +232,7 @@ func (s *Suite) VerifyProof(doc []byte, proof *models.Proof, opts *models.ProofO
return fmt.Errorf("decoding proofValue: %w", err)
}

err = verify(sigBase, sig, vmKey, s.verifier, s.kms)
err = verify(sigBase, sig, vmKey, s.verifier)
if err != nil {
return fmt.Errorf("failed to verify ecdsa-2019 DI proof: %w", err)
}
Expand Down Expand Up @@ -294,7 +295,7 @@ func kmsKID(key *jwk.JWK) (string, error) {
return base64.RawURLEncoding.EncodeToString(tp), nil
}

func sign(sigBase []byte, key *jwk.JWK, signer Signer, kms kmsapi.KeyManager) ([]byte, error) {
func sign(sigBase []byte, key *jwk.JWK, signer Signer, kms models.KeyManager) ([]byte, error) {
kid, err := kmsKID(key)
if err != nil {
return nil, err
Expand All @@ -313,7 +314,7 @@ func sign(sigBase []byte, key *jwk.JWK, signer Signer, kms kmsapi.KeyManager) ([
return sig, nil
}

func verify(sigBase, sig []byte, key *jwk.JWK, verifier Verifier, kms kmsapi.KeyManager) error {
func verify(sigBase, sig []byte, key *jwk.JWK, verifier Verifier) error {
pkBytes, err := key.PublicKeyBytes()
if err != nil {
return fmt.Errorf("getting verification key bytes: %w", err)
Expand All @@ -324,7 +325,7 @@ func verify(sigBase, sig []byte, key *jwk.JWK, verifier Verifier, kms kmsapi.Key
return fmt.Errorf("getting key type of verification key: %w", err)
}

kh, err := kms.PubKeyBytesToHandle(pkBytes, kt)
kh, err := localkms.PublicKeyBytesToHandle(pkBytes, kt)
if err != nil {
return err
}
Expand Down
11 changes: 0 additions & 11 deletions component/models/dataintegrity/suite/ecdsa2019/ecdsa2019_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -285,17 +285,6 @@ func TestSuite_VerifyProof(t *testing.T) {
testVerify(t, tc)
})

t.Run("get kms key handle", func(t *testing.T) {
tc := successCase(t)

errExpected := errors.New("expected error")

tc.kms.PubKeyBytesToHandleErr = errExpected
tc.errIs = errExpected

testVerify(t, tc)
})

t.Run("crypto verify", func(t *testing.T) {
tc := successCase(t)

Expand Down
2 changes: 2 additions & 0 deletions component/models/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)

replace github.com/hyperledger/aries-framework-go/component/kmscrypto => ../kmscrypto

0 comments on commit 25cbbcb

Please sign in to comment.