BUG/MINOR: ssl: Fix ocsp-update when using "add ssl crt-list"
When adding a new certificate through the CLI and appending it to a
crt-list with the 'ocsp-update' option set, the new certificate would
not be added to the OCSP response update list.
The only thing that was missing was the copy of the ocsp_update mode
from the ssl_bind_conf into the ckch_store's object.
An extra wakeup of the update task also needed to happen in case the
newly inserted entry needs to be updated before the next wakeup of the
task.
This patch does not need to be backported.
diff --git a/include/haproxy/ssl_ocsp-t.h b/include/haproxy/ssl_ocsp-t.h
index d78f941..52aeb08 100644
--- a/include/haproxy/ssl_ocsp-t.h
+++ b/include/haproxy/ssl_ocsp-t.h
@@ -81,6 +81,7 @@
extern struct eb_root cert_ocsp_tree;
extern struct eb_root ocsp_update_tree;
+extern struct task *ocsp_update_task;
__decl_thread(extern HA_SPINLOCK_T ocsp_tree_lock);
diff --git a/reg-tests/ssl/ocsp_auto_update.vtc b/reg-tests/ssl/ocsp_auto_update.vtc
index 800f4fe..f6d3d78 100644
--- a/reg-tests/ssl/ocsp_auto_update.vtc
+++ b/reg-tests/ssl/ocsp_auto_update.vtc
@@ -442,3 +442,79 @@
haproxy h5 -wait
process p5 -wait
+
+
+####################
+# #
+# SIXTH TEST CASE #
+# #
+####################
+
+# Check that a new certificate added via the CLI to a crt-list with
+# the 'ocsp-update on' option will be taken into account by the OCSP
+# auto update task
+#
+process p6 "openssl ocsp -index ${testdir}/ocsp_update/index.txt -rsigner ${testdir}/ocsp_update/ocsp.haproxy.com.pem -CA ${testdir}/ocsp_update/ocsp_update_rootca.crt -nrequest 1 -ndays 1 -port 12346 -timeout 5" -start
+
+barrier b6 cond 2 -cyclic
+
+syslog Syslog_http6 -level info {
+ recv
+ expect ~ "GET /MEMwQTA%2FMD0wOzAJBgUrDgMCGgUABBSKg%2BAGD6%2F3Ccp%2Bm5VSKi6BY1%2FaCgQU9lKw5DXV6pI4UVCPCtvpLYXeAHoCAhAV HTTP/1.1"
+
+ barrier b6 sync
+} -start
+
+haproxy h6 -conf {
+ global
+ tune.ssl.default-dh-param 2048
+ tune.ssl.capture-buffer-size 1
+ stats socket "${tmpdir}/h6/stats" level admin
+ crt-base ${testdir}
+
+ defaults
+ mode http
+ option httplog
+ log stderr local0 debug err
+ option logasap
+ timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
+ timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
+
+ frontend ssl-fe
+ bind "${tmpdir}/ssl.sock" ssl crt-list ${testdir}/simple.crt-list ca-file ${testdir}/set_cafile_rootCA.crt verify none crt-ignore-err all
+ http-request return status 200
+
+ listen http_rebound_lst
+ mode http
+ option httplog
+ log ${Syslog_http6_addr}:${Syslog_http6_port} local0
+ bind "127.0.0.1:12345"
+ server s1 "127.0.0.1:12346"
+} -start
+
+# We need to "enable" the cli with a first cli call before using it only through socats
+haproxy h6 -cli {
+ send "show ssl cert"
+ expect ~ ""
+}
+
+# Create a new certificate that has an OCSP uri and add it to the
+# existing CLI with the 'ocsp-update on' command.
+shell {
+ echo "new ssl cert ${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa" | socat "${tmpdir}/h6/stats" -
+ printf "set ssl cert ${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa <<\n$(cat ${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa)\n\n" | socat "${tmpdir}/h6/stats" -
+ printf "set ssl cert ${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa.issuer <<\n$(cat ${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa.issuer)\n\n" | socat "${tmpdir}/h6/stats" -
+ echo "commit ssl cert ${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa" | socat "${tmpdir}/h6/stats" -
+
+ printf "add ssl crt-list ${testdir}/simple.crt-list <<\n${testdir}/ocsp_update/multicert/server_ocsp.pem.rsa [ocsp-update on] foo.com\n\n" | socat "${tmpdir}/h6/stats" -
+}
+
+barrier b6 sync
+
+shell "sleep 1"
+
+haproxy h6 -cli {
+ send "show ssl ocsp-updates"
+ expect ~ "303b300906052b0e03021a050004148a83e0060faff709ca7e9b95522a2e81635fda0a0414f652b0e435d5ea923851508f0adbe92d85de007a02021016 .*| 1 | 0 | 1 | Update successful"
+}
diff --git a/src/ssl_crtlist.c b/src/ssl_crtlist.c
index e5a5c24..5d1f5f3 100644
--- a/src/ssl_crtlist.c
+++ b/src/ssl_crtlist.c
@@ -1322,6 +1322,16 @@
goto error;
}
+ /* No need to check 'ocsp-update' inconsistency on a store that is not
+ * used yet (it was just added through the CLI for instance).
+ */
+ if (!LIST_ISEMPTY(&store->ckch_inst) &&
+ ocsp_update_check_cfg_consistency(store, entry, cert_path, &err))
+ goto error;
+
+ if (entry->ssl_conf)
+ store->data->ocsp_update_mode = entry->ssl_conf->ocsp_update;
+
/* check if it's possible to insert this new crtlist_entry */
entry->node.key = store;
inserted = ebpt_insert(&crtlist->entries, &entry->node);
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 1ce2483..5ebc72f 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -1268,6 +1268,15 @@
strcpy(iocsp->path, path);
ssl_ocsp_update_insert(iocsp);
+ /* If we are during init the update task is not
+ * scheduled yet so a wakeup won't do anything.
+ * Otherwise, if the OCSP was added through the CLI, we
+ * wake the task up to manage the case of a new entry
+ * that needs to be updated before the previous first
+ * entry.
+ */
+ if (ocsp_update_task)
+ task_wakeup(ocsp_update_task, TASK_WOKEN_MSG);
}
}