• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 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 com.google.crypto.tink.testing;
18 
19 import static java.nio.charset.StandardCharsets.UTF_8;
20 
21 import com.google.crypto.tink.Aead;
22 import com.google.crypto.tink.InsecureSecretKeyAccess;
23 import com.google.crypto.tink.KeyTemplate;
24 import com.google.crypto.tink.KeyTemplates;
25 import com.google.crypto.tink.KeysetHandle;
26 import com.google.crypto.tink.TinkJsonProtoKeysetFormat;
27 import com.google.crypto.tink.TinkProtoKeysetFormat;
28 import com.google.crypto.tink.internal.KeyTemplateProtoConverter;
29 import com.google.crypto.tink.testing.proto.KeysetFromJsonRequest;
30 import com.google.crypto.tink.testing.proto.KeysetFromJsonResponse;
31 import com.google.crypto.tink.testing.proto.KeysetGenerateRequest;
32 import com.google.crypto.tink.testing.proto.KeysetGenerateResponse;
33 import com.google.crypto.tink.testing.proto.KeysetGrpc.KeysetImplBase;
34 import com.google.crypto.tink.testing.proto.KeysetPublicRequest;
35 import com.google.crypto.tink.testing.proto.KeysetPublicResponse;
36 import com.google.crypto.tink.testing.proto.KeysetReadEncryptedRequest;
37 import com.google.crypto.tink.testing.proto.KeysetReadEncryptedResponse;
38 import com.google.crypto.tink.testing.proto.KeysetReaderType;
39 import com.google.crypto.tink.testing.proto.KeysetTemplateRequest;
40 import com.google.crypto.tink.testing.proto.KeysetTemplateResponse;
41 import com.google.crypto.tink.testing.proto.KeysetToJsonRequest;
42 import com.google.crypto.tink.testing.proto.KeysetToJsonResponse;
43 import com.google.crypto.tink.testing.proto.KeysetWriteEncryptedRequest;
44 import com.google.crypto.tink.testing.proto.KeysetWriteEncryptedResponse;
45 import com.google.crypto.tink.testing.proto.KeysetWriterType;
46 import com.google.protobuf.ByteString;
47 import io.grpc.stub.StreamObserver;
48 import java.security.GeneralSecurityException;
49 
50 /** Implement a gRPC Keyset Testing service. */
51 public final class KeysetServiceImpl extends KeysetImplBase {
52 
KeysetServiceImpl()53   public KeysetServiceImpl() throws GeneralSecurityException {
54   }
55 
56   @Override
getTemplate( KeysetTemplateRequest request, StreamObserver<KeysetTemplateResponse> responseObserver)57   public void getTemplate(
58       KeysetTemplateRequest request, StreamObserver<KeysetTemplateResponse> responseObserver) {
59     KeysetTemplateResponse response;
60     try {
61       KeyTemplate template = KeyTemplates.get(request.getTemplateName());
62       response =
63           KeysetTemplateResponse.newBuilder()
64               .setKeyTemplate(ByteString.copyFrom(KeyTemplateProtoConverter.toByteArray(template)))
65               .build();
66     } catch (GeneralSecurityException e) {
67       response = KeysetTemplateResponse.newBuilder().setErr(e.toString()).build();
68     }
69     responseObserver.onNext(response);
70     responseObserver.onCompleted();
71   }
72 
73   @Override
generate( KeysetGenerateRequest request, StreamObserver<KeysetGenerateResponse> responseObserver)74   public void generate(
75       KeysetGenerateRequest request, StreamObserver<KeysetGenerateResponse> responseObserver) {
76     KeysetGenerateResponse response;
77     try {
78       KeyTemplate template =
79           KeyTemplateProtoConverter.fromByteArray(request.getTemplate().toByteArray());
80       KeysetHandle keysetHandle = KeysetHandle.generateNew(template);
81       byte[] serializedPublicKeyset =
82           TinkProtoKeysetFormat.serializeKeyset(keysetHandle, InsecureSecretKeyAccess.get());
83       response =
84           KeysetGenerateResponse.newBuilder()
85               .setKeyset(ByteString.copyFrom(serializedPublicKeyset))
86               .build();
87     } catch (GeneralSecurityException e) {
88       response = KeysetGenerateResponse.newBuilder().setErr(e.toString()).build();
89     }
90     responseObserver.onNext(response);
91     responseObserver.onCompleted();
92   }
93 
94   @Override
public_( KeysetPublicRequest request, StreamObserver<KeysetPublicResponse> responseObserver)95   public void public_(
96       KeysetPublicRequest request, StreamObserver<KeysetPublicResponse> responseObserver) {
97     KeysetPublicResponse response;
98     try {
99       KeysetHandle privateKeysetHandle =
100           TinkProtoKeysetFormat.parseKeyset(
101               request.getPrivateKeyset().toByteArray(), InsecureSecretKeyAccess.get());
102       KeysetHandle publicKeysetHandle = privateKeysetHandle.getPublicKeysetHandle();
103       byte[] serializedPublicKeyset =
104           TinkProtoKeysetFormat.serializeKeyset(publicKeysetHandle, InsecureSecretKeyAccess.get());
105       response =
106           KeysetPublicResponse.newBuilder()
107               .setPublicKeyset(ByteString.copyFrom(serializedPublicKeyset))
108               .build();
109     } catch (GeneralSecurityException e) {
110       response = KeysetPublicResponse.newBuilder().setErr(e.toString()).build();
111     }
112     responseObserver.onNext(response);
113     responseObserver.onCompleted();
114   }
115 
116   @Override
toJson( KeysetToJsonRequest request, StreamObserver<KeysetToJsonResponse> responseObserver)117   public void toJson(
118       KeysetToJsonRequest request, StreamObserver<KeysetToJsonResponse> responseObserver) {
119     KeysetToJsonResponse response;
120     try {
121       KeysetHandle keysetHandle =
122           TinkProtoKeysetFormat.parseKeyset(
123               request.getKeyset().toByteArray(), InsecureSecretKeyAccess.get());
124       String jsonKeyset =
125           TinkJsonProtoKeysetFormat.serializeKeyset(keysetHandle, InsecureSecretKeyAccess.get());
126       response = KeysetToJsonResponse.newBuilder().setJsonKeyset(jsonKeyset).build();
127     } catch (GeneralSecurityException e) {
128       response = KeysetToJsonResponse.newBuilder().setErr(e.toString()).build();
129     }
130     responseObserver.onNext(response);
131     responseObserver.onCompleted();
132   }
133 
134   @Override
fromJson( KeysetFromJsonRequest request, StreamObserver<KeysetFromJsonResponse> responseObserver)135   public void fromJson(
136       KeysetFromJsonRequest request, StreamObserver<KeysetFromJsonResponse> responseObserver) {
137     KeysetFromJsonResponse response;
138     try {
139       KeysetHandle keysetHandle =
140           TinkJsonProtoKeysetFormat.parseKeyset(
141               request.getJsonKeyset(), InsecureSecretKeyAccess.get());
142       byte[] serializeKeyset =
143           TinkProtoKeysetFormat.serializeKeyset(keysetHandle, InsecureSecretKeyAccess.get());
144       response =
145           KeysetFromJsonResponse.newBuilder()
146               .setKeyset(ByteString.copyFrom(serializeKeyset))
147               .build();
148     } catch (GeneralSecurityException e) {
149       response = KeysetFromJsonResponse.newBuilder().setErr(e.toString()).build();
150     }
151     responseObserver.onNext(response);
152     responseObserver.onCompleted();
153   }
154 
155   @Override
readEncrypted( KeysetReadEncryptedRequest request, StreamObserver<KeysetReadEncryptedResponse> responseObserver)156   public void readEncrypted(
157       KeysetReadEncryptedRequest request,
158       StreamObserver<KeysetReadEncryptedResponse> responseObserver) {
159     KeysetReadEncryptedResponse response;
160     try {
161       // get masterAead
162       KeysetHandle masterKeysetHandle =
163           TinkProtoKeysetFormat.parseKeyset(
164               request.getMasterKeyset().toByteArray(), InsecureSecretKeyAccess.get());
165       Aead masterAead = masterKeysetHandle.getPrimitive(Aead.class);
166 
167       // read encrypted keyset to keysetHandle
168       byte[] associatedData = request.getAssociatedData().getValue().toByteArray();
169 
170       KeysetHandle keysetHandle;
171       if (request.getKeysetReaderType() == KeysetReaderType.KEYSET_READER_BINARY) {
172         keysetHandle =
173             TinkProtoKeysetFormat.parseEncryptedKeyset(
174                 request.getEncryptedKeyset().toByteArray(), masterAead, associatedData);
175       } else if (request.getKeysetReaderType() == KeysetReaderType.KEYSET_READER_JSON) {
176         keysetHandle =
177             TinkJsonProtoKeysetFormat.parseEncryptedKeyset(
178                 request.getEncryptedKeyset().toStringUtf8(), masterAead, associatedData);
179       } else {
180         throw new IllegalArgumentException("unknown keyset reader type");
181       }
182 
183       // get keyset from keysetHandle
184       byte[] keyset =
185           TinkProtoKeysetFormat.serializeKeyset(keysetHandle, InsecureSecretKeyAccess.get());
186       response =
187           KeysetReadEncryptedResponse.newBuilder().setKeyset(ByteString.copyFrom(keyset)).build();
188     } catch (GeneralSecurityException e) {
189       response = KeysetReadEncryptedResponse.newBuilder().setErr(e.toString()).build();
190     }
191     responseObserver.onNext(response);
192     responseObserver.onCompleted();
193   }
194 
195   @Override
writeEncrypted( KeysetWriteEncryptedRequest request, StreamObserver<KeysetWriteEncryptedResponse> responseObserver)196   public void writeEncrypted(
197       KeysetWriteEncryptedRequest request,
198       StreamObserver<KeysetWriteEncryptedResponse> responseObserver) {
199     KeysetWriteEncryptedResponse response;
200     try {
201       // get masterAead
202       KeysetHandle masterKeysetHandle =
203           TinkProtoKeysetFormat.parseKeyset(
204               request.getMasterKeyset().toByteArray(), InsecureSecretKeyAccess.get());
205       Aead masterAead = masterKeysetHandle.getPrimitive(Aead.class);
206 
207       // get keysetHandle
208       KeysetHandle keysetHandle =
209           TinkProtoKeysetFormat.parseKeyset(
210               request.getKeyset().toByteArray(), InsecureSecretKeyAccess.get());
211 
212       // write keysetHandle as encrypted keyset
213       byte[] associatedData = request.getAssociatedData().getValue().toByteArray();
214       byte[] keyset;
215       if (request.getKeysetWriterType() == KeysetWriterType.KEYSET_WRITER_BINARY) {
216         keyset =
217             TinkProtoKeysetFormat.serializeEncryptedKeyset(
218                 keysetHandle, masterAead, associatedData);
219       } else if (request.getKeysetWriterType() == KeysetWriterType.KEYSET_WRITER_JSON) {
220         keyset =
221             TinkJsonProtoKeysetFormat.serializeEncryptedKeyset(
222                     keysetHandle, masterAead, associatedData)
223                 .getBytes(UTF_8);
224       } else {
225         throw new IllegalArgumentException("unknown keyset writer type");
226       }
227       response =
228           KeysetWriteEncryptedResponse.newBuilder()
229               .setEncryptedKeyset(ByteString.copyFrom(keyset))
230               .build();
231     } catch (GeneralSecurityException e) {
232       response = KeysetWriteEncryptedResponse.newBuilder().setErr(e.toString()).build();
233     }
234     responseObserver.onNext(response);
235     responseObserver.onCompleted();
236   }
237 }
238