[PATCH] allow notAfter after 2038 with 32-bit time_t

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] allow notAfter after 2038 with 32-bit time_t

Kyle J. McKay
RFC 5280 section 4.1.2.5 states:

    To indicate that a certificate has no well-defined expiration date,
    the notAfter SHOULD be assigned the GeneralizedTime value of
    99991231235959Z.

Unfortunately, if sizeof(time_t) == 4, 9999-12-31T23:59:59Z cannot be
represented as a time_t value causing valid certificates to be rejected
just because the notAfter value is after 2038-01-19T03:14:07Z.

Fix this problem by disabling the restriction in the X509_cmp_time function
and "wrap" far in the future notAfter values to 2038-01-19T03:14:07Z in the
tls_get_peer_cert_times function.

With both of these changes certificates with "no well-defined expiration
date" as specified by RFC 5280 are again accepted on platforms where the
sizeof(time_t) == 4.

In general, there's no reason that a notAfter value should not be wrapped
to 2038-01-19T03:14:07Z on a system with a 32-bit time_t.  The system itself
can never have a time after 2038-01-19T03:14:07Z because of the size of the
time_t type and so wrapping a notAfter date that is after 2038-01-19T03:14:07Z
to 2038-01-19T03:14:07Z can never result in any additional certificates being
accepted on such a system.

Signed-off-by: Kyle J. McKay <[hidden email]>
---

For those using the libressl-2.5.4.tar.gz distribution, an equivalent
patch that updates the tarball files instead can be found here:

  https://gist.github.com/7d4d59bbae9e4d18444b86aa79d6f350

Without this patch (or an equivalent), libressl-portable is not a viable
alternative to OpenSSL on systems with a 32-bit time_t.

It rejects valid TLS connections to any site that contains a notAfter date
after 2038-01-19T03:14:07Z in any certificate in the chain.

Besides the special case date mentioned above, there are many root certificates
already in use today that have notAfter dates beyond 2038-01-19.

These patches have been tested with libressl-portable 2.5.4 on a system with
a 32-bit time_t.  With both of these patches the "nc -c" command successfully
connects to sites with certificates that include notAfter dates after 2038-01-19.

If either patch is omitted, "nc -c" fails to connect.

 src/lib/libcrypto/x509/x509_vfy.c | 3 ++-
 src/lib/libtls/tls_conninfo.c     | 8 ++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c
index d8c09a12..c59bd258 100644
--- a/src/lib/libcrypto/x509/x509_vfy.c
+++ b/src/lib/libcrypto/x509/x509_vfy.c
@@ -1882,7 +1882,8 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
  * a time_t. A time_t must be sane if you care about times after
  * Jan 19 2038.
  */
- if ((time1 = timegm(&tm1)) == -1)
+ if (((time1 = timegm(&tm1)) == -1) &&
+    ((sizeof(time_t) != 4) || tm1.tm_year < 138))
  goto out;
 
  if (gmtime_r(&time2, &tm2) == NULL)
diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/tls_conninfo.c
index 5cdd0f77..a59b4ba2 100644
--- a/src/lib/libtls/tls_conninfo.c
+++ b/src/lib/libtls/tls_conninfo.c
@@ -142,8 +142,12 @@ tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore,
  goto err;
  if ((*notbefore = timegm(&before_tm)) == -1)
  goto err;
- if ((*notafter = timegm(&after_tm)) == -1)
- goto err;
+ if ((*notafter = timegm(&after_tm)) == -1) {
+ if (sizeof(time_t) == 4 && after_tm.tm_year >= 138)
+ *notafter = 2147483647;
+ else
+ goto err;
+ }
 
  return (0);
 
---

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] allow notAfter after 2038 with 32-bit time_t

Bob Beck-3
On Thu, May 18, 2017 at 7:31 AM, Kyle J. McKay <[hidden email]> wrote:

