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