1// Copyright 2023 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 17// Package kmsaead provides a keymanager for KmsAeadKey that may only be used in tests. 18// 19// Golang currently doesn't implement KmsAeadKey. This is an internal implementation 20// to be used by the cross-language tests. 21package kmsaead 22 23import ( 24 "errors" 25 "fmt" 26 27 "google.golang.org/protobuf/proto" 28 "github.com/google/tink/go/core/registry" 29 "github.com/google/tink/go/keyset" 30 kmsaeadpb "github.com/google/tink/go/proto/kms_aead_go_proto" 31 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 32) 33 34const kmsAEADTypeURL = "type.googleapis.com/google.crypto.tink.KmsAeadKey" 35 36type keyManager struct{} 37 38func (km *keyManager) Primitive(protoSerializedKey []byte) (interface{}, error) { 39 if len(protoSerializedKey) == 0 { 40 return nil, errors.New("kmsaead.keyManager: invalid key") 41 } 42 key := new(kmsaeadpb.KmsAeadKey) 43 if err := proto.Unmarshal(protoSerializedKey, key); err != nil { 44 return nil, errors.New("kmsaead.keyManager: invalid key") 45 } 46 err := keyset.ValidateKeyVersion(key.Version, 0) 47 if err != nil { 48 return nil, errors.New("kmsaead.keyManager: invalid version") 49 } 50 uri := key.GetParams().GetKeyUri() 51 kmsClient, err := registry.GetKMSClient(uri) 52 if err != nil { 53 return nil, err 54 } 55 return kmsClient.GetAEAD(uri) 56} 57 58func (km *keyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) { 59 if len(serializedKeyFormat) == 0 { 60 return nil, errors.New("kmsaead.keyManager: invalid key format") 61 } 62 keyFormat := new(kmsaeadpb.KmsAeadKeyFormat) 63 if err := proto.Unmarshal(serializedKeyFormat, keyFormat); err != nil { 64 return nil, errors.New("kmsaead.keyManager: invalid key format") 65 } 66 return &kmsaeadpb.KmsAeadKey{ 67 Version: 0, 68 Params: keyFormat, 69 }, nil 70} 71 72func (km *keyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) { 73 key, err := km.NewKey(serializedKeyFormat) 74 if err != nil { 75 return nil, err 76 } 77 serializedKey, err := proto.Marshal(key) 78 if err != nil { 79 return nil, err 80 } 81 return &tinkpb.KeyData{ 82 TypeUrl: kmsAEADTypeURL, 83 Value: serializedKey, 84 KeyMaterialType: tinkpb.KeyData_REMOTE, 85 }, nil 86} 87 88func (km *keyManager) DoesSupport(typeURL string) bool { 89 return typeURL == kmsAEADTypeURL 90} 91 92func (km *keyManager) TypeURL() string { 93 return kmsAEADTypeURL 94} 95 96// NewKeyManager returns a new KeyManager for the KMS AEAD key type. 97func NewKeyManager() registry.KeyManager { return new(keyManager) } 98 99// CreateKeyTemplate creates a new KMS AEAD key template. 100func CreateKeyTemplate(uri string) (*tinkpb.KeyTemplate, error) { 101 f := &kmsaeadpb.KmsAeadKeyFormat{KeyUri: uri} 102 serializedFormat, err := proto.Marshal(f) 103 if err != nil { 104 return nil, fmt.Errorf("failed to marshal key format: %s", err) 105 } 106 return &tinkpb.KeyTemplate{ 107 Value: serializedFormat, 108 TypeUrl: kmsAEADTypeURL, 109 OutputPrefixType: tinkpb.OutputPrefixType_RAW, 110 }, nil 111} 112