1*e7b1675dSTing-Kang Chang // Copyright 2022 Google LLC 2*e7b1675dSTing-Kang Chang // 3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License"); 4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License. 5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at 6*e7b1675dSTing-Kang Chang // 7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0 8*e7b1675dSTing-Kang Chang // 9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software 10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS, 11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and 13*e7b1675dSTing-Kang Chang // limitations under the License. 14*e7b1675dSTing-Kang Chang // 15*e7b1675dSTing-Kang Chang //////////////////////////////////////////////////////////////////////////////// 16*e7b1675dSTing-Kang Chang 17*e7b1675dSTing-Kang Chang #ifndef TINK_INTERNAL_KEY_PARSER_H_ 18*e7b1675dSTing-Kang Chang #define TINK_INTERNAL_KEY_PARSER_H_ 19*e7b1675dSTing-Kang Chang 20*e7b1675dSTing-Kang Chang #include <functional> 21*e7b1675dSTing-Kang Chang #include <memory> 22*e7b1675dSTing-Kang Chang #include <string> 23*e7b1675dSTing-Kang Chang #include <typeindex> 24*e7b1675dSTing-Kang Chang #include <utility> 25*e7b1675dSTing-Kang Chang 26*e7b1675dSTing-Kang Chang #include "absl/functional/function_ref.h" 27*e7b1675dSTing-Kang Chang #include "absl/log/log.h" 28*e7b1675dSTing-Kang Chang #include "absl/status/status.h" 29*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h" 30*e7b1675dSTing-Kang Chang #include "absl/types/optional.h" 31*e7b1675dSTing-Kang Chang #include "tink/internal/parser_index.h" 32*e7b1675dSTing-Kang Chang #include "tink/internal/serialization.h" 33*e7b1675dSTing-Kang Chang #include "tink/key.h" 34*e7b1675dSTing-Kang Chang #include "tink/secret_key_access_token.h" 35*e7b1675dSTing-Kang Chang #include "tink/util/status.h" 36*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h" 37*e7b1675dSTing-Kang Chang 38*e7b1675dSTing-Kang Chang namespace crypto { 39*e7b1675dSTing-Kang Chang namespace tink { 40*e7b1675dSTing-Kang Chang namespace internal { 41*e7b1675dSTing-Kang Chang 42*e7b1675dSTing-Kang Chang // Non-template base class that can be used with internal registry map. 43*e7b1675dSTing-Kang Chang class KeyParser { 44*e7b1675dSTing-Kang Chang public: 45*e7b1675dSTing-Kang Chang // Parses a `serialization` into a key. 46*e7b1675dSTing-Kang Chang // 47*e7b1675dSTing-Kang Chang // This function is usually called on a `Serialization` subclass matching the 48*e7b1675dSTing-Kang Chang // value returned by `ObjectIdentifier()`. However, implementations should 49*e7b1675dSTing-Kang Chang // check that this is the case. 50*e7b1675dSTing-Kang Chang virtual util::StatusOr<std::unique_ptr<Key>> ParseKey( 51*e7b1675dSTing-Kang Chang const Serialization& serialization, 52*e7b1675dSTing-Kang Chang absl::optional<SecretKeyAccessToken> token) const = 0; 53*e7b1675dSTing-Kang Chang 54*e7b1675dSTing-Kang Chang // Returns the object identifier for `SerializationT`, which is only valid 55*e7b1675dSTing-Kang Chang // for the lifetime of this object. 56*e7b1675dSTing-Kang Chang // 57*e7b1675dSTing-Kang Chang // The object identifier is a unique identifier per registry for this object 58*e7b1675dSTing-Kang Chang // (in the standard proto serialization, it is the type URL). In other words, 59*e7b1675dSTing-Kang Chang // when registering a `KeyParser`, the registry will invoke this to get 60*e7b1675dSTing-Kang Chang // the handled object identifier. In order to parse an object of 61*e7b1675dSTing-Kang Chang // `SerializationT`, the registry will then obtain the object identifier of 62*e7b1675dSTing-Kang Chang // this serialization object, and call the parser corresponding to this 63*e7b1675dSTing-Kang Chang // object. 64*e7b1675dSTing-Kang Chang virtual absl::string_view ObjectIdentifier() const = 0; 65*e7b1675dSTing-Kang Chang 66*e7b1675dSTing-Kang Chang // Returns an index that can be used to look up the `KeyParser` 67*e7b1675dSTing-Kang Chang // object registered for the `KeyT` type in a registry. 68*e7b1675dSTing-Kang Chang virtual ParserIndex Index() const = 0; 69*e7b1675dSTing-Kang Chang 70*e7b1675dSTing-Kang Chang virtual ~KeyParser() = default; 71*e7b1675dSTing-Kang Chang }; 72*e7b1675dSTing-Kang Chang 73*e7b1675dSTing-Kang Chang // Parses `SerializationT` objects into `KeyT` objects. 74*e7b1675dSTing-Kang Chang template <typename SerializationT, typename KeyT> 75*e7b1675dSTing-Kang Chang class KeyParserImpl : public KeyParser { 76*e7b1675dSTing-Kang Chang public: 77*e7b1675dSTing-Kang Chang // Creates a key parser with `object_identifier` and parsing `function`. The 78*e7b1675dSTing-Kang Chang // referenced `function` should outlive the created key parser object. KeyParserImpl(absl::string_view object_identifier,absl::FunctionRef<util::StatusOr<KeyT> (SerializationT,absl::optional<SecretKeyAccessToken>)> function)79*e7b1675dSTing-Kang Chang explicit KeyParserImpl( 80*e7b1675dSTing-Kang Chang absl::string_view object_identifier, 81*e7b1675dSTing-Kang Chang absl::FunctionRef<util::StatusOr<KeyT>( 82*e7b1675dSTing-Kang Chang SerializationT, absl::optional<SecretKeyAccessToken>)> 83*e7b1675dSTing-Kang Chang function) 84*e7b1675dSTing-Kang Chang : object_identifier_(object_identifier), function_(function) {} 85*e7b1675dSTing-Kang Chang ParseKey(const Serialization & serialization,absl::optional<SecretKeyAccessToken> token)86*e7b1675dSTing-Kang Chang util::StatusOr<std::unique_ptr<Key>> ParseKey( 87*e7b1675dSTing-Kang Chang const Serialization& serialization, 88*e7b1675dSTing-Kang Chang absl::optional<SecretKeyAccessToken> token) const override { 89*e7b1675dSTing-Kang Chang if (serialization.ObjectIdentifier() != object_identifier_) { 90*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument, 91*e7b1675dSTing-Kang Chang "Invalid object identifier for this key parser."); 92*e7b1675dSTing-Kang Chang } 93*e7b1675dSTing-Kang Chang const SerializationT* st = 94*e7b1675dSTing-Kang Chang dynamic_cast<const SerializationT*>(&serialization); 95*e7b1675dSTing-Kang Chang if (st == nullptr) { 96*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument, 97*e7b1675dSTing-Kang Chang "Invalid serialization type for this key parser."); 98*e7b1675dSTing-Kang Chang } 99*e7b1675dSTing-Kang Chang util::StatusOr<KeyT> key = function_(*st, token); 100*e7b1675dSTing-Kang Chang if (!key.ok()) return key.status(); 101*e7b1675dSTing-Kang Chang return {absl::make_unique<KeyT>(std::move(*key))}; 102*e7b1675dSTing-Kang Chang } 103*e7b1675dSTing-Kang Chang ObjectIdentifier()104*e7b1675dSTing-Kang Chang absl::string_view ObjectIdentifier() const override { 105*e7b1675dSTing-Kang Chang return object_identifier_; 106*e7b1675dSTing-Kang Chang } 107*e7b1675dSTing-Kang Chang Index()108*e7b1675dSTing-Kang Chang ParserIndex Index() const override { 109*e7b1675dSTing-Kang Chang return ParserIndex::Create<SerializationT>(object_identifier_); 110*e7b1675dSTing-Kang Chang } 111*e7b1675dSTing-Kang Chang 112*e7b1675dSTing-Kang Chang private: 113*e7b1675dSTing-Kang Chang std::string object_identifier_; 114*e7b1675dSTing-Kang Chang std::function<util::StatusOr<KeyT>(SerializationT, 115*e7b1675dSTing-Kang Chang absl::optional<SecretKeyAccessToken>)> 116*e7b1675dSTing-Kang Chang function_; 117*e7b1675dSTing-Kang Chang }; 118*e7b1675dSTing-Kang Chang 119*e7b1675dSTing-Kang Chang } // namespace internal 120*e7b1675dSTing-Kang Chang } // namespace tink 121*e7b1675dSTing-Kang Chang } // namespace crypto 122*e7b1675dSTing-Kang Chang 123*e7b1675dSTing-Kang Chang #endif // TINK_INTERNAL_KEY_PARSER_H_ 124