Download JWKS from the given URL with Kudu's EasyCurl wrapper.
| 623 | |
| 624 | // Download JWKS from the given URL with Kudu's EasyCurl wrapper. |
| 625 | Status JWKSSnapshot::LoadKeysFromUrl( |
| 626 | const std::string& jwks_url, bool jwks_verify_server_certificate, uint64_t cur_jwks_checksum, |
| 627 | bool* is_changed) { |
| 628 | kudu::EasyCurl curl; |
| 629 | kudu::faststring dst; |
| 630 | *is_changed = false; |
| 631 | |
| 632 | curl.set_timeout( |
| 633 | kudu::MonoDelta::FromMilliseconds(static_cast<int64_t>(FLAGS_jwks_pulling_timeout_s) * 1000)); |
| 634 | curl.set_verify_peer(jwks_verify_server_certificate); |
| 635 | |
| 636 | // TODO support CurlAuthType by calling kudu::EasyCurl::set_auth(). |
| 637 | RETURN_NOT_OK_PREPEND(curl.FetchURL(jwks_url, &dst), |
| 638 | Substitute("Error downloading JWKS from '$0'", jwks_url)); |
| 639 | if (dst.size() > 0) { |
| 640 | // Verify if the checksum of the downloaded JWKS has been changed. |
| 641 | jwks_checksum_ = HashUtil::FastHash64(dst.data(), dst.size(), /*seed*/ 0xcafebeef); |
| 642 | if (jwks_checksum_ == cur_jwks_checksum) { |
| 643 | return Status::OK(); |
| 644 | } |
| 645 | // Append '\0' so that the in-memory object could be parsed as StringStream. |
| 646 | dst.push_back('\0'); |
| 647 | #ifndef NDEBUG |
| 648 | VLOG(3) << "JWKS: " << dst.data(); |
| 649 | #endif |
| 650 | // Parse in-memory JWKS JSON object as StringStream. |
| 651 | Document jwks_doc; |
| 652 | jwks_doc.Parse(reinterpret_cast<char*>(dst.data())); |
| 653 | if (jwks_doc.HasParseError()) { |
| 654 | return Status::InvalidArgument(GetParseError_En(jwks_doc.GetParseError())); |
| 655 | } |
| 656 | if (!jwks_doc.IsObject()) { |
| 657 | return Status::InvalidArgument("root element must be a JSON Object"); |
| 658 | } |
| 659 | if (!jwks_doc.HasMember("keys")) { |
| 660 | return Status::InvalidArgument("keys is required"); |
| 661 | } |
| 662 | |
| 663 | // Load and initialize public keys. |
| 664 | JWKSetParser jwks_parser(this); |
| 665 | RETURN_NOT_OK(jwks_parser.Parse(jwks_doc)); |
| 666 | } |
| 667 | |
| 668 | *is_changed = true; |
| 669 | return Status::OK(); |
| 670 | } |
| 671 | |
| 672 | void JWKSSnapshot::AddHSKey(const std::string& key_id, |
| 673 | unique_ptr<JWTPublicKey> jwk_pub_key) { |
no test coverage detected