diff --git a/signature/BUILD.bazel b/signature/BUILD.bazel index f3df3bb..8218091 100644 --- a/signature/BUILD.bazel +++ b/signature/BUILD.bazel @@ -7,9 +7,6 @@ licenses(["notice"]) # keep go_library( name = "signature", srcs = [ - "ecdsa_signer_key_manager.go", - "ecdsa_verifier_key_manager.go", - "proto.go", "rsa.go", "rsassapkcs1_signer_key_manager.go", "rsassapkcs1_verifier_key_manager.go", @@ -37,9 +34,8 @@ go_library( "//proto/rsa_ssa_pkcs1_go_proto", "//proto/rsa_ssa_pss_go_proto", "//proto/tink_go_proto", + "//signature/ecdsa", "//signature/ed25519", - "//signature/subtle", - "//subtle", "//tink", "@org_golang_google_protobuf//proto", ], @@ -48,8 +44,6 @@ go_library( go_test( name = "signature_test", srcs = [ - "ecdsa_signer_key_manager_test.go", - "ecdsa_verifier_key_manager_test.go", "rsassapkcs1_signer_key_manager_test.go", "rsassapkcs1_verifier_key_manager_test.go", "rsassapss_signer_key_manager_test.go", @@ -71,11 +65,9 @@ go_test( "//mac", "//monitoring", "//proto/common_go_proto", - "//proto/ecdsa_go_proto", "//proto/rsa_ssa_pkcs1_go_proto", "//proto/rsa_ssa_pss_go_proto", "//proto/tink_go_proto", - "//signature/subtle", "//subtle/random", "//testing/fakemonitoring", "//testkeyset", diff --git a/signature/ecdsa/BUILD.bazel b/signature/ecdsa/BUILD.bazel new file mode 100644 index 0000000..1b3feb0 --- /dev/null +++ b/signature/ecdsa/BUILD.bazel @@ -0,0 +1,48 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "ecdsa", + srcs = [ + "ecdsa.go", + "proto.go", + "signer_key_manager.go", + "verifier_key_manager.go", + ], + importpath = "github.com/tink-crypto/tink-go/v2/signature/ecdsa", + visibility = ["//visibility:public"], + deps = [ + "//core/registry", + "//keyset", + "//proto/common_go_proto", + "//proto/ecdsa_go_proto", + "//proto/tink_go_proto", + "//signature/subtle", + "//subtle", + "@org_golang_google_protobuf//proto", + ], +) + +alias( + name = "go_default_library", + actual = ":ecdsa", + visibility = ["//visibility:public"], +) + +go_test( + name = "ecdsa_test", + srcs = [ + "signer_key_manager_test.go", + "verifier_key_manager_test.go", + ], + deps = [ + ":ecdsa", + "//core/registry", + "//proto/common_go_proto", + "//proto/ecdsa_go_proto", + "//proto/tink_go_proto", + "//signature/subtle", + "//subtle/random", + "//testutil", + "@org_golang_google_protobuf//proto", + ], +) diff --git a/signature/ecdsa/ecdsa.go b/signature/ecdsa/ecdsa.go new file mode 100644 index 0000000..8889140 --- /dev/null +++ b/signature/ecdsa/ecdsa.go @@ -0,0 +1,32 @@ +// Copyright 2024 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package ecdsa provides ECDSA keys and parameters definitions, and key +// managers. +package ecdsa + +import ( + "fmt" + + "github.com/tink-crypto/tink-go/v2/core/registry" +) + +func init() { + if err := registry.RegisterKeyManager(new(signerKeyManager)); err != nil { + panic(fmt.Sprintf("ecdsa.init() failed: %v", err)) + } + if err := registry.RegisterKeyManager(new(verifierKeyManager)); err != nil { + panic(fmt.Sprintf("ecdsa.init() failed: %v", err)) + } +} diff --git a/signature/proto.go b/signature/ecdsa/proto.go similarity index 55% rename from signature/proto.go rename to signature/ecdsa/proto.go index b708243..544c033 100644 --- a/signature/proto.go +++ b/signature/ecdsa/proto.go @@ -12,37 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -package signature +package ecdsa import ( commonpb "github.com/tink-crypto/tink-go/v2/proto/common_go_proto" ecdsapb "github.com/tink-crypto/tink-go/v2/proto/ecdsa_go_proto" ) -// getECDSAParamNames returns the string representations of each parameter in -// the given ECDSAParams. -func getECDSAParamNames(params *ecdsapb.EcdsaParams) (string, string, string) { +// paramNames returns the string representations of each parameter in +// [ecdsapb.EcdsaParams]. +func paramNames(params *ecdsapb.EcdsaParams) (string, string, string) { hashName := commonpb.HashType_name[int32(params.GetHashType())] curveName := commonpb.EllipticCurveType_name[int32(params.GetCurve())] encodingName := ecdsapb.EcdsaSignatureEncoding_name[int32(params.GetEncoding())] return hashName, curveName, encodingName } - -// newECDSAPrivateKey creates a ECDSAPrivateKey with the specified paramaters. -func newECDSAPrivateKey(version uint32, publicKey *ecdsapb.EcdsaPublicKey, keyValue []byte) *ecdsapb.EcdsaPrivateKey { - return &ecdsapb.EcdsaPrivateKey{ - Version: version, - PublicKey: publicKey, - KeyValue: keyValue, - } -} - -// newECDSAPublicKey creates a ECDSAPublicKey with the specified paramaters. -func newECDSAPublicKey(version uint32, params *ecdsapb.EcdsaParams, x, y []byte) *ecdsapb.EcdsaPublicKey { - return &ecdsapb.EcdsaPublicKey{ - Version: version, - Params: params, - X: x, - Y: y, - } -} diff --git a/signature/ecdsa_signer_key_manager.go b/signature/ecdsa/signer_key_manager.go similarity index 53% rename from signature/ecdsa_signer_key_manager.go rename to signature/ecdsa/signer_key_manager.go index 63606e5..486ab41 100644 --- a/signature/ecdsa_signer_key_manager.go +++ b/signature/ecdsa/signer_key_manager.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package signature +package ecdsa import ( "crypto/ecdsa" @@ -30,31 +30,33 @@ import ( ) const ( - ecdsaSignerKeyVersion = 0 - ecdsaSignerTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey" + signerKeyVersion = 0 + signerTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey" ) // common errors -var errInvalidECDSASignKey = errors.New("ecdsa_signer_key_manager: invalid key") -var errInvalidECDSASignKeyFormat = errors.New("ecdsa_signer_key_manager: invalid key format") +var errInvalidSignKey = errors.New("ecdsa_signer_key_manager: invalid key") +var errInvalidSignKeyFormat = errors.New("ecdsa_signer_key_manager: invalid key format") -// ecdsaSignerKeyManager is an implementation of KeyManager interface. -// It generates new ECDSAPrivateKeys and produces new instances of ECDSASign subtle. -type ecdsaSignerKeyManager struct{} +// signerKeyManager is an implementation of KeyManager interface. +// It generates new ECDSA private keys and produces new instances of +// [subtleSignature.ECDSASigner]. +type signerKeyManager struct{} -// Primitive creates an ECDSASign subtle for the given serialized ECDSAPrivateKey proto. -func (km *ecdsaSignerKeyManager) Primitive(serializedKey []byte) (any, error) { +// Primitive creates an [subtleSignature.ECDSASigner] for the given serialized +// [ecdsapb.EcdsaPrivateKey] proto. +func (km *signerKeyManager) Primitive(serializedKey []byte) (any, error) { if len(serializedKey) == 0 { - return nil, errInvalidECDSASignKey + return nil, errInvalidSignKey } key := new(ecdsapb.EcdsaPrivateKey) if err := proto.Unmarshal(serializedKey, key); err != nil { - return nil, errInvalidECDSASignKey + return nil, errInvalidSignKey } if err := km.validateKey(key); err != nil { return nil, err } - hash, curve, encoding := getECDSAParamNames(key.GetPublicKey().GetParams()) + hash, curve, encoding := paramNames(key.GetPublicKey().GetParams()) ret, err := subtleSignature.NewECDSASigner(hash, curve, encoding, key.KeyValue) if err != nil { return nil, fmt.Errorf("ecdsa_signer_key_manager: %s", err) @@ -62,10 +64,11 @@ func (km *ecdsaSignerKeyManager) Primitive(serializedKey []byte) (any, error) { return ret, nil } -// NewKey creates a new ECDSAPrivateKey according to specification the given serialized ECDSAKeyFormat. -func (km *ecdsaSignerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { +// NewKey creates a new [ecdsapb.EcdsaPrivateKey] according to specification +// the given serialized [ecdsapb.EcdsaKeyFormat]. +func (km *signerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { if len(serializedKeyFormat) == 0 { - return nil, errInvalidECDSASignKeyFormat + return nil, errInvalidSignKeyFormat } keyFormat := new(ecdsapb.EcdsaKeyFormat) if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil { @@ -83,74 +86,82 @@ func (km *ecdsaSignerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Messa } keyValue := tmpKey.D.Bytes() - pub := newECDSAPublicKey(ecdsaSignerKeyVersion, params, tmpKey.X.Bytes(), tmpKey.Y.Bytes()) - priv := newECDSAPrivateKey(ecdsaSignerKeyVersion, pub, keyValue) + priv := &ecdsapb.EcdsaPrivateKey{ + Version: signerKeyVersion, + PublicKey: &ecdsapb.EcdsaPublicKey{ + Version: signerKeyVersion, + Params: params, + X: tmpKey.X.Bytes(), + Y: tmpKey.Y.Bytes(), + }, + KeyValue: keyValue, + } return priv, nil } -// NewKeyData creates a new KeyData according to specification in the given -// serialized ECDSAKeyFormat. It should be used solely by the key management API. -func (km *ecdsaSignerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { +// NewKeyData creates a new [tinkpb.KeyData] according to specification in then +// give serialized [ecdsapb.EcdsaKeyFormat]. It should be used solely by the +// key management API. +func (km *signerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { key, err := km.NewKey(serializedKeyFormat) if err != nil { return nil, err } serializedKey, err := proto.Marshal(key) if err != nil { - return nil, errInvalidECDSASignKeyFormat + return nil, errInvalidSignKeyFormat } return &tinkpb.KeyData{ - TypeUrl: ecdsaSignerTypeURL, + TypeUrl: signerTypeURL, Value: serializedKey, KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE, }, nil } -// PublicKeyData extracts the public key data from the private key. -func (km *ecdsaSignerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) { +// PublicKeyData extracts the public key as [tinkpb.KeyData] from the private +// key. +func (km *signerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) { privKey := new(ecdsapb.EcdsaPrivateKey) if err := proto.Unmarshal(serializedPrivKey, privKey); err != nil { - return nil, errInvalidECDSASignKey + return nil, errInvalidSignKey } if err := km.validateKey(privKey); err != nil { return nil, err } serializedPubKey, err := proto.Marshal(privKey.PublicKey) if err != nil { - return nil, errInvalidECDSASignKey + return nil, errInvalidSignKey } return &tinkpb.KeyData{ - TypeUrl: ecdsaVerifierTypeURL, + TypeUrl: verifierTypeURL, Value: serializedPubKey, KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC, }, nil } // DoesSupport indicates if this key manager supports the given key type. -func (km *ecdsaSignerKeyManager) DoesSupport(typeURL string) bool { - return typeURL == ecdsaSignerTypeURL +func (km *signerKeyManager) DoesSupport(typeURL string) bool { + return typeURL == signerTypeURL } // TypeURL returns the key type of keys managed by this key manager. -func (km *ecdsaSignerKeyManager) TypeURL() string { - return ecdsaSignerTypeURL -} +func (km *signerKeyManager) TypeURL() string { return signerTypeURL } -// validateKey validates the given ECDSAPrivateKey. -func (km *ecdsaSignerKeyManager) validateKey(key *ecdsapb.EcdsaPrivateKey) error { - if err := keyset.ValidateKeyVersion(key.Version, ecdsaSignerKeyVersion); err != nil { - return fmt.Errorf("ecdsa_signer_key_manager: invalid key: %s", err) +// validateKey validates the given [ecdsapb.EcdsaPrivateKey]. +func (km *signerKeyManager) validateKey(key *ecdsapb.EcdsaPrivateKey) error { + if err := keyset.ValidateKeyVersion(key.Version, signerKeyVersion); err != nil { + return fmt.Errorf("invalid key version in key: %s", err) } - if err := keyset.ValidateKeyVersion(key.GetPublicKey().GetVersion(), ecdsaSignerKeyVersion); err != nil { - return fmt.Errorf("ecdsa_signer_key_manager: invalid key: %s", err) + if err := keyset.ValidateKeyVersion(key.GetPublicKey().GetVersion(), signerKeyVersion); err != nil { + return fmt.Errorf("invalid public version in key: %s", err) } - hash, curve, encoding := getECDSAParamNames(key.GetPublicKey().GetParams()) + hash, curve, encoding := paramNames(key.GetPublicKey().GetParams()) return subtleSignature.ValidateECDSAParams(hash, curve, encoding) } -// validateKeyFormat validates the given ECDSAKeyFormat. -func (km *ecdsaSignerKeyManager) validateKeyFormat(format *ecdsapb.EcdsaKeyFormat) error { - hash, curve, encoding := getECDSAParamNames(format.GetParams()) +// validateKeyFormat validates the given [ecdsapb.EcdsaKeyFormat]. +func (km *signerKeyManager) validateKeyFormat(format *ecdsapb.EcdsaKeyFormat) error { + hash, curve, encoding := paramNames(format.GetParams()) return subtleSignature.ValidateECDSAParams(hash, curve, encoding) } diff --git a/signature/ecdsa_signer_key_manager_test.go b/signature/ecdsa/signer_key_manager_test.go similarity index 67% rename from signature/ecdsa_signer_key_manager_test.go rename to signature/ecdsa/signer_key_manager_test.go index 41d016e..9133d7e 100644 --- a/signature/ecdsa_signer_key_manager_test.go +++ b/signature/ecdsa/signer_key_manager_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package signature_test +package ecdsa_test import ( "fmt" @@ -21,6 +21,7 @@ import ( "google.golang.org/protobuf/proto" "github.com/tink-crypto/tink-go/v2/core/registry" + _ "github.com/tink-crypto/tink-go/v2/signature/ecdsa" // register ECDSA key managers "github.com/tink-crypto/tink-go/v2/signature/subtle" "github.com/tink-crypto/tink-go/v2/subtle/random" "github.com/tink-crypto/tink-go/v2/testutil" @@ -34,37 +35,36 @@ type ecdsaParams struct { curve commonpb.EllipticCurveType } -func TestECDSASignerGetPrimitiveBasic(t *testing.T) { +func TestSignerKeyManagerGetPrimitiveBasic(t *testing.T) { testParams := genValidECDSAParams() - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) } for i := 0; i < len(testParams); i++ { serializedKey, err := proto.Marshal(testutil.NewRandomECDSAPrivateKey(testParams[i].hashType, testParams[i].curve)) if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - _, err = km.Primitive(serializedKey) + _, err = keyManager.Primitive(serializedKey) if err != nil { t.Errorf("unexpect error in test case %d: %s ", i, err) } } } -func TestECDSASignGetPrimitiveWithInvalidInput(t *testing.T) { - // invalid params +func TestSignerKeyManagerGetPrimitiveWithInvalidInput_InvalidParams(t *testing.T) { testParams := genInvalidECDSAParams() - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) } for i := 0; i < len(testParams); i++ { serializedKey, err := proto.Marshal(testutil.NewRandomECDSAPrivateKey(testParams[i].hashType, testParams[i].curve)) if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKey); err == nil { + if _, err := keyManager.Primitive(serializedKey); err == nil { t.Errorf("expect an error in test case %d", i) } } @@ -76,12 +76,17 @@ func TestECDSASignGetPrimitiveWithInvalidInput(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKey); err == nil { + if _, err := keyManager.Primitive(serializedKey); err == nil { t.Errorf("expect an error in test case with params: (curve = %q, hash = %q)", tc.curve, tc.hashType) } } +} - // invalid version +func TestSignerKeyManagerGetPrimitiveWithInvalidInput_InvalidVersion(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + if err != nil { + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) + } key := testutil.NewRandomECDSAPrivateKey(commonpb.HashType_SHA256, commonpb.EllipticCurveType_NIST_P256) key.Version = testutil.ECDSASignerKeyVersion + 1 @@ -89,17 +94,24 @@ func TestECDSASignGetPrimitiveWithInvalidInput(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKey); err == nil { + if _, err := keyManager.Primitive(serializedKey); err == nil { t.Errorf("expect an error when version is invalid") } - // nil input - if _, err := km.Primitive(nil); err == nil { +} + +func TestSignerKeyManagerGetPrimitiveWithInvalidInput_NilInputAndParams(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + if err != nil { + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) + } + // Nil or empty input. + if _, err := keyManager.Primitive(nil); err == nil { t.Errorf("expect an error when input is nil") } - if _, err := km.Primitive([]byte{}); err == nil { + if _, err := keyManager.Primitive([]byte{}); err == nil { t.Errorf("expect an error when input is empty slice") } - // nil params field + // Nil params field. keyNilParams := testutil.NewRandomECDSAPrivateKey(commonpb.HashType_SHA256, commonpb.EllipticCurveType_NIST_P256) keyNilParams.GetPublicKey().Params = nil @@ -107,16 +119,16 @@ func TestECDSASignGetPrimitiveWithInvalidInput(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKeyNilParams); err == nil { - t.Errorf("km.Primitive(serializedKeyNilParams) err = nil, want not nil") + if _, err := keyManager.Primitive(serializedKeyNilParams); err == nil { + t.Errorf("keyManager.Primitive(serializedKeyNilParams) err = nil, want not nil") } } -func TestECDSASignNewKeyBasic(t *testing.T) { +func TestSignerKeyManagerNewKeyBasic(t *testing.T) { testParams := genValidECDSAParams() - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("cannot obtain ECDSA signer key manager: %s", err) } for i := 0; i < len(testParams); i++ { params := testutil.NewECDSAParams(testParams[i].hashType, testParams[i].curve, @@ -125,23 +137,20 @@ func TestECDSASignNewKeyBasic(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - tmp, err := km.NewKey(serializedFormat) + tmp, err := keyManager.NewKey(serializedFormat) if err != nil { t.Errorf("unexpected error: %s", err) } key := tmp.(*ecdsapb.EcdsaPrivateKey) - if err := validateECDSAPrivateKey(key, params); err != nil { - t.Errorf("invalid private key in test case %d: %s", i, err) - } + validateECDSAPrivateKey(t, key, params) } } -func TestECDSASignNewKeyWithInvalidInput(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) +func TestSignerKeyManagerNewKeyWithInvalidInput_HashAndCurveType(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) } - // invalid hash and curve type testParams := genInvalidECDSAParams() for i := 0; i < len(testParams); i++ { params := testutil.NewECDSAParams(testParams[i].hashType, testParams[i].curve, @@ -150,12 +159,18 @@ func TestECDSASignNewKeyWithInvalidInput(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.NewKey(serializedFormat); err == nil { + if _, err := keyManager.NewKey(serializedFormat); err == nil { t.Errorf("expect an error in test case %d", i) } } +} +func TestSignerKeyManagerNewKeyWithInvalidInput_InvalidEncoding(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + if err != nil { + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) + } // invalid encoding - testParams = genValidECDSAParams() + testParams := genValidECDSAParams() for i := 0; i < len(testParams); i++ { params := testutil.NewECDSAParams(testParams[i].hashType, testParams[i].curve, ecdsapb.EcdsaSignatureEncoding_UNKNOWN_ENCODING) @@ -163,34 +178,40 @@ func TestECDSASignNewKeyWithInvalidInput(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.NewKey(serializedFormat); err == nil { + if _, err := keyManager.NewKey(serializedFormat); err == nil { t.Errorf("expect an error in test case %d", i) } } - // nil input - if _, err := km.NewKey(nil); err == nil { +} + +func TestSignerKeyManagerNewKeyWithInvalidInput_NilInputOrParameters(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + if err != nil { + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) + } + // Nil or empty input. + if _, err := keyManager.NewKey(nil); err == nil { t.Errorf("expect an error when input is nil") } - if _, err := km.NewKey([]byte{}); err == nil { + if _, err := keyManager.NewKey([]byte{}); err == nil { t.Errorf("expect an error when input is empty slice") } - // nil params field + // Nil params field. keyFormatNilParams := testutil.NewECDSAKeyFormat(nil) serializedKeyFormatNilParams, err := proto.Marshal(keyFormatNilParams) if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.NewKey(serializedKeyFormatNilParams); err == nil { - t.Errorf("km.newKey(serializedKeyFormatNilParams) err = nil, want not nil") + if _, err := keyManager.NewKey(serializedKeyFormatNilParams); err == nil { + t.Errorf("keyManager.newKey(serializedKeyFormatNilParams) err = nil, want not nil") } } -func TestECDSASignPrivateKeyManagerGetPublicKeyErrors(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) +func TestSignerKeyManagerPrivateKeyManagerGetPublicKeyErrors(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSASignerTypeURL, err) } - testCases := []struct { name string key []byte @@ -218,17 +239,17 @@ func TestECDSASignPrivateKeyManagerGetPublicKeyErrors(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - if _, err := km.(registry.PrivateKeyManager).PublicKeyData(tc.key); err == nil { - t.Fatalf("km.PublicKeyData(serilizedPrivateKey) err = nil, want non-nil") + if _, err := keyManager.(registry.PrivateKeyManager).PublicKeyData(tc.key); err == nil { + t.Fatalf("keyManager.PublicKeyData(serilizedPrivateKey) err = nil, want non-nil") } }) } } -func TestECDSASignNewKeyMultipleTimes(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) +func TestSignerKeyManagerNewKeyMultipleTimes(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("cannot obtain ECDSA signer key manager: %s", err) } testParams := genValidECDSAParams() nTest := 27 @@ -242,7 +263,7 @@ func TestECDSASignNewKeyMultipleTimes(t *testing.T) { t.Fatalf("proto.Marshal() err = %q, want nil", err) } for j := 0; j < nTest; j++ { - key, err := km.NewKey(serializedFormat) + key, err := keyManager.NewKey(serializedFormat) if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } @@ -252,9 +273,9 @@ func TestECDSASignNewKeyMultipleTimes(t *testing.T) { } keys[string(serializedKey)] = true - keyData, err := km.NewKeyData(serializedFormat) + keyData, err := keyManager.NewKeyData(serializedFormat) if err != nil { - t.Fatalf("km.NewKeyData() err = %q, want nil", err) + t.Fatalf("keyManager.NewKeyData() err = %q, want nil", err) } serializedKey = keyData.Value keys[string(serializedKey)] = true @@ -265,10 +286,10 @@ func TestECDSASignNewKeyMultipleTimes(t *testing.T) { } } -func TestECDSASignNewKeyDataBasic(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) +func TestSignerKeyManagerNewKeyDataBasic(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("cannot obtain ECDSA signer key manager: %s", err) } testParams := genValidECDSAParams() for i := 0; i < len(testParams); i++ { @@ -279,7 +300,7 @@ func TestECDSASignNewKeyDataBasic(t *testing.T) { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - keyData, err := km.NewKeyData(serializedFormat) + keyData, err := keyManager.NewKeyData(serializedFormat) if err != nil { t.Errorf("unexpected error in test case %d: %s", i, err) } @@ -295,16 +316,14 @@ func TestECDSASignNewKeyDataBasic(t *testing.T) { if err := proto.Unmarshal(keyData.Value, key); err != nil { t.Errorf("unexpect error in test case %d: %s", i, err) } - if err := validateECDSAPrivateKey(key, params); err != nil { - t.Errorf("invalid private key in test case %d: %s", i, err) - } + validateECDSAPrivateKey(t, key, params) } } -func TestECDSASignNewKeyDataWithInvalidInput(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) +func TestSignerKeyManagerNewKeyDataWithInvalidInput(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("cannot obtain ECDSA signer key manager: %s", err) } testParams := genInvalidECDSAParams() for i := 0; i < len(testParams); i++ { @@ -315,23 +334,23 @@ func TestECDSASignNewKeyDataWithInvalidInput(t *testing.T) { if err != nil { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.NewKeyData(serializedFormat); err == nil { + if _, err := keyManager.NewKeyData(serializedFormat); err == nil { t.Errorf("expect an error in test case %d", i) } } // nil input - if _, err := km.NewKeyData(nil); err == nil { + if _, err := keyManager.NewKeyData(nil); err == nil { t.Errorf("expect an error when input is nil") } } func TestPublicKeyDataBasic(t *testing.T) { testParams := genValidECDSAParams() - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("cannot obtain ECDSA signer key manager: %s", err) } - pkm, ok := km.(registry.PrivateKeyManager) + privateKeyManager, ok := keyManager.(registry.PrivateKeyManager) if !ok { t.Errorf("cannot obtain private key manager") } @@ -342,7 +361,7 @@ func TestPublicKeyDataBasic(t *testing.T) { t.Fatalf("proto.Marshal() err = %q, want nil", err) } - pubKeyData, err := pkm.PublicKeyData(serializedKey) + pubKeyData, err := privateKeyManager.PublicKeyData(serializedKey) if err != nil { t.Errorf("unexpect error in test case %d: %s ", i, err) } @@ -360,11 +379,11 @@ func TestPublicKeyDataBasic(t *testing.T) { } func TestPublicKeyDataWithInvalidInput(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSASignerTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSASigner key manager: %s", err) + t.Fatalf("cannot obtain ECDSA signer key manager: %s", err) } - pkm, ok := km.(registry.PrivateKeyManager) + privateKeyManager, ok := keyManager.(registry.PrivateKeyManager) if !ok { t.Errorf("cannot obtain private key manager") } @@ -376,34 +395,33 @@ func TestPublicKeyDataWithInvalidInput(t *testing.T) { t.Fatalf("proto.Marshal() err = %q, want nil", err) } serializedKey[0] = 0 - if _, err := pkm.PublicKeyData(serializedKey); err == nil { + if _, err := privateKeyManager.PublicKeyData(serializedKey); err == nil { t.Errorf("expect an error when input is a modified serialized key") } // invalid with a single byte - if _, err := pkm.PublicKeyData([]byte{42}); err == nil { + if _, err := privateKeyManager.PublicKeyData([]byte{42}); err == nil { t.Errorf("expect an error when input is an empty slice") } } var errSmallKey = fmt.Errorf("private key doesn't have adequate size") -func validateECDSAPrivateKey(key *ecdsapb.EcdsaPrivateKey, params *ecdsapb.EcdsaParams) error { +func validateECDSAPrivateKey(t *testing.T, key *ecdsapb.EcdsaPrivateKey, params *ecdsapb.EcdsaParams) { + t.Helper() if key.Version != testutil.ECDSASignerKeyVersion { - return fmt.Errorf("incorrect private key's version: expect %d, got %d", - testutil.ECDSASignerKeyVersion, key.Version) + t.Fatalf("incorrect private key's version: expect %d, got %d", testutil.ECDSASignerKeyVersion, key.Version) } publicKey := key.PublicKey if publicKey.Version != testutil.ECDSASignerKeyVersion { - return fmt.Errorf("incorrect public key's version: expect %d, got %d", - testutil.ECDSASignerKeyVersion, key.Version) + t.Fatalf("incorrect public key's version: expect %d, got %d", testutil.ECDSASignerKeyVersion, key.Version) } if params.HashType != publicKey.Params.HashType || params.Curve != publicKey.Params.Curve || params.Encoding != publicKey.Params.Encoding { - return fmt.Errorf("incorrect params: expect %s, got %s", params, publicKey.Params) + t.Fatalf("incorrect params: expect %s, got %s", params, publicKey.Params) } if len(publicKey.X) == 0 || len(publicKey.Y) == 0 { - return fmt.Errorf("public points are not initialized") + t.Fatalf("public points are not initialized") } // check private key's size d := new(big.Int).SetBytes(key.KeyValue) @@ -411,37 +429,35 @@ func validateECDSAPrivateKey(key *ecdsapb.EcdsaPrivateKey, params *ecdsapb.Ecdsa switch params.Curve { case commonpb.EllipticCurveType_NIST_P256: if keySize < 256/8-8 || keySize > 256/8+1 { - return errSmallKey + t.Fatal(errSmallKey) } case commonpb.EllipticCurveType_NIST_P384: if keySize < 384/8-8 || keySize > 384/8+1 { - return errSmallKey + t.Fatal(errSmallKey) } case commonpb.EllipticCurveType_NIST_P521: if keySize < 521/8-8 || keySize > 521/8+1 { - return errSmallKey + t.Fatal(errSmallKey) } } // try to sign and verify with the key hash, curve, encoding := testutil.GetECDSAParamNames(publicKey.Params) signer, err := subtle.NewECDSASigner(hash, curve, encoding, key.KeyValue) if err != nil { - return fmt.Errorf("unexpected error when creating ECDSASign: %s", err) + t.Fatalf("unexpected error when creating ECDSASign: %s", err) } verifier, err := subtle.NewECDSAVerifier(hash, curve, encoding, publicKey.X, publicKey.Y) if err != nil { - return fmt.Errorf("unexpected error when creating ECDSAVerify: %s", err) + t.Fatalf("unexpected error when creating ECDSAVerify: %s", err) } data := random.GetRandomBytes(1281) signature, err := signer.Sign(data) if err != nil { - return fmt.Errorf("unexpected error when signing: %s", err) + t.Fatalf("unexpected error when signing: %s", err) } - if err := verifier.Verify(signature, data); err != nil { - return fmt.Errorf("unexpected error when verifying signature: %s", err) + t.Fatalf("unexpected error when verifying signature: %s", err) } - return nil } func genValidECDSAParams() []ecdsaParams { diff --git a/signature/ecdsa/verifier_key_manager.go b/signature/ecdsa/verifier_key_manager.go new file mode 100644 index 0000000..d0aa86b --- /dev/null +++ b/signature/ecdsa/verifier_key_manager.go @@ -0,0 +1,86 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package ecdsa + +import ( + "fmt" + + "google.golang.org/protobuf/proto" + "github.com/tink-crypto/tink-go/v2/keyset" + "github.com/tink-crypto/tink-go/v2/signature/subtle" + ecdsapb "github.com/tink-crypto/tink-go/v2/proto/ecdsa_go_proto" + tinkpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto" +) + +const ( + verifierKeyVersion = 0 + verifierTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPublicKey" +) + +// common errors +var errInvalidVerifierKey = fmt.Errorf("ecdsa_verifier_key_manager: invalid key") +var errVerifierNotImplemented = fmt.Errorf("ecdsa_verifier_key_manager: not implemented") + +// verifierKeyManager is an implementation of KeyManager interface. +// It doesn't support key generation. +type verifierKeyManager struct{} + +// Primitive creates an [subtleSignature.ECDSAVerifier] for the given +// serialized [ecdsapb.EcdsaPublicKey] proto. +func (km *verifierKeyManager) Primitive(serializedKey []byte) (any, error) { + if len(serializedKey) == 0 { + return nil, errInvalidVerifierKey + } + key := new(ecdsapb.EcdsaPublicKey) + if err := proto.Unmarshal(serializedKey, key); err != nil { + return nil, errInvalidVerifierKey + } + if err := km.validateKey(key); err != nil { + return nil, err + } + hash, curve, encoding := paramNames(key.GetParams()) + ret, err := subtle.NewECDSAVerifier(hash, curve, encoding, key.X, key.Y) + if err != nil { + return nil, err + } + return ret, nil +} + +// NewKey is not implemented. +func (km *verifierKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { + return nil, errVerifierNotImplemented +} + +// NewKeyData is not implemented. +func (km *verifierKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { + return nil, errVerifierNotImplemented +} + +// DoesSupport indicates if this key manager supports the given key type. +func (km *verifierKeyManager) DoesSupport(typeURL string) bool { + return typeURL == verifierTypeURL +} + +// TypeURL returns the key type of keys managed by this key manager. +func (km *verifierKeyManager) TypeURL() string { return verifierTypeURL } + +// validateKey validates the given [ecdsapb.EcdsaPublicKey]. +func (km *verifierKeyManager) validateKey(key *ecdsapb.EcdsaPublicKey) error { + if err := keyset.ValidateKeyVersion(key.Version, verifierKeyVersion); err != nil { + return err + } + hash, curve, encoding := paramNames(key.GetParams()) + return subtle.ValidateECDSAParams(hash, curve, encoding) +} diff --git a/signature/ecdsa_verifier_key_manager_test.go b/signature/ecdsa/verifier_key_manager_test.go similarity index 54% rename from signature/ecdsa_verifier_key_manager_test.go rename to signature/ecdsa/verifier_key_manager_test.go index b73df4f..24792fa 100644 --- a/signature/ecdsa_verifier_key_manager_test.go +++ b/signature/ecdsa/verifier_key_manager_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package signature_test +package ecdsa_test import ( "testing" @@ -23,53 +23,53 @@ import ( commonpb "github.com/tink-crypto/tink-go/v2/proto/common_go_proto" ) -func TestECDSAVerifyGetPrimitiveBasic(t *testing.T) { +func TestVerifierKeyManagerGetPrimitiveBasic(t *testing.T) { testParams := genValidECDSAParams() - km, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSAVerifier key manager: %s", err) + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSAVerifierTypeURL, err) } for i := 0; i < len(testParams); i++ { serializedKey, err := proto.Marshal(testutil.NewRandomECDSAPublicKey(testParams[i].hashType, testParams[i].curve)) if err != nil { t.Errorf("proto.Marshal() err = %v, want nil", err) } - _, err = km.Primitive(serializedKey) + _, err = keyManager.Primitive(serializedKey) if err != nil { t.Errorf("unexpect error in test case %d: %s ", i, err) } } } -func TestECDSAVerifyWithInvalidPublicKeyFailsCreatingPrimitive(t *testing.T) { - km, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) +func TestVerifierKeyManagerWithInvalidPublicKeyFailsCreatingPrimitive(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSAVerifier key manager: %s", err) + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSAVerifierTypeURL, err) } pubKey := testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256, commonpb.EllipticCurveType_NIST_P256) pubKey.X = []byte{0, 32, 0} pubKey.Y = []byte{0, 32, 0} serializedPubKey, err := proto.Marshal(pubKey) if err != nil { - t.Errorf("proto.Marhsal() err = %v, want nil", err) + t.Fatalf("proto.Marhsal() err = %v, want nil", err) } - if _, err := km.Primitive(serializedPubKey); err == nil { - t.Errorf("km.Primitive() err = nil, want error") + if _, err := keyManager.Primitive(serializedPubKey); err == nil { + t.Errorf("keyManager.Primitive() err = nil, want error") } } -func TestECDSAVerifyGetPrimitiveWithInvalidInput(t *testing.T) { +func TestVerifierKeyManagerGetPrimitiveWithInvalidInput_InvalidParams(t *testing.T) { testParams := genInvalidECDSAParams() - km, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) + keyManager, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) if err != nil { - t.Errorf("cannot obtain ECDSAVerifier key manager: %s", err) + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSAVerifierTypeURL, err) } for i := 0; i < len(testParams); i++ { serializedKey, err := proto.Marshal(testutil.NewRandomECDSAPublicKey(testParams[i].hashType, testParams[i].curve)) if err != nil { - t.Errorf("proto.Marshal() err = %q, want nil", err) + t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKey); err == nil { + if _, err := keyManager.Primitive(serializedKey); err == nil { t.Errorf("expect an error in test case %d", i) } } @@ -79,39 +79,50 @@ func TestECDSAVerifyGetPrimitiveWithInvalidInput(t *testing.T) { k.GetParams().HashType = tc.hashType serializedKey, err := proto.Marshal(k) if err != nil { - t.Errorf("proto.Marshal() err = %q, want nil", err) + t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKey); err == nil { + if _, err := keyManager.Primitive(serializedKey); err == nil { t.Errorf("expect an error in test case with params: (curve = %q, hash = %q)", tc.curve, tc.hashType) } } - // invalid version - key := testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256, - commonpb.EllipticCurveType_NIST_P256) +} + +func TestVerifierKeyManagerGetPrimitiveWithInvalidInput_InvalidVersion(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) + if err != nil { + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSAVerifierTypeURL, err) + } + key := testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256, commonpb.EllipticCurveType_NIST_P256) key.Version = testutil.ECDSAVerifierKeyVersion + 1 serializedKey, err := proto.Marshal(key) if err != nil { - t.Errorf("proto.Marshal() err = %q, want nil", err) + t.Fatalf("proto.Marshal() err = %q, want nil", err) } - if _, err = km.Primitive(serializedKey); err == nil { + if _, err = keyManager.Primitive(serializedKey); err == nil { t.Errorf("expect an error when version is invalid") } - // nil input - if _, err := km.Primitive(nil); err == nil { +} + +func TestVerifierKeyManagerGetPrimitiveWithInvalidInput_NilInputAndParams(t *testing.T) { + keyManager, err := registry.GetKeyManager(testutil.ECDSAVerifierTypeURL) + if err != nil { + t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ECDSAVerifierTypeURL, err) + } + // Nil or empty input. + if _, err := keyManager.Primitive(nil); err == nil { t.Errorf("expect an error when input is nil") } - if _, err := km.Primitive([]byte{}); err == nil { + if _, err := keyManager.Primitive([]byte{}); err == nil { t.Errorf("expect an error when input is empty slice") } - // params field is nil - keyNilParams := testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256, - commonpb.EllipticCurveType_NIST_P256) + // Nil params. + keyNilParams := testutil.NewRandomECDSAPublicKey(commonpb.HashType_SHA256, commonpb.EllipticCurveType_NIST_P256) keyNilParams.Params = nil serializedKeyNilParams, err := proto.Marshal(keyNilParams) if err != nil { t.Errorf("proto.Marshal() err = %q, want nil", err) } - if _, err := km.Primitive(serializedKeyNilParams); err == nil { - t.Errorf("km.Primitive(serializedKeyNilParams); err = nil, want non-nil") + if _, err := keyManager.Primitive(serializedKeyNilParams); err == nil { + t.Errorf("keyManager.Primitive(serializedKeyNilParams); err = nil, want non-nil") } } diff --git a/signature/ecdsa_verifier_key_manager.go b/signature/ecdsa_verifier_key_manager.go deleted file mode 100644 index d713923..0000000 --- a/signature/ecdsa_verifier_key_manager.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2018 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package signature - -import ( - "fmt" - - "google.golang.org/protobuf/proto" - "github.com/tink-crypto/tink-go/v2/keyset" - "github.com/tink-crypto/tink-go/v2/signature/subtle" - ecdsapb "github.com/tink-crypto/tink-go/v2/proto/ecdsa_go_proto" - tinkpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto" -) - -const ( - ecdsaVerifierKeyVersion = 0 - ecdsaVerifierTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPublicKey" -) - -// common errors -var errInvalidECDSAVerifierKey = fmt.Errorf("ecdsa_verifier_key_manager: invalid key") -var errECDSAVerifierNotImplemented = fmt.Errorf("ecdsa_verifier_key_manager: not implemented") - -// ecdsaVerifierKeyManager is an implementation of KeyManager interface. -// It doesn't support key generation. -type ecdsaVerifierKeyManager struct{} - -// Primitive creates an ECDSAVerifier subtle for the given serialized ECDSAPublicKey proto. -func (km *ecdsaVerifierKeyManager) Primitive(serializedKey []byte) (any, error) { - if len(serializedKey) == 0 { - return nil, errInvalidECDSAVerifierKey - } - key := new(ecdsapb.EcdsaPublicKey) - if err := proto.Unmarshal(serializedKey, key); err != nil { - return nil, errInvalidECDSAVerifierKey - } - if err := km.validateKey(key); err != nil { - return nil, fmt.Errorf("ecdsa_verifier_key_manager: %s", err) - } - hash, curve, encoding := getECDSAParamNames(key.GetParams()) - ret, err := subtle.NewECDSAVerifier(hash, curve, encoding, key.X, key.Y) - if err != nil { - return nil, fmt.Errorf("ecdsa_verifier_key_manager: invalid key: %s", err) - } - return ret, nil -} - -// NewKey is not implemented. -func (km *ecdsaVerifierKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { - return nil, errECDSAVerifierNotImplemented -} - -// NewKeyData creates a new KeyData according to specification in the given -// serialized ECDSAKeyFormat. It should be used solely by the key management API. -func (km *ecdsaVerifierKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { - return nil, errECDSAVerifierNotImplemented -} - -// DoesSupport indicates if this key manager supports the given key type. -func (km *ecdsaVerifierKeyManager) DoesSupport(typeURL string) bool { - return typeURL == ecdsaVerifierTypeURL -} - -// TypeURL returns the key type of keys managed by this key manager. -func (km *ecdsaVerifierKeyManager) TypeURL() string { - return ecdsaVerifierTypeURL -} - -// validateKey validates the given ECDSAPublicKey. -func (km *ecdsaVerifierKeyManager) validateKey(key *ecdsapb.EcdsaPublicKey) error { - if err := keyset.ValidateKeyVersion(key.Version, ecdsaVerifierKeyVersion); err != nil { - return fmt.Errorf("ecdsa_verifier_key_manager: %s", err) - } - hash, curve, encoding := getECDSAParamNames(key.GetParams()) - return subtle.ValidateECDSAParams(hash, curve, encoding) -} diff --git a/signature/signature.go b/signature/signature.go index 7cf8e5d..fa96851 100644 --- a/signature/signature.go +++ b/signature/signature.go @@ -22,18 +22,11 @@ import ( "fmt" "github.com/tink-crypto/tink-go/v2/core/registry" - _ "github.com/tink-crypto/tink-go/v2/signature/ed25519" // register ed25519 key managers + _ "github.com/tink-crypto/tink-go/v2/signature/ecdsa" // register ECDSA key managers + _ "github.com/tink-crypto/tink-go/v2/signature/ed25519" // register ed25519 key managers and keys ) func init() { - // ECDSA - if err := registry.RegisterKeyManager(new(ecdsaSignerKeyManager)); err != nil { - panic(fmt.Sprintf("signature.init() failed: %v", err)) - } - if err := registry.RegisterKeyManager(new(ecdsaVerifierKeyManager)); err != nil { - panic(fmt.Sprintf("signature.init() failed: %v", err)) - } - // RSA SSA PKCS1 if err := registry.RegisterKeyManager(new(rsaSSAPKCS1SignerKeyManager)); err != nil { panic(fmt.Sprintf("signature.init() failed: %v", err)) diff --git a/signature/signature_key_templates.go b/signature/signature_key_templates.go index dde1242..97a2e8f 100644 --- a/signature/signature_key_templates.go +++ b/signature/signature_key_templates.go @@ -29,6 +29,11 @@ import ( // This file contains pre-generated KeyTemplates for Signer and Verifier. // One can use these templates to generate new Keysets. +const ( + ed25519SignerTypeURL = "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey" + ecdsaSignerTypeURL = "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey" +) + // ECDSAP256KeyTemplate is a KeyTemplate that generates a new ECDSA private key with the following parameters: // - Hash function: SHA256 // - Curve: NIST P-256 @@ -163,10 +168,6 @@ func createECDSAKeyTemplate(hashType commonpb.HashType, curve commonpb.EllipticC } } -const ( - ed25519SignerTypeURL = "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey" -) - // ED25519KeyTemplate is a KeyTemplate that generates a new ED25519 private key. func ED25519KeyTemplate() *tinkpb.KeyTemplate { return &tinkpb.KeyTemplate{