1 // Copyright 2021 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_JWT_INTERNAL_JWT_HMAC_KEY_MANAGER_H_ 17 #define TINK_JWT_INTERNAL_JWT_HMAC_KEY_MANAGER_H_ 18 19 #include <memory> 20 #include <string> 21 #include <utility> 22 23 #include "absl/memory/memory.h" 24 #include "absl/status/status.h" 25 #include "absl/strings/str_cat.h" 26 #include "tink/core/key_type_manager.h" 27 #include "tink/jwt/internal/jwt_mac_impl.h" 28 #include "tink/jwt/internal/jwt_mac_internal.h" 29 #include "tink/jwt/internal/raw_jwt_hmac_key_manager.h" 30 #include "tink/jwt/jwt_mac.h" 31 #include "tink/subtle/hmac_boringssl.h" 32 #include "tink/util/constants.h" 33 #include "tink/util/enums.h" 34 #include "tink/util/errors.h" 35 #include "tink/util/protobuf_helper.h" 36 #include "tink/util/secret_data.h" 37 #include "tink/util/status.h" 38 #include "tink/util/statusor.h" 39 #include "proto/jwt_hmac.pb.h" 40 41 namespace crypto { 42 namespace tink { 43 namespace jwt_internal { 44 45 class JwtHmacKeyManager 46 : public KeyTypeManager<google::crypto::tink::JwtHmacKey, 47 google::crypto::tink::JwtHmacKeyFormat, 48 List<JwtMacInternal>> { 49 public: 50 class JwtMacFactory : public PrimitiveFactory<JwtMacInternal> { Create(const google::crypto::tink::JwtHmacKey & jwt_hmac_key)51 crypto::tink::util::StatusOr<std::unique_ptr<JwtMacInternal>> Create( 52 const google::crypto::tink::JwtHmacKey& jwt_hmac_key) const override { 53 int tag_size; 54 std::string algorithm; 55 google::crypto::tink::HashType hash_type; 56 switch (jwt_hmac_key.algorithm()) { 57 case google::crypto::tink::JwtHmacAlgorithm::HS256: 58 hash_type = google::crypto::tink::HashType::SHA256; 59 tag_size = 32; 60 algorithm = "HS256"; 61 break; 62 case google::crypto::tink::JwtHmacAlgorithm::HS384: 63 hash_type = google::crypto::tink::HashType::SHA384; 64 tag_size = 48; 65 algorithm = "HS384"; 66 break; 67 case google::crypto::tink::JwtHmacAlgorithm::HS512: 68 hash_type = google::crypto::tink::HashType::SHA512; 69 tag_size = 64; 70 algorithm = "HS512"; 71 break; 72 default: 73 return util::Status(absl::StatusCode::kInvalidArgument, 74 "Unknown algorithm."); 75 } 76 crypto::tink::util::StatusOr<std::unique_ptr<Mac>> mac = 77 subtle::HmacBoringSsl::New( 78 util::Enums::ProtoToSubtle(hash_type), tag_size, 79 util::SecretDataFromStringView(jwt_hmac_key.key_value())); 80 if (!mac.ok()) { 81 return mac.status(); 82 } 83 absl::optional<std::string> custom_kid = absl::nullopt; 84 if (jwt_hmac_key.has_custom_kid()) { 85 custom_kid = jwt_hmac_key.custom_kid().value(); 86 } 87 std::unique_ptr<JwtMacInternal> jwt_mac = 88 absl::make_unique<jwt_internal::JwtMacImpl>(*std::move(mac), 89 algorithm, custom_kid); 90 return std::move(jwt_mac); 91 } 92 }; 93 JwtHmacKeyManager()94 JwtHmacKeyManager() : KeyTypeManager(absl::make_unique<JwtMacFactory>()) {} 95 96 uint32_t get_version() const override; 97 98 google::crypto::tink::KeyData::KeyMaterialType key_material_type() 99 const override; 100 101 const std::string& get_key_type() const override; 102 103 crypto::tink::util::Status ValidateKey( 104 const google::crypto::tink::JwtHmacKey& key) const override; 105 106 crypto::tink::util::Status ValidateKeyFormat( 107 const google::crypto::tink::JwtHmacKeyFormat& key_format) const override; 108 109 crypto::tink::util::StatusOr<google::crypto::tink::JwtHmacKey> CreateKey( 110 const google::crypto::tink::JwtHmacKeyFormat& key_format) const override; 111 112 crypto::tink::util::StatusOr<google::crypto::tink::JwtHmacKey> DeriveKey( 113 const google::crypto::tink::JwtHmacKeyFormat& key_format, 114 InputStream* input_stream) const override; 115 116 private: 117 const RawJwtHmacKeyManager raw_key_manager_; 118 }; 119 120 } // namespace jwt_internal 121 } // namespace tink 122 } // namespace crypto 123 124 #endif // TINK_JWT_INTERNAL_JWT_HMAC_KEY_MANAGER_H_ 125