diff --git a/client/SDL/SDL2/sdl_freerdp.cpp b/client/SDL/SDL2/sdl_freerdp.cpp index 4cb04b1e2..31907e194 100644 --- a/client/SDL/SDL2/sdl_freerdp.cpp +++ b/client/SDL/SDL2/sdl_freerdp.cpp @@ -1663,9 +1663,22 @@ int main(int argc, char* argv[]) if (status) { rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); - SdlPref::print_config_file_help(2); if (freerdp_settings_get_bool(settings, FreeRDP_ListMonitors)) sdl_list_monitors(sdl); + else + { + switch (status) + { + case COMMAND_LINE_STATUS_PRINT: + case COMMAND_LINE_STATUS_PRINT_VERSION: + case COMMAND_LINE_STATUS_PRINT_BUILDCONFIG: + break; + case COMMAND_LINE_STATUS_PRINT_HELP: + default: + SdlPref::print_config_file_help(2); + break; + } + } return rc; } diff --git a/client/SDL/SDL3/sdl_freerdp.cpp b/client/SDL/SDL3/sdl_freerdp.cpp index 368096c55..aec44811a 100644 --- a/client/SDL/SDL3/sdl_freerdp.cpp +++ b/client/SDL/SDL3/sdl_freerdp.cpp @@ -1647,9 +1647,22 @@ int main(int argc, char* argv[]) if (status) { rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); - SdlPref::print_config_file_help(3); if (freerdp_settings_get_bool(settings, FreeRDP_ListMonitors)) sdl_list_monitors(sdl); + else + { + switch (status) + { + case COMMAND_LINE_STATUS_PRINT: + case COMMAND_LINE_STATUS_PRINT_VERSION: + case COMMAND_LINE_STATUS_PRINT_BUILDCONFIG: + break; + case COMMAND_LINE_STATUS_PRINT_HELP: + default: + SdlPref::print_config_file_help(3); + break; + } + } return rc; } diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c index 97e31d5f2..9a0ef647b 100644 --- a/client/X11/cli/xfreerdp.c +++ b/client/X11/cli/xfreerdp.c @@ -80,11 +80,22 @@ int main(int argc, char* argv[]) { rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv); - xfreerdp_print_help(); - if (freerdp_settings_get_bool(settings, FreeRDP_ListMonitors)) xf_list_monitors(xfc); - + else + { + switch (status) + { + case COMMAND_LINE_STATUS_PRINT: + case COMMAND_LINE_STATUS_PRINT_VERSION: + case COMMAND_LINE_STATUS_PRINT_BUILDCONFIG: + break; + case COMMAND_LINE_STATUS_PRINT_HELP: + default: + xfreerdp_print_help(); + break; + } + } goto out; } diff --git a/cmake/CommonConfigOptions.cmake b/cmake/CommonConfigOptions.cmake index ce09dedf3..523b87bea 100644 --- a/cmake/CommonConfigOptions.cmake +++ b/cmake/CommonConfigOptions.cmake @@ -29,6 +29,8 @@ if (NOT ANDROID) option(CMAKE_INTERPROCEDURAL_OPTIMIZATION "build with link time optimization" ${supported}) endif() +set(SUPPORTED_BUILD_TYPES "Debug" "Release" "MinSizeRel" "RelWithDebInfo") + # Default to release build type if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) # Set a default build type if none was specified @@ -39,7 +41,13 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) STRING "Choose the type of build." FORCE) # Set the possible values of build type for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY - STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") + STRINGS ${SUPPORTED_BUILD_TYPES}) +endif() + +if (CMAKE_BUILD_TYPE) + if (NOT "${CMAKE_BUILD_TYPE}" IN_LIST SUPPORTED_BUILD_TYPES) + message(FATAL_ERROR "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not supported. Set to any of ${SUPPORTED_BUILD_TYPES}") + endif() endif() include(PlatformDefaults) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 8290fa242..b43b5bb9e 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -38,6 +38,12 @@ if (WIN32) string(REPLACE "\\" "\\\\" NATIVE_FREERDP_PROXY_PLUGINDIR "${NATIVE_FREERDP_PROXY_PLUGINDIR}") endif() +set(C_FLAGS ${CMAKE_C_FLAGS}) +if (CMAKE_BUILD_TYPE) + string(TOUPPER "${CMAKE_BUILD_TYPE}" CAPS_BUILD_TYPE) + string(APPEND C_FLAGS " ${CMAKE_C_FLAGS_${CAPS_BUILD_TYPE}}") +endif() + cleaning_configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp/version.h) cleaning_configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/build-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp/build-config.h) cleaning_configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/freerdp/config.h) diff --git a/include/config/buildflags.h.in b/include/config/buildflags.h.in index 3a286f233..ed9dfca53 100644 --- a/include/config/buildflags.h.in +++ b/include/config/buildflags.h.in @@ -1,7 +1,7 @@ #ifndef FREERDP_BUILD_FLAGS_H #define FREERDP_BUILD_FLAGS_H -#define FREERDP_CFLAGS "${CMAKE_C_FLAGS}" +#define FREERDP_CFLAGS "${C_FLAGS}" #define FREERDP_COMPILER_ID "${CMAKE_C_COMPILER_ID}" #define FREERDP_COMPILER_VERSION "${CMAKE_C_COMPILER_VERSION}" #define FREERDP_TARGET_ARCH "${TARGET_ARCH}" diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 03a48f10f..4c7e412b8 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -42,6 +42,14 @@ #define RDP_TAG FREERDP_TAG("core.rdp") +typedef struct +{ + const char* file; + const char* fkt; + size_t line; + DWORD level; +} log_line_t; + static const char* DATA_PDU_TYPE_STRINGS[80] = { "?", "?", /* 0x00 - 0x01 */ @@ -2782,6 +2790,20 @@ static BOOL parse_on_off_option(const char* value) #define STR(x) #x +static BOOL option_is_runtime_checks(wLog* log, const char* tok) +{ + const char* experimental[] = { STR(WITH_VERBOSE_WINPR_ASSERT) }; + for (size_t x = 0; x < ARRAYSIZE(experimental); x++) + { + const char* opt = experimental[x]; + if (starts_with(tok, opt)) + { + return parse_on_off_option(tok); + } + } + return FALSE; +} + static BOOL option_is_experimental(wLog* log, const char* tok) { const char* experimental[] = { STR(WITH_DSP_EXPERIMENTAL), STR(WITH_VAAPI) }; @@ -2903,6 +2925,141 @@ static void log_build_warn(rdpRdp* rdp, const char* what, const char* msg, free(list); } +#define print_first_line(log, firstLine, what) \ + print_first_line_int((log), (firstLine), (what), __FILE__, __func__, __LINE__) +static void print_first_line_int(wLog* log, log_line_t* firstLine, const char* what, + const char* file, const char* fkt, size_t line) +{ + WINPR_ASSERT(firstLine); + if (!firstLine->fkt) + { + const DWORD level = WLOG_WARN; + if (WLog_IsLevelActive(log, level)) + { + WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, level, line, file, fkt, + "*************************************************"); + WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, level, line, file, fkt, + "[SSL] {%s} build or configuration missing:", what); + } + firstLine->line = line; + firstLine->file = file; + firstLine->fkt = fkt; + firstLine->level = level; + } +} + +static void print_last_line(wLog* log, const log_line_t* firstLine) +{ + WINPR_ASSERT(firstLine); + if (firstLine->fkt) + { + if (WLog_IsLevelActive(log, firstLine->level)) + WLog_PrintMessage(log, WLOG_MESSAGE_TEXT, firstLine->level, firstLine->line, + firstLine->file, firstLine->fkt, + "*************************************************"); + } +} + +static void log_build_warn_cipher(rdpRdp* rdp, log_line_t* firstLine, WINPR_CIPHER_TYPE md, + const char* what) +{ + BOOL haveCipher = FALSE; + + char key[WINPR_CIPHER_MAX_KEY_LENGTH] = { 0 }; + char iv[WINPR_CIPHER_MAX_IV_LENGTH] = { 0 }; + WINPR_CIPHER_CTX* enc = winpr_Cipher_New(md, WINPR_ENCRYPT, key, iv); + WINPR_CIPHER_CTX* dec = winpr_Cipher_New(md, WINPR_DECRYPT, key, iv); + if (enc && dec) + { + haveCipher = TRUE; + } + winpr_Cipher_Free(enc); + winpr_Cipher_Free(dec); + + if (!haveCipher) + { + print_first_line(rdp->log, firstLine, "Cipher"); + WLog_Print(rdp->log, WLOG_WARN, "* %s: %s", winpr_cipher_type_to_string(md), what); + } +} + +static void log_build_warn_hmac(rdpRdp* rdp, log_line_t* firstLine, WINPR_MD_TYPE md, + const char* what) +{ + BOOL haveHmacX = FALSE; + WINPR_HMAC_CTX* hmac = winpr_HMAC_New(); + if (hmac) + { + /* We need some key length, but there is no real limit here. + * just take the cipher maximum key length as we already have that available. + */ + char key[WINPR_CIPHER_MAX_KEY_LENGTH] = { 0 }; + haveHmacX = winpr_HMAC_Init(hmac, md, key, sizeof(key)); + } + winpr_HMAC_Free(hmac); + + if (!haveHmacX) + { + print_first_line(rdp->log, firstLine, "HMAC"); + WLog_Print(rdp->log, WLOG_WARN, " * %s: %s", winpr_md_type_to_string(md), what); + } +} + +static void log_build_warn_hash(rdpRdp* rdp, log_line_t* firstLine, WINPR_MD_TYPE md, + const char* what) +{ + BOOL haveDigestX = FALSE; + + WINPR_DIGEST_CTX* digest = winpr_Digest_New(); + if (digest) + haveDigestX = winpr_Digest_Init(digest, md); + winpr_Digest_Free(digest); + + if (!haveDigestX) + { + print_first_line(rdp->log, firstLine, "Digest"); + WLog_Print(rdp->log, WLOG_WARN, " * %s: %s", winpr_md_type_to_string(md), what); + } +} + +static void log_build_warn_ssl(rdpRdp* rdp) +{ + WINPR_ASSERT(rdp); + + log_line_t firstHashLine = { 0 }; + log_build_warn_hash(rdp, &firstHashLine, WINPR_MD_MD4, "NTLM support not available"); + log_build_warn_hash(rdp, &firstHashLine, WINPR_MD_MD5, + "NTLM, assistance files with encrypted passwords, autoreconnect cookies, " + "licensing and RDP security will not work"); + log_build_warn_hash(rdp, &firstHashLine, WINPR_MD_SHA1, + "assistance files with encrypted passwords, Kerberos, Smartcard Logon, RDP " + "security support not available"); + log_build_warn_hash( + rdp, &firstHashLine, WINPR_MD_SHA256, + "file clipboard, AAD gateway, NLA security and certificates might not work"); + print_last_line(rdp->log, &firstHashLine); + + log_line_t firstHmacLine = { 0 }; + log_build_warn_hmac(rdp, &firstHmacLine, WINPR_MD_MD5, "Autoreconnect cookie not supported"); + log_build_warn_hmac(rdp, &firstHmacLine, WINPR_MD_SHA1, "RDP security not supported"); + print_last_line(rdp->log, &firstHmacLine); + + log_line_t firstCipherLine = { 0 }; + log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_ARC4_128, + "assistance files with encrypted passwords, NTLM, RDP licensing and RDP " + "security will not work"); + log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_DES_EDE3_CBC, + "RDP security FIPS mode will not work"); + log_build_warn_cipher( + rdp, &firstCipherLine, WINPR_CIPHER_AES_128_CBC, + "assistance file encrypted LHTicket will not work and ARM gateway might not"); + log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_AES_192_CBC, + "ARM gateway might not work"); + log_build_warn_cipher(rdp, &firstCipherLine, WINPR_CIPHER_AES_256_CBC, + "ARM gateway might not work"); + print_last_line(rdp->log, &firstCipherLine); +} + void rdp_log_build_warnings(rdpRdp* rdp) { static unsigned count = 0; @@ -2917,4 +3074,7 @@ void rdp_log_build_warnings(rdpRdp* rdp) log_build_warn(rdp, "experimental", "might crash the application", option_is_experimental); log_build_warn(rdp, "debug", "might leak sensitive information (credentials, ...)", option_is_debug); + log_build_warn(rdp, "runtime-check", "might slow down the application", + option_is_runtime_checks); + log_build_warn_ssl(rdp); } diff --git a/uwac/templates/CMakeLists.txt b/uwac/templates/CMakeLists.txt index b5e506bdf..427077897 100644 --- a/uwac/templates/CMakeLists.txt +++ b/uwac/templates/CMakeLists.txt @@ -32,6 +32,13 @@ FOREACH(var ${res}) LIST(APPEND UWAC_BUILD_CONFIG_LIST "${var}=${${var}}") ENDIF() ENDFOREACH() + +set(C_FLAGS ${CMAKE_C_FLAGS}) +if (CMAKE_BUILD_TYPE) + string(TOUPPER "${CMAKE_BUILD_TYPE}" CAPS_BUILD_TYPE) + string(APPEND C_FLAGS " ${CMAKE_C_FLAGS_${CAPS_BUILD_TYPE}}") +endif() + string(REPLACE ";" " " UWAC_BUILD_CONFIG "${UWAC_BUILD_CONFIG_LIST}") cleaning_configure_file(version.h.in ${CMAKE_CURRENT_BINARY_DIR}/../include/uwac/version.h) cleaning_configure_file(buildflags.h.in ${CMAKE_CURRENT_BINARY_DIR}/../include/uwac/buildflags.h) diff --git a/uwac/templates/buildflags.h.in b/uwac/templates/buildflags.h.in index d16dfb96c..2ac4d949b 100644 --- a/uwac/templates/buildflags.h.in +++ b/uwac/templates/buildflags.h.in @@ -1,7 +1,7 @@ #ifndef UWAC_BUILD_FLAGS_H #define UWAC_BUILD_FLAGS_H -#define UWAC_CFLAGS "${CMAKE_C_FLAGS}" +#define UWAC_CFLAGS "${C_FLAGS}" #define UWAC_COMPILER_ID "${CMAKE_C_COMPILER_ID}" #define UWAC_COMPILER_VERSION "${CMAKE_C_COMPILER_VERSION}" #define UWAC_TARGET_ARCH "${TARGET_ARCH}" diff --git a/winpr/include/CMakeLists.txt b/winpr/include/CMakeLists.txt index 7bbd89d1a..0717d20d3 100644 --- a/winpr/include/CMakeLists.txt +++ b/winpr/include/CMakeLists.txt @@ -15,6 +15,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +set(C_FLAGS ${CMAKE_C_FLAGS}) +if (CMAKE_BUILD_TYPE) + string(TOUPPER "${CMAKE_BUILD_TYPE}" CAPS_BUILD_TYPE) + string(APPEND C_FLAGS " ${CMAKE_C_FLAGS_${CAPS_BUILD_TYPE}}") +endif() + cleaning_configure_file(config/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/winpr/version.h) cleaning_configure_file(config/wtypes.h.in ${CMAKE_CURRENT_BINARY_DIR}/winpr/wtypes.h) cleaning_configure_file(config/build-config.h.in ${CMAKE_CURRENT_BINARY_DIR}/winpr/build-config.h) diff --git a/winpr/include/config/buildflags.h.in b/winpr/include/config/buildflags.h.in index 1e43c37ee..124c43d03 100644 --- a/winpr/include/config/buildflags.h.in +++ b/winpr/include/config/buildflags.h.in @@ -1,7 +1,7 @@ #ifndef WINPR_BUILD_FLAGS_H #define WINPR_BUILD_FLAGS_H -#define WINPR_CFLAGS "${CMAKE_C_FLAGS}" +#define WINPR_CFLAGS "${C_FLAGS}" #define WINPR_COMPILER_ID "${CMAKE_C_COMPILER_ID}" #define WINPR_COMPILER_VERSION "${CMAKE_C_COMPILER_VERSION}" #define WINPR_TARGET_ARCH "${TARGET_ARCH}" diff --git a/winpr/include/winpr/custom-crypto.h b/winpr/include/winpr/custom-crypto.h index 32ff5d4c2..cc1c37332 100644 --- a/winpr/include/winpr/custom-crypto.h +++ b/winpr/include/winpr/custom-crypto.h @@ -174,59 +174,68 @@ extern "C" #define WINPR_AES_BLOCK_SIZE 16 /* cipher operation types */ -#define WINPR_ENCRYPT 0 -#define WINPR_DECRYPT 1 +#define WINPR_CIPHER_MAX_IV_LENGTH 16u +#define WINPR_CIPHER_MAX_KEY_LENGTH 64u + +typedef enum +{ + WINPR_ENCRYPT = 0, + WINPR_DECRYPT = 1 +} WINPR_CRYPTO_OPERATION; /* cipher types */ -#define WINPR_CIPHER_NONE 0 -#define WINPR_CIPHER_NULL 1 -#define WINPR_CIPHER_AES_128_ECB 2 -#define WINPR_CIPHER_AES_192_ECB 3 -#define WINPR_CIPHER_AES_256_ECB 4 -#define WINPR_CIPHER_AES_128_CBC 5 -#define WINPR_CIPHER_AES_192_CBC 6 -#define WINPR_CIPHER_AES_256_CBC 7 -#define WINPR_CIPHER_AES_128_CFB128 8 -#define WINPR_CIPHER_AES_192_CFB128 9 -#define WINPR_CIPHER_AES_256_CFB128 10 -#define WINPR_CIPHER_AES_128_CTR 11 -#define WINPR_CIPHER_AES_192_CTR 12 -#define WINPR_CIPHER_AES_256_CTR 13 -#define WINPR_CIPHER_AES_128_GCM 14 -#define WINPR_CIPHER_AES_192_GCM 15 -#define WINPR_CIPHER_AES_256_GCM 16 -#define WINPR_CIPHER_CAMELLIA_128_ECB 17 -#define WINPR_CIPHER_CAMELLIA_192_ECB 18 -#define WINPR_CIPHER_CAMELLIA_256_ECB 19 -#define WINPR_CIPHER_CAMELLIA_128_CBC 20 -#define WINPR_CIPHER_CAMELLIA_192_CBC 21 -#define WINPR_CIPHER_CAMELLIA_256_CBC 22 -#define WINPR_CIPHER_CAMELLIA_128_CFB128 23 -#define WINPR_CIPHER_CAMELLIA_192_CFB128 24 -#define WINPR_CIPHER_CAMELLIA_256_CFB128 25 -#define WINPR_CIPHER_CAMELLIA_128_CTR 26 -#define WINPR_CIPHER_CAMELLIA_192_CTR 27 -#define WINPR_CIPHER_CAMELLIA_256_CTR 28 -#define WINPR_CIPHER_CAMELLIA_128_GCM 29 -#define WINPR_CIPHER_CAMELLIA_192_GCM 30 -#define WINPR_CIPHER_CAMELLIA_256_GCM 31 -#define WINPR_CIPHER_DES_ECB 32 -#define WINPR_CIPHER_DES_CBC 33 -#define WINPR_CIPHER_DES_EDE_ECB 34 -#define WINPR_CIPHER_DES_EDE_CBC 35 -#define WINPR_CIPHER_DES_EDE3_ECB 36 -#define WINPR_CIPHER_DES_EDE3_CBC 37 -#define WINPR_CIPHER_BLOWFISH_ECB 38 -#define WINPR_CIPHER_BLOWFISH_CBC 39 -#define WINPR_CIPHER_BLOWFISH_CFB64 40 -#define WINPR_CIPHER_BLOWFISH_CTR 41 -#define WINPR_CIPHER_ARC4_128 42 -#define WINPR_CIPHER_AES_128_CCM 43 -#define WINPR_CIPHER_AES_192_CCM 44 -#define WINPR_CIPHER_AES_256_CCM 45 -#define WINPR_CIPHER_CAMELLIA_128_CCM 46 -#define WINPR_CIPHER_CAMELLIA_192_CCM 47 -#define WINPR_CIPHER_CAMELLIA_256_CCM 48 +typedef enum +{ + WINPR_CIPHER_NONE = 0, + WINPR_CIPHER_NULL = 1, + WINPR_CIPHER_AES_128_ECB = 2, + WINPR_CIPHER_AES_192_ECB = 3, + WINPR_CIPHER_AES_256_ECB = 4, + WINPR_CIPHER_AES_128_CBC = 5, + WINPR_CIPHER_AES_192_CBC = 6, + WINPR_CIPHER_AES_256_CBC = 7, + WINPR_CIPHER_AES_128_CFB128 = 8, + WINPR_CIPHER_AES_192_CFB128 = 9, + WINPR_CIPHER_AES_256_CFB128 = 10, + WINPR_CIPHER_AES_128_CTR = 11, + WINPR_CIPHER_AES_192_CTR = 12, + WINPR_CIPHER_AES_256_CTR = 13, + WINPR_CIPHER_AES_128_GCM = 14, + WINPR_CIPHER_AES_192_GCM = 15, + WINPR_CIPHER_AES_256_GCM = 16, + WINPR_CIPHER_CAMELLIA_128_ECB = 17, + WINPR_CIPHER_CAMELLIA_192_ECB = 18, + WINPR_CIPHER_CAMELLIA_256_ECB = 19, + WINPR_CIPHER_CAMELLIA_128_CBC = 20, + WINPR_CIPHER_CAMELLIA_192_CBC = 21, + WINPR_CIPHER_CAMELLIA_256_CBC = 22, + WINPR_CIPHER_CAMELLIA_128_CFB128 = 23, + WINPR_CIPHER_CAMELLIA_192_CFB128 = 24, + WINPR_CIPHER_CAMELLIA_256_CFB128 = 25, + WINPR_CIPHER_CAMELLIA_128_CTR = 26, + WINPR_CIPHER_CAMELLIA_192_CTR = 27, + WINPR_CIPHER_CAMELLIA_256_CTR = 28, + WINPR_CIPHER_CAMELLIA_128_GCM = 29, + WINPR_CIPHER_CAMELLIA_192_GCM = 30, + WINPR_CIPHER_CAMELLIA_256_GCM = 31, + WINPR_CIPHER_DES_ECB = 32, + WINPR_CIPHER_DES_CBC = 33, + WINPR_CIPHER_DES_EDE_ECB = 34, + WINPR_CIPHER_DES_EDE_CBC = 35, + WINPR_CIPHER_DES_EDE3_ECB = 36, + WINPR_CIPHER_DES_EDE3_CBC = 37, + WINPR_CIPHER_BLOWFISH_ECB = 38, + WINPR_CIPHER_BLOWFISH_CBC = 39, + WINPR_CIPHER_BLOWFISH_CFB64 = 40, + WINPR_CIPHER_BLOWFISH_CTR = 41, + WINPR_CIPHER_ARC4_128 = 42, + WINPR_CIPHER_AES_128_CCM = 43, + WINPR_CIPHER_AES_192_CCM = 44, + WINPR_CIPHER_AES_256_CCM = 45, + WINPR_CIPHER_CAMELLIA_128_CCM = 46, + WINPR_CIPHER_CAMELLIA_192_CCM = 47, + WINPR_CIPHER_CAMELLIA_256_CCM = 48, +} WINPR_CIPHER_TYPE; typedef struct winpr_cipher_ctx_private_st WINPR_CIPHER_CTX; @@ -235,10 +244,29 @@ extern "C" { #endif + /** @brief convert a cipher string to an enum value + * + * @param name the name of the cipher + * @return the \b WINPR_CIPHER_* value matching or \b WINPR_CIPHER_NONE if not found. + * + * @since version 3.10.0 + */ + WINPR_API WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name); + + /** @brief convert a cipher enum value to string + * + * @param md the cipher enum value + * @return the string representation of the value + * + * @since version 3.10.0 + */ + WINPR_API const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE md); + WINPR_API void winpr_Cipher_Free(WINPR_CIPHER_CTX* ctx); WINPR_ATTR_MALLOC(winpr_Cipher_Free, 1) - WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_New(int cipher, int op, const void* key, + WINPR_API WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, + WINPR_CRYPTO_OPERATION op, const void* key, const void* iv); WINPR_API BOOL winpr_Cipher_SetPadding(WINPR_CIPHER_CTX* ctx, BOOL enabled); WINPR_API BOOL winpr_Cipher_Update(WINPR_CIPHER_CTX* ctx, const void* input, size_t ilen, diff --git a/winpr/libwinpr/crypto/cipher.c b/winpr/libwinpr/crypto/cipher.c index d1e2fd298..ee3df9c30 100644 --- a/winpr/libwinpr/crypto/cipher.c +++ b/winpr/libwinpr/crypto/cipher.c @@ -172,8 +172,100 @@ extern const EVP_MD* winpr_openssl_get_evp_md(WINPR_MD_TYPE md); extern mbedtls_md_type_t winpr_mbedtls_get_md_type(int md); #endif +struct cipher_map +{ + WINPR_CIPHER_TYPE md; + const char* name; +}; +static const struct cipher_map s_cipher_map[] = { + { WINPR_CIPHER_NONE, "none" }, + { WINPR_CIPHER_NULL, "null" }, + { WINPR_CIPHER_AES_128_ECB, "aes-128-ecb" }, + { WINPR_CIPHER_AES_192_ECB, "aes-192-ecb" }, + { WINPR_CIPHER_AES_256_ECB, "aes-256-ecb" }, + { WINPR_CIPHER_AES_128_CBC, "aes-128-cbc" }, + { WINPR_CIPHER_AES_192_CBC, "aes-192-cbc" }, + { WINPR_CIPHER_AES_256_CBC, "aes-256-cbc" }, + { WINPR_CIPHER_AES_128_CFB128, "aes-128-cfb128" }, + { WINPR_CIPHER_AES_192_CFB128, "aes-192-cfb128" }, + { WINPR_CIPHER_AES_256_CFB128, "aes-256-cfb128" }, + { WINPR_CIPHER_AES_128_CTR, "aes-128-ctr" }, + { WINPR_CIPHER_AES_192_CTR, "aes-192-ctr" }, + { WINPR_CIPHER_AES_256_CTR, "aes-256-ctr" }, + { WINPR_CIPHER_AES_128_GCM, "aes-128-gcm" }, + { WINPR_CIPHER_AES_192_GCM, "aes-192-gcm" }, + { WINPR_CIPHER_AES_256_GCM, "aes-256-gcm" }, + { WINPR_CIPHER_CAMELLIA_128_ECB, "camellia-128-ecb" }, + { WINPR_CIPHER_CAMELLIA_192_ECB, "camellia-192-ecb" }, + { WINPR_CIPHER_CAMELLIA_256_ECB, "camellia-256-ecb" }, + { WINPR_CIPHER_CAMELLIA_128_CBC, "camellia-128-cbc" }, + { WINPR_CIPHER_CAMELLIA_192_CBC, "camellia-192-cbc" }, + { WINPR_CIPHER_CAMELLIA_256_CBC, "camellia-256-cbc" }, + { WINPR_CIPHER_CAMELLIA_128_CFB128, "camellia-128-cfb128" }, + { WINPR_CIPHER_CAMELLIA_192_CFB128, "camellia-192-cfb128" }, + { WINPR_CIPHER_CAMELLIA_256_CFB128, "camellia-256-cfb128" }, + { WINPR_CIPHER_CAMELLIA_128_CTR, "camellia-128-ctr" }, + { WINPR_CIPHER_CAMELLIA_192_CTR, "camellia-192-ctr" }, + { WINPR_CIPHER_CAMELLIA_256_CTR, "camellia-256-ctr" }, + { WINPR_CIPHER_CAMELLIA_128_GCM, "camellia-128-gcm" }, + { WINPR_CIPHER_CAMELLIA_192_GCM, "camellia-192-gcm" }, + { WINPR_CIPHER_CAMELLIA_256_GCM, "camellia-256-gcm" }, + { WINPR_CIPHER_DES_ECB, "des-ecb" }, + { WINPR_CIPHER_DES_CBC, "des-cbc" }, + { WINPR_CIPHER_DES_EDE_ECB, "des-ede-ecb" }, + { WINPR_CIPHER_DES_EDE_CBC, "des-ede-cbc" }, + { WINPR_CIPHER_DES_EDE3_ECB, "des-ede3-ecb" }, + { WINPR_CIPHER_DES_EDE3_CBC, "des-ede3-cbc" }, + { WINPR_CIPHER_BLOWFISH_ECB, "blowfish-ecb" }, + { WINPR_CIPHER_BLOWFISH_CBC, "blowfish-cbc" }, + { WINPR_CIPHER_BLOWFISH_CFB64, "blowfish-cfb64" }, + { WINPR_CIPHER_BLOWFISH_CTR, "blowfish-ctr" }, + { WINPR_CIPHER_ARC4_128, "rc4" }, + { WINPR_CIPHER_AES_128_CCM, "aes-128-ccm" }, + { WINPR_CIPHER_AES_192_CCM, "aes-192-ccm" }, + { WINPR_CIPHER_AES_256_CCM, "aes-256-ccm" }, + { WINPR_CIPHER_CAMELLIA_128_CCM, "camellia-128-ccm" }, + { WINPR_CIPHER_CAMELLIA_192_CCM, "camellia-192-ccm" }, + { WINPR_CIPHER_CAMELLIA_256_CCM, "camellia-256-ccm" }, +}; + +static int cipher_compare(const void* a, const void* b) +{ + const WINPR_CIPHER_TYPE* cipher = a; + const struct cipher_map* map = b; + if (*cipher == map->md) + return 0; + return *cipher > map->md ? 1 : -1; +} + +const char* winpr_cipher_type_to_string(WINPR_CIPHER_TYPE cipher) +{ + WINPR_CIPHER_TYPE lc = cipher; + const struct cipher_map* ret = bsearch(&lc, s_cipher_map, ARRAYSIZE(s_cipher_map), + sizeof(struct cipher_map), cipher_compare); + if (!ret) + return "unknown"; + return ret->name; +} + +static int cipher_string_compare(const void* a, const void* b) +{ + const char* cipher = a; + const struct cipher_map* map = b; + return strcmp(cipher, map->name); +} + +WINPR_CIPHER_TYPE winpr_cipher_type_from_string(const char* name) +{ + const struct cipher_map* ret = bsearch(name, s_cipher_map, ARRAYSIZE(s_cipher_map), + sizeof(struct cipher_map), cipher_string_compare); + if (!ret) + return WINPR_CIPHER_NONE; + return ret->md; +} + #if defined(WITH_OPENSSL) -static const EVP_CIPHER* winpr_openssl_get_evp_cipher(int cipher) +static const EVP_CIPHER* winpr_openssl_get_evp_cipher(WINPR_CIPHER_TYPE cipher) { const EVP_CIPHER* evp = NULL; @@ -320,11 +412,11 @@ static const EVP_CIPHER* winpr_openssl_get_evp_cipher(int cipher) break; case WINPR_CIPHER_CAMELLIA_192_CCM: - evp = EVP_get_cipherbyname("camellia-192-gcm"); + evp = EVP_get_cipherbyname("camellia-192-ccm"); break; case WINPR_CIPHER_CAMELLIA_256_CCM: - evp = EVP_get_cipherbyname("camellia-256-gcm"); + evp = EVP_get_cipherbyname("camellia-256-ccm"); break; case WINPR_CIPHER_DES_ECB: @@ -467,7 +559,8 @@ mbedtls_cipher_type_t winpr_mbedtls_get_cipher_type(int cipher) } #endif -WINPR_CIPHER_CTX* winpr_Cipher_New(int cipher, int op, const void* key, const void* iv) +WINPR_CIPHER_CTX* winpr_Cipher_New(WINPR_CIPHER_TYPE cipher, WINPR_CRYPTO_OPERATION op, + const void* key, const void* iv) { WINPR_CIPHER_CTX* ctx = NULL; #if defined(WITH_OPENSSL)