初始提交:terminalX 可运行态(M0/M1/M1.5 已真机验证)

- M0: libghostty SSH 终端(渲染/输入/连接)+ 白屏修复(OutputGate) + 会话状态机/自动重连
- M1: tsnet 用户态组网 + SSH-over-tsnet(fd 桥),shell 级真机验证;R5(Go+gvisor+C+++Swift 同进程) retire
- M1.5: tmux -CC 原生 tab(MVP)
- 结构: packages/(TXCore·TXTransport), apps/TerminalX, vendor/(libghostty-spm/libssh2/mbedtls/tsnet-bridge), artifacts/
- 文档: CLAUDE.md + docs/HANDOFF.md(新会话入口)
- 环境: 认证代理→依赖 vendor 本地化;Go 在 ~/.local/go;仅模拟器/未签名
- 待续: M2 mosh, tmux 多 pane, M4 安全(host key/SE)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kid
2026-07-24 10:20:46 +08:00
commit aa92d0e676
2761 changed files with 803505 additions and 0 deletions

7
vendor/libssh2/src/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
.deps
.libs
Makefile.inc.cmake
libssh2.pc
libssh2_config.h
libssh2_config.h.in
stamp-h1

341
vendor/libssh2/src/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,341 @@
# Copyright (C) Alexander Lamaison <alexander.lamaison@gmail.com>
# Copyright (C) Viktor Szakats
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
# Redistributions of source code must retain the above
# copyright notice, this list of conditions and the
# following disclaimer.
#
# Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# Neither the name of the copyright holder nor the names
# of any other contributors may be used to endorse or
# promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# 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()
## Options
unset(_libssh2_definitions)
option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON)
if(NOT CLEAR_MEMORY)
list(APPEND _libssh2_definitions "LIBSSH2_NO_CLEAR_MEMORY")
endif()
option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression" OFF)
add_feature_info(Compression ENABLE_ZLIB_COMPRESSION
"using zlib for compression")
if(ENABLE_ZLIB_COMPRESSION)
find_package(ZLIB REQUIRED)
list(APPEND libssh2_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
list(APPEND LIBSSH2_LIBS ${ZLIB_LIBRARIES})
list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "zlib")
if(ZLIB_FOUND)
list(APPEND _libssh2_definitions "LIBSSH2_HAVE_ZLIB")
endif()
endif()
list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET})
# to find generated header
list(APPEND libssh2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
if(MSVC)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
endif()
## Sources
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")
set(_sources ${CSOURCES} ${HHEADERS})
## Library definition
# Ensure that the static library and import library filenames are different,
# when building both static and shared library. On Windows, with certain
# toolchains (e.g. MSVC) these libraries get the same by default, overwriting
# each other. MinGW is not affected.
if(WIN32 AND BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS AND
NOT STATIC_LIB_SUFFIX AND NOT IMPORT_LIB_SUFFIX AND
CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX)
set(STATIC_LIB_SUFFIX "_static")
endif()
unset(_libssh2_export)
# we want it to be called libssh2 on all platforms
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 ${LIBSSH2_LIBS})
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}>")
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")
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 ${LIBSSH2_LIBS})
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}>")
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"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(BUILD_STATIC_LIBS)
install(TARGETS ${LIB_STATIC}
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 "${PROJECT_NAME}-targets"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
list(APPEND _RUNTIME_DEPENDENCIES $<TARGET_FILE:${LIB_SHARED}>)
endif()
set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL
"Files that must be in the same directory as the executables at runtime.")
# Package config
## 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 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 with dependencies
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"
"${PROJECT_SOURCE_DIR}/cmake/FindLibgcrypt.cmake"
"${PROJECT_SOURCE_DIR}/cmake/FindMbedTLS.cmake"
"${PROJECT_SOURCE_DIR}/cmake/FindWolfSSL.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
# Calculate variables for pkg-config
set(LIBSSH2_PC_LIBS_PRIVATE "")
if(WIN32)
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lws2_32")
endif()
set(_ldflags "")
# Avoid getting unnecessary -L options for known system directories.
unset(_sys_libdirs)
foreach(_libdir IN LISTS CMAKE_SYSTEM_PREFIX_PATH)
if(_libdir MATCHES "/$")
set(_libdir "${_libdir}lib")
else()
set(_libdir "${_libdir}/lib")
endif()
if(IS_DIRECTORY "${_libdir}")
list(APPEND _sys_libdirs "${_libdir}")
endif()
if(DEFINED CMAKE_LIBRARY_ARCHITECTURE)
set(_libdir "${_libdir}/${CMAKE_LIBRARY_ARCHITECTURE}")
if(IS_DIRECTORY "${_libdir}")
list(APPEND _sys_libdirs "${_libdir}")
endif()
endif()
endforeach()
foreach(_libdir IN LISTS LIBSSH2_LIBDIRS)
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
endif()
endforeach()
unset(_implicit_libs)
if(NOT MINGW AND NOT UNIX)
set(_implicit_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
endif()
foreach(_lib IN LISTS _implicit_libs LIBSSH2_LIBS)
if(TARGET "${_lib}")
set(_libname "${_lib}")
get_target_property(_imported "${_libname}" IMPORTED)
if(NOT _imported)
# Reading the LOCATION property on non-imported target will error out.
# Assume the user will not need this information in the .pc file.
continue()
endif()
get_target_property(_lib "${_libname}" LOCATION)
if(NOT _lib)
message(WARNING "Bad lib in library list: ${_libname}")
continue()
endif()
endif()
if(_lib MATCHES "^-")
list(APPEND _ldflags "${_lib}")
elseif(_lib MATCHES ".*/.*")
# This gets a bit more complex, because we want to specify the
# directory separately, and only once per directory
get_filename_component(_libdir ${_lib} DIRECTORY)
get_filename_component(_libname ${_lib} NAME_WE)
if(_libname MATCHES "^lib")
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
endif()
string(REGEX REPLACE "^lib" "" _libname "${_libname}")
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-l${_libname}")
else()
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${_lib}")
endif()
else()
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-l${_lib}")
endif()
endforeach()
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(_ldflags)
list(REMOVE_DUPLICATES _ldflags)
string(REPLACE ";" " " _ldflags "${_ldflags}")
set(LIBSSH2_PC_LIBS_PRIVATE "${_ldflags} ${LIBSSH2_PC_LIBS_PRIVATE}")
string(STRIP "${LIBSSH2_PC_LIBS_PRIVATE}" LIBSSH2_PC_LIBS_PRIVATE)
endif()
# Merge 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(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
if(IS_ABSOLUTE ${CMAKE_INSTALL_INCLUDEDIR})
set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
else()
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
if(IS_ABSOLUTE ${CMAKE_INSTALL_LIBDIR})
set(libdir "${CMAKE_INSTALL_LIBDIR}")
else()
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()
# Generate a pkg-config file for client projects not using CMake.
# Consumed variables:
# exec_prefix
# includedir
# LIBSSH2_PC_LIBS
# LIBSSH2_PC_LIBS_PRIVATE
# LIBSSH2_PC_REQUIRES
# LIBSSH2_PC_REQUIRES_PRIVATE
# LIBSSH2_VERSION
# libdir
# prefix
configure_file("${PROJECT_SOURCE_DIR}/libssh2.pc.in" "libssh2.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
#
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${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}/${PROJECT_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")

61
vendor/libssh2/src/Makefile.am vendored Normal file
View File

@@ -0,0 +1,61 @@
# Copyright (C) The libssh2 project and its contributors.
# SPDX-License-Identifier: BSD-3-Clause
AUTOMAKE_OPTIONS = foreign nostdinc
# Get the CSOURCES, HHEADERS and EXTRA_DIST defines
include Makefile.inc
libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS)
if HAVE_WINDRES
libssh2_la_SOURCES += libssh2.rc
endif
EXTRA_DIST += libssh2_config.h.in libssh2_config_cmake.h.in CMakeLists.txt
lib_LTLIBRARIES = libssh2.la
# srcdir/include for the shipped headers
# builddir/src for the generated config header when building out of the source
# tree
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/include
# This might hold -Werror
AM_CFLAGS = @LIBSSH2_CFLAG_EXTRAS@
VERSION=-version-info 1:1:0
# This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
# 1.
#
# If either revision or age are omitted, they default to 0. Also note that age
# must be less than or equal to the current interface number.
#
# Here are a set of rules to help you update your library version information:
#
# 1.Start with version information of 0:0:0 for each libtool library.
#
# 2.Update the version information only immediately before a public release of
# your software. More frequent updates are unnecessary, and only guarantee
# that the current interface number gets larger faster.
#
# 3.If the library source code has changed at all since the last update, then
# increment revision (c:r+1:a)
#
# 4.If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0. (c+1:r=0:a)
#
# 5.If any interfaces have been added since the last public release, then
# increment age. (c:r:a+1)
#
# 6.If any interfaces have been removed since the last public release, then
# set age to 0. (c:r:a=0)
#
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
-export-symbols-regex '^libssh2_.*'
if HAVE_WINDRES
.rc.lo:
$(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@
endif

62
vendor/libssh2/src/Makefile.inc vendored Normal file
View File

@@ -0,0 +1,62 @@
# Copyright (C) The libssh2 project and its contributors.
# SPDX-License-Identifier: BSD-3-Clause
CSOURCES = \
agent.c \
bcrypt_pbkdf.c \
channel.c \
comp.c \
chacha.c \
cipher-chachapoly.c \
crypt.c \
crypto.c \
global.c \
hostkey.c \
keepalive.c \
kex.c \
knownhost.c \
mac.c \
misc.c \
packet.c \
pem.c \
poly1305.c \
publickey.c \
scp.c \
session.c \
sftp.c \
transport.c \
userauth.c \
userauth_kbd_packet.c \
version.c
HHEADERS = \
chacha.h \
channel.h \
cipher-chachapoly.h \
comp.h \
crypto.h \
crypto_config.h \
libgcrypt.h \
libssh2_priv.h \
libssh2_setup.h \
mac.h \
mbedtls.h \
misc.h \
openssl.h \
os400qc3.h \
packet.h \
poly1305.h \
session.h \
sftp.h \
transport.h \
userauth.h \
userauth_kbd_packet.h \
wincng.h
EXTRA_DIST = \
agent_win.c \
blowfish.c \
libgcrypt.c \
mbedtls.c \
openssl.c \
os400qc3.c \
wincng.c

1032
vendor/libssh2/src/agent.c vendored Normal file

File diff suppressed because it is too large Load Diff

349
vendor/libssh2/src/agent_win.c vendored Normal file
View File

@@ -0,0 +1,349 @@
/*
* Copyright (C) Daiki Ueno
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause AND BSD-2-Clause
*/
#ifdef HAVE_WIN32_AGENTS /* Compile this via agent.c */
#include <stdlib.h> /* for getenv() */
/* Code to talk to OpenSSH was taken and modified from the Win32 port of
* Portable OpenSSH by the PowerShell team. Commit
* 8ab565c53f3619d6a1f5ac229e212cad8a52852c of
* https://github.com/PowerShell/openssh-portable.git was used as the base,
* specifically the following files:
*
* - contrib\win32\win32compat\fileio.c
* - Structure of agent_connect_openssh from ssh_get_authentication_socket
* - Structure of agent_transact_openssh from ssh_request_reply
* - contrib\win32\win32compat\wmain_common.c
* - Windows equivalent functions for common Unix functions, inlined into
* this implementation
* - fileio_connect replacing connect
* - fileio_read replacing read
* - fileio_write replacing write
* - fileio_close replacing close
*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Functions for connecting the local authentication agent.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 implementation,
* Copyright (C) 2000 Markus Friedl. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright (C) 2015 Microsoft Corp.
* All rights reserved
*
* Microsoft openssh win32 port
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define WIN32_OPENSSH_AGENT_SOCK "\\\\.\\pipe\\openssh-ssh-agent"
static int
agent_connect_openssh(LIBSSH2_AGENT *agent)
{
int ret = LIBSSH2_ERROR_NONE;
const char *path;
HANDLE pipe = INVALID_HANDLE_VALUE;
HANDLE event = NULL;
path = agent->identity_agent_path;
if(!path) {
path = getenv("SSH_AUTH_SOCK");
if(!path)
path = WIN32_OPENSSH_AGENT_SOCK;
}
for(;;) {
pipe = CreateFileA(
path,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
/* Non-blocking mode for agent connections is not implemented at
* the point this was implemented. The code for Win32 OpenSSH
* should support non-blocking IO, but the code calling it doesn't
* support it as of yet.
* When non-blocking IO is implemented for the surrounding code,
* uncomment the following line to enable support within the Win32
* OpenSSH code.
*/
/* FILE_FLAG_OVERLAPPED | */
SECURITY_SQOS_PRESENT |
SECURITY_IDENTIFICATION,
NULL
);
if(pipe != INVALID_HANDLE_VALUE)
break;
if(GetLastError() != ERROR_PIPE_BUSY)
break;
/* Wait up to 1 second for a pipe instance to become available */
if(!WaitNamedPipeA(path, 1000))
break;
}
if(pipe == INVALID_HANDLE_VALUE) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to connect to agent pipe");
goto cleanup;
}
if(SetHandleInformation(pipe, HANDLE_FLAG_INHERIT, 0) == FALSE) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to set handle information of agent pipe");
goto cleanup;
}
event = CreateEventA(NULL, TRUE, FALSE, NULL);
if(!event) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to create async I/O event");
goto cleanup;
}
agent->pipe = pipe;
pipe = INVALID_HANDLE_VALUE;
agent->overlapped.hEvent = event;
event = NULL;
agent->fd = 0; /* Mark as the connection has been established */
cleanup:
if(event)
CloseHandle(event);
if(pipe != INVALID_HANDLE_VALUE)
CloseHandle(pipe);
return ret;
}
#define RECV_SEND_ALL(func, agent, buffer, length, total) \
DWORD bytes_transfered; \
BOOL ret; \
DWORD err; \
int rc; \
\
while(*total < length) { \
if(!agent->pending_io) \
ret = func(agent->pipe, (char *)buffer + *total, \
(DWORD)(length - *total), &bytes_transfered, \
&agent->overlapped); \
else \
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, \
&bytes_transfered, FALSE); \
\
*total += bytes_transfered; \
if(!ret) { \
err = GetLastError(); \
if((!agent->pending_io && ERROR_IO_PENDING == err) \
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) { \
agent->pending_io = TRUE; \
return LIBSSH2_ERROR_EAGAIN; \
} \
\
return LIBSSH2_ERROR_SOCKET_NONE; \
} \
agent->pending_io = FALSE; \
} \
\
rc = (int)*total; \
*total = 0; \
return rc;
static int
win32_openssh_send_all(LIBSSH2_AGENT *agent, void *buffer, size_t length,
size_t *send_recv_total)
{
RECV_SEND_ALL(WriteFile, agent, buffer, length, send_recv_total)
}
static int
win32_openssh_recv_all(LIBSSH2_AGENT *agent, void *buffer, size_t length,
size_t *send_recv_total)
{
RECV_SEND_ALL(ReadFile, agent, buffer, length, send_recv_total)
}
#undef RECV_SEND_ALL
static int
agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
unsigned char buf[4];
int rc;
/* Send the length of the request */
if(transctx->state == agent_NB_state_request_created) {
_libssh2_htonu32(buf, (uint32_t)transctx->request_len);
rc = win32_openssh_send_all(agent, buf, sizeof(buf),
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
transctx->state = agent_NB_state_request_length_sent;
}
/* Send the request body */
if(transctx->state == agent_NB_state_request_length_sent) {
rc = win32_openssh_send_all(agent, transctx->request,
transctx->request_len,
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
transctx->state = agent_NB_state_request_sent;
}
/* Receive the length of the body */
if(transctx->state == agent_NB_state_request_sent) {
rc = win32_openssh_recv_all(agent, buf, sizeof(buf),
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
transctx->response_len = _libssh2_ntohu32(buf);
transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len);
if(!transctx->response)
return LIBSSH2_ERROR_ALLOC;
transctx->state = agent_NB_state_response_length_received;
}
/* Receive the response body */
if(transctx->state == agent_NB_state_response_length_received) {
rc = win32_openssh_recv_all(agent, transctx->response,
transctx->response_len,
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
transctx->state = agent_NB_state_response_received;
}
return LIBSSH2_ERROR_NONE;
}
static int
agent_disconnect_openssh(LIBSSH2_AGENT *agent)
{
if(!CancelIo(agent->pipe))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to cancel pending IO of agent pipe");
if(!CloseHandle(agent->overlapped.hEvent))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to close handle to async I/O event");
agent->overlapped.hEvent = NULL;
/* let queued APCs (if any) drain */
SleepEx(0, TRUE);
if(!CloseHandle(agent->pipe))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to close handle to agent pipe");
agent->pipe = INVALID_HANDLE_VALUE;
agent->fd = LIBSSH2_INVALID_SOCKET;
return LIBSSH2_ERROR_NONE;
}
static struct agent_ops agent_ops_openssh = {
agent_connect_openssh,
agent_transact_openssh,
agent_disconnect_openssh
};
#endif /* HAVE_WIN32_AGENTS */

210
vendor/libssh2/src/bcrypt_pbkdf.c vendored Normal file
View File

@@ -0,0 +1,210 @@
/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */
/*
* Copyright (C) Ted Unangst <tedu@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#include "libssh2_priv.h"
#ifndef HAVE_BCRYPT_PBKDF
#include <stdlib.h>
#define LIBSSH2_BCRYPT_PBKDF_C
#include "blowfish.c"
/*
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
*
* The bcrypt hash function is derived from the bcrypt password hashing
* function with the following modifications:
* 1. The input password and salt are preprocessed with SHA512.
* 2. The output length is expanded to 256 bits.
* 3. Subsequently the magic string to be encrypted is lengthened and modified
* to "OxychromaticBlowfishSwatDynamite"
* 4. The hash function is defined to perform 64 rounds of initial state
* expansion. (More rounds are performed by iterating the hash.)
*
* Note that this implementation pulls the SHA512 operations into the caller
* as a performance optimization.
*
* One modification from official pbkdf2. Instead of outputting key material
* linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
* generate (i.e.) 512 bits of key material for use as two 256 bit keys, an
* attacker can merely run once through the outer loop below, but the user
* always runs it twice. Shuffling output bytes requires computing the
* entirety of the key material to assemble any subkey. This is something a
* wise caller could do; we just do it for you.
*/
#define BCRYPT_BLOCKS 8
#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4)
static void
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
{
blf_ctx state;
uint8_t ciphertext[BCRYPT_HASHSIZE] = {
'O', 'x', 'y', 'c', 'h', 'r', 'o', 'm', 'a', 't', 'i', 'c',
'B', 'l', 'o', 'w', 'f', 'i', 's', 'h',
'S', 'w', 'a', 't',
'D', 'y', 'n', 'a', 'm', 'i', 't', 'e' };
uint32_t cdata[BCRYPT_BLOCKS];
int i;
uint16_t j;
uint16_t shalen = SHA512_DIGEST_LENGTH;
/* key expansion */
Blowfish_initstate(&state);
Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
for(i = 0; i < 64; i++) {
Blowfish_expand0state(&state, sha2salt, shalen);
Blowfish_expand0state(&state, sha2pass, shalen);
}
/* encryption */
j = 0;
for(i = 0; i < BCRYPT_BLOCKS; i++)
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
&j);
for(i = 0; i < 64; i++)
blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
/* copy out */
for(i = 0; i < BCRYPT_BLOCKS; i++) {
out[4 * i + 3] = (uint8_t)((cdata[i] >> 24) & 0xff);
out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
out[4 * i + 0] = cdata[i] & 0xff;
}
/* zap */
_libssh2_explicit_zero(ciphertext, sizeof(ciphertext));
_libssh2_explicit_zero(cdata, sizeof(cdata));
_libssh2_explicit_zero(&state, sizeof(state));
}
static int
bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds)
{
uint8_t sha2pass[SHA512_DIGEST_LENGTH];
uint8_t sha2salt[SHA512_DIGEST_LENGTH];
uint8_t out[BCRYPT_HASHSIZE];
uint8_t tmpout[BCRYPT_HASHSIZE];
uint8_t *countsalt;
size_t i, j, amt, stride;
uint32_t count;
size_t origkeylen = keylen;
libssh2_sha512_ctx ctx;
/* nothing crazy */
if(rounds < 1)
return -1;
if(passlen == 0 || saltlen == 0 || keylen == 0 ||
keylen > sizeof(out) * sizeof(out) || saltlen > 1 << 20)
return -1;
countsalt = calloc(1, saltlen + 4);
if(!countsalt)
return -1;
stride = (keylen + sizeof(out) - 1) / sizeof(out);
amt = (keylen + stride - 1) / stride;
memcpy(countsalt, salt, saltlen);
/* collapse password */
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++) {
countsalt[saltlen + 0] = (uint8_t)((count >> 24) & 0xff);
countsalt[saltlen + 1] = (count >> 16) & 0xff;
countsalt[saltlen + 2] = (count >> 8) & 0xff;
countsalt[saltlen + 3] = count & 0xff;
/* first round, salt is salt */
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 */
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++)
out[j] ^= tmpout[j];
}
/*
* pbkdf2 deviation: output the key material non-linearly.
*/
amt = LIBSSH2_MIN(amt, keylen);
for(i = 0; i < amt; i++) {
size_t dest = i * stride + (count - 1);
if(dest >= origkeylen) {
break;
}
key[dest] = out[i];
}
keylen -= i;
}
/* zap */
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return 0;
}
#endif /* HAVE_BCRYPT_PBKDF */
/* Wrapper */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds)
{
return bcrypt_pbkdf(pass,
passlen,
salt,
saltlen,
key,
keylen,
rounds);
}

