diff --git a/src/ngx_http_voms_module.cpp b/src/ngx_http_voms_module.cpp
index 042bd634b07284689d750194b97077f1de0b3b32..2da800aeb37a805283098c5b13e23a96097cb747 100644
--- a/src/ngx_http_voms_module.cpp
+++ b/src/ngx_http_voms_module.cpp
@@ -27,6 +27,7 @@ extern "C" {
 #include <numeric>
 #include <string>
 #include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/replace.hpp>
 #include <boost/optional.hpp>
 
 using BioPtr = std::unique_ptr<BIO, decltype(&BIO_free)>;
@@ -208,223 +209,6 @@ static ngx_http_variable_t variables[] = {
     ngx_http_null_variable  //
 };
 
-static std::string to_rfc2253(X509_NAME* name)
-{
-  std::string result;
-
-  BioPtr bio(BIO_new(BIO_s_mem()), &BIO_free);
-  if (!bio) {
-    return result;
-  }
-
-  if (X509_NAME_print_ex(bio.get(), name, 0, XN_FLAG_RFC2253) < 0) {
-    return result;
-  }
-
-  auto len = BIO_pending(bio.get());
-  result.resize(len);
-
-  BIO_read(bio.get(), &result[0], result.size());
-
-  return result;
-}
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static uint32_t X509_get_extension_flags(X509* x)
-{
-  return x->ex_flags;
-}
-#endif
-
-static bool is_proxy(X509* cert)
-{
-  return X509_get_extension_flags(cert) & EXFLAG_PROXY;
-}
-
-
-static X509* get_ee_cert(ngx_http_request_t* r){
-
-  auto chain = SSL_get_peer_cert_chain(r->connection->ssl->connection);
-  if (!chain) {
-    ngx_log_error(
-        NGX_LOG_ERR, r->connection->log, 0, "SSL_get_peer_cert_chain() failed");
-    return nullptr;
-  }
-
-  X509* ee_cert = nullptr;
-
-  if (sk_X509_num(chain) == 0) {
-    ee_cert = SSL_get_peer_certificate(r->connection->ssl->connection);
-  } else {
-    // find first non-proxy
-    for (int i = 0; i != sk_X509_num(chain); ++i) {
-      auto cert = sk_X509_value(chain, i);
-      if (cert && !is_proxy(cert)) {
-        ee_cert = cert;
-        break;
-      }
-    }
-  }
-
-  return ee_cert;
-}
-
-static ngx_int_t get_ssl_client_ee_cert_raw(ngx_http_request_t* r,
-                                            ngx_str_t *s)
-{
-
-  ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
-  s->len = 0;
-
-  auto ee_cert = get_ee_cert(r);
-
-  if (!ee_cert) {
-    ngx_log_error(NGX_LOG_DEBUG,
-                  r->connection->log,
-                  0,
-                  "cannot identify end-entity certificate");
-    return NGX_OK;
-  }
-
-  
-  BioPtr bio(BIO_new(BIO_s_mem()), &BIO_free);
-  if (!bio) {
-    ngx_log_error(NGX_LOG_ERR,
-        r->connection->log,
-        0,
-        "cannot create OpenSSL BIO");
-    return NGX_ERROR;
-  }
-
-  if (PEM_write_bio_X509(bio.get(), ee_cert) == 0) {
-    ngx_log_error(NGX_LOG_ERR,
-        r->connection->log,
-        0,
-        "cannot write EEC to OpenSSL bio");
-    return NGX_ERROR;
-  }
-
-  size_t len = BIO_pending(bio.get());
-
-  s->len = len;
-  s->data = static_cast<u_char*>(ngx_pnalloc(r->pool, len));
-
-  if (s->data == nullptr) {
-    return NGX_ERROR;
-  }
-
-  BIO_read(bio.get(),s->data,len);
-
-  return NGX_OK;
-}
-
-static ngx_int_t get_ssl_client_ee_cert(ngx_http_request_t* r,
-                                        ngx_http_variable_value_t* v,
-                                        uintptr_t data)
-{
-
-  ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
-
-  v->not_found = 1;
-  v->valid = 0;
-
-  ngx_str_t cert;
-
-  if (get_ssl_client_ee_cert_raw(r, &cert) != NGX_OK) {
-    return NGX_ERROR;
-  }
-
-  if (cert.len == 0) {
-    v->len = 0;
-    return NGX_OK;
-  }
-
-  size_t len = cert.len -1;
-
-  for (int i=0; i < cert.len - 1; i++) {
-    if (cert.data[i] == '\n') {
-      len++;
-    }
-  }
-
-  auto buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, len));
-
-  if (!buffer) {
-    return NGX_OK;
-  }
-
-  u_char* p = buffer;
-
-  for (int i=0; i < cert.len - 1; i++) {
-    *p++ = cert.data[i];
-    if (cert.data[i] == '\n') {
-      *p++ = '\t';
-    }
-  }
-
-  v->data = buffer;
-  v->len = len;
-  v->valid = 1;
-  v->not_found = 0;
-  v->no_cacheable = 0;
-  return NGX_OK;
-
-}
-
-
-static ngx_int_t get_ssl_client_ee_dn(ngx_http_request_t* r,
-                                      ngx_http_variable_value_t* v,
-                                      uintptr_t data)
-{
-  ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
-
-  v->not_found = 1;
-  v->valid = 0;
-
-  auto ee_cert = get_ee_cert(r);
-
-  if (!ee_cert) {
-    ngx_log_error(NGX_LOG_DEBUG,
-                  r->connection->log,
-                  0,
-                  "cannot identify end-entity certificate");
-    return NGX_OK;
-  }
-
-  X509_NAME* dn;
-
-  switch (static_cast<EeDn>(data)) {
-    case EeDn::SUBJECT:
-      dn = X509_get_subject_name(ee_cert);
-      break;
-    case EeDn::ISSUER:
-      dn = X509_get_issuer_name(ee_cert);
-      break;
-    default:
-      dn = nullptr;
-  }
-
-  if (!dn) {
-    ngx_log_error(
-        NGX_LOG_DEBUG, r->connection->log, 0, "cannot get DN from certificate");
-    return NGX_OK;
-  }
-  std::string value = to_rfc2253(dn);
-
-  auto buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, value.size()));
-  if (!buffer) {
-    return NGX_OK;
-  }
-  ngx_memcpy(buffer, value.c_str(), value.size());
-
-  v->data = buffer;
-  v->len = value.size();
-  v->valid = 1;
-  v->not_found = 0;
-  v->no_cacheable = 0;
-  return NGX_OK;
-}
-
 static ngx_int_t add_variables(ngx_conf_t* cf)
 {
   for (ngx_http_variable_t* v = variables; v->name.len; ++v) {
@@ -672,3 +456,201 @@ std::string get_voms_serial(VomsAc const& ac)
 {
   return ac.serial;
 }
+
+static std::string to_rfc2253(X509_NAME* name)
+{
+  std::string result;
+
+  BioPtr bio(BIO_new(BIO_s_mem()), &BIO_free);
+  if (!bio) {
+    return result;
+  }
+
+  if (X509_NAME_print_ex(bio.get(), name, 0, XN_FLAG_RFC2253) < 0) {
+    return result;
+  }
+
+  auto len = BIO_pending(bio.get());
+  result.resize(len);
+
+  BIO_read(bio.get(), &result[0], result.size());
+
+  return result;
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+static uint32_t X509_get_extension_flags(X509* x)
+{
+  return x->ex_flags;
+}
+#endif
+
+static bool is_proxy(X509* cert)
+{
+  return X509_get_extension_flags(cert) & EXFLAG_PROXY;
+}
+
+static X509* get_ee_cert(ngx_http_request_t* r)
+{
+  auto chain = SSL_get_peer_cert_chain(r->connection->ssl->connection);
+  if (!chain) {
+    ngx_log_error(
+        NGX_LOG_ERR, r->connection->log, 0, "SSL_get_peer_cert_chain() failed");
+    return nullptr;
+  }
+
+  X509* ee_cert = nullptr;
+
+  if (sk_X509_num(chain) == 0) {
+    ee_cert = SSL_get_peer_certificate(r->connection->ssl->connection);
+  } else {
+    // find first non-proxy
+    for (int i = 0; i != sk_X509_num(chain); ++i) {
+      auto cert = sk_X509_value(chain, i);
+      if (cert && !is_proxy(cert)) {
+        ee_cert = cert;
+        break;
+      }
+    }
+  }
+
+  return ee_cert;
+}
+
+static ngx_int_t get_ssl_client_ee_dn(ngx_http_request_t* r,
+                                      ngx_http_variable_value_t* v,
+                                      uintptr_t data)
+{
+  ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
+
+  v->not_found = 1;
+  v->valid = 0;
+
+  auto ee_cert = get_ee_cert(r);
+
+  if (!ee_cert) {
+    ngx_log_error(NGX_LOG_DEBUG,
+                  r->connection->log,
+                  0,
+                  "cannot identify end-entity certificate");
+    return NGX_OK;
+  }
+
+  X509_NAME* dn;
+
+  switch (static_cast<EeDn>(data)) {
+    case EeDn::SUBJECT:
+      dn = X509_get_subject_name(ee_cert);
+      break;
+    case EeDn::ISSUER:
+      dn = X509_get_issuer_name(ee_cert);
+      break;
+    default:
+      dn = nullptr;
+  }
+
+  if (!dn) {
+    ngx_log_error(
+        NGX_LOG_DEBUG, r->connection->log, 0, "cannot get DN from certificate");
+    return NGX_OK;
+  }
+  std::string value = to_rfc2253(dn);
+
+  auto buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, value.size()));
+  if (!buffer) {
+    return NGX_OK;
+  }
+  ngx_memcpy(buffer, value.c_str(), value.size());
+
+  v->data = buffer;
+  v->len = value.size();
+  v->valid = 1;
+  v->not_found = 0;
+  v->no_cacheable = 0;
+  return NGX_OK;
+}
+
+static ngx_int_t get_ssl_client_ee_cert_raw(ngx_http_request_t* r,
+                                            ngx_str_t* result)
+{
+  ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
+
+  *result = {};
+
+  auto ee_cert = get_ee_cert(r);
+
+  if (!ee_cert) {
+    ngx_log_error(NGX_LOG_DEBUG,
+                  r->connection->log,
+                  0,
+                  "cannot identify end-entity certificate");
+    return NGX_OK;
+  }
+
+  BioPtr bio(BIO_new(BIO_s_mem()), &BIO_free);
+  if (!bio) {
+    ngx_log_error(
+        NGX_LOG_ERR, r->connection->log, 0, "cannot create OpenSSL BIO");
+    return NGX_ERROR;
+  }
+
+  if (PEM_write_bio_X509(bio.get(), ee_cert) == 0) {
+    ngx_log_error(
+        NGX_LOG_ERR, r->connection->log, 0, "cannot write EEC to OpenSSL BIO");
+    return NGX_ERROR;
+  }
+
+  result->len = BIO_pending(bio.get());
+  result->data = static_cast<u_char*>(ngx_pnalloc(r->pool, result->len));
+
+  if (result->data == nullptr) {
+    return NGX_ERROR;
+  }
+
+  BIO_read(bio.get(), result->data, result->len);
+
+  return NGX_OK;
+}
+
+static ngx_int_t get_ssl_client_ee_cert(ngx_http_request_t* r,
+                                        ngx_http_variable_value_t* v,
+                                        uintptr_t data)
+{
+  ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "%s", __func__);
+
+  v->not_found = 1;
+  v->valid = 0;
+
+  ngx_str_t cert{};
+
+  if (get_ssl_client_ee_cert_raw(r, &cert) != NGX_OK) {
+    return NGX_ERROR;
+  }
+
+  if (cert.len == 0) {
+    v->len = 0;
+    return NGX_OK;
+  }
+
+  // the first line is not prepended with a tab
+  auto const n_tabs = std::count(cert.data, cert.data + cert.len, '\n') - 1;
+  // cert is null-terminated
+  auto const len = cert.len - 1 + n_tabs;
+
+  auto const buffer = static_cast<u_char*>(ngx_pnalloc(r->pool, len));
+
+  if (!buffer) {
+    return NGX_OK;
+  }
+
+  // the last newline is not to be followed by a tab
+  boost::algorithm::replace_all_copy(
+      buffer, boost::make_iterator_range_n(cert.data, len - 1), "\n", "\n\t");
+
+  v->data = buffer;
+  v->len = len;
+  v->valid = 1;
+  v->not_found = 0;
+  v->no_cacheable = 0;
+  return NGX_OK;
+}