Coverage Report

Created: 2023-06-07 07:04

/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
80.7k
inline const uint8_t* castToUChar(const absl::string_view& str) {
36
80.7k
  return reinterpret_cast<const uint8_t*>(str.data());
37
80.7k
}
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.86k
                        size_t signed_data_len) {
42
4.86k
  if (key == nullptr || md == nullptr || signature == nullptr ||
43
4.86k
      signed_data == nullptr) {
44
0
    return false;
45
0
  }
46
4.86k
  bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
47
4.86k
  if (EVP_PKEY_set1_RSA(evp_pkey.get(), key) != 1) {
48
0
    return false;
49
0
  }
50
51
4.86k
  bssl::UniquePtr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_create());
52
4.86k
  if (EVP_DigestVerifyInit(md_ctx.get(), nullptr, md, nullptr,
53
4.86k
                           evp_pkey.get()) == 1) {
54
4.86k
    if (EVP_DigestVerifyUpdate(md_ctx.get(), signed_data, signed_data_len) ==
55
4.86k
        1) {
56
4.86k
      if (EVP_DigestVerifyFinal(md_ctx.get(), signature, signature_len) == 1) {
57
2
        return true;
58
2
      }
59
4.86k
    }
60
4.86k
  }
61
4.85k
  ERR_clear_error();
62
4.85k
  return false;
63
4.86k
}
64
65
bool verifySignatureRSA(RSA* key, const EVP_MD* md, absl::string_view signature,
66
4.86k
                        absl::string_view signed_data) {
67
4.86k
  return verifySignatureRSA(key, md, castToUChar(signature), signature.length(),
68
4.86k
                            castToUChar(signed_data), signed_data.length());
69
4.86k
}
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
7.21k
                           size_t signed_data_len) {
74
7.21k
  if (key == nullptr || md == nullptr || signature == nullptr ||
75
7.21k
      signed_data == nullptr) {
76
0
    return false;
77
0
  }
78
7.21k
  bssl::UniquePtr<EVP_PKEY> evp_pkey(EVP_PKEY_new());
79
7.21k
  if (EVP_PKEY_set1_RSA(evp_pkey.get(), key) != 1) {
80
0
    return false;
81
0
  }
82
83
7.21k
  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
7.21k
  EVP_PKEY_CTX* pctx;
86
7.21k
  if (EVP_DigestVerifyInit(md_ctx.get(), &pctx, md, nullptr, evp_pkey.get()) ==
87
7.21k
          1 &&
88
7.21k
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) == 1 &&
89
7.21k
      EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, md) == 1 &&
90
7.21k
      EVP_DigestVerify(md_ctx.get(), signature, signature_len, signed_data,
91
7.21k
                       signed_data_len) == 1) {
92
0
    return true;
93
0
  }
94
95
7.21k
  ERR_clear_error();
96
7.21k
  return false;
