mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-08-08 09:21:48 +08:00
Removed unnecessary CA and certificate handlers
This removes certificate and CA handlers not used by the openconnect client. This is a hardening measure to further reduce the attack surface of the worker process. Signed-off-by: Nikos Mavrogiannopoulos <n.mavrogiannopoulos@gmail.com>
This commit is contained in:
@@ -14,6 +14,11 @@
|
|||||||
body limit
|
body limit
|
||||||
- Fix build issue on FreeBSD (#704)
|
- Fix build issue on FreeBSD (#704)
|
||||||
- Build against Nettle 4.
|
- Build against Nettle 4.
|
||||||
|
- Removed unnecessary for openconnect client handlers to reduce attack surface:
|
||||||
|
* /cert.pem
|
||||||
|
* /cert.cer
|
||||||
|
* /ca.pem
|
||||||
|
* /ca.cer
|
||||||
|
|
||||||
|
|
||||||
* Version 1.4.2 (released 2026-04-16)
|
* Version 1.4.2 (released 2026-04-16)
|
||||||
|
|||||||
@@ -90,160 +90,6 @@ static int send_data(worker_st *ws, unsigned int http_ver,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_cert_handler(worker_st *ws, unsigned int http_ver)
|
|
||||||
{
|
|
||||||
if (ws->conn_type != SOCK_TYPE_UNIX) { /* we have TLS */
|
|
||||||
const gnutls_datum_t *certs;
|
|
||||||
gnutls_datum_t out = { NULL, 0 };
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
oclog(ws, LOG_DEBUG, "requested server certificate");
|
|
||||||
|
|
||||||
certs = gnutls_certificate_get_ours(ws->session);
|
|
||||||
if (certs == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gnutls_pem_base64_encode_alloc("CERTIFICATE", &certs[0],
|
|
||||||
&out);
|
|
||||||
if (ret < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = send_data(ws, http_ver, "application/x-pem-file",
|
|
||||||
(char *)out.data, out.size);
|
|
||||||
gnutls_free(out.data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int get_cert_der_handler(worker_st *ws, unsigned int http_ver)
|
|
||||||
{
|
|
||||||
if (ws->conn_type != SOCK_TYPE_UNIX) { /* we have TLS */
|
|
||||||
const gnutls_datum_t *certs;
|
|
||||||
|
|
||||||
oclog(ws, LOG_DEBUG, "requested raw server certificate");
|
|
||||||
|
|
||||||
certs = gnutls_certificate_get_ours(ws->session);
|
|
||||||
if (certs == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return send_data(ws, http_ver, "application/pkix-cert",
|
|
||||||
(char *)certs[0].data, certs[0].size);
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ca_handler(worker_st *ws, unsigned int http_ver, unsigned int der)
|
|
||||||
{
|
|
||||||
if (ws->conn_type != SOCK_TYPE_UNIX) { /* we have TLS */
|
|
||||||
const gnutls_datum_t *certs;
|
|
||||||
gnutls_datum_t out = { NULL, 0 }, tmpca;
|
|
||||||
unsigned int i;
|
|
||||||
int ret;
|
|
||||||
gnutls_x509_crt_t issuer = NULL, crt = NULL;
|
|
||||||
|
|
||||||
oclog(ws, LOG_DEBUG, "requested server CA");
|
|
||||||
|
|
||||||
certs = gnutls_certificate_get_ours(ws->session);
|
|
||||||
if (certs == NULL) {
|
|
||||||
oclog(ws, LOG_DEBUG, "could not obtain our cert");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gnutls_x509_crt_init(&crt);
|
|
||||||
if (ret < 0) {
|
|
||||||
oclog(ws, LOG_DEBUG, "could not initialize cert");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gnutls_x509_crt_import(crt, &certs[0],
|
|
||||||
GNUTLS_X509_FMT_DER);
|
|
||||||
if (ret < 0) {
|
|
||||||
ret = -1;
|
|
||||||
oclog(ws, LOG_DEBUG, "could not import our cert");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
ret = gnutls_certificate_get_crt_raw(WSCREDS(ws)->xcred,
|
|
||||||
i, 1, &tmpca);
|
|
||||||
if (ret < 0) {
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gnutls_x509_crt_init(&issuer);
|
|
||||||
if (ret < 0) {
|
|
||||||
ret = -1;
|
|
||||||
oclog(ws, LOG_DEBUG,
|
|
||||||
"could not initialize issuer cert");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gnutls_x509_crt_import(issuer, &tmpca,
|
|
||||||
GNUTLS_X509_FMT_DER);
|
|
||||||
if (ret < 0) {
|
|
||||||
ret = -1;
|
|
||||||
oclog(ws, LOG_DEBUG,
|
|
||||||
"could not import issuer cert");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = gnutls_x509_crt_check_issuer(crt, issuer);
|
|
||||||
if (ret != 0) {
|
|
||||||
ret = gnutls_x509_crt_export2(
|
|
||||||
issuer,
|
|
||||||
der ? GNUTLS_X509_FMT_DER :
|
|
||||||
GNUTLS_X509_FMT_PEM,
|
|
||||||
&out);
|
|
||||||
if (ret < 0) {
|
|
||||||
ret = -1;
|
|
||||||
oclog(ws, LOG_DEBUG,
|
|
||||||
"could not export issuer of cert");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gnutls_x509_crt_deinit(issuer);
|
|
||||||
issuer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = send_data(ws, http_ver, "application/pkix-cert",
|
|
||||||
(char *)out.data, out.size);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
|
|
||||||
oclog(ws, LOG_DEBUG,
|
|
||||||
"could not get CA; does the server cert list contain the CA certificate?");
|
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (crt)
|
|
||||||
gnutls_x509_crt_deinit(crt);
|
|
||||||
if (issuer)
|
|
||||||
gnutls_x509_crt_deinit(issuer);
|
|
||||||
gnutls_free(out.data);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_ca_handler(worker_st *ws, unsigned int http_ver)
|
|
||||||
{
|
|
||||||
return ca_handler(ws, http_ver, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int get_ca_der_handler(worker_st *ws, unsigned int http_ver)
|
|
||||||
{
|
|
||||||
return ca_handler(ws, http_ver, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ANYCONNECT_CLIENT_COMPAT
|
#ifdef ANYCONNECT_CLIENT_COMPAT
|
||||||
int get_config_handler(worker_st *ws, unsigned int http_ver)
|
int get_config_handler(worker_st *ws, unsigned int http_ver)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -61,10 +61,6 @@ static const struct known_urls_st known_urls[] = {
|
|||||||
LL("/", get_auth_handler, post_auth_handler),
|
LL("/", get_auth_handler, post_auth_handler),
|
||||||
LL("/auth", get_auth_handler, post_auth_handler),
|
LL("/auth", get_auth_handler, post_auth_handler),
|
||||||
LL("/VPN", get_auth_handler, post_auth_handler),
|
LL("/VPN", get_auth_handler, post_auth_handler),
|
||||||
LL("/cert.pem", get_cert_handler, NULL),
|
|
||||||
LL("/cert.cer", get_cert_der_handler, NULL),
|
|
||||||
LL("/ca.pem", get_ca_handler, NULL),
|
|
||||||
LL("/ca.cer", get_ca_der_handler, NULL),
|
|
||||||
#ifdef ANYCONNECT_CLIENT_COMPAT
|
#ifdef ANYCONNECT_CLIENT_COMPAT
|
||||||
LL_DIR("/profiles", get_config_handler, NULL),
|
LL_DIR("/profiles", get_config_handler, NULL),
|
||||||
LL("/VPNManifest.xml", get_string_handler, NULL),
|
LL("/VPNManifest.xml", get_string_handler, NULL),
|
||||||
|
|||||||
+1
-5
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2013-2016 Nikos Mavrogiannopoulos
|
* Copyright (C) 2013-2026 Nikos Mavrogiannopoulos
|
||||||
*
|
*
|
||||||
* Author: Nikos Mavrogiannopoulos
|
* Author: Nikos Mavrogiannopoulos
|
||||||
*
|
*
|
||||||
@@ -348,10 +348,6 @@ int auth_user_deinit(worker_st *ws);
|
|||||||
int get_auth_handler(worker_st *server, unsigned int http_ver);
|
int get_auth_handler(worker_st *server, unsigned int http_ver);
|
||||||
int post_auth_handler(worker_st *server, unsigned int http_ver);
|
int post_auth_handler(worker_st *server, unsigned int http_ver);
|
||||||
int post_kkdcp_handler(worker_st *server, unsigned int http_ver);
|
int post_kkdcp_handler(worker_st *server, unsigned int http_ver);
|
||||||
int get_cert_handler(worker_st *ws, unsigned int http_ver);
|
|
||||||
int get_cert_der_handler(worker_st *ws, unsigned int http_ver);
|
|
||||||
int get_ca_handler(worker_st *ws, unsigned int http_ver);
|
|
||||||
int get_ca_der_handler(worker_st *ws, unsigned int http_ver);
|
|
||||||
int get_svc_handler(worker_st *ws, unsigned int http_ver);
|
int get_svc_handler(worker_st *ws, unsigned int http_ver);
|
||||||
int post_svc_handler(worker_st *ws, unsigned int http_ver);
|
int post_svc_handler(worker_st *ws, unsigned int http_ver);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -116,7 +116,7 @@ if have_cwrap
|
|||||||
'test-pass', 'test-pass-cert', 'test-pass-cert-rfc822name',
|
'test-pass', 'test-pass-cert', 'test-pass-cert-rfc822name',
|
||||||
'test-cert', 'test-group-pass', 'test-pass-group-cert',
|
'test-cert', 'test-group-pass', 'test-pass-group-cert',
|
||||||
'test-pass-group-cert-no-pass', 'test-sighup',
|
'test-pass-group-cert-no-pass', 'test-sighup',
|
||||||
'test-enc-key', 'test-sighup-key-change', 'test-get-cert',
|
'test-enc-key', 'test-sighup-key-change',
|
||||||
'test-san-cert', 'test-pass-opt-cert',
|
'test-san-cert', 'test-pass-opt-cert',
|
||||||
'test-cert-opt-pass',
|
'test-cert-opt-pass',
|
||||||
'haproxy-auth', 'test-maintenance', 'resumption',
|
'haproxy-auth', 'test-maintenance', 'resumption',
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Checking with CURL that server returns HTTP 200 for user authenticated GET"
|
echo "Checking with CURL that server returns HTTP 200 for user authenticated GET"
|
||||||
http_result=$(curl --insecure https://localhost:${PORT}/cert.pem --output /dev/null --cookie "${HTTP_COOKIE}" --silent --write-out "%{http_code}")
|
http_result=$(curl --insecure https://localhost:${PORT}/svc --output /dev/null --cookie "${HTTP_COOKIE}" --silent --write-out "%{http_code}")
|
||||||
if [ "${http_result}" != "200" ]; then
|
if [ "${http_result}" != "200" ]; then
|
||||||
fail ${PID} "Server returned ${http_result} instead of 200 for GET"
|
fail ${PID} "Server returned ${http_result} instead of 200 for GET"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Copyright (C) 2013 Nikos Mavrogiannopoulos
|
|
||||||
#
|
|
||||||
# This file is part of ocserv.
|
|
||||||
#
|
|
||||||
# ocserv is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU General Public License as published by the
|
|
||||||
# Free Software Foundation; either version 2 of the License, or (at
|
|
||||||
# your option) any later version.
|
|
||||||
#
|
|
||||||
# ocserv is distributed in the hope that it will be useful, but
|
|
||||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with GnuTLS; if not, write to the Free Software Foundation,
|
|
||||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
SERV="${SERV:-../src/ocserv}"
|
|
||||||
srcdir=${srcdir:-.}
|
|
||||||
NO_NEED_ROOT=1
|
|
||||||
|
|
||||||
TMPFILE=getcert.$$.tmp
|
|
||||||
TMPFILE2=getcert2.$$.tmp
|
|
||||||
|
|
||||||
. `dirname $0`/common.sh
|
|
||||||
|
|
||||||
eval "${GETPORT}"
|
|
||||||
|
|
||||||
echo "Testing ocserv certificate GET handlers... "
|
|
||||||
|
|
||||||
update_config test-user-cert.config
|
|
||||||
launch_simple_sr_server -d 1 -f -c ${CONFIG}
|
|
||||||
PID=$!
|
|
||||||
|
|
||||||
wait_server $PID
|
|
||||||
|
|
||||||
echo -n "Connecting to GET PEM certificate... "
|
|
||||||
( LD_PRELOAD=libsocket_wrapper.so curl https://$ADDRESS:$PORT/cert.pem --insecure > $TMPFILE 2>/dev/null ) ||
|
|
||||||
fail $PID "Could not get certificate!"
|
|
||||||
|
|
||||||
cmp $TMPFILE "${srcdir}/certs/server-cert.pem"
|
|
||||||
if test $? != 0;then
|
|
||||||
fail $PID "failed, certs not match"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
echo -n "Connecting to GET DER certificate... "
|
|
||||||
( LD_PRELOAD=libsocket_wrapper.so curl https://$ADDRESS:$PORT/cert.cer --insecure > $TMPFILE 2>/dev/null ) ||
|
|
||||||
fail $PID "Could not get DER certificate!"
|
|
||||||
|
|
||||||
certtool --inder -i <"$TMPFILE" >$TMPFILE2
|
|
||||||
certtool -i <"${srcdir}/certs/server-cert.pem" >$TMPFILE
|
|
||||||
cmp "$TMPFILE" "$TMPFILE2"
|
|
||||||
if test $? != 0;then
|
|
||||||
fail $PID "failed, certs not match"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
echo -n "Connecting to GET CA PEM certificate... "
|
|
||||||
( LD_PRELOAD=libsocket_wrapper.so curl https://$ADDRESS:$PORT/ca.pem --insecure > $TMPFILE 2>/dev/null ) ||
|
|
||||||
fail $PID "Could not get certificate!"
|
|
||||||
|
|
||||||
cmp $TMPFILE "${srcdir}/certs/ca.pem"
|
|
||||||
if test $? != 0;then
|
|
||||||
fail $PID "failed, certs not match"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
echo -n "Connecting to GET CA DER certificate... "
|
|
||||||
( LD_PRELOAD=libsocket_wrapper.so curl https://$ADDRESS:$PORT/ca.cer --insecure > $TMPFILE 2>/dev/null ) ||
|
|
||||||
fail $PID "Could not get DER certificate!"
|
|
||||||
|
|
||||||
certtool --inder -i <"$TMPFILE" >$TMPFILE2
|
|
||||||
certtool -i <"${srcdir}/certs/ca.pem" >$TMPFILE
|
|
||||||
cmp "$TMPFILE" "$TMPFILE2"
|
|
||||||
if test $? != 0;then
|
|
||||||
fail $PID "failed, certs not match"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
cleanup
|
|
||||||
|
|
||||||
rm -f "$TMPFILE" "$TMPFILE2"
|
|
||||||
|
|
||||||
exit 0
|
|
||||||
@@ -111,27 +111,6 @@ results=$(LD_PRELOAD=libsocket_wrapper.so curl -I -X GET -s https://$ADDRESS:$PO
|
|||||||
CheckHeaders "$results"
|
CheckHeaders "$results"
|
||||||
echo "ok"
|
echo "ok"
|
||||||
|
|
||||||
echo -n "Testing /cert.pem ... "
|
|
||||||
results=$(LD_PRELOAD=libsocket_wrapper.so curl -I -X GET -s https://$ADDRESS:$PORT/cert.pem --insecure)
|
|
||||||
CheckHeaders "$results"
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
echo -n "Testing /cert.cer ... "
|
|
||||||
results=$(LD_PRELOAD=libsocket_wrapper.so curl -I -X GET -s https://$ADDRESS:$PORT/cert.cer --insecure)
|
|
||||||
CheckHeaders "$results"
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
echo -n "Testing /ca.pem ... "
|
|
||||||
results=$(LD_PRELOAD=libsocket_wrapper.so curl -I -X GET -s https://$ADDRESS:$PORT/ca.pem --insecure)
|
|
||||||
CheckHeaders "$results"
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
echo -n "Testing /ca.cer ... "
|
|
||||||
results=$(LD_PRELOAD=libsocket_wrapper.so curl -I -X GET -s https://$ADDRESS:$PORT/ca.cer --insecure)
|
|
||||||
CheckHeaders "$results"
|
|
||||||
echo "ok"
|
|
||||||
|
|
||||||
|
|
||||||
cleanup
|
cleanup
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
Reference in New Issue
Block a user