> RFC 5280 section 4.1.2.5 states:
>
>     To indicate that a certificate has no well-defined expiration date,
>     the notAfter SHOULD be assigned the GeneralizedTime value of
>     99991231235959Z.
>
>
True enough.



> Unfortunately, if sizeof(time_t) == 4, 9999-12-31T23:59:59Z cannot be
> represented as a time_t value causing valid certificates to be rejected
> just because the notAfter value is after 2038-01-19T03:14:07Z.
>

Correct

So, I'll ask - what is the platform you are using that needs this? OpenBSD
does not, nor do most modern unix systems - So what platform are we doing
this for?

I'm not asking it to be nasty, but to put it in a slightly different
context "OMG, windows 98 does not support this, but if you add this code I
can support windows 98". You and I both know what your answer would
probably be for the person with Windows 98, which is "Here's a nickel kid,
get a modern operating system".

We ripped out support for a lot of moribund platforms for a reason.  What
platform are you using with 32 bit time where this is an issue?  I'm not
saying no, I'm saying "convince me this matters for anything relevant
please", and I am open to being convinced.


Fix this problem by disabling the restriction in the X509_cmp_time function

> and "wrap" far in the future notAfter values to 2038-01-19T03:14:07Z in the
> tls_get_peer_cert_times function.
>
> With both of these changes certificates with "no well-defined expiration
> date" as specified by RFC 5280 are again accepted on platforms where the
> sizeof(time_t) == 4.
>
> In general, there's no reason that a notAfter value should not be wrapped
> to 2038-01-19T03:14:07Z on a system with a 32-bit time_t.  The system
> itself
> can never have a time after 2038-01-19T03:14:07Z because of the size of the
> time_t type and so wrapping a notAfter date that is after
> 2038-01-19T03:14:07Z
> to 2038-01-19T03:14:07Z can never result in any additional certificates
> being
> accepted on such a system.
>
> Signed-off-by: Kyle J. McKay <[hidden email]>
> ---
>
> For those using the libressl-2.5.4.tar.gz distribution, an equivalent
> patch that updates the tarball files instead can be found here:
>
>   https://gist.github.com/7d4d59bbae9e4d18444b86aa79d6f350
>
> Without this patch (or an equivalent), libressl-portable is not a viable
> alternative to OpenSSL on systems with a 32-bit time_t.
>
> It rejects valid TLS connections to any site that contains a notAfter date
> after 2038-01-19T03:14:07Z in any certificate in the chain.
>
> Besides the special case date mentioned above, there are many root
> certificates
> already in use today that have notAfter dates beyond 2038-01-19.
>
> These patches have been tested with libressl-portable 2.5.4 on a system
> with
> a 32-bit time_t.  With both of these patches the "nc -c" command
> successfully
> connects to sites with certificates that include notAfter dates after
> 2038-01-19.
>
> If either patch is omitted, "nc -c" fails to connect.
>
>  src/lib/libcrypto/x509/x509_vfy.c | 3 ++-
>  src/lib/libtls/tls_conninfo.c     | 8 ++++++--
>  2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/src/lib/libcrypto/x509/x509_vfy.c
> b/src/lib/libcrypto/x509/x509_vfy.c
> index d8c09a12..c59bd258 100644
> --- a/src/lib/libcrypto/x509/x509_vfy.c
> +++ b/src/lib/libcrypto/x509/x509_vfy.c
> @@ -1882,7 +1882,8 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
>          * a time_t. A time_t must be sane if you care about times after
>          * Jan 19 2038.
>          */
> -       if ((time1 = timegm(&tm1)) == -1)
> +       if (((time1 = timegm(&tm1)) == -1) &&
> +           ((sizeof(time_t) != 4) || tm1.tm_year < 138))
>                 goto out;
>
>         if (gmtime_r(&time2, &tm2) == NULL)
> diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/tls_conninfo.c
> index 5cdd0f77..a59b4ba2 100644
> --- a/src/lib/libtls/tls_conninfo.c
> +++ b/src/lib/libtls/tls_conninfo.c
> @@ -142,8 +142,12 @@ tls_get_peer_cert_times(struct tls *ctx, time_t
> *notbefore,
>                 goto err;
>         if ((*notbefore = timegm(&before_tm)) == -1)
>                 goto err;
> -       if ((*notafter = timegm(&after_tm)) == -1)
> -               goto err;
> +       if ((*notafter = timegm(&after_tm)) == -1) {
> +               if (sizeof(time_t) == 4 && after_tm.tm_year >= 138)
> +                       *notafter = 2147483647;
> +               else
> +                       goto err;
> +       }
>
>         return (0);
>
> ---
>
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] allow notAfter after 2038 with 32-bit time_t

