| 288 | } |
| 289 | |
| 290 | Optional<PublicOrPrivateKey> parseRsaKey(StringRef b64n, |
| 291 | StringRef b64e, |
| 292 | Optional<StringRef> b64d, |
| 293 | Optional<StringRef> b64p, |
| 294 | Optional<StringRef> b64q, |
| 295 | Optional<StringRef> b64dp, |
| 296 | Optional<StringRef> b64dq, |
| 297 | Optional<StringRef> b64qi, |
| 298 | int keyIndex) { |
| 299 | auto arena = Arena(); |
| 300 | RSA_DECLARE_DECODED_REQUIRED_BN_MEMBER(n); |
| 301 | RSA_DECLARE_DECODED_REQUIRED_BN_MEMBER(e); |
| 302 | RSA_DECLARE_DECODED_OPTIONAL_BN_MEMBER(d); |
| 303 | RSA_DECLARE_DECODED_OPTIONAL_BN_MEMBER(p); |
| 304 | RSA_DECLARE_DECODED_OPTIONAL_BN_MEMBER(q); |
| 305 | RSA_DECLARE_DECODED_OPTIONAL_BN_MEMBER(dp); |
| 306 | RSA_DECLARE_DECODED_OPTIONAL_BN_MEMBER(dq); |
| 307 | RSA_DECLARE_DECODED_OPTIONAL_BN_MEMBER(qi); |
| 308 | auto const isPublic = !d || !p || !q || !dp || !dq || !qi; |
| 309 | #if USE_V3_API |
| 310 | // avoid deprecated, algo-specific API |
| 311 | auto bld = AutoCPointer(::OSSL_PARAM_BLD_new(), &::OSSL_PARAM_BLD_free); |
| 312 | if (!bld) { |
| 313 | JWK_PARSE_ERROR_OSSL("OSSL_PARAM_BLD_new() for EC"); |
| 314 | return {}; |
| 315 | } |
| 316 | if (!::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n) || |
| 317 | !::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e)) { |
| 318 | JWK_PARSE_ERROR_OSSL("OSSL_PARAM_BLD_push_BN() for RSA (n, e)"); |
| 319 | return {}; |
| 320 | } |
| 321 | if (!isPublic) { |
| 322 | if (!::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, d) || |
| 323 | !::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR1, p) || |
| 324 | !::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_FACTOR2, q) || |
| 325 | !::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT1, dp) || |
| 326 | !::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_EXPONENT2, dq) || |
| 327 | !::OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, qi)) { |
| 328 | JWK_PARSE_ERROR_OSSL("OSSL_PARAM_BLD_push_BN() for RSA (d, p, q, dp, dq, qi)"); |
| 329 | return {}; |
| 330 | } |
| 331 | } |
| 332 | auto params = AutoCPointer(::OSSL_PARAM_BLD_to_param(bld), &::OSSL_PARAM_free); |
| 333 | if (!params) { |
| 334 | JWK_PARSE_ERROR_OSSL("OSSL_PARAM_BLD_to_param() for RSA"); |
| 335 | return {}; |
| 336 | } |
| 337 | auto pctx = AutoCPointer(::EVP_PKEY_CTX_new_from_name(nullptr, "RSA", nullptr), &::EVP_PKEY_CTX_free); |
| 338 | if (!pctx) { |
| 339 | JWK_PARSE_ERROR_OSSL("EVP_PKEY_CTX_new_from_name(RSA)"); |
| 340 | return {}; |
| 341 | } |
| 342 | if (1 != ::EVP_PKEY_fromdata_init(pctx)) { |
| 343 | JWK_PARSE_ERROR_OSSL("EVP_PKEY_fromdata_init() for RSA"); |
| 344 | return {}; |
| 345 | } |
| 346 | auto pkey = std::add_pointer_t<EVP_PKEY>(); |
| 347 | if (1 != ::EVP_PKEY_fromdata(pctx, &pkey, (!isPublic ? EVP_PKEY_KEYPAIR : EVP_PKEY_PUBLIC_KEY), params)) { |
no test coverage detected