@@ -392,10 +392,33 @@ CDoc2Reader::getFMK(std::vector<uint8_t>& fmk, unsigned int lock_idx)
392392 // server RFC9421 HTTP countersignature. The RP signing keys
393393 // are fetched from its well-known endpoint.
394394 std::string jwks;
395- if (auto rv = network->fetchWellKnownKeys (jwks, rp_url); rv != OK ) {
396- setLastError (network->getLastErrorStr (rv));
397- LOG_ERROR (" {}" , last_error);
398- return rv;
395+ {
396+ std::string jwks_url = rp_url + " /.well-known/jwks.jws" ;
397+ std::map<std::string, std::string> headers;
398+ std::vector<uint8_t > body;
399+ if (auto rv = network->get (jwks_url, body, headers, false ); rv != OK ) {
400+ setLastError (network->getLastErrorStr (rv));
401+ LOG_ERROR (" {}" , last_error);
402+ return rv;
403+ }
404+ jwks.assign (body.begin (), body.end ());
405+
406+ // The endpoint name says .jws: accept both a plain JWK
407+ // Set (what the servers currently return) and a JWS
408+ // compact serialization (header64.payload64.signature64)
409+ // whose payload is the JWK Set.
410+ if (jwks.find (" \" keys\" " ) == std::string::npos) {
411+ std::vector<std::string> parts = split (jwks, ' .' );
412+ if (parts.size () == 3 ) {
413+ std::vector<uint8_t > payload = fromBase64URL (parts[1 ]);
414+ jwks.assign (payload.begin (), payload.end ());
415+ }
416+ }
417+ if (jwks.find (" \" keys\" " ) == std::string::npos) {
418+ setLastError (" Well-known keys response is not a JWK Set" );
419+ LOG_ERROR (" {}" , last_error);
420+ return libcdoc::DATA_FORMAT_ERROR ;
421+ }
399422 }
400423 if (auto rv = validateAuthTicketMID (crypto, rcpt_id, auth_tokens[0 ], auth.cert , auth.params , jwks, v_err); rv != OK ) {
401424 setLastError (v_err);
0 commit comments