| 464 | } |
| 465 | |
| 466 | bool encodeEcKey(rapidjson::Writer<rapidjson::StringBuffer>& writer, |
| 467 | StringRef keyName, |
| 468 | EVP_PKEY* pKey, |
| 469 | const bool isPublic) { |
| 470 | auto arena = Arena(); |
| 471 | writer.StartObject(); |
| 472 | writer.Key("kty"); |
| 473 | writer.String("EC"); |
| 474 | writer.Key("alg"); |
| 475 | writer.String("ES256"); |
| 476 | writer.Key("kid"); |
| 477 | writer.String(reinterpret_cast<char const*>(keyName.begin()), keyName.size()); |
| 478 | #if USE_V3_API |
| 479 | auto curveNameBuf = std::array<char, 64>{}; |
| 480 | auto curveNameLen = 0ul; |
| 481 | if (1 != EVP_PKEY_get_utf8_string_param( |
| 482 | pKey, OSSL_PKEY_PARAM_GROUP_NAME, curveNameBuf.begin(), sizeof(curveNameBuf), &curveNameLen)) { |
| 483 | JWK_WRITE_ERROR_OSSL("Get group name from EC PKey"); |
| 484 | return false; |
| 485 | } |
| 486 | auto curveName = std::string_view(curveNameBuf.cbegin(), curveNameLen); |
| 487 | if (curveName != std::string_view("prime256v1")) { |
| 488 | JWK_WRITE_ERROR("Unsupported EC curve").detail("CurveName", curveName); |
| 489 | return false; |
| 490 | } |
| 491 | writer.Key("crv"); |
| 492 | writer.String("P-256"); |
| 493 | #define JWK_WRITE_BN_EC_PARAM(x, param) \ |
| 494 | do { \ |
| 495 | auto x = AutoCPointer(nullptr, &::BN_clear_free); \ |
| 496 | auto rawX = std::add_pointer_t<BIGNUM>(); \ |
| 497 | if (1 != ::EVP_PKEY_get_bn_param(pKey, param, &rawX)) { \ |
| 498 | JWK_WRITE_ERROR_OSSL("EVP_PKEY_get_bn_param(" #param ")"); \ |
| 499 | return false; \ |
| 500 | } \ |
| 501 | x.reset(rawX); \ |
| 502 | auto b64##x = bigNumToBase64Url(arena, x); \ |
| 503 | writer.Key(#x); \ |
| 504 | writer.String(reinterpret_cast<char const*>(b64##x.begin()), b64##x.size()); \ |
| 505 | } while (0) |
| 506 | // Get and write affine coordinates, X and Y |
| 507 | JWK_WRITE_BN_EC_PARAM(x, OSSL_PKEY_PARAM_EC_PUB_X); |
| 508 | JWK_WRITE_BN_EC_PARAM(y, OSSL_PKEY_PARAM_EC_PUB_Y); |
| 509 | if (!isPublic) { |
| 510 | JWK_WRITE_BN_EC_PARAM(d, OSSL_PKEY_PARAM_PRIV_KEY); |
| 511 | } |
| 512 | #undef JWK_WRITE_BN_EC_PARAM |
| 513 | #else // USE_V3_API |
| 514 | auto ecKey = ::EVP_PKEY_get0_EC_KEY(pKey); // get0 == no refcount, no need to free |
| 515 | if (!ecKey) { |
| 516 | JWK_WRITE_ERROR_OSSL("Could not extract EC_KEY from EVP_PKEY"); |
| 517 | return false; |
| 518 | } |
| 519 | auto group = ::EC_KEY_get0_group(ecKey); |
| 520 | if (!group) { |
| 521 | JWK_WRITE_ERROR("Could not get EC_GROUP from EVP_PKEY"); |
| 522 | return false; |
| 523 | } |
no test coverage detected