OpenVPN / easy-rsa

easy-rsa - Simple shell based CA utility
Other
4k stars 1.19k forks source link

show-expire bug - fails to parse date #1193

Closed warren-gallagher closed 3 weeks ago

warren-gallagher commented 1 month ago

When running the show-expire command I encountered the following error:

Using Easy-RSA 'vars' configuration:
* /Users/wgallagher/dev/aq/CertificateAuthorities/gallaghers.ca/vars

Using SSL:
* openssl OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)

Notice
------
* Showing certificates which expire in less than 90 days (--days):
  expire_status: SERIAL MISMATCH
  db_serial:     DC97BE341E1770EFE9223975C46D4E5E
  cert_serial:   2825CD0C4717BA82483A4F37720F2FD9
  commonName:    warren.lee.gallagher
  cert_issued:   /Users/wgallagher/dev/aq/CertificateAuthorities/gallaghers.ca/issued/warren.lee.gallagher.crt

**Easy-RSA error:

cert_date_to_timestamp_s:
'date' failed for in_date=2026-10-27 17:07:37Z**

EasyRSA Version Information
Version:     3.1.7
Generated:   Fri Oct 13 17:27:51 CDT 2023
SSL Lib:     OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)
Git Commit:  3c233d279d43e419b0529411ee62bba7a08f0c0f
Source Repo: https://github.com/OpenVPN/easy-rsa
Host: 3.1.7 | nix | Darwin | /bin/zsh

When I show-cert for the 'offending' certificate it shows the following:

Using Easy-RSA 'vars' configuration:
* /Users/wgallagher/dev/aq/CertificateAuthorities/gallaghers.ca/vars

Using SSL:
* openssl OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)

Notice
------
Showing 'cert' details for: 'warren.lee.gallagher'

This file is stored at:
* /Users/wgallagher/dev/aq/CertificateAuthorities/gallaghers.ca/issued/warren.lee.gallagher.crt

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            28:25:cd:0c:47:17:ba:82:48:3a:4f:37:72:0f:2f:d9
        Signature Algorithm: ecdsa-with-SHA256
        Issuer:
            countryName               = CA
            organizationName          = Gallagher Consulting
            commonName                = gallaghers.ca
        Validity
            Not Before: Jul 24 17:07:37 2024 GMT
            Not After : Oct 27 17:07:37 2026 GMT
        Subject:
            countryName               = CA
            organizationName          = Warren Lee Gallagher
            commonName                = warren.lee.gallagher
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            X509v3 Subject Key Identifier: 
                42:83:4C:BC:59:29:F1:42:B7:EB:CE:39:D6:96:98:7F:60:C6:24:82
            X509v3 Authority Key Identifier: 
                keyid:B6:BF:A0:AD:F7:89:E9:D2:09:40:9B:C9:FE:C8:9A:D1:01:24:F7:A4
                DirName:/C=CA/O=AffinitiQuest/CN=affinitiquest.io
                serial:C2:08:C2:54:A0:25:DC:B0:A6:DF:E3:4E:65:04:49:E6
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication
            X509v3 Key Usage: 
                Digital Signature, Key Encipherment
            X509v3 Subject Alternative Name: 
                DNS:warren.lee.gallagher
warren-gallagher commented 1 month ago

Note the double asterisk characters surrounding the error string. Those were added by me in a lame attempt to use the markdown bolding functionality, which of course, does not work within backtick rendering...

TinCanTech commented 1 month ago

@warren-gallagher thanks for your report.

This appears to be a Darwin specific bug, related to date.

Can you post the man page for your version of date ?

If you are familiar with date then you can also try to find the correct syntax for the command in question:

test_date='2026-10-27 17:07:37Z'
date -j -f '%b %d %T %Y %Z' "$test_date" +%s

This should return: 1721926313, without error.

warren-gallagher commented 1 month ago

Man paged attached. If you cat this file it should be the formatted text. date.man.txt

TinCanTech commented 1 month ago

@warren-gallagher I look forward to your PR.. :beer:

sdavids commented 4 weeks ago
test_date='2026-10-27 17:07:37Z'
date -j -f '%b %d %T %Y %Z' "$test_date" +%s

This should return: 1721926313, without error.

Is the example correct?

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 12 (bookworm)
Release:    12
Codename:   bookworm
$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
$ echo $TZ

$ timedatectl | grep "Time zone"
                Time zone: Europe/Berlin (CEST, +0200)
$ date -d "2026-10-27 17:07:37Z" +%s
1793120857
$ sudo timedatectl set-timezone Etc/UTC
$ timedatectl | grep "Time zone"
                Time zone: Etc/UTC (UTC, +0000)
$ date -d "2026-10-27 17:07:37Z" +%s
1793120857

Also, does OpenSSL not return dates (-startdate, -enddate, etc.) in RFC 2822 instead of ISO 8601:2004 format?

Oct 27 17:07:37 2026 GMT vs. 2026-10-27 17:07:37Z

