aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteffan Karger2014-04-28 21:50:22 +0200
committerGert Doering2014-04-30 13:06:06 +0200
commit142d4dd2e98317a03ca9827f03fc4643fe922834 (patch)
tree24ee2e69ff78909560688a08e0be5ee40ece0883
parenta291825f7145679e6d1806029290402d0430b465 (diff)
downloadopenvpn-142d4dd2e98317a03ca9827f03fc4643fe922834.zip
openvpn-142d4dd2e98317a03ca9827f03fc4643fe922834.tar.gz
Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.
This changes the representation of the tls_serial_{n} environment variable from hex to decimal for PolarSSL builds, to match OpenSSL build behaviour. Because hex representation for serials makes sense too, and to ease transition for PolarSSL users, added tls_serial_hex_{n} that exports the serial in hex represenation for both crypto library backends. Signed-off-by: Steffan Karger <steffan@karger.me> Acked-by: Gert Doering <gert@greenie.muc.de> Message-Id: <535EB49E.5090809@karger.me> URL: http://article.gmane.org/gmane.network.openvpn.devel/8664 Signed-off-by: Gert Doering <gert@greenie.muc.de>
-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);