From: beck Date: Mon, 27 Jun 2022 13:54:57 +0000 (+0000) Subject: Add new time manipulation funcitons that OpenSSL has exposed that X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=b680683fd908eef442bc791b38803536a59ee6b0;p=openbsd Add new time manipulation funcitons that OpenSSL has exposed that the world seems to be using. Symbols.list changes and exposure to wait for minor bump ok jsing@ jca@ --- diff --git a/lib/libcrypto/asn1/a_time.c b/lib/libcrypto/asn1/a_time.c index cd6a790cacd..03311e1b7f5 100644 --- a/lib/libcrypto/asn1/a_time.c +++ b/lib/libcrypto/asn1/a_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_time.c,v 1.33 2021/12/25 07:48:09 jsing Exp $ */ +/* $OpenBSD: a_time.c,v 1.34 2022/06/27 13:54:57 beck Exp $ */ /* ==================================================================== * Copyright (c) 1999 The OpenSSL Project. All rights reserved. * @@ -92,8 +92,7 @@ ASN1_TIME_free(ASN1_TIME *a) ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it); } -/* Public API in OpenSSL. Kept internal for now. */ -static int +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm) { time_t now; diff --git a/lib/libcrypto/asn1/a_time_tm.c b/lib/libcrypto/asn1/a_time_tm.c index 0e040ae5791..23e2ce4b4c0 100644 --- a/lib/libcrypto/asn1/a_time_tm.c +++ b/lib/libcrypto/asn1/a_time_tm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: a_time_tm.c,v 1.20 2022/04/28 17:31:29 tb Exp $ */ +/* $OpenBSD: a_time_tm.c,v 1.21 2022/06/27 13:54:57 beck Exp $ */ /* * Copyright (c) 2015 Bob Beck * @@ -379,6 +379,61 @@ ASN1_TIME_set_string(ASN1_TIME *s, const char *str) return (ASN1_TIME_set_string_internal(s, str, 0)); } +static int +ASN1_TIME_cmp_time_t_internal(const ASN1_TIME *s, time_t t2, int mode) +{ + struct tm tm1, tm2; + + /* + * This function has never handled failure conditions properly + * The OpenSSL version used to simply follow NULL pointers on failure. + * BoringSSL and OpenSSL now make it return -2 on failure. + * + * The danger is that users of this function will not differentiate the + * -2 failure case from s < t2. Callers must be careful. Sadly this is + * one of those pervasive things from OpenSSL we must continue with. + */ + + if (ASN1_time_parse(s->data, s->length, &tm1, mode) == -1) + return -2; + + if (gmtime_r(&t2, &tm2) == NULL) + return -2; + + return ASN1_time_tm_cmp(&tm1, &tm2); +} + +int +ASN1_TIME_compare(const ASN1_TIME *t1, const ASN1_TIME *t2) +{ + struct tm tm1, tm2; + + if (t1->type != V_ASN1_UTCTIME && t1->type != V_ASN1_GENERALIZEDTIME) + return -2; + + if (t2->type != V_ASN1_UTCTIME && t2->type != V_ASN1_GENERALIZEDTIME) + return -2; + + if (ASN1_time_parse(t1->data, t1->length, &tm1, t1->type) == -1) + return -2; + + if (ASN1_time_parse(t1->data, t2->length, &tm2, t2->type) == -1) + return -2; + + return ASN1_time_tm_cmp(&tm1, &tm2); +} + +int +ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t) +{ + if (s->type == V_ASN1_UTCTIME) + return ASN1_TIME_cmp_time_t_internal(s, t, V_ASN1_UTCTIME); + if (s->type == V_ASN1_GENERALIZEDTIME) + return ASN1_TIME_cmp_time_t_internal(s, t, + V_ASN1_GENERALIZEDTIME); + return -2; +} + /* * ASN1_UTCTIME wrappers */ @@ -413,26 +468,11 @@ ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec) } int -ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t2) +ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) { - struct tm tm1, tm2; - - /* - * This function has never handled failure conditions properly - * and should be deprecated. The OpenSSL version used to - * simply follow NULL pointers on failure. BoringSSL and - * OpenSSL now make it return -2 on failure. - * - * The danger is that users of this function will not - * differentiate the -2 failure case from t1 < t2. - */ - if (ASN1_time_parse(s->data, s->length, &tm1, V_ASN1_UTCTIME) == -1) - return (-2); /* XXX */ - - if (gmtime_r(&t2, &tm2) == NULL) - return (-2); /* XXX */ - - return ASN1_time_tm_cmp(&tm1, &tm2); + if (s->type == V_ASN1_UTCTIME) + return ASN1_TIME_cmp_time_t_internal(s, t, V_ASN1_UTCTIME); + return -2; } /* @@ -468,3 +508,19 @@ ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, V_ASN1_GENERALIZEDTIME)); } + +int +ASN1_TIME_normalize(ASN1_TIME *t) +{ + struct tm tm; + + if (!ASN1_TIME_to_tm(t, &tm)) + return 0; + return tm_to_rfc5280_time(&tm, t) != NULL; +} + +int +ASN1_TIME_set_string_x509(ASN1_TIME *s, const char *str) +{ + return ASN1_TIME_set_string_internal(s, str, RFC5280); +} diff --git a/lib/libcrypto/asn1/asn1.h b/lib/libcrypto/asn1/asn1.h index 0db0b1d8fee..3ff3f51d34d 100644 --- a/lib/libcrypto/asn1/asn1.h +++ b/lib/libcrypto/asn1/asn1.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1.h,v 1.64 2022/06/25 16:15:18 jsing Exp $ */ +/* $OpenBSD: asn1.h,v 1.65 2022/06/27 13:54:57 beck Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -719,6 +719,13 @@ ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len); int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out); extern const ASN1_ITEM ASN1_TIME_it; +#ifdef LIBRESSL_INTERNAL +int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm); +int ASN1_TIME_compare(const ASN1_TIME *t1, const ASN1_TIME *t2); +int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t2); +int ASN1_TIME_normalize(ASN1_TIME *t); +int ASN1_TIME_set_string_x509(ASN1_TIME *time, const char *str); +#endif int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to); diff --git a/regress/lib/libcrypto/asn1/asn1time.c b/regress/lib/libcrypto/asn1/asn1time.c index 6bbbf393a15..d3927929ca9 100644 --- a/regress/lib/libcrypto/asn1/asn1time.c +++ b/regress/lib/libcrypto/asn1/asn1time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1time.c,v 1.9 2021/12/09 16:31:33 jsing Exp $ */ +/* $OpenBSD: asn1time.c,v 1.10 2022/06/27 13:54:58 beck Exp $ */ /* * Copyright (c) 2015 Joel Sing * @@ -217,6 +217,11 @@ asn1_invtime_test(int test_no, struct asn1_time_test *att) "string '%s'\n", test_no, att->str); goto done; } + if (ASN1_TIME_set_string_x509(t, att->str) != 0) { + fprintf(stderr, "FAIL: test %i - successfully set x509 TIME " + "string '%s'\n", test_no, att->str); + goto done; + } failure = 0; @@ -357,7 +362,7 @@ asn1_utctime_test(int test_no, struct asn1_time_test *att) static int asn1_time_test(int test_no, struct asn1_time_test *att, int type) { - ASN1_TIME *t = NULL; + ASN1_TIME *t = NULL, *tx509 = NULL; int failure = 1; if (ASN1_TIME_set_string(NULL, att->str) != 1) { @@ -369,6 +374,9 @@ asn1_time_test(int test_no, struct asn1_time_test *att, int type) if ((t = ASN1_TIME_new()) == NULL) goto done; + if ((tx509 = ASN1_TIME_new()) == NULL) + goto done; + if (ASN1_TIME_set_string(t, att->str) != 1) { fprintf(stderr, "FAIL: test %i - failed to set string '%s'\n", test_no, att->str); @@ -381,11 +389,36 @@ asn1_time_test(int test_no, struct asn1_time_test *att, int type) goto done; } + if (ASN1_TIME_normalize(t) != 1) { + fprintf(stderr, "FAIL: test %i - failed to set normalize '%s'\n", + test_no, att->str); + goto done; + } + + if (ASN1_TIME_set_string_x509(tx509, t->data) != 1) { + fprintf(stderr, "FAIL: test %i - failed to set string X509 '%s'\n", + test_no, t->data); + goto done; + } + + if (t->type != tx509->type) { + fprintf(stderr, "FAIL: test %i - type %d, different from %d\n", + test_no, t->type, tx509->type); + goto done; + } + + if (ASN1_TIME_compare(t, tx509) != 0) { + fprintf(stderr, "FAIL: ASN1_TIME values differ!\n"); + goto done; + } + + failure = 0; done: ASN1_TIME_free(t); + ASN1_TIME_free(tx509); return (failure); }