github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/secp256k1/signer_factory.go (about)

     1  /*
     2  Copyright SecureKey Technologies Inc. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package secp256k1
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/google/tink/go/core/primitiveset"
    13  	"github.com/google/tink/go/core/registry"
    14  	"github.com/google/tink/go/keyset"
    15  	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
    16  	"github.com/google/tink/go/tink"
    17  )
    18  
    19  // NewSigner returns a Signer primitive from the given keyset handle.
    20  func NewSigner(h *keyset.Handle) (tink.Signer, error) {
    21  	return NewSignerWithKeyManager(h, nil /*keyManager*/)
    22  }
    23  
    24  // NewSignerWithKeyManager returns a Signer primitive from the given keyset handle and custom key manager.
    25  // Deprecated: register the KeyManager and use New above.
    26  func NewSignerWithKeyManager(h *keyset.Handle, km registry.KeyManager) (tink.Signer, error) {
    27  	ps, err := h.PrimitivesWithKeyManager(km)
    28  	if err != nil {
    29  		return nil, fmt.Errorf("public_key_sign_factory: cannot obtain primitive set: %w", err)
    30  	}
    31  
    32  	return newWrappedSigner(ps)
    33  }
    34  
    35  // wrappedSigner is an Signer implementation that uses the underlying primitive set for signing.
    36  type wrappedSigner struct {
    37  	ps *primitiveset.PrimitiveSet
    38  }
    39  
    40  // Asserts that wrappedSigner implements the Signer interface.
    41  var _ tink.Signer = (*wrappedSigner)(nil)
    42  
    43  func newWrappedSigner(ps *primitiveset.PrimitiveSet) (*wrappedSigner, error) {
    44  	if _, ok := (ps.Primary.Primitive).(tink.Signer); !ok {
    45  		return nil, fmt.Errorf("public_key_sign_factory: not a Signer primitive")
    46  	}
    47  
    48  	for _, primitives := range ps.Entries {
    49  		for _, p := range primitives {
    50  			if _, ok := (p.Primitive).(tink.Signer); !ok {
    51  				return nil, fmt.Errorf("public_key_sign_factory: not an Signer primitive")
    52  			}
    53  		}
    54  	}
    55  
    56  	ret := new(wrappedSigner)
    57  	ret.ps = ps
    58  
    59  	return ret, nil
    60  }
    61  
    62  // Sign signs the given data and returns the signature concatenated with the identifier of the
    63  // primary primitive.
    64  func (s *wrappedSigner) Sign(data []byte) ([]byte, error) {
    65  	primary := s.ps.Primary
    66  
    67  	signer, ok := (primary.Primitive).(tink.Signer)
    68  	if !ok {
    69  		return nil, fmt.Errorf("public_key_sign_factory: not a Signer primitive")
    70  	}
    71  
    72  	var signedData []byte
    73  	if primary.PrefixType == tinkpb.OutputPrefixType_LEGACY {
    74  		signedData = append(signedData, data...)
    75  		signedData = append(signedData, byte(0))
    76  	} else {
    77  		signedData = data
    78  	}
    79  
    80  	signature, err := signer.Sign(signedData)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	return append([]byte(primary.Prefix), signature...), nil
    86  }