xref: /aosp_15_r20/external/tink/cc/internal/keyset_wrapper_impl.h (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 #ifndef TINK_INTERNAL_KEYSET_WRAPPER_IMPL_H_
18 #define TINK_INTERNAL_KEYSET_WRAPPER_IMPL_H_
19 
20 #include <memory>
21 #include <string>
22 #include <utility>
23 
24 #include "absl/container/flat_hash_map.h"
25 #include "absl/functional/any_invocable.h"
26 #include "tink/internal/key_info.h"
27 #include "tink/internal/keyset_wrapper.h"
28 #include "tink/primitive_set.h"
29 #include "tink/primitive_wrapper.h"
30 #include "tink/util/status.h"
31 #include "tink/util/statusor.h"
32 #include "tink/util/validation.h"
33 #include "proto/tink.pb.h"
34 
35 namespace crypto {
36 namespace tink {
37 namespace internal {
38 
39 template <typename P, typename Q>
40 class KeysetWrapperImpl : public KeysetWrapper<Q> {
41  public:
42   // We allow injection of a function creating the P primitive from KeyData for
43   // testing -- later, this function will just be Registry::GetPrimitive().
KeysetWrapperImpl(const PrimitiveWrapper<P,Q> * transforming_wrapper,absl::AnyInvocable<crypto::tink::util::StatusOr<std::unique_ptr<P>> (const google::crypto::tink::KeyData & key_data)const> primitive_getter)44   explicit KeysetWrapperImpl(
45       const PrimitiveWrapper<P, Q>* transforming_wrapper,
46       absl::AnyInvocable<crypto::tink::util::StatusOr<std::unique_ptr<P>>(
47           const google::crypto::tink::KeyData& key_data) const>
48           primitive_getter)
49       : primitive_getter_(std::move(primitive_getter)),
50         transforming_wrapper_(*transforming_wrapper) {}
51 
Wrap(const google::crypto::tink::Keyset & keyset,const absl::flat_hash_map<std::string,std::string> & annotations)52   crypto::tink::util::StatusOr<std::unique_ptr<Q>> Wrap(
53       const google::crypto::tink::Keyset& keyset,
54       const absl::flat_hash_map<std::string, std::string>& annotations)
55       const override {
56     crypto::tink::util::Status status = ValidateKeyset(keyset);
57     if (!status.ok()) return status;
58     typename PrimitiveSet<P>::Builder primitives_builder;
59     primitives_builder.AddAnnotations(annotations);
60     for (const google::crypto::tink::Keyset::Key& key : keyset.key()) {
61       if (key.status() != google::crypto::tink::KeyStatusType::ENABLED) {
62         continue;
63       }
64       auto primitive = primitive_getter_(key.key_data());
65       if (!primitive.ok()) return primitive.status();
66       if (key.key_id() == keyset.primary_key_id()) {
67         primitives_builder.AddPrimaryPrimitive(std::move(primitive.value()),
68                                                KeyInfoFromKey(key));
69       } else {
70         primitives_builder.AddPrimitive(std::move(primitive.value()),
71                                         KeyInfoFromKey(key));
72       }
73     }
74     crypto::tink::util::StatusOr<PrimitiveSet<P>> primitives =
75         std::move(primitives_builder).Build();
76     if (!primitives.ok()) return primitives.status();
77     return transforming_wrapper_.Wrap(
78         absl::make_unique<PrimitiveSet<P>>(*std::move(primitives)));
79   }
80 
81  private:
82   absl::AnyInvocable<crypto::tink::util::StatusOr<std::unique_ptr<P>>(
83       const google::crypto::tink::KeyData& key_data) const>
84       primitive_getter_;
85   const PrimitiveWrapper<P, Q>& transforming_wrapper_;
86 };
87 
88 }  // namespace internal
89 }  // namespace tink
90 }  // namespace crypto
91 
92 #endif  // TINK_INTERNAL_KEYSET_WRAPPER_IMPL_H_
93