diff --git a/.gitignore b/.gitignore index f5544aa798..1d8ee8414b 100644 --- a/.gitignore +++ b/.gitignore @@ -468,3 +468,50 @@ wrapper/Ada/obj/ # Autogenerated debug trace headers wolfssl/debug-trace-error-codes.h wolfssl/debug-untrace-error-codes.h +/wrapper/CSharp/SmartDeviceProject1 +/commit_squash.sh +/gpg_refresh.sh +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32c2.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32c3.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32c6.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32h2.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32s2.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp32s3.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/esp8266.clog +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/testAll.sh.wip +/IDE/Espressif/ESP-IDF/examples/wolfssl_test/testMonitor.sh.wip +/server_loop.sh +/UpgradeLog.XML +/wolfcrypt/src/evp.c.wip +/wolfssl/PR_text.md +/wolfssl-VS2022.vcxproj.user +/wolfssl-VS2022a-options_h.vcxproj +/wolfssl-VS2022a.sln +/wolfssl-VS2022a.vcxproj +/wolfssl.sln +/wolfssl.vcproj.not found +/wolfssl_VS2008.sln +/wolfssl_VS2008.vcproj +/wolfssl_VS2008CE.sln +/wolfssl_VS2008CE.vcproj +/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-CE_2008_console.csproj +/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client-VS2008.csproj +/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS_CE_2008.csproj +/wrapper/CSharp/wolfSSL_CSharp/CSharp_CE_2008.csproj +/wrapper/CSharp/wolfSSL_CSharp/CSharp_CE_2008.sln +/wrapper/CSharp/wolfSSL_CSharp/wolfSSL_CSharp _VS2008.csproj +/wrapper/CSharp/wolfSSL_CSharp-Clients-old.sln +/wrapper/CSharp/wolfSSL_CSharp-Pull Request.sln +/wrapper/CSharp/wolfssl_VS2008.sln +/wrapper/CSharp/wolfssl_VS2008CE.sln +/wrapper/CSharp/wolfssl_VS2012.sln +/_UpgradeReport_Files +/_UpgradeReport_Files/UpgradeReport.css +/_UpgradeReport_Files/UpgradeReport.xslt +/_UpgradeReport_Files/UpgradeReport_Minus.gif +/_UpgradeReport_Files/UpgradeReport_Plus.gif +/DLL Release (options.h)/x64 +/wrapper/CSharp/wolfSSL_CSharp-Clients-VS2022.sln +/wrapper/CSharp/wolfSSL_CSharp-VS2022.sln +/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS_WCE_2008 diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index 236de66277..2c919753ca 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -440,6 +440,7 @@ PLATFORMIO PLUTON_CRYPTO_ECC PRINT_SESSION_STATS PTHREAD_STACK_MIN +PocketPC QAT_ENABLE_HASH QAT_ENABLE_RNG QAT_USE_POLLING_CHECK @@ -603,6 +604,7 @@ WC_STRICT_SIG WC_WANT_FLAG_DONT_USE_AESNI WC_XMSS_FULL_HASH WIFI_AVAILABLE +WINCE WIN_REUSE_CRYPT_HANDLE WOLFCRYPT_FIPS_CORE_DYNAMIC_HASH_VALUE WOLFSENTRY_H @@ -872,6 +874,7 @@ WOLFSSL_UNALIGNED_64BIT_ACCESS WOLFSSL_USER_FILESYSTEM WOLFSSL_USER_LOG WOLFSSL_USER_MUTEX +WOLFSSL_USER_SETTINGS_TAG WOLFSSL_USER_THREADING WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW WOLFSSL_USE_FLASHMEM @@ -897,7 +900,6 @@ WOLF_CRYPTO_CB_ONLY_ECC WOLF_CRYPTO_CB_ONLY_RSA WOLF_CRYPTO_DEV WOLF_NO_TRAILING_ENUM_COMMAS -WindowsCE XGETPASSWD XMSS_CALL_PRF_KEYGEN XPAR_VERSAL_CIPS_0_PSPMC_0_PSV_CORTEXA72_0_TIMESTAMP_CLK_FREQ diff --git a/IDE/WIN/user_settings.h b/IDE/WIN/user_settings.h index a1011abf8c..06093b6af7 100644 --- a/IDE/WIN/user_settings.h +++ b/IDE/WIN/user_settings.h @@ -6,6 +6,8 @@ #error This user_settings.h header is only designed for Windows #endif +#define WOLFSSL_USER_SETTINGS_TAG "wolfssl v5.8.0 for IDE/WIN example config" + #define USE_WOLFSSL_IO #define HAVE_AESGCM #define WOLFSSL_TLS13 diff --git a/src/bio.c b/src/bio.c index ce74983f8d..8f3c8fca29 100644 --- a/src/bio.c +++ b/src/bio.c @@ -28,7 +28,12 @@ #if !defined(WOLFSSL_BIO_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning bio.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "bio.c does not need to be compiled separately from ssl.c") + #else + #warning bio.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/conf.c b/src/conf.c index e0a8b03be8..31c56da8f8 100644 --- a/src/conf.c +++ b/src/conf.c @@ -23,7 +23,12 @@ #if !defined(WOLFSSL_CONF_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning conf.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "conf.c does not need to be compiled separately from ssl.c") + #else + #warning conf.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/pk.c b/src/pk.c index 7cb73d7a48..c34d882114 100644 --- a/src/pk.c +++ b/src/pk.c @@ -43,7 +43,12 @@ #if !defined(WOLFSSL_PK_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning pk.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "pk.c does not need to be compiled separately from ssl.c") + #else + #warning pk.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl.c b/src/ssl.c index 7370cccef7..9d7b14799e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15375,6 +15375,20 @@ const char* wolfSSL_lib_version(void) return LIBWOLFSSL_VERSION_STRING; } +/* current user_settings.h breadcrumb tag */ +const char* wolfSSL_user_settings_tag(void) +{ +#ifdef WOLFSSL_USER_SETTINGS + #ifdef WOLFSSL_USER_SETTINGS_TAG + return WOLFSSL_USER_SETTINGS_TAG; + #else + return "unknown or WOLFSSL_USER_SETTINGS_TAG not set"; + #endif +#else + return "WOLFSSL_USER_SETTINGS not defined, assuming options.h build"; +#endif +} + #ifdef OPENSSL_EXTRA #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L const char* wolfSSL_OpenSSL_version(int a) diff --git a/src/ssl_asn1.c b/src/ssl_asn1.c index f2ffbc6f34..93faba313d 100644 --- a/src/ssl_asn1.c +++ b/src/ssl_asn1.c @@ -28,7 +28,13 @@ #if !defined(WOLFSSL_SSL_ASN1_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_asn1.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_asn1.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_asn1.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_bn.c b/src/ssl_bn.c index 139684bd8c..a155628c5c 100644 --- a/src/ssl_bn.c +++ b/src/ssl_bn.c @@ -28,7 +28,12 @@ #if !defined(WOLFSSL_SSL_BN_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_bn.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_bn.c does not need to be compiled separately from ssl.c") + #else \ + #warning ssl_bn.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_certman.c b/src/ssl_certman.c index 286831b9d2..58abb75cba 100644 --- a/src/ssl_certman.c +++ b/src/ssl_certman.c @@ -25,7 +25,13 @@ #if !defined(WOLFSSL_SSL_CERTMAN_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_certman.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_certman.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_certman.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_crypto.c b/src/ssl_crypto.c index 6ba73ab25d..5c27aa1450 100644 --- a/src/ssl_crypto.c +++ b/src/ssl_crypto.c @@ -23,7 +23,13 @@ #ifndef WOLFSSL_SSL_CRYPTO_INCLUDED #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_crypto.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_crypto.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_crypto.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_load.c b/src/ssl_load.c index d50fae933f..a776694448 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -55,7 +55,13 @@ #if !defined(WOLFSSL_SSL_LOAD_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_load.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_load.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_load.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_misc.c b/src/ssl_misc.c index 4743ad0668..02bf39e902 100644 --- a/src/ssl_misc.c +++ b/src/ssl_misc.c @@ -23,7 +23,13 @@ #if !defined(WOLFSSL_SSL_MISC_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_misc.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_misc.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_misc.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_p7p12.c b/src/ssl_p7p12.c index 6313feb551..fff94d1db0 100644 --- a/src/ssl_p7p12.c +++ b/src/ssl_p7p12.c @@ -30,7 +30,13 @@ #if !defined(WOLFSSL_SSL_P7P12_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_p7p12.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_p7p12.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_p7p12.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/ssl_sess.c b/src/ssl_sess.c index bd869d3465..75918a4d0b 100644 --- a/src/ssl_sess.c +++ b/src/ssl_sess.c @@ -23,7 +23,13 @@ #if !defined(WOLFSSL_SSL_SESS_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning ssl_sess.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "ssl_sess.c does not need to be compiled separately from ssl.c") + #else + #warning \ + ssl_sess.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/wolfio.c b/src/wolfio.c index b3bb6a8ada..73a11b160b 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -400,7 +400,7 @@ int SslBioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) /* The receive embedded callback * return : nb bytes read, or error */ -int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) +int WOLFSSL_CALL EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) { int recvd; #ifndef WOLFSSL_LINUXKM @@ -424,7 +424,7 @@ int EmbedReceive(WOLFSSL *ssl, char *buf, int sz, void *ctx) /* The send embedded callback * return : nb bytes sent, or error */ -int EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) +int WOLFSSL_CALL EmbedSend(WOLFSSL* ssl, char *buf, int sz, void *ctx) { int sent; #ifndef WOLFSSL_LINUXKM @@ -637,7 +637,7 @@ static int isDGramSock(int sfd) /* The receive embedded callback * return : nb bytes read, or error */ -int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) +int WOLFSSL_CALL EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) { WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; int recvd; @@ -886,7 +886,7 @@ int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx) /* The send embedded callback * return : nb bytes sent, or error */ -int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) +int WOLFSSL_CALL EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx) { WOLFSSL_DTLS_CTX* dtlsCtx = (WOLFSSL_DTLS_CTX*)ctx; int sd = dtlsCtx->wfd; @@ -956,7 +956,7 @@ int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, int sz, void *ctx) /* The DTLS Generate Cookie callback * return : number of bytes copied into buf, or error */ -int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) +int WOLFSSL_CALL EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx) { int sd = ssl->wfd; SOCKADDR_S peer; diff --git a/src/x509.c b/src/x509.c index 323daa1190..899f12f592 100644 --- a/src/x509.c +++ b/src/x509.c @@ -23,7 +23,12 @@ #if !defined(WOLFSSL_X509_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning x509.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "x509.c does not need to be compiled separately from ssl.c") + #else + #warning x509.c does not need to be compiled separately from ssl.c + #endif #endif #else diff --git a/src/x509_str.c b/src/x509_str.c index 4571b95bd2..c3e4cfae25 100644 --- a/src/x509_str.c +++ b/src/x509_str.c @@ -23,7 +23,14 @@ #if !defined(WOLFSSL_X509_STORE_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning x509_str.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "x509_str.c does not need to be compiled separately from ssl.c") + #else + #warning \ + x509_str.c does not need to be compiled separately from ssl.c + #endif + #endif #else diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 5c9ac3e8d1..f5c537ffbb 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -23,7 +23,12 @@ #if !defined(WOLFSSL_EVP_INCLUDED) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning evp.c does not need to be compiled separately from ssl.c + #if defined(_MSC_VER) + #pragma message( \ + "evp.c does not need to be compiled separately from ssl.c") + #else \ + #warning evp.c does not need to be compiled separately from ssl.c + #endif #endif #elif defined(WOLFCRYPT_ONLY) #else diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 98fcb3565a..5d7c1ea93b 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -21,6 +21,15 @@ #include +#ifdef WOLFSSL_DLL + /* Breadcrumb Tag can be helpful when debugging Binary DLL compatibility */ + WOLFSSL_API const char* wolfSSL_dll_tag(void); + const char* wolfSSL_dll_tag(void) + { + return WOLFSSL_DLL_TAG; + } +#endif + #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) /* avoid adding WANT_READ and WANT_WRITE to error queue */ #include diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index e681d2bbdf..d44eb089f6 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -50,7 +50,13 @@ masking and clearing memory logic. /* Check for if compiling misc.c when not needed. */ #if !defined(WOLFSSL_MISC_INCLUDED) && !defined(NO_INLINE) #ifndef WOLFSSL_IGNORE_FILE_WARN - #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined) + #if defined(_MSC_VER) + #pragma message( \ +"misc.c does not need to be compiled when using inline (NO_INLINE not defined)") + #else + #warning \ +misc.c does not need to be compiled when using inline (NO_INLINE not defined) + #endif #endif #else diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 3873b25bc1..8e17f54549 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -242,7 +242,18 @@ enum wolfSSL_ErrorCodes { /* codes -1000 to -1999 are reserved for wolfCrypt. */ }; -wc_static_assert((int)WC_LAST_E <= (int)WOLFSSL_LAST_E); + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) /* VS2015 or newer */ + #pragma warning(push) + /* Visual Studio complains: "operands are different enum types" + * even with explicitly type cast. So ignore it here: */ + #pragma warning(disable: 5287) + wc_static_assert((int)WC_LAST_E <= (int)WOLFSSL_LAST_E); + #pragma warning(pop) +#else + wc_static_assert((int)WC_LAST_E <= (int)WOLFSSL_LAST_E); +#endif + /* I/O Callback default errors */ enum IOerrors { diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3e6865b417..f40ad7a935 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3288,6 +3288,8 @@ WOLFSSL_API void wolfSSL_set_security_level(WOLFSSL * ssl, int level); /* which library version do we have */ WOLFSSL_API const char* wolfSSL_lib_version(void); +/* which user_settings.h file was used to build wolfssl */ +WOLFSSL_API const char* wolfSSL_user_settings_tag(void); #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L WOLFSSL_API const char* wolfSSL_OpenSSL_version(int a); #else diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index fc08d66e22..f0acd8aa62 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -4429,6 +4429,92 @@ extern void uITRON4_free(void *p) ; /* Ciphersuite check done in internal.h */ #endif +/* Generate a space-delimited, alphabetical breadcrumb string for wolfssl.dll + * Example expected strings to be detected at runtime: + * + * Standard: + * + * Special cases: + * wolfssl.dll PocketPC; MSC_VER=1944 Debug + * + * See wolfcrypt.SelfCheck(); + */ +#ifdef WOLFSSL_DLL + #define WOLFSSL_DLL_TAG_TMP "" + /* Concatenate string */ + #define WOLFSSL_DLL_TAG_HELPER(a, b) a b + /* Get numeric Microsoft Compiler as a string */ + #ifdef _MSC_VER + #define MSC_VER_STR_HELPER(x) #x + #define MSC_VER_STR(x) MSC_VER_STR_HELPER(x) + #else + #define MSC_VER_STR(x) "UNKNOWN_MSCVER" + #endif + + /* For old compiler compatibility, we'll build the string in stages */ + + /* Stage 1: Base */ + #define WOLFSSL_DLL_TAG_1 "wolfssl.dll" + + /* Stage 2: Add PocketPC if defined */ + #ifdef PocketPC + #define WOLFSSL_DLL_TAG_2 \ + WOLFSSL_DLL_TAG_HELPER(WOLFSSL_DLL_TAG_1, " PocketPC") + #else + #define WOLFSSL_DLL_TAG_2 WOLFSSL_DLL_TAG_1 + #endif + + /* Stage 3: Add WindowsCE if defined */ + #ifdef WindowsCE + #define WOLFSSL_DLL_TAG_3 \ + WOLFSSL_DLL_TAG_HELPER(WOLFSSL_DLL_TAG_2, " WindowsCE") + #else + #define WOLFSSL_DLL_TAG_3 WOLFSSL_DLL_TAG_2 + #endif + + /* End fixed macro check */ + + /* Add semicolon break between expected config and other dynamic macros */ + #define WOLFSSL_DLL_TAG_DELIM_1 \ + WOLFSSL_DLL_TAG_HELPER(WOLFSSL_DLL_TAG_3, ";") + + /* Delim 2: Add _MSC_VER string, the version of Microsoft compiler used */ + #ifdef _MSC_VER + #define WOLFSSL_DLL_TAG_DELIM_2 \ + WOLFSSL_DLL_TAG_HELPER(WOLFSSL_DLL_TAG_DELIM_1, " MSC_VER=" \ + MSC_VER_STR(_MSC_VER)) + #else + #define WOLFSSL_DLL_TAG_DELIM_2 WOLFSSL_DLL_TAG_DELIM_1 + #endif + + /* Delim 3: Add Debug or Release Configuration */ + #if defined(_DEBUG) || defined(DEBUG) + #define WOLFSSL_DLL_TAG_DELIM_3 \ + WOLFSSL_DLL_TAG_HELPER(WOLFSSL_DLL_TAG_DELIM_2, " Debug") + #else + /* _RELEASE and RELEASE typically not defined */ + #define WOLFSSL_DLL_TAG_DELIM_3 \ + WOLFSSL_DLL_TAG_HELPER(WOLFSSL_DLL_TAG_DELIM_2, " Release") + #endif + + /* Final tag */ + #define WOLFSSL_DLL_TAG WOLFSSL_DLL_TAG_DELIM_3 +#else + /* ensure there's no WOLFSSL_DLL_TAG if we did not build with WOLFSSL_DLL */ + #undef WOLFSSL_DLL_TAG +#endif + +/* Breadcrub to identify user_settings.h file */ +#ifdef WOLFSSL_USER_SETTINGS + #ifdef WOLFSSL_USER_SETTINGS_TAG + /* found a value, probably in in user_settings.h or -D build option */ + #else + #define WOLFSSL_USER_SETTINGS_TAG "WOLFSSL_USER_SETTINGS_TAG not set" + #endif +#else + #define WOLFSSL_USER_SETTINGS_TAG "WOLFSSL_USER_SETTINGS not defined" +#endif + /* Some final sanity checks. See esp32-crypt.h for Apple HomeKit config. */ #if defined(WOLFSSL_APPLE_HOMEKIT) || defined(CONFIG_WOLFSSL_APPLE_HOMEKIT) #ifndef WOLFCRYPT_HAVE_SRP diff --git a/wolfssl/wolfcrypt/sp.h b/wolfssl/wolfcrypt/sp.h index c116cb0ae0..5f58da3f1c 100644 --- a/wolfssl/wolfcrypt/sp.h +++ b/wolfssl/wolfcrypt/sp.h @@ -28,7 +28,7 @@ #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) || \ defined(WOLFSSL_HAVE_SP_ECC) -#ifdef _WIN32_WCE +#if defined(_WIN32_WCE) || (defined(_MSC_VER) && (_MSC_VER < 1600)) typedef __int8 int8_t; typedef __int32 int32_t; typedef __int64 int64_t; diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index c0fd47f625..be29c5866d 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -492,7 +492,7 @@ #endif #elif defined(_MSC_VER) && !defined(WOLFSSL_NOT_WINDOWS_API) /* Use MSVC compiler intrinsics for atomic ops */ - #ifdef _WIN32_WCE + #if defined(_WIN32_WCE) && defined(_M_ARM) #include #else #include diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 74862018d4..e958ce099e 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -50,6 +50,13 @@ #endif #endif +/* CE Not always reliably detected. Define our own _WIN32_WCE as needed. */ +#if defined(_WIN32_WCE) || defined(WINCE) || defined(PocketPC) + #if !defined(_WIN32_WCE) + #define _WIN32_WCE + #endif +#endif + #if defined(USE_WOLFSSL_IO) || defined(WOLFSSL_USER_IO) || \ defined(HAVE_HTTP_CLIENT) #ifdef HAVE_LIBZ @@ -578,34 +585,40 @@ WOLFSSL_API int wolfIO_RecvFrom(SOCKET_T sd, WOLFSSL_BIO_ADDR *addr, char *buf, #endif #endif /* WOLFSSL_NO_SOCK */ -WOLFSSL_API int wolfSSL_BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); -WOLFSSL_API int wolfSSL_BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); +#ifdef PocketPC + #define WOLFSSL_CALL __stdcall +#else + #define WOLFSSL_CALL +#endif + +WOLFSSL_API int WOLFSSL_CALL wolfSSL_BioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); +WOLFSSL_API int WOLFSSL_CALL wolfSSL_BioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); #ifndef OPENSSL_COEXIST /* Preserve API previously exposed */ #define BioSend wolfSSL_BioSend #define BioReceive wolfSSL_BioReceive #endif -WOLFSSL_LOCAL int SslBioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); +WOLFSSL_LOCAL int WOLFSSL_CALL SslBioSend(WOLFSSL* ssl, char *buf, int sz, void *ctx); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) WOLFSSL_LOCAL int BioReceiveInternal(WOLFSSL_BIO* biord, WOLFSSL_BIO* biowr, char* buf, int sz); #endif -WOLFSSL_LOCAL int SslBioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); +WOLFSSL_LOCAL int WOLFSSL_CALL SslBioReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); #if defined(USE_WOLFSSL_IO) /* default IO callbacks */ - WOLFSSL_API int EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); - WOLFSSL_API int EmbedSend(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_API int WOLFSSL_CALL EmbedReceive(WOLFSSL* ssl, char* buf, int sz, void* ctx); + WOLFSSL_API int WOLFSSL_CALL EmbedSend(WOLFSSL* ssl, char* buf, int sz, void* ctx); #ifdef WOLFSSL_DTLS #ifdef NUCLEUS_PLUS_2_3 #define SELECT_FUNCTION nucyassl_select WOLFSSL_LOCAL int nucyassl_select(INT sd, UINT32 timeout); #endif - WOLFSSL_API int EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, + WOLFSSL_API int WOLFSSL_CALL EmbedReceiveFrom(WOLFSSL *ssl, char *buf, int sz, void *ctx); - WOLFSSL_API int EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx); - WOLFSSL_API int EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, + WOLFSSL_API int WOLFSSL_CALL EmbedSendTo(WOLFSSL* ssl, char *buf, int sz, void *ctx); + WOLFSSL_API int WOLFSSL_CALL EmbedGenerateCookie(WOLFSSL* ssl, byte *buf, int sz, void *ctx); #ifdef WOLFSSL_MULTICAST WOLFSSL_API int EmbedReceiveFromMcast(WOLFSSL *ssl, char *buf, @@ -663,8 +676,8 @@ typedef int (*WolfSSLGenericIORecvCb)(char *buf, int sz, void *ctx); /* I/O callbacks */ -typedef int (*CallbackIORecv)(WOLFSSL *ssl, char *buf, int sz, void *ctx); -typedef int (*CallbackIOSend)(WOLFSSL *ssl, char *buf, int sz, void *ctx); +typedef int (WOLFSSL_CALL *CallbackIORecv)(WOLFSSL *ssl, char *buf, int sz, void *ctx); +typedef int (WOLFSSL_CALL *CallbackIOSend)(WOLFSSL *ssl, char *buf, int sz, void *ctx); WOLFSSL_API void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv); WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend); WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv); @@ -912,18 +925,29 @@ WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags); #if defined(__WATCOMC__) #if defined(__OS2__) || defined(__NT__) && \ (NTDDI_VERSION >= NTDDI_VISTA) - #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) + #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) #else - #define XINET_PTON(a,b,c) *(unsigned *)(c) = inet_addr((b)) + #define XINET_PTON(a,b,c) *(unsigned *)(c) = inet_addr((b)) #endif #elif defined(USE_WINDOWS_API) /* Windows-friendly definition */ - #if defined(__MINGW64__) && !defined(UNICODE) - #define XINET_PTON(a,b,c) InetPton((a),(b),(c)) + #if defined(UNICODE) + /* Use Win API Pointer to a constant wide-character string */ + #define XINET_PTON(a,b,c) InetPton((a),(PCWSTR)(b),(c)) + #elif defined(__MINGW64__) && !defined(UNICODE) + #define XINET_PTON(a,b,c) InetPton((a),(b),(c)) + #elif defined(PocketPC) + #define XINET_PTON(a,b,c) InetPton((a),(PCSTR)(b),(c)) #else - #define XINET_PTON(a,b,c) InetPton((a),(PCWSTR)(b),(c)) + #if (defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(_WIN32_WCE) + /* Visual Studio 10.0 (aka VS 2010) and newer, or CE use wide chars */ + #define XINET_PTON(a,b,c) InetPton((a),(PCWSTR)(b),(c)) + #else + /* otherwise assume byte chars */ + #define XINET_PTON(a,b,c) InetPton((a),(PCSTR)(b),(c)) + #endif #endif #else - #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) + #define XINET_PTON(a,b,c) inet_pton((a),(b),(c)) #endif #endif diff --git a/wrapper/CSharp/.editorconfig b/wrapper/CSharp/.editorconfig new file mode 100644 index 0000000000..ed72e0d999 --- /dev/null +++ b/wrapper/CSharp/.editorconfig @@ -0,0 +1,90 @@ +# Top-level EditorConfig file +root = true + +# C code: use LF +[*.c] +end_of_line = lf + +[*.h] +end_of_line = lf + +# C# code: use CRLF +[*.cs] +end_of_line = crlf + +csharp_indent_labels = one_less_than_current +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent + +[*.{cs,vb}] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_object_initializer = true:suggestion +dotnet_style_collection_initializer = true:suggestion + diff --git a/wrapper/CSharp/README.md b/wrapper/CSharp/README.md index 537e6cc9b4..4c508b202c 100644 --- a/wrapper/CSharp/README.md +++ b/wrapper/CSharp/README.md @@ -25,9 +25,92 @@ project directly. To successfully run and build the solution on Windows Visual Studio you will need to open a new solution `wolfSSL_CSharp.sln` located in `wrapper\CSharp\wolfSSL_CSharp.sln`. +The default `user_settings.h` is part of the Additional Include Directories, typically in `[WOLFSSL_ROOT]/wrapper/CSharp` + +``` +AdditionalIncludeDirectories="./;./wrapper/CSharp" +``` + + +See also the alternative sample Windows `user_settings.h` in `[WOLFSSL_ROOT]/IDE/WIN`: + +``` +AdditionalIncludeDirectories="./;./IDE/WIN" +``` + + Select the CPU type, configuration, and target file. select `Build` and either `Rebuild Solution` or `Build Solution`. +The `wolfssl` project will typically need the `DLL_Debug` or `DLL_Release` configuration with `x64` platform. + + +Check that the proper preprocessor definitions are included: `BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS` + +Syntax for project file: +``` +PreprocessorDefinitions="BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS" +``` +Some older versions of Visual Studio will require manually setting the Configure Type to create a DLL file: + +``` +Configuration Properties - General + +- Configuration Type: change from Static Library (.lib) - Dynamic Library (.dll) +``` + +For errors such as these: + +``` +error LNK2019: unresolved external symbol __imp__inet_pton@12 ... +error LNK2019: unresolved external symbol __imp__htons@4 ... +error LNK2019: unresolved external symbol __imp__recv@16 ... +``` + +Add `Ws2_32.lib` to Configuration Properties - Linker - ( Input || Additional Dependency) + +Note the `AnyCPU` Platform may not work with C libraries compiled to a specific architecture. +An error like this will likely be encountered: + +``` +System.DllNotFoundException + HResult=0x80131524 + Message=Unable to load DLL 'wolfssl.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) + Source=wolfSSL_CSharp + StackTrace: + at wolfSSL.CSharp.wolfssl.wolfSSL_SetLoggingCb(loggingCb vc) + at wolfSSL.CSharp.wolfssl.SetLogging(loggingCb input) in C:\workspace\wolfssl\wrapper\CSharp\wolfSSL_CSharp\wolfSSL.cs:line 2716 + at wolfSSL_TLS_Client.Main(String[] args) in C:\workspace\wolfssl\wrapper\CSharp\wolfSSL-TLS-Client\wolfSSL-TLS-Client.cs:line 151 +``` + +There's a separate `wolfSSL_CSharp-Clients.sln` solution file to allow concurrent client +applications in Visual Studio, with server running in `wolfSSL_CSharp.sln`. + +Be sure to right-click and "Set as Startup Project" for whichever sample is being used. + +If you see this error: + +``` + 'pwsh.exe' is not recognized as an internal or external command, + operable program or batch file. +``` + +Run PowerShell manually from Windows Start Icon. Output should look something like this: + +``` +Windows PowerShell +Copyright (C) Microsoft Corporation. All rights reserved. + +Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows + +Loading personal and system profiles took 1026ms. +``` +## WindowsCE and Other Pocket PC Configurations + +The `WindowsCE` should be defined in each project pre-processor declarations as needed. + +Also can be manually defined in the `user_settings.h` when building the native C `wolfssl.dll`. + ## Linux (Ubuntu) using mono Prerequisites for linux: diff --git a/wrapper/CSharp/include.am b/wrapper/CSharp/include.am index ecd70d015e..38b14e9f90 100644 --- a/wrapper/CSharp/include.am +++ b/wrapper/CSharp/include.am @@ -1,4 +1,5 @@ # wolfSSL CSharp wrapper files +EXTRA_DIST+= wrapper/CSharp/.editorconfig EXTRA_DIST+= wrapper/CSharp/README.md EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-PSK-Server/App.config EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-PSK-Server/Properties/AssemblyInfo.cs @@ -26,6 +27,7 @@ EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/Properties/AssemblyInfo. EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.csproj EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp.sln +EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp-Clients.sln EXTRA_DIST+= wrapper/CSharp/user_settings.h EXTRA_DIST+= wrapper/CSharp/wolfssl.vcxproj EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs diff --git a/wrapper/CSharp/user_settings.h b/wrapper/CSharp/user_settings.h index 21a72a69b9..305c648348 100644 --- a/wrapper/CSharp/user_settings.h +++ b/wrapper/CSharp/user_settings.h @@ -24,6 +24,19 @@ #ifndef _WIN_CSHARP_USER_SETTINGS_H_ #define _WIN_CSHARP_USER_SETTINGS_H_ +#define WOLFSSL_USER_SETTINGS_TAG "wolfssl v5.8.0 for C# Wrapper v1.0" + +#ifdef WindowsCE + #define NO_WOLFSSL_DIR + #define WOLFSSL_NO_ATOMICS + #define WC_NO_ASYNC_THREADING + #define USE_WINDOWS_API + #define WOLFSSL_SMALL_STACK + #define MAX_SUPPORTED_THREADS 1024 + #define MAX_SUPPORTED_PRIV_KEYS 1024 + #define MAX_CONFIGURED_THREAD 512 +#endif + /* Features */ #define NO_OLD_TLS #define WOLFSSL_TLS13 diff --git a/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs b/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs index b9a1be3519..c051f7985e 100644 --- a/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs +++ b/wrapper/CSharp/wolfCrypt-Test/wolfCrypt-Test.cs @@ -854,9 +854,9 @@ private static void hash_test(uint hashType) } } /* END hash_test */ - public static void standard_log(int lvl, StringBuilder msg) - { - Console.WriteLine(msg); + public static void standard_log(int lvl, IntPtr msg) { + string str = Marshal.PtrToStringAnsi(msg); + Console.WriteLine(str); } public static void Main(string[] args) @@ -868,7 +868,7 @@ public static void Main(string[] args) wolfcrypt.Init(); /* setup logging to stdout */ - wolfcrypt.SetLogging(standard_log); + wolfssl.SetLogging(standard_log); random_test(); diff --git a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs index 1b3d184297..ad0fb353a1 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs @@ -80,7 +80,7 @@ public static void Main(string[] args) /* These paths should be changed according to use */ string fileCert = wolfssl.setPath("server-cert.pem"); string fileKey = wolfssl.setPath("server-key.pem"); - StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")); + string dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")).ToString(); if (fileCert == "" || fileKey == "" || dhparam.Length == 0) { Console.WriteLine("Platform not supported"); diff --git a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs index 5415b09dc4..0040c2896f 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs @@ -38,9 +38,9 @@ public class wolfSSL_DTLS_Server /// /// level of log /// message to log - public static void standard_log(int lvl, StringBuilder msg) - { - Console.WriteLine(msg); + public static void standard_log(int lvl, IntPtr msg) { + string str = Marshal.PtrToStringAnsi(msg); + Console.WriteLine(str); } @@ -60,7 +60,7 @@ public static void Main(string[] args) /* These paths should be changed for use */ string fileCert = wolfssl.setPath("server-cert.pem"); string fileKey = wolfssl.setPath(@"server-key.pem"); - StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")); + string dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")).ToString(); if (fileCert == "" || fileKey == "" || dhparam.Length == 0) { Console.WriteLine("Platform not supported"); diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs index 15b8d93779..e839fd5cbb 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs @@ -32,5 +32,4 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] + diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs index 78150a5aae..ba3df0607f 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs @@ -19,27 +19,76 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + +// Optionally set explicit cipher, see CIPHER_SUITE and wolfssl.CTX_set_cipher_list() +// #define USE_SPECIFIED_CIPHER + using System; -using System.Runtime.InteropServices; -using System.Text; using System.IO; -using System.Net; using System.Net.Sockets; +using System.Text; +using wolfSSL; using wolfSSL.CSharp; public class wolfSSL_TLS_Client { + // Sample listening server: + // See https://github.com/wolfSSL/wolfssl/tree/master/examples/server + // + // Examples disable client cert check with `-d`: + // ./examples/server/server -d -p 11111 -c ./certs/server-cert.pem -k ./certs/server-key.pem + // ./examples/server/server -d -p 12345 + // + // Ensure the -p [port] for client matches SERVER_PORT value here: + // + public static string SERVER_NAME = "192.168.142.146"; /* or IP address: "192.168.1.73 */ + public static int SERVER_PORT = 11111; + private static int byte_ct = 0; /* How many byte sent / received */ + + // public static string CIPHER_SUITE = "DHE-RSA-AES256-GCM-SHA384"; /* TLS 1.2 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 */ + public static string CIPHER_SUITE = "TLS13-AES256-GCM-SHA384"; + + public static void standard_log(int lvl, string msg) { + Console.WriteLine(msg); + } + /// - /// Example of a logging function + /// Show error code and level for either last transmit or receive history parameter /// - /// level of log - /// message to log - public static void standard_log(int lvl, StringBuilder msg) + /// + /// + private static void show_alert_history_code(wolfSSL.WOLFSSL_ALERT h, string m) { - Console.WriteLine(msg); + /* VS initializes .code and .level to zero; wolfSSL sets to -1 until there's a valid value. */ + if ((h.code > 0) || (h.level > 0)) { + Console.WriteLine(m + " code: " + h.code.ToString()); + Console.WriteLine(m + " level: " + h.level.ToString()); + } } + /// + /// Show alert history for both transmit and receive + /// + /// + private static void show_alert_history(IntPtr ssl) + { + WOLFSSL_ALERT_HISTORY myHistory = new wolfSSL.WOLFSSL_ALERT_HISTORY(); + int ret = 0; + ret = wolfssl.get_alert_history(ssl, ref myHistory); + if (ret == wolfssl.SUCCESS) { + show_alert_history_code(myHistory.last_tx, "myHistory last_tx"); + show_alert_history_code(myHistory.last_rx, "myHistory last_rx"); + } + else { + Console.WriteLine("Failed: call to get_alert_history failed with error " + ret.ToString()); + } + } + /// + /// Cleanup both ssl and ctx, releasing memory as needed. + /// + /// + /// private static void clean(IntPtr ssl, IntPtr ctx) { wolfssl.free(ssl); @@ -86,6 +135,34 @@ private static int haveSNI(string[] args) return -1; } + /// + /// Checks environment, attempts to manually load wolfssl.dll if not found in current directory. + /// + /// True if wolfssl.dll was found + private static bool CheckEnvironment() { + bool ret = false; + /* Ensure the DLL is loaded properly */ +#if WindowsCE + string exePath = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; + Console.WriteLine("Executable Path: " + exePath); +#else + Console.WriteLine("Current Directory: " + Environment.CurrentDirectory); +#endif + if (File.Exists("wolfssl.dll")) { + string fullPath = Path.GetFullPath("wolfssl.dll"); + Console.WriteLine("Found wolfssl.dll " + fullPath); + ret = true; + } + else { + /* Consider copying to working directory, or adding to path */ + Console.WriteLine("ERROR: Could not find wolfssl.dll; trying explicit load..."); + ret = wolfssl.LoadDLL(true); /* look in default directory, otherwise pass explicit path */ + } + wolfssl.SetVerbosity(true); + wolfcrypt.SelfCheck(); + return ret; + } + public static void Main(string[] args) { IntPtr ctx; @@ -93,9 +170,14 @@ public static void Main(string[] args) Socket tcp; IntPtr sniHostName; + /* Optional check of environment */ + CheckEnvironment(); + /* These paths should be changed for use */ string caCert = wolfssl.setPath("ca-cert.pem"); - StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")); + string clientCert = wolfssl.setPath("client-cert.pem"); + string clientKey = wolfssl.setPath("client-key.pem"); + string dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")).ToString(); if (caCert == "" || dhparam.Length == 0) { Console.WriteLine("Platform not supported."); @@ -103,22 +185,43 @@ public static void Main(string[] args) } StringBuilder buff = new StringBuilder(1024); - StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); + StringBuilder tx_msg = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); - //example of function used for setting logging + /* example of function used for setting logging */ wolfssl.SetLogging(standard_log); + /* optionally clear logging callback */ + /* wolfssl.ClearLogging(); */ + wolfssl.Init(); Console.WriteLine("Calling ctx Init from wolfSSL"); - ctx = wolfssl.CTX_new(wolfssl.usev23_client()); + + /* Use any version of TLS */ + // ctx = wolfssl.CTX_new(wolfssl.usev23_client()); + + /* Only TLS 1.3 */ + ctx = wolfssl.CTX_new(wolfssl.useTLSv1_3_client()); if (ctx == IntPtr.Zero) { Console.WriteLine("Error in creating ctx structure"); return; } - Console.WriteLine("Finished init of ctx .... now load in CA"); + foreach (TLSVersion v in wolfssl.TLSVersions) { + int result = wolfssl.CTX_SetMinVersion(ctx, v.Value); + Console.Write("MinVersion set to " + v.Value.ToString() + " " + v.Name ); + if (result == wolfssl.SUCCESS) { + Console.WriteLine(" OK"); + } + else { + Console.WriteLine(" Not supported for this build configuration"); + } + } + + long opts = wolfssl.CTX_get_options(ctx); + + Console.WriteLine("Finished init of ctx .... now load in CA"); if (!File.Exists(caCert)) { @@ -133,6 +236,19 @@ public static void Main(string[] args) return; } + if (wolfssl.CTX_use_certificate_file(ctx, clientCert, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS) { + Console.WriteLine("Error loading Client cert: " + clientCert); + wolfssl.CTX_free(ctx); + return; + } + + if (wolfssl.CTX_use_PrivateKey_file(ctx, clientKey, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS) { + Console.WriteLine("Error loading Client key: " + clientKey); + wolfssl.CTX_free(ctx); + return; + } + + if (wolfssl.CTX_load_verify_locations(ctx, caCert, null) != wolfssl.SUCCESS) { @@ -145,7 +261,7 @@ public static void Main(string[] args) if (sniArg >= 0) { string sniHostNameString = args[sniArg].Trim(); - sniHostName = Marshal.StringToHGlobalAnsi(sniHostNameString); + sniHostName = wolfssl.StringToAnsiPtr(sniHostNameString); ushort size = (ushort)sniHostNameString.Length; @@ -159,12 +275,12 @@ public static void Main(string[] args) StringBuilder ciphers = new StringBuilder(new String(' ', 4096)); wolfssl.get_ciphers(ciphers, 4096); - Console.WriteLine("Ciphers : " + ciphers.ToString()); + Console.WriteLine("Ciphers:\r\n" + ciphers.ToString().Replace(":", "\r\n")); /* Uncomment Section to enable specific cipher suite */ -#if false - ciphers = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256"); - if (wolfssl.CTX_set_cipher_list(ctx, ciphers) != wolfssl.SUCCESS) +#if USE_SPECIFIED_CIPHER + ciphers = new StringBuilder(CIPHER_SUITE); + if (wolfssl.CTX_set_cipher_list(ctx, ciphers.ToString()) != wolfssl.SUCCESS) { Console.WriteLine("ERROR CTX_set_cipher_list()"); wolfssl.CTX_free(ctx); @@ -188,7 +304,19 @@ public static void Main(string[] args) ProtocolType.Tcp); try { - tcp.Connect("localhost", 11111); +#if WindowsCE || PocketPC + IPAddress[] addresses = Dns.GetHostEntry(SERVER_NAME).AddressList; + foreach (IPAddress addr in addresses) + { + if (addr.AddressFamily == AddressFamily.InterNetwork) + { + tcp.Connect(new IPEndPoint(addr, SERVER_PORT)); + break; /* use only one connection */ + } + } +#else + tcp.Connect(SERVER_NAME, SERVER_PORT); +#endif } catch (Exception e) { @@ -213,7 +341,7 @@ public static void Main(string[] args) return; } - Console.WriteLine("Connection made wolfSSL_connect "); + Console.WriteLine("Created new ssl object"); if (wolfssl.set_fd(ssl, tcp) != wolfssl.SUCCESS) { /* get and print out the error */ @@ -224,11 +352,17 @@ public static void Main(string[] args) } wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM); - + opts = wolfssl.CTX_get_options(ctx); + opts = wolfssl.CTX_set_options(ctx, 1); + opts = wolfssl.CTX_clear_options(ctx, 1); if (wolfssl.connect(ssl) != wolfssl.SUCCESS) { + Console.WriteLine("Connection fsailed wolfssl.connect(ssl)"); + /* get and print out the error */ Console.WriteLine(wolfssl.get_error(ssl)); + show_alert_history(ssl); + tcp.Close(); clean(ssl, ctx); return; @@ -238,25 +372,34 @@ public static void Main(string[] args) Console.WriteLine("SSL version is " + wolfssl.get_version(ssl)); Console.WriteLine("SSL cipher suite is " + wolfssl.get_current_cipher(ssl)); - - if (wolfssl.write(ssl, reply, reply.Length) != reply.Length) + Console.WriteLine("Writing message to server: " + tx_msg); + byte_ct = wolfssl.write(ssl, tx_msg, tx_msg.Length); + if (byte_ct != tx_msg.Length) { Console.WriteLine("Error in write"); + Console.WriteLine("Bytes sent: " + byte_ct.ToString()); tcp.Close(); clean(ssl, ctx); return; } + Console.WriteLine("Sent " + byte_ct.ToString() + " bytes to server!"); + Console.WriteLine("Reading server response..."); + byte_ct = wolfssl.read(ssl, buff, 1023); /* read and print out the message then reply */ - if (wolfssl.read(ssl, buff, 1023) < 0) + if (byte_ct < 0) { Console.WriteLine("Error in read"); tcp.Close(); clean(ssl, ctx); return; } + Console.WriteLine("Read " + byte_ct.ToString() + " byte reply from server!"); Console.WriteLine(buff); + /* Optional code & level history */ + show_alert_history(ssl); + wolfssl.shutdown(ssl); tcp.Close(); clean(ssl, ctx); diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj index 7afffb9d4e..665aa0971d 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj +++ b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj @@ -121,4 +121,4 @@ --> - + \ No newline at end of file diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs b/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs index f2de70216a..890fbb724c 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.cs @@ -20,23 +20,16 @@ */ - - using System; using System.Runtime.InteropServices; using System.Text; -using System.Threading; using System.IO; -using System.Net; using System.Net.Sockets; using wolfSSL.CSharp; - public class wolfSSL_TLS_PSK_Client { - - /// /// Example of a PSK function call back /// @@ -49,6 +42,7 @@ public class wolfSSL_TLS_PSK_Client /// size of key set public static uint my_psk_client_cb(IntPtr ssl, string hint, IntPtr identity, uint id_max, IntPtr key, uint max_key) { + Console.WriteLine("Hello my_psk_client_cb!"); /* C# client */ byte[] id = { 67, 35, 32, 99, 108, 105, 101, 110, 116 }; if (id_max < 9) @@ -79,14 +73,18 @@ public static void Main(string[] args) IntPtr ctx; IntPtr ssl; Socket tcp; + StringBuilder dhparam; wolfssl.psk_client_delegate psk_cb = new wolfssl.psk_client_delegate(my_psk_client_cb); - StringBuilder dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")); + Console.WriteLine("Current path: " + Environment.CurrentDirectory); + dhparam = new StringBuilder(wolfssl.setPath("dh2048.pem")); + dhparam = new StringBuilder(Path.GetFullPath(dhparam.ToString())); if (dhparam.Length == 0) { Console.WriteLine("Platform not supported"); return; } + Console.WriteLine("Using cert: " + dhparam.ToString()); StringBuilder buff = new StringBuilder(1024); StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# client psk wrapper"); @@ -162,12 +160,13 @@ public static void Main(string[] args) } if (!File.Exists(dhparam.ToString())) { - Console.WriteLine("Could not find dh file"); + Console.WriteLine("Current path: " + Environment.CurrentDirectory); + Console.WriteLine("Could not find dh file: " + dhparam); wolfssl.CTX_free(ctx); return; } - wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM); + wolfssl.SetTmpDH_file(ssl, dhparam.ToString(), wolfssl.SSL_FILETYPE_PEM); if (wolfssl.connect(ssl) != wolfssl.SUCCESS) { diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.csproj b/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.csproj index 5c3e77e470..707f5f701d 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.csproj +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Client/wolfSSL-TLS-PSK-Client.csproj @@ -112,4 +112,4 @@ --> - + \ No newline at end of file diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs index 31e6a9869f..fce4d55baf 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs @@ -20,8 +20,6 @@ */ - - using System; using System.Runtime.InteropServices; using System.Text; @@ -35,7 +33,7 @@ public class wolfSSL_TLS_PSK_Server { - + static int SERVER_PORT = 11111; /// /// Example of a PSK function call back @@ -160,7 +158,7 @@ public static void Main(string[] args) /* set up TCP socket */ IPAddress ip = IPAddress.Parse("0.0.0.0"); //bind to any - TcpListener tcp = new TcpListener(ip, 11111); + TcpListener tcp = new TcpListener(ip, SERVER_PORT); tcp.Start(); Console.WriteLine("Started TCP and waiting for a connection"); @@ -184,7 +182,7 @@ public static void Main(string[] args) return; } - wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM); + wolfssl.SetTmpDH_file(ssl, dhparam.ToString(), wolfssl.SSL_FILETYPE_PEM); if (wolfssl.accept(ssl) != wolfssl.SUCCESS) { diff --git a/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs b/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs index b06af4ac62..e58fdd6a43 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs @@ -27,16 +27,16 @@ using System.Net.Sockets; using wolfSSL.CSharp; -public class wolfSSL_TLS_CSHarp +public class wolfSSL_TLS_CSharp { /// /// Example of a logging function /// /// level of log /// message to log - public static void standard_log(int lvl, StringBuilder msg) - { - Console.WriteLine(msg); + public static void standard_log(int lvl, IntPtr msg) { + string str = Marshal.PtrToStringAnsi(msg); + Console.WriteLine(str); } @@ -87,6 +87,18 @@ public static void Main(string[] args) Socket fd; IntPtr arg_sni; + Console.WriteLine(Environment.CurrentDirectory); + wolfssl.SetVerbosity(true); + if (File.Exists("wolfssl.dll")) { + Console.WriteLine("Found wolfssl.dll"); + } + else { + /* Consider copying to working directory, or adding to path */ + Console.WriteLine("ERROR: Could not find wolfssl.dll; trying explicit load..."); + wolfssl.LoadDLL(""); + } + + /* These paths should be changed for use */ string fileCert = wolfssl.setPath("server-cert.pem"); string fileKey = wolfssl.setPath("server-key.pem"); @@ -164,7 +176,7 @@ public static void Main(string[] args) return; } - if (haveSNI(args)) + if (haveSNI(args)) { // Allocating memory and setting SNI arg int test_value = 32; @@ -191,7 +203,7 @@ public static void Main(string[] args) return; } - if (wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS) + if (wolfssl.SetTmpDH_file(ssl, dhparam.ToString(), wolfssl.SSL_FILETYPE_PEM) != wolfssl.SUCCESS) { Console.WriteLine("Error in setting dh2048Pem"); Console.WriteLine(wolfssl.get_error(ssl)); @@ -258,8 +270,8 @@ public static void Main(string[] args) 0x0a, 0x05, 0x01, 0x04, 0x01, 0x02, 0x01, 0x04, 0x03, 0x02, 0x03 }; - int ret = wolfssl.SNI_GetFromBuffer(buffer, 1024, 0, result, inOutSz); - + int ret = wolfssl.SNI_GetFromBuffer(buffer, 1024, 0, result, inOutSz); + if (ret != wolfssl.SUCCESS) { Console.WriteLine("Error on reading SNI from buffer, ret value = " + ret); tcp.Stop(); diff --git a/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs b/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs index 9c9d978458..424535053d 100644 --- a/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs +++ b/wrapper/CSharp/wolfSSL-TLS-ServerThreaded/wolfSSL-TLS-ServerThreaded.cs @@ -106,9 +106,9 @@ public class wolfSSL_TLS_ServerThreaded /// /// level of log /// message to log - public static void standard_log(int lvl, StringBuilder msg) - { - Console.WriteLine(msg); + public static void standard_log(int lvl, IntPtr msg) { + string str = Marshal.PtrToStringAnsi(msg); + Console.WriteLine(str); } public static void Main(string[] args) @@ -171,7 +171,7 @@ public static void Main(string[] args) short minDhKey = 128; wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey); - wolfssl.CTX_SetTmpDH_file(ctx, dhparam, wolfssl.SSL_FILETYPE_PEM); + wolfssl.CTX_SetTmpDH_file(ctx, dhparam.ToString(), wolfssl.SSL_FILETYPE_PEM); /* set up TCP socket */ IPAddress ip = IPAddress.Parse("0.0.0.0"); /* bind to any */ diff --git a/wrapper/CSharp/wolfSSL_CSharp-Clients.sln b/wrapper/CSharp/wolfSSL_CSharp-Clients.sln new file mode 100644 index 0000000000..214ab68e5c --- /dev/null +++ b/wrapper/CSharp/wolfSSL_CSharp-Clients.sln @@ -0,0 +1,71 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35728.132 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-TLS-PSK-Client", "wolfSSL-TLS-PSK-Client\wolfSSL-TLS-PSK-Client.csproj", "{4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL_CSharp", "wolfSSL_CSharp\wolfSSL_CSharp.csproj", "{52609808-0418-46D3-8E17-141927A1A39A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfssl", "wolfssl.vcxproj", "{67932048-D67E-4C86-B55F-90899B9BDA64}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-DTLS-PSK-Client", "wolfSSL-DTLS-PSK-Client\wolfSSL-DTLS-PSK-Client.csproj", "{D7D1817F-DEBE-4A47-A34F-33A7D3B46204}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-TLS-Client", "wolfSSL-TLS-Client\wolfSSL-TLS-Client.csproj", "{B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Debug|x64.ActiveCfg = Debug|x64 + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Debug|x64.Build.0 = Debug|x64 + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Release|Any CPU.Build.0 = Release|Any CPU + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Release|x64.ActiveCfg = Release|x64 + {4F92ECF5-A1D8-4A13-AD0C-6571EB03C01C}.Release|x64.Build.0 = Release|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|x64.ActiveCfg = Debug|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|x64.Build.0 = Debug|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Release|Any CPU.Build.0 = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Release|x64.ActiveCfg = Release|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Release|x64.Build.0 = Release|x64 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Debug|Any CPU.ActiveCfg = DLL Debug|Win32 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Debug|Any CPU.Build.0 = DLL Debug|Win32 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Debug|x64.ActiveCfg = DLL Debug|x64 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Debug|x64.Build.0 = DLL Debug|x64 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Release|Any CPU.ActiveCfg = Release|x64 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Release|Any CPU.Build.0 = Release|x64 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Release|x64.ActiveCfg = Release|x64 + {67932048-D67E-4C86-B55F-90899B9BDA64}.Release|x64.Build.0 = Release|x64 + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Debug|x64.ActiveCfg = Debug|x64 + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Debug|x64.Build.0 = Debug|x64 + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Release|Any CPU.Build.0 = Release|Any CPU + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Release|x64.ActiveCfg = Release|x64 + {D7D1817F-DEBE-4A47-A34F-33A7D3B46204}.Release|x64.Build.0 = Release|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|x64.ActiveCfg = Debug|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|x64.Build.0 = Debug|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Any CPU.Build.0 = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.ActiveCfg = Release|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1A5504FC-6BDF-4876-AECD-42A4546C6D69} + EndGlobalSection +EndGlobal diff --git a/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs index 0c110c0b9a..82be14f7c0 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -10,7 +10,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL.CSharp")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2025")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.0.0")] -[assembly: AssemblyFileVersion("1.1.0.0")] + + diff --git a/wrapper/CSharp/wolfSSL_CSharp/X509.cs b/wrapper/CSharp/wolfSSL_CSharp/X509.cs index 1fa5808f6b..8925940c54 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/X509.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/X509.cs @@ -1,4 +1,4 @@ -/* X509.cs +/* X509.cs * * Copyright (C) 2006-2025 wolfSSL Inc. * @@ -19,10 +19,18 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + +/* Define our own WindowsCE as needed. */ +#if _WIN32_WCE || WINCE || PocketPC + /* WindowsCE should have been defined in the Project and user_settings.h */ + #if !WindowsCE + #define WindowsCE + #endif +#endif + + using System; using System.Runtime.InteropServices; -using System.Text; -using System.Threading; namespace wolfSSL.CSharp { diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs index 4f58139c25..286fb55e00 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfCrypt.cs @@ -19,17 +19,101 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ + +/* Define our own WindowsCE as needed. */ +#if _WIN32_WCE || WINCE || PocketPC + /* WindowsCE should have been defined in the Project and user_settings.h */ + #if !WindowsCE + #define WindowsCE + #endif +#endif + + using System; +using System.Reflection; using System.Runtime.InteropServices; -using System.Security.Cryptography; using System.Text; namespace wolfSSL.CSharp { public class wolfcrypt { + /* Ensure CPU architecture of all .cs projects matches wolfssl.dll + * + * For example: See the x64 wolfssl.dll file in + * [WOLFSSL_ROOT]\wrapper\CSharp\Debug\x64\wolfssl.dll + * not AnyCPU + * [WOLFSSL_ROOT]\wrapper\CSharp\DLL Debug\wolfssl.dll + * + * For DLL debugging, see: + * wolfSSL_user_settings_tag() in wolfssl library: ssl.h + * wolfSSL_dll_tag() in wolfssl library: wolfcrypt/logging.h + */ private const string wolfssl_dll = "wolfssl.dll"; + /******************************** + * Logging wolfSSL library + */ +#if WindowsCE + /* wolfSSL Version & DLL Tag (see settings.h) */ + [DllImport(wolfssl_dll)] + private extern static IntPtr wolfSSL_lib_version(); + [DllImport(wolfssl_dll)] + private extern static IntPtr wolfSSL_user_settings_tag(); + [DllImport(wolfssl_dll)] + private extern static IntPtr wolfSSL_dll_tag(); + + [DllImport(wolfssl_dll)] + private extern static IntPtr wolfSSL_ERR_reason_error_string(uint err); + [DllImport(wolfssl_dll)] + private extern static int wolfSSL_get_error(IntPtr ssl, int err); + /* No decorator needed for loggingCb, Note msg is String here, not StringBuilder */ + public delegate void loggingCb(int lvl, string msg); + /* No decorator needed for loggingCbEx */ + public delegate void loggingCbEx(int lvl, IntPtr msg); + [DllImport(wolfssl_dll)] + private extern static void wolfSSL_Debugging_ON(); + [DllImport(wolfssl_dll)] + private extern static void wolfSSL_Debugging_OFF(); + [DllImport(wolfssl_dll)] + private extern static int wolfSSL_SetLoggingCb(loggingCb vc); + + /* Internal field to store the original logging callback: string msg */ + private static loggingCb internal_log; +#else + [DllImport(wolfssl_dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] + private extern static IntPtr wolfSSL_lib_version(); + [DllImport(wolfssl_dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] + private extern static IntPtr wolfSSL_user_settings_tag(); + + [DllImport(wolfssl_dll, CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] + private extern static IntPtr wolfSSL_dll_tag(); + + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + private extern static IntPtr wolfSSL_ERR_reason_error_string(uint err); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_get_error(IntPtr ssl, int err); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void loggingCb(int lvl, StringBuilder msg); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void loggingCbExs(int lvl, string msg); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void loggingCbEx(int level, IntPtr msg); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static void wolfSSL_Debugging_ON(); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static void wolfSSL_Debugging_OFF(); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_SetLoggingCb(loggingCbEx vc); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_SetLoggingCb(loggingCbExs vc); + + /* Internal fields to store the non-CE logging callback; StringBuilder msg */ + private static loggingCbEx internal_log_ex = null; /* keep reference to prevent GC */ + private static loggingCbExs internal_log_exs = null; /* helper when using string loggingCb */ + private static loggingCbEx internal_bridge_cb = null; /* helper when using original loggingCb */ +#endif + /******************************** * Init wolfSSL library */ @@ -511,39 +595,12 @@ public class wolfcrypt #if WindowsCE [DllImport(wolfssl_dll)] private extern static IntPtr wc_GetErrorString(int error); - public delegate void loggingCb(int lvl, string msg); + /* No Windows CE decorator for logging call-back */ #else [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wc_GetErrorString(int error); - public delegate void loggingCb(int lvl, StringBuilder msg); -#endif - private static loggingCb internal_log; - - /// - /// Log a message to set logging function - /// - /// Level of log message - /// Message to log -#if WindowsCE - private static void log(int lvl, string msg) - { - /* if log is not set then print nothing */ - if (internal_log == null) - return; - internal_log(lvl, msg); - } -#else - private static void log(int lvl, string msg) - { - /* if log is not set then print nothing */ - if (internal_log == null) - return; - StringBuilder ptr = new StringBuilder(msg); - internal_log(lvl, ptr); - } #endif - /******************************** * Enum types from wolfSSL library */ @@ -594,6 +651,170 @@ private static void log(int lvl, string msg) /*********************************************************************** * Class Public Functions **********************************************************************/ + /// + /// Get wolfSSL Version text + /// + /// DLL Tag string from version.h + public static string LibVersion() { + string ret = ""; +#if WindowsCE + try { + ret = wolfssl.PtrToStringAnsi(wolfSSL_lib_version()); + } + catch (global::System.Exception ex) { + ret = ex.Message; + } +#else + try { + ret= Marshal.PtrToStringAnsi(wolfSSL_lib_version()); + } + catch (global::System.Exception ex) { + ret = ex.Message; + } +#endif + return ret; + } + + /// + /// Get wolfSSL Version text + /// + /// DLL Tag string from version.h + public static string UserSettingsTag() + { + string ret = ""; +#if WindowsCE + try { + ret = wolfssl.PtrToStringAnsi(wolfSSL_user_settings_tag()); + } + catch (global::System.Exception ex) { + ret = ex.Message; + } +#else + try + { + ret = Marshal.PtrToStringAnsi(wolfSSL_user_settings_tag()); + } + catch (global::System.Exception ex) + { + ret = ex.Message; + } +#endif + return ret; + } + + /// + /// Get the full text of DLL Tag + /// + /// DLL Tag string from settings.h + public static string DllTagFull() { + string ret = ""; +#if WindowsCE + try { + ret = wolfssl.PtrToStringAnsi(wolfSSL_dll_tag()); + } + catch (global::System.Exception ex) { + ret = ex.Message; + } +#else + try { + ret = Marshal.PtrToStringAnsi(wolfSSL_dll_tag()); + } + catch (global::System.Exception ex) { + ret = ex.Message; + } +#endif + return ret; + } + + /// + /// Get the partial text of DLL Tag, to be used for runtime checks. + /// + /// DLL Tag string from settings.h + public static string DllTag() { + string ret = DllTagFull(); + int i = -1; + + if (ret == null) { + ret = string.Empty; + } + else { + i = ret.IndexOf(';'); + if (i >= 0) { + ret = ret.Substring(0, i); + } + } + return ret; + } + + /// + /// Debugging tool to display various interesting DLL attributes. + /// + /// DLL Tag string from settings.h + public static bool SelfCheck() { + bool ret = false; + string this_DllTagFull = wolfcrypt.DllTagFull(); + string this_DllTag = wolfcrypt.DllTag(); /* excludes dynamic text after semicolon */ + string expected_DllTag = ""; + string this_LibVersion = wolfcrypt.LibVersion(); + string this_user_settings_tag = wolfcrypt.UserSettingsTag(); + + /* Ensure the compiled DLL is what we expect: wolfssl.dll, then alhpabretical order macros */ +#if WindowsCE && PocketPC + expected_DllTag = "wolfssl.dll PocketPC WindowsCE"; +#elif WindowsCE + expected_DllTag = "wolfssl.dll WindowsCE"; +#elif PocketPC + expected_DllTag = "wolfssl.dll PocketPC"; +#else + expected_DllTag = "wolfssl.dll"; +#endif + ret = (expected_DllTag == this_DllTag); + Console.WriteLine("user settings tag: " + this_user_settings_tag); + Console.WriteLine("WOLFSSL_VERSION: " + this_LibVersion); + Console.WriteLine("WOLFSSL_DLL_TAG: " + this_DllTagFull); + Console.WriteLine("DLL Tag Check: " + this_DllTag); + Console.WriteLine("Expected DLL_TAG: " + expected_DllTag); + + if (!ret) { + Console.WriteLine(""); + Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + Console.WriteLine("Warning: unexpected DLL Tag! Check wolfssl binary."); + Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + Console.WriteLine(""); + Console.WriteLine("App Info:"); + Console.WriteLine(" AppDomain.CurrentDomain.FriendlyName: " + AppDomain.CurrentDomain.FriendlyName); + + Console.WriteLine("\nEnvironment Info:"); + Console.WriteLine(" Environment.Version: " + Environment.Version); + Console.WriteLine(" OS Version: " + Environment.OSVersion); + Console.WriteLine(" Is 64-bit OS: " + (IntPtr.Size == 8).ToString()); + +#if WindowsCE + /* TODO: find equivalent Machine / User / Process values */ +#else + Console.WriteLine(" Machine Name: " + Environment.MachineName); + Console.WriteLine(" User Name: " + Environment.UserName); + #if _WIN64 + Console.WriteLine(" Is 64-bit Process: " + Environment.Is64BitProcess); + #endif +#endif + Console.WriteLine("\nAssembly Info:"); + Assembly asm = Assembly.GetExecutingAssembly(); + Console.WriteLine(" Full Name: " + asm.FullName); +#if _MSC_VER + Console.WriteLine("This _MSC_VER: " + _MSC_VER.tostring; +#else + Console.WriteLine("No _MSC_VER found"); +#endif + +#if _WIN32_WCE + Console.WriteLine("This _WIN32_WCE: " + _WIN32_WCE.tostring; +#else + Console.WriteLine("No _WIN32_WCE found"); +#endif + } + return ret; + } /// /// Initialize wolfCrypt library @@ -3185,22 +3406,10 @@ public enum hashType } /* END HASH */ - /*********************************************************************** * Logging / Other **********************************************************************/ - /// - /// Set the function to use for logging - /// - /// Function that conforms as to loggingCb - /// 0 on success - public static int SetLogging(loggingCb input) - { - internal_log = input; - return SUCCESS; - } - /// /// Get error string for wolfCrypt error codes /// @@ -3238,7 +3447,214 @@ public static bool ByteArrayVerify(byte[] array1, byte[] array2) } return true; } - } + + /// + /// Clean up old callbacks if previously assigned. + /// + private static int ClearLoggingCallbacks() { + /* Delegates are managed objects; nulling the reference allows GC to clean up. */ + int ret; +#if WindowsCE + internal_log = null; + ret = wolfSSL_SetLoggingCb((loggingCb)null); /* call wolfSSL callback cleanup, string param */ +#else + internal_log_ex = null; + internal_log_exs = null; + internal_bridge_cb = null; + ret = wolfSSL_SetLoggingCb((loggingCbEx)null); /* call wolfSSL callback cleanup */ +#endif + return ret; + } + + /// + /// Public clear callback. + /// + /// 1 on success + public static int ClearLogging() { + /* Note that for non-CE there are two possible types: loggingCb amd loggingCbEx */ + return SetLogging((loggingCb)null); + } + + /* SetLogging() and log() implementations are different for CE vs non-CE: String msg vs StringBuilder msg */ +#if WindowsCE + /// + /// Set the function to use for logging on Windows CE + /// + /// Function that conforms as to loggingCb String msg + /// 1 on success + public static int SetLogging(loggingCb input) + { + int ret = 1; + /* If SetLogging is called with a new logging function, clean up the old one first: */ + if (internal_log != null) + { + ret = ClearLoggingCallbacks(); + } + + /* Exit if there's no new cb function */ + if (input == null) { + return ret; + } + + /* Set our new callback logging function */ + internal_log = input; + + try + { + wolfSSL_SetLoggingCb(input); + } + catch (Exception ex) + { + if (ex.Message.StartsWith("Unable to load DLL 'wolfssl.dll': The specified module could not be found.")) + { + Console.WriteLine("Failed to load wolfssl.dll, try manually copying to Base Directory."); + } + + throw new Exception(ex.Message); + } + + return SUCCESS; + } + + /// + /// Log a message to set logging function + /// + /// Level of log message + /// Message to log + public static void log(int lvl, string msg) + { + /* if log is not set then print nothing */ + if (internal_log == null) { + return; + } + internal_log(lvl, msg); + } +#else + /// + /// Set the function to use for logging + /// + /// Function that conforms as to loggingCb StringBuilder msg + /// 1 on success + public static int SetLogging(loggingCb input) { + /* If SetLogging was previously called, clean it up and exit if there's no new cb function */ + if (input == null) { + ClearLoggingCallbacks(); + return SetLogging((loggingCbEx)null); + } + + /* If SetLogging is called with a new logging function, clean up the old one first: */ + if (internal_bridge_cb != null) { + ClearLoggingCallbacks(); + } + + /* Build a bridge that routes through internal_log_ex logic */ + internal_bridge_cb = new loggingCbEx(delegate (int lvl, IntPtr msgPtr) + { + string msg; + + if (msgPtr == IntPtr.Zero) { + msg = ""; + } + else { + int len = 0; + while (Marshal.ReadByte(msgPtr, len) != 0) { + len++; + } + + byte[] buffer = new byte[len]; + Marshal.Copy(msgPtr, buffer, 0, len); + msg = Encoding.ASCII.GetString(buffer, 0, buffer.Length); + } + + StringBuilder sb = new StringBuilder(); + sb.Append(msg); + + input(lvl, sb); + }); + + /* return the result of SetLogging(loggingCbEx input) */ + return SetLogging(internal_bridge_cb); + } + + /// + /// Set the function to use for logging + /// + /// Function that conforms as to loggingCb for preferred IntPtr msg + /// 1 on success + public static int SetLogging(loggingCbEx input) { + if (input == null) { + ClearLoggingCallbacks(); + return wolfSSL_SetLoggingCb((loggingCbEx)null); + } + + /* If SetLogging is called with a new logging function, clean up the old one first: */ + if (internal_log_ex != null) { + ClearLoggingCallbacks(); + } + + internal_log_ex = input; + + /* Return the result of the native call to wolfSSL */ + return wolfSSL_SetLoggingCb(input); + } + + /// + /// Set the function to use for logging + /// + /// Function that conforms as to loggingCb for preferred string msg + /// 1 on success + public static int SetLogging(loggingCbExs input) + { + if (input == null) + { + ClearLoggingCallbacks(); + return wolfSSL_SetLoggingCb((loggingCbEx)null); + } + + /* If SetLogging is called with a new logging function, clean up the old one first: */ + if (internal_log_exs != null) + { + ClearLoggingCallbacks(); + } + + internal_log_exs = input; + + return wolfSSL_SetLoggingCb(input); + } + + /// + /// Log a message to set logging function + /// + /// Level of log message + /// Message to log + public static void log(int lvl, string msg) { + IntPtr ptr = wolfssl.StringToAnsiPtr(msg); + try { + /* if log is not set then print nothing; has SetLogging been called? */ + if (internal_log_ex != null) { + internal_log_ex(lvl, ptr); + } + else if (internal_log_exs != null) { + internal_log_exs(lvl, msg); + } + } + finally { + Marshal.FreeHGlobal(ptr); + } + } + + /// + /// Log a message to set logging function, StringBuilder msg + /// + /// + /// + public static void log(int lvl, StringBuilder msg) + { + log(lvl, msg.ToString()); + } +#endif + + } /* public class wolfcrypt */ } diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs index 0ee293f2f5..4fb1b8241b 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs @@ -1,3 +1,5 @@ +// TODO check _MSC_VER_LT_1900 + /* wolfSSL.cs * * Copyright (C) 2006-2025 wolfSSL Inc. @@ -20,27 +22,273 @@ */ +/* Define our own WindowsCE as needed. */ +#if _WIN32_WCE || WINCE || PocketPC + /* WindowsCE should have been defined in the Project and user_settings.h */ + #if !WindowsCE + #define WindowsCE + #endif +#endif + +/* Although PocketPC is considered a CE device, it does not require special string treatment */ +#if WindowsCE && !PocketPC + /* See WideCharToMultiByte: + * Convert Unicode/Wide Char (16-bit) to MBCS (8-bit single/multi byte) character set */ + #define FORCE_MULTIBYTE_STRING +#endif + + using System; using System.Runtime.InteropServices; using System.Text; -using System.Threading; using System.IO; using System.Net; using System.Net.Sockets; +/* the mixed-case wolfSSL namespace contains some global types, used by lowercase wolfssl class */ +namespace wolfSSL +{ + /* Some global structs for use with wolfSSL_get_alert_history */ + + /// + /// wolfSSL_get_alert_history struct + /// + [StructLayout(LayoutKind.Sequential)] + public struct WOLFSSL_ALERT + { + public int code; + public int level; + } + + /// + /// wolfSSL_get_alert_history struct + /// + [StructLayout(LayoutKind.Sequential)] + public struct WOLFSSL_ALERT_HISTORY + { + public WOLFSSL_ALERT last_rx; + public WOLFSSL_ALERT last_tx; + } + + /// + /// Helper to convert TLS enum values to text descriptions + /// + public struct TLSVersion + { + /* No StructLayout needed as this helper is not passed to wolfSSL unmanaged code */ + public int Value; + public string Name; + + public TLSVersion(int value, string name) { + Value = value; + Name = name; + } + } +} /* namespace wolfSSL */ + + namespace wolfSSL.CSharp { + using wolfSSL; /* some global structs */ + public class wolfssl { private const string wolfssl_dll = "wolfssl.dll"; /* wait for 6 seconds default on TCP socket state poll if timeout not set */ private const int WC_WAIT = 6000000; + private static bool verbose = false; + + public static void SetVerbosity(bool b) { + verbose = b; + } + + /// + /// Use the SetDllDirectory from Windows kernel32.dll to set DLL location of wolfSSL + /// + /// + /// + [DllImport("kernel32.dll", SetLastError = true)] + static extern bool SetDllDirectory(string lpPathName); + + /// + /// Load DLL, assumeing the current directory. Otherwise pass path as parameter. + /// + /// + /// True if wolfssl.dll found + public static bool LoadDLL() { + return LoadDLL(""); + } + + /// + /// Load DLL and specify verbose mode, assuming the current directory. Otherwise pass path as parameter. + /// + /// Optionally set verbosity + /// True if wolfssl.dll found + public static bool LoadDLL(bool b) { + SetVerbosity(b); + return LoadDLL(""); + } + + /// + /// Load DLL and specify verbose mode, search in specified parh. + /// + /// + /// + /// True if wolfssl.dll found + public static bool LoadDLL(string wolfsslPath, bool b) { + SetVerbosity(b); + return LoadDLL(wolfsslPath); + } + + /// + /// Load DLL, search in specified parh. + /// + /// + /// True if wolfssl.dll found + public static bool LoadDLL(string wolfsslPath) { + string baseDir = ""; + bool ret = false; +#if WindowsCE + string codeBase = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; + string path = codeBase.Replace("file://", "").Replace("/", "\\"); + string currentDir = System.IO.Path.GetDirectoryName(path); + Console.WriteLine("Base Directory: " + currentDir); + /* + * NOTICE: If you find yourself here as the wolfssl.dll file was not loaded, + * there are limited options on a CE Device. + * + * Please check if: + * + * 1) The native library wolfssl.dll is not found in the expected path at runtime. + * 2) The wolfssl.dll is found, but it is not compatible with the process architecture (e.g., 32-bit vs 64-bit mismatch). + * 3) The wolfssl.dll is found, but is missing dependencies (such as a required MSVC runtime or another .dll it links to). + * + * If everything is ok, try copying the wolfssl.dll file to the target \windows directory. + * + */ +#else + /* Try to find the wolfSSL in all the usual build directories (non-CE platforms only) */ + string[] subDirsToCheck; + if (verbose) + { + Console.WriteLine("AppDomain.CurrentDomain.BaseDirectory: " + AppDomain.CurrentDomain.BaseDirectory); + } + bool is64Bit = (IntPtr.Size == 8); +#if DEBUG + if (is64Bit) + { + Console.WriteLine("wolfSSL CSharp is 64 bit;"); + subDirsToCheck = new string[] { "DLL Debug", "Debug", "Debug\\x64" }; + } + else + { + Console.WriteLine("wolfSSL CSharp is 32 bit;"); + subDirsToCheck = new string[] { "DLL Debug", "Debug", "Debug\\x86", "Debug\\Win32" }; + } +#elif RELEASE + if (is64Bit) { + subDirsToCheck = new string[] { "DLL Release", "Release", "Release\\x64" }; + } + else { + subDirsToCheck = new string[] { "DLL Release", "Release", "Release\\x86", "Release\\Win32" }; + } +#else + Console.WriteLine("Only DEBUG and RELEASE supported"); +#endif // conditional wolfssl.dll search directories + + /* We'll search for alternative locations of a compiled wolfssl.dll only on non-CE targets */ + if (wolfsslPath == "") + { + /* wolfSSL project should have created a DLL in [WOLFSSL_ROOT]\Debug, some number of directories up from here: */ + /* baseDir = Path.GetFullPath(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\..\..\..\Debug")); */ + string dir = Environment.CurrentDirectory; + if (verbose) + { + Console.WriteLine("Looking for wolfSSL in parents, start: " + dir); + } + + while ((!string.IsNullOrEmpty(dir) && Directory.Exists(dir)) || !ret) + { + for (int i = 0; i < subDirsToCheck.Length; i++) + { + string subdir = Path.Combine(dir, subDirsToCheck[i]); + string candidate = Path.Combine(subdir, wolfssl_dll); + if (verbose) + { + Console.WriteLine("Searching in dir: " + subdir); + } + if (File.Exists(candidate)) + { + if (verbose) + { + Console.WriteLine("Found wolfssl.dll " + candidate); + } + /* Be sure to use path without filename in call to SetDllDirectory */ + baseDir = subdir; + ret = true; + break; + } + } + + if (ret) + { + break; + } + + DirectoryInfo parent = Directory.GetParent(dir); + if (parent == null) + { + /* If we at the root, give up. */ + break; + } + + dir = parent.FullName; + } + + } + else { + baseDir = System.IO.Path.GetDirectoryName(wolfsslPath); + } + /* end of !WindowsCE directory search */ +#endif // WindowsCE conditional directory search + + /* When in verbose mode, show the details of the wolfssl.dll file being used */ + if (verbose) + { + String wolfssl_path = Path.Combine(baseDir, wolfssl_dll); + if (File.Exists(wolfssl_path)) + { + FileInfo info = new FileInfo(wolfssl_path); + Console.WriteLine("Found: " + wolfssl_path); + Console.WriteLine(" Size: " + info.Length + " bytes"); + Console.WriteLine(" Modified: " + info.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss")); + } + else + { + Console.WriteLine("File not found: " + wolfssl_path); + } + } + + if (SetDllDirectory(baseDir)) + { + if (verbose) + { + Console.WriteLine("Successfully SetDllDirectory to: " + baseDir); + } + ret = true; + } + else + { + Console.WriteLine("Failed SetDllDirectory for: " + baseDir); + } + return ret; + } /******************************** * Utility String Conversion functions */ -#if WindowsCE +#if WindowsCE || PocketPC /// /// Convert MBCS (8-bit single/multi byte) to Wide Char/Unicode (16-bit) character set /// @@ -63,6 +311,7 @@ public static string MultiByteToWideChar(string msg) /// public static string WideCharToMultiByte(string msg) { + /* Typically only used for CE. See FORCE_MULTIBYTE_STRING */ if (msg == null) return null; /* Get length and round up to even for multibyte / unicode */ @@ -104,6 +353,22 @@ public static string PtrToStringAnsi(IntPtr ptr) } #endif + /// + /// All platform Marshal for ASCII string to Multi-byte pointer + /// See companion PtrToStringAnsi + /// + public static IntPtr StringToAnsiPtr(string str) { + if (str == null) + { + return IntPtr.Zero; + } + + byte[] ansiBytes = Encoding.ASCII.GetBytes(str + '\0'); // ensure null-terminated + IntPtr ptr = Marshal.AllocHGlobal(ansiBytes.Length); + Marshal.Copy(ansiBytes, 0, ptr, ansiBytes.Length); + return ptr; + } + /******************************** * Class for DTLS connections @@ -131,11 +396,31 @@ private class ctx_handle private GCHandle sni_cb; private GCHandle sni_arg; private GCHandle vrf_cb; + +#if _MSC_VER_LT_1900 + /* additional helpers to avoid ESP corruption & Access violations on WindowsCE */ + + /// + /// Strong reference to the receive callback delegate to prevent it from being + /// garbage collected during native calls. This is essential because the delegate + /// is passed to unmanaged code, which may invoke it asynchronously. + /// + private CallbackIORecv_delegate recvDelegate; + /// + /// Strong reference to the send callback delegate to prevent it from being + /// garbage collected during native calls. This ensures the function pointer + /// remains valid throughout the lifetime of the connection. + /// + private CallbackIOSend_delegate sendDelegate; +#endif private IntPtr ctx; public void set_receive(GCHandle input) { this.rec_cb = input; +#if _MSC_VER_LT_1900 + this.recvDelegate = (CallbackIORecv_delegate)input.Target; +#endif } public GCHandle get_receive() { @@ -145,6 +430,9 @@ public GCHandle get_receive() public void set_send(GCHandle input) { this.snd_cb = input; +#if _MSC_VER_LT_1900 + this.sendDelegate = (CallbackIOSend_delegate)input.Target; +#endif } public GCHandle get_send() { @@ -224,8 +512,8 @@ public void free() { this.vrf_cb.Free(); } - } - } + } /* free */ + } /*ctx_handles */ /******************************** * Class for keeping ssl handle alive @@ -301,7 +589,6 @@ public void free() } } - /******************************** * Init wolfSSL library */ @@ -403,6 +690,14 @@ public void free() [DllImport(wolfssl_dll)] private extern static IntPtr wolfSSL_CTX_new(IntPtr method); [DllImport(wolfssl_dll)] + private extern static int wolfSSL_CTX_SetMinVersion(IntPtr ctx, int version); + [DllImport(wolfssl_dll)] + private extern static long wolfSSL_CTX_get_options(IntPtr ctx); + [DllImport(wolfssl_dll)] + private extern static long wolfSSL_CTX_set_options(IntPtr ctx, long opt); + [DllImport(wolfssl_dll)] + private extern static long wolfSSL_CTX_clear_options(IntPtr ctx, long opt); + [DllImport(wolfssl_dll)] private extern static int wolfSSL_CTX_use_certificate_file(IntPtr ctx, string file, int type); [DllImport(wolfssl_dll)] private extern static int wolfSSL_CTX_load_verify_locations(IntPtr ctx, string file, string path); @@ -416,6 +711,14 @@ public void free() [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wolfSSL_CTX_new(IntPtr method); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_CTX_SetMinVersion(IntPtr ctx, int version); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_CTX_get_options(IntPtr ctx); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_CTX_set_options(IntPtr ctx, long opt); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_CTX_clear_options(IntPtr ctx, long opt); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static int wolfSSL_CTX_use_certificate_file(IntPtr ctx, string file, int type); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static int wolfSSL_CTX_load_verify_locations(IntPtr ctx, string file, string path); @@ -454,7 +757,7 @@ public void free() [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static void wolfSSL_CTX_set_psk_client_callback(IntPtr ctx, psk_client_delegate psk_cb); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private extern static int wolfSSL_CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder identity); + private extern static int wolfSSL_CTX_use_psk_identity_hint(IntPtr ctx, string identity); #endif /******************************** @@ -535,8 +838,13 @@ public void free() private extern static int wolfSSL_CTX_set_cipher_list(IntPtr ctx, string ciphers); [DllImport(wolfssl_dll)] private extern static int wolfSSL_set_cipher_list(IntPtr ssl, string ciphers); + #if PocketPC + [DllImport(wolfssl_dll)] + private extern static int wolfSSL_get_ciphers(StringBuilder ciphers, int sz); + #else [DllImport(wolfssl_dll)] private extern static int wolfSSL_get_ciphers(string ciphers, int sz); + #endif [DllImport(wolfssl_dll)] private extern static IntPtr wolfSSL_get_cipher(IntPtr ssl); [DllImport(wolfssl_dll)] @@ -550,9 +858,9 @@ public void free() #else /* only supports full name from cipher_name[] delimited by : */ [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private extern static int wolfSSL_CTX_set_cipher_list(IntPtr ctx, StringBuilder ciphers); + private extern static int wolfSSL_CTX_set_cipher_list(IntPtr ctx, string ciphers); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private extern static int wolfSSL_set_cipher_list(IntPtr ssl, StringBuilder ciphers); + private extern static int wolfSSL_set_cipher_list(IntPtr ssl, string ciphers); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static int wolfSSL_get_ciphers(StringBuilder ciphers, int sz); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] @@ -570,33 +878,34 @@ public void free() /******************************** * Error logging */ -#if WindowsCE +#if WindowsCE || PocketPC [DllImport(wolfssl_dll)] private extern static IntPtr wolfSSL_ERR_reason_error_string(uint err); [DllImport(wolfssl_dll)] private extern static int wolfSSL_get_error(IntPtr ssl, int err); - public delegate void loggingCb(int lvl, string msg); + [DllImport(wolfssl_dll)] + private extern static int wolfSSL_get_alert_history(IntPtr ssl, ref WOLFSSL_ALERT_HISTORY h); [DllImport(wolfssl_dll)] private extern static void wolfSSL_Debugging_ON(); [DllImport(wolfssl_dll)] private extern static void wolfSSL_Debugging_OFF(); [DllImport(wolfssl_dll)] - private extern static int wolfSSL_SetLoggingCb(loggingCb vc); + private extern static int wolfSSL_SetLoggingCb(wolfcrypt.loggingCb vc); #else [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] private extern static IntPtr wolfSSL_ERR_reason_error_string(uint err); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static int wolfSSL_get_error(IntPtr ssl, int err); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void loggingCb(int lvl, StringBuilder msg); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_get_alert_history(IntPtr ssl, ref WOLFSSL_ALERT_HISTORY h); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static void wolfSSL_Debugging_ON(); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static void wolfSSL_Debugging_OFF(); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private extern static int wolfSSL_SetLoggingCb(loggingCb vc); + private extern static int wolfSSL_SetLoggingCb(wolfcrypt.loggingCbEx vc); + #endif - private static loggingCb internal_log; /******************************** * DH @@ -612,9 +921,9 @@ public void free() [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static int wolfSSL_CTX_SetMinDhKey_Sz(IntPtr ctx, short size); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private extern static int wolfSSL_SetTmpDH_file(IntPtr ssl, StringBuilder dhParam, int type); + private extern static int wolfSSL_SetTmpDH_file(IntPtr ssl, string dhParam, int type); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] - private extern static int wolfSSL_CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhParam, int type); + private extern static int wolfSSL_CTX_SetTmpDH_file(IntPtr ctx, string dhParam, int type); #endif @@ -709,6 +1018,30 @@ public void free() public static readonly int WOLFSSL_LOAD_FLAG_IGNORE_ZEROFILE = 0x00000010; public static readonly int WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS = WOLFSSL_LOAD_FLAG_NONE; + public static readonly int SSLV3 = 0; + public static readonly int TLSV1 = 1; + public static readonly int TLSV1_1 = 2; + public static readonly int TLSV1_2 = 3; + public static readonly int TLSV1_3 = 4; + public static readonly int _DTLSV1 = 5; + public static readonly int DTLSV1_2 = 6; + public static readonly int DTLSV1_3 = 7; + + public static readonly int USER_CA = 1; /* user added as trusted */ + public static readonly int CHAIN_CA = 2; /* added to cache from trusted chain */ + public static readonly int TEMP_CA = 3; /* Temp intermediate CA, only for use by X509_STORE */ + + /// + /// Define TLSVersions: pseudo Key Value Pair that works on every version of VS, + /// with wolfSSL values & text descriptions. + /// + public static readonly TLSVersion[] TLSVersions = new TLSVersion[] { + /* Ensure these are listed AFTER declarations; otherwise no error, but not values */ + new TLSVersion(wolfssl.TLSV1, "TLSv1.0"), + new TLSVersion(wolfssl.TLSV1_1, "TLSv1.1"), + new TLSVersion(wolfssl.TLSV1_2, "TLSv1.2"), + new TLSVersion(wolfssl.TLSV1_3, "TLSv1.3") + }; private static IntPtr unwrap_ctx(IntPtr ctx) { @@ -743,15 +1076,37 @@ private static IntPtr unwrap_ssl(IntPtr ssl) } } +#if WindowsCE + /* implement a Directory.GetParent(dir) helper for CE only */ + public static string GetParentDirectory(string path) { + if (string.IsNullOrEmpty(path)) + return string.Empty; + + string normalized = path.TrimEnd('\\'); + + int lastSeparator = normalized.LastIndexOf('\\'); + if (lastSeparator > 0) + return normalized.Substring(0, lastSeparator); + else + return string.Empty; // No parent exists + } +#endif + /// /// Utility function used to access the certificates /// based on the platform. /// return the platform specific path to the certificate /// - public static string setPath(string file) { + public static string setPath(string file) + { PlatformID platform = Environment.OSVersion.Platform; + string cert_path = "./"; + string current_dir = "."; + bool found_path = false; -#if !WindowsCE +#if WindowsCE + /* Skip this first check for CE, as Unix and MacOSX platforms are not defined */ +#else if (platform == PlatformID.Unix || platform == PlatformID.MacOSX) { @@ -765,10 +1120,36 @@ public static string setPath(string file) { platform == PlatformID.Win32S || platform == PlatformID.WinCE) { + current_dir = Directory.GetCurrentDirectory(); + while (!string.IsNullOrEmpty(current_dir) && !found_path) + { + cert_path = Path.Combine(current_dir, "certs"); + if (Directory.Exists(cert_path)) + { + Console.WriteLine("Found certs folder at: " + cert_path); + found_path = true; + } + + if (string.IsNullOrEmpty(current_dir)) + { + current_dir = ".\\"; + } + else + { +#if WindowsCE + current_dir = GetParentDirectory(current_dir); +#else + current_dir = Directory.GetParent(current_dir).FullName; +#endif + } + } /* while */ + Console.WriteLine("Windows - " + file); - return @"../../../../certs/" + file; - } else + return cert_path + "\\" + file; + } + else { + Console.WriteLine("Other environment: " + platform.ToString() + ", no cert file found."); return ""; } } @@ -786,7 +1167,7 @@ private static int wolfSSLCbIORecv(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx) { if (sz <= 0) { - log(ERROR_LOG, "wolfssl receive error, size less than 0"); + log(ERROR_LOG, "wolfssl receive error, size less than 1"); return wolfssl.CBIO_ERR_GENERAL; } @@ -839,7 +1220,7 @@ private static int wolfSSLCbIOSend(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx) { if (sz <= 0) { - log(ERROR_LOG, "wolfssl send error, size less than 0"); + log(ERROR_LOG, "wolfssl send error, size less than 1"); return wolfssl.CBIO_ERR_GENERAL; } @@ -870,7 +1251,7 @@ private static int wolfSSLCbIOSend(IntPtr ssl, IntPtr buf, int sz, IntPtr ctx) } catch (Exception e) { - log(ERROR_LOG, "socket connection issue " + e.ToString()); + log(ERROR_LOG, "socket connection issue: \r\n" + e.ToString()); return wolfssl.CBIO_ERR_CONN_CLOSE; } } @@ -1048,6 +1429,10 @@ public static int connect(IntPtr ssl) return FAILURE; } + /* If Run-Time Check Failure #0 (or other unexpected results) + * "The value of ESP was not properly saved across a function call" + * Check compilation of wolfssl and copy wolfssl.dll file if not in path. + * See also wolfcrypt.SelfCheck(); */ return wolfSSL_connect(sslCtx); } catch (Exception e) @@ -1064,7 +1449,7 @@ public static int connect(IntPtr ssl) /// structure containing info about connection /// object to hold incoming message (Unicode format) /// size of available memory in buf - /// amount of data read on success + /// amount of data read on success, zero or less for error public static int read(IntPtr ssl, StringBuilder buf, int sz) { if (ssl == IntPtr.Zero) @@ -1088,7 +1473,7 @@ public static int read(IntPtr ssl, StringBuilder buf, int sz) ret = wolfSSL_read(sslCtx, data, sz); - if (ret >= 0) + if (ret > 0) { /* Get data that was sent across and store it using a literal read of * the conversion from bytes to character. Takes care of if @@ -1272,8 +1657,7 @@ public static int shutdown(IntPtr ssl) try { IntPtr sslCtx = unwrap_ssl(ssl); - if (sslCtx == IntPtr.Zero) - { + if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "shutdown ssl unwrap error"); return FAILURE; } @@ -1375,15 +1759,21 @@ public static IntPtr CTX_new(IntPtr method) io.set_ctx(ctx); CallbackIORecv_delegate recv = new CallbackIORecv_delegate(wolfssl.wolfSSLCbIORecv); - io.set_receive(GCHandle.Alloc(recv)); + /* Ensures the GCHandle remains in scope and is not immediately eligible for garbage collection, with two lines here: */ + GCHandle recvHandle = GCHandle.Alloc(recv); + io.set_receive(recvHandle); wolfSSL_CTX_SetIORecv(ctx, recv); CallbackIOSend_delegate send = new CallbackIOSend_delegate(wolfssl.wolfSSLCbIOSend); - io.set_send(GCHandle.Alloc(send)); + /* Ensures the GCHandle remains in scope and is not immediately eligible for garbage collection, with two lines here: */ + GCHandle sendHandle = GCHandle.Alloc(send); + io.set_send(sendHandle); wolfSSL_CTX_SetIOSend(ctx, send); - /* keep memory pinned */ -#if WindowsCE +#if PocketPC + GCHandle ioHandle = GCHandle.Alloc(io); + return (IntPtr)ioHandle; +#elif WindowsCE || _MSC_VER_LT_1900 return (IntPtr)GCHandle.Alloc(io, GCHandleType.Pinned); #else return GCHandle.ToIntPtr(GCHandle.Alloc(io, GCHandleType.Pinned)); @@ -1396,6 +1786,90 @@ public static IntPtr CTX_new(IntPtr method) } } + public static int CTX_SetMinVersion(IntPtr ctx, int version) { + int ret = 0; + try { + IntPtr local_ctx = unwrap_ctx(ctx); + if (local_ctx == IntPtr.Zero) { + log(ERROR_LOG, "CTX set min version ctx unwrap error"); + return FAILURE; + } + ret = wolfSSL_CTX_SetMinVersion(ctx, version); + } + catch (Exception e) { + log(ERROR_LOG, "wolfssl CTX_get_options error: " + e.ToString()); + } + + return ret; + } + + + /// + /// Get CTX options mask + /// + /// + /// (long)ctx->mask + public static long CTX_get_options(IntPtr ctx) + { + long opts = 0; + try { + IntPtr local_ctx = unwrap_ctx(ctx); + if (local_ctx == IntPtr.Zero) { + log(ERROR_LOG, "CTX get options unwrap error"); + return FAILURE; + } + opts = wolfSSL_CTX_get_options(local_ctx); + } + catch (Exception e) { + log(ERROR_LOG, "wolfssl CTX_get_options error: " + e.ToString()); + } + + return opts; + } + + /// + /// Set CTX options mask + /// + /// + /// (long)ctx->mask + public static long CTX_set_options(IntPtr ctx, long opt) { + long opts = 0; + try { + IntPtr local_ctx = unwrap_ctx(ctx); + if (local_ctx == IntPtr.Zero) { + log(ERROR_LOG, "CTX get options unwrap error"); + return FAILURE; + } + opts = wolfSSL_CTX_set_options(local_ctx, opt); + } + catch (Exception e) { + log(ERROR_LOG, "wolfssl CTX_get_options error: " + e.ToString()); + } + + return opts; + } + + /// + /// Clear CTX options mask from opt + /// + /// + /// (long)ctx->mask + public static long CTX_clear_options(IntPtr ctx, long opt) { + long opts = 0; + try { + IntPtr local_ctx = unwrap_ctx(ctx); + if (local_ctx == IntPtr.Zero) { + log(ERROR_LOG, "CTX get options unwrap error"); + return FAILURE; + } + opts = wolfSSL_CTX_clear_options(local_ctx, opt); + } + catch (Exception e) { + log(ERROR_LOG, "wolfssl CTX_clear_options error: " + e.ToString()); + } + + return opts; + } /// /// Create a new CTX structure for a DTLS connection @@ -1565,11 +2039,7 @@ public static int SNI_GetFromBuffer(byte []clientHello, uint helloSz, byte type, /// pointer to structure of ctx to set hint in /// hint to use /// 1 on success -#if WindowsCE public static int CTX_use_psk_identity_hint(IntPtr ctx, string hint) -#else - public static int CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder hint) -#endif { try { @@ -1580,11 +2050,11 @@ public static int CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder hint) return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_CTX_use_psk_identity_hint(local_ctx, wolfssl.WideCharToMultiByte(hint)); - #else +#else return wolfSSL_CTX_use_psk_identity_hint(local_ctx, hint); - #endif +#endif } catch (Exception e) { @@ -1593,6 +2063,19 @@ public static int CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder hint) } } +#if WindowsCE + /* Ambiguities in marshaling (e.g. string and StringBuilder both as LPWSTR) + * may cause runtime errors or ambiguous match exceptions. + * So suffix this StringBuilder param function with '_sb' */ + public static int CTX_use_psk_identity_hint_sb(IntPtr ctx, StringBuilder hint) { + return CTX_use_psk_identity_hint(ctx, hint.ToString()); + } +#else + public static int CTX_use_psk_identity_hint(IntPtr ctx, StringBuilder hint) + { + return CTX_use_psk_identity_hint(ctx, hint.ToString()); + } +#endif /// /// Set the function to use for PSK connections @@ -1862,20 +2345,20 @@ public static string get_ciphers() { try { - #if WindowsCE +#if WindowsCE && !PocketPC string ciphers = new string(' ', 4096); - #else - StringBuilder ciphers = new StringBuilder(new String(' ', 4096)); - #endif +#else + StringBuilder ciphers = new StringBuilder(4096); +#endif int ret = wolfSSL_get_ciphers(ciphers, ciphers.Length); if (ret != SUCCESS) return null; - #if WindowsCE +#if WindowsCE && !PocketPC return wolfssl.MultiByteToWideChar(ciphers); - #else +#else return ciphers.ToString(); - #endif +#endif } catch (Exception e) { @@ -1890,18 +2373,17 @@ public static string get_ciphers() /// list to fill with cipher suite names /// size of list available to fill /// 1 on success -#if WindowsCE +#if WindowsCE && !PocketPC public static int get_ciphers(string list, int sz) #else public static int get_ciphers(StringBuilder list, int sz) #endif { - try - { + /* Warning: list modified but not passed by ref! Do not actually modify the pointer/reference itself. */ + try { return wolfSSL_get_ciphers(list, sz); } - catch (Exception e) - { + catch (Exception e) { log(ERROR_LOG, "wolfssl get_ciphers error " + e.ToString()); return FAILURE; } @@ -2044,6 +2526,7 @@ public static IntPtr usev23_client() catch (Exception e) { log(ERROR_LOG, "wolfssl error " + e.ToString()); + Console.WriteLine(e.Message); return IntPtr.Zero; } } @@ -2127,11 +2610,7 @@ public static string get_current_cipher(IntPtr ssl) /// CTX structure to set /// List full of ciphers suites /// 1 on success -#if WindowsCE public static int CTX_set_cipher_list(IntPtr ctx, string list) -#else - public static int CTX_set_cipher_list(IntPtr ctx, StringBuilder list) -#endif { try { @@ -2142,11 +2621,11 @@ public static int CTX_set_cipher_list(IntPtr ctx, StringBuilder list) return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_CTX_set_cipher_list(local_ctx, wolfssl.WideCharToMultiByte(list)); - #else +#else return wolfSSL_CTX_set_cipher_list(local_ctx, list); - #endif +#endif } catch (Exception e) { @@ -2155,6 +2634,16 @@ public static int CTX_set_cipher_list(IntPtr ctx, StringBuilder list) } } +#if WindowsCE + /* Ambiguities in marshaling (e.g. string and StringBuilder both as LPWSTR) may cause runtime errors or ambiguous match exceptions. */ + public static int CTX_set_cipher_list_cb(IntPtr ctx, StringBuilder list) { + return CTX_set_cipher_list(ctx, list.ToString()); + } +#else + public static int CTX_set_cipher_list(IntPtr ctx, StringBuilder list) { + return CTX_set_cipher_list(ctx, list.ToString()); + } +#endif /// /// Set available cipher suite in local connection @@ -2162,11 +2651,7 @@ public static int CTX_set_cipher_list(IntPtr ctx, StringBuilder list) /// Structure to set cipher suite in /// List of cipher suites /// 1 on success -#if WindowsCE public static int set_cipher_list(IntPtr ssl, string list) -#else - public static int set_cipher_list(IntPtr ssl, StringBuilder list) -#endif { try { @@ -2177,11 +2662,11 @@ public static int set_cipher_list(IntPtr ssl, StringBuilder list) return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_set_cipher_list(sslCtx, wolfssl.WideCharToMultiByte(list)); - #else +#else return wolfSSL_set_cipher_list(sslCtx, list); - #endif +#endif } catch (Exception e) { @@ -2190,6 +2675,21 @@ public static int set_cipher_list(IntPtr ssl, StringBuilder list) } } +#if WindowsCE + /* Ambiguities in marshaling (e.g. string and StringBuilder both as LPWSTR) may cause runtime errors or ambiguous match exceptions. + * So give the CE version a different name: / + public static int set_cipher_list_sb(IntPtr ctx, StringBuilder list) + { + return set_cipher_list(ssl, list.ToString()); + } +#else + /* Only non-CE versions will have the overloaded methods */ + public static int set_cipher_list(IntPtr ssl, StringBuilder list) + { + return set_cipher_list(ssl, list.ToString()); + } +#endif + /// /// Gets the version of the connection made ie TLSv1.2 @@ -2257,6 +2757,76 @@ public static string get_error(IntPtr ssl) } +#if WindowsCE +#if WindowsCE + public static int get_alert_history(IntPtr ssl, ref WOLFSSL_ALERT_HISTORY h) { + + if (ssl == IntPtr.Zero) + return FAILURE; + + try { + IntPtr local_ssl = unwrap_ssl(ssl); + if (local_ssl == IntPtr.Zero) { + log(ERROR_LOG, "wolfssl get_error error"); + return FAILURE; + } + + return wolfSSL_get_alert_history(local_ssl, ref h); + } + catch (Exception e) { + log(ERROR_LOG, "wolfssl get error, error " + e.ToString()); + return FAILURE; + } + } +#else + public static int get_alert_history(IntPtr ssl, ref WOLFSSL_ALERT_HISTORY hist) + { + int size = Marshal.SizeOf(typeof(WOLFSSL_ALERT_HISTORY)); + IntPtr mem = Marshal.AllocHGlobal(size); + + try + { + int ret = wolfSSL_get_alert_history(ssl, mem); + if (ret == 0) + { + hist = (WOLFSSL_ALERT_HISTORY) + Marshal.PtrToStructure(mem, typeof(WOLFSSL_ALERT_HISTORY)); + } + return ret; + } + finally + { + Marshal.FreeHGlobal(mem); + } + } +#endif +#else + /// + /// This function gets the alert history. + /// + /// SSL struct + /// a pointer to a WOLFSSL_ALERT_HISTORY structure that will hold the WOLFSSL struct’s alert_history member’s value. + /// Integer result of wolfSSL_get_alert_history SSL_SUCCESS or FAILURE + public static int get_alert_history(IntPtr ssl, ref WOLFSSL_ALERT_HISTORY h) { + if (ssl == IntPtr.Zero) + return FAILURE; + + try { + IntPtr local_ssl = unwrap_ssl(ssl); + if (local_ssl == IntPtr.Zero) { + log(ERROR_LOG, "wolfssl get_error error"); + return FAILURE; + } + + return wolfSSL_get_alert_history(local_ssl, ref h); + } + catch (Exception e) { + log(ERROR_LOG, "wolfssl get error, error " + e.ToString()); + return FAILURE; + } + } +#endif + /// /// Used to load in the certificate file /// @@ -2275,11 +2845,11 @@ public static int CTX_use_certificate_file(IntPtr ctx, string fileCert, int type return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_CTX_use_certificate_file(local_ctx, wolfssl.WideCharToMultiByte(fileCert), type); - #else +#else return wolfSSL_CTX_use_certificate_file(local_ctx, fileCert, type); - #endif +#endif } catch (Exception e) { @@ -2307,11 +2877,11 @@ public static int CTX_load_verify_locations(IntPtr ctx, string fileCert, string return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_CTX_load_verify_locations(local_ctx, wolfssl.WideCharToMultiByte(fileCert), wolfssl.WideCharToMultiByte(path)); - #else +#else return wolfSSL_CTX_load_verify_locations(local_ctx, fileCert, path); - #endif +#endif } catch (Exception e) { @@ -2338,11 +2908,11 @@ public static int CTX_use_PrivateKey_file(IntPtr ctx, string fileKey, int type) return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_CTX_use_PrivateKey_file(local_ctx, wolfssl.WideCharToMultiByte(fileKey), type); - #else +#else return wolfSSL_CTX_use_PrivateKey_file(local_ctx, fileKey, type); - #endif +#endif } catch (Exception e) { @@ -2359,11 +2929,7 @@ public static int CTX_use_PrivateKey_file(IntPtr ctx, string fileKey, int type) /// file name /// type of file ie PEM /// 1 on success -#if WindowsCE public static int SetTmpDH_file(IntPtr ssl, string dhparam, int file_type) -#else - public static int SetTmpDH_file(IntPtr ssl, StringBuilder dhparam, int file_type) -#endif { try { @@ -2374,11 +2940,11 @@ public static int SetTmpDH_file(IntPtr ssl, StringBuilder dhparam, int file_type return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_SetTmpDH_file(sslCtx, wolfssl.WideCharToMultiByte(dhparam), file_type); - #else +#else return wolfSSL_SetTmpDH_file(sslCtx, dhparam, file_type); - #endif +#endif } catch (Exception e) { @@ -2394,11 +2960,7 @@ public static int SetTmpDH_file(IntPtr ssl, StringBuilder dhparam, int file_type /// file name /// type of file ie PEM /// 1 on success -#if WindowsCE public static int CTX_SetTmpDH_file(IntPtr ctx, string dhparam, int file_type) -#else - public static int CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhparam, int file_type) -#endif { try { @@ -2409,11 +2971,11 @@ public static int CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhparam, int file_ return FAILURE; } - #if WindowsCE +#if FORCE_MULTIBYTE_STRING return wolfSSL_CTX_SetTmpDH_file(local_ctx, wolfssl.WideCharToMultiByte(dhparam), file_type); - #else +#else return wolfSSL_CTX_SetTmpDH_file(local_ctx, dhparam, file_type); - #endif +#endif } catch (Exception e) { @@ -2638,37 +3200,54 @@ public static void Debugging_OFF() wolfSSL_Debugging_OFF(); } + /* All of the logging is implemented in wolfCrypt, + * but also available in wolfssl */ + /// - /// Set the function to use for logging + /// Clear the logging callback. /// - /// Function that conforms as to loggingCb - /// 1 on success - public static int SetLogging(loggingCb input) + /// 1 if successful + public static int ClearLogging() { + return wolfcrypt.ClearLogging(); + } + +#if WindowsCE + public static int SetLogging(wolfcrypt.loggingCb input) { + return wolfcrypt.SetLogging(input); + } + + public static void log(int lvl, string msg) { - internal_log = input; + wolfcrypt.log(lvl, msg); + } +#else + /* StringBuilder msg param */ + public static int SetLogging(wolfcrypt.loggingCb input) { + return wolfcrypt.SetLogging(input); + } - wolfSSL_SetLoggingCb(input); + /* string msg param */ + public static int SetLogging(wolfcrypt.loggingCbExs input) + { + return wolfcrypt.SetLogging(input); + } - return SUCCESS; + /* IntPtr msg param */ + public static int SetLogging(wolfcrypt.loggingCbEx input) { + return wolfcrypt.SetLogging(input); } + /* Expose wolfcrypt.log to wolfssl for convenience */ + public static void log(int lvl, string msg) { + wolfcrypt.log(lvl, msg); + } - /// - /// Log a message to set logging function - /// - /// Level of log message - /// Message to log - public static void log(int lvl, string msg) + public static void log(int lvl, StringBuilder msg) { - /* if log is not set then print nothing */ - if (internal_log == null) - return; - #if WindowsCE - internal_log(lvl, msg); - #else - StringBuilder msg_sb = new StringBuilder(msg); - internal_log(lvl, msg_sb); - #endif + wolfcrypt.log(lvl, msg.ToString()); } - } -} + +#endif + + } /* class wolfssl */ +} /* namespace wolfSSL.CSharp */ diff --git a/wrapper/CSharp/wolfssl.vcxproj b/wrapper/CSharp/wolfssl.vcxproj index 8ac0fdb722..a9fc961b77 100644 --- a/wrapper/CSharp/wolfssl.vcxproj +++ b/wrapper/CSharp/wolfssl.vcxproj @@ -1,5 +1,5 @@  - + Debug