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/rsa" 21 "errors" 22 "fmt" 23 "math/big" 24 25 "google.golang.org/protobuf/proto" 26 "github.com/google/tink/go/core/registry" 27 internal "github.com/google/tink/go/internal/signature" 28 "github.com/google/tink/go/keyset" 29 rsassapsspb "github.com/google/tink/go/proto/rsa_ssa_pss_go_proto" 30 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 31) 32 33const ( 34 rsaSSAPSSVerifierKeyVersion = 0 35 rsaSSAPSSVerifierTypeURL = "type.googleapis.com/google.crypto.tink.RsaSsaPssPublicKey" 36) 37 38var ( 39 errInvalidRSASSAPSSVerifierKey = errors.New("rsassapss_verifier_key_manager: invalid key") 40 errRSASSAPSSNotImplemented = errors.New("rsassapss_verifier_key_manager: not implemented") 41) 42 43type rsaSSAPSSVerifierKeyManager struct{} 44 45var _ (registry.KeyManager) = (*rsaSSAPSSVerifierKeyManager)(nil) 46 47func (km *rsaSSAPSSVerifierKeyManager) Primitive(serializedKey []byte) (interface{}, error) { 48 if len(serializedKey) == 0 { 49 return nil, errInvalidRSASSAPSSVerifierKey 50 } 51 key := &rsassapsspb.RsaSsaPssPublicKey{} 52 if err := proto.Unmarshal(serializedKey, key); err != nil { 53 return nil, errInvalidRSASSAPSSVerifierKey 54 } 55 if err := validateRSAPSSPublicKey(key); err != nil { 56 return nil, err 57 } 58 pubKey := &rsa.PublicKey{ 59 E: int(new(big.Int).SetBytes(key.E).Uint64()), 60 N: new(big.Int).SetBytes(key.N), 61 } 62 return internal.New_RSA_SSA_PSS_Verifier(hashName(key.GetParams().GetSigHash()), int(key.GetParams().GetSaltLength()), pubKey) 63} 64 65func validateRSAPSSPublicKey(pubKey *rsassapsspb.RsaSsaPssPublicKey) error { 66 if err := keyset.ValidateKeyVersion(pubKey.GetVersion(), rsaSSAPSSVerifierKeyVersion); err != nil { 67 return err 68 } 69 if pubKey.GetParams().GetSigHash() != pubKey.GetParams().GetMgf1Hash() { 70 return fmt.Errorf("signature hash and MGF1 hash function must match") 71 } 72 if pubKey.GetParams().GetSaltLength() < 0 { 73 return fmt.Errorf("salt length can't be negative") 74 } 75 return validateRSAPubKeyParams( 76 pubKey.GetParams().GetSigHash(), 77 new(big.Int).SetBytes(pubKey.GetN()).BitLen(), 78 pubKey.GetE()) 79} 80 81func (km *rsaSSAPSSVerifierKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { 82 return nil, errRSASSAPSSNotImplemented 83} 84 85func (km *rsaSSAPSSVerifierKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { 86 return nil, errRSASSAPSSNotImplemented 87} 88 89func (km *rsaSSAPSSVerifierKeyManager) DoesSupport(typeURL string) bool { 90 return typeURL == rsaSSAPSSVerifierTypeURL 91} 92 93func (km *rsaSSAPSSVerifierKeyManager) TypeURL() string { 94 return rsaSSAPSSVerifierTypeURL 95} 96