diff --git a/apps/emqx/src/emqx_ocsp_cache.erl b/apps/emqx/src/emqx_ocsp_cache.erl index ef0411b37..5f30bc66f 100644 --- a/apps/emqx/src/emqx_ocsp_cache.erl +++ b/apps/emqx/src/emqx_ocsp_cache.erl @@ -542,7 +542,8 @@ build_ocsp_request(IssuerPem, ServerCert) -> } }, ReqDer = public_key:der_encode('OCSPRequest', Req), - base64:encode_to_string(ReqDer). + B64Encoded = base64:encode_to_string(ReqDer), + uri_string:quote(B64Encoded). to_bin(Str) when is_list(Str) -> list_to_binary(Str); to_bin(Bin) when is_binary(Bin) -> Bin. diff --git a/apps/emqx/test/emqx_ocsp_cache_SUITE.erl b/apps/emqx/test/emqx_ocsp_cache_SUITE.erl index d0efc8cd6..aa5d78121 100644 --- a/apps/emqx/test/emqx_ocsp_cache_SUITE.erl +++ b/apps/emqx/test/emqx_ocsp_cache_SUITE.erl @@ -175,13 +175,14 @@ init_per_testcase(_TestCase, Config) -> DataDir = ?config(data_dir, Config), Type = ssl, Name = test_ocsp, + ResponderURL = <<"http://localhost:9877/">>, ListenerOpts = #{ ssl_options => #{ certfile => filename:join(DataDir, "server.pem"), ocsp => #{ enable_ocsp_stapling => true, - responder_url => <<"http://localhost:9877/">>, + responder_url => ResponderURL, issuer_pem => filename:join(DataDir, "ocsp-issuer.pem"), refresh_http_timeout => <<"15s">>, refresh_interval => <<"1s">> @@ -197,7 +198,8 @@ init_per_testcase(_TestCase, Config) -> ListenerOpts2 = emqx_utils_maps:deep_get([listeners, Type, Name], Conf2), emqx_config:put_listener_conf(Type, Name, [], ListenerOpts2), [ - {cache_pid, CachePid} + {cache_pid, CachePid}, + {responder_url, ResponderURL} | Config ]. @@ -997,6 +999,39 @@ t_unknown_error_fetching_ocsp_response(_Config) -> end, ok. +t_path_encoding(Config) -> + ResponderURL = ?config(responder_url, Config), + ListenerID = <<"ssl:test_ocsp">>, + TestPid = self(), + ok = meck:expect( + emqx_ocsp_cache, + http_get, + fun(RequestURI, _HTTPTimeout) -> + TestPid ! {request_uri, RequestURI}, + {ok, {{"HTTP/1.0", 200, 'OK'}, [], <<"ocsp response">>}} + end + ), + ?check_trace( + begin + ?assertMatch({ok, _}, emqx_ocsp_cache:fetch_response(ListenerID)), + receive + {request_uri, <>} -> + <> = RequestURI, + ?assertEqual(nomatch, binary:match(Path, <<"/">>), #{path => Path}), + ok + after 100 -> + ct:pal( + "responder url: ~p\nmailbox: ~p", + [ResponderURL, process_info(self(), messages)] + ), + ct:fail("request not made") + end, + ok + end, + [] + ), + ok. + t_openssl_client(Config) -> TLSVsn = ?config(tls_vsn, Config), WithStatusRequest = ?config(status_request, Config), diff --git a/changes/ce/fix-11347.en.md b/changes/ce/fix-11347.en.md new file mode 100644 index 000000000..9131f4910 --- /dev/null +++ b/changes/ce/fix-11347.en.md @@ -0,0 +1 @@ +Ensure that OCSP request path is properly URL encoded.