1/* 2 * libwebsockets - small server side websockets and web server implementation 3 * 4 * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> 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 25#define WIN32_LEAN_AND_MEAN 26#include "private-lib-core.h" 27#include "private-lib-tls-openssl.h" 28 29#if !defined(LWS_PLAT_OPTEE) 30static int 31dec(char c) 32{ 33 return c - '0'; 34} 35#endif 36 37static time_t 38lws_tls_openssl_asn1time_to_unix(ASN1_TIME *as) 39{ 40#if !defined(LWS_PLAT_OPTEE) 41 42 const char *p = (const char *)as->data; 43 struct tm t; 44 45 /* [YY]YYMMDDHHMMSSZ */ 46 47 memset(&t, 0, sizeof(t)); 48 49 if (strlen(p) == 13) { 50 t.tm_year = (dec(p[0]) * 10) + dec(p[1]) + 100; 51 p += 2; 52 } else { 53 t.tm_year = (dec(p[0]) * 1000) + (dec(p[1]) * 100) + 54 (dec(p[2]) * 10) + dec(p[3]); 55 p += 4; 56 } 57 t.tm_mon = (dec(p[0]) * 10) + dec(p[1]) - 1; 58 p += 2; 59 t.tm_mday = (dec(p[0]) * 10) + dec(p[1]) - 1; 60 p += 2; 61 t.tm_hour = (dec(p[0]) * 10) + dec(p[1]); 62 p += 2; 63 t.tm_min = (dec(p[0]) * 10) + dec(p[1]); 64 p += 2; 65 t.tm_sec = (dec(p[0]) * 10) + dec(p[1]); 66 t.tm_isdst = 0; 67 68 return mktime(&t); 69#else 70 return (time_t)-1; 71#endif 72} 73 74#if defined(USE_WOLFSSL) 75#define AUTHORITY_KEYID WOLFSSL_AUTHORITY_KEYID 76#endif 77 78int 79lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type, 80 union lws_tls_cert_info_results *buf, size_t len) 81{ 82#ifndef USE_WOLFSSL 83 const unsigned char *dp; 84 ASN1_OCTET_STRING *val; 85 AUTHORITY_KEYID *akid; 86 X509_EXTENSION *ext; 87 int tag, xclass, r = 1; 88 long xlen, loc; 89#endif 90 X509_NAME *xn; 91#if !defined(LWS_PLAT_OPTEE) 92 char *p; 93#endif 94 95 buf->ns.len = 0; 96 97 if (!x509) 98 return -1; 99 if (!len) 100 len = sizeof(buf->ns.name); 101 102#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(X509_get_notBefore) 103#define X509_get_notBefore(x) X509_getm_notBefore(x) 104#define X509_get_notAfter(x) X509_getm_notAfter(x) 105#endif 106 107 switch (type) { 108 case LWS_TLS_CERT_INFO_VALIDITY_FROM: 109 buf->time = lws_tls_openssl_asn1time_to_unix( 110 X509_get_notBefore(x509)); 111 if (buf->time == (time_t)-1) 112 return -1; 113 break; 114 115 case LWS_TLS_CERT_INFO_VALIDITY_TO: 116 buf->time = lws_tls_openssl_asn1time_to_unix( 117 X509_get_notAfter(x509)); 118 if (buf->time == (time_t)-1) 119 return -1; 120 break; 121 122 case LWS_TLS_CERT_INFO_COMMON_NAME: 123#if defined(LWS_PLAT_OPTEE) 124 return -1; 125#else 126 xn = X509_get_subject_name(x509); 127 if (!xn) 128 return -1; 129 X509_NAME_oneline(xn, buf->ns.name, (int)len - 2); 130 p = strstr(buf->ns.name, "/CN="); 131 if (p) 132 memmove(buf->ns.name, p + 4, strlen(p + 4) + 1); 133 buf->ns.len = (int)strlen(buf->ns.name); 134 return 0; 135#endif 136 case LWS_TLS_CERT_INFO_ISSUER_NAME: 137 xn = X509_get_issuer_name(x509); 138 if (!xn) 139 return -1; 140 X509_NAME_oneline(xn, buf->ns.name, (int)len - 1); 141 buf->ns.len = (int)strlen(buf->ns.name); 142 return 0; 143 144 case LWS_TLS_CERT_INFO_USAGE: 145#if defined(LWS_HAVE_X509_get_key_usage) 146 buf->usage = X509_get_key_usage(x509); 147 break; 148#else 149 return -1; 150#endif 151 152 case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY: 153 { 154#ifndef USE_WOLFSSL 155 size_t klen = (unsigned int)i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x509), NULL); 156 uint8_t *tmp, *ptmp; 157 158 if (!klen || klen > len) 159 return -1; 160 161 tmp = (uint8_t *)OPENSSL_malloc(klen); 162 if (!tmp) 163 return -1; 164 165 ptmp = tmp; 166 if (i2d_X509_PUBKEY( 167 X509_get_X509_PUBKEY(x509), &ptmp) != (int)klen || 168 !ptmp || lws_ptr_diff(ptmp, tmp) != (int)klen) { 169 lwsl_info("%s: cert public key extraction failed\n", 170 __func__); 171 if (ptmp) 172 OPENSSL_free(tmp); 173 174 return -1; 175 } 176 177 buf->ns.len = (int)klen; 178 memcpy(buf->ns.name, tmp, klen); 179 OPENSSL_free(tmp); 180#endif 181 return 0; 182 } 183 case LWS_TLS_CERT_INFO_DER_RAW: 184 { 185 int der_len = i2d_X509(x509, NULL); 186 uint8_t *tmp = (uint8_t *)buf->ns.name; 187 188 buf->ns.len = der_len < 0 ? 0 : der_len; 189 190 if (der_len < 0 || (size_t)der_len > len) 191 return -1; 192 193 der_len = i2d_X509(x509, &tmp); 194 if (der_len < 0) 195 return -1; 196 197 return 0; 198 } 199 200#ifndef USE_WOLFSSL 201 202 case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID: 203 loc = X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1); 204 if (loc < 0) 205 return 1; 206 207 ext = X509_get_ext(x509, (int)loc); 208 if (!ext) 209 return 1; 210#ifndef USE_WOLFSSL 211 akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext); 212#else 213 akid = (AUTHORITY_KEYID *)wolfSSL_X509V3_EXT_d2i(ext); 214#endif 215 if (!akid || !akid->keyid) 216 return 1; 217 val = akid->keyid; 218 dp = (const unsigned char *)val->data; 219 xlen = val->length; 220 221 buf->ns.len = (int)xlen; 222 if (len < (size_t)buf->ns.len) 223 return -1; 224 225 memcpy(buf->ns.name, dp, (size_t)buf->ns.len); 226 227 AUTHORITY_KEYID_free(akid); 228 break; 229 230 case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_ISSUER: 231 loc = X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1); 232 if (loc < 0) 233 return 1; 234 235 ext = X509_get_ext(x509, (int)loc); 236 if (!ext) 237 return 1; 238 239#ifndef USE_WOLFSSL 240 akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext); 241#else 242 akid = (AUTHORITY_KEYID *)wolfSSL_X509V3_EXT_d2i(ext); 243#endif 244 if (!akid || !akid->issuer) 245 return 1; 246 247#if defined(LWS_HAVE_OPENSSL_STACK) 248 { 249 const X509V3_EXT_METHOD* method = X509V3_EXT_get(ext); 250 STACK_OF(CONF_VALUE) *cv; 251 int j; 252 253 cv = i2v_GENERAL_NAMES((X509V3_EXT_METHOD*)method, akid->issuer, NULL); 254 if (!cv) 255 goto bail_ak; 256 257 for (j = 0; j < OPENSSL_sk_num((const OPENSSL_STACK *)&cv); j++) { 258 CONF_VALUE *nval = OPENSSL_sk_value((const OPENSSL_STACK *)&cv, j); 259 size_t ln = (nval->name ? strlen(nval->name) : 0), 260 lv = (nval->value ? strlen(nval->value) : 0), 261 l = ln + lv; 262 263 if (len > l) { 264 if (nval->name) 265 memcpy(buf->ns.name + buf->ns.len, nval->name, ln); 266 if (nval->value) 267 memcpy(buf->ns.name + buf->ns.len + ln, nval->value, lv); 268 buf->ns.len = (int)((size_t)buf->ns.len + l); 269 len -= l; 270 buf->ns.name[buf->ns.len] = '\0'; 271 272 r = 0; 273 } 274 } 275 } 276 277bail_ak: 278#endif 279 AUTHORITY_KEYID_free(akid); 280 281 return r; 282 283 case LWS_TLS_CERT_INFO_AUTHORITY_KEY_ID_SERIAL: 284 loc = X509_get_ext_by_NID(x509, NID_authority_key_identifier, -1); 285 if (loc < 0) 286 return 1; 287 288 ext = X509_get_ext(x509, (int)loc); 289 if (!ext) 290 return 1; 291 akid = (AUTHORITY_KEYID *)X509V3_EXT_d2i(ext); 292 if (!akid || !akid->serial) 293 return 1; 294 295#if 0 296 // need to handle blobs, and ASN1_INTEGER_get_uint64 not 297 // available on older openssl 298 { 299 uint64_t res; 300 if (ASN1_INTEGER_get_uint64(&res, akid->serial) != 1) 301 break; 302 buf->ns.len = lws_snprintf(buf->ns.name, len, "%llu", 303 (unsigned long long)res); 304 } 305#endif 306 break; 307 308 case LWS_TLS_CERT_INFO_SUBJECT_KEY_ID: 309 310 loc = X509_get_ext_by_NID(x509, NID_subject_key_identifier, -1); 311 if (loc < 0) 312 return 1; 313 314 ext = X509_get_ext(x509, (int)loc); 315 if (!ext) 316 return 1; 317 318 val = X509_EXTENSION_get_data(ext); 319 if (!val) 320 return 1; 321 322#if defined(USE_WOLFSSL) 323 return 1; 324#else 325 dp = (const unsigned char *)val->data; 326 327 if (ASN1_get_object(&dp, &xlen, 328 &tag, &xclass, val->length) & 0x80) 329 return -1; 330 331 if (tag != V_ASN1_OCTET_STRING) { 332 lwsl_notice("not octet string %d\n", (int)tag); 333 return 1; 334 } 335#endif 336 buf->ns.len = (int)xlen; 337 if (len < (size_t)buf->ns.len) 338 return -1; 339 340 memcpy(buf->ns.name, dp, (size_t)buf->ns.len); 341 break; 342#endif 343 344 default: 345 return -1; 346 } 347 348 return 0; 349} 350 351int 352lws_x509_info(struct lws_x509_cert *x509, enum lws_tls_cert_info type, 353 union lws_tls_cert_info_results *buf, size_t len) 354{ 355 return lws_tls_openssl_cert_info(x509->cert, type, buf, len); 356} 357 358#if defined(LWS_WITH_NETWORK) 359int 360lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type, 361 union lws_tls_cert_info_results *buf, size_t len) 362{ 363#if defined(LWS_HAVE_SSL_CTX_get0_certificate) 364 X509 *x509 = SSL_CTX_get0_certificate(vhost->tls.ssl_ctx); 365 366 return lws_tls_openssl_cert_info(x509, type, buf, len); 367#else 368 lwsl_notice("openssl is too old to support %s\n", __func__); 369 370 return -1; 371#endif 372} 373 374 375 376int 377lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type, 378 union lws_tls_cert_info_results *buf, size_t len) 379{ 380 int rc = 0; 381 X509 *x509; 382 383 wsi = lws_get_network_wsi(wsi); 384 385 x509 = SSL_get_peer_certificate(wsi->tls.ssl); 386 387 if (!x509) { 388 lwsl_debug("no peer cert\n"); 389 390 return -1; 391 } 392 393 switch (type) { 394 case LWS_TLS_CERT_INFO_VERIFIED: 395 buf->verified = SSL_get_verify_result(wsi->tls.ssl) == 396 X509_V_OK; 397 break; 398 default: 399 rc = lws_tls_openssl_cert_info(x509, type, buf, len); 400 } 401 402 X509_free(x509); 403 404 return rc; 405} 406#endif 407 408int 409lws_x509_create(struct lws_x509_cert **x509) 410{ 411 *x509 = lws_malloc(sizeof(**x509), __func__); 412 if (*x509) 413 (*x509)->cert = NULL; 414 415 return !(*x509); 416} 417 418int 419lws_x509_parse_from_pem(struct lws_x509_cert *x509, const void *pem, size_t len) 420{ 421 BIO* bio = BIO_new(BIO_s_mem()); 422 423 BIO_write(bio, pem, (int)len); 424 x509->cert = PEM_read_bio_X509(bio, NULL, NULL, NULL); 425 BIO_free(bio); 426 if (!x509->cert) { 427 lwsl_err("%s: unable to parse PEM cert\n", __func__); 428 lws_tls_err_describe_clear(); 429 430 return -1; 431 } 432 433 return 0; 434} 435 436int 437lws_x509_verify(struct lws_x509_cert *x509, struct lws_x509_cert *trusted, 438 const char *common_name) 439{ 440 char c[32], *p; 441 int ret; 442 443 if (common_name) { 444 X509_NAME *xn = X509_get_subject_name(x509->cert); 445 if (!xn) 446 return -1; 447 X509_NAME_oneline(xn, c, (int)sizeof(c) - 2); 448 p = strstr(c, "/CN="); 449 if (p) 450 p = p + 4; 451 else 452 p = c; 453 454 if (strcmp(p, common_name)) { 455 lwsl_err("%s: common name mismatch\n", __func__); 456 return -1; 457 } 458 } 459 460 ret = X509_check_issued(trusted->cert, x509->cert); 461 if (ret != X509_V_OK) { 462 lwsl_err("%s: unable to verify cert relationship\n", __func__); 463 lws_tls_err_describe_clear(); 464 465 return -1; 466 } 467 468 return 0; 469} 470 471#if defined(LWS_WITH_JOSE) 472int 473lws_x509_public_to_jwk(struct lws_jwk *jwk, struct lws_x509_cert *x509, 474 const char *curves, int rsa_min_bits) 475{ 476 int id, n, ret = -1, count; 477 ASN1_OBJECT *obj = NULL; 478 const EC_POINT *ecpoint; 479 const EC_GROUP *ecgroup; 480 EC_KEY *ecpub = NULL; 481 X509_PUBKEY *pubkey; 482 RSA *rsapub = NULL; 483 BIGNUM *mpi[4]; 484 EVP_PKEY *pkey; 485 486 memset(jwk, 0, sizeof(*jwk)); 487 488 pubkey = X509_get_X509_PUBKEY(x509->cert); 489 if (!pubkey) { 490 lwsl_err("%s: missing pubkey alg in cert\n", __func__); 491 492 goto bail; 493 } 494 495 if (X509_PUBKEY_get0_param(&obj, NULL, NULL, NULL, pubkey) != 1) { 496 lwsl_err("%s: missing pubkey alg in cert\n", __func__); 497 498 goto bail; 499 } 500 501 id = OBJ_obj2nid(obj); 502 if (id == NID_undef) { 503 lwsl_err("%s: missing pubkey alg in cert\n", __func__); 504 505 goto bail; 506 } 507 508 lwsl_debug("%s: key type %d \"%s\"\n", __func__, id, OBJ_nid2ln(id)); 509 510 pkey = X509_get_pubkey(x509->cert); 511 if (!pkey) { 512 lwsl_notice("%s: unable to extract pubkey", __func__); 513 514 goto bail; 515 } 516 517 switch (id) { 518 case NID_X9_62_id_ecPublicKey: 519 lwsl_debug("%s: EC key\n", __func__); 520 jwk->kty = LWS_GENCRYPTO_KTY_EC; 521 522 if (!curves) { 523 lwsl_err("%s: ec curves not allowed\n", __func__); 524 525 goto bail1; 526 } 527 528 ecpub = EVP_PKEY_get1_EC_KEY(pkey); 529 if (!ecpub) { 530 lwsl_notice("%s: missing EC pubkey\n", __func__); 531 532 goto bail1; 533 } 534 535 ecpoint = EC_KEY_get0_public_key(ecpub); 536 if (!ecpoint) { 537 lwsl_err("%s: EC_KEY_get0_public_key failed\n", __func__); 538 goto bail2; 539 } 540 541 ecgroup = EC_KEY_get0_group(ecpub); 542 if (!ecgroup) { 543 lwsl_err("%s: EC_KEY_get0_group failed\n", __func__); 544 goto bail2; 545 } 546 547 /* validate the curve against ones we allow */ 548 549 if (lws_genec_confirm_curve_allowed_by_tls_id(curves, 550 EC_GROUP_get_curve_name(ecgroup), jwk)) 551 /* already logged */ 552 goto bail2; 553 554 mpi[LWS_GENCRYPTO_EC_KEYEL_CRV] = NULL; 555 mpi[LWS_GENCRYPTO_EC_KEYEL_X] = BN_new(); /* X */ 556 mpi[LWS_GENCRYPTO_EC_KEYEL_D] = NULL; 557 mpi[LWS_GENCRYPTO_EC_KEYEL_Y] = BN_new(); /* Y */ 558 559#if defined(LWS_HAVE_EC_POINT_get_affine_coordinates) 560 if (EC_POINT_get_affine_coordinates(ecgroup, ecpoint, 561#else 562 if (EC_POINT_get_affine_coordinates_GFp(ecgroup, ecpoint, 563#endif 564 mpi[LWS_GENCRYPTO_EC_KEYEL_X], 565 mpi[LWS_GENCRYPTO_EC_KEYEL_Y], 566 NULL) != 1) { 567 BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]); 568 BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]); 569 lwsl_err("%s: EC_POINT_get_aff failed\n", __func__); 570 goto bail2; 571 } 572 count = LWS_GENCRYPTO_EC_KEYEL_COUNT; 573 n = LWS_GENCRYPTO_EC_KEYEL_X; 574 break; 575 576 case NID_rsaEncryption: 577 lwsl_debug("%s: rsa key\n", __func__); 578 jwk->kty = LWS_GENCRYPTO_KTY_RSA; 579 580 rsapub = EVP_PKEY_get1_RSA(pkey); 581 if (!rsapub) { 582 lwsl_notice("%s: missing RSA pubkey\n", __func__); 583 584 goto bail1; 585 } 586 587 if ((size_t)RSA_size(rsapub) * 8 < (size_t)rsa_min_bits) { 588 lwsl_err("%s: key bits %d less than minimum %d\n", 589 __func__, RSA_size(rsapub) * 8, rsa_min_bits); 590 591 goto bail2; 592 } 593 594#if defined(LWS_HAVE_RSA_SET0_KEY) 595 /* we don't need d... but the api wants to write it */ 596 RSA_get0_key(rsapub, 597 (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_N], 598 (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_E], 599 (const BIGNUM **)&mpi[LWS_GENCRYPTO_RSA_KEYEL_D]); 600#else 601 mpi[LWS_GENCRYPTO_RSA_KEYEL_E] = rsapub->e; 602 mpi[LWS_GENCRYPTO_RSA_KEYEL_N] = rsapub->n; 603 mpi[LWS_GENCRYPTO_RSA_KEYEL_D] = NULL; 604#endif 605 count = LWS_GENCRYPTO_RSA_KEYEL_D; 606 n = LWS_GENCRYPTO_RSA_KEYEL_E; 607 break; 608 default: 609 lwsl_err("%s: unknown NID\n", __func__); 610 goto bail2; 611 } 612 613 for (; n < count; n++) { 614 if (!mpi[n]) 615 continue; 616 jwk->e[n].len = (unsigned int)BN_num_bytes(mpi[n]); 617 jwk->e[n].buf = lws_malloc(jwk->e[n].len, "certkeyimp"); 618 if (!jwk->e[n].buf) { 619 if (id == NID_X9_62_id_ecPublicKey) { 620 BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]); 621 BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]); 622 } 623 goto bail2; 624 } 625 BN_bn2bin(mpi[n], jwk->e[n].buf); 626 } 627 628 if (id == NID_X9_62_id_ecPublicKey) { 629 BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_X]); 630 BN_clear_free(mpi[LWS_GENCRYPTO_EC_KEYEL_Y]); 631 } 632 633 ret = 0; 634 635bail2: 636 if (id == NID_X9_62_id_ecPublicKey) 637 EC_KEY_free(ecpub); 638 else 639 RSA_free(rsapub); 640 641bail1: 642 EVP_PKEY_free(pkey); 643bail: 644 /* jwk destroy will clean any partial state */ 645 if (ret) 646 lws_jwk_destroy(jwk); 647 648 return ret; 649} 650 651static int 652lws_x509_jwk_privkey_pem_pp_cb(char *buf, int size, int rwflag, void *u) 653{ 654 const char *pp = (const char *)u; 655 size_t n = strlen(pp); 656 657 if ((int)n > size - 1) 658 return -1; 659 660 memcpy(buf, pp, n + 1); 661 662 return (int)n; 663} 664 665int 666lws_x509_jwk_privkey_pem(struct lws_context *cx, struct lws_jwk *jwk, 667 void *pem, size_t len, const char *passphrase) 668{ 669 BIO* bio = BIO_new(BIO_s_mem()); 670 BIGNUM *mpi, *dummy[6]; 671 EVP_PKEY *pkey = NULL; 672 EC_KEY *ecpriv = NULL; 673 RSA *rsapriv = NULL; 674 const BIGNUM *cmpi; 675 int n, m, ret = -1; 676 677 BIO_write(bio, pem, (int)len); 678 PEM_read_bio_PrivateKey(bio, &pkey, lws_x509_jwk_privkey_pem_pp_cb, 679 (void *)passphrase); 680 BIO_free(bio); 681 lws_explicit_bzero((void *)pem, len); 682 if (!pkey) { 683 lwsl_err("%s: unable to parse PEM privkey\n", __func__); 684 lws_tls_err_describe_clear(); 685 686 return -1; 687 } 688 689 /* confirm the key type matches the existing jwk situation */ 690 691 switch (jwk->kty) { 692 case LWS_GENCRYPTO_KTY_EC: 693 if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_EC) { 694 lwsl_err("%s: jwk is EC but privkey isn't\n", __func__); 695 696 goto bail; 697 } 698 ecpriv = EVP_PKEY_get1_EC_KEY(pkey); 699 if (!ecpriv) { 700 lwsl_notice("%s: missing EC key\n", __func__); 701 702 goto bail; 703 } 704 705 cmpi = EC_KEY_get0_private_key(ecpriv); 706 707 /* quick size check first */ 708 709 n = BN_num_bytes(cmpi); 710 if (jwk->e[LWS_GENCRYPTO_EC_KEYEL_Y].len != (uint32_t)n) { 711 lwsl_err("%s: jwk key size doesn't match\n", __func__); 712 713 goto bail1; 714 } 715 716 /* TODO.. check public curve / group + point */ 717 718 jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len = (unsigned int)n; 719 jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf = lws_malloc((unsigned int)n, "ec"); 720 if (!jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf) 721 goto bail1; 722 723 m = BN_bn2binpad(cmpi, jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].buf, 724 (int32_t)jwk->e[LWS_GENCRYPTO_EC_KEYEL_D].len); 725 if ((unsigned int)m != (unsigned int)BN_num_bytes(cmpi)) 726 goto bail1; 727 728 break; 729 730 case LWS_GENCRYPTO_KTY_RSA: 731 if (EVP_PKEY_type(EVP_PKEY_id(pkey)) != EVP_PKEY_RSA) { 732 lwsl_err("%s: RSA jwk, non-RSA privkey\n", __func__); 733 734 goto bail; 735 } 736 rsapriv = EVP_PKEY_get1_RSA(pkey); 737 if (!rsapriv) { 738 lwsl_notice("%s: missing RSA key\n", __func__); 739 740 goto bail; 741 } 742 743#if defined(LWS_HAVE_RSA_SET0_KEY) && !defined(USE_WOLFSSL) 744 RSA_get0_key(rsapriv, (const BIGNUM **)&dummy[0], /* n */ 745 (const BIGNUM **)&dummy[1], /* e */ 746 (const BIGNUM **)&mpi); /* d */ 747 RSA_get0_factors(rsapriv, (const BIGNUM **)&dummy[4], /* p */ 748 (const BIGNUM **)&dummy[5]); /* q */ 749#else 750 dummy[0] = rsapriv->n; 751 dummy[1] = rsapriv->e; 752 dummy[4] = rsapriv->p; 753 dummy[5] = rsapriv->q; 754 mpi = rsapriv->d; 755#endif 756 757 /* quick size check first */ 758 759 n = BN_num_bytes(mpi); 760 if (jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len != (uint32_t)n) { 761 lwsl_err("%s: jwk key size doesn't match\n", __func__); 762 763 goto bail1; 764 } 765 766 /* then check that n & e match what we got from the cert */ 767 768 dummy[2] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].buf, 769 (int32_t)jwk->e[LWS_GENCRYPTO_RSA_KEYEL_N].len, 770 NULL); 771 dummy[3] = BN_bin2bn(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].buf, 772 (int32_t)jwk->e[LWS_GENCRYPTO_RSA_KEYEL_E].len, 773 NULL); 774 775 m = BN_cmp(dummy[2], dummy[0]) | BN_cmp(dummy[3], dummy[1]); 776 BN_clear_free(dummy[2]); 777 BN_clear_free(dummy[3]); 778 if (m) { 779 lwsl_err("%s: privkey doesn't match jwk pubkey\n", 780 __func__); 781 782 goto bail1; 783 } 784 785 /* accept d from the PEM privkey into the JWK */ 786 787 jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].len = (unsigned int)n; 788 jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf = lws_malloc((unsigned int)n, "privjk"); 789 if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf) 790 goto bail1; 791 792 BN_bn2bin(mpi, jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf); 793 794 /* accept p and q from the PEM privkey into the JWK */ 795 796 jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].len = (unsigned int)BN_num_bytes(dummy[4]); 797 jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf = lws_malloc((unsigned int)n, "privjk"); 798 if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf) { 799 lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf); 800 goto bail1; 801 } 802 BN_bn2bin(dummy[4], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf); 803 804 jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].len = (unsigned int)BN_num_bytes(dummy[5]); 805 jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf = lws_malloc((unsigned int)n, "privjk"); 806 if (!jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf) { 807 lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_D].buf); 808 lws_free_set_NULL(jwk->e[LWS_GENCRYPTO_RSA_KEYEL_P].buf); 809 goto bail1; 810 } 811 BN_bn2bin(dummy[5], jwk->e[LWS_GENCRYPTO_RSA_KEYEL_Q].buf); 812 break; 813 default: 814 lwsl_err("%s: JWK has unknown kty %d\n", __func__, jwk->kty); 815 return -1; 816 } 817 818 ret = 0; 819 820bail1: 821 if (jwk->kty == LWS_GENCRYPTO_KTY_EC) 822 EC_KEY_free(ecpriv); 823 else 824 RSA_free(rsapriv); 825 826bail: 827 EVP_PKEY_free(pkey); 828 829 return ret; 830} 831#endif 832 833void 834lws_x509_destroy(struct lws_x509_cert **x509) 835{ 836 if (!*x509) 837 return; 838 839 if ((*x509)->cert) { 840 X509_free((*x509)->cert); 841 (*x509)->cert = NULL; 842 } 843 844 lws_free_set_NULL(*x509); 845} 846