openssl-x509.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. */
  24. #define WIN32_LEAN_AND_MEAN
  25. #include "private-lib-core.h"
  26. #include "private-lib-tls-openssl.h"
  27. #if !defined(LWS_PLAT_OPTEE)
  28. static int
  29. dec(char c)
  30. {
  31. return c - '0';
  32. }
  33. #endif
  34. static time_t
  35. lws_tls_openssl_asn1time_to_unix(ASN1_TIME *as)
  36. {
  37. #if !defined(LWS_PLAT_OPTEE)
  38. const char *p = (const char *)as->data;
  39. struct tm t;
  40. /* [YY]YYMMDDHHMMSSZ */
  41. memset(&t, 0, sizeof(t));
  42. if (strlen(p) == 13) {
  43. t.tm_year = (dec(p[0]) * 10) + dec(p[1]) + 100;
  44. p += 2;
  45. } else {
  46. t.tm_year = (dec(p[0]) * 1000) + (dec(p[1]) * 100) +
  47. (dec(p[2]) * 10) + dec(p[3]);
  48. p += 4;
  49. }
  50. t.tm_mon = (dec(p[0]) * 10) + dec(p[1]) - 1;
  51. p += 2;
  52. t.tm_mday = (dec(p[0]) * 10) + dec(p[1]) - 1;
  53. p += 2;
  54. t.tm_hour = (dec(p[0]) * 10) + dec(p[1]);
  55. p += 2;
  56. t.tm_min = (dec(p[0]) * 10) + dec(p[1]);
  57. p += 2;
  58. t.tm_sec = (dec(p[0]) * 10) + dec(p[1]);
  59. t.tm_isdst = 0;
  60. return mktime(&t);
  61. #else
  62. return (time_t)-1;
  63. #endif
  64. }
  65. int
  66. lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type,
  67. union lws_tls_cert_info_results *buf, size_t len)
  68. {
  69. X509_NAME *xn;
  70. #if !defined(LWS_PLAT_OPTEE)
  71. char *p;
  72. #endif
  73. if (!x509)
  74. return -1;
  75. #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(X509_get_notBefore)
  76. #define X509_get_notBefore(x) X509_getm_notBefore(x)
  77. #define X509_get_notAfter(x) X509_getm_notAfter(x)
  78. #endif
  79. switch (type) {
  80. case LWS_TLS_CERT_INFO_VALIDITY_FROM:
  81. buf->time = lws_tls_openssl_asn1time_to_unix(
  82. X509_get_notBefore(x509));
  83. if (buf->time == (time_t)-1)
  84. return -1;
  85. break;
  86. case LWS_TLS_CERT_INFO_VALIDITY_TO:
  87. buf->time = lws_tls_openssl_asn1time_to_unix(
  88. X509_get_notAfter(x509));
  89. if (buf->time == (time_t)-1)
  90. return -1;
  91. break;
  92. case LWS_TLS_CERT_INFO_COMMON_NAME:
  93. #if defined(LWS_PLAT_OPTEE)
  94. return -1;
  95. #else
  96. xn = X509_get_subject_name(x509);
  97. if (!xn)
  98. return -1;
  99. X509_NAME_oneline(xn, buf->ns.name, (int)len - 2);
  100. p = strstr(buf->ns.name, "/CN=");
  101. if (p)
  102. memmove(buf->ns.name, p + 4, strlen(p + 4) + 1);
  103. buf->ns.len = (int)strlen(buf->ns.name);
  104. return 0;
  105. #endif
  106. case LWS_TLS_CERT_INFO_ISSUER_NAME:
  107. xn = X509_get_issuer_name(x509);
  108. if (!xn)
  109. return -1;
  110. X509_NAME_oneline(xn, buf->ns.name, (int)len - 1);
  111. buf->ns.len = (int)strlen(buf->ns.name);
  112. return 0;
  113. case LWS_TLS_CERT_INFO_USAGE:
  114. #if defined(LWS_HAVE_X509_get_key_usage)
  115. buf->usage = X509_get_key_usage(x509);
  116. break;
  117. #else
  118. return -1;
  119. #endif
  120. case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY:
  121. {
  122. #ifndef USE_WOLFSSL
  123. size_t klen = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x509), NULL);
  124. uint8_t *tmp, *ptmp;
  125. if (!klen || klen > len)
  126. return -1;
  127. tmp = (uint8_t *)OPENSSL_malloc(klen);
  128. if (!tmp)
  129. return -1;
  130. ptmp = tmp;
  131. if (i2d_X509_PUBKEY(
  132. X509_get_X509_PUBKEY(x509), &ptmp) != (int)klen ||
  133. !ptmp || lws_ptr_diff(ptmp, tmp) != (int)klen) {
  134. lwsl_info("%s: cert public key extraction failed\n",
  135. __func__);
  136. if (ptmp)
  137. OPENSSL_free(tmp);
  138. return -1;
  139. }
  140. buf->ns.len = (int)klen;
  141. memcpy(buf->ns.name, tmp, klen);
  142. OPENSSL_free(tmp);
  143. #endif
  144. return 0;
  145. }
  146. default:
  147. return -1;
  148. }
  149. return 0;
  150. }
  151. int
  152. lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type,
  153. union lws_tls_cert_info_results *buf, size_t len)
  154. {
  155. return lws_tls_openssl_cert_info(x509->cert, type, buf, len);
  156. }
  157. #if defined(LWS_WITH_NETWORK)
  158. int
  159. lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type,
  160. union lws_tls_cert_info_results *buf, size_t len)
  161. {
  162. #if defined(LWS_HAVE_SSL_CTX_get0_certificate)
  163. X509 *x509 = SSL_CTX_get0_certificate(vhost->tls.ssl_ctx);
  164. return lws_tls_openssl_cert_info(x509, type, buf, len);
  165. #else
  166. lwsl_notice("openssl is too old to support %s\n", __func__);
  167. return -1;
  168. #endif
  169. }
  170. int
  171. lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type,
  172. union lws_tls_cert_info_results *buf, size_t len)
  173. {
  174. int rc = 0;
  175. X509 *x509;
  176. wsi = lws_get_network_wsi(wsi);
  177. x509 = SSL_get_peer_certificate(wsi->tls.ssl);
  178. if (!x509) {
  179. lwsl_debug("no peer cert\n");
  180. return -1;
  181. }
  182. switch (type) {
  183. case LWS_TLS_CERT_INFO_VERIFIED:
  184. buf->verified = SSL_get_verify_result(wsi->tls.ssl) ==
  185. X509_V_OK;
  186. break;
  187. default:
  188. rc = lws_tls_openssl_cert_info(x509, type, buf, len);
  189. }
  190. X509_free(x509);
  191. return rc;
  192. }
  193. #endif
  194. int
  195. lws_x509_create(struct lws_x509_cert **x509)
  196. {
  197. *x509 = lws_malloc(sizeof(**x509), __func__);
  198. if (*x509)
  199. (*x509)->cert = NULL;
  200. return !(*x509);
  201. }
  202. int
  203. lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len)
  204. {
  205. BIO* bio = BIO_new(BIO_s_mem());
  206. BIO_write(bio, pem, (int)len);
  207. x509->cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
  208. BIO_free(bio);
  209. if (!x509->cert) {
  210. lwsl_err("%s: unable to parse PEM cert\n", __func__);
  211. lws_tls_err_describe_clear();
  212. return -1;
  213. }
  214. return 0;
  215. }
  216. int
  217. lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted,
  218. const char *common_name)
  219. {
  220. char c[32], *p;
  221. int ret;
  222. if (common_name) {
  223. X509_NAME *xn = X509_get_subject_name(x509->cert);
  224. if (!xn)
  225. return -1;
  226. X509_NAME_oneline(xn, c, (int)sizeof(c) - 2);
  227. p = strstr(c, "/CN=");
  228. if (p)
  229. p = p + 4;
  230. else
  231. p = c;
  232. if (strcmp(p, common_name)) {
  233. lwsl_err("%s: common name mismatch\n", __func__);
  234. return -1;
  235. }
  236. }
  237. ret = X509_check_issued(trusted->cert, x509->cert);
  238. if (ret != X509_V_OK) {
  239. lwsl_err("%s: unable to verify cert relationship\n", __func__);
  240. lws_tls_err_describe_clear();
  241. return -1;
  242. }
  243. return 0;
  244. }
  245. #if defined(LWS_WITH_JOSE)
  246. int
  247. lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509,
  248. const char *curves, int rsa_min_bits)
  249. {
  250. int id, n, ret = -1, count;
  251. ASN1_OBJECT *obj = NULL;
  252. const EC_POINT *ecpoint;
  253. const EC_GROUP *ecgroup;
  254. EC_KEY *ecpub = NULL;
  255. X509_PUBKEY *pubkey;
  256. RSA *rsapub = NULL;
  257. BIGNUM *mpi[4];
  258. EVP_PKEY *pkey;
  259. memset(jwk, 0, sizeof(*jwk));
  260. pubkey = X509_get_X509_PUBKEY(x509->cert);
  261. if (!pubkey) {
  262. lwsl_err("%s: missing pubkey alg in cert\n", __func__);
  263. goto bail;
  264. }
  265. if (X509_PUBKEY_get0_param(&obj, NULL, NULL, NULL, pubkey) != 1) {
  266. lwsl_err("%s: missing pubkey alg in cert\n", __func__);
  267. goto bail;
  268. }
  269. id = OBJ_obj2nid(obj);
  270. if (id == NID_undef) {
  271. lwsl_err("%s: missing pubkey alg in cert\n", __func__);
  272. goto bail;
  273. }
  274. lwsl_debug("%s: key type %d \"%s\"\n", __func__, id, OBJ_nid2ln(id));
  275. pkey = X509_get_pubkey(x509->cert);
  276. if (!pkey) {
  277. lwsl_notice("%s: unable to extract pubkey", __func__);
  278. goto bail;
  279. }
  280. switch (id) {
  281. case NID_X9_62_id_ecPublicKey:
  282. lwsl_debug("%s: EC key\n", __func__);
  283. jwk->kty = LWS_GENCRYPTO_KTY_EC;
  284. if (!curves) {
  285. lwsl_err("%s: ec curves not allowed\n", __func__);
  286. goto bail1;
  287. }
  288. ecpub = EVP_PKEY_get1_EC_KEY(pkey);
  289. if (!ecpub) {
  290. lwsl_notice("%s: missing EC pubkey\n", __func__);
  291. goto bail1;
  292. }
  293. ecpoint = EC_KEY_get0_public_key(ecpub);
  294. if (!ecpoint) {
  295. lwsl_err("%s: EC_KEY_get0_public_key failed\n", __func__);
  296. goto bail2;
  297. }
  298. ecgroup = EC_KEY_get0_group(ecpub);
  299. if (!ecgroup) {
  300. lwsl_err("%s: EC_KEY_get0_group failed\n", __func__);
  301. goto bail2;
  302. }
  303. /* validate the curve against ones we allow */
  304. if (lws_genec_confirm_curve_allowed_by_tls_id(curves,
  305. EC_GROUP_get_curve_name(ecgroup), jwk))
  306. /* already logged */
  307. goto bail2;
  308. mpi[LWS_GENCRYPTO_EC_KEYEL_CRV] = NULL;
  309. mpi[LWS_GENCRYPTO_EC_KEYEL_X] = BN_new(); /* X */
  310. mpi[LWS_GENCRYPTO_EC_KEYEL_D] = NULL;
  311. mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = BN_new(); /* Y */
  312. #if defined(LWS_HAVE_EC_POINT_get_affine_coordinates)
  313. if (EC_POINT_get_affine_coordinates(ecgroup, ecpoint,
  314. #else
  315. if (EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint,
  316. #endif
  317. mpi[LWS_GENCRYPTO_EC_KEYEL_X],
  318. mpi[LWS_GENCRYPTO_EC_KEYEL_Y],
  319. NULL) != 1) {
  320. BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
  321. BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
  322. lwsl_err("%s: EC_POINT_get_aff failed\n", __func__);
  323. goto bail2;
  324. }
  325. count = LWS_GENCRYPTO_EC_KEYEL_COUNT;
  326. n = LWS_GENCRYPTO_EC_KEYEL_X;
  327. break;
  328. case NID_rsaEncryption:
  329. lwsl_debug("%s: rsa key\n", __func__);
  330. jwk->kty = LWS_GENCRYPTO_KTY_RSA;
  331. rsapub = EVP_PKEY_get1_RSA(pkey);
  332. if (!rsapub) {
  333. lwsl_notice("%s: missing RSA pubkey\n", __func__);
  334. goto bail1;
  335. }
  336. if ((size_t)RSA_size(rsapub) * 8 < (size_t)rsa_min_bits) {
  337. lwsl_err("%s: key bits %d less than minimum %d\n",
  338. __func__, RSA_size(rsapub) * 8, rsa_min_bits);
  339. goto bail2;
  340. }
  341. #if defined(LWS_HAVE_RSA_SET0_KEY)
  342. /* we don't need d... but the api wants to write it */
  343. RSA_get0_key(rsapub,
  344. (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_N],
  345. (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_E],
  346. (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_D]);
  347. #else
  348. mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = rsapub->e;
  349. mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = rsapub->n;
  350. mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = NULL;
  351. #endif
  352. count = LWS_GENCRYPTO_RSA_KEYEL_D;
  353. n = LWS_GENCRYPTO_RSA_KEYEL_E;
  354. break;
  355. default:
  356. lwsl_err("%s: unknown NID\n", __func__);
  357. goto bail2;
  358. }
  359. for (; n < count; n++) {
  360. if (!mpi[n])
  361. continue;
  362. jwk->e[n].len = BN_num_bytes(mpi[n]);
  363. jwk->e[n].buf = lws_malloc(jwk->e[n].len, "certkeyimp");
  364. if (!jwk->e[n].buf) {
  365. if (id == NID_X9_62_id_ecPublicKey) {
  366. BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
  367. BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
  368. }
  369. goto bail2;
  370. }
  371. BN_bn2bin(mpi[n], jwk->e[n].buf);
  372. }
  373. if (id == NID_X9_62_id_ecPublicKey) {
  374. BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]);
  375. BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]);
  376. }
  377. ret = 0;
  378. bail2:
  379. if (id == NID_X9_62_id_ecPublicKey)
  380. EC_KEY_free(ecpub);
  381. else
  382. RSA_free(rsapub);
  383. bail1:
  384. EVP_PKEY_free(pkey);
  385. bail:
  386. /* jwk destroy will clean any partial state */
  387. if (ret)
  388. lws_jwk_destroy(jwk);
  389. return ret;
  390. }
  391. static int
  392. lws_x509_jwk_privkey_pem_pp_cb(char *buf, int size, int rwflag, void *u)
  393. {
  394. const char *pp = (const char *)u;
  395. int n = (int)strlen(pp);
  396. if (n > size - 1)
  397. return -1;
  398. memcpy(buf, pp, n + 1);
  399. return n;
  400. }
  401. int
  402. lws_x509_jwk_privkey_pem(struct lws_jwk *jwk, void *pem, size_t len,
  403. const char *passphrase)
  404. {
  405. BIO* bio = BIO_new(BIO_s_mem());
  406. BIGNUM *mpi, *dummy[6];
  407. EVP_PKEY *pkey = NULL;
  408. EC_KEY *ecpriv = NULL;
  409. RSA *rsapriv = NULL;
  410. const BIGNUM *cmpi;
  411. int n, m, ret = -1;
  412. BIO_write(bio, pem, (int)len);
  413. PEM_read_bio_PrivateKey(bio, &pkey, lws_x509_jwk_privkey_pem_pp_cb,
  414. (void *)passphrase);
  415. BIO_free(bio);
  416. lws_explicit_bzero((void *)pem, len);
  417. if (!pkey) {
  418. lwsl_err("%s: unable to parse PEM privkey\n", __func__);
  419. lws_tls_err_describe_clear();
  420. return -1;
  421. }
  422. /* confirm the key type matches the existing jwk situation */
  423. switch (jwk->kty) {
  424. case LWS_GENCRYPTO_KTY_EC:
  425. if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) {
  426. lwsl_err("%s: jwk is EC but privkey isn't\n", __func__);
  427. goto bail;
  428. }
  429. ecpriv = EVP_PKEY_get1_EC_KEY(pkey);
  430. if (!ecpriv) {
  431. lwsl_notice("%s: missing EC key\n", __func__);
  432. goto bail;
  433. }
  434. cmpi = EC_KEY_get0_private_key(ecpriv);
  435. /* quick size check first */
  436. n = BN_num_bytes(cmpi);
  437. if (jwk->e[LWS_GENCRYPTO_EC_KEYEL_Y].len != (uint32_t)n) {
  438. lwsl_err("%s: jwk key size doesn't match\n", __func__);
  439. goto bail1;
  440. }
  441. /* TODO.. check public curve / group + point */
  442. jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len = n;
  443. jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf = lws_malloc(n, "ec");
  444. if (!jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf)
  445. goto bail1;
  446. m = BN_bn2binpad(cmpi, jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf,
  447. jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len);
  448. if ((unsigned int)m != (unsigned int)BN_num_bytes(cmpi))
  449. goto bail1;
  450. break;
  451. case LWS_GENCRYPTO_KTY_RSA:
  452. if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_RSA) {
  453. lwsl_err("%s: RSA jwk, non-RSA privkey\n", __func__);
  454. goto bail;
  455. }
  456. rsapriv = EVP_PKEY_get1_RSA(pkey);
  457. if (!rsapriv) {
  458. lwsl_notice("%s: missing RSA key\n", __func__);
  459. goto bail;
  460. }
  461. #if defined(LWS_HAVE_RSA_SET0_KEY)
  462. RSA_get0_key(rsapriv, (const BIGNUM **)&dummy[0], /* n */
  463. (const BIGNUM **)&dummy[1], /* e */
  464. (const BIGNUM **)&mpi); /* d */
  465. RSA_get0_factors(rsapriv, (const BIGNUM **)&dummy[4], /* p */
  466. (const BIGNUM **)&dummy[5]); /* q */
  467. #else
  468. dummy[0] = rsapriv->n;
  469. dummy[1] = rsapriv->e;
  470. dummy[4] = rsapriv->p;
  471. dummy[5] = rsapriv->q;
  472. mpi = rsapriv->d;
  473. #endif
  474. /* quick size check first */
  475. n = BN_num_bytes(mpi);
  476. if (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len != (uint32_t)n) {
  477. lwsl_err("%s: jwk key size doesn't match\n", __func__);
  478. goto bail1;
  479. }
  480. /* then check that n & e match what we got from the cert */
  481. dummy[2] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].buf,
  482. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len,
  483. NULL);
  484. dummy[3] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].buf,
  485. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].len,
  486. NULL);
  487. m = BN_cmp(dummy[2], dummy[0]) | BN_cmp(dummy[3], dummy[1]);
  488. BN_clear_free(dummy[2]);
  489. BN_clear_free(dummy[3]);
  490. if (m) {
  491. lwsl_err("%s: privkey doesn't match jwk pubkey\n",
  492. __func__);
  493. goto bail1;
  494. }
  495. /* accept d from the PEM privkey into the JWK */
  496. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].len = n;
  497. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf = lws_malloc(n, "privjk");
  498. if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf)
  499. goto bail1;
  500. BN_bn2bin(mpi, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
  501. /* accept p and q from the PEM privkey into the JWK */
  502. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].len = BN_num_bytes(dummy[4]);
  503. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf = lws_malloc(n, "privjk");
  504. if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf) {
  505. lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
  506. goto bail1;
  507. }
  508. BN_bn2bin(dummy[4], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf);
  509. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].len = BN_num_bytes(dummy[5]);
  510. jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf = lws_malloc(n, "privjk");
  511. if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf) {
  512. lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf);
  513. lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf);
  514. goto bail1;
  515. }
  516. BN_bn2bin(dummy[5], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf);
  517. break;
  518. default:
  519. lwsl_err("%s: JWK has unknown kty %d\n", __func__, jwk->kty);
  520. return -1;
  521. }
  522. ret = 0;
  523. bail1:
  524. if (jwk->kty == LWS_GENCRYPTO_KTY_EC)
  525. EC_KEY_free(ecpriv);
  526. else
  527. RSA_free(rsapriv);
  528. bail:
  529. EVP_PKEY_free(pkey);
  530. return ret;
  531. }
  532. #endif
  533. void
  534. lws_x509_destroy(struct lws_x509_cert **x509)
  535. {
  536. if (!*x509)
  537. return;
  538. if ((*x509)->cert) {
  539. X509_free((*x509)->cert);
  540. (*x509)->cert = NULL;
  541. }
  542. lws_free_set_NULL(*x509);
  543. }