From 59b87190a41a0ac34aee74edfff9184785a73485 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Wed, 30 Dec 2015 20:39:45 +0000 Subject: [PATCH] Support certificates in base64 expansion operator. Bug 1762 --- doc/doc-docbook/spec.xfpt | 5 +++++ doc/doc-txt/NewStuff | 2 +- src/src/expand.c | 15 +++++++++------ src/src/functions.h | 1 + src/src/tlscert-gnu.c | 22 ++++++++++++++++++++++ src/src/tlscert-openssl.c | 20 ++++++++++++++++++++ test/confs/2002 | 1 + test/confs/2102 | 1 + test/log/2002 | 1 + test/log/2102 | 1 + 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 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 R=abc T=local_delivery -- 2.30.2