xref: /aosp_15_r20/external/tink/go/signature/ecdsa_signer_key_manager.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2018 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15////////////////////////////////////////////////////////////////////////////////
16
17package signature
18
19import (
20	"crypto/ecdsa"
21	"crypto/rand"
22	"errors"
23	"fmt"
24
25	"google.golang.org/protobuf/proto"
26	"github.com/google/tink/go/keyset"
27	subtleSignature "github.com/google/tink/go/signature/subtle"
28	"github.com/google/tink/go/subtle"
29	commonpb "github.com/google/tink/go/proto/common_go_proto"
30	ecdsapb "github.com/google/tink/go/proto/ecdsa_go_proto"
31	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
32)
33
34const (
35	ecdsaSignerKeyVersion = 0
36	ecdsaSignerTypeURL    = "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey"
37)
38
39// common errors
40var errInvalidECDSASignKey = errors.New("ecdsa_signer_key_manager: invalid key")
41var errInvalidECDSASignKeyFormat = errors.New("ecdsa_signer_key_manager: invalid key format")
42
43// ecdsaSignerKeyManager is an implementation of KeyManager interface.
44// It generates new ECDSAPrivateKeys and produces new instances of ECDSASign subtle.
45type ecdsaSignerKeyManager struct{}
46
47// Primitive creates an ECDSASign subtle for the given serialized ECDSAPrivateKey proto.
48func (km *ecdsaSignerKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
49	if len(serializedKey) == 0 {
50		return nil, errInvalidECDSASignKey
51	}
52	key := new(ecdsapb.EcdsaPrivateKey)
53	if err := proto.Unmarshal(serializedKey, key); err != nil {
54		return nil, errInvalidECDSASignKey
55	}
56	if err := km.validateKey(key); err != nil {
57		return nil, err
58	}
59	hash, curve, encoding := getECDSAParamNames(key.PublicKey.Params)
60	ret, err := subtleSignature.NewECDSASigner(hash, curve, encoding, key.KeyValue)
61	if err != nil {
62		return nil, fmt.Errorf("ecdsa_signer_key_manager: %s", err)
63	}
64	return ret, nil
65}
66
67// NewKey creates a new ECDSAPrivateKey according to specification the given serialized ECDSAKeyFormat.
68func (km *ecdsaSignerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
69	if len(serializedKeyFormat) == 0 {
70		return nil, errInvalidECDSASignKeyFormat
71	}
72	keyFormat := new(ecdsapb.EcdsaKeyFormat)
73	if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil {
74		return nil, fmt.Errorf("ecdsa_signer_key_manager: invalid proto: %s", err)
75	}
76	if err := km.validateKeyFormat(keyFormat); err != nil {
77		return nil, fmt.Errorf("ecdsa_signer_key_manager: invalid key format: %s", err)
78	}
79	// generate key
80	params := keyFormat.Params
81	curve := commonpb.EllipticCurveType_name[int32(params.Curve)]
82	tmpKey, err := ecdsa.GenerateKey(subtle.GetCurve(curve), rand.Reader)
83	if err != nil {
84		return nil, fmt.Errorf("ecdsa_signer_key_manager: cannot generate ECDSA key: %s", err)
85	}
86
87	keyValue := tmpKey.D.Bytes()
88	pub := newECDSAPublicKey(ecdsaSignerKeyVersion, params, tmpKey.X.Bytes(), tmpKey.Y.Bytes())
89	priv := newECDSAPrivateKey(ecdsaSignerKeyVersion, pub, keyValue)
90	return priv, nil
91}
92
93// NewKeyData creates a new KeyData according to specification in  the given
94// serialized ECDSAKeyFormat. It should be used solely by the key management API.
95func (km *ecdsaSignerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
96	key, err := km.NewKey(serializedKeyFormat)
97	if err != nil {
98		return nil, err
99	}
100	serializedKey, err := proto.Marshal(key)
101	if err != nil {
102		return nil, errInvalidECDSASignKeyFormat
103	}
104	return &tinkpb.KeyData{
105		TypeUrl:         ecdsaSignerTypeURL,
106		Value:           serializedKey,
107		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
108	}, nil
109}
110
111// PublicKeyData extracts the public key data from the private key.
112func (km *ecdsaSignerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) {
113	privKey := new(ecdsapb.EcdsaPrivateKey)
114	if err := proto.Unmarshal(serializedPrivKey, privKey); err != nil {
115		return nil, errInvalidECDSASignKey
116	}
117	serializedPubKey, err := proto.Marshal(privKey.PublicKey)
118	if err != nil {
119		return nil, errInvalidECDSASignKey
120	}
121	return &tinkpb.KeyData{
122		TypeUrl:         ecdsaVerifierTypeURL,
123		Value:           serializedPubKey,
124		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC,
125	}, nil
126}
127
128// DoesSupport indicates if this key manager supports the given key type.
129func (km *ecdsaSignerKeyManager) DoesSupport(typeURL string) bool {
130	return typeURL == ecdsaSignerTypeURL
131}
132
133// TypeURL returns the key type of keys managed by this key manager.
134func (km *ecdsaSignerKeyManager) TypeURL() string {
135	return ecdsaSignerTypeURL
136}
137
138// validateKey validates the given ECDSAPrivateKey.
139func (km *ecdsaSignerKeyManager) validateKey(key *ecdsapb.EcdsaPrivateKey) error {
140	if err := keyset.ValidateKeyVersion(key.Version, ecdsaSignerKeyVersion); err != nil {
141		return fmt.Errorf("ecdsa_signer_key_manager: invalid key: %s", err)
142	}
143	hash, curve, encoding := getECDSAParamNames(key.PublicKey.Params)
144	return subtleSignature.ValidateECDSAParams(hash, curve, encoding)
145}
146
147// validateKeyFormat validates the given ECDSAKeyFormat.
148func (km *ecdsaSignerKeyManager) validateKeyFormat(format *ecdsapb.EcdsaKeyFormat) error {
149	hash, curve, encoding := getECDSAParamNames(format.Params)
150	return subtleSignature.ValidateECDSAParams(hash, curve, encoding)
151}
152