xref: /aosp_15_r20/external/libwebsockets/minimal-examples/crypto/minimal-crypto-jwk/main.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * lws-crypto-jwk
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Written in 2010-2019 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker  * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker  */
9*1c60b9acSAndroid Build Coastguard Worker 
10*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
11*1c60b9acSAndroid Build Coastguard Worker #include <sys/types.h>
12*1c60b9acSAndroid Build Coastguard Worker #include <fcntl.h>
13*1c60b9acSAndroid Build Coastguard Worker 
14*1c60b9acSAndroid Build Coastguard Worker /*
15*1c60b9acSAndroid Build Coastguard Worker  * handles escapes and line wrapping suitable for use
16*1c60b9acSAndroid Build Coastguard Worker  * defining a C char array ( -c option )
17*1c60b9acSAndroid Build Coastguard Worker  */
18*1c60b9acSAndroid Build Coastguard Worker 
19*1c60b9acSAndroid Build Coastguard Worker static int
format_c(int fd,const char * key)20*1c60b9acSAndroid Build Coastguard Worker format_c(int fd, const char *key)
21*1c60b9acSAndroid Build Coastguard Worker {
22*1c60b9acSAndroid Build Coastguard Worker 	const char *k = key;
23*1c60b9acSAndroid Build Coastguard Worker 	int seq = 0;
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker 	while (*k) {
26*1c60b9acSAndroid Build Coastguard Worker 		if (*k == '{') {
27*1c60b9acSAndroid Build Coastguard Worker 			if (write(fd, "\"{\"\n\t\"", 6) < 6)
28*1c60b9acSAndroid Build Coastguard Worker 				return -1;
29*1c60b9acSAndroid Build Coastguard Worker 			k++;
30*1c60b9acSAndroid Build Coastguard Worker 			seq = 0;
31*1c60b9acSAndroid Build Coastguard Worker 			continue;
32*1c60b9acSAndroid Build Coastguard Worker 		}
33*1c60b9acSAndroid Build Coastguard Worker 		if (*k == '}') {
34*1c60b9acSAndroid Build Coastguard Worker 			if (write(fd, "\"\n\"}\"\n", 6) < 6)
35*1c60b9acSAndroid Build Coastguard Worker 				return -1;
36*1c60b9acSAndroid Build Coastguard Worker 			k++;
37*1c60b9acSAndroid Build Coastguard Worker 			seq = 0;
38*1c60b9acSAndroid Build Coastguard Worker 			continue;
39*1c60b9acSAndroid Build Coastguard Worker 		}
40*1c60b9acSAndroid Build Coastguard Worker 		if (*k == '\"') {
41*1c60b9acSAndroid Build Coastguard Worker 			if (write(fd, "\\\"", 2) < 2)
42*1c60b9acSAndroid Build Coastguard Worker 				return -1;
43*1c60b9acSAndroid Build Coastguard Worker 			seq += 2;
44*1c60b9acSAndroid Build Coastguard Worker 			k++;
45*1c60b9acSAndroid Build Coastguard Worker 			continue;
46*1c60b9acSAndroid Build Coastguard Worker 		}
47*1c60b9acSAndroid Build Coastguard Worker 		if (*k == ',') {
48*1c60b9acSAndroid Build Coastguard Worker 			if (write(fd, ",\"\n\t\"", 5) < 5)
49*1c60b9acSAndroid Build Coastguard Worker 				return -1;
50*1c60b9acSAndroid Build Coastguard Worker 			k++;
51*1c60b9acSAndroid Build Coastguard Worker 			seq = 0;
52*1c60b9acSAndroid Build Coastguard Worker 			continue;
53*1c60b9acSAndroid Build Coastguard Worker 		}
54*1c60b9acSAndroid Build Coastguard Worker 		if (write(fd, k, 1) < 1)
55*1c60b9acSAndroid Build Coastguard Worker 			return -1;
56*1c60b9acSAndroid Build Coastguard Worker 		seq++;
57*1c60b9acSAndroid Build Coastguard Worker 		if (seq >= 60) {
58*1c60b9acSAndroid Build Coastguard Worker 			if (write(fd, "\"\n\t \"", 5) < 5)
59*1c60b9acSAndroid Build Coastguard Worker 				return -1;
60*1c60b9acSAndroid Build Coastguard Worker 			seq = 1;
61*1c60b9acSAndroid Build Coastguard Worker 		}
62*1c60b9acSAndroid Build Coastguard Worker 		k++;
63*1c60b9acSAndroid Build Coastguard Worker 	}
64*1c60b9acSAndroid Build Coastguard Worker 
65*1c60b9acSAndroid Build Coastguard Worker 	return 0;
66*1c60b9acSAndroid Build Coastguard Worker }
67*1c60b9acSAndroid Build Coastguard Worker 
main(int argc,const char ** argv)68*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
69*1c60b9acSAndroid Build Coastguard Worker {
70*1c60b9acSAndroid Build Coastguard Worker 	int result = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
71*1c60b9acSAndroid Build Coastguard Worker 	enum lws_gencrypto_kty kty = LWS_GENCRYPTO_KTY_RSA;
72*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context_creation_info info;
73*1c60b9acSAndroid Build Coastguard Worker 	const char *curve = "P-256", *p;
74*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context;
75*1c60b9acSAndroid Build Coastguard Worker 	struct lws_jwk jwk;
76*1c60b9acSAndroid Build Coastguard Worker 	int bits = 4096;
77*1c60b9acSAndroid Build Coastguard Worker 	char key[32768];
78*1c60b9acSAndroid Build Coastguard Worker 	int vl = sizeof(key);
79*1c60b9acSAndroid Build Coastguard Worker 
80*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-d")))
81*1c60b9acSAndroid Build Coastguard Worker 		logs = atoi(p);
82*1c60b9acSAndroid Build Coastguard Worker 
83*1c60b9acSAndroid Build Coastguard Worker 	lws_set_log_level(logs, NULL);
84*1c60b9acSAndroid Build Coastguard Worker 	lwsl_user("LWS JWK example\n");
85*1c60b9acSAndroid Build Coastguard Worker 
86*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-b")))
87*1c60b9acSAndroid Build Coastguard Worker 		bits = atoi(p);
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-t"))) {
90*1c60b9acSAndroid Build Coastguard Worker 		if (!strcmp(p, "RSA"))
91*1c60b9acSAndroid Build Coastguard Worker 			kty = LWS_GENCRYPTO_KTY_RSA;
92*1c60b9acSAndroid Build Coastguard Worker 		else
93*1c60b9acSAndroid Build Coastguard Worker 			if (!strcmp(p, "OCT"))
94*1c60b9acSAndroid Build Coastguard Worker 				kty = LWS_GENCRYPTO_KTY_OCT;
95*1c60b9acSAndroid Build Coastguard Worker 			else
96*1c60b9acSAndroid Build Coastguard Worker 				if (!strcmp(p, "EC"))
97*1c60b9acSAndroid Build Coastguard Worker 					kty = LWS_GENCRYPTO_KTY_EC;
98*1c60b9acSAndroid Build Coastguard Worker 				else {
99*1c60b9acSAndroid Build Coastguard Worker 					lwsl_err("Unknown key type (must be "
100*1c60b9acSAndroid Build Coastguard Worker 						 "OCT, RSA or EC)\n");
101*1c60b9acSAndroid Build Coastguard Worker 
102*1c60b9acSAndroid Build Coastguard Worker 					return 1;
103*1c60b9acSAndroid Build Coastguard Worker 				}
104*1c60b9acSAndroid Build Coastguard Worker 	}
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker 	memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
107*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
108*1c60b9acSAndroid Build Coastguard Worker 	info.port = CONTEXT_PORT_NO_LISTEN;
109*1c60b9acSAndroid Build Coastguard Worker #endif
110*1c60b9acSAndroid Build Coastguard Worker 	info.options = 0;
111*1c60b9acSAndroid Build Coastguard Worker 
112*1c60b9acSAndroid Build Coastguard Worker 	context = lws_create_context(&info);
113*1c60b9acSAndroid Build Coastguard Worker 	if (!context) {
114*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("lws init failed\n");
115*1c60b9acSAndroid Build Coastguard Worker 		return 1;
116*1c60b9acSAndroid Build Coastguard Worker 	}
117*1c60b9acSAndroid Build Coastguard Worker 
118*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "-v")))
119*1c60b9acSAndroid Build Coastguard Worker 		curve = p;
120*1c60b9acSAndroid Build Coastguard Worker 
121*1c60b9acSAndroid Build Coastguard Worker 	if (lws_jwk_generate(context, &jwk, kty, bits, curve)) {
122*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("lws_jwk_generate failed\n");
123*1c60b9acSAndroid Build Coastguard Worker 
124*1c60b9acSAndroid Build Coastguard Worker 		return 1;
125*1c60b9acSAndroid Build Coastguard Worker 	}
126*1c60b9acSAndroid Build Coastguard Worker 
127*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "--kid")))
128*1c60b9acSAndroid Build Coastguard Worker 		lws_jwk_strdup_meta(&jwk, JWK_META_KID, p, (int)strlen(p));
129*1c60b9acSAndroid Build Coastguard Worker 
130*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "--use")))
131*1c60b9acSAndroid Build Coastguard Worker 		lws_jwk_strdup_meta(&jwk, JWK_META_USE, p, (int)strlen(p));
132*1c60b9acSAndroid Build Coastguard Worker 
133*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "--alg")))
134*1c60b9acSAndroid Build Coastguard Worker 		lws_jwk_strdup_meta(&jwk, JWK_META_ALG, p, (int)strlen(p));
135*1c60b9acSAndroid Build Coastguard Worker 
136*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "--key-ops")))
137*1c60b9acSAndroid Build Coastguard Worker 		lws_jwk_strdup_meta(&jwk, JWK_META_KEY_OPS, p, (int)strlen(p));
138*1c60b9acSAndroid Build Coastguard Worker 
139*1c60b9acSAndroid Build Coastguard Worker 	if ((p = lws_cmdline_option(argc, argv, "--public")) &&
140*1c60b9acSAndroid Build Coastguard Worker 	    kty != LWS_GENCRYPTO_KTY_OCT) {
141*1c60b9acSAndroid Build Coastguard Worker 
142*1c60b9acSAndroid Build Coastguard Worker 		int fd;
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 		/* public version */
145*1c60b9acSAndroid Build Coastguard Worker 
146*1c60b9acSAndroid Build Coastguard Worker 		if (lws_jwk_export(&jwk, 0, key, &vl) < 0) {
147*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("lws_jwk_export failed\n");
148*1c60b9acSAndroid Build Coastguard Worker 
149*1c60b9acSAndroid Build Coastguard Worker 			return 1;
150*1c60b9acSAndroid Build Coastguard Worker 		}
151*1c60b9acSAndroid Build Coastguard Worker 
152*1c60b9acSAndroid Build Coastguard Worker 		fd = open(p, LWS_O_CREAT | LWS_O_TRUNC | LWS_O_WRONLY, 0600);
153*1c60b9acSAndroid Build Coastguard Worker 		if (fd < 0) {
154*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("Can't open public key file %s\n", p);
155*1c60b9acSAndroid Build Coastguard Worker 			return 1;
156*1c60b9acSAndroid Build Coastguard Worker 		}
157*1c60b9acSAndroid Build Coastguard Worker 
158*1c60b9acSAndroid Build Coastguard Worker 		if (lws_cmdline_option(argc, argv, "-c"))
159*1c60b9acSAndroid Build Coastguard Worker 			format_c(fd, key);
160*1c60b9acSAndroid Build Coastguard Worker 		else {
161*1c60b9acSAndroid Build Coastguard Worker 			if (write(fd, key,
162*1c60b9acSAndroid Build Coastguard Worker #if defined(WIN32)
163*1c60b9acSAndroid Build Coastguard Worker 					(unsigned int)
164*1c60b9acSAndroid Build Coastguard Worker #endif
165*1c60b9acSAndroid Build Coastguard Worker 					strlen(key)) < 0) {
166*1c60b9acSAndroid Build Coastguard Worker 				lwsl_err("Write public failed\n");
167*1c60b9acSAndroid Build Coastguard Worker 				return 1;
168*1c60b9acSAndroid Build Coastguard Worker 			}
169*1c60b9acSAndroid Build Coastguard Worker 		}
170*1c60b9acSAndroid Build Coastguard Worker 
171*1c60b9acSAndroid Build Coastguard Worker 		close(fd);
172*1c60b9acSAndroid Build Coastguard Worker 	}
173*1c60b9acSAndroid Build Coastguard Worker 
174*1c60b9acSAndroid Build Coastguard Worker 	/* private version */
175*1c60b9acSAndroid Build Coastguard Worker 
176*1c60b9acSAndroid Build Coastguard Worker 	if (lws_jwk_export(&jwk, LWSJWKF_EXPORT_PRIVATE, key, &vl) < 0) {
177*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("lws_jwk_export failed\n");
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 		return 1;
180*1c60b9acSAndroid Build Coastguard Worker 	}
181*1c60b9acSAndroid Build Coastguard Worker 
182*1c60b9acSAndroid Build Coastguard Worker 	if (lws_cmdline_option(argc, argv, "-c")) {
183*1c60b9acSAndroid Build Coastguard Worker 		if (format_c(1, key) < 0)
184*1c60b9acSAndroid Build Coastguard Worker 			return 1;
185*1c60b9acSAndroid Build Coastguard Worker 	} else
186*1c60b9acSAndroid Build Coastguard Worker 		if (write(1, key,
187*1c60b9acSAndroid Build Coastguard Worker #if defined(WIN32)
188*1c60b9acSAndroid Build Coastguard Worker 				(unsigned int)
189*1c60b9acSAndroid Build Coastguard Worker #endif
190*1c60b9acSAndroid Build Coastguard Worker 				strlen(key)) < 0) {
191*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("Write stdout failed\n");
192*1c60b9acSAndroid Build Coastguard Worker 			return 1;
193*1c60b9acSAndroid Build Coastguard Worker 		}
194*1c60b9acSAndroid Build Coastguard Worker 
195*1c60b9acSAndroid Build Coastguard Worker 	lws_jwk_destroy(&jwk);
196*1c60b9acSAndroid Build Coastguard Worker 
197*1c60b9acSAndroid Build Coastguard Worker 	lws_context_destroy(context);
198*1c60b9acSAndroid Build Coastguard Worker 
199*1c60b9acSAndroid Build Coastguard Worker 	return result;
200*1c60b9acSAndroid Build Coastguard Worker }
201