summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbeck <>2022-06-27 13:54:58 +0000
committerbeck <>2022-06-27 13:54:58 +0000
commit1dfc6d4bc0a9c452ed36f0b04d5dcf53b77e6f1f (patch)
tree5c0b15ff90e68ca58b32edaff42c8dceb326d227 /src
parent89b19fa26965d5b4d261248d57a3cd0650dc01e1 (diff)
downloadopenbsd-1dfc6d4bc0a9c452ed36f0b04d5dcf53b77e6f1f.tar.gz
openbsd-1dfc6d4bc0a9c452ed36f0b04d5dcf53b77e6f1f.tar.bz2
openbsd-1dfc6d4bc0a9c452ed36f0b04d5dcf53b77e6f1f.zip
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@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/a_time.c5
-rw-r--r--src/lib/libcrypto/asn1/a_time_tm.c96
-rw-r--r--src/lib/libcrypto/asn1/asn1.h9
-rw-r--r--src/regress/lib/libcrypto/asn1/asn1time.c37
4 files changed, 121 insertions, 26 deletions
diff --git a/src/lib/libcrypto/asn1/a_time.c b/src/lib/libcrypto/asn1/a_time.c
index cd6a790cac..03311e1b7f 100644
--- a/src/lib/libcrypto/asn1/a_time.c
+++ b/src/lib/libcrypto/asn1/a_time.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: a_time.c,v 1.33 2021/12/25 07:48:09 jsing Exp $ */ 1/* $OpenBSD: a_time.c,v 1.34 2022/06/27 13:54:57 beck Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -92,8 +92,7 @@ ASN1_TIME_free(ASN1_TIME *a)
92 ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it); 92 ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it);
93} 93}
94 94
95/* Public API in OpenSSL. Kept internal for now. */ 95int
96static int
97ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm) 96ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm)
98{ 97{
99 time_t now; 98 time_t now;
diff --git a/src/lib/libcrypto/asn1/a_time_tm.c b/src/lib/libcrypto/asn1/a_time_tm.c
index 0e040ae579..23e2ce4b4c 100644
--- a/src/lib/libcrypto/asn1/a_time_tm.c
+++ b/src/lib/libcrypto/asn1/a_time_tm.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: a_time_tm.c,v 1.20 2022/04/28 17:31:29 tb Exp $ */ 1/* $OpenBSD: a_time_tm.c,v 1.21 2022/06/27 13:54:57 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Bob Beck <beck@openbsd.org> 3 * Copyright (c) 2015 Bob Beck <beck@openbsd.org>
4 * 4 *
@@ -379,6 +379,61 @@ ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
379 return (ASN1_TIME_set_string_internal(s, str, 0)); 379 return (ASN1_TIME_set_string_internal(s, str, 0));
380} 380}
381 381
382static int
383ASN1_TIME_cmp_time_t_internal(const ASN1_TIME *s, time_t t2, int mode)
384{
385 struct tm tm1, tm2;
386
387 /*
388 * This function has never handled failure conditions properly
389 * The OpenSSL version used to simply follow NULL pointers on failure.
390 * BoringSSL and OpenSSL now make it return -2 on failure.
391 *
392 * The danger is that users of this function will not differentiate the
393 * -2 failure case from s < t2. Callers must be careful. Sadly this is
394 * one of those pervasive things from OpenSSL we must continue with.
395 */
396
397 if (ASN1_time_parse(s->data, s->length, &tm1, mode) == -1)
398 return -2;
399
400 if (gmtime_r(&t2, &tm2) == NULL)
401 return -2;
402
403 return ASN1_time_tm_cmp(&tm1, &tm2);
404}
405
406int
407ASN1_TIME_compare(const ASN1_TIME *t1, const ASN1_TIME *t2)
408{
409 struct tm tm1, tm2;
410
411 if (t1->type != V_ASN1_UTCTIME && t1->type != V_ASN1_GENERALIZEDTIME)
412 return -2;
413
414 if (t2->type != V_ASN1_UTCTIME && t2->type != V_ASN1_GENERALIZEDTIME)
415 return -2;
416
417 if (ASN1_time_parse(t1->data, t1->length, &tm1, t1->type) == -1)
418 return -2;
419
420 if (ASN1_time_parse(t1->data, t2->length, &tm2, t2->type) == -1)
421 return -2;
422
423 return ASN1_time_tm_cmp(&tm1, &tm2);
424}
425
426int
427ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t)
428{
429 if (s->type == V_ASN1_UTCTIME)
430 return ASN1_TIME_cmp_time_t_internal(s, t, V_ASN1_UTCTIME);
431 if (s->type == V_ASN1_GENERALIZEDTIME)
432 return ASN1_TIME_cmp_time_t_internal(s, t,
433 V_ASN1_GENERALIZEDTIME);
434 return -2;
435}
436
382/* 437/*
383 * ASN1_UTCTIME wrappers 438 * ASN1_UTCTIME wrappers
384 */ 439 */
@@ -413,26 +468,11 @@ ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec)
413} 468}
414 469
415int 470int
416ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t2) 471ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
417{ 472{
418 struct tm tm1, tm2; 473 if (s->type == V_ASN1_UTCTIME)
419 474 return ASN1_TIME_cmp_time_t_internal(s, t, V_ASN1_UTCTIME);
420 /* 475 return -2;
421 * This function has never handled failure conditions properly
422 * and should be deprecated. The OpenSSL version used to
423 * simply follow NULL pointers on failure. BoringSSL and
424 * OpenSSL now make it return -2 on failure.
425 *
426 * The danger is that users of this function will not
427 * differentiate the -2 failure case from t1 < t2.
428 */
429 if (ASN1_time_parse(s->data, s->length, &tm1, V_ASN1_UTCTIME) == -1)
430 return (-2); /* XXX */
431
432 if (gmtime_r(&t2, &tm2) == NULL)
433 return (-2); /* XXX */
434
435 return ASN1_time_tm_cmp(&tm1, &tm2);
436} 476}
437 477
438/* 478/*
@@ -468,3 +508,19 @@ ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day,
468 return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, 508 return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec,
469 V_ASN1_GENERALIZEDTIME)); 509 V_ASN1_GENERALIZEDTIME));
470} 510}
511
512int
513ASN1_TIME_normalize(ASN1_TIME *t)
514{
515 struct tm tm;
516
517 if (!ASN1_TIME_to_tm(t, &tm))
518 return 0;
519 return tm_to_rfc5280_time(&tm, t) != NULL;
520}
521
522int
523ASN1_TIME_set_string_x509(ASN1_TIME *s, const char *str)
524{
525 return ASN1_TIME_set_string_internal(s, str, RFC5280);
526}
diff --git a/src/lib/libcrypto/asn1/asn1.h b/src/lib/libcrypto/asn1/asn1.h
index 0db0b1d8fe..3ff3f51d34 100644
--- a/src/lib/libcrypto/asn1/asn1.h
+++ b/src/lib/libcrypto/asn1/asn1.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: asn1.h,v 1.64 2022/06/25 16:15:18 jsing Exp $ */ 1/* $OpenBSD: asn1.h,v 1.65 2022/06/27 13:54:57 beck Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -719,6 +719,13 @@ ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len);
719int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out); 719int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out);
720extern const ASN1_ITEM ASN1_TIME_it; 720extern const ASN1_ITEM ASN1_TIME_it;
721 721
722#ifdef LIBRESSL_INTERNAL
723int ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm);
724int ASN1_TIME_compare(const ASN1_TIME *t1, const ASN1_TIME *t2);
725int ASN1_TIME_cmp_time_t(const ASN1_TIME *s, time_t t2);
726int ASN1_TIME_normalize(ASN1_TIME *t);
727int ASN1_TIME_set_string_x509(ASN1_TIME *time, const char *str);
728#endif
722int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, 729int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from,
723 const ASN1_TIME *to); 730 const ASN1_TIME *to);
724 731
diff --git a/src/regress/lib/libcrypto/asn1/asn1time.c b/src/regress/lib/libcrypto/asn1/asn1time.c
index 6bbbf393a1..d3927929ca 100644
--- a/src/regress/lib/libcrypto/asn1/asn1time.c
+++ b/src/regress/lib/libcrypto/asn1/asn1time.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: asn1time.c,v 1.9 2021/12/09 16:31:33 jsing Exp $ */ 1/* $OpenBSD: asn1time.c,v 1.10 2022/06/27 13:54:58 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2015 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -217,6 +217,11 @@ asn1_invtime_test(int test_no, struct asn1_time_test *att)
217 "string '%s'\n", test_no, att->str); 217 "string '%s'\n", test_no, att->str);
218 goto done; 218 goto done;
219 } 219 }
220 if (ASN1_TIME_set_string_x509(t, att->str) != 0) {
221 fprintf(stderr, "FAIL: test %i - successfully set x509 TIME "
222 "string '%s'\n", test_no, att->str);
223 goto done;
224 }
220 225
221 failure = 0; 226 failure = 0;
222 227
@@ -357,7 +362,7 @@ asn1_utctime_test(int test_no, struct asn1_time_test *att)
357static int 362static int
358asn1_time_test(int test_no, struct asn1_time_test *att, int type) 363asn1_time_test(int test_no, struct asn1_time_test *att, int type)
359{ 364{
360 ASN1_TIME *t = NULL; 365 ASN1_TIME *t = NULL, *tx509 = NULL;
361 int failure = 1; 366 int failure = 1;
362 367
363 if (ASN1_TIME_set_string(NULL, att->str) != 1) { 368 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)
369 if ((t = ASN1_TIME_new()) == NULL) 374 if ((t = ASN1_TIME_new()) == NULL)
370 goto done; 375 goto done;
371 376
377 if ((tx509 = ASN1_TIME_new()) == NULL)
378 goto done;
379
372 if (ASN1_TIME_set_string(t, att->str) != 1) { 380 if (ASN1_TIME_set_string(t, att->str) != 1) {
373 fprintf(stderr, "FAIL: test %i - failed to set string '%s'\n", 381 fprintf(stderr, "FAIL: test %i - failed to set string '%s'\n",
374 test_no, att->str); 382 test_no, att->str);
@@ -381,11 +389,36 @@ asn1_time_test(int test_no, struct asn1_time_test *att, int type)
381 goto done; 389 goto done;
382 } 390 }
383 391
392 if (ASN1_TIME_normalize(t) != 1) {
393 fprintf(stderr, "FAIL: test %i - failed to set normalize '%s'\n",
394 test_no, att->str);
395 goto done;
396 }
397
398 if (ASN1_TIME_set_string_x509(tx509, t->data) != 1) {
399 fprintf(stderr, "FAIL: test %i - failed to set string X509 '%s'\n",
400 test_no, t->data);
401 goto done;
402 }
403
404 if (t->type != tx509->type) {
405 fprintf(stderr, "FAIL: test %i - type %d, different from %d\n",
406 test_no, t->type, tx509->type);
407 goto done;
408 }
409
410 if (ASN1_TIME_compare(t, tx509) != 0) {
411 fprintf(stderr, "FAIL: ASN1_TIME values differ!\n");
412 goto done;
413 }
414
415
384 failure = 0; 416 failure = 0;
385 417
386 done: 418 done:
387 419
388 ASN1_TIME_free(t); 420 ASN1_TIME_free(t);
421 ASN1_TIME_free(tx509);
389 422
390 return (failure); 423 return (failure);
391} 424}