]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.
authorSteffan Karger <steffan@karger.me>
Mon, 28 Apr 2014 19:50:22 +0000 (21:50 +0200)
committerGert Doering <gert@greenie.muc.de>
Wed, 30 Apr 2014 11:06:06 +0000 (13:06 +0200)
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>
doc/openvpn.8
src/openvpn/ssl_verify.c
src/openvpn/ssl_verify_backend.h
src/openvpn/ssl_verify_openssl.c
src/openvpn/ssl_verify_polarssl.c

index ec56030441be8634bb462c900c07459ef26026de..786719dfe6e253b4066655b44f38d57d0ce9f3aa 100644 (file)
@@ -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
index 0670f2a5a435f6c175123ff3ba2c441a197bc110..c90c2c38730c1adde98fa4557596ff24391481d1 100644 (file)
@@ -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))
     {
index 1658cc02c1ea028b96614c2de993d8ffa4a19f3d..6f118c96a4910a7eb571a18fd6c77f547fbec146 100644 (file)
@@ -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:
index 91a42b2fc99b7e9ac2b50bef24fd395138370626..19982ae8f14efcae1ced8d74da3c3f6925105e57 100644 (file)
@@ -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)
 {
index 5db4f0273099333e66f9644a60acefc47cbdebb4..3fd861cb6f179cb73f8952acf286cd5821eaadd0 100644 (file)
@@ -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,10 +125,48 @@ 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;