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 }