xref: /aosp_15_r20/external/tink/cc/core/private_key_manager_impl.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2019 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 #ifndef TINK_CORE_PRIVATE_KEY_MANAGER_IMPL_H_
17 #define TINK_CORE_PRIVATE_KEY_MANAGER_IMPL_H_
18 
19 #include <memory>
20 #include <string>
21 #include <utility>
22 
23 #include "absl/status/status.h"
24 #include "tink/core/key_manager_impl.h"
25 #include "tink/core/private_key_type_manager.h"
26 #include "tink/key_manager.h"
27 #include "tink/util/validation.h"
28 namespace crypto {
29 namespace tink {
30 namespace internal {
31 
32 // An implementation of a PrivateKeyFactory given a corresponding internal
33 // private key manager and an internal (public) key manager.
34 // The template arguments PrivatePrimitivesList and PublicPrimitivesList should
35 // be of type List<Primitives...>. The assumption is that the given pointers in
36 // the constructor are of type
37 //   PrivateKeyTypeManager<PrivateKeyProto, PrivateKeyFormatProto,
38 //                             PublicKeyProto, PrivatePrimitivesList>
39 // and
40 //   KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>.
41 template <class PrivateKeyProto, class PrivateKeyFormatProto,
42           class PublicKeyProto, class PrivatePrimitivesList,
43           class PublicPrimitivesList>
44 class PrivateKeyFactoryImpl : public PrivateKeyFactory {
45  public:
PrivateKeyFactoryImpl(PrivateKeyTypeManager<PrivateKeyProto,PrivateKeyFormatProto,PublicKeyProto,PrivatePrimitivesList> * private_key_manager,KeyTypeManager<PublicKeyProto,void,PublicPrimitivesList> * public_key_manager)46   PrivateKeyFactoryImpl(
47       PrivateKeyTypeManager<PrivateKeyProto, PrivateKeyFormatProto,
48                             PublicKeyProto, PrivatePrimitivesList>*
49           private_key_manager,
50       KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>*
51           public_key_manager)
52       : key_factory_impl_(private_key_manager),
53         private_key_manager_(private_key_manager),
54         public_key_type_(public_key_manager->get_key_type()),
55         public_key_material_type_(public_key_manager->key_material_type()) {}
56 
57   crypto::tink::util::StatusOr<std::unique_ptr<portable_proto::MessageLite>>
NewKey(const portable_proto::MessageLite & key_format)58   NewKey(const portable_proto::MessageLite& key_format) const override {
59     return key_factory_impl_.NewKey(key_format);
60   }
61 
62   crypto::tink::util::StatusOr<std::unique_ptr<portable_proto::MessageLite>>
NewKey(absl::string_view serialized_key_format)63   NewKey(absl::string_view serialized_key_format) const override {
64     return key_factory_impl_.NewKey(serialized_key_format);
65   }
66 
67   crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
NewKeyData(absl::string_view serialized_key_format)68   NewKeyData(absl::string_view serialized_key_format) const override {
69     return key_factory_impl_.NewKeyData(serialized_key_format);
70   }
71 
72   crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
GetPublicKeyData(absl::string_view serialized_private_key)73   GetPublicKeyData(absl::string_view serialized_private_key) const override {
74     PrivateKeyProto private_key;
75     if (!private_key.ParseFromString(std::string(serialized_private_key))) {
76       return crypto::tink::util::Status(
77           absl::StatusCode::kInvalidArgument,
78           absl::StrCat("Could not parse the passed string as proto '",
79                        PrivateKeyProto().GetTypeName(), "'."));
80     }
81     auto validation = private_key_manager_->ValidateKey(private_key);
82     if (!validation.ok()) return validation;
83     auto key_data = absl::make_unique<google::crypto::tink::KeyData>();
84     util::StatusOr<PublicKeyProto> public_key_result =
85         private_key_manager_->GetPublicKey(private_key);
86     if (!public_key_result.ok()) return public_key_result.status();
87     key_data->set_type_url(public_key_type_);
88     key_data->set_value(public_key_result.value().SerializeAsString());
89     key_data->set_key_material_type(public_key_material_type_);
90     return std::move(key_data);
91   }
92 
93  private:
94   // We create a key_factory_impl_ as a member, instead of using virtual
95   // inheritance to have it as a sub class. This means we have to forward the
96   // calls to NewKeyData as above, but developers do not have to know about
97   // virtual inheritance.
98   KeyFactoryImpl<KeyTypeManager<PrivateKeyProto, PrivateKeyFormatProto,
99                                 PrivatePrimitivesList>>
100       key_factory_impl_;
101   PrivateKeyTypeManager<PrivateKeyProto, PrivateKeyFormatProto, PublicKeyProto,
102                         PrivatePrimitivesList>* private_key_manager_;
103   const std::string public_key_type_;
104   google::crypto::tink::KeyData::KeyMaterialType public_key_material_type_;
105 };
106 
107 template <class Primitive, class PrivateKeyTypeManager,
108           class PublicKeyTypeManager>
109 class PrivateKeyManagerImpl;
110 
111 template <class Primitive, class PrivateKeyProto, class KeyFormatProto,
112           class PublicKeyProto, class PrivatePrimitivesList,
113           class PublicPrimitivesList>
114 class PrivateKeyManagerImpl<
115     Primitive,
116     PrivateKeyTypeManager<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
117                           PrivatePrimitivesList>,
118     KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>>
119     : public KeyManagerImpl<Primitive,
120                             KeyTypeManager<PrivateKeyProto, KeyFormatProto,
121                                            PrivatePrimitivesList>> {
122  public:
PrivateKeyManagerImpl(PrivateKeyTypeManager<PrivateKeyProto,KeyFormatProto,PublicKeyProto,PrivatePrimitivesList> * private_key_manager,KeyTypeManager<PublicKeyProto,void,PublicPrimitivesList> * public_key_manager)123   explicit PrivateKeyManagerImpl(
124       PrivateKeyTypeManager<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
125                             PrivatePrimitivesList>* private_key_manager,
126       KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>*
127           public_key_manager)
128       : KeyManagerImpl<Primitive,
129                        KeyTypeManager<PrivateKeyProto, KeyFormatProto,
130                                       PrivatePrimitivesList>>(
131             private_key_manager),
132         private_key_factory_(private_key_manager, public_key_manager) {}
133 
get_key_factory()134   const PrivateKeyFactory& get_key_factory() const override {
135     return private_key_factory_;
136   }
137 
138  private:
139   const PrivateKeyFactoryImpl<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
140                               PrivatePrimitivesList, PublicPrimitivesList>
141       private_key_factory_;
142 };
143 
144 // Helper function to create a KeyManager<Primitive> for a
145 // PrivateKeyTypeManager. Using this, all template arguments except the
146 // first one can be infered. Example:
147 //   std::unique_ptr<KeyManager<PublicKeySign>> km =
148 //     MakePrivateKeyManager<PublicKeySign>(internal_private_km,
149 //                                          internal_public_km);
150 //
151 // When creating a KeyManager like this, the passed in "private_key_manager"
152 // must outlive the constructed KeyManager. The passed in "public_key_manager"
153 // however must only be valid during construction of the KeyManager.
154 template <class Primitive, class PrivateKeyProto, class KeyFormatProto,
155           class PublicKeyProto, class PrivatePrimitivesList,
156           class PublicPrimitivesList>
MakePrivateKeyManager(PrivateKeyTypeManager<PrivateKeyProto,KeyFormatProto,PublicKeyProto,PrivatePrimitivesList> * private_key_manager,KeyTypeManager<PublicKeyProto,void,PublicPrimitivesList> * public_key_manager)157 std::unique_ptr<KeyManager<Primitive>> MakePrivateKeyManager(
158     PrivateKeyTypeManager<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
159                           PrivatePrimitivesList>* private_key_manager,
160     KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>*
161         public_key_manager) {
162   return absl::make_unique<PrivateKeyManagerImpl<
163       Primitive,
164       PrivateKeyTypeManager<PrivateKeyProto, KeyFormatProto, PublicKeyProto,
165                             PrivatePrimitivesList>,
166       KeyTypeManager<PublicKeyProto, void, PublicPrimitivesList>>>(
167       private_key_manager, public_key_manager);
168 }
169 
170 }  // namespace internal
171 }  // namespace tink
172 }  // namespace crypto
173 
174 #endif  // TINK_CORE_PRIVATE_KEY_MANAGER_IMPL_H_
175