751
vendor/libssh2/src/blowfish.c vendored Normal file
View File

@@ -0,0 +1,751 @@
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
/*
* Blowfish for OpenBSD - a fast block cipher designed by Bruce Schneier
*
* Copyright (C) Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* This code is derived from section 14.3 and the given source
* in section V of Applied Cryptography, second edition.
* Blowfish is an unpatented fast block cipher designed by
* Bruce Schneier.
*/
#if defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH)
#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
!defined(HAVE_BLF_ENC))
#ifdef _DEBUG_BLOWFISH
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#endif
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
static void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
#ifdef _DEBUG_BLOWFISH
static void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
#endif
static void Blowfish_initstate(blf_ctx *);
static void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
static void Blowfish_expandstate
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
#ifdef _DEBUG_BLOWFISH
static void blf_key(blf_ctx *, const uint8_t *, uint16_t);
#endif
static void blf_enc(blf_ctx *, uint32_t *, uint16_t);
#ifdef _DEBUG_BLOWFISH
static void blf_dec(blf_ctx *, uint32_t *, uint16_t);
#endif
#if 0
static void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
static void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
static void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
static void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
#endif
/* Converts uint8_t to uint32_t */
static uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *);
/* Function for Feistel Networks */
#define F(s, x) ((((s)[ (((x) >> 24) & 0xFF)] \
+ (s)[0x100 + (((x) >> 16) & 0xFF)]) \
^ (s)[0x200 + (((x) >> 8) & 0xFF)]) \
+ (s)[0x300 + ( (x) & 0xFF)])
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
static void
Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[0];
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
*xl = Xr ^ p[17];
*xr = Xl;
}
#ifdef _DEBUG_BLOWFISH
static void
Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[17];
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
*xl = Xr ^ p[0];
*xr = Xl;
}
#endif
static void
Blowfish_initstate(blf_ctx *c)
{
/* P-box and S-box tables initialized with digits of Pi */
static const blf_ctx initstate =
{ {
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
{
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
{
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
{
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
},
{
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
} };
*c = initstate;
}
static uint32_t
Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
uint16_t *current)
{
uint8_t i;
uint16_t j;
uint32_t temp;
temp = 0x00000000;
j = *current;
for(i = 0; i < 4; i++, j++) {
if(j >= databytes)
j = 0;
temp = (temp << 8) | data[j];
}
*current = j;
return temp;
}
static void
Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
{
int i;
int k;
uint16_t j;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for(i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for(i = 0; i < BLF_N + 2; i += 2) {
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for(i = 0; i < 4; i++) {
for(k = 0; k < 256; k += 2) {
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
static void
Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
const uint8_t *key, uint16_t keybytes)
{
int i;
int k;
uint16_t j;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for(i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for(i = 0; i < BLF_N + 2; i += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for(i = 0; i < 4; i++) {
for(k = 0; k < 256; k += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
#ifdef _DEBUG_BLOWFISH
static void
blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
{
/* Initialize S-boxes and subkeys with Pi */
Blowfish_initstate(c);
/* Transform S-boxes and subkeys with key */
Blowfish_expand0state(c, k, len);
}
#endif
static void
blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for(i = 0; i < blocks; i++) {
Blowfish_encipher(c, d, d + 1);
d += 2;
}
}
#ifdef _DEBUG_BLOWFISH
static void
blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for(i = 0; i < blocks; i++) {
Blowfish_decipher(c, d, d + 1);
d += 2;
}
}
#endif
#if 0
static void
blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for(i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
static void
blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for(i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
static void
blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i, j;
for(i = 0; i < len; i += 8) {
for(j = 0; j < 8; j++)
data[j] ^= iv[j];
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
iv = data;
data += 8;
}
}
static void
blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint8_t *iv;
uint32_t i, j;
iv = data + len - 16;
data = data + len - 8;
for(i = len - 8; i >= 8; i -= 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iv[j];
iv -= 8;
data -= 8;
}
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iva[j];
}
#endif
#ifdef _DEBUG_BLOWFISH
static void
report(uint32_t data[], uint16_t len)
{
int i;
for(i = 0; i < len; i += 2)
printf("Block %d: 0x%08lx 0x%08lx.\n",
i / 2, (unsigned long)data[i], (unsigned long)data[i + 1]);
}
int
main(void)
{
blf_ctx c;
char key[] = "AAAAA";
char key2[] = "abcdefghijklmnopqrstuvwxyz";
uint32_t data[10];
uint32_t data2[] =
{0x424c4f57l, 0x46495348l};
uint16_t i;
/* First test */
for(i = 0; i < 10; i++)
data[i] = i;
blf_key(&c, (uint8_t *) key, 5);
blf_enc(&c, data, 5);
blf_dec(&c, data, 1);
blf_dec(&c, data + 2, 4);
printf("Should read as 0 - 9.\n");
report(data, 10);
/* Second test */
blf_key(&c, (uint8_t *) key2, (uint16_t)strlen(key2));
blf_enc(&c, data2, 1);
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
report(data2, 2);
blf_dec(&c, data2, 1);
printf("\nShould read as: 0x424c4f57 0x46495348.\n");
report(data2, 2);
return 0;
}
#endif
#endif /* !defined(HAVE_BCRYPT_PBKDF) && \
(!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
'!defined(HAVE_BLF_ENC)) */
#endif /* defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH) */

224
vendor/libssh2/src/chacha.c vendored Normal file
View File

@@ -0,0 +1,224 @@
/*
* chacha-merged.c version 20080118
* D. J. Bernstein
* Public domain.
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#include "libssh2_priv.h"
#include "chacha.h"
/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
typedef unsigned char u8;
typedef unsigned int u32;
typedef struct chacha_ctx chacha_ctx;
#define U8C(v) (v##U)
#define U32C(v) (v##U)
#define U8V(v) ((u8)(v) & U8C(0xFF))
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
#define ROTL32(v, n) \
(U32V((v) << (n)) | ((v) >> (32 - (n))))
#define U8TO32_LITTLE(p) \
(((u32)((p)[0]) ) | \
((u32)((p)[1]) << 8) | \
((u32)((p)[2]) << 16) | \
((u32)((p)[3]) << 24))
#define U32TO8_LITTLE(p, v) \
do { \
(p)[0] = U8V((v) ); \
(p)[1] = U8V((v) >> 8); \
(p)[2] = U8V((v) >> 16); \
(p)[3] = U8V((v) >> 24); \
} while (0)
#define ROTATE(v,c) (ROTL32(v,c))
#define XOR(v,w) ((v) ^ (w))
#define PLUS(v,w) (U32V((v) + (w)))
#define PLUSONE(v) (PLUS((v),1))
#define QUARTERROUND(a,b,c,d) \
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
static const char sigma[17] = "expand 32-byte k";
static const char tau[17] = "expand 16-byte k";
void
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits)
{
const char *constants;
x->input[4] = U8TO32_LITTLE(k + 0);
x->input[5] = U8TO32_LITTLE(k + 4);
x->input[6] = U8TO32_LITTLE(k + 8);
x->input[7] = U8TO32_LITTLE(k + 12);
if(kbits == 256) { /* recommended */
k += 16;
constants = sigma;
}
else { /* kbits == 128 */
constants = tau;
}
x->input[8] = U8TO32_LITTLE(k + 0);
x->input[9] = U8TO32_LITTLE(k + 4);
x->input[10] = U8TO32_LITTLE(k + 8);
x->input[11] = U8TO32_LITTLE(k + 12);
x->input[0] = U8TO32_LITTLE(constants + 0);
x->input[1] = U8TO32_LITTLE(constants + 4);
x->input[2] = U8TO32_LITTLE(constants + 8);
x->input[3] = U8TO32_LITTLE(constants + 12);
}
void
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
{
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
x->input[14] = U8TO32_LITTLE(iv + 0);
x->input[15] = U8TO32_LITTLE(iv + 4);
}
void
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
{
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
u8 *ctarget = NULL;
u8 tmp[64];
u_int i;
if(!bytes)
return;
j0 = x->input[0];
j1 = x->input[1];
j2 = x->input[2];
j3 = x->input[3];
j4 = x->input[4];
j5 = x->input[5];
j6 = x->input[6];
j7 = x->input[7];
j8 = x->input[8];
j9 = x->input[9];
j10 = x->input[10];
j11 = x->input[11];
j12 = x->input[12];
j13 = x->input[13];
j14 = x->input[14];
j15 = x->input[15];
for(;;) {
if(bytes < 64) {
for(i = 0; i < bytes;++i) tmp[i] = m[i];
m = tmp;
ctarget = c;
c = tmp;
}
x0 = j0;
x1 = j1;
x2 = j2;
x3 = j3;
x4 = j4;
x5 = j5;
x6 = j6;
x7 = j7;
x8 = j8;
x9 = j9;
x10 = j10;
x11 = j11;
x12 = j12;
x13 = j13;
x14 = j14;
x15 = j15;
for(i = 20; i > 0; i -= 2) {
QUARTERROUND(x0, x4, x8, x12)
QUARTERROUND(x1, x5, x9, x13)
QUARTERROUND(x2, x6, x10, x14)
QUARTERROUND(x3, x7, x11, x15)
QUARTERROUND(x0, x5, x10, x15)
QUARTERROUND(x1, x6, x11, x12)
QUARTERROUND(x2, x7, x8, x13)
QUARTERROUND(x3, x4, x9, x14)
}
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
x3 = PLUS(x3, j3);
x4 = PLUS(x4, j4);
x5 = PLUS(x5, j5);
x6 = PLUS(x6, j6);
x7 = PLUS(x7, j7);
x8 = PLUS(x8, j8);
x9 = PLUS(x9, j9);
x10 = PLUS(x10, j10);
x11 = PLUS(x11, j11);
x12 = PLUS(x12, j12);
x13 = PLUS(x13, j13);
x14 = PLUS(x14, j14);
x15 = PLUS(x15, j15);
x0 = XOR(x0, U8TO32_LITTLE(m + 0));
x1 = XOR(x1, U8TO32_LITTLE(m + 4));
x2 = XOR(x2, U8TO32_LITTLE(m + 8));
x3 = XOR(x3, U8TO32_LITTLE(m + 12));
x4 = XOR(x4, U8TO32_LITTLE(m + 16));
x5 = XOR(x5, U8TO32_LITTLE(m + 20));
x6 = XOR(x6, U8TO32_LITTLE(m + 24));
x7 = XOR(x7, U8TO32_LITTLE(m + 28));
x8 = XOR(x8, U8TO32_LITTLE(m + 32));
x9 = XOR(x9, U8TO32_LITTLE(m + 36));
x10 = XOR(x10, U8TO32_LITTLE(m + 40));
x11 = XOR(x11, U8TO32_LITTLE(m + 44));
x12 = XOR(x12, U8TO32_LITTLE(m + 48));
x13 = XOR(x13, U8TO32_LITTLE(m + 52));
x14 = XOR(x14, U8TO32_LITTLE(m + 56));
x15 = XOR(x15, U8TO32_LITTLE(m + 60));
j12 = PLUSONE(j12);
if(!j12) {
j13 = PLUSONE(j13);
/* stopping at 2^70 bytes per nonce is user's responsibility */
}
U32TO8_LITTLE(c + 0, x0);
U32TO8_LITTLE(c + 4, x1);
U32TO8_LITTLE(c + 8, x2);
U32TO8_LITTLE(c + 12, x3);
U32TO8_LITTLE(c + 16, x4);
U32TO8_LITTLE(c + 20, x5);
U32TO8_LITTLE(c + 24, x6);
U32TO8_LITTLE(c + 28, x7);
U32TO8_LITTLE(c + 32, x8);
U32TO8_LITTLE(c + 36, x9);
U32TO8_LITTLE(c + 40, x10);
U32TO8_LITTLE(c + 44, x11);
U32TO8_LITTLE(c + 48, x12);
U32TO8_LITTLE(c + 52, x13);
U32TO8_LITTLE(c + 56, x14);
U32TO8_LITTLE(c + 60, x15);
if(bytes <= 64) {
if(bytes < 64) {
for(i = 0; i < bytes;++i) ctarget[i] = c[i];
}
x->input[12] = j12;
x->input[13] = j13;
return;
}
bytes -= 64;
c += 64;
m += 64;
}
}

33
vendor/libssh2/src/chacha.h vendored Normal file
View File

@@ -0,0 +1,33 @@
/* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */
/*
* chacha-merged.c version 20080118
* D. J. Bernstein
* Public domain.
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#ifndef CHACHA_H
#define CHACHA_H
#include <stdlib.h>
struct chacha_ctx {
u_int input[16];
};
#define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
u_char *c, u_int bytes);
#endif /* CHACHA_H */

3075
vendor/libssh2/src/channel.c vendored Normal file

File diff suppressed because it is too large Load Diff

142
vendor/libssh2/src/channel.h vendored Normal file
View File

@@ -0,0 +1,142 @@
#ifndef LIBSSH2_CHANNEL_H
#define LIBSSH2_CHANNEL_H
/* Copyright (C) Daniel Stenberg
*
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* _libssh2_channel_receive_window_adjust
*
* 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
* adjustment amount will be queued for a later packet.
*
* Always non-blocking.
*/
int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
uint32_t adjustment,
unsigned char force,
unsigned int *store);
/*
* _libssh2_channel_flush
*
* Flush data from one (or all) stream
* Returns number of bytes flushed, or negative on failure
*/
int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid);
/*
* _libssh2_channel_free
*
* Make sure a channel is closed, then remove the channel from the session
* and free its resource(s)
*
* Returns 0 on success, negative on failure
*/
int _libssh2_channel_free(LIBSSH2_CHANNEL *channel);
int
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
/*
* _libssh2_channel_write
*
* Send data to a channel
*/
ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const unsigned char *buf, size_t buflen);
/*
* _libssh2_channel_open
*
* Establish a generic session channel
*/
LIBSSH2_CHANNEL *
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
uint32_t channel_type_len,
uint32_t window_size,
uint32_t packet_size,
const unsigned char *message, size_t message_len);
/*
* _libssh2_channel_process_startup
*
* Primitive for libssh2_channel_(shell|exec|subsystem)
*/
int
_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request, size_t request_len,
const char *message, size_t message_len);
/*
* _libssh2_channel_read
*
* Read data from a channel
*
* It is important to not return 0 until the currently read channel is
* complete. If we read stuff from the wire but it was no payload data to fill
* in the buffer with, we MUST make sure to return PACKET_EAGAIN.
*/
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
uint32_t channel_id);
size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
/*
* _libssh2_channel_forward_cancel
*
* Stop listening on a remote port and free the listener
* Toss out any pending (un-accept()ed) connections
*
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
*/
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
#endif /* LIBSSH2_CHANNEL_H */

134
vendor/libssh2/src/cipher-chachapoly.c vendored Normal file
View File

@@ -0,0 +1,134 @@
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
* Adapted by Will Cosgrove <will@panic.com> for libssh2
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */
#include "libssh2_priv.h"
#include "misc.h"
#include "cipher-chachapoly.h"
int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n);
int
chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen)
{
if(keylen != (32 + 32)) /* 2 x 256 bit keys */
return LIBSSH2_ERROR_INVAL;
chacha_keysetup(&ctx->main_ctx, key, 256);
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
return 0;
}
/*
* chachapoly_crypt() operates as following:
* En/decrypt with header key 'aadlen' bytes from 'src', storing result
* to 'dest'. The ciphertext here is treated as additional authenticated
* data for MAC calculation.
* En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
* POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
* tag. This tag is written on encryption and verified on decryption.
*/
int
chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
const u_char *src, u_int len, u_int aadlen, int do_encrypt)
{
u_char seqbuf[8];
const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
int r = LIBSSH2_ERROR_INVAL;
unsigned char *ptr = NULL;
/*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
* packet sequence number.
*/
memset(poly_key, 0, sizeof(poly_key));
ptr = &seqbuf[0];
_libssh2_store_u64(&ptr, seqnr);
chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->main_ctx,
poly_key, poly_key, sizeof(poly_key));
/* If decrypting, check tag before anything else */
if(!do_encrypt) {
const u_char *tag = src + aadlen + len;
poly1305_auth(expected_tag, src, aadlen + len, poly_key);
if(chachapoly_timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN)
!= 0) {
r = LIBSSH2_ERROR_DECRYPT;
goto out;
}
}
/* Crypt additional data */
if(aadlen) {
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen);
}
/* Set Chacha's block counter to 1 */
chacha_ivsetup(&ctx->main_ctx, seqbuf, one);
chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen,
dest + aadlen, len);
/* If encrypting, calculate and append tag */
if(do_encrypt) {
poly1305_auth(dest + aadlen + len, dest, aadlen + len,
poly_key);
}
r = 0;
out:
memset(expected_tag, 0, sizeof(expected_tag));
memset(seqbuf, 0, sizeof(seqbuf));
memset(poly_key, 0, sizeof(poly_key));
return r;
}
/* Decrypt and extract the encrypted packet length */
int
chachapoly_get_length(struct chachapoly_ctx *ctx, unsigned int *plenp,
unsigned int seqnr, const unsigned char *cp,
unsigned int len)
{
u_char buf[4], seqbuf[8];
unsigned char *ptr = NULL;
if(len < 4)
return -1;
ptr = &seqbuf[0];
_libssh2_store_u64(&ptr, seqnr);
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);
*plenp = _libssh2_ntohu32(buf);
return 0;
}
int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for(; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}

41
vendor/libssh2/src/cipher-chachapoly.h vendored Normal file
View File

@@ -0,0 +1,41 @@
/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) Damien Miller 2013 <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef CHACHA_POLY_AEAD_H
#define CHACHA_POLY_AEAD_H
#include "chacha.h"
#include "poly1305.h"
#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */
struct chachapoly_ctx {
struct chacha_ctx main_ctx, header_ctx;
};
int chachapoly_init(struct chachapoly_ctx *cpctx,
const u_char *key, u_int keylen);
int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
u_char *dest, const u_char *src, u_int len, u_int aadlen,
int do_encrypt);
int chachapoly_get_length(struct chachapoly_ctx *cpctx,
u_int *plenp, u_int seqnr, const u_char *cp,
u_int len);
#endif /* CHACHA_POLY_AEAD_H */

381
vendor/libssh2/src/comp.c vendored Normal file
View File