Kyle J. McKay
On Jul 5, 2017, at 22:30, Bob Beck wrote:

> On Thu, May 18, 2017 at 7:31 AM, Kyle J. McKay <[hidden email]>  
> wrote:
> RFC 5280 section 4.1.2.5 states:
>
>     To indicate that a certificate has no well-defined expiration  
> date,
>     the notAfter SHOULD be assigned the GeneralizedTime value of
>     99991231235959Z.
>
>
> True enough.
>
>
> Unfortunately, if sizeof(time_t) == 4, 9999-12-31T23:59:59Z cannot be
> represented as a time_t value causing valid certificates to be  
> rejected
> just because the notAfter value is after 2038-01-19T03:14:07Z.
>
> Correct
>
> So, I'll ask - what is the platform you are using that needs this?  
> OpenBSD does not, nor do most modern unix systems - So what platform  
> are we doing this for?

I make a Git OS X installer for older (and current) Mac OS X  
(mackyle.github.io/git-osx-installer).  I will, in the near future, be  
providing a LibreSSL installer too and it can be used to redirect the  
Git OS X Installer Git from the native SecureTransport to using  
LibreSSL instead (prior to OS X 10.8 only TLS 1.0 is available via  
SecureTransport).  The installer must support 32-bit PPC and 32-bit  
Intel in order to be compatible with older machines.  Those have a 32-
bit time_t.  I also see that my Raspberry Pi (it's not a "3") running  
Raspbian has a 32-bit time_t, so LibreSSL portable out-of-the-box  
would not work properly on it either (even on an RPi 3 I don't think  
64-bit Raspbbian builds are officially supported yet).

> I'm not asking it to be nasty, but to put it in a slightly different  
> context "OMG, windows 98 does not support this, but if you add this  
> code I can support windows 98". You and I both know what your answer  
> would probably be for the person with Windows 98, which is "Here's a  
> nickel kid, get a modern operating system".

Yes, well, I could also just build OpenSSL and use that instead, but  
I'd much rather use LibreSSL.  Initially I thought I was just going to  
have to use OpenSSL, but then I poked around and worked out the  
patch.  So I'm willing to maintain that patch separately for the  
LibreSSL installer since it's really such a tiny change.  I'm just not  
comfortable shipping a 32-bit installer for LibreSSL that can't  
connect to current web sites, so I need to include the patch if I use  
LibreSSL rather than OpenSSL.

> We ripped out support for a lot of moribund platforms for a reason.  
> What platform are you using with 32 bit time where this is an  
> issue?  I'm not saying no, I'm saying "convince me this matters for  
> anything relevant please", and I am open to being convinced.

It's really a portable-only change.  The way the patch is written the  
compiler will omit the changes unless sizeof(time_t) == 4, but that  
does still leave that test in there making the code a bit less elegant.

Do you have some other suggestion for how I can ship a version of  
LibreSSL for older Mac OS X systems that works with those certificates?

Some folks are deliberately hanging on to their PPC Macs because they  
have legacy hardware/software that they need to use.  Or they just  
can't afford to plunk down 1K+ for a new system, they'd rather use  
that money to eat.  Those systems cannot be upgraded past Mac OS X  
10.5.  Even some Intel Macs with older graphic cards can't be upgraded  
past 10.7 (thank you very much Cupertino).  Macs are not quite as  
cheap to replace as wintel so the kid will need more than a nickel. ;)

