summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormiod <>2014-09-21 12:14:34 +0000
committermiod <>2014-09-21 12:14:34 +0000
commit80b8016d7545ad41a60ce062e675d55c19b94636 (patch)
tree77b01cab9a1322522996df4c81401ee0a96143e0 /src
parenta53ab35a157425f24f2ecc1c879119d6ab466343 (diff)
downloadopenbsd-80b8016d7545ad41a60ce062e675d55c19b94636.tar.gz
openbsd-80b8016d7545ad41a60ce062e675d55c19b94636.tar.bz2
openbsd-80b8016d7545ad41a60ce062e675d55c19b94636.zip
Fix a memory leak in the error path in ASN1_mbstring_ncopy().
Replace an if() posse with a switch() statement in traverse_string(). Remove unnecessary casts in cpy_*(), with tweaks from guenther@; ok bcook@ jsing@ guenther@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/a_mbstr.c48
-rw-r--r--src/lib/libssl/src/crypto/asn1/a_mbstr.c48
2 files changed, 58 insertions, 38 deletions
diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c
index 3bad3b2ec2..985d29824d 100644
--- a/src/lib/libcrypto/asn1/a_mbstr.c
+++ b/src/lib/libcrypto/asn1/a_mbstr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: a_mbstr.c,v 1.19 2014/07/11 08:44:47 jsing Exp $ */ 1/* $OpenBSD: a_mbstr.c,v 1.20 2014/09/21 12:14:34 miod Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999. 3 * project 1999.
4 */ 4 */
@@ -212,7 +212,7 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
212 if (!ASN1_STRING_set(dest, in, len)) { 212 if (!ASN1_STRING_set(dest, in, len)) {
213 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 213 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
214 ERR_R_MALLOC_FAILURE); 214 ERR_R_MALLOC_FAILURE);
215 return -1; 215 goto err;
216 } 216 }
217 return str_type; 217 return str_type;
218 } 218 }
@@ -239,22 +239,27 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
239 if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) { 239 if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) {
240 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 240 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
241 ASN1_R_ILLEGAL_CHARACTERS); 241 ASN1_R_ILLEGAL_CHARACTERS);
242 return -1; 242 goto err;
243 } 243 }
244 cpyfunc = cpy_utf8; 244 cpyfunc = cpy_utf8;
245 break; 245 break;
246 } 246 }
247 if (!(p = malloc(outlen + 1))) { 247 if (!(p = malloc(outlen + 1))) {
248 if (free_out)
249 ASN1_STRING_free(dest);
250 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); 248 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
251 return -1; 249 goto err;
252 } 250 }
253 dest->length = outlen; 251 dest->length = outlen;
254 dest->data = p; 252 dest->data = p;
255 p[outlen] = 0; 253 p[outlen] = 0;
256 traverse_string(in, len, inform, cpyfunc, &p); 254 traverse_string(in, len, inform, cpyfunc, &p);
257 return str_type; 255 return str_type;
256
257err:
258 if (free_out) {
259 ASN1_STRING_free(dest);
260 *out = NULL;
261 }
262 return -1;
258} 263}
259 264
260/* This function traverses a string and passes the value of each character 265/* This function traverses a string and passes the value of each character
@@ -269,30 +274,35 @@ traverse_string(const unsigned char *p, int len, int inform,
269 int ret; 274 int ret;
270 275
271 while (len) { 276 while (len) {
272 if (inform == MBSTRING_ASC) { 277 switch (inform) {
278 case MBSTRING_ASC:
273 value = *p++; 279 value = *p++;
274 len--; 280 len--;
275 } else if (inform == MBSTRING_BMP) { 281 break;
282 case MBSTRING_BMP:
276 value = *p++ << 8; 283 value = *p++ << 8;
277 value |= *p++; 284 value |= *p++;
278 /* BMP is explictly defined to not support surrogates */ 285 /* BMP is explictly defined to not support surrogates */
279 if (UNICODE_IS_SURROGATE(value)) 286 if (UNICODE_IS_SURROGATE(value))
280 return -1; 287 return -1;
281 len -= 2; 288 len -= 2;
282 } else if (inform == MBSTRING_UNIV) { 289 break;
283 value = ((unsigned long)*p++) << 24; 290 case MBSTRING_UNIV:
284 value |= ((unsigned long)*p++) << 16; 291 value = *p++ << 24;
292 value |= *p++ << 16;
285 value |= *p++ << 8; 293 value |= *p++ << 8;
286 value |= *p++; 294 value |= *p++;
287 if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value)) 295 if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value))
288 return -1; 296 return -1;
289 len -= 4; 297 len -= 4;
290 } else { 298 break;
299 default:
291 ret = UTF8_getc(p, len, &value); 300 ret = UTF8_getc(p, len, &value);
292 if (ret < 0) 301 if (ret < 0)
293 return -1; 302 return -1;
294 len -= ret; 303 len -= ret;
295 p += ret; 304 p += ret;
305 break;
296 } 306 }
297 if (rfunc) { 307 if (rfunc) {
298 ret = rfunc(value, arg); 308 ret = rfunc(value, arg);
@@ -366,7 +376,7 @@ cpy_asc(unsigned long value, void *arg)
366 376
367 p = arg; 377 p = arg;
368 q = *p; 378 q = *p;
369 *q = (unsigned char) value; 379 *q = value;
370 (*p)++; 380 (*p)++;
371 return 1; 381 return 1;
372} 382}
@@ -380,8 +390,8 @@ cpy_bmp(unsigned long value, void *arg)
380 390
381 p = arg; 391 p = arg;
382 q = *p; 392 q = *p;
383 *q++ = (unsigned char) ((value >> 8) & 0xff); 393 *q++ = (value >> 8) & 0xff;
384 *q = (unsigned char) (value & 0xff); 394 *q = value & 0xff;
385 *p += 2; 395 *p += 2;
386 return 1; 396 return 1;
387} 397}
@@ -395,10 +405,10 @@ cpy_univ(unsigned long value, void *arg)
395 405
396 p = arg; 406 p = arg;
397 q = *p; 407 q = *p;
398 *q++ = (unsigned char) ((value >> 24) & 0xff); 408 *q++ = (value >> 24) & 0xff;
399 *q++ = (unsigned char) ((value >> 16) & 0xff); 409 *q++ = (value >> 16) & 0xff;
400 *q++ = (unsigned char) ((value >> 8) & 0xff); 410 *q++ = (value >> 8) & 0xff;
401 *q = (unsigned char) (value & 0xff); 411 *q = value & 0xff;
402 *p += 4; 412 *p += 4;
403 return 1; 413 return 1;
404} 414}
diff --git a/src/lib/libssl/src/crypto/asn1/a_mbstr.c b/src/lib/libssl/src/crypto/asn1/a_mbstr.c
index 3bad3b2ec2..985d29824d 100644
--- a/src/lib/libssl/src/crypto/asn1/a_mbstr.c
+++ b/src/lib/libssl/src/crypto/asn1/a_mbstr.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: a_mbstr.c,v 1.19 2014/07/11 08:44:47 jsing Exp $ */ 1/* $OpenBSD: a_mbstr.c,v 1.20 2014/09/21 12:14:34 miod Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 1999. 3 * project 1999.
4 */ 4 */
@@ -212,7 +212,7 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
212 if (!ASN1_STRING_set(dest, in, len)) { 212 if (!ASN1_STRING_set(dest, in, len)) {
213 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 213 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
214 ERR_R_MALLOC_FAILURE); 214 ERR_R_MALLOC_FAILURE);
215 return -1; 215 goto err;
216 } 216 }
217 return str_type; 217 return str_type;
218 } 218 }
@@ -239,22 +239,27 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
239 if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) { 239 if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) {
240 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 240 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
241 ASN1_R_ILLEGAL_CHARACTERS); 241 ASN1_R_ILLEGAL_CHARACTERS);
242 return -1; 242 goto err;
243 } 243 }
244 cpyfunc = cpy_utf8; 244 cpyfunc = cpy_utf8;
245 break; 245 break;
246 } 246 }
247 if (!(p = malloc(outlen + 1))) { 247 if (!(p = malloc(outlen + 1))) {
248 if (free_out)
249 ASN1_STRING_free(dest);
250 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); 248 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
251 return -1; 249 goto err;
252 } 250 }
253 dest->length = outlen; 251 dest->length = outlen;
254 dest->data = p; 252 dest->data = p;
255 p[outlen] = 0; 253 p[outlen] = 0;
256 traverse_string(in, len, inform, cpyfunc, &p); 254 traverse_string(in, len, inform, cpyfunc, &p);
257 return str_type; 255 return str_type;
256
257err:
258 if (free_out) {
259 ASN1_STRING_free(dest);
260 *out = NULL;
261 }
262 return -1;
258} 263}
259 264
260/* This function traverses a string and passes the value of each character 265/* This function traverses a string and passes the value of each character
@@ -269,30 +274,35 @@ traverse_string(const unsigned char *p, int len, int inform,
269 int ret; 274 int ret;
270 275
271 while (len) { 276 while (len) {
272 if (inform == MBSTRING_ASC) { 277 switch (inform) {
278 case MBSTRING_ASC:
273 value = *p++; 279 value = *p++;
274 len--; 280 len--;
275 } else if (inform == MBSTRING_BMP) { 281 break;
282 case MBSTRING_BMP:
276 value = *p++ << 8; 283 value = *p++ << 8;
277 value |= *p++; 284 value |= *p++;
278 /* BMP is explictly defined to not support surrogates */ 285 /* BMP is explictly defined to not support surrogates */
279 if (UNICODE_IS_SURROGATE(value)) 286 if (UNICODE_IS_SURROGATE(value))
280 return -1; 287 return -1;
281 len -= 2; 288 len -= 2;
282 } else if (inform == MBSTRING_UNIV) { 289 break;
283 value = ((unsigned long)*p++) << 24; 290 case MBSTRING_UNIV:
284 value |= ((unsigned long)*p++) << 16; 291 value = *p++ << 24;
292 value |= *p++ << 16;
285 value |= *p++ << 8; 293 value |= *p++ << 8;
286 value |= *p++; 294 value |= *p++;
287 if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value)) 295 if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value))
288 return -1; 296 return -1;
289 len -= 4; 297 len -= 4;
290 } else { 298 break;
299 default:
291 ret = UTF8_getc(p, len, &value); 300 ret = UTF8_getc(p, len, &value);
292 if (ret < 0) 301 if (ret < 0)
293 return -1; 302 return -1;
294 len -= ret; 303 len -= ret;
295 p += ret; 304 p += ret;
305 break;
296 } 306 }
297 if (rfunc) { 307 if (rfunc) {
298 ret = rfunc(value, arg); 308 ret = rfunc(value, arg);
@@ -366,7 +376,7 @@ cpy_asc(unsigned long value, void *arg)
366 376
367 p = arg; 377 p = arg;
368 q = *p; 378 q = *p;
369 *q = (unsigned char) value; 379 *q = value;
370 (*p)++; 380 (*p)++;
371 return 1; 381 return 1;
372} 382}
@@ -380,8 +390,8 @@ cpy_bmp(unsigned long value, void *arg)
380 390
381 p = arg; 391 p = arg;
382 q = *p; 392 q = *p;
383 *q++ = (unsigned char) ((value >> 8) & 0xff); 393 *q++ = (value >> 8) & 0xff;
384 *q = (unsigned char) (value & 0xff); 394 *q = value & 0xff;
385 *p += 2; 395 *p += 2;
386 return 1; 396 return 1;
387} 397}
@@ -395,10 +405,10 @@ cpy_univ(unsigned long value, void *arg)
395 405
396 p = arg; 406 p = arg;
397 q = *p; 407 q = *p;
398 *q++ = (unsigned char) ((value >> 24) & 0xff); 408 *q++ = (value >> 24) & 0xff;
399 *q++ = (unsigned char) ((value >> 16) & 0xff); 409 *q++ = (value >> 16) & 0xff;
400 *q++ = (unsigned char) ((value >> 8) & 0xff); 410 *q++ = (value >> 8) & 0xff;
401 *q = (unsigned char) (value & 0xff); 411 *q = value & 0xff;
402 *p += 4; 412 *p += 4;
403 return 1; 413 return 1;
404} 414}