-
Notifications
You must be signed in to change notification settings - Fork 9
/
jwt_sign.cc
114 lines (97 loc) · 3.79 KB
/
jwt_sign.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
///////////////////////////////////////////////////////////////////////////////
// [START jwt-sign]
// An example for signing JSON Web Tokens (JWT).
#include <iostream>
#include <memory>
#include <ostream>
#include <string>
#include <utility>
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/log/check.h"
#include "absl/strings/string_view.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
#include "tink/config/global_registry.h"
#include "util/util.h"
#include "tink/jwt/jwt_public_key_sign.h"
#include "tink/jwt/jwt_signature_config.h"
#include "tink/jwt/raw_jwt.h"
#include "tink/keyset_handle.h"
#include "tink/util/status.h"
ABSL_FLAG(std::string, keyset_filename, "", "Keyset file in JSON format");
ABSL_FLAG(std::string, audience, "", "Expected audience in the token");
ABSL_FLAG(std::string, token_filename, "", "Path to the token file");
namespace {
using ::crypto::tink::JwtPublicKeySign;
using ::crypto::tink::KeysetHandle;
using ::crypto::tink::RawJwt;
using ::crypto::tink::RawJwtBuilder;
using ::crypto::tink::util::Status;
using ::crypto::tink::util::StatusOr;
void ValidateParams() {
// [START_EXCLUDE]
CHECK(!absl::GetFlag(FLAGS_keyset_filename).empty())
<< "Keyset file must be specified";
CHECK(!absl::GetFlag(FLAGS_audience).empty())
<< "Expected audience in the token must be specified";
CHECK(!absl::GetFlag(FLAGS_token_filename).empty())
<< "Token file must be specified";
// [END_EXCLUDE]
}
} // namespace
namespace tink_cc_examples {
// JWT sign example CLI implementation.
Status JwtSign(const std::string& keyset_filename, absl::string_view audience,
const std::string& token_filename) {
Status result = crypto::tink::JwtSignatureRegister();
if (!result.ok()) return result;
// Read the keyset from file.
StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
ReadJsonCleartextKeyset(keyset_filename);
if (!keyset_handle.ok()) return keyset_handle.status();
StatusOr<RawJwt> raw_jwt =
RawJwtBuilder()
.AddAudience(audience)
.SetExpiration(absl::Now() + absl::Seconds(100))
.Build();
if (!raw_jwt.ok()) return raw_jwt.status();
StatusOr<std::unique_ptr<JwtPublicKeySign>> jwt_signer =
(*keyset_handle)
->GetPrimitive<crypto::tink::JwtPublicKeySign>(
crypto::tink::ConfigGlobalRegistry());
if (!jwt_signer.ok()) return jwt_signer.status();
StatusOr<std::string> token = (*jwt_signer)->SignAndEncode(*raw_jwt);
if (!token.ok()) return token.status();
return WriteToFile(*token, token_filename);
}
} // namespace tink_cc_examples
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
ValidateParams();
std::string keyset_filename = absl::GetFlag(FLAGS_keyset_filename);
std::string audience = absl::GetFlag(FLAGS_audience);
std::string token_filename = absl::GetFlag(FLAGS_token_filename);
std::clog << "Using keyset in " << keyset_filename << " to ";
std::clog << " generate and sign a token using audience '" << audience
<< "'; the resulting signature is written to " << token_filename
<< '\n';
CHECK_OK(
tink_cc_examples::JwtSign(keyset_filename, audience, token_filename));
return 0;
}
// [END jwt-sign]