1 // Copyright 2023 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 // [START jwt-verify]
17 // A utility for creating, signing and verifying JSON Web Tokens (JWT).
18 #include <iostream>
19 #include <memory>
20 #include <ostream>
21 #include <string>
22 #include <utility>
23
24 #include "absl/flags/flag.h"
25 #include "absl/flags/parse.h"
26 #include "absl/log/check.h"
27 #include "util/util.h"
28 #include "tink/jwt/jwk_set_converter.h"
29 #include "tink/jwt/jwt_public_key_verify.h"
30 #include "tink/jwt/jwt_signature_config.h"
31 #include "tink/jwt/jwt_validator.h"
32 #include "tink/keyset_handle.h"
33 #include "tink/util/status.h"
34
35 ABSL_FLAG(std::string, jwk_set_filename, "", "Path to the JWK set file");
36 ABSL_FLAG(std::string, audience, "", "Expected audience in the token");
37 ABSL_FLAG(std::string, token_filename, "", "Path to the token file");
38
39 namespace {
40
41 using ::crypto::tink::JwkSetToPublicKeysetHandle;
42 using ::crypto::tink::JwtPublicKeyVerify;
43 using ::crypto::tink::JwtValidator;
44 using ::crypto::tink::KeysetHandle;
45 using ::crypto::tink::util::Status;
46 using ::crypto::tink::util::StatusOr;
47
ValidateParams()48 void ValidateParams() {
49 // [START_EXCLUDE]
50 CHECK(!absl::GetFlag(FLAGS_jwk_set_filename).empty())
51 << "Keyset file must be specified";
52 CHECK(!absl::GetFlag(FLAGS_audience).empty())
53 << "Expected audience in the token must be specified";
54 CHECK(!absl::GetFlag(FLAGS_token_filename).empty())
55 << "Token file must be specified";
56 // [END_EXCLUDE]
57 }
58
59 } // namespace
60
61 namespace tink_cc_examples {
62
63 // JWT verify example CLI implementation.
JwtVerify(const std::string & jwk_set_filename,absl::string_view audience,const std::string & token_filename)64 Status JwtVerify(const std::string& jwk_set_filename,
65 absl::string_view audience,
66 const std::string& token_filename) {
67 Status result = crypto::tink::JwtSignatureRegister();
68 if (!result.ok()) return result;
69
70 // Read the JWK set from file and convert it.
71 StatusOr<std::string> jwk_set = ReadFile(jwk_set_filename);
72 if (!jwk_set.ok()) return jwk_set.status();
73 StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
74 JwkSetToPublicKeysetHandle(*jwk_set);
75
76 // Read the token.
77 StatusOr<std::string> token = ReadFile(token_filename);
78 if (!token.ok()) return token.status();
79
80 StatusOr<JwtValidator> validator =
81 crypto::tink::JwtValidatorBuilder().ExpectAudience(audience).Build();
82 if (!validator.ok()) return validator.status();
83
84 StatusOr<std::unique_ptr<JwtPublicKeyVerify>> jwt_verifier =
85 (*keyset_handle)->GetPrimitive<JwtPublicKeyVerify>();
86 if (!jwt_verifier.ok()) return jwt_verifier.status();
87
88 return (*jwt_verifier)->VerifyAndDecode(*token, *validator).status();
89 }
90
91 } // namespace tink_cc_examples
92
main(int argc,char ** argv)93 int main(int argc, char** argv) {
94 absl::ParseCommandLine(argc, argv);
95
96 ValidateParams();
97
98 std::string jwk_set_filename = absl::GetFlag(FLAGS_jwk_set_filename);
99 std::string audience = absl::GetFlag(FLAGS_audience);
100 std::string token_filename = absl::GetFlag(FLAGS_token_filename);
101
102 std::clog << "Using keyset in " << jwk_set_filename << " to ";
103 std::clog << " verify a token with expected audience '" << audience
104 << std::endl;
105
106 CHECK_OK(
107 tink_cc_examples::JwtVerify(jwk_set_filename, audience, token_filename));
108 return 0;
109 }
110 // [END jwt-verify]
111