@@ -0,0 +1,381 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg <daniel@haxx.se>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef LIBSSH2_HAVE_ZLIB
#include <zlib.h>
#undef compress /* dodge name clash with ZLIB macro */
#endif
#include "comp.h"
/* ********
* none *
******** */
/*
* comp_method_none_comp
*
* Minimalist compression: Absolutely none
*/
static int
comp_method_none_comp(LIBSSH2_SESSION *session,
unsigned char *dest,
size_t *dest_len,
const unsigned char *src,
size_t src_len,
void **abstract)
{
(void)session;
(void)abstract;
(void)dest;
(void)dest_len;
(void)src;
(void)src_len;
return 0;
}
/*
* comp_method_none_decomp
*
* Minimalist decompression: Absolutely none
*/
static int
comp_method_none_decomp(LIBSSH2_SESSION * session,
unsigned char **dest,
size_t *dest_len,
size_t payload_limit,
const unsigned char *src,
size_t src_len, void **abstract)
{
(void)session;
(void)payload_limit;
(void)abstract;
*dest = (unsigned char *) src;
*dest_len = src_len;
return 0;
}
static const LIBSSH2_COMP_METHOD comp_method_none = {
"none",
0, /* not really compressing */
0, /* isn't used in userauth, go figure */
NULL,
comp_method_none_comp,
comp_method_none_decomp,
NULL
};
#ifdef LIBSSH2_HAVE_ZLIB
/* ********
* zlib *
******** */
/* Memory management wrappers
* Yes, I realize we're doing a callback to a callback,
* Deal...
*/
static voidpf
comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
{
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
return (voidpf) LIBSSH2_ALLOC(session, items * size);
}
static void
comp_method_zlib_free(voidpf opaque, voidpf address)
{
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
LIBSSH2_FREE(session, address);
}
/* libssh2_comp_method_zlib_init
* All your bandwidth are belong to us (so save some)
*/
static int
comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
void **abstract)
{
z_stream *strm;
int status;
strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
if(!strm) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"zlib compression/decompression");
}
strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
strm->zfree = (free_func) comp_method_zlib_free;
if(compr) {
/* deflate */
status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
}
else {
/* inflate */
status = inflateInit(strm);
}
if(status != Z_OK) {
LIBSSH2_FREE(session, strm);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status));
return LIBSSH2_ERROR_COMPRESS;
}
*abstract = strm;
return LIBSSH2_ERROR_NONE;
}
/*
* libssh2_comp_method_zlib_comp
*
* Compresses source to destination. Without allocation.
*/
static int
comp_method_zlib_comp(LIBSSH2_SESSION *session,
unsigned char *dest,
/* dest_len is a pointer to allow this function to
update it with the final actual size used */
size_t *dest_len,
const unsigned char *src,
size_t src_len,
void **abstract)
{
z_stream *strm = *abstract;
uInt out_maxlen = (uInt)*dest_len;
int status;
strm->next_in = (unsigned char *) src;
strm->avail_in = (uInt)src_len;
strm->next_out = dest;
strm->avail_out = out_maxlen;
status = deflate(strm, Z_PARTIAL_FLUSH);
if((status == Z_OK) && (strm->avail_out > 0)) {
*dest_len = out_maxlen - strm->avail_out;
return 0;
}
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d, avail_out %u",
status, strm->avail_out));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
}
/*
* libssh2_comp_method_zlib_decomp
*
* Decompresses source to destination. Allocates the output memory.
*/
static int
comp_method_zlib_decomp(LIBSSH2_SESSION * session,
unsigned char **dest,
size_t *dest_len,
size_t payload_limit,
const unsigned char *src,
size_t src_len, void **abstract)
{
z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of
reallocs */
char *out;
size_t out_maxlen;
if(src_len <= SIZE_MAX / 4)
out_maxlen = (uInt)src_len * 4;
else
out_maxlen = payload_limit;
/* If strm is null, then we have not yet been initialized. */
if(!strm)
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
"decompression uninitialized");
/* In practice they never come smaller than this */
if(out_maxlen < 25)
out_maxlen = 25;
if(out_maxlen > payload_limit)
out_maxlen = payload_limit;
strm->next_in = (unsigned char *) src;
strm->avail_in = (uInt)src_len;
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session,
(uInt)out_maxlen);
out = (char *) strm->next_out;
strm->avail_out = (uInt)out_maxlen;
if(!strm->next_out)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate decompression buffer");
/* Loop until it's all inflated or hit error */
for(;;) {
int status;
size_t out_ofs;
char *newout;
status = inflate(strm, Z_PARTIAL_FLUSH);
if(status == Z_OK) {
if(strm->avail_out > 0)
/* status is OK and the output buffer has not been exhausted
so we're done */
break;
}
else if(status == Z_BUF_ERROR) {
/* the input data has been exhausted so we are done */
break;
}
else {
/* error state */
LIBSSH2_FREE(session, out);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"decompression failure");
}
if(out_maxlen > payload_limit || out_maxlen > SIZE_MAX / 2) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase");
}
/* If we get here we need to grow the output buffer and try again */
out_ofs = out_maxlen - strm->avail_out;
out_maxlen *= 2;
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if(!newout) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand decompression buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out = (uInt)(out_maxlen - out_ofs);
}
*dest = (unsigned char *) out;
*dest_len = out_maxlen - strm->avail_out;
return 0;
}
/* libssh2_comp_method_zlib_dtor
* All done, no more compression for you
*/
static int
comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
{
z_stream *strm = *abstract;
if(strm) {
if(compr)
deflateEnd(strm);
else
inflateEnd(strm);
LIBSSH2_FREE(session, strm);
}
*abstract = NULL;
return 0;
}
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
"zlib",
1, /* yes, this compresses */
1, /* do compression during userauth */
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_decomp,
comp_method_zlib_dtor,
};
static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = {
"zlib@openssh.com",
1, /* yes, this compresses */
0, /* don't use compression during userauth */
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_decomp,
comp_method_zlib_dtor,
};
#endif /* LIBSSH2_HAVE_ZLIB */
/* If compression is enabled by the API, then this array is used which then
may allow compression if zlib is available at build time */
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
#ifdef LIBSSH2_HAVE_ZLIB
&comp_method_zlib,
&comp_method_zlib_openssh,
#endif /* LIBSSH2_HAVE_ZLIB */
&comp_method_none,
NULL
};
/* If compression is disabled by the API, then this array is used */
static const LIBSSH2_COMP_METHOD *no_comp_methods[] = {
&comp_method_none,
NULL
};
const LIBSSH2_COMP_METHOD **
_libssh2_comp_methods(LIBSSH2_SESSION *session)
{
if(session->flag.compress)
return comp_methods;
else
return no_comp_methods;
}

45
vendor/libssh2/src/comp.h vendored Normal file
View File

@@ -0,0 +1,45 @@
#ifndef LIBSSH2_COMP_H
#define LIBSSH2_COMP_H
/* Copyright (C) Daniel Stenberg
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session);
#endif /* LIBSSH2_COMP_H */

549
vendor/libssh2/src/crypt.c vendored Normal file
View File

@@ -0,0 +1,549 @@
/* Copyright (C) Simon Josefsson <simon@josefsson.org>
* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "cipher-chachapoly.h"
#include <assert.h>
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE)
/* crypt_none_crypt
* Minimalist cipher: no encryption. DO NOT USE.
*
* The SSH2 Transport allows for unencrypted data transmission using
* the "none" cipher. Because this is such a huge security hole, it is
* typically disabled on SSH2 implementations and is disabled in libssh2
* by default as well.
*
* Enabling this option will allow for "none" as a negotiable method,
* however it still requires that the method be advertised by the remote
* end and that no more-preferable methods are available.
*
*/
static int
crypt_none_crypt(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
/* Do nothing to the data! */
return 0;
}
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
"none",
"DEK-Info: NONE",
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */
0, /* secret_len */
0, /* flags */
NULL,
crypt_none_crypt,
NULL
};
#endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE) */
struct crypt_ctx
{
int encrypt;
_libssh2_cipher_type(algo);
_libssh2_cipher_ctx h;
struct chachapoly_ctx chachapoly_ctx;
};
static int
crypt_init(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
if(!ctx)
return LIBSSH2_ERROR_ALLOC;
ctx->encrypt = encrypt;
ctx->algo = method->algo;
if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
LIBSSH2_FREE(session, ctx);
return -1;
}
*abstract = ctx;
*free_iv = 1;
*free_secret = 1;
return 0;
}
static int
crypt_encrypt(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
(void) session;
(void) seqno;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, buf,
buf_len, firstlast);
}
static int
crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if(cctx && *cctx) {
_libssh2_cipher_dtor(&(*cctx)->h);
LIBSSH2_FREE(session, *cctx);
*abstract = NULL;
}
return 0;
}
#if LIBSSH2_AES_GCM
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_gcm = {
"aes256-gcm@openssh.com",
"",
16, /* blocksize */
12, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
16, /* length of the authentication tag */
LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD,
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256gcm
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_gcm = {
"aes128-gcm@openssh.com",
"",
16, /* blocksize */
12, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
16, /* length of the authentication tag */
LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD,
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128gcm
};
#endif
#if LIBSSH2_AES_CTR
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
"aes128-ctr",
"",
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128ctr
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
"aes192-ctr",
"",
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192ctr
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
"aes256-ctr",
"",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256ctr
};
#endif
#if LIBSSH2_AES_CBC
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc",
"DEK-Info: AES-128-CBC",
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
"aes192-cbc",
"DEK-Info: AES-192-CBC",
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
"aes256-cbc",
"DEK-Info: AES-256-CBC",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
/* rijndael-cbc@lysator.liu.se == aes256-cbc */
static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
"rijndael-cbc@lysator.liu.se",
"DEK-Info: AES-256-CBC",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
#endif /* LIBSSH2_AES_CBC */
#if LIBSSH2_BLOWFISH
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
"blowfish-cbc",
"",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_blowfish
};
#endif /* LIBSSH2_BLOWFISH */
#if LIBSSH2_RC4
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
"arcfour",
"DEK-Info: RC4",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
};
static int
crypt_init_arcfour128(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
int rc;
rc = crypt_init(session, method, iv, free_iv, secret, free_secret,
encrypt, abstract);
if(rc == 0) {
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
unsigned char block[8];
size_t discard = 1536;
for(; discard; discard -= 8)
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
method->blocksize, MIDDLE_BLOCK);
/* Not all middle, but here it doesn't matter */
}
return rc;
}
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
"arcfour128",
"",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init_arcfour128,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
};
#endif /* LIBSSH2_RC4 */
#if LIBSSH2_CAST
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
"cast128-cbc",
"",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_cast5
};
#endif /* LIBSSH2_CAST */
#if LIBSSH2_3DES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
"3des-cbc",
"DEK-Info: DES-EDE3-CBC",
8, /* blocksize */
8, /* initial value length */
24, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_3des
};
#endif
static int
crypt_init_chacha20_poly(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
(void)iv;
if(!ctx)
return LIBSSH2_ERROR_ALLOC;
ctx->encrypt = encrypt;
ctx->algo = method->algo;
if(chachapoly_init(&ctx->chachapoly_ctx, secret, method->secret_len)) {
LIBSSH2_FREE(session, ctx);
return -1;
}
*abstract = ctx;
*free_iv = 1;
*free_secret = 1;
return 0;
}
static int
crypt_encrypt_chacha20_poly_buffer(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
int ret = 1;
struct crypt_ctx *ctx = *(struct crypt_ctx **) abstract;
(void)session;
(void)firstlast;
if(ctx) {
if(ctx->encrypt) {
/* requires out_buf to be large enough to hold encrypted output
plus auth tag (auth len)
buf is a full packet so we need to subtract packet length from
length
*/
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len) - 4, 4, ctx->encrypt);
}
else {
/* buf is full packet including size and auth tag but buf_len
doesn't include size */
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len), 4, ctx->encrypt);
/* the api expects the size field to already be removed
from the decrypted packet so we'll help it out */
if(ret == 0) {
memmove(buf, buf + 4, buf_len - 4);
}
}
}
return (ret == 0 ? 0 : 1);
}
static int
crypt_get_length_chacha20_poly(LIBSSH2_SESSION * session, unsigned int seqno,
unsigned char *data, size_t data_size,
unsigned int *len, void **abstract)
{
struct crypt_ctx *ctx = *(struct crypt_ctx **) abstract;
(void)session;
return chachapoly_get_length(&ctx->chachapoly_ctx, len, seqno, data,
(u_int)data_size);
}
static int
crypt_dtor_chacha20_poly(LIBSSH2_SESSION * session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if(cctx && *cctx) {
LIBSSH2_FREE(session, *cctx);
*abstract = NULL;
}
return 0;
}
static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_chacha20_poly1305_openssh = {
"chacha20-poly1305@openssh.com",
"",
8, /* blocksize */
0, /* initial value length */
64, /* secret length */
16, /* length of the auth_tag */
LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET, /* flags */
&crypt_init_chacha20_poly,
&crypt_get_length_chacha20_poly,
&crypt_encrypt_chacha20_poly_buffer,
&crypt_dtor_chacha20_poly,
_libssh2_cipher_chacha20 /* not actually used */
};
/* These are the crypt methods that are available to be negotiated. Methods
towards the start are chosen in preference to ones further down the list. */
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
&libssh2_crypt_method_chacha20_poly1305_openssh,
#if LIBSSH2_AES_GCM
&libssh2_crypt_method_aes256_gcm,
&libssh2_crypt_method_aes128_gcm,
#endif /* LIBSSH2_AES_GCM */
#if LIBSSH2_AES_CTR
&libssh2_crypt_method_aes256_ctr,
&libssh2_crypt_method_aes192_ctr,
&libssh2_crypt_method_aes128_ctr,
#endif /* LIBSSH2_AES_CTR */
#if LIBSSH2_AES_CBC
&libssh2_crypt_method_aes256_cbc,
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
&libssh2_crypt_method_aes192_cbc,
&libssh2_crypt_method_aes128_cbc,
#endif /* LIBSSH2_AES_CBC */
#if LIBSSH2_BLOWFISH
&libssh2_crypt_method_blowfish_cbc,
#endif /* LIBSSH2_BLOWFISH */
#if LIBSSH2_RC4
&libssh2_crypt_method_arcfour128,
&libssh2_crypt_method_arcfour,
#endif /* LIBSSH2_RC4 */
#if LIBSSH2_CAST
&libssh2_crypt_method_cast128_cbc,
#endif /* LIBSSH2_CAST */
#if LIBSSH2_3DES
&libssh2_crypt_method_3des_cbc,
#endif /* LIBSSH2_DES */
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE)
&libssh2_crypt_method_none,
#endif
NULL
};
/* Expose to kex.c */
const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)
{
return _libssh2_crypt_methods;
}

19
vendor/libssh2/src/crypto.c vendored Normal file
View File

@@ -0,0 +1,19 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_C
#include "libssh2_priv.h"
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include "openssl.c"
#elif defined(LIBSSH2_LIBGCRYPT)
#include "libgcrypt.c"
#elif defined(LIBSSH2_MBEDTLS)
#include "mbedtls.c"
#elif defined(LIBSSH2_OS400QC3)
#include "os400qc3.c"
#elif defined(LIBSSH2_WINCNG)
#include "wincng.c"
#endif

357
vendor/libssh2/src/crypto.h vendored Normal file
View File

@@ -0,0 +1,357 @@
#ifndef LIBSSH2_CRYPTO_H
#define LIBSSH2_CRYPTO_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include "openssl.h"
#elif defined(LIBSSH2_LIBGCRYPT)
#include "libgcrypt.h"
#elif defined(LIBSSH2_MBEDTLS)
#include "mbedtls.h"
#elif defined(LIBSSH2_OS400QC3)
#include "os400qc3.h"
#elif defined(LIBSSH2_WINCNG)
#include "wincng.h"
#else
#error "no cryptography backend selected"
#endif
/* 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
#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
#define LIBSSH2_ED25519_SIG_LEN 64
#if LIBSSH2_RSA
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata, unsigned long coefflen);
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
#if LIBSSH2_RSA_SHA1
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,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa,
size_t hash_len,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m, size_t m_len);
#endif
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif
#if LIBSSH2_DSA
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *gdata,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *x, unsigned long x_len);
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, size_t m_len);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
size_t hash_len, unsigned char *sig);
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif
#if LIBSSH2_ECDSA
int
_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx,
const unsigned char *k,
size_t k_len,
libssh2_curve_type type);
int
_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * 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
_libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
_libssh2_ec_key **out_private_key,
unsigned char **out_public_key_octal,
size_t *out_public_key_octal_len,
libssh2_curve_type curve_type);
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);
int
_libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx,
const unsigned char *hash, size_t hash_len,
unsigned char **signature, size_t *signature_len);
int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int _libssh2_ecdsa_new_private_frommemory_sk(libssh2_ecdsa_ctx ** ec_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
libssh2_curve_type
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx);
int
_libssh2_ecdsa_curve_type_from_name(const char *name,
libssh2_curve_type *out_type);
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
int
_libssh2_curve25519_new(LIBSSH2_SESSION *session, uint8_t **out_public_key,
uint8_t **out_private_key);
int
_libssh2_curve25519_gen_k(_libssh2_bn **k,
uint8_t private_key[LIBSSH2_ED25519_KEY_LEN],
uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]);
int
_libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
size_t s_len, const uint8_t *m, size_t m_len);
int
_libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filename, const uint8_t *passphrase);
int
_libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION *session,
const char *filename,
const uint8_t *passphrase);
int
_libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const unsigned char *raw_pub_key,
const size_t key_len);
int
_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
uint8_t **out_sig, size_t *out_sig_len,
const uint8_t *message, size_t message_len);
int
_libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int
_libssh2_ed25519_new_private_frommemory_sk(libssh2_ed25519_ctx **ed_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif /* LIBSSH2_ED25519 */
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret, int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blocksize,
int firstlast);
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekey,
const char *passphrase);
int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase);
int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
int *algorithm,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase);
/**
* @function _libssh2_supported_key_sign_algorithms
* @abstract Returns supported algorithms used for upgrading public
* key signing RFC 8332
* @discussion Based on the incoming key_method value, this function
* will return supported algorithms that can upgrade the key method
* @related _libssh2_key_sign_algorithm()
* @param key_method current key method, usually the default key sig method
* @param key_method_len length of the key method buffer
* @result comma separated list of supported upgrade options per RFC 8332, if
* there is no upgrade option return NULL
*/
const char *
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len);
#endif /* LIBSSH2_CRYPTO_H */

76
vendor/libssh2/src/crypto_config.h vendored Normal file
View File

@@ -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
#if !defined(LIBSSH2_DSA_ENABLE)
#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

80
vendor/libssh2/src/global.c vendored Normal file
View File

@@ -0,0 +1,80 @@
/* Copyright (C) Lars Nordin <Lars.Nordin@SDlabs.se>
* Copyright (C) Simon Josefsson <simon@josefsson.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
static int _libssh2_initialized = 0;
static int _libssh2_init_flags = 0;
LIBSSH2_API int
libssh2_init(int flags)
{
if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) {
libssh2_crypto_init();
}
_libssh2_initialized++;
_libssh2_init_flags |= flags;
return 0;
}
LIBSSH2_API void
libssh2_exit(void)
{
if(_libssh2_initialized == 0)
return;
_libssh2_initialized--;
if(_libssh2_initialized == 0 &&
!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
libssh2_crypto_exit();
}
return;
}
void
_libssh2_init_if_needed(void)
{
if(_libssh2_initialized == 0)
(void)libssh2_init(0);
}

1492
vendor/libssh2/src/hostkey.c vendored Normal file

File diff suppressed because it is too large Load Diff

101
vendor/libssh2/src/keepalive.c vendored Normal file
View File

@@ -0,0 +1,101 @@
/* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "transport.h" /* _libssh2_transport_write */
/* Keep-alive stuff. */
LIBSSH2_API void
libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply,
unsigned int interval)
{
if(interval == 1)
session->keepalive_interval = 2;
else
session->keepalive_interval = interval;
session->keepalive_want_reply = want_reply ? 1 : 0;
}
LIBSSH2_API int
libssh2_keepalive_send(LIBSSH2_SESSION *session,
int *seconds_to_next)
{
time_t now;
if(!session->keepalive_interval) {
if(seconds_to_next)
*seconds_to_next = 0;
return 0;
}
now = time(NULL);
if(session->keepalive_last_sent + session->keepalive_interval <= now) {
/* Format is
"SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
unsigned char keepalive_data[]
= "\x50\x00\x00\x00\x15keepalive@libssh2.orgW";
size_t len = sizeof(keepalive_data) - 1;
int rc;
keepalive_data[len - 1] =
(unsigned char)session->keepalive_want_reply;
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
already full, sending another keepalive is not useful. */
if(rc && rc != LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keepalive message");
return rc;
}
session->keepalive_last_sent = now;
if(seconds_to_next)
*seconds_to_next = session->keepalive_interval;
}
else if(seconds_to_next) {
*seconds_to_next = (int) (session->keepalive_last_sent - now)
+ session->keepalive_interval;
}
return 0;
}

4439
vendor/libssh2/src/kex.c vendored Normal file

File diff suppressed because it is too large Load Diff

1280
vendor/libssh2/src/knownhost.c vendored Normal file

File diff suppressed because it is too large Load Diff

863
vendor/libssh2/src/libgcrypt.c vendored Normal file
View File

