Skip to content

Commit 0f30790

Browse files
committed
openssl compat: fix ASN1_STRING_{length,get0_data} for ASN1_INTEGER
In OpenSSL, ASN1_INTEGER is typedef'd to ASN1_STRING (same struct), so calling ASN1_STRING_length() / ASN1_STRING_get0_data() on an ASN1_INTEGER* is valid and well-defined. wolfSSL has them as distinct, incompatible structs. This fixes the openvpn master failures introduced in OpenVPN/openvpn#1003
1 parent 7efc962 commit 0f30790

3 files changed

Lines changed: 72 additions & 0 deletions

File tree

src/ssl_asn1.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,6 +1000,54 @@ void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in)
10001000
XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL);
10011001
}
10021002

1003+
/* Get the length of the raw integer value bytes, stripping the DER tag/length
1004+
* header if present. Required for OpenSSL compatibility where ASN1_INTEGER is
1005+
* typedef'd to ASN1_STRING and callers use ASN1_STRING_length() on integers.
1006+
*
1007+
* @param [in] ai ASN.1 INTEGER object.
1008+
* @return Length of the raw integer value on success.
1009+
* @return 0 when ai is NULL or data is invalid.
1010+
*/
1011+
int wolfSSL_ASN1_INTEGER_get_length(const WOLFSSL_ASN1_INTEGER* ai)
1012+
{
1013+
if (ai == NULL || ai->data == NULL || ai->length <= 0) {
1014+
return 0;
1015+
}
1016+
if (ai->data[0] == ASN_INTEGER) {
1017+
word32 idx = 1;
1018+
int len = 0;
1019+
if (GetLength(ai->data, &idx, &len, (word32)ai->length) > 0) {
1020+
return len;
1021+
}
1022+
}
1023+
/* WOLFSSL_QT / WOLFSSL_HAPROXY format: raw bytes without DER header */
1024+
return ai->length;
1025+
}
1026+
1027+
/* Get a pointer to the raw integer value bytes, skipping the DER tag/length
1028+
* header if present. Required for OpenSSL compatibility where ASN1_INTEGER is
1029+
* typedef'd to ASN1_STRING and callers use ASN1_STRING_get0_data() on integers.
1030+
*
1031+
* @param [in] ai ASN.1 INTEGER object.
1032+
* @return Pointer to the raw integer value bytes on success.
1033+
* @return NULL when ai is NULL or data is invalid.
1034+
*/
1035+
const unsigned char* wolfSSL_ASN1_INTEGER_get0_data(const WOLFSSL_ASN1_INTEGER* ai)
1036+
{
1037+
if (ai == NULL || ai->data == NULL || ai->length <= 0) {
1038+
return NULL;
1039+
}
1040+
if (ai->data[0] == ASN_INTEGER) {
1041+
word32 idx = 1;
1042+
int len = 0;
1043+
if (GetLength(ai->data, &idx, &len, (word32)ai->length) > 0) {
1044+
return ai->data + idx;
1045+
}
1046+
}
1047+
/* WOLFSSL_QT / WOLFSSL_HAPROXY format: raw bytes without DER header */
1048+
return ai->data;
1049+
}
1050+
10031051
#if defined(OPENSSL_EXTRA)
10041052
/* Reset the data of ASN.1 INTEGER object back to empty fixed array.
10051053
*

wolfssl/openssl/ssl.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,8 +1022,29 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_
10221022
#define ASN1_STRING_cmp wolfSSL_ASN1_STRING_cmp
10231023
#define ASN1_OCTET_STRING_cmp wolfSSL_ASN1_STRING_cmp
10241024
#define ASN1_STRING_data wolfSSL_ASN1_STRING_data
1025+
/* In OpenSSL, ASN1_INTEGER and ASN1_BIT_STRING are typedef aliases of
1026+
* ASN1_STRING (same struct), so ASN1_STRING_length/get0_data work on all.
1027+
* In wolfSSL they are distinct structs, so dispatch by type using _Generic. */
1028+
#if !defined(__cplusplus) && defined(__STDC_VERSION__) && \
1029+
__STDC_VERSION__ >= 201112L
1030+
#define ASN1_STRING_length(x) _Generic((x), \
1031+
WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get_length( \
1032+
(const WOLFSSL_ASN1_INTEGER*)(x)), \
1033+
const WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get_length( \
1034+
(const WOLFSSL_ASN1_INTEGER*)(x)), \
1035+
default: wolfSSL_ASN1_STRING_length( \
1036+
(const WOLFSSL_ASN1_STRING*)(x)))
1037+
#define ASN1_STRING_get0_data(x) _Generic((x), \
1038+
WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get0_data( \
1039+
(const WOLFSSL_ASN1_INTEGER*)(x)), \
1040+
const WOLFSSL_ASN1_INTEGER*: wolfSSL_ASN1_INTEGER_get0_data( \
1041+
(const WOLFSSL_ASN1_INTEGER*)(x)), \
1042+
default: wolfSSL_ASN1_STRING_get0_data( \
1043+
(const WOLFSSL_ASN1_STRING*)(x)))
1044+
#else
10251045
#define ASN1_STRING_get0_data wolfSSL_ASN1_STRING_get0_data
10261046
#define ASN1_STRING_length wolfSSL_ASN1_STRING_length
1047+
#endif
10271048
#define ASN1_STRING_to_UTF8 wolfSSL_ASN1_STRING_to_UTF8
10281049
#define ASN1_UNIVERSALSTRING_to_string wolfSSL_ASN1_UNIVERSALSTRING_to_string
10291050
#define ASN1_STRING_print_ex wolfSSL_ASN1_STRING_print_ex

wolfssl/ssl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,6 +2356,9 @@ WOLFSSL_API unsigned char* wolfSSL_ASN1_STRING_data(WOLFSSL_ASN1_STRING* asn);
23562356
WOLFSSL_API const unsigned char* wolfSSL_ASN1_STRING_get0_data(
23572357
const WOLFSSL_ASN1_STRING* asn);
23582358
WOLFSSL_API int wolfSSL_ASN1_STRING_length(const WOLFSSL_ASN1_STRING* asn);
2359+
WOLFSSL_API int wolfSSL_ASN1_INTEGER_get_length(const WOLFSSL_ASN1_INTEGER* ai);
2360+
WOLFSSL_API const unsigned char* wolfSSL_ASN1_INTEGER_get0_data(
2361+
const WOLFSSL_ASN1_INTEGER* ai);
23592362
WOLFSSL_API int wolfSSL_ASN1_STRING_copy(WOLFSSL_ASN1_STRING* dst,
23602363
const WOLFSSL_ASN1_STRING* src);
23612364
WOLFSSL_API int wolfSSL_X509_verify_cert(WOLFSSL_X509_STORE_CTX* ctx);

0 commit comments

Comments
 (0)