Skip to content

Commit

Permalink
Move ECDSA key managers to signature/ecdsa
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 673965296
Change-Id: I7676049e22ae40a287104825f9e9cdf8edb49748
  • Loading branch information
morambro authored and copybara-github committed Sep 12, 2024
1 parent 4aca4d8 commit 6e26116
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 294 deletions.
10 changes: 1 addition & 9 deletions signature/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
],
Expand All @@ -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",
Expand All @@ -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",
Expand Down
48 changes: 48 additions & 0 deletions signature/ecdsa/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -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",
],
)
32 changes: 32 additions & 0 deletions signature/ecdsa/ecdsa.go
Original file line number Diff line number Diff line change
@@ -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))
}
}
27 changes: 4 additions & 23 deletions signature/proto.go → signature/ecdsa/proto.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -30,42 +30,45 @@ 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)
}
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 {
Expand All @@ -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)
}
Loading

0 comments on commit 6e26116

Please sign in to comment.