Add ASN1_TIME_set_string_X509
rust-openssl uses this function when targetting OpenSSL 1.1.x. Change-Id: Ifeb1b65be9976358f9ee636ed23c1a931e03b275 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60609 Auto-Submit: David Benjamin <davidben@google.com> Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: Bob Beck <bbe@google.com>
This commit is contained in:
parent
1ca572304a
commit
761c3ed03c
@ -61,6 +61,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include <openssl/asn1t.h>
|
#include <openssl/asn1t.h>
|
||||||
|
#include <openssl/bytestring.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#include <openssl/mem.h>
|
#include <openssl/mem.h>
|
||||||
|
|
||||||
@ -82,6 +83,10 @@ ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t time) {
|
|||||||
return ASN1_TIME_adj(s, time, 0, 0);
|
return ASN1_TIME_adj(s, time, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int fits_in_utc_time(const struct tm *tm) {
|
||||||
|
return 50 <= tm->tm_year && tm->tm_year < 150;
|
||||||
|
}
|
||||||
|
|
||||||
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, int offset_day,
|
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, int offset_day,
|
||||||
long offset_sec) {
|
long offset_sec) {
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
@ -95,7 +100,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, int offset_day,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((tm.tm_year >= 50) && (tm.tm_year < 150)) {
|
if (fits_in_utc_time(&tm)) {
|
||||||
return ASN1_UTCTIME_adj(s, posix_time, offset_day, offset_sec);
|
return ASN1_UTCTIME_adj(s, posix_time, offset_day, offset_sec);
|
||||||
}
|
}
|
||||||
return ASN1_GENERALIZEDTIME_adj(s, posix_time, offset_day, offset_sec);
|
return ASN1_GENERALIZEDTIME_adj(s, posix_time, offset_day, offset_sec);
|
||||||
@ -171,6 +176,34 @@ int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) {
|
|||||||
ASN1_GENERALIZEDTIME_set_string(s, str);
|
ASN1_GENERALIZEDTIME_set_string(s, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str) {
|
||||||
|
CBS cbs;
|
||||||
|
CBS_init(&cbs, (const uint8_t*)str, strlen(str));
|
||||||
|
int type;
|
||||||
|
struct tm tm;
|
||||||
|
if (CBS_parse_utc_time(&cbs, /*out_tm=*/NULL,
|
||||||
|
/*allow_timezone_offset=*/0)) {
|
||||||
|
type = V_ASN1_UTCTIME;
|
||||||
|
} else if (CBS_parse_generalized_time(&cbs, &tm,
|
||||||
|
/*allow_timezone_offset=*/0)) {
|
||||||
|
type = V_ASN1_GENERALIZEDTIME;
|
||||||
|
if (fits_in_utc_time(&tm)) {
|
||||||
|
type = V_ASN1_UTCTIME;
|
||||||
|
CBS_skip(&cbs, 2);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s != NULL) {
|
||||||
|
if (!ASN1_STRING_set(s, CBS_data(&cbs), CBS_len(&cbs))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
s->type = type;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t,
|
static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t,
|
||||||
int allow_timezone_offset) {
|
int allow_timezone_offset) {
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
|
@ -1100,6 +1100,32 @@ TEST(ASN1Test, TimeSetString) {
|
|||||||
EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get()));
|
EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get()));
|
||||||
EXPECT_EQ("19700101000000Z", ASN1StringToStdString(s.get()));
|
EXPECT_EQ("19700101000000Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
|
// |ASN1_TIME_set_string_X509| behaves similarly except it additionally
|
||||||
|
// converts GeneralizedTime to UTCTime if it fits.
|
||||||
|
ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "700101000000Z"));
|
||||||
|
EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get()));
|
||||||
|
EXPECT_EQ("700101000000Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
|
ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "19700101000000Z"));
|
||||||
|
EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get()));
|
||||||
|
EXPECT_EQ("700101000000Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
|
ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "19500101000000Z"));
|
||||||
|
EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get()));
|
||||||
|
EXPECT_EQ("500101000000Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
|
ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "19491231235959Z"));
|
||||||
|
EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get()));
|
||||||
|
EXPECT_EQ("19491231235959Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
|
ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "20491231235959Z"));
|
||||||
|
EXPECT_EQ(V_ASN1_UTCTIME, ASN1_STRING_type(s.get()));
|
||||||
|
EXPECT_EQ("491231235959Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
|
ASSERT_TRUE(ASN1_TIME_set_string_X509(s.get(), "20500101000000Z"));
|
||||||
|
EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(s.get()));
|
||||||
|
EXPECT_EQ("20500101000000Z", ASN1StringToStdString(s.get()));
|
||||||
|
|
||||||
// Invalid inputs are rejected.
|
// Invalid inputs are rejected.
|
||||||
EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "nope"));
|
EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "nope"));
|
||||||
EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "19700101000000Z"));
|
EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "19700101000000Z"));
|
||||||
@ -1111,17 +1137,26 @@ TEST(ASN1Test, TimeSetString) {
|
|||||||
// to anything.
|
// to anything.
|
||||||
EXPECT_TRUE(ASN1_UTCTIME_set_string(nullptr, "700101000000Z"));
|
EXPECT_TRUE(ASN1_UTCTIME_set_string(nullptr, "700101000000Z"));
|
||||||
EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "700101000000Z"));
|
EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "700101000000Z"));
|
||||||
|
EXPECT_TRUE(ASN1_TIME_set_string_X509(nullptr, "700101000000Z"));
|
||||||
EXPECT_TRUE(ASN1_GENERALIZEDTIME_set_string(nullptr, "19700101000000Z"));
|
EXPECT_TRUE(ASN1_GENERALIZEDTIME_set_string(nullptr, "19700101000000Z"));
|
||||||
EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "19700101000000Z"));
|
EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "19700101000000Z"));
|
||||||
|
EXPECT_TRUE(ASN1_TIME_set_string_X509(nullptr, "19700101000000Z"));
|
||||||
|
// Test an input |ASN1_TIME_set_string_X509| won't convert to UTCTime.
|
||||||
|
EXPECT_TRUE(ASN1_GENERALIZEDTIME_set_string(nullptr, "20500101000000Z"));
|
||||||
|
EXPECT_TRUE(ASN1_TIME_set_string(nullptr, "20500101000000Z"));
|
||||||
|
EXPECT_TRUE(ASN1_TIME_set_string_X509(nullptr, "20500101000000Z"));
|
||||||
EXPECT_FALSE(ASN1_UTCTIME_set_string(nullptr, "nope"));
|
EXPECT_FALSE(ASN1_UTCTIME_set_string(nullptr, "nope"));
|
||||||
EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(nullptr, "nope"));
|
EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(nullptr, "nope"));
|
||||||
EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "nope"));
|
EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "nope"));
|
||||||
|
EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "nope"));
|
||||||
|
|
||||||
// Timezone offsets are not allowed by DER.
|
// Timezone offsets are not allowed by DER.
|
||||||
EXPECT_FALSE(ASN1_UTCTIME_set_string(nullptr, "700101000000-0400"));
|
EXPECT_FALSE(ASN1_UTCTIME_set_string(nullptr, "700101000000-0400"));
|
||||||
EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "700101000000-0400"));
|
EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "700101000000-0400"));
|
||||||
|
EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "700101000000-0400"));
|
||||||
EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(nullptr, "19700101000000-0400"));
|
EXPECT_FALSE(ASN1_GENERALIZEDTIME_set_string(nullptr, "19700101000000-0400"));
|
||||||
EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "19700101000000-0400"));
|
EXPECT_FALSE(ASN1_TIME_set_string(nullptr, "19700101000000-0400"));
|
||||||
|
EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "19700101000000-0400"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(ASN1Test, AdjTime) {
|
TEST(ASN1Test, AdjTime) {
|
||||||
|
@ -1355,6 +1355,11 @@ OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(
|
|||||||
// GeneralizedTime. If |str| is neither, it returns zero.
|
// GeneralizedTime. If |str| is neither, it returns zero.
|
||||||
OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
|
OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str);
|
||||||
|
|
||||||
|
// ASN1_TIME_set_string_X509 behaves like |ASN1_TIME_set_string| except it
|
||||||
|
// additionally converts GeneralizedTime to UTCTime if it is in the range where
|
||||||
|
// UTCTime is used. See RFC 5280, section 4.1.2.5.
|
||||||
|
OPENSSL_EXPORT int ASN1_TIME_set_string_X509(ASN1_TIME *s, const char *str);
|
||||||
|
|
||||||
// ASN1_TIME_to_time_t converts |t| to a time_t value in |out|. On
|
// ASN1_TIME_to_time_t converts |t| to a time_t value in |out|. On
|
||||||
// success, one is returned. On failure zero is returned. This function
|
// success, one is returned. On failure zero is returned. This function
|
||||||
// will fail if the time can not be represented in a time_t.
|
// will fail if the time can not be represented in a time_t.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user