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