From e162d0f889bb7cc1b9cdad00fbefec70cfc67ac5 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 6 Oct 2020 16:16:03 -0500 Subject: [PATCH 1/4] add wolfSSL_get_ocsp_producedDate(). --- examples/client/client.c | 10 ++++++++++ src/internal.c | 5 +++++ src/ssl.c | 18 ++++++++++++++++++ wolfssl/internal.h | 2 ++ wolfssl/ssl.h | 4 ++++ 5 files changed, 39 insertions(+) diff --git a/examples/client/client.c b/examples/client/client.c index cb79a84c8..362f4c8e5 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3007,6 +3007,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) showPeerEx(ssl, lng_index); +#ifdef HAVE_OCSP + { + struct tm tm; + char date[32]; + ret = wolfSSL_get_ocsp_producedDate(ssl, &tm); + if ((ret == 0) && (strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S %z",&tm) > 0)) + printf("OCSP response timestamp: %s\n",date); + } +#endif + #ifdef OPENSSL_EXTRA printf("Session timeout set to %ld seconds\n", wolfSSL_get_timeout(ssl)); { diff --git a/src/internal.c b/src/internal.c index 9122c43d2..526e94f37 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9857,6 +9857,11 @@ static int ProcessCSR(WOLFSSL* ssl, byte* input, word32* inOutIdx, else if (response->status->status != CERT_GOOD) ret = BAD_CERTIFICATE_STATUS_ERROR; + else { + XMEMCPY(ssl->ocspProducedDate, response->producedDate, sizeof ssl->ocspProducedDate); + ssl->ocspProducedDateFormat = response->producedDateFormat; + } + *inOutIdx += status_length; #ifdef WOLFSSL_SMALL_STACK diff --git a/src/ssl.c b/src/ssl.c index 70574db35..e394c8879 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -44134,6 +44134,24 @@ int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url) #endif /* OCSP */ #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ +#ifdef HAVE_OCSP +int wolfSSL_get_ocsp_producedDate(WOLFSSL *ssl, struct tm *producedTime) { + int idx = 0; + + if ((producedTime == NULL) || (ssl->ocspProducedDate == NULL)) + return BAD_FUNC_ARG; + if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) && + (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME)) + return BAD_FUNC_ARG; + + if (ExtractDate(ssl->ocspProducedDate, ssl->ocspProducedDateFormat, producedTime, &idx)) + return 0; + else + return ASN_PARSE_E; +} +#endif + + #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, WOLF_STACK_OF(X509)** chain) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c3829fe14..dd9dc36bc 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4167,6 +4167,8 @@ struct WOLFSSL { #endif /* HAVE_TLS_EXTENSIONS */ #ifdef HAVE_OCSP void* ocspIOCtx; + byte ocspProducedDate[MAX_DATE_SZ]; + int ocspProducedDateFormat; #ifdef OPENSSL_EXTRA byte* ocspResp; int ocspRespSz; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 9122a783f..2eb91ec85 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3791,6 +3791,10 @@ WOLFSSL_API int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *, int (*)( WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc)); #endif +#ifdef HAVE_OCSP + WOLFSSL_API int wolfSSL_get_ocsp_producedDate(WOLFSSL *ssl, struct tm *producedTime); +#endif + #if defined(HAVE_OCSP) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLFSSL_API int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, From 7a77b6d9906232321156a21ccde2d05fd505536e Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Tue, 6 Oct 2020 23:51:06 -0500 Subject: [PATCH 2/4] rename wolfSSL_get_ocsp_producedDate(WOLFSSL *, struct tm *) to wolfSSL_get_ocsp_producedDate_tm(), and add wolfSSL_get_ocsp_producedDate() accessing the raw ASN.1 producedDate; fix location of prototypes in ssl.h to obtain proper conditionalization; omit frivolous nullness test on ssl->ocspProducedDate (always true). --- examples/client/client.c | 2 +- src/ssl.c | 35 +++++++++++++++++++++++++++++------ wolfssl/ssl.h | 14 ++++++++++---- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 362f4c8e5..e5463a04c 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3011,7 +3011,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) { struct tm tm; char date[32]; - ret = wolfSSL_get_ocsp_producedDate(ssl, &tm); + ret = wolfSSL_get_ocsp_producedDate_tm(ssl, &tm); if ((ret == 0) && (strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S %z",&tm) > 0)) printf("OCSP response timestamp: %s\n",date); } diff --git a/src/ssl.c b/src/ssl.c index e394c8879..dcfb92849 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -44135,16 +44135,39 @@ int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url) #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ #ifdef HAVE_OCSP -int wolfSSL_get_ocsp_producedDate(WOLFSSL *ssl, struct tm *producedTime) { - int idx = 0; - - if ((producedTime == NULL) || (ssl->ocspProducedDate == NULL)) - return BAD_FUNC_ARG; +int wolfSSL_get_ocsp_producedDate( + WOLFSSL *ssl, + byte *producedDate, + size_t producedDate_space, + int *producedDateFormat) +{ if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) && (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME)) return BAD_FUNC_ARG; - if (ExtractDate(ssl->ocspProducedDate, ssl->ocspProducedDateFormat, producedTime, &idx)) + if ((producedDate == NULL) || (producedDateFormat == NULL)) + return BAD_FUNC_ARG; + + if (XSTRLEN((char *)ssl->ocspProducedDate) >= producedDate_space) + return BUFFER_E; + + XSTRNCPY((char *)producedDate, (const char *)ssl->ocspProducedDate, producedDate_space); + *producedDateFormat = ssl->ocspProducedDateFormat; + + return 0; +} + +int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, struct tm *produced_tm) { + int idx = 0; + + if ((ssl->ocspProducedDateFormat != ASN_UTC_TIME) && + (ssl->ocspProducedDateFormat != ASN_GENERALIZED_TIME)) + return BAD_FUNC_ARG; + + if (produced_tm == NULL) + return BAD_FUNC_ARG; + + if (ExtractDate(ssl->ocspProducedDate, ssl->ocspProducedDateFormat, produced_tm, &idx)) return 0; else return ASN_PARSE_E; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2eb91ec85..358875604 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3735,6 +3735,16 @@ WOLFSSL_API void *wolfSSL_OPENSSL_memdup(const void *data, WOLFSSL_API void wolfSSL_ERR_load_BIO_strings(void); #endif +#ifdef HAVE_OCSP + WOLFSSL_API int wolfSSL_get_ocsp_producedDate( + WOLFSSL *ssl, + byte *producedDate, + size_t producedDate_space, + int *producedDateFormat); + WOLFSSL_API int wolfSSL_get_ocsp_producedDate_tm(WOLFSSL *ssl, + struct tm *produced_tm); +#endif + #if defined(OPENSSL_ALL) \ || defined(WOLFSSL_NGINX) \ || defined(WOLFSSL_HAPROXY) \ @@ -3791,10 +3801,6 @@ WOLFSSL_API int wolfSSL_CTX_set_tlsext_ticket_key_cb(WOLFSSL_CTX *, int (*)( WOLFSSL_EVP_CIPHER_CTX *ectx, WOLFSSL_HMAC_CTX *hctx, int enc)); #endif -#ifdef HAVE_OCSP - WOLFSSL_API int wolfSSL_get_ocsp_producedDate(WOLFSSL *ssl, struct tm *producedTime); -#endif - #if defined(HAVE_OCSP) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) || \ defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) WOLFSSL_API int wolfSSL_CTX_get_extra_chain_certs(WOLFSSL_CTX* ctx, From 570f55a0e3eb05380d8ea503d345503e1acc6b4d Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Thu, 8 Oct 2020 23:26:28 -0500 Subject: [PATCH 3/4] wolfSSL_get_ocsp_producedDate*(): gate on !defined(NO_ASN_TIME), and in client_test(), gate call to strftime() on HAVE_STRFTIME and add fallback code; add HAVE_STRFTIME test to configure.ac. --- configure.ac | 4 ++-- examples/client/client.c | 16 +++++++++++++--- src/ssl.c | 2 +- wolfssl/ssl.h | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 941fb24b3..cd4d95054 100644 --- a/configure.ac +++ b/configure.ac @@ -67,8 +67,8 @@ AC_CHECK_SIZEOF([long long]) AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([time_t]) AC_CHECK_TYPES([__uint128_t]) -AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r inet_ntoa memset socket]) -AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stddef.h sys/ioctl.h sys/socket.h sys/time.h errno.h]) +AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r inet_ntoa memset socket strftime]) +AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stddef.h time.h sys/ioctl.h sys/socket.h sys/time.h errno.h]) AC_CHECK_LIB([network],[socket]) AC_C_BIGENDIAN diff --git a/examples/client/client.c b/examples/client/client.c index e5463a04c..f55a44816 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3007,14 +3007,24 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) showPeerEx(ssl, lng_index); -#ifdef HAVE_OCSP +#if defined(HAVE_OCSP) && !defined(NO_ASN_TIME) +#ifdef HAVE_STRFTIME { struct tm tm; char date[32]; ret = wolfSSL_get_ocsp_producedDate_tm(ssl, &tm); - if ((ret == 0) && (strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S %z",&tm) > 0)) - printf("OCSP response timestamp: %s\n",date); + if ((ret == 0) && (strftime(date, sizeof date, "%Y-%m-%d %H:%M:%S %z", &tm) > 0)) + printf("OCSP response timestamp: %s\n", date); } +#else + { + byte date[MAX_DATE_SIZE]; + int asn_date_format; + ret = wolfSSL_get_ocsp_producedDate(ssl, date, sizeof date, &asn_date_format); + if (ret == 0) + printf("OCSP response timestamp: %s (ASN.1 type %d)\n", (char *)date, asn_date_format); + } +#endif #endif #ifdef OPENSSL_EXTRA diff --git a/src/ssl.c b/src/ssl.c index dcfb92849..55817f477 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -44134,7 +44134,7 @@ int wolfSSL_set_ocsp_url(WOLFSSL* ssl, char* url) #endif /* OCSP */ #endif /* OPENSSL_ALL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ -#ifdef HAVE_OCSP +#if defined(HAVE_OCSP) && !defined(NO_ASN_TIME) int wolfSSL_get_ocsp_producedDate( WOLFSSL *ssl, byte *producedDate, diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 358875604..7acee6797 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3735,7 +3735,7 @@ WOLFSSL_API void *wolfSSL_OPENSSL_memdup(const void *data, WOLFSSL_API void wolfSSL_ERR_load_BIO_strings(void); #endif -#ifdef HAVE_OCSP +#if defined(HAVE_OCSP) && !defined(NO_ASN_TIME) WOLFSSL_API int wolfSSL_get_ocsp_producedDate( WOLFSSL *ssl, byte *producedDate, From 9de5eea1d91fdf59d74926ebaa4542af090482db Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Fri, 9 Oct 2020 22:18:51 -0500 Subject: [PATCH 4/4] configure.ac: supplement AC_CHECK_FUNCS() (function link test) with AC_CHECK_DECLS() (function declaration test) to avoid false positives. fixes various build failure modes. --- configure.ac | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index cd4d95054..a022b86ae 100644 --- a/configure.ac +++ b/configure.ac @@ -67,11 +67,46 @@ AC_CHECK_SIZEOF([long long]) AC_CHECK_SIZEOF([long]) AC_CHECK_SIZEOF([time_t]) AC_CHECK_TYPES([__uint128_t]) -AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r inet_ntoa memset socket strftime]) + AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h netdb.h netinet/in.h stddef.h time.h sys/ioctl.h sys/socket.h sys/time.h errno.h]) AC_CHECK_LIB([network],[socket]) AC_C_BIGENDIAN +# check if functions of interest are linkable, but also check if +# they're declared by the expected headers, and if not, supersede the +# unusable positive from AC_CHECK_FUNCS(). +AC_CHECK_FUNCS([gethostbyname getaddrinfo gettimeofday gmtime_r inet_ntoa memset socket strftime]) +AC_CHECK_DECLS([gethostbyname, getaddrinfo, gettimeofday, gmtime_r, inet_ntoa, memset, socket, strftime], [], [ +if test "$(eval echo \$"$(eval 'echo ac_cv_func_${as_decl_name}')")" = "yes" +then + echo " note: earlier check for $(eval 'echo ${as_decl_name}') superseded." + eval "$(eval 'echo ac_cv_func_${as_decl_name}=no')" + _mask_varname=HAVE_`eval "echo '${as_decl_name}'" | tr 'a-z' 'A-Z'` + echo "g/#define $_mask_varname 1/s//\/* #undef $_mask_varname *\// +wq +." | ed -s confdefs.h +fi +], [[ +#ifdef HAVE_SYS_SOCKET_H + #include +#endif +#ifdef HAVE_STRING_H + #include +#endif +#ifdef HAVE_NETDB_H + #include +#endif +#ifdef HAVE_ARPA_INET_H + #include +#endif +#ifdef HAVE_SYS_TIME_H + #include +#endif +#ifdef HAVE_TIME_H + #include +#endif +]]) + AC_PROG_INSTALL AC_TYPE_SIZE_T AC_TYPE_UINT8_T @@ -2163,7 +2198,9 @@ fi if test "$ENABLED_STACKSIZE" = "yes" then AC_CHECK_FUNC([posix_memalign], [], [AC_MSG_ERROR(stacksize needs posix_memalign)]) + AC_CHECK_DECL([posix_memalign], [], [AC_MSG_ERROR(stacksize needs posix_memalign)]) AC_CHECK_FUNC([pthread_attr_setstack], [], AC_CHECK_LIB([pthread],[pthread_attr_setstack])) + AC_CHECK_DECL([pthread_attr_setstack], [], [AC_MSG_ERROR(stacksize needs pthread_attr_setstack)], [[#include ]]) AM_CFLAGS="$AM_CFLAGS -DHAVE_STACK_SIZE" fi