@@ -287,17 +287,29 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
287287 ASN1err (ASN1_F_D2I_ASN1_OBJECT ,i );
288288 return (NULL );
289289}
290+
290291ASN1_OBJECT * c2i_ASN1_OBJECT (ASN1_OBJECT * * a , const unsigned char * * pp ,
291292 long len )
292293 {
293294 ASN1_OBJECT * ret = NULL ;
294295 const unsigned char * p ;
295296 unsigned char * data ;
296- int i ;
297- /* Sanity check OID encoding: can't have leading 0x80 in
298- * subidentifiers, see: X.690 8.19.2
297+ int i , length ;
298+
299+ /* Sanity check OID encoding.
300+ * Need at least one content octet.
301+ * MSB must be clear in the last octet.
302+ * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
299303 */
300- for (i = 0 , p = * pp ; i < len ; i ++ , p ++ )
304+ if (len <= 0 || len > INT_MAX || pp == NULL || (p = * pp ) == NULL ||
305+ p [len - 1 ] & 0x80 )
306+ {
307+ ASN1err (ASN1_F_C2I_ASN1_OBJECT ,ASN1_R_INVALID_OBJECT_ENCODING );
308+ return NULL ;
309+ }
310+ /* Now 0 < len <= INT_MAX, so the cast is safe. */
311+ length = (int )len ;
312+ for (i = 0 ; i < length ; i ++ , p ++ )
301313 {
302314 if (* p == 0x80 && (!i || !(p [-1 ] & 0x80 )))
303315 {
@@ -320,23 +332,23 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
320332 data = (unsigned char * )ret -> data ;
321333 ret -> data = NULL ;
322334 /* once detached we can change it */
323- if ((data == NULL ) || (ret -> length < len ))
335+ if ((data == NULL ) || (ret -> length < length ))
324336 {
325337 ret -> length = 0 ;
326338 if (data != NULL ) OPENSSL_free (data );
327- data = (unsigned char * )OPENSSL_malloc (len ? ( int ) len : 1 );
339+ data = (unsigned char * )OPENSSL_malloc (length );
328340 if (data == NULL )
329341 { i = ERR_R_MALLOC_FAILURE ; goto err ; }
330342 ret -> flags |=ASN1_OBJECT_FLAG_DYNAMIC_DATA ;
331343 }
332- memcpy (data ,p ,( int ) len );
344+ memcpy (data ,p ,length );
333345 /* reattach data to object, after which it remains const */
334346 ret -> data = data ;
335- ret -> length = ( int ) len ;
347+ ret -> length = length ;
336348 ret -> sn = NULL ;
337349 ret -> ln = NULL ;
338350 /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
339- p += len ;
351+ p += length ;
340352
341353 if (a != NULL ) (* a )= ret ;
342354 * pp = p ;
0 commit comments