Coverage Report

Created: 2023-08-17 06:18

/proc/self/cwd/src/verify.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2018 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
//    https://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
#include "jwt_verify_lib/verify.h"
16
17
#include "absl/strings/string_view.h"
18
#include "absl/time/clock.h"
19
#include "jwt_verify_lib/check_audience.h"
20
#include "openssl/bn.h"
21
#include "openssl/curve25519.h"
22
#include "openssl/ecdsa.h"
23
#include "openssl/err.h"
24
#include "openssl/evp.h"
25
#include "openssl/hmac.h"
26
#include "openssl/mem.h"
27
#include "openssl/rsa.h"
28
#include "openssl/sha.h"
29
30
namespace google {
31
namespace jwt_verify {
32
namespace {
33
34
// A convenience inline cast function.
35
72.0k
inline const uint8_t* castToUChar(const absl::string_view& str) {
36
72.0k
  return reinterpret_cast<const uint8_t*>(str.data());
37
72.0k
}
38
39
bool verifySignatureRSA(RSA* key, const EVP_MD* md, const uint8_t* signature,
40
                        size_t signature_len, const uint8_t* signed_data,
41
4.94k
                        size_t signed_data_len) {
42
4.94k
  if (key == nullptr || md == nullptr || signature == nullptr ||
43
4.94k
      signed_data == nullptr) {
44
0
    return false;
45
0
  }
46
4.94k
  bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
47
4.94k
  if (EVP_PKEY_set1_RSA(evp_pkey.get(), key) != 1) {
48
0
    return false;
49
0
  }
50
51
4.94k
  bssl::UniquePtr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_create());
52
4.94k
  if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, md, nullptr,
53
4.94k
                           evp_pkey.get()) == 1) {
54
4.94k
    if (EVP_DigestVerifyUpdate(md_ctx.get(), signed_data, signed_data_len) ==
55
4.94k
        1) {
56
4.94k
      if (EVP_DigestVerifyFinal(md_ctx.get(), signature, signature_len) == 1) {
57
1
        return true;
58
1
      }
59
4.94k
    }
60
4.94k
  }
61
4.94k
  ERR_clear_error();
62
4.94k
  return false;
63
4.94k
}
64
65
bool verifySignatureRSA(RSA* key, const EVP_MD* md, absl::string_view signature,
66
4.94k
                        absl::string_view signed_data) {
67
4.94k
  return verifySignatureRSA(key, md, castToUChar(signature), signature.length(),
68
4.94k
                            castToUChar(signed_data), signed_data.length());
69
4.94k
}
70
71
bool verifySignatureRSAPSS(RSA* key, const EVP_MD* md, const uint8_t* signature,
72
                           size_t signature_len, const uint8_t* signed_data,
73
4.60k
                           size_t signed_data_len) {
74
4.60k
  if (key == nullptr || md == nullptr || signature == nullptr ||
75
4.60k
      signed_data == nullptr) {
76
0
    return false;
77
0
  }
78
4.60k
  bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
79
4.60k
  if (EVP_PKEY_set1_RSA(evp_pkey.get(), key) != 1) {
80
0
    return false;
81
0
  }
82
83
4.60k
  bssl::UniquePtr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_create());
84
  // pctx is owned by md_ctx, no need to free it separately.
85
4.60k
  EVP_PKEY_CTX* pctx;
86
4.60k
  if (EVP_DigestVerifyInit(md_ctx.get(), &pctx, md, nullptr, evp_pkey.get()) ==
87
4.60k
          1 &&
88
4.60k
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) == 1 &&
89
4.60k
      EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, md) == 1 &&
90
4.60k
      EVP_DigestVerify(md_ctx.get(), signature, signature_len, signed_data,
91
4.60k
                       signed_data_len) == 1) {
92
0
    return true;
93
0
  }
94
95
4.60k
  ERR_clear_error();
96
4.60k
  return false;
97
4.60k
}
98
99
bool verifySignatureRSAPSS(RSA* key, const EVP_MD* md,
100
                           absl::string_view signature,
101
4.60k
                           absl::string_view signed_data) {
102
4.60k
  return verifySignatureRSAPSS(key, md, castToUChar(signature),
103
4.60k
                               signature.length(), castToUChar(signed_data),
104
4.60k
                               signed_data.length());
105
4.60k
}
106
107
bool verifySignatureEC(EC_KEY* key, const EVP_MD* md, const uint8_t* signature,
108
                       size_t signature_len, const uint8_t* signed_data,
109
8.21k
                       size_t signed_data_len) {
110
8.21k
  if (key == nullptr || md == nullptr || signature == nullptr ||
111
8.21k
      signed_data == nullptr) {
112
0
    return false;
113
0
  }
114
8.21k
  bssl::UniquePtr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_create());
115
8.21k
  std::vector<uint8_t> digest(EVP_MAX_MD_SIZE);
116
8.21k
  unsigned int digest_len = 0;
