aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openvpn.86
-rw-r--r--src/openvpn/ssl_verify.c9
-rw-r--r--src/openvpn/ssl_verify_backend.h21
-rw-r--r--src/openvpn/ssl_verify_openssl.c10
-rw-r--r--src/openvpn/ssl_verify_polarssl.c42
5 files changed, 81 insertions, 7 deletions
diff --git a/doc/openvpn.8 b/doc/openvpn.8
index ec56030..786719d 100644
--- a/doc/openvpn.8
+++ b/doc/openvpn.8
@@ -6054,6 +6054,12 @@ code should check that.
See the contrib/OCSP_check/OCSP_check.sh script for an example.
.\"*********************************************************
.TP
+.B tls_serial_hex_{n}
+Like
+.B tls_serial_{n}\fR,
+but in hex form (e.g. "12:34:56:78:9A").
+.\"*********************************************************
+.TP
.B tun_mtu
The MTU of the TUN/TAP device.
Set prior to
diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
index 0670f2a..c90c2c3 100644
--- a/src/openvpn/ssl_verify.c
+++ b/src/openvpn/ssl_verify.c
@@ -435,10 +435,15 @@ verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert
}
/* export serial number as environmental variable */
- serial = x509_get_serial(peer_cert, &gc);
+ serial = backend_x509_get_serial(peer_cert, &gc);
openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", cert_depth);
setenv_str (es, envname, serial);
+ /* export serial number in hex as environmental variable */
+ serial = backend_x509_get_serial_hex(peer_cert, &gc);
+ openvpn_snprintf (envname, sizeof(envname), "tls_serial_hex_%d", cert_depth);
+ setenv_str (es, envname, serial);
+
gc_free(&gc);
}
@@ -562,7 +567,7 @@ verify_check_crl_dir(const char *crl_dir, openvpn_x509_cert_t *cert)
int fd = -1;
struct gc_arena gc = gc_new();
- char *serial = x509_get_serial(cert, &gc);
+ char *serial = backend_x509_get_serial(cert, &gc);
if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", crl_dir, OS_SPECIFIC_DIRSEP, serial))
{
diff --git a/src/openvpn/ssl_verify_backend.h b/src/openvpn/ssl_verify_backend.h
index 1658cc0..6f118c9 100644
--- a/src/openvpn/ssl_verify_backend.h
+++ b/src/openvpn/ssl_verify_backend.h
@@ -113,16 +113,31 @@ result_t x509_get_username (char *common_name, int cn_len,
char * x509_username_field, openvpn_x509_cert_t *peer_cert);
/*
- * Return the certificate's serial number.
+ * Return the certificate's serial number in decimal string representation.
*
* The serial number is returned as a string, since it might be a bignum.
*
* @param cert Certificate to retrieve the serial number from.
* @param gc Garbage collection arena to use when allocating string.
*
- * @return The certificate's serial number.
+ * @return String representation of the certificate's serial number
+ * in decimal notation, or NULL on error.
*/
-char *x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc);
+char *backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc);
+
+/*
+ * Return the certificate's serial number in hex string representation.
+ *
+ * The serial number is returned as a string, since it might be a bignum.
+ *
+ * @param cert Certificate to retrieve the serial number from.
+ * @param gc Garbage collection arena to use when allocating string.
+ *
+ * @return String representation of the certificate's serial number
+ * in hex notation, or NULL on error.
+ */
+char *backend_x509_get_serial_hex (openvpn_x509_cert_t *cert,
+ struct gc_arena *gc);
/*
* Save X509 fields to environment, using the naming convention:
diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c
index 91a42b2..19982ae 100644
--- a/src/openvpn/ssl_verify_openssl.c
+++ b/src/openvpn/ssl_verify_openssl.c
@@ -220,7 +220,7 @@ x509_get_username (char *common_name, int cn_len,
}
char *
-x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
+backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
{
ASN1_INTEGER *asn1_i;
BIGNUM *bignum;
@@ -238,6 +238,14 @@ x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
return serial;
}
+char *
+backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc)
+{
+ const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);
+
+ return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
+}
+
unsigned char *
x509_get_sha1_hash (X509 *cert, struct gc_arena *gc)
{
diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c
index 5db4f02..3fd861c 100644
--- a/src/openvpn/ssl_verify_polarssl.c
+++ b/src/openvpn/ssl_verify_polarssl.c
@@ -38,6 +38,8 @@
#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL)
#include "ssl_verify.h"
+#include <polarssl/error.h>
+#include <polarssl/bignum.h>
#include <polarssl/sha1.h>
#define MAX_SUBJECT_LENGTH 256
@@ -123,11 +125,49 @@ x509_get_username (char *cn, int cn_len,
}
char *
-x509_get_serial (x509_cert *cert, struct gc_arena *gc)
+backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
{
int ret = 0;
int i = 0;
char *buf = NULL;
+ size_t buflen = 0;
+ mpi serial_mpi = { 0 };
+ int retval = 0;
+
+ /* Transform asn1 integer serial into PolarSSL MPI */
+ mpi_init(&serial_mpi);
+ retval = mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len);
+ if (retval < 0)
+ {
+ char errbuf[128];
+ error_strerror(retval, errbuf, sizeof(errbuf));
+
+ msg(M_WARN, "Failed to retrieve serial from certificate: %s.", errbuf);
+ return NULL;
+ }
+
+ /* Determine decimal representation length, allocate buffer */
+ mpi_write_string(&serial_mpi, 10, buf, &buflen);
+ buf = gc_malloc(buflen, true, gc);
+
+ /* Write MPI serial as decimal string into buffer */
+ retval = mpi_write_string(&serial_mpi, 10, buf, &buflen);
+ if (retval < 0)
+ {
+ char errbuf[128];
+ error_strerror(retval, errbuf, sizeof(errbuf));
+
+ msg(M_WARN, "Failed to write serial to string: %s.", errbuf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+char *
+backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc)
+{
+ char *buf = NULL;
size_t len = cert->serial.len * 3 + 1;
buf = gc_malloc(len, true, gc);