And the $5 Pi isn't 64-bit either.

My arguments are:

1) The compiler should produce exactly the same code before and after  
patch for 64-bit time_t systems
2) 32-bit systems are going to be around for many years still; 32-bit  
ARM platforms are everywhere
3) 32-bit systems typically have 32-bit time_t values (I'm not aware  
of anything in the standard preventing use of a 64-bit time_t on a 32-
bit system but that doesn't seem to be happening, at least not yet)
4) 32-bit time_t has potentially still got over 20 years of life left  
in it
5) There are already pre-trusted root certificates with post  
2038-01-19 expiration dates (I've seen 2041 for example), the number  
of these will continue to increase
6) The alternatives to LibreSSL are (a) OpenSSL [0.9.8zh, that's a  
joke, right?  "zh"!]  (b) BoringSSL [will get you caught up in goo*le  
specific stuff sooner or later] (c) GnuTLS [but it's GPL 3 and used to  
have horrible benchmarks in comparison to OpenSSL, but perhaps that's  
been addressed].  I'm sure there are more but those are obvious  
choices.  If you need to stay away from GPL 3 (for whatever reason)  
then the only reasonable choice left for 32-bit time_t systems will be  
OpenSSL.  I admit there hasn't been a 1.0.2zh [yet] but it's already  
at 1.0.2l.  Then there's the OpenSSL 1.1.0 API changes.  If folks  
adopt OpenSSL to get 32-bit time_t support they will likely be gone  
for good unless LibreSSL picks up the same API changes allowing them  
to migrate back after they no longer need 32-bit time_t support.

This is all, of course, a LibreSSL-portable argument and doesn't apply  
to the non-portable version, but there really aren't two versions of  
the core LibreSSL files, are there?

The LibreSSL installer I'm creating will have 3 patches and a kludge  
in it:

1) added OIDs for EV certificates -- this change has already been  
picked up and committed, so this is really actually a backport now  
since there hasn't yet been a LibreSSL portable release with it
2) the patch below
3) a netcat patch to provide "-T tlscompat" (to go with the pre-
existing "-T tlsall" option)
4) a compile kludge to redirect all "poll(...)" function calls to a  
"pollcompat(...)" wrapper function that emulates poll() properly on  
Mac OS X

(1) will shortly become unnecessary, (4) I'll always be stuck with.  
I'm not exactly sure what the current status of (3) is.  (2) I must  
have for the reasons above.  So it's not that big a deal to always be  
stuck with (2) in addition to the others.  They're all tiny changes  
except for (4) which just does something with compiler options and a  
tiny static library that provides the wrapper implementation but  
doesn't actually change any LibreSSL code at all.

Cheers,

Kyle

