diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/a_object.c')
-rw-r--r-- | src/lib/libcrypto/asn1/a_object.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/lib/libcrypto/asn1/a_object.c b/src/lib/libcrypto/asn1/a_object.c index dc980421d0..e5fbe7cbb1 100644 --- a/src/lib/libcrypto/asn1/a_object.c +++ b/src/lib/libcrypto/asn1/a_object.c | |||
@@ -281,8 +281,6 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, | |||
281 | return ret; | 281 | return ret; |
282 | err: | 282 | err: |
283 | ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); | 283 | ASN1err(ASN1_F_D2I_ASN1_OBJECT,i); |
284 | if ((ret != NULL) && ((a == NULL) || (*a != ret))) | ||
285 | ASN1_OBJECT_free(ret); | ||
286 | return(NULL); | 284 | return(NULL); |
287 | } | 285 | } |
288 | ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, | 286 | ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, |
@@ -290,7 +288,19 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, | |||
290 | { | 288 | { |
291 | ASN1_OBJECT *ret=NULL; | 289 | ASN1_OBJECT *ret=NULL; |
292 | const unsigned char *p; | 290 | const unsigned char *p; |
291 | unsigned char *data; | ||
293 | int i; | 292 | int i; |
293 | /* Sanity check OID encoding: can't have leading 0x80 in | ||
294 | * subidentifiers, see: X.690 8.19.2 | ||
295 | */ | ||
296 | for (i = 0, p = *pp + 1; i < len - 1; i++, p++) | ||
297 | { | ||
298 | if (*p == 0x80 && (!i || !(p[-1] & 0x80))) | ||
299 | { | ||
300 | ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING); | ||
301 | return NULL; | ||
302 | } | ||
303 | } | ||
294 | 304 | ||
295 | /* only the ASN1_OBJECTs from the 'table' will have values | 305 | /* only the ASN1_OBJECTs from the 'table' will have values |
296 | * for ->sn or ->ln */ | 306 | * for ->sn or ->ln */ |
@@ -302,15 +312,22 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, | |||
302 | else ret=(*a); | 312 | else ret=(*a); |
303 | 313 | ||
304 | p= *pp; | 314 | p= *pp; |
305 | if ((ret->data == NULL) || (ret->length < len)) | 315 | /* detach data from object */ |
316 | data = (unsigned char *)ret->data; | ||
317 | ret->data = NULL; | ||
318 | /* once detached we can change it */ | ||
319 | if ((data == NULL) || (ret->length < len)) | ||
306 | { | 320 | { |
307 | if (ret->data != NULL) OPENSSL_free(ret->data); | 321 | ret->length=0; |
308 | ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); | 322 | if (data != NULL) OPENSSL_free(data); |
309 | ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; | 323 | data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1); |
310 | if (ret->data == NULL) | 324 | if (data == NULL) |
311 | { i=ERR_R_MALLOC_FAILURE; goto err; } | 325 | { i=ERR_R_MALLOC_FAILURE; goto err; } |
326 | ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA; | ||
312 | } | 327 | } |
313 | memcpy(ret->data,p,(int)len); | 328 | memcpy(data,p,(int)len); |
329 | /* reattach data to object, after which it remains const */ | ||
330 | ret->data =data; | ||
314 | ret->length=(int)len; | 331 | ret->length=(int)len; |
315 | ret->sn=NULL; | 332 | ret->sn=NULL; |
316 | ret->ln=NULL; | 333 | ret->ln=NULL; |
@@ -359,7 +376,7 @@ void ASN1_OBJECT_free(ASN1_OBJECT *a) | |||
359 | } | 376 | } |
360 | if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) | 377 | if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) |
361 | { | 378 | { |
362 | if (a->data != NULL) OPENSSL_free(a->data); | 379 | if (a->data != NULL) OPENSSL_free((void *)a->data); |
363 | a->data=NULL; | 380 | a->data=NULL; |
364 | a->length=0; | 381 | a->length=0; |
365 | } | 382 | } |