From 72486333c30df3e64540eec58d0f615940ae1008 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 9 Sep 2021 12:19:50 +1000 Subject: [PATCH] Get host name: add code to use popen and the command 'host' When compiling for QEMU, the gethostbyname call doesn't have access to the OS DNS. Implemented a lookup of hostname that uses the system command host. Fix for QEMU Aarch64 where 'char' is unsigned and the -1 return is being converted to 255 in wolfSSL_OPENSSL_hexchar2int(). Test TLSv1.3 with www.google.com if wolfSSL supports it. CMAC: cannot cast size_t* to word32* when big-endian. SP math all: Random prime - munge bits before moving them around for big-endian. BIO, no filesystem: Allow BIO_prinf to be used with mem BIO. --- scripts/google.test | 9 +++++- src/ssl.c | 25 +++++++++------ src/wolfio.c | 64 +++++++++++++++++++++++++++++++++++++ wolfcrypt/src/sp_int.c | 17 +++++----- wolfssl/ssl.h | 2 -- wolfssl/test.h | 55 ++++++++++++++++++++++++++++++- wolfssl/wolfcrypt/wc_port.h | 32 +++++++++---------- 7 files changed, 167 insertions(+), 37 deletions(-) diff --git a/scripts/google.test b/scripts/google.test index 7b58a8a29..b55026a94 100755 --- a/scripts/google.test +++ b/scripts/google.test @@ -6,7 +6,6 @@ server=www.google.com [ ! -x ./examples/client/client ] && echo -e "\n\nClient doesn't exist" && exit 1 -# TODO: [TLS13] Remove this when google supports final version of TLS 1.3 ./examples/client/client -v 3 2>&1 | grep -- 'Bad SSL version' if [ $? -eq 0 ]; then echo -e "\n\nClient doesn't support TLS v1.2" @@ -23,4 +22,12 @@ RESULT=$? RESULT=$? [ $RESULT -ne 0 ] && echo -e "\n\nClient connection failed" && exit 1 +./examples/client/client -v 4 2>&1 | grep -- 'Bad SSL version' +if [ $? -ne 0 ]; then + # client test against the server using TLS v1.3 + ./examples/client/client -v 4 -X -C -h $server -p 443 -g -d + RESULT=$? + [ $RESULT -ne 0 ] && echo -e "\n\nTLSv1.3 Client connection failed" && exit 1 +fi + exit 0 diff --git a/src/ssl.c b/src/ssl.c index cc89e119b..82bb5710f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -34382,8 +34382,8 @@ int wolfSSL_CMAC_Init(WOLFSSL_CMAC_CTX* ctx, const void *key, size_t keyLen, } if (ret == WOLFSSL_SUCCESS) { - ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key, (word32)keyLen, - WC_CMAC_AES, NULL); + ret = wc_InitCmac((Cmac*)ctx->internal, (const byte*)key, + (word32)keyLen, WC_CMAC_AES, NULL); if (ret != 0) { ret = WOLFSSL_FAILURE; } @@ -34413,7 +34413,8 @@ int wolfSSL_CMAC_Update(WOLFSSL_CMAC_CTX* ctx, const void* data, size_t len) if (ret == WOLFSSL_SUCCESS) { if (data) { - ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data, (word32)len); + ret = wc_CmacUpdate((Cmac*)ctx->internal, (const byte*)data, + (word32)len); if (ret != 0){ ret = WOLFSSL_FAILURE; } @@ -34436,7 +34437,8 @@ int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, WOLFSSL_ENTER("wolfSSL_CMAC_Final"); - if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL || len == NULL) { + if (ctx == NULL || ctx->cctx == NULL || ctx->internal == NULL || + len == NULL) { ret = WOLFSSL_FAILURE; } @@ -34450,7 +34452,10 @@ int wolfSSL_CMAC_Final(WOLFSSL_CMAC_CTX* ctx, unsigned char* out, } } if (ret == WOLFSSL_SUCCESS) { - ret = wc_CmacFinal((Cmac*)ctx->internal, out, (word32*)len); + word32 len32 = (word32)*len; + + ret = wc_CmacFinal((Cmac*)ctx->internal, out, &len32); + *len = (size_t)len32; if (ret != 0) { ret = WOLFSSL_FAILURE; } @@ -34483,7 +34488,8 @@ void *wolfSSL_OPENSSL_malloc(size_t a) int wolfSSL_OPENSSL_hexchar2int(unsigned char c) { - return (int)HexCharToByte((char)c); + /* 'char' is unsigned on some platforms. */ + return (int)(signed char)HexCharToByte((char)c); } unsigned char *wolfSSL_OPENSSL_hexstr2buf(const char *str, long *len) @@ -57070,7 +57076,7 @@ void *wolfSSL_BIO_get_ex_data(WOLFSSL_BIO *bio, int idx) #endif #endif -#if !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA) +#ifdef OPENSSL_EXTRA /* returns amount printed on success, negative in fail case */ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) { @@ -57080,6 +57086,7 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) return WOLFSSL_FATAL_ERROR; switch (bio->type) { +#if !defined(NO_FILESYSTEM) case WOLFSSL_BIO_FILE: if (bio->ptr == NULL) { va_end(args); @@ -57087,6 +57094,7 @@ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) } ret = XVFPRINTF((XFILE)bio->ptr, format, args); break; +#endif case WOLFSSL_BIO_MEMORY: /* In Visual Studio versions prior to Visual Studio 2013, the va_* symbols @@ -57146,8 +57154,7 @@ int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) return ret; } - -#endif /* !NO_FILESYSTEM && OPENSSL_EXTRA */ +#endif /* OPENSSL_EXTRA */ #if !defined(NO_FILESYSTEM) && defined(__clang__) #pragma clang diagnostic pop diff --git a/src/wolfio.c b/src/wolfio.c index e7234075e..23afcb812 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -765,7 +765,9 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) ADDRINFO* answer = NULL; char strPort[6]; #else +#if !defined(WOLFSSL_USE_POPEN_HOST) HOSTENT* entry; +#endif SOCKADDR_IN *sin; #endif @@ -799,6 +801,68 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) sockaddr_len = answer->ai_addrlen; XMEMCPY(&addr, answer->ai_addr, sockaddr_len); freeaddrinfo(answer); +#elif defined(WOLFSSL_USE_POPEN_HOST) + { + char host_ipaddr[4] = { 127, 0, 0, 1 }; + int found = 1; + + if ((XSTRNCMP(ip, "localhost", 10) != 0) && + (XSTRNCMP(ip, "127.0.0.1", 10) != 0)) { + FILE* fp; + char host_out[100]; + char cmd[100]; + + XSTRNCPY(cmd, "host ", 6); + XSTRNCAT(cmd, ip, 99 - XSTRLEN(cmd)); + found = 0; + fp = popen(cmd, "r"); + if (fp != NULL) { + while (fgets(host_out, sizeof(host_out), fp) != NULL) { + int i; + int j = 0; + for (j = 0; host_out[j] != '\0'; j++) { + if ((host_out[j] >= '0') && (host_out[j] <= '9')) { + break; + } + } + found = (host_out[j] >= '0') && (host_out[j] <= '9'); + if (!found) { + continue; + } + + for (i = 0; i < 4; i++) { + host_ipaddr[i] = atoi(host_out + j); + while ((host_out[j] >= '0') && (host_out[j] <= '9')) { + j++; + } + if (host_out[j] == '.') { + j++; + found &= (i != 3); + } + else { + found &= (i == 3); + break; + } + } + if (found) { + break; + } + } + pclose(fp); + } + } + if (found) { + sin = (SOCKADDR_IN *)&addr; + + sin->sin_family = AF_INET; + sin->sin_port = XHTONS(port); + XMEMCPY(&sin->sin_addr.s_addr, host_ipaddr, sizeof(host_ipaddr)); + } + else { + WOLFSSL_MSG("no addr info for responder"); + return -1; + } + } #else entry = gethostbyname(ip); sin = (SOCKADDR_IN *)&addr; diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 73b12db63..471c3a03c 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -12952,6 +12952,15 @@ int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap) err = MP_VAL; break; } + + /* munge bits */ +#ifndef LITTLE_ENDIAN_ORDER + ((byte*)(r->dp + r->used - 1))[0] |= 0x80 | 0x40; +#else + ((byte*)r->dp)[len-1] |= 0x80 | 0x40; +#endif /* LITTLE_ENDIAN_ORDER */ + r->dp[0] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); + #ifndef LITTLE_ENDIAN_ORDER if (((len * 8) & SP_WORD_MASK) != 0) { r->dp[r->used-1] >>= SP_WORD_SIZE - ((len * 8) & SP_WORD_MASK); @@ -12963,14 +12972,6 @@ int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap) } #endif /* WOLFSSL_SP_MATH_ALL */ - /* munge bits */ -#ifndef LITTLE_ENDIAN_ORDER - ((byte*)(r->dp + r->used - 1))[0] |= 0x80 | 0x40; -#else - ((byte*)r->dp)[len-1] |= 0x80 | 0x40; -#endif /* LITTLE_ENDIAN_ORDER */ - r->dp[0] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); - /* test */ /* Running Miller-Rabin up to 3 times gives us a 2^{-80} chance * of a 1024-bit candidate being a false positive, when it is our diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index ce6ce7f23..023351f47 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2437,11 +2437,9 @@ WOLFSSL_API int wolfSSL_want(WOLFSSL*); WOLFSSL_API int wolfSSL_want_read(WOLFSSL*); WOLFSSL_API int wolfSSL_want_write(WOLFSSL*); -#if !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA) #include /* var_arg */ WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args); -#endif WOLFSSL_API int wolfSSL_BIO_printf(WOLFSSL_BIO*, const char*, ...); WOLFSSL_API int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char*, int); WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*, diff --git a/wolfssl/test.h b/wolfssl/test.h index 32641f428..49a8bfdd7 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1042,7 +1042,60 @@ static WC_INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, #ifndef TEST_IPV6 /* peer could be in human readable form */ if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) { - #ifndef WOLFSSL_USE_GETADDRINFO + #ifdef WOLFSSL_USE_POPEN_HOST + char host_ipaddr[4] = { 127, 0, 0, 1 }; + int found = 1; + + if ((XSTRNCMP(peer, "localhost", 10) != 0) && + (XSTRNCMP(peer, "127.0.0.1", 10) != 0)) { + FILE* fp; + char host_out[100]; + char cmd[100]; + + XSTRNCPY(cmd, "host ", 6); + XSTRNCAT(cmd, peer, 99 - XSTRLEN(cmd)); + found = 0; + fp = popen(cmd, "r"); + if (fp != NULL) { + while (fgets(host_out, sizeof(host_out), fp) != NULL) { + int i; + int j = 0; + for (j = 0; host_out[j] != '\0'; j++) { + if ((host_out[j] >= '0') && (host_out[j] <= '9')) { + break; + } + } + found = (host_out[j] >= '0') && (host_out[j] <= '9'); + if (!found) { + continue; + } + + for (i = 0; i < 4; i++) { + host_ipaddr[i] = atoi(host_out + j); + while ((host_out[j] >= '0') && (host_out[j] <= '9')) { + j++; + } + if (host_out[j] == '.') { + j++; + found &= (i != 3); + } + else { + found &= (i == 3); + break; + } + } + if (found) { + break; + } + } + pclose(fp); + } + } + if (found) { + XMEMCPY(&addr->sin_addr.s_addr, host_ipaddr, sizeof(host_ipaddr)); + useLookup = 1; + } + #elif !defined(WOLFSSL_USE_GETADDRINFO) #if defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) int err; struct hostent* entry = gethostbyname(peer, &err); diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 35a07bee9..d579679bf 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -1012,22 +1012,6 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #endif #endif -/* Defaults, user may over-ride with user_settings.h or in a porting section - * above - */ -#ifndef XVFPRINTF - #define XVFPRINTF vfprintf -#endif -#ifndef XVSNPRINTF - #define XVSNPRINTF vsnprintf -#endif -#ifndef XFPUTS - #define XFPUTS fputs -#endif -#ifndef XSPRINTF - #define XSPRINTF sprintf -#endif - #ifndef MAX_FILENAME_SZ #define MAX_FILENAME_SZ 256 /* max file name length */ #endif @@ -1082,6 +1066,22 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); #endif /* !NO_FILESYSTEM */ +/* Defaults, user may over-ride with user_settings.h or in a porting section + * above + */ +#ifndef XVFPRINTF + #define XVFPRINTF vfprintf +#endif +#ifndef XVSNPRINTF + #define XVSNPRINTF vsnprintf +#endif +#ifndef XFPUTS + #define XFPUTS fputs +#endif +#ifndef XSPRINTF + #define XSPRINTF sprintf +#endif + /* MIN/MAX MACRO SECTION */ /* Windows API defines its own min() macro. */