1 // Copyright 2023 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_MUTABLE_SERIALIZATION_REGISTRY_H_ 18 #define TINK_INTERNAL_MUTABLE_SERIALIZATION_REGISTRY_H_ 19 20 #include <memory> 21 22 #include "absl/base/thread_annotations.h" 23 #include "absl/synchronization/mutex.h" 24 #include "absl/types/optional.h" 25 #include "tink/internal/key_parser.h" 26 #include "tink/internal/key_serializer.h" 27 #include "tink/internal/parameters_parser.h" 28 #include "tink/internal/parameters_serializer.h" 29 #include "tink/internal/serialization.h" 30 #include "tink/internal/serialization_registry.h" 31 #include "tink/key.h" 32 #include "tink/parameters.h" 33 #include "tink/secret_key_access_token.h" 34 #include "tink/util/status.h" 35 #include "tink/util/statusor.h" 36 37 namespace crypto { 38 namespace tink { 39 namespace internal { 40 41 // This class provides a global, mutable serialization registry by wrapping an 42 // instance of an immutable `SerializationRegistry`. This registry will enable 43 // the Tink 2.0 C++ Keyset API in the near term. 44 class MutableSerializationRegistry { 45 public: 46 // Returns the global serialization registry. 47 static MutableSerializationRegistry& GlobalInstance(); 48 49 // Registers parameters `parser`. Returns an error if a different parameters 50 // parser with the same parser index has already been registered. 51 util::Status RegisterParametersParser(ParametersParser* parser) 52 ABSL_LOCKS_EXCLUDED(registry_mutex_); 53 54 // Registers parameters `serializer`. Returns an error if a different 55 // parameters serializer with the same serializer index has already been 56 // registered. 57 util::Status RegisterParametersSerializer(ParametersSerializer* serializer) 58 ABSL_LOCKS_EXCLUDED(registry_mutex_); 59 60 // Registers key `parser`. Returns an error if a different key parser with the 61 // same parser index has already been registered. 62 util::Status RegisterKeyParser(KeyParser* parser) 63 ABSL_LOCKS_EXCLUDED(registry_mutex_); 64 65 // Registers key `serializer`. Returns an error if a different key serializer 66 // with the same serializer index has already been registered. 67 util::Status RegisterKeySerializer(KeySerializer* serializer) 68 ABSL_LOCKS_EXCLUDED(registry_mutex_); 69 70 // Parses `serialization` into a `Parameters` instance. 71 util::StatusOr<std::unique_ptr<Parameters>> ParseParameters( 72 const Serialization& serialization) ABSL_LOCKS_EXCLUDED(registry_mutex_); 73 74 // Serializes `parameters` into a `Serialization` instance. 75 template <typename SerializationT> SerializeParameters(const Parameters & parameters)76 util::StatusOr<std::unique_ptr<Serialization>> SerializeParameters( 77 const Parameters& parameters) ABSL_LOCKS_EXCLUDED(registry_mutex_) { 78 absl::ReaderMutexLock lock(®istry_mutex_); 79 return registry_.SerializeParameters<SerializationT>(parameters); 80 } 81 82 // Parses `serialization` into a `Key` instance. 83 util::StatusOr<std::unique_ptr<Key>> ParseKey( 84 const Serialization& serialization, 85 absl::optional<SecretKeyAccessToken> token) 86 ABSL_LOCKS_EXCLUDED(registry_mutex_); 87 88 // Similar to `ParseKey` but falls back to legacy proto key serialization if 89 // the corresponding key parser is not found. 90 util::StatusOr<std::unique_ptr<Key>> ParseKeyWithLegacyFallback( 91 const Serialization& serialization, SecretKeyAccessToken token); 92 93 // Serializes `parameters` into a `Serialization` instance. 94 template <typename SerializationT> SerializeKey(const Key & key,absl::optional<SecretKeyAccessToken> token)95 util::StatusOr<std::unique_ptr<Serialization>> SerializeKey( 96 const Key& key, absl::optional<SecretKeyAccessToken> token) 97 ABSL_LOCKS_EXCLUDED(registry_mutex_) { 98 absl::ReaderMutexLock lock(®istry_mutex_); 99 return registry_.SerializeKey<SerializationT>(key, token); 100 } 101 102 // Resets to a new empty registry. Reset()103 void Reset() ABSL_LOCKS_EXCLUDED(registry_mutex_) { 104 absl::WriterMutexLock lock(®istry_mutex_); 105 registry_ = SerializationRegistry(); 106 } 107 108 private: 109 mutable absl::Mutex registry_mutex_; 110 // Simple wrappers around const methods of `registry_` may safely acquire a 111 // shared (reader) lock. Other calls require an exclusive (writer) lock. 112 SerializationRegistry registry_ ABSL_GUARDED_BY(registry_mutex_); 113 }; 114 115 } // namespace internal 116 } // namespace tink 117 } // namespace crypto 118 119 #endif // TINK_INTERNAL_MUTABLE_SERIALIZATION_REGISTRY_H_ 120