diff options
author | Mathieu GIANNECCHINI <mat.giann@free.fr> | 2010-03-02 00:26:57 +0100 |
---|---|---|
committer | David Sommerseth <dazo@users.sourceforge.net> | 2010-10-21 21:11:46 +0200 |
commit | 39238d1b173d8b7f08e061dd51e30605ce722e92 (patch) | |
tree | b9f102e8328ff2af22739cae2f630d3cc2cbd818 /ssl.c | |
parent | Reworked the eurephia patch for inclusion to the openvpn-testing tree (diff) | |
download | openvpn-39238d1b173d8b7f08e061dd51e30605ce722e92.tar.xz |
enhance tls-verify possibility
It should be nice to enhance tls-verify check possibilities against peer
cert during a pending TLS connection like :
- OCSP verification
- check any X509 extensions of the peer certificate
- delta CRL verification
- ...
This patch add a new "tls-export-cert" option which allow to get peer
certificate in PEM format and to store it in an openvpn temporary file.
Peer certificate is stored before tls-script execution and deleted after.
The name of the related temporary file is available under tls-verify
script by an environment variable "peer_cert".
The patch was made from OpenVPN svn Beta21 branches.
Here is a very simple exemple of Tls-verify script which provide OCSP
support to OpenVPN (with tls-export-cert option) without any OpenVPN
"core" modification :
X509=$2
openssl ocsp \
-issuer /etc/openvpn/ssl.crt/RootCA.pem \
-CAfile /etc/openvpn/ssl.capath/OpenVPNServeur-cafile.pem \
-cert $peer_cert \
-url http://your-ocsp-url
if [ $? -ne 0 ]
then
echo "error : OCSP check failed for ${X509}" | logger -t
"tls-verify"
exit 1
fi
This has been discussed here:
<http://thread.gmane.org/gmane.network.openvpn.devel/2492>
<http://thread.gmane.org/gmane.network.openvpn.devel/3150>
<http://thread.gmane.org/gmane.network.openvpn.devel/3217>
This patch has been modified by David Sommerseth, by fixing a few issues
which came up to during the code review process. The man page has been
updated and tmp_file in ssl.c is checked for not being NULL before calling
delete_file().
Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
Acked-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'ssl.c')
-rw-r--r-- | ssl.c | 61 |
1 files changed, 61 insertions, 0 deletions
@@ -691,6 +691,49 @@ string_mod_sslname (char *str, const unsigned int restrictive_flags, const unsig string_mod (str, restrictive_flags, 0, '_'); } +/* Get peer cert and store it in pem format in a temporary file + * in tmp_dir + */ + +const char * +get_peer_cert(X509_STORE_CTX *ctx, const char *tmp_dir, struct gc_arena *gc) +{ + X509 *peercert; + FILE *peercert_file; + const char *peercert_filename=""; + + if(!tmp_dir) + return NULL; + + /* get peer cert */ + peercert = X509_STORE_CTX_get_current_cert(ctx); + if(!peercert) + { + msg (M_ERR, "Unable to get peer certificate from current context"); + return NULL; + } + + /* create tmp file to store peer cert */ + peercert_filename = create_temp_filename (tmp_dir, "pcf", gc); + + /* write peer-cert in tmp-file */ + peercert_file = fopen(peercert_filename, "w+"); + if(!peercert_file) + { + msg (M_ERR, "Failed to open temporary file : %s", peercert_filename); + return NULL; + } + if(PEM_write_X509(peercert_file,peercert)<0) + { + msg (M_ERR, "Failed to write peer certificate in PEM format"); + fclose(peercert_file); + return NULL; + } + + fclose(peercert_file); + return peercert_filename; +} + /* * Our verify callback function -- check * that an incoming peer certificate is good. @@ -920,10 +963,21 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) /* run --tls-verify script */ if (opt->verify_command) { + const char *tmp_file; + struct gc_arena gc; int ret; setenv_str (opt->es, "script_type", "tls-verify"); + if (opt->verify_export_cert) + { + gc = gc_new(); + if (tmp_file=get_peer_cert(ctx, opt->verify_export_cert,&gc)) + { + setenv_str(opt->es, "peer_cert", tmp_file); + } + } + argv_printf (&argv, "%sc %d %s", opt->verify_command, ctx->error_depth, @@ -931,6 +985,13 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) argv_msg_prefix (D_TLS_DEBUG, &argv, "TLS: executing verify command"); ret = openvpn_execve (&argv, opt->es, S_SCRIPT); + if (opt->verify_export_cert) + { + if (tmp_file) + delete_file(tmp_file); + gc_free(&gc); + } + if (system_ok (ret)) { msg (D_HANDSHAKE, "VERIFY SCRIPT OK: depth=%d, %s", |