>
> Fix this problem by disabling the restriction in the X509_cmp_time  
> function
> and "wrap" far in the future notAfter values to 2038-01-19T03:14:07Z  
> in the
> tls_get_peer_cert_times function.
>
> With both of these changes certificates with "no well-defined  
> expiration
> date" as specified by RFC 5280 are again accepted on platforms where  
> the
> sizeof(time_t) == 4.
>
> In general, there's no reason that a notAfter value should not be  
> wrapped
> to 2038-01-19T03:14:07Z on a system with a 32-bit time_t.  The  
> system itself
> can never have a time after 2038-01-19T03:14:07Z because of the size  
> of the
> time_t type and so wrapping a notAfter date that is after  
> 2038-01-19T03:14:07Z
> to 2038-01-19T03:14:07Z can never result in any additional  
> certificates being
> accepted on such a system.
>
> Signed-off-by: Kyle J. McKay <[hidden email]>
> ---
>
> For those using the libressl-2.5.4.tar.gz distribution, an equivalent
> patch that updates the tarball files instead can be found here:
>
>   https://gist.github.com/7d4d59bbae9e4d18444b86aa79d6f350
>
> Without this patch (or an equivalent), libressl-portable is not a  
> viable
> alternative to OpenSSL on systems with a 32-bit time_t.
>
> It rejects valid TLS connections to any site that contains a  
> notAfter date
> after 2038-01-19T03:14:07Z in any certificate in the chain.
>
> Besides the special case date mentioned above, there are many root  
> certificates
> already in use today that have notAfter dates beyond 2038-01-19.
>
> These patches have been tested with libressl-portable 2.5.4 on a  
> system with
> a 32-bit time_t.  With both of these patches the "nc -c" command  
> successfully
> connects to sites with certificates that include notAfter dates  
> after 2038-01-19.
>
> If either patch is omitted, "nc -c" fails to connect.
>
>  src/lib/libcrypto/x509/x509_vfy.c | 3 ++-
>  src/lib/libtls/tls_conninfo.c     | 8 ++++++--
>  2 files changed, 8 insertions(+), 3 deletions(-)
>
> diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/
> x509/x509_vfy.c
> index d8c09a12..c59bd258 100644
> --- a/src/lib/libcrypto/x509/x509_vfy.c
> +++ b/src/lib/libcrypto/x509/x509_vfy.c
> @@ -1882,7 +1882,8 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t  
> *cmp_time)
>          * a time_t. A time_t must be sane if you care about times  
> after
>          * Jan 19 2038.
>          */
> -       if ((time1 = timegm(&tm1)) == -1)
> +       if (((time1 = timegm(&tm1)) == -1) &&
> +           ((sizeof(time_t) != 4) || tm1.tm_year < 138))
>                 goto out;
>
>         if (gmtime_r(&time2, &tm2) == NULL)
> diff --git a/src/lib/libtls/tls_conninfo.c b/src/lib/libtls/
> tls_conninfo.c
> index 5cdd0f77..a59b4ba2 100644
> --- a/src/lib/libtls/tls_conninfo.c
> +++ b/src/lib/libtls/tls_conninfo.c
> @@ -142,8 +142,12 @@ tls_get_peer_cert_times(struct tls *ctx, time_t  
> *notbefore,
>                 goto err;
>         if ((*notbefore = timegm(&before_tm)) == -1)
>                 goto err;
> -       if ((*notafter = timegm(&after_tm)) == -1)
> -               goto err;
> +       if ((*notafter = timegm(&after_tm)) == -1) {
> +               if (sizeof(time_t) == 4 && after_tm.tm_year >= 138)
> +                       *notafter = 2147483647;
> +               else
> +                       goto err;
> +       }
>
>         return (0);
>
> ---
>
>

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] allow notAfter after 2038 with 32-bit time_t

Stuart Henderson
On 2017/07/11 01:55, Kyle J. McKay wrote:
> 2) 32-bit systems are going to be around for many years still; 32-bit ARM
> platforms are everywhere
..
> 4) 32-bit time_t has potentially still got over 20 years of life left in it

Yes. The gamble is whether 32-bit systems will still be around then.
I don't see why they _wouldn't_ be. The sooner that OS adapt, the less
likely there are to still be operational systems when 2038 comes around.

> 3) 32-bit systems typically have 32-bit time_t values (I'm not aware of
> anything in the standard preventing use of a 64-bit time_t on a 32-bit
> system but that doesn't seem to be happening, at least not yet)

This depends on the OS. Linux's general avoidance of ABI breaks is
certainly a problem in this area. NetBSD has used 64-bit time_t on all
architectures since 6.0 (2012) and OpenBSD since 5.5 (2014). I haven't
looked recently but IIRC FreeBSD has 64-bit time_t on 32-bit ARM
(and of course on 64-bit systems).

Plenty of software still needs patching to fix operation on a 32-bit
arch with 64-bit time_t - we have a lot of these in the ports tree
(with mixed success feeding such changes upstream - "Linux doesn't
need it"...).

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] allow notAfter after 2038 with 32-bit time_t

Andrew Grillet
Hi,

I have built embedded systems that have run 20 years with no update - but I
doubt they are common.

More of an issue is archived data. I have read data 30 years old, and may
well do so again. While
I think the answer is "human readable date formats" The Americans have
scuppered that with M-D-Y.

I am sure there will still be 32 bit systems in 30 years time - there will
still be 8-bit systems too.

In summary:

1) 64 bit dates are needed ASAP, even on 8 bit machines.