117
118
8.21k
  if (EVP_DigestInit(md_ctx.get(), md) == 0) {
119
0
    return false;
120
0
  }
121
122
8.21k
  if (EVP_DigestUpdate(md_ctx.get(), signed_data, signed_data_len) == 0) {
123
0
    return false;
124
0
  }
125
126
8.21k
  if (EVP_DigestFinal(md_ctx.get(), digest.data(), &digest_len) == 0) {
127
0
    return false;
128
0
  }
129
130
8.21k
  bssl::UniquePtr<ECDSA_SIG> ecdsa_sig(ECDSA_SIG_new());
131
8.21k
  if (!ecdsa_sig) {
132
0
    return false;
133
0
  }
134
135
8.21k
  if (BN_bin2bn(signature, signature_len / 2, ecdsa_sig->r) == nullptr ||
136
8.21k
      BN_bin2bn(signature + (signature_len / 2), signature_len / 2,
137
8.21k
                ecdsa_sig->s) == nullptr) {
138
0
    return false;
139
0
  }
140
141
8.21k
  if (ECDSA_do_verify(digest.data(), digest_len, ecdsa_sig.get(), key) == 1) {
142
3
    return true;
143
3
  }
144
145
8.20k
  ERR_clear_error();
146
8.20k
  return false;
