summaryrefslogtreecommitdiff
path: root/libs/libssh2/src
diff options
context:
space:
mode:
authorGeorge Hazan <george.hazan@gmail.com>2024-01-31 19:13:48 +0300
committerGeorge Hazan <george.hazan@gmail.com>2024-01-31 19:13:48 +0300
commita5b576429205ffa3c9397614ea31363b31944e79 (patch)
treef5b92958748d66556f0f6af0b313ce42d8ad8903 /libs/libssh2/src
parent4ce9ed24b5fabd39d82aaf81147377f3906dec3b (diff)
libssh2: update to 1.11
Diffstat (limited to 'libs/libssh2/src')
-rw-r--r--libs/libssh2/src/CMakeLists.txt121
-rw-r--r--libs/libssh2/src/Makefile.am3
-rw-r--r--libs/libssh2/src/Makefile.inc1
-rw-r--r--libs/libssh2/src/agent.c16
-rw-r--r--libs/libssh2/src/bcrypt_pbkdf.c29
-rw-r--r--libs/libssh2/src/channel.c81
-rw-r--r--libs/libssh2/src/channel.h6
-rw-r--r--libs/libssh2/src/comp.c2
-rw-r--r--libs/libssh2/src/comp.h6
-rw-r--r--libs/libssh2/src/crypto.h94
-rw-r--r--libs/libssh2/src/crypto_config.h76
-rw-r--r--libs/libssh2/src/hostkey.c96
-rw-r--r--libs/libssh2/src/keepalive.c2
-rw-r--r--libs/libssh2/src/kex.c470
-rw-r--r--libs/libssh2/src/knownhost.c20
-rw-r--r--libs/libssh2/src/libgcrypt.c107
-rw-r--r--libs/libssh2/src/libgcrypt.h84
-rw-r--r--libs/libssh2/src/libssh2.rc6
-rw-r--r--libs/libssh2/src/libssh2_priv.h97
-rw-r--r--libs/libssh2/src/libssh2_setup.h10
-rw-r--r--libs/libssh2/src/mac.c136
-rw-r--r--libs/libssh2/src/mac.h6
-rw-r--r--libs/libssh2/src/misc.c68
-rw-r--r--libs/libssh2/src/misc.h15
-rw-r--r--libs/libssh2/src/openssl.c1400
-rw-r--r--libs/libssh2/src/openssl.h187
-rw-r--r--libs/libssh2/src/packet.c252
-rw-r--r--libs/libssh2/src/packet.h8
-rw-r--r--libs/libssh2/src/pem.c67
-rw-r--r--libs/libssh2/src/publickey.c4
-rw-r--r--libs/libssh2/src/scp.c4
-rw-r--r--libs/libssh2/src/session.c142
-rw-r--r--libs/libssh2/src/session.h6
-rw-r--r--libs/libssh2/src/sftp.c51
-rw-r--r--libs/libssh2/src/sftp.h6
-rw-r--r--libs/libssh2/src/transport.c67
-rw-r--r--libs/libssh2/src/transport.h6
-rw-r--r--libs/libssh2/src/userauth.c27
-rw-r--r--libs/libssh2/src/userauth.h6
-rw-r--r--libs/libssh2/src/userauth_kbd_packet.h6
40 files changed, 2682 insertions, 1109 deletions
diff --git a/libs/libssh2/src/CMakeLists.txt b/libs/libssh2/src/CMakeLists.txt
index 3a2077d06b..bca1b23d5b 100644
--- a/libs/libssh2/src/CMakeLists.txt
+++ b/libs/libssh2/src/CMakeLists.txt
@@ -36,9 +36,13 @@
#
# SPDX-License-Identifier: BSD-3-Clause
+set(LIBSSH2_SOVERSION 1)
+set(LIBSSH2_LIBVERSION 1.0.1)
+
if(CRYPTO_BACKEND)
list(APPEND PRIVATE_COMPILE_DEFINITIONS ${CRYPTO_BACKEND_DEFINE})
list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CRYPTO_BACKEND_INCLUDE_DIR})
+ add_feature_info("Crypto backend" ON "${CRYPTO_BACKEND}")
else()
message(FATAL_ERROR "No suitable cryptography backend found.")
endif()
@@ -47,10 +51,10 @@ endif()
option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON)
if(NOT CLEAR_MEMORY)
- list(APPEND libssh2_DEFINITIONS LIBSSH2_NO_CLEAR_MEMORY)
+ list(APPEND libssh2_DEFINITIONS "LIBSSH2_NO_CLEAR_MEMORY")
endif()
-option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression")
+option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression" OFF)
add_feature_info(Compression ENABLE_ZLIB_COMPRESSION
"using zlib for compression")
if(ENABLE_ZLIB_COMPRESSION)
@@ -58,16 +62,17 @@ if(ENABLE_ZLIB_COMPRESSION)
list(APPEND libssh2_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
list(APPEND LIBRARIES ${ZLIB_LIBRARIES})
- list(APPEND PC_REQUIRES_PRIVATE zlib)
+ list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lz")
+ list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "zlib")
if(ZLIB_FOUND)
- list(APPEND libssh2_DEFINITIONS LIBSSH2_HAVE_ZLIB)
+ list(APPEND libssh2_DEFINITIONS "LIBSSH2_HAVE_ZLIB")
endif()
endif()
list(APPEND LIBRARIES ${SOCKET_LIBRARIES})
if(WIN32)
- list(APPEND PC_LIBS -lws2_32)
+ list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lws2_32")
endif()
# to find generated header
@@ -83,7 +88,7 @@ endif()
include(GNUInstallDirs)
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
# Get 'CSOURCES' and 'HHEADERS' variables
-include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake)
+include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
set(SOURCES ${CSOURCES} ${HHEADERS})
## Library definition
@@ -102,55 +107,62 @@ endif()
if(BUILD_STATIC_LIBS)
list(APPEND libssh2_export ${LIB_STATIC})
add_library(${LIB_STATIC} STATIC ${SOURCES})
+ add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
target_compile_definitions(${LIB_STATIC} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${libssh2_DEFINITIONS})
target_link_libraries(${LIB_STATIC} PRIVATE ${LIBRARIES})
- set_target_properties(${LIB_STATIC} PROPERTIES PREFIX "" OUTPUT_NAME "libssh2")
- set_target_properties(${LIB_STATIC} PROPERTIES SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
+ set_target_properties(${LIB_STATIC} PROPERTIES
+ PREFIX "" OUTPUT_NAME "libssh2" SOVERSION "${LIBSSH2_SOVERSION}" VERSION "${LIBSSH2_LIBVERSION}"
+ SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
target_include_directories(${LIB_STATIC}
PRIVATE "${PROJECT_SOURCE_DIR}/include/" ${libssh2_INCLUDE_DIRS} ${PRIVATE_INCLUDE_DIRECTORIES}
PUBLIC
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
- $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>)
+ "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
+ "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
endif()
if(BUILD_SHARED_LIBS)
list(APPEND libssh2_export ${LIB_SHARED})
add_library(${LIB_SHARED} SHARED ${SOURCES})
+ add_library(${PROJECT_NAME}::${LIB_SHARED} ALIAS ${LIB_SHARED})
if(WIN32)
- set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES libssh2.rc)
+ set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libssh2.rc")
endif()
target_compile_definitions(${LIB_SHARED} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${libssh2_DEFINITIONS} ${LIB_SHARED_DEFINITIONS})
target_compile_options(${LIB_SHARED} PRIVATE ${LIB_SHARED_C_FLAGS})
target_link_libraries(${LIB_SHARED} PRIVATE ${LIBRARIES})
- set_target_properties(${LIB_SHARED} PROPERTIES PREFIX "" IMPORT_PREFIX "" OUTPUT_NAME "libssh2")
- set_target_properties(${LIB_SHARED} PROPERTIES IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}")
- set_target_properties(${LIB_SHARED} PROPERTIES POSITION_INDEPENDENT_CODE ON)
+ set_target_properties(${LIB_SHARED} PROPERTIES
+ PREFIX "" OUTPUT_NAME "libssh2" SOVERSION "${LIBSSH2_SOVERSION}" VERSION "${LIBSSH2_LIBVERSION}"
+ IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
+ POSITION_INDEPENDENT_CODE ON)
target_include_directories(${LIB_SHARED}
PRIVATE "${PROJECT_SOURCE_DIR}/include/" ${libssh2_INCLUDE_DIRS} ${PRIVATE_INCLUDE_DIRECTORIES}
PUBLIC
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
- $<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>)
+ "$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
+ "$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
endif()
+add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED})
+add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})
+
## Installation
install(FILES
- ${PROJECT_SOURCE_DIR}/include/libssh2.h
- ${PROJECT_SOURCE_DIR}/include/libssh2_publickey.h
- ${PROJECT_SOURCE_DIR}/include/libssh2_sftp.h
+ "${PROJECT_SOURCE_DIR}/include/libssh2.h"
+ "${PROJECT_SOURCE_DIR}/include/libssh2_publickey.h"
+ "${PROJECT_SOURCE_DIR}/include/libssh2_sftp.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(BUILD_STATIC_LIBS)
install(TARGETS ${LIB_STATIC}
- EXPORT Libssh2Config
+ EXPORT "${PROJECT_NAME}-targets"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
if(BUILD_SHARED_LIBS)
install(TARGETS ${LIB_SHARED}
- EXPORT Libssh2Config
+ EXPORT "${PROJECT_NAME}-targets"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
@@ -163,55 +175,54 @@ set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL
# Package config
-## During package installation, install Libssh2Config.cmake
-install(EXPORT Libssh2Config
- NAMESPACE Libssh2::
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libssh2)
+## During package installation, install libssh2-targets.cmake
+install(EXPORT "${PROJECT_NAME}-targets"
+ NAMESPACE "${PROJECT_NAME}::"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
## During build, register directly from build tree
-# create Libssh2Config.cmake
-export(TARGETS ${libssh2_export} NAMESPACE Libssh2:: FILE Libssh2Config.cmake)
-export(PACKAGE Libssh2) # register it
+# create libssh2-targets.cmake
+export(TARGETS ${libssh2_export} NAMESPACE "${PROJECT_NAME}::" FILE "${PROJECT_NAME}-targets.cmake")
+export(PACKAGE ${PROJECT_NAME}) # register it
+
+# Generate libssh2-config.cmake into build tree and install it
+configure_file("${PROJECT_SOURCE_DIR}/cmake/libssh2-config.cmake.in" "${PROJECT_NAME}-config.cmake" @ONLY)
+install(
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
## Export a .pc file for client projects not using CMaek
-if(PC_REQUIRES_PRIVATE)
- string(REPLACE ";" "," PC_REQUIRES_PRIVATE "${PC_REQUIRES_PRIVATE}")
+if(LIBSSH2_PC_REQUIRES_PRIVATE)
+ string(REPLACE ";" "," LIBSSH2_PC_REQUIRES_PRIVATE "${LIBSSH2_PC_REQUIRES_PRIVATE}")
+endif()
+if(LIBSSH2_PC_LIBS_PRIVATE)
+ list(REMOVE_DUPLICATES LIBSSH2_PC_LIBS_PRIVATE)
+ string(REPLACE ";" " " LIBSSH2_PC_LIBS_PRIVATE "${LIBSSH2_PC_LIBS_PRIVATE}")
endif()
-if(PC_LIBS)
- string(REPLACE ";" " " PC_LIBS "${PC_LIBS}")
+# merge the pkg-config private fields into public ones when static-only
+if(BUILD_SHARED_LIBS)
+ set(LIBSSH2_PC_REQUIRES "")
+ set(LIBSSH2_PC_LIBS "")
+else()
+ set(LIBSSH2_PC_REQUIRES "${LIBSSH2_PC_REQUIRES_PRIVATE}")
+ set(LIBSSH2_PC_LIBS "${LIBSSH2_PC_LIBS_PRIVATE}")
endif()
-set(LIBSSH2VER ${LIBSSH2_VERSION})
-set(LIBSREQUIRED ${PC_REQUIRES_PRIVATE})
-set(LIBS ${PC_LIBS})
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
set(libdir "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
-configure_file(${CMAKE_SOURCE_DIR}/libssh2.pc.in libssh2.pc @ONLY)
+configure_file("${PROJECT_SOURCE_DIR}/libssh2.pc.in" "libssh2.pc" @ONLY)
install(
- FILES ${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
-## Versioning
-
-set(LIBSSH2_SOVERSION 1)
-set(LIBSSH2_VERSION 1.0.1)
-if(BUILD_STATIC_LIBS)
- set_target_properties(${LIB_STATIC} PROPERTIES
- SOVERSION ${LIBSSH2_SOVERSION}
- VERSION ${LIBSSH2_VERSION})
-endif()
-if(BUILD_SHARED_LIBS)
- set_target_properties(${LIB_SHARED} PROPERTIES
- SOVERSION ${LIBSSH2_SOVERSION}
- VERSION ${LIBSSH2_VERSION})
-endif()
+#
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
- ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake
+ "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}"
COMPATIBILITY SameMajorVersion)
install(
- FILES ${CMAKE_CURRENT_BINARY_DIR}/Libssh2ConfigVersion.cmake
- DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libssh2)
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
diff --git a/libs/libssh2/src/Makefile.am b/libs/libssh2/src/Makefile.am
index bd7b8de8ea..45b7a17275 100644
--- a/libs/libssh2/src/Makefile.am
+++ b/libs/libssh2/src/Makefile.am
@@ -19,6 +19,9 @@ lib_LTLIBRARIES = libssh2.la
# tree
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/include
+# This might hold -Werror
+CFLAGS += @LIBSSH2_CFLAG_EXTRAS@
+
VERSION=-version-info 1:1:0
# This flag accepts an argument of the form current[:revision[:age]]. So,
diff --git a/libs/libssh2/src/Makefile.inc b/libs/libssh2/src/Makefile.inc
index a1876daceb..9133819a62 100644
--- a/libs/libssh2/src/Makefile.inc
+++ b/libs/libssh2/src/Makefile.inc
@@ -29,6 +29,7 @@ HHEADERS = \
channel.h \
comp.h \
crypto.h \
+ crypto_config.h \
libgcrypt.h \
libssh2_priv.h \
libssh2_setup.h \
diff --git a/libs/libssh2/src/agent.c b/libs/libssh2/src/agent.c
index d99a319550..dd709eb1fc 100644
--- a/libs/libssh2/src/agent.c
+++ b/libs/libssh2/src/agent.c
@@ -53,13 +53,14 @@
#undef PF_UNIX
#endif
-#if defined(WIN32) && !defined(LIBSSH2_WINDOWS_UWP)
+#if defined(_WIN32) && !defined(LIBSSH2_WINDOWS_UWP)
#define HAVE_WIN32_AGENTS
#endif
#include "userauth.h"
#include "session.h"
+#if 0
/* Requests from client to agent for protocol 1 key operations */
#define SSH_AGENTC_REQUEST_RSA_IDENTITIES 1
#define SSH_AGENTC_RSA_CHALLENGE 3
@@ -67,10 +68,12 @@
#define SSH_AGENTC_REMOVE_RSA_IDENTITY 8
#define SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES 9
#define SSH_AGENTC_ADD_RSA_ID_CONSTRAINED 24
+#endif
/* Requests from client to agent for protocol 2 key operations */
#define SSH2_AGENTC_REQUEST_IDENTITIES 11
#define SSH2_AGENTC_SIGN_REQUEST 13
+#if 0
#define SSH2_AGENTC_ADD_IDENTITY 17
#define SSH2_AGENTC_REMOVE_IDENTITY 18
#define SSH2_AGENTC_REMOVE_ALL_IDENTITIES 19
@@ -91,13 +94,14 @@
#define SSH_AGENT_RSA_IDENTITIES_ANSWER 2
#define SSH_AGENT_RSA_RESPONSE 4
-/* Replies from agent to client for protocol 2 key operations */
-#define SSH2_AGENT_IDENTITIES_ANSWER 12
-#define SSH2_AGENT_SIGN_RESPONSE 14
-
/* Key constraint identifiers */
#define SSH_AGENT_CONSTRAIN_LIFETIME 1
#define SSH_AGENT_CONSTRAIN_CONFIRM 2
+#endif
+
+/* Replies from agent to client for protocol 2 key operations */
+#define SSH2_AGENT_IDENTITIES_ANSWER 12
+#define SSH2_AGENT_SIGN_RESPONSE 14
/* Signature request methods */
#define SSH_AGENT_RSA_SHA2_256 2
@@ -559,7 +563,7 @@ agent_sign(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
_libssh2_debug((session,
LIBSSH2_TRACE_KEX,
"Agent sign method %.*s",
- method_len, method_name));
+ (int)method_len, method_name));
rc = LIBSSH2_ERROR_ALGO_UNSUPPORTED;
goto error;
diff --git a/libs/libssh2/src/bcrypt_pbkdf.c b/libs/libssh2/src/bcrypt_pbkdf.c
index d088587873..414c5e4e36 100644
--- a/libs/libssh2/src/bcrypt_pbkdf.c
+++ b/libs/libssh2/src/bcrypt_pbkdf.c
@@ -127,9 +127,12 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
memcpy(countsalt, salt, saltlen);
/* collapse password */
- (void)libssh2_sha512_init(&ctx);
- libssh2_sha512_update(ctx, pass, passlen);
- libssh2_sha512_final(ctx, sha2pass);
+ if(!libssh2_sha512_init(&ctx) ||
+ !libssh2_sha512_update(ctx, pass, passlen) ||
+ !libssh2_sha512_final(ctx, sha2pass)) {
+ free(countsalt);
+ return -1;
+ }
/* generate key, sizeof(out) at a time */
for(count = 1; keylen > 0; count++) {
@@ -139,18 +142,26 @@ bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
countsalt[saltlen + 3] = count & 0xff;
/* first round, salt is salt */
- (void)libssh2_sha512_init(&ctx);
- libssh2_sha512_update(ctx, countsalt, saltlen + 4);
- libssh2_sha512_final(ctx, sha2salt);
+ if(!libssh2_sha512_init(&ctx) ||
+ !libssh2_sha512_update(ctx, countsalt, saltlen + 4) ||
+ !libssh2_sha512_final(ctx, sha2salt)) {
+ _libssh2_explicit_zero(out, sizeof(out));
+ free(countsalt);
+ return -1;
+ }
bcrypt_hash(sha2pass, sha2salt, tmpout);
memcpy(out, tmpout, sizeof(out));
for(i = 1; i < rounds; i++) {
/* subsequent rounds, salt is previous output */
- (void)libssh2_sha512_init(&ctx);
- libssh2_sha512_update(ctx, tmpout, sizeof(tmpout));
- libssh2_sha512_final(ctx, sha2salt);
+ if(!libssh2_sha512_init(&ctx) ||
+ !libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)) ||
+ !libssh2_sha512_final(ctx, sha2salt)) {
+ _libssh2_explicit_zero(out, sizeof(out));
+ free(countsalt);
+ return -1;
+ }
bcrypt_hash(sha2pass, sha2salt, tmpout);
for(j = 0; j < sizeof(out); j++)
diff --git a/libs/libssh2/src/channel.c b/libs/libssh2/src/channel.c
index c35658a04e..2f7d162c72 100644
--- a/libs/libssh2/src/channel.c
+++ b/libs/libssh2/src/channel.c
@@ -84,7 +84,7 @@ _libssh2_channel_nextid(LIBSSH2_SESSION * session)
*/
session->next_channel = id + 1;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Allocated new channel ID#%lu", id));
+ "Allocated new channel ID#%u", id));
return id;
}
@@ -265,8 +265,8 @@ _libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
session->open_channel->local.packet_size =
_libssh2_ntohu32(session->open_data + 13);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Connection Established - ID: %lu/%lu win: %lu/%lu"
- " pack: %lu/%lu",
+ "Connection Established - ID: %u/%u win: %u/%u"
+ " pack: %u/%u",
session->open_channel->local.id,
session->open_channel->remote.id,
session->open_channel->local.window_size,
@@ -902,7 +902,7 @@ static int channel_setenv(LIBSSH2_CHANNEL *channel,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Setting remote environment variable: %s=%s on "
- "channel %lu/%lu",
+ "channel %u/%u",
varname, value, channel->local.id, channel->remote.id));
s = channel->setenv_packet =
@@ -1036,7 +1036,7 @@ static int channel_request_pty(LIBSSH2_CHANNEL *channel,
sizeof(channel->reqPTY_packet_requirev_state));
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Allocating tty on channel %lu/%lu", channel->local.id,
+ "Allocating tty on channel %u/%u", channel->local.id,
channel->remote.id));
s = channel->reqPTY_packet;
@@ -1139,7 +1139,7 @@ static int channel_request_auth_agent(LIBSSH2_CHANNEL *channel,
sizeof(channel->req_auth_agent_requirev_state));
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Requesting auth agent on channel %lu/%lu",
+ "Requesting auth agent on channel %u/%u",
channel->local.id, channel->remote.id));
/*
@@ -1303,7 +1303,7 @@ channel_request_pty_size(LIBSSH2_CHANNEL * channel, int width,
sizeof(channel->reqPTY_packet_requirev_state));
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "changing tty size on channel %lu/%lu",
+ "changing tty size on channel %u/%u",
channel->local.id,
channel->remote.id));
@@ -1392,7 +1392,7 @@ channel_x11_req(LIBSSH2_CHANNEL *channel, int single_connection,
sizeof(channel->reqX11_packet_requirev_state));
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Requesting x11-req for channel %lu/%lu: single=%d "
+ "Requesting x11-req for channel %u/%u: single=%d "
"proto=%s cookie=%s screen=%d",
channel->local.id, channel->remote.id,
single_connection,
@@ -1550,7 +1550,7 @@ _libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
channel->process_packet_len += + 4;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "starting request(%s) on channel %lu/%lu, message=%s",
+ "starting request(%s) on channel %u/%u, message=%s",
request, channel->local.id, channel->remote.id,
message ? message : "<null>"));
s = channel->process_packet =
@@ -1719,9 +1719,9 @@ _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid)
packet->data_head;
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
- "Flushing %d bytes of data from stream "
- "%lu on channel %lu/%lu",
- bytes_to_flush, packet_stream_id,
+ "Flushing %ld bytes of data from stream "
+ "%d on channel %u/%u",
+ (long)bytes_to_flush, packet_stream_id,
channel->local.id, channel->remote.id));
/* It's one of the streams we wanted to flush */
@@ -1882,8 +1882,8 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
&& (adjustment + channel->adjust_queue <
LIBSSH2_CHANNEL_MINADJUST)) {
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
- "Queueing %lu bytes for receive window adjustment "
- "for channel %lu/%lu",
+ "Queueing %u bytes for receive window adjustment "
+ "for channel %u/%u",
adjustment, channel->local.id, channel->remote.id));
channel->adjust_queue += adjustment;
return 0;
@@ -1901,8 +1901,8 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
_libssh2_htonu32(&channel->adjust_adjust[1], channel->remote.id);
_libssh2_htonu32(&channel->adjust_adjust[5], adjustment);
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
- "Adjusting window %lu bytes for data on "
- "channel %lu/%lu",
+ "Adjusting window %u bytes for data on "
+ "channel %u/%u",
adjustment, channel->local.id, channel->remote.id));
channel->adjust_state = libssh2_NB_state_created;
@@ -1930,10 +1930,9 @@ _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
return 0;
}
+#ifndef LIBSSH2_NO_DEPRECATED
/*
- * libssh2_channel_receive_window_adjust
- *
- * DEPRECATED
+ * libssh2_channel_receive_window_adjust (DEPRECATED, DO NOT USE!)
*
* Adjust the receive window for a channel by adjustment bytes. If the amount
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
@@ -1963,6 +1962,7 @@ libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL *channel,
kept for backwards compatibility */
return rc ? (unsigned long)rc : window;
}
+#endif
/*
* libssh2_channel_receive_window_adjust2
@@ -1998,7 +1998,7 @@ _libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode)
{
if(channel->extData2_state == libssh2_NB_state_idle) {
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
- "Setting channel %lu/%lu handle_extended_data"
+ "Setting channel %u/%u handle_extended_data"
" mode to %d",
channel->local.id, channel->remote.id, ignore_mode));
channel->remote.extended_data_ignore_mode = (char)ignore_mode;
@@ -2038,10 +2038,9 @@ libssh2_channel_handle_extended_data2(LIBSSH2_CHANNEL *channel,
return rc;
}
+#ifndef LIBSSH2_NO_DEPRECATED
/*
- * libssh2_channel_handle_extended_data
- *
- * DEPRECATED DO NOTE USE!
+ * libssh2_channel_handle_extended_data (DEPRECATED, DO NOT USE!)
*
* How should extended data look to the calling app? Keep it in separate
* channels[_read() _read_stdder()]? (NORMAL) Merge the extended data to the
@@ -2054,7 +2053,7 @@ libssh2_channel_handle_extended_data(LIBSSH2_CHANNEL *channel,
{
(void)libssh2_channel_handle_extended_data2(channel, ignore_mode);
}
-
+#endif
/*
@@ -2081,9 +2080,9 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
LIBSSH2_PACKET *read_next;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "channel_read() wants %d bytes from channel %lu/%lu "
+ "channel_read() wants %ld bytes from channel %u/%u "
"stream #%d",
- (int) buflen, channel->local.id, channel->remote.id,
+ (long)buflen, channel->local.id, channel->remote.id,
stream_id));
/* expand the receiving window first if it has become too narrow */
@@ -2178,8 +2177,8 @@ ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
}
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "channel_read() got %d of data from %lu/%lu/%d%s",
- bytes_want, channel->local.id,
+ "channel_read() got %ld of data from %u/%u/%d%s",
+ (long)bytes_want, channel->local.id,
channel->remote.id, stream_id,
unlink_packet?" [ul]":""));
@@ -2356,8 +2355,8 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
unsigned char *s = channel->write_packet;
_libssh2_debug((channel->session, LIBSSH2_TRACE_CONN,
- "Writing %d bytes on channel %lu/%lu, stream #%d",
- (int) buflen, channel->local.id, channel->remote.id,
+ "Writing %ld bytes on channel %u/%u, stream #%d",
+ (long)buflen, channel->local.id, channel->remote.id,
stream_id));
if(channel->local.close)
@@ -2405,16 +2404,16 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
/* REMEMBER local means local as the SOURCE of the data */
if(channel->write_bufwrite > channel->local.window_size) {
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Splitting write block due to %lu byte "
- "window_size on %lu/%lu/%d",
+ "Splitting write block due to %u byte "
+ "window_size on %u/%u/%d",
channel->local.window_size, channel->local.id,
channel->remote.id, stream_id));
channel->write_bufwrite = channel->local.window_size;
}
if(channel->write_bufwrite > channel->local.packet_size) {
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Splitting write block due to %lu byte "
- "packet_size on %lu/%lu/%d",
+ "Splitting write block due to %u byte "
+ "packet_size on %u/%u/%d",
channel->local.packet_size, channel->local.id,
channel->remote.id, stream_id));
channel->write_bufwrite = channel->local.packet_size;
@@ -2425,8 +2424,8 @@ _libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
channel->write_packet_len = s - channel->write_packet;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Sending %d bytes on channel %lu/%lu, stream_id=%d",
- (int) channel->write_bufwrite, channel->local.id,
+ "Sending %ld bytes on channel %u/%u, stream_id=%d",
+ (long)channel->write_bufwrite, channel->local.id,
channel->remote.id, stream_id));
channel->write_state = libssh2_NB_state_created;
@@ -2500,7 +2499,7 @@ static int channel_send_eof(LIBSSH2_CHANNEL *channel)
int rc;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Sending EOF on channel %lu/%lu",
+ "Sending EOF on channel %u/%u",
channel->local.id, channel->remote.id));
packet[0] = SSH_MSG_CHANNEL_EOF;
_libssh2_htonu32(packet + 1, channel->remote.id);
@@ -2590,7 +2589,7 @@ static int channel_wait_eof(LIBSSH2_CHANNEL *channel)
if(channel->wait_eof_state == libssh2_NB_state_idle) {
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Awaiting EOF for channel %lu/%lu", channel->local.id,
+ "Awaiting EOF for channel %u/%u", channel->local.id,
channel->remote.id));
channel->wait_eof_state = libssh2_NB_state_created;
@@ -2671,7 +2670,7 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel)
late for us to wait for it. Continue closing! */
if(channel->close_state == libssh2_NB_state_idle) {
- _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Closing channel %lu/%lu",
+ _libssh2_debug((session, LIBSSH2_TRACE_CONN, "Closing channel %u/%u",
channel->local.id, channel->remote.id));
channel->close_packet[0] = SSH_MSG_CHANNEL_CLOSE;
@@ -2762,7 +2761,7 @@ static int channel_wait_closed(LIBSSH2_CHANNEL *channel)
if(channel->wait_closed_state == libssh2_NB_state_idle) {
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Awaiting close of channel %lu/%lu", channel->local.id,
+ "Awaiting close of channel %u/%u", channel->local.id,
channel->remote.id));
channel->wait_closed_state = libssh2_NB_state_created;
@@ -2825,7 +2824,7 @@ int _libssh2_channel_free(LIBSSH2_CHANNEL *channel)
if(channel->free_state == libssh2_NB_state_idle) {
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Freeing channel %lu/%lu resources", channel->local.id,
+ "Freeing channel %u/%u resources", channel->local.id,
channel->remote.id));
channel->free_state = libssh2_NB_state_created;
diff --git a/libs/libssh2/src/channel.h b/libs/libssh2/src/channel.h
index 6d03550164..709ec0615f 100644
--- a/libs/libssh2/src/channel.h
+++ b/libs/libssh2/src/channel.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_CHANNEL_H
-#define __LIBSSH2_CHANNEL_H
+#ifndef LIBSSH2_CHANNEL_H
+#define LIBSSH2_CHANNEL_H
/* Copyright (C) Daniel Stenberg
*
* All rights reserved.
@@ -139,4 +139,4 @@ int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
*/
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
-#endif /* __LIBSSH2_CHANNEL_H */
+#endif /* LIBSSH2_CHANNEL_H */
diff --git a/libs/libssh2/src/comp.c b/libs/libssh2/src/comp.c
index 55ddb85a48..ecfb28a315 100644
--- a/libs/libssh2/src/comp.c
+++ b/libs/libssh2/src/comp.c
@@ -208,7 +208,7 @@ comp_method_zlib_comp(LIBSSH2_SESSION *session,
}
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
- "unhandled zlib compression error %d, avail_out",
+ "unhandled zlib compression error %d, avail_out %u",
status, strm->avail_out));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
}
diff --git a/libs/libssh2/src/comp.h b/libs/libssh2/src/comp.h
index cce113b2bc..6a35d69494 100644
--- a/libs/libssh2/src/comp.h
+++ b/libs/libssh2/src/comp.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_COMP_H
-#define __LIBSSH2_COMP_H
+#ifndef LIBSSH2_COMP_H
+#define LIBSSH2_COMP_H
/* Copyright (C) Daniel Stenberg
*
* Redistribution and use in source and binary forms,
@@ -42,4 +42,4 @@
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session);
-#endif /* __LIBSSH2_COMP_H */
+#endif /* LIBSSH2_COMP_H */
diff --git a/libs/libssh2/src/crypto.h b/libs/libssh2/src/crypto.h
index 561cd96e2b..487444145d 100644
--- a/libs/libssh2/src/crypto.h
+++ b/libs/libssh2/src/crypto.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_CRYPTO_H
-#define __LIBSSH2_CRYPTO_H
+#ifndef LIBSSH2_CRYPTO_H
+#define LIBSSH2_CRYPTO_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
@@ -55,70 +55,26 @@
#error "no cryptography backend selected"
#endif
-#ifdef LIBSSH2_NO_MD5
-#undef LIBSSH2_MD5
-#define LIBSSH2_MD5 0
+/* return: success = 1, error = 0 */
+int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx);
+#if LIBSSH2_MD5
+int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen);
#endif
-
-#ifdef LIBSSH2_NO_HMAC_RIPEMD
-#undef LIBSSH2_HMAC_RIPEMD
-#define LIBSSH2_HMAC_RIPEMD 0
-#endif
-
-#ifdef LIBSSH2_NO_DSA
-#undef LIBSSH2_DSA
-#define LIBSSH2_DSA 0
-#endif
-
-#ifdef LIBSSH2_NO_RSA
-#undef LIBSSH2_RSA
-#define LIBSSH2_RSA 0
-#endif
-
-#ifdef LIBSSH2_NO_RSA_SHA1
-#undef LIBSSH2_RSA_SHA1
-#define LIBSSH2_RSA_SHA1 0
-#endif
-
-#ifdef LIBSSH2_NO_ECDSA
-#undef LIBSSH2_ECDSA
-#define LIBSSH2_ECDSA 0
-#endif
-
-#ifdef LIBSSH2_NO_ED25519
-#undef LIBSSH2_ED25519
-#define LIBSSH2_ED25519 0
-#endif
-
-#ifdef LIBSSH2_NO_AES_CTR
-#undef LIBSSH2_AES_CTR
-#define LIBSSH2_AES_CTR 0
-#endif
-
-#ifdef LIBSSH2_NO_AES_CBC
-#undef LIBSSH2_AES_CBC
-#define LIBSSH2_AES_CBC 0
-#endif
-
-#ifdef LIBSSH2_NO_BLOWFISH
-#undef LIBSSH2_BLOWFISH
-#define LIBSSH2_BLOWFISH 0
-#endif
-
-#ifdef LIBSSH2_NO_RC4
-#undef LIBSSH2_RC4
-#define LIBSSH2_RC4 0
-#endif
-
-#ifdef LIBSSH2_NO_CAST
-#undef LIBSSH2_CAST
-#define LIBSSH2_CAST 0
-#endif
-
-#ifdef LIBSSH2_NO_3DES
-#undef LIBSSH2_3DES
-#define LIBSSH2_3DES 0
+#if LIBSSH2_HMAC_RIPEMD
+int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen);
#endif
+int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen);
+int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen);
+int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen);
+int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
+ const void *data, size_t datalen);
+int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data);
+void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx);
#define LIBSSH2_ED25519_KEY_LEN 32
#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64
@@ -146,16 +102,16 @@ int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
const char *filename,
unsigned const char *passphrase);
#if LIBSSH2_RSA_SHA1
-int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
- const unsigned char *sig,
- size_t sig_len,
- const unsigned char *m, size_t m_len);
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
+int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
+ const unsigned char *sig,
+ size_t sig_len,
+ const unsigned char *m, size_t m_len);
#endif
#if LIBSSH2_RSA_SHA2
int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
@@ -398,4 +354,4 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len);
-#endif /* __LIBSSH2_CRYPTO_H */
+#endif /* LIBSSH2_CRYPTO_H */
diff --git a/libs/libssh2/src/crypto_config.h b/libs/libssh2/src/crypto_config.h
new file mode 100644
index 0000000000..5934e140b6
--- /dev/null
+++ b/libs/libssh2/src/crypto_config.h
@@ -0,0 +1,76 @@
+/* Copyright (C) Viktor Szakats
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define LIBSSH2_MD5_PEM LIBSSH2_MD5
+
+#ifdef LIBSSH2_NO_MD5
+#undef LIBSSH2_MD5
+#define LIBSSH2_MD5 0
+#endif
+
+#ifdef LIBSSH2_NO_MD5_PEM
+#undef LIBSSH2_MD5_PEM
+#define LIBSSH2_MD5_PEM 0
+#endif
+
+#ifdef LIBSSH2_NO_HMAC_RIPEMD
+#undef LIBSSH2_HMAC_RIPEMD
+#define LIBSSH2_HMAC_RIPEMD 0
+#endif
+
+#ifdef LIBSSH2_NO_DSA
+#undef LIBSSH2_DSA
+#define LIBSSH2_DSA 0
+#endif
+
+#ifdef LIBSSH2_NO_RSA
+#undef LIBSSH2_RSA
+#define LIBSSH2_RSA 0
+#endif
+
+#ifdef LIBSSH2_NO_RSA_SHA1
+#undef LIBSSH2_RSA_SHA1
+#define LIBSSH2_RSA_SHA1 0
+#endif
+
+#ifdef LIBSSH2_NO_ECDSA
+#undef LIBSSH2_ECDSA
+#define LIBSSH2_ECDSA 0
+#endif
+
+#ifdef LIBSSH2_NO_ED25519
+#undef LIBSSH2_ED25519
+#define LIBSSH2_ED25519 0
+#endif
+
+#ifdef LIBSSH2_NO_AES_CTR
+#undef LIBSSH2_AES_CTR
+#define LIBSSH2_AES_CTR 0
+#endif
+
+#ifdef LIBSSH2_NO_AES_CBC
+#undef LIBSSH2_AES_CBC
+#define LIBSSH2_AES_CBC 0
+#endif
+
+#ifdef LIBSSH2_NO_BLOWFISH
+#undef LIBSSH2_BLOWFISH
+#define LIBSSH2_BLOWFISH 0
+#endif
+
+#ifdef LIBSSH2_NO_RC4
+#undef LIBSSH2_RC4
+#define LIBSSH2_RC4 0
+#endif
+
+#ifdef LIBSSH2_NO_CAST
+#undef LIBSSH2_CAST
+#define LIBSSH2_CAST 0
+#endif
+
+#ifdef LIBSSH2_NO_3DES
+#undef LIBSSH2_3DES
+#define LIBSSH2_3DES 0
+#endif
diff --git a/libs/libssh2/src/hostkey.c b/libs/libssh2/src/hostkey.c
index 56eee369f5..b28b4e6995 100644
--- a/libs/libssh2/src/hostkey.c
+++ b/libs/libssh2/src/hostkey.c
@@ -106,7 +106,7 @@ hostkey_method_ssh_rsa_init(LIBSSH2_SESSION * session,
#endif
{
_libssh2_debug((session, LIBSSH2_TRACE_ERROR,
- "unexpected rsa type: %.*s", type_len, type));
+ "unexpected rsa type: %.*s", (int)type_len, type));
return -1;
}
@@ -242,11 +242,18 @@ hostkey_method_ssh_rsa_signv(LIBSSH2_SESSION * session,
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_sha1_ctx ctx;
- (void)libssh2_sha1_init(&ctx);
+ if(!libssh2_sha1_init(&ctx)) {
+ return -1;
+ }
for(i = 0; i < veccount; i++) {
- libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
+ if(!libssh2_sha1_update(ctx,
+ datavec[i].iov_base, datavec[i].iov_len)) {
+ return -1;
+ }
+ }
+ if(!libssh2_sha1_final(ctx, hash)) {
+ return -1;
}
- libssh2_sha1_final(ctx, hash);
ret = _libssh2_rsa_sha1_sign(session, rsactx, hash, SHA_DIGEST_LENGTH,
signature, signature_len);
@@ -316,9 +323,14 @@ hostkey_method_ssh_rsa_sha2_256_signv(LIBSSH2_SESSION * session,
return -1;
}
for(i = 0; i < veccount; i++) {
- libssh2_sha256_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
+ if(!libssh2_sha256_update(ctx,
+ datavec[i].iov_base, datavec[i].iov_len)) {
+ return -1;
+ }
+ }
+ if(!libssh2_sha256_final(ctx, hash)) {
+ return -1;
}
- libssh2_sha256_final(ctx, hash);
ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA256_DIGEST_LENGTH,
signature, signature_len);
@@ -386,9 +398,14 @@ hostkey_method_ssh_rsa_sha2_512_signv(LIBSSH2_SESSION * session,
return -1;
}
for(i = 0; i < veccount; i++) {
- libssh2_sha512_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
+ if(!libssh2_sha512_update(ctx,
+ datavec[i].iov_base, datavec[i].iov_len)) {
+ return -1;
+ }
+ }
+ if(!libssh2_sha512_final(ctx, hash)) {
+ return -1;
}
- libssh2_sha512_final(ctx, hash);
ret = _libssh2_rsa_sha2_sign(session, rsactx, hash, SHA512_DIGEST_LENGTH,
signature, signature_len);
@@ -659,6 +676,12 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
libssh2_sha1_ctx ctx;
int i;
+ if(!libssh2_sha1_init(&ctx)) {
+ *signature = NULL;
+ *signature_len = 0;
+ return -1;
+ }
+
*signature = LIBSSH2_CALLOC(session, 2 * SHA_DIGEST_LENGTH);
if(!*signature) {
return -1;
@@ -666,11 +689,15 @@ hostkey_method_ssh_dss_signv(LIBSSH2_SESSION * session,
*signature_len = 2 * SHA_DIGEST_LENGTH;
- (void)libssh2_sha1_init(&ctx);
for(i = 0; i < veccount; i++) {
- libssh2_sha1_update(ctx, datavec[i].iov_base, datavec[i].iov_len);
+ if(!libssh2_sha1_update(ctx,
+ datavec[i].iov_base, datavec[i].iov_len)) {
+ return -1;
+ }
+ }
+ if(!libssh2_sha1_final(ctx, hash)) {
+ return -1;
}
- libssh2_sha1_final(ctx, hash);
if(_libssh2_dsa_sha1_sign(dsactx, hash, SHA_DIGEST_LENGTH, *signature)) {
LIBSSH2_FREE(session, *signature);
@@ -909,20 +936,33 @@ hostkey_method_ssh_ecdsa_sig_verify(LIBSSH2_SESSION * session,
}
-#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \
- do { \
- unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
- libssh2_sha##digest_type##_ctx ctx; \
- int i; \
- (void)libssh2_sha##digest_type##_init(&ctx); \
- for(i = 0; i < veccount; i++) { \
- libssh2_sha##digest_type##_update(ctx, datavec[i].iov_base, \
- datavec[i].iov_len); \
- } \
- libssh2_sha##digest_type##_final(ctx, hash); \
- ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \
- SHA##digest_type##_DIGEST_LENGTH, \
- signature, signature_len); \
+#define LIBSSH2_HOSTKEY_METHOD_EC_SIGNV_HASH(digest_type) \
+ do { \
+ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
+ libssh2_sha##digest_type##_ctx ctx; \
+ int i; \
+ if(!libssh2_sha##digest_type##_init(&ctx)) { \
+ ret = -1; \
+ break; \
+ } \
+ for(i = 0; i < veccount; i++) { \
+ if(!libssh2_sha##digest_type##_update(ctx, \
+ datavec[i].iov_base, \
+ datavec[i].iov_len)) { \
+ ret = -1; \
+ break; \
+ } \
+ } \
+ if(ret == -1) { \
+ break; \
+ } \
+ if(!libssh2_sha##digest_type##_final(ctx, hash)) { \
+ ret = -1; \
+ break; \
+ } \
+ ret = _libssh2_ecdsa_sign(session, ec_ctx, hash, \
+ SHA##digest_type##_DIGEST_LENGTH, \
+ signature, signature_len); \
} while(0)
@@ -1224,7 +1264,8 @@ hostkey_method_ssh_ed25519_signv(LIBSSH2_SESSION * session,
}
return _libssh2_ed25519_sign(ctx, session, signature, signature_len,
- datavec[0].iov_base, datavec[0].iov_len);
+ (const uint8_t *)datavec[0].iov_base,
+ datavec[0].iov_len);
}
@@ -1326,18 +1367,15 @@ libssh2_hostkey_hash(LIBSSH2_SESSION * session, int hash_type)
return (session->server_hostkey_md5_valid)
? (char *) session->server_hostkey_md5
: NULL;
- break;
#endif /* LIBSSH2_MD5 */
case LIBSSH2_HOSTKEY_HASH_SHA1:
return (session->server_hostkey_sha1_valid)
? (char *) session->server_hostkey_sha1
: NULL;
- break;
case LIBSSH2_HOSTKEY_HASH_SHA256:
return (session->server_hostkey_sha256_valid)
? (char *) session->server_hostkey_sha256
: NULL;
- break;
default:
return NULL;
}
diff --git a/libs/libssh2/src/keepalive.c b/libs/libssh2/src/keepalive.c
index 54fddb060f..489a1daaa9 100644
--- a/libs/libssh2/src/keepalive.c
+++ b/libs/libssh2/src/keepalive.c
@@ -45,7 +45,7 @@
LIBSSH2_API void
libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply,
- unsigned interval)
+ unsigned int interval)
{
if(interval == 1)
session->keepalive_interval = 2;
diff --git a/libs/libssh2/src/kex.c b/libs/libssh2/src/kex.c
index 8972d44bb3..8c65a0fee6 100644
--- a/libs/libssh2/src/kex.c
+++ b/libs/libssh2/src/kex.c
@@ -55,6 +55,7 @@
/* Helper macro called from
kex_method_diffie_hellman_group1_sha1_key_exchange */
+#if LIBSSH2_ECDSA
#define LIBSSH2_KEX_METHOD_EC_SHA_VALUE_HASH(value, reqlen, version) \
do { \
if(type == LIBSSH2_EC_CURVE_NISTP256) { \
@@ -67,6 +68,7 @@
LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(512, value, reqlen, version); \
} \
} while(0)
+#endif
#define LIBSSH2_KEX_METHOD_SHA_VALUE_HASH(digest_type, value, \
reqlen, version) \
@@ -79,22 +81,40 @@ do { \
} \
if(value) \
while(len < (size_t)reqlen) { \
- (void)libssh2_sha##digest_type##_init(&hash); \
- libssh2_sha##digest_type##_update(hash, \
- exchange_state->k_value, \
- exchange_state->k_value_len); \
- libssh2_sha##digest_type##_update(hash, \
- exchange_state->h_sig_comp, \
- SHA##digest_type##_DIGEST_LENGTH); \
+ if(!libssh2_sha##digest_type##_init(&hash) || \
+ !libssh2_sha##digest_type##_update(hash, \
+ exchange_state->k_value, \
+ exchange_state->k_value_len) || \
+ !libssh2_sha##digest_type##_update(hash, \
+ exchange_state->h_sig_comp, \
+ SHA##digest_type##_DIGEST_LENGTH)) { \
+ LIBSSH2_FREE(session, value); \
+ value = NULL; \
+ break; \
+ } \
if(len > 0) { \
- libssh2_sha##digest_type##_update(hash, value, len); \
+ if(!libssh2_sha##digest_type##_update(hash, value, len)) { \
+ LIBSSH2_FREE(session, value); \
+ value = NULL; \
+ break; \
+ } \
} \
else { \
- libssh2_sha##digest_type##_update(hash, (version), 1); \
- libssh2_sha##digest_type##_update(hash, session->session_id,\
- session->session_id_len); \
+ if(!libssh2_sha##digest_type##_update(hash, \
+ (version), 1) || \
+ !libssh2_sha##digest_type##_update(hash, \
+ session->session_id, \
+ session->session_id_len)) { \
+ LIBSSH2_FREE(session, value); \
+ value = NULL; \
+ break; \
+ } \
+ } \
+ if(!libssh2_sha##digest_type##_final(hash, (value) + len)) { \
+ LIBSSH2_FREE(session, value); \
+ value = NULL; \
+ break; \
} \
- libssh2_sha##digest_type##_final(hash, (value) + len); \
len += SHA##digest_type##_DIGEST_LENGTH; \
} \
} while(0)
@@ -106,75 +126,80 @@ do { \
* don't allow it so we have to wrap them up in helper functions
*/
-static void _libssh2_sha_algo_ctx_init(int sha_algo, void *ctx)
+static int _libssh2_sha_algo_ctx_init(int sha_algo, void *ctx)
{
if(sha_algo == 512) {
- (void)libssh2_sha512_init((libssh2_sha512_ctx*)ctx);
+ return libssh2_sha512_init((libssh2_sha512_ctx*)ctx);
}
else if(sha_algo == 384) {
- (void)libssh2_sha384_init((libssh2_sha384_ctx*)ctx);
+ return libssh2_sha384_init((libssh2_sha384_ctx*)ctx);
}
else if(sha_algo == 256) {
- (void)libssh2_sha256_init((libssh2_sha256_ctx*)ctx);
+ return libssh2_sha256_init((libssh2_sha256_ctx*)ctx);
}
else if(sha_algo == 1) {
- (void)libssh2_sha1_init((libssh2_sha1_ctx*)ctx);
+ return libssh2_sha1_init((libssh2_sha1_ctx*)ctx);
}
else {
+#ifdef LIBSSH2DEBUG
assert(0);
+#endif
}
+ return 0;
}
-static void _libssh2_sha_algo_ctx_update(int sha_algo, void *ctx,
- void *data, size_t len)
+static int _libssh2_sha_algo_ctx_update(int sha_algo, void *ctx,
+ void *data, size_t len)
{
if(sha_algo == 512) {
libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx;
- libssh2_sha512_update(*_ctx, data, len);
+ return libssh2_sha512_update(*_ctx, data, len);
}
else if(sha_algo == 384) {
libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx;
- libssh2_sha384_update(*_ctx, data, len);
+ return libssh2_sha384_update(*_ctx, data, len);
}
else if(sha_algo == 256) {
libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx;
- libssh2_sha256_update(*_ctx, data, len);
+ return libssh2_sha256_update(*_ctx, data, len);
}
else if(sha_algo == 1) {
libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx;
- libssh2_sha1_update(*_ctx, data, len);
+ return libssh2_sha1_update(*_ctx, data, len);
}
else {
#ifdef LIBSSH2DEBUG
assert(0);
#endif
}
+ return 0;
}
-static void _libssh2_sha_algo_ctx_final(int sha_algo, void *ctx,
- void *hash)
+static int _libssh2_sha_algo_ctx_final(int sha_algo, void *ctx,
+ void *hash)
{
if(sha_algo == 512) {
libssh2_sha512_ctx *_ctx = (libssh2_sha512_ctx*)ctx;
- libssh2_sha512_final(*_ctx, hash);
+ return libssh2_sha512_final(*_ctx, hash);
}
else if(sha_algo == 384) {
libssh2_sha384_ctx *_ctx = (libssh2_sha384_ctx*)ctx;
- libssh2_sha384_final(*_ctx, hash);
+ return libssh2_sha384_final(*_ctx, hash);
}
else if(sha_algo == 256) {
libssh2_sha256_ctx *_ctx = (libssh2_sha256_ctx*)ctx;
- libssh2_sha256_final(*_ctx, hash);
+ return libssh2_sha256_final(*_ctx, hash);
}
else if(sha_algo == 1) {
libssh2_sha1_ctx *_ctx = (libssh2_sha1_ctx*)ctx;
- libssh2_sha1_final(*_ctx, hash);
+ return libssh2_sha1_final(*_ctx, hash);
}
else {
#ifdef LIBSSH2DEBUG
assert(0);
#endif
}
+ return 0;
}
static void _libssh2_sha_algo_value_hash(int sha_algo,
@@ -300,8 +325,8 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
exchange_state->e_packet + 6);
}
- _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sending KEX packet %d",
- (int) packet_type_init));
+ _libssh2_debug((session, LIBSSH2_TRACE_KEX, "Sending KEX packet %u",
+ (unsigned int) packet_type_init));
exchange_state->state = libssh2_NB_state_created;
}
@@ -355,6 +380,7 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
struct string_buf buf;
size_t host_key_len;
int err;
+ int hok;
rc = _libssh2_packet_require(session, packet_type_reply,
&exchange_state->s_packet,
@@ -397,11 +423,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
{
libssh2_md5_ctx fingerprint_ctx;
- if(libssh2_md5_init(&fingerprint_ctx)) {
- libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_md5_final(fingerprint_ctx,
- session->server_hostkey_md5);
+ if(libssh2_md5_init(&fingerprint_ctx) &&
+ libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_md5_final(fingerprint_ctx,
+ session->server_hostkey_md5)) {
session->server_hostkey_md5_valid = TRUE;
}
else {
@@ -425,11 +451,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
{
libssh2_sha1_ctx fingerprint_ctx;
- if(libssh2_sha1_init(&fingerprint_ctx)) {
- libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_sha1_final(fingerprint_ctx,
- session->server_hostkey_sha1);
+ if(libssh2_sha1_init(&fingerprint_ctx) &&
+ libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_sha1_final(fingerprint_ctx,
+ session->server_hostkey_sha1)) {
session->server_hostkey_sha1_valid = TRUE;
}
else {
@@ -452,11 +478,11 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
{
libssh2_sha256_ctx fingerprint_ctx;
- if(libssh2_sha256_init(&fingerprint_ctx)) {
- libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_sha256_final(fingerprint_ctx,
- session->server_hostkey_sha256);
+ if(libssh2_sha256_init(&fingerprint_ctx) &&
+ libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_sha256_final(fingerprint_ctx,
+ session->server_hostkey_sha256)) {
session->server_hostkey_sha256_valid = TRUE;
}
else {
@@ -532,59 +558,66 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
}
exchange_state->exchange_hash = (void *)&exchange_hash_ctx;
- _libssh2_sha_algo_ctx_init(sha_algo_value, exchange_hash_ctx);
-
+ if(!_libssh2_sha_algo_ctx_init(sha_algo_value, exchange_hash_ctx)) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_HASH_INIT,
+ "Unable to initialize hash context");
+ goto clean_exit;
+ }
+ hok = 1;
if(session->local.banner) {
_libssh2_htonu32(exchange_state->h_sig_comp,
(uint32_t)(strlen((char *) session->local.banner) - 2));
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- session->local.banner,
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value,
+ exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value,
+ exchange_hash_ctx,
+ session->local.banner,
strlen((char *) session->local.banner) - 2);
}
else {
_libssh2_htonu32(exchange_state->h_sig_comp,
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- (unsigned char *)
- LIBSSH2_SSH_DEFAULT_BANNER,
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value,
+ exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value,
+ exchange_hash_ctx,
+ (unsigned char *)LIBSSH2_SSH_DEFAULT_BANNER,
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
}
_libssh2_htonu32(exchange_state->h_sig_comp,
(uint32_t)strlen((char *) session->remote.banner));
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- session->remote.banner,
- strlen((char *) session->remote.banner));
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ session->remote.banner,
+ strlen((char *)session->remote.banner));
_libssh2_htonu32(exchange_state->h_sig_comp,
(uint32_t)session->local.kexinit_len);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- session->local.kexinit,
- session->local.kexinit_len);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ session->local.kexinit,
+ session->local.kexinit_len);
_libssh2_htonu32(exchange_state->h_sig_comp,
(uint32_t)session->remote.kexinit_len);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- session->remote.kexinit,
- session->remote.kexinit_len);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ session->remote.kexinit,
+ session->remote.kexinit_len);
_libssh2_htonu32(exchange_state->h_sig_comp,
session->server_hostkey_len);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- session->server_hostkey,
- session->server_hostkey_len);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ session->server_hostkey,
+ session->server_hostkey_len);
if(packet_type_init == SSH_MSG_KEX_DH_GEX_INIT) {
/* diffie-hellman-group-exchange hashes additional fields */
@@ -594,33 +627,41 @@ static int diffie_hellman_sha_algo(LIBSSH2_SESSION *session,
LIBSSH2_DH_GEX_OPTGROUP);
_libssh2_htonu32(exchange_state->h_sig_comp + 8,
LIBSSH2_DH_GEX_MAXGROUP);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 12);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value,
+ exchange_hash_ctx,
+ exchange_state->h_sig_comp,
+ 12);
}
if(midhash) {
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- midhash, midhash_len);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value,
+ exchange_hash_ctx,
+ midhash, midhash_len);
}
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->e_packet + 1,
- exchange_state->e_packet_len - 1);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->e_packet + 1,
+ exchange_state->e_packet_len - 1);
_libssh2_htonu32(exchange_state->h_sig_comp,
(uint32_t)exchange_state->f_value_len);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp, 4);
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->f_value,
- exchange_state->f_value_len);
-
- _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
- exchange_state->k_value,
- exchange_state->k_value_len);
-
- _libssh2_sha_algo_ctx_final(sha_algo_value, exchange_hash_ctx,
- exchange_state->h_sig_comp);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->h_sig_comp, 4);
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->f_value,
+ exchange_state->f_value_len);
+
+ hok &= _libssh2_sha_algo_ctx_update(sha_algo_value, exchange_hash_ctx,
+ exchange_state->k_value,
+ exchange_state->k_value_len);
+
+ if(!hok ||
+ !_libssh2_sha_algo_ctx_final(sha_algo_value, exchange_hash_ctx,
+ exchange_state->h_sig_comp)) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_HASH_CALC,
+ "kex: failed to calculate hash");
+ goto clean_exit;
+ }
err = session->hostkey->sig_verify(session,
exchange_state->h_sig,
@@ -1568,6 +1609,7 @@ dh_gex_clean_exit:
return ret;
}
+#if LIBSSH2_ECDSA
/* LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY
*
@@ -1585,101 +1627,104 @@ dh_gex_clean_exit:
* mpint K, shared secret
*
*/
-
#define LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(digest_type) \
do { \
libssh2_sha##digest_type##_ctx ctx; \
+ int hok; \
+ if(!libssh2_sha##digest_type##_init(&ctx)) { \
+ rc = -1; \
+ break; \
+ } \
exchange_state->exchange_hash = (void *)&ctx; \
- (void)libssh2_sha##digest_type##_init(&ctx); \
+ hok = 1; \
if(session->local.banner) { \
_libssh2_htonu32(exchange_state->h_sig_comp, \
(uint32_t)(strlen((char *) session->local.banner) - 2)); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- (char *) session->local.banner, \
- strlen((char *) \
- session->local.banner) \
- - 2); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, \
+ 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ (char *)session->local.banner, \
+ strlen((char *)session->local.banner) \
+ - 2); \
} \
else { \
_libssh2_htonu32(exchange_state->h_sig_comp, \
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1); \
- libssh2_sha##digest_type##_update(ctx, \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- LIBSSH2_SSH_DEFAULT_BANNER, \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ LIBSSH2_SSH_DEFAULT_BANNER, \
sizeof(LIBSSH2_SSH_DEFAULT_BANNER) \
- 1); \
} \
\
_libssh2_htonu32(exchange_state->h_sig_comp, \
(uint32_t)strlen((char *) session->remote.banner)); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- session->remote.banner, \
- strlen((char *) \
- session->remote.banner)); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, session->remote.banner, \
+ strlen((char *)session->remote.banner)); \
\
_libssh2_htonu32(exchange_state->h_sig_comp, \
(uint32_t)session->local.kexinit_len); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- session->local.kexinit, \
- session->local.kexinit_len); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ session->local.kexinit, \
+ session->local.kexinit_len); \
\
_libssh2_htonu32(exchange_state->h_sig_comp, \
(uint32_t)session->remote.kexinit_len); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- session->remote.kexinit, \
- session->remote.kexinit_len); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ session->remote.kexinit, \
+ session->remote.kexinit_len); \
\
_libssh2_htonu32(exchange_state->h_sig_comp, \
session->server_hostkey_len); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- session->server_hostkey, \
- session->server_hostkey_len); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ session->server_hostkey, \
+ session->server_hostkey_len); \
\
_libssh2_htonu32(exchange_state->h_sig_comp, \
(uint32_t)public_key_len); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- public_key, \
- public_key_len); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ public_key, \
+ public_key_len); \
\
_libssh2_htonu32(exchange_state->h_sig_comp, \
(uint32_t)server_public_key_len); \
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->h_sig_comp, 4); \
- libssh2_sha##digest_type##_update(ctx, \
- server_public_key, \
- server_public_key_len); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->h_sig_comp, 4); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ server_public_key, \
+ server_public_key_len); \
\
- libssh2_sha##digest_type##_update(ctx, \
- exchange_state->k_value, \
- exchange_state->k_value_len); \
+ hok &= libssh2_sha##digest_type##_update(ctx, \
+ exchange_state->k_value, \
+ exchange_state->k_value_len); \
\
- libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp); \
+ if(!hok || \
+ !libssh2_sha##digest_type##_final(ctx, exchange_state->h_sig_comp)) { \
+ rc = -1; \
+ break; \
+ } \
\
if(session->hostkey-> \
- sig_verify(session, exchange_state->h_sig, \
- exchange_state->h_sig_len, exchange_state->h_sig_comp, \
- SHA##digest_type##_DIGEST_LENGTH, \
- &session->server_hostkey_abstract)) { \
+ sig_verify(session, exchange_state->h_sig, \
+ exchange_state->h_sig_len, exchange_state->h_sig_comp, \
+ SHA##digest_type##_DIGEST_LENGTH, \
+ &session->server_hostkey_abstract)) { \
rc = -1; \
} \
} while(0)
-
-#if LIBSSH2_ECDSA
-
/* kex_session_ecdh_curve_type
* returns the EC curve type by name used in key exchange
*/
@@ -1764,11 +1809,11 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type,
{
libssh2_md5_ctx fingerprint_ctx;
- if(libssh2_md5_init(&fingerprint_ctx)) {
- libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_md5_final(fingerprint_ctx,
- session->server_hostkey_md5);
+ if(libssh2_md5_init(&fingerprint_ctx) &&
+ libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_md5_final(fingerprint_ctx,
+ session->server_hostkey_md5)) {
session->server_hostkey_md5_valid = TRUE;
}
else {
@@ -1792,11 +1837,11 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type,
{
libssh2_sha1_ctx fingerprint_ctx;
- if(libssh2_sha1_init(&fingerprint_ctx)) {
- libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_sha1_final(fingerprint_ctx,
- session->server_hostkey_sha1);
+ if(libssh2_sha1_init(&fingerprint_ctx) &&
+ libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_sha1_final(fingerprint_ctx,
+ session->server_hostkey_sha1)) {
session->server_hostkey_sha1_valid = TRUE;
}
else {
@@ -1820,11 +1865,11 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type,
{
libssh2_sha256_ctx fingerprint_ctx;
- if(libssh2_sha256_init(&fingerprint_ctx)) {
- libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_sha256_final(fingerprint_ctx,
- session->server_hostkey_sha256);
+ if(libssh2_sha256_init(&fingerprint_ctx) &&
+ libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_sha256_final(fingerprint_ctx,
+ session->server_hostkey_sha256)) {
session->server_hostkey_sha256_valid = TRUE;
}
else {
@@ -1909,7 +1954,6 @@ static int ecdh_sha2_nistp(LIBSSH2_SESSION *session, libssh2_curve_type type,
case LIBSSH2_EC_CURVE_NISTP256:
LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(256);
break;
-
case LIBSSH2_EC_CURVE_NISTP384:
LIBSSH2_KEX_METHOD_EC_SHA_HASH_CREATE_VERIFY(384);
break;
@@ -2396,11 +2440,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
{
libssh2_md5_ctx fingerprint_ctx;
- if(libssh2_md5_init(&fingerprint_ctx)) {
- libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_md5_final(fingerprint_ctx,
- session->server_hostkey_md5);
+ if(libssh2_md5_init(&fingerprint_ctx) &&
+ libssh2_md5_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_md5_final(fingerprint_ctx,
+ session->server_hostkey_md5)) {
session->server_hostkey_md5_valid = TRUE;
}
else {
@@ -2424,11 +2468,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
{
libssh2_sha1_ctx fingerprint_ctx;
- if(libssh2_sha1_init(&fingerprint_ctx)) {
- libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_sha1_final(fingerprint_ctx,
- session->server_hostkey_sha1);
+ if(libssh2_sha1_init(&fingerprint_ctx) &&
+ libssh2_sha1_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_sha1_final(fingerprint_ctx,
+ session->server_hostkey_sha1)) {
session->server_hostkey_sha1_valid = TRUE;
}
else {
@@ -2452,11 +2496,11 @@ curve25519_sha256(LIBSSH2_SESSION *session, unsigned char *data,
{
libssh2_sha256_ctx fingerprint_ctx;
- if(libssh2_sha256_init(&fingerprint_ctx)) {
- libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
- session->server_hostkey_len);
- libssh2_sha256_final(fingerprint_ctx,
- session->server_hostkey_sha256);
+ if(libssh2_sha256_init(&fingerprint_ctx) &&
+ libssh2_sha256_update(fingerprint_ctx, session->server_hostkey,
+ session->server_hostkey_len) &&
+ libssh2_sha256_final(fingerprint_ctx,
+ session->server_hostkey_sha256)) {
session->server_hostkey_sha256_valid = TRUE;
}
else {
@@ -3033,6 +3077,13 @@ kex_method_extension_negotiation = {
0,
};
+static const LIBSSH2_KEX_METHOD
+kex_method_strict_client_extension = {
+ "kex-strict-c-v00@openssh.com",
+ NULL,
+ 0,
+};
+
static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
#if LIBSSH2_ED25519
&kex_method_ssh_curve25519_sha256,
@@ -3051,6 +3102,7 @@ static const LIBSSH2_KEX_METHOD *libssh2_kex_methods[] = {
&kex_method_diffie_helman_group1_sha1,
&kex_method_diffie_helman_group_exchange_sha1,
&kex_method_extension_negotiation,
+ &kex_method_strict_client_extension,
NULL
};
@@ -3303,13 +3355,13 @@ static int kexinit(LIBSSH2_SESSION * session)
return 0;
}
-/* kex_agree_instr
+/* _libssh2_kex_agree_instr
* Kex specific variant of strstr()
* Needle must be preceded by BOL or ',', and followed by ',' or EOL
*/
-static unsigned char *
-kex_agree_instr(unsigned char *haystack, size_t haystack_len,
- const unsigned char *needle, size_t needle_len)
+unsigned char *
+_libssh2_kex_agree_instr(unsigned char *haystack, size_t haystack_len,
+ const unsigned char *needle, size_t needle_len)
{
unsigned char *s;
unsigned char *end_haystack;
@@ -3342,6 +3394,7 @@ kex_agree_instr(unsigned char *haystack, size_t haystack_len,
left = end_haystack - s;
if((left >= 1) && (left <= haystack_len) && (left > needle_len)) {
s++;
+ left--;
}
else {
return NULL;
@@ -3394,7 +3447,7 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
while(s && *s) {
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
- if(kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
+ if(_libssh2_kex_agree_instr(hostkey, hostkey_len, s, method_len)) {
const LIBSSH2_HOSTKEY_METHOD *method =
(const LIBSSH2_HOSTKEY_METHOD *)
kex_get_method_by_name((char *) s, method_len,
@@ -3428,9 +3481,9 @@ static int kex_agree_hostkey(LIBSSH2_SESSION * session,
}
while(hostkeyp && (*hostkeyp) && (*hostkeyp)->name) {
- s = kex_agree_instr(hostkey, hostkey_len,
- (unsigned char *) (*hostkeyp)->name,
- strlen((*hostkeyp)->name));
+ s = _libssh2_kex_agree_instr(hostkey, hostkey_len,
+ (unsigned char *) (*hostkeyp)->name,
+ strlen((*hostkeyp)->name));
if(s) {
/* So far so good, but does it suit our purposes? (Encrypting vs
Signing) */
@@ -3464,6 +3517,12 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
{
const LIBSSH2_KEX_METHOD **kexp = libssh2_kex_methods;
unsigned char *s;
+ const unsigned char *strict =
+ (unsigned char *)"kex-strict-s-v00@openssh.com";
+
+ if(_libssh2_kex_agree_instr(kex, kex_len, strict, 28)) {
+ session->kex_strict = 1;
+ }
if(session->kex_prefs) {
s = (unsigned char *) session->kex_prefs;
@@ -3471,7 +3530,7 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
while(s && *s) {
unsigned char *q, *p = (unsigned char *) strchr((char *) s, ',');
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
- q = kex_agree_instr(kex, kex_len, s, method_len);
+ q = _libssh2_kex_agree_instr(kex, kex_len, s, method_len);
if(q) {
const LIBSSH2_KEX_METHOD *method = (const LIBSSH2_KEX_METHOD *)
kex_get_method_by_name((char *) s, method_len,
@@ -3505,9 +3564,9 @@ static int kex_agree_kex_hostkey(LIBSSH2_SESSION * session, unsigned char *kex,
}
while(*kexp && (*kexp)->name) {
- s = kex_agree_instr(kex, kex_len,
- (unsigned char *) (*kexp)->name,
- strlen((*kexp)->name));
+ s = _libssh2_kex_agree_instr(kex, kex_len,
+ (unsigned char *) (*kexp)->name,
+ strlen((*kexp)->name));
if(s) {
/* We've agreed on a key exchange method,
* Can we agree on a hostkey that works with this kex?
@@ -3551,7 +3610,7 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
- if(kex_agree_instr(crypt, crypt_len, s, method_len)) {
+ if(_libssh2_kex_agree_instr(crypt, crypt_len, s, method_len)) {
const LIBSSH2_CRYPT_METHOD *method =
(const LIBSSH2_CRYPT_METHOD *)
kex_get_method_by_name((char *) s, method_len,
@@ -3573,9 +3632,9 @@ static int kex_agree_crypt(LIBSSH2_SESSION * session,
}
while(*cryptp && (*cryptp)->name) {
- s = kex_agree_instr(crypt, crypt_len,
- (unsigned char *) (*cryptp)->name,
- strlen((*cryptp)->name));
+ s = _libssh2_kex_agree_instr(crypt, crypt_len,
+ (unsigned char *) (*cryptp)->name,
+ strlen((*cryptp)->name));
if(s) {
endpoint->crypt = *cryptp;
return 0;
@@ -3615,7 +3674,7 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
- if(kex_agree_instr(mac, mac_len, s, method_len)) {
+ if(_libssh2_kex_agree_instr(mac, mac_len, s, method_len)) {
const LIBSSH2_MAC_METHOD *method = (const LIBSSH2_MAC_METHOD *)
kex_get_method_by_name((char *) s, method_len,
(const LIBSSH2_COMMON_METHOD **)
@@ -3636,8 +3695,9 @@ static int kex_agree_mac(LIBSSH2_SESSION * session,
}
while(*macp && (*macp)->name) {
- s = kex_agree_instr(mac, mac_len, (unsigned char *) (*macp)->name,
- strlen((*macp)->name));
+ s = _libssh2_kex_agree_instr(mac, mac_len,
+ (unsigned char *) (*macp)->name,
+ strlen((*macp)->name));
if(s) {
endpoint->mac = *macp;
return 0;
@@ -3668,7 +3728,7 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
unsigned char *p = (unsigned char *) strchr((char *) s, ',');
size_t method_len = (p ? (size_t)(p - s) : strlen((char *) s));
- if(kex_agree_instr(comp, comp_len, s, method_len)) {
+ if(_libssh2_kex_agree_instr(comp, comp_len, s, method_len)) {
const LIBSSH2_COMP_METHOD *method =
(const LIBSSH2_COMP_METHOD *)
kex_get_method_by_name((char *) s, method_len,
@@ -3690,8 +3750,9 @@ static int kex_agree_comp(LIBSSH2_SESSION *session,
}
while(*compp && (*compp)->name) {
- s = kex_agree_instr(comp, comp_len, (unsigned char *) (*compp)->name,
- strlen((*compp)->name));
+ s = _libssh2_kex_agree_instr(comp, comp_len,
+ (unsigned char *) (*compp)->name,
+ strlen((*compp)->name));
if(s) {
endpoint->comp = *compp;
return 0;
@@ -3872,6 +3933,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
session->local.kexinit = key_state->oldlocal;
session->local.kexinit_len = key_state->oldlocal_len;
key_state->state = libssh2_NB_state_idle;
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
return -1;
@@ -3897,6 +3959,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
session->local.kexinit = key_state->oldlocal;
session->local.kexinit_len = key_state->oldlocal_len;
key_state->state = libssh2_NB_state_idle;
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
return -1;
@@ -3945,6 +4008,7 @@ _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
session->remote.kexinit = NULL;
}
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
session->state &= ~LIBSSH2_STATE_KEX_ACTIVE;
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
diff --git a/libs/libssh2/src/knownhost.c b/libs/libssh2/src/knownhost.c
index 1caab14789..5eba6a108c 100644
--- a/libs/libssh2/src/knownhost.c
+++ b/libs/libssh2/src/knownhost.c
@@ -421,19 +421,23 @@ knownhost_check(LIBSSH2_KNOWNHOSTS *hosts,
*/
unsigned char hash[SHA_DIGEST_LENGTH];
libssh2_hmac_ctx ctx;
- libssh2_hmac_ctx_init(ctx);
+ if(!_libssh2_hmac_ctx_init(&ctx))
+ break;
if(SHA_DIGEST_LENGTH != node->name_len) {
/* the name hash length must be the sha1 size or
we can't match it */
break;
}
- libssh2_hmac_sha1_init(&ctx, (unsigned char *)node->salt,
- node->salt_len);
- libssh2_hmac_update(ctx, (unsigned char *)host,
- strlen(host));
- libssh2_hmac_final(ctx, hash);
- libssh2_hmac_cleanup(&ctx);
+ if(!_libssh2_hmac_sha1_init(&ctx,
+ node->salt, node->salt_len))
+ break;
+ if(!_libssh2_hmac_update(&ctx, host, strlen(host)) ||
+ !_libssh2_hmac_final(&ctx, hash)) {
+ _libssh2_hmac_cleanup(&ctx);
+ break;
+ }
+ _libssh2_hmac_cleanup(&ctx);
if(!memcmp(hash, node->name, SHA_DIGEST_LENGTH))
/* this is a node we're interested in */
@@ -1049,7 +1053,7 @@ knownhost_writeline(LIBSSH2_KNOWNHOSTS *hosts,
break;
}
/* otherwise fallback to default and error */
- /* FALL-THROUGH */
+ LIBSSH2_FALLTHROUGH();
default:
return _libssh2_error(hosts->session,
LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
diff --git a/libs/libssh2/src/libgcrypt.c b/libs/libssh2/src/libgcrypt.c
index e463d9e347..b92ec7c97d 100644
--- a/libs/libssh2/src/libgcrypt.c
+++ b/libs/libssh2/src/libgcrypt.c
@@ -40,6 +40,105 @@
#ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */
+int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
+{
+ *ctx = NULL;
+ return 1;
+}
+
+#if LIBSSH2_MD5
+int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+ gcry_error_t err;
+ err = gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ err = gcry_md_setkey(*ctx, key, keylen);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ return 1;
+}
+#endif
+
+#if LIBSSH2_HMAC_RIPEMD
+int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+ gcry_error_t err;
+ err = gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ err = gcry_md_setkey(*ctx, key, keylen);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ return 1;
+}
+#endif
+
+int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+ gcry_error_t err;
+ err = gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ err = gcry_md_setkey(*ctx, key, keylen);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ return 1;
+}
+
+int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+ gcry_error_t err;
+ err = gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ err = gcry_md_setkey(*ctx, key, keylen);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ return 1;
+}
+
+int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+ gcry_error_t err;
+ err = gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ err = gcry_md_setkey(*ctx, key, keylen);
+ if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
+ return 0;
+ return 1;
+}
+
+int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
+ const void *data, size_t datalen)
+{
+ gcry_md_write(*ctx, data, datalen);
+ return 1;
+}
+
+int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
+{
+ unsigned char *res = gcry_md_read(*ctx, 0);
+
+ if(!res)
+ return 0;
+
+ memcpy(data, res, gcry_md_get_algo_dlen(gcry_md_get_algo(*ctx)));
+
+ return 1;
+}
+
+void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
+{
+ gcry_md_close(*ctx);
+}
+
#if LIBSSH2_RSA
int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
@@ -95,7 +194,9 @@ _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
gcry_sexp_t s_sig, s_hash;
int rc = -1;
- libssh2_sha1(m, m_len, hash);
+ if(libssh2_sha1(m, m_len, hash)) {
+ return -1;
+ }
rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
@@ -544,7 +645,9 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
gcry_sexp_t s_sig, s_hash;
int rc = -1;
- libssh2_sha1(m, m_len, hash + 1);
+ if(libssh2_sha1(m, m_len, hash + 1)) {
+ return -1;
+ }
hash[0] = 0;
if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
diff --git a/libs/libssh2/src/libgcrypt.h b/libs/libssh2/src/libgcrypt.h
index 77a1b8aba3..7fc8148720 100644
--- a/libs/libssh2/src/libgcrypt.h
+++ b/libs/libssh2/src/libgcrypt.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_LIBGCRYPT_H
-#define __LIBSSH2_LIBGCRYPT_H
+#ifndef LIBSSH2_LIBGCRYPT_H
+#define LIBSSH2_LIBGCRYPT_H
/*
* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
@@ -53,7 +53,7 @@
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
-#define LIBSSH2_AES_GCM 1
+#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 1
@@ -61,12 +61,16 @@
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
-#define LIBSSH2_RSA_SHA2 1
+#define LIBSSH2_RSA_SHA2 0
#define LIBSSH2_DSA 1
-#define LIBSSH2_ECDSA 1
-#define LIBSSH2_ED25519 1
+#define LIBSSH2_ECDSA 0
+#define LIBSSH2_ED25519 0
+#include "crypto_config.h"
+
+#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
+#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
@@ -80,86 +84,62 @@
#define libssh2_prepare_iovec(vec, len) /* Empty. */
#define libssh2_sha1_ctx gcry_md_hd_t
-
/* returns 0 in case of failure */
#define libssh2_sha1_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0))
#define libssh2_sha1_update(ctx, data, len) \
- gcry_md_write(ctx, (unsigned char *) data, len)
+ (gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha1_final(ctx, out) \
- memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx)
+ (memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), \
+ gcry_md_close(ctx), 1)
#define libssh2_sha1(message, len, out) \
- gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len)
+ (gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len), 0)
#define libssh2_sha256_ctx gcry_md_hd_t
-
#define libssh2_sha256_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0))
#define libssh2_sha256_update(ctx, data, len) \
- gcry_md_write(ctx, (unsigned char *) data, len)
+ (gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha256_final(ctx, out) \
- memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx)
+ (memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), \
+ gcry_md_close(ctx), 1)
#define libssh2_sha256(message, len, out) \
- gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len)
+ (gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len), 0)
#define libssh2_sha384_ctx gcry_md_hd_t
-
#define libssh2_sha384_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0))
#define libssh2_sha384_update(ctx, data, len) \
- gcry_md_write(ctx, (unsigned char *) data, len)
+ (gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha384_final(ctx, out) \
- memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx)
+ (memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), \
+ gcry_md_close(ctx), 1)
#define libssh2_sha384(message, len, out) \
- gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len)
+ (gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len), 0)
#define libssh2_sha512_ctx gcry_md_hd_t
-
#define libssh2_sha512_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0))
#define libssh2_sha512_update(ctx, data, len) \
- gcry_md_write(ctx, (unsigned char *) data, len)
+ (gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha512_final(ctx, out) \
- memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx)
+ (memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), \
+ gcry_md_close(ctx), 1)
#define libssh2_sha512(message, len, out) \
- gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len)
+ (gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len), 0)
+#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx gcry_md_hd_t
-
-/* returns 0 in case of failure */
#define libssh2_md5_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0))
-
#define libssh2_md5_update(ctx, data, len) \
- gcry_md_write(ctx, (unsigned char *) data, len)
+ (gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_md5_final(ctx, out) \
- memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx)
-#define libssh2_md5(message, len, out) \
- gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len)
+ (memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), \
+ gcry_md_close(ctx), 1)
+#endif
#define libssh2_hmac_ctx gcry_md_hd_t
-#define libssh2_hmac_ctx_init(ctx)
-#define libssh2_hmac_sha1_init(ctx, key, keylen) \
- gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
- gcry_md_setkey(*ctx, key, keylen)
-#define libssh2_hmac_md5_init(ctx, key, keylen) \
- gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
- gcry_md_setkey(*ctx, key, keylen)
-#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
- gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
- gcry_md_setkey(*ctx, key, keylen)
-#define libssh2_hmac_sha256_init(ctx, key, keylen) \
- gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \
- gcry_md_setkey(*ctx, key, keylen)
-#define libssh2_hmac_sha512_init(ctx, key, keylen) \
- gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \
- gcry_md_setkey(*ctx, key, keylen)
-#define libssh2_hmac_update(ctx, data, datalen) \
- gcry_md_write(ctx, (unsigned char *) data, datalen)
-#define libssh2_hmac_final(ctx, data) \
- memcpy(data, gcry_md_read(ctx, 0), \
- gcry_md_get_algo_dlen(gcry_md_get_algo(ctx)))
-#define libssh2_hmac_cleanup(ctx) gcry_md_close(*ctx)
#define libssh2_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM)
#define libssh2_crypto_exit()
@@ -250,4 +230,4 @@ extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
-#endif /* __LIBSSH2_LIBGCRYPT_H */
+#endif /* LIBSSH2_LIBGCRYPT_H */
diff --git a/libs/libssh2/src/libssh2.rc b/libs/libssh2/src/libssh2.rc
index 4862d78eef..3021d8e69c 100644
--- a/libs/libssh2/src/libssh2.rc
+++ b/libs/libssh2/src/libssh2.rc
@@ -1,7 +1,7 @@
/***************************************************************************
* libssh2 Windows resource file
* Copyright (C) The libssh2 project and its contributors.
-*
+*
* SPDX-License-Identifier: BSD-3-Clause
***************************************************************************/
#include <winver.h>
@@ -29,7 +29,7 @@ BEGIN
BEGIN
BLOCK "040904b0" /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
BEGIN
- VALUE "CompanyName", "The libssh2 library, https://www.libssh2.org/\0"
+ VALUE "CompanyName", "The libssh2 library, https://libssh2.org/\0"
VALUE "FileDescription", "libssh2 Shared Library\0"
VALUE "FileVersion", LIBSSH2_VERSION "\0"
VALUE "InternalName", "libssh2\0"
@@ -37,7 +37,7 @@ BEGIN
VALUE "ProductName", "The libssh2 library\0"
VALUE "ProductVersion", LIBSSH2_VERSION "\0"
VALUE "LegalCopyright", "Copyright (C) " LIBSSH2_COPYRIGHT "\0"
- VALUE "License", "https://www.libssh2.org/license.html\0"
+ VALUE "License", "https://libssh2.org/license.html\0"
END
END
diff --git a/libs/libssh2/src/libssh2_priv.h b/libs/libssh2/src/libssh2_priv.h
index 96af134279..18d9ab2130 100644
--- a/libs/libssh2/src/libssh2_priv.h
+++ b/libs/libssh2/src/libssh2_priv.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_PRIV_H
-#define __LIBSSH2_PRIV_H
+#ifndef LIBSSH2_PRIV_H
+#define LIBSSH2_PRIV_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson
@@ -41,7 +41,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-/* Header used by 'src' */
+/* Header used by 'src' and 'tests' */
+
+/* FIXME: Disable warnings for 'src' */
+#if !defined(LIBSSH2_TESTS) && !defined(LIBSSH2_WARN_SIGN_CONVERSION)
+#ifdef __GNUC__
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#endif
+#endif
#define LIBSSH2_LIBRARY
@@ -86,6 +93,19 @@
#include "libssh2_sftp.h"
#include "misc.h"
+#ifdef _WIN32
+/* Detect Windows App environment which has a restricted access
+ to the Win32 APIs. */
+# if (defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)) || \
+ defined(WINAPI_FAMILY)
+# include <winapifamily.h>
+# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && \
+ !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+# define LIBSSH2_WINDOWS_UWP
+# endif
+# endif
+#endif
+
#ifndef FALSE
#define FALSE 0
#endif
@@ -93,12 +113,28 @@
#define TRUE 1
#endif
+#if (defined(__GNUC__) || defined(__clang__)) && \
+ defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
+ !defined(LIBSSH2_NO_FMT_CHECKS)
+#ifdef __MINGW_PRINTF_FORMAT
+#define LIBSSH2_PRINTF(fmt, arg) \
+ __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, arg)))
+#elif !defined(__MINGW32__)
+#define LIBSSH2_PRINTF(fmt, arg) \
+ __attribute__((format(printf, fmt, arg)))
+#endif
+#endif
+#ifndef LIBSSH2_PRINTF
+#define LIBSSH2_PRINTF(fmt, arg)
+#endif
+
/* Use local implementation when not available */
#if !defined(HAVE_SNPRINTF)
#undef snprintf
#define snprintf _libssh2_snprintf
#define LIBSSH2_SNPRINTF
-int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...);
+int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
+ LIBSSH2_PRINTF(3, 4);
#endif
#if !defined(HAVE_GETTIMEOFDAY)
@@ -111,6 +147,15 @@ int _libssh2_gettimeofday(struct timeval *tp, void *tzp);
#include <sys/time.h>
#endif
+#if !defined(LIBSSH2_FALLTHROUGH)
+#if (defined(__GNUC__) && __GNUC__ >= 7) || \
+ (defined(__clang__) && __clang_major__ >= 10)
+# define LIBSSH2_FALLTHROUGH() __attribute__((fallthrough))
+#else
+# define LIBSSH2_FALLTHROUGH() do {} while (0)
+#endif
+#endif
+
/* "inline" keyword is valid only with C++ engine! */
#ifdef __GNUC__
#undef inline
@@ -121,7 +166,7 @@ int _libssh2_gettimeofday(struct timeval *tp, void *tzp);
#endif
/* 3DS doesn't seem to have iovec */
-#if defined(WIN32) || defined(_3DS)
+#if defined(_WIN32) || defined(_3DS)
struct iovec {
size_t iov_len;
@@ -152,6 +197,9 @@ struct iovec {
#define LIBSSH2_MAX(x, y) ((x) > (y) ? (x) : (y))
#define LIBSSH2_MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
+#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */
+
/* RFC4253 section 6.1 Maximum Packet Length says:
*
* "All implementations MUST be able to process packets with
@@ -402,7 +450,7 @@ struct _LIBSSH2_CHANNEL
struct list_node node;
unsigned char *channel_type;
- unsigned channel_type_len;
+ size_t channel_type_len;
/* channel's program exit status */
int exit_status;
@@ -455,7 +503,7 @@ struct _LIBSSH2_CHANNEL
size_t flush_refund_bytes;
size_t flush_flush_bytes;
- /* State variables used in libssh2_channel_receive_window_adjust() */
+ /* State variables used in libssh2_channel_receive_window_adjust2() */
libssh2_nonblocking_states adjust_state;
unsigned char adjust_adjust[9]; /* packet_type(1) + channel(4) +
adjustment(4) */
@@ -688,6 +736,9 @@ struct _LIBSSH2_SESSION
/* key signing algorithm preferences -- NULL yields server order */
char *sign_algo_prefs;
+ /* Whether to use the OpenSSH Strict KEX extension */
+ int kex_strict;
+
/* (remote as source of data -- packet_read ) */
libssh2_endpoint_data remote;
@@ -710,7 +761,8 @@ struct _LIBSSH2_SESSION
int socket_state;
int socket_block_directions;
int socket_prev_blockstate; /* stores the state of the socket blockiness
- when libssh2_session_startup() is called */
+ when libssh2_session_handshake()
+ is called */
/* Error tracking */
const char *err_msg;
@@ -736,7 +788,7 @@ struct _LIBSSH2_SESSION
unsigned char *kexinit_data;
size_t kexinit_data_len;
- /* State variables used in libssh2_session_startup() */
+ /* State variables used in libssh2_session_handshake() */
libssh2_nonblocking_states startup_state;
unsigned char *startup_data;
size_t startup_data_len;
@@ -859,6 +911,7 @@ struct _LIBSSH2_SESSION
int fullpacket_macstate;
size_t fullpacket_payload_len;
int fullpacket_packet_type;
+ uint32_t fullpacket_required_type;
/* State variables used in libssh2_sftp_init() */
libssh2_nonblocking_states sftpInit_state;
@@ -869,7 +922,7 @@ struct _LIBSSH2_SESSION
size_t sftpInit_sent; /* number of bytes from the buffer that have been
sent */
- /* State variables used in libssh2_scp_recv() / libssh_scp_recv2() */
+ /* State variables used in libssh2_scp_recv2() */
libssh2_nonblocking_states scpRecv_state;
unsigned char *scpRecv_command;
size_t scpRecv_command_len;
@@ -899,10 +952,11 @@ struct _LIBSSH2_SESSION
};
/* session.state bits */
-#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000001
-#define LIBSSH2_STATE_NEWKEYS 0x00000002
-#define LIBSSH2_STATE_AUTHENTICATED 0x00000004
-#define LIBSSH2_STATE_KEX_ACTIVE 0x00000008
+#define LIBSSH2_STATE_INITIAL_KEX 0x00000001
+#define LIBSSH2_STATE_EXCHANGING_KEYS 0x00000002
+#define LIBSSH2_STATE_NEWKEYS 0x00000004
+#define LIBSSH2_STATE_AUTHENTICATED 0x00000008
+#define LIBSSH2_STATE_KEX_ACTIVE 0x00000010
/* session.flag helpers */
#ifdef MSG_NOSIGNAL
@@ -1032,7 +1086,7 @@ struct _LIBSSH2_COMP_METHOD
#ifdef LIBSSH2DEBUG
void
_libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
- ...);
+ ...) LIBSSH2_PRINTF(3, 4);
#define _libssh2_debug(x) _libssh2_debug_low x
#else
#define _libssh2_debug(x) do {} while(0)
@@ -1133,6 +1187,11 @@ ssize_t _libssh2_send(libssh2_socket_t socket, const void *buffer,
int _libssh2_kex_exchange(LIBSSH2_SESSION * session, int reexchange,
key_exchange_state_t * state);
+unsigned char *_libssh2_kex_agree_instr(unsigned char *haystack,
+ size_t haystack_len,
+ const unsigned char *needle,
+ size_t needle_len);
+
/* Let crypt.c/hostkey.c expose their method structs */
const LIBSSH2_CRYPT_METHOD **libssh2_crypt_methods(void);
const LIBSSH2_HOSTKEY_METHOD **libssh2_hostkey_methods(void);
@@ -1182,6 +1241,8 @@ size_t plain_method(char *method, size_t method_len);
/* define to output the libssh2_int64_t type in a *printf() */
#if defined(__BORLANDC__) || defined(_MSC_VER)
#define LIBSSH2_INT64_T_FORMAT "I64d"
+#elif defined(__MINGW32__)
+#define LIBSSH2_INT64_T_FORMAT PRId64
#else
#define LIBSSH2_INT64_T_FORMAT "lld"
#endif
@@ -1189,12 +1250,12 @@ size_t plain_method(char *method, size_t method_len);
/* In Windows the default file mode is text but an application can override it.
Therefore we specify it explicitly. https://github.com/curl/curl/pull/258
*/
-#if defined(WIN32) || defined(MSDOS)
+#if defined(_WIN32) || defined(MSDOS)
#define FOPEN_READTEXT "rt"
#define FOPEN_WRITETEXT "wt"
#define FOPEN_APPENDTEXT "at"
#elif defined(__CYGWIN__)
-/* Cygwin has specific behavior we need to address when WIN32 is not defined.
+/* Cygwin has specific behavior we need to address when _WIN32 is not defined.
https://cygwin.com/cygwin-ug-net/using-textbinary.html
For write we want our output to have line endings of LF and be compatible
with other Cygwin utilities. For read we want to handle input that may have
@@ -1209,4 +1270,4 @@ size_t plain_method(char *method, size_t method_len);
#define FOPEN_APPENDTEXT "a"
#endif
-#endif /* __LIBSSH2_PRIV_H */
+#endif /* LIBSSH2_PRIV_H */
diff --git a/libs/libssh2/src/libssh2_setup.h b/libs/libssh2/src/libssh2_setup.h
index 8e56a06042..7e084f993a 100644
--- a/libs/libssh2/src/libssh2_setup.h
+++ b/libs/libssh2/src/libssh2_setup.h
@@ -9,10 +9,6 @@
/* Header for platform/compiler-specific initialization.
Used by 'src', 'example', 'tests' */
-#if defined(_WIN32) && !defined(WIN32)
-#define WIN32
-#endif
-
/* Define mingw-w64 version macros, eg __MINGW{32,64}_{MINOR,MAJOR}_VERSION */
#ifdef __MINGW32__
#include <_mingw.h>
@@ -26,7 +22,7 @@
/* Hand-crafted configuration for platforms which lack config tool.
Keep this synced with root CMakeLists.txt */
-#elif defined(WIN32)
+#elif defined(_WIN32)
#define HAVE_SELECT
#define HAVE_SNPRINTF
@@ -54,7 +50,7 @@
/* Below applies to both auto-detected and hand-crafted configs */
-#ifdef WIN32
+#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
@@ -103,6 +99,6 @@
# endif
#endif
-#endif /* WIN32 */
+#endif /* _WIN32 */
#endif /* LIBSSH2_SETUP_H */
diff --git a/libs/libssh2/src/mac.c b/libs/libssh2/src/mac.c
index db6f57a44e..03ecd329ee 100644
--- a/libs/libssh2/src/mac.c
+++ b/libs/libssh2/src/mac.c
@@ -124,23 +124,27 @@ mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
+ int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
- libssh2_hmac_ctx_init(ctx);
- libssh2_hmac_sha512_init(&ctx, *abstract, 64);
- libssh2_hmac_update(ctx, seqno_buf, 4);
- libssh2_hmac_update(ctx, packet, packet_len);
- if(addtl && addtl_len) {
- libssh2_hmac_update(ctx, addtl, addtl_len);
- }
- libssh2_hmac_final(ctx, buf);
- libssh2_hmac_cleanup(&ctx);
-
- return 0;
+ if(!_libssh2_hmac_ctx_init(&ctx))
+ return 1;
+ res = _libssh2_hmac_sha512_init(&ctx, *abstract, 64) &&
+ _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
+ _libssh2_hmac_update(&ctx, packet, packet_len);
+ if(res && addtl && addtl_len)
+ res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
+ if(res)
+ res = _libssh2_hmac_final(&ctx, buf);
+ _libssh2_hmac_cleanup(&ctx);
+
+ return !res;
}
+
+
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
"hmac-sha2-512",
64,
@@ -179,21 +183,23 @@ mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
+ int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
- libssh2_hmac_ctx_init(ctx);
- libssh2_hmac_sha256_init(&ctx, *abstract, 32);
- libssh2_hmac_update(ctx, seqno_buf, 4);
- libssh2_hmac_update(ctx, packet, packet_len);
- if(addtl && addtl_len) {
- libssh2_hmac_update(ctx, addtl, addtl_len);
- }
- libssh2_hmac_final(ctx, buf);
- libssh2_hmac_cleanup(&ctx);
-
- return 0;
+ if(!_libssh2_hmac_ctx_init(&ctx))
+ return 1;
+ res = _libssh2_hmac_sha256_init(&ctx, *abstract, 32) &&
+ _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
+ _libssh2_hmac_update(&ctx, packet, packet_len);
+ if(res && addtl && addtl_len)
+ res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
+ if(res)
+ res = _libssh2_hmac_final(&ctx, buf);
+ _libssh2_hmac_cleanup(&ctx);
+
+ return !res;
}
@@ -236,21 +242,23 @@ mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
+ int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
- libssh2_hmac_ctx_init(ctx);
- libssh2_hmac_sha1_init(&ctx, *abstract, 20);
- libssh2_hmac_update(ctx, seqno_buf, 4);
- libssh2_hmac_update(ctx, packet, packet_len);
- if(addtl && addtl_len) {
- libssh2_hmac_update(ctx, addtl, addtl_len);
- }
- libssh2_hmac_final(ctx, buf);
- libssh2_hmac_cleanup(&ctx);
-
- return 0;
+ if(!_libssh2_hmac_ctx_init(&ctx))
+ return 1;
+ res = _libssh2_hmac_sha1_init(&ctx, *abstract, 20) &&
+ _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
+ _libssh2_hmac_update(&ctx, packet, packet_len);
+ if(res && addtl && addtl_len)
+ res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
+ if(res)
+ res = _libssh2_hmac_final(&ctx, buf);
+ _libssh2_hmac_cleanup(&ctx);
+
+ return !res;
}
@@ -288,10 +296,11 @@ mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
{
unsigned char temp[SHA_DIGEST_LENGTH];
- mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
- addtl, addtl_len, abstract);
- memcpy(buf, (char *) temp, 96 / 8);
+ if(mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
+ addtl, addtl_len, abstract))
+ return 1;
+ memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
@@ -321,21 +330,23 @@ mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
+ int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
- libssh2_hmac_ctx_init(ctx);
- libssh2_hmac_md5_init(&ctx, *abstract, 16);
- libssh2_hmac_update(ctx, seqno_buf, 4);
- libssh2_hmac_update(ctx, packet, packet_len);
- if(addtl && addtl_len) {
- libssh2_hmac_update(ctx, addtl, addtl_len);
- }
- libssh2_hmac_final(ctx, buf);
- libssh2_hmac_cleanup(&ctx);
-
- return 0;
+ if(!_libssh2_hmac_ctx_init(&ctx))
+ return 1;
+ res = _libssh2_hmac_md5_init(&ctx, *abstract, 16) &&
+ _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
+ _libssh2_hmac_update(&ctx, packet, packet_len);
+ if(res && addtl && addtl_len)
+ res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
+ if(res)
+ res = _libssh2_hmac_final(&ctx, buf);
+ _libssh2_hmac_cleanup(&ctx);
+
+ return !res;
}
@@ -362,8 +373,11 @@ mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
size_t addtl_len, void **abstract)
{
unsigned char temp[MD5_DIGEST_LENGTH];
- mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
- addtl, addtl_len, abstract);
+
+ if(mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
+ addtl, addtl_len, abstract))
+ return 1;
+
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
@@ -396,21 +410,23 @@ mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
+ int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
- libssh2_hmac_ctx_init(ctx);
- libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
- libssh2_hmac_update(ctx, seqno_buf, 4);
- libssh2_hmac_update(ctx, packet, packet_len);
- if(addtl && addtl_len) {
- libssh2_hmac_update(ctx, addtl, addtl_len);
- }
- libssh2_hmac_final(ctx, buf);
- libssh2_hmac_cleanup(&ctx);
-
- return 0;
+ if(!_libssh2_hmac_ctx_init(&ctx))
+ return 1;
+ res = _libssh2_hmac_ripemd160_init(&ctx, *abstract, 20) &&
+ _libssh2_hmac_update(&ctx, seqno_buf, 4) &&
+ _libssh2_hmac_update(&ctx, packet, packet_len);
+ if(res && addtl && addtl_len)
+ res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
+ if(res)
+ res = _libssh2_hmac_final(&ctx, buf);
+ _libssh2_hmac_cleanup(&ctx);
+
+ return !res;
}
diff --git a/libs/libssh2/src/mac.h b/libs/libssh2/src/mac.h
index 696f835aa6..8e5b8c280f 100644
--- a/libs/libssh2/src/mac.h
+++ b/libs/libssh2/src/mac.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_MAC_H
-#define __LIBSSH2_MAC_H
+#ifndef LIBSSH2_MAC_H
+#define LIBSSH2_MAC_H
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
@@ -69,4 +69,4 @@ const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
const LIBSSH2_MAC_METHOD *_libssh2_mac_override(
const LIBSSH2_CRYPT_METHOD *crypt);
-#endif /* __LIBSSH2_MAC_H */
+#endif /* LIBSSH2_MAC_H */
diff --git a/libs/libssh2/src/misc.c b/libs/libssh2/src/misc.c
index b386e3d667..0dee48f5f5 100644
--- a/libs/libssh2/src/misc.c
+++ b/libs/libssh2/src/misc.c
@@ -40,7 +40,6 @@
*/
#include "libssh2_priv.h"
-#include "misc.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
@@ -49,7 +48,7 @@
#include <errno.h>
#include <assert.h>
-#ifdef WIN32
+#ifdef _WIN32
/* Force parameter type. */
#define recv(s, b, l, f) recv((s), (b), (int)(l), (f))
#define send(s, b, l, f) send((s), (b), (int)(l), (f))
@@ -73,7 +72,14 @@ int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
if(cp_max_len < 2)
return 0;
va_start(args, fmt);
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#endif
n = vsnprintf(cp, cp_max_len, fmt, args);
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
va_end(args);
return (n < (int)cp_max_len) ? n : (int)(cp_max_len - 1);
}
@@ -126,8 +132,8 @@ int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg)
return _libssh2_error_flags(session, errcode, errmsg, 0);
}
-#ifdef WIN32
-static int wsa2errno(void)
+#ifdef _WIN32
+int _libssh2_wsa2errno(void)
{
switch(WSAGetLastError()) {
case WSAEWOULDBLOCK:
@@ -161,23 +167,29 @@ _libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
(void)abstract;
rc = recv(sock, buffer, length, flags);
-#ifdef WIN32
- if(rc < 0)
- return -wsa2errno();
-#else
if(rc < 0) {
+ int err;
+#ifdef _WIN32
+ err = _libssh2_wsa2errno();
+#else
+ err = errno;
+#endif
+ /* Profiling tools that use SIGPROF can cause EINTR responses.
+ recv() does not modify its arguments when it returns EINTR,
+ but there may be data waiting, so the caller should try again */
+ if(err == EINTR)
+ return -EAGAIN;
/* Sometimes the first recv() function call sets errno to ENOENT on
Solaris and HP-UX */
- if(errno == ENOENT)
+ if(err == ENOENT)
return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
- else if(errno == EWOULDBLOCK)
- return -EAGAIN;
+ else if(err == EWOULDBLOCK)
+ return -EAGAIN;
#endif
else
- return -errno;
+ return -err;
}
-#endif
return rc;
}
@@ -194,18 +206,24 @@ _libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
(void)abstract;
rc = send(sock, buffer, length, flags);
-#ifdef WIN32
- if(rc < 0)
- return -wsa2errno();
-#else
if(rc < 0) {
+ int err;
+#ifdef _WIN32
+ err = _libssh2_wsa2errno();
+#else
+ err = errno;
+#endif
+ /* Profiling tools that use SIGPROF can cause EINTR responses.
+ send() is defined as not yet sending any data when it returns EINTR,
+ so the caller should try again */
+ if(err == EINTR)
+ return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
- if(errno == EWOULDBLOCK)
+ if(err == EWOULDBLOCK)
return -EAGAIN;
#endif
- return -errno;
+ return -err;
}
-#endif
return rc;
}
@@ -557,7 +575,14 @@ _libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
buflen -= len;
msglen = len;
va_start(vargs, format);
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wformat-nonliteral"
+#endif
len = vsnprintf(buffer + msglen, buflen, format, vargs);
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
va_end(vargs);
msglen += len < buflen ? len : buflen - 1;
}
@@ -709,7 +734,7 @@ int _libssh2_gettimeofday(struct timeval *tp, void *tzp)
{
(void)tzp;
if(tp) {
-#ifdef WIN32
+#ifdef _WIN32
/* Offset between 1601-01-01 and 1970-01-01 in 100 nanosec units */
#define _WIN32_FT_OFFSET (116444736000000000)
@@ -901,7 +926,6 @@ int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
}
}
else {
- *outlen = 0;
*outbuf = NULL;
}
diff --git a/libs/libssh2/src/misc.h b/libs/libssh2/src/misc.h
index bf3e3c3623..c7b090f1b8 100644
--- a/libs/libssh2/src/misc.h
+++ b/libs/libssh2/src/misc.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_MISC_H
-#define __LIBSSH2_MISC_H
+#ifndef LIBSSH2_MISC_H
+#define LIBSSH2_MISC_H
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
@@ -44,8 +44,7 @@
(void)(buf); \
(void)(size); \
} while(0)
-#else
-#ifdef WIN32
+#elif defined(_WIN32)
#define _libssh2_explicit_zero(buf, size) SecureZeroMemory(buf, size)
#elif defined(HAVE_EXPLICIT_BZERO)
#define _libssh2_explicit_zero(buf, size) explicit_bzero(buf, size)
@@ -58,7 +57,6 @@
void _libssh2_memzero(void *buf, size_t size);
#define _libssh2_explicit_zero(buf, size) _libssh2_memzero(buf, size)
#endif
-#endif
struct list_head {
struct list_node *last;
@@ -81,6 +79,11 @@ int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags);
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg);
+#ifdef _WIN32
+/* Convert Win32 WSAGetLastError to errno equivalent */
+int _libssh2_wsa2errno(void);
+#endif
+
void _libssh2_list_init(struct list_head *head);
/* add a node last in the list */
@@ -139,4 +142,4 @@ void _libssh2_xor_data(unsigned char *output,
void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length);
-#endif /* _LIBSSH2_MISC_H */
+#endif /* LIBSSH2_MISC_H */
diff --git a/libs/libssh2/src/openssl.c b/libs/libssh2/src/openssl.c
index 2dc2340c3b..31220f9cc8 100644
--- a/libs/libssh2/src/openssl.c
+++ b/libs/libssh2/src/openssl.c
@@ -44,16 +44,161 @@
#include <stdlib.h>
#include <assert.h>
-#ifndef EVP_MAX_BLOCK_LENGTH
-#define EVP_MAX_BLOCK_LENGTH 32
+int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
+{
+#ifdef USE_OPENSSL_3
+ *ctx = NULL;
+ return 1;
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ *ctx = HMAC_CTX_new();
+ return *ctx ? 1 : 0;
+#else
+ HMAC_CTX_init(ctx);
+ return 1;
#endif
+}
-int
-read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session,
- const char *key_type,
- const char *filedata,
- size_t filedata_len,
- unsigned const char *passphrase);
+#ifdef USE_OPENSSL_3
+static int _libssh2_hmac_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen,
+ const char *digest_name)
+{
+ EVP_MAC* mac;
+ OSSL_PARAM params[3];
+
+ mac = EVP_MAC_fetch(NULL, OSSL_MAC_NAME_HMAC, NULL);
+ if(!mac)
+ return 0;
+
+ *ctx = EVP_MAC_CTX_new(mac);
+ EVP_MAC_free(mac);
+ if(!*ctx)
+ return 0;
+
+ params[0] = OSSL_PARAM_construct_octet_string(
+ OSSL_MAC_PARAM_KEY, (void *)key, keylen);
+ params[1] = OSSL_PARAM_construct_utf8_string(
+ OSSL_MAC_PARAM_DIGEST, (char *)digest_name, 0);
+ params[2] = OSSL_PARAM_construct_end();
+
+ return EVP_MAC_init(*ctx, NULL, 0, params);
+}
+#endif
+
+#if LIBSSH2_MD5
+int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+#ifdef USE_OPENSSL_3
+ return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_MD5);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_md5(), NULL);
+#else
+ return HMAC_Init_ex(ctx, key, (int)keylen, EVP_md5(), NULL);
+#endif
+}
+#endif
+
+#if LIBSSH2_HMAC_RIPEMD
+int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+#ifdef USE_OPENSSL_3
+ return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_RIPEMD160);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_ripemd160(), NULL);
+#else
+ return HMAC_Init_ex(ctx, key, (int)keylen, EVP_ripemd160(), NULL);
+#endif
+}
+#endif
+
+int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+#ifdef USE_OPENSSL_3
+ return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_SHA1);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_sha1(), NULL);
+#else
+ return HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha1(), NULL);
+#endif
+}
+
+int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+#ifdef USE_OPENSSL_3
+ return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_SHA2_256);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_sha256(), NULL);
+#else
+ return HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha256(), NULL);
+#endif
+}
+
+int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
+ void *key, size_t keylen)
+{
+#ifdef USE_OPENSSL_3
+ return _libssh2_hmac_init(ctx, key, keylen, OSSL_DIGEST_NAME_SHA2_512);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ return HMAC_Init_ex(*ctx, key, (int)keylen, EVP_sha512(), NULL);
+#else
+ return HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha512(), NULL);
+#endif
+}
+
+int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
+ const void *data, size_t datalen)
+{
+#ifdef USE_OPENSSL_3
+ return EVP_MAC_update(*ctx, data, datalen);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+/* FIXME: upstream bug as of v5.6.0: datalen is int instead of size_t */
+#if defined(LIBSSH2_WOLFSSL)
+ return HMAC_Update(*ctx, data, (int)datalen);
+#else /* !LIBSSH2_WOLFSSL */
+ return HMAC_Update(*ctx, data, datalen);
+#endif /* LIBSSH2_WOLFSSL */
+#else
+ return HMAC_Update(ctx, data, datalen);
+#endif
+}
+
+int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
+{
+#ifdef USE_OPENSSL_3
+ return EVP_MAC_final(*ctx, data, NULL, MAX_MACSIZE);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ return HMAC_Final(*ctx, data, NULL);
+#else
+ return HMAC_Final(ctx, data, NULL);
+#endif
+}
+
+void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
+{
+#ifdef USE_OPENSSL_3
+ EVP_MAC_CTX_free(*ctx);
+#elif defined(HAVE_OPAQUE_STRUCTS)
+ HMAC_CTX_free(*ctx);
+#else
+ HMAC_cleanup(ctx);
+#endif
+}
+
+static int
+_libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
+ void **key_ctx,
+ const char *key_type,
+ unsigned char **method,
+ size_t *method_len,
+ unsigned char **pubkeydata,
+ size_t *pubkeydata_len,
+ const char *privatekeydata,
+ size_t privatekeydata_len,
+ unsigned const char *passphrase);
static int
_libssh2_sk_pub_openssh_keyfilememory(LIBSSH2_SESSION *session,
@@ -92,6 +237,20 @@ write_bn(unsigned char *buf, const BIGNUM *bn, int bn_bytes)
}
#endif
+static inline void
+_libssh2_swap_bytes(unsigned char *buf, unsigned long len)
+{
+#if !defined(WORDS_BIGENDIAN) || !WORDS_BIGENDIAN
+ unsigned long i, j;
+ unsigned char temp;
+ for(i = 0, j = len - 1; i < j; i++, j--) {
+ temp = buf[i];
+ buf[i] = buf[j];
+ buf[j] = temp;
+ }
+#endif
+}
+
int
_libssh2_openssl_random(void *buf, size_t len)
{
@@ -121,6 +280,76 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
unsigned long e2len,
const unsigned char *coeffdata, unsigned long coefflen)
{
+#ifdef USE_OPENSSL_3
+ int ret = 0;
+ EVP_PKEY_CTX *ctx;
+ OSSL_PARAM params[4];
+ int param_num = 0;
+ unsigned char *nbuf = NULL;
+ unsigned char *ebuf = NULL;
+ unsigned char *dbuf = NULL;
+
+ (void)pdata;
+ (void)plen;
+ (void)qdata;
+ (void)qlen;
+ (void)e1data;
+ (void)e1len;
+ (void)e2data;
+ (void)e2len;
+ (void)coeffdata;
+ (void)coefflen;
+
+ if(ndata && nlen > 0) {
+ nbuf = OPENSSL_malloc(nlen);
+
+ if(nbuf) {
+ memcpy(nbuf, ndata, nlen);
+ _libssh2_swap_bytes(nbuf, nlen);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_N, nbuf, nlen);
+ }
+ }
+
+ if(edata && elen > 0) {
+ ebuf = OPENSSL_malloc(elen);
+ if(ebuf) {
+ memcpy(ebuf, edata, elen);
+ _libssh2_swap_bytes(ebuf, elen);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_E, ebuf, elen);
+ }
+ }
+
+ if(ddata && dlen > 0) {
+ dbuf = OPENSSL_malloc(dlen);
+ if(dbuf) {
+ memcpy(dbuf, ddata, dlen);
+ _libssh2_swap_bytes(dbuf, dlen);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_RSA_D, dbuf, dlen);
+ }
+ }
+
+ params[param_num] = OSSL_PARAM_construct_end();
+
+ *rsa = NULL;
+ ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
+
+ if(EVP_PKEY_fromdata_init(ctx) > 0) {
+ ret = EVP_PKEY_fromdata(ctx, rsa, EVP_PKEY_KEYPAIR, params);
+ }
+ if(nbuf)
+ OPENSSL_clear_free(nbuf, nlen);
+
+ if(ebuf)
+ OPENSSL_clear_free(ebuf, elen);
+
+ if(dbuf)
+ OPENSSL_clear_free(dbuf, dlen);
+
+ return (ret == 1) ? 0 : -1;
+#else
BIGNUM * e;
BIGNUM * n;
BIGNUM * d = 0;
@@ -180,6 +409,8 @@ _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
(*rsa)->iqmp = iqmp;
#endif
return 0;
+
+#endif /* USE_OPENSSL_3 */
}
int
@@ -189,6 +420,11 @@ _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
size_t sig_len,
const unsigned char *m, size_t m_len)
{
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = NULL;
+ const EVP_MD *md = NULL;
+#endif
+
int ret;
int nid_type;
unsigned char *hash = malloc(hash_len);
@@ -202,7 +438,6 @@ _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
else if(hash_len == SHA256_DIGEST_LENGTH) {
nid_type = NID_sha256;
ret = _libssh2_sha256(m, m_len, hash);
-
}
else if(hash_len == SHA512_DIGEST_LENGTH) {
nid_type = NID_sha512;
@@ -222,9 +457,37 @@ _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsactx,
return -1; /* failure */
}
+#ifdef USE_OPENSSL_3
+ ctx = EVP_PKEY_CTX_new(rsactx, NULL);
+
+ if(nid_type == NID_sha1) {
+ md = EVP_sha1();
+ }
+ else if(nid_type == NID_sha256) {
+ md = EVP_sha256();
+ }
+ else if(nid_type == NID_sha512) {
+ md = EVP_sha512();
+ }
+
+ if(ctx && md) {
+ if(EVP_PKEY_verify_init(ctx) > 0 &&
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) > 0 &&
+ EVP_PKEY_CTX_set_signature_md(ctx, md) > 0) {
+ ret = EVP_PKEY_verify(ctx, sig, sig_len, hash, hash_len);
+ }
+ }
+
+ if(ctx) {
+ EVP_PKEY_CTX_free(ctx);
+ }
+
+#else
+
ret = RSA_verify(nid_type, hash, (unsigned int) hash_len,
(unsigned char *) sig,
(unsigned int) sig_len, rsactx);
+#endif
free(hash);
@@ -257,6 +520,97 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
unsigned long y_len,
const unsigned char *x, unsigned long x_len)
{
+#ifdef USE_OPENSSL_3
+ int ret = 0;
+ EVP_PKEY_CTX *ctx = NULL;
+ OSSL_PARAM params[6];
+ int param_num = 0;
+ unsigned char *p_buf = NULL;
+ unsigned char *q_buf = NULL;
+ unsigned char *g_buf = NULL;
+ unsigned char *y_buf = NULL;
+ unsigned char *x_buf = NULL;
+
+ if(p && p_len > 0) {
+ p_buf = OPENSSL_malloc(p_len);
+
+ if(p_buf) {
+ memcpy(p_buf, p, p_len);
+ _libssh2_swap_bytes(p_buf, p_len);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_P, p_buf, p_len);
+ }
+ }
+
+ if(q && q_len > 0) {
+ q_buf = OPENSSL_malloc(q_len);
+
+ if(q_buf) {
+ memcpy(q_buf, q, q_len);
+ _libssh2_swap_bytes(q_buf, q_len);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_Q, q_buf, q_len);
+ }
+ }
+
+ if(g && g_len > 0) {
+ g_buf = OPENSSL_malloc(g_len);
+
+ if(g_buf) {
+ memcpy(g_buf, g, g_len);
+ _libssh2_swap_bytes(g_buf, g_len);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_FFC_G, g_buf, g_len);
+ }
+ }
+
+ if(y && y_len > 0) {
+ y_buf = OPENSSL_malloc(y_len);
+
+ if(y_buf) {
+ memcpy(y_buf, y, y_len);
+ _libssh2_swap_bytes(y_buf, y_len);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PUB_KEY, y_buf, y_len);
+ }
+ }
+
+ if(x && x_len > 0) {
+ x_buf = OPENSSL_malloc(x_len);
+
+ if(x_buf) {
+ memcpy(x_buf, x, x_len);
+ _libssh2_swap_bytes(x_buf, x_len);
+ params[param_num++] =
+ OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY,
+ x_buf, x_len);
+ }
+ }
+
+ params[param_num] = OSSL_PARAM_construct_end();
+
+ *dsactx = NULL;
+ ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL);
+
+ if(EVP_PKEY_fromdata_init(ctx) > 0) {
+ ret = EVP_PKEY_fromdata(ctx, dsactx, EVP_PKEY_KEYPAIR, params);
+ }
+
+ if(p_buf)
+ OPENSSL_clear_free(p_buf, p_len);
+ if(q_buf)
+ OPENSSL_clear_free(q_buf, q_len);
+ if(g_buf)
+ OPENSSL_clear_free(g_buf, g_len);
+ if(x_buf)
+ OPENSSL_clear_free(x_buf, x_len);
+ if(y_buf)
+ OPENSSL_clear_free(y_buf, y_len);
+
+ return (ret == 1) ? 0 : -1;
+
+#else
+
BIGNUM * p_bn;
BIGNUM * q_bn;
BIGNUM * g_bn;
@@ -297,6 +651,8 @@ _libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
(*dsactx)->priv_key = priv_key;
#endif
return 0;
+
+#endif /* USE_OPENSSL_3 */
}
int
@@ -304,6 +660,12 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, size_t m_len)
{
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = NULL;
+ unsigned char *der = NULL;
+ int der_len = 0;
+#endif
+
unsigned char hash[SHA_DIGEST_LENGTH];
DSA_SIG * dsasig;
BIGNUM * r;
@@ -322,9 +684,30 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
dsasig->r = r;
dsasig->s = s;
#endif
+
+#ifdef USE_OPENSSL_3
+ ctx = EVP_PKEY_CTX_new(dsactx, NULL);
+ der_len = i2d_DSA_SIG(dsasig, &der);
+
+ if(ctx && !_libssh2_sha1(m, m_len, hash)) {
+ /* _libssh2_sha1() succeeded */
+ if(EVP_PKEY_verify_init(ctx) > 0) {
+ ret = EVP_PKEY_verify(ctx, der, der_len, hash, SHA_DIGEST_LENGTH);
+ }
+ }
+
+ if(ctx) {
+ EVP_PKEY_CTX_free(ctx);
+ }
+
+ if(der) {
+ OPENSSL_clear_free(der, der_len);
+ }
+#else
if(!_libssh2_sha1(m, m_len, hash))
/* _libssh2_sha1() succeeded */
ret = DSA_do_verify(hash, SHA_DIGEST_LENGTH, dsasig, dsactx);
+#endif
DSA_SIG_free(dsasig);
@@ -343,8 +726,25 @@ _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
libssh2_curve_type
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx)
{
+#ifdef USE_OPENSSL_3
+ int bits = 0;
+ EVP_PKEY_get_int_param(ec_ctx, OSSL_PKEY_PARAM_BITS, &bits);
+
+ if(bits == 256) {
+ return LIBSSH2_EC_CURVE_NISTP256;
+ }
+ else if(bits == 384) {
+ return LIBSSH2_EC_CURVE_NISTP384;
+ }
+ else if(bits == 521) {
+ return LIBSSH2_EC_CURVE_NISTP521;
+ }
+
+ return LIBSSH2_EC_CURVE_NISTP256;
+#else
const EC_GROUP *group = EC_KEY_get0_group(ec_ctx);
return EC_GROUP_get_curve_name(group);
+#endif
}
/* _libssh2_ecdsa_curve_type_from_name
@@ -390,13 +790,56 @@ _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx,
const unsigned char *k,
size_t k_len, libssh2_curve_type curve)
{
-
int ret = 0;
- const EC_GROUP *ec_group = NULL;
+
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+ const char *n = EC_curve_nid2nist(curve);
+ char *group_name = NULL;
+ unsigned char *data = NULL;
+
+ if(n) {
+ group_name = OPENSSL_zalloc(strlen(n) + 1);
+ }
+
+ if(k_len > 0) {
+ data = OPENSSL_malloc(k_len);
+ }
+
+ if(group_name && data) {
+ OSSL_PARAM params[3] = { 0 };
+
+ memcpy(group_name, n, strlen(n));
+ memcpy(data, k, k_len);
+
+ params[0] =
+ OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
+ group_name, 0);
+
+ params[1] =
+ OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
+ data, k_len);
+
+ params[2] = OSSL_PARAM_construct_end();
+
+ if(EVP_PKEY_fromdata_init(ctx) > 0) {
+ ret = EVP_PKEY_fromdata(ctx, ec_ctx, EVP_PKEY_PUBLIC_KEY,
+ params);
+ }
+
+ if(group_name)
+ OPENSSL_clear_free(group_name, strlen(n));
+
+ if(data)
+ OPENSSL_clear_free(data, k_len);
+ }
+#else
EC_KEY *ec_key = EC_KEY_new_by_curve_name(curve);
- EC_POINT *point = NULL;
if(ec_key) {
+ const EC_GROUP *ec_group = NULL;
+ EC_POINT *point = NULL;
+
ec_group = EC_KEY_get0_group(ec_key);
point = EC_POINT_new(ec_group);
ret = EC_POINT_oct2point(ec_group, point, k, k_len, NULL);
@@ -408,27 +851,51 @@ _libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ec_ctx,
if(ec_ctx)
*ec_ctx = ec_key;
}
+#endif
return (ret == 1) ? 0 : -1;
}
+#ifdef USE_OPENSSL_3
#define LIBSSH2_ECDSA_VERIFY(digest_type) \
do { \
unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
- libssh2_sha##digest_type(m, m_len, hash); \
- ret = ECDSA_do_verify(hash, SHA##digest_type##_DIGEST_LENGTH, \
- ecdsa_sig, ec_key); \
+ if(libssh2_sha##digest_type(m, m_len, hash) == 0) { \
+ ret = EVP_PKEY_verify_init(ctx); \
+ if(ret > 0) { \
+ ret = EVP_PKEY_verify(ctx, der, der_len, hash, \
+ SHA##digest_type##_DIGEST_LENGTH); \
+ } \
+ } \
} while(0)
+#else
+#define LIBSSH2_ECDSA_VERIFY(digest_type) \
+ do { \
+ unsigned char hash[SHA##digest_type##_DIGEST_LENGTH]; \
+ if(libssh2_sha##digest_type(m, m_len, hash) == 0) { \
+ ret = ECDSA_do_verify(hash, \
+ SHA##digest_type##_DIGEST_LENGTH, \
+ ecdsa_sig, ec_key); \
+ } \
+ } while(0)
+#endif
int
-_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
+_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ecdsa_ctx,
const unsigned char *r, size_t r_len,
const unsigned char *s, size_t s_len,
const unsigned char *m, size_t m_len)
{
int ret = 0;
- EC_KEY *ec_key = (EC_KEY*)ctx;
- libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ec_key);
+ libssh2_curve_type type = _libssh2_ecdsa_get_curve_type(ecdsa_ctx);
+
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = NULL;
+ unsigned char *der = NULL;
+ int der_len = 0;
+#else
+ EC_KEY *ec_key = (EC_KEY*)ecdsa_ctx;
+#endif
#ifdef HAVE_OPAQUE_STRUCTS
ECDSA_SIG *ecdsa_sig = ECDSA_SIG_new();
@@ -438,7 +905,6 @@ _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
BN_bin2bn(r, (int) r_len, pr);
BN_bin2bn(s, (int) s_len, ps);
ECDSA_SIG_set0(ecdsa_sig, pr, ps);
-
#else
ECDSA_SIG ecdsa_sig_;
ECDSA_SIG *ecdsa_sig = &ecdsa_sig_;
@@ -448,6 +914,11 @@ _libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
BN_bin2bn(s, (int) s_len, ecdsa_sig_.s);
#endif
+#ifdef USE_OPENSSL_3
+ ctx = EVP_PKEY_CTX_new(ecdsa_ctx, NULL);
+ der_len = i2d_ECDSA_SIG(ecdsa_sig, &der);
+#endif
+
if(type == LIBSSH2_EC_CURVE_NISTP256) {
LIBSSH2_ECDSA_VERIFY(256);
}
@@ -502,6 +973,10 @@ _libssh2_cipher_init(_libssh2_cipher_ctx * h,
#endif
}
+#ifndef EVP_MAX_BLOCK_LENGTH
+#define EVP_MAX_BLOCK_LENGTH 32
+#endif
+
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
@@ -568,8 +1043,7 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
#endif
}
-#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || \
- defined(LIBSSH2_WOLFSSL)
+#if defined(USE_OPENSSL_3) || defined(LIBSSH2_WOLFSSL)
if(ret != -1)
#else
if(ret >= 1)
@@ -617,13 +1091,8 @@ _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
void _libssh2_openssl_crypto_init(void)
{
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L && \
- !defined(LIBRESSL_VERSION_NUMBER)
-#ifndef OPENSSL_NO_ENGINE
- ENGINE_load_builtin_engines();
- ENGINE_register_all_complete();
-#endif
-#else
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
@@ -632,6 +1101,9 @@ void _libssh2_openssl_crypto_init(void)
ENGINE_register_all_complete();
#endif
#endif
+#if defined(LIBSSH2_WOLFSSL) && defined(DEBUG_WOLFSSL)
+ wolfSSL_Debugging_ON();
+#endif
}
void _libssh2_openssl_crypto_exit(void)
@@ -717,43 +1189,69 @@ read_private_key_from_file(void **key_ctx,
int
_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
- const char *filedata, size_t filedata_len,
+ const char *filedata,
+ size_t filedata_len,
unsigned const char *passphrase)
{
int rc;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_rsa =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
pem_read_bio_func read_rsa =
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
+#endif
_libssh2_init_if_needed();
- rc = read_private_key_from_memory((void **) rsa, read_rsa,
- filedata, filedata_len, passphrase);
+ rc = read_private_key_from_memory((void **)rsa, read_rsa,
+ filedata, filedata_len,
+ passphrase);
if(rc) {
- rc = read_openssh_private_key_from_memory((void **)rsa, session,
- "ssh-rsa", filedata, filedata_len, passphrase);
+ rc = _libssh2_pub_priv_openssh_keyfilememory(session, (void **)rsa,
+ "ssh-rsa",
+ NULL, NULL, NULL, NULL,
+ filedata, filedata_len,
+ passphrase);
}
return rc;
}
static unsigned char *
-gen_publickey_from_rsa(LIBSSH2_SESSION *session, RSA *rsa,
+gen_publickey_from_rsa(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsa,
size_t *key_len)
{
int e_bytes, n_bytes;
unsigned long len;
unsigned char *key;
unsigned char *p;
+
+#ifdef USE_OPENSSL_3
+ BIGNUM * e = NULL;
+ BIGNUM * n = NULL;
+
+ EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_E, &e);
+ EVP_PKEY_get_bn_param(rsa, OSSL_PKEY_PARAM_RSA_N, &n);
+#else
const BIGNUM * e;
const BIGNUM * n;
-#ifdef HAVE_OPAQUE_STRUCTS
+#if defined(HAVE_OPAQUE_STRUCTS)
+ e = NULL;
+ n = NULL;
+
RSA_get0_key(rsa, &n, &e, NULL);
#else
e = rsa->e;
n = rsa->n;
#endif
+#endif
+ if(!e || !n) {
+ return NULL;
+ }
+
e_bytes = BN_num_bytes(e) + 1;
n_bytes = BN_num_bytes(n) + 1;
@@ -788,7 +1286,7 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
size_t *pubkeydata_len,
EVP_PKEY *pk)
{
- RSA* rsa = NULL;
+ libssh2_rsa_ctx* rsa = NULL;
unsigned char *key;
unsigned char *method_buf = NULL;
size_t key_len;
@@ -797,7 +1295,11 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
LIBSSH2_TRACE_AUTH,
"Computing public key from RSA private key envelope"));
+#ifdef USE_OPENSSL_3
+ rsa = pk;
+#else
rsa = EVP_PKEY_get1_RSA(pk);
+#endif
if(!rsa) {
/* Assume memory allocation error... what else could it be ? */
goto __alloc_error;
@@ -812,19 +1314,27 @@ gen_publickey_from_rsa_evp(LIBSSH2_SESSION *session,
if(!key) {
goto __alloc_error;
}
+#ifndef USE_OPENSSL_3
RSA_free(rsa);
+#endif
memcpy(method_buf, "ssh-rsa", 7);
- *method = method_buf;
- *method_len = 7;
- *pubkeydata = key;
- *pubkeydata_len = key_len;
+ *method = method_buf;
+ if(method_len) {
+ *method_len = 7;
+ }
+ *pubkeydata = key;
+ if(pubkeydata_len) {
+ *pubkeydata_len = key_len;
+ }
return 0;
__alloc_error:
+#ifndef USE_OPENSSL_3
if(rsa) {
RSA_free(rsa);
}
+#endif
if(method_buf) {
LIBSSH2_FREE(session, method_buf);
}
@@ -834,7 +1344,8 @@ __alloc_error:
"Unable to allocate memory for private key data");
}
-static int _libssh2_rsa_new_additional_parameters(RSA *rsa)
+#ifndef USE_OPENSSL_3
+static int _libssh2_rsa_new_additional_parameters(libssh2_rsa_ctx *rsa)
{
BN_CTX *ctx = NULL;
BIGNUM *aux = NULL;
@@ -905,6 +1416,7 @@ out:
return rc;
}
+#endif /* ndef USE_OPENSSL_3 */
static int
gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session,
@@ -918,7 +1430,7 @@ gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session,
int rc = 0;
size_t nlen, elen, dlen, plen, qlen, coefflen, commentlen;
unsigned char *n, *e, *d, *p, *q, *coeff, *comment;
- RSA *rsa = NULL;
+ libssh2_rsa_ctx *rsa = NULL;
_libssh2_debug((session,
LIBSSH2_TRACE_AUTH,
@@ -983,32 +1495,40 @@ gen_publickey_from_rsa_openssh_priv_data(LIBSSH2_SESSION *session,
goto fail;
}
+#ifndef USE_OPENSSL_3
if(rsa)
rc = _libssh2_rsa_new_additional_parameters(rsa);
+#endif
if(rsa && pubkeydata && method) {
+#ifdef USE_OPENSSL_3
+ EVP_PKEY *pk = rsa;
+#else
EVP_PKEY *pk = EVP_PKEY_new();
EVP_PKEY_set1_RSA(pk, rsa);
+#endif
rc = gen_publickey_from_rsa_evp(session, method, method_len,
pubkeydata, pubkeydata_len,
pk);
+#ifndef USE_OPENSSL_3
if(pk)
EVP_PKEY_free(pk);
+#endif
}
if(rsa_ctx)
*rsa_ctx = rsa;
else
- RSA_free(rsa);
+ _libssh2_rsa_free(rsa);
return rc;
fail:
if(rsa)
- RSA_free(rsa);
+ _libssh2_rsa_free(rsa);
return _libssh2_error(session,
LIBSSH2_ERROR_ALLOC,
@@ -1058,8 +1578,8 @@ _libssh2_rsa_new_openssh_private(libssh2_rsa_ctx ** rsa,
if(strcmp("ssh-rsa", (const char *)buf) == 0) {
rc = gen_publickey_from_rsa_openssh_priv_data(session, decrypted,
- NULL, 0,
- NULL, 0, rsa);
+ NULL, NULL,
+ NULL, NULL, rsa);
}
else {
rc = -1;
@@ -1078,8 +1598,13 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
{
int rc;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_rsa =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
pem_read_bio_func read_rsa =
(pem_read_bio_func) &PEM_read_bio_RSAPrivateKey;
+#endif
_libssh2_init_if_needed();
@@ -1099,13 +1624,19 @@ _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
int
_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
- const char *filedata, size_t filedata_len,
+ const char *filedata,
+ size_t filedata_len,
unsigned const char *passphrase)
{
int rc;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_dsa =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
pem_read_bio_func read_dsa =
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
+#endif
_libssh2_init_if_needed();
@@ -1114,17 +1645,18 @@ _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
passphrase);
if(rc) {
- rc = read_openssh_private_key_from_memory((void **)dsa, session,
- "ssh-dsa",
- filedata, filedata_len,
- passphrase);
+ rc = _libssh2_pub_priv_openssh_keyfilememory(session, (void **)dsa,
+ "ssh-dsa",
+ NULL, NULL, NULL, NULL,
+ filedata, filedata_len,
+ passphrase);
}
return rc;
}
static unsigned char *
-gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
+gen_publickey_from_dsa(LIBSSH2_SESSION* session, libssh2_dsa_ctx *dsa,
size_t *key_len)
{
int p_bytes, q_bytes, g_bytes, k_bytes;
@@ -1132,6 +1664,17 @@ gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
unsigned char *key;
unsigned char *p;
+#ifdef USE_OPENSSL_3
+ BIGNUM * p_bn;
+ BIGNUM * q;
+ BIGNUM * g;
+ BIGNUM * pub_key;
+
+ EVP_PKEY_get_bn_param(dsa, OSSL_PKEY_PARAM_FFC_P, &p_bn);
+ EVP_PKEY_get_bn_param(dsa, OSSL_PKEY_PARAM_FFC_G, &q);
+ EVP_PKEY_get_bn_param(dsa, OSSL_PKEY_PARAM_FFC_Q, &g);
+ EVP_PKEY_get_bn_param(dsa, OSSL_PKEY_PARAM_PUB_KEY, &pub_key);
+#else
const BIGNUM * p_bn;
const BIGNUM * q;
const BIGNUM * g;
@@ -1149,6 +1692,7 @@ gen_publickey_from_dsa(LIBSSH2_SESSION* session, DSA *dsa,
#else
pub_key = dsa->pub_key;
#endif
+#endif
p_bytes = BN_num_bytes(p_bn) + 1;
q_bytes = BN_num_bytes(q) + 1;
g_bytes = BN_num_bytes(g) + 1;
@@ -1187,7 +1731,7 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
size_t *pubkeydata_len,
EVP_PKEY *pk)
{
- DSA* dsa = NULL;
+ libssh2_dsa_ctx *dsa = NULL;
unsigned char *key;
unsigned char *method_buf = NULL;
size_t key_len;
@@ -1196,7 +1740,11 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
LIBSSH2_TRACE_AUTH,
"Computing public key from DSA private key envelope"));
+#ifdef USE_OPENSSL_3
+ dsa = pk;
+#else
dsa = EVP_PKEY_get1_DSA(pk);
+#endif
if(!dsa) {
/* Assume memory allocation error... what else could it be ? */
goto __alloc_error;
@@ -1211,19 +1759,27 @@ gen_publickey_from_dsa_evp(LIBSSH2_SESSION *session,
if(!key) {
goto __alloc_error;
}
+#ifndef USE_OPENSSL_3
DSA_free(dsa);
+#endif
memcpy(method_buf, "ssh-dss", 7);
- *method = method_buf;
- *method_len = 7;
- *pubkeydata = key;
- *pubkeydata_len = key_len;
+ *method = method_buf;
+ if(method_len) {
+ *method_len = 7;
+ }
+ *pubkeydata = key;
+ if(pubkeydata_len) {
+ *pubkeydata_len = key_len;
+ }
return 0;
__alloc_error:
+#ifndef USE_OPENSSL_3
if(dsa) {
DSA_free(dsa);
}
+#endif
if(method_buf) {
LIBSSH2_FREE(session, method_buf);
}
@@ -1245,7 +1801,7 @@ gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session,
int rc = 0;
size_t plen, qlen, glen, pub_len, priv_len;
unsigned char *p, *q, *g, *pub_key, *priv_key;
- DSA *dsa = NULL;
+ libssh2_dsa_ctx *dsa = NULL;
_libssh2_debug((session,
LIBSSH2_TRACE_AUTH,
@@ -1295,28 +1851,34 @@ gen_publickey_from_dsa_openssh_priv_data(LIBSSH2_SESSION *session,
}
if(dsa && pubkeydata && method) {
+#ifdef USE_OPENSSL_3
+ EVP_PKEY *pk = dsa;
+#else
EVP_PKEY *pk = EVP_PKEY_new();
EVP_PKEY_set1_DSA(pk, dsa);
+#endif
rc = gen_publickey_from_dsa_evp(session, method, method_len,
pubkeydata, pubkeydata_len,
pk);
+#ifndef USE_OPENSSL_3
if(pk)
EVP_PKEY_free(pk);
+#endif
}
if(dsa_ctx)
*dsa_ctx = dsa;
else
- DSA_free(dsa);
+ _libssh2_dsa_free(dsa);
return rc;
fail:
if(dsa)
- DSA_free(dsa);
+ _libssh2_dsa_free(dsa);
return _libssh2_error(session,
LIBSSH2_ERROR_ALLOC,
@@ -1366,8 +1928,8 @@ _libssh2_dsa_new_openssh_private(libssh2_dsa_ctx ** dsa,
if(strcmp("ssh-dss", (const char *)buf) == 0) {
rc = gen_publickey_from_dsa_openssh_priv_data(session, decrypted,
- NULL, 0,
- NULL, 0, dsa);
+ NULL, NULL,
+ NULL, NULL, dsa);
}
else {
rc = -1;
@@ -1386,8 +1948,13 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
{
int rc;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_dsa =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
pem_read_bio_func read_dsa =
(pem_read_bio_func) &PEM_read_bio_DSAPrivateKey;
+#endif
_libssh2_init_if_needed();
@@ -1404,7 +1971,6 @@ _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
#endif /* LIBSSH_DSA */
#if LIBSSH2_ECDSA
-
int
_libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
@@ -1414,20 +1980,26 @@ _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
{
int rc;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_ec =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
pem_read_bio_func read_ec =
(pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
+#endif
_libssh2_init_if_needed();
- rc = read_private_key_from_memory((void **) ec_ctx, read_ec,
+ rc = read_private_key_from_memory((void **)ec_ctx, read_ec,
filedata, filedata_len,
passphrase);
if(rc) {
- rc = read_openssh_private_key_from_memory((void **)ec_ctx, session,
- "ssh-ecdsa",
- filedata, filedata_len,
- passphrase);
+ rc = _libssh2_pub_priv_openssh_keyfilememory(session, (void **)ec_ctx,
+ "ssh-ecdsa",
+ NULL, NULL, NULL, NULL,
+ filedata, filedata_len,
+ passphrase);
}
return rc;
@@ -1584,10 +2156,14 @@ gen_publickey_from_ed_evp(LIBSSH2_SESSION *session,
goto fail;
}
- *method = methodBuf;
- *method_len = sizeof(methodName) - 1;
- *pubkeydata = keyBuf;
- *pubkeydata_len = bufLen;
+ *method = methodBuf;
+ if(method_len) {
+ *method_len = sizeof(methodName) - 1;
+ }
+ *pubkeydata = keyBuf;
+ if(pubkeydata_len) {
+ *pubkeydata_len = bufLen;
+ }
return 0;
fail:
@@ -1896,7 +2472,6 @@ clean_exit:
return -1;
}
-
int
_libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx,
LIBSSH2_SESSION * session,
@@ -1939,12 +2514,9 @@ _libssh2_ed25519_new_private(libssh2_ed25519_ctx ** ed_ctx,
}
if(strcmp("ssh-ed25519", (const char *)buf) == 0) {
- rc = gen_publickey_from_ed25519_openssh_priv_data(session,
- decrypted,
- NULL,
- NULL,
- NULL,
- NULL,
+ rc = gen_publickey_from_ed25519_openssh_priv_data(session, decrypted,
+ NULL, NULL,
+ NULL, NULL,
&ctx);
}
else {
@@ -2013,10 +2585,8 @@ _libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx,
if(strcmp("sk-ssh-ed25519@openssh.com", (const char *)buf) == 0) {
rc = gen_publickey_from_sk_ed25519_openssh_priv_data(session,
decrypted,
- NULL,
- NULL,
- NULL,
- NULL,
+ NULL, NULL,
+ NULL, NULL,
flags,
application,
key_handle,
@@ -2066,10 +2636,11 @@ _libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx ** ed_ctx,
return 0;
}
- return read_openssh_private_key_from_memory((void **)ed_ctx, session,
- "ssh-ed25519",
- filedata, filedata_len,
- passphrase);
+ return _libssh2_pub_priv_openssh_keyfilememory(session, (void **)ed_ctx,
+ "ssh-ed25519",
+ NULL, NULL, NULL, NULL,
+ filedata, filedata_len,
+ passphrase);
}
int
@@ -2136,17 +2707,57 @@ _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
size_t hash_len,
unsigned char **signature, size_t *signature_len)
{
- int ret;
- unsigned char *sig;
- unsigned int sig_len;
+ int ret = -1;
+ unsigned char *sig = NULL;
+
+#ifdef USE_OPENSSL_3
+ size_t sig_len = 0;
+ BIGNUM *n = NULL;
+ const EVP_MD *md = NULL;
+
+ if(EVP_PKEY_get_bn_param(rsactx, OSSL_PKEY_PARAM_RSA_N, &n) > 0) {
+ sig_len = BN_num_bytes(n);
+ }
+
+ if(sig_len > 0)
+ sig = LIBSSH2_ALLOC(session, sig_len);
+#else
+ unsigned int sig_len = 0;
sig_len = RSA_size(rsactx);
sig = LIBSSH2_ALLOC(session, sig_len);
+#endif
if(!sig) {
return -1;
}
+#ifdef USE_OPENSSL_3
+ if(hash_len == SHA_DIGEST_LENGTH)
+ md = EVP_sha1();
+ else if(hash_len == SHA256_DIGEST_LENGTH)
+ md = EVP_sha256();
+ else if(hash_len == SHA512_DIGEST_LENGTH)
+ md = EVP_sha512();
+ else {
+ _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unsupported hash digest length");
+ }
+
+ if(md) {
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(rsactx, NULL);
+ if(ctx &&
+ EVP_PKEY_sign_init(ctx) > 0 &&
+ EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) > 0 &&
+ EVP_PKEY_CTX_set_signature_md(ctx, md) > 0) {
+ ret = EVP_PKEY_sign(ctx, sig, &sig_len, hash, hash_len);
+ }
+
+ if(ctx) {
+ EVP_PKEY_CTX_free(ctx);
+ }
+ }
+#else
if(hash_len == SHA_DIGEST_LENGTH)
ret = RSA_sign(NID_sha1,
hash, (unsigned int) hash_len, sig, &sig_len, rsactx);
@@ -2161,6 +2772,7 @@ _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
"Unsupported hash digest length");
ret = -1;
}
+#endif
if(!ret) {
LIBSSH2_FREE(session, sig);
@@ -2193,14 +2805,41 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
size_t hash_len, unsigned char *signature)
{
- DSA_SIG *sig;
+ DSA_SIG *sig = NULL;
const BIGNUM * r;
const BIGNUM * s;
int r_len, s_len;
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(dsactx, NULL);
+ unsigned char *buf = NULL;
+ size_t sig_len = 0;
+ int size = 0;
+
+ if(EVP_PKEY_get_int_param(dsactx, OSSL_PKEY_PARAM_MAX_SIZE, &size) > 0) {
+ sig_len = size;
+ buf = OPENSSL_malloc(size);
+ }
+
+ if(buf && ctx && EVP_PKEY_sign_init(ctx) > 0) {
+ EVP_PKEY_sign(ctx, buf, &sig_len, hash, hash_len);
+ }
+
+ if(ctx) {
+ EVP_PKEY_CTX_free(ctx);
+ }
+
+ if(buf) {
+ const unsigned char *in = buf;
+ d2i_DSA_SIG(&sig, &in, (long)sig_len);
+ OPENSSL_clear_free(buf, size);
+ }
+#else
(void)hash_len;
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
+#endif
+
if(!sig) {
return -1;
}
@@ -2212,20 +2851,20 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
s = sig->s;
#endif
r_len = BN_num_bytes(r);
- if(r_len < 1 || r_len > 20) {
+ if(r_len < 1 || r_len > SHA_DIGEST_LENGTH) {
DSA_SIG_free(sig);
return -1;
}
s_len = BN_num_bytes(s);
- if(s_len < 1 || s_len > 20) {
+ if(s_len < 1 || s_len > SHA_DIGEST_LENGTH) {
DSA_SIG_free(sig);
return -1;
}
- memset(signature, 0, 40);
+ memset(signature, 0, SHA_DIGEST_LENGTH * 2);
- BN_bn2bin(r, signature + (20 - r_len));
- BN_bn2bin(s, signature + 20 + (20 - s_len));
+ BN_bn2bin(r, signature + (SHA_DIGEST_LENGTH - r_len));
+ BN_bn2bin(s, signature + SHA_DIGEST_LENGTH + (SHA_DIGEST_LENGTH - s_len));
DSA_SIG_free(sig);
@@ -2247,10 +2886,47 @@ _libssh2_ecdsa_sign(LIBSSH2_SESSION * session, libssh2_ecdsa_ctx * ec_ctx,
const BIGNUM *pr = NULL, *ps = NULL;
unsigned char *temp_buffer = NULL;
unsigned char *out_buffer = NULL;
+ ECDSA_SIG *sig = NULL;
+
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(ec_ctx, NULL);
+ const unsigned char *p = NULL;
+ rc = -1;
+
+ if(!ctx) {
+ return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+ "out of memory");
+ }
+
+ out_buffer_len = EVP_PKEY_get_size(ec_ctx);
+ temp_buffer = LIBSSH2_ALLOC(session, out_buffer_len);
+ if(!temp_buffer) {
+ goto clean_exit;
+ }
+
+ rc = EVP_PKEY_sign_init(ctx);
+ if(rc <= 0) {
+ rc = -1;
+ goto clean_exit;
+ }
+
+ rc = EVP_PKEY_sign(ctx, temp_buffer, &out_buffer_len, hash, hash_len);
+ if(rc <= 0) {
+ rc = -1;
+ goto clean_exit;
+ }
- ECDSA_SIG *sig = ECDSA_do_sign(hash, (int) hash_len, ec_ctx);
+ rc = 0;
+
+ p = temp_buffer;
+ sig = d2i_ECDSA_SIG(NULL, &p, (long)out_buffer_len);
+ OPENSSL_clear_free(temp_buffer, out_buffer_len);
+#else
+ sig = ECDSA_do_sign(hash, (int)hash_len, ec_ctx);
if(!sig)
return -1;
+#endif
+
#ifdef HAVE_OPAQUE_STRUCTS
ECDSA_SIG_get0(sig, &pr, &ps);
#else
@@ -2292,6 +2968,11 @@ clean_exit:
if(sig)
ECDSA_SIG_free(sig);
+#ifdef USE_OPENSSL_3
+ if(ctx)
+ EVP_PKEY_CTX_free(ctx);
+#endif
+
return rc;
}
#endif /* LIBSSH2_ECDSA */
@@ -2319,6 +3000,30 @@ _libssh2_sha1_init(libssh2_sha1_ctx *ctx)
}
int
+_libssh2_sha1_update(libssh2_sha1_ctx *ctx,
+ const void *data, size_t len)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ return EVP_DigestUpdate(*ctx, data, len);
+#else
+ return EVP_DigestUpdate(ctx, data, len);
+#endif
+}
+
+int
+_libssh2_sha1_final(libssh2_sha1_ctx *ctx,
+ unsigned char *out)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ int ret = EVP_DigestFinal(*ctx, out, NULL);
+ EVP_MD_CTX_free(*ctx);
+ return ret;
+#else
+ return EVP_DigestFinal(ctx, out, NULL);
+#endif
+}
+
+int
_libssh2_sha1(const unsigned char *message, size_t len,
unsigned char *out)
{
@@ -2371,6 +3076,30 @@ _libssh2_sha256_init(libssh2_sha256_ctx *ctx)
}
int
+_libssh2_sha256_update(libssh2_sha256_ctx *ctx,
+ const void *data, size_t len)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ return EVP_DigestUpdate(*ctx, data, len);
+#else
+ return EVP_DigestUpdate(ctx, data, len);
+#endif
+}
+
+int
+_libssh2_sha256_final(libssh2_sha256_ctx *ctx,
+ unsigned char *out)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ int ret = EVP_DigestFinal(*ctx, out, NULL);
+ EVP_MD_CTX_free(*ctx);
+ return ret;
+#else
+ return EVP_DigestFinal(ctx, out, NULL);
+#endif
+}
+
+int
_libssh2_sha256(const unsigned char *message, size_t len,
unsigned char *out)
{
@@ -2423,6 +3152,30 @@ _libssh2_sha384_init(libssh2_sha384_ctx *ctx)
}
int
+_libssh2_sha384_update(libssh2_sha384_ctx *ctx,
+ const void *data, size_t len)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ return EVP_DigestUpdate(*ctx, data, len);
+#else
+ return EVP_DigestUpdate(ctx, data, len);
+#endif
+}
+
+int
+_libssh2_sha384_final(libssh2_sha384_ctx *ctx,
+ unsigned char *out)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ int ret = EVP_DigestFinal(*ctx, out, NULL);
+ EVP_MD_CTX_free(*ctx);
+ return ret;
+#else
+ return EVP_DigestFinal(ctx, out, NULL);
+#endif
+}
+
+int
_libssh2_sha384(const unsigned char *message, size_t len,
unsigned char *out)
{
@@ -2475,6 +3228,30 @@ _libssh2_sha512_init(libssh2_sha512_ctx *ctx)
}
int
+_libssh2_sha512_update(libssh2_sha512_ctx *ctx,
+ const void *data, size_t len)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ return EVP_DigestUpdate(*ctx, data, len);
+#else
+ return EVP_DigestUpdate(ctx, data, len);
+#endif
+}
+
+int
+_libssh2_sha512_final(libssh2_sha512_ctx *ctx,
+ unsigned char *out)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ int ret = EVP_DigestFinal(*ctx, out, NULL);
+ EVP_MD_CTX_free(*ctx);
+ return ret;
+#else
+ return EVP_DigestFinal(ctx, out, NULL);
+#endif
+}
+
+int
_libssh2_sha512(const unsigned char *message, size_t len,
unsigned char *out)
{
@@ -2504,6 +3281,7 @@ _libssh2_sha512(const unsigned char *message, size_t len,
return 1; /* error */
}
+#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
int
_libssh2_md5_init(libssh2_md5_ctx *ctx)
{
@@ -2513,8 +3291,7 @@ _libssh2_md5_init(libssh2_md5_ctx *ctx)
* So, just return 0 in FIPS mode
*/
#if OPENSSL_VERSION_NUMBER >= 0x000907000L && \
- defined(OPENSSL_VERSION_MAJOR) && \
- OPENSSL_VERSION_MAJOR < 3 && \
+ !defined(USE_OPENSSL_3) && \
!defined(LIBRESSL_VERSION_NUMBER)
if(FIPS_mode())
@@ -2540,6 +3317,31 @@ _libssh2_md5_init(libssh2_md5_ctx *ctx)
#endif
}
+int
+_libssh2_md5_update(libssh2_md5_ctx *ctx,
+ const void *data, size_t len)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ return EVP_DigestUpdate(*ctx, data, len);
+#else
+ return EVP_DigestUpdate(ctx, data, len);
+#endif
+}
+
+int
+_libssh2_md5_final(libssh2_md5_ctx *ctx,
+ unsigned char *out)
+{
+#ifdef HAVE_OPAQUE_STRUCTS
+ int ret = EVP_DigestFinal(*ctx, out, NULL);
+ EVP_MD_CTX_free(*ctx);
+ return ret;
+#else
+ return EVP_DigestFinal(ctx, out, NULL);
+#endif
+}
+#endif
+
#if LIBSSH2_ECDSA
static int
@@ -2552,17 +3354,26 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
EVP_PKEY *pk)
{
int rc = 0;
- EC_KEY *ec = NULL;
unsigned char *p;
unsigned char *method_buf = NULL;
unsigned char *key;
+ size_t method_buf_len = 0;
size_t key_len = 0;
unsigned char *octal_value = NULL;
size_t octal_len;
+ libssh2_curve_type type;
+
+#ifdef USE_OPENSSL_3
+ _libssh2_debug((session,
+ LIBSSH2_TRACE_AUTH,
+ "Computing public key from EC private key envelope"));
+
+ type = _libssh2_ecdsa_get_curve_type(pk);
+#else
+ EC_KEY *ec = NULL;
const EC_POINT *public_key;
const EC_GROUP *group;
- BN_CTX *bn_ctx;
- libssh2_curve_type type;
+ BN_CTX *bn_ctx = NULL;
_libssh2_debug((session,
LIBSSH2_TRACE_AUTH,
@@ -2581,26 +3392,32 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
public_key = EC_KEY_get0_public_key(ec);
group = EC_KEY_get0_group(ec);
type = _libssh2_ecdsa_get_curve_type(ec);
+#endif
if(is_sk)
- *method_len = 34;
+ method_buf_len = 34;
else
- *method_len = 19;
+ method_buf_len = 19;
- method_buf = LIBSSH2_ALLOC(session, *method_len);
+ method_buf = LIBSSH2_ALLOC(session, method_buf_len);
if(!method_buf) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"out of memory");
}
- if(is_sk)
- memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com", *method_len);
- else if(type == LIBSSH2_EC_CURVE_NISTP256)
- memcpy(method_buf, "ecdsa-sha2-nistp256", *method_len);
- else if(type == LIBSSH2_EC_CURVE_NISTP384)
- memcpy(method_buf, "ecdsa-sha2-nistp384", *method_len);
- else if(type == LIBSSH2_EC_CURVE_NISTP521)
- memcpy(method_buf, "ecdsa-sha2-nistp521", *method_len);
+ if(is_sk) {
+ memcpy(method_buf, "sk-ecdsa-sha2-nistp256@openssh.com",
+ method_buf_len);
+ }
+ else if(type == LIBSSH2_EC_CURVE_NISTP256) {
+ memcpy(method_buf, "ecdsa-sha2-nistp256", method_buf_len);
+ }
+ else if(type == LIBSSH2_EC_CURVE_NISTP384) {
+ memcpy(method_buf, "ecdsa-sha2-nistp384", method_buf_len);
+ }
+ else if(type == LIBSSH2_EC_CURVE_NISTP521) {
+ memcpy(method_buf, "ecdsa-sha2-nistp521", method_buf_len);
+ }
else {
_libssh2_debug((session,
LIBSSH2_TRACE_ERROR,
@@ -2609,6 +3426,12 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
goto clean_exit;
}
+#ifdef USE_OPENSSL_3
+ octal_len = EC_MAX_POINT_LEN;
+ octal_value = LIBSSH2_ALLOC(session, octal_len);
+ EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
+ octal_value, octal_len, &octal_len);
+#else
/* get length */
octal_len = EC_POINT_point2oct(group, public_key,
POINT_CONVERSION_UNCOMPRESSED,
@@ -2630,10 +3453,11 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
rc = -1;
goto clean_exit;
}
+#endif
- /* Key form is: type_len(4) + type(method_len) + domain_len(4) + domain(8)
- + pub_key_len(4) + pub_key(~65). */
- key_len = 4 + *method_len + 4 + 8 + 4 + octal_len;
+ /* Key form is: type_len(4) + type(method_buf_len) + domain_len(4)
+ + domain(8) + pub_key_len(4) + pub_key(~65). */
+ key_len = 4 + method_buf_len + 4 + 8 + 4 + octal_len;
key = LIBSSH2_ALLOC(session, key_len);
if(!key) {
rc = -1;
@@ -2644,7 +3468,7 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
p = key;
/* Key type */
- _libssh2_store_str(&p, (const char *)method_buf, *method_len);
+ _libssh2_store_str(&p, (const char *)method_buf, method_buf_len);
/* Name domain */
if(is_sk) {
@@ -2657,18 +3481,25 @@ gen_publickey_from_ec_evp(LIBSSH2_SESSION *session,
/* Public key */
_libssh2_store_str(&p, (const char *)octal_value, octal_len);
- *method = method_buf;
- *pubkeydata = key;
- *pubkeydata_len = key_len;
+ *method = method_buf;
+ if(method_len) {
+ *method_len = method_buf_len;
+ }
+ *pubkeydata = key;
+ if(pubkeydata_len) {
+ *pubkeydata_len = key_len;
+ }
clean_exit:
+#ifndef USE_OPENSSL_3
if(ec)
EC_KEY_free(ec);
if(bn_ctx) {
BN_CTX_free(bn_ctx);
}
+#endif
if(octal_value)
free(octal_value);
@@ -2695,8 +3526,16 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
int rc = 0;
size_t curvelen, exponentlen, pointlen;
unsigned char *curve, *exponent, *point_buf;
- EC_KEY *ec_key = NULL;
+ libssh2_ecdsa_ctx *ec_key = NULL;
+
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *fromdata_ctx = NULL;
+ OSSL_PARAM params[4];
+ const char *n = EC_curve_nid2nist(curve_type);
+ char *group_name = NULL;
+#else
BIGNUM *bn_exponent;
+#endif
_libssh2_debug((session,
LIBSSH2_TRACE_AUTH,
@@ -2721,6 +3560,43 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
return -1;
}
+#ifdef USE_OPENSSL_3
+ if(!n)
+ return -1;
+
+ fromdata_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+
+ if(!fromdata_ctx)
+ goto fail;
+
+ group_name = OPENSSL_zalloc(strlen(n) + 1);
+
+ if(!group_name)
+ goto fail;
+
+ memcpy(group_name, n, strlen(n));
+ _libssh2_swap_bytes(exponent, (unsigned long)exponentlen);
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
+ group_name, 0);
+
+ params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
+ point_buf, pointlen);
+
+ params[2] = OSSL_PARAM_construct_BN(OSSL_PKEY_PARAM_PRIV_KEY, exponent,
+ exponentlen);
+
+ params[3] = OSSL_PARAM_construct_end();
+
+ if(EVP_PKEY_fromdata_init(fromdata_ctx) <= 0)
+ goto fail;
+
+ rc = EVP_PKEY_fromdata(fromdata_ctx, &ec_key, EVP_PKEY_KEYPAIR, params);
+ rc = rc != 1;
+
+ if(group_name)
+ OPENSSL_clear_free(group_name, strlen(n));
+#else
rc = _libssh2_ecdsa_curve_name_with_octal_new(&ec_key,
point_buf, pointlen,
curve_type);
@@ -2741,29 +3617,46 @@ gen_publickey_from_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
BN_bin2bn(exponent, (int) exponentlen, bn_exponent);
rc = (EC_KEY_set_private_key(ec_key, bn_exponent) != 1);
+#endif
if(rc == 0 && ec_key && pubkeydata && method) {
+#ifdef USE_OPENSSL_3
+ EVP_PKEY *pk = ec_key;
+#else
EVP_PKEY *pk = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(pk, ec_key);
+#endif
rc = gen_publickey_from_ec_evp(session, method, method_len,
pubkeydata, pubkeydata_len,
0, pk);
+#ifndef USE_OPENSSL_3
if(pk)
EVP_PKEY_free(pk);
+#endif
}
+#ifdef USE_OPENSSL_3
+ if(fromdata_ctx)
+ EVP_PKEY_CTX_free(fromdata_ctx);
+#endif
+
if(ec_ctx)
*ec_ctx = ec_key;
else
- EC_KEY_free(ec_key);
+ _libssh2_ecdsa_free(ec_key);
return rc;
fail:
+#ifdef USE_OPENSSL_3
+ if(fromdata_ctx)
+ EVP_PKEY_CTX_free(fromdata_ctx);
+#endif
+
if(ec_key)
- EC_KEY_free(ec_key);
+ _libssh2_ecdsa_free(ec_key);
return rc;
}
@@ -2784,7 +3677,7 @@ gen_publickey_from_sk_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
int rc = 0;
size_t curvelen, pointlen, key_len, app_len;
unsigned char *curve, *point_buf, *p, *key, *app;
- EC_KEY *ec_key = NULL;
+ libssh2_ecdsa_ctx *ec_key = NULL;
_libssh2_debug((session,
LIBSSH2_TRACE_AUTH,
@@ -2843,15 +3736,21 @@ gen_publickey_from_sk_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
}
if(rc == 0 && ec_key && pubkeydata && method) {
+#ifdef USE_OPENSSL_3
+ EVP_PKEY *pk = ec_key;
+#else
EVP_PKEY *pk = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(pk, ec_key);
+#endif
rc = gen_publickey_from_ec_evp(session, method, method_len,
pubkeydata, pubkeydata_len,
1, pk);
+#ifndef USE_OPENSSL_3
if(pk)
EVP_PKEY_free(pk);
+#endif
}
if(rc == 0 && pubkeydata) {
@@ -2886,13 +3785,13 @@ gen_publickey_from_sk_ecdsa_openssh_priv_data(LIBSSH2_SESSION *session,
if(ec_ctx)
*ec_ctx = ec_key;
else
- EC_KEY_free(ec_key);
+ _libssh2_ecdsa_free(ec_key);
return rc;
fail:
if(ec_key)
- EC_KEY_free(ec_key);
+ _libssh2_ecdsa_free(ec_key);
if(application && *application) {
LIBSSH2_FREE(session, (void *)application);
@@ -2954,8 +3853,9 @@ _libssh2_ecdsa_new_openssh_private(libssh2_ecdsa_ctx ** ec_ctx,
if(rc == 0) {
rc = gen_publickey_from_ecdsa_openssh_priv_data(session, type,
- decrypted, NULL, 0,
- NULL, 0, ec_ctx);
+ decrypted,
+ NULL, NULL,
+ NULL, NULL, ec_ctx);
}
else {
rc = -1;
@@ -3015,8 +3915,8 @@ _libssh2_ecdsa_new_openssh_private_sk(libssh2_ecdsa_ctx ** ec_ctx,
if(strcmp("sk-ecdsa-sha2-nistp256@openssh.com", (const char *)buf) == 0) {
rc = gen_publickey_from_sk_ecdsa_openssh_priv_data(session,
decrypted,
- NULL, 0,
- NULL, 0,
+ NULL, NULL,
+ NULL, NULL,
flags,
application,
key_handle,
@@ -3040,12 +3940,18 @@ _libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
{
int rc;
- pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_ec =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
+ pem_read_bio_func read_ec =
+ (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
+#endif
_libssh2_init_if_needed();
rc = read_private_key_from_file((void **) ec_ctx, read_ec,
- filename, passphrase);
+ filename, passphrase);
if(rc) {
return _libssh2_ecdsa_new_openssh_private(ec_ctx, session,
@@ -3067,12 +3973,18 @@ _libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx,
{
int rc;
- pem_read_bio_func read_ec = (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
+#if defined(USE_OPENSSL_3)
+ pem_read_bio_func read_ec =
+ (pem_read_bio_func) &PEM_read_bio_PrivateKey;
+#else
+ pem_read_bio_func read_ec =
+ (pem_read_bio_func) &PEM_read_bio_ECPrivateKey;
+#endif
_libssh2_init_if_needed();
rc = read_private_key_from_file((void **) ec_ctx, read_ec,
- filename, passphrase);
+ filename, passphrase);
if(rc) {
return _libssh2_ecdsa_new_openssh_private_sk(ec_ctx,
@@ -3107,8 +4019,51 @@ _libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
int ret = 1;
size_t octal_len = 0;
unsigned char octal_value[EC_MAX_POINT_LEN];
+ _libssh2_ec_key *private_key = NULL;
+
+#ifdef USE_OPENSSL_3
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+
+ if(ctx &&
+ EVP_PKEY_keygen_init(ctx) >0 &&
+ EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, curve_type) > 0) {
+ ret = EVP_PKEY_keygen(ctx, &private_key);
+ }
+
+ if(ret <= 0) {
+ goto clean_exit;
+ }
+
+ if(out_private_key)
+ *out_private_key = private_key;
+
+ ret = EVP_PKEY_get_octet_string_param(private_key, OSSL_PKEY_PARAM_PUB_KEY,
+ NULL, 0, &octal_len);
+
+ if(ret <= 0) {
+ goto clean_exit;
+ }
+
+ *out_public_key_octal = LIBSSH2_ALLOC(session, octal_len);
+
+ if(!(*out_public_key_octal)) {
+ ret = -1;
+ goto clean_exit;
+ }
+
+ ret = EVP_PKEY_get_octet_string_param(private_key, OSSL_PKEY_PARAM_PUB_KEY,
+ octal_value, octal_len, &octal_len);
+
+ if(ret <= 0) {
+ goto clean_exit;
+ }
+
+ memcpy(*out_public_key_octal, octal_value, octal_len);
+
+ if(out_public_key_octal_len)
+ *out_public_key_octal_len = octal_len;
+#else
const EC_POINT *public_key = NULL;
- EC_KEY *private_key = NULL;
const EC_GROUP *group = NULL;
/* create key */
@@ -3153,11 +4108,16 @@ _libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
if(out_public_key_octal_len)
*out_public_key_octal_len = octal_len;
+#endif /* USE_OPENSSL_3 */
clean_exit:
-
+#ifdef USE_OPENSSL_3
+ if(ctx)
+ EVP_PKEY_CTX_free(ctx);
+#else
if(bn_ctx)
BN_CTX_free(bn_ctx);
+#endif
return (ret == 1) ? 0 : -1;
}
@@ -3170,16 +4130,120 @@ clean_exit:
int
_libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
- const unsigned char *server_public_key, size_t server_public_key_len)
+ const unsigned char *server_public_key,
+ size_t server_public_key_len)
{
int ret = 0;
- int rc;
+ BN_CTX *bn_ctx = NULL;
+
+#ifdef USE_OPENSSL_3
+ char *group_name = NULL;
+ size_t group_name_len = 0;
+ unsigned char *out_shared_key = NULL;
+ EVP_PKEY *peer_key = NULL, *server_key = NULL;
+ EVP_PKEY_CTX *key_fromdata_ctx = NULL;
+ EVP_PKEY_CTX *server_key_ctx = NULL;
+ OSSL_PARAM params[3];
+
+ size_t out_len = 0;
+
+ if(!k || !(*k) || server_public_key_len <= 0)
+ return -1;
+
+ bn_ctx = BN_CTX_new();
+ if(!bn_ctx)
+ goto clean_exit;
+
+ key_fromdata_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
+ if(!key_fromdata_ctx)
+ goto clean_exit;
+
+ ret = EVP_PKEY_get_utf8_string_param(private_key,
+ OSSL_PKEY_PARAM_GROUP_NAME,
+ NULL, 0, &group_name_len);
+
+ if(ret <= 0)
+ goto clean_exit;
+
+ group_name_len += 1;
+ group_name = OPENSSL_zalloc(group_name_len);
+
+ if(!group_name)
+ goto clean_exit;
+
+ ret = EVP_PKEY_get_utf8_string_param(private_key,
+ OSSL_PKEY_PARAM_GROUP_NAME,
+ group_name, group_name_len,
+ &group_name_len);
+
+ if(ret <= 0)
+ goto clean_exit;
+
+ out_shared_key = OPENSSL_malloc(server_public_key_len);
+
+ if(!out_shared_key)
+ goto clean_exit;
+
+ memcpy(out_shared_key, server_public_key, server_public_key_len);
+
+ params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
+ group_name, 0);
+
+ params[1] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
+ out_shared_key,
+ server_public_key_len);
+
+ params[2] = OSSL_PARAM_construct_end();
+
+ ret = EVP_PKEY_fromdata_init(key_fromdata_ctx);
+ if(ret <= 0)
+ goto clean_exit;
+
+ ret = EVP_PKEY_fromdata(key_fromdata_ctx, &peer_key,
+ EVP_PKEY_PUBLIC_KEY, params);
+
+ if(ret <= 0)
+ goto clean_exit;
+
+ server_key = private_key;
+
+ if(!peer_key || !server_key) {
+ goto clean_exit;
+ }
+
+ server_key_ctx = EVP_PKEY_CTX_new(server_key, NULL);
+ if(!server_key_ctx) {
+ goto clean_exit;
+ }
+
+ ret = EVP_PKEY_derive_init(server_key_ctx);
+ if(ret <= 0)
+ goto clean_exit;
+
+ ret = EVP_PKEY_derive_set_peer(server_key_ctx, peer_key);
+ if(ret <= 0)
+ goto clean_exit;
+
+ ret = EVP_PKEY_derive(server_key_ctx, NULL, &out_len);
+ if(ret <= 0)
+ goto clean_exit;
+
+ ret = EVP_PKEY_derive(server_key_ctx, out_shared_key, &out_len);
+
+ if(ret == 1) {
+ BN_bin2bn(out_shared_key, (int)out_len, *k);
+ }
+ else {
+ ret = -1;
+ }
+#else
+ int rc = -1;
size_t secret_len;
unsigned char *secret = NULL;
const EC_GROUP *private_key_group;
EC_POINT *server_public_key_point;
- BN_CTX *bn_ctx = BN_CTX_new();
+ bn_ctx = BN_CTX_new();
if(!bn_ctx)
return -1;
@@ -3216,9 +4280,19 @@ _libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
}
BN_bin2bn(secret, (int) secret_len, *k);
+#endif
clean_exit:
+#ifdef USE_OPENSSL_3
+ if(group_name)
+ OPENSSL_clear_free(group_name, group_name_len);
+ if(out_shared_key)
+ OPENSSL_clear_free(out_shared_key, server_public_key_len);
+
+ if(server_key_ctx)
+ EVP_PKEY_CTX_free(server_key_ctx);
+#else
if(server_public_key_point)
EC_POINT_free(server_public_key_point);
@@ -3227,8 +4301,13 @@ clean_exit:
if(secret)
free(secret);
+#endif
+#ifdef USE_OPENSSL_3
+ return ret == 1 ? 0 : -1;
+#else
return ret;
+#endif
}
@@ -3522,7 +4601,7 @@ _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
"file: Unable to open private key file");
}
- BIO_reset(bp);
+ (void)BIO_reset(bp);
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
BIO_free(bp);
@@ -3664,10 +4743,8 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
method_len,
pubkeydata,
pubkeydata_len,
- NULL,
- NULL,
- NULL,
- NULL,
+ NULL, NULL,
+ NULL, NULL,
(libssh2_ed25519_ctx**)key_ctx);
}
}
@@ -3696,16 +4773,15 @@ _libssh2_pub_priv_openssh_keyfilememory(LIBSSH2_SESSION *session,
#endif
#if LIBSSH2_ECDSA
{
- libssh2_curve_type type;
+ libssh2_curve_type type;
if(strcmp("sk-ecdsa-sha2-nistp256@openssh.com", (const char *)buf) == 0) {
rc = gen_publickey_from_sk_ecdsa_openssh_priv_data(session, decrypted,
method, method_len,
pubkeydata,
pubkeydata_len,
- NULL,
NULL, NULL,
- NULL,
+ NULL, NULL,
(libssh2_ecdsa_ctx**)key_ctx);
}
else if(_libssh2_ecdsa_curve_type_from_name((const char *)buf, &type)
@@ -3840,19 +4916,6 @@ _libssh2_sk_pub_openssh_keyfilememory(LIBSSH2_SESSION *session,
return rc;
}
-int
-read_openssh_private_key_from_memory(void **key_ctx, LIBSSH2_SESSION *session,
- const char *key_type,
- const char *filedata,
- size_t filedata_len,
- unsigned const char *passphrase)
-{
- return _libssh2_pub_priv_openssh_keyfilememory(session, key_ctx, key_type,
- NULL, NULL, NULL, NULL,
- filedata, filedata_len,
- passphrase);
-}
-
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#define HAVE_SSLERROR_BAD_DECRYPT
#endif
@@ -3888,7 +4951,7 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory when"
"computing public key");
- BIO_reset(bp);
+ (void)BIO_reset(bp);
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
#ifdef HAVE_SSLERROR_BAD_DECRYPT
sslError = ERR_get_error();
@@ -3932,8 +4995,8 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
switch(pktype) {
#if LIBSSH2_ED25519
case EVP_PKEY_ED25519:
- st = gen_publickey_from_ed_evp(
- session, method, method_len, pubkeydata, pubkeydata_len, pk);
+ st = gen_publickey_from_ed_evp(session, method, method_len,
+ pubkeydata, pubkeydata_len, pk);
break;
#endif /* LIBSSH2_ED25519 */
#if LIBSSH2_RSA
@@ -3951,8 +5014,7 @@ _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
#if LIBSSH2_ECDSA
case EVP_PKEY_EC:
st = gen_publickey_from_ec_evp(session, method, method_len,
- pubkeydata, pubkeydata_len,
- 0, pk);
+ pubkeydata, pubkeydata_len, 0, pk);
break;
#endif /* LIBSSH2_ECDSA */
default:
@@ -4000,7 +5062,7 @@ _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory when"
"computing public key");
- BIO_reset(bp);
+ (void)BIO_reset(bp);
pk = PEM_read_bio_PrivateKey(bp, NULL, NULL, (void *)passphrase);
BIO_free(bp);
@@ -4074,7 +5136,11 @@ _libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
#if LIBSSH2_RSA_SHA2
if(key_method_len == 7 &&
memcmp(key_method, "ssh-rsa", key_method_len) == 0) {
- return "rsa-sha2-512,rsa-sha2-256,ssh-rsa";
+ return "rsa-sha2-512,rsa-sha2-256"
+#if LIBSSH2_RSA_SHA1
+ ",ssh-rsa"
+#endif
+ ;
}
#endif
diff --git a/libs/libssh2/src/openssl.h b/libs/libssh2/src/openssl.h
index efd9a007f6..e44c87498c 100644
--- a/libs/libssh2/src/openssl.h
+++ b/libs/libssh2/src/openssl.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_OPENSSL_H
-#define __LIBSSH2_OPENSSL_H
+#ifndef LIBSSH2_OPENSSL_H
+#define LIBSSH2_OPENSSL_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
@@ -78,6 +78,7 @@
#endif /* LIBSSH2_WOLFSSL */
+#include <openssl/opensslconf.h>
#include <openssl/sha.h>
#include <openssl/rsa.h>
#ifndef OPENSSL_NO_ENGINE
@@ -96,9 +97,15 @@
#include <openssl/pem.h>
#include <openssl/rand.h>
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#define USE_OPENSSL_3 1
+#include <openssl/core_names.h>
+#endif
+
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) || \
- LIBRESSL_VERSION_NUMBER >= 0x3050000fL
+ (defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
/* For wolfSSL, whether the structs are truly opaque or not, it's best to not
* rely on their internal data members being exposed publicly. */
# define HAVE_OPAQUE_STRUCTS 1
@@ -192,6 +199,8 @@
# define LIBSSH2_3DES 1
#endif
+#include "crypto_config.h"
+
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \
@@ -207,19 +216,15 @@
/* returns 0 in case of failure */
int _libssh2_sha1_init(libssh2_sha1_ctx *ctx);
-#define libssh2_sha1_init(x) _libssh2_sha1_init(x)
-#ifdef HAVE_OPAQUE_STRUCTS
-#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
-#define libssh2_sha1_final(ctx, out) do { \
- EVP_DigestFinal(ctx, out, NULL); \
- EVP_MD_CTX_free(ctx); \
- } while(0)
-#else
-#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
-#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
-#endif
+int _libssh2_sha1_update(libssh2_sha1_ctx *ctx,
+ const void *data, size_t len);
+int _libssh2_sha1_final(libssh2_sha1_ctx *ctx, unsigned char *out);
int _libssh2_sha1(const unsigned char *message, size_t len,
unsigned char *out);
+#define libssh2_sha1_init(x) _libssh2_sha1_init(x)
+#define libssh2_sha1_update(ctx, data, len) \
+ _libssh2_sha1_update(&(ctx), data, len)
+#define libssh2_sha1_final(ctx, out) _libssh2_sha1_final(&(ctx), out)
#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
@@ -230,20 +235,15 @@ int _libssh2_sha1(const unsigned char *message, size_t len,
/* returns 0 in case of failure */
int _libssh2_sha256_init(libssh2_sha256_ctx *ctx);
-#define libssh2_sha256_init(x) _libssh2_sha256_init(x)
-#ifdef HAVE_OPAQUE_STRUCTS
-#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
-#define libssh2_sha256_final(ctx, out) do { \
- EVP_DigestFinal(ctx, out, NULL); \
- EVP_MD_CTX_free(ctx); \
- } while(0)
-#else
-#define libssh2_sha256_update(ctx, data, len) \
- EVP_DigestUpdate(&(ctx), data, len)
-#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
-#endif
+int _libssh2_sha256_update(libssh2_sha256_ctx *ctx,
+ const void *data, size_t len);
+int _libssh2_sha256_final(libssh2_sha256_ctx *ctx, unsigned char *out);
int _libssh2_sha256(const unsigned char *message, size_t len,
unsigned char *out);
+#define libssh2_sha256_init(x) _libssh2_sha256_init(x)
+#define libssh2_sha256_update(ctx, data, len) \
+ _libssh2_sha256_update(&(ctx), data, len)
+#define libssh2_sha256_final(ctx, out) _libssh2_sha256_final(&(ctx), out)
#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
@@ -254,20 +254,15 @@ int _libssh2_sha256(const unsigned char *message, size_t len,
/* returns 0 in case of failure */
int _libssh2_sha384_init(libssh2_sha384_ctx *ctx);
-#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
-#ifdef HAVE_OPAQUE_STRUCTS
-#define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
-#define libssh2_sha384_final(ctx, out) do { \
- EVP_DigestFinal(ctx, out, NULL); \
- EVP_MD_CTX_free(ctx); \
- } while(0)
-#else
-#define libssh2_sha384_update(ctx, data, len) \
- EVP_DigestUpdate(&(ctx), data, len)
-#define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
-#endif
+int _libssh2_sha384_update(libssh2_sha384_ctx *ctx,
+ const void *data, size_t len);
+int _libssh2_sha384_final(libssh2_sha384_ctx *ctx, unsigned char *out);
int _libssh2_sha384(const unsigned char *message, size_t len,
unsigned char *out);
+#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
+#define libssh2_sha384_update(ctx, data, len) \
+ _libssh2_sha384_update(&(ctx), data, len)
+#define libssh2_sha384_final(ctx, out) _libssh2_sha384_final(&(ctx), out)
#define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
@@ -278,22 +273,18 @@ int _libssh2_sha384(const unsigned char *message, size_t len,
/* returns 0 in case of failure */
int _libssh2_sha512_init(libssh2_sha512_ctx *ctx);
-#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
-#ifdef HAVE_OPAQUE_STRUCTS
-#define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
-#define libssh2_sha512_final(ctx, out) do { \
- EVP_DigestFinal(ctx, out, NULL); \
- EVP_MD_CTX_free(ctx); \
- } while(0)
-#else
-#define libssh2_sha512_update(ctx, data, len) \
- EVP_DigestUpdate(&(ctx), data, len)
-#define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
-#endif
+int _libssh2_sha512_update(libssh2_sha512_ctx *ctx,
+ const void *data, size_t len);
+int _libssh2_sha512_final(libssh2_sha512_ctx *ctx, unsigned char *out);
int _libssh2_sha512(const unsigned char *message, size_t len,
unsigned char *out);
+#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
+#define libssh2_sha512_update(ctx, data, len) \
+ _libssh2_sha512_update(&(ctx), data, len)
+#define libssh2_sha512_final(ctx, out) _libssh2_sha512_final(&(ctx), out)
#define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z)
+#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_md5_ctx EVP_MD_CTX *
#else
@@ -302,62 +293,22 @@ int _libssh2_sha512(const unsigned char *message, size_t len,
/* returns 0 in case of failure */
int _libssh2_md5_init(libssh2_md5_ctx *ctx);
+int _libssh2_md5_update(libssh2_md5_ctx *ctx,
+ const void *data, size_t len);
+int _libssh2_md5_final(libssh2_md5_ctx *ctx, unsigned char *out);
#define libssh2_md5_init(x) _libssh2_md5_init(x)
-#ifdef HAVE_OPAQUE_STRUCTS
-#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
-#define libssh2_md5_final(ctx, out) do { \
- EVP_DigestFinal(ctx, out, NULL); \
- EVP_MD_CTX_free(ctx); \
- } while(0)
-#else
-#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
-#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
-#endif
-
-#ifdef HAVE_OPAQUE_STRUCTS
+#define libssh2_md5_update(ctx, data, len) \
+ _libssh2_md5_update(&(ctx), data, len)
+#define libssh2_md5_final(ctx, out) _libssh2_md5_final(&(ctx), out)
+#endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */
+
+#ifdef USE_OPENSSL_3
+#define libssh2_hmac_ctx EVP_MAC_CTX *
+#elif defined(HAVE_OPAQUE_STRUCTS)
#define libssh2_hmac_ctx HMAC_CTX *
-#define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new()
-#define libssh2_hmac_sha1_init(ctx, key, keylen) \
- HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha1(), NULL)
-#define libssh2_hmac_md5_init(ctx, key, keylen) \
- HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_md5(), NULL)
-#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
- HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_ripemd160(), NULL)
-#define libssh2_hmac_sha256_init(ctx, key, keylen) \
- HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha256(), NULL)
-#define libssh2_hmac_sha512_init(ctx, key, keylen) \
- HMAC_Init_ex(*(ctx), key, (int)keylen, EVP_sha512(), NULL)
-
-#ifdef LIBSSH2_WOLFSSL
-/* FIXME: upstream bug as of v5.6.0: datalen is int instead of size_t */
-#define libssh2_hmac_update(ctx, data, datalen) \
- HMAC_Update(ctx, data, (int)datalen)
-#else
-#define libssh2_hmac_update(ctx, data, datalen) \
- HMAC_Update(ctx, data, datalen)
-#endif /* LIBSSH2_WOLFSSL */
-#define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL)
-#define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx))
-#else
+#else /* !HAVE_OPAQUE_STRUCTS */
#define libssh2_hmac_ctx HMAC_CTX
-#define libssh2_hmac_ctx_init(ctx) \
- HMAC_CTX_init(&ctx)
-#define libssh2_hmac_sha1_init(ctx, key, keylen) \
- HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha1(), NULL)
-#define libssh2_hmac_md5_init(ctx, key, keylen) \
- HMAC_Init_ex(ctx, key, (int)keylen, EVP_md5(), NULL)
-#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
- HMAC_Init_ex(ctx, key, (int)keylen, EVP_ripemd160(), NULL)
-#define libssh2_hmac_sha256_init(ctx, key, keylen) \
- HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha256(), NULL)
-#define libssh2_hmac_sha512_init(ctx, key, keylen) \
- HMAC_Init_ex(ctx, key, (int)keylen, EVP_sha512(), NULL)
-
-#define libssh2_hmac_update(ctx, data, datalen) \
- HMAC_Update(&(ctx), data, datalen)
-#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
-#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
-#endif
+#endif /* USE_OPENSSL_3 */
extern void _libssh2_openssl_crypto_init(void);
extern void _libssh2_openssl_crypto_exit(void);
@@ -365,21 +316,40 @@ extern void _libssh2_openssl_crypto_exit(void);
#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit()
#if LIBSSH2_RSA
-#define libssh2_rsa_ctx RSA
+#ifdef USE_OPENSSL_3
+#define libssh2_rsa_ctx EVP_PKEY
+#define _libssh2_rsa_free(rsactx) EVP_PKEY_free(rsactx)
+#else
+#define libssh2_rsa_ctx RSA
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
#endif
+#endif /* LIBSSH2_RSA */
+
#if LIBSSH2_DSA
-#define libssh2_dsa_ctx DSA
+#ifdef USE_OPENSSL_3
+#define libssh2_dsa_ctx EVP_PKEY
+#define _libssh2_dsa_free(rsactx) EVP_PKEY_free(rsactx)
+#else
+#define libssh2_dsa_ctx DSA
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
#endif
+#endif /* LIBSSH2_DSA */
+
#if LIBSSH2_ECDSA
+
+#ifdef USE_OPENSSL_3
+#define libssh2_ecdsa_ctx EVP_PKEY
+#define _libssh2_ecdsa_free(ecdsactx) EVP_PKEY_free(ecdsactx)
+#define _libssh2_ec_key EVP_PKEY
+#else
#define libssh2_ecdsa_ctx EC_KEY
#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx)
#define _libssh2_ec_key EC_KEY
+#endif
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1,
@@ -387,15 +357,14 @@ typedef enum {
LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1
}
libssh2_curve_type;
-#else
+#else /* !LIBSSH2_ECDSA */
#define _libssh2_ec_key void
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
#define libssh2_ed25519_ctx EVP_PKEY
-
#define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx)
-#endif /* ED25519 */
+#endif /* LIBSSH2_ED25519 */
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
#ifdef HAVE_OPAQUE_STRUCTS
@@ -468,4 +437,4 @@ const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);
-#endif /* __LIBSSH2_OPENSSL_H */
+#endif /* LIBSSH2_OPENSSL_H */
diff --git a/libs/libssh2/src/packet.c b/libs/libssh2/src/packet.c
index e3ccf814d4..6da14e9fa1 100644
--- a/libs/libssh2/src/packet.c
+++ b/libs/libssh2/src/packet.c
@@ -71,14 +71,14 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
* Look for a matching listener
*/
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
- size_t packet_len = 17 + (sizeof(FwdNotReq) - 1);
+ size_t packet_len = 17 + strlen(FwdNotReq);
unsigned char *p;
LIBSSH2_LISTENER *listn = _libssh2_list_first(&session->listeners);
char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
int rc;
if(listen_state->state == libssh2_NB_state_idle) {
- size_t offset = (sizeof("forwarded-tcpip") - 1) + 5;
+ size_t offset = strlen("forwarded-tcpip") + 5;
size_t temp_len = 0;
struct string_buf buf;
buf.data = data;
@@ -126,7 +126,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
}
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Remote received connection from %s:%ld to %s:%ld",
+ "Remote received connection from %s:%u to %s:%u",
listen_state->shost, listen_state->sport,
listen_state->host, listen_state->port));
@@ -137,8 +137,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
while(listn) {
if((listn->port == (int) listen_state->port) &&
(strlen(listn->host) == listen_state->host_len) &&
- (memcmp (listn->host, listen_state->host,
- listen_state->host_len) == 0)) {
+ (memcmp(listn->host, listen_state->host,
+ listen_state->host_len) == 0)) {
/* This is our listener */
LIBSSH2_CHANNEL *channel = NULL;
listen_state->channel = NULL;
@@ -166,7 +166,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
listen_state->channel = channel;
channel->session = session;
- channel->channel_type_len = sizeof("forwarded-tcpip") - 1;
+ channel->channel_type_len = strlen("forwarded-tcpip");
channel->channel_type = LIBSSH2_ALLOC(session,
channel->
channel_type_len +
@@ -199,8 +199,8 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
channel->local.packet_size = listen_state->packet_size;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Connection queued: channel %lu/%lu "
- "win %lu/%lu packet %lu/%lu",
+ "Connection queued: channel %u/%u "
+ "win %u/%u packet %u/%u",
channel->local.id, channel->remote.id,
channel->local.window_size,
channel->remote.window_size,
@@ -253,7 +253,7 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
_libssh2_store_u32(&p, listen_state->sender_channel);
_libssh2_store_u32(&p, failure_code);
- _libssh2_store_str(&p, FwdNotReq, sizeof(FwdNotReq) - 1);
+ _libssh2_store_str(&p, FwdNotReq, strlen(FwdNotReq));
_libssh2_htonu32(p, 0);
rc = _libssh2_transport_send(session, listen_state->packet,
@@ -282,14 +282,14 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
{
int failure_code = SSH_OPEN_CONNECT_FAILED;
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
- size_t packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
+ size_t packet_len = 17 + strlen(X11FwdUnAvil);
unsigned char *p;
LIBSSH2_CHANNEL *channel = x11open_state->channel;
int rc;
if(x11open_state->state == libssh2_NB_state_idle) {
- size_t offset = (sizeof("x11") - 1) + 5;
+ size_t offset = strlen("x11") + 5;
size_t temp_len = 0;
struct string_buf buf;
buf.data = data;
@@ -339,7 +339,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
}
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "X11 Connection Received from %s:%ld on channel %lu",
+ "X11 Connection Received from %s:%u on channel %u",
x11open_state->shost, x11open_state->sport,
x11open_state->sender_channel));
@@ -357,7 +357,7 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
}
channel->session = session;
- channel->channel_type_len = sizeof("x11") - 1;
+ channel->channel_type_len = strlen("x11");
channel->channel_type = LIBSSH2_ALLOC(session,
channel->channel_type_len +
1);
@@ -384,8 +384,8 @@ packet_x11_open(LIBSSH2_SESSION * session, unsigned char *data,
channel->local.packet_size = x11open_state->packet_size;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "X11 Connection established: channel %lu/%lu "
- "win %lu/%lu packet %lu/%lu",
+ "X11 Connection established: channel %u/%u "
+ "win %u/%u packet %u/%u",
channel->local.id, channel->remote.id,
channel->local.window_size,
channel->remote.window_size,
@@ -436,7 +436,7 @@ x11_exit:
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
_libssh2_store_u32(&p, x11open_state->sender_channel);
_libssh2_store_u32(&p, failure_code);
- _libssh2_store_str(&p, X11FwdUnAvil, sizeof(X11FwdUnAvil) - 1);
+ _libssh2_store_str(&p, X11FwdUnAvil, strlen(X11FwdUnAvil));
_libssh2_htonu32(p, 0);
rc = _libssh2_transport_send(session, x11open_state->packet, packet_len,
@@ -464,23 +464,40 @@ packet_authagent_open(LIBSSH2_SESSION * session,
{
int failure_code = SSH_OPEN_CONNECT_FAILED;
/* 17 = packet_type(1) + channel(4) + reason(4) + descr(4) + lang(4) */
- size_t packet_len = 17 + (sizeof(X11FwdUnAvil) - 1);
+ size_t packet_len = 17 + strlen(X11FwdUnAvil);
unsigned char *p;
LIBSSH2_CHANNEL *channel = authagent_state->channel;
int rc;
+ struct string_buf buf;
+ size_t offset = strlen("auth-agent@openssh.org") + 5;
- (void)datalen;
+ buf.data = data;
+ buf.dataptr = buf.data;
+ buf.len = datalen;
+
+ buf.dataptr += offset;
+
+ if(datalen < offset) {
+ return _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Unexpected packet size");
+ }
if(authagent_state->state == libssh2_NB_state_idle) {
- unsigned char *s = data + (sizeof("auth-agent@openssh.org") - 1) + 5;
- authagent_state->sender_channel = _libssh2_ntohu32(s);
- s += 4;
- authagent_state->initial_window_size = _libssh2_ntohu32(s);
- s += 4;
- authagent_state->packet_size = _libssh2_ntohu32(s);
+ if(_libssh2_get_u32(&buf, &(authagent_state->sender_channel))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting channel");
+ }
+ if(_libssh2_get_u32(&buf, &(authagent_state->initial_window_size))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting window size");
+ }
+ if(_libssh2_get_u32(&buf, &(authagent_state->packet_size))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting packet");
+ }
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Auth Agent Connection Received on channel %lu",
+ "Auth Agent Connection Received on channel %u",
authagent_state->sender_channel));
authagent_state->state = libssh2_NB_state_allocated;
@@ -500,7 +517,7 @@ packet_authagent_open(LIBSSH2_SESSION * session,
memset(channel, 0, sizeof(LIBSSH2_CHANNEL));
channel->session = session;
- channel->channel_type_len = sizeof("auth agent") - 1;
+ channel->channel_type_len = strlen("auth agent");
channel->channel_type = LIBSSH2_ALLOC(session,
channel->channel_type_len +
1);
@@ -528,7 +545,7 @@ packet_authagent_open(LIBSSH2_SESSION * session,
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Auth Agent Connection established: channel "
- "%lu/%lu win %lu/%lu packet %lu/%lu",
+ "%u/%u win %u/%u packet %u/%u",
channel->local.id, channel->remote.id,
channel->local.window_size,
channel->remote.window_size,
@@ -584,7 +601,7 @@ authagent_exit:
*(p++) = SSH_MSG_CHANNEL_OPEN_FAILURE;
_libssh2_store_u32(&p, authagent_state->sender_channel);
_libssh2_store_u32(&p, failure_code);
- _libssh2_store_str(&p, AuthAgentUnavail, sizeof(AuthAgentUnavail) - 1);
+ _libssh2_store_str(&p, AuthAgentUnavail, strlen(AuthAgentUnavail));
_libssh2_htonu32(p, 0);
rc = _libssh2_transport_send(session, authagent_state->packet, packet_len,
@@ -607,14 +624,13 @@ authagent_exit:
* layer when it has received a packet.
*
* The input pointer 'data' is pointing to allocated data that this function
- * is asked to deal with so on failure OR success, it must be freed fine.
- * The only exception is when the return code is LIBSSH2_ERROR_EAGAIN.
+ * will be freed unless return the code is LIBSSH2_ERROR_EAGAIN.
*
* This function will always be called with 'datalen' greater than zero.
*/
int
_libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
- size_t datalen, int macstate)
+ size_t datalen, int macstate, uint32_t seq)
{
int rc = 0;
unsigned char *message = NULL;
@@ -628,8 +644,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
switch(session->packAdd_state) {
case libssh2_NB_state_idle:
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
- "Packet type %d received, length=%d",
- (int) msg, (int) datalen));
+ "Packet type %u received, length=%ld",
+ (unsigned int) msg, (long) datalen));
if((macstate == LIBSSH2_MAC_INVALID) &&
(!session->macerror ||
@@ -659,6 +675,70 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
break;
}
+ if(session->state & LIBSSH2_STATE_INITIAL_KEX) {
+ if(msg == SSH_MSG_KEXINIT) {
+ if(!session->kex_strict) {
+ if(datalen < 17) {
+ LIBSSH2_FREE(session, data);
+ session->packAdd_state = libssh2_NB_state_idle;
+ return _libssh2_error(session,
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting kex");
+ }
+ else {
+ const unsigned char *strict =
+ (unsigned char *)"kex-strict-s-v00@openssh.com";
+ struct string_buf buf;
+ unsigned char *algs = NULL;
+ size_t algs_len = 0;
+
+ buf.data = (unsigned char *)data;
+ buf.dataptr = buf.data;
+ buf.len = datalen;
+ buf.dataptr += 17; /* advance past type and cookie */
+
+ if(_libssh2_get_string(&buf, &algs, &algs_len)) {
+ LIBSSH2_FREE(session, data);
+ session->packAdd_state = libssh2_NB_state_idle;
+ return _libssh2_error(session,
+ LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Algs too short");
+ }
+
+ if(algs_len == 0 ||
+ _libssh2_kex_agree_instr(algs, algs_len, strict, 28)) {
+ session->kex_strict = 1;
+ }
+ }
+ }
+
+ if(session->kex_strict && seq) {
+ LIBSSH2_FREE(session, data);
+ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
+ session->packAdd_state = libssh2_NB_state_idle;
+ libssh2_session_disconnect(session, "strict KEX violation: "
+ "KEXINIT was not the first packet");
+
+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
+ "strict KEX violation: "
+ "KEXINIT was not the first packet");
+ }
+ }
+
+ if(session->kex_strict && session->fullpacket_required_type &&
+ session->fullpacket_required_type != msg) {
+ LIBSSH2_FREE(session, data);
+ session->socket_state = LIBSSH2_SOCKET_DISCONNECTED;
+ session->packAdd_state = libssh2_NB_state_idle;
+ libssh2_session_disconnect(session, "strict KEX violation: "
+ "unexpected packet type");
+
+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
+ "strict KEX violation: "
+ "unexpected packet type");
+ }
+ }
+
if(session->packAdd_state == libssh2_NB_state_allocated) {
/* A couple exceptions to the packet adding rule: */
switch(msg) {
@@ -795,7 +875,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
_libssh2_debug((session,
LIBSSH2_TRACE_KEX,
"Server to Client extension %.*s: %.*s",
- name_len, name, value_len, value));
+ (int)name_len, name,
+ (int)value_len, value));
}
if(name_len == 15 &&
@@ -843,7 +924,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
_libssh2_debug((session,
LIBSSH2_TRACE_CONN,
"Received global request type %.*s (wr %X)",
- len, data + 5, want_reply));
+ (int)len, data + 5, want_reply));
}
@@ -872,7 +953,7 @@ libssh2_packet_add_jump_point5:
/* streamid(4) */
data_head += 4;
- /* fall-through */
+ LIBSSH2_FALLTHROUGH();
/*
byte SSH_MSG_CHANNEL_DATA
@@ -903,8 +984,8 @@ libssh2_packet_add_jump_point5:
stream_id = _libssh2_ntohu32(data + 5);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "%d bytes packet_add() for %lu/%lu/%lu",
- (int) (datalen - data_head),
+ "%ld bytes packet_add() for %u/%u/%u",
+ (long) (datalen - data_head),
channelp->local.id,
channelp->remote.id,
stream_id));
@@ -917,8 +998,8 @@ libssh2_packet_add_jump_point5:
LIBSSH2_FREE(session, data);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Ignoring extended data and refunding %d bytes",
- (int) (datalen - 13)));
+ "Ignoring extended data and refunding %ld bytes",
+ (long) (datalen - 13)));
if(channelp->read_avail + datalen - data_head >=
channelp->remote.window_size)
datalen = channelp->remote.window_size -
@@ -927,11 +1008,11 @@ libssh2_packet_add_jump_point5:
channelp->remote.window_size -= (uint32_t)(datalen -
data_head);
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "shrinking window size by %lu bytes to %lu, "
- "read_avail %lu",
- datalen - data_head,
+ "shrinking window size by %ld bytes to %u, "
+ "read_avail %ld",
+ (long) (datalen - data_head),
channelp->remote.window_size,
- channelp->read_avail));
+ (long) channelp->read_avail));
session->packAdd_channelp = channelp;
@@ -993,10 +1074,10 @@ libssh2_packet_add_jump_point1:
channelp->read_avail += datalen - data_head;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "increasing read_avail by %lu bytes to %lu/%lu",
+ "increasing read_avail by %ld bytes to %ld/%u",
(long)(datalen - data_head),
(long)channelp->read_avail,
- (long)channelp->remote.window_size));
+ channelp->remote.window_size));
break;
@@ -1016,7 +1097,7 @@ libssh2_packet_add_jump_point1:
else {
_libssh2_debug((session,
LIBSSH2_TRACE_CONN,
- "EOF received for channel %lu/%lu",
+ "EOF received for channel %u/%u",
channelp->local.id,
channelp->remote.id));
channelp->remote.eof = 1;
@@ -1044,43 +1125,45 @@ libssh2_packet_add_jump_point1:
_libssh2_debug((session,
LIBSSH2_TRACE_CONN,
- "Channel %d received request type %.*s (wr %X)",
- channel, len, data + 9, want_reply));
+ "Channel %u received request type %.*s (wr %X)",
+ channel, (int)len, data + 9, want_reply));
- if(len == sizeof("exit-status") - 1
- && (sizeof("exit-status") - 1 + 9) <= datalen
+ if(len == strlen("exit-status")
+ && (strlen("exit-status") + 9) <= datalen
&& !memcmp("exit-status", data + 9,
- sizeof("exit-status") - 1)) {
+ strlen("exit-status"))) {
/* we've got "exit-status" packet. Set the session value */
if(datalen >= 20)
channelp =
_libssh2_channel_locate(session, channel);
- if(channelp && (sizeof("exit-status") + 13) <= datalen) {
+ if(channelp && (strlen("exit-status") + 14) <= datalen) {
channelp->exit_status =
- _libssh2_ntohu32(data + 9 + sizeof("exit-status"));
+ _libssh2_ntohu32(data + 10 +
+ strlen("exit-status"));
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Exit status %lu received for "
- "channel %lu/%lu",
+ "Exit status %d received for "
+ "channel %u/%u",
channelp->exit_status,
channelp->local.id,
channelp->remote.id));
}
}
- else if(len == sizeof("exit-signal") - 1
- && (sizeof("exit-signal") - 1 + 9) <= datalen
+ else if(len == strlen("exit-signal")
+ && (strlen("exit-signal") + 9) <= datalen
&& !memcmp("exit-signal", data + 9,
- sizeof("exit-signal") - 1)) {
+ strlen("exit-signal"))) {
/* command terminated due to signal */
if(datalen >= 20)
channelp = _libssh2_channel_locate(session, channel);
- if(channelp && (sizeof("exit-signal") + 13) <= datalen) {
+ if(channelp && (strlen("exit-signal") + 14) <= datalen) {
/* set signal name (without SIG prefix) */
uint32_t namelen =
- _libssh2_ntohu32(data + 9 + sizeof("exit-signal"));
+ _libssh2_ntohu32(data + 10 +
+ strlen("exit-signal"));
if(namelen <= UINT_MAX - 1) {
channelp->exit_signal =
@@ -1093,15 +1176,15 @@ libssh2_packet_add_jump_point1:
if(!channelp->exit_signal)
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"memory for signal name");
- else if((sizeof("exit-signal") + 13 + namelen <=
+ else if((strlen("exit-signal") + 14 + namelen <=
datalen)) {
memcpy(channelp->exit_signal,
- data + 13 + sizeof("exit-signal"), namelen);
+ data + 14 + strlen("exit-signal"), namelen);
channelp->exit_signal[namelen] = '\0';
/* TODO: save error message and language tag */
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
"Exit signal %s received for "
- "channel %lu/%lu",
+ "channel %u/%u",
channelp->exit_signal,
channelp->local.id,
channelp->remote.id));
@@ -1142,7 +1225,7 @@ libssh2_packet_add_jump_point4:
return 0;
}
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Close received for channel %lu/%lu",
+ "Close received for channel %u/%u",
channelp->local.id,
channelp->remote.id));
@@ -1164,12 +1247,12 @@ libssh2_packet_add_jump_point4:
case SSH_MSG_CHANNEL_OPEN:
if(datalen < 17)
;
- else if((datalen >= (sizeof("forwarded-tcpip") + 4)) &&
- ((sizeof("forwarded-tcpip") - 1) ==
+ else if((datalen >= (strlen("forwarded-tcpip") + 5)) &&
+ (strlen("forwarded-tcpip") ==
_libssh2_ntohu32(data + 1))
&&
(memcmp(data + 5, "forwarded-tcpip",
- sizeof("forwarded-tcpip") - 1) == 0)) {
+ strlen("forwarded-tcpip")) == 0)) {
/* init the state struct */
memset(&session->packAdd_Qlstn_state, 0,
@@ -1180,9 +1263,9 @@ libssh2_packet_add_jump_point2:
rc = packet_queue_listener(session, data, datalen,
&session->packAdd_Qlstn_state);
}
- else if((datalen >= (sizeof("x11") + 4)) &&
- ((sizeof("x11") - 1) == _libssh2_ntohu32(data + 1)) &&
- (memcmp(data + 5, "x11", sizeof("x11") - 1) == 0)) {
+ else if((datalen >= (strlen("x11") + 5)) &&
+ ((strlen("x11")) == _libssh2_ntohu32(data + 1)) &&
+ (memcmp(data + 5, "x11", strlen("x11")) == 0)) {
/* init the state struct */
memset(&session->packAdd_x11open_state, 0,
@@ -1193,11 +1276,11 @@ libssh2_packet_add_jump_point3:
rc = packet_x11_open(session, data, datalen,
&session->packAdd_x11open_state);
}
- else if((datalen >= (sizeof("auth-agent@openssh.com") + 4)) &&
- ((sizeof("auth-agent@openssh.com") - 1) ==
+ else if((datalen >= (strlen("auth-agent@openssh.com") + 5)) &&
+ (strlen("auth-agent@openssh.com") ==
_libssh2_ntohu32(data + 1)) &&
(memcmp(data + 5, "auth-agent@openssh.com",
- sizeof("auth-agent@openssh.com") - 1) == 0)) {
+ strlen("auth-agent@openssh.com")) == 0)) {
/* init the state struct */
memset(&session->packAdd_authagent_state, 0,
@@ -1232,8 +1315,8 @@ libssh2_packet_add_jump_authagent:
channelp->local.window_size += bytestoadd;
_libssh2_debug((session, LIBSSH2_TRACE_CONN,
- "Window adjust for channel %lu/%lu, "
- "adding %lu bytes, new window_size=%lu",
+ "Window adjust for channel %u/%u, "
+ "adding %u bytes, new window_size=%u",
channelp->local.id,
channelp->remote.id,
bytestoadd,
@@ -1325,7 +1408,8 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
LIBSSH2_PACKET *packet = _libssh2_list_first(&session->packets);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
- "Looking for packet of type: %d", (int) packet_type));
+ "Looking for packet of type: %u",
+ (unsigned int)packet_type));
while(packet) {
if(packet->data[0] == packet_type
@@ -1343,6 +1427,15 @@ _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
return 0;
}
+ else if(session->kex_strict &&
+ (session->state & LIBSSH2_STATE_INITIAL_KEX)) {
+ libssh2_session_disconnect(session, "strict KEX violation: "
+ "unexpected packet type");
+
+ return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
+ "strict KEX violation: "
+ "unexpected packet type");
+ }
packet = _libssh2_list_next(&packet->node);
}
return -1;
@@ -1404,7 +1497,10 @@ _libssh2_packet_require(LIBSSH2_SESSION * session, unsigned char packet_type,
}
while(session->socket_state == LIBSSH2_SOCKET_CONNECTED) {
- int ret = _libssh2_transport_read(session);
+ int ret;
+ session->fullpacket_required_type = packet_type;
+ ret = _libssh2_transport_read(session);
+ session->fullpacket_required_type = 0;
if(ret == LIBSSH2_ERROR_EAGAIN)
return ret;
else if(ret < 0) {
diff --git a/libs/libssh2/src/packet.h b/libs/libssh2/src/packet.h
index 55428d0651..955351e5f6 100644
--- a/libs/libssh2/src/packet.h
+++ b/libs/libssh2/src/packet.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_PACKET_H
-#define __LIBSSH2_PACKET_H
+#ifndef LIBSSH2_PACKET_H
+#define LIBSSH2_PACKET_H
/*
* Copyright (C) Daniel Stenberg
* All rights reserved.
@@ -72,6 +72,6 @@ int _libssh2_packet_burn(LIBSSH2_SESSION * session,
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
- size_t datalen, int macstate);
+ size_t datalen, int macstate, uint32_t seq);
-#endif /* __LIBSSH2_PACKET_H */
+#endif /* LIBSSH2_PACKET_H */
diff --git a/libs/libssh2/src/pem.c b/libs/libssh2/src/pem.c
index 912498c5d3..c658896809 100644
--- a/libs/libssh2/src/pem.c
+++ b/libs/libssh2/src/pem.c
@@ -106,12 +106,6 @@ static unsigned char hex_decode(char digit)
((digit >= 'A') ? (0xA + (digit - 'A')) : (digit - '0'));
}
-/* Hack to fix builds with crypto backends with MD5 support disabled.
- FIXME: Honor our LIBSSH2_MD5 macro for MD5-dependent logic. */
-#ifdef OPENSSL_NO_MD5
-#define MD5_DIGEST_LENGTH 16
-#endif
-
int
_libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
@@ -215,6 +209,7 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
}
if(method) {
+#if LIBSSH2_MD5_PEM
/* Set up decryption */
int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0;
int blocksize = method->blocksize;
@@ -223,24 +218,26 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
libssh2_md5_ctx fingerprint_ctx;
/* Perform key derivation (PBKDF1/MD5) */
- if(!libssh2_md5_init(&fingerprint_ctx)) {
+ if(!libssh2_md5_init(&fingerprint_ctx) ||
+ !libssh2_md5_update(fingerprint_ctx, passphrase,
+ strlen((char *)passphrase)) ||
+ !libssh2_md5_update(fingerprint_ctx, iv, 8) ||
+ !libssh2_md5_final(fingerprint_ctx, secret)) {
ret = -1;
goto out;
}
- libssh2_md5_update(fingerprint_ctx, passphrase,
- strlen((char *)passphrase));
- libssh2_md5_update(fingerprint_ctx, iv, 8);
- libssh2_md5_final(fingerprint_ctx, secret);
if(method->secret_len > MD5_DIGEST_LENGTH) {
- if(!libssh2_md5_init(&fingerprint_ctx)) {
+ if(!libssh2_md5_init(&fingerprint_ctx) ||
+ !libssh2_md5_update(fingerprint_ctx,
+ secret, MD5_DIGEST_LENGTH) ||
+ !libssh2_md5_update(fingerprint_ctx,
+ passphrase, strlen((char *)passphrase)) ||
+ !libssh2_md5_update(fingerprint_ctx, iv, 8) ||
+ !libssh2_md5_final(fingerprint_ctx,
+ secret + MD5_DIGEST_LENGTH)) {
ret = -1;
goto out;
}
- libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH);
- libssh2_md5_update(fingerprint_ctx, passphrase,
- strlen((char *)passphrase));
- libssh2_md5_update(fingerprint_ctx, iv, 8);
- libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH);
}
/* Initialize the decryption */
@@ -292,6 +289,10 @@ _libssh2_pem_parse(LIBSSH2_SESSION * session,
/* Clean up */
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
+#else
+ ret = -1;
+ goto out;
+#endif
}
ret = 0;
@@ -599,13 +600,17 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
}
while((size_t)len_decrypted <= decrypted.len - blocksize) {
+ /* We always pass MIDDLE_BLOCK here because OpenSSH Key Files
+ * do not use AAD to authenticate the length.
+ * Furthermore, the authentication tag is appended after the
+ * encrypted key, and the length of the authentication tag is
+ * not included in the key length, so we check it after the
+ * loop.
+ */
if(method->crypt(session, decrypted.data + len_decrypted,
blocksize,
&abstract,
- len_decrypted == 0 ? FIRST_BLOCK : (
- ((size_t)len_decrypted == decrypted.len - blocksize) ?
- LAST_BLOCK : MIDDLE_BLOCK)
- )) {
+ MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
@@ -616,6 +621,26 @@ _libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
/* No padding */
+ /* for the AES GCM methods, the 16 byte authentication tag is
+ * appended to the encrypted key */
+ if(strcmp(method->name, "aes256-gcm@openssh.com") == 0 ||
+ strcmp(method->name, "aes128-gcm@openssh.com") == 0) {
+ if(!_libssh2_check_length(&decoded, 16)) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "GCM auth tag missing");
+ method->dtor(session, &abstract);
+ goto out;
+ }
+ if(method->crypt(session, decoded.dataptr, 16, &abstract,
+ LAST_BLOCK)) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
+ "GCM auth tag invalid");
+ method->dtor(session, &abstract);
+ goto out;
+ }
+ decoded.dataptr += 16;
+ }
+
method->dtor(session, &abstract);
}
diff --git a/libs/libssh2/src/publickey.c b/libs/libssh2/src/publickey.c
index db45be99be..9c9fa61884 100644
--- a/libs/libssh2/src/publickey.c
+++ b/libs/libssh2/src/publickey.c
@@ -516,13 +516,13 @@ static LIBSSH2_PUBLICKEY *publickey_init(LIBSSH2_SESSION *session)
LIBSSH2_PUBLICKEY_VERSION) {
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
"Truncate remote publickey version "
- "from %lu",
+ "from %u",
session->pkeyInit_pkey->version));
session->pkeyInit_pkey->version =
LIBSSH2_PUBLICKEY_VERSION;
}
_libssh2_debug((session, LIBSSH2_TRACE_PUBLICKEY,
- "Enabling publickey subsystem version %lu",
+ "Enabling publickey subsystem version %u",
session->pkeyInit_pkey->version));
LIBSSH2_FREE(session, session->pkeyInit_data);
session->pkeyInit_data = NULL;
diff --git a/libs/libssh2/src/scp.c b/libs/libssh2/src/scp.c
index ff20a80ae5..0900655aac 100644
--- a/libs/libssh2/src/scp.c
+++ b/libs/libssh2/src/scp.c
@@ -748,7 +748,7 @@ scp_recv(LIBSSH2_SESSION * session, const char *path, libssh2_struct_stat * sb)
}
_libssh2_debug((session, LIBSSH2_TRACE_SCP,
"mode = 0%lo size = %ld", session->scpRecv_mode,
- session->scpRecv_size));
+ (long)session->scpRecv_size));
/* We *should* check that basename is valid, but why let that
stop us? */
@@ -792,6 +792,7 @@ scp_recv_error:
return NULL;
}
+#ifndef LIBSSH2_NO_DEPRECATED
/*
* libssh2_scp_recv
*
@@ -828,6 +829,7 @@ libssh2_scp_recv(LIBSSH2_SESSION *session, const char *path, struct stat *sb)
return ptr;
}
+#endif
/*
* libssh2_scp_recv2
diff --git a/libs/libssh2/src/session.c b/libs/libssh2/src/session.c
index 4d9edc5c8c..9d89ade8ec 100644
--- a/libs/libssh2/src/session.c
+++ b/libs/libssh2/src/session.c
@@ -41,7 +41,7 @@
#include "libssh2_priv.h"
-#ifdef WIN32
+#ifdef _WIN32
#include <ws2tcpip.h> /* for socklen_t */
#endif
#ifdef HAVE_UNISTD_H
@@ -60,7 +60,7 @@
#include "channel.h"
#include "mac.h"
-#if defined(WIN32)
+#if defined(_WIN32)
#define libssh2_usec_t long
#elif defined(__APPLE__)
#define libssh2_usec_t suseconds_t
@@ -132,11 +132,11 @@ banner_receive(LIBSSH2_SESSION * session)
if(session->api_block_mode || (ret != -EAGAIN))
/* ignore EAGAIN when non-blocking */
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Error recving %d bytes: %d", 1, (int)-ret));
+ "Error recving %d bytes: %ld", 1, (long)-ret));
}
else
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Recved %d bytes banner", (int)ret));
+ "Recved %ld bytes banner", (long)ret));
if(ret < 0) {
if(ret == -EAGAIN) {
@@ -253,13 +253,14 @@ banner_send(LIBSSH2_SESSION * session)
LIBSSH2_SOCKET_SEND_FLAGS(session));
if(ret < 0)
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Error sending %d bytes: %d",
- banner_len - session->banner_TxRx_total_send, -ret));
+ "Error sending %ld bytes: %ld",
+ (long)(banner_len - session->banner_TxRx_total_send),
+ (long)-ret));
else
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Sent %d/%d bytes at %p+%d", ret,
- banner_len - session->banner_TxRx_total_send,
- banner, session->banner_TxRx_total_send));
+ "Sent %ld/%ld bytes at %p+%ld", (long)ret,
+ (long)(banner_len - session->banner_TxRx_total_send),
+ (void *)banner, (long)session->banner_TxRx_total_send));
if(ret != (ssize_t)(banner_len - session->banner_TxRx_total_send)) {
if(ret >= 0 || ret == -EAGAIN) {
@@ -313,7 +314,7 @@ session_nonblock(libssh2_socket_t sockfd, /* operate on this */
/* BeOS */
long b = nonblock ? 1 : 0;
return setsockopt(sockfd, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-#elif defined(WIN32)
+#elif defined(_WIN32)
unsigned long flags;
flags = nonblock;
@@ -366,7 +367,7 @@ get_socket_nonblocking(libssh2_socket_t sockfd)
return 1;
}
return 0;
-#elif defined(WIN32)
+#elif defined(_WIN32)
unsigned int option_value;
socklen_t option_len = sizeof(option_value);
@@ -417,6 +418,7 @@ libssh2_session_banner_set(LIBSSH2_SESSION * session, const char *banner)
return 0;
}
+#ifndef LIBSSH2_NO_DEPRECATED
/* libssh2_banner_set
* Set the local banner. DEPRECATED VERSION
*/
@@ -425,6 +427,7 @@ libssh2_banner_set(LIBSSH2_SESSION * session, const char *banner)
{
return libssh2_session_banner_set(session, banner);
}
+#endif
/*
* libssh2_session_init_ex
@@ -466,6 +469,8 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
session->abstract = abstract;
session->api_timeout = 0; /* timeout-free API by default */
session->api_block_mode = 1; /* blocking API by default */
+ session->state = LIBSSH2_STATE_INITIAL_KEX;
+ session->fullpacket_required_type = 0;
session->packet_read_timeout = LIBSSH2_DEFAULT_READ_TIMEOUT;
session->flag.quote_paths = 1; /* default behavior is to quote paths
for the scp subsystem */
@@ -477,77 +482,68 @@ libssh2_session_init_ex(LIBSSH2_ALLOC_FUNC((*my_alloc)),
}
/*
- * libssh2_session_callback_set
+ * libssh2_session_callback_set2
*
* Set (or reset) a callback function
* Returns the prior address
- *
- * ALERT: this function relies on that we can typecast function pointers
- * to void pointers, which isn't allowed in ISO C!
*/
-#ifdef _MSC_VER
-#pragma warning(push)
-/* nonstandard extension, function/data pointer conversion in expression */
-#pragma warning(disable:4152)
-#else
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpedantic"
-#endif
-LIBSSH2_API void *
-libssh2_session_callback_set(LIBSSH2_SESSION * session,
- int cbtype, void *callback)
+LIBSSH2_API libssh2_cb_generic *
+libssh2_session_callback_set2(LIBSSH2_SESSION *session, int cbtype,
+ libssh2_cb_generic *callback)
{
- void *oldcb;
+ libssh2_cb_generic *oldcb;
switch(cbtype) {
case LIBSSH2_CALLBACK_IGNORE:
- oldcb = session->ssh_msg_ignore;
- session->ssh_msg_ignore = callback;
+ oldcb = (libssh2_cb_generic *)session->ssh_msg_ignore;
+ session->ssh_msg_ignore = (LIBSSH2_IGNORE_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_DEBUG:
- oldcb = session->ssh_msg_debug;
- session->ssh_msg_debug = callback;
+ oldcb = (libssh2_cb_generic *)session->ssh_msg_debug;
+ session->ssh_msg_debug = (LIBSSH2_DEBUG_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_DISCONNECT:
- oldcb = session->ssh_msg_disconnect;
- session->ssh_msg_disconnect = callback;
+ oldcb = (libssh2_cb_generic *)session->ssh_msg_disconnect;
+ session->ssh_msg_disconnect = (LIBSSH2_DISCONNECT_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_MACERROR:
- oldcb = session->macerror;
- session->macerror = callback;
+ oldcb = (libssh2_cb_generic *)session->macerror;
+ session->macerror = (LIBSSH2_MACERROR_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_X11:
- oldcb = session->x11;
- session->x11 = callback;
+ oldcb = (libssh2_cb_generic *)session->x11;
+ session->x11 = (LIBSSH2_X11_OPEN_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_SEND:
- oldcb = session->send;
- session->send = callback;
+ oldcb = (libssh2_cb_generic *)session->send;
+ session->send = (LIBSSH2_SEND_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_RECV:
- oldcb = session->recv;
- session->recv = callback;
+ oldcb = (libssh2_cb_generic *)session->recv;
+ session->recv = (LIBSSH2_RECV_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_AUTHAGENT:
- oldcb = session->authagent;
- session->authagent = callback;
+ oldcb = (libssh2_cb_generic *)session->authagent;
+ session->authagent = (LIBSSH2_AUTHAGENT_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_AUTHAGENT_IDENTITIES:
- oldcb = session->addLocalIdentities;
- session->addLocalIdentities = callback;
+ oldcb = (libssh2_cb_generic *)session->addLocalIdentities;
+ session->addLocalIdentities =
+ (LIBSSH2_ADD_IDENTITIES_FUNC((*)))callback;
return oldcb;
case LIBSSH2_CALLBACK_AUTHAGENT_SIGN:
- oldcb = session->agentSignCallback;
- session->agentSignCallback = callback;
+ oldcb = (libssh2_cb_generic *)session->agentSignCallback;
+ session->agentSignCallback =
+ (LIBSSH2_AUTHAGENT_SIGN_FUNC((*)))callback;
return oldcb;
}
_libssh2_debug((session, LIBSSH2_TRACE_TRANS, "Setting Callback %d",
@@ -555,6 +551,33 @@ libssh2_session_callback_set(LIBSSH2_SESSION * session,
return NULL;
}
+
+/*
+ * libssh2_session_callback_set (DEPRECATED, DO NOT USE!)
+ *
+ * Set (or reset) a callback function
+ * Returns the prior address
+ *
+ * ALERT: this function relies on that we can typecast function pointers
+ * to void pointers, which isn't allowed in ISO C!
+ */
+#ifdef _MSC_VER
+#pragma warning(push)
+/* 'type cast': from data pointer to function pointer */
+#pragma warning(disable:4054)
+/* 'type cast': from function pointer to data pointer */
+#pragma warning(disable:4055)
+#else
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+LIBSSH2_API void *
+libssh2_session_callback_set(LIBSSH2_SESSION * session,
+ int cbtype, void *callback)
+{
+ return (void *)libssh2_session_callback_set2(session, cbtype,
+ (libssh2_cb_generic *)callback);
+}
#ifdef _MSC_VER
#pragma warning(pop)
#else
@@ -670,6 +693,18 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t start_time)
"Timed out waiting on socket");
}
if(rc < 0) {
+ int err;
+#ifdef _WIN32
+ err = _libssh2_wsa2errno();
+#else
+ err = errno;
+#endif
+ /* Profiling tools that use SIGPROF can cause EINTR responses.
+ poll() / select() do not set any descriptor states on EINTR,
+ but some fds may be ready, so the caller should try again */
+ if(err == EINTR)
+ return 0;
+
return _libssh2_error(session, LIBSSH2_ERROR_TIMEOUT,
"Error waiting on socket");
}
@@ -684,7 +719,7 @@ session_startup(LIBSSH2_SESSION *session, libssh2_socket_t sock)
if(session->startup_state == libssh2_NB_state_idle) {
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
- "session_startup for socket %d", sock));
+ "session_startup for socket %ld", (long)sock));
if(LIBSSH2_INVALID_SOCKET == sock) {
/* Did we forget something? */
return _libssh2_error(session, LIBSSH2_ERROR_BAD_SOCKET,
@@ -830,6 +865,7 @@ libssh2_session_handshake(LIBSSH2_SESSION *session, libssh2_socket_t sock)
return rc;
}
+#ifndef LIBSSH2_NO_DEPRECATED
/*
* libssh2_session_startup
*
@@ -846,6 +882,7 @@ libssh2_session_startup(LIBSSH2_SESSION *session, int sock)
{
return libssh2_session_handshake(session, (libssh2_socket_t) sock);
}
+#endif
/*
* session_free
@@ -864,8 +901,8 @@ session_free(LIBSSH2_SESSION *session)
if(session->free_state == libssh2_NB_state_idle) {
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
- "Freeing session resource",
- session->remote.banner));
+ "Freeing session resource %p",
+ (void *)session->remote.banner));
session->free_state = libssh2_NB_state_created;
}
@@ -1188,6 +1225,7 @@ libssh2_session_disconnect_ex(LIBSSH2_SESSION *session, int reason,
const char *desc, const char *lang)
{
int rc;
+ session->state &= ~LIBSSH2_STATE_INITIAL_KEX;
session->state &= ~LIBSSH2_STATE_EXCHANGING_KEYS;
BLOCK_ADJUST(rc, session,
session_disconnect(session, reason, desc, lang));
@@ -1773,7 +1811,11 @@ libssh2_poll(LIBSSH2_POLLFD * fds, unsigned int nfds, long timeout)
}
#elif defined(HAVE_SELECT)
tv.tv_sec = timeout_remaining / 1000;
+#ifdef libssh2_usec_t
+ tv.tv_usec = (libssh2_usec_t)((timeout_remaining % 1000) * 1000);
+#else
tv.tv_usec = (timeout_remaining % 1000) * 1000;
+#endif
{
struct timeval tv_begin, tv_end;
diff --git a/libs/libssh2/src/session.h b/libs/libssh2/src/session.h
index bfc9b545b8..d4fc5755e5 100644
--- a/libs/libssh2/src/session.h
+++ b/libs/libssh2/src/session.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_SESSION_H
-#define __LIBSSH2_SESSION_H
+#ifndef LIBSSH2_SESSION_H
+#define LIBSSH2_SESSION_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson <simon@josefsson.org>
@@ -91,4 +91,4 @@ int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time);
/* this is the lib-internal set blocking function */
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
-#endif /* __LIBSSH2_SESSION_H */
+#endif /* LIBSSH2_SESSION_H */
diff --git a/libs/libssh2/src/sftp.c b/libs/libssh2/src/sftp.c
index 16ee7b8689..f8f1323e02 100644
--- a/libs/libssh2/src/sftp.c
+++ b/libs/libssh2/src/sftp.c
@@ -152,7 +152,7 @@ remove_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
request_id);
if(zombie) {
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "Removing request ID %ld from the list of "
+ "Removing request ID %u from the list of "
"zombie requests",
request_id));
@@ -169,13 +169,13 @@ add_zombie_request(LIBSSH2_SFTP *sftp, uint32_t request_id)
struct sftp_zombie_requests *zombie;
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "Marking request ID %ld as a zombie request", request_id));
+ "Marking request ID %u as a zombie request", request_id));
zombie = LIBSSH2_ALLOC(sftp->channel->session,
sizeof(struct sftp_zombie_requests));
if(!zombie)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
- "malloc fail for zombie request ID");
+ "malloc fail for zombie request ID");
else {
zombie->request_id = request_id;
_libssh2_list_add(&sftp->zombie_requests, &zombie->node);
@@ -199,8 +199,8 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
}
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "Received packet type %d (len %d)",
- (int) data[0], data_len));
+ "Received packet type %u (len %lu)",
+ (unsigned int)data[0], (unsigned long)data_len));
/*
* Experience shows that if we mess up EAGAIN handling somewhere or
@@ -306,11 +306,11 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
packet = sftp->partial_packet;
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "partial read cont, len: %lu", sftp->partial_len));
+ "partial read cont, len: %u", sftp->partial_len));
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
"partial read cont, already recvd: %lu",
- sftp->partial_received));
- /* fall-through */
+ (unsigned long)sftp->partial_received));
+ LIBSSH2_FALLTHROUGH();
default:
if(!packet) {
/* only do this if there's not already a packet buffer allocated
@@ -359,7 +359,7 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
"Data begin - Packet Length: %lu",
- sftp->partial_len));
+ (unsigned long)sftp->partial_len));
packet = LIBSSH2_ALLOC(session, sftp->partial_len);
if(!packet)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
@@ -526,13 +526,13 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
return LIBSSH2_ERROR_BAD_USE;
}
- _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld",
- (int) packet_type, request_id));
+ _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Requiring packet %u id %u",
+ (unsigned int) packet_type, request_id));
if(sftp_packet_ask(sftp, packet_type, request_id, data, data_len) == 0) {
/* The right packet was available in the packet brigade */
- _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Got %d",
- (int) packet_type));
+ _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Got %u",
+ (unsigned int) packet_type));
if(*data_len < required_size) {
return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
@@ -550,7 +550,7 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
if(!sftp_packet_ask(sftp, packet_type, request_id, data, data_len)) {
/* The right packet was available in the packet brigade */
_libssh2_debug((session, LIBSSH2_TRACE_SFTP, "Got %d",
- (int) packet_type));
+ (unsigned int) packet_type));
if(*data_len < required_size) {
return LIBSSH2_ERROR_BUFFER_TOO_SMALL;
@@ -979,12 +979,12 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
if(sftp_handle->version > LIBSSH2_SFTP_VERSION) {
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "Truncating remote SFTP version from %lu",
+ "Truncating remote SFTP version from %u",
sftp_handle->version));
sftp_handle->version = LIBSSH2_SFTP_VERSION;
}
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "Enabling SFTP version %lu compatibility",
+ "Enabling SFTP version %u compatibility",
sftp_handle->version));
while(buf.dataptr < endp) {
unsigned char *extname, *extdata;
@@ -1567,10 +1567,11 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
more packets */
count -= LIBSSH2_MIN(size, count);
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "read request id %d sent (offset: %d, size: %d)",
- request_id, (int)chunk->offset, (int)chunk->len));
+ "read request id %d sent (offset: %lu, size: %lu)",
+ request_id, (unsigned long)chunk->offset,
+ (unsigned long)chunk->len));
}
- /* FALL-THROUGH */
+ LIBSSH2_FALLTHROUGH();
case libssh2_NB_state_sent:
sftp->read_state = libssh2_NB_state_idle;
@@ -1610,7 +1611,7 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
/* move on to the next chunk with data to send */
chunk = _libssh2_list_next(&chunk->node);
}
- /* FALL-THROUGH */
+ LIBSSH2_FALLTHROUGH();
case libssh2_NB_state_sent2:
@@ -1690,7 +1691,6 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP READ error");
}
- break;
case SSH_FXP_DATA:
if(chunk->offset != filep->offset) {
@@ -1922,8 +1922,8 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
end:
_libssh2_debug((session, LIBSSH2_TRACE_SFTP,
- "libssh2_sftp_readdir_ex() return %d",
- filename_len));
+ "libssh2_sftp_readdir_ex() return %lu",
+ (unsigned long)filename_len));
return (ssize_t)filename_len;
}
@@ -2003,7 +2003,7 @@ end:
sftp->readdir_state = libssh2_NB_state_idle;
num_names = _libssh2_ntohu32(data + 5);
- _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "%lu entries returned",
+ _libssh2_debug((session, LIBSSH2_TRACE_SFTP, "%u entries returned",
num_names));
if(!num_names) {
LIBSSH2_FREE(session, data);
@@ -2185,7 +2185,8 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
chunk = _libssh2_list_next(&chunk->node);
}
- /* fall-through */
+ LIBSSH2_FALLTHROUGH();
+
case libssh2_NB_state_sent:
sftp->write_state = libssh2_NB_state_idle;
diff --git a/libs/libssh2/src/sftp.h b/libs/libssh2/src/sftp.h
index 647ddbc007..267c8fef0d 100644
--- a/libs/libssh2/src/sftp.h
+++ b/libs/libssh2/src/sftp.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_SFTP_H
-#define __LIBSSH2_SFTP_H
+#ifndef LIBSSH2_SFTP_PRIV_H
+#define LIBSSH2_SFTP_PRIV_H
/*
* Copyright (C) Daniel Stenberg
* All rights reserved.
@@ -233,4 +233,4 @@ struct _LIBSSH2_SFTP
uint32_t symlink_request_id;
};
-#endif /* __LIBSSH2_SFTP_H */
+#endif /* LIBSSH2_SFTP_PRIV_H */
diff --git a/libs/libssh2/src/transport.c b/libs/libssh2/src/transport.c
index c73b859e4d..531f5aa15a 100644
--- a/libs/libssh2/src/transport.c
+++ b/libs/libssh2/src/transport.c
@@ -51,9 +51,6 @@
#include "transport.h"
#include "mac.h"
-#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
-#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */
-
#ifdef LIBSSH2DEBUG
#define UNPRINTABLE_CHAR '.'
static void
@@ -72,8 +69,8 @@ debugdump(LIBSSH2_SESSION * session,
return;
}
- used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
- desc, (int) size);
+ used = snprintf(buffer, sizeof(buffer), "=> %s (%lu bytes)\n",
+ desc, (unsigned long) size);
if(session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context,
buffer, used);
@@ -189,6 +186,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
struct transportpacket *p = &session->packet;
int rc;
int compressed;
+ uint32_t seq = session->remote.seqno;
if(session->fullpacket_state == libssh2_NB_state_idle) {
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
@@ -320,7 +318,7 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
if(session->fullpacket_state == libssh2_NB_state_created) {
rc = _libssh2_packet_add(session, p->payload,
session->fullpacket_payload_len,
- session->fullpacket_macstate);
+ session->fullpacket_macstate, seq);
if(rc == LIBSSH2_ERROR_EAGAIN)
return rc;
if(rc) {
@@ -331,6 +329,11 @@ fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
session->fullpacket_state = libssh2_NB_state_idle;
+ if(session->kex_strict &&
+ session->fullpacket_packet_type == SSH_MSG_NEWKEYS) {
+ session->remote.seqno = 0;
+ }
+
return session->fullpacket_packet_type;
}
@@ -467,13 +470,15 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
return LIBSSH2_ERROR_EAGAIN;
}
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Error recving %d bytes (got %d)",
- PACKETBUFSIZE - remainbuf, -nread));
+ "Error recving %ld bytes (got %ld)",
+ (long)(PACKETBUFSIZE - remainbuf),
+ (long)-nread));
return LIBSSH2_ERROR_SOCKET_RECV;
}
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Recved %d/%d bytes to %p+%d", nread,
- PACKETBUFSIZE - remainbuf, p->buf, remainbuf));
+ "Recved %ld/%ld bytes to %p+%ld", (long)nread,
+ (long)(PACKETBUFSIZE - remainbuf), (void *)p->buf,
+ (long)remainbuf));
debugdump(session, "libssh2_transport_read() raw",
&p->buf[remainbuf], nread);
@@ -790,11 +795,12 @@ send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if(rc < 0)
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Error sending %d bytes: %d", length, -rc));
+ "Error sending %ld bytes: %ld",
+ (long)length, (long)-rc));
else {
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
- p->osent));
+ "Sent %ld/%ld bytes at %p+%lu", (long)rc, (long)length,
+ (void *)p->outbuf, (unsigned long)p->osent));
debugdump(session, "libssh2_transport_write send()",
&p->outbuf[p->osent], rc);
}
@@ -1022,10 +1028,12 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
INTEGRATED_MAC case, where the crypto algorithm also does its
own hash. */
if(!etm && !CRYPT_FLAG_R(session, INTEGRATED_MAC)) {
- session->local.mac->hash(session, p->outbuf + packet_length,
- session->local.seqno, p->outbuf,
- packet_length, NULL, 0,
- &session->local.mac_abstract);
+ if(session->local.mac->hash(session, p->outbuf + packet_length,
+ session->local.seqno, p->outbuf,
+ packet_length, NULL, 0,
+ &session->local.mac_abstract))
+ return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
+ "Failed to calculate MAC");
}
/* Encrypt the whole packet data, one block size at a time.
@@ -1058,8 +1066,8 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
i += bsize - session->local.crypt->blocksize;
}
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "crypting bytes %d-%d", i,
- i + session->local.crypt->blocksize - 1));
+ "crypting bytes %lu-%lu", (unsigned long)i,
+ (unsigned long)(i + bsize - 1)));
if(session->local.crypt->crypt(session, ptr,
bsize,
&session->local.crypt_abstract,
@@ -1084,24 +1092,31 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
calculated on the entire packet (length plain the rest
encrypted), including all fields except the MAC field
itself. */
- session->local.mac->hash(session, p->outbuf + packet_length,
- session->local.seqno, p->outbuf,
- packet_length, NULL, 0,
- &session->local.mac_abstract);
+ if(session->local.mac->hash(session, p->outbuf + packet_length,
+ session->local.seqno, p->outbuf,
+ packet_length, NULL, 0,
+ &session->local.mac_abstract))
+ return _libssh2_error(session, LIBSSH2_ERROR_MAC_FAILURE,
+ "Failed to calculate MAC");
}
}
session->local.seqno++;
+ if(session->kex_strict && data[0] == SSH_MSG_NEWKEYS) {
+ session->local.seqno = 0;
+ }
+
ret = LIBSSH2_SEND(session, p->outbuf, total_length,
LIBSSH2_SOCKET_SEND_FLAGS(session));
if(ret < 0)
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Error sending %d bytes: %d", total_length, -ret));
+ "Error sending %ld bytes: %ld",
+ (long)total_length, (long)-ret));
else {
_libssh2_debug((session, LIBSSH2_TRACE_SOCKET,
- "Sent %d/%d bytes at %p",
- ret, total_length, p->outbuf));
+ "Sent %ld/%ld bytes at %p",
+ (long)ret, (long)total_length, (void *)p->outbuf));
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
}
diff --git a/libs/libssh2/src/transport.h b/libs/libssh2/src/transport.h
index 64482290ee..4b824e2096 100644
--- a/libs/libssh2/src/transport.h
+++ b/libs/libssh2/src/transport.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_TRANSPORT_H
-#define __LIBSSH2_TRANSPORT_H
+#ifndef LIBSSH2_TRANSPORT_H
+#define LIBSSH2_TRANSPORT_H
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* All rights reserved.
@@ -84,4 +84,4 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
*/
int _libssh2_transport_read(LIBSSH2_SESSION * session);
-#endif /* __LIBSSH2_TRANSPORT_H */
+#endif /* LIBSSH2_TRANSPORT_H */
diff --git a/libs/libssh2/src/userauth.c b/libs/libssh2/src/userauth.c
index e7578759f3..60fd48e47d 100644
--- a/libs/libssh2/src/userauth.c
+++ b/libs/libssh2/src/userauth.c
@@ -818,11 +818,17 @@ struct privkey_file {
const char *passphrase;
};
+struct privkey_mem {
+ const char *passphrase;
+ const char *data;
+ size_t data_len;
+};
+
static int
sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
const unsigned char *data, size_t data_len, void **abstract)
{
- struct privkey_file *pk_file = (struct privkey_file *) (*abstract);
+ struct privkey_mem *pk_mem = (struct privkey_mem *) (*abstract);
const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
void *hostkey_abstract;
struct iovec datavec;
@@ -831,9 +837,9 @@ sign_frommemory(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len,
rc = memory_read_privatekey(session, &privkeyobj, &hostkey_abstract,
session->userauth_pblc_method,
session->userauth_pblc_method_len,
- pk_file->filename,
- strlen(pk_file->filename),
- pk_file->passphrase);
+ pk_mem->data,
+ pk_mem->data_len,
+ pk_mem->passphrase);
if(rc)
return rc;
@@ -1410,7 +1416,7 @@ _libssh2_key_sign_algorithm(LIBSSH2_SESSION *session,
LIBSSH2_FREE(session, *key_method);
*key_method = LIBSSH2_ALLOC(session, match_len);
- if(key_method) {
+ if(*key_method) {
memcpy(*key_method, match, match_len);
*key_method_len = match_len;
}
@@ -1511,7 +1517,7 @@ retry_auth:
_libssh2_debug((session,
LIBSSH2_TRACE_KEX,
"Signing using %.*s",
- session->userauth_pblc_method_len,
+ (int)session->userauth_pblc_method_len,
session->userauth_pblc_method));
}
@@ -1835,12 +1841,13 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
{
unsigned char *pubkeydata = NULL;
size_t pubkeydata_len = 0;
- struct privkey_file privkey_file;
- void *abstract = &privkey_file;
+ struct privkey_mem privkey_mem;
+ void *abstract = &privkey_mem;
int rc;
- privkey_file.filename = privatekeydata;
- privkey_file.passphrase = passphrase;
+ privkey_mem.data = privatekeydata;
+ privkey_mem.data_len = privatekeydata_len;
+ privkey_mem.passphrase = passphrase;
if(session->userauth_pblc_state == libssh2_NB_state_idle) {
if(publickeydata_len && publickeydata) {
diff --git a/libs/libssh2/src/userauth.h b/libs/libssh2/src/userauth.h
index 24f8037ec2..2f53ac5be9 100644
--- a/libs/libssh2/src/userauth.h
+++ b/libs/libssh2/src/userauth.h
@@ -1,5 +1,5 @@
-#ifndef __LIBSSH2_USERAUTH_H
-#define __LIBSSH2_USERAUTH_H
+#ifndef LIBSSH2_USERAUTH_H
+#define LIBSSH2_USERAUTH_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* All rights reserved.
@@ -50,4 +50,4 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
((*sign_callback)),
void *abstract);
-#endif /* __LIBSSH2_USERAUTH_H */
+#endif /* LIBSSH2_USERAUTH_H */
diff --git a/libs/libssh2/src/userauth_kbd_packet.h b/libs/libssh2/src/userauth_kbd_packet.h
index bee34495e1..56e88b3f32 100644
--- a/libs/libssh2/src/userauth_kbd_packet.h
+++ b/libs/libssh2/src/userauth_kbd_packet.h
@@ -37,9 +37,9 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
-#ifndef __LIBSSH2_USERAUTH_KBD_PARSE_H
-#define __LIBSSH2_USERAUTH_KBD_PARSE_H
+#ifndef LIBSSH2_USERAUTH_KBD_PACKET_H
+#define LIBSSH2_USERAUTH_KBD_PACKET_H
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *);
-#endif /* __LIBSSH2_USERAUTH_KBD_PARSE_H */
+#endif /* LIBSSH2_USERAUTH_KBD_PACKET_H */