aboutsummaryrefslogtreecommitdiff
path: root/crypto/asn1
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2023-06-04 12:21:29 -0400
committerBoringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-06-08 21:49:20 +0000
commit761c3ed03c80e1dd8806bc114c26226fa5aeec62 (patch)
tree03cfd7283a3bc902af96dda13a98ef4338dd81fd /crypto/asn1
parent1ca572304a8e3c7da7e7d20a36f81d4337e8f8a6 (diff)
downloadboringssl-761c3ed03c80e1dd8806bc114c26226fa5aeec62.zip
boringssl-761c3ed03c80e1dd8806bc114c26226fa5aeec62.tar.gz
boringssl-761c3ed03c80e1dd8806bc114c26226fa5aeec62.tar.bz2
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>
Diffstat (limited to 'crypto/asn1')
-rw-r--r--crypto/asn1/a_time.c35
-rw-r--r--crypto/asn1/asn1_test.cc35
2 files changed, 69 insertions, 1 deletions
diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c
index 87bf092..d8ec85f 100644
--- a/crypto/asn1/a_time.c
+++ b/crypto/asn1/a_time.c
@@ -61,6 +61,7 @@
#include <time.h>
#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
#include <openssl/err.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);
}
+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,
long offset_sec) {
struct tm tm;
@@ -95,7 +100,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, int64_t posix_time, int offset_day,
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_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);
}
+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,
int allow_timezone_offset) {
if (t == NULL) {
diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc
index c7e0bf0..94f2272 100644
--- a/crypto/asn1/asn1_test.cc
+++ b/crypto/asn1/asn1_test.cc
@@ -1100,6 +1100,32 @@ TEST(ASN1Test, TimeSetString) {
EXPECT_EQ(V_ASN1_GENERALIZEDTIME, ASN1_STRING_type(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.
EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "nope"));
EXPECT_FALSE(ASN1_UTCTIME_set_string(s.get(), "19700101000000Z"));
@@ -1111,17 +1137,26 @@ TEST(ASN1Test, TimeSetString) {
// to anything.
EXPECT_TRUE(ASN1_UTCTIME_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_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_GENERALIZEDTIME_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.
EXPECT_FALSE(ASN1_UTCTIME_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_TIME_set_string(nullptr, "19700101000000-0400"));
+ EXPECT_FALSE(ASN1_TIME_set_string_X509(nullptr, "19700101000000-0400"));
}
TEST(ASN1Test, AdjTime) {