@@ -0,0 +1,863 @@
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#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,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata, unsigned long coefflen)
{
int rc;
(void)e1data;
(void)e1len;
(void)e2data;
(void)e2len;
if(ddata) {
rc = gcry_sexp_build(rsa, NULL,
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata);
}
else {
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata);
}
if(rc) {
*rsa = NULL;
return -1;
}
return 0;
}
#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)
{
unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
if(libssh2_sha1(m, m_len, hash)) {
return -1;
}
rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash);
if(rc) {
return -1;
}
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
if(rc) {
gcry_sexp_release(s_hash);
return -1;
}
rc = gcry_pk_verify(s_sig, s_hash, rsa);
gcry_sexp_release(s_sig);
gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1;
}
#endif
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
const unsigned char *p,
unsigned long p_len,
const unsigned char *q,
unsigned long q_len,
const unsigned char *g,
unsigned long g_len,
const unsigned char *y,
unsigned long y_len,
const unsigned char *x, unsigned long x_len)
{
int rc;
if(x_len) {
rc = gcry_sexp_build(dsactx, NULL,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
}
else {
rc = gcry_sexp_build(dsactx, NULL,
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
p_len, p, q_len, q, g_len, g, y_len, y);
}
if(rc) {
*dsactx = NULL;
return -1;
}
return 0;
}
#endif
#if LIBSSH2_RSA
int
_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
unsigned const char *passphrase)
{
(void)rsa;
(void)filedata;
(void)filedata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filename, unsigned const char *passphrase)
{
FILE *fp;
unsigned char *data, *save_data;
size_t datalen;
int ret;
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
fp = fopen(filename, FOPEN_READTEXT);
if(!fp) {
return -1;
}
ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen);
fclose(fp);
if(ret) {
return -1;
}
save_data = data;
if(_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if(ret || (nlen != 1 && *n != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
if(ret) {
ret = -1;
goto fail;
}
if(_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
LIBSSH2_FREE(session, save_data);
return ret;
}
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
unsigned const char *passphrase)
{
(void)dsa;
(void)filedata;
(void)filedata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filename, unsigned const char *passphrase)
{
FILE *fp;
unsigned char *data, *save_data;
size_t datalen;
int ret;
unsigned char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen;
fp = fopen(filename, FOPEN_READTEXT);
if(!fp) {
return -1;
}
ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen);
fclose(fp);
if(ret) {
return -1;
}
save_data = data;
if(_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret || (plen != 1 && *p != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
if(ret) {
ret = -1;
goto fail;
}
if(datalen) {
ret = -1;
goto fail;
}
if(_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
LIBSSH2_FREE(session, save_data);
return ret;
}
#endif
#if LIBSSH2_RSA
#if LIBSSH2_RSA_SHA1
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)
{
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
int rc;
const char *tmp;
size_t size;
if(hash_len != SHA_DIGEST_LENGTH) {
return -1;
}
if(gcry_sexp_build(&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) {
return -1;
}
rc = gcry_pk_sign(&sig_sexp, data, rsactx);
gcry_sexp_release(data);
if(rc) {
return -1;
}
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if(!data) {
return -1;
}
tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp) {
gcry_sexp_release(data);
return -1;
}
if(tmp[0] == '\0') {
tmp++;
size--;
}
*signature = LIBSSH2_ALLOC(session, size);
if(!*signature) {
gcry_sexp_release(data);
return -1;
}
memcpy(*signature, tmp, size);
*signature_len = size;
gcry_sexp_release(data);
return rc;
}
#endif
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
size_t hash_len, unsigned char *sig)
{
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
int ret;
const char *tmp;
size_t size;
if(hash_len != SHA_DIGEST_LENGTH) {
return -1;
}
memcpy(zhash + 1, hash, hash_len);
zhash[0] = 0;
if(gcry_sexp_build(&data, NULL, "(data (value %b))",
(int)(hash_len + 1), zhash)) {
return -1;
}
ret = gcry_pk_sign(&sig_sexp, data, dsactx);
gcry_sexp_release(data);
if(ret) {
return -1;
}
memset(sig, 0, 40);
/* Extract R. */
data = gcry_sexp_find_token(sig_sexp, "r", 0);
if(!data)
goto err;
tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp)
goto err;
if(tmp[0] == '\0') {
tmp++;
size--;
}
if(size < 1 || size > 20)
goto err;
memcpy(sig + (20 - size), tmp, size);
gcry_sexp_release(data);
/* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if(!data)
goto err;
tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp)
goto err;
if(tmp[0] == '\0') {
tmp++;
size--;
}
if(size < 1 || size > 20)
goto err;
memcpy(sig + 20 + (20 - size), tmp, size);
goto out;
err:
ret = -1;
out:
if(sig_sexp) {
gcry_sexp_release(sig_sexp);
}
if(data) {
gcry_sexp_release(data);
}
return ret;
}
int
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, size_t m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t s_sig, s_hash;
int rc = -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))",
SHA_DIGEST_LENGTH + 1, hash)) {
return -1;
}
if(gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) {
gcry_sexp_release(s_hash);
return -1;
}
rc = gcry_pk_verify(s_sig, s_hash, dsactx);
gcry_sexp_release(s_sig);
gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1;
}
#endif
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *secret, int encrypt)
{
int ret;
int cipher = _libssh2_gcry_cipher(algo);
int mode = _libssh2_gcry_mode(algo);
size_t keylen = gcry_cipher_get_algo_keylen(cipher);
(void)encrypt;
ret = gcry_cipher_open(h, cipher, mode, 0);
if(ret) {
return -1;
}
ret = gcry_cipher_setkey(*h, secret, keylen);
if(ret) {
gcry_cipher_close(*h);
return -1;
}
if(mode != GCRY_CIPHER_MODE_STREAM) {
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
if(mode == GCRY_CIPHER_MODE_CTR)
ret = gcry_cipher_setctr(*h, iv, blklen);
else
ret = gcry_cipher_setiv(*h, iv, blklen);
if(ret) {
gcry_cipher_close(*h);
return -1;
}
}
return 0;
}
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blklen,
int firstlast)
{
int ret;
(void)algo;
(void)firstlast;
if(encrypt) {
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
}
else {
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
}
return ret;
}
int
_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)privatekeydata;
(void)privatekeydata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract public key from private "
"key in memory: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekey,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)privatekey;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to extract public key from private key file: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
int *algorithm,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)algorithm;
(void)flags;
(void)application;
(void)key_handle;
(void)handle_len;
(void)privatekeydata;
(void)privatekeydata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to extract public SK key from private key file: "
"Method unimplemented in libgcrypt backend");
}
void _libssh2_init_aes_ctr(void)
{
/* no implementation */
}
void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
{
*dhctx = gcry_mpi_new(0); /* Random from client */
}
int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order)
{
/* Generate x and e */
gcry_mpi_randomize(*dhctx, group_order * 8 - 1, GCRY_WEAK_RANDOM);
gcry_mpi_powm(public, g, *dhctx, p);
return 0;
}
int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p)
{
/* Compute the shared secret */
gcry_mpi_powm(secret, f, *dhctx, p);
return 0;
}
void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
{
gcry_mpi_release(*dhctx);
*dhctx = NULL;
}
/* _libssh2_supported_key_sign_algorithms
*
* Return supported key hash algo upgrades, see crypto.h
*
*/
const char *
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len)
{
(void)session;
(void)key_method;
(void)key_method_len;
return NULL;
}
#endif /* LIBSSH2_CRYPTO_C */

235
vendor/libssh2/src/libgcrypt.h vendored Normal file
View File

@@ -0,0 +1,235 @@
#ifndef LIBSSH2_LIBGCRYPT_H
#define LIBSSH2_LIBGCRYPT_H
/*
* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_gcrypt
#include <gcrypt.h>
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 1
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 1
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 0
#define LIBSSH2_DSA 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
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \
(gcry_randomize((buf), (len), GCRY_STRONG_RANDOM), 0)
#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), 1)
#define libssh2_sha1_final(ctx, out) \
(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), 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), 1)
#define libssh2_sha256_final(ctx, out) \
(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), 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), 1)
#define libssh2_sha384_final(ctx, out) \
(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), 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), 1)
#define libssh2_sha512_final(ctx, out) \
(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), 0)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx gcry_md_hd_t
#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), 1)
#define libssh2_md5_final(ctx, out) \
(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_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM)
#define libssh2_crypto_exit()
#define libssh2_rsa_ctx struct gcry_sexp
#define _libssh2_rsa_free(rsactx) gcry_sexp_release(rsactx)
#define libssh2_dsa_ctx struct gcry_sexp
#define _libssh2_dsa_free(dsactx) gcry_sexp_release(dsactx)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
#define _libssh2_cipher_type(name) int name
#define _libssh2_cipher_ctx gcry_cipher_hd_t
#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m)
#define _libssh2_gcry_cipher(c) (c >> 8)
#define _libssh2_gcry_mode(m) (m & 0xFF)
#define _libssh2_cipher_aes256ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes192ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes128ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes256 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes192 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes128 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_blowfish \
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_arcfour \
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_cast5 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_3des \
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_chacha20 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
#define _libssh2_bn struct gcry_mpi
#define _libssh2_bn_ctx int
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
#define _libssh2_bn_init() gcry_mpi_new(0)
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a
new bignum */
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) \
gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
#define _libssh2_bn_to_bin(bn, val) \
gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
#define _libssh2_bn_bytes(bn) \
(gcry_mpi_get_nbits(bn) / 8 + \
((gcry_mpi_get_nbits(bn) % 8 == 0) ? 0 : 1))
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits(bn)
#define _libssh2_bn_free(bn) gcry_mpi_release(bn)
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 8192
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
#define _libssh2_dh_ctx struct gcry_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_init_aes_ctr(void);
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
int group_order);
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 */

48
vendor/libssh2/src/libssh2.rc vendored Normal file
View File

@@ -0,0 +1,48 @@
/***************************************************************************
* libssh2 Windows resource file
* Copyright (C) The libssh2 project and its contributors.
*
* SPDX-License-Identifier: BSD-3-Clause
***************************************************************************/
#include <winver.h>
#include "libssh2.h"
LANGUAGE 0, 0
#define RC_VERSION LIBSSH2_VERSION_MAJOR, LIBSSH2_VERSION_MINOR, LIBSSH2_VERSION_PATCH, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#if defined(LIBSSH2DEBUG) || defined(_DEBUG)
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
BEGIN
VALUE "CompanyName", "The libssh2 library, https://libssh2.org/\0"
VALUE "FileDescription", "libssh2 Shared Library\0"
VALUE "FileVersion", LIBSSH2_VERSION "\0"
VALUE "InternalName", "libssh2\0"
VALUE "OriginalFilename", "libssh2.dll\0"
VALUE "ProductName", "The libssh2 library\0"
VALUE "ProductVersion", LIBSSH2_VERSION "\0"
VALUE "LegalCopyright", "Copyright (C) " LIBSSH2_COPYRIGHT "\0"
VALUE "License", "https://libssh2.org/license.html\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 0x04b0 /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
END
END

View File

@@ -0,0 +1,76 @@
/* Copyright (C) Alexander Lamaison <alexander.lamaison@gmail.com>
* Copyright (C) Douglas Gilbert
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Headers */
#cmakedefine HAVE_UNISTD_H
#cmakedefine HAVE_INTTYPES_H
#cmakedefine HAVE_SYS_SELECT_H
#cmakedefine HAVE_SYS_UIO_H
#cmakedefine HAVE_SYS_SOCKET_H
#cmakedefine HAVE_SYS_IOCTL_H
#cmakedefine HAVE_SYS_TIME_H
#cmakedefine HAVE_SYS_UN_H
/* for example and tests */
#cmakedefine HAVE_ARPA_INET_H
#cmakedefine HAVE_NETINET_IN_H
/* Functions */
#cmakedefine HAVE_GETTIMEOFDAY
#cmakedefine HAVE_STRTOLL
#cmakedefine HAVE_STRTOI64
#cmakedefine HAVE_SNPRINTF
#cmakedefine HAVE_EXPLICIT_BZERO
#cmakedefine HAVE_EXPLICIT_MEMSET
#cmakedefine HAVE_MEMSET_S
#cmakedefine HAVE_POLL
#cmakedefine HAVE_SELECT
/* Socket non-blocking support */
#cmakedefine HAVE_O_NONBLOCK
#cmakedefine HAVE_FIONBIO
#cmakedefine HAVE_IOCTLSOCKET_CASE
#cmakedefine HAVE_SO_NONBLOCK
/* attribute to export symbol */
#if defined(LIBSSH2_EXPORTS) && defined(LIBSSH2_LIBRARY)
#cmakedefine LIBSSH2_API ${LIBSSH2_API}
#endif

1283
vendor/libssh2/src/libssh2_priv.h vendored Normal file

File diff suppressed because it is too large Load Diff

103
vendor/libssh2/src/libssh2_setup.h vendored Normal file
View File

@@ -0,0 +1,103 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_SETUP_H
#define LIBSSH2_SETUP_H
/* Header for platform/compiler-specific initialization.
Used by 'src', 'example', 'tests' */
/* Define mingw-w64 version macros, eg __MINGW{32,64}_{MINOR,MAJOR}_VERSION */
#ifdef __MINGW32__
#include <_mingw.h>
#endif
/* Configuration provided by build tools (autotools and CMake),
and via platform-specific directories for os400 and vms */
#if defined(HAVE_CONFIG_H) || defined(__OS400__) || defined(__VMS)
#include "libssh2_config.h"
/* Hand-crafted configuration for platforms which lack config tool.
Keep this synced with root CMakeLists.txt */
#elif defined(_WIN32)
#define HAVE_SELECT
#define HAVE_SNPRINTF
#ifdef __MINGW32__
# define HAVE_UNISTD_H
# define HAVE_INTTYPES_H
# define HAVE_SYS_TIME_H
# define HAVE_GETTIMEOFDAY
# define HAVE_STRTOLL
#elif defined(_MSC_VER)
# if _MSC_VER >= 1800
# define HAVE_INTTYPES_H
# define HAVE_STRTOLL
# else
# define HAVE_STRTOI64
# endif
# if _MSC_VER < 1900
# undef HAVE_SNPRINTF
# endif
#endif
#endif /* defined(HAVE_CONFIG_H) */
/* Below applies to both auto-detected and hand-crafted configs */
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOGDI
#define NOGDI
#endif
#ifndef NONLS
#define NONLS
#endif
#ifdef __MINGW32__
# ifdef __MINGW64_VERSION_MAJOR
/* Number of bits in a file offset, on hosts where this is settable. */
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
# endif
# endif
#elif defined(_MSC_VER)
# ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS /* for fopen(), getenv() */
# endif
# if !defined(LIBSSH2_LIBRARY) || defined(LIBSSH2_TESTS)
/* apply to examples and tests only */
# ifndef _CRT_NONSTDC_NO_DEPRECATE
# define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write() */
# endif
# ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* for inet_addr() */
# endif
/* we cannot access our internal snprintf() implementation in examples and
tests when linking to a shared libssh2. */
# if _MSC_VER < 1900
# undef HAVE_SNPRINTF
# define HAVE_SNPRINTF
# define snprintf _snprintf
# endif
# endif
# if _MSC_VER < 1500
# define vsnprintf _vsnprintf
# endif
# if _MSC_VER < 1900
# define strdup _strdup
/* Silence bogus warning C4127: conditional expression is constant */
# pragma warning(disable:4127)
# endif
#endif
#endif /* _WIN32 */
#endif /* LIBSSH2_SETUP_H */

553
vendor/libssh2/src/mac.c vendored Normal file
View File

@@ -0,0 +1,553 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "mac.h"
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE)
/* mac_none_MAC
*
* Minimalist MAC: No MAC. DO NOT USE.
*
* The SSH2 Transport allows implementations to forego a message
* authentication code. While this is less of a security risk than using
* a "none" cipher, it is still not recommended as disabling MAC hashes
* removes a layer of security.
*
* Enabling this option will allow for "none" as a negotiable method,
* however it still requires that the method be advertised by the remote
* end and that no more-preferable methods are available.
*
*/
static int
mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno, const unsigned char *packet,
size_t packet_len, const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
return 0;
}
static LIBSSH2_MAC_METHOD mac_method_none = {
"none",
0,
0,
NULL,
mac_none_MAC,
NULL,
0
};
#endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE) */
/* mac_method_common_init
* Initialize simple mac methods
*/
static int
mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{
*abstract = key;
*free_key = 0;
(void)session;
return 0;
}
/* mac_method_common_dtor
* Cleanup simple mac methods
*/
static int
mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
{
if(*abstract) {
LIBSSH2_FREE(session, *abstract);
}
*abstract = NULL;
return 0;
}
#if LIBSSH2_HMAC_SHA512
/* mac_method_hmac_sha512_hash
* Calculate hash using full sha512 value
*/
static int
mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
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,
64,
mac_method_common_init,
mac_method_hmac_sha2_512_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512_etm = {
"hmac-sha2-512-etm@openssh.com",
64,
64,
mac_method_common_init,
mac_method_hmac_sha2_512_hash,
mac_method_common_dtor,
1
};
#endif
#if LIBSSH2_HMAC_SHA256
/* mac_method_hmac_sha256_hash
* Calculate hash using full sha256 value
*/
static int
mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
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;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = {
"hmac-sha2-256",
32,
32,
mac_method_common_init,
mac_method_hmac_sha2_256_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256_etm = {
"hmac-sha2-256-etm@openssh.com",
32,
32,
mac_method_common_init,
mac_method_hmac_sha2_256_hash,
mac_method_common_dtor,
1
};
#endif
/* mac_method_hmac_sha1_hash
* Calculate hash using full sha1 value
*/
static int
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
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;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
"hmac-sha1",
20,
20,
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_etm = {
"hmac-sha1-etm@openssh.com",
20,
20,
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
1
};
/* mac_method_hmac_sha1_96_hash
* Calculate hash using first 96 bits of sha1 value
*/
static int
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
unsigned char temp[SHA_DIGEST_LENGTH];
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;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
"hmac-sha1-96",
12,
20,
mac_method_common_init,
mac_method_hmac_sha1_96_hash,
mac_method_common_dtor,
0
};
#if LIBSSH2_MD5
/* mac_method_hmac_md5_hash
* Calculate hash using full md5 value
*/
static int
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
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;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
"hmac-md5",
16,
16,
mac_method_common_init,
mac_method_hmac_md5_hash,
mac_method_common_dtor,
0
};
/* mac_method_hmac_md5_96_hash
* Calculate hash using first 96 bits of md5 value
*/
static int
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
unsigned char temp[MD5_DIGEST_LENGTH];
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;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
"hmac-md5-96",
12,
16,
mac_method_common_init,
mac_method_hmac_md5_96_hash,
mac_method_common_dtor,
0
};
#endif /* LIBSSH2_MD5 */
#if LIBSSH2_HMAC_RIPEMD
/* mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value
*/
static int
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len,
void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
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;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
"hmac-ripemd160",
20,
20,
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
"hmac-ripemd160@openssh.com",
20,
20,
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
0
};
#endif /* LIBSSH2_HMAC_RIPEMD */
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
#if LIBSSH2_HMAC_SHA256
&mac_method_hmac_sha2_256,
&mac_method_hmac_sha2_256_etm,
#endif
#if LIBSSH2_HMAC_SHA512
&mac_method_hmac_sha2_512,
&mac_method_hmac_sha2_512_etm,
#endif
&mac_method_hmac_sha1,
&mac_method_hmac_sha1_etm,
&mac_method_hmac_sha1_96,
#if LIBSSH2_MD5
&mac_method_hmac_md5,
&mac_method_hmac_md5_96,
#endif
#if LIBSSH2_HMAC_RIPEMD
&mac_method_hmac_ripemd160,
&mac_method_hmac_ripemd160_openssh_com,
#endif /* LIBSSH2_HMAC_RIPEMD */
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE)
&mac_method_none,
#endif
NULL
};
const LIBSSH2_MAC_METHOD **
_libssh2_mac_methods(void)
{
return mac_methods;
}
#if LIBSSH2_AES_GCM
static int
mac_method_none_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{
(void)session;
(void)key;
(void)free_key;
(void)abstract;
return 0;
}
static int
mac_method_hmac_none_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
(void)session;
(void)buf;
(void)seqno;
(void)packet;
(void)packet_len;
(void)addtl;
(void)addtl_len;
(void)abstract;
return 0;
}
static int
mac_method_none_dtor(LIBSSH2_SESSION * session, void **abstract)
{
(void)session;
(void)abstract;
return 0;
}
/* Stub for aes256-gcm@openssh.com crypto type, which has an integrated
HMAC method. This must not be added to mac_methods[] since it cannot be
negotiated separately. */
static const LIBSSH2_MAC_METHOD mac_method_hmac_aesgcm = {
"INTEGRATED-AES-GCM", /* made up name for display only */
16,
16,
mac_method_none_init,
mac_method_hmac_none_hash,
mac_method_none_dtor,
0
};
#endif /* LIBSSH2_AES_GCM */
/* See if the negotiated crypto method has its own authentication scheme that
* obviates the need for a separate negotiated hmac method */
const LIBSSH2_MAC_METHOD *
_libssh2_mac_override(const LIBSSH2_CRYPT_METHOD *crypt)
{
#if LIBSSH2_AES_GCM
if(!strcmp(crypt->name, "aes256-gcm@openssh.com") ||
!strcmp(crypt->name, "aes128-gcm@openssh.com"))
return &mac_method_hmac_aesgcm;
#else
(void) crypt;
#endif /* LIBSSH2_AES_GCM */
return NULL;
}

72
vendor/libssh2/src/mac.h vendored Normal file
View File

@@ -0,0 +1,72 @@
#ifndef LIBSSH2_MAC_H
#define LIBSSH2_MAC_H
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
struct _LIBSSH2_MAC_METHOD
{
const char *name;
/* The length of a given MAC packet */
int mac_len;
/* integrity key length */
int key_len;
/* Message Authentication Code Hashing algo */
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
void **abstract);
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno, const unsigned char *packet,
size_t packet_len, const unsigned char *addtl,
size_t addtl_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
int etm; /* encrypt-then-mac */
};
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
const LIBSSH2_MAC_METHOD *_libssh2_mac_override(
const LIBSSH2_CRYPT_METHOD *crypt);
#endif /* LIBSSH2_MAC_H */

1533
vendor/libssh2/src/mbedtls.c vendored Normal file

File diff suppressed because it is too large Load Diff

514
vendor/libssh2/src/mbedtls.h vendored Normal file
View File