2) What has Linux got to do with the price of fish?

Andrew

On 11 July 2017 at 11:23, Stuart Henderson <[hidden email]> wrote:

> On 2017/07/11 01:55, Kyle J. McKay wrote:
> > 2) 32-bit systems are going to be around for many years still; 32-bit ARM
> > platforms are everywhere
> ..
> > 4) 32-bit time_t has potentially still got over 20 years of life left in
> it
>
> Yes. The gamble is whether 32-bit systems will still be around then.
> I don't see why they _wouldn't_ be. The sooner that OS adapt, the less
> likely there are to still be operational systems when 2038 comes around.
>
> > 3) 32-bit systems typically have 32-bit time_t values (I'm not aware of
> > anything in the standard preventing use of a 64-bit time_t on a 32-bit
> > system but that doesn't seem to be happening, at least not yet)
>
> This depends on the OS. Linux's general avoidance of ABI breaks is
> certainly a problem in this area. NetBSD has used 64-bit time_t on all
> architectures since 6.0 (2012) and OpenBSD since 5.5 (2014). I haven't
> looked recently but IIRC FreeBSD has 64-bit time_t on 32-bit ARM
> (and of course on 64-bit systems).
>
> Plenty of software still needs patching to fix operation on a 32-bit
> arch with 64-bit time_t - we have a lot of these in the ports tree
> (with mixed success feeding such changes upstream - "Linux doesn't
> need it"...).
>
>
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] allow notAfter after 2038 with 32-bit time_t

Bob Beck-3
In reply to this post by Stuart Henderson
https://github.com/openbsd/src/commit/b943944faeecf3a978bf3f57df1b35335ffecbec

On Tue, Jul 11, 2017 at 4:23 AM, Stuart Henderson <[hidden email]>
wrote:

> On 2017/07/11 01:55, Kyle J. McKay wrote:
> > 2) 32-bit systems are going to be around for many years still; 32-bit ARM
> > platforms are everywhere
> ..
> > 4) 32-bit time_t has potentially still got over 20 years of life left in
> it
>
> Yes. The gamble is whether 32-bit systems will still be around then.
> I don't see why they _wouldn't_ be. The sooner that OS adapt, the less
> likely there are to still be operational systems when 2038 comes around.
>
> > 3) 32-bit systems typically have 32-bit time_t values (I'm not aware of
> > anything in the standard preventing use of a 64-bit time_t on a 32-bit
> > system but that doesn't seem to be happening, at least not yet)
>
> This depends on the OS. Linux's general avoidance of ABI breaks is
> certainly a problem in this area. NetBSD has used 64-bit time_t on all
> architectures since 6.0 (2012) and OpenBSD since 5.5 (2014). I haven't
> looked recently but IIRC FreeBSD has 64-bit time_t on 32-bit ARM
> (and of course on 64-bit systems).
>
> Plenty of software still needs patching to fix operation on a 32-bit
> arch with 64-bit time_t - we have a lot of these in the ports tree
> (with mixed success feeding such changes upstream - "Linux doesn't
> need it"...).
>
>
Reply | Threaded
Open this post in threaded view
|

[PATCH 0/2] SMALL_TIME_T follow-ups (was Re: [PATCH] allow notAfter after 2038 with 32-bit time_t)

Kyle J. McKay
In reply to this post by Bob Beck-3
Thank you.

I have applied the change to the latest LibreSSL portable tarball and  
tested it.

With the new define (SMALL_TIME_T) enabled, a 32-bit time_t build  
using "openssl s_client -connect" can successfully connect to a server  
and verify its certificate chain when one or more notAfter dates after  
2038 are present.

However, using "nc -c" fails to connect to the same server.

The reason being that libtls also needs to clamp the notAfter date.

Unfortunately the new ASN1_time_tm_clamp_notafter symbol is not public  
and is located in libcrypto which makes it unavailable to libtls.

Seems to me there are two approaches:

1) duplicate the ASN1_time_tm_clamp_notafter function in libtls

2) make the symbol public to avoid duplicating code and potentially  
creating an out-of-sync/maintenance problem

