| 579 | } |
| 580 | |
| 581 | bool encodeRsaKey(rapidjson::Writer<rapidjson::StringBuffer>& writer, |
| 582 | StringRef keyName, |
| 583 | EVP_PKEY* pKey, |
| 584 | const bool isPublic) { |
| 585 | auto arena = Arena(); |
| 586 | writer.StartObject(); |
| 587 | writer.Key("kty"); |
| 588 | writer.String("RSA"); |
| 589 | writer.Key("alg"); |
| 590 | writer.String("RS256"); |
| 591 | writer.Key("kid"); |
| 592 | writer.String(reinterpret_cast<char const*>(keyName.begin()), keyName.size()); |
| 593 | #if USE_V3_API |
| 594 | #define JWK_WRITE_BN_RSA_PARAM_V3(x, param) \ |
| 595 | do { \ |
| 596 | auto x = AutoCPointer(nullptr, &::BN_clear_free); \ |
| 597 | auto rawX = std::add_pointer_t<BIGNUM>(); \ |
| 598 | if (1 != ::EVP_PKEY_get_bn_param(pKey, param, &rawX)) { \ |
| 599 | JWK_WRITE_ERROR_OSSL("EVP_PKEY_get_bn_param(" #x ")"); \ |
| 600 | return false; \ |
| 601 | } \ |
| 602 | x.reset(rawX); \ |
| 603 | auto b64##x = bigNumToBase64Url(arena, x); \ |
| 604 | writer.Key(#x); \ |
| 605 | writer.String(reinterpret_cast<char const*>(b64##x.begin()), b64##x.size()); \ |
| 606 | } while (0) |
| 607 | JWK_WRITE_BN_RSA_PARAM_V3(n, OSSL_PKEY_PARAM_RSA_N); |
| 608 | JWK_WRITE_BN_RSA_PARAM_V3(e, OSSL_PKEY_PARAM_RSA_E); |
| 609 | if (!isPublic) { |
| 610 | JWK_WRITE_BN_RSA_PARAM_V3(d, OSSL_PKEY_PARAM_RSA_D); |
| 611 | JWK_WRITE_BN_RSA_PARAM_V3(p, OSSL_PKEY_PARAM_RSA_FACTOR1); |
| 612 | JWK_WRITE_BN_RSA_PARAM_V3(q, OSSL_PKEY_PARAM_RSA_FACTOR2); |
| 613 | JWK_WRITE_BN_RSA_PARAM_V3(dp, OSSL_PKEY_PARAM_RSA_EXPONENT1); |
| 614 | JWK_WRITE_BN_RSA_PARAM_V3(dq, OSSL_PKEY_PARAM_RSA_EXPONENT2); |
| 615 | JWK_WRITE_BN_RSA_PARAM_V3(qi, OSSL_PKEY_PARAM_RSA_COEFFICIENT1); |
| 616 | } |
| 617 | #undef JWK_WRITE_BN_RSA_PARAM_V3 |
| 618 | #else // USE_V3_API |
| 619 | #define JWK_WRITE_BN_RSA_PARAM_V1(x) \ |
| 620 | do { \ |
| 621 | if (!x) { \ |
| 622 | JWK_WRITE_ERROR_OSSL("RSA_get0_* returned null " #x); \ |
| 623 | return false; \ |
| 624 | } \ |
| 625 | auto b64##x = bigNumToBase64Url(arena, x); \ |
| 626 | writer.Key(#x); \ |
| 627 | writer.String(reinterpret_cast<char const*>(b64##x.begin()), b64##x.size()); \ |
| 628 | } while (0) |
| 629 | auto rsaKey = ::EVP_PKEY_get0_RSA(pKey); // get0 == no refcount, no need to free |
| 630 | if (!rsaKey) { |
| 631 | JWK_WRITE_ERROR_OSSL("Could not extract RSA key from EVP_PKEY"); |
| 632 | return false; |
| 633 | } |
| 634 | auto n = std::add_pointer_t<const BIGNUM>(); |
| 635 | auto e = std::add_pointer_t<const BIGNUM>(); |
| 636 | auto d = std::add_pointer_t<const BIGNUM>(); |
| 637 | auto p = std::add_pointer_t<const BIGNUM>(); |
| 638 | auto q = std::add_pointer_t<const BIGNUM>(); |