> > Index: a_time.c > > +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; > > + out = &tmp; > > So we no longer return the newly-allocated ASN1_GENERALIZEDTIME through > *out? This might be a problem, since callers seem to use the value in > *out instead of storing the return value.
Oh, you mean in the case where out != NULL but *out == NULL. You're right. The last line above should be if (out != NULL) *out = tmp; else out = &tmp; Fixed diff below. Index: a_gentm.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/asn1/a_gentm.c,v retrieving revision 1.17 diff -u -p -r1.17 a_gentm.c --- a_gentm.c 19 Apr 2014 11:43:07 -0000 1.17 +++ a_gentm.c 15 May 2014 19:34:46 -0000 @@ -208,20 +208,15 @@ ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZE 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); @@ -249,4 +244,25 @@ ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZE s->length = strlen(p); 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; + } Index: a_time.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/asn1/a_time.c,v retrieving revision 1.17 diff -u -p -r1.17 a_time.c --- a_time.c 21 Apr 2014 00:52:00 -0000 1.17 +++ a_time.c 15 May 2014 19:34:46 -0000 @@ -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 * 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,12 +146,35 @@ ASN1_TIME_to_generalizedtime(ASN1_TIME * /* 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; } Index: a_utctm.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/asn1/a_utctm.c,v retrieving revision 1.22 diff -u -p -r1.22 a_utctm.c --- a_utctm.c 21 Apr 2014 11:23:09 -0000 1.22 +++ a_utctm.c 15 May 2014 19:34:46 -0000 @@ -149,19 +149,15 @@ ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_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); @@ -191,6 +187,25 @@ ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t s->length = strlen(p); s->type = V_ASN1_UTCTIME; 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 Index: asn_mime.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/asn1/asn_mime.c,v retrieving revision 1.13 diff -u -p -r1.13 asn_mime.c --- asn_mime.c 26 Apr 2014 18:56:37 -0000 1.13 +++ asn_mime.c 15 May 2014 19:34:46 -0000 @@ -825,11 +825,12 @@ static MIME_HEADER * mime_hdr_new(char *name, char *value) { MIME_HEADER *mhdr; - char *tmpname, *tmpval, *p; + char *tmpname = NULL, *tmpval = NULL, *p; int c; + if (name) { if (!(tmpname = BUF_strdup(name))) - return NULL; + goto err; for (p = tmpname; *p; p++) { c = (unsigned char)*p; if (isupper(c)) { @@ -837,11 +838,10 @@ mime_hdr_new(char *name, char *value) *p = c; } } - } else - tmpname = NULL; + } if (value) { if (!(tmpval = BUF_strdup(value))) - return NULL; + goto err; for (p = tmpval; *p; p++) { c = (unsigned char)*p; if (isupper(c)) { @@ -849,32 +849,34 @@ mime_hdr_new(char *name, char *value) *p = c; } } - } else tmpval = NULL; - mhdr = malloc(sizeof(MIME_HEADER)); - if (!mhdr) { - OPENSSL_free(tmpname); - return NULL; } + mhdr = malloc(sizeof(MIME_HEADER)); + if (!mhdr) + goto err; mhdr->name = tmpname; mhdr->value = tmpval; if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) { free(mhdr); - return NULL; + goto err; } return mhdr; +err: + free(tmpname); + free(tmpval); + return NULL; } static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value) { - char *tmpname, *tmpval, *p; + char *tmpname = NULL, *tmpval = NULL, *p; int c; MIME_PARAM *mparam; if (name) { tmpname = BUF_strdup(name); if (!tmpname) - return 0; + goto err; for (p = tmpname; *p; p++) { c = (unsigned char)*p; if (isupper(c)) { @@ -882,22 +884,24 @@ mime_hdr_addparam(MIME_HEADER *mhdr, cha *p = c; } } - } else - tmpname = NULL; + } if (value) { tmpval = BUF_strdup(value); if (!tmpval) - return 0; - } else - tmpval = NULL; + goto err; + } /* Parameter values are case sensitive so leave as is */ mparam = malloc(sizeof(MIME_PARAM)); if (!mparam) - return 0; + goto err; mparam->param_name = tmpname; mparam->param_value = tmpval; sk_MIME_PARAM_push(mhdr->params, mparam); return 1; +err: + free(tmpname); + free(tmpval); + return 0; } static int Index: asn_pack.c =================================================================== RCS file: /cvs/src/lib/libssl/src/crypto/asn1/asn_pack.c,v retrieving revision 1.10 diff -u -p -r1.10 asn_pack.c --- asn_pack.c 12 May 2014 19:16:35 -0000 1.10 +++ asn_pack.c 15 May 2014 19:34:46 -0000 @@ -137,22 +137,26 @@ ASN1_pack_string(void *obj, i2d_of_void ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); return NULL; } - if (oct) - *oct = octmp; } else octmp = *oct; if (!(octmp->length = i2d(obj, NULL))) { ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR); - return NULL; + goto err; } if (!(p = malloc (octmp->length))) { ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE); - return NULL; + goto err; } octmp->data = p; i2d (obj, &p); + if (oct) + *oct = octmp; return octmp; +err: + if (!oct || octmp != *oct) + ASN1_STRING_free(octmp); + return NULL; } #endif @@ -169,8 +173,6 @@ ASN1_item_pack(void *obj, const ASN1_ITE ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); return NULL; } - if (oct) - *oct = octmp; } else octmp = *oct; @@ -181,13 +183,19 @@ ASN1_item_pack(void *obj, const ASN1_ITE if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) { ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR); - return NULL; + goto err; } if (!octmp->data) { ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); - return NULL; + goto err; } + if (oct) + *oct = octmp; return octmp; +err: + if (!oct || octmp != *oct) + ASN1_STRING_free(octmp); + return NULL; } /* Extract an ASN1 object from an ASN1_STRING */