97
7.21k
}
98
99
bool verifySignatureRSAPSS(RSA* key, const EVP_MD* md,
100
                           absl::string_view signature,
101
7.21k
                           absl::string_view signed_data) {
102
7.21k
  return verifySignatureRSAPSS(key, md, castToUChar(signature),
103
7.21k
                               signature.length(), castToUChar(signed_data),
104
7.21k
                               signed_data.length());
105
7.21k
}
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
9.54k
                       size_t signed_data_len) {
110
9.54k
  if (key == nullptr || md == nullptr || signature == nullptr ||
111
9.54k
      signed_data == nullptr) {
112
0
    return false;
113
0
  }
114
9.54k
  bssl::UniquePtr<EVP_MD_CTX> md_ctx(EVP_MD_CTX_create());
115
9.54k
  std::vector<uint8_t> digest(EVP_MAX_MD_SIZE);
116
9.54k
  unsigned int digest_len = 0;
117
118
9.54k
  if (EVP_DigestInit(md_ctx.get(), md) == 0) {
119
0
    return false;
120
0
  }
121
122
9.54k
  if (EVP_DigestUpdate(md_ctx.get(), signed_data, signed_data_len) == 0) {
123
0
    return false;
124
0
  }
125
126
9.54k
  if (EVP_DigestFinal(md_ctx.get(), digest.data(), &digest_len) == 0) {
127
0
    return false;
128
0
  }
129
130
9.54k
  bssl::UniquePtr<ECDSA_SIG> ecdsa_sig(ECDSA_SIG_new());
131
9.54k
  if (!ecdsa_sig) {
132
0
    return false;
133
0
  }
134
135
9.54k
  if (BN_bin2bn(signature, signature_len / 2, ecdsa_sig->r) == nullptr ||
136
9.54k
      BN_bin2bn(signature + (signature_len / 2), signature_len / 2,
137
9.54k
                ecdsa_sig->s) == nullptr) {
138
0
    return false;
139
0
  }
140
141
9.54k
  if (ECDSA_do_verify(digest.data(), digest_len, ecdsa_sig.get(), key) == 1) {
142
3
    return true;
143
3
  }
144
145
9.53k
  ERR_clear_error();
146
9.53k
  return false;
147
9.54k
}
148
149
bool verifySignatureEC(EC_KEY* key, const EVP_MD* md,
150
                       absl::string_view signature,
151
9.54k
                       absl::string_view signed_data) {
152
9.54k
  return verifySignatureEC(key, md, castToUChar(signature), signature.length(),
153
9.54k
                           castToUChar(signed_data), signed_data.length());
154
9.54k
}
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
4.95k
                        const uint8_t* signed_data, size_t signed_data_len) {
159
4.95k
  if (key == nullptr || md == nullptr || signature == nullptr ||
160
4.95k
      signed_data == nullptr) {
161
0
    return false;
162
0
  }
163
164
4.95k
  std::vector<uint8_t> out(EVP_MAX_MD_SIZE);
165
4.95k
  unsigned int out_len = 0;
166
4.95k
  if (HMAC(md, key, key_len, signed_data, signed_data_len, out.data(),
167
4.95k
           &out_len) == nullptr) {
168
0
    ERR_clear_error();
169
0
    return false;
170
0
  }
171
172
4.95k
  if (out_len != signature_len) {
173
4.61k
    return false;
174
4.61k
  }
175
176
342
  if (CRYPTO_memcmp(out.data(), signature, signature_len) == 0) {
177
1
    return true;
178
1
  }
179
180
341
  ERR_clear_error();
181
341
  return false;
182
342
}
183
184
bool verifySignatureOct(absl::string_view key, const EVP_MD* md,
185
                        absl::string_view signature,
186
4.95k
                        absl::string_view signed_data) {
187
4.95k
  return verifySignatureOct(castToUChar(key), key.length(), md,
188
4.95k
                            castToUChar(signature), signature.length(),
189
4.95k
                            castToUChar(signed_data), signed_data.length());
190
4.95k
}
191
192
Status verifySignatureEd25519(absl::string_view key,
193
                              absl::string_view signature,
194
7.56k
                              absl::string_view signed_data) {
195
7.56k
  if (signature.length() != ED25519_SIGNATURE_LEN) {
196
17
    return Status::JwtEd25519SignatureWrongLength;
197
17
  }
198
199
7.54k
  if (ED25519_verify(castToUChar(signed_data), signed_data.length(),
200
7.54k
                     castToUChar(signature), castToUChar(key.data())) == 1) {
201
1
    return Status::Ok;
202
1
  }
203
204
7.54k
  ERR_clear_error();
205
7.54k
  return Status::JwtVerificationFail;
206
7.54k
}
207
208
}  // namespace
209
210
2.37k
Status verifyJwtWithoutTimeChecking(const Jwt& jwt, const Jwks& jwks) {
211
  // Verify signature
212
2.37k
  std::string signed_data =
213
2.37k
      jwt.header_str_base64url_ + '.' + jwt.payload_str_base64url_;
214
2.37k
  bool kid_alg_matched = false;
215
37.3k
  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
37.3k
    if (!jwt.kid_.empty() && !jwk->kid_.empty() && jwk->kid_ != jwt.kid_) {
220
1.67k
      continue;
221
1.67k
    }
222
223
    // The same alg must be used.
224
35.6k
    if (!jwk->alg_.empty() && jwk->alg_ != jwt.alg_) {
225
1.35k
      continue;
226
1.35k
    }
227
34.3k
    kid_alg_matched = true;
228
229
34.3k
    if (jwk->kty_ == "EC") {
230
9.54k
      const EVP_MD* md;
231
9.54k
      if (jwt.alg_ == "ES384") {
232
0
        md = EVP_sha384();
233
9.54k
      } else if (jwt.alg_ == "ES512") {
234
1.63k
        md = EVP_sha512();
235
7.90k
      } else {
236
        // default to SHA256
237
7.90k
        md = EVP_sha256();
238
7.90k
      }
239
240
9.54k
      if (verifySignatureEC(jwk->ec_key_.get(), md, jwt.signature_,
241
9.54k
                            signed_data)) {
242
        // Verification succeeded.
243
3
        return Status::Ok;
244
3
      }
245
24.7k
    } else if (jwk->kty_ == "RSA") {
246
12.2k
      const EVP_MD* md;
247
12.2k
      if (jwt.alg_ == "RS384" || jwt.alg_ == "PS384") {
248
0
        md = EVP_sha384();
249
12.2k
      } else if (jwt.alg_ == "RS512" || jwt.alg_ == "PS512") {
250
721
        md = EVP_sha512();
251
11.5k
      } else {
252
        // default to SHA256
253
11.5k
        md = EVP_sha256();
254
11.5k
      }
255
256
12.2k
      if (jwt.alg_.compare(0, 2, "RS") == 0) {
257
4.86k
        if (verifySignatureRSA(jwk->rsa_.get(), md, jwt.signature_,
258
4.86k
                               signed_data)) {
259
          // Verification succeeded.
260
2
          return Status::Ok;
261
2
        }
262
7.41k
      } else if (jwt.alg_.compare(0, 2, "PS") == 0) {
263
7.21k
        if (verifySignatureRSAPSS(jwk->rsa_.get(), md, jwt.signature_,
264
7.21k
                                  signed_data)) {
265
          // Verification succeeded.
266
0
          return Status::Ok;
267
0
        }
268
7.21k
      }
269
12.5k
    } else if (jwk->kty_ == "oct") {
270
4.95k
      const EVP_MD* md;
271
4.95k
      if (jwt.alg_ == "HS384") {
272
0
        md = EVP_sha384();
273
4.95k
      } else if (jwt.alg_ == "HS512") {
274
1.40k
        md = EVP_sha512();
275
3.54k
      } else {
276
        // default to SHA256
277
3.54k
        md = EVP_sha256();
278
3.54k
      }
279
280
4.95k
      if (verifySignatureOct(jwk->hmac_key_, md, jwt.signature_, signed_data)) {
281
        // Verification succeeded.
282
1
        return Status::Ok;
283
1
      }
284
7.56k
    } else if (jwk->kty_ == "OKP" && jwk->crv_ == "Ed25519") {
285
7.56k
      Status status = verifySignatureEd25519(jwk->okp_key_raw_, jwt.signature_,
286
7.56k
                                             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.56k
      if (status == Status::Ok ||
291
7.56k
          status == Status::JwtEd25519SignatureWrongLength) {
292
18
        return status;
293
18
      }
294
7.56k
    }
295
34.3k
  }
296
297
  // Verification failed.
298
2.35k
  return kid_alg_matched ? Status::JwtVerificationFail
299
2.35k
                         : Status::JwksKidAlgMismatch;
300
2.37k
}
301
302
2.39k
Status verifyJwt(const Jwt& jwt, const Jwks& jwks) {
303
2.39k
  return verifyJwt(jwt, jwks, absl::ToUnixSeconds(absl::Now()));
304
2.39k
}
305
306
Status verifyJwt(const Jwt& jwt, const Jwks& jwks, uint64_t now,
307
2.39k
                 uint64_t clock_skew) {
308
2.39k
  Status time_status = jwt.verifyTimeConstraint(now, clock_skew);
309
2.39k
  if (time_status != Status::Ok) {
310
11
    return time_status;
311
11
  }
312
313
2.37k
  return verifyJwtWithoutTimeChecking(jwt, jwks);
314
2.39k
}
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