| // 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 |
| } |