The two patches in this series take approach (2).  The first makes  
ASN1_time_tm_clamp_notafter public and the second calls it from the  
appropriate place in libtls.

A 32-bit time_t build including these two additional patches (and with  
SMALL_TIME_T defined) successfully connects using "nc -c" to servers  
with one or more notAfter dates after 2038.

These patches are submitted under the standard OpenBSD license.

--Kyle

On Aug 13, 2017, at 14:26, Bob Beck wrote:

> https://github.com/openbsd/src/commit/b943944faeecf3a978bf3f57df1b35335ffecbec
>
> On Sun, Aug 13, 2017 at 1:56 PM, Bob Beck <[hidden email]> wrote:
>
>>
>> So. To summarize my take on this
>>
>> If you're still running OSX 9, I think you like peril.. for lots of
>> reasons.. Running OpenSSL is probably the least of your perils.
>>
>> Sadly, Linux Raspberry PI sucks, because 32 bit Linux still hasn't  
>> dealt
>> with this.
>>
>> RFC 5280 section 4.1.2.5 guarantees you may see these.
>>
>> So in the interest of allowing 32 bit linux to use LibreSSL, I've  
>> just
>> committed a change to that portable
>> can make use of.
>>
>> We will allow portable to clamp he notAfter field in a certificate  
>> to the
>> largest represntable 32 bit time
>> if a notafter field from a certificate is larger than that value.  
>> We do
>> not clamp any other times
>> in any other places (a larger than 32 bit notBefore, for example,  
>> would
>> continue to be not accepted.
>>
>> This will alllow RFC 5280 4.1.2.5 compliant certs, and certs with  
>> notAfter
>> dates after 2038 to
>> be accepted as if the notAfter date was 03:14:08 UTC on Tuesday, 19
>> January 2038.

Reply | Threaded
Open this post in threaded view
|

[PATCH 1/2] libcrypto: make ASN1_time_tm_clamp_notafter public

Kyle J. McKay
The ASN1_time_tm_clamp_notafter function does nothing except when
the portable-only SMALL_TIME_T define has been enabled.

However, the SMALL_TIME_T functionality also needs to be accessed
by the libtls tls_get_peer_cert_times function in order for the
portable build of libtls to also support SMALL_TIME_T.

Therefore make the ASN1_time_tm_clamp_notafter function a public
external rather than a private symbol.

Signed-off-by: Kyle J. McKay <[hidden email]>

---
 lib/libcrypto/Symbols.list     | 1 +
 lib/libcrypto/asn1/asn1.h      | 1 +
 lib/libcrypto/asn1/asn1_locl.h | 2 --
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/libcrypto/Symbols.list b/lib/libcrypto/Symbols.list
index 2b8557b1..94442cc5 100644
--- a/lib/libcrypto/Symbols.list
+++ b/lib/libcrypto/Symbols.list
@@ -214,6 +214,7 @@ ASN1_template_free
 ASN1_template_i2d
 ASN1_template_new
 ASN1_time_parse
+ASN1_time_tm_clamp_notafter
 ASN1_time_tm_cmp
 ASN1_unpack_string
 AUTHORITY_INFO_ACCESS_free
diff --git a/lib/libcrypto/asn1/asn1.h b/lib/libcrypto/asn1/asn1.h
index da16d5c5..fe9a6c5d 100644
--- a/lib/libcrypto/asn1/asn1.h
+++ b/lib/libcrypto/asn1/asn1.h
@@ -1454,6 +1454,7 @@ void ERR_load_ASN1_strings(void);
 
 int ASN1_time_parse(const char *_bytes, size_t _len, struct tm *_tm, int _mode);
 int ASN1_time_tm_cmp(struct tm *_tm1, struct tm *_tm2);
+int ASN1_time_tm_clamp_notafter(struct tm *tm);
 #ifdef  __cplusplus
 }
 #endif
