diff --git a/include/mbedtls/asn1write.h b/include/mbedtls/asn1write.h index 4d2917ee9..73ff32b66 100644 --- a/include/mbedtls/asn1write.h +++ b/include/mbedtls/asn1write.h @@ -40,8 +40,6 @@ extern "C" { * \param start start of the buffer (for bounds-checking) * \param len the length to write * - * \note lengths over 65535 are not supported at the moment - * * \return the length written or a negative error code */ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ); diff --git a/library/asn1write.c b/library/asn1write.c index ef35ee438..69b61b205 100644 --- a/library/asn1write.c +++ b/library/asn1write.c @@ -41,11 +41,6 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) { - // We don't support lengths over 65535 for now - // - if( len > 0xFFFF ) - return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); - if( len < 0x80 ) { if( *p - start < 1 ) @@ -65,14 +60,43 @@ int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len return( 2 ); } - if( *p - start < 3 ) - return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + if( len <= 0xFFFF ) + { + if( *p - start < 3 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - *--(*p) = len % 256; - *--(*p) = ( len / 256 ) % 256; - *--(*p) = 0x82; + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = 0x82; + return( 3 ); + } - return( 3 ); + if( len <= 0xFFFFFF ) + { + if( *p - start < 4 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = 0x83; + return( 4 ); + } + + if( len <= 0xFFFFFFFF ) + { + if( *p - start < 5 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = ( len >> 24 ) & 0xFF; + *--(*p) = 0x84; + return( 5 ); + } + + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); } int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) diff --git a/tests/suites/test_suite_asn1write.data b/tests/suites/test_suite_asn1write.data index 3518ed945..c2a78b1af 100644 --- a/tests/suites/test_suite_asn1write.data +++ b/tests/suites/test_suite_asn1write.data @@ -67,14 +67,26 @@ mbedtls_asn1_write_len:255:"81FF":2:2 ASN.1 Write / Read Length #5 (Len = 255, buffer too small) mbedtls_asn1_write_len:255:"81FF":1:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -ASN.1 Write / Read Length #6 (Len = 256, long form) -mbedtls_asn1_write_len:256:"820100":3:3 +ASN.1 Write / Read Length #6 (Len = 258, byte order) +mbedtls_asn1_write_len:258:"820102":3:3 -ASN.1 Write / Read Length #7 (Len = 65535, max supported length) +ASN.1 Write / Read Length #7 (Len = 65535, long form) mbedtls_asn1_write_len:65535:"82FFFF":3:3 ASN.1 Write / Read Length #8 (Len = 65535, buffer too small) mbedtls_asn1_write_len:65535:"82FFFF":2:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL -ASN.1 Write / Read Length #9 (Len = 65536, not supported) -mbedtls_asn1_write_len:65536:"":0:MBEDTLS_ERR_ASN1_INVALID_LENGTH +ASN.1 Write / Read Length #9 (Len = 66051, byte order) +mbedtls_asn1_write_len:66051:"83010203":4:4 + +ASN.1 Write / Read Length #10 (Len = 16777215, long form) +mbedtls_asn1_write_len:16777215:"83FFFFFF":4:4 + +ASN.1 Write / Read Length #11 (Len = 16777215, buffer too small) +mbedtls_asn1_write_len:16777215:"83FFFFFF":3:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL + +ASN.1 Write / Read Length #12 (Len = 16909060, byte order) +mbedtls_asn1_write_len:16909060:"8401020304":5:5 + +ASN.1 Write / Read Length #12 (Len = 16909060, buffer too small) +mbedtls_asn1_write_len:16909060:"8401020304":4:MBEDTLS_ERR_ASN1_BUF_TOO_SMALL