summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2014-05-15 21:06:11 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2014-05-15 21:06:11 +0000
commit06c9bf96ea51d14b7758a71b4cf5b5fb5cde2ac5 (patch)
treed1b510fe996011a27da53d9ef846f8937fedf87a /lib
parent3fb8c691b2af959e856ebae9f6b357637db64c6e (diff)
Replace ASN1_GENERALIZEDTIME_adj(), ASN1_UTCTIME_adj() and
ASN1_TIME_to_generalizedtime() with wrappers around their former implementations, making sure memory allocated is freed in all failure cases. help and ok from beck@ and Brendan MacDonell.
Diffstat (limited to 'lib')
-rw-r--r--lib/libcrypto/asn1/a_gentm.c32
-rw-r--r--lib/libcrypto/asn1/a_time.c37
-rw-r--r--lib/libcrypto/asn1/a_utctm.c29
3 files changed, 73 insertions, 25 deletions
diff --git a/lib/libcrypto/asn1/a_gentm.c b/lib/libcrypto/asn1/a_gentm.c
index f331bff3202..7f8bc2fef72 100644
--- a/lib/libcrypto/asn1/a_gentm.c
+++ b/lib/libcrypto/asn1/a_gentm.c
@@ -208,20 +208,15 @@ ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t)
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
}
-ASN1_GENERALIZEDTIME *
-ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day,
- long offset_sec)
+static ASN1_GENERALIZEDTIME *
+ASN1_GENERALIZEDTIME_adj_internal(ASN1_GENERALIZEDTIME *s, time_t t,
+ int offset_day, long offset_sec)
{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
- if (s == NULL)
- s = M_ASN1_GENERALIZEDTIME_new();
- if (s == NULL)
- return (NULL);
-
ts = gmtime_r(&t, &data);
if (ts == NULL)
return (NULL);
@@ -250,3 +245,24 @@ ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day,
s->type = V_ASN1_GENERALIZEDTIME;
return (s);
}
+
+ASN1_GENERALIZEDTIME *
+ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day,
+ long offset_sec)
+{
+ ASN1_GENERALIZEDTIME *tmp = NULL, *ret;
+
+ if (s == NULL) {
+ tmp = M_ASN1_GENERALIZEDTIME_new();
+ if (tmp == NULL)
+ return NULL;
+ s = tmp;
+ }
+
+ ret = ASN1_GENERALIZEDTIME_adj_internal(s, t, offset_day, offset_sec);
+ if (ret == NULL && tmp != NULL)
+ M_ASN1_GENERALIZEDTIME_free(tmp);
+
+ return ret;
+
+}
diff --git a/lib/libcrypto/asn1/a_time.c b/lib/libcrypto/asn1/a_time.c
index 8db21636228..574c99bbf8e 100644
--- a/lib/libcrypto/asn1/a_time.c
+++ b/lib/libcrypto/asn1/a_time.c
@@ -120,8 +120,8 @@ ASN1_TIME_check(ASN1_TIME *t)
}
/* Convert an ASN1_TIME structure to GeneralizedTime */
-ASN1_GENERALIZEDTIME *
-ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
+static ASN1_GENERALIZEDTIME *
+ASN1_TIME_to_generalizedtime_internal(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
{
ASN1_GENERALIZEDTIME *ret;
char *str;
@@ -131,13 +131,7 @@ ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
if (!ASN1_TIME_check(t))
return NULL;
- if (!out || !*out) {
- if (!(ret = ASN1_GENERALIZEDTIME_new ()))
- return NULL;
- if (out)
- *out = ret;
- } else
- ret = *out;
+ ret = *out;
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME) {
@@ -152,15 +146,38 @@ ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
newlen = t->length + 2 + 1;
str = (char *)ret->data;
+ /* XXX ASN1_TIME is not Y2050 compatible */
i = snprintf(str, newlen, "%s%s", (t->data[0] >= '5') ? "19" : "20",
(char *) t->data);
if (i == -1 || i >= newlen) {
- ASN1_STRING_free(ret);
+ M_ASN1_GENERALIZEDTIME_free(ret);
+ *out = NULL;
return NULL;
}
return ret;
}
+ASN1_GENERALIZEDTIME *
+ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
+{
+ ASN1_GENERALIZEDTIME *tmp = NULL, *ret;
+
+ if (!out || !*out) {
+ if (!(tmp = ASN1_GENERALIZEDTIME_new()))
+ return NULL;
+ if (out != NULL)
+ *out = tmp;
+ else
+ out = &tmp;
+ }
+
+ ret = ASN1_TIME_to_generalizedtime_internal(t, out);
+ if (ret == NULL && tmp != NULL)
+ ASN1_GENERALIZEDTIME_free(tmp);
+
+ return ret;
+}
+
int
ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
{
diff --git a/lib/libcrypto/asn1/a_utctm.c b/lib/libcrypto/asn1/a_utctm.c
index e4db9f8a994..35f2b7fd668 100644
--- a/lib/libcrypto/asn1/a_utctm.c
+++ b/lib/libcrypto/asn1/a_utctm.c
@@ -149,19 +149,15 @@ ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
return ASN1_UTCTIME_adj(s, t, 0, 0);
}
-ASN1_UTCTIME *
-ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec)
+static ASN1_UTCTIME *
+ASN1_UTCTIME_adj_internal(ASN1_UTCTIME *s, time_t t, int offset_day,
+ long offset_sec)
{
char *p;
struct tm *ts;
struct tm data;
size_t len = 20;
- if (s == NULL)
- s = M_ASN1_UTCTIME_new();
- if (s == NULL)
- return (NULL);
-
ts = gmtime_r(&t, &data);
if (ts == NULL)
return (NULL);
@@ -193,6 +189,25 @@ ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec)
return (s);
}
+ASN1_UTCTIME *
+ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec)
+{
+ ASN1_UTCTIME *tmp = NULL, *ret;
+
+ if (s == NULL) {
+ tmp = M_ASN1_UTCTIME_new();
+ if (tmp == NULL)
+ return NULL;
+ s = tmp;
+ }
+
+ ret = ASN1_UTCTIME_adj_internal(s, t, offset_day, offset_sec);
+ if (ret == NULL && tmp != NULL)
+ M_ASN1_UTCTIME_free(tmp);
+
+ return ret;
+}
+
int
ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
{