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-generate-public-jwk-set]
17 // An example for converting a Tink keyset with public keys into a JWK set.
18 #include <iostream>
19 #include <memory>
20 #include <ostream>
21 #include <string>
22
23 #include "absl/flags/flag.h"
24 #include "absl/flags/parse.h"
25 #include "absl/log/check.h"
26 #include "util/util.h"
27 #include "tink/jwt/jwk_set_converter.h"
28 #include "tink/jwt/jwt_signature_config.h"
29 #include "tink/keyset_handle.h"
30 #include "tink/util/status.h"
31
32 ABSL_FLAG(std::string, public_keyset_filename, "",
33 "Public keyset file in Tink's JSON format");
34 ABSL_FLAG(std::string, public_jwk_set_filename, "",
35 "Path to the output public JWK set file");
36
37 namespace {
38
39 using ::crypto::tink::JwkSetFromPublicKeysetHandle;
40 using ::crypto::tink::KeysetHandle;
41 using ::crypto::tink::util::Status;
42 using ::crypto::tink::util::StatusOr;
43
ValidateParams()44 void ValidateParams() {
45 // [START_EXCLUDE]
46 CHECK(!absl::GetFlag(FLAGS_public_keyset_filename).empty())
47 << "Public keyset file must be specified";
48 CHECK(!absl::GetFlag(FLAGS_public_jwk_set_filename).empty())
49 << "Public JWK set file must be specified";
50 // [END_EXCLUDE]
51 }
52
53 } // namespace
54
55 namespace tink_cc_examples {
56
JwtGeneratePublicJwkSet(const std::string & public_keyset_filename,const std::string & public_jwk_set_filename)57 Status JwtGeneratePublicJwkSet(const std::string& public_keyset_filename,
58 const std::string& public_jwk_set_filename) {
59 Status result = crypto::tink::JwtSignatureRegister();
60 if (!result.ok()) return result;
61
62 StatusOr<std::unique_ptr<KeysetHandle>> keyset_handle =
63 ReadJsonCleartextKeyset(public_keyset_filename);
64 if (!keyset_handle.ok()) return keyset_handle.status();
65
66 StatusOr<std::string> public_jwk_set =
67 JwkSetFromPublicKeysetHandle(**keyset_handle);
68 if (!public_jwk_set.ok()) return keyset_handle.status();
69
70 return WriteToFile(*public_jwk_set, public_jwk_set_filename);
71 }
72
73 } // namespace tink_cc_examples
74
main(int argc,char ** argv)75 int main(int argc, char** argv) {
76 absl::ParseCommandLine(argc, argv);
77
78 ValidateParams();
79
80 std::string public_keyset_filename =
81 absl::GetFlag(FLAGS_public_keyset_filename);
82 std::string public_jwk_set_filename =
83 absl::GetFlag(FLAGS_public_jwk_set_filename);
84
85 std::clog << "Convert public keyset in " << public_keyset_filename << " to ";
86 std::clog << " to JWK set format; the result is written to "
87 << public_jwk_set_filename << std::endl;
88
89 CHECK_OK(tink_cc_examples::JwtGeneratePublicJwkSet(public_keyset_filename,
90 public_jwk_set_filename));
91 return 0;
92 }
93 // [END jwt-generate-public-jwk-set]
94