提交 20ee2bf1 编写于 作者: T Todd Short 提交者: Richard Levitte

Fix time offset calculation.

ASN1_GENERALIZEDTIME and ASN1_UTCTIME may be specified using offsets,
even though that's not supported within certificates.

To convert the offset time back to GMT, the offsets are supposed to be
subtracted, not added. e.g. 1759-0500 == 2359+0100 == 2259Z.
Reviewed-by: NMatt Caswell <matt@openssl.org>
Reviewed-by: NRichard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2654)
上级 ee6b68ce
...@@ -101,7 +101,7 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) ...@@ -101,7 +101,7 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
if (a[o] == 'Z') if (a[o] == 'Z')
o++; o++;
else if ((a[o] == '+') || (a[o] == '-')) { else if ((a[o] == '+') || (a[o] == '-')) {
int offsign = a[o] == '-' ? -1 : 1, offset = 0; int offsign = a[o] == '-' ? 1 : -1, offset = 0;
o++; o++;
if (o + 4 > l) if (o + 4 > l)
goto err; goto err;
......
...@@ -75,7 +75,7 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) ...@@ -75,7 +75,7 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
if (a[o] == 'Z') if (a[o] == 'Z')
o++; o++;
else if ((a[o] == '+') || (a[o] == '-')) { else if ((a[o] == '+') || (a[o] == '-')) {
int offsign = a[o] == '-' ? -1 : 1, offset = 0; int offsign = a[o] == '-' ? 1 : -1, offset = 0;
o++; o++;
if (o + 4 > l) if (o + 4 > l)
goto err; goto err;
......
...@@ -42,7 +42,8 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN ...@@ -42,7 +42,8 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \
bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \ bioprinttest sslapitest dtlstest sslcorrupttest bio_enc_test \
pkey_meth_test uitest cipherbytes_test asn1_encode_test \ pkey_meth_test uitest cipherbytes_test asn1_encode_test \
x509_time_test x509_dup_cert_test recordlentest x509_time_test x509_dup_cert_test recordlentest \
time_offset_test
SOURCE[aborttest]=aborttest.c SOURCE[aborttest]=aborttest.c
INCLUDE[aborttest]=../include INCLUDE[aborttest]=../include
...@@ -345,6 +346,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN ...@@ -345,6 +346,10 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN
INCLUDE[asn1_encode_test]=../include INCLUDE[asn1_encode_test]=../include
DEPEND[asn1_encode_test]=../libcrypto libtestutil.a DEPEND[asn1_encode_test]=../libcrypto libtestutil.a
SOURCE[time_offset_test]=time_offset_test.c
INCLUDE[time_offset_test]=.. ../include
DEPEND[time_offset_test]=../libcrypto libtestutil.a
# Internal test programs. These are essentially a collection of internal # Internal test programs. These are essentially a collection of internal
# test routines. Some of them need to reach internal symbols that aren't # test routines. Some of them need to reach internal symbols that aren't
# available through the shared library (at least on Linux, Solaris, Windows # available through the shared library (at least on Linux, Solaris, Windows
......
#! /usr/bin/env perl
# Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
use OpenSSL::Test::Simple;
simple_test("test_time_offset", "time_offset_test");
/*
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
/* time_t/offset (+/-XXXX) tests for ASN1 and X509 */
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/asn1.h>
#include <openssl/x509.h>
#include "testutil.h"
#include "e_os.h"
typedef struct {
const char *data;
int time_result;
int type;
} TESTDATA;
/**********************************************************************
*
* Test driver
*
***/
static TESTDATA tests[] = {
{ "20001201000000Z", 0, V_ASN1_GENERALIZEDTIME },
{ "20001201010000+0100", 0, V_ASN1_GENERALIZEDTIME },
{ "20001201050000+0500", 0, V_ASN1_GENERALIZEDTIME },
{ "20001130230000-0100", 0, V_ASN1_GENERALIZEDTIME },
{ "20001130190000-0500", 0, V_ASN1_GENERALIZEDTIME },
{ "20001130190001-0500", 1, V_ASN1_GENERALIZEDTIME }, /* +1 second */
{ "20001130185959-0500", -1, V_ASN1_GENERALIZEDTIME }, /* -1 second */
{ "001201000000Z", 0, V_ASN1_UTCTIME },
{ "001201010000+0100", 0, V_ASN1_UTCTIME },
{ "001201050000+0500", 0, V_ASN1_UTCTIME },
{ "001130230000-0100", 0, V_ASN1_UTCTIME },
{ "001130190000-0500", 0, V_ASN1_UTCTIME },
{ "001201000000-0000", 0, V_ASN1_UTCTIME },
{ "001201000001-0000", 1, V_ASN1_UTCTIME }, /* +1 second */
{ "001130235959-0000", -1, V_ASN1_UTCTIME }, /* -1 second */
{ "20001201000000+0000", 0, V_ASN1_GENERALIZEDTIME },
{ "20001201000000+0100", -1, V_ASN1_GENERALIZEDTIME },
{ "001201000000+0100", -1, V_ASN1_UTCTIME },
{ "20001201000000-0100", 1, V_ASN1_GENERALIZEDTIME },
{ "001201000000-0100", 1, V_ASN1_UTCTIME },
{ "20001201123400+1234", 0, V_ASN1_GENERALIZEDTIME },
{ "20001130112600-1234", 0, V_ASN1_GENERALIZEDTIME },
};
static time_t the_time = 975628800;
static ASN1_TIME the_asn1_time = {
15,
V_ASN1_GENERALIZEDTIME,
(unsigned char*)"20001201000000Z",
0
};
static int test_offset(int idx)
{
ASN1_TIME at;
const TESTDATA *testdata = &tests[idx];
int ret = -2;
int day, sec;
at.data = (unsigned char*)testdata->data;
at.length = strlen(testdata->data);
at.type = testdata->type;
if (!TEST_true(ASN1_TIME_diff(&day, &sec, &the_asn1_time, &at))) {
TEST_info("ASN1_TIME_diff() failed for %s\n", at.data);
return 0;
}
if (day > 0)
ret = 1;
else if (day < 0)
ret = -1;
else if (sec > 0)
ret = 1;
else if (sec < 0)
ret = -1;
else
ret = 0;
if (!TEST_int_eq(testdata->time_result, ret)) {
TEST_info("ASN1_TIME_diff() test failed for %s day=%d sec=%d\n", at.data, day, sec);
return 0;
}
if (at.type == V_ASN1_UTCTIME)
ret = ASN1_UTCTIME_cmp_time_t(&at, the_time);
else
return 1; /* no other cmp_time_t() functions available, yet */
if (!TEST_int_eq(testdata->time_result, ret)) {
TEST_info("ASN1_UTCTIME_cmp_time_t() test failed for %s\n", at.data);
return 0;
}
return 1;
}
void register_tests()
{
ADD_ALL_TESTS(test_offset, OSSL_NELEM(tests));
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册