// Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // /////////////////////////////////////////////////////////////////////////////// // Package services is implements gRPC services for testing_api. package services import ( "bytes" "context" "errors" "github.com/google/tink/go/aead" "github.com/google/tink/go/daead" "github.com/google/tink/go/hybrid" "github.com/google/tink/go/insecurecleartextkeyset" "github.com/google/tink/go/jwt" "github.com/google/tink/go/keyset" "github.com/google/tink/go/mac" "github.com/google/tink/go/prf" "github.com/google/tink/go/signature" "github.com/google/tink/go/streamingaead" tinkpb "github.com/google/tink/go/proto/tink_go_proto" pb "github.com/google/tink/testing/go/protos/testing_api_go_grpc" "google.golang.org/protobuf/proto" ) // KeysetService implements the Keyset testing service. type KeysetService struct { Templates map[string]*tinkpb.KeyTemplate pb.KeysetServer } func (s *KeysetService) GetTemplate(ctx context.Context, req *pb.KeysetTemplateRequest) (*pb.KeysetTemplateResponse, error) { if s.Templates == nil { s.Templates = map[string]*tinkpb.KeyTemplate{ "AES128_GCM": aead.AES128GCMKeyTemplate(), "AES256_GCM": aead.AES256GCMKeyTemplate(), "AES256_GCM_RAW": aead.AES256GCMNoPrefixKeyTemplate(), "AES128_GCM_SIV": aead.AES128GCMSIVKeyTemplate(), "AES256_GCM_SIV": aead.AES256GCMSIVKeyTemplate(), "AES256_GCM_SIV_RAW": aead.AES256GCMSIVNoPrefixKeyTemplate(), "AES128_CTR_HMAC_SHA256": aead.AES128CTRHMACSHA256KeyTemplate(), "AES256_CTR_HMAC_SHA256": aead.AES256CTRHMACSHA256KeyTemplate(), "CHACHA20_POLY1305": aead.ChaCha20Poly1305KeyTemplate(), "XCHACHA20_POLY1305": aead.XChaCha20Poly1305KeyTemplate(), "AES256_SIV": daead.AESSIVKeyTemplate(), "AES128_CTR_HMAC_SHA256_4KB": streamingaead.AES128CTRHMACSHA256Segment4KBKeyTemplate(), "AES128_CTR_HMAC_SHA256_1MB": streamingaead.AES128CTRHMACSHA256Segment1MBKeyTemplate(), "AES256_CTR_HMAC_SHA256_4KB": streamingaead.AES256CTRHMACSHA256Segment4KBKeyTemplate(), "AES256_CTR_HMAC_SHA256_1MB": streamingaead.AES256CTRHMACSHA256Segment1MBKeyTemplate(), "AES128_GCM_HKDF_4KB": streamingaead.AES128GCMHKDF4KBKeyTemplate(), "AES128_GCM_HKDF_1MB": streamingaead.AES128GCMHKDF1MBKeyTemplate(), "AES256_GCM_HKDF_4KB": streamingaead.AES256GCMHKDF4KBKeyTemplate(), "AES256_GCM_HKDF_1MB": streamingaead.AES256GCMHKDF1MBKeyTemplate(), "ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM": hybrid.ECIESHKDFAES128GCMKeyTemplate(), "ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256": hybrid.ECIESHKDFAES128CTRHMACSHA256KeyTemplate(), "DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM": hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template(), "DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_RAW": hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Raw_Key_Template(), "DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM": hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM_Key_Template(), "DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM_RAW": hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM_Raw_Key_Template(), "DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305": hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305_Key_Template(), "DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305_RAW": hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305_Raw_Key_Template(), "AES_CMAC": mac.AESCMACTag128KeyTemplate(), "HMAC_SHA256_128BITTAG": mac.HMACSHA256Tag128KeyTemplate(), "HMAC_SHA256_256BITTAG": mac.HMACSHA256Tag256KeyTemplate(), "HMAC_SHA512_256BITTAG": mac.HMACSHA512Tag256KeyTemplate(), "HMAC_SHA512_512BITTAG": mac.HMACSHA512Tag512KeyTemplate(), "ECDSA_P256": signature.ECDSAP256KeyTemplate(), "ECDSA_P256_RAW": signature.ECDSAP256RawKeyTemplate(), "ECDSA_P384_SHA384": signature.ECDSAP384SHA384KeyTemplate(), "ECDSA_P384_SHA512": signature.ECDSAP384SHA512KeyTemplate(), "ECDSA_P521": signature.ECDSAP521KeyTemplate(), "ED25519": signature.ED25519KeyTemplate(), "RSA_SSA_PKCS1_3072_SHA256_F4": signature.RSA_SSA_PKCS1_3072_SHA256_F4_Key_Template(), "RSA_SSA_PKCS1_4096_SHA512_F4": signature.RSA_SSA_PKCS1_4096_SHA512_F4_Key_Template(), "RSA_SSA_PSS_3072_SHA256_SHA256_32_F4": signature.RSA_SSA_PSS_3072_SHA256_32_F4_Key_Template(), "RSA_SSA_PSS_4096_SHA512_SHA512_64_F4": signature.RSA_SSA_PSS_4096_SHA512_64_F4_Key_Template(), "AES_CMAC_PRF": prf.AESCMACPRFKeyTemplate(), "HMAC_SHA256_PRF": prf.HMACSHA256PRFKeyTemplate(), "HMAC_SHA512_PRF": prf.HMACSHA512PRFKeyTemplate(), "HKDF_SHA256": prf.HKDFSHA256PRFKeyTemplate(), "JWT_HS256": jwt.HS256Template(), "JWT_HS256_RAW": jwt.RawHS256Template(), "JWT_HS384": jwt.HS384Template(), "JWT_HS384_RAW": jwt.RawHS384Template(), "JWT_HS512": jwt.HS512Template(), "JWT_HS512_RAW": jwt.RawHS512Template(), "JWT_ES256": jwt.ES256Template(), "JWT_ES256_RAW": jwt.RawES256Template(), "JWT_ES384": jwt.ES384Template(), "JWT_ES384_RAW": jwt.RawES384Template(), "JWT_ES512": jwt.ES512Template(), "JWT_ES512_RAW": jwt.RawES512Template(), "JWT_RS256_2048_F4": jwt.RS256_2048_F4_Key_Template(), "JWT_RS256_2048_F4_RAW": jwt.RawRS256_2048_F4_Key_Template(), "JWT_RS256_3072_F4": jwt.RS256_3072_F4_Key_Template(), "JWT_RS256_3072_F4_RAW": jwt.RawRS256_3072_F4_Key_Template(), "JWT_RS384_3072_F4": jwt.RS384_3072_F4_Key_Template(), "JWT_RS384_3072_F4_RAW": jwt.RawRS384_3072_F4_Key_Template(), "JWT_RS512_4096_F4": jwt.RS512_4096_F4_Key_Template(), "JWT_RS512_4096_F4_RAW": jwt.RawRS512_4096_F4_Key_Template(), "JWT_PS256_2048_F4": jwt.PS256_2048_F4_Key_Template(), "JWT_PS256_2048_F4_RAW": jwt.RawPS256_2048_F4_Key_Template(), "JWT_PS256_3072_F4": jwt.PS256_3072_F4_Key_Template(), "JWT_PS256_3072_F4_RAW": jwt.RawPS256_3072_F4_Key_Template(), "JWT_PS384_3072_F4": jwt.PS384_3072_F4_Key_Template(), "JWT_PS384_3072_F4_RAW": jwt.RawPS384_3072_F4_Key_Template(), "JWT_PS512_4096_F4": jwt.PS512_4096_F4_Key_Template(), "JWT_PS512_4096_F4_RAW": jwt.RawPS512_4096_F4_Key_Template(), } } template, success := s.Templates[req.GetTemplateName()] if success && template != nil { d, err := proto.Marshal(template) if err != nil { return &pb.KeysetTemplateResponse{ Result: &pb.KeysetTemplateResponse_Err{err.Error()}}, nil } return &pb.KeysetTemplateResponse{ Result: &pb.KeysetTemplateResponse_KeyTemplate{d}}, nil } return &pb.KeysetTemplateResponse{ Result: &pb.KeysetTemplateResponse_Err{"key template not found"}}, nil } func (s *KeysetService) Generate(ctx context.Context, req *pb.KeysetGenerateRequest) (*pb.KeysetGenerateResponse, error) { template := &tinkpb.KeyTemplate{} err := proto.Unmarshal(req.Template, template) if err != nil { return &pb.KeysetGenerateResponse{ Result: &pb.KeysetGenerateResponse_Err{err.Error()}}, nil } handle, err := keyset.NewHandle(template) if err != nil { return &pb.KeysetGenerateResponse{ Result: &pb.KeysetGenerateResponse_Err{err.Error()}}, nil } buf := new(bytes.Buffer) writer := keyset.NewBinaryWriter(buf) err = insecurecleartextkeyset.Write(handle, writer) if err != nil { return &pb.KeysetGenerateResponse{ Result: &pb.KeysetGenerateResponse_Err{err.Error()}}, nil } return &pb.KeysetGenerateResponse{ Result: &pb.KeysetGenerateResponse_Keyset{buf.Bytes()}}, nil } func (s *KeysetService) Public(ctx context.Context, req *pb.KeysetPublicRequest) (*pb.KeysetPublicResponse, error) { reader := keyset.NewBinaryReader(bytes.NewReader(req.PrivateKeyset)) privateHandle, err := insecurecleartextkeyset.Read(reader) if err != nil { return &pb.KeysetPublicResponse{ Result: &pb.KeysetPublicResponse_Err{err.Error()}}, nil } publicHandle, err := privateHandle.Public() if err != nil { return &pb.KeysetPublicResponse{ Result: &pb.KeysetPublicResponse_Err{err.Error()}}, nil } buf := new(bytes.Buffer) writer := keyset.NewBinaryWriter(buf) err = insecurecleartextkeyset.Write(publicHandle, writer) if err != nil { return &pb.KeysetPublicResponse{ Result: &pb.KeysetPublicResponse_Err{err.Error()}}, nil } return &pb.KeysetPublicResponse{ Result: &pb.KeysetPublicResponse_PublicKeyset{buf.Bytes()}}, nil } func (s *KeysetService) ToJson(ctx context.Context, req *pb.KeysetToJsonRequest) (*pb.KeysetToJsonResponse, error) { reader := keyset.NewBinaryReader(bytes.NewReader(req.Keyset)) handle, err := insecurecleartextkeyset.Read(reader) if err != nil { return &pb.KeysetToJsonResponse{ Result: &pb.KeysetToJsonResponse_Err{err.Error()}}, nil } buf := new(bytes.Buffer) writer := keyset.NewJSONWriter(buf) if err := insecurecleartextkeyset.Write(handle, writer); err != nil { return &pb.KeysetToJsonResponse{ Result: &pb.KeysetToJsonResponse_Err{err.Error()}}, nil } return &pb.KeysetToJsonResponse{ Result: &pb.KeysetToJsonResponse_JsonKeyset{buf.String()}}, nil } func (s *KeysetService) FromJson(ctx context.Context, req *pb.KeysetFromJsonRequest) (*pb.KeysetFromJsonResponse, error) { reader := keyset.NewJSONReader(bytes.NewBufferString(req.JsonKeyset)) handle, err := insecurecleartextkeyset.Read(reader) if err != nil { return &pb.KeysetFromJsonResponse{ Result: &pb.KeysetFromJsonResponse_Err{err.Error()}}, nil } buf := new(bytes.Buffer) writer := keyset.NewBinaryWriter(buf) if err := insecurecleartextkeyset.Write(handle, writer); err != nil { return &pb.KeysetFromJsonResponse{ Result: &pb.KeysetFromJsonResponse_Err{err.Error()}}, nil } return &pb.KeysetFromJsonResponse{ Result: &pb.KeysetFromJsonResponse_Keyset{buf.Bytes()}}, nil } func (s *KeysetService) WriteEncrypted(ctx context.Context, req *pb.KeysetWriteEncryptedRequest) (*pb.KeysetWriteEncryptedResponse, error) { masterReader := keyset.NewBinaryReader(bytes.NewReader(req.GetMasterKeyset())) masterHandle, err := insecurecleartextkeyset.Read(masterReader) if err != nil { return &pb.KeysetWriteEncryptedResponse{ Result: &pb.KeysetWriteEncryptedResponse_Err{err.Error()}}, nil } masterAead, err := aead.New(masterHandle) if err != nil { return &pb.KeysetWriteEncryptedResponse{ Result: &pb.KeysetWriteEncryptedResponse_Err{err.Error()}}, nil } reader := keyset.NewBinaryReader(bytes.NewReader(req.GetKeyset())) handle, err := insecurecleartextkeyset.Read(reader) if err != nil { return &pb.KeysetWriteEncryptedResponse{ Result: &pb.KeysetWriteEncryptedResponse_Err{err.Error()}}, nil } buf := new(bytes.Buffer) var writer keyset.Writer if req.GetKeysetWriterType() == pb.KeysetWriterType_KEYSET_WRITER_BINARY { writer = keyset.NewBinaryWriter(buf) } else if req.GetKeysetWriterType() == pb.KeysetWriterType_KEYSET_WRITER_JSON { writer = keyset.NewJSONWriter(buf) } else { return nil, errors.New("unknown keyset writer type") } if req.GetAssociatedData() != nil { err = handle.WriteWithAssociatedData(writer, masterAead, req.GetAssociatedData().GetValue()) } else { err = handle.Write(writer, masterAead) } if err != nil { return &pb.KeysetWriteEncryptedResponse{ Result: &pb.KeysetWriteEncryptedResponse_Err{err.Error()}}, nil } return &pb.KeysetWriteEncryptedResponse{ Result: &pb.KeysetWriteEncryptedResponse_EncryptedKeyset{buf.Bytes()}}, nil } func (s *KeysetService) ReadEncrypted(ctx context.Context, req *pb.KeysetReadEncryptedRequest) (*pb.KeysetReadEncryptedResponse, error) { masterReader := keyset.NewBinaryReader(bytes.NewReader(req.GetMasterKeyset())) masterHandle, err := insecurecleartextkeyset.Read(masterReader) if err != nil { return &pb.KeysetReadEncryptedResponse{ Result: &pb.KeysetReadEncryptedResponse_Err{err.Error()}}, nil } masterAead, err := aead.New(masterHandle) if err != nil { return &pb.KeysetReadEncryptedResponse{ Result: &pb.KeysetReadEncryptedResponse_Err{err.Error()}}, nil } var reader keyset.Reader if req.GetKeysetReaderType() == pb.KeysetReaderType_KEYSET_READER_BINARY { reader = keyset.NewBinaryReader(bytes.NewReader(req.GetEncryptedKeyset())) } else if req.GetKeysetReaderType() == pb.KeysetReaderType_KEYSET_READER_JSON { reader = keyset.NewJSONReader(bytes.NewReader(req.GetEncryptedKeyset())) } else { return nil, errors.New("unknown keyset reader type") } var handle *keyset.Handle if req.GetAssociatedData() != nil { handle, err = keyset.ReadWithAssociatedData(reader, masterAead, req.GetAssociatedData().GetValue()) } else { handle, err = keyset.Read(reader, masterAead) } if err != nil { return &pb.KeysetReadEncryptedResponse{ Result: &pb.KeysetReadEncryptedResponse_Err{err.Error()}}, nil } buf := new(bytes.Buffer) writer := keyset.NewBinaryWriter(buf) if err := insecurecleartextkeyset.Write(handle, writer); err != nil { return &pb.KeysetReadEncryptedResponse{ Result: &pb.KeysetReadEncryptedResponse_Err{err.Error()}}, nil } return &pb.KeysetReadEncryptedResponse{ Result: &pb.KeysetReadEncryptedResponse_Keyset{buf.Bytes()}}, nil }