diff --git a/src/ssl_asn1.c b/src/ssl_asn1.c index 4f9d12647f..6a46c25d53 100644 --- a/src/ssl_asn1.c +++ b/src/ssl_asn1.c @@ -1016,11 +1016,14 @@ int wolfSSL_ASN1_INTEGER_get_length(const WOLFSSL_ASN1_INTEGER* ai) if (ai->data[0] == ASN_INTEGER) { word32 idx = 1; int len = 0; - if (GetLength(ai->data, &idx, &len, (word32)ai->length) > 0) { + if (GetLength(ai->data, &idx, &len, (word32)ai->length) > 0 && + idx + (word32)len == (word32)ai->length) { return len; } } - /* WOLFSSL_QT / WOLFSSL_HAPROXY format: raw bytes without DER header */ + /* WOLFSSL_QT / WOLFSSL_HAPROXY format: raw bytes without DER header, + * or data that coincidentally starts with 0x02 but whose header+value + * boundaries do not span exactly ai->length. */ return ai->length; } @@ -1040,11 +1043,14 @@ const unsigned char* wolfSSL_ASN1_INTEGER_get0_data(const WOLFSSL_ASN1_INTEGER* if (ai->data[0] == ASN_INTEGER) { word32 idx = 1; int len = 0; - if (GetLength(ai->data, &idx, &len, (word32)ai->length) > 0) { + if (GetLength(ai->data, &idx, &len, (word32)ai->length) > 0 && + idx + (word32)len == (word32)ai->length) { return ai->data + idx; } } - /* WOLFSSL_QT / WOLFSSL_HAPROXY format: raw bytes without DER header */ + /* WOLFSSL_QT / WOLFSSL_HAPROXY format: raw bytes without DER header, + * or data that coincidentally starts with 0x02 but whose header+value + * boundaries do not span exactly ai->length. */ return ai->data; } diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index e1304aa27b..063500675e 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1022,25 +1022,23 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ASN1_STRING_cmp wolfSSL_ASN1_STRING_cmp #define ASN1_OCTET_STRING_cmp wolfSSL_ASN1_STRING_cmp #define ASN1_STRING_data wolfSSL_ASN1_STRING_data -/* In OpenSSL, ASN1_INTEGER and ASN1_BIT_STRING are typedef aliases of - * ASN1_STRING (same struct), so ASN1_STRING_length/get0_data work on all. +/* In OpenSSL, ASN1_INTEGER is a typedef alias of ASN1_STRING (same struct), + * so ASN1_STRING_length/get0_data work on ASN1_INTEGER* as well. * In wolfSSL they are distinct structs, so dispatch by type using _Generic. */ #if !defined(__cplusplus) && defined(__STDC_VERSION__) && \ __STDC_VERSION__ >= 201112L -#define ASN1_STRING_length(x) _Generic((x), \ - WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get_length( \ - (const WOLFSSL_ASN1_INTEGER*)(x)), \ - const WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get_length( \ - (const WOLFSSL_ASN1_INTEGER*)(x)), \ - default: wolfSSL_ASN1_STRING_length( \ - (const WOLFSSL_ASN1_STRING*)(x))) -#define ASN1_STRING_get0_data(x) _Generic((x), \ - WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get0_data( \ - (const WOLFSSL_ASN1_INTEGER*)(x)), \ - const WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get0_data( \ - (const WOLFSSL_ASN1_INTEGER*)(x)), \ - default: wolfSSL_ASN1_STRING_get0_data( \ - (const WOLFSSL_ASN1_STRING*)(x))) +#define ASN1_STRING_length(x) \ + _Generic((x), \ + WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get_length, \ + const WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get_length, \ + default: wolfSSL_ASN1_STRING_length \ + )(x) +#define ASN1_STRING_get0_data(x) \ + _Generic((x), \ + WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get0_data, \ + const WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get0_data, \ + default: wolfSSL_ASN1_STRING_get0_data \ + )(x) #else #define ASN1_STRING_get0_data wolfSSL_ASN1_STRING_get0_data #define ASN1_STRING_length wolfSSL_ASN1_STRING_length