@@ -0,0 +1,514 @@
#ifndef LIBSSH2_MBEDTLS_H
#define LIBSSH2_MBEDTLS_H
/* Copyright (C) Art <https://github.com/wildart>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_mbedtls
#ifdef __GNUC__
#pragma GCC diagnostic push
/* mbedTLS (as of v3.5.1) has a `[-Werror=arith-conversion]`
warning in its public headers. */
#if !defined(__clang__) && __GNUC__ >= 10
#pragma GCC diagnostic ignored "-Warith-conversion"
#endif
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
/* mbedTLS (as of v3.5.1) has a duplicate function declaration
in its public headers. Disable the warning that detects it. */
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#include <mbedtls/version.h>
#include <mbedtls/platform.h>
#include <mbedtls/md.h>
#include <mbedtls/rsa.h>
#include <mbedtls/bignum.h>
#include <mbedtls/cipher.h>
#ifdef MBEDTLS_ECDH_C
# include <mbedtls/ecdh.h>
#endif
#ifdef MBEDTLS_ECDSA_C
# include <mbedtls/ecdsa.h>
#endif
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/pk.h>
#include <mbedtls/error.h>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
/* Define which features are supported. */
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 1
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
# define LIBSSH2_BLOWFISH 1
#else
# define LIBSSH2_BLOWFISH 0
#endif
#ifdef MBEDTLS_CIPHER_ARC4_128
# define LIBSSH2_RC4 1
#else
# define LIBSSH2_RC4 0
#endif
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 0
#ifdef MBEDTLS_ECDSA_C
# define LIBSSH2_ECDSA 1
#else
# define LIBSSH2_ECDSA 0
#endif
#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
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
/*******************************************************************/
/*
* mbedTLS backend: Generic functions
*/
#define libssh2_crypto_init() \
_libssh2_mbedtls_init()
#define libssh2_crypto_exit() \
_libssh2_mbedtls_free()
#define _libssh2_random(buf, len) \
_libssh2_mbedtls_random(buf, len)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
/*******************************************************************/
/*
* mbedTLS backend: HMAC functions
*/
#define libssh2_hmac_ctx mbedtls_md_context_t
/*******************************************************************/
/*
* mbedTLS backend: SHA1 functions
*/
#define libssh2_sha1_ctx mbedtls_md_context_t
#define libssh2_sha1_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0)
#define libssh2_sha1_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha1_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha1(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA256 functions
*/
#define libssh2_sha256_ctx mbedtls_md_context_t
#define libssh2_sha256_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0)
#define libssh2_sha256_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha256_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha256(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA384 functions
*/
#define libssh2_sha384_ctx mbedtls_md_context_t
#define libssh2_sha384_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0)
#define libssh2_sha384_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha384_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA512 functions
*/
#define libssh2_sha512_ctx mbedtls_md_context_t
#define libssh2_sha512_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0)
#define libssh2_sha512_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha512_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha512(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash)
/*******************************************************************/
/*
* mbedTLS backend: MD5 functions
*/
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx mbedtls_md_context_t
#define libssh2_md5_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0)
#define libssh2_md5_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_md5_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#endif
/*******************************************************************/
/*
* mbedTLS backend: RSA functions
*/
#define libssh2_rsa_ctx mbedtls_rsa_context
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len) \
_libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
_libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase)
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_mbedtls_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_mbedtls_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_mbedtls_rsa_free(rsactx)
/*******************************************************************/
/*
* mbedTLS backend: ECDSA structures
*/
#if LIBSSH2_ECDSA
typedef enum {
#ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_SECP256R1,
#else
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_NONE,
#endif
#ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_SECP384R1,
#else
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_NONE,
#endif
#ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_SECP521R1
#else
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_NONE,
#endif
} libssh2_curve_type;
# define _libssh2_ec_key mbedtls_ecp_keypair
#else
# define _libssh2_ec_key void
#endif /* LIBSSH2_ECDSA */
/*******************************************************************/
/*
* mbedTLS backend: ECDSA functions
*/
#if LIBSSH2_ECDSA
#define libssh2_ecdsa_ctx mbedtls_ecdsa_context
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve) \
_libssh2_mbedtls_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve)
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
_libssh2_mbedtls_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len)
#define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \
_libssh2_mbedtls_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
_libssh2_mbedtls_ecdsa_new_private(ctx, session, filename, passphrase)
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase) \
_libssh2_mbedtls_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase)
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
_libssh2_mbedtls_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
#define _libssh2_ecdsa_get_curve_type(ctx) \
_libssh2_mbedtls_ecdsa_get_curve_type(ctx)
#define _libssh2_ecdsa_free(ctx) \
_libssh2_mbedtls_ecdsa_free(ctx)
#endif /* LIBSSH2_ECDSA */
/*******************************************************************/
/*
* mbedTLS backend: Key functions
*/
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
_libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw) \
_libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw) \
_libssh2_mbedtls_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw)
/*******************************************************************/
/*
* mbedTLS backend: Cipher Context structure
*/
#define _libssh2_cipher_ctx mbedtls_cipher_context_t
#define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo
#define _libssh2_cipher_aes256ctr MBEDTLS_CIPHER_AES_256_CTR
#define _libssh2_cipher_aes192ctr MBEDTLS_CIPHER_AES_192_CTR
#define _libssh2_cipher_aes128ctr MBEDTLS_CIPHER_AES_128_CTR
#define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC
#define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC
#define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
#define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC
#endif
#ifdef MBEDTLS_CIPHER_ARC4_128
#define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128
#endif
#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC
#define _libssh2_cipher_chacha20 MBEDTLS_CIPHER_CHACHA20_POLY1305
/*******************************************************************/
/*
* mbedTLS backend: Cipher functions
*/
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
_libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \
_libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen, fl)
#define _libssh2_cipher_dtor(ctx) \
_libssh2_mbedtls_cipher_dtor(ctx)
/*******************************************************************/
/*
* mbedTLS backend: BigNumber Support
*/
#define _libssh2_bn_ctx int /* not used */
#define _libssh2_bn_ctx_new() 0 /* not used */
#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */
#define _libssh2_bn mbedtls_mpi
#define _libssh2_bn_init() \
_libssh2_mbedtls_bignum_init()
#define _libssh2_bn_init_from_bin() \
_libssh2_mbedtls_bignum_init()
#define _libssh2_bn_set_word(bn, word) \
mbedtls_mpi_lset(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \
mbedtls_mpi_read_binary(bn, bin, len)
#define _libssh2_bn_to_bin(bn, bin) \
mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn))
#define _libssh2_bn_bytes(bn) \
mbedtls_mpi_size(bn)
#define _libssh2_bn_bits(bn) \
mbedtls_mpi_bitlen(bn)
#define _libssh2_bn_free(bn) \
_libssh2_mbedtls_bignum_free(bn)
/*******************************************************************/
/*
* mbedTLS backend: Diffie-Hellman support.
*/
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 8192
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
#define _libssh2_dh_ctx mbedtls_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/
/*
* mbedTLS backend: forward declarations
*/
void
_libssh2_mbedtls_init(void);
void
_libssh2_mbedtls_free(void);
int
_libssh2_mbedtls_random(unsigned char *buf, size_t len);
void
_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx);
int
_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
mbedtls_md_type_t mdtype,
const unsigned char *key, size_t keylen);
int
_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash);
int
_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen,
mbedtls_md_type_t mdtype, unsigned char *hash);
_libssh2_bn *
_libssh2_mbedtls_bignum_init(void);
void
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn);
void
_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa);
#if LIBSSH2_ECDSA
libssh2_curve_type
_libssh2_mbedtls_ecdsa_key_get_curve_type(libssh2_ecdsa_ctx *ctx);
int
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
libssh2_curve_type *type);
void
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx);
#endif /* LIBSSH2_ECDSA */
extern void
_libssh2_init_aes_ctr(void);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
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_MBEDTLS_H */

989
vendor/libssh2/src/misc.c vendored Normal file
View File

@@ -0,0 +1,989 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include <assert.h>
#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))
#endif
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
We provide a safe wrapper if snprintf not found */
#ifdef LIBSSH2_SNPRINTF
#include <stdarg.h>
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
* then assume cp is pointing to a null char and do nothing. Returns number
* number of chars placed in cp excluding the trailing null char. So for
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
* <= 0 the return value is 0 (and no chars are written to cp). */
int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
{
va_list args;
int n;
if(cp_max_len < 2)
return 0;
va_start(args, fmt);
n = vsnprintf(cp, cp_max_len, fmt, args);
va_end(args);
return (n < (int)cp_max_len) ? n : (int)(cp_max_len - 1);
}
#endif
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags)
{
if(!session) {
if(errmsg)
fprintf(stderr, "Session is NULL, error: %s\n", errmsg);
return errcode;
}
if(session->err_flags & LIBSSH2_ERR_FLAG_DUP)
LIBSSH2_FREE(session, (char *)session->err_msg);
session->err_code = errcode;
session->err_flags = 0;
if(errmsg && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
size_t len = strlen(errmsg);
char *copy = LIBSSH2_ALLOC(session, len + 1);
if(copy) {
memcpy(copy, errmsg, len + 1);
session->err_flags = LIBSSH2_ERR_FLAG_DUP;
session->err_msg = copy;
}
else
/* Out of memory: this code path is very unlikely */
session->err_msg = "former error forgotten (OOM)";
}
else
session->err_msg = errmsg;
#ifdef LIBSSH2DEBUG
if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode)
/* if this is EAGAIN and we're in non-blocking mode, don't generate
a debug output for this */
return errcode;
_libssh2_debug((session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code,
session->err_msg));
#endif
return errcode;
}
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg)
{
return _libssh2_error_flags(session, errcode, errmsg, 0);
}
#ifdef _WIN32
int _libssh2_wsa2errno(void)
{
switch(WSAGetLastError()) {
case WSAEWOULDBLOCK:
return EAGAIN;
case WSAENOTSOCK:
return EBADF;
case WSAEINTR:
return EINTR;
default:
/* It is most important to ensure errno does not stay at EAGAIN
* when a different error occurs so just set errno to a generic
* error */
return EIO;
}
}
#endif
/* _libssh2_recv
*
* Replacement for the standard recv, return -errno on failure.
*/
ssize_t
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
int flags, void **abstract)
{
ssize_t rc;
(void)abstract;
rc = recv(sock, buffer, length, flags);
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(err == ENOENT)
return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
else if(err == EWOULDBLOCK)
return -EAGAIN;
#endif
else
return -err;
}
return rc;
}
/* _libssh2_send
*
* Replacement for the standard send, return -errno on failure.
*/
ssize_t
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
int flags, void **abstract)
{
ssize_t rc;
(void)abstract;
rc = send(sock, buffer, length, flags);
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(err == EWOULDBLOCK)
return -EAGAIN;
#endif
return -err;
}
return rc;
}
/* libssh2_ntohu32
*/
uint32_t
_libssh2_ntohu32(const unsigned char *buf)
{
return ((uint32_t)buf[0] << 24)
| ((uint32_t)buf[1] << 16)
| ((uint32_t)buf[2] << 8)
| ((uint32_t)buf[3]);
}
/* _libssh2_ntohu64
*/
libssh2_uint64_t
_libssh2_ntohu64(const unsigned char *buf)
{
return ((libssh2_uint64_t)buf[0] << 56)
| ((libssh2_uint64_t)buf[1] << 48)
| ((libssh2_uint64_t)buf[2] << 40)
| ((libssh2_uint64_t)buf[3] << 32)
| ((libssh2_uint64_t)buf[4] << 24)
| ((libssh2_uint64_t)buf[5] << 16)
| ((libssh2_uint64_t)buf[6] << 8)
| ((libssh2_uint64_t)buf[7]);
}
/* _libssh2_htonu32
*/
void
_libssh2_htonu32(unsigned char *buf, uint32_t value)
{
buf[0] = (unsigned char)((value >> 24) & 0xFF);
buf[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF;
}
/* _libssh2_store_u32
*/
void _libssh2_store_u32(unsigned char **buf, uint32_t value)
{
_libssh2_htonu32(*buf, value);
*buf += sizeof(uint32_t);
}
/* _libssh2_store_u64
*/
void _libssh2_store_u64(unsigned char **buf, libssh2_uint64_t value)
{
unsigned char *ptr = *buf;
ptr[0] = (unsigned char)((value >> 56) & 0xFF);
ptr[1] = (unsigned char)((value >> 48) & 0xFF);
ptr[2] = (unsigned char)((value >> 40) & 0xFF);
ptr[3] = (unsigned char)((value >> 32) & 0xFF);
ptr[4] = (unsigned char)((value >> 24) & 0xFF);
ptr[5] = (unsigned char)((value >> 16) & 0xFF);
ptr[6] = (unsigned char)((value >> 8) & 0xFF);
ptr[7] = (unsigned char)(value & 0xFF);
*buf += sizeof(libssh2_uint64_t);
}
/* _libssh2_store_str
*/
int _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
{
uint32_t len_stored = (uint32_t)len;
_libssh2_store_u32(buf, len_stored);
if(len_stored) {
memcpy(*buf, str, len_stored);
*buf += len_stored;
}
assert(len_stored == len);
return len_stored == len;
}
/* _libssh2_store_bignum2_bytes
*/
int _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len)
{
uint32_t len_stored;
uint32_t extraByte;
const unsigned char *p;
for(p = bytes; len > 0 && *p == 0; --len, ++p) {}
extraByte = (len > 0 && (p[0] & 0x80) != 0);
len_stored = (uint32_t)len;
if(extraByte && len_stored == UINT32_MAX)
len_stored--;
_libssh2_store_u32(buf, len_stored + extraByte);
if(extraByte) {
*buf[0] = 0;
*buf += 1;
}
if(len_stored) {
memcpy(*buf, p, len_stored);
*buf += len_stored;
}
assert(len_stored == len);
return len_stored == len;
}
/* Base64 Conversion */
static const short base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
/* libssh2_base64_decode
*
* Legacy public function. DEPRECATED.
*/
LIBSSH2_API int
libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{
int rc;
size_t dlen;
rc = _libssh2_base64_decode(session, data, &dlen, src, src_len);
if(datalen)
*datalen = (unsigned int)dlen;
return rc;
}
/* _libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
*/
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len)
{
unsigned char *d;
const char *s;
short v;
ssize_t i = 0, len = 0;
*data = LIBSSH2_ALLOC(session, ((src_len / 4) * 3) + 1);
d = (unsigned char *) *data;
if(!d) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding");
}
for(s = src; s < (src + src_len); s++) {
v = base64_reverse_table[(unsigned char)*s];
if(v < 0)
continue;
switch(i % 4) {
case 0:
d[len] = (unsigned char)(v << 2);
break;
case 1:
d[len++] |= (unsigned char)(v >> 4);
d[len] = (unsigned char)(v << 4);
break;
case 2:
d[len++] |= (unsigned char)(v >> 2);
d[len] = (unsigned char)(v << 6);
break;
case 3:
d[len++] |= (unsigned char)v;
break;
}
i++;
}
if((i % 4) == 1) {
/* Invalid -- We have a byte which belongs exclusively to a partial
octet */
LIBSSH2_FREE(session, *data);
*data = NULL;
return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64");
}
*datalen = len;
return 0;
}
/* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* _libssh2_base64_encode
*
* Returns the length of the newly created base64 string. The third argument
* is a pointer to an allocated area holding the base64 data. If something
* went wrong, 0 is returned.
*
*/
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr)
{
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
int inputparts;
char *output;
char *base64data;
const char *indata = inp;
*outptr = NULL; /* set to NULL in case of failure before we reach the
end */
if(insize == 0)
insize = strlen(indata);
base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4);
if(!output)
return 0;
while(insize > 0) {
for(i = inputparts = 0; i < 3; i++) {
if(insize > 0) {
inputparts++;
ibuf[i] = *indata;
indata++;
insize--;
}
else
ibuf[i] = 0;
}
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
((ibuf[1] & 0xF0) >> 4));
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
((ibuf[2] & 0xC0) >> 6));
obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
switch(inputparts) {
case 1: /* only one byte read */
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = '=';
output[3] = '=';
break;
case 2: /* two bytes read */
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = table64[obuf[2]];
output[3] = '=';
break;
default:
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = table64[obuf[2]];
output[3] = table64[obuf[3]];
break;
}
output += 4;
}
*output = 0;
*outptr = base64data; /* make it return the actual data memory */
return strlen(base64data); /* return the length of the new data */
}
/* ---- End of Base64 Encoding ---- */
LIBSSH2_API void
libssh2_free(LIBSSH2_SESSION *session, void *ptr)
{
LIBSSH2_FREE(session, ptr);
}
#ifdef LIBSSH2DEBUG
#include <stdarg.h>
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{
session->showmask = bitmask;
return 0;
}
LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback)
{
session->tracehandler = callback;
session->tracehandler_context = handler_context;
return 0;
}
void
_libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
...)
{
char buffer[1536];
int len, msglen, buflen = sizeof(buffer);
va_list vargs;
struct timeval now;
static long firstsec;
static const char *const contexts[] = {
"Unknown",
"Transport",
"Key Ex",
"Userauth",
"Conn",
"SCP",
"SFTP",
"Failure Event",
"Publickey",
"Socket",
};
const char *contexttext = contexts[0];
unsigned int contextindex;
if(!(session->showmask & context)) {
/* no such output asked for */
return;
}
/* Find the first matching context string for this message */
for(contextindex = 0; contextindex < ARRAY_SIZE(contexts);
contextindex++) {
if((context & (1 << contextindex)) != 0) {
contexttext = contexts[contextindex];
break;
}
}
gettimeofday(&now, NULL);
if(!firstsec) {
firstsec = now.tv_sec;
}
now.tv_sec -= firstsec;
len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ",
(int)now.tv_sec, (int)now.tv_usec, contexttext);
if(len >= buflen)
msglen = buflen - 1;
else {
buflen -= len;
msglen = len;
va_start(vargs, format);
len = vsnprintf(buffer + msglen, buflen, format, vargs);
va_end(vargs);
msglen += len < buflen ? len : buflen - 1;
}
if(session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer,
msglen);
else
fprintf(stderr, "%s\n", buffer);
}
#else
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{
(void)session;
(void)bitmask;
return 0;
}
LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback)
{
(void)session;
(void)handler_context;
(void)callback;
return 0;
}
#endif
/* init the list head */
void _libssh2_list_init(struct list_head *head)
{
head->first = head->last = NULL;
}
/* add a node to the list */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry)
{
/* store a pointer to the head */
entry->head = head;
/* we add this entry at the "top" so it has no next */
entry->next = NULL;
/* make our prev point to what the head thinks is last */
entry->prev = head->last;
/* and make head's last be us now */
head->last = entry;
/* make sure our 'prev' node points to us next */
if(entry->prev)
entry->prev->next = entry;
else
head->first = entry;
}
/* return the "first" node in the list this head points to */
void *_libssh2_list_first(struct list_head *head)
{
return head->first;
}
/* return the next node in the list */
void *_libssh2_list_next(struct list_node *node)
{
return node->next;
}
/* return the prev node in the list */
void *_libssh2_list_prev(struct list_node *node)
{
return node->prev;
}
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry)
{
if(entry->prev)
entry->prev->next = entry->next;
else
entry->head->first = entry->next;
if(entry->next)
entry->next->prev = entry->prev;
else
entry->head->last = entry->prev;
}
#if 0
/* insert a node before the given 'after' entry */
void _libssh2_list_insert(struct list_node *after, /* insert before this */
struct list_node *entry)
{
/* 'after' is next to 'entry' */
bentry->next = after;
/* entry's prev is then made to be the prev after current has */
entry->prev = after->prev;
/* the node that is now before 'entry' was previously before 'after'
and must be made to point to 'entry' correctly */
if(entry->prev)
entry->prev->next = entry;
else
/* there was no node before this, so we make sure we point the head
pointer to this node */
after->head->first = entry;
/* after's prev entry points back to entry */
after->prev = entry;
/* after's next entry is still the same as before */
/* entry's head is the same as after's */
entry->head = after->head;
}
#endif
/* Defined in libssh2_priv.h for the correct platforms */
#ifdef LIBSSH2_GETTIMEOFDAY
/*
* _libssh2_gettimeofday
* Implementation according to:
* The Open Group Base Specifications Issue 6
* IEEE Std 1003.1, 2004 Edition
*/
/*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Contributed by:
* Danny Smith <dannysmith@users.sourceforge.net>
*/
int _libssh2_gettimeofday(struct timeval *tp, void *tzp)
{
(void)tzp;
if(tp) {
#ifdef _WIN32
/* Offset between 1601-01-01 and 1970-01-01 in 100 nanosec units */
#define _WIN32_FT_OFFSET (116444736000000000)
union {
libssh2_uint64_t ns100; /* time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
GetSystemTimeAsFileTime(&_now.ft);
tp->tv_usec = (long)((_now.ns100 / 10) % 1000000);
tp->tv_sec = (long)((_now.ns100 - _WIN32_FT_OFFSET) / 10000000);
#else
/* Platforms without a native implementation or local replacement */
tp->tv_usec = 0;
tp->tv_sec = 0;
#endif
}
/* Always return 0 as per Open Group Base Specifications Issue 6.
Do not set errno on error. */
return 0;
}
#endif
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
{
void *p = LIBSSH2_ALLOC(session, size);
if(p) {
memset(p, 0, size);
}
return p;
}
/* XOR operation on buffers input1 and input2, result in output.
It is safe to use an input buffer as the output buffer. */
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
const unsigned char *input2,
size_t length)
{
size_t i;
for(i = 0; i < length; i++)
*output++ = *input1++ ^ *input2++;
}
/* Increments an AES CTR buffer to prepare it for use with the
next AES block. */
void _libssh2_aes_ctr_increment(unsigned char *ctr,
size_t length)
{
unsigned char *pc;
unsigned int val, carry;
pc = ctr + length - 1;
carry = 1;
while(pc >= ctr) {
val = (unsigned int)*pc + carry;
*pc-- = val & 0xFF;
carry = val >> 8;
}
}
#ifdef LIBSSH2_MEMZERO
static void * (* const volatile memset_libssh)(void *, int, size_t) = memset;
void _libssh2_memzero(void *buf, size_t size)
{
memset_libssh(buf, 0, size);
}
#endif
/* String buffer */
struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session)
{
struct string_buf *ret;
ret = _libssh2_calloc(session, sizeof(*ret));
if(!ret)
return NULL;
return ret;
}
void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf)
{
if(!buf)
return;
if(buf->data)
LIBSSH2_FREE(session, buf->data);
LIBSSH2_FREE(session, buf);
buf = NULL;
}
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out)
{
if(!_libssh2_check_length(buf, 1)) {
return -1;
}
*out = buf->dataptr[0];
buf->dataptr += 1;
return 0;
}
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out)
{
if(!_libssh2_check_length(buf, 1)) {
return -1;
}
*out = buf->dataptr[0] == 0 ? 0 : 1;
buf->dataptr += 1;
return 0;
}
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out)
{
if(!_libssh2_check_length(buf, 4)) {
return -1;
}
*out = _libssh2_ntohu32(buf->dataptr);
buf->dataptr += 4;
return 0;
}
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out)
{
if(!_libssh2_check_length(buf, 8)) {
return -1;
}
*out = _libssh2_ntohu64(buf->dataptr);
buf->dataptr += 8;
return 0;
}
int _libssh2_match_string(struct string_buf *buf, const char *match)
{
unsigned char *out;
size_t len = 0;
if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) ||
strncmp((char *)out, match, strlen(match)) != 0) {
return -1;
}
return 0;
}
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
if(!buf || _libssh2_get_u32(buf, &data_len) != 0) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
return -1;
}
*outbuf = buf->dataptr;
buf->dataptr += data_len;
if(outlen)
*outlen = (size_t)data_len;
return 0;
}
int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
unsigned char **outbuf, size_t *outlen)
{
size_t str_len;
unsigned char *str;
if(_libssh2_get_string(buf, &str, &str_len)) {
return -1;
}
if(str_len) {
*outbuf = LIBSSH2_ALLOC(session, str_len);
if(*outbuf) {
memcpy(*outbuf, str, str_len);
}
else {
return -1;
}
}
else {
*outbuf = NULL;
}
if(outlen)
*outlen = str_len;
return 0;
}
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
uint32_t bn_len;
unsigned char *bnptr;
if(_libssh2_get_u32(buf, &data_len)) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
return -1;
}
bn_len = data_len;
bnptr = buf->dataptr;
/* trim leading zeros */
while(bn_len > 0 && *bnptr == 0x00) {
bn_len--;
bnptr++;
}
*outbuf = bnptr;
buf->dataptr += data_len;
if(outlen)
*outlen = (size_t)bn_len;
return 0;
}
/* Given the current location in buf, _libssh2_check_length ensures
callers can read the next len number of bytes out of the buffer
before reading the buffer content */
int _libssh2_check_length(struct string_buf *buf, size_t len)
{
unsigned char *endp = &buf->data[buf->len];
size_t left = endp - buf->dataptr;
return (len <= left) && (left <= buf->len);
}
int _libssh2_eob(struct string_buf *buf)
{
unsigned char *endp = &buf->data[buf->len];
return buf->dataptr >= endp;
}

