xref: /aosp_15_r20/external/tink/go/signature/rsassapss_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	"fmt"
23
24	"errors"
25	"math/big"
26
27	"google.golang.org/protobuf/proto"
28	"github.com/google/tink/go/core/registry"
29	internal "github.com/google/tink/go/internal/signature"
30	"github.com/google/tink/go/keyset"
31	rsassapsspb "github.com/google/tink/go/proto/rsa_ssa_pss_go_proto"
32	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
33)
34
35const (
36	rsaSSAPSSSignerKeyVersion = 0
37	rsaSSAPSSSignerTypeURL    = "type.googleapis.com/google.crypto.tink.RsaSsaPssPrivateKey"
38)
39
40var (
41	errInvalidRSASSAPSSSignKey = errors.New("rsassapss_signer_key_manager: invalid key")
42)
43
44type rsaSSAPSSSignerKeyManager struct{}
45
46var _ registry.PrivateKeyManager = (*rsaSSAPSSSignerKeyManager)(nil)
47
48func (km *rsaSSAPSSSignerKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
49	if len(serializedKey) == 0 {
50		return nil, errInvalidRSASSAPSSSignKey
51	}
52	key := &rsassapsspb.RsaSsaPssPrivateKey{}
53	if err := proto.Unmarshal(serializedKey, key); err != nil {
54		return nil, err
55	}
56	if err := validateRSAPSSPrivateKey(key); err != nil {
57		return nil, err
58	}
59	privKey := &rsa.PrivateKey{
60		PublicKey: rsa.PublicKey{
61			N: bytesToBigInt(key.GetPublicKey().GetN()),
62			E: int(bytesToBigInt(key.GetPublicKey().GetE()).Uint64()),
63		},
64		D: bytesToBigInt(key.GetD()),
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	params := key.GetPublicKey().GetParams()
76	if err := internal.Validate_RSA_SSA_PSS(hashName(params.GetSigHash()), int(params.GetSaltLength()), privKey); err != nil {
77		return nil, err
78	}
79	return internal.New_RSA_SSA_PSS_Signer(hashName(params.GetSigHash()), int(params.GetSaltLength()), privKey)
80}
81
82func validateRSAPSSPrivateKey(privKey *rsassapsspb.RsaSsaPssPrivateKey) error {
83	if err := keyset.ValidateKeyVersion(privKey.GetVersion(), rsaSSAPSSSignerKeyVersion); err != nil {
84		return err
85	}
86	if err := validateRSAPSSPublicKey(privKey.GetPublicKey()); err != nil {
87		return err
88	}
89	if len(privKey.GetD()) == 0 ||
90		len(privKey.GetPublicKey().GetN()) == 0 ||
91		len(privKey.GetPublicKey().GetE()) == 0 ||
92		len(privKey.GetP()) == 0 ||
93		len(privKey.GetQ()) == 0 ||
94		len(privKey.GetDp()) == 0 ||
95		len(privKey.GetDq()) == 0 ||
96		len(privKey.GetCrt()) == 0 {
97		return errInvalidRSASSAPSSSignKey
98	}
99	return nil
100}
101
102func (km *rsaSSAPSSSignerKeyManager) PublicKeyData(serializedPrivKey []byte) (*tinkpb.KeyData, error) {
103	if serializedPrivKey == nil {
104		return nil, errInvalidRSASSAPSSSignKey
105	}
106	privKey := &rsassapsspb.RsaSsaPssPrivateKey{}
107	if err := proto.Unmarshal(serializedPrivKey, privKey); err != nil {
108		return nil, err
109	}
110	if err := validateRSAPSSPrivateKey(privKey); err != nil {
111		return nil, err
112	}
113	serializedPubKey, err := proto.Marshal(privKey.GetPublicKey())
114	if err != nil {
115		return nil, err
116	}
117	return &tinkpb.KeyData{
118		TypeUrl:         rsaSSAPSSVerifierTypeURL,
119		Value:           serializedPubKey,
120		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PUBLIC,
121	}, nil
122}
123
124func (km *rsaSSAPSSSignerKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
125	if len(serializedKeyFormat) == 0 {
126		return nil, fmt.Errorf("invalid key format")
127	}
128	keyFormat := &rsassapsspb.RsaSsaPssKeyFormat{}
129	if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil {
130		return nil, err
131	}
132	params := keyFormat.GetParams()
133	if params.GetSigHash() != params.GetMgf1Hash() {
134		return nil, fmt.Errorf("signature hash and mgf1 hash must be the same")
135	}
136	if params.GetSaltLength() < 0 {
137		return nil, fmt.Errorf("salt length can't be negative")
138	}
139	if err := validateRSAPubKeyParams(
140		params.GetSigHash(),
141		int(keyFormat.GetModulusSizeInBits()),
142		keyFormat.GetPublicExponent()); err != nil {
143		return nil, err
144	}
145	privKey, err := rsa.GenerateKey(rand.Reader, int(keyFormat.GetModulusSizeInBits()))
146	if err != nil {
147		return nil, err
148	}
149	return &rsassapsspb.RsaSsaPssPrivateKey{
150		Version: rsaSSAPSSSignerKeyVersion,
151		PublicKey: &rsassapsspb.RsaSsaPssPublicKey{
152			Version: rsaSSAPSSSignerKeyVersion,
153			Params:  keyFormat.GetParams(),
154			N:       privKey.PublicKey.N.Bytes(),
155			E:       big.NewInt(int64(privKey.PublicKey.E)).Bytes(),
156		},
157		D:   privKey.D.Bytes(),
158		P:   privKey.Primes[0].Bytes(),
159		Q:   privKey.Primes[1].Bytes(),
160		Dp:  privKey.Precomputed.Dp.Bytes(),
161		Dq:  privKey.Precomputed.Dq.Bytes(),
162		Crt: privKey.Precomputed.Qinv.Bytes(),
163	}, nil
164}
165
166func (km *rsaSSAPSSSignerKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
167	key, err := km.NewKey(serializedKeyFormat)
168	if err != nil {
169		return nil, err
170	}
171	serializedKey, err := proto.Marshal(key)
172	if err != nil {
173		return nil, err
174	}
175	return &tinkpb.KeyData{
176		TypeUrl:         rsaSSAPSSSignerTypeURL,
177		Value:           serializedKey,
178		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
179	}, nil
180}
181
182func (km *rsaSSAPSSSignerKeyManager) DoesSupport(typeURL string) bool {
183	return typeURL == rsaSSAPSSSignerTypeURL
184}
185
186func (km *rsaSSAPSSSignerKeyManager) TypeURL() string {
187	return rsaSSAPSSSignerTypeURL
188}
189