include/openssl: don't include <windows.h> in public headers. If application uses any of Windows-specific interfaces, make it application developer's respondibility to include <windows.h>. Rationale is that <windows.h> is quite "toxic" and is sensitive to inclusion order (most notably in relation to <winsock2.h>). It's only natural to give complete control to the application developer. Reviewed-by: Rich Salz <rsalz@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org>
diff --git a/crypto/async/arch/async_null.c b/crypto/async/arch/async_null.c index a9ae35d..3eaf170 100644 --- a/crypto/async/arch/async_null.c +++ b/crypto/async/arch/async_null.c
@@ -11,9 +11,6 @@ #include "../async_locl.h" #ifdef ASYNC_NULL -# include <openssl/ct.h> -# include <openssl/x509v3.h> - int ASYNC_is_capable(void) { return 0; @@ -22,6 +19,5 @@ void async_local_cleanup(void) { } - #endif
diff --git a/crypto/async/async_locl.h b/crypto/async/async_locl.h index 786cf00..f0ac05a 100644 --- a/crypto/async/async_locl.h +++ b/crypto/async/async_locl.h
@@ -16,6 +16,10 @@ # pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif +#if defined(_WIN32) +# include <windows.h> +#endif + #include <internal/async.h> #include <openssl/crypto.h>
diff --git a/crypto/threads_win.c b/crypto/threads_win.c index 545b9be..4e0de90 100644 --- a/crypto/threads_win.c +++ b/crypto/threads_win.c
@@ -7,6 +7,10 @@ * https://www.openssl.org/source/license.html */ +#if defined(_WIN32) +# include <windows.h> +#endif + #include <openssl/crypto.h> #if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && defined(OPENSSL_SYS_WINDOWS)
diff --git a/doc/crypto/ASYNC_WAIT_CTX_new.pod b/doc/crypto/ASYNC_WAIT_CTX_new.pod index 364cbb4..de1bd57 100644 --- a/doc/crypto/ASYNC_WAIT_CTX_new.pod +++ b/doc/crypto/ASYNC_WAIT_CTX_new.pod
@@ -112,6 +112,15 @@ ASYNC_WAIT_CTX_get_changed_fds and ASYNC_WAIT_CTX_clear_fd all return 1 on success or 0 on error. +=head1 NOTES + +On Windows platforms the openssl/async.h header is dependent on some +of the types customarily made available by including windows.h. The +application developer is likely to require control over when the latter +is included, commonly as one of the first included headers. Therefore +it is defined as an application developer's responsibility to include +windows.h prior to async.h. + =head1 SEE ALSO L<crypto(3)>, L<ASYNC_start_job(3)>
diff --git a/doc/crypto/ASYNC_start_job.pod b/doc/crypto/ASYNC_start_job.pod index 20bc1ad..eb12da8 100644 --- a/doc/crypto/ASYNC_start_job.pod +++ b/doc/crypto/ASYNC_start_job.pod
@@ -161,10 +161,22 @@ ASYNC_is_capable() returns 1 if the current platform is async capable or 0 otherwise. +=head1 NOTES + +On Windows platforms the openssl/async.h header is dependent on some +of the types customarily made available by including windows.h. The +application developer is likely to require control over when the latter +is included, commonly as one of the first included headers. Therefore +it is defined as an application developer's responsibility to include +windows.h prior to async.h. + =head1 EXAMPLE The following example demonstrates how to use most of the core async APIs: + #ifdef _WIN32 + # include <windows.h> + #endif #include <stdio.h> #include <unistd.h> #include <openssl/async.h>
diff --git a/doc/crypto/CRYPTO_THREAD_run_once.pod b/doc/crypto/CRYPTO_THREAD_run_once.pod index 37671b9..7795a04 100644 --- a/doc/crypto/CRYPTO_THREAD_run_once.pod +++ b/doc/crypto/CRYPTO_THREAD_run_once.pod
@@ -79,10 +79,23 @@ The other functions return 1 on success or 0 on error. +=head1 NOTES + +On Windows platforms the CRYPTO_THREAD_* types and functions in the +openssl/crypto.h header are dependent on some of the types customarily +made available by including windows.h. The application developer is +likely to require control over when the latter is included, commonly as +one of the first included headers. Therefore it is defined as an +application developer's responsibility to include windows.h prior to +crypto.h where use of CRYPTO_THREAD_* types and functions is required. + =head1 EXAMPLE This example safely initializes and uses a lock. + #ifdef _WIN32 + # include <windows.h> + #endif #include <openssl/crypto.h> static CRYPTO_ONCE once = CRYPTO_ONCE_STATIC_INIT;
diff --git a/doc/ssl/SSL_get_all_async_fds.pod b/doc/ssl/SSL_get_all_async_fds.pod index deb81e1..636f765 100644 --- a/doc/ssl/SSL_get_all_async_fds.pod +++ b/doc/ssl/SSL_get_all_async_fds.pod
@@ -7,6 +7,7 @@ =head1 SYNOPSIS + #include <openssl/async.h> #include <openssl/ssl.h> int SSL_waiting_for_async(SSL *s); @@ -53,6 +54,15 @@ SSL_get_all_async_fds() and SSL_get_changed_async_fds() return 1 on success or 0 on error. +=head1 NOTES + +On Windows platforms the openssl/async.h header is dependent on some +of the types customarily made available by including windows.h. The +application developer is likely to require control over when the latter +is included, commonly as one of the first included headers. Therefore +it is defined as an application developer's responsibility to include +windows.h prior to async.h. + =head1 SEE ALSO L<SSL_get_error(3)>, L<SSL_CTX_set_mode(3)>
diff --git a/engines/e_capi.c b/engines/e_capi.c index 4923eef..9e9e4f3 100644 --- a/engines/e_capi.c +++ b/engines/e_capi.c
@@ -7,13 +7,23 @@ * https://www.openssl.org/source/license.html */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> +#ifdef _WIN32 +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif +# include <windows.h> +# include <wincrypt.h> -#include <openssl/crypto.h> +# include <stdio.h> +# include <string.h> +# include <stdlib.h> +# include <malloc.h> +# ifndef alloca +# define alloca _alloca +# endif -#ifdef OPENSSL_SYS_WIN32 +# include <openssl/crypto.h> + # ifndef OPENSSL_NO_CAPIENG # include <openssl/buffer.h> @@ -21,17 +31,6 @@ # include <openssl/rsa.h> # include <openssl/dsa.h> -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif - -# include <windows.h> -# include <wincrypt.h> -# include <malloc.h> -# ifndef alloca -# define alloca _alloca -# endif - /* * This module uses several "new" interfaces, among which is * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is @@ -50,7 +49,7 @@ # define __COMPILE_CAPIENG # endif /* CERT_KEY_PROV_INFO_PROP_ID */ # endif /* OPENSSL_NO_CAPIENG */ -#endif /* OPENSSL_SYS_WIN32 */ +#endif /* _WIN32 */ #ifdef __COMPILE_CAPIENG
diff --git a/engines/e_dasync.c b/engines/e_dasync.c index ed3f00a..89b1277 100644 --- a/engines/e_dasync.c +++ b/engines/e_dasync.c
@@ -7,6 +7,10 @@ * https://www.openssl.org/source/license.html */ +#if defined(_WIN32) +# include <windows.h> +#endif + #include <stdio.h> #include <string.h> @@ -28,7 +32,6 @@ #elif defined(_WIN32) # undef ASYNC_WIN # define ASYNC_WIN -# include <windows.h> #endif #define DASYNC_LIB_NAME "DASYNC"
diff --git a/include/openssl/async.h b/include/openssl/async.h index 160766a..ca51bb3 100644 --- a/include/openssl/async.h +++ b/include/openssl/async.h
@@ -13,9 +13,11 @@ # define HEADER_ASYNC_H #if defined(_WIN32) -#include <windows.h> +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include <windows.h> to use this */ #define OSSL_ASYNC_FD HANDLE #define OSSL_BAD_ASYNC_FD INVALID_HANDLE_VALUE +# endif #else #define OSSL_ASYNC_FD int #define OSSL_BAD_ASYNC_FD -1 @@ -37,6 +39,7 @@ int ASYNC_init_thread(size_t max_size, size_t init_size); void ASYNC_cleanup_thread(void); +#ifdef OSSL_ASYNC_FD ASYNC_WAIT_CTX *ASYNC_WAIT_CTX_new(void); void ASYNC_WAIT_CTX_free(ASYNC_WAIT_CTX *ctx); int ASYNC_WAIT_CTX_set_wait_fd(ASYNC_WAIT_CTX *ctx, const void *key, @@ -52,6 +55,7 @@ size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds); int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); +#endif int ASYNC_is_capable(void);
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index acdb48b..cbd05a8 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h
@@ -387,33 +387,37 @@ /* Low-level control of initialization */ OPENSSL_INIT_SETTINGS *OPENSSL_INIT_new(void); -#ifndef OPENSSL_NO_STDIO +# ifndef OPENSSL_NO_STDIO int OPENSSL_INIT_set_config_appname(OPENSSL_INIT_SETTINGS *settings, const char *config_file); -#endif +# endif void OPENSSL_INIT_free(OPENSSL_INIT_SETTINGS *settings); -# if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG) -typedef unsigned int CRYPTO_ONCE; -typedef unsigned int CRYPTO_THREAD_LOCAL; -typedef unsigned int CRYPTO_THREAD_ID; - -# define CRYPTO_ONCE_STATIC_INIT 0 -# elif defined(OPENSSL_SYS_WINDOWS) -# include <windows.h> +# if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) +# if defined(_WIN32) +# if defined(BASETYPES) || defined(_WINDEF_H) +/* application has to include <windows.h> in order to use this */ typedef DWORD CRYPTO_THREAD_LOCAL; typedef DWORD CRYPTO_THREAD_ID; typedef LONG CRYPTO_ONCE; -# define CRYPTO_ONCE_STATIC_INIT 0 - -# else -# include <pthread.h> +# define CRYPTO_ONCE_STATIC_INIT 0 +# endif +# else +# include <pthread.h> typedef pthread_once_t CRYPTO_ONCE; typedef pthread_key_t CRYPTO_THREAD_LOCAL; typedef pthread_t CRYPTO_THREAD_ID; -# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# define CRYPTO_ONCE_STATIC_INIT PTHREAD_ONCE_INIT +# endif +# endif + +# if !defined(CRYPTO_ONCE_STATIC_INIT) +typedef unsigned int CRYPTO_ONCE; +typedef unsigned int CRYPTO_THREAD_LOCAL; +typedef unsigned int CRYPTO_THREAD_ID; +# define CRYPTO_ONCE_STATIC_INIT 0 # endif int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void));
diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h index adc50ed..129a67f 100644 --- a/include/openssl/ossl_typ.h +++ b/include/openssl/ossl_typ.h
@@ -63,10 +63,11 @@ typedef struct asn1_pctx_st ASN1_PCTX; typedef struct asn1_sctx_st ASN1_SCTX; -# ifdef OPENSSL_SYS_WIN32 +# ifdef _WIN32 # undef X509_NAME # undef X509_EXTENSIONS # undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO # undef OCSP_REQUEST # undef OCSP_RESPONSE # endif
diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h index 6148cec..328a4f6 100644 --- a/include/openssl/pkcs7.h +++ b/include/openssl/pkcs7.h
@@ -21,12 +21,6 @@ extern "C" { #endif -# ifdef OPENSSL_SYS_WIN32 -/* Under Win32 these are defined in wincrypt.h */ -# undef PKCS7_ISSUER_AND_SERIAL -# undef PKCS7_SIGNER_INFO -# endif - /*- Encryption_ID DES-CBC Digest_ID MD5
diff --git a/include/openssl/rand.h b/include/openssl/rand.h index d0f8eab..8dab1a0 100644 --- a/include/openssl/rand.h +++ b/include/openssl/rand.h
@@ -14,10 +14,6 @@ # include <openssl/ossl_typ.h> # include <openssl/e_os2.h> -# if defined(OPENSSL_SYS_WINDOWS) -# include <windows.h> -# endif - #ifdef __cplusplus extern "C" { #endif @@ -65,7 +61,8 @@ # endif int RAND_poll(void); -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +#if defined(_WIN32) && (defined(BASETYPES) || defined(_WINDEF_H)) +/* application has to include <windows.h> in order to use these */ DEPRECATEDIN_1_1_0(void RAND_screen(void)) DEPRECATEDIN_1_1_0(int RAND_event(UINT, WPARAM, LPARAM)) #endif
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index d2736e2..2669f73 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h
@@ -1532,11 +1532,16 @@ void SSL_certs_clear(SSL *s); void SSL_free(SSL *ssl); +# ifdef OSSL_ASYNC_FD +/* + * Windows applcation developer has to include windows.h to use these. + */ __owur int SSL_waiting_for_async(SSL *s); __owur int SSL_get_all_async_fds(SSL *s, OSSL_ASYNC_FD *fds, size_t *numfds); __owur int SSL_get_changed_async_fds(SSL *s, OSSL_ASYNC_FD *addfd, size_t *numaddfds, OSSL_ASYNC_FD *delfd, size_t *numdelfds); +# endif __owur int SSL_accept(SSL *ssl); __owur int SSL_connect(SSL *ssl); __owur int SSL_read(SSL *ssl, void *buf, int num);
diff --git a/include/openssl/ts.h b/include/openssl/ts.h index 3fbaf55..3e31b2f 100644 --- a/include/openssl/ts.h +++ b/include/openssl/ts.h
@@ -27,11 +27,6 @@ extern "C" { # endif -# ifdef WIN32 -/* Under Win32 this is defined in wincrypt.h */ -# undef X509_NAME -# endif - # include <openssl/x509.h> # include <openssl/x509v3.h>
diff --git a/include/openssl/x509.h b/include/openssl/x509.h index 4b7a1f6..2f7444d 100644 --- a/include/openssl/x509.h +++ b/include/openssl/x509.h
@@ -17,7 +17,7 @@ # define HEADER_X509_H # include <openssl/e_os2.h> -# include <openssl/opensslconf.h> +# include <openssl/ossl_typ.h> # include <openssl/symhacks.h> # include <openssl/buffer.h> # include <openssl/evp.h> @@ -40,12 +40,6 @@ extern "C" { #endif -# ifdef OPENSSL_SYS_WIN32 -/* Under Win32 these are defined in wincrypt.h */ -# undef X509_NAME -# undef X509_EXTENSIONS -# endif - # define X509_FILETYPE_PEM 1 # define X509_FILETYPE_ASN1 2 # define X509_FILETYPE_DEFAULT 3
diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 7b0403b..14e25d7 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h
@@ -18,12 +18,6 @@ extern "C" { #endif -# ifdef OPENSSL_SYS_WIN32 -/* Under Win32 these are defined in wincrypt.h */ -# undef X509_NAME -# undef X509_EXTENSIONS -# endif - /* Forward reference */ struct v3_ext_method; struct v3_ext_ctx;
diff --git a/test/asynctest.c b/test/asynctest.c index 6728058..026536b 100644 --- a/test/asynctest.c +++ b/test/asynctest.c
@@ -7,6 +7,10 @@ * https://www.openssl.org/source/license.html */ +#ifdef _WIN32 +# include <windows.h> +#endif + #include <stdio.h> #include <string.h> #include <openssl/async.h>
diff --git a/test/threadstest.c b/test/threadstest.c index db864b2..b2e96fa 100644 --- a/test/threadstest.c +++ b/test/threadstest.c
@@ -7,6 +7,10 @@ * https://www.openssl.org/source/license.html */ +#if defined(_WIN32) +# include <windows.h> +#endif + #include <stdio.h> #include <openssl/crypto.h>
diff --git a/util/mkdef.pl b/util/mkdef.pl index c2fbfe7..fa37ccb 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl
@@ -73,7 +73,7 @@ my $safe_stack_def = 0; my @known_platforms = ( "__FreeBSD__", "PERL5", - "EXPORT_VAR_AS_FUNCTION", "ZLIB" + "EXPORT_VAR_AS_FUNCTION", "ZLIB", "_WIN32" ); my @known_ossl_platforms = ( "VMS", "WIN32", "WINNT", "OS2" ); my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", @@ -1121,6 +1121,7 @@ if ($keyword eq "VMSNonVAX" && $VMSNonVAX) { return 1; } if ($keyword eq "VMS" && $VMS) { return 1; } if ($keyword eq "WIN32" && $W32) { return 1; } + if ($keyword eq "_WIN32" && $W32) { return 1; } if ($keyword eq "WINNT" && $NT) { return 1; } # Special platforms: # EXPORT_VAR_AS_FUNCTION means that global variables