146
vendor/libssh2/src/misc.h vendored Normal file
View File

@@ -0,0 +1,146 @@
#ifndef LIBSSH2_MISC_H
#define LIBSSH2_MISC_H
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifdef LIBSSH2_NO_CLEAR_MEMORY
#define _libssh2_explicit_zero(buf, size) do { \
(void)(buf); \
(void)(size); \
} while(0)
#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)
#elif defined(HAVE_EXPLICIT_MEMSET)
#define _libssh2_explicit_zero(buf, size) (void)explicit_memset(buf, 0, size)
#elif defined(HAVE_MEMSET_S)
#define _libssh2_explicit_zero(buf, size) (void)memset_s(buf, size, 0, size)
#else
#define LIBSSH2_MEMZERO
void _libssh2_memzero(void *buf, size_t size);
#define _libssh2_explicit_zero(buf, size) _libssh2_memzero(buf, size)
#endif
struct list_head {
struct list_node *last;
struct list_node *first;
};
struct list_node {
struct list_node *next;
struct list_node *prev;
struct list_head *head;
};
struct string_buf {
unsigned char *data;
unsigned char *dataptr;
size_t len;
};
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 */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry);
/* return the "first" node in the list this head points to */
void *_libssh2_list_first(struct list_head *head);
/* return the next node in the list */
void *_libssh2_list_next(struct list_node *node);
/* return the prev node in the list */
void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry);
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len);
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);
uint32_t _libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
void _libssh2_store_u64(unsigned char **buf, libssh2_uint64_t value);
int _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
int _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len);
void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size);
struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session);
void _libssh2_string_buf_free(LIBSSH2_SESSION *session,
struct string_buf *buf);
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out);
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out);
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out);
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out);
int _libssh2_match_string(struct string_buf *buf, const char *match);
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf,
unsigned char **outbuf, size_t *outlen);
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_check_length(struct string_buf *buf, size_t requested_len);
int _libssh2_eob(struct string_buf *buf);
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
const unsigned char *input2,
size_t length);
void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length);
#endif /* LIBSSH2_MISC_H */

5225
vendor/libssh2/src/openssl.c vendored Normal file

File diff suppressed because it is too large Load Diff

463
vendor/libssh2/src/openssl.h vendored Normal file
View File

@@ -0,0 +1,463 @@
#ifndef LIBSSH2_OPENSSL_H
#define LIBSSH2_OPENSSL_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_openssl
/* disable deprecated warnings in OpenSSL 3 */
#define OPENSSL_SUPPRESS_DEPRECATED
#ifdef LIBSSH2_WOLFSSL
#include <wolfssl/options.h>
#include <wolfssl/openssl/ecdh.h>
#if defined(NO_DSA) || defined(HAVE_FIPS)
#define OPENSSL_NO_DSA
#endif
#if defined(NO_MD5) || defined(HAVE_FIPS)
#define OPENSSL_NO_MD5
#endif
#if !defined(WOLFSSL_RIPEMD) || defined(HAVE_FIPS)
#define OPENSSL_NO_RIPEMD
#endif
#if defined(NO_RC4) || defined(HAVE_FIPS)
#define OPENSSL_NO_RC4
#endif
#ifdef NO_DES3
#define OPENSSL_NO_DES
#endif
/* wolfSSL doesn't support Blowfish or CAST. */
#define OPENSSL_NO_BF
#define OPENSSL_NO_CAST
/* wolfSSL has no engine framework. */
#define OPENSSL_NO_ENGINE
#include <wolfssl/openssl/opensslconf.h>
#include <wolfssl/openssl/sha.h>
#include <wolfssl/openssl/rsa.h>
#ifndef OPENSSL_NO_DSA
#include <wolfssl/openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <wolfssl/openssl/md5.h>
#endif
#include <wolfssl/openssl/err.h>
#include <wolfssl/openssl/evp.h>
#include <wolfssl/openssl/hmac.h>
#include <wolfssl/openssl/bn.h>
#include <wolfssl/openssl/pem.h>
#include <wolfssl/openssl/rand.h>
#else /* !LIBSSH2_WOLFSSL */
#include <openssl/opensslconf.h>
#include <openssl/sha.h>
#include <openssl/rsa.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#define USE_OPENSSL_3 1
#include <openssl/core_names.h>
#endif
#endif /* LIBSSH2_WOLFSSL */
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) || \
(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
#endif
#ifdef OPENSSL_NO_RSA
# define LIBSSH2_RSA 0
# define LIBSSH2_RSA_SHA1 0
# define LIBSSH2_RSA_SHA2 0
#else
# define LIBSSH2_RSA 1
# define LIBSSH2_RSA_SHA1 1
# define LIBSSH2_RSA_SHA2 1
#endif
#ifdef OPENSSL_NO_DSA
# define LIBSSH2_DSA 0
#else
# define LIBSSH2_DSA 1
#endif
#if defined(OPENSSL_NO_ECDSA) || defined(OPENSSL_NO_EC)
# define LIBSSH2_ECDSA 0
#else
# define LIBSSH2_ECDSA 1
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
# define LIBSSH2_ED25519 1
#else
# define LIBSSH2_ED25519 0
#endif
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160)
# define LIBSSH2_HMAC_RIPEMD 0
#else
# define LIBSSH2_HMAC_RIPEMD 1
#endif
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)) || \
(defined(LIBSSH2_WOLFSSL) && defined(WOLFSSL_AES_COUNTER))
# define LIBSSH2_AES_CTR 1
# define LIBSSH2_AES_CBC 1
#else
# define LIBSSH2_AES_CTR 0
# define LIBSSH2_AES_CBC 0
#endif
/* wolfSSL v5.4.0 is required due to possibly this bug:
https://github.com/wolfSSL/wolfssl/pull/5205
Before this release, all libssh2 tests crash with AES-GCM enabled */
#if (OPENSSL_VERSION_NUMBER >= 0x01010100fL && !defined(OPENSSL_NO_AES)) || \
(defined(LIBSSH2_WOLFSSL) && LIBWOLFSSL_VERSION_HEX >= 0x05004000 && \
defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM))
# define LIBSSH2_AES_GCM 1
#else
# define LIBSSH2_AES_GCM 0
#endif
#ifdef OPENSSL_NO_BF
# define LIBSSH2_BLOWFISH 0
#else
# define LIBSSH2_BLOWFISH 1
#endif
#ifdef OPENSSL_NO_RC4
# define LIBSSH2_RC4 0
#else
# define LIBSSH2_RC4 1
#endif
#ifdef OPENSSL_NO_CAST
# define LIBSSH2_CAST 0
#else
# define LIBSSH2_CAST 1
#endif
#ifdef OPENSSL_NO_DES
# define LIBSSH2_3DES 0
#else
# define LIBSSH2_3DES 1
#endif
#include "crypto_config.h"
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \
_libssh2_openssl_random((buf), (len))
#define libssh2_prepare_iovec(vec, len) /* Empty. */
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha1_ctx EVP_MD_CTX *
#else
#define libssh2_sha1_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha1_init(libssh2_sha1_ctx *ctx);
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
#define libssh2_sha256_ctx EVP_MD_CTX *
#else
#define libssh2_sha256_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha256_init(libssh2_sha256_ctx *ctx);
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
#define libssh2_sha384_ctx EVP_MD_CTX *
#else
#define libssh2_sha384_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha384_init(libssh2_sha384_ctx *ctx);
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
#define libssh2_sha512_ctx EVP_MD_CTX *
#else
#define libssh2_sha512_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha512_init(libssh2_sha512_ctx *ctx);
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
#define libssh2_md5_ctx EVP_MD_CTX
#endif
/* 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)
#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 *
#else /* !HAVE_OPAQUE_STRUCTS */
#define libssh2_hmac_ctx HMAC_CTX
#endif /* USE_OPENSSL_3 */
extern void _libssh2_openssl_crypto_init(void);
extern void _libssh2_openssl_crypto_exit(void);
#define libssh2_crypto_init() _libssh2_openssl_crypto_init()
#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit()
#if LIBSSH2_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
#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,
LIBSSH2_EC_CURVE_NISTP384 = NID_secp384r1,
LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1
}
libssh2_curve_type;
#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 /* LIBSSH2_ED25519 */
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
#ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_ctx EVP_CIPHER_CTX *
#else
#define _libssh2_cipher_ctx EVP_CIPHER_CTX
#endif
#define _libssh2_cipher_aes256gcm EVP_aes_256_gcm
#define _libssh2_cipher_aes128gcm EVP_aes_128_gcm
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr
#define _libssh2_cipher_blowfish EVP_bf_cbc
#define _libssh2_cipher_arcfour EVP_rc4
#define _libssh2_cipher_cast5 EVP_cast5_cbc
#define _libssh2_cipher_3des EVP_des_ede3_cbc
#define _libssh2_cipher_chacha20 NULL
#ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx))
#else
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
#endif
#define _libssh2_bn BIGNUM
#define _libssh2_bn_ctx BN_CTX
#define _libssh2_bn_ctx_new() BN_CTX_new()
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
#define _libssh2_bn_init() BN_new()
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_set_word(bn, val) !BN_set_word(bn, val)
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, size_t len,
const unsigned char *v);
#define _libssh2_bn_to_bin(bn, val) (BN_bn2bin(bn, val) <= 0)
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
#define _libssh2_bn_free(bn) BN_clear_free(bn)
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 8192
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
#define _libssh2_dh_ctx BIGNUM *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p, bnctx)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
int group_order,
_libssh2_bn_ctx *bnctx);
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p,
_libssh2_bn_ctx *bnctx);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
extern int _libssh2_openssl_random(void *buf, size_t len);
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 */

2535
vendor/libssh2/src/os400qc3.c vendored Normal file

File diff suppressed because it is too large Load Diff

397
vendor/libssh2/src/os400qc3.h vendored Normal file
View File

@@ -0,0 +1,397 @@
#ifndef LIBSSH2_OS400QC3_H
#define LIBSSH2_OS400QC3_H
/*
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_os400qc3
#include <stdlib.h>
#include <string.h>
#include <qc3cci.h>
/* Redefine character/string literals as always EBCDIC. */
#undef Qc3_Alg_Token
#define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */
#undef Qc3_Alg_Block_Cipher
#define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */
#undef Qc3_Alg_Block_CipherAuth
#define Qc3_Alg_Block_CipherAuth \
"\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */
#undef Qc3_Alg_Stream_Cipher
#define Qc3_Alg_Stream_Cipher \
"\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */
#undef Qc3_Alg_Public_Key
#define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */
#undef Qc3_Alg_Hash
#define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */
#undef Qc3_Data
#define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */
#undef Qc3_Array
#define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */
#undef Qc3_Key_Token
#define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */
#undef Qc3_Key_Parms
#define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */
#undef Qc3_Key_KSLabel
#define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */
#undef Qc3_Key_PKCS5
#define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */
#undef Qc3_Key_PEMCert
#define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */
#undef Qc3_Key_CSLabel
#define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */
#undef Qc3_Key_CSDN
#define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */
#undef Qc3_Key_AppID
#define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */
#undef Qc3_ECB
#define Qc3_ECB '\xF0' /* '0' */
#undef Qc3_CBC
#define Qc3_CBC '\xF1' /* '1' */
#undef Qc3_OFB
#define Qc3_OFB '\xF2' /* '2' */
#undef Qc3_CFB1Bit
#define Qc3_CFB1Bit '\xF3' /* '3' */
#undef Qc3_CFB8Bit
#define Qc3_CFB8Bit '\xF4' /* '4' */
#undef Qc3_CFB64Bit
#define Qc3_CFB64Bit '\xF5' /* '5' */
#undef Qc3_CUSP
#define Qc3_CUSP '\xF6' /* '6' */
#undef Qc3_CTR
#define Qc3_CTR '\xF7' /* '7' */
#undef Qc3_CCM
#define Qc3_CCM '\xF8' /* '8' */
#undef Qc3_No_Pad
#define Qc3_No_Pad '\xF0' /* '0' */
#undef Qc3_Pad_Char
#define Qc3_Pad_Char '\xF1' /* '1' */
#undef Qc3_Pad_Counter
#define Qc3_Pad_Counter '\xF2' /* '2' */
#undef Qc3_PKCS1_00
#define Qc3_PKCS1_00 '\xF0' /* '0' */
#undef Qc3_PKCS1_01
#define Qc3_PKCS1_01 '\xF1' /* '1' */
#undef Qc3_PKCS1_02
#define Qc3_PKCS1_02 '\xF2' /* '2' */
#undef Qc3_ISO9796
#define Qc3_ISO9796 '\xF3' /* '3' */
#undef Qc3_Zero_Pad
#define Qc3_Zero_Pad '\xF4' /* '4' */
#undef Qc3_ANSI_X931
#define Qc3_ANSI_X931 '\xF5' /* '5' */
#undef Qc3_OAEP
#define Qc3_OAEP '\xF6' /* '6' */
#undef Qc3_Bin_String
#define Qc3_Bin_String '\xF0' /* '0' */
#undef Qc3_BER_String
#define Qc3_BER_String '\xF1' /* '1' */
#undef Qc3_MK_Struct
#define Qc3_MK_Struct '\xF3' /* '3' */
#undef Qc3_KSLabel_Struct
#define Qc3_KSLabel_Struct '\xF4' /* '4' */
#undef Qc3_PKCS5_Struct
#define Qc3_PKCS5_Struct '\xF5' /* '5' */
#undef Qc3_PEMCert_String
#define Qc3_PEMCert_String '\xF6' /* '6' */
#undef Qc3_CSLabel_String
#define Qc3_CSLabel_String '\xF7' /* '7' */
#undef Qc3_CSDN_String
#define Qc3_CSDN_String '\xF8' /* '8' */
#undef Qc3_Clear
#define Qc3_Clear '\xF0' /* '0' */
#undef Qc3_Encrypted
#define Qc3_Encrypted '\xF1' /* '1' */
#undef Qc3_MK_Encrypted
#define Qc3_MK_Encrypted '\xF2' /* '2' */
#undef Qc3_Any_CSP
#define Qc3_Any_CSP '\xF0' /* '0' */
#undef Qc3_Sfw_CSP
#define Qc3_Sfw_CSP '\xF1' /* '1' */
#undef Qc3_Hdw_CSP
#define Qc3_Hdw_CSP '\xF2' /* '2' */
#undef Qc3_Continue
#define Qc3_Continue '\xF0' /* '0' */
#undef Qc3_Final
#define Qc3_Final '\xF1' /* '1' */
#undef Qc3_MK_New
#define Qc3_MK_New '\xF0' /* '0' */
#undef Qc3_MK_Current
#define Qc3_MK_Current '\xF1' /* '1' */
#undef Qc3_MK_Old
#define Qc3_MK_Old '\xF2' /* '2' */
#undef Qc3_MK_Pending
#define Qc3_MK_Pending '\xF3' /* '3' */
/* Define which features are supported. */
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 0
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: global handles structures.
*
*******************************************************************/
/* HMAC & private key algorithms support structure. */
typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx;
struct _libssh2_os400qc3_crypto_ctx {
Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */
Qc3_Format_KEYD0100_T key; /* Key. */
_libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */
};
typedef struct { /* Big number. */
unsigned char * bignum; /* Number bits, little-endian. */
unsigned int length; /* Length of bignum (# bytes). */
} _libssh2_bn;
typedef struct { /* Algorithm description. */
char * fmt; /* Format of Qc3 structure. */
int algo; /* Algorithm identifier. */
unsigned char size; /* Block length. */
unsigned char mode; /* Block mode. */
int keylen; /* Key length. */
} _libssh2_os400qc3_cipher_t;
typedef struct { /* Diffie-Hellman context. */
char token[8]; /* Context token. */
} _libssh2_os400qc3_dh_ctx;
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Define global types/codes.
*
*******************************************************************/
#define libssh2_crypto_init()
#define libssh2_crypto_exit()
#define libssh2_sha1_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha384_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha512_ctx Qc3_Format_ALGD0100_T
#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx
#define libssh2_sha1_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA1)
#define libssh2_sha1_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA256)
#define libssh2_sha256_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA256)
#define libssh2_sha384_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA384)
#define libssh2_sha384_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha384(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA384)
#define libssh2_sha512_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA512)
#define libssh2_sha512_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha512(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA512)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#define libssh2_md5_ctx Qc3_Format_ALGD0100_T
#define libssh2_md5_init(x) _libssh2_os400qc3_hash_init(x, Qc3_MD5)
#define libssh2_md5_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#endif
#define _libssh2_bn_ctx int /* Not used. */
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void) 0)
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_bytes(bn) ((bn)->length)
#define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name
#define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 16}
#define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 24}
#define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 32}
#define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 16}
#define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 24}
#define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 32}
#define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 8, \
Qc3_CBC, 24}
/* Nonsense values for chacha20-poly1305 */
#define _libssh2_cipher_chacha20 {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16}
#define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16}
#define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx)
#define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \
free((char *) ctx))
#define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \
(len) * sizeof(struct iovec))
#define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA1, sig, siglen, \
count, vector, ctx)
#define _libssh2_rsa_sha2_256_signv(session, sig, siglen, cnt, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA256, sig, siglen, \
cnt, vector, ctx)
#define _libssh2_rsa_sha2_512_signv(session, sig, siglen, cnt, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA512, sig, siglen, \
cnt, vector, ctx)
/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1
Qc3 is limited to a maximum 2048-bit modulus/key size. */
#define LIBSSH2_DH_GEX_MINGROUP 1024
#define LIBSSH2_DH_GEX_OPTGROUP 1536
#define LIBSSH2_DH_GEX_MAXGROUP 2048
#define LIBSSH2_DH_MAX_MODULUS_BITS 2048
#define _libssh2_dh_ctx _libssh2_os400qc3_dh_ctx
#define libssh2_dh_init(dhctx) _libssh2_os400qc3_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_os400qc3_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_os400qc3_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_os400qc3_dh_dtor(dhctx)
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Support procedure prototypes.
*
*******************************************************************/
extern _libssh2_bn * _libssh2_bn_init(void);
extern void _libssh2_bn_free(_libssh2_bn *bn);
extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn);
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, size_t len,
const unsigned char *v);
extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val);
extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val);
extern int _libssh2_random(unsigned char *buf, size_t len);
extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x);
extern int _libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x,
unsigned int algo);
extern int _libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx,
const unsigned char *data,
int len);
extern int _libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx,
unsigned char *out);
extern int _libssh2_os400qc3_hash(const unsigned char *message,
unsigned long len, unsigned char *out,
unsigned int algo);
extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec vector[],
libssh2_rsa_ctx *ctx);
extern void _libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx,
_libssh2_bn *public,
_libssh2_bn *g,
_libssh2_bn *p, int group_order);
extern int _libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx,
_libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void _libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* LIBSSH2_OS400QC3_H */
/* vim: set expandtab ts=4 sw=4: */

