xref: /aosp_15_r20/external/tink/cc/jwt/internal/raw_jwt_rsa_ssa_pss_verify_key_manager.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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/raw_jwt_rsa_ssa_pss_verify_key_manager.h"
18 
19 #include <memory>
20 #include <utility>
21 
22 #include "absl/status/status.h"
23 #include "absl/strings/str_cat.h"
24 #include "absl/strings/string_view.h"
25 #include "tink/internal/bn_util.h"
26 #include "tink/internal/rsa_util.h"
27 #include "tink/internal/ssl_unique_ptr.h"
28 #include "tink/public_key_verify.h"
29 #include "tink/subtle/rsa_ssa_pss_verify_boringssl.h"
30 #include "tink/util/enums.h"
31 #include "tink/util/errors.h"
32 #include "tink/util/protobuf_helper.h"
33 #include "tink/util/status.h"
34 #include "tink/util/statusor.h"
35 #include "tink/util/validation.h"
36 #include "proto/jwt_rsa_ssa_pss.pb.h"
37 #include "proto/tink.pb.h"
38 
39 namespace crypto {
40 namespace tink {
41 
42 using ::crypto::tink::subtle::RsaSsaPssVerifyBoringSsl;
43 using ::crypto::tink::util::Enums;
44 using ::crypto::tink::util::Status;
45 using ::crypto::tink::util::StatusOr;
46 using ::google::crypto::tink::HashType;
47 using ::google::crypto::tink::JwtRsaSsaPssAlgorithm;
48 using ::google::crypto::tink::JwtRsaSsaPssPublicKey;
49 
50 StatusOr<std::unique_ptr<PublicKeyVerify>>
Create(const JwtRsaSsaPssPublicKey & rsa_ssa_pss_public_key) const51 RawJwtRsaSsaPssVerifyKeyManager::PublicKeyVerifyFactory::Create(
52     const JwtRsaSsaPssPublicKey& rsa_ssa_pss_public_key) const {
53   internal::RsaPublicKey rsa_pub_key;
54   rsa_pub_key.n = rsa_ssa_pss_public_key.n();
55   rsa_pub_key.e = rsa_ssa_pss_public_key.e();
56   JwtRsaSsaPssAlgorithm algorithm = rsa_ssa_pss_public_key.algorithm();
57   StatusOr<HashType> hash_or = HashForPssAlgorithm(algorithm);
58   if (!hash_or.ok()) {
59     return hash_or.status();
60   }
61   StatusOr<int> salt_length = SaltLengthForPssAlgorithm(algorithm);
62   if (!salt_length.ok()) {
63     return salt_length.status();
64   }
65   internal::RsaSsaPssParams params;
66   params.sig_hash = Enums::ProtoToSubtle(hash_or.value());
67   params.mgf1_hash = Enums::ProtoToSubtle(hash_or.value());
68   params.salt_length = *salt_length;
69 
70   util::StatusOr<std::unique_ptr<RsaSsaPssVerifyBoringSsl>> verify =
71       subtle::RsaSsaPssVerifyBoringSsl::New(rsa_pub_key, params);
72   if (!verify.ok()) {
73     return verify.status();
74   }
75   return {*std::move(verify)};
76 }
77 
ValidateKey(const JwtRsaSsaPssPublicKey & key) const78 Status RawJwtRsaSsaPssVerifyKeyManager::ValidateKey(
79     const JwtRsaSsaPssPublicKey& key) const {
80   Status status = ValidateVersion(key.version(), get_version());
81   if (!status.ok()) {
82     return status;
83   }
84   StatusOr<internal::SslUniquePtr<BIGNUM>> n =
85       internal::StringToBignum(key.n());
86   if (!n.ok()) {
87     return n.status();
88   }
89   Status modulus_status =
90       internal::ValidateRsaModulusSize(BN_num_bits(n->get()));
91   if (!modulus_status.ok()) {
92     return modulus_status;
93   }
94   Status exponent_status = internal::ValidateRsaPublicExponent(key.e());
95   if (!exponent_status.ok()) {
96     return exponent_status;
97   }
98   return ValidateAlgorithm(key.algorithm());
99 }
100 
ValidateAlgorithm(const JwtRsaSsaPssAlgorithm & algorithm)101 Status RawJwtRsaSsaPssVerifyKeyManager::ValidateAlgorithm(
102     const JwtRsaSsaPssAlgorithm& algorithm) {
103   switch (algorithm) {
104     case JwtRsaSsaPssAlgorithm::PS256:
105     case JwtRsaSsaPssAlgorithm::PS384:
106     case JwtRsaSsaPssAlgorithm::PS512:
107       return util::OkStatus();
108     default:
109       return Status(absl::StatusCode::kInvalidArgument,
110                     "Unsupported RSA SSA PSS Algorithm");
111   }
112   return util::OkStatus();
113 }
114 
HashForPssAlgorithm(const JwtRsaSsaPssAlgorithm & algorithm)115 StatusOr<HashType> RawJwtRsaSsaPssVerifyKeyManager::HashForPssAlgorithm(
116     const JwtRsaSsaPssAlgorithm& algorithm) {
117   switch (algorithm) {
118     case JwtRsaSsaPssAlgorithm::PS256:
119       return HashType::SHA256;
120     case JwtRsaSsaPssAlgorithm::PS384:
121       return HashType::SHA384;
122     case JwtRsaSsaPssAlgorithm::PS512:
123       return HashType::SHA512;
124     default:
125       return Status(absl::StatusCode::kInvalidArgument,
126                     "Unsupported RSA SSA PSS Algorithm");
127   }
128 }
129 
SaltLengthForPssAlgorithm(const JwtRsaSsaPssAlgorithm & algorithm)130 StatusOr<int> RawJwtRsaSsaPssVerifyKeyManager::SaltLengthForPssAlgorithm(
131     const JwtRsaSsaPssAlgorithm& algorithm) {
132   switch (algorithm) {
133     case JwtRsaSsaPssAlgorithm::PS256:
134       return 32;
135     case JwtRsaSsaPssAlgorithm::PS384:
136       return 48;
137     case JwtRsaSsaPssAlgorithm::PS512:
138       return 64;
139     default:
140       return Status(absl::StatusCode::kInvalidArgument,
141                     "Unsupported RSA SSA PSS Algorithm");
142   }
143 }
144 
145 }  // namespace tink
146 }  // namespace crypto
147