From 9fc3669524ffd3d0ffaf2b50d35ed87ba2c123f7 Mon Sep 17 00:00:00 2001 From: beck <> Date: Sun, 13 Aug 2017 19:47:49 +0000 Subject: Add ability to clamp a notafter to values representable in a 32 bit time_t This will only be used in portable. As noted, necessary to make us conformant to RFC 5280 4.1.2.5. ok jsing@ bcook@ --- src/lib/libcrypto/asn1/a_time_tm.c | 18 +++++++++++++++++- src/lib/libcrypto/asn1/asn1_locl.h | 4 +++- src/lib/libcrypto/x509/x509_vfy.c | 26 +++++++++++++++++++++----- 3 files changed, 41 insertions(+), 7 deletions(-) (limited to 'src/lib') diff --git a/src/lib/libcrypto/asn1/a_time_tm.c b/src/lib/libcrypto/asn1/a_time_tm.c index f0afc00be4..48f9f8b5e1 100644 --- a/src/lib/libcrypto/asn1/a_time_tm.c +++ b/src/lib/libcrypto/asn1/a_time_tm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_time_tm.c,v 1.12 2017/05/06 17:12:59 beck Exp $ */ +/* $OpenBSD: a_time_tm.c,v 1.13 2017/08/13 19:47:49 beck Exp $ */ /* * Copyright (c) 2015 Bob Beck * @@ -58,6 +58,22 @@ ASN1_time_tm_cmp(struct tm *tm1, struct tm *tm2) { return 0; } +int +ASN1_time_tm_clamp_notafter(struct tm *tm) +{ +#ifdef SMALL_TIME_T + struct tm broken_os_epoch_tm; + time_t broken_os_epoch_time = INT_MAX; + + if (gmtime_r(&broken_os_epoch_time, &broken_os_epoch_tm) == NULL) + return 0; + + if (ASN1_time_tm_cmp(tm, &broken_os_epoch_tm) == 1) + memcpy(tm, &broken_os_epoch_tm, sizeof(*tm)); +#endif + return 1; +} + /* Format a time as an RFC 5280 format Generalized time */ char * gentime_string_from_tm(struct tm *tm) diff --git a/src/lib/libcrypto/asn1/asn1_locl.h b/src/lib/libcrypto/asn1/asn1_locl.h index 17bb4157a9..68f71dfc4a 100644 --- a/src/lib/libcrypto/asn1/asn1_locl.h +++ b/src/lib/libcrypto/asn1/asn1_locl.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_locl.h,v 1.8 2016/12/21 15:49:29 jsing Exp $ */ +/* $OpenBSD: asn1_locl.h,v 1.9 2017/08/13 19:47:49 beck Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -152,4 +152,6 @@ 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 diff --git a/src/lib/libcrypto/x509/x509_vfy.c b/src/lib/libcrypto/x509/x509_vfy.c index 0d01301446..23ecf63d60 100644 --- a/src/lib/libcrypto/x509/x509_vfy.c +++ b/src/lib/libcrypto/x509/x509_vfy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: x509_vfy.c,v 1.64 2017/04/28 23:03:58 beck Exp $ */ +/* $OpenBSD: x509_vfy.c,v 1.65 2017/08/13 19:47:49 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -73,8 +73,9 @@ #include #include #include -#include "x509_lcl.h" +#include "asn1_locl.h" #include "vpm_int.h" +#include "x509_lcl.h" /* CRL score values */ @@ -137,6 +138,8 @@ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path, STACK_OF(X509) *crl_path); +static int X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, + int clamp_notafter); static int internal_verify(X509_STORE_CTX *ctx); @@ -1745,7 +1748,7 @@ x509_check_cert_time(X509_STORE_CTX *ctx, X509 *x, int depth) X509_V_ERR_CERT_NOT_YET_VALID)) return 0; - i = X509_cmp_time(X509_get_notAfter(x), ptime); + i = X509_cmp_time_internal(X509_get_notAfter(x), ptime, 1); if (i <= 0 && depth < 0) return 0; if (i == 0 && !verify_cb_cert(ctx, x, depth, @@ -1852,8 +1855,8 @@ X509_cmp_current_time(const ASN1_TIME *ctm) * 1 if the ASN1_time is later than *cmp_time. * 0 on error. */ -int -X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +static int +X509_cmp_time_internal(const ASN1_TIME *ctm, time_t *cmp_time, int clamp_notafter) { time_t time1, time2; struct tm tm1, tm2; @@ -1877,6 +1880,12 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) if (tm1.tm_year >= 150 && type != V_ASN1_GENERALIZEDTIME) goto out; + if (clamp_notafter) { + /* Allow for completely broken operating systems. */ + if (!ASN1_time_tm_clamp_notafter(&tm1)) + goto out; + } + /* * Defensively fail if the time string is not representable as * a time_t. A time_t must be sane if you care about times after @@ -1895,6 +1904,13 @@ X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) return (ret); } +int +X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +{ + return X509_cmp_time_internal(ctm, cmp_time, 0); +} + + ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj) { -- cgit v1.2.3-55-g6feb