1658
vendor/libssh2/src/packet.c vendored Normal file

File diff suppressed because it is too large Load Diff

77
vendor/libssh2/src/packet.h vendored Normal file
View File

@@ -0,0 +1,77 @@
#ifndef LIBSSH2_PACKET_H
#define LIBSSH2_PACKET_H
/*
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
int _libssh2_packet_read(LIBSSH2_SESSION * session);
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len);
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len);
int _libssh2_packet_require(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
size_t *data_len, int match_ofs,
const unsigned char *match_buf,
size_t match_len,
packet_require_state_t * state);
int _libssh2_packet_requirev(LIBSSH2_SESSION *session,
const unsigned char *packet_types,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len,
packet_requirev_state_t * state);
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
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, uint32_t seq);
#endif /* LIBSSH2_PACKET_H */

975
vendor/libssh2/src/pem.c vendored Normal file
View File

@@ -0,0 +1,975 @@
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Simon Josefsson
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
static int
readline(char *line, int line_size, FILE * fp)
{
size_t len;
if(!line) {
return -1;
}
if(!fgets(line, line_size, fp)) {
return -1;
}
if(*line) {
len = strlen(line);
if(len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\0';
}
}
if(*line) {
len = strlen(line);
if(len > 0 && line[len - 1] == '\r') {
line[len - 1] = '\0';
}
}
return 0;
}
static int
readline_memory(char *line, size_t line_size,
const char *filedata, size_t filedata_len,
size_t *filedata_offset)
{
size_t off, len;
off = *filedata_offset;
for(len = 0; off + len < filedata_len && len < line_size - 1; len++) {
if(filedata[off + len] == '\n' ||
filedata[off + len] == '\r') {
break;
}
}
if(len) {
memcpy(line, filedata + off, len);
*filedata_offset += len;
}
line[len] = '\0';
*filedata_offset += 1;
return 0;
}
#define LINE_SIZE 128
static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED";
static unsigned char hex_decode(char digit)
{
return (unsigned char)
((digit >= 'A') ? (0xA + (digit - 'A')) : (digit - '0'));
}
int
_libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
unsigned char iv[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
int ret;
const LIBSSH2_CRYPT_METHOD *method = NULL;
do {
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
} while(strcmp(line, headerbegin) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
if(passphrase &&
memcmp(line, crypt_annotation, strlen(crypt_annotation)) == 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
int i;
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
all_methods = libssh2_crypt_methods();
/* !checksrc! disable EQUALSNULL 1 */
while((cur_method = *all_methods++) != NULL) {
if(*cur_method->pem_annotation &&
memcmp(line, cur_method->pem_annotation,
strlen(cur_method->pem_annotation)) == 0) {
method = cur_method;
memcpy(iv, line + strlen(method->pem_annotation) + 1,
2*method->iv_len);
}
}
/* None of the available crypt methods were able to decrypt the key */
if(!method)
return -1;
/* Decode IV from hex */
for(i = 0; i < method->iv_len; ++i) {
iv[i] = (unsigned char)(hex_decode(iv[2*i]) << 4);
iv[i] |= hex_decode(iv[2*i + 1]);
}
/* skip to the next line */
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
}
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for PEM parsing");
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while(strcmp(line, headerend) != 0);
if(!b64data) {
return -1;
}
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
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;
void *abstract;
unsigned char secret[2*MD5_DIGEST_LENGTH];
libssh2_md5_ctx fingerprint_ctx;
/* Perform key derivation (PBKDF1/MD5) */
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;
}
if(method->secret_len > MD5_DIGEST_LENGTH) {
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;
}
}
/* Initialize the decryption */
if(method->init(session, method, iv, &free_iv, secret,
&free_secret, 0, &abstract)) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
LIBSSH2_FREE(session, data);
ret = -1;
goto out;
}
if(free_secret) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
}
/* Do the actual decryption */
if((*datalen % blocksize) != 0) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
ret = -1;
goto out;
}
if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
if(method->crypt(session, 0, *data, *datalen, &abstract, 0)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
goto out;
}
}
else {
while(len_decrypted <= (int)*datalen - blocksize) {
if(method->crypt(session, 0, *data + len_decrypted, blocksize,
&abstract,
len_decrypted == 0 ? FIRST_BLOCK :
((len_decrypted == (int)*datalen - blocksize) ?
LAST_BLOCK : MIDDLE_BLOCK)
)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
goto out;
}
len_decrypted += blocksize;
}
}
/* Account for padding */
padding = (*data)[*datalen - 1];
memset(&(*data)[*datalen-padding], 0, padding);
*datalen -= padding;
/* Clean up */
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
#else
ret = -1;
goto out;
#endif
}
ret = 0;
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
int
_libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const char *filedata, size_t filedata_len,
unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
size_t off = 0;
int ret;
do {
*line = '\0';
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
} while(strcmp(line, headerbegin) != 0);
*line = '\0';
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for PEM parsing");
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
ret = -1;
goto out;
}
} while(strcmp(line, headerend) != 0);
if(!b64data) {
return -1;
}
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
ret = 0;
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
/* OpenSSH formatted keys */
#define AUTH_MAGIC "openssh-key-v1"
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
#define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----"
static int
_libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *b64data, size_t b64datalen,
struct string_buf **decrypted_buf)
{
const LIBSSH2_CRYPT_METHOD *method = NULL;
struct string_buf decoded, decrypted, kdf_buf;
unsigned char *ciphername = NULL;
unsigned char *kdfname = NULL;
unsigned char *kdf = NULL;
unsigned char *buf = NULL;
unsigned char *salt = NULL;
uint32_t nkeys, check1, check2;
uint32_t rounds = 0;
unsigned char *key = NULL;
unsigned char *key_part = NULL;
unsigned char *iv_part = NULL;
unsigned char *f = NULL;
size_t f_len = 0;
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
if(decrypted_buf)
*decrypted_buf = NULL;
/* decode file */
if(_libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, b64datalen)) {
ret = -1;
goto out;
}
/* Parse the file */
decoded.data = (unsigned char *)f;
decoded.dataptr = (unsigned char *)f;
decoded.len = f_len;
if(decoded.len < strlen(AUTH_MAGIC)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key too short");
goto out;
}
if(strncmp((char *) decoded.dataptr, AUTH_MAGIC,
strlen(AUTH_MAGIC)) != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"key auth magic mismatch");
goto out;
}
decoded.dataptr += strlen(AUTH_MAGIC) + 1;
if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ciphername is missing");
goto out;
}
if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdfname is missing");
goto out;
}
if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf is missing");
goto out;
}
else {
kdf_buf.data = kdf;
kdf_buf.dataptr = kdf;
kdf_buf.len = kdf_len;
}
if((!passphrase || strlen((const char *)passphrase) == 0) &&
strcmp((const char *)ciphername, "none") != 0) {
/* passphrase required */
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(strcmp((const char *)kdfname, "none") != 0 &&
strcmp((const char *)kdfname, "bcrypt") != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"unknown cipher");
goto out;
}
if(!strcmp((const char *)kdfname, "none") &&
strcmp((const char *)ciphername, "none") != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"invalid format");
goto out;
}
if(_libssh2_get_u32(&decoded, &nkeys) != 0 || nkeys != 1) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Multiple keys are unsupported");
goto out;
}
/* unencrypted public key */
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid private key; "
"expect embedded public key");
goto out;
}
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key data not found");
goto out;
}
/* decode encrypted private key */
decrypted.data = decrypted.dataptr = buf;
decrypted.len = tmp_len;
if(ciphername && strcmp((const char *)ciphername, "none") != 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
all_methods = libssh2_crypt_methods();
/* !checksrc! disable EQUALSNULL 1 */
while((cur_method = *all_methods++) != NULL) {
if(*cur_method->name &&
memcmp(ciphername, cur_method->name,
strlen(cur_method->name)) == 0) {
method = cur_method;
}
}
/* None of the available crypt methods were able to decrypt the key */
if(!method) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"No supported cipher found");
goto out;
}
}
if(method) {
int free_iv = 0, free_secret = 0, len_decrypted = 0;
int blocksize;
void *abstract = NULL;
keylen = method->secret_len;
ivlen = method->iv_len;
total_len = keylen + ivlen;
key = LIBSSH2_CALLOC(session, total_len);
if(!key) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key");
goto out;
}
if(strcmp((const char *)kdfname, "bcrypt") == 0 && passphrase) {
if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) ||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf contains unexpected values");
LIBSSH2_FREE(session, key);
goto out;
}
if(_libssh2_bcrypt_pbkdf((const char *)passphrase,
strlen((const char *)passphrase),
salt, salt_len, key,
keylen + ivlen, rounds) < 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
"invalid format");
LIBSSH2_FREE(session, key);
goto out;
}
}
else {
ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED,
"bcrypted without passphrase");
LIBSSH2_FREE(session, key);
goto out;
}
/* Set up decryption */
blocksize = method->blocksize;
key_part = LIBSSH2_CALLOC(session, keylen);
if(!key_part) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key part");
goto out;
}
iv_part = LIBSSH2_CALLOC(session, ivlen);
if(!iv_part) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc iv part");
goto out;
}
memcpy(key_part, key, keylen);
memcpy(iv_part, key + keylen, ivlen);
/* Initialize the decryption */
if(method->init(session, method, iv_part, &free_iv, key_part,
&free_secret, 0, &abstract)) {
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
/* Do the actual decryption */
if((decrypted.len % blocksize) != 0) {
method->dtor(session, &abstract);
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
if(method->crypt(session, 0, decrypted.data,
decrypted.len,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
}
else {
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, 0, decrypted.data + len_decrypted,
blocksize,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
len_decrypted += blocksize;
}
/* 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, 0, 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);
}
/* Check random bytes match */
if(_libssh2_get_u32(&decrypted, &check1) != 0 ||
_libssh2_get_u32(&decrypted, &check2) != 0 ||
check1 != check2) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key unpack failed (correct password?)");
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(decrypted_buf) {
/* copy data to out-going buffer */
struct string_buf *out_buf = _libssh2_string_buf_new(session);
if(!out_buf) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
goto out;
}
out_buf->data = LIBSSH2_CALLOC(session, decrypted.len);
if(!out_buf->data) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
_libssh2_string_buf_free(session, out_buf);
goto out;
}
memcpy(out_buf->data, decrypted.data, decrypted.len);
out_buf->dataptr = out_buf->data +
(decrypted.dataptr - decrypted.data);
out_buf->len = decrypted.len;
*decrypted_buf = out_buf;
}
out:
/* Clean up */
if(key) {
_libssh2_explicit_zero(key, total_len);
LIBSSH2_FREE(session, key);
}
if(key_part) {
_libssh2_explicit_zero(key_part, keylen);
LIBSSH2_FREE(session, key_part);
}
if(iv_part) {
_libssh2_explicit_zero(iv_part, ivlen);
LIBSSH2_FREE(session, iv_part);
}
if(f) {
_libssh2_explicit_zero(f, f_len);
LIBSSH2_FREE(session, f);
}
return ret;
}
int
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
FILE * fp, struct string_buf **decrypted_buf)
{
char line[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
int ret = 0;
/* read file */
do {
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
} while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for PEM parsing");
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
if(!b64data) {
return -1;
}
ret = _libssh2_openssh_pem_parse_data(session,
passphrase,
(const char *)b64data,
b64datalen,
decrypted_buf);
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
out:
return ret;
}
int
_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *filedata, size_t filedata_len,
struct string_buf **decrypted_buf)
{
char line[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
size_t off = 0;
int ret;
if(!filedata || filedata_len <= 0)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: filedata missing");
do {
*line = '\0';
if(off >= filedata_len)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: "
"OpenSSH header not found");
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
} while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
*line = '\0';
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"PEM parsing");
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(off >= filedata_len) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: offset out of bounds");
goto out;
}
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
ret = -1;
goto out;
}
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
if(!b64data)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: base 64 data missing");
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
b64datalen, decrypted_buf);
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
static int
read_asn1_length(const unsigned char *data,
size_t datalen, size_t *len)
{
unsigned int lenlen;
int nextpos;
if(datalen < 1) {
return -1;
}
*len = data[0];
if(*len >= 0x80) {
lenlen = *len & 0x7F;
*len = data[1];
if(1 + lenlen > datalen) {
return -1;
}
if(lenlen > 1) {
*len <<= 8;
*len |= data[2];
}
}
else {
lenlen = 0;
}
nextpos = 1 + lenlen;
if(lenlen > 2 || 1 + lenlen + *len > datalen) {
return -1;
}
return nextpos;
}
int
_libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen)
{
size_t len;
int lenlen;
if(*datalen < 1) {
return -1;
}
if((*data)[0] != '\x30') {
return -1;
}
(*data)++;
(*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len);
if(lenlen < 0 || lenlen + len != *datalen) {
return -1;
}
*data += lenlen;
*datalen -= lenlen;
return 0;
}
int
_libssh2_pem_decode_integer(unsigned char **data, size_t *datalen,
unsigned char **i, unsigned int *ilen)
{
size_t len;
int lenlen;
if(*datalen < 1) {
return -1;
}
if((*data)[0] != '\x02') {
return -1;
}
(*data)++;
(*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len);
if(lenlen < 0 || lenlen + len > *datalen) {
return -1;
}
*data += lenlen;
*datalen -= lenlen;
*i = *data;
*ilen = (unsigned int)len;
*data += len;
*datalen -= len;
return 0;
}

206
vendor/libssh2/src/poly1305.c vendored Normal file
View File

