summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2015-12-30 20:39:45 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2015-12-30 20:39:45 +0000
commit59b87190a41a0ac34aee74edfff9184785a73485 (patch)
tree9475c507c34819a1cc84d7a5513c4f986bcb266b
parent9aa35e9ce70bb9bf61e4e4dbc7089e49eeded1b3 (diff)
Support certificates in base64 expansion operator. Bug 1762
-rw-r--r--doc/doc-docbook/spec.xfpt5
-rw-r--r--doc/doc-txt/NewStuff2
-rw-r--r--src/src/expand.c15
-rw-r--r--src/src/functions.h1
-rw-r--r--src/src/tlscert-gnu.c22
-rw-r--r--src/src/tlscert-openssl.c20
-rw-r--r--test/confs/20021
-rw-r--r--test/confs/21021
-rw-r--r--test/log/20021
-rw-r--r--test/log/21021
10 files changed, 62 insertions, 7 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 6f6ee4557..14486cf59 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -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"
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index e82feffcc..e4d1f0607 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -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
diff --git a/src/src/expand.c b/src/src/expand.c
index fad8cc7c7..4d3dd6fd5 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -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)
{
diff --git a/src/src/functions.h b/src/src/functions.h
index d37b7489b..1d2d6b8ae 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -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 *);
diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c
index d00258b9e..80b6fb142 100644
--- a/src/src/tlscert-gnu.c
+++ b/src/src/tlscert-gnu.c
@@ -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)
{
diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c
index 94534d808..4d45ad9f9 100644
--- a/src/src/tlscert-openssl.c
+++ b/src/src/tlscert-openssl.c
@@ -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)
{
diff --git a/test/confs/2002 b/test/confs/2002
index 7299122e8..76e6f1eec 100644
--- a/test/confs/2002
+++ b/test/confs/2002
@@ -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 -----
diff --git a/test/confs/2102 b/test/confs/2102
index 804a846bf..1de92e962 100644
--- a/test/confs/2102
+++ b/test/confs/2102
@@ -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 -----
diff --git a/test/log/2002 b/test/log/2002
index e0eb36ccb..933905460 100644
--- a/test/log/2002
+++ b/test/log/2002
@@ -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
diff --git a/test/log/2102 b/test/log/2102
index 48e586053..838930a82 100644
--- a/test/log/2102
+++ b/test/log/2102
@@ -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