From 25ba25448b55c2fd5ea9b1aeed82e02d59816a07 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Tue, 13 May 2014 23:50:13 +0100 Subject: [PATCH] Extractors for certificate time fields support integer output modifier --- doc/doc-docbook/spec.xfpt | 34 +++++++++++++++++++--------------- src/src/tlscert-gnu.c | 21 +++++++++++++++------ src/src/tlscert-openssl.c | 23 +++++++++++++++++++---- test/confs/2002 | 1 + test/confs/2102 | 1 + test/log/2002 | 1 + test/log/2102 | 1 + 7 files changed, 57 insertions(+), 25 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index e85ba6629..ce4d0ba1d 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -8899,8 +8899,8 @@ the certificate. Supported fields are: &`serial_number `& &`subject `& RFC4514 DN &`issuer `& RFC4514 DN -&`notbefore `& -&`notafter `& +&`notbefore `& time +&`notafter `& time &`sig_algorithm `& &`signature `& &`subj_altname `& tagged list @@ -8919,18 +8919,6 @@ extracted is used. Some field names take optional modifiers, appended and separated by commas. -The field selectors marked as "list" above return a list, -newline-separated by default, -(embedded separator characters in elements are doubled). -The separator may be changed by a modifier of -a right angle-bracket followed immediately by the new separator. - -The field selectors marked as "tagged" above -prefix each list element with a type string and an equals sign. -Elements of only one type may be selected by a modifier -which is one of "dns", "uri" or "mail"; -if so the elenment tags are omitted. - The field selectors marked as "RFC4514" above output a Distinguished Name string which is not quite @@ -8943,7 +8931,23 @@ The separator may be changed by another modifer of a right angle-bracket followed immediately by the new separator. Recognised RDN type labels include "CN", "O", "OU" and "DC". -Field values are generally presented in human-readable form. +The field selectors marked as "time" above +may output a number of seconds since epoch +if the modifier "int" is used. + +The field selectors marked as "list" above return a list, +newline-separated by default, +(embedded separator characters in elements are doubled). +The separator may be changed by a modifier of +a right angle-bracket followed immediately by the new separator. + +The field selectors marked as "tagged" above +prefix each list element with a type string and an equals sign. +Elements of only one type may be selected by a modifier +which is one of "dns", "uri" or "mail"; +if so the elenment tags are omitted. + +If not otherwise noted field values are presented in human-readable form. .wen .vitem "&*${dlfunc{*&<&'file'&>&*}{*&<&'function'&>&*}{*&<&'arg'&>&*}&&& diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c index 085e05689..9b9c83d8b 100644 --- a/src/src/tlscert-gnu.c +++ b/src/src/tlscert-gnu.c @@ -84,11 +84,18 @@ return NULL; static uschar * -time_copy(time_t t) +time_copy(time_t t, uschar * mod) { -uschar * cp = store_get(32); -struct tm * tp = gmtime(&t); -size_t len = strftime(CS cp, 32, "%b %e %T %Y %Z", tp); +uschar * cp; +struct tm * tp; +size_t len; + +if (mod && Ustrcmp(mod, "int") == 0) + return string_sprintf("%u", (unsigned)t); + +cp = store_get(32); +tp = gmtime(&t); +len = strftime(CS cp, 32, "%b %e %T %Y %Z", tp); return len > 0 ? cp : NULL; } @@ -116,14 +123,16 @@ uschar * tls_cert_not_after(void * cert, uschar * mod) { return time_copy( - gnutls_x509_crt_get_expiration_time((gnutls_x509_crt_t)cert)); + gnutls_x509_crt_get_expiration_time((gnutls_x509_crt_t)cert), + mod); } uschar * tls_cert_not_before(void * cert, uschar * mod) { return time_copy( - gnutls_x509_crt_get_activation_time((gnutls_x509_crt_t)cert)); + gnutls_x509_crt_get_activation_time((gnutls_x509_crt_t)cert), + mod); } uschar * diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c index 00a3cb555..29095782a 100644 --- a/src/src/tlscert-openssl.c +++ b/src/src/tlscert-openssl.c @@ -89,11 +89,26 @@ return cp; } static uschar * -asn1_time_copy(const ASN1_TIME * time) +bio_string_time_to_int(BIO * bp, int len) +{ +uschar * cp = US""; +struct tm t; +len = len > 0 ? (int) BIO_get_mem_data(bp, &cp) : 0; +/*XXX %Z might be glibc-specific? */ +(void) strptime(CS cp, "%b%t%e%t%T%t%Y%t%Z", &t); +BIO_free(bp); +/*XXX timegm might not be portable? */ +return string_sprintf("%u", (unsigned) timegm(&t)); +} + +static uschar * +asn1_time_copy(const ASN1_TIME * time, uschar * mod) { BIO * bp = BIO_new(BIO_s_mem()); int len = ASN1_TIME_print(bp, time); -return bio_string_copy(bp, len); +return mod && Ustrcmp(mod, "int") == 0 + ? bio_string_time_to_int(bp, len) + : bio_string_copy(bp, len); } static uschar * @@ -118,13 +133,13 @@ return mod ? tls_field_from_dn(cp, mod) : cp; uschar * tls_cert_not_before(void * cert, uschar * mod) { -return asn1_time_copy(X509_get_notBefore((X509 *)cert)); +return asn1_time_copy(X509_get_notBefore((X509 *)cert), mod); } uschar * tls_cert_not_after(void * cert, uschar * mod) { -return asn1_time_copy(X509_get_notAfter((X509 *)cert)); +return asn1_time_copy(X509_get_notAfter((X509 *)cert), mod); } uschar * diff --git a/test/confs/2002 b/test/confs/2002 index dc958ec38..9f664e8f7 100644 --- a/test/confs/2002 +++ b/test/confs/2002 @@ -53,6 +53,7 @@ check_recipient: logwrite = IN <${certextract {issuer} {$tls_in_peercert}}> logwrite = IN/O <${certextract {issuer,O} {$tls_in_peercert}}> logwrite = NB <${certextract {notbefore} {$tls_in_peercert}}> + logwrite = NB/i <${certextract {notbefore,int}{$tls_in_peercert}}> logwrite = NA <${certextract {notafter} {$tls_in_peercert}}> logwrite = SA <${certextract {sig_algorithm}{$tls_in_peercert}}> logwrite = SG <${certextract {signature} {$tls_in_peercert}}> diff --git a/test/confs/2102 b/test/confs/2102 index 8879cd07d..7d5d13a5a 100644 --- a/test/confs/2102 +++ b/test/confs/2102 @@ -54,6 +54,7 @@ check_recipient: logwrite = IN <${certextract {issuer} {$tls_in_peercert}}> logwrite = IN/O <${certextract {issuer,O} {$tls_in_peercert}}> logwrite = NB <${certextract {notbefore} {$tls_in_peercert}}> + logwrite = NB/i <${certextract {notbefore,int}{$tls_in_peercert}}> logwrite = NA <${certextract {notafter} {$tls_in_peercert}}> logwrite = SA <${certextract {sig_algorithm}{$tls_in_peercert}}> logwrite = SG <${certextract {signature} {$tls_in_peercert}}> diff --git a/test/log/2002 b/test/log/2002 index 1cfa6e875..73c76baf1 100644 --- a/test/log/2002 +++ b/test/log/2002 @@ -14,6 +14,7 @@ 1999-03-02 09:44:33 IN 1999-03-02 09:44:33 IN/O 1999-03-02 09:44:33 NB +1999-03-02 09:44:33 NB/i <1351773246> 1999-03-02 09:44:33 NA 1999-03-02 09:44:33 SA 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> diff --git a/test/log/2102 b/test/log/2102 index 79c51d0df..25bef1864 100644 --- a/test/log/2102 +++ b/test/log/2102 @@ -15,6 +15,7 @@ 1999-03-02 09:44:33 IN 1999-03-02 09:44:33 IN/O 1999-03-02 09:44:33 NB +1999-03-02 09:44:33 NB/i <1351773246> 1999-03-02 09:44:33 NA 1999-03-02 09:44:33 SA 1999-03-02 09:44:33 SG < Signature Algorithm: sha1WithRSAEncryption\n 6c:37:41:26:4d:5d:f4:b5:31:10:67:ca:fb:64:b6:22:98:62:\n f7:1e:95:7b:6c:e6:74:47:21:f4:5e:89:36:3e:b9:9c:8a:c5:\n 52:bb:c4:af:12:93:26:3b:d7:3d:e0:56:71:1e:1d:21:20:02:\n ed:f0:4e:d5:5e:45:42:fd:3c:38:41:54:83:86:0b:3b:bf:c5:\n 47:39:ff:15:ea:93:dc:fd:c7:3d:18:58:59:ca:dd:2a:d8:b9:\n f9:2f:b9:76:93:f4:ae:e3:91:56:80:2f:8c:04:2f:ad:57:ef:\n d2:51:19:f4:b4:ef:32:9c:ac:3a:7c:0d:b8:39:db:b1:e3:30:\n 73:1a\n> -- 2.30.2