Load JWKS from the given local json file.
| 611 | |
| 612 | // Load JWKS from the given local json file. |
| 613 | Status JWKSSnapshot::LoadKeysFromFile(const string& jwks_file_path) { |
| 614 | hs_key_map_.clear(); |
| 615 | rsa_pub_key_map_.clear(); |
| 616 | |
| 617 | // Read the file. |
| 618 | FILE* jwks_file = fopen(jwks_file_path.c_str(), "r"); |
| 619 | if (jwks_file == nullptr) { |
| 620 | return Status( |
| 621 | Substitute("Could not open JWKS file '$0'; $1", jwks_file_path, strerror(errno))); |
| 622 | } |
| 623 | // Check for an empty file and ignore it. |
| 624 | struct stat jwks_file_stats; |
| 625 | if (fstat(fileno(jwks_file), &jwks_file_stats)) { |
| 626 | fclose(jwks_file); |
| 627 | return Status( |
| 628 | Substitute("Error reading JWKS file '$0'; $1", jwks_file_path, strerror(errno))); |
| 629 | } |
| 630 | if (jwks_file_stats.st_size == 0) { |
| 631 | fclose(jwks_file); |
| 632 | return Status::OK(); |
| 633 | } |
| 634 | |
| 635 | char readBuffer[65536]; |
| 636 | rapidjson::FileReadStream stream(jwks_file, readBuffer, sizeof(readBuffer)); |
| 637 | Document jwks_doc; |
| 638 | jwks_doc.ParseStream(stream); |
| 639 | fclose(jwks_file); |
| 640 | if (jwks_doc.HasParseError()) { |
| 641 | return Status( |
| 642 | TErrorCode::JWKS_PARSE_ERROR, GetParseError_En(jwks_doc.GetParseError())); |
| 643 | } else if (!jwks_doc.IsObject()) { |
| 644 | return Status(TErrorCode::JWKS_PARSE_ERROR, "root element must be a JSON Object"); |
| 645 | } else if (!jwks_doc.HasMember("keys")) { |
| 646 | return Status(TErrorCode::JWKS_PARSE_ERROR, "keys is required"); |
| 647 | } |
| 648 | |
| 649 | JWKSetParser jwks_parser(this); |
| 650 | return jwks_parser.Parse(jwks_doc); |
| 651 | } |
| 652 | |
| 653 | // Download JWKS from the given URL with Kudu's EasyCurl wrapper. |
| 654 | Status JWKSSnapshot::LoadKeysFromUrl( |