.vitem &*${md5:*&<&'string'&>&*}*&
.cindex "MD5 hash"
.cindex "expansion" "MD5 hash"
+.cindex "certificate fingerprint"
.cindex "&%md5%& expansion item"
The &%md5%& operator computes the MD5 hash value of the string, and returns it
as a 32-digit hexadecimal number, in which any letters are in lower case.
.vitem &*${sha1:*&<&'string'&>&*}*&
.cindex "SHA-1 hash"
.cindex "expansion" "SHA-1 hashing"
+.cindex "certificate fingerprint"
.cindex "&%sha2%& expansion item"
The &%sha1%& operator computes the SHA-1 hash value of the string, and returns
it as a 40-digit hexadecimal number, in which any letters are in upper case.
+.vitem &*${sha256:*&<&'certificate'&>&*}*&
+.cindex "SHA-256 hash"
+.cindex "certificate fingerprint"
+.cindex "expansion" "SHA-256 hashing"
+.cindex "&%sha256%& expansion item"
+The &%sha256%& operator computes the SHA-256 hash fingerprint of the
+certificate,
+and returns
+it as a 64-digit hexadecimal number, in which any letters are in upper case.
+Only arguments which are a single variable of certificate type are supported.
+
+
.vitem &*${stat:*&<&'string'&>&*}*&
.cindex "expansion" "statting a file"
.cindex "file" "extracting characteristics"
JH/22 Expansion operators ${md5:string} and ${sha1::string} can now
operate on certificate variables to give certificate fingerprints
+ Also new ${sha256:cert_variable}.
Exim version 4.82
10. New variables "tls_(in,out)_(our,peer)cert" and expansion item
"certextract" to extract fields from them. Hash operators md5 and sha1
- work over them for generating fingerprints.
+ work over them for generating fingerprints, and a new sha256 operator
+ for them added.
Version 4.82
US"rxquote",
US"s",
US"sha1",
+ US"sha256",
US"stat",
US"str2b64",
US"strlen",
EOP_RXQUOTE,
EOP_S,
EOP_SHA1,
+ EOP_SHA256,
EOP_STAT,
EOP_STR2B64,
EOP_STRLEN,
switch(c)
{
#ifdef SUPPORT_TLS
- case EOP_SHA1:
case EOP_MD5:
+ case EOP_SHA1:
+ case EOP_SHA256:
if (s[1] == '$')
{
uschar * s1 = s;
}
continue;
+ case EOP_SHA256:
+#ifdef SUPPORT_TLS
+ if (vp && *(void **)vp->value)
+ {
+ uschar * cp = tls_cert_fprt_sha256(*(void **)vp->value);
+ yield = string_cat(yield, &size, &ptr, cp, (int)strlen(cp));
+ }
+ else
+#endif
+ expand_string_message = US"sha256 only supported for certificates";
+ continue;
+
/* Convert hex encoding to base64 encoding */
case EOP_HEX2B64:
extern uschar * tls_cert_fprt_md5(void *);
extern uschar * tls_cert_fprt_sha1(void *);
+extern uschar * tls_cert_fprt_sha256(void *);
extern int tls_client_start(int, host_item *, address_item *,
void *);
return fingerprint((gnutls_x509_crt_t)cert, GNUTLS_DIG_SHA1);
}
+uschar *
+tls_cert_fprt_sha256(void * cert)
+{
+return fingerprint((gnutls_x509_crt_t)cert, GNUTLS_DIG_SHA256);
+}
+
/* vi: aw ai sw=2
*/
return fingerprint((X509 *)cert, EVP_sha1());
}
+uschar *
+tls_cert_fprt_sha256(void * cert)
+{
+return fingerprint((X509 *)cert, EVP_sha256());
+}
+
/* vi: aw ai sw=2
*/
logwrite = ${certextract {subj_altname} {$tls_in_peercert} {SAN <$value>}{(no SAN)}}
# logwrite = ${certextract {ocsp_uri} {$tls_in_peercert} {OCU <$value>}{(no OCU)}}
logwrite = ${certextract {crl_uri} {$tls_in_peercert} {CRU <$value>}{(no CRU)}}
- logwrite = md5 fingerprint ${md5:$tls_in_peercert}
+ logwrite = md5 fingerprint ${md5:$tls_in_peercert}
logwrite = sha1 fingerprint ${sha1:$tls_in_peercert}
+ logwrite = sha256 fingerprint ${sha256:$tls_in_peercert}
# ----- Routers -----
logwrite = ${certextract {subj_altname} {$tls_in_peercert} {SAN <$value>}{(no SAN)}}
logwrite = ${certextract {ocsp_uri} {$tls_in_peercert} {OCU <$value>}{(no OCU)}}
logwrite = ${certextract {crl_uri} {$tls_in_peercert} {CRU <$value>}{(no CRU)}}
- logwrite = md5 fingerprint ${md5:$tls_in_peercert}
- logwrite = sha1 fingerprint ${sha1:$tls_in_peercert}
+ logwrite = md5 fingerprint ${md5:$tls_in_peercert}
+ logwrite = sha1 fingerprint ${sha1:$tls_in_peercert}
+ logwrite = sha256 fingerprint ${sha256:$tls_in_peercert}
# ----- Routers -----
1999-03-02 09:44:33 SG <6c 37 41 26 4d 5d f4 b5 31 10 67 ca fb 64 b6 22 98 62 f7 1e 95 7b 6c e6 74 47 21 f4 5e 89 36 3e b9 9c 8a c5 52 bb c4 af 12 93 26 3b d7 3d e0 56 71 1e 1d 21 20 02 ed f0 4e d5 5e 45 42 fd 3c 38 41 54 83 86 0b 3b bf c5 47 39 ff 15 ea 93 dc fd c7 3d 18 58 59 ca dd 2a d8 b9 f9 2f b9 76 93 f4 ae e3 91 56 80 2f 8c 04 2f ad 57 ef d2 51 19 f4 b4 ef 32 9c ac 3a 7c 0d b8 39 db b1 e3 30 73 1a>
1999-03-02 09:44:33 SAN <DNS=server2.example.com>
1999-03-02 09:44:33 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 md5 fingerprint C5FA6C8B1BE926DBC4E436AF08F92B55
+1999-03-02 09:44:33 md5 fingerprint C5FA6C8B1BE926DBC4E436AF08F92B55
1999-03-02 09:44:33 sha1 fingerprint 40B2135E6B67AE36A397696DA328423685E74CE3
+1999-03-02 09:44:33 sha256 fingerprint 6064D93E235FBA6FC66788F2AAC087752D856ECC7901FFCB8B53B21A09D232D2
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 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
1999-03-02 09:44:33 SAN <DNS=server2.example.com>
1999-03-02 09:44:33 OCU <http://oscp/example.com/>
1999-03-02 09:44:33 CRU <http://crl.example.com/latest.crl>
-1999-03-02 09:44:33 md5 fingerprint C5FA6C8B1BE926DBC4E436AF08F92B55
-1999-03-02 09:44:33 sha1 fingerprint 40B2135E6B67AE36A397696DA328423685E74CE3
+1999-03-02 09:44:33 md5 fingerprint C5FA6C8B1BE926DBC4E436AF08F92B55
+1999-03-02 09:44:33 sha1 fingerprint 40B2135E6B67AE36A397696DA328423685E74CE3
+1999-03-02 09:44:33 sha256 fingerprint 6064D93E235FBA6FC66788F2AAC087752D856ECC7901FFCB8B53B21A09D232D2
1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex H=[ip4.ip4.ip4.ip4] P=smtps X=TLSv1:AES256-SHA:256 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