147
8.21k
}
148
149
bool verifySignatureEC(EC_KEY* key, const EVP_MD* md,
150
                       absl::string_view signature,
151
8.21k
                       absl::string_view signed_data) {
152
8.21k
  return verifySignatureEC(key, md, castToUChar(signature), signature.length(),
153
8.21k
                           castToUChar(signed_data), signed_data.length());
154
8.21k
}
155
156
bool verifySignatureOct(const uint8_t* key, size_t key_len, const EVP_MD* md,
157
                        const uint8_t* signature, size_t signature_len,
158
5.07k
                        const uint8_t* signed_data, size_t signed_data_len) {
159
5.07k
  if (key == nullptr || md == nullptr || signature == nullptr ||
160
5.07k
      signed_data == nullptr) {
161
0
    return false;
162
0
  }
163
164
5.07k
  std::vector<uint8_t> out(EVP_MAX_MD_SIZE);
165
5.07k
  unsigned int out_len = 0;
166
5.07k
  if (HMAC(md, key, key_len, signed_data, signed_data_len, out.data(),
167
5.07k
           &out_len) == nullptr) {
168
0
    ERR_clear_error();
169
0
    return false;
170
0
  }
171
172
5.07k
  if (out_len != signature_len) {
173
4.86k
    return false;
174
4.86k
  }
175
176
205
  if (CRYPTO_memcmp(out.data(), signature, signature_len) == 0) {
177
1
    return true;
178
1
  }
179
180
204
  ERR_clear_error();
181
204
  return false;
182
205
}
183
184
bool verifySignatureOct(absl::string_view key, const EVP_MD* md,
185
                        absl::string_view signature,
186
5.07k
                        absl::string_view signed_data) {
187
5.07k
  return verifySignatureOct(castToUChar(key), key.length(), md,
188
5.07k
                            castToUChar(signature), signature.length(),
189
5.07k
                            castToUChar(signed_data), signed_data.length());
190
5.07k
}
191
192
Status verifySignatureEd25519(absl::string_view key,
193
                              absl::string_view signature,
194
7.12k
                              absl::string_view signed_data) {
195
7.12k
  if (signature.length() != ED25519_SIGNATURE_LEN) {
196
13
    return Status::JwtEd25519SignatureWrongLength;
197
13
  }
198
199
7.10k
  if (ED25519_verify(castToUChar(signed_data), signed_data.length(),
200
7.10k
                     castToUChar(signature), castToUChar(key.data())) == 1) {
201
1
    return Status::Ok;
202
1
  }
203
204
7.10k
  ERR_clear_error();
205
7.10k
  return Status::JwtVerificationFail;
206
7.10k
}
207
208
}  // namespace
209
210
1.73k
Status verifyJwtWithoutTimeChecking(const Jwt& jwt, const Jwks& jwks) {
211
  // Verify signature
212
1.73k
  std::string signed_data =
213
1.73k
      jwt.header_str_base64url_ + '.' + jwt.payload_str_base64url_;
214
1.73k
  bool kid_alg_matched = false;
215
33.0k
  for (const auto& jwk : jwks.keys()) {
216
    // If kid is specified in JWT, JWK with the same kid is used for
217
    // verification.
218
    // If kid is not specified in JWT, try all JWK.
219
33.0k
    if (!jwt.kid_.empty() && !jwk->kid_.empty() && jwk->kid_ != jwt.kid_) {
220
1.64k
      continue;
221
1.64k
    }
222
223
    // The same alg must be used.
224
31.3k
    if (!jwk->alg_.empty() && jwk->alg_ != jwt.alg_) {
225
1.23k
      continue;
226
1.23k
    }
227
30.1k
    kid_alg_matched = true;
228
229
30.1k
    if (jwk->kty_ == "EC") {
230
8.21k
      const EVP_MD* md;
231
8.21k
      if (jwt.alg_ == "ES384") {
232
0
        md = EVP_sha384();
233
8.21k
      } else if (jwt.alg_ == "ES512") {
234
1.29k
        md = EVP_sha512();
235
6.91k
      } else {
236
        // default to SHA256
237
6.91k
        md = EVP_sha256();
238
6.91k
      }
239
240
8.21k
      if (verifySignatureEC(jwk->ec_key_.get(), md, jwt.signature_,
241
8.21k
                            signed_data)) {
242
        // Verification succeeded.
243
3
        return Status::Ok;
244
3
      }
245
21.9k
    } else if (jwk->kty_ == "RSA") {
246
9.74k
      const EVP_MD* md;
247
9.74k
      if (jwt.alg_ == "RS384" || jwt.alg_ == "PS384") {
248
0
        md = EVP_sha384();
249
9.74k
      } else if (jwt.alg_ == "RS512" || jwt.alg_ == "PS512") {
250
1.09k
        md = EVP_sha512();
251
8.65k
      } else {
252
        // default to SHA256
253
8.65k
        md = EVP_sha256();
254
8.65k
      }
255
256
9.74k
      if (jwt.alg_.compare(0, 2, "RS") == 0) {
257
4.94k
        if (verifySignatureRSA(jwk->rsa_.get(), md, jwt.signature_,
258
4.94k
                               signed_data)) {
259
          // Verification succeeded.
260
1
          return Status::Ok;
261
1
        }
262
4.94k
      } else if (jwt.alg_.compare(0, 2, "PS") == 0) {
263
4.60k
        if (verifySignatureRSAPSS(jwk->rsa_.get(), md, jwt.signature_,
264
4.60k
                                  signed_data)) {
265
          // Verification succeeded.
266
0
          return Status::Ok;
267
0
        }
268
4.60k
      }
269
12.1k
    } else if (jwk->kty_ == "oct") {
270
5.07k
      const EVP_MD* md;
271
5.07k
      if (jwt.alg_ == "HS384") {
272
0
        md = EVP_sha384();
273
5.07k
      } else if (jwt.alg_ == "HS512") {
274
1.45k
        md = EVP_sha512();
275
3.61k
      } else {
276
        // default to SHA256
277
3.61k
        md = EVP_sha256();
278
3.61k
      }
279
280
5.07k
      if (verifySignatureOct(jwk->hmac_key_, md, jwt.signature_, signed_data)) {
281
        // Verification succeeded.
282
1
        return Status::Ok;
283
1
      }
284
7.12k
    } else if (jwk->kty_ == "OKP" && jwk->crv_ == "Ed25519") {
285
7.12k
      Status status = verifySignatureEd25519(jwk->okp_key_raw_, jwt.signature_,
286
7.12k
                                             signed_data);
287
      // For verification failures keep going and try the rest of the keys in
288
      // the JWKS. Otherwise status is either OK or an error with the JWT and we
289
      // can return immediately.
290
7.12k
      if (status == Status::Ok ||
291
7.12k
          status == Status::JwtEd25519SignatureWrongLength) {
292
14
        return status;
293
14
      }
294
7.12k
    }
295
30.1k
  }
296
297
  // Verification failed.
298
1.72k
  return kid_alg_matched ? Status::JwtVerificationFail
299
1.72k
                         : Status::JwksKidAlgMismatch;
300
1.73k
}
301
302
1.75k
Status verifyJwt(const Jwt& jwt, const Jwks& jwks) {
303
1.75k
  return verifyJwt(jwt, jwks, absl::ToUnixSeconds(absl::Now()));
304
1.75k
}
305
306
Status verifyJwt(const Jwt& jwt, const Jwks& jwks, uint64_t now,
307
1.75k
                 uint64_t clock_skew) {
308
1.75k
  Status time_status = jwt.verifyTimeConstraint(now, clock_skew);
309
1.75k
  if (time_status != Status::Ok) {
310
12
    return time_status;
311
12
  }
312
313
1.73k
  return verifyJwtWithoutTimeChecking(jwt, jwks);
314
1.75k
}
315
316
Status verifyJwt(const Jwt& jwt, const Jwks& jwks,
317
0
                 const std::vector<std::string>& audiences) {
318
0
  return verifyJwt(jwt, jwks, audiences, absl::ToUnixSeconds(absl::Now()));
319
0
}
320
321
Status verifyJwt(const Jwt& jwt, const Jwks& jwks,
322
0
                 const std::vector<std::string>& audiences, uint64_t now) {
323
0
  CheckAudience checker(audiences);
324
0
  if (!checker.areAudiencesAllowed(jwt.audiences_)) {
325
0
    return Status::JwtAudienceNotAllowed;
326
0
  }
327
0
  return verifyJwt(jwt, jwks, now);
328
0
}
329
330
}  // namespace jwt_verify
331
}  // namespace google