Support certificates in base64 expansion operator. Bug 1762
authorJeremy Harris <jgh146exb@wizmail.org>
Wed, 30 Dec 2015 20:39:45 +0000 (20:39 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Wed, 30 Dec 2015 20:39:45 +0000 (20:39 +0000)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/expand.c
src/src/functions.h
src/src/tlscert-gnu.c
src/src/tlscert-openssl.c
test/confs/2002
test/confs/2102
test/log/2002
test/log/2102

index 6f6ee4557282ce027ac6cadbdb2bfe88001e0902..14486cf5934ab829608eb303f34b77573d860a50 100644 (file)
@@ -10038,8 +10038,13 @@ string.
 .cindex "expansion" "base64 encoding"
 .cindex "base64 encoding" "in string expansion"
 .cindex "&%base64%& expansion item"
+.cindex certificate "base64 of DER"
 This operator converts a string into one that is base64 encoded.
 
+If the string is a single variable of type certificate,
+returns the base64 encoding of the DER form of the certificate.
+
+
 .vitem &*${base64d:*&<&'string'&>&*}*&
 .cindex "expansion" "base64 decoding"
 .cindex "base64 decoding" "in string expansion"
index e82feffccfaaef01e39f0fb51da71c40e2d224cb..e4d1f0607838f61667895e781ef9092db59c3935 100644 (file)
@@ -29,7 +29,7 @@ Version 4.87
  6. New $dkim_key_length variable.
 
  7. New base64d and base64 expansion items (the existing str2b64 being a
-    synonym of the latter).
+    synonym of the latter).  Add support in base64 for certificates.
 
 
 Version 4.86
index fad8cc7c7d3abfb67fbdfebfe5e0a909dba6bb4a..4d3dd6fd5197203d5b9a7e19c5a43fb4e6209d49 100644 (file)
@@ -6043,6 +6043,7 @@ while (*s != 0)
       case EOP_MD5:
       case EOP_SHA1:
       case EOP_SHA256:
