From 1b1b5b90cc3dd72dc4639c723b97e1ae6792be0a Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Fri, 14 Aug 2020 07:27:40 +0200 Subject: cert-session: check OCSP error responses If the OCSP responder returns an error code, such as tryLater, we can't proceed to examine the response bytes. In that case, just skip the check unless the stapling is mandatory on this certificate. Signed-off-by: Daiki Ueno --- lib/cert-session.c | 21 +++++ tests/Makefile.am | 2 +- tests/ocsp-tests/ocsp-must-staple-connection | 111 ++++++++++++++++++++++++++- tests/ocsp-tests/response3.der | 2 + 4 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 tests/ocsp-tests/response3.der diff --git a/lib/cert-session.c b/lib/cert-session.c index db04a25e5d..5192083211 100644 --- a/lib/cert-session.c +++ b/lib/cert-session.c @@ -224,6 +224,11 @@ gnutls_certificate_set_verify_limits(gnutls_certificate_credentials_t res, } #ifdef ENABLE_OCSP +static int +_gnutls_ocsp_verify_mandatory_stapling(gnutls_session_t session, + gnutls_x509_crt_t cert, + unsigned int * ocsp_status); + /* If the certificate is revoked status will be GNUTLS_CERT_REVOKED. * * Returns: @@ -260,6 +265,22 @@ check_ocsp_response(gnutls_session_t session, gnutls_x509_crt_t cert, goto cleanup; } + if (gnutls_ocsp_resp_get_status(resp) != GNUTLS_OCSP_RESP_SUCCESSFUL) { + ret = _gnutls_ocsp_verify_mandatory_stapling(session, cert, ostatus); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + if (*ostatus & GNUTLS_CERT_MISSING_OCSP_STATUS) { + _gnutls_audit_log(session, + "Missing basic OCSP response while required: %s.\n", + gnutls_strerror(ret)); + check_failed = 1; + } + ret = gnutls_assert_val(0); + goto cleanup; + } + ret = gnutls_ocsp_resp_check_crt(resp, 0, cert); if (ret < 0) { ret = gnutls_assert_val(0); diff --git a/tests/Makefile.am b/tests/Makefile.am index 8d71fc4bf0..0387bf7389 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -57,7 +57,7 @@ EXTRA_DIST = suppressions.valgrind eagain-common.h cert-common.h test-chains.h \ scripts/common.sh scripts/starttls-common.sh \ rng-op.c x509sign-verify-common.h common-key-tests.h \ ocsp-tests/certs/ca.key ocsp-tests/certs/ca.pem ocsp-tests/certs/ocsp-server.key ocsp-tests/certs/ocsp-server.pem ocsp-tests/response1.der \ - ocsp-tests/response2.der ocsp-tests/certs/ocsp_index.txt ocsp-tests/certs/ocsp_index.txt.attr \ + ocsp-tests/response2.der ocsp-tests/response3.der ocsp-tests/certs/ocsp_index.txt ocsp-tests/certs/ocsp_index.txt.attr \ ocsp-tests/response1.pem ocsp-tests/response2.pem \ ocsp-tests/certs/server_good.key ocsp-tests/certs/server_bad.key ocsp-tests/certs/server_good.template \ ocsp-tests/certs/server_bad.template ocsp-tests/certs/ocsp-staple-unrelated.der ocsp-tests/suppressions.valgrind \ diff --git a/tests/ocsp-tests/ocsp-must-staple-connection b/tests/ocsp-tests/ocsp-must-staple-connection index 49c355dda3..55d718ddf0 100755 --- a/tests/ocsp-tests/ocsp-must-staple-connection +++ b/tests/ocsp-tests/ocsp-must-staple-connection @@ -26,6 +26,7 @@ GNUTLS_CLI="${GNUTLS_CLI:-../src/gnutls-cli${EXEEXT}}" DIFF="${DIFF:-diff}" TEMPLATE_FILE="ms-out.$$.tmpl.tmp" SERVER_CERT_FILE="ms-cert.$$.pem.tmp" +SERVER_CERT_NO_EXT_FILE="ms-cert-no-ext.$$.pem.tmp" OCSP_RESPONSE_FILE="ms-resp.$$.tmp" OCSP_REQ_FILE="ms-req.$$.tmp" @@ -86,6 +87,7 @@ stop_servers () test -z "${TLS_SERVER_PID}" || kill "${TLS_SERVER_PID}" rm -f "$TEMPLATE_FILE" rm -f "$SERVER_CERT_FILE" + rm -f "$SERVER_CERT_NO_EXT_FILE" rm -f "$OCSP_RESPONSE_FILE" rm -f "$OCSP_REQ_FILE" } @@ -97,9 +99,17 @@ rm -f "$TEMPLATE_FILE" cp "${srcdir}/ocsp-tests/certs/server_good.template" "$TEMPLATE_FILE" chmod u+w "$TEMPLATE_FILE" echo "ocsp_uri=http://localhost:${OCSP_PORT}/ocsp/" >>"$TEMPLATE_FILE" -echo "tls_feature = 5" >>"$TEMPLATE_FILE" # Generate certificates with the random port +datefudge -s "${CERTDATE}" ${CERTTOOL} \ + --generate-certificate --load-ca-privkey "${srcdir}/ocsp-tests/certs/ca.key" \ + --load-ca-certificate "${srcdir}/ocsp-tests/certs/ca.pem" \ + --load-privkey "${srcdir}/ocsp-tests/certs/server_good.key" \ + --template "${TEMPLATE_FILE}" --outfile "${SERVER_CERT_NO_EXT_FILE}" 2>/dev/null + +# Generate certificates with the random port (with mandatory stapling extension) +echo "tls_feature = 5" >>"$TEMPLATE_FILE" + datefudge -s "${CERTDATE}" ${CERTTOOL} \ --generate-certificate --load-ca-privkey "${srcdir}/ocsp-tests/certs/ca.key" \ --load-ca-certificate "${srcdir}/ocsp-tests/certs/ca.pem" \ @@ -392,6 +402,105 @@ kill "${TLS_SERVER_PID}" wait "${TLS_SERVER_PID}" unset TLS_SERVER_PID +echo "=== Test 7: OSCP response error - client doesn't send status_request ===" + +eval "${GETPORT}" +# Port for gnutls-serv +TLS_SERVER_PORT=$PORT +PORT=${TLS_SERVER_PORT} +launch_bare_server $$ \ + datefudge "${TESTDATE}" \ + "${GNUTLS_SERV}" --echo --disable-client-cert \ + --x509keyfile="${srcdir}/ocsp-tests/certs/server_good.key" \ + --x509certfile="${SERVER_CERT_FILE}" \ + --port="${TLS_SERVER_PORT}" \ + --ocsp-response="${srcdir}/ocsp-tests/response3.der" --ignore-ocsp-response-errors +TLS_SERVER_PID="${!}" +wait_server $TLS_SERVER_PID + +wait_for_port "${TLS_SERVER_PORT}" + +echo "test 123456" | \ + datefudge -s "${TESTDATE}" \ + "${GNUTLS_CLI}" --priority "NORMAL:%NO_EXTENSIONS" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \ + --port="${TLS_SERVER_PORT}" localhost +rc=$? + +if test "${rc}" != "0"; then + echo "Connecting to server with valid certificate and OCSP error response failed" + exit ${rc} +fi + +kill "${TLS_SERVER_PID}" +wait "${TLS_SERVER_PID}" +unset TLS_SERVER_PID + +echo "=== Test 8: OSCP response error - client sends status_request, no TLS feature extension ===" + +eval "${GETPORT}" +# Port for gnutls-serv +TLS_SERVER_PORT=$PORT +PORT=${TLS_SERVER_PORT} +launch_bare_server $$ \ + datefudge "${TESTDATE}" \ + "${GNUTLS_SERV}" --echo --disable-client-cert \ + --x509keyfile="${srcdir}/ocsp-tests/certs/server_good.key" \ + --x509certfile="${SERVER_CERT_NO_EXT_FILE}" \ + --port="${TLS_SERVER_PORT}" \ + --ocsp-response="${srcdir}/ocsp-tests/response3.der" --ignore-ocsp-response-errors +TLS_SERVER_PID="${!}" +wait_server $TLS_SERVER_PID + +wait_for_port "${TLS_SERVER_PORT}" + +echo "test 123456" | \ + datefudge -s "${TESTDATE}" \ + "${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \ + --port="${TLS_SERVER_PORT}" localhost +rc=$? + +if test "${rc}" != "0"; then + echo "Connecting to server with valid certificate and OCSP error response failed" + exit ${rc} +fi + +kill "${TLS_SERVER_PID}" +wait "${TLS_SERVER_PID}" +unset TLS_SERVER_PID + +echo "=== Test 9: OSCP response error - client sends status_request, TLS feature extension present ===" + +eval "${GETPORT}" +# Port for gnutls-serv +TLS_SERVER_PORT=$PORT +PORT=${TLS_SERVER_PORT} +launch_bare_server $$ \ + datefudge "${TESTDATE}" \ + "${GNUTLS_SERV}" --echo --disable-client-cert \ + --x509keyfile="${srcdir}/ocsp-tests/certs/server_good.key" \ + --x509certfile="${SERVER_CERT_FILE}" \ + --port="${TLS_SERVER_PORT}" \ + --ocsp-response="${srcdir}/ocsp-tests/response3.der" --ignore-ocsp-response-errors +TLS_SERVER_PID="${!}" +wait_server $TLS_SERVER_PID + +wait_for_port "${TLS_SERVER_PORT}" + +echo "test 123456" | \ + datefudge -s "${TESTDATE}" \ + "${GNUTLS_CLI}" --ocsp --x509cafile="${srcdir}/ocsp-tests/certs/ca.pem" \ + --port="${TLS_SERVER_PORT}" localhost +rc=$? + +if test "${rc}" = "0"; then + echo "Connecting to server with valid certificate and OCSP error response unexpectedly succeeded" + exit ${rc} +fi + +kill "${TLS_SERVER_PID}" +wait "${TLS_SERVER_PID}" +unset TLS_SERVER_PID + kill ${OCSP_PID} wait ${OCSP_PID} diff --git a/tests/ocsp-tests/response3.der b/tests/ocsp-tests/response3.der new file mode 100644 index 0000000000..39e09cffaa --- /dev/null +++ b/tests/ocsp-tests/response3.der @@ -0,0 +1,2 @@ +0 + \ No newline at end of file -- cgit v1.2.1