@@ -0,0 +1,206 @@
/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */
#include "libssh2_priv.h"
#include "poly1305.h"
#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
#define U8TO32_LE(p) \
(((uint32_t)((p)[0])) | \
((uint32_t)((p)[1]) << 8) | \
((uint32_t)((p)[2]) << 16) | \
((uint32_t)((p)[3]) << 24))
#define U32TO8_LE(p, v) \
do { \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24); \
} while (0)
void
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m,
size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
uint32_t t0;
uint32_t t1;
uint32_t t2;
uint32_t t3;
uint32_t h0;
uint32_t h1;
uint32_t h2;
uint32_t h3;
uint32_t h4;
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t b;
uint32_t nb;
size_t j;
uint64_t t[5];
uint64_t f0;
uint64_t f1;
uint64_t f2;
uint64_t f3;
uint32_t g0;
uint32_t g1;
uint32_t g2;
uint32_t g3;
uint32_t g4;
uint64_t c;
unsigned char mp[16];
/* clamp key */
t0 = U8TO32_LE(key + 0);
t1 = U8TO32_LE(key + 4);
t2 = U8TO32_LE(key + 8);
t3 = U8TO32_LE(key + 12);
/* precompute multipliers */
r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
r3 = t2 & 0x3f03fff; t3 >>= 8;
r4 = t3 & 0x00fffff;
s1 = r1 * 5;
s2 = r2 * 5;
s3 = r3 * 5;
s4 = r4 * 5;
/* init state */
h0 = 0;
h1 = 0;
h2 = 0;
h3 = 0;
h4 = 0;
/* full blocks */
if(inlen < 16)
goto poly1305_donna_atmost15bytes;
poly1305_donna_16bytes:
m += 16;
inlen -= 16;
t0 = U8TO32_LE(m-16);
t1 = U8TO32_LE(m-12);
t2 = U8TO32_LE(m-8);
t3 = U8TO32_LE(m-4);
h0 += t0 & 0x3ffffff;
h1 += ((uint32_t)((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff);
h2 += ((uint32_t)((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff);
h3 += ((uint32_t)((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff);
h4 += (t3 >> 8) | (1 << 24);
poly1305_donna_mul:
t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) +
mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) +
mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) +
mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) +
mul32x32_64(h3, r0) + mul32x32_64(h4, s4);
t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) +
mul32x32_64(h3, r1) + mul32x32_64(h4, r0);
h0 = (uint32_t)t[0] & 0x3ffffff;
c = (t[0] >> 26);
t[1] += c;
h1 = (uint32_t)t[1] & 0x3ffffff;
b = (uint32_t)(t[1] >> 26);
t[2] += b;
h2 = (uint32_t)t[2] & 0x3ffffff;
b = (uint32_t)(t[2] >> 26);
t[3] += b;
h3 = (uint32_t)t[3] & 0x3ffffff;
b = (uint32_t)(t[3] >> 26);
t[4] += b;
h4 = (uint32_t)t[4] & 0x3ffffff;
b = (uint32_t)(t[4] >> 26);
h0 += b * 5;
if(inlen >= 16)
goto poly1305_donna_16bytes;
/* final bytes */
poly1305_donna_atmost15bytes:
if(!inlen)
goto poly1305_donna_finish;
for(j = 0; j < inlen; j++) mp[j] = m[j];
mp[j++] = 1;
for(; j < 16; j++)
mp[j] = 0;
inlen = 0;
t0 = U8TO32_LE(mp + 0);
t1 = U8TO32_LE(mp + 4);
t2 = U8TO32_LE(mp + 8);
t3 = U8TO32_LE(mp + 12);
h0 += t0 & 0x3ffffff;
h1 += ((uint32_t)((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff);
h2 += ((uint32_t)((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff);
h3 += ((uint32_t)((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff);
h4 += (t3 >> 8);
goto poly1305_donna_mul;
poly1305_donna_finish:
b = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += b;
g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
g4 = h4 + b - (1 << 26);
b = (g4 >> 31) - 1;
nb = ~b;
h0 = (h0 & nb) | (g0 & b);
h1 = (h1 & nb) | (g1 & b);
h2 = (h2 & nb) | (g2 & b);
h3 = (h3 & nb) | (g3 & b);
h4 = (h4 & nb) | (g4 & b);
f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);
U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
U32TO8_LE(&out[12], f3);
}

20
vendor/libssh2/src/poly1305.h vendored Normal file
View File

@@ -0,0 +1,20 @@
/* $OpenBSD: poly1305.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */
/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#ifndef POLY1305_H
#define POLY1305_H
#define POLY1305_KEYLEN 32
#define POLY1305_TAGLEN 16
void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
const u_char key[POLY1305_KEYLEN]);
#endif /* POLY1305_H */

1284
vendor/libssh2/src/publickey.c vendored Normal file

File diff suppressed because it is too large Load Diff

1185
vendor/libssh2/src/scp.c vendored Normal file

File diff suppressed because it is too large Load Diff

1958
vendor/libssh2/src/session.c vendored Normal file

File diff suppressed because it is too large Load Diff

94
vendor/libssh2/src/session.h vendored Normal file
View File

@@ -0,0 +1,94 @@
#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>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Conveniance-macros to allow code like this;
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock));
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock));
The point being to make sure that while in non-blocking mode these always
return no matter what the return code is, but in blocking mode it blocks
if EAGAIN is the reason for the return from the underlying function.
*/
#define BLOCK_ADJUST(rc, sess, x) \
do { \
time_t entry_time = time(NULL); \
do { \
rc = x; \
/* the order of the check below is important to properly \
deal with the case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
} while(0)
/*
* For functions that returns a pointer, we need to check if the API is
* non-blocking and return immediately. If the pointer is non-NULL we return
* immediately. If the API is blocking and we get a NULL we check the errno
* and *only* if that is EAGAIN we loop and wait for socket action.
*/
#define BLOCK_ADJUST_ERRNO(ptr, sess, x) \
do { \
time_t entry_time = time(NULL); \
int rc; \
do { \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN)) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
} while(0)
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 */

3974
vendor/libssh2/src/sftp.c vendored Normal file

File diff suppressed because it is too large Load Diff

242
vendor/libssh2/src/sftp.h vendored Normal file
View File

@@ -0,0 +1,242 @@
#ifndef LIBSSH2_SFTP_PRIV_H
#define LIBSSH2_SFTP_PRIV_H
/*
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the
* amount of data sent in each FXP_WRITE packet
*/
#define MAX_SFTP_OUTGOING_SIZE 30000
/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ
* packets.
*/
#define MAX_SFTP_READ_SIZE 30000
struct sftp_pipeline_chunk {
struct list_node node;
libssh2_uint64_t offset; /* READ: offset at which to start reading
WRITE: not used */
size_t len; /* WRITE: size of the data to write
READ: how many bytes that was asked for */
size_t sent;
ssize_t lefttosend; /* if 0, the entire packet has been sent off */
uint32_t request_id;
unsigned char packet[1]; /* data */
};
struct sftp_zombie_requests {
struct list_node node;
uint32_t request_id;
};
struct _LIBSSH2_SFTP_PACKET
{
struct list_node node; /* linked list header */
uint32_t request_id;
unsigned char *data;
size_t data_len; /* payload size */
};
typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET;
/* Increasing from 256 to 4092 since OpenSSH doesn't honor it. */
#define SFTP_HANDLE_MAXLEN 4092 /* according to spec, this should be 256! */
struct _LIBSSH2_SFTP_HANDLE
{
struct list_node node;
LIBSSH2_SFTP *sftp;
char handle[SFTP_HANDLE_MAXLEN];
size_t handle_len;
enum {
LIBSSH2_SFTP_HANDLE_FILE,
LIBSSH2_SFTP_HANDLE_DIR
} handle_type;
union _libssh2_sftp_handle_data
{
struct _libssh2_sftp_handle_file_data
{
libssh2_uint64_t offset;
libssh2_uint64_t offset_sent;
size_t acked; /* container for acked data that hasn't been
returned to caller yet, used for sftp_write */
/* 'data' is used by sftp_read() and is allocated data that has
been received already from the server but wasn't returned to
the caller yet. It is of size 'data_len' and 'data_left is the
number of bytes not yet returned, counted from the end of the
buffer. */
unsigned char *data;
size_t data_len;
size_t data_left;
char eof; /* we have read to the end */
} file;
struct _libssh2_sftp_handle_dir_data
{
uint32_t names_left;
void *names_packet;
char *next_name;
size_t names_packet_len;
} dir;
} u;
/* State variables used in libssh2_sftp_close_handle() */
libssh2_nonblocking_states close_state;
uint32_t close_request_id;
unsigned char *close_packet;
/* list of outstanding packets sent to server */
struct list_head packet_list;
};
struct _LIBSSH2_SFTP
{
LIBSSH2_CHANNEL *channel;
uint32_t request_id, version, posix_rename_version;
struct list_head packets;
/* List of FXP_READ responses to ignore because EOF already received. */
struct list_head zombie_requests;
/* a list of _LIBSSH2_SFTP_HANDLE structs */
struct list_head sftp_handles;
uint32_t last_errno;
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
unsigned char packet_header[9];
/* packet size (4) packet type (1) request id (4) */
size_t packet_header_len; /* packet_header length */
unsigned char *partial_packet; /* The data, with header */
uint32_t partial_len; /* Desired number of bytes */
size_t partial_received; /* Bytes received so far */
/* Time that libssh2_sftp_packet_requirev() started reading */
time_t requirev_start;
/* State variables used in libssh2_sftp_open_ex() */
libssh2_nonblocking_states open_state;
unsigned char *open_packet;
uint32_t open_packet_len; /* 32 bit on the wire */
size_t open_packet_sent;
uint32_t open_request_id;
/* State variable used in sftp_read() */
libssh2_nonblocking_states read_state;
/* State variable used in sftp_packet_read() */
libssh2_nonblocking_states packet_state;
/* State variable used in sftp_write() */
libssh2_nonblocking_states write_state;
/* State variables used in sftp_fsync() */
libssh2_nonblocking_states fsync_state;
unsigned char *fsync_packet;
uint32_t fsync_request_id;
/* State variables used in libssh2_sftp_readdir() */
libssh2_nonblocking_states readdir_state;
unsigned char *readdir_packet;
uint32_t readdir_request_id;
/* State variables used in libssh2_sftp_fstat_ex() */
libssh2_nonblocking_states fstat_state;
unsigned char *fstat_packet;
uint32_t fstat_request_id;
/* State variables used in libssh2_sftp_unlink_ex() */
libssh2_nonblocking_states unlink_state;
unsigned char *unlink_packet;
uint32_t unlink_request_id;
/* State variables used in libssh2_sftp_rename_ex() */
libssh2_nonblocking_states rename_state;
unsigned char *rename_packet;
unsigned char *rename_s;
uint32_t rename_request_id;
/* State variables used in libssh2_sftp_posix_rename_ex() */
libssh2_nonblocking_states posix_rename_state;
unsigned char *posix_rename_packet;
uint32_t posix_rename_request_id;
/* State variables used in libssh2_sftp_fstatvfs() */
libssh2_nonblocking_states fstatvfs_state;
unsigned char *fstatvfs_packet;
uint32_t fstatvfs_request_id;
/* State variables used in libssh2_sftp_statvfs() */
libssh2_nonblocking_states statvfs_state;
unsigned char *statvfs_packet;
uint32_t statvfs_request_id;
/* State variables used in libssh2_sftp_mkdir() */
libssh2_nonblocking_states mkdir_state;
unsigned char *mkdir_packet;
uint32_t mkdir_request_id;
/* State variables used in libssh2_sftp_rmdir() */
libssh2_nonblocking_states rmdir_state;
unsigned char *rmdir_packet;
uint32_t rmdir_request_id;
/* State variables used in libssh2_sftp_stat() */
libssh2_nonblocking_states stat_state;
unsigned char *stat_packet;
uint32_t stat_request_id;
/* State variables used in libssh2_sftp_symlink() */
libssh2_nonblocking_states symlink_state;
unsigned char *symlink_packet;
uint32_t symlink_request_id;
};
#endif /* LIBSSH2_SFTP_PRIV_H */

1306
vendor/libssh2/src/transport.c vendored Normal file

File diff suppressed because it is too large Load Diff

87
vendor/libssh2/src/transport.h vendored Normal file
View File

@@ -0,0 +1,87 @@
#ifndef LIBSSH2_TRANSPORT_H
#define LIBSSH2_TRANSPORT_H
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file handles reading and writing to the SECSH transport layer. RFC4253.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "packet.h"
/*
* libssh2_transport_send
*
* Send a packet, encrypting it and adding a MAC code if necessary
* Returns 0 on success, non-zero on failure.
*
* The data is provided as _two_ data areas that are combined by this
* function. The 'data' part is sent immediately before 'data2'. 'data2' can
* be set to NULL (or data2_len to 0) to only use a single part.
*
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
* not sent yet. If it does so, the caller should call this function again as
* soon as it is likely that more data can be sent, and this function MUST
* then be called with the same argument set (same data pointer and same
* data_len) until ERROR_NONE or failure is returned.
*
* This function DOES NOT call _libssh2_error() on any errors.
*/
int _libssh2_transport_send(LIBSSH2_SESSION *session,
const unsigned char *data, size_t data_len,
const unsigned char *data2, size_t data2_len);
/*
* _libssh2_transport_read
*
* Collect a packet into the input brigade block only controls whether or not
* to wait for a packet to start.
*
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
* packet.
*/
/*
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*/
int _libssh2_transport_read(LIBSSH2_SESSION * session);
#endif /* LIBSSH2_TRANSPORT_H */

2506
vendor/libssh2/src/userauth.c vendored Normal file

File diff suppressed because it is too large Load Diff

53
vendor/libssh2/src/userauth.h vendored Normal file
View File

@@ -0,0 +1,53 @@
#ifndef LIBSSH2_USERAUTH_H
#define LIBSSH2_USERAUTH_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
int
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *username,
size_t username_len,
const unsigned char *pubkeydata,
size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
void *abstract);
#endif /* LIBSSH2_USERAUTH_H */

166
vendor/libssh2/src/userauth_kbd_packet.c vendored Normal file
View File

@@ -0,0 +1,166 @@
/* Copyright (C) Xaver Loppenstedt <xaver@loppenstedt.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "userauth_kbd_packet.h"
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *session)
{
unsigned char *language_tag;
size_t language_tag_len;
unsigned int i;
unsigned char packet_type;
uint32_t tmp_u32;
struct string_buf decoded;
decoded.data = session->userauth_kybd_data;
decoded.dataptr = session->userauth_kybd_data;
decoded.len = session->userauth_kybd_data_len;
if(session->userauth_kybd_data_len < 17) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small "
"to get length");
return -1;
}
/* byte SSH_MSG_USERAUTH_INFO_REQUEST */
_libssh2_get_byte(&decoded, &packet_type);
/* string name (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_auth_name,
&session->userauth_kybd_auth_name_len) == -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'name' "
"request field");
return -1;
}
/* string instruction (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_auth_instruction,
&session->userauth_kybd_auth_instruction_len)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'instruction' "
"request field");
return -1;
}
/* string language tag (as defined in [RFC-3066]) */
if(_libssh2_get_string(&decoded, &language_tag,
&language_tag_len) == -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'language tag' "
"request field");
return -1;
}
/* int num-prompts */
if(_libssh2_get_u32(&decoded, &tmp_u32) == -1 ||
(session->userauth_kybd_num_prompts = tmp_u32) != tmp_u32) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Unable to decode "
"keyboard-interactive number of keyboard prompts");
return -1;
}
if(session->userauth_kybd_num_prompts > 100) {
_libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
"Too many replies for "
"keyboard-interactive prompts");
return -1;
}
if(session->userauth_kybd_num_prompts == 0) {
return 0;
}
session->userauth_kybd_prompts =
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
session->userauth_kybd_num_prompts);
if(!session->userauth_kybd_prompts) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive prompts array");
return -1;
}
session->userauth_kybd_responses =
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
session->userauth_kybd_num_prompts);
if(!session->userauth_kybd_responses) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive responses array");
return -1;
}
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
/* string prompt[1] (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_prompts[i].text,
&session->userauth_kybd_prompts[i].length)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive prompt message");
return -1;
}
/* boolean echo[1] */
if(_libssh2_get_boolean(&decoded,
&session->userauth_kybd_prompts[i].echo)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Unable to decode "
"user auth keyboard prompt echo");
return -1;
}
}
return 0;
}

View File

@@ -0,0 +1,45 @@
/* Copyright (C) Xaver Loppenstedt <xaver@loppenstedt.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#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_PACKET_H */

54
vendor/libssh2/src/version.c vendored Normal file
View File

@@ -0,0 +1,54 @@
/* Copyright (C) Daniel Stenberg
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
LIBSSH2_API
const char *libssh2_version(int req_version_num)
{
if(req_version_num <= LIBSSH2_VERSION_NUM)
return LIBSSH2_VERSION;
return NULL; /* this is not a suitable library! */
}
LIBSSH2_API
libssh2_crypto_engine_t libssh2_crypto_engine(void)
{
return LIBSSH2_CRYPTO_ENGINE;
}

4185
vendor/libssh2/src/wincng.c vendored Normal file

File diff suppressed because it is too large Load Diff

561
vendor/libssh2/src/wincng.h vendored Normal file
View File

@@ -0,0 +1,561 @@
#ifndef LIBSSH2_WINCNG_H
#define LIBSSH2_WINCNG_H
/*
* Copyright (C) Marc Hoersken <info@marc-hoersken.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
*
* Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* Neither the name of the copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_wincng
/* required for cross-compilation against the w64 mingw-runtime package */
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#include <windows.h>
#include <bcrypt.h>
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 1
#define LIBSSH2_ED25519 0
/*
* Conditionally enable ECDSA support.
*
* ECDSA support requires the use of
*
* BCryptDeriveKey(..., BCRYPT_KDF_RAW_SECRET, ... )
*
* This functionality is only available as of Windows 10. To maintain
* backward compatibility, ECDSA support is therefore disabled
* by default and needs to be explicitly enabled using a build
* flag.
*/
#ifdef LIBSSH2_ECDSA_WINCNG
#define LIBSSH2_ECDSA 1
#else
#define LIBSSH2_ECDSA 0
#endif
#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
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
/*******************************************************************/
/*
* Windows CNG backend: Global context handles
*/
struct _libssh2_wincng_ctx {
BCRYPT_ALG_HANDLE hAlgRNG;
BCRYPT_ALG_HANDLE hAlgHashMD5;
BCRYPT_ALG_HANDLE hAlgHashSHA1;
BCRYPT_ALG_HANDLE hAlgHashSHA256;
BCRYPT_ALG_HANDLE hAlgHashSHA384;
BCRYPT_ALG_HANDLE hAlgHashSHA512;
BCRYPT_ALG_HANDLE hAlgHmacMD5;
BCRYPT_ALG_HANDLE hAlgHmacSHA1;
BCRYPT_ALG_HANDLE hAlgHmacSHA256;
BCRYPT_ALG_HANDLE hAlgHmacSHA384;
BCRYPT_ALG_HANDLE hAlgHmacSHA512;
BCRYPT_ALG_HANDLE hAlgRSA;
BCRYPT_ALG_HANDLE hAlgDSA;
BCRYPT_ALG_HANDLE hAlgAES_CBC;
BCRYPT_ALG_HANDLE hAlgAES_ECB;
BCRYPT_ALG_HANDLE hAlgRC4_NA;
BCRYPT_ALG_HANDLE hAlg3DES_CBC;
BCRYPT_ALG_HANDLE hAlgDH;
BCRYPT_ALG_HANDLE hAlgChacha20;
#if LIBSSH2_ECDSA
BCRYPT_ALG_HANDLE hAlgECDH[3]; /* indexed by libssh2_curve_type */
BCRYPT_ALG_HANDLE hAlgECDSA[3]; /* indexed by libssh2_curve_type */
#endif
volatile int hasAlgDHwithKDF; /* -1=no, 0=maybe, 1=yes */
};
extern struct _libssh2_wincng_ctx _libssh2_wincng;
/*******************************************************************/
/*
* Windows CNG backend: Generic functions
*/
#define libssh2_crypto_init() \
_libssh2_wincng_init()
#define libssh2_crypto_exit() \
_libssh2_wincng_free()
#define _libssh2_random(buf, len) \
_libssh2_wincng_random(buf, len)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
/*******************************************************************/
/*
* Windows CNG backend: Hash structure
*/
typedef struct __libssh2_wincng_hash_ctx {
BCRYPT_HASH_HANDLE hHash;
unsigned char *pbHashObject;
ULONG dwHashObject;
ULONG cbHash;
} _libssh2_wincng_hash_ctx;
/*
* Windows CNG backend: Hash functions
*/
#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha1_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
SHA_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha1_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha1_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha1(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \
hash, SHA_DIGEST_LENGTH)
#define libssh2_sha256_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha256_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \
SHA256_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha256_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha256_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha256(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \
hash, SHA256_DIGEST_LENGTH)
#define libssh2_sha384_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha384_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \
SHA384_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha384_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha384_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \
hash, SHA384_DIGEST_LENGTH)
#define libssh2_sha512_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha512_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \
SHA512_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha512_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha512_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha512(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \
hash, SHA512_DIGEST_LENGTH)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx _libssh2_wincng_hash_ctx
#define libssh2_md5_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
MD5_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_md5_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_md5_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#endif
/*
* Windows CNG backend: HMAC functions
*/
#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx
/*******************************************************************/
/*
* Windows CNG backend: Key Context structure
*/
typedef struct __libssh2_wincng_key_ctx {
BCRYPT_KEY_HANDLE hKey;
void *pbKeyObject;
DWORD cbKeyObject;
} _libssh2_wincng_key_ctx;
/*
* Windows CNG backend: RSA functions
*/
#define libssh2_rsa_ctx _libssh2_wincng_key_ctx
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len) \
_libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
_libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase)
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_wincng_rsa_free(rsactx)
/*
* Windows CNG backend: DSA functions
*/
#define libssh2_dsa_ctx _libssh2_wincng_key_ctx
#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len) \
_libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len)
#define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \
_libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase)
#define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \
_libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig)
#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \
_libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len)
#define _libssh2_dsa_free(dsactx) \
_libssh2_wincng_dsa_free(dsactx)
/*
* Windows CNG backend: ECDSA functions
*/
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = 0,
LIBSSH2_EC_CURVE_NISTP384 = 1,
LIBSSH2_EC_CURVE_NISTP521 = 2,
} libssh2_curve_type;
typedef struct __libssh2_wincng_ecdsa_ctx {
BCRYPT_KEY_HANDLE handle;
libssh2_curve_type curve;
} _libssh2_wincng_ecdsa_key;
#define libssh2_ecdsa_ctx _libssh2_wincng_ecdsa_key
#if LIBSSH2_ECDSA
#define _libssh2_ec_key _libssh2_wincng_ecdsa_key
#endif
void
_libssh2_wincng_ecdsa_free(libssh2_ecdsa_ctx* ctx);
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve) \
_libssh2_wincng_ecdh_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve)
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
_libssh2_wincng_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
_libssh2_wincng_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len)
#define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \
_libssh2_wincng_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
_libssh2_wincng_ecdsa_new_private(ctx, session, filename, passphrase)
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase)
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
_libssh2_wincng_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
#define _libssh2_ecdsa_get_curve_type(ctx) \
_libssh2_wincng_ecdsa_get_curve_type(ctx)
#define _libssh2_ecdsa_free(ecdsactx) \
_libssh2_wincng_ecdsa_free(ecdsactx)
/*
* Windows CNG backend: Key functions
*/
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
_libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw) \
_libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw) \
_libssh2_wincng_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw)
/*******************************************************************/
/*
* Windows CNG backend: Cipher Context structure
*/
struct _libssh2_wincng_cipher_ctx {
BCRYPT_KEY_HANDLE hKey;
unsigned char *pbKeyObject;
unsigned char *pbIV;
unsigned char *pbCtr;
ULONG dwKeyObject;
ULONG dwIV;
ULONG dwBlockLength;
ULONG dwCtrLength;
};
#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx
/*
* Windows CNG backend: Cipher Type structure
*/
struct _libssh2_wincng_cipher_type {
BCRYPT_ALG_HANDLE *phAlg;
ULONG dwKeyLength;
int useIV; /* TODO: Convert to bool when a C89 compatible bool type
is defined */
int ctrMode;
};
#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type
#define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 }
#define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 }
#define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 }
#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 }
#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 }
#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 }
#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 }
#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 }
#define _libssh2_cipher_chacha20 { &_libssh2_wincng.hAlgChacha20, 24, 1, 0 }
/*
* Windows CNG backend: Cipher functions
*/
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
_libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \
_libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen, fl)
#define _libssh2_cipher_dtor(ctx) \
_libssh2_wincng_cipher_dtor(ctx)
/*******************************************************************/
/*
* Windows CNG backend: BigNumber Context
*/
#define _libssh2_bn_ctx int /* not used */
#define _libssh2_bn_ctx_new() 0 /* not used */
#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */
/*******************************************************************/
/*
* Windows CNG backend: BigNumber structure
*/
struct _libssh2_wincng_bignum {
unsigned char *bignum;
ULONG length;
};
#define _libssh2_bn struct _libssh2_wincng_bignum
/*
* Windows CNG backend: BigNumber functions
*/
#define _libssh2_bn_init() \
_libssh2_wincng_bignum_init()
#define _libssh2_bn_init_from_bin() \
_libssh2_bn_init()
#define _libssh2_bn_set_word(bn, word) \
_libssh2_wincng_bignum_set_word(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \
_libssh2_wincng_bignum_from_bin(bn, (ULONG) len, bin)
#define _libssh2_bn_to_bin(bn, bin) \
_libssh2_wincng_bignum_to_bin(bn, bin)
#define _libssh2_bn_bytes(bn) bn->length
#define _libssh2_bn_bits(bn) \
_libssh2_wincng_bignum_bits(bn)
#define _libssh2_bn_free(bn) \
_libssh2_wincng_bignum_free(bn)
/*
* Windows CNG backend: Diffie-Hellman support
*/
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 4096
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
typedef struct {
/* holds our private and public key components */
BCRYPT_KEY_HANDLE dh_handle;
/* records the parsed out modulus and generator
* parameters that are shared with the peer */
BCRYPT_DH_PARAMETER_HEADER *dh_params;
/* records the parsed out private key component for
* fallback if the DH API raw KDF is not supported */
struct _libssh2_wincng_bignum *dh_privbn;
} _libssh2_dh_ctx;
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/
/*
* Windows CNG backend: forward declarations
*/
void _libssh2_wincng_init(void);
void _libssh2_wincng_free(void);
int _libssh2_wincng_random(void *buf, size_t len);
int
_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
BCRYPT_ALG_HANDLE hAlg, ULONG hashlen,
unsigned char *key, ULONG keylen);
int
_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx,
const void *data, ULONG datalen);
int
_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash);
int
_libssh2_wincng_hash(const unsigned char *data, ULONG datalen,
BCRYPT_ALG_HANDLE hAlg,
unsigned char *hash, ULONG hashlen);
void
_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa);
#if LIBSSH2_DSA
void
_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa);
#endif
void
_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx);
_libssh2_bn *
_libssh2_wincng_bignum_init(void);
int
_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, ULONG word);
ULONG
_libssh2_wincng_bignum_bits(const _libssh2_bn *bn);
int
_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, ULONG len,
const unsigned char *bin);
int
_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin);
void
_libssh2_wincng_bignum_free(_libssh2_bn *bn);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
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_WINCNG_H */