diff options
author | miod <> | 2014-09-21 12:14:34 +0000 |
---|---|---|
committer | miod <> | 2014-09-21 12:14:34 +0000 |
commit | 80b8016d7545ad41a60ce062e675d55c19b94636 (patch) | |
tree | 77b01cab9a1322522996df4c81401ee0a96143e0 /src | |
parent | a53ab35a157425f24f2ecc1c879119d6ab466343 (diff) | |
download | openbsd-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.c | 48 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_mbstr.c | 48 |
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 | |||
257 | err: | ||
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 | |||
257 | err: | ||
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 | } |