From a851e13f1d332f8f68a65fa250686af50a22a838 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 6 Aug 2021 14:53:55 +0900 Subject: [PATCH] implemented X509_VERIFY_PARAM_set1_ip --- src/ssl.c | 127 ++++++++++++++++++++++++++++++++++++++++++ tests/api.c | 66 ++++++++++++++++++++++ wolfssl/openssl/ssl.h | 1 + wolfssl/ssl.h | 2 + 4 files changed, 196 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 5cb2ff162..b5eba9abb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25186,6 +25186,133 @@ int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param, return ret; } +/* Sets the expected IP address to ip(asc) + * by re-constructing IP address in ascii + * @param param is a pointer to the X509_VERIFY_PARAM structure + * @param ip in binary format of ip address + * @param iplen size of ip, 4 for ipv4, 16 for ipv6 + * @return 1 for success and 0 for failure + */ +int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param, + const unsigned char* ip, size_t iplen) +{ + int ret = WOLFSSL_FAILURE; + char* buf = NULL; + char* p = NULL; + word32 val = 0; + int i; + const int max_ipv6_len = 40; + byte write_zero = 0; + + /* sanity check */ + if (param == NULL || (iplen != 0 && iplen != 4 && iplen != 16)) { + WOLFSSL_MSG("bad function arg"); + return ret; + } +#ifndef NO_FILESYSTEM + if (iplen == 4) { + /* ipv4 www.xxx.yyy.zzz max 15 length + Null termination */ + buf = XMALLOC(16, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (!buf) { + WOLFSSL_MSG("failed malloc"); + return ret; + } + + XSPRINTF(buf, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + buf[15] = '\0'; + } + else if (iplen == 16) { + /* ipv6 normal address scheme + * y1:y2:y3:y4:y5:y6:y7:y8, len(yx):4, len(y1-y8):32. len(":"):7 + * Max len is 32 + 7 + 1(Termination) = 40 bytes + * + * ipv6 dual address + * Or y1:y2:y3:y4:y:y6:x.x.x.x yx is 4, y1-y6 is 24, ":" is 6 + * x.x.x.x is 15. + * Max len is 24 + 6 + 15 + 1(Termination) = 46 bytes + * + * Expect data in ip[16] + * e.g (aaaa):(bbbb):(cccc):....(hhhh) + * (aaaa) = (ip[0<<8)|ip[1] + * ...... + * (hhhh) = (ip[14]<<8)|(ip[15]) + * + * e.g ::(gggg):(hhhh) + * ip[0]-[11] = 0 + * (gggg) = (ip[12]<<8) |(ip[13]) + * (hhhh) = (ip[14]<<8) |(ip[15]) + * + * Because it is not able to know which ivp6 scheme uses from data to + * reconstruct IP address, this function assumes + * ivp6 normal address scheme, not dual adress scheme, + * to re-construct IP address in ascii. + */ + buf = XMALLOC(max_ipv6_len, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + if (!buf) { + WOLFSSL_MSG("failed malloc"); + return ret; + } + p = buf; + for (i = 0;i < 16;i += 2) { + val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF; + if (val == 0){ + if (!write_zero) { + *p = ':'; + } + p++; + *p = '\0'; + write_zero = 1; + } + else { + if (i != 0) + *p++ = ':'; + XSPRINTF(p, "%x", val); + } + /* sanity check */ + if (XSTRLEN(buf) > max_ipv6_len) { + printf("The target ip adress exceeds buffer length(40)\n"); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + buf = NULL; + break; + } + /* move the pointer to the last */ + /* XSTRLEN includes NULL because of XSPRINTF use */ + p = buf + (XSTRLEN(buf)); + } + /* termination */ + if(i == 16 && buf) { + p--; + if ((*p) == ':') { + /* when the last character is :, the followig segments are zero + * Therefore, adding : and null termination + */ + p++; + *p++ = ':'; + *p = '\0'; + } + } + } + else { + WOLFSSL_MSG("iplen is zero, do nothig"); + return WOLFSSL_SUCCESS; + } + + if (buf) { + /* set address to ip asc */ + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, buf); + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#else + (void)param; + (void)ip; + (void)iplen; + (void)buf; +#endif + + return ret; +} #ifndef NO_WOLFSSL_STUB void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj) diff --git a/tests/api.c b/tests/api.c index 43798fa50..0f0555649 100644 --- a/tests/api.c +++ b/tests/api.c @@ -30617,6 +30617,71 @@ static void test_wolfSSL_X509_VERIFY_PARAM_set1_host(void) #endif /* OPENSSL_EXTRA */ } +static void test_wolfSSL_X509_VERIFY_PARAM_set1_ip(void) +{ +#if defined(OPENSSL_EXTRA) + unsigned char buf[16] = {0}; + WOLFSSL_X509_VERIFY_PARAM* param; + + printf(testingFmt, "test_wolfSSL_X509_VERIFY_PARAM_set1_ip()"); + + AssertNotNull(param = X509_VERIFY_PARAM_new()); + + /* test 127.0.0.1 */ + buf[0] =0x7f; buf[1] = 0; buf[2] = 0; buf[3] = 1; + AssertIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 4), SSL_SUCCESS); + AssertIntEQ(XSTRNCMP(param->ipasc, "127.0.0.1", sizeof(param->ipasc)), 0); + + /* test 2001:db8:3333:4444:5555:6666:7777:8888 */ + buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184; + buf[4]=51;buf[5]=51;buf[6]=68;buf[7]=68; + buf[8]=85;buf[9]=85;buf[10]=102;buf[11]=102; + buf[12]=119;buf[13]=119;buf[14]=136;buf[15]=136; + AssertIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS); + AssertIntEQ(XSTRNCMP(param->ipasc, + "2001:db8:3333:4444:5555:6666:7777:8888", sizeof(param->ipasc)), 0); + + /* test 2001:db8:: */ + buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184; + buf[4]=0;buf[5]=0;buf[6]=0;buf[7]=0; + buf[8]=0;buf[9]=0;buf[10]=0;buf[11]=0; + buf[12]=0;buf[13]=0;buf[14]=0;buf[15]=0; + AssertIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS); + AssertIntEQ(XSTRNCMP(param->ipasc, "2001:db8::", sizeof(param->ipasc)), 0); + + /* test ::1234:5678 */ + buf[0]=0;buf[1]=0;buf[2]=0;buf[3]=0; + buf[4]=0;buf[5]=0;buf[6]=0;buf[7]=0; + buf[8]=0;buf[9]=0;buf[10]=0;buf[11]=0; + buf[12]=18;buf[13]=52;buf[14]=86;buf[15]=120; + AssertIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS); + AssertIntEQ(XSTRNCMP(param->ipasc, "::1234:5678", sizeof(param->ipasc)), 0); + + + /* test 2001:db8::1234:5678 */ + buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184; + buf[4]=0;buf[5]=0;buf[6]=0;buf[7]=0; + buf[8]=0;buf[9]=0;buf[10]=0;buf[11]=0; + buf[12]=18;buf[13]=52;buf[14]=86;buf[15]=120; + AssertIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS); + AssertIntEQ(XSTRNCMP(param->ipasc, "2001:db8::1234:5678", + sizeof(param->ipasc)), 0); + + /* test 2001:0db8:0001:0000:0000:0ab9:c0a8:0102*/ + /* 2001:db8:1::ab9:c0a8:102 */ + buf[0]=32;buf[1]=1;buf[2]=13;buf[3]=184; + buf[4]=0;buf[5]=1;buf[6]=0;buf[7]=0; + buf[8]=0;buf[9]=0;buf[10]=10;buf[11]=185; + buf[12]=192;buf[13]=168;buf[14]=1;buf[15]=2; + AssertIntEQ(X509_VERIFY_PARAM_set1_ip(param, &buf[0], 16), SSL_SUCCESS); + AssertIntEQ(XSTRNCMP(param->ipasc, "2001:db8:1::ab9:c0a8:102", + sizeof(param->ipasc)), 0); + + XFREE(param, HEAP_HINT, DYNAMIC_TYPE_OPENSSL); + printf(resultFmt, passed); +#endif /* OPENSSL_EXTRA */ +} + static void test_wolfSSL_X509_STORE_CTX_get0_store(void) { #if defined(OPENSSL_EXTRA) @@ -46899,6 +46964,7 @@ void ApiTest(void) test_wolfSSL_X509_STORE_CTX_set_time(); test_wolfSSL_get0_param(); test_wolfSSL_X509_VERIFY_PARAM_set1_host(); + test_wolfSSL_X509_VERIFY_PARAM_set1_ip(); test_wolfSSL_X509_STORE_CTX_get0_store(); test_wolfSSL_X509_STORE(); test_wolfSSL_X509_STORE_load_locations(); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 14843fd2b..0428f7851 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -643,6 +643,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define X509_VERIFY_PARAM_set_hostflags wolfSSL_X509_VERIFY_PARAM_set_hostflags #define X509_VERIFY_PARAM_set1_host wolfSSL_X509_VERIFY_PARAM_set1_host #define X509_VERIFY_PARAM_set1_ip_asc wolfSSL_X509_VERIFY_PARAM_set1_ip_asc +#define X509_VERIFY_PARAM_set1_ip wolfSSL_X509_VERIFY_PARAM_set1_ip #define X509_VERIFY_PARAM_set1 wolfSSL_X509_VERIFY_PARAM_set1 #define X509_STORE_load_locations wolfSSL_X509_STORE_load_locations diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 290737337..9e06c1972 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1744,6 +1744,8 @@ WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* p unsigned int nameSz); WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc( WOLFSSL_X509_VERIFY_PARAM *param, const char *ipasc); +WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_ip( + WOLFSSL_X509_VERIFY_PARAM* param, const unsigned char* ip, size_t iplen); WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1(WOLFSSL_X509_VERIFY_PARAM* to, const WOLFSSL_X509_VERIFY_PARAM* from); WOLFSSL_API int wolfSSL_X509_load_crl_file(WOLFSSL_X509_LOOKUP *ctx,