$ node -e "console.log(Date.parse('2026-10-27 17:07:37Z'))"
1793120857000
$ node -e "console.log(Date.parse('Oct 27 17:07:37 2026 GMT'))"
1793120857000

This is how you would parse them on macOS:

$ test_date='2026-10-27 17:07:37Z'                   
$ date -u -j -f '%Y-%m-%d %H:%M:%SZ' "$test_date" +%s
1793120857

$ test_date='Oct 27 17:07:37 2026 GMT'    
$ LC_ALL='C' date -j -f '%b %d %T %Y %Z' "$test_date" +%s
1793120857

Note the usage of -u:

$ test_date='2026-10-27 17:07:37Z'                   
$ date -u -j -f '%Y-%m-%d %H:%M:%SZ' "$test_date" +%s
1793120857
$ date -j -f '%Y-%m-%d %H:%M:%SZ' "$test_date" +%s 
1793117257

And LC_ALL='C':

$ test_date='Oct 27 17:07:37 2026 GMT'
$ LC_ALL='C' date -u -j -f '%b %d %T %Y %Z' "$test_date" +%s
1793120857
$ LC_ALL='en_US.UTF-8' date -u -j -f '%b %d %T %Y %Z' "$test_date" +%s
1793120857
$ LC_ALL='de_DE.UTF-8' date -u -j -f '%b %d %T %Y %Z' "$test_date" +%s
Failed conversion of ``Oct 27 17:07:37 2026 GMT'' using format ``%b %d %T %Y %Z''
date: illegal time format
usage: date [-jnRu] [-r seconds|file] [-v[+|-]val[ymwdHMS]]
            [-I[date | hours | minutes | seconds]]
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
$ LC_ALL='de_DE.UTF-8' date -u -j -f '%b %d %T %Y %Z' "Oct 27 17:07:37 2026 GMT" +%s
Failed conversion of ``Oct 27 17:07:37 2026 GMT'' using format ``%b %d %T %Y %Z''
date: illegal time format
usage: date [-jnRu] [-r seconds|file] [-v[+|-]val[ymwdHMS]]
            [-I[date | hours | minutes | seconds]]
            [-f fmt date | [[[mm]dd]HH]MM[[cc]yy][.ss]] [+format]
$ LC_ALL='de_DE.UTF-8' date -u -j -f '%b %d %T %Y %Z' "Okt 27 17:07:37 2026 GMT" +%s
1793120857
$ LC_ALL='C' date -u -j -f '%Y-%m-%d %H:%M:%SZ' "2026-10-27 17:07:37Z" +%b
Oct
$ LC_ALL='de_DE.UTF-8' date -u -j -f '%Y-%m-%d %H:%M:%SZ' "2026-10-27 17:07:37Z" +%b
Okt

%b locale's abbreviated month name (e.g., Jan)

https://www.man7.org/linux/man-pages/man1/date.1.html

On Linux, one could use LC_TIME instead of LC_ALL but unfortunately macOS' date does not support it:

macOS

$ LC_ALL='de_DE.UTF-8' date -u -j -f '%Y-%m-%d %H:%M:%SZ' "2026-10-27 17:07:37Z" +%b
Okt
$ LC_TIME='de_DE.UTF-8' date -u -j -f '%Y-%m-%d %H:%M:%SZ' "2026-10-27 17:07:37Z" +%b
Oct

Linux

$ LC_TIME='de_DE.UTF-8' date -d "2026-10-27 17:07:37Z" +%b
Okt
TinCanTech commented 4 weeks ago

@sdavids Thanks for your work, I'll take a closer look soon.

TinCanTech commented 3 weeks ago

@warren-gallagher Please test the PR #1211

@sdavids If you have access to a macOS system then please test #1211

sdavids commented 3 weeks ago
$ git clone git@github.com:TinCanTech/easy-rsa.git
$ cd easy-rsa
$ git checkout tools-macos-certdate-to-timestamp
Switched to a new branch 'tools-macos-certdate-to-timestamp'
$ die() { print "$1${NL}" }
$ verbose() { printf '%s\n' "  # $*" }
$ force_set_var() { eval "export \"$1\"=\"\${$1-$2}\"" }
$ export EASYRSA_TOOLS_CALLER=1
$ export LC_ALL='de_DE.UTF-8'
$ . dev/easyrsa-tools.lib
$ echo $EASYRSA_TOOLS_VERSION
321
$ cert_date_to_timestamp_s "2026-10-27 17:07:37Z" ISO_8601
$ echo $ISO_8601
1793120857
$ cert_date_to_timestamp_s "Oct 27 17:07:37 2026 GMT" RFC_2822
  # DEPRECATED: cert_date_to_timestamp_s
cert_date_to_timestamp_s:
'date' failed for in_date=Oct 27 17:07:37 2026 GMT
$ echo $RFC_2822

You forgot the LC_ALL='C'.

sdavids commented 3 weeks ago

https://github.com/TinCanTech/easy-rsa/pull/1