Skip to contentSkip to conversation

Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.

PATCH In review Steffan Karger 2 participants 6 messages Apr 27, 2014 – Apr 30, 2014

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 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.

---
 doc/openvpn.8                     |  6 ++++++
 src/openvpn/ssl_verify.c          |  5 +++++
 src/openvpn/ssl_verify_backend.h  | 19 +++++++++++++++++--
 src/openvpn/ssl_verify_openssl.c  |  8 ++++++++
 src/openvpn/ssl_verify_polarssl.c | 40 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 76 insertions(+), 2 deletions(-)
doc/openvpn.8 +6 -0
index ae3a4e0..2f9ebdf 100644
@@ -6102,6 +6102,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
src/openvpn/ssl_verify.c +5 -0
index 7a9a56e..2d10d15 100644
@@ -435,6 +435,11 @@ verify_cert_set_env(struct env_set *es, openvpn_x509_cert_t *peer_cert, int cert
   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);
 }
 
src/openvpn/ssl_verify_backend.h +17 -2
index fa4369d..4e9ad60 100644
@@ -113,18 +113,33 @@ result_t backend_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 *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:
  *
  * X509_{cert_depth}_{name}={value}
src/openvpn/ssl_verify_openssl.c +8 -0
index 0f571d9..98a888a 100644
@@ -238,6 +238,14 @@ backend_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)
 {
src/openvpn/ssl_verify_polarssl.c +40 -0
index 1b2990c..1d622cc 100644
@@ -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/oid.h>
 #include <polarssl/sha1.h>
 
@@ -127,6 +129,44 @@ char *
 backend_x509_get_serial (x509_crt *cert, struct gc_arena *gc)
 {
   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];
+      polarssl_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];
+      polarssl_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 (x509_crt *cert, struct gc_arena *gc)
+{
+  char *buf = NULL;
   size_t len = cert->serial.len * 3 + 1;
 
   buf = gc_malloc(len, true, gc);
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 2/2 Fix OCSP_check.sh to also use decimal for stdout verification.

This is an extra fix needed on top of 959d607, which already changes the serial parameter to correctly use decimal representation.

---
 contrib/OCSP_check/OCSP_check.sh | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
contrib/OCSP_check/OCSP_check.sh +3 -3
index 7e9e1e8..553c3dc 100644
@@ -71,7 +71,7 @@ if [ $check_depth -eq -1 ] || [ $cur_depth -eq $check_depth ]; then
   # - The serial number must not be empty
   # - The exit status of "openssl ocsp" must be zero
   # - The output of the above command must contain the line
-  #   "0x${serial}: good"
+  #   "${serial}: good"
   #
   # Everything else fails with exit status 1.
 
@@ -83,7 +83,7 @@ if [ $check_depth -eq -1 ] || [ $cur_depth -eq $check_depth ]; then
     # Sample output that is assumed here:
     #
     # Response verify OK
-    # 0x428740A5: good
+    # 4287405: good
     #      This Update: Apr 24 19:38:49 2010 GMT
     #      Next Update: May  2 14:23:42 2010 GMT
     #
@@ -101,7 +101,7 @@ if [ $check_depth -eq -1 ] || [ $cur_depth -eq $check_depth ]; then
 
     if [ $? -eq 0 ]; then
       # check that it's good
-      if echo "$status" | grep -Fq "0x${serial}: good"; then
+      if echo "$status" | grep -Fq "^${serial}: good"; then
         exit 0
       fi
     fi
Signature · 1 line
1.8.3.2
#2 lore raw

[Openvpn-devel] [PATCH applied] Re: Fix OCSP_check.sh to also use decimal for stdout verification.

ACK.

Your patch has been applied to the master and release/2.3 branches.

commit 6ea78cbef6367590567156a20106c620fec224c9 (master) commit 78e1175cc510a98775eb393ec6d1ebf8309019c0 (release/2.3)

Author: Steffan Karger
Date:   Sun Apr 27 10:49:21 2014 +0200
     Fix OCSP_check.sh to also use decimal for stdout verification.

     Signed-off-by: Steffan Karger <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8650
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#3 lore raw
In reply to Steffan Karger

ACK. Tested both OpenSSL and PolarSSL builds on the server side, and certificate reporting is consistent, if differing in uppercase/lowercase:

OpenSSL:

tls_serial_0=22
tls_serial_1=13617978572412530086
tls_serial_hex_0=16
tls_serial_hex_1=bc:fc:c7:5c:47:87:ad:a6

PolarSSL:

tls_serial_0=22
tls_serial_1=13617978572412530086
tls_serial_hex_0=16
tls_serial_hex_1=BC:FC:C7:5C:47:87:AD:A6

(I'm too lazy right now to actually multiply out whether the hex representation of cert 1 matches the decimal representation, but if both libraries return the same thing, that is good enough for me)

Your patch has been applied to the master branch ONLY, as it doesn't work with PolarSSL 1.2 (no "x509_crt" type there) - so 2.3.x still has inconsistency here.

commit f80a52b09eed8e5e0cad990c56ec99256d6cc2d0 (master)

Author: Steffan Karger
Date:   Sun Apr 27 10:49:20 2014 +0200
     Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.

     Signed-off-by: Steffan Karger <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8649
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering

#4 lore raw

Hi,

Quoted 3 lines · Gert Doering

Your patch has been applied to the master branch ONLY, as it doesn't work with PolarSSL 1.2 (no "x509_crt" type there) - so 2.3.x still has inconsistency here.

Right, different PolarSSL API. Attached a reworked patch for 2.3. Same functionality, slightly different API calls.

-Steffan

From 52d5f5a76dc70e20da740acd347cbdaab40b60df Mon Sep 17 00:00:00 2001
From: Steffan Karger <[email protected]...>
Date: Mon, 28 Apr 2014 21:50:22 +0200
Subject: [PATCH] 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.

---
 doc/openvpn.8                     |  6 ++++++
 src/openvpn/ssl_verify.c          |  9 +++++++--
 src/openvpn/ssl_verify_backend.h  | 21 +++++++++++++++++---
 src/openvpn/ssl_verify_openssl.c  | 10 +++++++++-
 src/openvpn/ssl_verify_polarssl.c | 42 ++++++++++++++++++++++++++++++++++++++-
 5 files changed, 81 insertions(+), 7 deletions(-)
doc/openvpn.8 +6 -0
index 7a33f8a..585751b 100644
@@ -6048,6 +6048,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
src/openvpn/ssl_verify.c +7 -2
index 0670f2a..c90c2c3 100644
@@ -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))
     {
src/openvpn/ssl_verify_backend.h +18 -3
index 1658cc0..6f118c9 100644
@@ -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:
src/openvpn/ssl_verify_openssl.c +9 -1
index 91a42b2..19982ae 100644
@@ -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)
 {
src/openvpn/ssl_verify_polarssl.c +41 -1

58 lines not on this page · raw message

Signature · 1 line
1.9.1
#5 lore raw

ACK.

Patch is slightly bigger than f80a52b09eed8e5e0cad ("the same thing for master") as it also backports the renaming of x509_get_serial() to backend_x509_get_serial() - which is purely cosmetic, but now the code is better aligned.

Your patch has been applied to the release/2.3 branch.

commit 142d4dd2e98317a03ca9827f03fc4643fe922834 (release/2.3)

Author: Steffan Karger
Date:   Mon Apr 28 21:50:22 2014 +0200
     Make serial env exporting consistent amongst OpenSSL and PolarSSL builds.

     Signed-off-by: Steffan Karger <[email protected]...>
     Acked-by: Gert Doering <[email protected]...>
     Message-Id: <[email protected]...>
     URL: http://article.gmane.org/gmane.network.openvpn.devel/8664
     Signed-off-by: Gert Doering <[email protected]...>

--
kind regards,

Gert Doering