xref: /aosp_15_r20/external/tink/testing/cc/keyset_impl.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 // Implementation of a Keyset Service.
18 #include "keyset_impl.h"
19 
20 #include <ostream>
21 #include <memory>
22 #include <sstream>
23 #include <string>
24 #include <utility>
25 
26 #include "tink/aead/aead_key_templates.h"
27 #include "tink/binary_keyset_reader.h"
28 #include "tink/binary_keyset_writer.h"
29 #include "tink/cleartext_keyset_handle.h"
30 #include "tink/daead/deterministic_aead_key_templates.h"
31 #include "tink/hybrid/hybrid_key_templates.h"
32 #include "tink/json_keyset_reader.h"
33 #include "tink/json_keyset_writer.h"
34 #include "tink/jwt/jwt_key_templates.h"
35 #include "tink/keyset_handle.h"
36 #include "tink/mac/mac_key_templates.h"
37 #include "tink/prf/prf_key_templates.h"
38 #include "tink/signature/signature_key_templates.h"
39 #include "tink/streamingaead/streaming_aead_key_templates.h"
40 #include "proto/tink.pb.h"
41 
42 namespace tink_testing_api {
43 
44 using ::crypto::tink::BinaryKeysetReader;
45 using ::crypto::tink::BinaryKeysetWriter;
46 using ::crypto::tink::CleartextKeysetHandle;
47 using ::crypto::tink::JsonKeysetReader;
48 using ::crypto::tink::JsonKeysetWriter;
49 using ::crypto::tink::KeysetHandle;
50 using ::crypto::tink::KeysetReader;
51 using ::crypto::tink::KeysetWriter;
52 using ::crypto::tink::util::StatusOr;
53 using ::google::crypto::tink::KeyTemplate;
54 
KeysetImpl()55 KeysetImpl::KeysetImpl() {
56   key_templates_["AES128_EAX"] = crypto::tink::AeadKeyTemplates::Aes128Eax();
57   key_templates_["AES256_EAX"] = crypto::tink::AeadKeyTemplates::Aes256Eax();
58   key_templates_["AES128_GCM"] = crypto::tink::AeadKeyTemplates::Aes128Gcm();
59   key_templates_["AES128_GCM_RAW"] =
60       crypto::tink::AeadKeyTemplates::Aes128GcmNoPrefix();
61   key_templates_["AES256_GCM"] = crypto::tink::AeadKeyTemplates::Aes256Gcm();
62   key_templates_["AES256_GCM_RAW"] =
63       crypto::tink::AeadKeyTemplates::Aes256GcmNoPrefix();
64   key_templates_["AES128_GCM_SIV"] =
65       crypto::tink::AeadKeyTemplates::Aes128GcmSiv();
66   key_templates_["AES256_GCM_SIV"] =
67       crypto::tink::AeadKeyTemplates::Aes256GcmSiv();
68   key_templates_["AES128_CTR_HMAC_SHA256"] =
69       crypto::tink::AeadKeyTemplates::Aes128CtrHmacSha256();
70   key_templates_["AES256_CTR_HMAC_SHA256"] =
71       crypto::tink::AeadKeyTemplates::Aes256CtrHmacSha256();
72   key_templates_["CHACHA20_POLY1305"] =
73       crypto::tink::AeadKeyTemplates::XChaCha20Poly1305();
74   key_templates_["XCHACHA20_POLY1305"] =
75       crypto::tink::AeadKeyTemplates::XChaCha20Poly1305();
76   key_templates_["AES256_SIV"] =
77       crypto::tink::DeterministicAeadKeyTemplates::Aes256Siv();
78   key_templates_["AES128_CTR_HMAC_SHA256_4KB"] =
79       crypto::tink::StreamingAeadKeyTemplates::Aes128CtrHmacSha256Segment4KB();
80   key_templates_["AES128_CTR_HMAC_SHA256_1MB"] =
81       crypto::tink::StreamingAeadKeyTemplates::Aes128CtrHmacSha256Segment1MB();
82   key_templates_["AES256_CTR_HMAC_SHA256_4KB"] =
83       crypto::tink::StreamingAeadKeyTemplates::Aes256CtrHmacSha256Segment4KB();
84   key_templates_["AES256_CTR_HMAC_SHA256_1MB"] =
85       crypto::tink::StreamingAeadKeyTemplates::Aes256CtrHmacSha256Segment1MB();
86   key_templates_["AES128_GCM_HKDF_4KB"] =
87       crypto::tink::StreamingAeadKeyTemplates::Aes128GcmHkdf4KB();
88   key_templates_["AES256_GCM_HKDF_4KB"] =
89       crypto::tink::StreamingAeadKeyTemplates::Aes256GcmHkdf4KB();
90   key_templates_["AES256_GCM_HKDF_1MB"] =
91       crypto::tink::StreamingAeadKeyTemplates::Aes256GcmHkdf1MB();
92   key_templates_["ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM"] =
93       crypto::tink::HybridKeyTemplates::EciesP256HkdfHmacSha256Aes128Gcm();
94   key_templates_["ECIES_P256_COMPRESSED_HKDF_HMAC_SHA256_AES128_GCM"] = crypto::
95       tink::HybridKeyTemplates::EciesP256CompressedHkdfHmacSha256Aes128Gcm();
96   key_templates_["ECIES_P256_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256"] =
97       crypto::tink::HybridKeyTemplates::
98           EciesP256HkdfHmacSha256Aes128CtrHmacSha256();
99   key_templates_
100       ["ECIES_P256_COMPRESSED_HKDF_HMAC_SHA256_AES128_CTR_HMAC_SHA256"] =
101           crypto::tink::HybridKeyTemplates::
102               EciesP256CompressedHkdfHmacSha256Aes128CtrHmacSha256();
103   key_templates_["DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM"] =
104       crypto::tink::HybridKeyTemplates::HpkeX25519HkdfSha256Aes128Gcm();
105   key_templates_["DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_RAW"] =
106       crypto::tink::HybridKeyTemplates::HpkeX25519HkdfSha256Aes128GcmRaw();
107   key_templates_["DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM"] =
108       crypto::tink::HybridKeyTemplates::HpkeX25519HkdfSha256Aes256Gcm();
109   key_templates_["DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM_RAW"] =
110       crypto::tink::HybridKeyTemplates::HpkeX25519HkdfSha256Aes256GcmRaw();
111   key_templates_["DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305"] =
112       crypto::tink::HybridKeyTemplates::HpkeX25519HkdfSha256ChaCha20Poly1305();
113   key_templates_["DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305_RAW"] =
114       crypto::tink::HybridKeyTemplates::
115           HpkeX25519HkdfSha256ChaCha20Poly1305Raw();
116   key_templates_["AES_CMAC"] = crypto::tink::MacKeyTemplates::AesCmac();
117   key_templates_["HMAC_SHA256_128BITTAG"] =
118       crypto::tink::MacKeyTemplates::HmacSha256HalfSizeTag();
119   key_templates_["HMAC_SHA256_256BITTAG"] =
120       crypto::tink::MacKeyTemplates::HmacSha256();
121   key_templates_["HMAC_SHA512_256BITTAG"] =
122       crypto::tink::MacKeyTemplates::HmacSha512HalfSizeTag();
123   key_templates_["HMAC_SHA512_512BITTAG"] =
124       crypto::tink::MacKeyTemplates::HmacSha512();
125   key_templates_["ECDSA_P256"] =
126       crypto::tink::SignatureKeyTemplates::EcdsaP256();
127   key_templates_["ECDSA_P256_RAW"] =
128       crypto::tink::SignatureKeyTemplates::EcdsaP256Raw();
129   key_templates_["ECDSA_P384"] =
130       crypto::tink::SignatureKeyTemplates::EcdsaP384();
131   key_templates_["ECDSA_P384_SHA384"] =
132       crypto::tink::SignatureKeyTemplates::EcdsaP384Sha384();
133   key_templates_["ECDSA_P384_SHA512"] =
134       crypto::tink::SignatureKeyTemplates::EcdsaP384Sha512();
135   key_templates_["ECDSA_P521"] =
136       crypto::tink::SignatureKeyTemplates::EcdsaP521();
137   key_templates_["ECDSA_P256_IEEE_P1363"] =
138       crypto::tink::SignatureKeyTemplates::EcdsaP256Ieee();
139   key_templates_["ECDSA_P384_IEEE_P1363"] =
140       crypto::tink::SignatureKeyTemplates::EcdsaP384Ieee();
141   key_templates_["ECDSA_P521_IEEE_P1363"] =
142       crypto::tink::SignatureKeyTemplates::EcdsaP521Ieee();
143   key_templates_["ED25519"] = crypto::tink::SignatureKeyTemplates::Ed25519();
144   key_templates_["RSA_SSA_PKCS1_3072_SHA256_F4"] =
145       crypto::tink::SignatureKeyTemplates::RsaSsaPkcs13072Sha256F4();
146   key_templates_["RSA_SSA_PKCS1_4096_SHA512_F4"] =
147       crypto::tink::SignatureKeyTemplates::RsaSsaPkcs14096Sha512F4();
148   key_templates_["RSA_SSA_PSS_3072_SHA256_SHA256_32_F4"] =
149       crypto::tink::SignatureKeyTemplates::RsaSsaPss3072Sha256Sha256F4();
150   key_templates_["RSA_SSA_PSS_4096_SHA512_SHA512_64_F4"] =
151       crypto::tink::SignatureKeyTemplates::RsaSsaPss4096Sha512Sha512F4();
152   key_templates_["AES_CMAC_PRF"] = crypto::tink::PrfKeyTemplates::AesCmac();
153   key_templates_["HMAC_SHA256_PRF"] =
154       crypto::tink::PrfKeyTemplates::HmacSha256();
155   key_templates_["HMAC_SHA512_PRF"] =
156       crypto::tink::PrfKeyTemplates::HmacSha512();
157   key_templates_["HKDF_SHA256"] = crypto::tink::PrfKeyTemplates::HkdfSha256();
158   key_templates_["JWT_HS256"] = crypto::tink::JwtHs256Template();
159   key_templates_["JWT_HS256_RAW"] = crypto::tink::RawJwtHs256Template();
160   key_templates_["JWT_HS384"] = crypto::tink::JwtHs384Template();
161   key_templates_["JWT_HS384_RAW"] = crypto::tink::RawJwtHs384Template();
162   key_templates_["JWT_HS512"] = crypto::tink::JwtHs512Template();
163   key_templates_["JWT_HS512_RAW"] = crypto::tink::RawJwtHs512Template();
164   key_templates_["JWT_ES256"] = crypto::tink::JwtEs256Template();
165   key_templates_["JWT_ES256_RAW"] = crypto::tink::RawJwtEs256Template();
166   key_templates_["JWT_ES384"] = crypto::tink::JwtEs384Template();
167   key_templates_["JWT_ES384_RAW"] = crypto::tink::RawJwtEs384Template();
168   key_templates_["JWT_ES512"] = crypto::tink::JwtEs512Template();
169   key_templates_["JWT_ES512_RAW"] = crypto::tink::RawJwtEs512Template();
170   key_templates_["JWT_RS256_2048_F4"] =
171       crypto::tink::JwtRs256_2048_F4_Template();
172   key_templates_["JWT_RS256_2048_F4_RAW"] =
173       crypto::tink::RawJwtRs256_2048_F4_Template();
174   key_templates_["JWT_RS256_3072_F4"] =
175       crypto::tink::JwtRs256_3072_F4_Template();
176   key_templates_["JWT_RS256_3072_F4_RAW"] =
177       crypto::tink::RawJwtRs256_3072_F4_Template();
178   key_templates_["JWT_RS384_3072_F4"] =
179       crypto::tink::JwtRs384_3072_F4_Template();
180   key_templates_["JWT_RS384_3072_F4_RAW"] =
181       crypto::tink::RawJwtRs384_3072_F4_Template();
182   key_templates_["JWT_RS512_4096_F4"] =
183       crypto::tink::JwtRs512_4096_F4_Template();
184   key_templates_["JWT_RS512_4096_F4_RAW"] =
185       crypto::tink::RawJwtRs512_4096_F4_Template();
186   key_templates_["JWT_PS256_2048_F4"] =
187       crypto::tink::JwtPs256_2048_F4_Template();
188   key_templates_["JWT_PS256_2048_F4_RAW"] =
189       crypto::tink::RawJwtPs256_2048_F4_Template();
190   key_templates_["JWT_PS256_3072_F4"] =
191       crypto::tink::JwtPs256_3072_F4_Template();
192   key_templates_["JWT_PS256_3072_F4_RAW"] =
193       crypto::tink::RawJwtPs256_3072_F4_Template();
194   key_templates_["JWT_PS384_3072_F4"] =
195       crypto::tink::JwtPs384_3072_F4_Template();
196   key_templates_["JWT_PS384_3072_F4_RAW"] =
197       crypto::tink::RawJwtPs384_3072_F4_Template();
198   key_templates_["JWT_PS512_4096_F4"] =
199       crypto::tink::JwtPs512_4096_F4_Template();
200   key_templates_["JWT_PS512_4096_F4_RAW"] =
201       crypto::tink::RawJwtPs512_4096_F4_Template();
202 }
203 
204 // Returns the key template for the given template name.
GetTemplate(grpc::ServerContext * context,const KeysetTemplateRequest * request,KeysetTemplateResponse * response)205 grpc::Status KeysetImpl::GetTemplate(grpc::ServerContext* context,
206                                        const KeysetTemplateRequest* request,
207                                        KeysetTemplateResponse* response) {
208   auto it = key_templates_.find(request->template_name());
209   if (it == key_templates_.end()) {
210     response->set_err(
211         absl::StrCat("key template not found: ", request->template_name()));
212     return grpc::Status::OK;
213   }
214   std::string templ;
215   if (!it->second.SerializeToString(&templ)) {
216     response->set_err("Failed to serialize template.");
217     return grpc::Status::OK;
218   }
219   response->set_key_template(templ);
220   return grpc::Status::OK;
221 }
222 
223 // Generates a new keyset with one key from a template.
Generate(grpc::ServerContext * context,const KeysetGenerateRequest * request,KeysetGenerateResponse * response)224 grpc::Status KeysetImpl::Generate(grpc::ServerContext* context,
225                                     const KeysetGenerateRequest* request,
226                                     KeysetGenerateResponse* response) {
227   KeyTemplate key_template;
228   if (!key_template.ParseFromString(request->template_())) {
229     response->set_err("Could not parse the key template");
230     return grpc::Status::OK;
231   }
232   auto handle_result = ::crypto::tink::KeysetHandle::GenerateNew(key_template);
233   if (!handle_result.ok()) {
234     response->set_err(std::string(handle_result.status().message()));
235     return grpc::Status::OK;
236   }
237   std::stringbuf keyset;
238   auto writer_result =
239       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
240   if (!writer_result.ok()) {
241     response->set_err(std::string(writer_result.status().message()));
242     return grpc::Status::OK;
243   }
244   auto status = CleartextKeysetHandle::Write(writer_result.value().get(),
245                                              *handle_result.value());
246   if (!status.ok()) {
247     response->set_err(std::string(status.message()));
248     return grpc::Status::OK;
249   }
250   response->set_keyset(keyset.str());
251   return grpc::Status::OK;
252 }
253 
254 // Returns a public keyset for a given private keyset.
Public(grpc::ServerContext * context,const KeysetPublicRequest * request,KeysetPublicResponse * response)255 grpc::Status KeysetImpl::Public(grpc::ServerContext* context,
256                                   const KeysetPublicRequest* request,
257                                   KeysetPublicResponse* response) {
258   auto reader_result = BinaryKeysetReader::New(request->private_keyset());
259   if (!reader_result.ok()) {
260     response->set_err(std::string(reader_result.status().message()));
261     return grpc::Status::OK;
262   }
263   auto private_handle_result =
264       CleartextKeysetHandle::Read(std::move(reader_result.value()));
265   if (!private_handle_result.ok()) {
266     response->set_err(std::string(private_handle_result.status().message()));
267     return grpc::Status::OK;
268   }
269   auto public_handle_result =
270       private_handle_result.value()->GetPublicKeysetHandle();
271   if (!public_handle_result.ok()) {
272     response->set_err(std::string(public_handle_result.status().message()));
273     return grpc::Status::OK;
274   }
275   std::stringbuf public_keyset;
276   auto writer_result =
277       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&public_keyset));
278   if (!writer_result.ok()) {
279     response->set_err(std::string(writer_result.status().message()));
280     return grpc::Status::OK;
281   }
282   auto status = CleartextKeysetHandle::Write(writer_result.value().get(),
283                                              *public_handle_result.value());
284   if (!status.ok()) {
285     response->set_err(std::string(status.message()));
286     return grpc::Status::OK;
287   }
288   response->set_public_keyset(public_keyset.str());
289   return grpc::Status::OK;
290 }
291 
292 // Converts a keyset from binary to JSON format.
ToJson(grpc::ServerContext * context,const KeysetToJsonRequest * request,KeysetToJsonResponse * response)293 grpc::Status KeysetImpl::ToJson(grpc::ServerContext* context,
294                                   const KeysetToJsonRequest* request,
295                                   KeysetToJsonResponse* response) {
296   auto reader_result = BinaryKeysetReader::New(request->keyset());
297   if (!reader_result.ok()) {
298     response->set_err(std::string(reader_result.status().message()));
299     return grpc::Status::OK;
300   }
301   auto handle_result =
302       CleartextKeysetHandle::Read(std::move(reader_result.value()));
303   if (!handle_result.ok()) {
304     response->set_err(std::string(handle_result.status().message()));
305     return grpc::Status::OK;
306   }
307   std::stringbuf json_keyset;
308   auto writer_result =
309       JsonKeysetWriter::New(absl::make_unique<std::ostream>(&json_keyset));
310   if (!writer_result.ok()) {
311     response->set_err(std::string(writer_result.status().message()));
312     return grpc::Status::OK;
313   }
314   auto status = CleartextKeysetHandle::Write(writer_result.value().get(),
315                                              *handle_result.value());
316   if (!status.ok()) {
317     response->set_err(std::string(status.message()));
318     return grpc::Status::OK;
319   }
320   response->set_json_keyset(json_keyset.str());
321   return grpc::Status::OK;
322 }
323 
324 // Converts a keyset from JSON to binary format.
FromJson(grpc::ServerContext * context,const KeysetFromJsonRequest * request,KeysetFromJsonResponse * response)325 grpc::Status KeysetImpl::FromJson(grpc::ServerContext* context,
326                                     const KeysetFromJsonRequest* request,
327                                     KeysetFromJsonResponse* response) {
328   auto reader_result = JsonKeysetReader::New(request->json_keyset());
329   if (!reader_result.ok()) {
330     response->set_err(std::string(reader_result.status().message()));
331     return grpc::Status::OK;
332   }
333   auto handle_result =
334       CleartextKeysetHandle::Read(std::move(reader_result.value()));
335   if (!handle_result.ok()) {
336     response->set_err(std::string(handle_result.status().message()));
337     return grpc::Status::OK;
338   }
339   std::stringbuf keyset;
340   auto writer_result =
341       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
342   if (!writer_result.ok()) {
343     response->set_err(std::string(writer_result.status().message()));
344     return grpc::Status::OK;
345   }
346   auto status = CleartextKeysetHandle::Write(writer_result.value().get(),
347                                              *handle_result.value());
348   if (!status.ok()) {
349     response->set_err(std::string(status.message()));
350     return grpc::Status::OK;
351   }
352   response->set_keyset(keyset.str());
353   return grpc::Status::OK;
354 }
355 
WriteEncrypted(grpc::ServerContext * context,const KeysetWriteEncryptedRequest * request,KeysetWriteEncryptedResponse * response)356 grpc::Status KeysetImpl::WriteEncrypted(
357     grpc::ServerContext* context, const KeysetWriteEncryptedRequest* request,
358     KeysetWriteEncryptedResponse* response) {
359   StatusOr<std::unique_ptr<KeysetReader>>
360       master_keyset_reader = BinaryKeysetReader::New(request->master_keyset());
361   if (!master_keyset_reader.ok()) {
362     response->set_err(std::string(master_keyset_reader.status().message()));
363     return grpc::Status::OK;
364   }
365   StatusOr<std::unique_ptr<KeysetHandle>> master_keyset_handle =
366       CleartextKeysetHandle::Read(*std::move(master_keyset_reader));
367   if (!master_keyset_handle.ok()) {
368     response->set_err(std::string(master_keyset_handle.status().message()));
369     return grpc::Status::OK;
370   }
371   StatusOr<std::unique_ptr<crypto::tink::Aead>> master_aead =
372       (*master_keyset_handle)->GetPrimitive<crypto::tink::Aead>();
373   if (!master_aead.ok()) {
374     response->set_err(std::string(master_aead.status().message()));
375     return grpc::Status::OK;
376   }
377 
378   StatusOr<std::unique_ptr<KeysetReader>> keyset_reader =
379       BinaryKeysetReader::New(request->keyset());
380   if (!keyset_reader.ok()) {
381     response->set_err(std::string(keyset_reader.status().message()));
382     return grpc::Status::OK;
383   }
384   StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
385       CleartextKeysetHandle::Read(*std::move(keyset_reader));
386   if (!keyset_handle.ok()) {
387     response->set_err(std::string(keyset_handle.status().message()));
388     return grpc::Status::OK;
389   }
390 
391   std::stringbuf encrypted_keyset;
392   std::unique_ptr<KeysetWriter> keyset_writer;
393 
394   if (request->keyset_writer_type() == KEYSET_WRITER_BINARY) {
395     StatusOr<std::unique_ptr<BinaryKeysetWriter>> binary_keyset_writer =
396         BinaryKeysetWriter::New(
397             absl::make_unique<std::ostream>(&encrypted_keyset));
398     if (!binary_keyset_writer.ok()) {
399       response->set_err(std::string(binary_keyset_writer.status().message()));
400       return grpc::Status::OK;
401     }
402     keyset_writer = *std::move(binary_keyset_writer);
403   } else if (request->keyset_writer_type() == KEYSET_WRITER_JSON) {
404     StatusOr<std::unique_ptr<JsonKeysetWriter>> json_keyset_writer =
405         JsonKeysetWriter::New(
406             absl::make_unique<std::ostream>(&encrypted_keyset));
407     if (!json_keyset_writer.ok()) {
408       response->set_err(std::string(json_keyset_writer.status().message()));
409       return grpc::Status::OK;
410     }
411     keyset_writer = *std::move(json_keyset_writer);
412   } else {
413     return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
414                         "unknown keyset_writer_type");
415   }
416 
417   if (request->has_associated_data()) {
418     crypto::tink::util::Status status =
419         (*keyset_handle)
420             ->WriteWithAssociatedData(keyset_writer.get(), **master_aead,
421                                       request->associated_data().value());
422     if (!status.ok()) {
423       response->set_err(std::string(status.message()));
424       return grpc::Status::OK;
425     }
426   } else {
427     crypto::tink::util::Status status =
428         (*keyset_handle)->Write(keyset_writer.get(), **master_aead);
429     if (!status.ok()) {
430       response->set_err(std::string(status.message()));
431       return grpc::Status::OK;
432     }
433   }
434   response->set_encrypted_keyset(encrypted_keyset.str());
435   return grpc::Status::OK;
436 }
437 
ReadEncrypted(grpc::ServerContext * context,const KeysetReadEncryptedRequest * request,KeysetReadEncryptedResponse * response)438 grpc::Status KeysetImpl::ReadEncrypted(
439     grpc::ServerContext* context, const KeysetReadEncryptedRequest* request,
440     KeysetReadEncryptedResponse* response) {
441   StatusOr<std::unique_ptr<KeysetReader>> master_keyset_reader =
442       BinaryKeysetReader::New(request->master_keyset());
443   if (!master_keyset_reader.ok()) {
444     response->set_err(std::string(master_keyset_reader.status().message()));
445     return grpc::Status::OK;
446   }
447   StatusOr<std::unique_ptr<KeysetHandle>> master_keyset_handle =
448       CleartextKeysetHandle::Read(*std::move(master_keyset_reader));
449   if (!master_keyset_handle.ok()) {
450     response->set_err(std::string(master_keyset_handle.status().message()));
451     return grpc::Status::OK;
452   }
453   StatusOr<std::unique_ptr<crypto::tink::Aead>> master_aead =
454       (*master_keyset_handle)->GetPrimitive<crypto::tink::Aead>();
455   if (!master_aead.ok()) {
456     response->set_err(std::string(master_aead.status().message()));
457     return grpc::Status::OK;
458   }
459 
460   std::unique_ptr<KeysetReader> keyset_reader;
461   if (request->keyset_reader_type() == KEYSET_READER_BINARY) {
462     StatusOr<std::unique_ptr<KeysetReader>> binary_keyset_reader =
463         BinaryKeysetReader::New(request->encrypted_keyset());
464     if (!binary_keyset_reader.ok()) {
465       response->set_err(std::string(binary_keyset_reader.status().message()));
466       return grpc::Status::OK;
467     }
468     keyset_reader = *std::move(binary_keyset_reader);
469   } else if (request->keyset_reader_type() == KEYSET_READER_JSON) {
470     StatusOr<std::unique_ptr<KeysetReader>> json_keyset_reader =
471         JsonKeysetReader::New(request->encrypted_keyset());
472     if (!json_keyset_reader.ok()) {
473       response->set_err(std::string(json_keyset_reader.status().message()));
474       return grpc::Status::OK;
475     }
476     keyset_reader = *std::move(json_keyset_reader);
477   } else {
478     return grpc::Status(grpc::StatusCode::INVALID_ARGUMENT,
479                         "unknown keyset_writer_type");
480   }
481 
482   std::unique_ptr<KeysetHandle> keyset_handle;
483   if (request->has_associated_data()) {
484     StatusOr<std::unique_ptr<KeysetHandle>> read_result =
485         ::crypto::tink::KeysetHandle::ReadWithAssociatedData(
486             std::move(keyset_reader), **master_aead,
487             request->associated_data().value());
488     if (!read_result.ok()) {
489       response->set_err(std::string(read_result.status().message()));
490       return grpc::Status::OK;
491     }
492     keyset_handle = *std::move(read_result);
493   } else {
494     StatusOr<std::unique_ptr<KeysetHandle>> read_result =
495         ::crypto::tink::KeysetHandle::Read(std::move(keyset_reader),
496                                            **master_aead);
497     if (!read_result.ok()) {
498       response->set_err(std::string(read_result.status().message()));
499       return grpc::Status::OK;
500     }
501     keyset_handle = *std::move(read_result);
502   }
503 
504   std::stringbuf keyset;
505   StatusOr<std::unique_ptr<BinaryKeysetWriter>> keyset_writer =
506       BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
507   if (!keyset_writer.ok()) {
508     response->set_err(std::string(keyset_writer.status().message()));
509     return grpc::Status::OK;
510   }
511   crypto::tink::util::Status status =
512       CleartextKeysetHandle::Write(keyset_writer->get(), *keyset_handle);
513   if (!status.ok()) {
514     response->set_err(std::string(status.message()));
515     return grpc::Status::OK;
516   }
517   response->set_keyset(keyset.str());
518   return grpc::Status::OK;
519 }
520 
521 }  // namespace tink_testing_api
522