| 748 | } // anonymous namespace |
| 749 | |
| 750 | Optional<JsonWebKeySet> JsonWebKeySet::parse(StringRef jwksString, VectorRef<StringRef> allowedUses) { |
| 751 | auto d = rapidjson::Document(); |
| 752 | d.Parse(reinterpret_cast<const char*>(jwksString.begin()), jwksString.size()); |
| 753 | if (d.HasParseError()) { |
| 754 | JWKS_PARSE_ERROR("ParseError") |
| 755 | .detail("Message", GetParseError_En(d.GetParseError())) |
| 756 | .detail("Offset", d.GetErrorOffset()); |
| 757 | return {}; |
| 758 | } |
| 759 | auto keysItr = d.FindMember("keys"); |
| 760 | if (!d.IsObject() || keysItr == d.MemberEnd() || !keysItr->value.IsArray()) { |
| 761 | JWKS_PARSE_ERROR("JWKS must be an object and have 'keys' array member"); |
| 762 | return {}; |
| 763 | } |
| 764 | auto const& keys = keysItr->value; |
| 765 | auto ret = JsonWebKeySet{}; |
| 766 | for (auto keyIndex = 0; keyIndex < keys.Size(); keyIndex++) { |
| 767 | if (!keys[keyIndex].IsObject()) { |
| 768 | JWKS_PARSE_ERROR("element of 'keys' array must be an object"); |
| 769 | return {}; |
| 770 | } |
| 771 | auto const& key = keys[keyIndex]; |
| 772 | DECLARE_JWK_REQUIRED_STRING_MEMBER(key, kty); |
| 773 | DECLARE_JWK_REQUIRED_STRING_MEMBER(key, kid); |
| 774 | DECLARE_JWK_OPTIONAL_STRING_MEMBER(key, use); |
| 775 | if (use.present() && !allowedUses.empty()) { |
| 776 | auto allowed = false; |
| 777 | for (auto allowedUse : allowedUses) { |
| 778 | if (allowedUse == use.get()) { |
| 779 | allowed = true; |
| 780 | break; |
| 781 | } |
| 782 | } |
| 783 | if (!allowed) { |
| 784 | JWK_PARSE_ERROR("Illegal optional 'use' member found").detail("Use", use.get().toString()); |
| 785 | return {}; |
| 786 | } |
| 787 | } |
| 788 | auto parsedKey = parseKey(key, kty, keyIndex); |
| 789 | if (!parsedKey.present()) |
| 790 | return {}; |
| 791 | auto [iter, inserted] = ret.keys.insert({ Standalone<StringRef>(kid), parsedKey.get() }); |
| 792 | if (!inserted) { |
| 793 | JWK_PARSE_ERROR("Duplicate key name").detail("KeyName", kid.toString()); |
| 794 | return {}; |
| 795 | } |
| 796 | } |
| 797 | return ret; |
| 798 | } |
| 799 | |
| 800 | Optional<StringRef> JsonWebKeySet::toStringRef(Arena& arena) { |
| 801 | using Buffer = rapidjson::StringBuffer; |
nothing calls this directly
no test coverage detected