diff --git a/lib/libcrypto/asn1/asn1_locl.h b/lib/libcrypto/asn1/asn1_locl.h
index 68f71dfc..c05eb3b9 100644
--- a/lib/libcrypto/asn1/asn1_locl.h
+++ b/lib/libcrypto/asn1/asn1_locl.h
@@ -152,6 +152,4 @@ struct x509_crl_method_st {
 int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
 int UTF8_putc(unsigned char *str, int len, unsigned long value);
 
-int ASN1_time_tm_clamp_notafter(struct tm *tm);
-
 __END_HIDDEN_DECLS

--

Reply | Threaded
Open this post in threaded view
|

[PATCH 2/2] tls_conninfo.c: use ASN1_time_tm_clamp_notafter

Kyle J. McKay
In reply to this post by Kyle J. McKay
The tls_get_peer_cert_times function returns a certificate's notAfter
date as a time_t value.

Make use of the ASN1_time_tm_clamp_notafter function so that when
SMALL_TIME_T has been defined for a portable build tls_get_peer_cert_times
does not fail when it would otherwise succeed.

Signed-off-by: Kyle J. McKay <[hidden email]>

---
 lib/libtls/tls_conninfo.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/libtls/tls_conninfo.c b/lib/libtls/tls_conninfo.c
index 87660fa9..c8ee4f0f 100644
--- a/lib/libtls/tls_conninfo.c
+++ b/lib/libtls/tls_conninfo.c
@@ -123,7 +123,8 @@ tls_get_peer_cert_times(struct tls *ctx, time_t *notbefore,
  goto err;
  if ((*notbefore = timegm(&before_tm)) == -1)
  goto err;
- if ((*notafter = timegm(&after_tm)) == -1)
+ if (!ASN1_time_tm_clamp_notafter(&after_tm) ||
+    (*notafter = timegm(&after_tm)) == -1)
  goto err;
 
  return (0);

--

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 0/2] SMALL_TIME_T follow-ups (was Re: [PATCH] allow notAfter after 2038 with 32-bit time_t)

Bob Beck-2
In reply to this post by Kyle J. McKay
>
> With the new define (SMALL_TIME_T) enabled, a 32-bit time_t build  
> using "openssl s_client -connect" can successfully connect to a server  
> and verify its certificate chain when one or more notAfter dates after  
> 2038 are present.
>
> However, using "nc -c" fails to connect to the same server.
>
> The reason being that libtls also needs to clamp the notAfter date.

I've just committed a change that enables libtls to use it. so
nc and libtls should work on broken computers now.

I still think karma for me doing this is I will be killed by an
embedded 32 bit linux device in 2038...

 -Bob


Reply | Threaded
Open this post in threaded view
|

Re: [PATCH 0/2] SMALL_TIME_T follow-ups (was Re: [PATCH] allow notAfter after 2038 with 32-bit time_t)

Kyle J. McKay
On Aug 26, 2017, at 18:52, Bob Beck wrote:

>> With the new define (SMALL_TIME_T) enabled, a 32-bit time_t build
>> using "openssl s_client -connect" can successfully connect to a  
>> server
>> and verify its certificate chain when one or more notAfter dates  
>> after
>> 2038 are present.
>>
>> However, using "nc -c" fails to connect to the same server.
>>
>> The reason being that libtls also needs to clamp the notAfter date.
>
> I've just committed a change that enables libtls to use it. so
> nc and libtls should work on broken computers now.

Thank you.  I tried it out by applying it to the LibreSSL portable  
tarball (together with the previous change) and it works great.

-Kyle