+      case EOP_BASE64:
        if (s[1] == '$')
          {
          const uschar * s1 = s;
@@ -6888,15 +6889,17 @@ while (*s != 0)
 
       case EOP_STR2B64:
       case EOP_BASE64:
-        {
-        uschar *encstr = b64encode(sub, Ustrlen(sub));
-        yield = string_cat(yield, &size, &ptr, encstr, Ustrlen(encstr));
-        continue;
-        }
+       {
+       uschar * s = vp && *(void **)vp->value
+         ? tls_cert_der_b64(*(void **)vp->value)
+         : b64encode(sub, Ustrlen(sub));
+       yield = string_cat(yield, &size, &ptr, s, Ustrlen(s));
+       continue;
+       }
 
       case EOP_BASE64D:
         {
-        uschar *s;
+        uschar * s;
         int len = b64decode(sub, &s);
        if (len < 0)
           {
index d37b7489b73317b5b8eb7e415896c815a552223d..1d2d6b8ae2364b5d3b8a224f3c4c86ee398c476b 100644 (file)
@@ -39,6 +39,7 @@ extern uschar * tls_cert_subject(void *, uschar * mod);
 extern uschar * tls_cert_subject_altname(void *, uschar * mod);
 extern uschar * tls_cert_version(void *, uschar * mod);
 
+extern uschar * tls_cert_der_b64(void * cert);
 extern uschar * tls_cert_fprt_md5(void *);
 extern uschar * tls_cert_fprt_sha1(void *);
 extern uschar * tls_cert_fprt_sha256(void *);
index d00258b9e250dcbe0734f2f8079a0a5941051ebb..80b6fb142ccae4c59617ffc1469083ef1f6cebd6 100644 (file)
@@ -418,6 +418,28 @@ for(index = 0;; index++)
 /*****************************************************
 *  Certificate operator routines
 *****************************************************/
+uschar *
+tls_cert_der_b64(void * cert)
+{
+size_t len = 0;
+uschar * cp = NULL;
+int fail;
+
+if (  (fail = gnutls_x509_crt_export((gnutls_x509_crt_t)cert,
+       GNUTLS_X509_FMT_DER, cp, &len)) != GNUTLS_E_SHORT_MEMORY_BUFFER
+   || !(cp = store_get((int)len))
+   || (fail = gnutls_x509_crt_export((gnutls_x509_crt_t)cert,
+        GNUTLS_X509_FMT_DER, cp, &len))
+   )
+  {
+  log_write(0, LOG_MAIN, "TLS error in certificate export: %s",
+    gnutls_strerror(fail));
+  return NULL;
+  }
+return b64encode(cp, (int)len);
+}
+
+
 static uschar *
 fingerprint(gnutls_x509_crt_t cert, gnutls_digest_algorithm_t algo)
 {
index 94534d8082c507d82094504c367db4403fb96932..4d45ad9f91b7dd127fcba16085fadf3075bac9fd 100644 (file)
@@ -464,6 +464,26 @@ return list;
 /*****************************************************
 *  Certificate operator routines
 *****************************************************/
+uschar *
+tls_cert_der_b64(void * cert)
+{
+BIO * bp = BIO_new(BIO_s_mem());
+uschar * cp = NULL;
+
+if (!i2d_X509_bio(bp, (X509 *)cert))
+  log_write(0, LOG_MAIN, "TLS error in certificate export: %s",
+    ERR_error_string(ERR_get_error(), NULL));
+else
+  {
+  long len = BIO_get_mem_data(bp, &cp);
+  cp = b64encode(cp, (int)len);
+  }
+
+BIO_free(bp);
+return cp;
+}
+
+
 static uschar *
 fingerprint(X509 * cert, const EVP_MD * fdig)
 {
index 7299122e8fa2c1cd05304a695262c19e9392eafb..76e6f1eec0f0dd8a48af2caf2168ee1487f5ec8a 100644 (file)
@@ -64,6 +64,7 @@ check_recipient:
          logwrite =  md5    fingerprint ${md5:$tls_in_peercert}
          logwrite =  sha1 fingerprint ${sha1:$tls_in_peercert}
          logwrite =  sha256 fingerprint ${sha256:$tls_in_peercert}
+         logwrite =  der_b64 ${base64:$tls_in_peercert}
 
 
 # ----- Routers -----
index 804a846bf0e11c4961c98c92cd181d81542312fa..1de92e96296bcea5deef3a93121774c8dc4d56fb 100644 (file)
@@ -68,6 +68,7 @@ check_recipient:
          logwrite =  md5    fingerprint ${md5:$tls_in_peercert}
          logwrite =  sha1   fingerprint ${sha1:$tls_in_peercert}
          logwrite =  sha256 fingerprint ${sha256:$tls_in_peercert}
+         logwrite =  der_b64 ${base64:$tls_in_peercert}
 
 
 # ----- Routers -----
index e0eb36ccb96cb3991ccfbe5eb281b859cae8685a..933905460ed80f2d582ccf7073bfaba5a92b361a 100644 (file)
@@ -23,6 +23,7 @@
 1999-03-02 09:44:33 md5    fingerprint 33728C89BBE99028425D137F7508F74A
 1999-03-02 09:44:33 sha1 fingerprint 1A420D865B90068FB822E71567A456A3578D26AA
 1999-03-02 09:44:33 sha256 fingerprint 7E194665AE12FD9AF8E604427D512E846E75EC96032BF78BAD707426F01CFF17
+1999-03-02 09:44:33 der_b64 MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDExMjM0MzhaFw0zODAxMDExMjM0MzhaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALoxxS9eRRSkEJF5CmlLToLY3886wsCOc+vuBo+2V69Q7aCC3Wa13UTZ7SVPhliw29gl48Ua7Go5E6E4+6n7SNL+VfuMtNg2zs4BIhXTfiPZ9U2YF77+Y64MFPBxK98F/RB/wjqAiWf5aigaQCSGX7Bf1bb1s3UwCi0M/wXHYj7TAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHgYDVR0RBBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOBgQCZCepTW/JRRZlxxEIcQVlQLpdcxuJnYvNbZwzn7Os0K7og1S7jl4PDncao6APk6f4WAfFjb4ZZc1NytSHPLuodWToY1bUzIBMKwk9Jof2yw2mr/3ElyzRDlVmXri+6b0X5WmfMeWI7npeb6Pl6n18tTYKkGGcFwsFsC+CeuLOzNw==
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=[ip4.ip4.ip4.ip4] P=smtps X=TLS1.x:xxxxRSA_AES_256_CBC_SHAnnn:256 CV=yes DN="CN=server2.example.com" S=sss
 1999-03-02 09:44:33 Start queue run: pid=pppp -qf
 1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER <CALLER@test.ex> R=abc T=local_delivery
index 48e58605392781c92cf0d2724f984e582f3b82a0..838930a8241bca84ff570984e0b34a1e2600c162 100644 (file)
@@ -26,6 +26,7 @@
 1999-03-02 09:44:33 md5    fingerprint 33728C89BBE99028425D137F7508F74A
 1999-03-02 09:44:33 sha1   fingerprint 1A420D865B90068FB822E71567A456A3578D26AA
 1999-03-02 09:44:33 sha256 fingerprint 7E194665AE12FD9AF8E604427D512E846E75EC96032BF78BAD707426F01CFF17
+1999-03-02 09:44:33 der_b64 MIICiDCCAfGgAwIBAgICAMkwDQYJKoZIhvcNAQELBQAwMzEUMBIGA1UEChMLZXhhbXBsZS5jb20xGzAZBgNVBAMTEmNsaWNhIFNpZ25pbmcgQ2VydDAeFw0xMjExMDExMjM0MzhaFw0zODAxMDExMjM0MzhaMB4xHDAaBgNVBAMTE3NlcnZlcjIuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALoxxS9eRRSkEJF5CmlLToLY3886wsCOc+vuBo+2V69Q7aCC3Wa13UTZ7SVPhliw29gl48Ua7Go5E6E4+6n7SNL+VfuMtNg2zs4BIhXTfiPZ9U2YF77+Y64MFPBxK98F/RB/wjqAiWf5aigaQCSGX7Bf1bb1s3UwCi0M/wXHYj7TAgMBAAGjgb8wgbwwDgYDVR0PAQH/BAQDAgTwMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLmV4YW1wbGUuY29tL2xhdGVzdC5jcmwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb3NjcC9leGFtcGxlLmNvbS8wHgYDVR0RBBcwFYITc2VydmVyMi5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOBgQCZCepTW/JRRZlxxEIcQVlQLpdcxuJnYvNbZwzn7Os0K7og1S7jl4PDncao6APk6f4WAfFjb4ZZc1NytSHPLuodWToY1bUzIBMKwk9Jof2yw2mr/3ElyzRDlVmXri+6b0X5WmfMeWI7npeb6Pl6n18tTYKkGGcFwsFsC+CeuLOzNw==
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=[ip4.ip4.ip4.ip4] P=smtps X=TLSv1:AES256-SHA:256 CV=yes DN="/CN=server2.example.com" S=sss
 1999-03-02 09:44:33 Start queue run: pid=pppp -qf
 1999-03-02 09:44:33 10HmaX-0005vi-00 => CALLER <CALLER@test.ex> R=abc T=local_delivery