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 17 #include "tink/jwt/internal/jwt_public_key_sign_wrapper.h" 18 19 #include <memory> 20 #include <string> 21 #include <utility> 22 23 #include "absl/status/status.h" 24 #include "tink/jwt/internal/jwt_format.h" 25 #include "tink/jwt/internal/jwt_public_key_sign_internal.h" 26 #include "tink/jwt/jwt_public_key_sign.h" 27 #include "tink/primitive_set.h" 28 #include "tink/util/status.h" 29 #include "tink/util/statusor.h" 30 31 namespace crypto { 32 namespace tink { 33 namespace jwt_internal { 34 35 using google::crypto::tink::OutputPrefixType; 36 37 namespace { 38 39 class JwtPublicKeySignSetWrapper : public JwtPublicKeySign { 40 public: JwtPublicKeySignSetWrapper(std::unique_ptr<PrimitiveSet<JwtPublicKeySignInternal>> jwt_sign_set)41 explicit JwtPublicKeySignSetWrapper( 42 std::unique_ptr<PrimitiveSet<JwtPublicKeySignInternal>> jwt_sign_set) 43 : jwt_sign_set_(std::move(jwt_sign_set)) {} 44 45 crypto::tink::util::StatusOr<std::string> SignAndEncode( 46 const crypto::tink::RawJwt& token) const override; 47 48 ~JwtPublicKeySignSetWrapper() override = default; 49 50 private: 51 std::unique_ptr<PrimitiveSet<JwtPublicKeySignInternal>> jwt_sign_set_; 52 }; 53 Validate(PrimitiveSet<JwtPublicKeySignInternal> * jwt_sign_set)54util::Status Validate(PrimitiveSet<JwtPublicKeySignInternal>* jwt_sign_set) { 55 if (jwt_sign_set == nullptr) { 56 return util::Status(absl::StatusCode::kInternal, 57 "jwt_sign_set must be non-NULL"); 58 } 59 if (jwt_sign_set->get_primary() == nullptr) { 60 return util::Status(absl::StatusCode::kInvalidArgument, 61 "jwt_sign_set has no primary"); 62 } 63 for (const auto* entry : jwt_sign_set->get_all()) { 64 if ((entry->get_output_prefix_type() != OutputPrefixType::RAW) && 65 (entry->get_output_prefix_type() != OutputPrefixType::TINK)) { 66 return util::Status(absl::StatusCode::kInvalidArgument, 67 "all JWT keys must be either RAW or TINK"); 68 } 69 } 70 return util::OkStatus(); 71 } 72 SignAndEncode(const crypto::tink::RawJwt & token) const73util::StatusOr<std::string> JwtPublicKeySignSetWrapper::SignAndEncode( 74 const crypto::tink::RawJwt& token) const { 75 auto primary = jwt_sign_set_->get_primary(); 76 return primary->get_primitive().SignAndEncodeWithKid( 77 token, GetKid(primary->get_key_id(), primary->get_output_prefix_type())); 78 } 79 80 } // namespace 81 Wrap(std::unique_ptr<PrimitiveSet<JwtPublicKeySignInternal>> jwt_sign_set) const82util::StatusOr<std::unique_ptr<JwtPublicKeySign>> JwtPublicKeySignWrapper::Wrap( 83 std::unique_ptr<PrimitiveSet<JwtPublicKeySignInternal>> jwt_sign_set) 84 const { 85 util::Status status = Validate(jwt_sign_set.get()); 86 if (!status.ok()) return status; 87 std::unique_ptr<JwtPublicKeySign> jwt_sign = 88 absl::make_unique<JwtPublicKeySignSetWrapper>(std::move(jwt_sign_set)); 89 return std::move(jwt_sign); 90 } 91 92 } // namespace jwt_internal 93 } // namespace tink 94 } // namespace crypto 95