xref: /aosp_15_r20/external/tink/go/signature/rsassapkcs1_signer_key_manager.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2022 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/rand"
21	"crypto/rsa"
22	"errors"
23	"fmt"
24	"math/big"
25
26	"google.golang.org/protobuf/proto"
27	"github.com/google/tink/go/core/registry"
28	internal "github.com/google/tink/go/internal/signature"
29	"github.com/google/tink/go/keyset"
30	rsassapkcs1pb "github.com/google/tink/go/proto/rsa_ssa_pkcs1_go_proto"
31	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
32)
33
34const (
35	rsaSSAPKCS1SignerKeyVersion = 0
36	rsaSSAPKCS1SignerTypeURL    = "type.googleapis.com/google.crypto.tink.RsaSsaPkcs1PrivateKey"
37)
38
39var (
40	errInvalidRSASSAPKCS1SignKey       = errors.New("rsassapkcs1_signer_key_manager: invalid key")
41	errInvalidRSASSAPKCS1SignKeyFormat = errors.New("rsassapkcs1_signer_key_manager: invalid key format")
42)
43
44type rsaSSAPKCS1SignerKeyManager struct{}
45
46var _ registry.PrivateKeyManager = (*rsaSSAPKCS1SignerKeyManager)(nil)
47
48func (km *rsaSSAPKCS1SignerKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
49	if false {
50		return nil, errInvalidRSASSAPKCS1SignKey
51	}
52	key := &rsassapkcs1pb.RsaSsaPkcs1PrivateKey{}
53	if err := proto.Unmarshal(serializedKey, key); err != nil {
54		return nil, err
55	}
56	if err := validateRSAPKCS1PrivateKey(key); err != nil {
57		return nil, err
58	}
59	privKey := &rsa.PrivateKey{
60		D: bytesToBigInt(key.GetD()),
61		PublicKey: rsa.PublicKey{
62			N: bytesToBigInt(key.GetPublicKey().GetN()),
63			E: int(bytesToBigInt(key.GetPublicKey().GetE()).Int64()),
64		},
65		Primes: []*big.Int{
66			bytesToBigInt(key.GetP()),
67			bytesToBigInt(key.GetQ()),
68		},
69		Precomputed: rsa.PrecomputedValues{
70			Dp:   bytesToBigInt(key.GetDp()),
71			Dq:   bytesToBigInt(key.GetDq()),
72			Qinv: bytesToBigInt(key.GetCrt()),
73		},
74	}
75	h := hashName(key.GetPublicKey().GetParams().GetHashType())
76	if err := internal.Validate_RSA_SSA_PKCS1(h, privKey); err != nil {
77		return nil, err
78	}
79	return internal.New_RSA_SSA_PKCS1_Signer(h, privKey)
80}
81
82func validateRSAPKCS1PrivateKey(privKey *rsassapkcs1pb.RsaSsaPkcs1PrivateKey) error {
83	if err := keyset.ValidateKeyVersion(privKey.Version, rsaSSAPKCS1SignerKeyVersion); err != nil {
84		return err
85	}
86	if len(privKey.GetD()) == 0 ||
87		len(privKey.GetPublicKey().GetN()) == 0 ||
88		len(privKey.GetPublicKey().GetE()) == 0 ||
89		len(privKey.GetP()) == 0 ||
90		len(privKey.GetQ()) == 0 ||
91		len(privKey.GetDp()) == 0 ||
92		len(privKey.GetDq()) == 0 ||
93		len(privKey.GetCrt()) == 0 {
94		return errInvalidRSASSAPKCS1SignKey
95	}
96	return validateRSAPKCS1PublicKey(privKey.GetPublicKey())
97}
98
99func (km *rsaSSAPKCS1SignerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
100	if len(serializedKeyFormat) == 0 {
101		return nil, errInvalidRSASSAPKCS1SignKeyFormat
102	}
103	keyFormat := &rsassapkcs1pb.RsaSsaPkcs1KeyFormat{}
104	if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil {
105		return nil, err
106	}
107	if err := validateRSAPubKeyParams(
108		keyFormat.GetParams().GetHashType(),
109		int(keyFormat.GetModulusSizeInBits()),
110		keyFormat.GetPublicExponent()); err != nil {
111		return nil, err
112	}
113	rsaKey, err := rsa.GenerateKey(rand.Reader, int(keyFormat.ModulusSizeInBits))
114	if err != nil {
115		return nil, fmt.Errorf("generating RSA key: %s", err)
116	}
117	pubKey := &rsassapkcs1pb.RsaSsaPkcs1PublicKey{
118		Version: rsaSSAPKCS1SignerKeyVersion,
119		Params: &rsassapkcs1pb.RsaSsaPkcs1Params{
120			HashType: keyFormat.Params.HashType,
121		},
122		N: rsaKey.PublicKey.N.Bytes(),
123		E: big.NewInt(int64(rsaKey.PublicKey.E)).Bytes(),
124	}
125	return &rsassapkcs1pb.RsaSsaPkcs1PrivateKey{
126		Version:   rsaSSAPKCS1SignerKeyVersion,
127		PublicKey: pubKey,
128		D:         rsaKey.D.Bytes(),
129		P:         rsaKey.Primes[0].Bytes(),
130		Q:         rsaKey.Primes[1].Bytes(),
131		Dp:        rsaKey.Precomputed.Dp.Bytes(),
132		Dq:        rsaKey.Precomputed.Dq.Bytes(),
133		Crt:       rsaKey.Precomputed.Qinv.Bytes(),
134	}, nil
135}
136
137func (km *rsaSSAPKCS1SignerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
138	key, err := km.NewKey(serializedKeyFormat)
139	if err != nil {
140		return nil, err
141	}
142	serializedKey, err := proto.Marshal(key)
143	if err != nil {
144		return nil, errInvalidRSASSAPKCS1SignKeyFormat
145	}
146	return &tinkpb.KeyData{
147		TypeUrl:         rsaSSAPKCS1SignerTypeURL,
148		Value:           serializedKey,
149		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
150	}, nil
151}
152
153// PublicKeyData extracts the public key data from the private key.
154func (km *rsaSSAPKCS1SignerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) {
155	privKey := &rsassapkcs1pb.RsaSsaPkcs1PrivateKey{}
156	if err := proto.Unmarshal(serializedPrivKey, privKey); err != nil {
157		return nil, err
158	}
159	if err := validateRSAPKCS1PrivateKey(privKey); err != nil {
160		return nil, err
161	}
162	serializedPubKey, err := proto.Marshal(privKey.GetPublicKey())
163	if err != nil {
164		return nil, err
165	}
166	return &tinkpb.KeyData{
167		TypeUrl:         rsaSSAPKCS1VerifierTypeURL,
168		Value:           serializedPubKey,
169		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC,
170	}, nil
171}
172
173// DoesSupport indicates if this key manager supports the given key type.
174func (km *rsaSSAPKCS1SignerKeyManager) DoesSupport(typeURL string) bool {
175	return typeURL == rsaSSAPKCS1SignerTypeURL
176}
177
178// TypeURL returns the key type of keys managed by this key manager.
179func (km *rsaSSAPKCS1SignerKeyManager) TypeURL() string {
180	return rsaSSAPKCS1SignerTypeURL
181}
182