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

Commit

Permalink
fix: data-integrity ecdsa2019 signer uses common signer interface
Browse files Browse the repository at this point in the history
Signed-off-by: Filip Burlacu <[email protected]>
  • Loading branch information
Moopli committed Aug 28, 2023
1 parent 917ccf5 commit 8507677
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 61 deletions.
32 changes: 9 additions & 23 deletions component/models/dataintegrity/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ const (
)

func TestIntegration(t *testing.T) {
suiteOpts := suiteOptions(t)
docLoader, err := documentloader.NewDocumentLoader(createMockProvider())
require.NoError(t, err)

storeProv := mockstorage.NewMockStoreProvider()

Expand All @@ -52,16 +53,17 @@ func TestIntegration(t *testing.T) {
kms, err := localkms.New("local-lock://custom/master/key/", kmsProv)
require.NoError(t, err)

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

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

verifierInit := ecdsa2019.NewVerifierInitializer(&ecdsa2019.VerifierInitializerOptions{
LDDocumentLoader: suiteOpts.LDDocumentLoader,
Verifier: suiteOpts.Verifier,
KMS: suiteOpts.KMS,
LDDocumentLoader: docLoader,
Verifier: cr,
})

_, p256Bytes, err := kms.CreateAndExportPubKeyBytes(kmsapi.ECDSAP256IEEEP1363)
Expand Down Expand Up @@ -223,22 +225,6 @@ func TestIntegration(t *testing.T) {
})
}

