xref: /aosp_15_r20/external/tink/testing/cc/create.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2022 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 #ifndef TINK_TESTING_CREATE_H_
18 #define TINK_TESTING_CREATE_H_
19 
20 #include <grpcpp/grpcpp.h>
21 #include <grpcpp/server_context.h>
22 #include <grpcpp/support/status.h>
23 
24 #include <memory>
25 #include <string>
26 #include <utility>
27 
28 #include "absl/container/flat_hash_map.h"
29 #include "tink/binary_keyset_reader.h"
30 #include "tink/cleartext_keyset_handle.h"
31 #include "tink/keyset_handle.h"
32 #include "tink/keyset_reader.h"
33 #include "proto/testing_api.grpc.pb.h"
34 
35 namespace tink_testing_api {
36 
37 // Tries to create a primitive from a keyset serialized in binary proto format.
38 // This function might be better in Tink itself (except that it should take an
39 // optional SecretKeyAccessToken).
40 template <typename T>
41 crypto::tink::util::StatusOr<std::unique_ptr<T>>
PrimitiveFromSerializedBinaryProtoKeyset(const AnnotatedKeyset & annotated_keyset)42 PrimitiveFromSerializedBinaryProtoKeyset(
43     const AnnotatedKeyset& annotated_keyset) {
44   crypto::tink::util::StatusOr<std::unique_ptr<crypto::tink::KeysetReader>>
45       reader = crypto::tink::BinaryKeysetReader::New(
46           annotated_keyset.serialized_keyset());
47   if (!reader.ok()) {
48     return reader.status();
49   }
50   absl::flat_hash_map<std::string, std::string> annotations;
51   for (const auto& annotation : annotated_keyset.annotations()) {
52     annotations[annotation.first] = annotation.second;
53   }
54   crypto::tink::util::StatusOr<std::unique_ptr<crypto::tink::KeysetHandle>>
55       handle = crypto::tink::CleartextKeysetHandle::Read(*std::move(reader),
56                                                          annotations);
57   if (!handle.ok()) {
58     return handle.status();
59   }
60   return (*handle)->GetPrimitive<T>();
61 }
62 
63 // Tries to create a primitive of type T from the creation request and
64 // populates the response accordingly. This can be used in implementations
65 // of the "Create" RPC calls in the Tink Services.
66 template <typename T>
CreatePrimitiveForRpc(const CreationRequest * request,CreationResponse * response)67 grpc::Status CreatePrimitiveForRpc(const CreationRequest* request,
68                                    CreationResponse* response) {
69   crypto::tink::util::StatusOr<std::unique_ptr<T>> primitive =
70       PrimitiveFromSerializedBinaryProtoKeyset<T>(request->annotated_keyset());
71   if (!primitive.ok()) {
72     response->set_err(std::string(primitive.status().message()));
73   }
74   return grpc::Status::OK;
75 }
76 
77 }  // namespace tink_testing_api
78 
79 #endif  // TINK_TESTING_CREATE_H_
80