From 05ee7b34c74758ff7862f78e9ecfb37209387e83 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 21 Jul 2017 14:25:38 -0700 Subject: [PATCH 1/8] IDE Add initial IDE build support with Windows VisualStudio. Just put in the autoconf includes and a readme. --- Makefile.am | 1 + ide/include.am | 5 +++++ ide/winvs/README.txt | 1 + ide/winvs/include.am | 7 +++++++ 4 files changed, 14 insertions(+) create mode 100644 ide/include.am create mode 100644 ide/winvs/README.txt create mode 100644 ide/winvs/include.am diff --git a/Makefile.am b/Makefile.am index c8b64065..d38b1d0f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -35,6 +35,7 @@ include wolfssh/include.am include examples/include.am include tests/include.am include keys/include.am +include ide/include.am TEST_EXTENSIONS = .test diff --git a/ide/include.am b/ide/include.am new file mode 100644 index 00000000..e028e04c --- /dev/null +++ b/ide/include.am @@ -0,0 +1,5 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +include ide/winvs/include.am diff --git a/ide/winvs/README.txt b/ide/winvs/README.txt new file mode 100644 index 00000000..7e5693f9 --- /dev/null +++ b/ide/winvs/README.txt @@ -0,0 +1 @@ +VisualStudio solution for wolfSSH diff --git a/ide/winvs/include.am b/ide/winvs/include.am new file mode 100644 index 00000000..cb78061b --- /dev/null +++ b/ide/winvs/include.am @@ -0,0 +1,7 @@ +# vim:ft=automake +# All paths should be given relative to the root + +EXTRA_DIST+= ide/winvs/README.txt +#EXTRA_DIST+= ide/winvs/api.vcxproj +#EXTRA_DIST+= ide/winvs/wolfssh.sln +#EXTRA_DIST+= ide/winvs/wolfssh.vcxproj From 6ac63009dc2730699da870b8d0c32ed38a3a26fa Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 30 Aug 2017 16:19:06 -0700 Subject: [PATCH 2/8] IDE 1. Adding the VisualStudio solution file. 2. Updated gitignore with the VS debris. 3. Adding project files for wolfssh library and apt-test. --- .gitignore | 8 +++ ide/winvs/api-test/api-test.vcxproj | 86 +++++++++++++++++++++++++++ ide/winvs/include.am | 6 +- ide/winvs/wolfssh.sln | 29 ++++++++++ ide/winvs/wolfssh/wolfssh.vcxproj | 90 +++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 ide/winvs/api-test/api-test.vcxproj create mode 100644 ide/winvs/wolfssh.sln create mode 100644 ide/winvs/wolfssh/wolfssh.vcxproj diff --git a/.gitignore b/.gitignore index b4a08d9c..7cf05ff4 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,11 @@ client.plist # misc .DS_Store + +# VS debris +*.sdf +*.v11.suo +*.vcxproj.filters +*.opensdf +Debug +Release diff --git a/ide/winvs/api-test/api-test.vcxproj b/ide/winvs/api-test/api-test.vcxproj new file mode 100644 index 00000000..43aa4629 --- /dev/null +++ b/ide/winvs/api-test/api-test.vcxproj @@ -0,0 +1,86 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7} + Win32Proj + apitest + + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + true + $(Configuration)\$(Platform)\obj + $(SolutionDir)$(Configuration)\$(Platform) + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/ide/winvs/include.am b/ide/winvs/include.am index cb78061b..b5c20962 100644 --- a/ide/winvs/include.am +++ b/ide/winvs/include.am @@ -2,6 +2,6 @@ # All paths should be given relative to the root EXTRA_DIST+= ide/winvs/README.txt -#EXTRA_DIST+= ide/winvs/api.vcxproj -#EXTRA_DIST+= ide/winvs/wolfssh.sln -#EXTRA_DIST+= ide/winvs/wolfssh.vcxproj +EXTRA_DIST+= ide/winvs/wolfssh.sln +EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj +EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj diff --git a/ide/winvs/wolfssh.sln b/ide/winvs/wolfssh.sln new file mode 100644 index 00000000..6183d929 --- /dev/null +++ b/ide/winvs/wolfssh.sln @@ -0,0 +1,29 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows Desktop +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfssh", "wolfssh\wolfssh.vcxproj", "{7C2CCF0D-A155-4914-BD1C-9A47C0530E65}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-test", "api-test\api-test.vcxproj", "{07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}" + ProjectSection(ProjectDependencies) = postProject + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.ActiveCfg = Debug|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.Build.0 = Debug|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.ActiveCfg = Release|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.Build.0 = Release|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.Build.0 = Debug|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.ActiveCfg = Release|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ide/winvs/wolfssh/wolfssh.vcxproj b/ide/winvs/wolfssh/wolfssh.vcxproj new file mode 100644 index 00000000..11a8853b --- /dev/null +++ b/ide/winvs/wolfssh/wolfssh.vcxproj @@ -0,0 +1,90 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} + Win32Proj + wolfssh + + + + StaticLibrary + true + v110 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;%(PreprocessorDefinitions) + ..\..\..;%(AdditionalIncludeDirectories) + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + + + + From a48a13e6bab5c01835c6a4daae5430c1313f171f Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 31 Aug 2017 10:59:21 -0700 Subject: [PATCH 3/8] IDE 1. Added a user_settings.h file to be used with building wolfSSL. 2. Removed misc.c from the wolfSSH library project. 3. Added the WOLFSSL_USER_SETTINGS define to the wolfSSH library project. 4. Replaced vsnprintf() and localtime_r() with macros to use the correct functions for Win32 builds. 5. Replaced the misc.c warning with the VS style of doing it if building for Win32. 6. Defined USE_WINDOWS_API if _WIN32 is set. Note: The wolfSSH library builds in 32-bit Debug mode. To do so, you need to add the directory holding the wolfSSL headers to the AdditionalIncludeDirectories list. --- ide/winvs/include.am | 1 + ide/winvs/user_settings.h | 27 +++++++++++++++++++++++++++ ide/winvs/wolfssh/wolfssh.vcxproj | 5 ++--- src/log.c | 4 ++-- src/misc.c | 7 ++++++- wolfssh/port.h | 5 +++++ wolfssh/settings.h | 5 +++++ 7 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 ide/winvs/user_settings.h diff --git a/ide/winvs/include.am b/ide/winvs/include.am index b5c20962..67fda29e 100644 --- a/ide/winvs/include.am +++ b/ide/winvs/include.am @@ -5,3 +5,4 @@ EXTRA_DIST+= ide/winvs/README.txt EXTRA_DIST+= ide/winvs/wolfssh.sln EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj +EXTRA_DIST+= ide/winvs/user_settings.h diff --git a/ide/winvs/user_settings.h b/ide/winvs/user_settings.h new file mode 100644 index 00000000..e9fd2aaf --- /dev/null +++ b/ide/winvs/user_settings.h @@ -0,0 +1,27 @@ +#ifndef _WIN_USER_SETTINGS_H_ +#define _WIN_USER_SETTINGS_H_ + +/* Verify this is Windows */ +#ifndef _WIN32 +#error This user_settings.h header is only designed for Windows +#endif + +#define WOLFCRYPT_ONLY +#define WOLFSSL_KEY_GEN +#define HAVE_ECC +#define HAVE_AESGCM +#define HAVE_HASHDRBG +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA512 +#define NO_PSK +#define NO_HC128 +#define NO_RC4 +#define NO_RABBIT +#define NO_DSA +#define NO_MD4 +#define WC_RSA_BLINDING +#define USE_FAST_MATH +#define TFM_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT + +#endif /* _WIN_USER_SETTINGS_H_ */ diff --git a/ide/winvs/wolfssh/wolfssh.vcxproj b/ide/winvs/wolfssh/wolfssh.vcxproj index 11a8853b..334844de 100644 --- a/ide/winvs/wolfssh/wolfssh.vcxproj +++ b/ide/winvs/wolfssh/wolfssh.vcxproj @@ -16,7 +16,6 @@ - @@ -59,7 +58,7 @@ Level3 Disabled - WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) ..\..\..;%(AdditionalIncludeDirectories) @@ -87,4 +86,4 @@ - + \ No newline at end of file diff --git a/src/log.c b/src/log.c index 05d988dc..53430b09 100644 --- a/src/log.c +++ b/src/log.c @@ -139,7 +139,7 @@ void WLOG(enum wolfSSH_LogLevel level, const char *const fmt, ...) struct tm local; current = time(NULL); - if (localtime_r(¤t, &local)) { + if (WLOCALTIME(¤t, &local)) { /* make pretty */ strftime(timeStr, sizeof(timeStr), "%b %d %T %Y", &local); } @@ -149,7 +149,7 @@ void WLOG(enum wolfSSH_LogLevel level, const char *const fmt, ...) /* format msg */ va_start(vlist, fmt); - vsnprintf(msgStr, sizeof(msgStr), fmt, vlist); + WVSNPRINTF(msgStr, sizeof(msgStr), fmt, vlist); va_end(vlist); msgStr[sizeof(msgStr)-1] = '\0'; diff --git a/src/misc.c b/src/misc.c index a841dcb5..fad0d231 100644 --- a/src/misc.c +++ b/src/misc.c @@ -49,8 +49,13 @@ /* Check for if compiling misc.c when not needed. */ #if !defined(WOLFSSH_MISC_INCLUDED) && !defined(NO_INLINE) + #define MISC_WARNING "misc.c does not need to be compiled when using inline (NO_INLINE not defined))" - #warning misc.c does not need to be compiled when using inline (NO_INLINE not defined) + #ifndef _MSC_VER + #warning MISC_WARNING + #else + #pragma message("warning: " MISC_WARNING) + #endif #else /* !WOLFSSL_MISC_INCLUDED && !NO_INLINE */ diff --git a/wolfssh/port.h b/wolfssh/port.h index 500f303f..359fc930 100644 --- a/wolfssh/port.h +++ b/wolfssh/port.h @@ -75,9 +75,14 @@ extern "C" { #include #define WSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n)) #define WSNPRINTF snprintf + #define WVSNPRINTF(a,b,c,d) vsnprintf(a,b,c,d) + #define WLOCALTIME(a,b) (localtime_r(a,b)!=NULL) + #else #define WSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) #define WSNPRINTF _snprintf + #define WVSNPRINTF(a,b,c,d) vsnprintf_s(a,b,(b-1),c,d) + #define WLOCALTIME(a,b) (localtime_s(b,a)==0) #endif #endif /* WSTRING_USER */ diff --git a/wolfssh/settings.h b/wolfssh/settings.h index 631e742a..bda707e4 100644 --- a/wolfssh/settings.h +++ b/wolfssh/settings.h @@ -41,6 +41,11 @@ extern "C" { #endif /* WMALLOC_USER */ +#if defined (_WIN32) + #define USE_WINDOWS_API +#endif + + #ifdef __cplusplus } #endif From faf3f45ed80f2029a56e73a625ac5f775fffdd9a Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 31 Aug 2017 11:26:24 -0700 Subject: [PATCH 4/8] IDE Updated the two projects with similar settings so they build without warnings. The wolfSSH library project needs the wolfSSL header path added before building. The api-test project needs the wolfSSL library added before building. --- ide/winvs/api-test/api-test.vcxproj | 18 ++++++++++++++---- ide/winvs/wolfssh/wolfssh.vcxproj | 3 ++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ide/winvs/api-test/api-test.vcxproj b/ide/winvs/api-test/api-test.vcxproj index 43aa4629..8976a92e 100644 --- a/ide/winvs/api-test/api-test.vcxproj +++ b/ide/winvs/api-test/api-test.vcxproj @@ -13,6 +13,11 @@ + + + {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7} Win32Proj @@ -43,9 +48,9 @@ - true - $(Configuration)\$(Platform)\obj - $(SolutionDir)$(Configuration)\$(Platform) + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ false @@ -57,10 +62,15 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + ..\..\..;%(AdditionalIncludeDirectories) + ProgramDatabase Console true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib @@ -83,4 +93,4 @@ - \ No newline at end of file + diff --git a/ide/winvs/wolfssh/wolfssh.vcxproj b/ide/winvs/wolfssh/wolfssh.vcxproj index 334844de..b4189465 100644 --- a/ide/winvs/wolfssh/wolfssh.vcxproj +++ b/ide/winvs/wolfssh/wolfssh.vcxproj @@ -60,6 +60,7 @@ Disabled WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) ..\..\..;%(AdditionalIncludeDirectories) + ProgramDatabase Windows @@ -86,4 +87,4 @@ - \ No newline at end of file + From 60d945699ad0d0125a78a9e82c611e73e97329c5 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 31 Aug 2017 13:25:03 -0700 Subject: [PATCH 5/8] IDE Add the echoserver to the project. --- ide/winvs/api-test/api-test.vcxproj | 2 +- ide/winvs/echoserver/echoserver.vcxproj | 96 +++++++++++++++++++++++++ ide/winvs/include.am | 1 + ide/winvs/wolfssh.sln | 9 +++ 4 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 ide/winvs/echoserver/echoserver.vcxproj diff --git a/ide/winvs/api-test/api-test.vcxproj b/ide/winvs/api-test/api-test.vcxproj index 8976a92e..2e9cfd5c 100644 --- a/ide/winvs/api-test/api-test.vcxproj +++ b/ide/winvs/api-test/api-test.vcxproj @@ -61,7 +61,7 @@ Level3 Disabled - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) ..\..\..;%(AdditionalIncludeDirectories) ProgramDatabase diff --git a/ide/winvs/echoserver/echoserver.vcxproj b/ide/winvs/echoserver/echoserver.vcxproj new file mode 100644 index 00000000..135ce921 --- /dev/null +++ b/ide/winvs/echoserver/echoserver.vcxproj @@ -0,0 +1,96 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + + + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D} + Win32Proj + echoserver + + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + diff --git a/ide/winvs/include.am b/ide/winvs/include.am index 67fda29e..62cf37dc 100644 --- a/ide/winvs/include.am +++ b/ide/winvs/include.am @@ -5,4 +5,5 @@ EXTRA_DIST+= ide/winvs/README.txt EXTRA_DIST+= ide/winvs/wolfssh.sln EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj +EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj EXTRA_DIST+= ide/winvs/user_settings.h diff --git a/ide/winvs/wolfssh.sln b/ide/winvs/wolfssh.sln index 6183d929..7bab7bc7 100644 --- a/ide/winvs/wolfssh.sln +++ b/ide/winvs/wolfssh.sln @@ -8,6 +8,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "api-test", "api-test\api-te {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echoserver", "echoserver\echoserver.vcxproj", "{B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}" + ProjectSection(ProjectDependencies) = postProject + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -22,6 +27,10 @@ Global {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.Build.0 = Debug|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.ActiveCfg = Release|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.Build.0 = Release|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.Build.0 = Debug|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.ActiveCfg = Release|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 1498bc540916e23dbf48427af05a27c0e0ede9ef Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 12 Sep 2017 11:26:54 -0700 Subject: [PATCH 6/8] IDE Support 1. Added Windows Visual Studio build solution. Includes projects for: * wolfSSH static library * echoserver * unit-test * api-test * 32- and 64-bit debug and release builds for all 2. Made necessary tweaks including adding some wrapper functions so the code compiles for both Linux/macOS and Windows. 3. Fixed a bug in the KDF test where the output buffer wasn't updated when SHA-256 was added. 4. Added the fallthrough attribute for GCC7. 5. Replaced all uses of `uint8_t`, `uint16_t`, and `uint32_t` with the wolfCrypt provided `byte`, `word16`, and `word32`. 6. Split the new channel function into new and init. 7. Added some ECC keys for authentication testing. 8. Moved some functions and includes around. 9. Removed the keying state machine and replaced with a flag. 10. Added rekey trigger if the client sends *CTRL-F* to echoserver. 11. Moved the sequence number increase outside `CreateMac()`. Incremented if the packet was successfully created. This way the sequence number is incremented when using AES-GCM. 12. Removed the redundant function `SendText()`. 13. Renamed the `clientId` related functions and data members to `protoId` to keep things role agnostic. 14. Changed all references of `clientKey` and `serverKey` to `keys` and `peerKeys`. 15. Updated `GenerateKeys()` to generate `keys` and `peerKeys` appropriately based on the endpoint side. 16. Added the wolfSSL style _test.h_ file to group shared example functions in one place. 17. Changed the echoserver to be similar to wolfSSL's where the code may be included without the main function in another executable. Note: This commit is a squash of more than a dozen commits. IDE support was added to the client branch, but the client branch is on hold. There were many changes in the client branch that are needed going forward. The code at the head of the client branch was copied over to the IDE branch, and the client code either deleted or removed from the build. --- README.md | 9 +- configure.ac | 3 + examples/echoserver/echoserver.c | 502 ++--- examples/echoserver/echoserver.h | 31 + ide/winvs/api-test/api-test.vcxproj | 87 +- ide/winvs/echoserver/echoserver.vcxproj | 87 +- ide/winvs/include.am | 2 + ide/winvs/unit-test/unit-test.vcxproj | 177 ++ ide/winvs/wolfcrypt/README.txt | 21 + ide/winvs/wolfssh.sln | 24 + ide/winvs/wolfssh/wolfssh.vcxproj | 79 +- src/internal.c | 2687 ++++++++++++++++------- src/io.c | 4 +- src/keygen.c | 10 +- src/misc.c | 18 +- src/port.c | 16 +- src/ssh.c | 114 +- tests/api.c | 31 + tests/unit.c | 74 +- wolfssh/error.h | 3 +- wolfssh/internal.h | 447 ++-- wolfssh/keygen.h | 2 +- wolfssh/misc.h | 10 +- wolfssh/port.h | 40 +- wolfssh/settings.h | 3 + wolfssh/ssh.h | 89 +- wolfssh/test.h | 544 +++++ 27 files changed, 3600 insertions(+), 1514 deletions(-) create mode 100755 examples/echoserver/echoserver.h create mode 100644 ide/winvs/unit-test/unit-test.vcxproj create mode 100644 ide/winvs/wolfcrypt/README.txt create mode 100755 wolfssh/test.h diff --git a/README.md b/README.md index 1d5f1b5a..b9d5b22f 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,8 @@ testing notes After cloning the repository, be sure to make the testing private keys read- only for the user, otherwise ssh_client will tell you to do it. - $ chmod 0600 ./keys/key-gretel.pem ./keys/key-hansel.pem + $ chmod 0600 ./keys/gretel-key-rsa.pem ./keys/hansel-key-rsa.pem \ + ./keys/gretel-key-ecc.pem ./keys/hansel-key-ecc.pem Authentication against the example echoserver can be done with a password or public key. To use a password the command line: @@ -78,9 +79,9 @@ Where the `USER` and password pairs are: To use public key authentication use the command line: - $ ssh_client -i ./keys/key-USER.pem -p 22222 USER@localhost + $ ssh_client -i ./keys/USER-key-TYPE.pem -p 22222 USER@localhost -Where the user can be `gretel` or `hansel`. +Where the user can be `gretel` or `hansel`, and type is `rsa` or `ecc`. release notes @@ -89,7 +90,7 @@ release notes ### wolfSSH v1.2.0 (07/XX/2017) - Added ECDH Group Exchange with SHA2 hashing and curves nistp256, - nistp384, and nistp521. + nistp384, and nistp521. - Added ECDSA with SHA2 hashing and curves nistp256, nistp384, and nistp521. - Changed the echoserver to allow only one connection, but multiple connections are allowed with a command line option. diff --git a/configure.ac b/configure.ac index f8a13cc6..918327c7 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,9 @@ TAO_REQUIRE_LIBWOLFSSL #REQUIRE_CYASSL([scep]) #REQUIRE_WOLFCRYPT([aes rsa dh]) +# Disable any client code. For size, as nothing calls it. +AM_CPPFLAGS="$AM_CPPFLAGS -DWOLFSSL_NO_CLIENT" + # since we have autoconf available, we can use cyassl options header AM_CPPFLAGS="$AM_CPPFLAGS -DHAVE_CYASSL_OPTIONS" diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 5a64c0a1..c6467ba3 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -1,6 +1,6 @@ /* echoserver.c * - * Copyright (C) 2014-2016 wolfSSL Inc. + * Copyright (C) 2014-2017 wolfSSL Inc. * * This file is part of wolfSSH. * @@ -19,80 +19,21 @@ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include #include -#ifndef SO_NOSIGPIPE - #include -#endif +#include +#include "examples/echoserver/echoserver.h" static const char echoserverBanner[] = "wolfSSH Example Echo Server\n"; -typedef int SOCKET_T; -#ifdef TEST_IPV6 - typedef struct sockaddr_in6 SOCKADDR_IN_T; - #define AF_INET_V AF_INET6 - static const char* wolfsshIP = "::1"; -#else - typedef struct sockaddr_in SOCKADDR_IN_T; - #define AF_INET_V AF_INET - static const char* wolfsshIP = "127.0.0.1"; -#endif -#define SERVER_PORT_NUMBER 22222 -#define SCRATCH_BUFFER_SIZE 1200 - -#if defined(__MACH__) || defined(USE_WINDOWS_API) - #ifndef _SOCKLEN_T - typedef int socklen_t; - #endif -#endif -/* HPUX doesn't use socklent_t for third parameter to accept, unless - _XOPEN_SOURCE_EXTENDED is defined */ -#if !defined(__hpux__) && !defined(CYASSL_MDK_ARM) && !defined(CYASSL_IAR_ARM) - typedef socklen_t SOCKLEN_T; -#else - #if defined _XOPEN_SOURCE_EXTENDED - typedef socklen_t SOCKLEN_T; - #else - typedef int SOCKLEN_T; - #endif -#endif - - -#if defined(_POSIX_THREADS) && !defined(__MINGW32__) - typedef void* THREAD_RETURN; - typedef pthread_t THREAD_TYPE; - #define CYASSL_THREAD - #define INFINITE -1 - #define WAIT_OBJECT_0 0L -#elif defined(CYASSL_MDK_ARM) - typedef unsigned int THREAD_RETURN; - typedef int THREAD_TYPE; - #define CYASSL_THREAD -#else - typedef unsigned int THREAD_RETURN; - typedef intptr_t THREAD_TYPE; - #define CYASSL_THREAD __stdcall -#endif typedef struct { WOLFSSH* ssh; SOCKET_T fd; - uint32_t id; + word32 id; } thread_ctx_t; @@ -102,247 +43,12 @@ typedef struct { #ifndef EXAMPLE_BUFFER_SZ #define EXAMPLE_BUFFER_SZ 4096 #endif +#define SCRATCH_BUFFER_SZ 1200 -#ifdef __GNUC__ - #define WS_NORETURN __attribute__((noreturn)) -#else - #define WS_NORETURN -#endif - - -#define MY_EX_USAGE 2 - -extern int myoptind; -extern char* myoptarg; - -static INLINE int mygetopt(int argc, char** argv, const char* optstring) +static byte find_char(const byte* str, const byte* buf, word32 bufSz) { - static char* next = NULL; - - char c; - char* cp; - - if (myoptind == 0) - next = NULL; /* we're starting new/over */ - - if (next == NULL || *next == '\0') { - if (myoptind == 0) - myoptind++; - - if (myoptind >= argc || argv[myoptind][0] != '-' || - argv[myoptind][1] == '\0') { - myoptarg = NULL; - if (myoptind < argc) - myoptarg = argv[myoptind]; - - return -1; - } - - if (strcmp(argv[myoptind], "--") == 0) { - myoptind++; - myoptarg = NULL; - - if (myoptind < argc) - myoptarg = argv[myoptind]; - - return -1; - } - - next = argv[myoptind]; - next++; /* skip - */ - myoptind++; - } - - c = *next++; - /* The C++ strchr can return a different value */ - cp = (char*)strchr(optstring, c); - - if (cp == NULL || c == ':') - return '?'; - - cp++; - - if (*cp == ':') { - if (*next != '\0') { - myoptarg = next; - next = NULL; - } - else if (myoptind < argc) { - myoptarg = argv[myoptind]; - myoptind++; - } - else - return '?'; - } - - return c; -} - - -static INLINE WS_NORETURN void err_sys(const char* msg) -{ - printf("server error: %s\n", msg); - -#ifndef __GNUC__ - /* scan-build (which pretends to be gnuc) can get confused and think the - * msg pointer can be null even when hardcoded and then it won't exit, - * making null pointer checks above the err_sys() call useless. - * We could just always exit() but some compilers will complain about no - * possible return, with gcc we know the attribute to handle that with - * WS_NORETURN. */ - if (msg) -#endif - { - exit(EXIT_FAILURE); - } -} - - -static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, - uint16_t port) -{ - int useLookup = 0; - (void)useLookup; - - memset(addr, 0, sizeof(SOCKADDR_IN_T)); - -#ifndef TEST_IPV6 - /* peer could be in human readable form */ - if ( (peer != INADDR_ANY) && isalpha((int)peer[0])) { - #ifdef CYASSL_MDK_ARM - int err; - struct hostent* entry = gethostbyname(peer, &err); - #else - struct hostent* entry = gethostbyname(peer); - #endif - - if (entry) { - memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0], - entry->h_length); - useLookup = 1; - } - else - err_sys("no entry for host"); - } -#endif - -#ifndef TEST_IPV6 - #if defined(CYASSL_MDK_ARM) - addr->sin_family = PF_INET; - #else - addr->sin_family = AF_INET_V; - #endif - addr->sin_port = htons(port); - if (peer == INADDR_ANY) - addr->sin_addr.s_addr = INADDR_ANY; - else { - if (!useLookup) - addr->sin_addr.s_addr = inet_addr(peer); - } -#else - addr->sin6_family = AF_INET_V; - addr->sin6_port = htons(port); - if (peer == INADDR_ANY) - addr->sin6_addr = in6addr_any; - else { - #ifdef HAVE_GETADDRINFO - struct addrinfo hints; - struct addrinfo* answer = NULL; - int ret; - char strPort[80]; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_INET_V; - hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; - - SNPRINTF(strPort, sizeof(strPort), "%d", port); - strPort[79] = '\0'; - - ret = getaddrinfo(peer, strPort, &hints, &answer); - if (ret < 0 || answer == NULL) - err_sys("getaddrinfo failed"); - - memcpy(addr, answer->ai_addr, answer->ai_addrlen); - freeaddrinfo(answer); - #else - printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); - addr->sin6_addr = in6addr_loopback; - #endif - } -#endif -} - - -static INLINE void tcp_socket(SOCKET_T* sockFd) -{ - *sockFd = socket(AF_INET_V, SOCK_STREAM, 0); - -#ifdef USE_WINDOWS_API - if (*sockFd == INVALID_SOCKET) - err_sys("socket failed\n"); -#else - if (*sockFd < 0) - err_sys("socket failed\n"); -#endif - -#ifndef USE_WINDOWS_API -#ifdef SO_NOSIGPIPE - { - int on = 1; - socklen_t len = sizeof(on); - int res = setsockopt(*sockFd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); - if (res < 0) - err_sys("setsockopt SO_NOSIGPIPE failed\n"); - } -#elif defined(CYASSL_MDK_ARM) - /* nothing to define */ -#else /* no S_NOSIGPIPE */ - signal(SIGPIPE, SIG_IGN); -#endif /* S_NOSIGPIPE */ - -#if defined(TCP_NODELAY) - { - int on = 1; - socklen_t len = sizeof(on); - int res = setsockopt(*sockFd, IPPROTO_TCP, TCP_NODELAY, &on, len); - if (res < 0) - err_sys("setsockopt TCP_NODELAY failed\n"); - } -#endif -#endif /* USE_WINDOWS_API */ -} - - -static INLINE void tcp_bind(SOCKET_T* sockFd, uint16_t port, int useAnyAddr) -{ - SOCKADDR_IN_T addr; - - /* don't use INADDR_ANY by default, firewall may block, make user switch - on */ - build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfsshIP), port); - tcp_socket(sockFd); - -#if !defined(USE_WINDOWS_API) && !defined(CYASSL_MDK_ARM) - { - int res, on = 1; - socklen_t len = sizeof(on); - res = setsockopt(*sockFd, SOL_SOCKET, SO_REUSEADDR, &on, len); - if (res < 0) - err_sys("setsockopt SO_REUSEADDR failed\n"); - } -#endif - - if (bind(*sockFd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) - err_sys("tcp bind failed"); -} - - -static uint8_t find_char(const uint8_t* str, const uint8_t* buf, uint32_t bufSz) -{ - const uint8_t* cur; + const byte* cur; while (bufSz) { cur = str; @@ -362,35 +68,36 @@ static uint8_t find_char(const uint8_t* str, const uint8_t* buf, uint32_t bufSz) static int dump_stats(thread_ctx_t* ctx) { char stats[1024]; - uint32_t statsSz; - uint32_t txCount, rxCount, seq, peerSeq; + word32 statsSz; + word32 txCount, rxCount, seq, peerSeq; wolfSSH_GetStats(ctx->ssh, &txCount, &rxCount, &seq, &peerSeq); - sprintf(stats, + WSNPRINTF(stats, sizeof(stats), "Statistics for Thread #%u:\r\n" " txCount = %u\r\n rxCount = %u\r\n" " seq = %u\r\n peerSeq = %u\r\n", ctx->id, txCount, rxCount, seq, peerSeq); - statsSz = (uint32_t)strlen(stats); + statsSz = (word32)strlen(stats); fprintf(stderr, "%s", stats); - return wolfSSH_stream_send(ctx->ssh, (uint8_t*)stats, statsSz); + return wolfSSH_stream_send(ctx->ssh, (byte*)stats, statsSz); } -static THREAD_RETURN CYASSL_THREAD server_worker(void* vArgs) + +static THREAD_RETURN WOLFSSH_THREAD server_worker(void* vArgs) { thread_ctx_t* threadCtx = (thread_ctx_t*)vArgs; if (wolfSSH_accept(threadCtx->ssh) == WS_SUCCESS) { - uint8_t* buf = NULL; - uint8_t* tmpBuf; + byte* buf = NULL; + byte* tmpBuf; int bufSz, backlogSz = 0, rxSz, txSz, stop = 0, txSum; do { bufSz = EXAMPLE_BUFFER_SZ + backlogSz; - tmpBuf = realloc(buf, bufSz); + tmpBuf = (byte*)realloc(buf, bufSz); if (tmpBuf == NULL) stop = 1; else @@ -411,20 +118,25 @@ static THREAD_RETURN CYASSL_THREAD server_worker(void* vArgs) backlogSz - txSum); if (txSz > 0) { - uint8_t c; - const uint8_t matches[] = { 0x03, 0x04, 0x05, 0x00 }; + byte c; + const byte matches[] = { 0x03, 0x05, 0x06, 0x00 }; c = find_char(matches, buf + txSum, txSz); switch (c) { case 0x03: stop = 1; break; + case 0x06: + if (wolfSSH_TriggerKeyExchange(threadCtx->ssh) + != WS_SUCCESS) + stop = 1; + break; case 0x05: if (dump_stats(threadCtx) <= 0) stop = 1; - default: - txSum += txSz; + break; } + txSum += txSz; } else if (txSz != WS_REKEYING) stop = 1; @@ -441,7 +153,7 @@ static THREAD_RETURN CYASSL_THREAD server_worker(void* vArgs) free(buf); } - close(threadCtx->fd); + WCLOSESOCKET(threadCtx->fd); wolfSSH_free(threadCtx->ssh); free(threadCtx); @@ -449,18 +161,18 @@ static THREAD_RETURN CYASSL_THREAD server_worker(void* vArgs) } -static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz) +static int load_file(const char* fileName, byte* buf, word32 bufSz) { FILE* file; - uint32_t fileSz; - uint32_t readSz; + word32 fileSz; + word32 readSz; if (fileName == NULL) return 0; - file = fopen(fileName, "rb"); - if (file == NULL) return 0; + if (WFOPEN(&file, fileName, "rb") != 0) + return 0; fseek(file, 0, SEEK_END); - fileSz = (uint32_t)ftell(file); + fileSz = (word32)ftell(file); rewind(file); if (fileSz > bufSz) { @@ -468,7 +180,7 @@ static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz) return 0; } - readSz = (uint32_t)fread(buf, 1, fileSz, file); + readSz = (word32)fread(buf, 1, fileSz, file); if (readSz < fileSz) { fclose(file); return 0; @@ -480,7 +192,7 @@ static int load_file(const char* fileName, uint8_t* buf, uint32_t bufSz) } -static inline void c32toa(uint32_t u32, uint8_t* c) +static INLINE void c32toa(word32 u32, byte* c) { c[0] = (u32 >> 24) & 0xff; c[1] = (u32 >> 16) & 0xff; @@ -493,10 +205,10 @@ static inline void c32toa(uint32_t u32, uint8_t* c) /* Use arrays for username and p. The password or public key can * be hashed and the hash stored here. Then I won't need the type. */ typedef struct PwMap { - uint8_t type; - uint8_t username[32]; - uint32_t usernameSz; - uint8_t p[SHA256_DIGEST_SIZE]; + byte type; + byte username[32]; + word32 usernameSz; + byte p[SHA256_DIGEST_SIZE]; struct PwMap* next; } PwMap; @@ -506,15 +218,15 @@ typedef struct PwMapList { } PwMapList; -static PwMap* PwMapNew(PwMapList* list, uint8_t type, const uint8_t* username, - uint32_t usernameSz, const uint8_t* p, uint32_t pSz) +static PwMap* PwMapNew(PwMapList* list, byte type, const byte* username, + word32 usernameSz, const byte* p, word32 pSz) { PwMap* map; map = (PwMap*)malloc(sizeof(PwMap)); if (map != NULL) { Sha256 sha; - uint8_t flatSz[4]; + byte flatSz[4]; map->type = type; if (usernameSz >= sizeof(map->username)) @@ -557,7 +269,16 @@ static const char samplePasswordBuffer[] = "jack:fetchapail\n"; -static const char samplePublicKeyBuffer[] = +static const char samplePublicKeyEccBuffer[] = + "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA" + "BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25" + "qUzgDtH7oyaQROUnNvk= hansel\n" + "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA" + "BBBKAtH8cqaDbtJFjtviLobHBmjCtG56DMkP6A4M2H9zX2/YCg1h9bYS7WHd9UQDwXO1Hh" + "IZzRYecXh7SG9P4GhRY= gretel\n"; + + +static const char samplePublicKeyRsaBuffer[] = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho" "MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G" "p2yEhUZUEkDhtOXyqjns1ickC9Gh4u80aSVtwHRnJZh9xPhSq5tLOhId4eP61s+a5pwjTj" @@ -572,7 +293,7 @@ static const char samplePublicKeyBuffer[] = "RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n"; -static int LoadPasswordBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list) +static int LoadPasswordBuffer(byte* buf, word32 bufSz, PwMapList* list) { char* str = (char*)buf; char* delimiter; @@ -598,8 +319,8 @@ static int LoadPasswordBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list) *str = 0; str++; if (PwMapNew(list, WOLFSSH_USERAUTH_PASSWORD, - (uint8_t*)username, (uint32_t)strlen(username), - (uint8_t*)password, (uint32_t)strlen(password)) == NULL ) { + (byte*)username, (word32)strlen(username), + (byte*)password, (word32)strlen(password)) == NULL ) { return -1; } @@ -609,16 +330,16 @@ static int LoadPasswordBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list) } -static int LoadPublicKeyBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list) +static int LoadPublicKeyBuffer(byte* buf, word32 bufSz, PwMapList* list) { char* str = (char*)buf; char* delimiter; - uint8_t* publicKey64; - uint32_t publicKey64Sz; - uint8_t* username; - uint32_t usernameSz; - uint8_t publicKey[300]; - uint32_t publicKeySz; + byte* publicKey64; + word32 publicKey64Sz; + byte* username; + word32 usernameSz; + byte publicKey[300]; + word32 publicKeySz; /* Each line of passwd.txt is in the format * ssh-rsa AAAB3BASE64ENCODEDPUBLICKEYBLOB username\n @@ -634,14 +355,14 @@ static int LoadPublicKeyBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list) delimiter = strchr(str, ' '); str = delimiter + 1; delimiter = strchr(str, ' '); - publicKey64 = (uint8_t*)str; + publicKey64 = (byte*)str; *delimiter = 0; - publicKey64Sz = (uint32_t)(delimiter - str); + publicKey64Sz = (word32)(delimiter - str); str = delimiter + 1; delimiter = strchr(str, '\n'); - username = (uint8_t*)str; + username = (byte*)str; *delimiter = 0; - usernameSz = (uint32_t)(delimiter - str); + usernameSz = (word32)(delimiter - str); str = delimiter + 1; publicKeySz = sizeof(publicKey); @@ -663,13 +384,13 @@ static int LoadPublicKeyBuffer(uint8_t* buf, uint32_t bufSz, PwMapList* list) } -static int wsUserAuth(uint8_t authType, - const WS_UserAuthData* authData, +static int wsUserAuth(byte authType, + WS_UserAuthData* authData, void* ctx) { PwMapList* list; PwMap* map; - uint8_t authHash[SHA256_DIGEST_SIZE]; + byte authHash[SHA256_DIGEST_SIZE]; if (ctx == NULL) { fprintf(stderr, "wsUserAuth: ctx not set"); @@ -685,7 +406,7 @@ static int wsUserAuth(uint8_t authType, /* Hash the password or public key with its length. */ { Sha256 sha; - uint8_t flatSz[4]; + byte flatSz[4]; wc_InitSha256(&sha); if (authType == WOLFSSH_USERAUTH_PASSWORD) { c32toa(authData->sf.password.passwordSz, flatSz); @@ -741,20 +462,21 @@ static void ShowUsage(void) } -int main(int argc, char** argv) +THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) { WOLFSSH_CTX* ctx = NULL; PwMapList pwMapList; SOCKET_T listenFd = 0; - uint32_t defaultHighwater = EXAMPLE_HIGHWATER_MARK; - uint32_t threadCount = 0; + word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK; + word32 threadCount = 0; int multipleConnections = 0; int useEcc = 0; char ch; + word16 port = wolfSshPort; - #ifdef DEBUG_WOLFSSH - wolfSSH_Debugging_ON(); - #endif + int argc = ((func_args*)args)->argc; + char** argv = ((func_args*)args)->argv; + ((func_args*)args)->return_code = 0; while ((ch = mygetopt(argc, argv, "hme")) != -1) { switch (ch) { @@ -793,13 +515,13 @@ int main(int argc, char** argv) wolfSSH_CTX_SetBanner(ctx, echoserverBanner); { - uint8_t buf[SCRATCH_BUFFER_SIZE]; - uint32_t bufSz; + const char* bufName; + byte buf[SCRATCH_BUFFER_SZ]; + word32 bufSz; - bufSz = load_file(useEcc ? - "./keys/server-key-ecc.der" : - "./keys/server-key-rsa.der", - buf, SCRATCH_BUFFER_SIZE); + bufName = useEcc ? "./keys/server-key-ecc.der" : + "./keys/server-key-rsa.der" ; + bufSz = load_file(bufName, buf, SCRATCH_BUFFER_SZ); if (bufSz == 0) { fprintf(stderr, "Couldn't load key file.\n"); exit(EXIT_FAILURE); @@ -810,26 +532,25 @@ int main(int argc, char** argv) exit(EXIT_FAILURE); } - bufSz = (uint32_t)strlen((char*)samplePasswordBuffer); + bufSz = (word32)strlen(samplePasswordBuffer); memcpy(buf, samplePasswordBuffer, bufSz); buf[bufSz] = 0; LoadPasswordBuffer(buf, bufSz, &pwMapList); - bufSz = (uint32_t)strlen((char*)samplePublicKeyBuffer); - memcpy(buf, samplePublicKeyBuffer, bufSz); + bufName = useEcc ? samplePublicKeyEccBuffer : + samplePublicKeyRsaBuffer; + bufSz = (word32)strlen(bufName); + memcpy(buf, bufName, bufSz); buf[bufSz] = 0; LoadPublicKeyBuffer(buf, bufSz, &pwMapList); } - tcp_bind(&listenFd, SERVER_PORT_NUMBER, 0); - - if (listen(listenFd, 5) != 0) - err_sys("tcp listen failed"); + tcp_listen(&listenFd, &port, 0); do { SOCKET_T clientFd = 0; SOCKADDR_IN_T clientAddr; - SOCKLEN_T clientAddrSz = sizeof(clientAddr); + socklen_t clientAddrSz = sizeof(clientAddr); THREAD_TYPE thread; WOLFSSH* ssh; thread_ctx_t* threadCtx; @@ -857,18 +578,18 @@ int main(int argc, char** argv) if (clientFd == -1) err_sys("tcp accept failed"); - wolfSSH_set_fd(ssh, clientFd); + wolfSSH_set_fd(ssh, (int)clientFd); threadCtx->ssh = ssh; threadCtx->fd = clientFd; threadCtx->id = threadCount++; - pthread_create(&thread, 0, server_worker, threadCtx); + start_thread(server_worker, threadCtx, &thread); if (multipleConnections) - pthread_detach(thread); + detach_thread(thread); else - pthread_join(thread, NULL); + join_thread(thread); } while (multipleConnections); @@ -882,5 +603,36 @@ int main(int argc, char** argv) return 0; } -int myoptind = 0; -char* myoptarg = NULL; +#ifndef NO_MAIN_DRIVER + + int main(int argc, char** argv) + { + func_args args; + + args.argc = argc; + args.argv = argv; + args.return_code = 0; + + WSTARTTCP(); + + ChangeToWolfSshRoot(); + #ifdef DEBUG_WOLFSSH + wolfSSH_Debugging_ON(); + #endif + + wolfSSH_Init(); + + #ifndef NO_WOLFSSH_CLIENT + echoserver_test(&args); + #endif /* NO_WOLFSSH_CLIENT */ + + wolfSSH_Cleanup(); + + return args.return_code; + } + + + int myoptind = 0; + char* myoptarg = NULL; + +#endif /* NO_MAIN_DRIVER */ diff --git a/examples/echoserver/echoserver.h b/examples/echoserver/echoserver.h new file mode 100755 index 00000000..87d7542b --- /dev/null +++ b/examples/echoserver/echoserver.h @@ -0,0 +1,31 @@ +/* echoserver.h + * + * Copyright (C) 2014-2017 wolfSSL Inc. + * + * This file is part of wolfSSH. + * + * wolfSSH is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfSSH is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wolfSSH. If not, see . + */ + + +#pragma once + +#ifndef _WOLFSSH_ECHOSERVER_H_ +#define _WOLFSSH_ECHOSERVER_H_ + + +THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args); + + +#endif /* _WOLFSSH_ECHOSERVER_H_ */ diff --git a/ide/winvs/api-test/api-test.vcxproj b/ide/winvs/api-test/api-test.vcxproj index 2e9cfd5c..b553fc57 100644 --- a/ide/winvs/api-test/api-test.vcxproj +++ b/ide/winvs/api-test/api-test.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + @@ -18,6 +26,9 @@ {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7} Win32Proj @@ -30,6 +41,12 @@ v110 Unicode + + Application + true + v110 + Unicode + Application false @@ -37,23 +54,48 @@ true Unicode + + Application + false + v110 + true + Unicode + + + + + + + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ @@ -62,7 +104,25 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;%(AdditionalIncludeDirectories) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) ProgramDatabase @@ -81,11 +141,32 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) Console true + ws2_32.lib;advapi32.lib + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + ws2_32.lib;advapi32.lib true true @@ -93,4 +174,4 @@ - + \ No newline at end of file diff --git a/ide/winvs/echoserver/echoserver.vcxproj b/ide/winvs/echoserver/echoserver.vcxproj index 135ce921..991f3b90 100644 --- a/ide/winvs/echoserver/echoserver.vcxproj +++ b/ide/winvs/echoserver/echoserver.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + @@ -18,6 +26,9 @@ {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D} Win32Proj @@ -30,6 +41,12 @@ v110 Unicode + + Application + true + v110 + Unicode + Application false @@ -37,23 +54,48 @@ true Unicode + + Application + false + v110 + true + Unicode + + + + + + + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ @@ -62,7 +104,25 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;%(AdditionalIncludeDirectories) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) ProgramDatabase @@ -81,11 +141,32 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) Console true + ws2_32.lib;advapi32.lib + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + ws2_32.lib;advapi32.lib true true @@ -93,4 +174,4 @@ - + \ No newline at end of file diff --git a/ide/winvs/include.am b/ide/winvs/include.am index 62cf37dc..e6148e91 100644 --- a/ide/winvs/include.am +++ b/ide/winvs/include.am @@ -5,5 +5,7 @@ EXTRA_DIST+= ide/winvs/README.txt EXTRA_DIST+= ide/winvs/wolfssh.sln EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj +EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj EXTRA_DIST+= ide/winvs/user_settings.h +EXTRA_DIST+= ide/winvs/wolfcrypt/README.txt diff --git a/ide/winvs/unit-test/unit-test.vcxproj b/ide/winvs/unit-test/unit-test.vcxproj new file mode 100644 index 00000000..7db2872e --- /dev/null +++ b/ide/winvs/unit-test/unit-test.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + + + + + + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02} + Win32Proj + unittest + + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + ws2_32.lib;advapi32.lib + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + ws2_32.lib;advapi32.lib + true + true + + + + + + \ No newline at end of file diff --git a/ide/winvs/wolfcrypt/README.txt b/ide/winvs/wolfcrypt/README.txt new file mode 100644 index 00000000..13e1fe15 --- /dev/null +++ b/ide/winvs/wolfcrypt/README.txt @@ -0,0 +1,21 @@ +WOLFCRYPT + +This directory is provided as a convenience for the test and sample +tools to find the wolfSSL library and headers. + +The library should just be copied into this directory with the name +`wolfssl.lib`. The headers that come with the library are in the +directory `wolfssl` and `wolfssl\wolfcrypt`. That wolfssl directory +should be copied here. + +The following is a subset of files and the directories they live in, +as an example. + + src\ssh.c + src\internal.c + wolfcrypt\readme.txt (this file) + wolfcrypt\wolfssl.lib + wolfcrypt\wolfssl\ssl.h + wolfcrypt\wolfssl\options.h + wolfcrypt\wolfssl\wolfcrypt\aes.h + wolfcrypt\wolfssl\wolfcrypt\user_settings.h diff --git a/ide/winvs/wolfssh.sln b/ide/winvs/wolfssh.sln index 7bab7bc7..d73e6530 100644 --- a/ide/winvs/wolfssh.sln +++ b/ide/winvs/wolfssh.sln @@ -13,24 +13,48 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "echoserver", "echoserver\ec {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} = {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-test", "unit-test\unit-test.vcxproj", "{CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.ActiveCfg = Debug|Win32 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.Build.0 = Debug|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.ActiveCfg = Debug|x64 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.Build.0 = Debug|x64 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.ActiveCfg = Release|Win32 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.Build.0 = Release|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.ActiveCfg = Release|x64 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.Build.0 = Release|x64 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.ActiveCfg = Debug|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.Build.0 = Debug|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.ActiveCfg = Debug|x64 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.Build.0 = Debug|x64 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.ActiveCfg = Release|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.Build.0 = Release|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.ActiveCfg = Release|x64 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.Build.0 = Release|x64 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.ActiveCfg = Debug|Win32 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.Build.0 = Debug|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.ActiveCfg = Debug|x64 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.Build.0 = Debug|x64 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.ActiveCfg = Release|Win32 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.Build.0 = Release|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.ActiveCfg = Release|x64 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.Build.0 = Release|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.ActiveCfg = Debug|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.Build.0 = Debug|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.ActiveCfg = Debug|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.Build.0 = Debug|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.ActiveCfg = Release|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.Build.0 = Release|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.ActiveCfg = Release|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ide/winvs/wolfssh/wolfssh.vcxproj b/ide/winvs/wolfssh/wolfssh.vcxproj index b4189465..e5102d2f 100644 --- a/ide/winvs/wolfssh/wolfssh.vcxproj +++ b/ide/winvs/wolfssh/wolfssh.vcxproj @@ -5,10 +5,18 @@ Debug Win32 + + Debug + x64 + Release Win32 + + Release + x64 + @@ -31,6 +39,12 @@ v110 Unicode + + StaticLibrary + true + v110 + Unicode + StaticLibrary false @@ -38,20 +52,45 @@ true Unicode + + StaticLibrary + false + v110 + true + Unicode + + + + + + + $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + @@ -59,7 +98,22 @@ Level3 Disabled WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;%(AdditionalIncludeDirectories) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) ProgramDatabase @@ -75,7 +129,26 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) Windows @@ -87,4 +160,4 @@ - + \ No newline at end of file diff --git a/src/internal.c b/src/internal.c index a5708e79..2f7acd9d 100644 --- a/src/internal.c +++ b/src/internal.c @@ -33,9 +33,11 @@ #include #include #include +#include #include #include #include +#include #ifdef NO_INLINE #include @@ -45,9 +47,18 @@ #endif -static const char sshIdStr[] = "SSH-2.0-wolfSSHv" - LIBWOLFSSH_VERSION_STRING - "\r\n"; +static const char sshProtoIdStr[] = "SSH-2.0-wolfSSHv" + LIBWOLFSSH_VERSION_STRING + "\r\n"; +#ifndef WOLFSSH_DEFAULT_GEXDH_MIN + #define WOLFSSH_DEFAULT_GEXDH_MIN 1024 +#endif +#ifndef WOLFSSH_DEFAULT_GEXDH_PREFERRED + #define WOLFSSH_DEFAULT_GEXDH_PREFERRED 3072 +#endif +#ifndef WOLFSSH_DEFAULT_GEXDH_MAX + #define WOLFSSH_DEFAULT_GEXDH_MAX 8192 +#endif const char* GetErrorString(int err) @@ -157,6 +168,9 @@ const char* GetErrorString(int err) case WS_ECC_E: return "ECDSA buffer error"; + case WS_CHANOPEN_FAILED: + return "peer returned channel open failure"; + default: return "Unknown error code"; } @@ -216,6 +230,9 @@ static HandshakeInfo* HandshakeInfoNew(void* heap) newHs->macId = ID_NONE; newHs->blockSz = MIN_BLOCK_SZ; newHs->hashId = WC_HASH_TYPE_NONE; + newHs->dhGexMinSz = WOLFSSH_DEFAULT_GEXDH_MIN; + newHs->dhGexPreferredSz = WOLFSSH_DEFAULT_GEXDH_PREFERRED; + newHs->dhGexMaxSz = WOLFSSH_DEFAULT_GEXDH_MAX; } return newHs; @@ -228,7 +245,9 @@ static void HandshakeInfoFree(HandshakeInfo* hs, void* heap) WLOG(WS_LOG_DEBUG, "Entering HandshakeInfoFree()"); if (hs) { - WFREE(hs->serverKexInit, heap, DYNTYPE_STRING); + WFREE(hs->kexInit, heap, DYNTYPE_STRING); + WFREE(hs->primeGroup, heap, DYNTYPE_MPINT); + WFREE(hs->generator, heap, DYNTYPE_MPINT); ForceZero(hs, sizeof(HandshakeInfo)); WFREE(hs, heap, DYNTYPE_HS); } @@ -243,12 +262,12 @@ static const char cannedBanner[] = "It should have its own banner, but\r\n" "it is currently using a canned one in " "the library. Be happy or not.\r\n"; -static const uint32_t cannedBannerSz = sizeof(cannedBanner) - 1; +static const word32 cannedBannerSz = sizeof(cannedBanner) - 1; #endif /* DEBUG_WOLFSSH */ -WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, void* heap) +WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, byte side, void* heap) { WLOG(WS_LOG_DEBUG, "Entering CtxInit()"); @@ -260,6 +279,7 @@ WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, void* heap) if (heap) ctx->heap = heap; + ctx->side = side; #ifndef WOLFSSH_USER_IO ctx->ioRecvCb = wsEmbedRecv; ctx->ioSendCb = wsEmbedSend; @@ -322,7 +342,7 @@ WOLFSSH* SshInit(WOLFSSH* ssh, WOLFSSH_CTX* ctx) ssh->highwaterCtx = (void*)ssh; ssh->acceptState = ACCEPT_BEGIN; ssh->clientState = CLIENT_BEGIN; - ssh->keyingState = KEYING_UNKEYED; + ssh->isKeying = 1; ssh->nextChannel = DEFAULT_NEXT_CHANNEL; ssh->blockSz = MIN_BLOCK_SZ; ssh->encryptId = ID_NONE; @@ -354,8 +374,8 @@ void SshResourceFree(WOLFSSH* ssh, void* heap) ShrinkBuffer(&ssh->outputBuffer, 1); ForceZero(ssh->k, ssh->kSz); HandshakeInfoFree(ssh->handshake, heap); - ForceZero(&ssh->clientKeys, sizeof(Keys)); - ForceZero(&ssh->serverKeys, sizeof(Keys)); + ForceZero(&ssh->keys, sizeof(Keys)); + ForceZero(&ssh->peerKeys, sizeof(Keys)); if (ssh->rng) { wc_FreeRng(ssh->rng); WFREE(ssh->rng, heap, DYNTYPE_RNG); @@ -363,8 +383,8 @@ void SshResourceFree(WOLFSSH* ssh, void* heap) if (ssh->userName) { WFREE(ssh->userName, heap, DYNTYPE_STRING); } - if (ssh->clientId) { - WFREE(ssh->clientId, heap, DYNTYPE_STRING); + if (ssh->peerProtoId) { + WFREE(ssh->peerProtoId, heap, DYNTYPE_STRING); } if (ssh->channelList) { WOLFSSH_CHANNEL* cur = ssh->channelList; @@ -378,13 +398,13 @@ void SshResourceFree(WOLFSSH* ssh, void* heap) } -int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz, +int ProcessBuffer(WOLFSSH_CTX* ctx, const byte* in, word32 inSz, int format, int type) { int dynamicType; void* heap; - uint8_t* der; - uint32_t derSz; + byte* der; + word32 derSz; if (ctx == NULL || in == NULL || inSz == 0) return WS_BAD_ARGUMENT; @@ -408,7 +428,7 @@ int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz, return WS_UNIMPLEMENTED_E; else { /* format is ASN1 or RAW */ - der = (uint8_t*)WMALLOC(inSz, heap, dynamicType); + der = (byte*)WMALLOC(inSz, heap, dynamicType); if (der == NULL) return WS_MEMORY_E; WMEMCPY(der, in, inSz); @@ -434,7 +454,7 @@ int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz, RsaKey rsa; ecc_key ecc; } key; - uint32_t scratch = 0; + word32 scratch = 0; int ret; if (wc_InitRsaKey(&key.rsa, NULL) < 0) @@ -473,8 +493,201 @@ int ProcessBuffer(WOLFSSH_CTX* ctx, const uint8_t* in, uint32_t inSz, } +int GenerateKey(byte hashId, byte keyId, + byte* key, word32 keySz, + const byte* k, word32 kSz, + const byte* h, word32 hSz, + const byte* sessionId, word32 sessionIdSz) +{ + word32 blocks, remainder; + wc_HashAlg hash; + byte kPad = 0; + byte pad = 0; + byte kSzFlat[LENGTH_SZ]; + int digestSz; + int ret; + + if (key == NULL || keySz == 0 || + k == NULL || kSz == 0 || + h == NULL || hSz == 0 || + sessionId == NULL || sessionIdSz == 0) { + + WLOG(WS_LOG_DEBUG, "GK: bad argument"); + return WS_BAD_ARGUMENT; + } + + digestSz = wc_HashGetDigestSize(hashId); + if (digestSz == 0) { + WLOG(WS_LOG_DEBUG, "GK: bad hash ID"); + return WS_BAD_ARGUMENT; + } + + if (k[0] & 0x80) kPad = 1; + c32toa(kSz + kPad, kSzFlat); + + blocks = keySz / digestSz; + remainder = keySz % digestSz; + + ret = wc_HashInit(&hash, hashId); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, kSzFlat, LENGTH_SZ); + if (ret == WS_SUCCESS && kPad) + ret = wc_HashUpdate(&hash, hashId, &pad, 1); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, k, kSz); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, h, hSz); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, &keyId, sizeof(keyId)); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, sessionId, sessionIdSz); + + if (ret == WS_SUCCESS) { + if (blocks == 0) { + if (remainder > 0) { + byte lastBlock[WC_MAX_DIGEST_SIZE]; + ret = wc_HashFinal(&hash, hashId, lastBlock); + if (ret == WS_SUCCESS) + WMEMCPY(key, lastBlock, remainder); + } + } + else { + word32 runningKeySz, curBlock; + + runningKeySz = digestSz; + ret = wc_HashFinal(&hash, hashId, key); + + for (curBlock = 1; curBlock < blocks; curBlock++) { + ret = wc_HashInit(&hash, hashId); + if (ret != WS_SUCCESS) break; + ret = wc_HashUpdate(&hash, hashId, kSzFlat, LENGTH_SZ); + if (ret != WS_SUCCESS) break; + if (kPad) + ret = wc_HashUpdate(&hash, hashId, &pad, 1); + if (ret != WS_SUCCESS) break; + ret = wc_HashUpdate(&hash, hashId, k, kSz); + if (ret != WS_SUCCESS) break; + ret = wc_HashUpdate(&hash, hashId, h, hSz); + if (ret != WS_SUCCESS) break; + ret = wc_HashUpdate(&hash, hashId, key, runningKeySz); + if (ret != WS_SUCCESS) break; + ret = wc_HashFinal(&hash, hashId, key + runningKeySz); + if (ret != WS_SUCCESS) break; + runningKeySz += digestSz; + } + + if (remainder > 0) { + byte lastBlock[WC_MAX_DIGEST_SIZE]; + if (ret == WS_SUCCESS) + ret = wc_HashInit(&hash, hashId); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, kSzFlat, LENGTH_SZ); + if (ret == WS_SUCCESS && kPad) + ret = wc_HashUpdate(&hash, hashId, &pad, 1); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, k, kSz); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, h, hSz); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&hash, hashId, key, runningKeySz); + if (ret == WS_SUCCESS) + ret = wc_HashFinal(&hash, hashId, lastBlock); + if (ret == WS_SUCCESS) + WMEMCPY(key + runningKeySz, lastBlock, remainder); + } + } + } + + if (ret != WS_SUCCESS) + ret = WS_CRYPTO_FAILED; + + return ret; +} + + +static int GenerateKeys(WOLFSSH* ssh) +{ + Keys* cK; + Keys* sK; + byte hashId; + int ret = WS_SUCCESS; + + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + else { + if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) { + cK = &ssh->handshake->peerKeys; + sK = &ssh->handshake->keys; + } + else { + cK = &ssh->handshake->keys; + sK = &ssh->handshake->peerKeys; + } + hashId = ssh->handshake->hashId; + } + + if (ret == WS_SUCCESS) + ret = GenerateKey(hashId, 'A', + cK->iv, cK->ivSz, + ssh->k, ssh->kSz, ssh->h, ssh->hSz, + ssh->sessionId, ssh->sessionIdSz); + if (ret == WS_SUCCESS) + ret = GenerateKey(hashId, 'B', + sK->iv, sK->ivSz, + ssh->k, ssh->kSz, ssh->h, ssh->hSz, + ssh->sessionId, ssh->sessionIdSz); + if (ret == WS_SUCCESS) + ret = GenerateKey(hashId, 'C', + cK->encKey, cK->encKeySz, + ssh->k, ssh->kSz, ssh->h, ssh->hSz, + ssh->sessionId, ssh->sessionIdSz); + if (ret == WS_SUCCESS) + ret = GenerateKey(hashId, 'D', + sK->encKey, sK->encKeySz, + ssh->k, ssh->kSz, ssh->h, ssh->hSz, + ssh->sessionId, ssh->sessionIdSz); + if (!ssh->handshake->aeadMode) { + if (ret == WS_SUCCESS) + ret = GenerateKey(hashId, 'E', + cK->macKey, cK->macKeySz, + ssh->k, ssh->kSz, ssh->h, ssh->hSz, + ssh->sessionId, ssh->sessionIdSz); + if (ret == WS_SUCCESS) + ret = GenerateKey(hashId, 'F', + sK->macKey, sK->macKeySz, + ssh->k, ssh->kSz, ssh->h, ssh->hSz, + ssh->sessionId, ssh->sessionIdSz); + } +#ifdef SHOW_SECRETS + if (ret == WS_SUCCESS) { + printf("\n** Showing Secrets **\nK:\n"); + DumpOctetString(ssh->k, ssh->kSz); + printf("H:\n"); + DumpOctetString(ssh->h, ssh->hSz); + printf("Session ID:\n"); + DumpOctetString(ssh->sessionId, ssh->sessionIdSz); + printf("A:\n"); + DumpOctetString(cK->iv, cK->ivSz); + printf("B:\n"); + DumpOctetString(sK->iv, sK->ivSz); + printf("C:\n"); + DumpOctetString(cK->encKey, cK->encKeySz); + printf("D:\n"); + DumpOctetString(sK->encKey, sK->encKeySz); + printf("E:\n"); + DumpOctetString(cK->macKey, cK->macKeySz); + printf("F:\n"); + DumpOctetString(sK->macKey, sK->macKeySz); + printf("\n"); + } +#endif /* SHOW_SECRETS */ + + return ret; +} + + typedef struct { - uint8_t id; + byte id; const char* name; } NameIdPair; @@ -505,6 +718,10 @@ static const NameIdPair NameIdMap[] = { { ID_ECDSA_SHA2_NISTP384, "ecdsa-sha2-nistp384" }, { ID_ECDSA_SHA2_NISTP521, "ecdsa-sha2-nistp521" }, + /* Service IDs */ + { ID_SERVICE_USERAUTH, "ssh-userauth" }, + { ID_SERVICE_CONNECTION, "ssh-connection" }, + /* UserAuth IDs */ { ID_USERAUTH_PASSWORD, "password" }, { ID_USERAUTH_PUBLICKEY, "publickey" }, @@ -514,10 +731,10 @@ static const NameIdPair NameIdMap[] = { }; -uint8_t NameToId(const char* name, uint32_t nameSz) +byte NameToId(const char* name, word32 nameSz) { - uint8_t id = ID_UNKNOWN; - uint32_t i; + byte id = ID_UNKNOWN; + word32 i; for (i = 0; i < (sizeof(NameIdMap)/sizeof(NameIdPair)); i++) { if (nameSz == WSTRLEN(NameIdMap[i].name) && @@ -532,10 +749,10 @@ uint8_t NameToId(const char* name, uint32_t nameSz) } -const char* IdToName(uint8_t id) +const char* IdToName(byte id) { const char* name = "unknown"; - uint32_t i; + word32 i; for (i = 0; i < (sizeof(NameIdMap)/sizeof(NameIdPair)); i++) { if (NameIdMap[i].id == id) { @@ -548,10 +765,8 @@ const char* IdToName(uint8_t id) } -WOLFSSH_CHANNEL* ChannelNew(WOLFSSH* ssh, uint8_t channelType, - uint32_t peerChannel, - uint32_t peerInitialWindowSz, - uint32_t peerMaxPacketSz) +WOLFSSH_CHANNEL* ChannelNew(WOLFSSH* ssh, byte channelType, + word32 initialWindowSz, word32 maxPacketSz) { WOLFSSH_CHANNEL* newChannel = NULL; @@ -566,18 +781,15 @@ WOLFSSH_CHANNEL* ChannelNew(WOLFSSH* ssh, uint8_t channelType, heap, DYNTYPE_CHANNEL); if (newChannel != NULL) { - uint8_t* buffer; + byte* buffer; - buffer = (uint8_t*)WMALLOC(DEFAULT_WINDOW_SZ, heap, DYNTYPE_BUFFER); + buffer = (byte*)WMALLOC(initialWindowSz, heap, DYNTYPE_BUFFER); if (buffer != NULL) { WMEMSET(newChannel, 0, sizeof(WOLFSSH_CHANNEL)); newChannel->channelType = channelType; newChannel->channel = ssh->nextChannel++; - newChannel->windowSz = DEFAULT_WINDOW_SZ; - newChannel->maxPacketSz = DEFAULT_MAX_PACKET_SZ; - newChannel->peerChannel = peerChannel; - newChannel->peerWindowSz = peerInitialWindowSz; - newChannel->peerMaxPacketSz = peerMaxPacketSz; + newChannel->windowSz = initialWindowSz; + newChannel->maxPacketSz = maxPacketSz; /* * In the context of the channel input buffer, the buffer is * a fixed size. The property length will be the insert point @@ -586,7 +798,7 @@ WOLFSSH_CHANNEL* ChannelNew(WOLFSSH* ssh, uint8_t channelType, */ newChannel->inputBuffer.heap = heap; newChannel->inputBuffer.buffer = buffer; - newChannel->inputBuffer.bufferSz = DEFAULT_WINDOW_SZ; + newChannel->inputBuffer.bufferSz = initialWindowSz; newChannel->inputBuffer.dynamicFlag = 1; } else { @@ -621,7 +833,7 @@ void ChannelDelete(WOLFSSH_CHANNEL* channel, void* heap) #define FIND_SELF 0 #define FIND_PEER 1 -WOLFSSH_CHANNEL* ChannelFind(WOLFSSH* ssh, uint32_t channel, uint8_t peer) +WOLFSSH_CHANNEL* ChannelFind(WOLFSSH* ssh, word32 channel, byte peer) { WOLFSSH_CHANNEL* findChannel = NULL; @@ -632,7 +844,7 @@ WOLFSSH_CHANNEL* ChannelFind(WOLFSSH* ssh, uint32_t channel, uint8_t peer) } else { WOLFSSH_CHANNEL* list = ssh->channelList; - uint32_t listSz = ssh->channelListSz; + word32 listSz = ssh->channelListSz; while (list && listSz) { if (channel == ((peer == FIND_PEER) ? @@ -651,7 +863,50 @@ WOLFSSH_CHANNEL* ChannelFind(WOLFSSH* ssh, uint32_t channel, uint8_t peer) } -int ChannelRemove(WOLFSSH* ssh, uint32_t channel, uint8_t peer) +int ChannelUpdate(WOLFSSH_CHANNEL* channel, word32 peerChannelId, + word32 peerInitialWindowSz, word32 peerMaxPacketSz) +{ + int ret = WS_SUCCESS; + + if (channel == NULL) + ret = WS_BAD_ARGUMENT; + else { + channel->peerChannel = peerChannelId; + channel->peerWindowSz = peerInitialWindowSz; + channel->peerMaxPacketSz = peerMaxPacketSz; + } + + return ret; +} + + +static int ChannelAppend(WOLFSSH* ssh, WOLFSSH_CHANNEL* channel) +{ + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering ChannelAppend()"); + + if (ssh == NULL || channel == NULL) + ret = WS_BAD_ARGUMENT; + + if (ssh->channelList == NULL) { + ssh->channelList = channel; + ssh->channelListSz = 1; + } + else { + WOLFSSH_CHANNEL* cur = ssh->channelList; + while (cur->next != NULL) + cur = cur->next; + cur->next = channel; + ssh->channelListSz++; + } + + WLOG(WS_LOG_DEBUG, "Leaving ChannelAppend(), ret = %d", ret); + return ret; +} + + +int ChannelRemove(WOLFSSH* ssh, word32 channel, byte peer) { int ret = WS_SUCCESS; WOLFSSH_CHANNEL* list; @@ -667,7 +922,7 @@ int ChannelRemove(WOLFSSH* ssh, uint32_t channel, uint8_t peer) if (ret == WS_SUCCESS) { WOLFSSH_CHANNEL* prev = NULL; - uint32_t listSz = ssh->channelListSz; + word32 listSz = ssh->channelListSz; while (list && listSz) { if (channel == ((peer == FIND_PEER) ? @@ -695,7 +950,7 @@ int ChannelRemove(WOLFSSH* ssh, uint32_t channel, uint8_t peer) } -int ChannelPutData(WOLFSSH_CHANNEL* channel, uint8_t* data, uint32_t dataSz) +int ChannelPutData(WOLFSSH_CHANNEL* channel, byte* data, word32 dataSz) { Buffer* inBuf; @@ -725,7 +980,7 @@ int ChannelPutData(WOLFSSH_CHANNEL* channel, uint8_t* data, uint32_t dataSz) } -int BufferInit(Buffer* buffer, uint32_t size, void* heap) +int BufferInit(Buffer* buffer, word32 size, void* heap) { if (buffer == NULL) return WS_BAD_ARGUMENT; @@ -737,7 +992,7 @@ int BufferInit(Buffer* buffer, uint32_t size, void* heap) buffer->heap = heap; buffer->bufferSz = size; if (size > STATIC_BUFFER_LEN) { - buffer->buffer = (uint8_t*)WMALLOC(size, heap, DYNTYPE_BUFFER); + buffer->buffer = (byte*)WMALLOC(size, heap, DYNTYPE_BUFFER); if (buffer->buffer == NULL) return WS_MEMORY_E; buffer->dynamicFlag = 1; @@ -749,7 +1004,7 @@ int BufferInit(Buffer* buffer, uint32_t size, void* heap) } -int GrowBuffer(Buffer* buf, uint32_t sz, uint32_t usedSz) +int GrowBuffer(Buffer* buf, word32 sz, word32 usedSz) { #if 0 WLOG(WS_LOG_DEBUG, "GB: buf = %p", buf); @@ -759,11 +1014,11 @@ int GrowBuffer(Buffer* buf, uint32_t sz, uint32_t usedSz) /* New buffer will end up being sz+usedSz long * empty space at the head of the buffer will be compressed */ if (buf != NULL) { - uint32_t newSz = sz + usedSz; + word32 newSz = sz + usedSz; /*WLOG(WS_LOG_DEBUG, "GB: newSz = %d", newSz);*/ if (newSz > buf->bufferSz) { - uint8_t* newBuffer = (uint8_t*)WMALLOC(newSz, + byte* newBuffer = (byte*)WMALLOC(newSz, buf->heap, DYNTYPE_BUFFER); if (newBuffer == NULL) @@ -794,7 +1049,7 @@ void ShrinkBuffer(Buffer* buf, int forcedFree) WLOG(WS_LOG_DEBUG, "Entering ShrinkBuffer()"); if (buf != NULL) { - uint32_t usedSz = buf->length - buf->idx; + word32 usedSz = buf->length - buf->idx; WLOG(WS_LOG_DEBUG, "SB: usedSz = %u, forcedFree = %u", usedSz, forcedFree); @@ -822,7 +1077,7 @@ void ShrinkBuffer(Buffer* buf, int forcedFree) } -static int Receive(WOLFSSH* ssh, uint8_t* buf, uint32_t sz) +static int Receive(WOLFSSH* ssh, byte* buf, word32 sz) { int recvd; @@ -864,7 +1119,7 @@ retry: } -static int GetInputText(WOLFSSH* ssh, uint8_t** pEol) +static int GetInputText(WOLFSSH* ssh, byte** pEol) { int gotLine = 0; int inSz = 255; @@ -899,7 +1154,7 @@ static int GetInputText(WOLFSSH* ssh, uint8_t** pEol) } while (!gotLine && inSz); if (pEol) - *pEol = (uint8_t*)eol; + *pEol = (byte*)eol; return (gotLine ? WS_SUCCESS : WS_VERSION_E); } @@ -935,7 +1190,7 @@ static int SendBuffered(WOLFSSH* ssh) return WS_SOCKET_ERROR_E; } - if ((uint32_t)sent > ssh->outputBuffer.length) { + if ((word32)sent > ssh->outputBuffer.length) { WLOG(WS_LOG_DEBUG, "SendBuffered() out of bounds read"); return WS_SEND_OOB_READ_E; } @@ -955,27 +1210,7 @@ static int SendBuffered(WOLFSSH* ssh) } -static int SendText(WOLFSSH* ssh, const char* text, uint32_t textLen) -{ - int ret = WS_SUCCESS; - - if (ssh == NULL) - ret = WS_BAD_ARGUMENT; - - if (ret == WS_SUCCESS) - ret = GrowBuffer(&ssh->outputBuffer, textLen, 0); - - if (ret == WS_SUCCESS) { - WMEMCPY(ssh->outputBuffer.buffer, text, textLen); - ssh->outputBuffer.length = textLen; - ret = SendBuffered(ssh); - } - - return ret; -} - - -static int GetInputData(WOLFSSH* ssh, uint32_t size) +static int GetInputData(WOLFSSH* ssh, word32 size) { int in; int inSz; @@ -1046,7 +1281,7 @@ static int GetInputData(WOLFSSH* ssh, uint32_t size) } -static int GetBoolean(uint8_t* v, uint8_t* buf, uint32_t len, uint32_t* idx) +static int GetBoolean(byte* v, byte* buf, word32 len, word32* idx) { int result = WS_BUFFER_E; @@ -1060,7 +1295,7 @@ static int GetBoolean(uint8_t* v, uint8_t* buf, uint32_t len, uint32_t* idx) } -static int GetUint32(uint32_t* v, uint8_t* buf, uint32_t len, uint32_t* idx) +static int GetUint32(word32* v, byte* buf, word32 len, word32* idx) { int result = WS_BUFFER_E; @@ -1074,13 +1309,38 @@ static int GetUint32(uint32_t* v, uint8_t* buf, uint32_t len, uint32_t* idx) } -/* Gets the size of a string, copies it as much of it as will fit in - * the provided buffer, and terminates it with a NULL. */ -static int GetString(char* s, uint32_t* sSz, - uint8_t* buf, uint32_t len, uint32_t *idx) +#ifndef WOLFSSH_NO_CLIENT +/* Gets the size of the mpint, and puts the pointer to the start of + * buf's number into *mpint. This function does not copy. */ +static int GetMpint(word32* mpintSz, byte** mpint, + byte* buf, word32 len, word32* idx) { int result; - uint32_t strSz; + + result = GetUint32(mpintSz, buf, len, idx); + + if (result == WS_SUCCESS) { + result = WS_BUFFER_E; + + if (*idx < len && *idx + *mpintSz <= len) { + *mpint = buf + *idx; + *idx += *mpintSz; + result = WS_SUCCESS; + } + } + + return result; +} +#endif /* WOLFSSH_NO_CLIENT */ + + +/* Gets the size of a string, copies it as much of it as will fit in + * the provided buffer, and terminates it with a NULL. */ +static int GetString(char* s, word32* sSz, + byte* buf, word32 len, word32 *idx) +{ + int result; + word32 strSz; result = GetUint32(&strSz, buf, len, idx); @@ -1099,17 +1359,17 @@ static int GetString(char* s, uint32_t* sSz, } -static int DoNameList(uint8_t* idList, uint32_t* idListSz, - uint8_t* buf, uint32_t len, uint32_t* idx) +static int GetNameList(byte* idList, word32* idListSz, + byte* buf, word32 len, word32* idx) { - uint8_t idListIdx; - uint32_t nameListSz, nameListIdx; - uint32_t begin; - uint8_t* name; - uint32_t nameSz; + byte idListIdx; + word32 nameListSz, nameListIdx; + word32 begin; + byte* name; + word32 nameSz; int ret = WS_SUCCESS; - WLOG(WS_LOG_DEBUG, "Entering DoNameList()"); + WLOG(WS_LOG_DEBUG, "Entering GetNameList()"); if (idList == NULL || idListSz == NULL || buf == NULL || len == 0 || idx == NULL) { @@ -1147,14 +1407,13 @@ static int DoNameList(uint8_t* idList, uint32_t* idListSz, nameSz++; if (nameListIdx == nameListSz || name[nameSz] == ',') { - uint8_t id; + byte id; id = NameToId((char*)name, nameSz); { const char* displayName = IdToName(id); if (displayName) { - /*WLOG(WS_LOG_DEBUG, - "DNL: name ID = %s", displayName);*/ + WLOG(WS_LOG_DEBUG, "DNL: name ID = %s", displayName); } } if (id != ID_UNKNOWN) @@ -1172,36 +1431,36 @@ static int DoNameList(uint8_t* idList, uint32_t* idListSz, *idx = begin; } - WLOG(WS_LOG_DEBUG, "Leaving DoNameList(), ret = %d", ret); + WLOG(WS_LOG_DEBUG, "Leaving GetNameList(), ret = %d", ret); return ret; } -static const uint8_t cannedEncAlgo[] = {ID_AES128_GCM, ID_AES128_CBC}; -static const uint8_t cannedMacAlgo[] = {ID_HMAC_SHA2_256, ID_HMAC_SHA1_96, +static const byte cannedEncAlgo[] = {ID_AES128_GCM, ID_AES128_CBC}; +static const byte cannedMacAlgo[] = {ID_HMAC_SHA2_256, ID_HMAC_SHA1_96, ID_HMAC_SHA1}; -static const uint8_t cannedKeyAlgoRsa[] = {ID_SSH_RSA}; -static const uint8_t cannedKeyAlgoEcc256[] = {ID_ECDSA_SHA2_NISTP256}; -static const uint8_t cannedKeyAlgoEcc384[] = {ID_ECDSA_SHA2_NISTP384}; -static const uint8_t cannedKeyAlgoEcc521[] = {ID_ECDSA_SHA2_NISTP521}; -static const uint8_t cannedKexAlgo[] = {ID_ECDH_SHA2_NISTP256, +static const byte cannedKeyAlgoRsa[] = {ID_SSH_RSA}; +static const byte cannedKeyAlgoEcc256[] = {ID_ECDSA_SHA2_NISTP256}; +static const byte cannedKeyAlgoEcc384[] = {ID_ECDSA_SHA2_NISTP384}; +static const byte cannedKeyAlgoEcc521[] = {ID_ECDSA_SHA2_NISTP521}; +static const byte cannedKexAlgo[] = {ID_ECDH_SHA2_NISTP256, ID_DH_GEX_SHA256, ID_DH_GROUP14_SHA1, ID_DH_GROUP1_SHA1}; -static const uint32_t cannedEncAlgoSz = sizeof(cannedEncAlgo); -static const uint32_t cannedMacAlgoSz = sizeof(cannedMacAlgo); -static const uint32_t cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa); -static const uint32_t cannedKeyAlgoEcc256Sz = sizeof(cannedKeyAlgoEcc256); -static const uint32_t cannedKeyAlgoEcc384Sz = sizeof(cannedKeyAlgoEcc384); -static const uint32_t cannedKeyAlgoEcc521Sz = sizeof(cannedKeyAlgoEcc521); -static const uint32_t cannedKexAlgoSz = sizeof(cannedKexAlgo); +static const word32 cannedEncAlgoSz = sizeof(cannedEncAlgo); +static const word32 cannedMacAlgoSz = sizeof(cannedMacAlgo); +static const word32 cannedKeyAlgoRsaSz = sizeof(cannedKeyAlgoRsa); +static const word32 cannedKeyAlgoEcc256Sz = sizeof(cannedKeyAlgoEcc256); +static const word32 cannedKeyAlgoEcc384Sz = sizeof(cannedKeyAlgoEcc384); +static const word32 cannedKeyAlgoEcc521Sz = sizeof(cannedKeyAlgoEcc521); +static const word32 cannedKexAlgoSz = sizeof(cannedKexAlgo); -static uint8_t MatchIdLists(const uint8_t* left, uint32_t leftSz, - const uint8_t* right, uint32_t rightSz) +static byte MatchIdLists(const byte* left, word32 leftSz, + const byte* right, word32 rightSz) { - uint32_t i, j; + word32 i, j; if (left != NULL && leftSz > 0 && right != NULL && rightSz > 0) { for (i = 0; i < leftSz; i++) { @@ -1220,7 +1479,7 @@ static uint8_t MatchIdLists(const uint8_t* left, uint32_t leftSz, } -static INLINE uint8_t BlockSzForId(uint8_t id) +static INLINE byte BlockSzForId(byte id) { switch (id) { case ID_AES128_CBC: @@ -1232,7 +1491,7 @@ static INLINE uint8_t BlockSzForId(uint8_t id) } -static INLINE uint8_t MacSzForId(uint8_t id) +static INLINE byte MacSzForId(byte id) { switch (id) { case ID_HMAC_SHA1: @@ -1247,7 +1506,7 @@ static INLINE uint8_t MacSzForId(uint8_t id) } -static INLINE uint8_t KeySzForId(uint8_t id) +static INLINE byte KeySzForId(byte id) { switch (id) { case ID_HMAC_SHA1: @@ -1264,7 +1523,7 @@ static INLINE uint8_t KeySzForId(uint8_t id) } -static INLINE uint8_t HashForId(uint8_t id) +static INLINE byte HashForId(byte id) { switch (id) { case ID_DH_GROUP1_SHA1: @@ -1287,7 +1546,7 @@ static INLINE uint8_t HashForId(uint8_t id) } -static INLINE int wcPrimeForId(uint8_t id) +static INLINE int wcPrimeForId(byte id) { switch (id) { case ID_ECDH_SHA2_NISTP256: @@ -1303,7 +1562,7 @@ static INLINE int wcPrimeForId(uint8_t id) return ECC_CURVE_INVALID; } } -static INLINE const char *PrimeNameForId(uint8_t id) +static INLINE const char *PrimeNameForId(byte id) { switch (id) { case ID_ECDH_SHA2_NISTP256: @@ -1321,20 +1580,20 @@ static INLINE const char *PrimeNameForId(uint8_t id) } -static INLINE uint8_t AeadModeForId(uint8_t id) +static INLINE byte AeadModeForId(byte id) { return (id == ID_AES128_GCM); } -static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) +static int DoKexInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { int ret = WS_SUCCESS; - uint8_t algoId; - uint8_t list[6]; - uint32_t listSz; - uint32_t skipSz; - uint32_t begin; + byte algoId; + byte list[6]; + word32 listSz; + word32 skipSz; + word32 begin; WLOG(WS_LOG_DEBUG, "Entering DoKexInit()"); @@ -1375,7 +1634,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: KEX Algorithms"); listSz = 2; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS) { algoId = MatchIdLists(list, listSz, cannedKexAlgo, cannedKexAlgoSz); if (algoId == ID_UNKNOWN) { @@ -1393,10 +1652,10 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: Server Host Key Algorithms"); listSz = 1; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS) { - const uint8_t *cannedKeyAlgo; - uint32_t cannedKeyAlgoSz; + const byte *cannedKeyAlgo; + word32 cannedKeyAlgoSz; switch (ssh->ctx->useEcc) { case ECC_SECP256R1: @@ -1430,7 +1689,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Client to Server"); listSz = 3; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS) { algoId = MatchIdLists(list, listSz, cannedEncAlgo, cannedEncAlgoSz); if (algoId == ID_UNKNOWN) { @@ -1444,7 +1703,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: Enc Algorithms - Server to Client"); listSz = 3; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Encryption Algo S2C"); ret = WS_INVALID_ALGO_ID; @@ -1453,17 +1712,17 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) ssh->handshake->encryptId = algoId; ssh->handshake->aeadMode = AeadModeForId(algoId); ssh->handshake->blockSz = BlockSzForId(algoId); - ssh->handshake->clientKeys.encKeySz = - ssh->handshake->serverKeys.encKeySz = + ssh->handshake->keys.encKeySz = + ssh->handshake->peerKeys.encKeySz = KeySzForId(algoId); if (!ssh->handshake->aeadMode) { - ssh->handshake->clientKeys.ivSz = - ssh->handshake->serverKeys.ivSz = + ssh->handshake->keys.ivSz = + ssh->handshake->peerKeys.ivSz = ssh->handshake->blockSz; } else { - ssh->handshake->clientKeys.ivSz = - ssh->handshake->serverKeys.ivSz = + ssh->handshake->keys.ivSz = + ssh->handshake->peerKeys.ivSz = AEAD_NONCE_SZ; ssh->handshake->macSz = ssh->handshake->blockSz; } @@ -1474,7 +1733,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Client to Server"); listSz = 2; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS && !ssh->aeadMode) { algoId = MatchIdLists(list, listSz, cannedMacAlgo, cannedMacAlgoSz); if (algoId == ID_UNKNOWN) { @@ -1488,7 +1747,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: MAC Algorithms - Server to Client"); listSz = 2; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS && !ssh->handshake->aeadMode) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate MAC Algo S2C"); @@ -1497,8 +1756,8 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) else { ssh->handshake->macId = algoId; ssh->handshake->macSz = MacSzForId(algoId); - ssh->handshake->clientKeys.macKeySz = - ssh->handshake->serverKeys.macKeySz = + ssh->handshake->keys.macKeySz = + ssh->handshake->peerKeys.macKeySz = KeySzForId(algoId); } } @@ -1511,7 +1770,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Client to Server"); listSz = 1; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo C2S"); @@ -1524,7 +1783,7 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { WLOG(WS_LOG_DEBUG, "DKI: Compression Algorithms - Server to Client"); listSz = 1; - ret = DoNameList(list, &listSz, buf, len, &begin); + ret = GetNameList(list, &listSz, buf, len, &begin); if (ret == WS_SUCCESS) { if (MatchIdLists(list, listSz, &algoId, 1) == ID_UNKNOWN) { WLOG(WS_LOG_DEBUG, "Unable to negotiate Compression Algo S2C"); @@ -1564,30 +1823,26 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) } if (ret == WS_SUCCESS) { - uint8_t scratchLen[LENGTH_SZ]; - uint32_t strSz; + byte scratchLen[LENGTH_SZ]; + word32 strSz; - if (ssh->keyingState == KEYING_UNKEYED || - ssh->keyingState == KEYING_KEYED) { - - WLOG(WS_LOG_DEBUG, "KeyingState now KEXINIT_RECV"); - ssh->keyingState = KEYING_KEXINIT_RECV; + if (!ssh->isKeying) { + WLOG(WS_LOG_DEBUG, "Keying initiated"); ret = SendKexInit(ssh); } - else if (ssh->keyingState == KEYING_KEXINIT_SENT) { - WLOG(WS_LOG_DEBUG, "KeyingState now KEXINIT_DONE"); - ssh->keyingState = KEYING_KEXINIT_DONE; - } if (ret == WS_SUCCESS) ret = wc_HashInit(&ssh->handshake->hash, ssh->handshake->hashId); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, - ssh->clientId, ssh->clientIdSz); + if (ret == WS_SUCCESS) { + if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + ssh->peerProtoId, ssh->peerProtoIdSz); + } if (ret == WS_SUCCESS) { - strSz = (uint32_t)WSTRLEN(sshIdStr) - SSH_PROTO_EOL_SZ; + strSz = (word32)WSTRLEN(sshProtoIdStr) - SSH_PROTO_EOL_SZ; c32toa(strSz, scratchLen); ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, scratchLen, LENGTH_SZ); @@ -1595,7 +1850,20 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, - (const uint8_t*)sshIdStr, strSz); + (const byte*)sshProtoIdStr, strSz); + + if (ret == WS_SUCCESS) { + if (ssh->ctx->side == WOLFSSH_ENDPOINT_CLIENT) { + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + ssh->peerProtoId, ssh->peerProtoIdSz); + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + ssh->handshake->kexInit, + ssh->handshake->kexInitSz); + } + } if (ret == WS_SUCCESS) { c32toa(len + 1, scratchLen); @@ -1613,14 +1881,20 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, buf, len); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, - ssh->handshake->serverKexInit, - ssh->handshake->serverKexInitSz); + if (ret == WS_SUCCESS) { + if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + ssh->handshake->kexInit, + ssh->handshake->kexInitSz); + } if (ret == WS_SUCCESS) { *idx = begin; - ssh->clientState = CLIENT_KEXINIT_DONE; + if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) + ssh->clientState = CLIENT_KEXINIT_DONE; + else + ssh->serverState = SERVER_KEXINIT_DONE; } } @@ -1629,8 +1903,8 @@ static int DoKexInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) } -static const uint8_t dhGenerator[] = { 2 }; -static const uint8_t dhPrimeGroup1[] = { +static const byte dhGenerator[] = { 2 }; +static const byte dhPrimeGroup1[] = { /* SSH DH Group 1 (Oakley Group 2, 1024-bit MODP Group, RFC 2409) */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, @@ -1649,7 +1923,7 @@ static const uint8_t dhPrimeGroup1[] = { 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -static const uint8_t dhPrimeGroup14[] = { +static const byte dhPrimeGroup14[] = { /* SSH DH Group 14 (Oakley Group 14, 2048-bit MODP Group, RFC 3526) */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, @@ -1685,12 +1959,12 @@ static const uint8_t dhPrimeGroup14[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; -static const uint32_t dhGeneratorSz = sizeof(dhGenerator); -static const uint32_t dhPrimeGroup1Sz = sizeof(dhPrimeGroup1); -static const uint32_t dhPrimeGroup14Sz = sizeof(dhPrimeGroup14); +static const word32 dhGeneratorSz = sizeof(dhGenerator); +static const word32 dhPrimeGroup1Sz = sizeof(dhPrimeGroup1); +static const word32 dhPrimeGroup14Sz = sizeof(dhPrimeGroup14); -static int DoKexDhInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) +static int DoKexDhInit(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { /* First get the length of the MP_INT, and then add in the hash of the * mp_int value of e as it appears in the packet. After that, decode e @@ -1701,13 +1975,11 @@ static int DoKexDhInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) * in the message isn't of the DH e value. Treat the Q as e. */ /* DYNTYPE_DH */ - uint8_t* e; - uint32_t eSz; - uint32_t begin; + byte* e; + word32 eSz; + word32 begin; int ret = WS_SUCCESS; - (void)len; - if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) ret = WS_BAD_ARGUMENT; @@ -1735,7 +2007,318 @@ static int DoKexDhInit(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) } -static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) +#ifndef WOLFSSH_NO_CLIENT +static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) +{ + byte* pubKey; + word32 pubKeySz; + byte* f; + word32 fSz; + byte* sig; + word32 sigSz; + word32 scratch; + byte scratchLen[LENGTH_SZ]; + word32 kPad = 0; + struct { + byte useRsa; + word32 keySz; + union { + struct { + RsaKey key; + } rsa; + struct { + ecc_key key; + } ecc; + } sk; + } sigKeyBlock; + word32 begin; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoKexDhReply()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + begin = *idx; + pubKey = buf + begin; + ret = GetUint32(&pubKeySz, buf, len, &begin); + } + + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + pubKey, pubKeySz + LENGTH_SZ); + + if (ret == WS_SUCCESS) { + pubKey = buf + begin; + begin += pubKeySz; + } + + /* If using DH-GEX include the GEX specific values. */ + if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { + byte primeGroupPad = 0, generatorPad = 0; + + /* Hash in the client's requested minimum key size. */ + if (ret == 0) { + c32toa(ssh->handshake->dhGexMinSz, scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + /* Hash in the client's requested preferred key size. */ + if (ret == 0) { + c32toa(ssh->handshake->dhGexPreferredSz, scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + /* Hash in the client's requested maximum key size. */ + if (ret == 0) { + c32toa(ssh->handshake->dhGexMaxSz, scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + /* Add a pad byte if the mpint has the MSB set. */ + if (ret == 0) { + if (ssh->handshake->primeGroup[0] & 0x80) + primeGroupPad = 1; + + /* Hash in the length of the GEX prime group. */ + c32toa(ssh->handshake->primeGroupSz + primeGroupPad, + scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + /* Hash in the pad byte for the GEX prime group. */ + if (ret == 0) { + if (primeGroupPad) { + scratchLen[0] = 0; + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, 1); + } + } + /* Hash in the GEX prime group. */ + if (ret == 0) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + ssh->handshake->primeGroup, + ssh->handshake->primeGroupSz); + /* Add a pad byte if the mpint has the MSB set. */ + if (ret == 0) { + if (ssh->handshake->generator[0] & 0x80) + generatorPad = 1; + + /* Hash in the length of the GEX generator. */ + c32toa(ssh->handshake->generatorSz + generatorPad, scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + /* Hash in the pad byte for the GEX generator. */ + if (ret == 0) { + if (generatorPad) { + scratchLen[0] = 0; + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + scratchLen, 1); + } + } + /* Hash in the GEX generator. */ + if (ret == 0) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + ssh->handshake->generator, + ssh->handshake->generatorSz); + } + + /* Hash in the size of the client's DH e-value (ECDH Q-value). */ + if (ret == 0) { + c32toa(ssh->handshake->eSz, scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + /* Hash in the client's DH e-value (ECDH Q-value). */ + if (ret == 0) + ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, + ssh->handshake->e, ssh->handshake->eSz); + + /* Get and hash in the server's DH f-value (ECDH Q-value) */ + if (ret == WS_SUCCESS) { + f = buf + begin; + ret = GetUint32(&fSz, buf, len, &begin); + } + + if (ret == WS_SUCCESS) + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, + f, fSz + LENGTH_SZ); + + if (ret == WS_SUCCESS) { + f = buf + begin; + begin += fSz; + ret = GetUint32(&sigSz, buf, len, &begin); + } + + if (ret == WS_SUCCESS) { + sig = buf + begin; + begin += sigSz; + *idx = begin; + + /* Load in the server's public signing key */ + sigKeyBlock.useRsa = ssh->handshake->pubKeyId == ID_SSH_RSA; + + if (sigKeyBlock.useRsa) { + byte* e; + word32 eSz; + byte* n; + word32 nSz; + word32 pubKeyIdx = 0; + + ret = wc_InitRsaKey(&sigKeyBlock.sk.rsa.key, ssh->ctx->heap); + if (ret != 0) + ret = WS_RSA_E; + if (ret == 0) + ret = GetUint32(&scratch, pubKey, pubKeySz, &pubKeyIdx); + /* This is the algo name. */ + if (ret == WS_SUCCESS) { + pubKeyIdx += scratch; + ret = GetUint32(&eSz, pubKey, pubKeySz, &pubKeyIdx); + } + if (ret == WS_SUCCESS) { + e = pubKey + pubKeyIdx; + pubKeyIdx += eSz; + ret = GetUint32(&nSz, pubKey, pubKeySz, &pubKeyIdx); + } + if (ret == WS_SUCCESS) { + n = pubKey + pubKeyIdx; + ret = wc_RsaPublicKeyDecodeRaw(n, nSz, e, eSz, + &sigKeyBlock.sk.rsa.key); + } + + if (ret == 0) + sigKeyBlock.keySz = sizeof(sigKeyBlock.sk.rsa.key); + else + ret = WS_RSA_E; + } + else { + ret = wc_ecc_init_ex(&sigKeyBlock.sk.ecc.key, ssh->ctx->heap, + INVALID_DEVID); + if (ret == 0) + ret = wc_ecc_import_x963(pubKey, pubKeySz, + &sigKeyBlock.sk.ecc.key); + if (ret == 0) + sigKeyBlock.keySz = sizeof(sigKeyBlock.sk.ecc.key); + else + ret = WS_ECC_E; + } + + /* Generate and hash in the shared secret */ + if (ret == 0) { + if (!ssh->handshake->useEcc) { + ret = wc_DhAgree(&ssh->handshake->privKey.dh, + ssh->k, &ssh->kSz, + ssh->handshake->x, ssh->handshake->xSz, + f, fSz); + ForceZero(ssh->handshake->x, ssh->handshake->xSz); + wc_FreeDhKey(&ssh->handshake->privKey.dh); + } + else { + ecc_key key; + ret = wc_ecc_init(&key); + if (ret == 0) + ret = wc_ecc_import_x963(f, fSz, &key); + if (ret == 0) + ret = wc_ecc_shared_secret(&ssh->handshake->privKey.ecc, + &key, ssh->k, &ssh->kSz); + wc_ecc_free(&key); + wc_ecc_free(&ssh->handshake->privKey.ecc); + } + } + + /* Hash in the shared secret K. */ + if (ret == 0) { + kPad = (ssh->k[0] & 0x80) ? 1 : 0; + c32toa(ssh->kSz + kPad, scratchLen); + ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, + scratchLen, LENGTH_SZ); + } + if (ret == 0) { + if (kPad) { + scratchLen[0] = 0; + ret = wc_HashUpdate(&ssh->handshake->hash, + ssh->handshake->hashId, scratchLen, 1); + } + } + if (ret == 0) + ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, + ssh->k, ssh->kSz); + + /* Save the exchange hash value H, and session ID. */ + if (ret == 0) + ret = wc_HashFinal(&ssh->handshake->hash, + ssh->handshake->hashId, ssh->h); + if (ret == 0) { + ssh->hSz = wc_HashGetDigestSize(ssh->handshake->hashId); + if (ssh->sessionIdSz == 0) { + WMEMCPY(ssh->sessionId, ssh->h, ssh->hSz); + ssh->sessionIdSz = ssh->hSz; + } + } + + if (ret != WS_SUCCESS) + ret = WS_CRYPTO_FAILED; + } + + /* Verify h with the server's public key. */ + if (ret == WS_SUCCESS) { + /* Skip past the sig name. Check it, though. Other SSH implementations + * do the verify based on the name, despite what was agreed upon. XXX*/ + begin = 0; + ret = GetUint32(&scratch, sig, sigSz, &begin); + if (ret == WS_SUCCESS) { + begin += scratch; + ret = GetUint32(&scratch, sig, sigSz, &begin); + } + if (ret == WS_SUCCESS) { + sig = sig + begin; + sigSz = scratch; + + ret = wc_SignatureVerify(HashForId(ssh->handshake->pubKeyId), + sigKeyBlock.useRsa ? + WC_SIGNATURE_TYPE_RSA_W_ENC : + WC_SIGNATURE_TYPE_ECC, + ssh->h, ssh->hSz, sig, sigSz, + &sigKeyBlock.sk, sigKeyBlock.keySz); + if (ret != 0) { + WLOG(WS_LOG_DEBUG, + "DoKexDhReply: Signature Verify fail (%d)", ret); + ret = sigKeyBlock.useRsa ? WS_RSA_E : WS_ECC_E; + } + } + } + + if (sigKeyBlock.useRsa) + wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key); + else + wc_ecc_free(&sigKeyBlock.sk.ecc.key); + + if (ret == WS_SUCCESS) + ret = GenerateKeys(ssh); + + if (ret == WS_SUCCESS) + ret = SendNewKeys(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving DoKexDhReply(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + +static int DoNewKeys(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { int ret = WS_SUCCESS; @@ -1752,7 +2335,7 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) ssh->peerBlockSz = ssh->handshake->blockSz; ssh->peerMacSz = ssh->handshake->macSz; ssh->peerAeadMode = ssh->handshake->aeadMode; - WMEMCPY(&ssh->clientKeys, &ssh->handshake->clientKeys, sizeof(Keys)); + WMEMCPY(&ssh->peerKeys, &ssh->handshake->peerKeys, sizeof(Keys)); switch (ssh->peerEncryptId) { case ID_NONE: @@ -1762,16 +2345,15 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) case ID_AES128_CBC: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-cbc"); ret = wc_AesSetKey(&ssh->decryptCipher.aes, - ssh->clientKeys.encKey, - ssh->clientKeys.encKeySz, - ssh->clientKeys.iv, AES_DECRYPTION); + ssh->peerKeys.encKey, ssh->peerKeys.encKeySz, + ssh->peerKeys.iv, AES_DECRYPTION); break; case ID_AES128_GCM: WLOG(WS_LOG_DEBUG, "DNK: peer using cipher aes128-gcm"); ret = wc_AesGcmSetKey(&ssh->decryptCipher.aes, - ssh->clientKeys.encKey, - ssh->clientKeys.encKeySz); + ssh->peerKeys.encKey, + ssh->peerKeys.encKeySz); break; default: @@ -1787,18 +2369,11 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) if (ret == WS_SUCCESS) { ssh->rxCount = 0; - if (ssh->keyingState == KEYING_USING_KEYS_SENT) { - ssh->clientState = CLIENT_USING_KEYS; - ssh->highwaterFlag = 0; - ssh->keyingState = KEYING_KEYED; - HandshakeInfoFree(ssh->handshake, ssh->ctx->heap); - ssh->handshake = NULL; - WLOG(WS_LOG_DEBUG, "KeyingState now KEYED"); - } - else { - ssh->keyingState = KEYING_USING_KEYS_RECV; - WLOG(WS_LOG_DEBUG, "KeyingState now USING_KEYS_RECV"); - } + ssh->highwaterFlag = 0; + ssh->isKeying = 0; + HandshakeInfoFree(ssh->handshake, ssh->ctx->heap); + ssh->handshake = NULL; + WLOG(WS_LOG_DEBUG, "Keying completed"); } return ret; @@ -1806,10 +2381,9 @@ static int DoNewKeys(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) static int DoKexDhGexRequest(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, - uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t begin; + word32 begin; int ret = WS_SUCCESS; if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) @@ -1833,7 +2407,6 @@ static int DoKexDhGexRequest(WOLFSSH* ssh, ssh->handshake->dhGexMinSz, ssh->handshake->dhGexPreferredSz, ssh->handshake->dhGexMaxSz); - ssh->clientState = CLIENT_KEXDH_INIT_DONE; /* XXX Different state. */ *idx = begin; ret = SendKexDhGexGroup(ssh); } @@ -1842,197 +2415,70 @@ static int DoKexDhGexRequest(WOLFSSH* ssh, } -int GenerateKey(uint8_t hashId, uint8_t keyId, - uint8_t* key, uint32_t keySz, - const uint8_t* k, uint32_t kSz, - const uint8_t* h, uint32_t hSz, - const uint8_t* sessionId, uint32_t sessionIdSz) +#ifndef WOLFSSH_NO_CLIENT +static int DoKexDhGexGroup(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) { - uint32_t blocks, remainder; - wc_HashAlg hash; - uint8_t kPad = 0; - uint8_t pad = 0; - uint8_t kSzFlat[LENGTH_SZ]; - int digestSz; - int ret; + byte* primeGroup = NULL; + word32 primeGroupSz; + byte* generator = NULL; + word32 generatorSz; + word32 begin; + int ret = WS_UNIMPLEMENTED_E; - if (key == NULL || keySz == 0 || - k == NULL || kSz == 0 || - h == NULL || hSz == 0 || - sessionId == NULL || sessionIdSz == 0) { - - WLOG(WS_LOG_DEBUG, "GK: bad argument"); - return WS_BAD_ARGUMENT; - } - - digestSz = wc_HashGetDigestSize(hashId); - if (digestSz == 0) { - WLOG(WS_LOG_DEBUG, "GK: bad hash ID"); - return WS_BAD_ARGUMENT; - } - - if (k[0] & 0x80) kPad = 1; - c32toa(kSz + kPad, kSzFlat); - - blocks = keySz / digestSz; - remainder = keySz % digestSz; - - ret = wc_HashInit(&hash, hashId); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, kSzFlat, LENGTH_SZ); - if (ret == WS_SUCCESS && kPad) - ret = wc_HashUpdate(&hash, hashId, &pad, 1); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, k, kSz); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, h, hSz); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, &keyId, sizeof(keyId)); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, sessionId, sessionIdSz); - - if (ret == WS_SUCCESS) { - if (blocks == 0) { - if (remainder > 0) { - uint8_t lastBlock[WC_MAX_DIGEST_SIZE]; - ret = wc_HashFinal(&hash, hashId, lastBlock); - if (ret == WS_SUCCESS) - WMEMCPY(key, lastBlock, remainder); - } - } - else { - uint32_t runningKeySz, curBlock; - - runningKeySz = digestSz; - ret = wc_HashFinal(&hash, hashId, key); - - for (curBlock = 1; curBlock < blocks; curBlock++) { - ret = wc_HashInit(&hash, hashId); - if (ret != WS_SUCCESS) break; - ret = wc_HashUpdate(&hash, hashId, kSzFlat, LENGTH_SZ); - if (ret != WS_SUCCESS) break; - if (kPad) - ret = wc_HashUpdate(&hash, hashId, &pad, 1); - if (ret != WS_SUCCESS) break; - ret = wc_HashUpdate(&hash, hashId, k, kSz); - if (ret != WS_SUCCESS) break; - ret = wc_HashUpdate(&hash, hashId, h, hSz); - if (ret != WS_SUCCESS) break; - ret = wc_HashUpdate(&hash, hashId, key, runningKeySz); - if (ret != WS_SUCCESS) break; - ret = wc_HashFinal(&hash, hashId, key + runningKeySz); - if (ret != WS_SUCCESS) break; - runningKeySz += digestSz; - } - - if (remainder > 0) { - uint8_t lastBlock[WC_MAX_DIGEST_SIZE]; - if (ret == WS_SUCCESS) - ret = wc_HashInit(&hash, hashId); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, kSzFlat, LENGTH_SZ); - if (ret == WS_SUCCESS && kPad) - ret = wc_HashUpdate(&hash, hashId, &pad, 1); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, k, kSz); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, h, hSz); - if (ret == WS_SUCCESS) - ret = wc_HashUpdate(&hash, hashId, key, runningKeySz); - if (ret == WS_SUCCESS) - ret = wc_HashFinal(&hash, hashId, lastBlock); - if (ret == WS_SUCCESS) - WMEMCPY(key + runningKeySz, lastBlock, remainder); - } - } - } - - if (ret != WS_SUCCESS) - ret = WS_CRYPTO_FAILED; - - return ret; -} - - -static int GenerateKeys(WOLFSSH* ssh) -{ - Keys* cK; - Keys* sK; - uint8_t hashId; - int ret = WS_SUCCESS; - - if (ssh == NULL) + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) ret = WS_BAD_ARGUMENT; - else { - cK = &ssh->handshake->clientKeys; - sK = &ssh->handshake->serverKeys; - hashId = ssh->handshake->hashId; + + if (ret == WS_SUCCESS) { + begin = *idx; + ret = GetMpint(&primeGroupSz, &primeGroup, buf, len, &begin); } if (ret == WS_SUCCESS) - ret = GenerateKey(hashId, 'A', - cK->iv, cK->ivSz, - ssh->k, ssh->kSz, ssh->h, ssh->hSz, - ssh->sessionId, ssh->sessionIdSz); - if (ret == WS_SUCCESS) - ret = GenerateKey(hashId, 'B', - sK->iv, sK->ivSz, - ssh->k, ssh->kSz, ssh->h, ssh->hSz, - ssh->sessionId, ssh->sessionIdSz); - if (ret == WS_SUCCESS) - ret = GenerateKey(hashId, 'C', - cK->encKey, cK->encKeySz, - ssh->k, ssh->kSz, ssh->h, ssh->hSz, - ssh->sessionId, ssh->sessionIdSz); - if (ret == WS_SUCCESS) - ret = GenerateKey(hashId, 'D', - sK->encKey, sK->encKeySz, - ssh->k, ssh->kSz, ssh->h, ssh->hSz, - ssh->sessionId, ssh->sessionIdSz); - if (!ssh->handshake->aeadMode) { - if (ret == WS_SUCCESS) - ret = GenerateKey(hashId, 'E', - cK->macKey, cK->macKeySz, - ssh->k, ssh->kSz, ssh->h, ssh->hSz, - ssh->sessionId, ssh->sessionIdSz); - if (ret == WS_SUCCESS) - ret = GenerateKey(hashId, 'F', - sK->macKey, sK->macKeySz, - ssh->k, ssh->kSz, ssh->h, ssh->hSz, - ssh->sessionId, ssh->sessionIdSz); - } -#ifdef SHOW_SECRETS + ret = GetMpint(&generatorSz, &generator, buf, len, &begin); + if (ret == WS_SUCCESS) { - printf("\n** Showing Secrets **\nK:\n"); - DumpOctetString(ssh->k, ssh->kSz); - printf("H:\n"); - DumpOctetString(ssh->h, ssh->hSz); - printf("Session ID:\n"); - DumpOctetString(ssh->sessionId, ssh->sessionIdSz); - printf("A:\n"); - DumpOctetString(cK->iv, cK->ivSz); - printf("B:\n"); - DumpOctetString(sK->iv, sK->ivSz); - printf("C:\n"); - DumpOctetString(cK->encKey, cK->encKeySz); - printf("D:\n"); - DumpOctetString(sK->encKey, sK->encKeySz); - printf("E:\n"); - DumpOctetString(cK->macKey, cK->macKeySz); - printf("F:\n"); - DumpOctetString(sK->macKey, sK->macKeySz); - printf("\n"); + ssh->handshake->primeGroup = + (byte*)WMALLOC(primeGroupSz + UINT32_SZ, + ssh->ctx->heap, DYNTYPE_MPINT); + if (ssh->handshake->primeGroup == NULL) + ret = WS_MEMORY_E; + } + + if (ret == WS_SUCCESS) { + ssh->handshake->generator = + (byte*)WMALLOC(generatorSz + UINT32_SZ, + ssh->ctx->heap, DYNTYPE_MPINT); + if (ssh->handshake->generator == NULL) { + ret = WS_MEMORY_E; + WFREE(ssh->handshake->primeGroup, ssh->ctx->heap, DYNTYPE_MPINT); + ssh->handshake->primeGroup = NULL; + } + } + + if (WS_SUCCESS) { + c32toa(primeGroupSz, ssh->handshake->primeGroup); + WMEMCPY(ssh->handshake->primeGroup + UINT32_SZ, + primeGroup, primeGroupSz); + ssh->handshake->primeGroupSz = primeGroupSz; + c32toa(generatorSz, ssh->handshake->generator); + WMEMCPY(ssh->handshake->generator + UINT32_SZ, + generator, generatorSz); + ssh->handshake->generatorSz = generatorSz; + + *idx = begin; + ret = SendKexDhInit(ssh); } -#endif /* SHOW_SECRETS */ return ret; } +#endif /* WOLFSSH_NO_CLIENT */ -static int DoIgnore(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) +static int DoIgnore(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { - uint32_t dataSz; - uint32_t begin = *idx; + word32 dataSz; + word32 begin = *idx; (void)ssh; (void)len; @@ -2046,13 +2492,13 @@ static int DoIgnore(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) } -static int DoDebug(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) +static int DoDebug(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { - uint8_t alwaysDisplay; + byte alwaysDisplay; char* msg = NULL; char* lang = NULL; - uint32_t strSz; - uint32_t begin = *idx; + word32 strSz; + word32 begin = *idx; (void)ssh; (void)len; @@ -2104,10 +2550,10 @@ static int DoDebug(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) static int DoUnimplemented(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t seq; - uint32_t begin = *idx; + word32 seq; + word32 begin = *idx; (void)ssh; (void)len; @@ -2123,11 +2569,11 @@ static int DoUnimplemented(WOLFSSH* ssh, } -static int DoDisconnect(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) +static int DoDisconnect(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) { - uint32_t reason; + word32 reason; const char* reasonStr; - uint32_t begin = *idx; + word32 begin = *idx; (void)ssh; (void)len; @@ -2182,17 +2628,11 @@ static int DoDisconnect(WOLFSSH* ssh, uint8_t* buf, uint32_t len, uint32_t* idx) } -#if 0 -static const char serviceNameUserAuth[] = "ssh-userauth"; -static const char serviceNameConnection[] = "ssh-connection"; -#endif - - static int DoServiceRequest(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t begin = *idx; - uint32_t nameSz; + word32 begin = *idx; + word32 nameSz; char serviceName[32]; (void)len; @@ -2213,11 +2653,38 @@ static int DoServiceRequest(WOLFSSH* ssh, } +#ifndef WOLFSSH_NO_CLIENT +static int DoServiceAccept(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) +{ + word32 begin = *idx; + word32 nameSz; + char serviceName[32]; + + (void)len; + + ato32(buf + begin, &nameSz); + begin += LENGTH_SZ; + + WMEMCPY(serviceName, buf + begin, nameSz); + begin += nameSz; + serviceName[nameSz] = 0; + + *idx = begin; + + WLOG(WS_LOG_DEBUG, "Accepted service: %s", serviceName); + ssh->serverState = SERVER_USERAUTH_REQUEST_DONE; + + return WS_SUCCESS; +} +#endif /* WOLFSSH_NO_CLIENT */ + + /* Utility for DoUserAuthRequest() */ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t begin; + word32 begin; WS_UserAuthData_Password* pw; int ret = WS_SUCCESS; @@ -2288,16 +2755,16 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData, /* Utility for DoUserAuthRequestPublicKey() */ /* returns negative for error, positive is size of digest. */ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk, - uint8_t* digest, uint32_t digestSz) + byte* digest, word32 digestSz) { RsaKey key; - uint8_t* publicKeyType; - uint32_t publicKeyTypeSz = 0; - uint8_t* n; - uint32_t nSz = 0; - uint8_t* e; - uint32_t eSz = 0; - uint32_t i = 0; + byte* publicKeyType; + word32 publicKeyTypeSz = 0; + byte* n; + word32 nSz = 0; + byte* e; + word32 eSz = 0; + word32 i = 0; int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestRsa()"); @@ -2384,9 +2851,9 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk, /* Utility for DoUserAuthRequest() */ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t begin; + word32 begin; WS_UserAuthData_PublicKey* pk; int ret = WS_SUCCESS; int authFailure = 0; @@ -2461,11 +2928,11 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, pk->publicKey, pk->publicKeySz); } else { - uint8_t checkDigest[MAX_ENCODED_SIG_SZ]; - uint32_t checkDigestSz = sizeof(checkDigest); - uint8_t encDigest[MAX_ENCODED_SIG_SZ]; - uint32_t encDigestSz; - uint8_t pkTypeId; + byte checkDigest[MAX_ENCODED_SIG_SZ]; + word32 checkDigestSz = sizeof(checkDigest); + byte encDigest[MAX_ENCODED_SIG_SZ]; + word32 encDigestSz; + byte pkTypeId; WMEMSET(checkDigest, 0, sizeof(checkDigest)); WMEMSET(encDigest, 0, sizeof(encDigest)); @@ -2478,14 +2945,14 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, ret = WS_INVALID_ALGO_ID; if (ret > 0) { - checkDigestSz = (uint32_t)ret; + checkDigestSz = (word32)ret; ret = WS_SUCCESS; } if (ret == WS_SUCCESS) { wc_HashAlg hash; - uint8_t hashId = WC_HASH_TYPE_SHA; - uint8_t digest[WC_MAX_DIGEST_SIZE]; + byte hashId = WC_HASH_TYPE_SHA; + byte digest[WC_MAX_DIGEST_SIZE]; volatile int compare; volatile int sizeCompare; @@ -2544,48 +3011,12 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData, } -static int DoGlobalRequest(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) -{ - uint32_t begin; - int ret = WS_SUCCESS; - char name[80]; - uint32_t nameSz = sizeof(name); - uint8_t wantReply = 0; - - WLOG(WS_LOG_DEBUG, "Entering DoGlobalRequest()"); - - if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) - ret = WS_BAD_ARGUMENT; - - if (ret == WS_SUCCESS) { - begin = *idx; - ret = GetString(name, &nameSz, buf, len, &begin); - } - - if (ret == WS_SUCCESS) { - WLOG(WS_LOG_DEBUG, "DGR: request name = %s", name); - ret = GetBoolean(&wantReply, buf, len, &begin); - } - - if (ret == WS_SUCCESS) { - *idx += len; - - if (wantReply) - ret = SendRequestSuccess(ssh, 0); - } - - WLOG(WS_LOG_DEBUG, "Leaving DoGlobalRequest(), ret = %d", ret); - return ret; -} - - static int DoUserAuthRequest(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t begin; + word32 begin; int ret = WS_SUCCESS; - uint8_t authNameId; + byte authNameId; WS_UserAuthData authData; WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequest()"); @@ -2643,17 +3074,133 @@ static int DoUserAuthRequest(WOLFSSH* ssh, } -static int DoChannelOpen(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) +#ifndef WOLFSSH_NO_CLIENT +static int DoUserAuthFailure(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) { - uint32_t begin = *idx; - uint32_t typeSz; - char type[32]; - uint8_t typeId = ID_UNKNOWN; - uint32_t peerChannelId; - uint32_t peerInitialWindowSz; - uint32_t peerMaxPacketSz; - int ret; + byte authList[3]; /* Should only ever be password, publickey, hostname */ + word32 authListSz; + byte partialSuccess; + byte authId = ID_USERAUTH_PASSWORD; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoUserAuthFailure()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) + ret = GetNameList(authList, &authListSz, buf, len, idx); + + if (ret == WS_SUCCESS) + ret = GetBoolean(&partialSuccess, buf, len, idx); + + if (ret == WS_SUCCESS) + ret = SendUserAuthRequest(ssh, authId); + + WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthFailure(), ret = %d", ret); + return ret; +} + + +static int DoUserAuthSuccess(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) +{ + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoUserAuthSuccess()"); + + /* This message does not have any payload. len should be 0. */ + if (ssh == NULL || buf == NULL || len != 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + ssh->serverState = SERVER_USERAUTH_ACCEPT_DONE; + + WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthSuccess(), ret = %d", ret); + return ret; +} + + +static int DoUserAuthBanner(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) +{ + word32 begin; + char banner[80]; + word32 bannerSz = sizeof(banner); + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoUserAuthBanner()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + begin = *idx; + ret = GetString(banner, &bannerSz, buf, len, idx); + } + + if (ret == WS_SUCCESS) + ret = GetUint32(&bannerSz, buf, len, idx); + + if (ret == WS_SUCCESS) { + begin += bannerSz; + if (ssh->ctx->showBanner) { + WLOG(WS_LOG_INFO, "%s", banner); + } + } + + WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthBanner(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + +static int DoGlobalRequest(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) +{ + word32 begin; + int ret = WS_SUCCESS; + char name[80]; + word32 nameSz = sizeof(name); + byte wantReply = 0; + + WLOG(WS_LOG_DEBUG, "Entering DoGlobalRequest()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + begin = *idx; + ret = GetString(name, &nameSz, buf, len, &begin); + } + + if (ret == WS_SUCCESS) { + WLOG(WS_LOG_DEBUG, "DGR: request name = %s", name); + ret = GetBoolean(&wantReply, buf, len, &begin); + } + + if (ret == WS_SUCCESS) { + *idx += len; + + if (wantReply) + ret = SendRequestSuccess(ssh, 0); + } + + WLOG(WS_LOG_DEBUG, "Leaving DoGlobalRequest(), ret = %d", ret); + return ret; +} + + +static int DoChannelOpen(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) +{ + word32 begin = *idx; + word32 typeSz; + char type[32]; + byte typeId = ID_UNKNOWN; + word32 peerChannelId; + word32 peerInitialWindowSz; + word32 peerMaxPacketSz; + int ret; WOLFSSH_CHANNEL* newChannel; WLOG(WS_LOG_DEBUG, "Entering DoChannelOpen()"); @@ -2684,15 +3231,16 @@ static int DoChannelOpen(WOLFSSH* ssh, } if (ret == WS_SUCCESS) { - newChannel = ChannelNew(ssh, typeId, peerChannelId, - peerInitialWindowSz, peerMaxPacketSz); + newChannel = ChannelNew(ssh, typeId, + DEFAULT_WINDOW_SZ, DEFAULT_MAX_PACKET_SZ); if (newChannel == NULL) ret = WS_RESOURCE_E; else { - newChannel->next = ssh->channelList; - ssh->channelList = newChannel; - ssh->channelListSz++; - ssh->defaultPeerChannelId = peerChannelId; + ChannelUpdate(newChannel, peerChannelId, + peerInitialWindowSz, peerMaxPacketSz); + if (ssh->channelListSz == 0) + ssh->defaultPeerChannelId = peerChannelId; + ChannelAppend(ssh, newChannel); ssh->clientState = CLIENT_DONE; } @@ -2703,13 +3251,110 @@ static int DoChannelOpen(WOLFSSH* ssh, } +static int DoChannelOpenConf(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) +{ + WOLFSSH_CHANNEL* channel; + word32 begin, channelId, peerChannelId, + peerInitialWindowSz, peerMaxPacketSz; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoChannelOpenConf()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + begin = *idx; + ret = GetUint32(&channelId, buf, len, &begin); + } + + if (ret == WS_SUCCESS) + ret = GetUint32(&peerChannelId, buf, len, &begin); + + if (ret == WS_SUCCESS) + ret = GetUint32(&peerInitialWindowSz, buf, len, &begin); + + if (ret == WS_SUCCESS) + ret = GetUint32(&peerMaxPacketSz, buf, len, &begin); + + if (ret == WS_SUCCESS) { + WLOG(WS_LOG_INFO, " channelId = %u", channelId); + WLOG(WS_LOG_INFO, " peerChannelId = %u", peerChannelId); + WLOG(WS_LOG_INFO, " peerInitialWindowSz = %u", peerInitialWindowSz); + WLOG(WS_LOG_INFO, " peerMaxPacketSz = %u", peerMaxPacketSz); + + channel = ChannelFind(ssh, channelId, FIND_SELF); + if (channel == NULL) + ret = WS_INVALID_CHANID; + } + + if (ret == WS_SUCCESS) + ret = ChannelUpdate(channel, peerChannelId, + peerInitialWindowSz, peerMaxPacketSz); + + if (ret == WS_SUCCESS) + ssh->serverState = SERVER_CHANNEL_OPEN_DONE; + + WLOG(WS_LOG_DEBUG, "Leaving DoChannelOpenConf(), ret = %d", ret); + return ret; +} + + +static int DoChannelOpenFail(WOLFSSH* ssh, + byte* buf, word32 len, word32* idx) +{ + char desc[80]; + word32 begin, channelId, reasonId, descSz, langSz; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoChannelOpenFail()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + begin = *idx; + ret = GetUint32(&channelId, buf, len, &begin); + } + + if (ret == WS_SUCCESS) + ret = GetUint32(&reasonId, buf, len, &begin); + + if (ret == WS_SUCCESS) { + descSz = sizeof(desc); + ret = GetString(desc, &descSz, buf, len, &begin); + } + + if (ret == WS_SUCCESS) + ret = GetUint32(&langSz, buf, len, &begin); + + if (ret == WS_SUCCESS) { + *idx = begin + langSz; + + WLOG(WS_LOG_INFO, "channel open failure reason code: %u", reasonId); + if (descSz > 0) { + WLOG(WS_LOG_INFO, "description: %s", desc); + } + + ret = ChannelRemove(ssh, channelId, FIND_SELF); + } + + if (ret == WS_SUCCESS) + ret = WS_CHANOPEN_FAILED; + + WLOG(WS_LOG_DEBUG, "Leaving DoChannelOpenFail(), ret = %d", ret); + return ret; +} + + static int DoChannelClose(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { WOLFSSH_CHANNEL* channel = NULL; - uint32_t begin = *idx; - uint32_t channelId; - int ret; + word32 begin = *idx; + word32 channelId; + int ret; WLOG(WS_LOG_DEBUG, "Entering DoChannelClose()"); @@ -2736,14 +3381,14 @@ static int DoChannelClose(WOLFSSH* ssh, static int DoChannelRequest(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { - uint32_t begin = *idx; - uint32_t channelId; - uint32_t typeSz; - char type[32]; - uint8_t wantReply; - int ret; + word32 begin = *idx; + word32 channelId; + word32 typeSz; + char type[32]; + byte wantReply; + int ret; WLOG(WS_LOG_DEBUG, "Entering DoChannelRequest()"); @@ -2767,10 +3412,10 @@ static int DoChannelRequest(WOLFSSH* ssh, WLOG(WS_LOG_DEBUG, " wantReply = %u", wantReply); if (WSTRNCMP(type, "pty-req", typeSz) == 0) { - char term[32]; - uint32_t termSz; - uint32_t widthChar, heightRows, widthPixels, heightPixels; - uint32_t modesSz; + char term[32]; + word32 termSz; + word32 widthChar, heightRows, widthPixels, heightPixels; + word32 modesSz; termSz = sizeof(term); ret = GetString(term, &termSz, buf, len, &begin); @@ -2795,10 +3440,10 @@ static int DoChannelRequest(WOLFSSH* ssh, } } else if (WSTRNCMP(type, "env", typeSz) == 0) { - char name[32]; - uint32_t nameSz; - char value[32]; - uint32_t valueSz; + char name[32]; + word32 nameSz; + char value[32]; + word32 valueSz; nameSz = sizeof(name); valueSz = sizeof(value); @@ -2826,13 +3471,45 @@ static int DoChannelRequest(WOLFSSH* ssh, } +static int DoChannelSuccess(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) +{ + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoChannelSuccess()"); + + if (ssh == NULL || buf == NULL || len == 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + ssh->serverState = SERVER_DONE; + + WLOG(WS_LOG_DEBUG, "Leaving DoChannelSuccess(), ret = %d", ret); + return ret; +} + + +static int DoChannelFailure(WOLFSSH* ssh, byte* buf, word32 len, word32* idx) +{ + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering DoChannelFailure()"); + + if (ssh == NULL || buf == NULL || len != 0 || idx == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) + ret = WS_CHANOPEN_FAILED; + WLOG(WS_LOG_DEBUG, "Leaving DoChannelFailure(), ret = %d", ret); + return ret; +} + + static int DoChannelWindowAdjust(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { WOLFSSH_CHANNEL* channel = NULL; - uint32_t begin = *idx; - uint32_t channelId, bytesToAdd; - int ret; + word32 begin = *idx; + word32 channelId, bytesToAdd; + int ret; WLOG(WS_LOG_DEBUG, "Entering DoChannelWindowAdjust()"); @@ -2866,13 +3543,13 @@ static int DoChannelWindowAdjust(WOLFSSH* ssh, static int DoChannelData(WOLFSSH* ssh, - uint8_t* buf, uint32_t len, uint32_t* idx) + byte* buf, word32 len, word32* idx) { WOLFSSH_CHANNEL* channel = NULL; - uint32_t begin = *idx; - uint32_t dataSz = 0; - uint32_t channelId; - int ret; + word32 begin = *idx; + word32 dataSz = 0; + word32 channelId; + int ret; WLOG(WS_LOG_DEBUG, "Entering DoChannelData()"); @@ -2897,13 +3574,13 @@ static int DoChannelData(WOLFSSH* ssh, static int DoPacket(WOLFSSH* ssh) { - uint8_t* buf = (uint8_t*)ssh->inputBuffer.buffer; - uint32_t idx = ssh->inputBuffer.idx; - uint32_t len = ssh->inputBuffer.length; - uint32_t payloadSz; - uint8_t padSz; - uint8_t msg; - uint32_t payloadIdx = 0; + byte* buf = (byte*)ssh->inputBuffer.buffer; + word32 idx = ssh->inputBuffer.idx; + word32 len = ssh->inputBuffer.length; + word32 payloadSz; + byte padSz; + byte msg; + word32 payloadIdx = 0; int ret; WLOG(WS_LOG_DEBUG, "DoPacket sequence number: %d", ssh->peerSeq); @@ -2982,6 +3659,16 @@ static int DoPacket(WOLFSSH* ssh) ret = DoChannelOpen(ssh, buf + idx, payloadSz, &payloadIdx); break; + case MSGID_CHANNEL_OPEN_CONF: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_CHANNEL_OPEN_CONF"); + ret = DoChannelOpenConf(ssh, buf + idx, payloadSz, &payloadIdx); + break; + + case MSGID_CHANNEL_OPEN_FAIL: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_CHANNEL_OPEN_FAIL"); + ret = DoChannelOpenFail(ssh, buf + idx, payloadSz, &payloadIdx); + break; + case MSGID_CHANNEL_WINDOW_ADJUST: WLOG(WS_LOG_DEBUG, "Decoding MSGID_CHANNEL_WINDOW_ADJUST"); ret = DoChannelWindowAdjust(ssh, buf + idx, payloadSz, &payloadIdx); @@ -3007,13 +3694,60 @@ static int DoPacket(WOLFSSH* ssh) ret = DoChannelRequest(ssh, buf + idx, payloadSz, &payloadIdx); break; + case MSGID_CHANNEL_SUCCESS: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_CHANNEL_SUCCESS"); + ret = DoChannelSuccess(ssh, buf + idx, payloadSz, &payloadIdx); + break; + + case MSGID_CHANNEL_FAILURE: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_CHANNEL_FAILURE"); + ret = DoChannelFailure(ssh, buf + idx, payloadSz, &payloadIdx); + break; + +#ifndef WOLFSSH_NO_CLIENT + case MSGID_KEXDH_REPLY: + if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { + WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_GROUP"); + ret = DoKexDhGexGroup(ssh, buf + idx, payloadSz, &payloadIdx); + } + else { + WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_REPLY"); + ret = DoKexDhReply(ssh, buf + idx, payloadSz, &payloadIdx); + } + break; + + case MSGID_KEXDH_GEX_REPLY: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_KEXDH_GEX_INIT"); + ret = DoKexDhReply(ssh, buf + idx, payloadSz, &payloadIdx); + break; + + case MSGID_SERVICE_ACCEPT: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_SERVER_ACCEPT"); + ret = DoServiceAccept(ssh, buf + idx, payloadSz, &payloadIdx); + break; + + case MSGID_USERAUTH_FAILURE: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_FAILURE"); + ret = DoUserAuthFailure(ssh, buf + idx, payloadSz, &payloadIdx); + break; + + case MSGID_USERAUTH_SUCCESS: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_SUCCESS"); + ret = DoUserAuthSuccess(ssh, buf + idx, payloadSz, &payloadIdx); + break; + + case MSGID_USERAUTH_BANNER: + WLOG(WS_LOG_DEBUG, "Decoding MSGID_USERAUTH_BANNER"); + ret = DoUserAuthBanner(ssh, buf + idx, payloadSz, &payloadIdx); + break; +#endif /* WOLFSSL_NO_CLIENT */ + default: WLOG(WS_LOG_DEBUG, "Unimplemented message ID (%d)", msg); #ifdef SHOW_UNIMPLEMENTED DumpOctetString(buf + idx, payloadSz); #endif ret = SendUnimplemented(ssh); - break; } if (ret == WS_SUCCESS) { @@ -3035,8 +3769,8 @@ static int DoPacket(WOLFSSH* ssh) } -static INLINE int Encrypt(WOLFSSH* ssh, uint8_t* cipher, const uint8_t* input, - uint16_t sz) +static INLINE int Encrypt(WOLFSSH* ssh, byte* cipher, const byte* input, + word16 sz) { int ret = WS_SUCCESS; @@ -3067,8 +3801,8 @@ static INLINE int Encrypt(WOLFSSH* ssh, uint8_t* cipher, const uint8_t* input, } -static INLINE int Decrypt(WOLFSSH* ssh, uint8_t* plain, const uint8_t* input, - uint16_t sz) +static INLINE int Decrypt(WOLFSSH* ssh, byte* plain, const byte* input, + word16 sz) { int ret = WS_SUCCESS; @@ -3100,13 +3834,13 @@ static INLINE int Decrypt(WOLFSSH* ssh, uint8_t* plain, const uint8_t* input, } -static INLINE int CreateMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, - uint8_t* mac) +static INLINE int CreateMac(WOLFSSH* ssh, const byte* in, word32 inSz, + byte* mac) { - uint8_t flatSeq[LENGTH_SZ]; + byte flatSeq[LENGTH_SZ]; int ret; - c32toa(ssh->seq++, flatSeq); + c32toa(ssh->seq, flatSeq); WLOG(WS_LOG_DEBUG, "CreateMac %s", IdToName(ssh->macId)); @@ -3119,11 +3853,10 @@ static INLINE int CreateMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, case ID_HMAC_SHA1_96: { Hmac hmac; - uint8_t digest[SHA_DIGEST_SIZE]; + byte digest[SHA_DIGEST_SIZE]; ret = wc_HmacSetKey(&hmac, SHA, - ssh->serverKeys.macKey, - ssh->serverKeys.macKeySz); + ssh->keys.macKey, ssh->keys.macKeySz); if (ret == WS_SUCCESS) ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq)); if (ret == WS_SUCCESS) @@ -3140,8 +3873,7 @@ static INLINE int CreateMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, Hmac hmac; ret = wc_HmacSetKey(&hmac, SHA, - ssh->serverKeys.macKey, - ssh->serverKeys.macKeySz); + ssh->keys.macKey, ssh->keys.macKeySz); if (ret == WS_SUCCESS) ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq)); if (ret == WS_SUCCESS) @@ -3156,8 +3888,8 @@ static INLINE int CreateMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, Hmac hmac; ret = wc_HmacSetKey(&hmac, SHA256, - ssh->serverKeys.macKey, - ssh->serverKeys.macKeySz); + ssh->keys.macKey, + ssh->keys.macKeySz); if (ret == WS_SUCCESS) ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq)); if (ret == WS_SUCCESS) @@ -3176,20 +3908,20 @@ static INLINE int CreateMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, } -static INLINE int VerifyMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, - const uint8_t* mac) +static INLINE int VerifyMac(WOLFSSH* ssh, const byte* in, word32 inSz, + const byte* mac) { - int ret; - uint8_t flatSeq[LENGTH_SZ]; - uint8_t checkMac[MAX_HMAC_SZ]; - Hmac hmac; + int ret; + byte flatSeq[LENGTH_SZ]; + byte checkMac[MAX_HMAC_SZ]; + Hmac hmac; c32toa(ssh->peerSeq, flatSeq); WLOG(WS_LOG_DEBUG, "VerifyMac %s", IdToName(ssh->peerMacId)); WLOG(WS_LOG_DEBUG, "VM: inSz = %u", inSz); WLOG(WS_LOG_DEBUG, "VM: seq = %u", ssh->peerSeq); - WLOG(WS_LOG_DEBUG, "VM: keyLen = %u", ssh->clientKeys.macKeySz); + WLOG(WS_LOG_DEBUG, "VM: keyLen = %u", ssh->peerKeys.macKeySz); WMEMSET(checkMac, 0, sizeof(checkMac)); @@ -3201,8 +3933,7 @@ static INLINE int VerifyMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, case ID_HMAC_SHA1: case ID_HMAC_SHA1_96: ret = wc_HmacSetKey(&hmac, SHA, - ssh->clientKeys.macKey, - ssh->clientKeys.macKeySz); + ssh->peerKeys.macKey, ssh->peerKeys.macKeySz); if (ret == WS_SUCCESS) ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq)); if (ret == WS_SUCCESS) @@ -3215,8 +3946,7 @@ static INLINE int VerifyMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, case ID_HMAC_SHA2_256: ret = wc_HmacSetKey(&hmac, SHA256, - ssh->clientKeys.macKey, - ssh->clientKeys.macKeySz); + ssh->peerKeys.macKey, ssh->peerKeys.macKeySz); if (ret == WS_SUCCESS) ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq)); if (ret == WS_SUCCESS) @@ -3235,7 +3965,7 @@ static INLINE int VerifyMac(WOLFSSH* ssh, const uint8_t* in, uint32_t inSz, } -static INLINE void AeadIncrementExpIv(uint8_t* iv) +static INLINE void AeadIncrementExpIv(byte* iv) { int i; @@ -3247,10 +3977,10 @@ static INLINE void AeadIncrementExpIv(uint8_t* iv) } -static INLINE int EncryptAead(WOLFSSH* ssh, uint8_t* cipher, - const uint8_t* input, uint16_t sz, - uint8_t* authTag, const uint8_t* auth, - uint16_t authSz) +static INLINE int EncryptAead(WOLFSSH* ssh, byte* cipher, + const byte* input, word16 sz, + byte* authTag, const byte* auth, + word16 authSz) { int ret = WS_SUCCESS; @@ -3262,23 +3992,23 @@ static INLINE int EncryptAead(WOLFSSH* ssh, uint8_t* cipher, if (ssh->encryptId == ID_AES128_GCM) { ret = wc_AesGcmEncrypt(&ssh->encryptCipher.aes, cipher, input, sz, - ssh->serverKeys.iv, ssh->serverKeys.ivSz, + ssh->keys.iv, ssh->keys.ivSz, authTag, ssh->macSz, auth, authSz); } else ret = WS_INVALID_ALGO_ID; - AeadIncrementExpIv(ssh->serverKeys.iv); + AeadIncrementExpIv(ssh->keys.iv); ssh->txCount += sz; return ret; } -static INLINE int DecryptAead(WOLFSSH* ssh, uint8_t* plain, - const uint8_t* input, uint16_t sz, - const uint8_t* authTag, const uint8_t* auth, - uint16_t authSz) +static INLINE int DecryptAead(WOLFSSH* ssh, byte* plain, + const byte* input, word16 sz, + const byte* authTag, const byte* auth, + word16 authSz) { int ret = WS_SUCCESS; @@ -3290,13 +4020,13 @@ static INLINE int DecryptAead(WOLFSSH* ssh, uint8_t* plain, if (ssh->peerEncryptId == ID_AES128_GCM) { ret = wc_AesGcmDecrypt(&ssh->decryptCipher.aes, plain, input, sz, - ssh->clientKeys.iv, ssh->clientKeys.ivSz, + ssh->peerKeys.iv, ssh->peerKeys.ivSz, authTag, ssh->peerMacSz, auth, authSz); } else ret = WS_INVALID_ALGO_ID; - AeadIncrementExpIv(ssh->clientKeys.iv); + AeadIncrementExpIv(ssh->peerKeys.iv); ssh->rxCount += sz; HighwaterCheck(ssh, WOLFSSH_HWSIDE_RECEIVE); @@ -3308,10 +4038,10 @@ int DoReceive(WOLFSSH* ssh) { int ret = WS_FATAL_ERROR; int verifyResult; - uint32_t readSz; - uint8_t peerBlockSz = ssh->peerBlockSz; - uint8_t peerMacSz = ssh->peerMacSz; - uint8_t aeadMode = ssh->peerAeadMode; + word32 readSz; + byte peerBlockSz = ssh->peerBlockSz; + byte peerMacSz = ssh->peerMacSz; + byte aeadMode = ssh->peerAeadMode; for (;;) { switch (ssh->processReplyState) { @@ -3336,12 +4066,14 @@ int DoReceive(WOLFSSH* ssh) return ret; } } + FALL_THROUGH; case PROCESS_PACKET_LENGTH: /* Peek at the packet_length field. */ ato32(ssh->inputBuffer.buffer + ssh->inputBuffer.idx, &ssh->curSz); ssh->processReplyState = PROCESS_PACKET_FINISH; + FALL_THROUGH; case PROCESS_PACKET_FINISH: readSz = ssh->curSz + LENGTH_SZ + peerMacSz; @@ -3407,6 +4139,7 @@ int DoReceive(WOLFSSH* ssh) } } ssh->processReplyState = PROCESS_PACKET; + FALL_THROUGH; case PROCESS_PACKET: if ( (ret = DoPacket(ssh)) < 0) { @@ -3432,11 +4165,11 @@ int DoReceive(WOLFSSH* ssh) } -int ProcessClientVersion(WOLFSSH* ssh) +int DoProtoId(WOLFSSH* ssh) { int ret; - uint32_t idSz; - uint8_t* eol; + word32 idSz; + byte* eol; if ( (ret = GetInputText(ssh, &eol)) < 0) { WLOG(WS_LOG_DEBUG, "get input text failed"); @@ -3449,9 +4182,12 @@ int ProcessClientVersion(WOLFSSH* ssh) } if (WSTRNCASECMP((char*)ssh->inputBuffer.buffer, - sshIdStr, SSH_PROTO_SZ) == 0) { + sshProtoIdStr, SSH_PROTO_SZ) == 0) { - ssh->clientState = CLIENT_VERSION_DONE; + if (ssh->ctx->side == WOLFSSH_ENDPOINT_SERVER) + ssh->clientState = CLIENT_VERSION_DONE; + else + ssh->serverState = SERVER_VERSION_DONE; } else { WLOG(WS_LOG_DEBUG, "SSH version mismatch"); @@ -3460,17 +4196,17 @@ int ProcessClientVersion(WOLFSSH* ssh) *eol = 0; - idSz = (uint32_t)WSTRLEN((char*)ssh->inputBuffer.buffer); + idSz = (word32)WSTRLEN((char*)ssh->inputBuffer.buffer); - /* Store the client ID for later use. It is used in keying and rekeying. */ - ssh->clientId = (uint8_t*)WMALLOC(idSz + LENGTH_SZ, - ssh->ctx->heap, DYNTYPE_STRING); - if (ssh->clientId == NULL) + /* Store the proto ID for later use. It is used in keying and rekeying. */ + ssh->peerProtoId = (byte*)WMALLOC(idSz + LENGTH_SZ, + ssh->ctx->heap, DYNTYPE_STRING); + if (ssh->peerProtoId == NULL) ret = WS_MEMORY_E; else { - c32toa(idSz, ssh->clientId); - WMEMCPY(ssh->clientId + LENGTH_SZ, ssh->inputBuffer.buffer, idSz); - ssh->clientIdSz = idSz + LENGTH_SZ; + c32toa(idSz, ssh->peerProtoId); + WMEMCPY(ssh->peerProtoId + LENGTH_SZ, ssh->inputBuffer.buffer, idSz); + ssh->peerProtoIdSz = idSz + LENGTH_SZ; } ssh->inputBuffer.idx += idSz + SSH_PROTO_EOL_SZ; @@ -3480,32 +4216,38 @@ int ProcessClientVersion(WOLFSSH* ssh) } -int SendServerVersion(WOLFSSH* ssh) +int SendProtoId(WOLFSSH* ssh) { int ret = WS_SUCCESS; - uint32_t sshIdStrSz; + word32 sshProtoIdStrSz; if (ssh == NULL) ret = WS_BAD_ARGUMENT; if (ret == WS_SUCCESS) { - WLOG(WS_LOG_DEBUG, "%s", sshIdStr); - sshIdStrSz = (uint32_t)WSTRLEN(sshIdStr); - ret = SendText(ssh, sshIdStr, sshIdStrSz); + WLOG(WS_LOG_DEBUG, "%s", sshProtoIdStr); + sshProtoIdStrSz = (word32)WSTRLEN(sshProtoIdStr); + ret = GrowBuffer(&ssh->outputBuffer, sshProtoIdStrSz, 0); + } + + if (ret == WS_SUCCESS) { + WMEMCPY(ssh->outputBuffer.buffer, sshProtoIdStr, sshProtoIdStrSz); + ssh->outputBuffer.length = sshProtoIdStrSz; + ret = SendBuffered(ssh); } return ret; } -static int PreparePacket(WOLFSSH* ssh, uint32_t payloadSz) +static int PreparePacket(WOLFSSH* ssh, word32 payloadSz) { - int ret = WS_SUCCESS; - uint8_t* output; - uint32_t outputSz; - uint32_t packetSz; - uint32_t usedSz; - uint8_t paddingSz; + int ret = WS_SUCCESS; + byte* output; + word32 outputSz; + word32 packetSz; + word32 usedSz; + byte paddingSz; if (ssh == NULL) ret = WS_BAD_ARGUMENT; @@ -3542,10 +4284,10 @@ static int PreparePacket(WOLFSSH* ssh, uint32_t payloadSz) static int BundlePacket(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx; - uint8_t paddingSz; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + byte paddingSz; + int ret = WS_SUCCESS; if (ssh == NULL) ret = WS_BAD_ARGUMENT; @@ -3606,8 +4348,10 @@ static int BundlePacket(WOLFSSH* ssh) } } - if (ret == WS_SUCCESS) + if (ret == WS_SUCCESS) { + ssh->seq++; ssh->outputBuffer.length = idx; + } else { WLOG(WS_LOG_DEBUG, "BP: failed to encrypt buffer"); } @@ -3616,10 +4360,10 @@ static int BundlePacket(WOLFSSH* ssh) } -static INLINE void CopyNameList(uint8_t* buf, uint32_t* idx, - const char* src, uint32_t srcSz) +static INLINE void CopyNameList(byte* buf, word32* idx, + const char* src, word32 srcSz) { - uint32_t begin = *idx; + word32 begin = *idx; c32toa(srcSz, buf + begin); begin += LENGTH_SZ; @@ -3641,37 +4385,37 @@ static const char cannedKexAlgoNames[] = "ecdh-sha2-nistp256," "diffie-hellman-group-exchange-sha256," "diffie-hellman-group14-sha1," "diffie-hellman-group1-sha1"; -static const char cannedNoneNames[] = "none"; +static const char cannedNoneNames[] = "none"; -static const uint32_t cannedEncAlgoNamesSz = sizeof(cannedEncAlgoNames) - 1; -static const uint32_t cannedMacAlgoNamesSz = sizeof(cannedMacAlgoNames) - 1; -static const uint32_t cannedKeyAlgoRsaNamesSz = - sizeof(cannedKeyAlgoRsaNames) - 1; -static const uint32_t cannedKeyAlgoEcc256NamesSz = +static const word32 cannedEncAlgoNamesSz = sizeof(cannedEncAlgoNames) - 1; +static const word32 cannedMacAlgoNamesSz = sizeof(cannedMacAlgoNames) - 1; +static const word32 cannedKeyAlgoRsaNamesSz = sizeof(cannedKeyAlgoRsaNames) - 1; +static const word32 cannedKeyAlgoEcc256NamesSz = sizeof(cannedKeyAlgoEcc256Names) - 1; -static const uint32_t cannedKeyAlgoEcc384NamesSz = +static const word32 cannedKeyAlgoEcc384NamesSz = sizeof(cannedKeyAlgoEcc384Names) - 1; -static const uint32_t cannedKeyAlgoEcc521NamesSz = +static const word32 cannedKeyAlgoEcc521NamesSz = sizeof(cannedKeyAlgoEcc521Names) - 1; -static const uint32_t cannedKexAlgoNamesSz = sizeof(cannedKexAlgoNames) - 1; -static const uint32_t cannedNoneNamesSz = sizeof(cannedNoneNames) - 1; +static const word32 cannedKexAlgoNamesSz = sizeof(cannedKexAlgoNames) - 1; +static const word32 cannedNoneNamesSz = sizeof(cannedNoneNames) - 1; int SendKexInit(WOLFSSH* ssh) { - uint8_t* output; - uint8_t* payload; - uint32_t idx = 0; - uint32_t payloadSz; + byte* output; + byte* payload; + word32 idx = 0; + word32 payloadSz; int ret = WS_SUCCESS; const char* cannedKeyAlgoNames; - uint32_t cannedKeyAlgoNamesSz; + word32 cannedKeyAlgoNamesSz; WLOG(WS_LOG_DEBUG, "Entering SendKexInit()"); if (ssh == NULL) ret = WS_BAD_ARGUMENT; + ssh->isKeying = 1; if (ssh->handshake == NULL) { ssh->handshake = HandshakeInfoNew(ssh->ctx->heap); if (ssh->handshake == NULL) { @@ -3717,8 +4461,8 @@ int SendKexInit(WOLFSSH* ssh) } if (ret == WS_SUCCESS) { - uint8_t* buf; - uint32_t bufSz = payloadSz + LENGTH_SZ; + byte* buf; + word32 bufSz = payloadSz + LENGTH_SZ; idx += COOKIE_SZ; @@ -3740,7 +4484,7 @@ int SendKexInit(WOLFSSH* ssh) ssh->outputBuffer.length = idx; - buf = (uint8_t*)WMALLOC(bufSz, ssh->ctx->heap, DYNTYPE_STRING); + buf = (byte*)WMALLOC(bufSz, ssh->ctx->heap, DYNTYPE_STRING); if (buf == NULL) { WLOG(WS_LOG_DEBUG, "Cannot allocate storage for KEX Init msg"); ret = WS_MEMORY_E; @@ -3748,8 +4492,8 @@ int SendKexInit(WOLFSSH* ssh) else { c32toa(payloadSz, buf); WMEMCPY(buf + LENGTH_SZ, payload, payloadSz); - ssh->handshake->serverKexInit = buf; - ssh->handshake->serverKexInitSz = bufSz; + ssh->handshake->kexInit = buf; + ssh->handshake->kexInitSz = bufSz; } } @@ -3759,23 +4503,12 @@ int SendKexInit(WOLFSSH* ssh) if (ret == WS_SUCCESS) ret = SendBuffered(ssh); - if (ret == WS_SUCCESS) { - if (ssh->keyingState == KEYING_KEXINIT_RECV) { - WLOG(WS_LOG_DEBUG, "KeyingState now KEXINIT_DONE"); - ssh->keyingState = KEYING_KEXINIT_DONE; - } - else if (ssh->keyingState == KEYING_KEYED) { - WLOG(WS_LOG_DEBUG, "KeyingState now KEXINIT_SENT"); - ssh->keyingState = KEYING_KEXINIT_SENT; - } - } - WLOG(WS_LOG_DEBUG, "Leaving SendKexInit(), ret = %d", ret); return ret; } -/* This function is clunky, but outdated. +/* SendKexDhReply() * It is also the funciton used for MSGID_KEXECDH_REPLY. The parameters * are analogous between the two messages. Where MSGID_KEXDH_REPLY has * server's public host key (K_S), f, and the signature of H; @@ -3785,69 +4518,69 @@ int SendKexInit(WOLFSSH* ssh) * for GEXDH. */ int SendKexDhReply(WOLFSSH* ssh) { - const uint8_t* primeGroup = dhPrimeGroup14; - uint32_t primeGroupSz = dhPrimeGroup14Sz; - const uint8_t* generator = dhGenerator; - uint32_t generatorSz = dhGeneratorSz; +/* This function and DoKexDhReply() are unwieldy and in need of refactoring. */ + const byte* primeGroup = dhPrimeGroup14; + word32 primeGroupSz = dhPrimeGroup14Sz; + const byte* generator = dhGenerator; + word32 generatorSz = dhGeneratorSz; - uint8_t useEcc = 0; - uint8_t f[257]; - uint32_t fSz = sizeof(f); - uint8_t fPad = 0; - uint8_t kPad = 0; + byte useEcc = 0; + byte f[257]; + word32 fSz = sizeof(f); + byte fPad = 0; + byte kPad = 0; struct { - uint8_t useRsa; - uint32_t sz; + byte useRsa; + word32 sz; const char *name; - uint32_t nameSz; + word32 nameSz; union { struct { - RsaKey key; - uint8_t e[257]; - uint32_t eSz; - uint8_t ePad; - uint8_t n[257]; - uint32_t nSz; - uint8_t nPad; + RsaKey key; + byte e[257]; + word32 eSz; + byte ePad; + byte n[257]; + word32 nSz; + byte nPad; } rsa; struct { ecc_key key; - uint32_t keyBlobSz; + word32 keyBlobSz; const char *keyBlobName; - uint32_t keyBlobNameSz; - uint8_t q[257]; - uint32_t qSz; - uint8_t qPad; + word32 keyBlobNameSz; + byte q[257]; + word32 qSz; + byte qPad; const char *primeName; - uint32_t primeNameSz; + word32 primeNameSz; } ecc; } sk; } sigKeyBlock; - uint8_t sig[512]; - uint32_t sigSz = sizeof(sig); - uint32_t sigBlockSz; + byte sig[512]; + word32 sigSz = sizeof(sig); + word32 sigBlockSz; - uint32_t payloadSz; - uint8_t scratchLen[LENGTH_SZ]; - uint32_t scratch = 0; - uint8_t* output; - uint32_t idx; + word32 payloadSz; + byte scratchLen[LENGTH_SZ]; + word32 scratch = 0; + byte* output; + word32 idx; int ret = WS_SUCCESS; - uint8_t msgId = MSGID_KEXDH_REPLY; + byte msgId = MSGID_KEXDH_REPLY; WLOG(WS_LOG_DEBUG, "Entering SendKexDhReply()"); sigKeyBlock.useRsa = ssh->handshake->pubKeyId == ID_SSH_RSA; sigKeyBlock.name = IdToName(ssh->handshake->pubKeyId); - sigKeyBlock.nameSz = (uint32_t)strlen(sigKeyBlock.name); + sigKeyBlock.nameSz = (word32)strlen(sigKeyBlock.name); switch (ssh->handshake->kexId) { case ID_DH_GROUP1_SHA1: primeGroup = dhPrimeGroup1; primeGroupSz = dhPrimeGroup1Sz; - msgId = MSGID_KEXDH_REPLY; break; case ID_DH_GROUP14_SHA1: @@ -3917,7 +4650,7 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == 0) ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, - (uint8_t*)sigKeyBlock.name, + (byte*)sigKeyBlock.name, sigKeyBlock.nameSz); /* Hash in the length of the RSA public key E value. */ if (ret == 0) { @@ -3968,7 +4701,7 @@ int SendKexDhReply(WOLFSSH* ssh) sigKeyBlock.sk.ecc.primeName = PrimeNameForId(ssh->handshake->pubKeyId); sigKeyBlock.sk.ecc.primeNameSz = - (uint32_t)strlen(sigKeyBlock.sk.ecc.primeName); + (word32)strlen(sigKeyBlock.sk.ecc.primeName); /* Decode the user-configured ECDSA private key. */ sigKeyBlock.sk.ecc.qSz = sizeof(sigKeyBlock.sk.ecc.q); @@ -4006,7 +4739,7 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == 0) ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, - (uint8_t*)sigKeyBlock.name, + (byte*)sigKeyBlock.name, sigKeyBlock.nameSz); /* Hash in the length of the name of the prime. */ if (ret == 0) { @@ -4019,7 +4752,7 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == 0) ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, - (const uint8_t*)sigKeyBlock.sk.ecc.primeName, + (const byte*)sigKeyBlock.sk.ecc.primeName, sigKeyBlock.sk.ecc.primeNameSz); /* Hash in the length of the public key. */ if (ret == 0) { @@ -4038,7 +4771,7 @@ int SendKexDhReply(WOLFSSH* ssh) /* If using DH-GEX include the GEX specific values. */ if (ssh->handshake->kexId == ID_DH_GEX_SHA256) { - uint8_t primeGroupPad = 0, generatorPad = 0; + byte primeGroupPad = 0, generatorPad = 0; /* Hash in the client's requested minimum key size. */ if (ret == 0) { @@ -4128,9 +4861,9 @@ int SendKexDhReply(WOLFSSH* ssh) /* Or make the server's ECDH private value, and the shared secret K. */ if (ret == 0) { if (!useEcc) { - DhKey privKey; - uint8_t y[256]; - uint32_t ySz = sizeof(y); + DhKey privKey; + byte y[256]; + word32 ySz = sizeof(y); ret = wc_InitDhKey(&privKey); if (ret == 0) @@ -4179,14 +4912,9 @@ int SendKexDhReply(WOLFSSH* ssh) } } - /* Add a pad byte if the mpint has the MSB set. */ - if (ret == 0) { - fPad = (f[0] & 0x80) ? 1 : 0; - kPad = (ssh->k[0] & 0x80) ? 1 : 0; - } - /* Hash in the server's DH f-value. */ if (ret == 0) { + fPad = (f[0] & 0x80) ? 1 : 0; c32toa(fSz + fPad, scratchLen); ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, scratchLen, LENGTH_SZ); @@ -4201,8 +4929,10 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == 0) ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, f, fSz); + /* Hash in the shared secret K. */ if (ret == 0) { + kPad = (ssh->k[0] & 0x80) ? 1 : 0; c32toa(ssh->kSz + kPad, scratchLen); ret = wc_HashUpdate(&ssh->handshake->hash, ssh->handshake->hashId, scratchLen, LENGTH_SZ); @@ -4237,8 +4967,8 @@ int SendKexDhReply(WOLFSSH* ssh) /* Sign h with the server's private key. */ if (ret == WS_SUCCESS) { wc_HashAlg digestHash; - uint8_t digest[WC_MAX_DIGEST_SIZE]; - uint8_t sigHashId; + byte digest[WC_MAX_DIGEST_SIZE]; + byte sigHashId; sigHashId = HashForId(ssh->handshake->pubKeyId); @@ -4252,8 +4982,8 @@ int SendKexDhReply(WOLFSSH* ssh) if (ret == WS_SUCCESS) { if (sigKeyBlock.useRsa) { - uint8_t encSig[MAX_ENCODED_SIG_SZ]; - uint32_t encSigSz; + byte encSig[MAX_ENCODED_SIG_SZ]; + word32 encSigSz; encSigSz = wc_EncodeSignature(encSig, digest, wc_HashGetDigestSize(sigHashId), @@ -4283,12 +5013,12 @@ int SendKexDhReply(WOLFSSH* ssh) ret = WS_ECC_E; } else { - uint8_t r[257]; - uint32_t rSz = sizeof(r); - uint8_t rPad; - uint8_t s[257]; - uint32_t sSz = sizeof(s); - uint8_t sPad; + byte r[257]; + word32 rSz = sizeof(r); + byte rPad; + byte s[257]; + word32 sSz = sizeof(s); + byte sPad; ret = wc_ecc_sig_to_rs(sig, sigSz, r, &rSz, s, &sSz); if (ret == 0) { @@ -4406,8 +5136,8 @@ int SendKexDhReply(WOLFSSH* ssh) int SendNewKeys(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx = 0; + byte* output; + word32 idx = 0; int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Entering SendNewKeys()"); @@ -4437,7 +5167,7 @@ int SendNewKeys(WOLFSSH* ssh) ssh->macSz = ssh->handshake->macSz; ssh->macId = ssh->handshake->macId; ssh->aeadMode = ssh->handshake->aeadMode; - WMEMCPY(&ssh->serverKeys, &ssh->handshake->serverKeys, sizeof(Keys)); + WMEMCPY(&ssh->keys, &ssh->handshake->keys, sizeof(Keys)); switch (ssh->encryptId) { case ID_NONE: @@ -4447,16 +5177,14 @@ int SendNewKeys(WOLFSSH* ssh) case ID_AES128_CBC: WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-cbc"); ret = wc_AesSetKey(&ssh->encryptCipher.aes, - ssh->serverKeys.encKey, - ssh->serverKeys.encKeySz, - ssh->serverKeys.iv, AES_ENCRYPTION); + ssh->keys.encKey, ssh->keys.encKeySz, + ssh->keys.iv, AES_ENCRYPTION); break; case ID_AES128_GCM: WLOG(WS_LOG_DEBUG, "SNK: using cipher aes128-gcm"); ret = wc_AesGcmSetKey(&ssh->encryptCipher.aes, - ssh->serverKeys.encKey, - ssh->serverKeys.encKeySz); + ssh->keys.encKey, ssh->keys.encKeySz); break; default: @@ -4467,17 +5195,6 @@ int SendNewKeys(WOLFSSH* ssh) if (ret == WS_SUCCESS) { ssh->txCount = 0; - if (ssh->keyingState == KEYING_USING_KEYS_RECV) { - ssh->highwaterFlag = 0; - ssh->keyingState = KEYING_KEYED; - HandshakeInfoFree(ssh->handshake, ssh->ctx->heap); - ssh->handshake = NULL; - WLOG(WS_LOG_DEBUG, "KeyingState now KEYED"); - } - else { - ssh->keyingState = KEYING_USING_KEYS_SENT; - WLOG(WS_LOG_DEBUG, "KeyingState now USING_KEYS_SENT"); - } } WLOG(WS_LOG_DEBUG, "Leaving SendNewKeys(), ret = %d", ret); @@ -4485,17 +5202,61 @@ int SendNewKeys(WOLFSSH* ssh) } +#ifndef WOLFSSH_NO_CLIENT +int SendKexDhGexRequest(WOLFSSH* ssh) +{ + byte* output; + word32 idx = 0; + word32 payloadSz; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering SendKexDhGexRequest()"); + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + payloadSz = MSG_ID_SZ + (UINT32_SZ * 3); + ret = PreparePacket(ssh, payloadSz); + } + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_KEXDH_GEX_REQUEST; + + c32toa(ssh->handshake->dhGexMinSz, output + idx); + idx += UINT32_SZ; + c32toa(ssh->handshake->dhGexPreferredSz, output + idx); + idx += UINT32_SZ; + c32toa(ssh->handshake->dhGexMaxSz, output + idx); + idx += UINT32_SZ; + + ssh->outputBuffer.length = idx; + + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = SendBuffered(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendKexDhGexRequest(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + int SendKexDhGexGroup(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx = 0; - uint32_t payloadSz; - const uint8_t* primeGroup = dhPrimeGroup14; - uint32_t primeGroupSz = dhPrimeGroup14Sz; - const uint8_t* generator = dhGenerator; - uint32_t generatorSz = dhGeneratorSz; - uint8_t primePad = 0; - uint8_t generatorPad = 0; + byte* output; + word32 idx = 0; + word32 payloadSz; + const byte* primeGroup = dhPrimeGroup14; + word32 primeGroupSz = dhPrimeGroup14Sz; + const byte* generator = dhGenerator; + word32 generatorSz = dhGeneratorSz; + byte primePad = 0; + byte generatorPad = 0; int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Entering SendKexDhGexGroup()"); @@ -4551,18 +5312,145 @@ int SendKexDhGexGroup(WOLFSSH* ssh) if (ret == WS_SUCCESS) ret = SendBuffered(ssh); - /* Act on data */ - WLOG(WS_LOG_DEBUG, "Leaving SendKexDhGexGroup(), ret = %d", ret); return ret; } +#ifndef WOLFSSH_NO_CLIENT +int SendKexDhInit(WOLFSSH* ssh) +{ + byte* output; + word32 idx = 0; + word32 payloadSz; + const byte* primeGroup = dhPrimeGroup14; + word32 primeGroupSz = dhPrimeGroup14Sz; + const byte* generator = dhGenerator; + word32 generatorSz = dhGeneratorSz; + int ret = WS_SUCCESS; + byte msgId = MSGID_KEXDH_INIT; + byte e[256]; + word32 eSz = sizeof(e); + byte ePad = 0; + + WLOG(WS_LOG_DEBUG, "Entering SendKexDhInit()"); + + switch (ssh->handshake->kexId) { + case ID_DH_GROUP1_SHA1: + primeGroup = dhPrimeGroup1; + primeGroupSz = dhPrimeGroup1Sz; + break; + + case ID_DH_GROUP14_SHA1: + /* This is the default case. */ + break; + + case ID_DH_GEX_SHA256: + primeGroup = ssh->handshake->primeGroup; + primeGroupSz = ssh->handshake->primeGroupSz; + generator = ssh->handshake->generator; + generatorSz = ssh->handshake->generatorSz; + msgId = MSGID_KEXDH_GEX_INIT; + break; + + case ID_ECDH_SHA2_NISTP256: + case ID_ECDH_SHA2_NISTP384: + case ID_ECDH_SHA2_NISTP521: + ssh->handshake->useEcc = 1; + msgId = MSGID_KEXECDH_INIT; + break; + + default: + WLOG(WS_LOG_DEBUG, "Invalid algo: %u", ssh->handshake->kexId); + ret = WS_INVALID_ALGO_ID; + } + + + if (ret == WS_SUCCESS) { + if (!ssh->handshake->useEcc) { + DhKey* privKey = &ssh->handshake->privKey.dh; + + ret = wc_InitDhKey(privKey); + if (ret == 0) + ret = wc_DhSetKey(privKey, primeGroup, primeGroupSz, + generator, generatorSz); + if (ret == 0) + ret = wc_DhGenerateKeyPair(privKey, ssh->rng, + ssh->handshake->x, + &ssh->handshake->xSz, + e, &eSz); + } + else { + ecc_key* privKey = &ssh->handshake->privKey.ecc; + int primeId = wcPrimeForId(ssh->handshake->kexId); + + if (primeId == ECC_CURVE_INVALID) + ret = WS_INVALID_PRIME_CURVE; + + if (ret == 0) + ret = wc_ecc_init_ex(privKey, ssh->ctx->heap, + INVALID_DEVID); + + if (ret == 0) + ret = wc_ecc_make_key_ex(ssh->rng, + wc_ecc_get_curve_size_from_id(primeId), + privKey, primeId); + if (ret == 0) + ret = wc_ecc_export_x963(privKey, e, &eSz); + } + + if (ret == 0) + ret = WS_SUCCESS; + } + + if (ret == WS_SUCCESS) { + if (e[0] & 0x80) { + ePad = 1; + ssh->handshake->e[0] = 0; + } + WMEMCPY(ssh->handshake->e + ePad, e, eSz); + ssh->handshake->eSz = eSz + ePad; + + payloadSz = MSG_ID_SZ + LENGTH_SZ + eSz + ePad; + ret = PreparePacket(ssh, payloadSz); + } + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = msgId; + + c32toa(eSz + ePad, output + idx); + idx += LENGTH_SZ; + + if (ePad) { + output[idx] = 0; + idx += 1; + } + + WMEMCPY(output + idx, e, eSz); + idx += eSz; + + ssh->outputBuffer.length = idx; + + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = SendBuffered(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendKexDhInit(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + int SendUnimplemented(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx = 0; - int ret = WS_SUCCESS; + byte* output; + word32 idx = 0; + int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Entering SendUnimplemented(), peerSeq = %u", ssh->peerSeq); @@ -4594,11 +5482,11 @@ int SendUnimplemented(WOLFSSH* ssh) } -int SendDisconnect(WOLFSSH* ssh, uint32_t reason) +int SendDisconnect(WOLFSSH* ssh, word32 reason) { - uint8_t* output; - uint32_t idx = 0; - int ret = WS_SUCCESS; + byte* output; + word32 idx = 0; + int ret = WS_SUCCESS; if (ssh == NULL) ret = WS_BAD_ARGUMENT; @@ -4630,11 +5518,11 @@ int SendDisconnect(WOLFSSH* ssh, uint32_t reason) } -int SendIgnore(WOLFSSH* ssh, const unsigned char* data, uint32_t dataSz) +int SendIgnore(WOLFSSH* ssh, const unsigned char* data, word32 dataSz) { - uint8_t* output; - uint32_t idx = 0; - int ret = WS_SUCCESS; + byte* output; + word32 idx = 0; + int ret = WS_SUCCESS; if (ssh == NULL || (data == NULL && dataSz > 0)) ret = WS_BAD_ARGUMENT; @@ -4666,22 +5554,22 @@ int SendIgnore(WOLFSSH* ssh, const unsigned char* data, uint32_t dataSz) } -static const char cannedLangTag[] = "en-us"; -static const uint32_t cannedLangTagSz = sizeof(cannedLangTag) - 1; +static const char cannedLangTag[] = "en-us"; +static const word32 cannedLangTagSz = sizeof(cannedLangTag) - 1; int SendDebug(WOLFSSH* ssh, byte alwaysDisplay, const char* msg) { - uint32_t msgSz; - uint8_t* output; - uint32_t idx = 0; - int ret = WS_SUCCESS; + word32 msgSz; + byte* output; + word32 idx = 0; + int ret = WS_SUCCESS; if (ssh == NULL) ret = WS_BAD_ARGUMENT; if (ret == WS_SUCCESS) { - msgSz = (msg != NULL) ? (uint32_t)WSTRLEN(msg) : 0; + msgSz = (msg != NULL) ? (word32)WSTRLEN(msg) : 0; ret = PreparePacket(ssh, MSG_ID_SZ + BOOLEAN_SZ + (LENGTH_SZ * 2) + @@ -4717,22 +5605,66 @@ int SendDebug(WOLFSSH* ssh, byte alwaysDisplay, const char* msg) } -const char userAuthName[] = "ssh-userauth"; - - -int SendServiceAccept(WOLFSSH* ssh) +#ifndef WOLFSSH_NO_CLIENT +int SendServiceRequest(WOLFSSH* ssh, byte serviceId) { - uint32_t nameSz; - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + const char* serviceName; + word32 serviceNameSz; + byte* output; + word32 idx; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering SendServiceRequest()"); if (ssh == NULL) ret = WS_BAD_ARGUMENT; if (ret == WS_SUCCESS) { - nameSz = (uint32_t)WSTRLEN(userAuthName); - ret = PreparePacket(ssh, MSG_ID_SZ + LENGTH_SZ + nameSz); + serviceName = IdToName(serviceId); + serviceNameSz = (word32)WSTRLEN(serviceName); + + ret = PreparePacket(ssh, + MSG_ID_SZ + LENGTH_SZ + serviceNameSz); + } + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_SERVICE_REQUEST; + c32toa(serviceNameSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, serviceName, serviceNameSz); + idx += serviceNameSz; + + ssh->outputBuffer.length = idx; + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = SendBuffered(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendServiceRequest(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + +int SendServiceAccept(WOLFSSH* ssh, byte serviceId) +{ + const char* serviceName; + word32 serviceNameSz; + byte* output; + word32 idx; + int ret = WS_SUCCESS; + + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + serviceName = IdToName(serviceId); + serviceNameSz = (word32)WSTRLEN(serviceName); + ret = PreparePacket(ssh, MSG_ID_SZ + LENGTH_SZ + serviceNameSz); } if (ret == WS_SUCCESS) { @@ -4740,10 +5672,10 @@ int SendServiceAccept(WOLFSSH* ssh) idx = ssh->outputBuffer.length; output[idx++] = MSGID_SERVICE_ACCEPT; - c32toa(nameSz, output + idx); + c32toa(serviceNameSz, output + idx); idx += LENGTH_SZ; - WMEMCPY(output + idx, userAuthName, nameSz); - idx += nameSz; + WMEMCPY(output + idx, serviceName, serviceNameSz); + idx += serviceNameSz; ssh->outputBuffer.length = idx; @@ -4758,13 +5690,106 @@ int SendServiceAccept(WOLFSSH* ssh) static const char cannedAuths[] = "publickey,password"; -static const uint32_t cannedAuthsSz = sizeof(cannedAuths) - 1; +static const word32 cannedAuthsSz = sizeof(cannedAuths) - 1; -int SendUserAuthFailure(WOLFSSH* ssh, uint8_t partialSuccess) +#ifndef WOLFSSH_NO_CLIENT +int SendUserAuthRequest(WOLFSSH* ssh, byte authId) { - uint8_t* output; - uint32_t idx; + byte* output; + word32 idx; + const char* authName; + word32 authNameSz; + const char* serviceName; + word32 serviceNameSz; + word32 payloadSz; + int ret = WS_SUCCESS; + WS_UserAuthData authData; + + WLOG(WS_LOG_DEBUG, "Entering SendUserAuthRequest()"); + + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + if (authId == ID_USERAUTH_PASSWORD && ssh->ctx->userAuthCb != NULL) { + WLOG(WS_LOG_DEBUG, "SUARPW: Calling the userauth callback"); + ret = ssh->ctx->userAuthCb(WOLFSSH_USERAUTH_PASSWORD, + &authData, ssh->userAuthCtx); + if (ret != WOLFSSH_USERAUTH_SUCCESS) { + WLOG(WS_LOG_DEBUG, "SUARPW: Couldn't get password"); + ret = WS_FATAL_ERROR; + } + } + } + + if (ret == WS_SUCCESS) { + serviceName = IdToName(ID_SERVICE_CONNECTION); + serviceNameSz = (word32)WSTRLEN(serviceName); + authName = IdToName(authId); + authNameSz = (word32)WSTRLEN(authName); + + payloadSz = MSG_ID_SZ + (LENGTH_SZ * 3) + + ssh->userNameSz + serviceNameSz + authNameSz; + + if (authId == ID_USERAUTH_PASSWORD) { + payloadSz += BOOLEAN_SZ + LENGTH_SZ + + authData.sf.password.passwordSz; + } + else if (authId != ID_NONE) + ret = WS_INVALID_ALGO_ID; + } + + if (ret == WS_SUCCESS) + ret = PreparePacket(ssh, payloadSz); + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_USERAUTH_REQUEST; + c32toa(ssh->userNameSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, ssh->userName, ssh->userNameSz); + idx += ssh->userNameSz; + + c32toa(serviceNameSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, serviceName, serviceNameSz); + idx += serviceNameSz; + + c32toa(authNameSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, authName, authNameSz); + idx += authNameSz; + + if (authId == ID_USERAUTH_PASSWORD) { + output[idx++] = 0; /* Boolean "FALSE" for password change */ + c32toa(authData.sf.password.passwordSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, authData.sf.password.password, + authData.sf.password.passwordSz); + idx += authData.sf.password.passwordSz; + } + + ssh->outputBuffer.length = idx; + + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = SendBuffered(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendUserAuthRequest(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + +int SendUserAuthFailure(WOLFSSH* ssh, byte partialSuccess) +{ + byte* output; + word32 idx; int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Entering SendUserAuthFailure()"); @@ -4802,9 +5827,9 @@ int SendUserAuthFailure(WOLFSSH* ssh, uint8_t partialSuccess) int SendUserAuthSuccess(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + int ret = WS_SUCCESS; if (ssh == NULL) ret = WS_BAD_ARGUMENT; @@ -4831,11 +5856,11 @@ int SendUserAuthSuccess(WOLFSSH* ssh) int SendUserAuthPkOk(WOLFSSH* ssh, - const uint8_t* algoName, uint32_t algoNameSz, - const uint8_t* publicKey, uint32_t publicKeySz) + const byte* algoName, word32 algoNameSz, + const byte* publicKey, word32 publicKeySz) { - uint8_t* output; - uint32_t idx; + byte* output; + word32 idx; int ret = WS_SUCCESS; if (ssh == NULL || @@ -4877,11 +5902,11 @@ int SendUserAuthPkOk(WOLFSSH* ssh, int SendUserAuthBanner(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + int ret = WS_SUCCESS; const char* banner; - uint32_t bannerSz = 0; + word32 bannerSz = 0; if (ssh == NULL) ret = WS_BAD_ARGUMENT; @@ -4924,8 +5949,8 @@ int SendUserAuthBanner(WOLFSSH* ssh) int SendRequestSuccess(WOLFSSH* ssh, int success) { - uint8_t* output; - uint32_t idx; + byte* output; + word32 idx; int ret = WS_SUCCESS; WLOG(WS_LOG_DEBUG, "Entering SendRequestSuccess(), %s", @@ -4957,11 +5982,75 @@ int SendRequestSuccess(WOLFSSH* ssh, int success) } +#ifndef WOLFSSH_NO_CLIENT +int SendChannelOpenSession(WOLFSSH* ssh, + word32 initialWindowSz, word32 maxPacketSz) +{ + WOLFSSH_CHANNEL* newChannel; + byte* output; + const char* channelType; + word32 channelTypeSz, channelId, idx; + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering SendChannelOpenSession()"); + + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + channelId = ssh->nextChannel; + newChannel = ChannelNew(ssh, ID_CHANTYPE_SESSION, + initialWindowSz, maxPacketSz); + if (newChannel == NULL) + ret = WS_MEMORY_E; + + if (ret == WS_SUCCESS) + ret = ChannelAppend(ssh, newChannel); + } + + if (ret == WS_SUCCESS) { + channelType = IdToName(ID_CHANTYPE_SESSION); + channelTypeSz = (word32)WSTRLEN(channelType); + + ret = PreparePacket(ssh, MSG_ID_SZ + LENGTH_SZ + channelTypeSz + + (UINT32_SZ * 3)); + } + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_CHANNEL_OPEN; + c32toa(channelTypeSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, channelType, channelTypeSz); + idx += channelTypeSz; + c32toa(channelId, output + idx); + idx += UINT32_SZ; + c32toa(initialWindowSz, output + idx); + idx += UINT32_SZ; + c32toa(maxPacketSz, output + idx); + idx += UINT32_SZ; + + ssh->outputBuffer.length = idx; + + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = SendBuffered(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendChannelOpenSession(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + int SendChannelOpenConf(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + int ret = WS_SUCCESS; WOLFSSH_CHANNEL* channel; WLOG(WS_LOG_DEBUG, "Entering SendChannelOpenConf()"); @@ -5005,11 +6094,11 @@ int SendChannelOpenConf(WOLFSSH* ssh) } -int SendChannelEof(WOLFSSH* ssh, uint32_t peerChannelId) +int SendChannelEof(WOLFSSH* ssh, word32 peerChannelId) { - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + int ret = WS_SUCCESS; WOLFSSH_CHANNEL* channel; WLOG(WS_LOG_DEBUG, "Entering SendChannelEof()"); @@ -5047,11 +6136,11 @@ int SendChannelEof(WOLFSSH* ssh, uint32_t peerChannelId) } -int SendChannelClose(WOLFSSH* ssh, uint32_t peerChannelId) +int SendChannelClose(WOLFSSH* ssh, word32 peerChannelId) { - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + int ret = WS_SUCCESS; WOLFSSH_CHANNEL* channel; WLOG(WS_LOG_DEBUG, "Entering SendChannelClose()"); @@ -5089,12 +6178,12 @@ int SendChannelClose(WOLFSSH* ssh, uint32_t peerChannelId) } -int SendChannelData(WOLFSSH* ssh, uint32_t peerChannel, - uint8_t* data, uint32_t dataSz) +int SendChannelData(WOLFSSH* ssh, word32 peerChannel, + byte* data, word32 dataSz) { - uint8_t* output; - uint32_t idx; - int ret = WS_SUCCESS; + byte* output; + word32 idx; + int ret = WS_SUCCESS; WOLFSSH_CHANNEL* channel; WLOG(WS_LOG_DEBUG, "Entering SendChannelData()"); @@ -5103,7 +6192,7 @@ int SendChannelData(WOLFSSH* ssh, uint32_t peerChannel, ret = WS_BAD_ARGUMENT; if (ret == WS_SUCCESS) { - if (ssh->keyingState != KEYING_KEYED) + if (ssh->isKeying) ret = WS_REKEYING; } @@ -5116,7 +6205,7 @@ int SendChannelData(WOLFSSH* ssh, uint32_t peerChannel, } if (ret == WS_SUCCESS) { - uint32_t bound = min(channel->peerWindowSz, channel->peerMaxPacketSz); + word32 bound = min(channel->peerWindowSz, channel->peerMaxPacketSz); if (dataSz > bound) { WLOG(WS_LOG_DEBUG, @@ -5161,11 +6250,11 @@ int SendChannelData(WOLFSSH* ssh, uint32_t peerChannel, } -int SendChannelWindowAdjust(WOLFSSH* ssh, uint32_t peerChannel, - uint32_t bytesToAdd) +int SendChannelWindowAdjust(WOLFSSH* ssh, word32 peerChannel, + word32 bytesToAdd) { - uint8_t* output; - uint32_t idx; + byte* output; + word32 idx; int ret = WS_SUCCESS; WOLFSSH_CHANNEL* channel; @@ -5205,10 +6294,64 @@ int SendChannelWindowAdjust(WOLFSSH* ssh, uint32_t peerChannel, } -int SendChannelSuccess(WOLFSSH* ssh, uint32_t channelId, int success) +#ifndef WOLFSSH_NO_CLIENT +static const char cannedShellName[] = "shell"; +static const word32 cannedShellNameSz = sizeof(cannedShellName) - 1; + + +int SendChannelRequestShell(WOLFSSH* ssh) { - uint8_t* output; - uint32_t idx; + byte* output; + word32 idx; + int ret = WS_SUCCESS; + WOLFSSH_CHANNEL* channel; + + WLOG(WS_LOG_DEBUG, "Entering SendChannelRequestShell()"); + + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) { + channel = ChannelFind(ssh, ssh->defaultPeerChannelId, FIND_PEER); + if (channel == NULL) + ret = WS_INVALID_CHANID; + } + + if (ret == WS_SUCCESS) + ret = PreparePacket(ssh, MSG_ID_SZ + UINT32_SZ + LENGTH_SZ + + cannedShellNameSz + BOOLEAN_SZ); + + if (ret == WS_SUCCESS) { + output = ssh->outputBuffer.buffer; + idx = ssh->outputBuffer.length; + + output[idx++] = MSGID_CHANNEL_REQUEST; + c32toa(channel->peerChannel, output + idx); + idx += UINT32_SZ; + c32toa(cannedShellNameSz, output + idx); + idx += LENGTH_SZ; + WMEMCPY(output + idx, cannedShellName, cannedShellNameSz); + idx += cannedShellNameSz; + output[idx++] = 1; + + ssh->outputBuffer.length = idx; + + ret = BundlePacket(ssh); + } + + if (ret == WS_SUCCESS) + ret = SendBuffered(ssh); + + WLOG(WS_LOG_DEBUG, "Leaving SendChannelRequestShell(), ret = %d", ret); + return ret; +} +#endif /* WOLFSSH_NO_CLIENT */ + + +int SendChannelSuccess(WOLFSSH* ssh, word32 channelId, int success) +{ + byte* output; + word32 idx; int ret = WS_SUCCESS; WOLFSSH_CHANNEL* channel; @@ -5254,7 +6397,7 @@ int SendChannelSuccess(WOLFSSH* ssh, uint32_t channelId, int success) #ifdef DEBUG_WOLFSSH #define LINE_WIDTH 16 -void DumpOctetString(const uint8_t* input, uint32_t inputSz) +void DumpOctetString(const byte* input, word32 inputSz) { int rows = inputSz / LINE_WIDTH; int remainder = inputSz % LINE_WIDTH; diff --git a/src/io.c b/src/io.c index b1824767..01c2d175 100644 --- a/src/io.c +++ b/src/io.c @@ -268,7 +268,7 @@ static INLINE int LastError(void) /* The receive embedded callback * return : nb bytes read, or error */ -int wsEmbedRecv(WOLFSSH* ssh, void* data, uint32_t sz, void* ctx) +int wsEmbedRecv(WOLFSSH* ssh, void* data, word32 sz, void* ctx) { int recvd; int err; @@ -320,7 +320,7 @@ int wsEmbedRecv(WOLFSSH* ssh, void* data, uint32_t sz, void* ctx) /* The send embedded callback * return : nb bytes sent, or error */ -int wsEmbedSend(WOLFSSH* ssh, void* data, uint32_t sz, void* ctx) +int wsEmbedSend(WOLFSSH* ssh, void* data, word32 sz, void* ctx) { int sd = *(int*)ctx; int sent; diff --git a/src/keygen.c b/src/keygen.c index 2bdb09ef..e5c56ce7 100644 --- a/src/keygen.c +++ b/src/keygen.c @@ -29,12 +29,12 @@ #include #endif -#include -#include -#include #include #include #include +#include +#include +#include #ifdef WOLFSSH_KEYGEN @@ -46,8 +46,8 @@ #endif -int wolfSSH_MakeRsaKey(uint8_t* out, uint32_t outSz, - uint32_t size, uint32_t e) +int wolfSSH_MakeRsaKey(byte* out, word32 outSz, + word32 size, word32 e) { int ret = WS_SUCCESS; WC_RNG rng; diff --git a/src/misc.c b/src/misc.c index fad0d231..eb4046e7 100644 --- a/src/misc.c +++ b/src/misc.c @@ -61,7 +61,7 @@ #ifndef min -STATIC INLINE uint32_t min(uint32_t a, uint32_t b) +STATIC INLINE word32 min(word32 a, word32 b) { return a > b ? b : a; } @@ -69,14 +69,14 @@ STATIC INLINE uint32_t min(uint32_t a, uint32_t b) /* convert opaque to 32 bit integer */ -STATIC INLINE void ato32(const uint8_t* c, uint32_t* u32) +STATIC INLINE void ato32(const byte* c, word32* u32) { *u32 = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; } /* convert 32 bit integer to opaque */ -STATIC INLINE void c32toa(uint32_t u32, uint8_t* c) +STATIC INLINE void c32toa(word32 u32, byte* c) { c[0] = (u32 >> 24) & 0xff; c[1] = (u32 >> 16) & 0xff; @@ -86,20 +86,20 @@ STATIC INLINE void c32toa(uint32_t u32, uint8_t* c) /* Make sure compiler doesn't skip */ -STATIC INLINE void ForceZero(const void* mem, uint32_t length) +STATIC INLINE void ForceZero(const void* mem, word32 length) { - volatile uint8_t* z = (volatile uint8_t*)mem; + volatile byte* z = (volatile byte*)mem; while (length--) *z++ = 0; } /* check all length bytes for equality, return 0 on success */ -STATIC INLINE int ConstantCompare(const uint8_t* a, const uint8_t* b, - uint32_t length) +STATIC INLINE int ConstantCompare(const byte* a, const byte* b, + word32 length) { - uint32_t i; - uint32_t compareSum = 0; + word32 i; + word32 compareSum = 0; for (i = 0; i < length; i++) { compareSum |= a[i] ^ b[i]; diff --git a/src/port.c b/src/port.c index 1f6550b1..43d3d0ff 100644 --- a/src/port.c +++ b/src/port.c @@ -31,9 +31,24 @@ #include #endif +#include #include +int wfopen(WFILE** f, const char* filename, const char* mode) +{ +#ifdef USE_WINDOWS_API + return fopen_s(f, filename, mode) != 0; +#else + if (f != NULL) { + *f = fopen(filename, mode); + return *f == NULL; + } + return 1; +#endif +} + + #ifndef WSTRING_USER char* wstrnstr(const char* s1, const char* s2, unsigned int n) @@ -55,4 +70,3 @@ char* wstrnstr(const char* s1, const char* s2, unsigned int n) } #endif /* WSTRING_USER */ - diff --git a/src/ssh.c b/src/ssh.c index bb8552bd..2bc55284 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -56,13 +56,19 @@ int wolfSSH_Init(void) int wolfSSH_Cleanup(void) { + int ret = WS_SUCCESS; + WLOG(WS_LOG_DEBUG, "Entering wolfSSH_Cleanup()"); - WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_Cleanup(), returning %d", WS_SUCCESS); - return WS_SUCCESS; + + if (wolfCrypt_Cleanup() != 0) + ret = WS_CRYPTO_FAILED; + + WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_Cleanup(), returning %d", ret); + return ret; } -WOLFSSH_CTX* wolfSSH_CTX_new(uint8_t side, void* heap) +WOLFSSH_CTX* wolfSSH_CTX_new(byte side, void* heap) { WOLFSSH_CTX* ctx; @@ -74,7 +80,7 @@ WOLFSSH_CTX* wolfSSH_CTX_new(uint8_t side, void* heap) } ctx = (WOLFSSH_CTX*)WMALLOC(sizeof(WOLFSSH_CTX), heap, DYNTYPE_CTX); - ctx = CtxInit(ctx, heap); + ctx = CtxInit(ctx, side, heap); WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CTX_new(), ctx = %p", ctx); @@ -158,7 +164,7 @@ int wolfSSH_get_fd(const WOLFSSH* ssh) } -int wolfSSH_SetHighwater(WOLFSSH* ssh, uint32_t highwater) +int wolfSSH_SetHighwater(WOLFSSH* ssh, word32 highwater) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetHighwater()"); @@ -172,7 +178,7 @@ int wolfSSH_SetHighwater(WOLFSSH* ssh, uint32_t highwater) } -uint32_t wolfSSH_GetHighwater(WOLFSSH* ssh) +word32 wolfSSH_GetHighwater(WOLFSSH* ssh) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_GetHighwater()"); @@ -183,7 +189,7 @@ uint32_t wolfSSH_GetHighwater(WOLFSSH* ssh) } -void wolfSSH_SetHighwaterCb(WOLFSSH_CTX* ctx, uint32_t highwater, +void wolfSSH_SetHighwaterCb(WOLFSSH_CTX* ctx, word32 highwater, WS_CallbackHighwater cb) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_SetHighwaterCb()"); @@ -245,19 +251,23 @@ int wolfSSH_accept(WOLFSSH* ssh) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_accept()"); + if (ssh == NULL) + return WS_BAD_ARGUMENT; + switch (ssh->acceptState) { case ACCEPT_BEGIN: - if ( (ssh->error = SendServerVersion(ssh)) < WS_SUCCESS) { + if ( (ssh->error = SendProtoId(ssh)) < WS_SUCCESS) { WLOG(WS_LOG_DEBUG, acceptError, "BEGIN", ssh->error); return WS_FATAL_ERROR; } ssh->acceptState = ACCEPT_SERVER_VERSION_SENT; WLOG(WS_LOG_DEBUG, acceptState, "SERVER_VERSION_SENT"); + FALL_THROUGH; case ACCEPT_SERVER_VERSION_SENT: while (ssh->clientState < CLIENT_VERSION_DONE) { - if ( (ssh->error = ProcessClientVersion(ssh)) < WS_SUCCESS) { + if ( (ssh->error = DoProtoId(ssh)) < WS_SUCCESS) { WLOG(WS_LOG_DEBUG, acceptError, "SERVER_VERSION_SENT", ssh->error); return WS_FATAL_ERROR; @@ -265,17 +275,29 @@ int wolfSSH_accept(WOLFSSH* ssh) } ssh->acceptState = ACCEPT_CLIENT_VERSION_DONE; WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_VERSION_DONE"); + FALL_THROUGH; case ACCEPT_CLIENT_VERSION_DONE: - while (ssh->keyingState < KEYING_KEYED) { + if ( (ssh->error = SendKexInit(ssh)) < WS_SUCCESS) { + WLOG(WS_LOG_DEBUG, acceptError, + "CLIENT_VERSION_DONE", ssh->error); + return WS_FATAL_ERROR; + } + ssh->acceptState = ACCEPT_SERVER_KEXINIT_SENT; + WLOG(WS_LOG_DEBUG, acceptState, "SERVER_KEXINIT_SENT"); + FALL_THROUGH; + + case ACCEPT_SERVER_KEXINIT_SENT: + while (ssh->isKeying) { if ( (ssh->error = DoReceive(ssh)) < WS_SUCCESS) { WLOG(WS_LOG_DEBUG, acceptError, - "CLIENT_VERSION_DONE", ssh->error); + "SERVER_KEXINIT_SENT", ssh->error); return WS_FATAL_ERROR; } } ssh->acceptState = ACCEPT_KEYED; WLOG(WS_LOG_DEBUG, acceptState, "KEYED"); + FALL_THROUGH; case ACCEPT_KEYED: while (ssh->clientState < CLIENT_USERAUTH_REQUEST_DONE) { @@ -287,9 +309,11 @@ int wolfSSH_accept(WOLFSSH* ssh) } ssh->acceptState = ACCEPT_CLIENT_USERAUTH_REQUEST_DONE; WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_USERAUTH_REQUEST_DONE"); + FALL_THROUGH; case ACCEPT_CLIENT_USERAUTH_REQUEST_DONE: - if ( (ssh->error = SendServiceAccept(ssh)) < WS_SUCCESS) { + if ( (ssh->error = SendServiceAccept(ssh, ID_SERVICE_USERAUTH)) < + WS_SUCCESS) { WLOG(WS_LOG_DEBUG, acceptError, "CLIENT_USERAUTH_REQUEST_DONE", ssh->error); return WS_FATAL_ERROR; @@ -297,6 +321,7 @@ int wolfSSH_accept(WOLFSSH* ssh) ssh->acceptState = ACCEPT_SERVER_USERAUTH_ACCEPT_SENT; WLOG(WS_LOG_DEBUG, acceptState, "ACCEPT_SERVER_USERAUTH_ACCEPT_SENT"); + FALL_THROUGH; case ACCEPT_SERVER_USERAUTH_ACCEPT_SENT: while (ssh->clientState < CLIENT_USERAUTH_DONE) { @@ -308,6 +333,7 @@ int wolfSSH_accept(WOLFSSH* ssh) } ssh->acceptState = ACCEPT_CLIENT_USERAUTH_DONE; WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_USERAUTH_DONE"); + FALL_THROUGH; case ACCEPT_CLIENT_USERAUTH_DONE: if ( (ssh->error = SendUserAuthSuccess(ssh)) < WS_SUCCESS) { @@ -317,6 +343,7 @@ int wolfSSH_accept(WOLFSSH* ssh) } ssh->acceptState = ACCEPT_SERVER_USERAUTH_SENT; WLOG(WS_LOG_DEBUG, acceptState, "SERVER_USERAUTH_SENT"); + FALL_THROUGH; case ACCEPT_SERVER_USERAUTH_SENT: while (ssh->clientState < CLIENT_DONE) { @@ -328,6 +355,7 @@ int wolfSSH_accept(WOLFSSH* ssh) } ssh->acceptState = ACCEPT_CLIENT_CHANNEL_REQUEST_DONE; WLOG(WS_LOG_DEBUG, acceptState, "CLIENT_CHANNEL_REQUEST_DONE"); + FALL_THROUGH; case ACCEPT_CLIENT_CHANNEL_REQUEST_DONE: if ( (ssh->error = SendChannelOpenConf(ssh)) < WS_SUCCESS) { @@ -343,6 +371,29 @@ int wolfSSH_accept(WOLFSSH* ssh) } +int wolfSSH_shutdown(WOLFSSH* ssh) +{ + int ret = WS_SUCCESS; + + WLOG(WS_LOG_DEBUG, "Entering wolfSSH_shutdown()"); + + if (ssh == NULL) + ret = WS_BAD_ARGUMENT; + + if (ret == WS_SUCCESS) + ret = SendChannelEof(ssh, 0); + + if (ret == WS_SUCCESS) + ret = SendChannelClose(ssh, 0); + + if (ret == WS_SUCCESS) + ret = SendDisconnect(ssh, WOLFSSH_DISCONNECT_BY_APPLICATION); + + WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_shutdown(), ret = %d", ret); + return ret; +} + + int wolfSSH_TriggerKeyExchange(WOLFSSH* ssh) { int ret = WS_SUCCESS; @@ -359,7 +410,7 @@ int wolfSSH_TriggerKeyExchange(WOLFSSH* ssh) } -int wolfSSH_stream_read(WOLFSSH* ssh, uint8_t* buf, uint32_t bufSz) +int wolfSSH_stream_read(WOLFSSH* ssh, byte* buf, word32 bufSz) { Buffer* inputBuffer; @@ -382,11 +433,10 @@ int wolfSSH_stream_read(WOLFSSH* ssh, uint8_t* buf, uint32_t bufSz) WMEMCPY(buf, inputBuffer->buffer + inputBuffer->idx, bufSz); inputBuffer->idx += bufSz; - if (ssh->keyingState == KEYING_KEYED && - (inputBuffer->length > inputBuffer->bufferSz / 2)) { + if (!ssh->isKeying && (inputBuffer->length > inputBuffer->bufferSz / 2)) { - uint32_t usedSz = inputBuffer->length - inputBuffer->idx; - uint32_t bytesToAdd = inputBuffer->idx; + word32 usedSz = inputBuffer->length - inputBuffer->idx; + word32 bytesToAdd = inputBuffer->idx; int sendResult; WLOG(WS_LOG_DEBUG, "Making more room: %u", usedSz); @@ -416,7 +466,7 @@ int wolfSSH_stream_read(WOLFSSH* ssh, uint8_t* buf, uint32_t bufSz) } -int wolfSSH_stream_send(WOLFSSH* ssh, uint8_t* buf, uint32_t bufSz) +int wolfSSH_stream_send(WOLFSSH* ssh, byte* buf, word32 bufSz) { int bytesTxd = 0; @@ -460,7 +510,7 @@ void* wolfSSH_GetUserAuthCtx(WOLFSSH* ssh) int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx, const char* newBanner) { - uint32_t newBannerSz = 0; + word32 newBannerSz = 0; WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_SetBanner()"); @@ -469,7 +519,7 @@ int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx, if (newBanner != NULL) { WLOG(WS_LOG_INFO, " setting banner to: \"%s\"", newBanner); - newBannerSz = (uint32_t)WSTRLEN(newBanner); + newBannerSz = (word32)WSTRLEN(newBanner); } ctx->banner = newBanner; @@ -480,20 +530,20 @@ int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx, int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX* ctx, - const uint8_t* in, uint32_t inSz, int format) + const byte* in, word32 inSz, int format) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_UsePrivateKey_buffer()"); return ProcessBuffer(ctx, in, inSz, format, BUFTYPE_PRIVKEY); } -void wolfSSH_GetStats(WOLFSSH* ssh, uint32_t* txCount, uint32_t* rxCount, - uint32_t* seq, uint32_t* peerSeq) +void wolfSSH_GetStats(WOLFSSH* ssh, word32* txCount, word32* rxCount, + word32* seq, word32* peerSeq) { - uint32_t rTxCount = 0; - uint32_t rRxCount = 0; - uint32_t rSeq = 0; - uint32_t rPeerSeq = 0; + word32 rTxCount = 0; + word32 rRxCount = 0; + word32 rSeq = 0; + word32 rPeerSeq = 0; if (ssh != NULL) { rTxCount = ssh->txCount; @@ -513,11 +563,11 @@ void wolfSSH_GetStats(WOLFSSH* ssh, uint32_t* txCount, uint32_t* rxCount, } -int wolfSSH_KDF(uint8_t hashId, uint8_t keyId, - uint8_t* key, uint32_t keySz, - const uint8_t* k, uint32_t kSz, - const uint8_t* h, uint32_t hSz, - const uint8_t* sessionId, uint32_t sessionIdSz) +int wolfSSH_KDF(byte hashId, byte keyId, + byte* key, word32 keySz, + const byte* k, word32 kSz, + const byte* h, word32 hSz, + const byte* sessionId, word32 sessionIdSz) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_KDF()"); return GenerateKey(hashId, keyId, key, keySz, k, kSz, h, hSz, diff --git a/tests/api.c b/tests/api.c index 923d2bd6..5cb08dd6 100644 --- a/tests/api.c +++ b/tests/api.c @@ -124,6 +124,36 @@ static void test_client_wolfSSH_new(void) } +static void test_wolfSSH_SetUsername(void) +{ +#ifndef WOLFSSH_NO_CLIENT + WOLFSSH_CTX* ctx; + WOLFSSH* ssh; + const char username[] = "johnny"; + const char empty[] = ""; + + + AssertIntNE(WS_SUCCESS, wolfSSH_SetUsername(NULL, NULL)); + + AssertNotNull(ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL)); + AssertNotNull(ssh = wolfSSH_new(ctx)); + AssertIntNE(WS_SUCCESS, wolfSSH_SetUsername(ssh, username)); + wolfSSH_free(ssh); + wolfSSH_CTX_free(ctx); + + AssertNotNull(ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL)); + AssertNotNull(ssh = wolfSSH_new(ctx)); + AssertIntNE(WS_SUCCESS, wolfSSH_SetUsername(ssh, NULL)); + AssertIntNE(WS_SUCCESS, wolfSSH_SetUsername(ssh, empty)); + wolfSSH_free(ssh); + AssertNotNull(ssh = wolfSSH_new(ctx)); + AssertIntEQ(WS_SUCCESS, wolfSSH_SetUsername(ssh, username)); + wolfSSH_free(ssh); + wolfSSH_CTX_free(ctx); +#endif /* WOLFSSH_NO_CLIENT */ +} + + int main(void) { AssertIntEQ(wolfSSH_Init(), WS_SUCCESS); @@ -131,6 +161,7 @@ int main(void) test_wolfSSH_CTX_new(); test_server_wolfSSH_new(); test_client_wolfSSH_new(); + test_wolfSSH_SetUsername(); AssertIntEQ(wolfSSH_Cleanup(), WS_SUCCESS); diff --git a/tests/unit.c b/tests/unit.c index d2a93999..5cc45022 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -29,7 +29,7 @@ #define BAD 0xFF -const uint8_t hexDecode[] = +const byte hexDecode[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, BAD, BAD, BAD, BAD, BAD, BAD, BAD, @@ -42,14 +42,14 @@ const uint8_t hexDecode[] = }; /* A starts at 0x41 not 0x3A */ -static int Base16_Decode(const uint8_t* in, uint32_t inLen, - uint8_t* out, uint32_t* outLen) +static int Base16_Decode(const byte* in, word32 inLen, + byte* out, word32* outLen) { - uint32_t inIdx = 0; - uint32_t outIdx = 0; + word32 inIdx = 0; + word32 outIdx = 0; if (inLen == 1 && *outLen && in) { - uint8_t b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ + byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ /* sanity check */ if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) @@ -73,8 +73,8 @@ static int Base16_Decode(const uint8_t* in, uint32_t inLen, return -1; while (inLen) { - uint8_t b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ - uint8_t b2 = in[inIdx++] - 0x30; + byte b = in[inIdx++] - 0x30; /* 0 starts at 0x30 */ + byte b2 = in[inIdx++] - 0x30; /* sanity checks */ if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) @@ -88,7 +88,7 @@ static int Base16_Decode(const uint8_t* in, uint32_t inLen, if (b == BAD || b2 == BAD) return -1; - out[outIdx++] = (uint8_t)((b << 4) | b2); + out[outIdx++] = (byte)((b << 4) | b2); inLen -= 2; } @@ -97,7 +97,7 @@ static int Base16_Decode(const uint8_t* in, uint32_t inLen, } -static void FreeBins(uint8_t* b1, uint8_t* b2, uint8_t* b3, uint8_t* b4) +static void FreeBins(byte* b1, byte* b2, byte* b3, byte* b4) { if (b1 != NULL) free(b1); if (b2 != NULL) free(b2); @@ -107,20 +107,20 @@ static void FreeBins(uint8_t* b1, uint8_t* b2, uint8_t* b3, uint8_t* b4) /* convert hex string to binary, store size, 0 success (free mem on failure) */ -static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz, - const char* h2, uint8_t** b2, uint32_t* b2Sz, - const char* h3, uint8_t** b3, uint32_t* b3Sz, - const char* h4, uint8_t** b4, uint32_t* b4Sz) +static int ConvertHexToBin(const char* h1, byte** b1, word32* b1Sz, + const char* h2, byte** b2, word32* b2Sz, + const char* h3, byte** b3, word32* b3Sz, + const char* h4, byte** b4, word32* b4Sz) { int ret; /* b1 */ if (h1 && b1 && b1Sz) { - *b1Sz = (uint32_t)strlen(h1) / 2; - *b1 = (uint8_t*)malloc(*b1Sz); + *b1Sz = (word32)strlen(h1) / 2; + *b1 = (byte*)malloc(*b1Sz); if (*b1 == NULL) return -1; - ret = Base16_Decode((const uint8_t*)h1, (uint32_t)strlen(h1), + ret = Base16_Decode((const byte*)h1, (word32)strlen(h1), *b1, b1Sz); if (ret != 0) { FreeBins(*b1, NULL, NULL, NULL); @@ -130,13 +130,13 @@ static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz, /* b2 */ if (h2 && b2 && b2Sz) { - *b2Sz = (uint32_t)strlen(h2) / 2; - *b2 = (uint8_t*)malloc(*b2Sz); + *b2Sz = (word32)strlen(h2) / 2; + *b2 = (byte*)malloc(*b2Sz); if (*b2 == NULL) { FreeBins(b1 ? *b1 : NULL, NULL, NULL, NULL); return -1; } - ret = Base16_Decode((const uint8_t*)h2, (uint32_t)strlen(h2), + ret = Base16_Decode((const byte*)h2, (word32)strlen(h2), *b2, b2Sz); if (ret != 0) { FreeBins(b1 ? *b1 : NULL, *b2, NULL, NULL); @@ -146,13 +146,13 @@ static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz, /* b3 */ if (h3 && b3 && b3Sz) { - *b3Sz = (uint32_t)strlen(h3) / 2; - *b3 = (uint8_t*)malloc(*b3Sz); + *b3Sz = (word32)strlen(h3) / 2; + *b3 = (byte*)malloc(*b3Sz); if (*b3 == NULL) { FreeBins(b1 ? *b1 : NULL, b2 ? *b2 : NULL, NULL, NULL); return -1; } - ret = Base16_Decode((const uint8_t*)h3, (uint32_t)strlen(h3), + ret = Base16_Decode((const byte*)h3, (word32)strlen(h3), *b3, b3Sz); if (ret != 0) { FreeBins(b1 ? *b1 : NULL, b2 ? *b2 : NULL, *b3, NULL); @@ -162,13 +162,13 @@ static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz, /* b4 */ if (h4 && b4 && b4Sz) { - *b4Sz = (uint32_t)strlen(h4) / 2; - *b4 = (uint8_t*)malloc(*b4Sz); + *b4Sz = (word32)strlen(h4) / 2; + *b4 = (byte*)malloc(*b4Sz); if (*b4 == NULL) { FreeBins(b1 ? *b1 : NULL, b2 ? *b2 : NULL, b3 ? *b3 : NULL, NULL); return -1; } - ret = Base16_Decode((const uint8_t*)h4, (uint32_t)strlen(h4), + ret = Base16_Decode((const byte*)h4, (word32)strlen(h4), *b4, b4Sz); if (ret != 0) { FreeBins(b1 ? *b1 : NULL, b2 ? *b2 : NULL, b3 ? *b3 : NULL, *b4); @@ -183,8 +183,8 @@ static int ConvertHexToBin(const char* h1, uint8_t** b1, uint32_t* b1Sz, /* Key Derivation Function (KDF) Unit Test */ typedef struct { - uint8_t hashId; - uint8_t keyId; + byte hashId; + byte keyId; const char* k; const char* h; const char* sessionId; @@ -310,15 +310,15 @@ static const KdfTestVector kdfTestVectors[] = { static int test_KDF(void) { int result = 0; - uint32_t i; - uint32_t tc = sizeof(kdfTestVectors)/sizeof(KdfTestVector); + word32 i; + word32 tc = sizeof(kdfTestVectors)/sizeof(KdfTestVector); const KdfTestVector* tv = NULL; - uint8_t* k = NULL; - uint8_t* h = NULL; - uint8_t* sId = NULL; - uint8_t* eKey = NULL; - uint32_t kSz, hSz, sIdSz, eKeySz; - uint8_t cKey[20]; /* Greater of SHA_DIGEST_SIZE and AES_BLOCK_SIZE */ + byte* k = NULL; + byte* h = NULL; + byte* sId = NULL; + byte* eKey = NULL; + word32 kSz, hSz, sIdSz, eKeySz; + byte cKey[32]; /* Greater of SHA256_DIGEST_SIZE and AES_BLOCK_SIZE */ /* sId - Session ID, eKey - Expected Key, cKey - Calculated Key */ for (i = 0, tv = kdfTestVectors; i < tc; i++, tv++) { @@ -362,7 +362,7 @@ static int test_KDF(void) static int test_RsaKeyGen(void) { int result = 0; - uint8_t der[1200]; + byte der[1200]; int derSz; derSz = wolfSSH_MakeRsaKey(der, sizeof(der), diff --git a/wolfssh/error.h b/wolfssh/error.h index b90a74fa..5e17d2b8 100644 --- a/wolfssh/error.h +++ b/wolfssh/error.h @@ -70,7 +70,8 @@ enum WS_ErrorCodes { WS_INVALID_STATE_E = -30, WS_REKEYING = -31, WS_INVALID_PRIME_CURVE = -32, - WS_ECC_E = -33 + WS_ECC_E = -33, + WS_CHANOPEN_FAILED = -34 }; diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 6d8230b3..5bb77258 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -28,10 +28,11 @@ #pragma once #include -#include #include #include #include +#include +#include #if !defined (ALIGN16) @@ -82,6 +83,10 @@ enum { ID_ECDSA_SHA2_NISTP384, ID_ECDSA_SHA2_NISTP521, + /* Service IDs */ + ID_SERVICE_USERAUTH, + ID_SERVICE_CONNECTION, + /* UserAuth IDs */ ID_USERAUTH_PASSWORD, ID_USERAUTH_PUBLICKEY, @@ -93,25 +98,25 @@ enum { }; -#define MAX_ENCRYPTION 3 -#define MAX_INTEGRITY 2 +#define MAX_ENCRYPTION 3 +#define MAX_INTEGRITY 2 #define MAX_KEY_EXCHANGE 2 -#define MAX_PUBLIC_KEY 1 -#define MAX_HMAC_SZ SHA256_DIGEST_SIZE -#define MIN_BLOCK_SZ 8 -#define COOKIE_SZ 16 -#define LENGTH_SZ 4 -#define PAD_LENGTH_SZ 1 -#define MIN_PAD_LENGTH 4 -#define BOOLEAN_SZ 1 -#define MSG_ID_SZ 1 -#define SHA1_96_SZ 12 -#define UINT32_SZ 4 -#define SSH_PROTO_SZ 7 /* "SSH-2.0" */ -#define SSH_PROTO_EOL_SZ 2 /* Just the CRLF */ -#define AEAD_IMP_IV_SZ 4 -#define AEAD_EXP_IV_SZ 8 -#define AEAD_NONCE_SZ (AEAD_IMP_IV_SZ+AEAD_EXP_IV_SZ) +#define MAX_PUBLIC_KEY 1 +#define MAX_HMAC_SZ SHA256_DIGEST_SIZE +#define MIN_BLOCK_SZ 8 +#define COOKIE_SZ 16 +#define LENGTH_SZ 4 +#define PAD_LENGTH_SZ 1 +#define MIN_PAD_LENGTH 4 +#define BOOLEAN_SZ 1 +#define MSG_ID_SZ 1 +#define SHA1_96_SZ 12 +#define UINT32_SZ 4 +#define SSH_PROTO_SZ 7 /* "SSH-2.0" */ +#define SSH_PROTO_EOL_SZ 2 /* Just the CRLF */ +#define AEAD_IMP_IV_SZ 4 +#define AEAD_EXP_IV_SZ 8 +#define AEAD_NONCE_SZ (AEAD_IMP_IV_SZ+AEAD_EXP_IV_SZ) #ifndef DEFAULT_HIGHWATER_MARK #define DEFAULT_HIGHWATER_MARK ((1024 * 1024 * 1024) - (32 * 1024)) #endif @@ -121,11 +126,13 @@ enum { #ifndef DEFAULT_MAX_PACKET_SZ #define DEFAULT_MAX_PACKET_SZ (16 * 1024) #endif -#define DEFAULT_NEXT_CHANNEL 13013 +#ifndef DEFAULT_NEXT_CHANNEL + #define DEFAULT_NEXT_CHANNEL 0 +#endif -WOLFSSH_LOCAL uint8_t NameToId(const char*, uint32_t); -WOLFSSH_LOCAL const char* IdToName(uint8_t); +WOLFSSH_LOCAL byte NameToId(const char*, word32); +WOLFSSH_LOCAL const char* IdToName(byte); #define STATIC_BUFFER_LEN AES_BLOCK_SIZE @@ -135,35 +142,37 @@ WOLFSSH_LOCAL const char* IdToName(uint8_t); typedef struct Buffer { - void* heap; /* Heap for allocations */ - uint32_t length; /* total buffer length used */ - uint32_t idx; /* idx to part of length already consumed */ - uint8_t* buffer; /* place holder for actual buffer */ - uint32_t bufferSz; /* current buffer size */ - ALIGN16 uint8_t staticBuffer[STATIC_BUFFER_LEN]; - uint8_t dynamicFlag; /* dynamic memory currently in use */ + void* heap; /* Heap for allocations */ + word32 length; /* total buffer length used */ + word32 idx; /* idx to part of length already consumed */ + byte* buffer; /* place holder for actual buffer */ + word32 bufferSz; /* current buffer size */ + ALIGN16 byte staticBuffer[STATIC_BUFFER_LEN]; + byte dynamicFlag; /* dynamic memory currently in use */ } Buffer; -WOLFSSH_LOCAL int BufferInit(Buffer*, uint32_t, void*); -WOLFSSH_LOCAL int GrowBuffer(Buffer*, uint32_t, uint32_t); +WOLFSSH_LOCAL int BufferInit(Buffer*, word32, void*); +WOLFSSH_LOCAL int GrowBuffer(Buffer*, word32, word32); WOLFSSH_LOCAL void ShrinkBuffer(Buffer* buf, int); /* our wolfSSH Context */ struct WOLFSSH_CTX { - void* heap; /* heap hint */ - WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */ - WS_CallbackIOSend ioSendCb; /* I/O Send Callback */ - WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */ + void* heap; /* heap hint */ + WS_CallbackIORecv ioRecvCb; /* I/O Receive Callback */ + WS_CallbackIOSend ioSendCb; /* I/O Send Callback */ + WS_CallbackUserAuth userAuthCb; /* User Authentication Callback */ WS_CallbackHighwater highwaterCb; /* Data Highwater Mark Callback */ - uint8_t* privateKey; /* Owned by CTX */ - uint32_t privateKeySz; - uint8_t useEcc; /* Depends on the private key */ - uint32_t highwaterMark; - const char* banner; - uint32_t bannerSz; + byte* privateKey; /* Owned by CTX */ + word32 privateKeySz; + byte useEcc; /* Depends on the private key */ + word32 highwaterMark; + const char* banner; + word32 bannerSz; + byte side; /* client or server */ + byte showBanner; }; @@ -173,202 +182,205 @@ typedef struct Ciphers { typedef struct Keys { - uint8_t iv[AES_BLOCK_SIZE]; - uint8_t ivSz; - uint8_t encKey[AES_BLOCK_SIZE]; - uint8_t encKeySz; - uint8_t macKey[MAX_HMAC_SZ]; - uint8_t macKeySz; + byte iv[AES_BLOCK_SIZE]; + byte ivSz; + byte encKey[AES_BLOCK_SIZE]; + byte encKeySz; + byte macKey[MAX_HMAC_SZ]; + byte macKeySz; } Keys; typedef struct HandshakeInfo { - uint8_t kexId; - uint8_t pubKeyId; - uint8_t encryptId; - uint8_t macId; - uint8_t hashId; - uint8_t kexPacketFollows; - uint8_t aeadMode; + byte kexId; + byte pubKeyId; + byte encryptId; + byte macId; + byte hashId; + byte kexPacketFollows; + byte aeadMode; - uint8_t blockSz; - uint8_t macSz; + byte blockSz; + byte macSz; - Keys clientKeys; - Keys serverKeys; - wc_HashAlg hash; - uint8_t e[257]; /* May have a leading zero, for unsigned, or - * it is a nistp521 Q_S value. */ - uint32_t eSz; - uint8_t* serverKexInit; - uint32_t serverKexInitSz; + Keys keys; + Keys peerKeys; + wc_HashAlg hash; + byte e[257]; /* May have a leading zero for unsigned or is a Q_S value. */ + word32 eSz; + byte x[257]; /* May have a leading zero, for unsigned. */ + word32 xSz; + byte* kexInit; + word32 kexInitSz; - uint32_t dhGexMinSz; - uint32_t dhGexPreferredSz; - uint32_t dhGexMaxSz; + word32 dhGexMinSz; + word32 dhGexPreferredSz; + word32 dhGexMaxSz; + byte* primeGroup; + word32 primeGroupSz; + byte* generator; + word32 generatorSz; + + byte useEcc; + union { + DhKey dh; + ecc_key ecc; + } privKey; } HandshakeInfo; /* our wolfSSH session */ struct WOLFSSH { - WOLFSSH_CTX* ctx; /* owner context */ - int error; - int rfd; - int wfd; - void* ioReadCtx; /* I/O Read Context handle */ - void* ioWriteCtx; /* I/O Write Context handle */ - int rflags; /* optional read flags */ - int wflags; /* optional write flags */ - uint32_t txCount; - uint32_t rxCount; - uint32_t highwaterMark; - uint8_t highwaterFlag; /* Set when highwater CB called */ - void* highwaterCtx; - uint32_t curSz; - uint32_t seq; - uint32_t peerSeq; - uint32_t packetStartIdx; /* Current send packet start index */ - uint8_t paddingSz; /* Current send packet padding size */ - uint8_t acceptState; - uint8_t clientState; - uint8_t processReplyState; - uint8_t keyingState; + WOLFSSH_CTX* ctx; /* owner context */ + int error; + int rfd; + int wfd; + void* ioReadCtx; /* I/O Read Context handle */ + void* ioWriteCtx; /* I/O Write Context handle */ + int rflags; /* optional read flags */ + int wflags; /* optional write flags */ + word32 txCount; + word32 rxCount; + word32 highwaterMark; + byte highwaterFlag; /* Set when highwater CB called */ + void* highwaterCtx; + word32 curSz; + word32 seq; + word32 peerSeq; + word32 packetStartIdx; /* Current send packet start index */ + byte paddingSz; /* Current send packet padding size */ + byte acceptState; + byte connectState; + byte clientState; + byte serverState; + byte processReplyState; + byte isKeying; - uint8_t connReset; - uint8_t isClosed; + byte connReset; + byte isClosed; - uint8_t blockSz; - uint8_t encryptId; - uint8_t macId; - uint8_t macSz; - uint8_t aeadMode; - uint8_t peerBlockSz; - uint8_t peerEncryptId; - uint8_t peerMacId; - uint8_t peerMacSz; - uint8_t peerAeadMode; + byte blockSz; + byte encryptId; + byte macId; + byte macSz; + byte aeadMode; + byte peerBlockSz; + byte peerEncryptId; + byte peerMacId; + byte peerMacSz; + byte peerAeadMode; - Ciphers encryptCipher; - Ciphers decryptCipher; + Ciphers encryptCipher; + Ciphers decryptCipher; - uint32_t nextChannel; + word32 nextChannel; WOLFSSH_CHANNEL* channelList; - uint32_t channelListSz; - uint32_t defaultPeerChannelId; + word32 channelListSz; + word32 defaultPeerChannelId; - Buffer inputBuffer; - Buffer outputBuffer; - WC_RNG* rng; + Buffer inputBuffer; + Buffer outputBuffer; + WC_RNG* rng; - uint8_t h[WC_MAX_DIGEST_SIZE]; - uint32_t hSz; - uint8_t k[257]; /* May have a leading zero, for unsigned. */ - uint32_t kSz; - uint8_t sessionId[WC_MAX_DIGEST_SIZE]; - uint32_t sessionIdSz; + byte h[WC_MAX_DIGEST_SIZE]; + word32 hSz; + byte k[257]; /* May have a leading zero, for unsigned. */ + word32 kSz; + byte sessionId[WC_MAX_DIGEST_SIZE]; + word32 sessionIdSz; - Keys clientKeys; - Keys serverKeys; + Keys keys; + Keys peerKeys; HandshakeInfo* handshake; - void* userAuthCtx; - uint8_t* userName; - uint32_t userNameSz; - uint8_t* pkBlob; - uint32_t pkBlobSz; - uint8_t* clientId; /* Save for rekey */ - uint32_t clientIdSz; + void* userAuthCtx; + char* userName; + word32 userNameSz; + char* password; + word32 passwordSz; + byte* pkBlob; + word32 pkBlobSz; + byte* peerProtoId; /* Save for rekey */ + word32 peerProtoIdSz; }; struct WOLFSSH_CHANNEL { - uint8_t channelType; - uint32_t channel; - uint32_t windowSz; - uint32_t maxPacketSz; - uint32_t peerChannel; - uint32_t peerWindowSz; - uint32_t peerMaxPacketSz; - Buffer inputBuffer; + byte channelType; + word32 channel; + word32 windowSz; + word32 maxPacketSz; + word32 peerChannel; + word32 peerWindowSz; + word32 peerMaxPacketSz; + Buffer inputBuffer; struct WOLFSSH* ssh; struct WOLFSSH_CHANNEL* next; }; -WOLFSSH_LOCAL WOLFSSH_CTX* CtxInit(WOLFSSH_CTX*, void*); +WOLFSSH_LOCAL WOLFSSH_CTX* CtxInit(WOLFSSH_CTX*, byte, void*); WOLFSSH_LOCAL void CtxResourceFree(WOLFSSH_CTX*); WOLFSSH_LOCAL WOLFSSH* SshInit(WOLFSSH*, WOLFSSH_CTX*); WOLFSSH_LOCAL void SshResourceFree(WOLFSSH*, void*); -WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelNew(WOLFSSH*, uint8_t, uint32_t, - uint32_t, uint32_t); +WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelNew(WOLFSSH*, byte, word32, word32); +WOLFSSH_LOCAL int ChannelUpdate(WOLFSSH_CHANNEL*, word32, word32, word32); WOLFSSH_LOCAL void ChannelDelete(WOLFSSH_CHANNEL*, void*); -WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelFind(WOLFSSH*, uint32_t, uint8_t); -WOLFSSH_LOCAL int ChannelRemove(WOLFSSH*, uint32_t, uint8_t); -WOLFSSH_LOCAL int ChannelPutData(WOLFSSH_CHANNEL*, uint8_t*, uint32_t); -WOLFSSH_LOCAL int ProcessBuffer(WOLFSSH_CTX*, const uint8_t*, uint32_t, - int, int); +WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelFind(WOLFSSH*, word32, byte); +WOLFSSH_LOCAL int ChannelRemove(WOLFSSH*, word32, byte); +WOLFSSH_LOCAL int ChannelPutData(WOLFSSH_CHANNEL*, byte*, word32); +WOLFSSH_LOCAL int ProcessBuffer(WOLFSSH_CTX*, const byte*, word32, int, int); #ifndef WOLFSSH_USER_IO /* default I/O handlers */ -WOLFSSH_LOCAL int wsEmbedRecv(WOLFSSH*, void*, uint32_t, void*); -WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH*, void*, uint32_t, void*); +WOLFSSH_LOCAL int wsEmbedRecv(WOLFSSH*, void*, word32, void*); +WOLFSSH_LOCAL int wsEmbedSend(WOLFSSH*, void*, word32, void*); #endif /* WOLFSSH_USER_IO */ WOLFSSH_LOCAL int DoReceive(WOLFSSH*); -WOLFSSH_LOCAL int ProcessClientVersion(WOLFSSH*); -WOLFSSH_LOCAL int SendServerVersion(WOLFSSH*); +WOLFSSH_LOCAL int DoProtoId(WOLFSSH*); +WOLFSSH_LOCAL int SendProtoId(WOLFSSH*); WOLFSSH_LOCAL int SendKexInit(WOLFSSH*); +WOLFSSH_LOCAL int SendKexDhInit(WOLFSSH*); WOLFSSH_LOCAL int SendKexDhReply(WOLFSSH*); +WOLFSSH_LOCAL int SendKexDhGexRequest(WOLFSSH*); WOLFSSH_LOCAL int SendKexDhGexGroup(WOLFSSH*); WOLFSSH_LOCAL int SendNewKeys(WOLFSSH*); WOLFSSH_LOCAL int SendUnimplemented(WOLFSSH*); -WOLFSSH_LOCAL int SendDisconnect(WOLFSSH*, uint32_t); -WOLFSSH_LOCAL int SendIgnore(WOLFSSH*, const unsigned char*, uint32_t); +WOLFSSH_LOCAL int SendDisconnect(WOLFSSH*, word32); +WOLFSSH_LOCAL int SendIgnore(WOLFSSH*, const unsigned char*, word32); WOLFSSH_LOCAL int SendDebug(WOLFSSH*, byte, const char*); -WOLFSSH_LOCAL int SendServiceAccept(WOLFSSH*); +WOLFSSH_LOCAL int SendServiceRequest(WOLFSSH*, byte); +WOLFSSH_LOCAL int SendServiceAccept(WOLFSSH*, byte); +WOLFSSH_LOCAL int SendUserAuthRequest(WOLFSSH*, byte); WOLFSSH_LOCAL int SendUserAuthSuccess(WOLFSSH*); -WOLFSSH_LOCAL int SendUserAuthFailure(WOLFSSH*, uint8_t); +WOLFSSH_LOCAL int SendUserAuthFailure(WOLFSSH*, byte); WOLFSSH_LOCAL int SendUserAuthBanner(WOLFSSH*); -WOLFSSH_LOCAL int SendUserAuthPkOk(WOLFSSH*, const uint8_t*, uint32_t, - const uint8_t*, uint32_t); +WOLFSSH_LOCAL int SendUserAuthPkOk(WOLFSSH*, const byte*, word32, + const byte*, word32); WOLFSSH_LOCAL int SendRequestSuccess(WOLFSSH*, int); +WOLFSSH_LOCAL int SendChannelOpenSession(WOLFSSH*, word32, word32); WOLFSSH_LOCAL int SendChannelOpenConf(WOLFSSH*); -WOLFSSH_LOCAL int SendChannelEof(WOLFSSH*, uint32_t); -WOLFSSH_LOCAL int SendChannelClose(WOLFSSH*, uint32_t); -WOLFSSH_LOCAL int SendChannelData(WOLFSSH*, uint32_t, uint8_t*, uint32_t); -WOLFSSH_LOCAL int SendChannelWindowAdjust(WOLFSSH*, uint32_t, uint32_t); -WOLFSSH_LOCAL int SendChannelSuccess(WOLFSSH*, uint32_t, int); -WOLFSSH_LOCAL int GenerateKey(uint8_t, uint8_t, uint8_t*, uint32_t, - const uint8_t*, uint32_t, - const uint8_t*, uint32_t, - const uint8_t*, uint32_t); - - -enum KeyingStates { - KEYING_UNKEYED = 0, - - KEYING_KEXINIT_SENT, - KEYING_KEXINIT_RECV, - KEYING_KEXINIT_DONE, - - KEYING_KEXDH_INIT_RECV, - KEYING_KEXDH_DONE, - - KEYING_USING_KEYS_SENT, - KEYING_USING_KEYS_RECV, - KEYING_KEYED -}; +WOLFSSH_LOCAL int SendChannelEof(WOLFSSH*, word32); +WOLFSSH_LOCAL int SendChannelClose(WOLFSSH*, word32); +WOLFSSH_LOCAL int SendChannelData(WOLFSSH*, word32, byte*, word32); +WOLFSSH_LOCAL int SendChannelWindowAdjust(WOLFSSH*, word32, word32); +WOLFSSH_LOCAL int SendChannelRequestShell(WOLFSSH*); +WOLFSSH_LOCAL int SendChannelSuccess(WOLFSSH*, word32, int); +WOLFSSH_LOCAL int GenerateKey(byte, byte, byte*, word32, const byte*, word32, + const byte*, word32, const byte*, word32); enum AcceptStates { ACCEPT_BEGIN = 0, ACCEPT_SERVER_VERSION_SENT, ACCEPT_CLIENT_VERSION_DONE, + ACCEPT_SERVER_KEXINIT_SENT, ACCEPT_KEYED, ACCEPT_CLIENT_USERAUTH_REQUEST_DONE, ACCEPT_SERVER_USERAUTH_ACCEPT_SENT, @@ -379,18 +391,47 @@ enum AcceptStates { }; +enum ConnectStates { + CONNECT_BEGIN = 0, + CONNECT_CLIENT_VERSION_SENT, + CONNECT_SERVER_VERSION_DONE, + CONNECT_CLIENT_KEXINIT_SENT, + CONNECT_SERVER_KEXINIT_DONE, + CONNECT_CLIENT_KEXDH_INIT_SENT, + CONNECT_KEYED, + CONNECT_CLIENT_USERAUTH_REQUEST_SENT, + CONNECT_SERVER_USERAUTH_REQUEST_DONE, + CONNECT_CLIENT_USERAUTH_SENT, + CONNECT_SERVER_USERAUTH_ACCEPT_DONE, + CONNECT_CLIENT_CHANNEL_OPEN_SESSION_SENT, + CONNECT_SERVER_CHANNEL_OPEN_SESSION_DONE, + CONNECT_CLIENT_CHANNEL_REQUEST_SHELL_SENT, + CONNECT_SERVER_CHANNEL_REQUEST_SHELL_DONE +}; + + enum ClientStates { CLIENT_BEGIN = 0, CLIENT_VERSION_DONE, CLIENT_KEXINIT_DONE, CLIENT_KEXDH_INIT_DONE, - CLIENT_USING_KEYS, CLIENT_USERAUTH_REQUEST_DONE, CLIENT_USERAUTH_DONE, CLIENT_DONE }; +enum ServerStates { + SERVER_BEGIN = 0, + SERVER_VERSION_DONE, + SERVER_KEXINIT_DONE, + SERVER_USERAUTH_REQUEST_DONE, + SERVER_USERAUTH_ACCEPT_DONE, + SERVER_CHANNEL_OPEN_DONE, + SERVER_DONE +}; + + enum ProcessReplyStates { PROCESS_INIT, PROCESS_PACKET_LENGTH, @@ -400,44 +441,47 @@ enum ProcessReplyStates { enum WS_MessageIds { - MSGID_DISCONNECT = 1, - MSGID_IGNORE = 2, - MSGID_UNIMPLEMENTED = 3, - MSGID_DEBUG = 4, + MSGID_DISCONNECT = 1, + MSGID_IGNORE = 2, + MSGID_UNIMPLEMENTED = 3, + MSGID_DEBUG = 4, MSGID_SERVICE_REQUEST = 5, - MSGID_SERVICE_ACCEPT = 6, + MSGID_SERVICE_ACCEPT = 6, - MSGID_KEXINIT = 20, - MSGID_NEWKEYS = 21, + MSGID_KEXINIT = 20, + MSGID_NEWKEYS = 21, - MSGID_KEXDH_INIT = 30, - MSGID_KEXDH_REPLY = 31, + MSGID_KEXDH_INIT = 30, + MSGID_KEXECDH_INIT = 30, - MSGID_KEXDH_GEX_REQUEST = 34, + MSGID_KEXDH_REPLY = 31, + MSGID_KEXECDH_REPLY = 31, MSGID_KEXDH_GEX_GROUP = 31, - MSGID_KEXDH_GEX_INIT = 32, + MSGID_KEXDH_GEX_INIT = 32, MSGID_KEXDH_GEX_REPLY = 33, + MSGID_KEXDH_GEX_REQUEST = 34, MSGID_USERAUTH_REQUEST = 50, MSGID_USERAUTH_FAILURE = 51, MSGID_USERAUTH_SUCCESS = 52, - MSGID_USERAUTH_BANNER = 53, - MSGID_USERAUTH_PK_OK = 60, /* Public Key OK */ + MSGID_USERAUTH_BANNER = 53, + MSGID_USERAUTH_PK_OK = 60, /* Public Key OK */ MSGID_USERAUTH_PW_CHRQ = 60, /* Password Change Request */ - MSGID_GLOBAL_REQUEST = 80, - MSGID_REQUEST_SUCCESS = 81, - MSGID_REQUEST_FAILURE = 82, + MSGID_GLOBAL_REQUEST = 80, + MSGID_REQUEST_SUCCESS = 81, + MSGID_REQUEST_FAILURE = 82, - MSGID_CHANNEL_OPEN = 90, + MSGID_CHANNEL_OPEN = 90, MSGID_CHANNEL_OPEN_CONF = 91, + MSGID_CHANNEL_OPEN_FAIL = 92, MSGID_CHANNEL_WINDOW_ADJUST = 93, - MSGID_CHANNEL_DATA = 94, - MSGID_CHANNEL_EOF = 96, - MSGID_CHANNEL_CLOSE = 97, - MSGID_CHANNEL_REQUEST = 98, - MSGID_CHANNEL_SUCCESS = 99, - MSGID_CHANNEL_FAILURE = 100 + MSGID_CHANNEL_DATA = 94, + MSGID_CHANNEL_EOF = 96, + MSGID_CHANNEL_CLOSE = 97, + MSGID_CHANNEL_REQUEST = 98, + MSGID_CHANNEL_SUCCESS = 99, + MSGID_CHANNEL_FAILURE = 100 }; @@ -455,7 +499,8 @@ enum WS_DynamicTypes { DYNTYPE_PUBKEY, DYNTYPE_DH, DYNTYPE_RNG, - DYNTYPE_STRING + DYNTYPE_STRING, + DYNTYPE_MPINT }; @@ -467,7 +512,7 @@ enum WS_BufferTypes { }; -WOLFSSH_LOCAL void DumpOctetString(const uint8_t*, uint32_t); +WOLFSSH_LOCAL void DumpOctetString(const byte*, word32); #ifdef __cplusplus diff --git a/wolfssh/keygen.h b/wolfssh/keygen.h index ca55d7b7..1506491d 100644 --- a/wolfssh/keygen.h +++ b/wolfssh/keygen.h @@ -42,7 +42,7 @@ extern "C" { #define WOLFSSH_RSAKEY_DEFAULT_E 65537 -WOLFSSH_API int wolfSSH_MakeRsaKey(uint8_t*, uint32_t, uint32_t, uint32_t); +WOLFSSH_API int wolfSSH_MakeRsaKey(byte*, word32, word32, word32); #ifdef __cplusplus diff --git a/wolfssh/misc.h b/wolfssh/misc.h index 5f2c7c1a..4f111095 100644 --- a/wolfssh/misc.h +++ b/wolfssh/misc.h @@ -36,13 +36,13 @@ #ifndef min -WOLFSSH_LOCAL uint32_t min(uint32_t, uint32_t); +WOLFSSH_LOCAL word32 min(word32, word32); #endif /* min */ -WOLFSSH_LOCAL void ato32(const uint8_t*, uint32_t*); -WOLFSSH_LOCAL void c32toa(uint32_t, uint8_t*); -WOLFSSH_LOCAL void ForceZero(const void*, uint32_t); -WOLFSSH_LOCAL int ConstantCompare(const uint8_t*, const uint8_t*, uint32_t); +WOLFSSH_LOCAL void ato32(const byte*, word32*); +WOLFSSH_LOCAL void c32toa(word32, byte*); +WOLFSSH_LOCAL void ForceZero(const void*, word32); +WOLFSSH_LOCAL int ConstantCompare(const byte*, const byte*, word32); #endif /* NO_INLINE */ diff --git a/wolfssh/port.h b/wolfssh/port.h index 359fc930..557d2f63 100644 --- a/wolfssh/port.h +++ b/wolfssh/port.h @@ -36,12 +36,6 @@ extern "C" { #endif -#ifndef WUSER_TYPE - #include - /* we need uint8, uint32, stdint provides them */ -#endif - - /* setup memory handling */ #ifndef WMALLOC_USER #include @@ -56,7 +50,10 @@ extern "C" { #ifndef WSTRING_USER #include - char* wstrnstr(const char* s1, const char* s2, unsigned int n); + #define WFILE FILE + + WOLFSSH_API char* wstrnstr(const char*, const char*, unsigned int); + WOLFSSH_API int wfopen(WFILE**, const char*, const char*); #define WMEMCPY(d,s,l) memcpy((d),(s),(l)) #define WMEMSET(b,c,l) memset((b),(c),(l)) @@ -64,25 +61,28 @@ extern "C" { #define WMEMMOVE(d,s,l) memmove((d),(s),(l)) #define WSTRLEN(s1) strlen((s1)) - #define WSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) #define WSTRSTR(s1,s2) strstr((s1),(s2)) #define WSTRNSTR(s1,s2,n) wstrnstr((s1),(s2),(n)) #define WSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n)) #define WSTRNCAT(s1,s2,n) strncat((s1),(s2),(n)) #define WSTRSPN(s1,s2) strspn((s1),(s2)) #define WSTRCSPN(s1,s2) strcspn((s1),(s2)) + #define WFOPEN(f,fn,m) wfopen((f),(fn),(m)) + #define WFCLOSE(f) fclose(f) + #ifndef USE_WINDOWS_API #include + #define WSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n)) #define WSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n)) - #define WSNPRINTF snprintf - #define WVSNPRINTF(a,b,c,d) vsnprintf(a,b,c,d) - #define WLOCALTIME(a,b) (localtime_r(a,b)!=NULL) - + #define WSNPRINTF(s,n,f,...) snprintf((s),(n),(f),##__VA_ARGS__) + #define WVSNPRINTF(s,n,f,...) vsnprintf((s),(n),(f),##__VA_ARGS__) + #define WLOCALTIME(c,r) (localtime_r((c),(r))!=NULL) #else + #define WSTRNCPY(s1,s2,n) strncpy_s((s1),(n),(s2),(n)) #define WSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n)) - #define WSNPRINTF _snprintf - #define WVSNPRINTF(a,b,c,d) vsnprintf_s(a,b,(b-1),c,d) - #define WLOCALTIME(a,b) (localtime_s(b,a)==0) + #define WSNPRINTF(s,n,f,...) _snprintf_s((s),(n),(n),(f),##__VA_ARGS__) + #define WVSNPRINTF(s,n,f,...) vsnprintf_s((s),(n),(n),(f),##__VA_ARGS__) + #define WLOCALTIME(c,r) (localtime_s((r),(c))==0) #endif #endif /* WSTRING_USER */ @@ -107,6 +107,16 @@ extern "C" { #endif /* INLINE */ +/* GCC 7 has new switch() fall-through detection */ +#if defined(__GNUC__) + #if ((__GNUC__ > 7) || ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 1))) + #define FALL_THROUGH __attribute__ ((fallthrough)); + #endif +#endif +#ifndef FALL_THROUGH + #define FALL_THROUGH +#endif + #ifdef __cplusplus } diff --git a/wolfssh/settings.h b/wolfssh/settings.h index bda707e4..5ae684a3 100644 --- a/wolfssh/settings.h +++ b/wolfssh/settings.h @@ -45,6 +45,9 @@ extern "C" { #define USE_WINDOWS_API #endif +#define WOLFSSH_NO_CLIENT + /* The client code is incomplete. */ + #ifdef __cplusplus } diff --git a/wolfssh/ssh.h b/wolfssh/ssh.h index 934799dc..ca5af78b 100644 --- a/wolfssh/ssh.h +++ b/wolfssh/ssh.h @@ -26,6 +26,8 @@ #pragma once +#include +#include #include #include #include @@ -41,30 +43,30 @@ typedef struct WOLFSSH WOLFSSH; typedef struct WOLFSSH_CHANNEL WOLFSSH_CHANNEL; -WOLFSSH_API int wolfSSH_Init(void); -WOLFSSH_API int wolfSSH_Cleanup(void); +WOLFSSH_API int wolfSSH_Init(void); +WOLFSSH_API int wolfSSH_Cleanup(void); /* debugging output functions */ -WOLFSSH_API int wolfSSH_Debugging_ON(void); +WOLFSSH_API int wolfSSH_Debugging_ON(void); WOLFSSH_API void wolfSSH_Debugging_OFF(void); /* context functions */ -WOLFSSH_API WOLFSSH_CTX* wolfSSH_CTX_new(uint8_t, void*); -WOLFSSH_API void wolfSSH_CTX_free(WOLFSSH_CTX*); +WOLFSSH_API WOLFSSH_CTX* wolfSSH_CTX_new(byte, void*); +WOLFSSH_API void wolfSSH_CTX_free(WOLFSSH_CTX*); /* ssh session functions */ WOLFSSH_API WOLFSSH* wolfSSH_new(WOLFSSH_CTX*); -WOLFSSH_API void wolfSSH_free(WOLFSSH*); +WOLFSSH_API void wolfSSH_free(WOLFSSH*); -WOLFSSH_API int wolfSSH_set_fd(WOLFSSH*, int); -WOLFSSH_API int wolfSSH_get_fd(const WOLFSSH*); +WOLFSSH_API int wolfSSH_set_fd(WOLFSSH*, int); +WOLFSSH_API int wolfSSH_get_fd(const WOLFSSH*); /* data high water mark functions */ -WOLFSSH_API int wolfSSH_SetHighwater(WOLFSSH*, uint32_t); -WOLFSSH_API uint32_t wolfSSH_GetHighwater(WOLFSSH*); +WOLFSSH_API int wolfSSH_SetHighwater(WOLFSSH*, word32); +WOLFSSH_API word32 wolfSSH_GetHighwater(WOLFSSH*); -typedef int (*WS_CallbackHighwater)(uint8_t, void*); -WOLFSSH_API void wolfSSH_SetHighwaterCb(WOLFSSH_CTX*, uint32_t, +typedef int (*WS_CallbackHighwater)(byte, void*); +WOLFSSH_API void wolfSSH_SetHighwaterCb(WOLFSSH_CTX*, word32, WS_CallbackHighwater); WOLFSSH_API void wolfSSH_SetHighwaterCtx(WOLFSSH*, void*); WOLFSSH_API void* wolfSSH_GetHighwaterCtx(WOLFSSH*); @@ -74,8 +76,8 @@ WOLFSSH_API int wolfSSH_get_error(const WOLFSSH*); WOLFSSH_API const char* wolfSSH_get_error_name(const WOLFSSH*); /* I/O callbacks */ -typedef int (*WS_CallbackIORecv)(WOLFSSH*, void*, uint32_t, void*); -typedef int (*WS_CallbackIOSend)(WOLFSSH*, void*, uint32_t, void*); +typedef int (*WS_CallbackIORecv)(WOLFSSH*, void*, word32, void*); +typedef int (*WS_CallbackIOSend)(WOLFSSH*, void*, word32, void*); WOLFSSH_API void wolfSSH_SetIORecv(WOLFSSH_CTX*, WS_CallbackIORecv); WOLFSSH_API void wolfSSH_SetIOSend(WOLFSSH_CTX*, WS_CallbackIOSend); WOLFSSH_API void wolfSSH_SetIOReadCtx(WOLFSSH*, void*); @@ -84,63 +86,60 @@ WOLFSSH_API void* wolfSSH_GetIOReadCtx(WOLFSSH*); WOLFSSH_API void* wolfSSH_GetIOWriteCtx(WOLFSSH*); /* User Authentication callback */ - typedef struct WS_UserAuthData_Password { - uint8_t* password; - uint32_t passwordSz; + byte* password; + word32 passwordSz; /* The following are present for future use. */ - uint8_t hasNewPassword; - uint8_t* newPassword; - uint32_t newPasswordSz; + byte hasNewPassword; + byte* newPassword; + word32 newPasswordSz; } WS_UserAuthData_Password; typedef struct WS_UserAuthData_PublicKey { - uint8_t* dataToSign; - uint8_t* publicKeyType; - uint32_t publicKeyTypeSz; - uint8_t* publicKey; - uint32_t publicKeySz; - uint8_t hasSignature; - uint8_t* signature; - uint32_t signatureSz; + byte* dataToSign; + byte* publicKeyType; + word32 publicKeyTypeSz; + byte* publicKey; + word32 publicKeySz; + byte hasSignature; + byte* signature; + word32 signatureSz; } WS_UserAuthData_PublicKey; typedef struct WS_UserAuthData { - uint8_t type; - uint8_t* username; - uint32_t usernameSz; - uint8_t* serviceName; - uint32_t serviceNameSz; - uint8_t* authName; - uint32_t authNameSz; + byte type; + byte* username; + word32 usernameSz; + byte* serviceName; + word32 serviceNameSz; + byte* authName; + word32 authNameSz; union { WS_UserAuthData_Password password; WS_UserAuthData_PublicKey publicKey; } sf; } WS_UserAuthData; -typedef int (*WS_CallbackUserAuth)(uint8_t, const WS_UserAuthData*, void*); +typedef int (*WS_CallbackUserAuth)(byte, WS_UserAuthData*, void*); WOLFSSH_API void wolfSSH_SetUserAuth(WOLFSSH_CTX*, WS_CallbackUserAuth); WOLFSSH_API void wolfSSH_SetUserAuthCtx(WOLFSSH*, void*); WOLFSSH_API void* wolfSSH_GetUserAuthCtx(WOLFSSH*); WOLFSSH_API int wolfSSH_CTX_SetBanner(WOLFSSH_CTX*, const char*); WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*, - const uint8_t*, uint32_t, int); + const byte*, word32, int); WOLFSSH_API int wolfSSH_accept(WOLFSSH*); -WOLFSSH_API int wolfSSH_stream_read(WOLFSSH*, uint8_t*, uint32_t); -WOLFSSH_API int wolfSSH_stream_send(WOLFSSH*, uint8_t*, uint32_t); -WOLFSSH_API int wolfSSH_channel_read(WOLFSSH_CHANNEL*, uint8_t*, uint32_t); -WOLFSSH_API int wolfSSH_channel_send(WOLFSSH_CHANNEL*, uint8_t*, uint32_t); +WOLFSSH_API int wolfSSH_shutdown(WOLFSSH*); +WOLFSSH_API int wolfSSH_stream_read(WOLFSSH*, byte*, word32); +WOLFSSH_API int wolfSSH_stream_send(WOLFSSH*, byte*, word32); WOLFSSH_API int wolfSSH_TriggerKeyExchange(WOLFSSH*); WOLFSSH_API void wolfSSH_GetStats(WOLFSSH*, - uint32_t*, uint32_t*, uint32_t*, uint32_t*); + word32*, word32*, word32*, word32*); -WOLFSSH_API int wolfSSH_KDF(uint8_t, uint8_t, uint8_t*, uint32_t, - const uint8_t*, uint32_t, const uint8_t*, uint32_t, - const uint8_t*, uint32_t); +WOLFSSH_API int wolfSSH_KDF(byte, byte, byte*, word32, const byte*, word32, + const byte*, word32, const byte*, word32); enum WS_HighwaterSide { diff --git a/wolfssh/test.h b/wolfssh/test.h new file mode 100755 index 00000000..49e43e43 --- /dev/null +++ b/wolfssh/test.h @@ -0,0 +1,544 @@ +/* test.h */ + +#pragma once + +#ifndef _WOLFSSH_TEST_H_ +#define _WOLFSSH_TEST_H_ + + +#include +/*#include */ +#include +/*#include */ + +#ifdef USE_WINDOWS_API + #include + #include + #include + #ifdef TEST_IPV6 /* don't require newer SDK for IPV4 */ + #include + #include + #endif + #define SOCKET_T SOCKET +#else /* USE_WINDOWS_API */ + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifndef SO_NOSIGPIPE + #include /* ignore SIGPIPE */ + #endif + #define SOCKET_T int +#endif /* USE_WINDOWS_API */ + + +/* Socket Handling */ +#ifndef WOLFSSH_SOCKET_INVALID +#ifdef USE_WINDOWS_API + #define WOLFSSH_SOCKET_INVALID ((SOCKET_T)INVALID_SOCKET) +#elif defined(WOLFSSH_TIRTOS) + #define WOLFSSH_SOCKET_INVALID ((SOCKET_T)-1) +#else + #define WOLFSSH_SOCKET_INVALID (SOCKET_T)(0) +#endif +#endif /* WOLFSSH_SOCKET_INVALID */ + +#ifndef WOLFSSL_SOCKET_IS_INVALID +#if defined(USE_WINDOWS_API) || defined(WOLFSSL_TIRTOS) + #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) == WOLFSSL_SOCKET_INVALID) +#else + #define WOLFSSL_SOCKET_IS_INVALID(s) ((SOCKET_T)(s) < WOLFSSL_SOCKET_INVALID) +#endif +#endif /* WOLFSSL_SOCKET_IS_INVALID */ + + +#if defined(__MACH__) || defined(USE_WINDOWS_API) + #ifndef _SOCKLEN_T + typedef int socklen_t; + #endif +#endif + + +#ifdef USE_WINDOWS_API + #define WCLOSESOCKET(s) closesocket(s) + #define WSTARTTCP() do { WSADATA wsd; WSAStartup(0x0002, &wsd); } while(0) +#else + #define WCLOSESOCKET(s) close(s) + #define WSTARTTCP() +#endif + + +#ifdef SINGLE_THREADED + typedef unsigned int THREAD_RETURN; + typedef void* THREAD_TYPE; + #define WOLFSSH_THREAD +#else + #if defined(_POSIX_THREADS) && !defined(__MINGW32__) + typedef void* THREAD_RETURN; + typedef pthread_t THREAD_TYPE; + #define WOLFSSH_THREAD + #define INFINITE -1 + #define WAIT_OBJECT_0 0L + #else + typedef unsigned int THREAD_RETURN; + typedef intptr_t THREAD_TYPE; + #define WOLFSSH_THREAD __stdcall + #endif +#endif + +#ifdef TEST_IPV6 + typedef struct sockaddr_in6 SOCKADDR_IN_T; + #define AF_INET_V AF_INET6 +#else + typedef struct sockaddr_in SOCKADDR_IN_T; + #define AF_INET_V AF_INET +#endif + + +#define serverKeyRsaPemFile "./keys/server-key-rsa.pem" + + +typedef struct tcp_ready { + word16 ready; /* predicate */ + word16 port; + char* srfName; /* server ready file name */ +#if defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_mutex_t mutex; + pthread_cond_t cond; +#endif +} tcp_ready; + + +static INLINE void InitTcpReady(tcp_ready* ready) +{ + ready->ready = 0; + ready->port = 0; + ready->srfName = NULL; +#ifdef SINGLE_THREADED +#elif defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_mutex_init(&ready->mutex, 0); + pthread_cond_init(&ready->cond, 0); +#endif +} + + +static INLINE void FreeTcpReady(tcp_ready* ready) +{ +#ifdef SINGLE_THREADED + (void)ready; +#elif defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_mutex_destroy(&ready->mutex); + pthread_cond_destroy(&ready->cond); +#else + (void)ready; +#endif +} + + +typedef void (*ctx_callback)(WOLFSSH_CTX*); +typedef void (*ssh_callback)(WOLFSSH*); + +typedef struct callback_functions { + ctx_callback ctx_ready; + ssh_callback ssh_ready; + ssh_callback on_result; +} callback_functions; + +typedef struct func_args { + int argc; + char** argv; + int return_code; + tcp_ready* signal; + callback_functions *callbacks; +} func_args; + + +#ifndef SINGLE_THREADED + +typedef THREAD_RETURN WOLFSSH_THREAD THREAD_FUNC(void*); + +static void start_thread(THREAD_FUNC fun, void* args, THREAD_TYPE* thread) +{ +#if defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_create(thread, 0, fun, args); + return; +#elif defined(WOLFSSL_TIRTOS) + /* Initialize the defaults and set the parameters. */ + Task_Params taskParams; + Task_Params_init(&taskParams); + taskParams.arg0 = (UArg)args; + taskParams.stackSize = 65535; + *thread = Task_create((Task_FuncPtr)fun, &taskParams, NULL); + if (*thread == NULL) { + printf("Failed to create new Task\n"); + } + Task_yield(); +#else + *thread = (THREAD_TYPE)_beginthreadex(0, 0, fun, args, 0, 0); +#endif +} + + +static void join_thread(THREAD_TYPE thread) +{ +#if defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_join(thread, 0); +#elif defined(WOLFSSL_TIRTOS) + while(1) { + if (Task_getMode(thread) == Task_Mode_TERMINATED) { + Task_sleep(5); + break; + } + Task_yield(); + } +#else + int res = WaitForSingleObject((HANDLE)thread, INFINITE); + assert(res == WAIT_OBJECT_0); + res = CloseHandle((HANDLE)thread); + assert(res); + (void)res; /* Suppress un-used variable warning */ +#endif +} + + +static void detach_thread(THREAD_TYPE thread) +{ +#if defined(_POSIX_THREADS) && !defined(__MINGW32__) + pthread_detach(thread); +#elif defined(WOLFSSL_TIRTOS) +#if 0 + while(1) { + if (Task_getMode(thread) == Task_Mode_TERMINATED) { + Task_sleep(5); + break; + } + Task_yield(); + } +#endif +#else + int res = CloseHandle((HANDLE)thread); + assert(res); + (void)res; /* Suppress un-used variable warning */ +#endif +} + +#endif /* SINGLE_THREADED */ + + +#ifndef TEST_IPV6 + static const char* const wolfSshIp = "127.0.0.1"; +#else /* TEST_IPV6 */ + static const char* const wolfSshIp = "::1"; +#endif /* TEST_IPV6 */ +static const word16 wolfSshPort = 22222; + + +#ifdef __GNUC__ + #define WS_NORETURN __attribute__((noreturn)) +#else + #define WS_NORETURN +#endif + +static INLINE WS_NORETURN void err_sys(const char* msg) +{ + printf("wolfSSH error: %s\n", msg); + +#ifndef __GNUC__ + /* scan-build (which pretends to be gnuc) can get confused and think the + * msg pointer can be null even when hardcoded and then it won't exit, + * making null pointer checks above the err_sys() call useless. + * We could just always exit() but some compilers will complain about no + * possible return, with gcc we know the attribute to handle that with + * WS_NORETURN. */ + if (msg) +#endif + { + exit(EXIT_FAILURE); + } +} + + +#define MY_EX_USAGE 2 + +extern int myoptind; +extern char* myoptarg; + +static INLINE int mygetopt(int argc, char** argv, const char* optstring) +{ + static char* next = NULL; + + char c; + char* cp; + + if (myoptind == 0) + next = NULL; /* we're starting new/over */ + + if (next == NULL || *next == '\0') { + if (myoptind == 0) + myoptind++; + + if (myoptind >= argc || argv[myoptind][0] != '-' || + argv[myoptind][1] == '\0') { + myoptarg = NULL; + if (myoptind < argc) + myoptarg = argv[myoptind]; + + return -1; + } + + if (strcmp(argv[myoptind], "--") == 0) { + myoptind++; + myoptarg = NULL; + + if (myoptind < argc) + myoptarg = argv[myoptind]; + + return -1; + } + + next = argv[myoptind]; + next++; /* skip - */ + myoptind++; + } + + c = *next++; + /* The C++ strchr can return a different value */ + cp = (char*)strchr(optstring, c); + + if (cp == NULL || c == ':') + return '?'; + + cp++; + + if (*cp == ':') { + if (*next != '\0') { + myoptarg = next; + next = NULL; + } + else if (myoptind < argc) { + myoptarg = argv[myoptind]; + myoptind++; + } + else + return '?'; + } + + return c; +} + + +#ifdef USE_WINDOWS_API + #pragma warning(push) + #pragma warning(disable:4996) + /* For Windows builds, disable compiler warnings for: + * - 4996: deprecated function */ +#endif + +static INLINE void build_addr(SOCKADDR_IN_T* addr, const char* peer, + word16 port) +{ + int useLookup = 0; + (void)useLookup; + + memset(addr, 0, sizeof(SOCKADDR_IN_T)); + +#ifndef TEST_IPV6 + /* peer could be in human readable form */ + if ( ((size_t)peer != INADDR_ANY) && isalpha((int)peer[0])) { + #ifdef CYASSL_MDK_ARM + int err; + struct hostent* entry = gethostbyname(peer, &err); + #else + struct hostent* entry = gethostbyname(peer); + #endif + + if (entry) { + memcpy(&addr->sin_addr.s_addr, entry->h_addr_list[0], + entry->h_length); + useLookup = 1; + } + else + err_sys("no entry for host"); + } +#endif + +#ifndef TEST_IPV6 + #if defined(CYASSL_MDK_ARM) + addr->sin_family = PF_INET; + #else + addr->sin_family = AF_INET_V; + #endif + addr->sin_port = htons(port); + if ((size_t)peer == INADDR_ANY) + addr->sin_addr.s_addr = INADDR_ANY; + else { + if (!useLookup) + addr->sin_addr.s_addr = inet_addr(peer); + } +#else + addr->sin6_family = AF_INET_V; + addr->sin6_port = htons(port); + if ((size_t)peer == INADDR_ANY) + addr->sin6_addr = in6addr_any; + else { + #ifdef HAVE_GETADDRINFO + struct addrinfo hints; + struct addrinfo* answer = NULL; + int ret; + char strPort[80]; + + memset(&hints, 0, sizeof(hints)); + + hints.ai_family = AF_INET_V; + hints.ai_socktype = udp ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = udp ? IPPROTO_UDP : IPPROTO_TCP; + + WSNPRINTF(strPort, sizeof(strPort), "%d", port); + strPort[79] = '\0'; + + ret = getaddrinfo(peer, strPort, &hints, &answer); + if (ret < 0 || answer == NULL) + err_sys("getaddrinfo failed"); + + memcpy(addr, answer->ai_addr, answer->ai_addrlen); + freeaddrinfo(answer); + #else + printf("no ipv6 getaddrinfo, loopback only tests/examples\n"); + addr->sin6_addr = in6addr_loopback; + #endif + } +#endif +} + +#ifdef USE_WINDOWS_API + #pragma warning(pop) +#endif + + +static INLINE void tcp_socket(SOCKET_T* sockFd) +{ + *sockFd = socket(AF_INET_V, SOCK_STREAM, 0); + +#ifdef USE_WINDOWS_API + if (*sockFd == INVALID_SOCKET) + err_sys("socket failed\n"); +#else + if (*sockFd < 0) + err_sys("socket failed\n"); +#endif + +#ifndef USE_WINDOWS_API +#ifdef SO_NOSIGPIPE + { + int on = 1; + socklen_t len = sizeof(on); + int res = setsockopt(*sockFd, SOL_SOCKET, SO_NOSIGPIPE, &on, len); + if (res < 0) + err_sys("setsockopt SO_NOSIGPIPE failed\n"); + } +#elif defined(CYASSL_MDK_ARM) + /* nothing to define */ +#else /* no S_NOSIGPIPE */ + signal(SIGPIPE, SIG_IGN); +#endif /* S_NOSIGPIPE */ + +#if defined(TCP_NODELAY) + { + int on = 1; + socklen_t len = sizeof(on); + int res = setsockopt(*sockFd, IPPROTO_TCP, TCP_NODELAY, &on, len); + if (res < 0) + err_sys("setsockopt TCP_NODELAY failed\n"); + } +#endif +#endif /* USE_WINDOWS_API */ +} + + +#ifndef XNTOHS + #define XNTOHS(a) ntohs((a)) +#endif + + +static INLINE void tcp_listen(SOCKET_T* sockfd, word16* port, int useAnyAddr) +{ + SOCKADDR_IN_T addr; + + /* don't use INADDR_ANY by default, firewall may block, make user switch + on */ + build_addr(&addr, (useAnyAddr ? INADDR_ANY : wolfSshIp), *port); + tcp_socket(sockfd); + +#if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_MDK_ARM)\ + && !defined(WOLFSSL_KEIL_TCP_NET) + { + int res, on = 1; + socklen_t len = sizeof(on); + res = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, &on, len); + if (res < 0) + err_sys("setsockopt SO_REUSEADDR failed\n"); + } +#endif + + if (bind(*sockfd, (const struct sockaddr*)&addr, sizeof(addr)) != 0) + err_sys("tcp bind failed"); + if (listen(*sockfd, 5) != 0) + err_sys("tcp listen failed"); + #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_TIRTOS) + if (*port == 0) { + socklen_t len = sizeof(addr); + if (getsockname(*sockfd, (struct sockaddr*)&addr, &len) == 0) { + #ifndef TEST_IPV6 + *port = XNTOHS(addr.sin_port); + #else + *port = XNTOHS(addr.sin6_port); + #endif + } + } + #endif +} + + +/* Wolf Root Directory Helper */ +/* KEIL-RL File System does not support relative directory */ +#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS) + /* Maximum depth to search for WolfSSL root */ + #define MAX_WOLF_ROOT_DEPTH 5 + + static INLINE int ChangeToWolfSshRoot(void) + { + #if !defined(NO_FILESYSTEM) + int depth, res; + WFILE* file; + for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { + if (WFOPEN(&file, serverKeyRsaPemFile, "rb") == 0) { + WFCLOSE(file); + return depth; + } + #ifdef USE_WINDOWS_API + res = SetCurrentDirectoryA("..\\"); + #else + res = chdir("../"); + #endif + if (res < 0) { + printf("chdir to ../ failed!\n"); + break; + } + } + + err_sys("wolfSSH root not found"); + return -1; + #else + return 0; + #endif + } +#endif /* !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOL +FSSL_TIRTOS) */ + + +#endif /* _WOLFSSH_TEST_H_ */ From e47163537331ce6ad5577ef2aa6edf1c2a602d12 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Wed, 13 Sep 2017 11:38:19 -0700 Subject: [PATCH 7/8] IDE 1. Added DLL builds. 2. Cleaned up some of the build configuration. 3. Updated the README files for building. 4. Renamed the function ProcessBuffer() with a prefix due to a conflicting name with wolfSSL. 5. Added test.h to include.am. 6. Moved the user_settings.h for wolfSSL into the wolfcrypt directory. 7. Changed the echoserver so that it binds to INADDR_ANY. --- .gitignore | 4 + README.md | 12 +- examples/echoserver/echoserver.c | 6 +- examples/echoserver/include.am | 1 + ide/winvs/README.md | 42 ++++++ ide/winvs/README.txt | 1 - ide/winvs/api-test/api-test.vcxproj | 155 +++++++++++++++++++++- ide/winvs/echoserver/echoserver.vcxproj | 155 +++++++++++++++++++++- ide/winvs/include.am | 5 +- ide/winvs/unit-test/unit-test.vcxproj | 155 +++++++++++++++++++++- ide/winvs/wolfcrypt/README.txt | 21 --- ide/winvs/{ => wolfcrypt}/user_settings.h | 0 ide/winvs/wolfssh.sln | 36 +++++ ide/winvs/wolfssh/wolfssh.vcxproj | 144 ++++++++++++++++++++ src/internal.c | 5 +- src/ssh.c | 2 +- wolfssh/include.am | 3 +- wolfssh/internal.h | 4 +- 18 files changed, 704 insertions(+), 47 deletions(-) create mode 100644 ide/winvs/README.md delete mode 100644 ide/winvs/README.txt delete mode 100644 ide/winvs/wolfcrypt/README.txt rename ide/winvs/{ => wolfcrypt}/user_settings.h (100%) diff --git a/.gitignore b/.gitignore index 7cf05ff4..45dfb614 100644 --- a/.gitignore +++ b/.gitignore @@ -66,5 +66,9 @@ client.plist *.v11.suo *.vcxproj.filters *.opensdf +*.pdb +*.vcxproj.user Debug Release +DLL Debug +DLL Release diff --git a/README.md b/README.md index b9d5b22f..b771d716 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ The `autogen.sh` script only has to be run the first time after cloning the repository. If you have already run it or are using code from a source archive, you should skip it. +For building under Windows with Visual Studio, see the file +"ide/winvs/README.md". + examples -------- @@ -79,15 +82,15 @@ Where the `USER` and password pairs are: To use public key authentication use the command line: - $ ssh_client -i ./keys/USER-key-TYPE.pem -p 22222 USER@localhost + $ ssh_client -i ./keys/key-USER.pem -p 22222 USER@localhost -Where the user can be `gretel` or `hansel`, and type is `rsa` or `ecc`. +Where the user can be `gretel` or `hansel`. release notes ------------- -### wolfSSH v1.2.0 (07/XX/2017) +### wolfSSH v1.2.0 (09/XX/2017) - Added ECDH Group Exchange with SHA2 hashing and curves nistp256, nistp384, and nistp521. @@ -95,7 +98,8 @@ release notes - Changed the echoserver to allow only one connection, but multiple connections are allowed with a command line option. - Added option to echoserver to offer an ECC public key. -- Other small bug fixes and enhancements. +- Added a Visual Studio solution to build the library, examples, and tests. +- Other bug fixes and enhancements. ### wolfSSH v1.1.0 (06/16/2017) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index c6467ba3..c29a8ba2 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -545,7 +545,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) LoadPublicKeyBuffer(buf, bufSz, &pwMapList); } - tcp_listen(&listenFd, &port, 0); + tcp_listen(&listenFd, &port, 1); do { SOCKET_T clientFd = 0; @@ -622,9 +622,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) wolfSSH_Init(); - #ifndef NO_WOLFSSH_CLIENT - echoserver_test(&args); - #endif /* NO_WOLFSSH_CLIENT */ + echoserver_test(&args); wolfSSH_Cleanup(); diff --git a/examples/echoserver/include.am b/examples/echoserver/include.am index ca6ef8ef..b39ac496 100644 --- a/examples/echoserver/include.am +++ b/examples/echoserver/include.am @@ -2,6 +2,7 @@ # All paths should be given relative to the root noinst_PROGRAMS += examples/echoserver/echoserver +noinst_HEADERS += examples/echoserver/echoserver.h examples_echoserver_echoserver_SOURCES = examples/echoserver/echoserver.c examples_echoserver_echoserver_LDADD = src/libwolfssh.la examples_echoserver_echoserver_DEPENDENCIES = src/libwolfssh.la diff --git a/ide/winvs/README.md b/ide/winvs/README.md new file mode 100644 index 00000000..cbed56a5 --- /dev/null +++ b/ide/winvs/README.md @@ -0,0 +1,42 @@ +VisualStudio solution for wolfSSH +================================= + +The solution file, wolfssh.sln, facilitates bulding wolfSSH and its +example and test programs. The solution provides both Debug and Release +builds of Static and Dynamic 32- or 64-bit libraries. +the wolfSSL library with your wolfCrypt configuration. The file +`wolfcrypt/user_settings.h` should be used in the wolfSSL build to +configure it. + +The wolfcrypt directory is provided as a convenience for the test and +sample tools to find the wolfSSL library and headers. + +The wolfSSL library should just be copied into this directory with the +name `wolfssl.lib`. The headers that come with the library are in the +directory `wolfssl` and `wolfssl\wolfcrypt`. That wolfssl directory +should be copied here. If available, copy the file `wolfssl.pdb` to +`wolfssl.pdb`. It might be called `vs110.pdb`, and may be in the `obj` +directory. If it isn't copied, the wolfSSH build will warn about not +finding it and assume wolfSSL isn't built with debugging information. +It isn't critical. + +Depending on the build, you may need to copy over other versions +of the wolfSSL library files. If you make a 64-bit build of wolfSSL, +you can only make a 64-bit build of wolfSSH. + +You can build wolfSSL as either a Debug or Release build. It does not +need to match your build on wolfSSH. You cannot use the DLL build of +wolfSSL with these projects. wolfSSL is linked statically to wolfSSH. + +The following is a subset of files and the directories they live in, +as an example. + + src\ssh.c + src\internal.c + wolfcrypt\readme.txt (this file) + wolfcrypt\wolfssl.lib + wolfcrypt\wolfssl.pdb + wolfcrypt\wolfssl\ssl.h + wolfcrypt\wolfssl\options.h + wolfcrypt\wolfssl\wolfcrypt\aes.h + wolfcrypt\wolfssl\wolfcrypt\user_settings.h diff --git a/ide/winvs/README.txt b/ide/winvs/README.txt deleted file mode 100644 index 7e5693f9..00000000 --- a/ide/winvs/README.txt +++ /dev/null @@ -1 +0,0 @@ -VisualStudio solution for wolfSSH diff --git a/ide/winvs/api-test/api-test.vcxproj b/ide/winvs/api-test/api-test.vcxproj index b553fc57..18951eaf 100644 --- a/ide/winvs/api-test/api-test.vcxproj +++ b/ide/winvs/api-test/api-test.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + Release Win32 @@ -26,9 +42,6 @@ {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} - - - {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7} Win32Proj @@ -41,12 +54,24 @@ v110 Unicode + + Application + true + v110 + Unicode + Application true v110 Unicode + + Application + true + v110 + Unicode + Application false @@ -54,6 +79,13 @@ true Unicode + + Application + false + v110 + true + Unicode + Application false @@ -61,43 +93,101 @@ true Unicode + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + false $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + ..\wolfcrypt + + + @@ -116,6 +206,25 @@ + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + ..\wolfcrypt + + + @@ -134,6 +243,26 @@ + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;advapi32.lib + true + true + ..\wolfcrypt + + + Level3 @@ -153,6 +282,26 @@ + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;advapi32.lib + true + true + ..\wolfcrypt + + + Level3 diff --git a/ide/winvs/echoserver/echoserver.vcxproj b/ide/winvs/echoserver/echoserver.vcxproj index 991f3b90..9111d5d4 100644 --- a/ide/winvs/echoserver/echoserver.vcxproj +++ b/ide/winvs/echoserver/echoserver.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + Release Win32 @@ -26,9 +42,6 @@ {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} - - - {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D} Win32Proj @@ -41,12 +54,24 @@ v110 Unicode + + Application + true + v110 + Unicode + Application true v110 Unicode + + Application + true + v110 + Unicode + Application false @@ -54,6 +79,13 @@ true Unicode + + Application + false + v110 + true + Unicode + Application false @@ -61,43 +93,101 @@ true Unicode + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + false $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + ..\wolfcrypt + + + @@ -116,6 +206,25 @@ + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + ..\wolfcrypt + + + @@ -134,6 +243,26 @@ + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;advapi32.lib + true + true + ..\wolfcrypt + + + Level3 @@ -153,6 +282,26 @@ + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;advapi32.lib + true + true + ..\wolfcrypt + + + Level3 diff --git a/ide/winvs/include.am b/ide/winvs/include.am index e6148e91..d8951fef 100644 --- a/ide/winvs/include.am +++ b/ide/winvs/include.am @@ -1,11 +1,10 @@ # vim:ft=automake # All paths should be given relative to the root -EXTRA_DIST+= ide/winvs/README.txt +EXTRA_DIST+= ide/winvs/README.md EXTRA_DIST+= ide/winvs/wolfssh.sln EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj -EXTRA_DIST+= ide/winvs/user_settings.h -EXTRA_DIST+= ide/winvs/wolfcrypt/README.txt +EXTRA_DIST+= ide/winvs/wolfcrypt/user_settings.h diff --git a/ide/winvs/unit-test/unit-test.vcxproj b/ide/winvs/unit-test/unit-test.vcxproj index 7db2872e..1f4f2418 100644 --- a/ide/winvs/unit-test/unit-test.vcxproj +++ b/ide/winvs/unit-test/unit-test.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + Release Win32 @@ -26,9 +42,6 @@ {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} - - - {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02} Win32Proj @@ -41,12 +54,24 @@ v110 Unicode + + Application + true + v110 + Unicode + Application true v110 Unicode + + Application + true + v110 + Unicode + Application false @@ -54,6 +79,13 @@ true Unicode + + Application + false + v110 + true + Unicode + Application false @@ -61,43 +93,101 @@ true Unicode + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false $(Configuration)\$(Platform)\obj\ $(SolutionDir)$(Configuration)\$(Platform)\ + + false + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ + false $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + false $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + ..\wolfcrypt + + + @@ -116,6 +206,25 @@ + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + msvcrt.lib + ..\wolfcrypt + + + @@ -134,6 +243,26 @@ + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;advapi32.lib + true + true + ..\wolfcrypt + + + Level3 @@ -153,6 +282,26 @@ + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;advapi32.lib + true + true + ..\wolfcrypt + + + Level3 diff --git a/ide/winvs/wolfcrypt/README.txt b/ide/winvs/wolfcrypt/README.txt deleted file mode 100644 index 13e1fe15..00000000 --- a/ide/winvs/wolfcrypt/README.txt +++ /dev/null @@ -1,21 +0,0 @@ -WOLFCRYPT - -This directory is provided as a convenience for the test and sample -tools to find the wolfSSL library and headers. - -The library should just be copied into this directory with the name -`wolfssl.lib`. The headers that come with the library are in the -directory `wolfssl` and `wolfssl\wolfcrypt`. That wolfssl directory -should be copied here. - -The following is a subset of files and the directories they live in, -as an example. - - src\ssh.c - src\internal.c - wolfcrypt\readme.txt (this file) - wolfcrypt\wolfssl.lib - wolfcrypt\wolfssl\ssl.h - wolfcrypt\wolfssl\options.h - wolfcrypt\wolfssl\wolfcrypt\aes.h - wolfcrypt\wolfssl\wolfcrypt\user_settings.h diff --git a/ide/winvs/user_settings.h b/ide/winvs/wolfcrypt/user_settings.h similarity index 100% rename from ide/winvs/user_settings.h rename to ide/winvs/wolfcrypt/user_settings.h diff --git a/ide/winvs/wolfssh.sln b/ide/winvs/wolfssh.sln index d73e6530..db071946 100644 --- a/ide/winvs/wolfssh.sln +++ b/ide/winvs/wolfssh.sln @@ -19,6 +19,10 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Debug|x64 = DLL Debug|x64 + DLL Release|Win32 = DLL Release|Win32 + DLL Release|x64 = DLL Release|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection @@ -27,6 +31,14 @@ Global {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|Win32.Build.0 = Debug|Win32 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.ActiveCfg = Debug|x64 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Debug|x64.Build.0 = Debug|x64 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.DLL Release|x64.Build.0 = DLL Release|x64 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.ActiveCfg = Release|Win32 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|Win32.Build.0 = Release|Win32 {7C2CCF0D-A155-4914-BD1C-9A47C0530E65}.Release|x64.ActiveCfg = Release|x64 @@ -35,6 +47,14 @@ Global {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|Win32.Build.0 = Debug|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.ActiveCfg = Debug|x64 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Debug|x64.Build.0 = Debug|x64 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.DLL Release|x64.Build.0 = DLL Release|x64 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.ActiveCfg = Release|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|Win32.Build.0 = Release|Win32 {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7}.Release|x64.ActiveCfg = Release|x64 @@ -43,6 +63,14 @@ Global {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|Win32.Build.0 = Debug|Win32 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.ActiveCfg = Debug|x64 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Debug|x64.Build.0 = Debug|x64 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.DLL Release|x64.Build.0 = DLL Release|x64 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.ActiveCfg = Release|Win32 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|Win32.Build.0 = Release|Win32 {B4E163C2-ECA0-4DA2-9FD9-4CD6599C9D4D}.Release|x64.ActiveCfg = Release|x64 @@ -51,6 +79,14 @@ Global {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|Win32.Build.0 = Debug|Win32 {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.ActiveCfg = Debug|x64 {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Debug|x64.Build.0 = Debug|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.DLL Release|x64.Build.0 = DLL Release|x64 {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.ActiveCfg = Release|Win32 {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|Win32.Build.0 = Release|Win32 {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02}.Release|x64.ActiveCfg = Release|x64 diff --git a/ide/winvs/wolfssh/wolfssh.vcxproj b/ide/winvs/wolfssh/wolfssh.vcxproj index e5102d2f..8ef5e937 100644 --- a/ide/winvs/wolfssh/wolfssh.vcxproj +++ b/ide/winvs/wolfssh/wolfssh.vcxproj @@ -9,6 +9,22 @@ Debug x64 + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + Release Win32 @@ -39,12 +55,24 @@ v110 Unicode + + DynamicLibrary + true + v110 + Unicode + StaticLibrary true v110 Unicode + + DynamicLibrary + true + v110 + Unicode + StaticLibrary false @@ -52,6 +80,13 @@ true Unicode + + DynamicLibrary + false + v110 + true + Unicode + StaticLibrary false @@ -59,38 +94,73 @@ true Unicode + + DynamicLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + $(SolutionDir)$(Configuration)\$(Platform)\ $(Configuration)\$(Platform)\obj\ + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\obj\ + @@ -106,6 +176,23 @@ true + + + + + Level3 + Disabled + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + ..\wolfcrypt + wolfssl.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + @@ -121,6 +208,23 @@ true + + + + + Level3 + Disabled + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ..\wolfcrypt + + Level3 @@ -139,6 +243,26 @@ true + + + Level3 + + + MaxSpeed + true + true + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + ..\wolfcrypt + wolfssl.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + Level3 @@ -157,6 +281,26 @@ true + + + Level3 + + + MaxSpeed + true + true + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + + + Windows + true + true + true + wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + ..\wolfcrypt + + diff --git a/src/internal.c b/src/internal.c index 2f7acd9d..f712c26b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -398,8 +398,9 @@ void SshResourceFree(WOLFSSH* ssh, void* heap) } -int ProcessBuffer(WOLFSSH_CTX* ctx, const byte* in, word32 inSz, - int format, int type) +int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx, + const byte* in, word32 inSz, + int format, int type) { int dynamicType; void* heap; diff --git a/src/ssh.c b/src/ssh.c index 2bc55284..d260f922 100644 --- a/src/ssh.c +++ b/src/ssh.c @@ -533,7 +533,7 @@ int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX* ctx, const byte* in, word32 inSz, int format) { WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_UsePrivateKey_buffer()"); - return ProcessBuffer(ctx, in, inSz, format, BUFTYPE_PRIVKEY); + return wolfSSH_ProcessBuffer(ctx, in, inSz, format, BUFTYPE_PRIVKEY); } diff --git a/wolfssh/include.am b/wolfssh/include.am index 0fa6c9ed..63bc1a0d 100644 --- a/wolfssh/include.am +++ b/wolfssh/include.am @@ -13,7 +13,8 @@ nobase_include_HEADERS+= \ wolfssh/error.h \ wolfssh/visibility.h \ wolfssh/misc.h \ - wolfssh/log.h + wolfssh/log.h \ + wolfssh/test.h noinst_HEADERS+= \ wolfssh/internal.h diff --git a/wolfssh/internal.h b/wolfssh/internal.h index 5bb77258..7513a918 100644 --- a/wolfssh/internal.h +++ b/wolfssh/internal.h @@ -330,7 +330,9 @@ WOLFSSH_LOCAL void ChannelDelete(WOLFSSH_CHANNEL*, void*); WOLFSSH_LOCAL WOLFSSH_CHANNEL* ChannelFind(WOLFSSH*, word32, byte); WOLFSSH_LOCAL int ChannelRemove(WOLFSSH*, word32, byte); WOLFSSH_LOCAL int ChannelPutData(WOLFSSH_CHANNEL*, byte*, word32); -WOLFSSH_LOCAL int ProcessBuffer(WOLFSSH_CTX*, const byte*, word32, int, int); +WOLFSSH_LOCAL int wolfSSH_ProcessBuffer(WOLFSSH_CTX*, + const byte*, word32, + int, int); #ifndef WOLFSSH_USER_IO From 7e084697942b87303260c60c3cd3d0f348ed18af Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 14 Sep 2017 17:27:21 -0700 Subject: [PATCH 8/8] IDE DLL Builds 1. Moved some of the files around. 2. Updated the readme. 3. Added a property file with a set of user macros to point at wolfSSL include and build directories. 4. Updated all the project files to use the new user macros. 5. Add guard around including options.h in the echoserver. --- .gitignore | 1 - examples/echoserver/echoserver.c | 7 +- ide/winvs/README.md | 69 +- ide/winvs/api-test/api-test.vcxproj | 660 ++++++++++--------- ide/winvs/api-test/api-test.vcxproj.user | 19 + ide/winvs/echoserver/echoserver.vcxproj | 58 +- ide/winvs/echoserver/echoserver.vcxproj.user | 19 + ide/winvs/include.am | 6 +- ide/winvs/unit-test/unit-test.vcxproj | 660 ++++++++++--------- ide/winvs/unit-test/unit-test.vcxproj.user | 19 + ide/winvs/{wolfcrypt => }/user_settings.h | 0 ide/winvs/wolfssh.props | 45 ++ ide/winvs/wolfssh/wolfssh.vcxproj | 622 ++++++++--------- 13 files changed, 1167 insertions(+), 1018 deletions(-) create mode 100644 ide/winvs/api-test/api-test.vcxproj.user create mode 100644 ide/winvs/echoserver/echoserver.vcxproj.user create mode 100644 ide/winvs/unit-test/unit-test.vcxproj.user rename ide/winvs/{wolfcrypt => }/user_settings.h (100%) create mode 100644 ide/winvs/wolfssh.props diff --git a/.gitignore b/.gitignore index 45dfb614..b2fb7e02 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,6 @@ client.plist *.vcxproj.filters *.opensdf *.pdb -*.vcxproj.user Debug Release DLL Debug diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index c29a8ba2..b9ec8659 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -19,7 +19,12 @@ */ -#include +#ifdef WOLFSSL_USER_SETTINGS + #include +#else + #include +#endif + #include #include #include diff --git a/ide/winvs/README.md b/ide/winvs/README.md index cbed56a5..88a03cf1 100644 --- a/ide/winvs/README.md +++ b/ide/winvs/README.md @@ -3,40 +3,47 @@ VisualStudio solution for wolfSSH The solution file, wolfssh.sln, facilitates bulding wolfSSH and its example and test programs. The solution provides both Debug and Release -builds of Static and Dynamic 32- or 64-bit libraries. -the wolfSSL library with your wolfCrypt configuration. The file -`wolfcrypt/user_settings.h` should be used in the wolfSSL build to -configure it. +builds of Static and Dynamic 32- or 64-bit libraries. The file +`user_settings.h` should be used in the wolfSSL build to configure it. -The wolfcrypt directory is provided as a convenience for the test and -sample tools to find the wolfSSL library and headers. -The wolfSSL library should just be copied into this directory with the -name `wolfssl.lib`. The headers that come with the library are in the -directory `wolfssl` and `wolfssl\wolfcrypt`. That wolfssl directory -should be copied here. If available, copy the file `wolfssl.pdb` to -`wolfssl.pdb`. It might be called `vs110.pdb`, and may be in the `obj` -directory. If it isn't copied, the wolfSSH build will warn about not -finding it and assume wolfSSL isn't built with debugging information. -It isn't critical. +This project assumes that the wolfSSH and wolfSSL source directories +are installed side-by-side and do not have the version number in their +names: -Depending on the build, you may need to copy over other versions -of the wolfSSL library files. If you make a 64-bit build of wolfSSL, -you can only make a 64-bit build of wolfSSH. + Projects\ + wolfssh\ + wolfssl\ -You can build wolfSSL as either a Debug or Release build. It does not -need to match your build on wolfSSH. You cannot use the DLL build of -wolfSSL with these projects. wolfSSL is linked statically to wolfSSH. -The following is a subset of files and the directories they live in, -as an example. +User Macros +----------- - src\ssh.c - src\internal.c - wolfcrypt\readme.txt (this file) - wolfcrypt\wolfssl.lib - wolfcrypt\wolfssl.pdb - wolfcrypt\wolfssl\ssl.h - wolfcrypt\wolfssl\options.h - wolfcrypt\wolfssl\wolfcrypt\aes.h - wolfcrypt\wolfssl\wolfcrypt\user_settings.h +The solution is using user macros to indicate the location of the +wolfSSL library and headers. All paths are set to the default build +destinations in the wolfssl64 solution. The user macro `wolfCryptDir` +is used as the base path for finding the libraries. It is initially +set to `..\..\..\..\wolfssl`. And then, for example, the additional +include directories value for the API test project is set to +`$(wolfCryptDir)`. + + +The wolfCryptDir path must be relative to the project files, which are +all one directory down + + wolfssh/wolfssh.vcxproj + unit-test/unit-test.vcxproj + +etc. The other user macros are the directories where the wolfSSL +libraries for the different builds may be found. So the user macro +`wolfCryptDllRelease64` is initially set to + + $(wolfCryptDir)\x64\DLL Release + +This value is used in the debugging environment for the echoserver's +64-bit DLL Release build is set to + + PATH=$(wolfCryptDllRelease64);%PATH% + +When you run the echoserver from the debugger, it finds the wolfSSL +DLL in that directory. diff --git a/ide/winvs/api-test/api-test.vcxproj b/ide/winvs/api-test/api-test.vcxproj index 18951eaf..c3e69efb 100644 --- a/ide/winvs/api-test/api-test.vcxproj +++ b/ide/winvs/api-test/api-test.vcxproj @@ -1,326 +1,334 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - DLL Debug - Win32 - - - DLL Debug - x64 - - - DLL Release - Win32 - - - DLL Release - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} - - - - {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7} - Win32Proj - apitest - - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - ..\wolfcrypt - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - ..\wolfcrypt - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - wolfssl.lib;ws2_32.lib;advapi32.lib - true - true - ..\wolfcrypt - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - ws2_32.lib;advapi32.lib - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - wolfssl.lib;ws2_32.lib;advapi32.lib - true - true - ..\wolfcrypt - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - ws2_32.lib;advapi32.lib - true - true - - - - - - \ No newline at end of file + + + + + Debug + Win32 + + + Debug + x64 + + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + + + {07D36DB5-210E-45A6-8270-2DAD9DCDEFD7} + Win32Proj + apitest + + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDebug32) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDllDebug32) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDebug64) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDllDebug64) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptRelease32) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptDllRelease32) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptRelease64) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptDllRelease64) + + + + + + diff --git a/ide/winvs/api-test/api-test.vcxproj.user b/ide/winvs/api-test/api-test.vcxproj.user new file mode 100644 index 00000000..23a5dce7 --- /dev/null +++ b/ide/winvs/api-test/api-test.vcxproj.user @@ -0,0 +1,19 @@ + + + + WindowsLocalDebugger + PATH=$(wolfCryptDllDebug32);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllDebug64);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllRelease32);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllRelease64);%PATH% + + diff --git a/ide/winvs/echoserver/echoserver.vcxproj b/ide/winvs/echoserver/echoserver.vcxproj index 9111d5d4..363a86f6 100644 --- a/ide/winvs/echoserver/echoserver.vcxproj +++ b/ide/winvs/echoserver/echoserver.vcxproj @@ -105,27 +105,35 @@ + + + + + + + + @@ -175,16 +183,15 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) ProgramDatabase Console true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) msvcrt.lib - ..\wolfcrypt + $(wolfCryptDebug32) @@ -194,15 +201,15 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) ProgramDatabase Console true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) msvcrt.lib + $(wolfCryptDllDebug32) @@ -212,16 +219,15 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) ProgramDatabase Console true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) msvcrt.lib - ..\wolfcrypt + $(wolfCryptDebug64) @@ -231,15 +237,15 @@ Level3 Disabled WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) ProgramDatabase Console true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) msvcrt.lib + $(wolfCryptDllDebug64) @@ -251,15 +257,15 @@ true true WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) Console true - wolfssl.lib;ws2_32.lib;advapi32.lib + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) true true - ..\wolfcrypt + $(wolfCryptRelease32) @@ -271,14 +277,15 @@ true true WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) Console true - ws2_32.lib;advapi32.lib + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) true true + $(wolfCryptDllRelease32) @@ -290,15 +297,15 @@ true true WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) Console true - wolfssl.lib;ws2_32.lib;advapi32.lib + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) true true - ..\wolfcrypt + $(wolfCryptRelease64) @@ -310,17 +317,18 @@ true true WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) Console true - ws2_32.lib;advapi32.lib + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) true true + $(wolfCryptDllRelease64) - \ No newline at end of file + diff --git a/ide/winvs/echoserver/echoserver.vcxproj.user b/ide/winvs/echoserver/echoserver.vcxproj.user new file mode 100644 index 00000000..23a5dce7 --- /dev/null +++ b/ide/winvs/echoserver/echoserver.vcxproj.user @@ -0,0 +1,19 @@ + + + + WindowsLocalDebugger + PATH=$(wolfCryptDllDebug32);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllDebug64);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllRelease32);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllRelease64);%PATH% + + diff --git a/ide/winvs/include.am b/ide/winvs/include.am index d8951fef..a033848b 100644 --- a/ide/winvs/include.am +++ b/ide/winvs/include.am @@ -2,9 +2,13 @@ # All paths should be given relative to the root EXTRA_DIST+= ide/winvs/README.md +EXTRA_DIST+= ide/winvs/user_settings.h EXTRA_DIST+= ide/winvs/wolfssh.sln +EXTRA_DIST+= ide/winvs/wolfssh.props EXTRA_DIST+= ide/winvs/wolfssh/wolfssh.vcxproj EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj +EXTRA_DIST+= ide/winvs/api-test/api-test.vcxproj.user EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj +EXTRA_DIST+= ide/winvs/unit-test/unit-test.vcxproj.user EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj -EXTRA_DIST+= ide/winvs/wolfcrypt/user_settings.h +EXTRA_DIST+= ide/winvs/echoserver/echoserver.vcxproj.user diff --git a/ide/winvs/unit-test/unit-test.vcxproj b/ide/winvs/unit-test/unit-test.vcxproj index 1f4f2418..7a0c9c7e 100644 --- a/ide/winvs/unit-test/unit-test.vcxproj +++ b/ide/winvs/unit-test/unit-test.vcxproj @@ -1,326 +1,334 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - DLL Debug - Win32 - - - DLL Debug - x64 - - - DLL Release - Win32 - - - DLL Release - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} - - - - {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02} - Win32Proj - unittest - - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - true - v110 - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - Application - false - v110 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(Configuration)\$(Platform)\obj\ - $(SolutionDir)$(Configuration)\$(Platform)\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - false - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - ..\wolfcrypt - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - ..\wolfcrypt - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Console - true - ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - UseLinkTimeCodeGeneration - msvcrt.lib - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - wolfssl.lib;ws2_32.lib;advapi32.lib - true - true - ..\wolfcrypt - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - ws2_32.lib;advapi32.lib - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - wolfssl.lib;ws2_32.lib;advapi32.lib - true - true - ..\wolfcrypt - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Console - true - ws2_32.lib;advapi32.lib - true - true - - - - - - \ No newline at end of file + + + + + Debug + Win32 + + + Debug + x64 + + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + {7c2ccf0d-a155-4914-bd1c-9a47c0530e65} + + + + {CBF8A91E-C52B-4044-9FDA-B99D5D3CFF02} + Win32Proj + unittest + + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + true + v110 + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + Application + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(Configuration)\$(Platform)\ + $(SolutionDir)$(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + false + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDebug32) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDllDebug32) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDebug64) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + msvcrt.lib + $(wolfCryptDllDebug64) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptRelease32) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptDllRelease32) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptRelease64) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Console + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + true + true + $(wolfCryptDllRelease64) + + + + + + diff --git a/ide/winvs/unit-test/unit-test.vcxproj.user b/ide/winvs/unit-test/unit-test.vcxproj.user new file mode 100644 index 00000000..23a5dce7 --- /dev/null +++ b/ide/winvs/unit-test/unit-test.vcxproj.user @@ -0,0 +1,19 @@ + + + + WindowsLocalDebugger + PATH=$(wolfCryptDllDebug32);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllDebug64);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllRelease32);%PATH% + + + WindowsLocalDebugger + PATH=$(wolfCryptDllRelease64);%PATH% + + diff --git a/ide/winvs/wolfcrypt/user_settings.h b/ide/winvs/user_settings.h similarity index 100% rename from ide/winvs/wolfcrypt/user_settings.h rename to ide/winvs/user_settings.h diff --git a/ide/winvs/wolfssh.props b/ide/winvs/wolfssh.props new file mode 100644 index 00000000..652f16ce --- /dev/null +++ b/ide/winvs/wolfssh.props @@ -0,0 +1,45 @@ + + + + + ..\..\..\..\wolfssl + $(wolfCryptDir)\Debug + $(wolfCryptDir)\Release + $(wolfCryptDir)\x64\Debug + $(wolfCryptDir)\x64\Release + $(wolfCryptDir)\DLL Debug + $(wolfCryptDir)\DLL Release + $(wolfCryptDir)\x64\DLL Debug + $(wolfCryptDir)\x64\DLL Release + + + + + $(wolfCryptDir) + + + $(wolfCryptDebug32) + + + $(wolfCryptRelease32) + + + $(wolfCryptDebug64) + + + $(wolfCryptRelease64) + + + $(wolfCryptDllDebug32) + + + $(wolfCryptDllRelease32) + + + $(wolfCryptDllDebug64) + + + $(wolfCryptDllRelease64) + + + diff --git a/ide/winvs/wolfssh/wolfssh.vcxproj b/ide/winvs/wolfssh/wolfssh.vcxproj index 8ef5e937..ce39d203 100644 --- a/ide/winvs/wolfssh/wolfssh.vcxproj +++ b/ide/winvs/wolfssh/wolfssh.vcxproj @@ -1,307 +1,315 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - DLL Debug - Win32 - - - DLL Debug - x64 - - - DLL Release - Win32 - - - DLL Release - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} - Win32Proj - wolfssh - - - - StaticLibrary - true - v110 - Unicode - - - DynamicLibrary - true - v110 - Unicode - - - StaticLibrary - true - v110 - Unicode - - - DynamicLibrary - true - v110 - Unicode - - - StaticLibrary - false - v110 - true - Unicode - - - DynamicLibrary - false - v110 - true - Unicode - - - StaticLibrary - false - v110 - true - Unicode - - - DynamicLibrary - false - v110 - true - Unicode - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - $(SolutionDir)$(Configuration)\$(Platform)\ - $(Configuration)\$(Platform)\obj\ - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Windows - true - - - - - - - Level3 - Disabled - WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Windows - true - ..\wolfcrypt - wolfssl.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Windows - true - - - - - - - Level3 - Disabled - WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - ProgramDatabase - - - Windows - true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - ..\wolfcrypt - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - ..\wolfcrypt - wolfssl.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) - ..\..\..;..\wolfcrypt;%(AdditionalIncludeDirectories) - - - Windows - true - true - true - wolfssl.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) - ..\wolfcrypt - - - - - - \ No newline at end of file + + + + + Debug + Win32 + + + Debug + x64 + + + DLL Debug + Win32 + + + DLL Debug + x64 + + + DLL Release + Win32 + + + DLL Release + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + {7C2CCF0D-A155-4914-BD1C-9A47C0530E65} + Win32Proj + wolfssh + + + + StaticLibrary + true + v110 + Unicode + + + DynamicLibrary + true + v110 + Unicode + + + StaticLibrary + true + v110 + Unicode + + + DynamicLibrary + true + v110 + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + DynamicLibrary + false + v110 + true + Unicode + + + StaticLibrary + false + v110 + true + Unicode + + + DynamicLibrary + false + v110 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + $(SolutionDir)$(Configuration)\$(Platform)\ + $(Configuration)\$(Platform)\ + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + + + + + + + Level3 + Disabled + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + $(wolfCryptDllDebug32) + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + + + + + + + Level3 + Disabled + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;_DEBUG;_LIB;DEBUG_WOLFSSH;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + ProgramDatabase + + + Windows + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + $(wolfCryptDllDebug64) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Windows + true + true + true + $(wolfCryptDllRelease32) + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + WOLFSSH_LIB;BUILDING_WOLFSSH;WOLFSSH_DLL;WIN32;NDEBUG;_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + ..;..\..\..;$(wolfCryptDir);%(AdditionalIncludeDirectories) + + + Windows + true + true + true + wolfssl.lib;ws2_32.lib;%(AdditionalDependencies) + $(wolfCryptDllRelease64) + + + + + +