github.com/trustbloc/kms-go@v1.1.2/crypto/tinkcrypto/primitive/secp256k1/verifier_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  	"errors"
    11  	"fmt"
    12  
    13  	"github.com/google/tink/go/core/cryptofmt"
    14  	"github.com/google/tink/go/core/primitiveset"
    15  	"github.com/google/tink/go/core/registry"
    16  	"github.com/google/tink/go/keyset"
    17  	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
    18  	"github.com/google/tink/go/tink"
    19  )
    20  
    21  // NewVerifier returns a Verifier primitive from the given keyset handle.
    22  func NewVerifier(h *keyset.Handle) (tink.Verifier, error) {
    23  	return NewVerifierWithKeyManager(h, nil /*keyManager*/)
    24  }
    25  
    26  // NewVerifierWithKeyManager returns a Verifier primitive from the given keyset handle and custom key manager.
    27  // Deprecated: register the KeyManager and use New above.
    28  func NewVerifierWithKeyManager(h *keyset.Handle, km registry.KeyManager) (tink.Verifier, error) {
    29  	ps, err := h.PrimitivesWithKeyManager(km)
    30  	if err != nil {
    31  		return nil, fmt.Errorf("verifier_factory: cannot obtain primitive set: %w", err)
    32  	}
    33  
    34  	return newWrappedVerifier(ps)
    35  }
    36  
    37  // verifierSet is a Verifier implementation that uses the
    38  // underlying primitive set for verifying.
    39  type wrappedVerifier struct {
    40  	ps *primitiveset.PrimitiveSet
    41  }
    42  
    43  // Asserts that verifierSet implements the Verifier interface.
    44  var _ tink.Verifier = (*wrappedVerifier)(nil)
    45  
    46  func newWrappedVerifier(ps *primitiveset.PrimitiveSet) (*wrappedVerifier, error) {
    47  	if _, ok := (ps.Primary.Primitive).(tink.Verifier); !ok {
    48  		return nil, fmt.Errorf("verifier_factory: not a Verifier primitive")
    49  	}
    50  
    51  	for _, primitives := range ps.Entries {
    52  		for _, p := range primitives {
    53  			if _, ok := (p.Primitive).(tink.Verifier); !ok {
    54  				return nil, fmt.Errorf("verifier_factory: not an Verifier primitive")
    55  			}
    56  		}
    57  	}
    58  
    59  	ret := new(wrappedVerifier)
    60  	ret.ps = ps
    61  
    62  	return ret, nil
    63  }
    64  
    65  var errInvalidSignature = errors.New("verifier_factory: invalid signature")
    66  
    67  // Verify checks whether the given signature is a valid signature of the given data.
    68  // nolint:gocyclo
    69  func (v *wrappedVerifier) Verify(signature, data []byte) error {
    70  	prefixSize := cryptofmt.NonRawPrefixSize
    71  	if len(signature) < prefixSize {
    72  		return errInvalidSignature
    73  	}
    74  
    75  	// try non-raw keys
    76  	prefix := signature[:prefixSize]
    77  	signatureNoPrefix := signature[prefixSize:]
    78  
    79  	entries, err := v.ps.EntriesForPrefix(string(prefix))
    80  	if err == nil {
    81  		for i := 0; i < len(entries); i++ {
    82  			var signedData []byte
    83  			if entries[i].PrefixType == tinkpb.OutputPrefixType_LEGACY {
    84  				signedData = append(data, byte(0)) //nolint:gocritic
    85  			} else {
    86  				signedData = data
    87  			}
    88  
    89  			verifier, ok := (entries[i].Primitive).(tink.Verifier)
    90  			if !ok {
    91  				return fmt.Errorf("verifier_factory: not an Verifier primitive")
    92  			}
    93  
    94  			if err = verifier.Verify(signatureNoPrefix, signedData); err == nil {
    95  				return nil
    96  			}
    97  		}
    98  	}
    99  
   100  	// try raw keys
   101  	entries, err = v.ps.RawEntries()
   102  	if err == nil {
   103  		for i := 0; i < len(entries); i++ {
   104  			verifier, ok := (entries[i].Primitive).(tink.Verifier)
   105  			if !ok {
   106  				return fmt.Errorf("verifier_factory: not an Verifier primitive")
   107  			}
   108  
   109  			if err = verifier.Verify(signature, data); err == nil {
   110  				return nil
   111  			}
   112  		}
   113  	}
   114  
   115  	return errInvalidSignature
   116  }