diff --git a/src/ssl.c b/src/ssl.c index ac775c14e..88278cee6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -46467,6 +46467,42 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line, #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) +/* converts an IPv6 or IPv4 address into an octet string for use with rfc3280 + * example input would be "127.0.0.1" and the returned value would be 7F000001 + */ +WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa) +{ + int ipaSz = WOLFSSL_IP4_ADDR_LEN; + char buf[WOLFSSL_IP6_ADDR_LEN + 1]; /* plus 1 for terminator */ + int af = WOLFSSL_IP4; + WOLFSSL_ASN1_STRING *ret = NULL; + + if (ipa == NULL) + return NULL; + + if (XSTRSTR(ipa, ":") != NULL) { + af = WOLFSSL_IP6; + ipaSz = WOLFSSL_IP6_ADDR_LEN; + } + + buf[WOLFSSL_IP6_ADDR_LEN] = '\0'; + if (XINET_PTON(af, ipa, (void*)buf) != 1) { + WOLFSSL_MSG("Error parsing IP address"); + return NULL; + } + + ret = wolfSSL_ASN1_STRING_new(); + if (ret != NULL) { + if (wolfSSL_ASN1_STRING_set(ret, buf, ipaSz) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Error setting the string"); + wolfSSL_ASN1_STRING_free(ret); + ret = NULL; + } + } + + return ret; +} + /* Is the specified cipher suite a fake one used an an extension proxy? */ static WC_INLINE int SCSV_Check(byte suite0, byte suite) diff --git a/tests/api.c b/tests/api.c index aaf8f848c..9aa4156da 100644 --- a/tests/api.c +++ b/tests/api.c @@ -32554,6 +32554,51 @@ static void test_wolfSSL_a2i_ASN1_INTEGER(void) #endif } +static void test_wolfSSL_a2i_IPADDRESS(void) +{ +#ifdef OPENSSL_ALL + const unsigned char* data; + int dataSz = 0; + ASN1_OCTET_STRING *st; + + unsigned char ipv4_exp[] = {0x7F, 0, 0, 1}; + unsigned char ipv6_exp[] = { + 0x20, 0x21, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x42, 0x77, 0x77 + }; + unsigned char ipv6_home[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + printf(testingFmt, "test_wolfSSL_a2i_IPADDRESS()"); + + AssertNull(st = a2i_IPADDRESS("127.0.0.1bad")); + AssertNotNull(st = a2i_IPADDRESS("127.0.0.1")); + data = ASN1_STRING_get0_data(st); + dataSz = ASN1_STRING_length(st); + AssertIntEQ(dataSz, WOLFSSL_IP4_ADDR_LEN); + AssertIntEQ(XMEMCMP(data, ipv4_exp, dataSz), 0); + ASN1_STRING_free(st); + + AssertNotNull(st = a2i_IPADDRESS("::1")); + data = ASN1_STRING_get0_data(st); + dataSz = ASN1_STRING_length(st); + AssertIntEQ(dataSz, WOLFSSL_IP6_ADDR_LEN); + AssertIntEQ(XMEMCMP(data, ipv6_home, dataSz), 0); + ASN1_STRING_free(st); + + AssertNotNull(st = a2i_IPADDRESS("2021:db8::ff00:42:7777")); + data = ASN1_STRING_get0_data(st); + dataSz = ASN1_STRING_length(st); + AssertIntEQ(dataSz, WOLFSSL_IP6_ADDR_LEN); + AssertIntEQ(XMEMCMP(data, ipv6_exp, dataSz), 0); + ASN1_STRING_free(st); + + printf(resultFmt, passed); + +#endif +} + static void test_wolfSSL_DES_ecb_encrypt(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_DES3) && defined(WOLFSSL_DES_ECB) @@ -46804,6 +46849,7 @@ void ApiTest(void) test_wolfSSL_ASN1_STRING(); test_wolfSSL_ASN1_BIT_STRING(); test_wolfSSL_a2i_ASN1_INTEGER(); + test_wolfSSL_a2i_IPADDRESS(); test_wolfSSL_X509(); test_wolfSSL_X509_VERIFY_PARAM(); test_wolfSSL_X509_sign(); diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index db471dd8d..9ce13110b 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -103,6 +103,7 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_print(WOLFSSL_BIO *out, WOLFSSL_X509_EXTENSION *ext, unsigned long flag, int indent); WOLFSSL_API int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_CTX *ctx, const char *section, WOLFSSL_X509 *cert); +WOLFSSL_API WOLFSSL_ASN1_STRING* wolfSSL_a2i_IPADDRESS(const char* ipa); #define BASIC_CONSTRAINTS_free wolfSSL_BASIC_CONSTRAINTS_free #define AUTHORITY_KEYID_free wolfSSL_AUTHORITY_KEYID_free @@ -116,6 +117,7 @@ WOLFSSL_API int wolfSSL_X509V3_EXT_add_nconf(WOLFSSL_CONF *conf, WOLFSSL_X509V3_ #define X509V3_parse_list(...) NULL #endif #define i2s_ASN1_OCTET_STRING wolfSSL_i2s_ASN1_STRING +#define a2i_IPADDRESS wolfSSL_a2i_IPADDRESS #define X509V3_EXT_print wolfSSL_X509V3_EXT_print #define X509V3_EXT_conf_nid wolfSSL_X509V3_EXT_conf_nid #define X509V3_set_ctx wolfSSL_X509V3_set_ctx