func suiteOptions(t *testing.T) *ecdsa2019.Options {
t.Helper()

docLoader, err := documentloader.NewDocumentLoader(createMockProvider())
require.NoError(t, err)

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

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

type provider struct {
ContextStore store.ContextStore
RemoteProviderStore store.RemoteProviderStore
Expand Down
93 changes: 67 additions & 26 deletions component/models/dataintegrity/suite/ecdsa2019/ecdsa2019.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,58 @@ const (
SuiteType = "ecdsa-2019"
)

// A Signer is able to sign messages.
type Signer interface {
// SignerGetter returns a Signer, which must sign with the private key matching
// the public key provided in models.ProofOptions.VerificationMethod.
type SignerGetter func(pub *jwk.JWK) (Signer, error)

// WithStaticSigner sets the Suite to use a fixed Signer, with externally-chosen signing key.
//
// Use when a signing Suite is initialized for a single signature, then thrown away.
func WithStaticSigner(signer Signer) SignerGetter {
return func(*jwk.JWK) (Signer, error) {
return signer, nil
}

Check warning on line 46 in component/models/dataintegrity/suite/ecdsa2019/ecdsa2019.go

View check run for this annotation

Codecov / codecov/patch

component/models/dataintegrity/suite/ecdsa2019/ecdsa2019.go#L43-L46

Added lines #L43 - L46 were not covered by tests
}

// WithLocalKMSSigner returns a SignerGetter that will sign using the given localkms, using the private key matching
// the given public key.
func WithLocalKMSSigner(kms models.KeyManager, kmsSigner KMSSigner) SignerGetter {
return func(pub *jwk.JWK) (Signer, error) {
kid, err := kmsKID(pub)
if err != nil {
return nil, err
}

kh, err := kms.Get(kid)
if err != nil {
return nil, err
}

return &wrapSigner{
kmsSigner: kmsSigner,
kh: kh,
}, nil
}
}

// A KMSSigner is able to sign messages.
type KMSSigner interface {
// Sign will sign msg using a matching signature primitive in kh key handle of a private key
// returns:
// signature in []byte
// error in case of errors
Sign(msg []byte, kh interface{}) ([]byte, error)
}

// A Signer is able to sign messages.
type Signer interface {
// Sign will sign msg using a private key internal to the Signer.
// returns:
// signature in []byte
// error in case of errors
Sign(msg []byte) ([]byte, error)
}

// A Verifier is able to verify messages.
type Verifier interface {
// Verify will verify a signature for the given msg using a matching signature primitive in kh key handle of
Expand All @@ -53,18 +96,16 @@ type Verifier interface {

// Suite implements the ecdsa-2019 data integrity cryptographic suite.
type Suite struct {
ldLoader ld.DocumentLoader
signer Signer
verifier Verifier
kms models.KeyManager
ldLoader ld.DocumentLoader
signerGetter SignerGetter
verifier Verifier
}

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

// SuiteInitializer is the initializer for Suite.
Expand All @@ -74,10 +115,9 @@ type SuiteInitializer func() (suite.Suite, error)
func New(options *Options) SuiteInitializer {
return func() (suite.Suite, error) {
return &Suite{
ldLoader: options.LDDocumentLoader,
signer: options.Signer,
verifier: options.Verifier,
kms: options.KMS,
ldLoader: options.LDDocumentLoader,
signerGetter: options.SignerGetter,
verifier: options.Verifier,
}, nil
}
}
Expand All @@ -103,25 +143,22 @@ func (i initializer) Type() string {
// SignerInitializerOptions provides options for a SignerInitializer.
type SignerInitializerOptions struct {
LDDocumentLoader ld.DocumentLoader
Signer Signer
KMS models.KeyManager
SignerGetter SignerGetter
}

// NewSignerInitializer returns a suite.SignerInitializer that initializes an ecdsa-2019
// signing Suite with the given SignerInitializerOptions.
func NewSignerInitializer(options *SignerInitializerOptions) suite.SignerInitializer {
return initializer(New(&Options{
LDDocumentLoader: options.LDDocumentLoader,
Signer: options.Signer,
KMS: options.KMS,
SignerGetter: options.SignerGetter,
}))
}

// VerifierInitializerOptions provides options for a VerifierInitializer.
type VerifierInitializerOptions struct {
LDDocumentLoader ld.DocumentLoader
Verifier Verifier
KMS models.KeyManager
}

// NewVerifierInitializer returns a suite.VerifierInitializer that initializes an
Expand All @@ -130,7 +167,6 @@ func NewVerifierInitializer(options *VerifierInitializerOptions) suite.VerifierI
return initializer(New(&Options{
LDDocumentLoader: options.LDDocumentLoader,
Verifier: options.Verifier,
KMS: options.KMS,
}))
}

Expand All @@ -146,7 +182,7 @@ func (s *Suite) CreateProof(doc []byte, opts *models.ProofOptions) (*models.Proo
return nil, err
}

sig, err := sign(docHash, vmKey, s.signer, s.kms)
sig, err := sign(docHash, vmKey, s.signerGetter)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -294,18 +330,23 @@ func kmsKID(key *jwk.JWK) (string, error) {
return base64.RawURLEncoding.EncodeToString(tp), nil
}

func sign(sigBase []byte, key *jwk.JWK, signer Signer, kms models.KeyManager) ([]byte, error) {
kid, err := kmsKID(key)
if err != nil {
return nil, err
}
type wrapSigner struct {
kmsSigner KMSSigner
kh interface{}
}

// Sign signs using wrapped kms and key handle.
func (s *wrapSigner) Sign(msg []byte) ([]byte, error) {
return s.kmsSigner.Sign(msg, s.kh)
}

kh, err := kms.Get(kid)
func sign(sigBase []byte, key *jwk.JWK, signerGetter SignerGetter) ([]byte, error) {
signer, err := signerGetter(key)
if err != nil {
return nil, err
}

sig, err := signer.Sign(sigBase, kh)
sig, err := signer.Sign(sigBase)
if err != nil {
return nil, err
}
Expand Down
10 changes: 4 additions & 6 deletions component/models/dataintegrity/suite/ecdsa2019/ecdsa2019_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ func TestNew(t *testing.T) {
cryp := &mockcrypto.Crypto{}
kms := &mockkms.KeyManager{}

signerGetter := WithLocalKMSSigner(kms, cryp)

t.Run("signer success", func(t *testing.T) {
sigInit := NewSignerInitializer(&SignerInitializerOptions{
LDDocumentLoader: docLoader,
Signer: cryp,
KMS: kms,
SignerGetter: signerGetter,
})

signer, err := sigInit.Signer()
Expand All @@ -65,7 +66,6 @@ func TestNew(t *testing.T) {
verInit := NewVerifierInitializer(&VerifierInitializerOptions{
LDDocumentLoader: docLoader,
Verifier: cryp,
KMS: kms,
})

verifier, err := verInit.Verifier()
Expand Down Expand Up @@ -137,8 +137,7 @@ func successCase(t *testing.T) *testCase {
func testSign(t *testing.T, tc *testCase) {
sigInit := NewSignerInitializer(&SignerInitializerOptions{
LDDocumentLoader: tc.docLoader,
Signer: tc.crypto,
KMS: tc.kms,
SignerGetter: WithLocalKMSSigner(tc.kms, tc.crypto),
})

signer, err := sigInit.Signer()
Expand Down Expand Up @@ -167,7 +166,6 @@ func testVerify(t *testing.T, tc *testCase) {
verInit := NewVerifierInitializer(&VerifierInitializerOptions{
LDDocumentLoader: tc.docLoader,
Verifier: tc.crypto,
KMS: tc.kms,
})

verifier, err := verInit.Verifier()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ func TestIntegration(t *testing.T) {

signerInit := NewSignerInitializer(&SignerInitializerOptions{
LDDocumentLoader: docLoader,
Signer: cr,
KMS: kms,
SignerGetter: WithLocalKMSSigner(kms, cr),
})

signer, err := signerInit.Signer()
Expand All @@ -51,7 +50,6 @@ func TestIntegration(t *testing.T) {
verifierInit := NewVerifierInitializer(&VerifierInitializerOptions{
LDDocumentLoader: docLoader,
Verifier: cr,
KMS: kms,
})

verifier, err := verifierInit.Verifier()
Expand Down
4 changes: 1 addition & 3 deletions component/models/verifiable/data_integrity_proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ func Test_DataIntegrity_SignVerify(t *testing.T) {
})

signerSuite := ecdsa2019.NewSignerInitializer(&ecdsa2019.SignerInitializerOptions{
KMS: kms,
Signer: cr,
SignerGetter: ecdsa2019.WithLocalKMSSigner(kms, cr),
LDDocumentLoader: docLoader,
})

Expand All @@ -93,7 +92,6 @@ func Test_DataIntegrity_SignVerify(t *testing.T) {
}

verifySuite := ecdsa2019.NewVerifierInitializer(&ecdsa2019.VerifierInitializerOptions{
KMS: kms,
Verifier: cr,
LDDocumentLoader: docLoader,
})
Expand Down

0 comments on commit 8507677

Please sign in to comment.