1 /* Copyright (C) 2019 Jeremy Thien <jeremy.thien@gmail.com>
2 This file is part of the JWT C Library
3
4 This Source Code Form is subject to the terms of the Mozilla Public
5 License, v. 2.0. If a copy of the MPL was not distributed with this
6 file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <jwt.h>
11 #include <getopt.h>
12 #include <string.h>
13 #include <time.h>
14 #include <string.h>
15 #include <libgen.h>
16
usage(const char * name)17 void usage(const char *name)
18 {
19 printf("%s OPTIONS\n", name);
20 printf("Options:\n"
21 " -k --key KEY The private key to use for signing\n"
22 " -a --alg ALG The algorithm to use for signing\n"
23 " -c --claim KEY=VALUE A claim to add to JWT\n"
24 " -j --json '{key1:value1}' A json to add to JWT\n"
25 );
26 exit(0);
27 }
28
main(int argc,char * argv[])29 int main(int argc, char *argv[])
30 {
31 char opt_key_name[200] = "test-rsa256.pem";
32 jwt_alg_t opt_alg = JWT_ALG_RS256;
33 time_t iat = time(NULL);
34
35 int oc = 0;
36 char *optstr = "hk:a:c:j:";
37 struct option opttbl[] = {
38 { "help", no_argument, NULL, 'h' },
39 { "key", required_argument, NULL, 'k' },
40 { "alg", required_argument, NULL, 'a' },
41 { "claim", required_argument, NULL, 'c' },
42 { "json", required_argument, NULL, 'j' },
43 { NULL, 0, 0, 0 },
44 };
45
46 char *k = NULL, *v = NULL;
47 int claims_count = 0;
48 int i = 0;
49 unsigned char key[10240];
50 size_t key_len = 0;
51 FILE *fp_priv_key;
52 int ret = 0;
53 jwt_t *jwt;
54 struct kv {
55 char *key;
56 char *val;
57 } opt_claims[100];
58 memset(opt_claims, 0, sizeof(opt_claims));
59 char* opt_json = NULL;
60
61 while ((oc = getopt_long(argc, argv, optstr, opttbl, NULL)) != -1) {
62 switch (oc) {
63 case 'k':
64 strncpy(opt_key_name, optarg, sizeof(opt_key_name));
65 opt_key_name[sizeof(opt_key_name) - 1] = '\0';
66 break;
67
68 case 'a':
69 opt_alg = jwt_str_alg(optarg);
70 if (opt_alg == JWT_ALG_INVAL) {
71 fprintf(stderr, "%s is not supported algorithm, using RS256\n", optarg);
72 opt_alg = JWT_ALG_RS256;
73 }
74 break;
75
76 case 'c':
77 k = strtok(optarg, "=");
78 if (k) {
79 v = strtok(NULL, "=");
80 if (v) {
81 opt_claims[claims_count].key = strdup(k);
82 opt_claims[claims_count].val = strdup(v);
83 claims_count++;
84 }
85 }
86 break;
87 case 'j':
88 if (optarg != NULL) {
89 opt_json = strdup(optarg);
90 }
91 break;
92
93 case 'h':
94 usage(basename(argv[0]));
95 return 0;
96
97 default: /* '?' */
98 usage(basename(argv[0]));
99 exit(EXIT_FAILURE);
100 }
101 }
102
103 fprintf(stderr, "jwtgen: privkey %s algorithm %s\n",
104 opt_key_name, jwt_alg_str(opt_alg));
105
106 if (opt_alg > JWT_ALG_NONE) {
107 fp_priv_key = fopen(opt_key_name, "r");
108 key_len = fread(key, 1, sizeof(key), fp_priv_key);
109 fclose(fp_priv_key);
110 key[key_len] = '\0';
111 fprintf(stderr, "priv key loaded %s (%zu)!\n", opt_key_name, key_len);
112 }
113
114 ret = jwt_new(&jwt);
115 if (ret != 0 || jwt == NULL) {
116 fprintf(stderr, "invalid jwt\n");
117 goto finish;
118 }
119
120 ret = jwt_add_grant_int(jwt, "iat", iat);
121 for (i = 0; i < claims_count; i++) {
122 fprintf(stderr, "Adding claim %s with valu %s\n", opt_claims[i].key, opt_claims[i].val);
123 jwt_add_grant(jwt, opt_claims[i].key, opt_claims[i].val);
124 }
125
126 if (opt_json != NULL) {
127 ret = jwt_add_grants_json(jwt, opt_json);
128 if (ret != 0) {
129 fprintf(stderr, "Input json is invalid\n");
130 goto finish;
131 }
132 }
133
134 ret = jwt_set_alg(jwt, opt_alg, opt_alg == JWT_ALG_NONE ? NULL : key, opt_alg == JWT_ALG_NONE ? 0 : key_len);
135 if (ret < 0) {
136 fprintf(stderr, "jwt incorrect algorithm\n");
137 goto finish;
138 }
139
140 jwt_dump_fp(jwt, stderr, 1);
141
142 fprintf(stderr, "jwt algo %s!\n", jwt_alg_str(opt_alg));
143
144 char *out = jwt_encode_str(jwt);
145 printf("%s\n", out);
146
147 jwt_free_str(out);
148 finish:
149 if (opt_json != NULL) {
150 free(opt_json);
151 }
152 jwt_free(jwt);
153
154 return 0;
155 }
156
157