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_INTERNAL_KEY_SERIALIZER_H_ 18 #define TINK_INTERNAL_KEY_SERIALIZER_H_ 19 20 #include <functional> 21 #include <memory> 22 #include <typeindex> 23 #include <utility> 24 25 #include "absl/functional/function_ref.h" 26 #include "absl/log/log.h" 27 #include "absl/status/status.h" 28 #include "absl/types/optional.h" 29 #include "tink/internal/serialization.h" 30 #include "tink/internal/serializer_index.h" 31 #include "tink/key.h" 32 #include "tink/secret_key_access_token.h" 33 #include "tink/util/status.h" 34 #include "tink/util/statusor.h" 35 36 namespace crypto { 37 namespace tink { 38 namespace internal { 39 40 // Non-template base class that can be used with internal registry map. 41 class KeySerializer { 42 public: 43 // Returns the serialization of `key`. 44 virtual util::StatusOr<std::unique_ptr<Serialization>> SerializeKey( 45 const Key& key, absl::optional<SecretKeyAccessToken> token) const = 0; 46 47 // Returns an index that can be used to look up the `KeySerializer` 48 // object registered for the `KeyT` type in a registry. 49 virtual SerializerIndex Index() const = 0; 50 51 virtual ~KeySerializer() = default; 52 }; 53 54 // Serializes `KeyT` objects into `SerializationT` objects. 55 template <typename KeyT, typename SerializationT> 56 class KeySerializerImpl : public KeySerializer { 57 public: 58 // Creates a key serializer with serialization `function`. The referenced 59 // `function` should outlive the created key serializer object. KeySerializerImpl(absl::FunctionRef<util::StatusOr<SerializationT> (KeyT,absl::optional<SecretKeyAccessToken>)> function)60 explicit KeySerializerImpl(absl::FunctionRef<util::StatusOr<SerializationT>( 61 KeyT, absl::optional<SecretKeyAccessToken>)> 62 function) 63 : function_(function) {} 64 SerializeKey(const Key & key,absl::optional<SecretKeyAccessToken> token)65 util::StatusOr<std::unique_ptr<Serialization>> SerializeKey( 66 const Key& key, 67 absl::optional<SecretKeyAccessToken> token) const override { 68 const KeyT* kt = dynamic_cast<const KeyT*>(&key); 69 if (kt == nullptr) { 70 return util::Status(absl::StatusCode::kInvalidArgument, 71 "Invalid key type for this key serializer."); 72 } 73 util::StatusOr<SerializationT> serialization = function_(*kt, token); 74 if (!serialization.ok()) return serialization.status(); 75 return {absl::make_unique<SerializationT>(std::move(*serialization))}; 76 } 77 Index()78 SerializerIndex Index() const override { 79 return SerializerIndex::Create<KeyT, SerializationT>(); 80 } 81 82 private: 83 std::function<util::StatusOr<SerializationT>( 84 KeyT, absl::optional<SecretKeyAccessToken>)> 85 function_; 86 }; 87 88 } // namespace internal 89 } // namespace tink 90 } // namespace crypto 91 92 #endif // TINK_INTERNAL_KEY_SERIALIZER_H_ 93