mirror of
https://github.com/tmate-io/tmate.git
synced 2025-01-20 21:08:35 +01:00
Update libssh
This commit is contained in:
parent
0783022d6d
commit
6e4adcc140
@ -1,7 +1,7 @@
|
||||
Author(s):
|
||||
Aris Adamantiadis <aris@0xbadc0de.be> (project initiator)
|
||||
|
||||
Andreas Schneider <mail@cynapses.org> (developer)
|
||||
Andreas Schneider <asn@cryptomilk.org> (developer)
|
||||
|
||||
Nick Zitzmann <seiryu (at) comcast (dot) net> (mostly client SFTP stuff)
|
||||
|
||||
|
@ -7,8 +7,8 @@ cmake_minimum_required(VERSION 2.6.0)
|
||||
set(APPLICATION_NAME ${PROJECT_NAME})
|
||||
|
||||
set(APPLICATION_VERSION_MAJOR "0")
|
||||
set(APPLICATION_VERSION_MINOR "5")
|
||||
set(APPLICATION_VERSION_PATCH "90")
|
||||
set(APPLICATION_VERSION_MINOR "7")
|
||||
set(APPLICATION_VERSION_PATCH "0")
|
||||
|
||||
set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
|
||||
|
||||
@ -39,10 +39,6 @@ include(CPackConfig.cmake)
|
||||
include(MacroEnsureOutOfSourceBuild)
|
||||
macro_ensure_out_of_source_build("${PROJECT_NAME} requires an out of source build. Please create a separate build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there.")
|
||||
|
||||
# add macros
|
||||
include(MacroAddPlugin)
|
||||
include(MacroCopyFile)
|
||||
|
||||
# search for libraries
|
||||
if (WITH_ZLIB)
|
||||
find_package(ZLIB REQUIRED)
|
||||
@ -101,18 +97,22 @@ install(
|
||||
)
|
||||
|
||||
# cmake config files
|
||||
configure_file(libssh-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake @ONLY)
|
||||
configure_file(libssh-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake @ONLY)
|
||||
set(LIBSSH_LIBRARY_NAME @CMAKE_SHARED_LIBRARY_PREFIX@ssh@CMAKE_SHARED_LIBRARY_SUFFIX@)
|
||||
set(LIBSSH_THREADS_LIBRARY_NAME @CMAKE_SHARED_LIBRARY_PREFIX@ssh@CMAKE_SHARED_LIBRARY_SUFFIX@)
|
||||
|
||||
configure_file(${PROJECT_NAME}-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake @ONLY)
|
||||
configure_file(${PROJECT_NAME}-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake @ONLY)
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/libssh-config-version.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_DIR}
|
||||
${CMAKE_INSTALL_DIR}/${PROJECT_NAME}
|
||||
COMPONENT
|
||||
devel
|
||||
)
|
||||
|
||||
|
||||
# in tree build settings
|
||||
configure_file(libssh-build-tree-settings.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/libssh-build-tree-settings.cmake @ONLY)
|
||||
|
||||
|
@ -19,7 +19,7 @@ set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSIO
|
||||
|
||||
### source generator
|
||||
set(CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;tags;cscope.*")
|
||||
set(CPACK_SOURCE_IGNORE_FILES "~$;[.]swp$;/[.]svn/;/[.]git/;.gitignore;/build/;/obj/;tags;cscope.*")
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
if (WIN32)
|
||||
|
@ -48,9 +48,11 @@ endif(CMAKE_COMPILER_IS_GNUCC AND NOT MINGW AND NOT OS2)
|
||||
# HEADER FILES
|
||||
check_include_file(argp.h HAVE_ARGP_H)
|
||||
check_include_file(pty.h HAVE_PTY_H)
|
||||
check_include_file(utmp.h HAVE_UTMP_H)
|
||||
check_include_file(termios.h HAVE_TERMIOS_H)
|
||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||
check_include_file(util.h HAVE_UTIL_H)
|
||||
check_include_file(libutil.h HAVE_LIBUTIL_H)
|
||||
|
||||
if (WIN32)
|
||||
check_include_files("winsock2.h;ws2tcpip.h;wspiapi.h" HAVE_WSPIAPI_H)
|
||||
@ -178,11 +180,9 @@ if (GCRYPT_FOUND)
|
||||
endif (GCRYPT_VERSION VERSION_GREATER "1.4.6")
|
||||
endif (GCRYPT_FOUND)
|
||||
|
||||
if (CMAKE_HAVE_THREADS_LIBRARY)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(HAVE_PTHREAD 1)
|
||||
endif (CMAKE_USE_PTHREADS_INIT)
|
||||
endif (CMAKE_HAVE_THREADS_LIBRARY)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set(HAVE_PTHREAD 1)
|
||||
endif (CMAKE_USE_PTHREADS_INIT)
|
||||
|
||||
# OPTIONS
|
||||
check_c_source_compiles("
|
||||
|
0
libssh/build/.gitkeep
Normal file
0
libssh/build/.gitkeep
Normal file
@ -1,7 +1,7 @@
|
||||
# - ADD_CHECK_TEST(test_name test_source linklib1 ... linklibN)
|
||||
|
||||
# Copyright (c) 2007 Daniel Gollub <dgollub@suse.de>
|
||||
# Copyright (c) 2007-2010 Andreas Schneider <asn@cynapses.org>
|
||||
# Copyright (c) 2007-2010 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
@ -25,3 +25,6 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
|
||||
)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# Create the compile command database for clang by default
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
@ -75,3 +75,10 @@ if (MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
||||
endif (MSVC)
|
||||
|
||||
# This removes this annoying warning
|
||||
# "warning: 'BN_CTX_free' is deprecated: first deprecated in OS X 10.7 [-Wdeprecated-declarations]"
|
||||
if (OSX)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-deprecated-declarations")
|
||||
endif (OSX)
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
# ARGP_LIBRARIES - Link these to use Argp
|
||||
# ARGP_DEFINITIONS - Compiler switches required for using Argp
|
||||
#
|
||||
# Copyright (c) 2010 Andreas Schneider <asn@cynapses.org>
|
||||
# Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
|
@ -6,7 +6,7 @@
|
||||
# NACL_LIBRARIES - Link these to use NaCl
|
||||
# NACL_DEFINITIONS - Compiler switches required for using NaCl
|
||||
#
|
||||
# Copyright (c) 2010 Andreas Schneider <asn@cynapses.org>
|
||||
# Copyright (c) 2010 Andreas Schneider <asn@cryptomilk.org>
|
||||
# Copyright (c) 2013 Aris Adamantiadis <aris@badcode.be>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
|
@ -1,21 +0,0 @@
|
||||
# - MACRO_ADD_COMPILE_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_COMPILE_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} COMPILE_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags ${_flags} ${ARGN})
|
||||
else (_flags)
|
||||
set(_flags ${ARGN})
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES COMPILE_FLAGS ${_flags})
|
||||
|
||||
endmacro (MACRO_ADD_COMPILE_FLAGS)
|
@ -1,20 +0,0 @@
|
||||
# - MACRO_ADD_LINK_FLAGS(target_name flag1 ... flagN)
|
||||
|
||||
# Copyright (c) 2006, Oswald Buddenhagen, <ossi@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
macro (MACRO_ADD_LINK_FLAGS _target)
|
||||
|
||||
get_target_property(_flags ${_target} LINK_FLAGS)
|
||||
if (_flags)
|
||||
set(_flags "${_flags} ${ARGN}")
|
||||
else (_flags)
|
||||
set(_flags "${ARGN}")
|
||||
endif (_flags)
|
||||
|
||||
set_target_properties(${_target} PROPERTIES LINK_FLAGS "${_flags}")
|
||||
|
||||
endmacro (MACRO_ADD_LINK_FLAGS)
|
@ -1,30 +0,0 @@
|
||||
# - MACRO_ADD_PLUGIN(name [WITH_PREFIX] file1 .. fileN)
|
||||
#
|
||||
# Create a plugin from the given source files.
|
||||
# If WITH_PREFIX is given, the resulting plugin will have the
|
||||
# prefix "lib", otherwise it won't.
|
||||
#
|
||||
# Copyright (c) 2006, Alexander Neundorf, <neundorf@kde.org>
|
||||
# Copyright (c) 2006, Laurent Montel, <montel@kde.org>
|
||||
# Copyright (c) 2006, Andreas Schneider, <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
macro (MACRO_ADD_PLUGIN _target_NAME _with_PREFIX)
|
||||
|
||||
if (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC)
|
||||
else (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
set(_first_SRC ${_with_PREFIX})
|
||||
endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
|
||||
|
||||
add_library(${_target_NAME} MODULE ${_first_SRC} ${ARGN})
|
||||
|
||||
if (_first_SRC)
|
||||
set_target_properties(${_target_NAME} PROPERTIES PREFIX "")
|
||||
endif (_first_SRC)
|
||||
|
||||
endmacro (MACRO_ADD_PLUGIN _name _sources)
|
||||
|
@ -1,33 +0,0 @@
|
||||
# - macro_copy_file(_src _dst)
|
||||
# Copies a file to ${_dst} only if ${_src} is different (newer) than ${_dst}
|
||||
#
|
||||
# Example:
|
||||
# macro_copy_file(${CMAKE_CURRENT_SOURCE_DIR}/icon.png ${CMAKE_CURRENT_BINARY_DIR}/.)
|
||||
# Copies file icon.png to ${CMAKE_CURRENT_BINARY_DIR} directory
|
||||
#
|
||||
# Copyright (c) 2006-2007 Wengo
|
||||
# Copyright (c) 2006-2008 Andreas Schneider <mail@cynapses.org>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING file.
|
||||
|
||||
|
||||
macro (macro_copy_file _src _dst)
|
||||
# Removes all path containing .svn or CVS or CMakeLists.txt during the copy
|
||||
if (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
|
||||
if (CMAKE_VERBOSE_MAKEFILE)
|
||||
message(STATUS "Copy file from ${_src} to ${_dst}")
|
||||
endif (CMAKE_VERBOSE_MAKEFILE)
|
||||
|
||||
# Creates directory if necessary
|
||||
get_filename_component(_path ${_dst} PATH)
|
||||
file(MAKE_DIRECTORY ${_path})
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND} -E copy_if_different ${_src} ${_dst}
|
||||
OUTPUT_QUIET
|
||||
)
|
||||
endif (NOT ${_src} MATCHES ".*\\.svn|CVS|CMakeLists\\.txt.*")
|
||||
endmacro (macro_copy_file)
|
@ -2,10 +2,18 @@
|
||||
#
|
||||
# Adds a doxygen target that runs doxygen to generate the html
|
||||
# and optionally the LaTeX API documentation.
|
||||
# The doxygen target is added to the doc target as dependency.
|
||||
# The doxygen target is added to the doc target as a dependency.
|
||||
# i.e.: the API documentation is built with:
|
||||
# make doc
|
||||
#
|
||||
# USAGE: GLOBAL INSTALL
|
||||
#
|
||||
# Install it with:
|
||||
# cmake ./ && sudo make install
|
||||
# Add the following to the CMakeLists.txt of your project:
|
||||
# include(UseDoxygen OPTIONAL)
|
||||
# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and edit it.
|
||||
#
|
||||
# USAGE: INCLUDE IN PROJECT
|
||||
#
|
||||
# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
@ -13,88 +21,120 @@
|
||||
# Add the Doxyfile.in and UseDoxygen.cmake files to the projects source directory.
|
||||
#
|
||||
#
|
||||
# CONFIGURATION
|
||||
#
|
||||
# To configure Doxygen you can edit Doxyfile.in and set some variables in cmake.
|
||||
# Variables you may define are:
|
||||
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored. Defaults to "doc".
|
||||
#
|
||||
# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is stored. Defaults to "latex".
|
||||
#
|
||||
# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is stored. Defaults to "html".
|
||||
# DOXYFILE_SOURCE_DIR - Path where the Doxygen input files are.
|
||||
# Defaults to the current source directory.
|
||||
# DOXYFILE_EXTRA_SOURCES - Additional source diretories/files for Doxygen to scan.
|
||||
# The Paths should be in double quotes and separated by space. e.g.:
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/foo.c" "${CMAKE_CURRENT_BINARY_DIR}/bar/"
|
||||
#
|
||||
# DOXYFILE_OUTPUT_DIR - Path where the Doxygen output is stored.
|
||||
# Defaults to "${CMAKE_CURRENT_BINARY_DIR}/doc".
|
||||
#
|
||||
# DOXYFILE_LATEX - ON/OFF; Set to "ON" if you want the LaTeX documentation
|
||||
# to be built.
|
||||
# DOXYFILE_LATEX_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
|
||||
# the Doxygen LaTeX output is stored. Defaults to "latex".
|
||||
#
|
||||
# DOXYFILE_HTML_DIR - Directory relative to DOXYFILE_OUTPUT_DIR where
|
||||
# the Doxygen html output is stored. Defaults to "html".
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright (c) 2009-2010 Tobias Rautenkranz <tobias@rautenkranz.ch>
|
||||
# Copyright (c) 2010 Andreas Schneider <mail@cynapses.org>
|
||||
# Copyright (c) 2009, 2010, 2011 Tobias Rautenkranz <tobias@rautenkranz.ch>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the New
|
||||
# BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
#
|
||||
|
||||
macro(usedoxygen_set_default name value)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${value}")
|
||||
endif()
|
||||
macro(usedoxygen_set_default name value type docstring)
|
||||
if(NOT DEFINED "${name}")
|
||||
set("${name}" "${value}" CACHE "${type}" "${docstring}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
find_package(Doxygen)
|
||||
|
||||
if(DOXYGEN_FOUND)
|
||||
find_file(DOXYFILE_IN
|
||||
NAMES
|
||||
doxy.config.in
|
||||
PATHS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_ROOT}/Modules/
|
||||
NO_DEFAULT_PATH)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
|
||||
find_file(DOXYFILE_IN "Doxyfile.in"
|
||||
PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/"
|
||||
NO_DEFAULT_PATH
|
||||
DOC "Path to the doxygen configuration template file")
|
||||
set(DOXYFILE "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
|
||||
endif()
|
||||
|
||||
if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
|
||||
add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
|
||||
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc"
|
||||
PATH "Doxygen output directory")
|
||||
usedoxygen_set_default(DOXYFILE_HTML_DIR "html"
|
||||
STRING "Doxygen HTML output directory")
|
||||
usedoxygen_set_default(DOXYFILE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
PATH "Input files source directory")
|
||||
usedoxygen_set_default(DOXYFILE_EXTRA_SOURCE_DIRS ""
|
||||
STRING "Additional source files/directories separated by space")
|
||||
set(DOXYFILE_SOURCE_DIRS "\"${DOXYFILE_SOURCE_DIR}\" ${DOXYFILE_EXTRA_SOURCES}")
|
||||
|
||||
usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
usedoxygen_set_default(DOXYFILE_HTML_DIR "html")
|
||||
usedoxygen_set_default(DOXYFILE_LATEX YES BOOL "Generate LaTeX API documentation" OFF)
|
||||
usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex" STRING "LaTex output directory")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
|
||||
mark_as_advanced(DOXYFILE_OUTPUT_DIR DOXYFILE_HTML_DIR DOXYFILE_LATEX_DIR
|
||||
DOXYFILE_SOURCE_DIR DOXYFILE_EXTRA_SOURCE_DIRS DOXYFILE_IN)
|
||||
|
||||
set(DOXYFILE_LATEX FALSE)
|
||||
set(DOXYFILE_PDFLATEX FALSE)
|
||||
set(DOXYFILE_DOT FALSE)
|
||||
|
||||
#find_package(LATEX)
|
||||
#if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
|
||||
# set(DOXYFILE_LATEX TRUE)
|
||||
# usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex")
|
||||
#
|
||||
# set_property(DIRECTORY APPEND PROPERTY
|
||||
# ADDITIONAL_MAKE_CLEAN_FILES
|
||||
# "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
#
|
||||
# if(PDFLATEX_COMPILER)
|
||||
# set(DOXYFILE_PDFLATEX TRUE)
|
||||
# endif()
|
||||
# if(DOXYGEN_DOT_EXECUTABLE)
|
||||
# set(DOXYFILE_DOT TRUE)
|
||||
# endif()
|
||||
#
|
||||
# add_custom_command(TARGET doxygen
|
||||
# POST_BUILD
|
||||
# COMMAND ${CMAKE_MAKE_PROGRAM}
|
||||
# WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
#endif()
|
||||
set_property(DIRECTORY
|
||||
APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
|
||||
|
||||
configure_file(${DOXYFILE_IN} ${CMAKE_CURRENT_BINARY_DIR}/doxy.config ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doxy.trac.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac ESCAPE_QUOTES IMMEDIATE @ONLY)
|
||||
add_custom_target(doxygen-trac ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxy.trac)
|
||||
endif()
|
||||
add_custom_target(doxygen
|
||||
COMMAND "${DOXYGEN_EXECUTABLE}"
|
||||
"${DOXYFILE}"
|
||||
COMMENT "Writing documentation to ${DOXYFILE_OUTPUT_DIR}..."
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
get_target_property(DOC_TARGET doc TYPE)
|
||||
if(NOT DOC_TARGET)
|
||||
add_custom_target(doc)
|
||||
endif()
|
||||
set(DOXYFILE_DOT "NO")
|
||||
if(DOXYGEN_DOT_EXECUTABLE)
|
||||
set(DOXYFILE_DOT "YES")
|
||||
endif()
|
||||
|
||||
add_dependencies(doc doxygen)
|
||||
## LaTeX
|
||||
set(DOXYFILE_PDFLATEX "NO")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY
|
||||
ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
|
||||
if(DOXYFILE_LATEX STREQUAL "ON")
|
||||
set(DOXYFILE_GENERATE_LATEX "YES")
|
||||
find_package(LATEX)
|
||||
find_program(DOXYFILE_MAKE make)
|
||||
mark_as_advanced(DOXYFILE_MAKE)
|
||||
if(LATEX_COMPILER AND MAKEINDEX_COMPILER AND DOXYFILE_MAKE)
|
||||
if(PDFLATEX_COMPILER)
|
||||
set(DOXYFILE_PDFLATEX "YES")
|
||||
endif()
|
||||
|
||||
add_custom_command(TARGET doxygen
|
||||
POST_BUILD
|
||||
COMMAND "${DOXYFILE_MAKE}"
|
||||
COMMENT "Running LaTeX for Doxygen documentation in ${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}..."
|
||||
WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
|
||||
else()
|
||||
set(DOXYGEN_LATEX "NO")
|
||||
endif()
|
||||
else()
|
||||
set(DOXYFILE_GENERATE_LATEX "NO")
|
||||
endif()
|
||||
|
||||
|
||||
configure_file("${DOXYFILE_IN}" "${DOXYFILE}" @ONLY)
|
||||
|
||||
add_custom_target(doc)
|
||||
add_dependencies(doc doxygen)
|
||||
endif()
|
||||
|
@ -20,9 +20,15 @@
|
||||
/* Define to 1 if you have the <pty.h> header file. */
|
||||
#cmakedefine HAVE_PTY_H 1
|
||||
|
||||
/* Define to 1 if you have the <utmp.h> header file. */
|
||||
#cmakedefine HAVE_UTMP_H 1
|
||||
|
||||
/* Define to 1 if you have the <util.h> header file. */
|
||||
#cmakedefine HAVE_UTIL_H 1
|
||||
|
||||
/* Define to 1 if you have the <libutil.h> header file. */
|
||||
#cmakedefine HAVE_LIBUTIL_H 1
|
||||
|
||||
/* Define to 1 if you have the <termios.h> header file. */
|
||||
#cmakedefine HAVE_TERMIOS_H 1
|
||||
|
||||
|
@ -721,7 +721,7 @@ EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS = */.git/* \
|
||||
*/.svn/* \
|
||||
*/cmake/* \
|
||||
*/build/*
|
||||
*/obj/*
|
||||
|
||||
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
|
||||
# (namespaces, classes, functions, etc.) that should be excluded from the
|
@ -285,7 +285,7 @@ int authenticate_kbdint(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = ssh_userauth_none(session, NULL, NULL);
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
return rc;
|
||||
}
|
||||
@endcode
|
||||
@ -304,7 +304,7 @@ int test_several_auth_methods(ssh_session session)
|
||||
{
|
||||
int method, rc;
|
||||
|
||||
rc = ssh_userauth_none(session, NULL, NULL);
|
||||
rc = ssh_userauth_none(session, NULL);
|
||||
if (rc != SSH_AUTH_SUCCESS) {
|
||||
return rc;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -144,10 +144,10 @@ or whatever use you have for it.
|
||||
|
||||
@subsection libssh_reverse Doing reverse port forwarding with libssh
|
||||
|
||||
To do reverse port forwarding, call ssh_forward_listen(),
|
||||
then ssh_forward_accept().
|
||||
To do reverse port forwarding, call ssh_channel_listen_forward(),
|
||||
then ssh_channel_accept_forward().
|
||||
|
||||
When you call ssh_forward_listen(), you can let the remote server
|
||||
When you call ssh_channel_listen_forward(), you can let the remote server
|
||||
chose the non-priviledged port it should listen to. Otherwise, you can chose
|
||||
your own priviledged or non-priviledged port. Beware that you should have
|
||||
administrative priviledges on the remote server to open a priviledged port
|
||||
@ -164,6 +164,7 @@ int web_server(ssh_session session)
|
||||
ssh_channel channel;
|
||||
char buffer[256];
|
||||
int nbytes, nwritten;
|
||||
int port = 0;
|
||||
char *helloworld = ""
|
||||
"HTTP/1.1 200 OK\n"
|
||||
"Content-Type: text/html\n"
|
||||
@ -178,7 +179,7 @@ int web_server(ssh_session session)
|
||||
" </body>\n"
|
||||
"</html>\n";
|
||||
|
||||
rc = ssh_forward_listen(session, NULL, 8080, NULL);
|
||||
rc = ssh_channel_listen_forward(session, NULL, 8080, NULL);
|
||||
if (rc != SSH_OK)
|
||||
{
|
||||
fprintf(stderr, "Error opening remote port: %s\n",
|
||||
@ -186,7 +187,7 @@ int web_server(ssh_session session)
|
||||
return rc;
|
||||
}
|
||||
|
||||
channel = ssh_forward_accept(session, 60000);
|
||||
channel = ssh_channel_accept_forward(session, 60000, &port);
|
||||
if (channel == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error waiting for incoming connection: %s\n",
|
||||
|
@ -61,5 +61,6 @@ implement the following methods :
|
||||
- mutex_destroy
|
||||
- thread_id
|
||||
|
||||
libgcrypt 1.6 and bigger backend does not support custom callback. Using anything else than pthreads (ssh_threads_get_pthread()) here will fail.
|
||||
Good luck !
|
||||
*/
|
||||
|
@ -25,13 +25,6 @@ if (UNIX AND NOT WIN32)
|
||||
add_executable(sshnetcat sshnetcat.c ${examples_SRCS})
|
||||
target_link_libraries(sshnetcat ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
if (WITH_SERVER)
|
||||
if (HAVE_LIBUTIL)
|
||||
add_executable(samplesshd-tty samplesshd-tty.c)
|
||||
target_link_libraries(samplesshd-tty ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util)
|
||||
endif (HAVE_LIBUTIL)
|
||||
endif (WITH_SERVER)
|
||||
|
||||
if (WITH_SFTP)
|
||||
add_executable(samplesftp samplesftp.c ${examples_SRCS})
|
||||
target_link_libraries(samplesftp ${LIBSSH_SHARED_LIBRARY})
|
||||
@ -41,8 +34,10 @@ if (UNIX AND NOT WIN32)
|
||||
target_link_libraries(samplessh ${LIBSSH_SHARED_LIBRARY})
|
||||
|
||||
if (WITH_SERVER)
|
||||
add_executable(samplesshd samplesshd.c)
|
||||
target_link_libraries(samplesshd ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES})
|
||||
if (HAVE_LIBUTIL)
|
||||
add_executable(ssh_server_fork ssh_server_fork.c)
|
||||
target_link_libraries(ssh_server_fork ${LIBSSH_SHARED_LIBRARY} ${ARGP_LIBRARIES} util)
|
||||
endif (HAVE_LIBUTIL)
|
||||
|
||||
if (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
add_executable(samplesshd-cb samplesshd-cb.c)
|
||||
|
@ -116,7 +116,7 @@ int authenticate_console(ssh_session session){
|
||||
return rc;
|
||||
}
|
||||
|
||||
method = ssh_auth_list(session);
|
||||
method = ssh_userauth_list(session, NULL);
|
||||
while (rc != SSH_AUTH_SUCCESS) {
|
||||
if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
|
||||
rc = ssh_userauth_gssapi(session);
|
||||
@ -129,10 +129,10 @@ int authenticate_console(ssh_session session){
|
||||
}
|
||||
// Try to authenticate with public key first
|
||||
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
|
||||
rc = ssh_userauth_autopubkey(session, NULL);
|
||||
rc = ssh_userauth_publickey_auto(session, NULL, NULL);
|
||||
if (rc == SSH_AUTH_ERROR) {
|
||||
error(session);
|
||||
return rc;
|
||||
error(session);
|
||||
return rc;
|
||||
} else if (rc == SSH_AUTH_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
@ -1,466 +0,0 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2003-2011 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
#include <libssh/callbacks.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#ifdef HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#define SSHD_USER "libssh"
|
||||
#define SSHD_PASSWORD "libssh"
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
const char *pcap_file="debug.server.pcap";
|
||||
ssh_pcap_file pcap;
|
||||
|
||||
static void set_pcap(ssh_session session){
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
static void cleanup_pcap(){
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int auth_password(const char *user, const char *password){
|
||||
if(strcmp(user, SSHD_USER))
|
||||
return 0;
|
||||
if(strcmp(password, SSHD_PASSWORD))
|
||||
return 0;
|
||||
return 1; // authenticated
|
||||
}
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
static int port = 22;
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the host key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure.
|
||||
*/
|
||||
ssh_bind sshbind = state->input;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
port = atoi(arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
static int authenticate(ssh_session session) {
|
||||
ssh_message message;
|
||||
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(!message)
|
||||
break;
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_AUTH:
|
||||
switch(ssh_message_subtype(message)){
|
||||
case SSH_AUTH_METHOD_PASSWORD:
|
||||
printf("User %s wants to auth with pass %s\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message));
|
||||
if(auth_password(ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message))){
|
||||
ssh_message_auth_reply_success(message,0);
|
||||
ssh_message_free(message);
|
||||
return 1;
|
||||
}
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
// not authenticated, send default message
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
|
||||
case SSH_AUTH_METHOD_NONE:
|
||||
default:
|
||||
printf("User %s wants to auth with unknown auth %d\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_subtype(message));
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_message_auth_set_methods(message,
|
||||
SSH_AUTH_METHOD_PASSWORD |
|
||||
SSH_AUTH_METHOD_INTERACTIVE);
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int copy_fd_to_chan(socket_t fd, int revents, void *userdata) {
|
||||
ssh_channel chan = (ssh_channel)userdata;
|
||||
char buf[2048];
|
||||
int sz = 0;
|
||||
|
||||
if(!chan) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
if(revents & POLLIN) {
|
||||
sz = read(fd, buf, 2048);
|
||||
if(sz > 0) {
|
||||
ssh_channel_write(chan, buf, sz);
|
||||
}
|
||||
}
|
||||
if(revents & POLLHUP) {
|
||||
ssh_channel_close(chan);
|
||||
sz = -1;
|
||||
}
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int copy_chan_to_fd(ssh_session session,
|
||||
ssh_channel channel,
|
||||
void *data,
|
||||
uint32_t len,
|
||||
int is_stderr,
|
||||
void *userdata) {
|
||||
int fd = *(int*)userdata;
|
||||
int sz;
|
||||
(void)session;
|
||||
(void)channel;
|
||||
(void)is_stderr;
|
||||
|
||||
sz = write(fd, data, len);
|
||||
return sz;
|
||||
}
|
||||
|
||||
static void chan_close(ssh_session session, ssh_channel channel, void *userdata) {
|
||||
int fd = *(int*)userdata;
|
||||
(void)session;
|
||||
(void)channel;
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
struct ssh_channel_callbacks_struct cb = {
|
||||
.channel_data_function = copy_chan_to_fd,
|
||||
.channel_eof_function = chan_close,
|
||||
.channel_close_function = chan_close,
|
||||
.userdata = NULL
|
||||
};
|
||||
|
||||
static int main_loop(ssh_channel chan) {
|
||||
ssh_session session = ssh_channel_get_session(chan);
|
||||
socket_t fd;
|
||||
struct termios *term = NULL;
|
||||
struct winsize *win = NULL;
|
||||
pid_t childpid;
|
||||
ssh_event event;
|
||||
short events;
|
||||
int rc;
|
||||
|
||||
childpid = forkpty(&fd, NULL, term, win);
|
||||
if(childpid == 0) {
|
||||
execl("/bin/bash", "/bin/bash", (char *)NULL);
|
||||
abort();
|
||||
}
|
||||
|
||||
cb.userdata = &fd;
|
||||
ssh_callbacks_init(&cb);
|
||||
ssh_set_channel_callbacks(chan, &cb);
|
||||
|
||||
events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
|
||||
|
||||
event = ssh_event_new();
|
||||
if(event == NULL) {
|
||||
printf("Couldn't get a event\n");
|
||||
return -1;
|
||||
}
|
||||
if(ssh_event_add_fd(event, fd, events, copy_fd_to_chan, chan) != SSH_OK) {
|
||||
printf("Couldn't add an fd to the event\n");
|
||||
ssh_event_free(event);
|
||||
return -1;
|
||||
}
|
||||
if(ssh_event_add_session(event, session) != SSH_OK) {
|
||||
printf("Couldn't add the session to the event\n");
|
||||
ssh_event_remove_fd(event, fd);
|
||||
ssh_event_free(event);
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
rc = ssh_event_dopoll(event, 1000);
|
||||
if (rc == SSH_ERROR){
|
||||
fprintf(stderr, "Error : %s\n", ssh_get_error(session));
|
||||
ssh_event_free(event);
|
||||
ssh_disconnect(session);
|
||||
return -1;
|
||||
}
|
||||
} while(!ssh_channel_is_closed(chan));
|
||||
|
||||
ssh_event_remove_fd(event, fd);
|
||||
|
||||
ssh_event_remove_session(event, session);
|
||||
|
||||
ssh_event_free(event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
ssh_message message;
|
||||
ssh_channel chan=0;
|
||||
int auth=0;
|
||||
int shell=0;
|
||||
int r;
|
||||
|
||||
sshbind=ssh_bind_new();
|
||||
session=ssh_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
|
||||
KEYS_FOLDER "ssh_host_dsa_key");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
|
||||
KEYS_FOLDER "ssh_host_rsa_key");
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
/*
|
||||
* Parse our arguments; every option seen by parse_opt will
|
||||
* be reflected in arguments.
|
||||
*/
|
||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
#endif
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
|
||||
if(ssh_bind_listen(sshbind)<0){
|
||||
printf("Error listening to socket: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
printf("Started sample libssh sshd on port %d\n", port);
|
||||
printf("You can login as the user %s with the password %s\n", SSHD_USER,
|
||||
SSHD_PASSWORD);
|
||||
r = ssh_bind_accept(sshbind, session);
|
||||
if(r==SSH_ERROR){
|
||||
printf("Error accepting a connection: %s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* proceed to authentication */
|
||||
auth = authenticate(session);
|
||||
if(!auth){
|
||||
printf("Authentication error: %s\n", ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* wait for a channel session */
|
||||
do {
|
||||
message = ssh_message_get(session);
|
||||
if(message){
|
||||
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL_OPEN &&
|
||||
ssh_message_subtype(message) == SSH_CHANNEL_SESSION) {
|
||||
chan = ssh_message_channel_request_open_reply_accept(message);
|
||||
ssh_message_free(message);
|
||||
break;
|
||||
} else {
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(!chan);
|
||||
|
||||
if(!chan) {
|
||||
printf("Error: cleint did not ask for a channel session (%s)\n",
|
||||
ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* wait for a shell */
|
||||
do {
|
||||
message = ssh_message_get(session);
|
||||
if(message != NULL) {
|
||||
if(ssh_message_type(message) == SSH_REQUEST_CHANNEL) {
|
||||
if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_SHELL) {
|
||||
shell = 1;
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
ssh_message_free(message);
|
||||
break;
|
||||
} else if(ssh_message_subtype(message) == SSH_CHANNEL_REQUEST_PTY) {
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
ssh_message_free(message);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ssh_message_reply_default(message);
|
||||
ssh_message_free(message);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(!shell);
|
||||
|
||||
if(!shell) {
|
||||
printf("Error: No shell requested (%s)\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("it works !\n");
|
||||
|
||||
main_loop(chan);
|
||||
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,314 +0,0 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2003-2009 Aris Adamantiadis
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action. It's not a reference on how terminal
|
||||
clients must be made or how a client should react.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libssh/libssh.h>
|
||||
#include <libssh/server.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PCAP
|
||||
static const char *pcap_file="debug.server.pcap";
|
||||
static ssh_pcap_file pcap;
|
||||
|
||||
static void set_pcap(ssh_session session) {
|
||||
if(!pcap_file)
|
||||
return;
|
||||
pcap=ssh_pcap_file_new();
|
||||
if(ssh_pcap_file_open(pcap,pcap_file) == SSH_ERROR){
|
||||
printf("Error opening pcap file\n");
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
return;
|
||||
}
|
||||
ssh_set_pcap_file(session,pcap);
|
||||
}
|
||||
|
||||
static void cleanup_pcap(void) {
|
||||
ssh_pcap_file_free(pcap);
|
||||
pcap=NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int auth_password(const char *user, const char *password){
|
||||
if(strcmp(user,"aris"))
|
||||
return 0;
|
||||
if(strcmp(password,"lala"))
|
||||
return 0;
|
||||
return 1; // authenticated
|
||||
}
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the host key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure.
|
||||
*/
|
||||
ssh_bind sshbind = state->input;
|
||||
|
||||
switch (key) {
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "3");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
int main(int argc, char **argv){
|
||||
ssh_session session;
|
||||
ssh_bind sshbind;
|
||||
ssh_message message;
|
||||
ssh_channel chan=0;
|
||||
char buf[2048];
|
||||
int auth=0;
|
||||
int sftp=0;
|
||||
int i;
|
||||
int r;
|
||||
|
||||
sshbind=ssh_bind_new();
|
||||
session=ssh_new();
|
||||
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, KEYS_FOLDER "ssh_host_dsa_key");
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, KEYS_FOLDER "ssh_host_rsa_key");
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
/*
|
||||
* Parse our arguments; every option seen by parse_opt will
|
||||
* be reflected in arguments.
|
||||
*/
|
||||
argp_parse (&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
#endif
|
||||
#ifdef WITH_PCAP
|
||||
set_pcap(session);
|
||||
#endif
|
||||
|
||||
if(ssh_bind_listen(sshbind)<0){
|
||||
printf("Error listening to socket: %s\n",ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
r=ssh_bind_accept(sshbind,session);
|
||||
if(r==SSH_ERROR){
|
||||
printf("error accepting a connection : %s\n",ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
if (ssh_handle_key_exchange(session)) {
|
||||
printf("ssh_handle_key_exchange: %s\n", ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(!message)
|
||||
break;
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_AUTH:
|
||||
switch(ssh_message_subtype(message)){
|
||||
case SSH_AUTH_METHOD_PASSWORD:
|
||||
printf("User %s wants to auth with pass %s\n",
|
||||
ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message));
|
||||
if(auth_password(ssh_message_auth_user(message),
|
||||
ssh_message_auth_password(message))){
|
||||
auth=1;
|
||||
ssh_message_auth_reply_success(message,0);
|
||||
break;
|
||||
}
|
||||
// not authenticated, send default message
|
||||
case SSH_AUTH_METHOD_NONE:
|
||||
default:
|
||||
ssh_message_auth_set_methods(message,SSH_AUTH_METHOD_PASSWORD);
|
||||
ssh_message_reply_default(message);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (!auth);
|
||||
if(!auth){
|
||||
printf("auth error: %s\n",ssh_get_error(session));
|
||||
ssh_disconnect(session);
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(message){
|
||||
switch(ssh_message_type(message)){
|
||||
case SSH_REQUEST_CHANNEL_OPEN:
|
||||
if(ssh_message_subtype(message)==SSH_CHANNEL_SESSION){
|
||||
chan=ssh_message_channel_request_open_reply_accept(message);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
}
|
||||
} while(message && !chan);
|
||||
if(!chan){
|
||||
printf("error : %s\n",ssh_get_error(session));
|
||||
ssh_finalize();
|
||||
return 1;
|
||||
}
|
||||
do {
|
||||
message=ssh_message_get(session);
|
||||
if(message && ssh_message_type(message)==SSH_REQUEST_CHANNEL &&
|
||||
(ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_SHELL ||
|
||||
ssh_message_subtype(message)==SSH_CHANNEL_REQUEST_PTY)) {
|
||||
// if(!strcmp(ssh_message_channel_request_subsystem(message),"sftp")){
|
||||
sftp=1;
|
||||
ssh_message_channel_request_reply_success(message);
|
||||
break;
|
||||
// }
|
||||
}
|
||||
if(!sftp){
|
||||
ssh_message_reply_default(message);
|
||||
}
|
||||
ssh_message_free(message);
|
||||
} while (message && !sftp);
|
||||
if(!sftp){
|
||||
printf("error : %s\n",ssh_get_error(session));
|
||||
return 1;
|
||||
}
|
||||
printf("it works !\n");
|
||||
do{
|
||||
i=ssh_channel_read(chan,buf, 2048, 0);
|
||||
if(i>0) {
|
||||
ssh_channel_write(chan, buf, i);
|
||||
if (write(1,buf,i) < 0) {
|
||||
printf("error writing to buffer\n");
|
||||
return 1;
|
||||
}
|
||||
if (buf[0] == '\x0d') {
|
||||
if (write(1, "\n", 1) < 0) {
|
||||
printf("error writing to buffer\n");
|
||||
return 1;
|
||||
}
|
||||
ssh_channel_write(chan, "\n", 1);
|
||||
}
|
||||
}
|
||||
} while (i>0);
|
||||
ssh_disconnect(session);
|
||||
ssh_bind_free(sshbind);
|
||||
#ifdef WITH_PCAP
|
||||
cleanup_pcap();
|
||||
#endif
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
||||
|
697
libssh/examples/ssh_server_fork.c
Normal file
697
libssh/examples/ssh_server_fork.c
Normal file
@ -0,0 +1,697 @@
|
||||
/* This is a sample implementation of a libssh based SSH server */
|
||||
/*
|
||||
Copyright 2014 Audrius Butkevicius
|
||||
|
||||
This file is part of the SSH Library
|
||||
|
||||
You are free to copy this file, modify it in any way, consider it being public
|
||||
domain. This does not apply to the rest of the library though, but it is
|
||||
allowed to cut-and-paste working code from this file to any license of
|
||||
program.
|
||||
The goal is to show the API in action.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <libssh/callbacks.h>
|
||||
#include <libssh/poll.h>
|
||||
#include <libssh/server.h>
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
#include <argp.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#ifdef HAVE_PTY_H
|
||||
#include <pty.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UTMP_H
|
||||
#include <utmp.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef KEYS_FOLDER
|
||||
#ifdef _WIN32
|
||||
#define KEYS_FOLDER
|
||||
#else
|
||||
#define KEYS_FOLDER "/etc/ssh/"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define USER "myuser"
|
||||
#define PASS "mypassword"
|
||||
#define BUF_SIZE 1048576
|
||||
#define SESSION_END (SSH_CLOSED | SSH_CLOSED_ERROR)
|
||||
#define SFTP_SERVER_PATH "/usr/lib/sftp-server"
|
||||
|
||||
static void set_default_keys(ssh_bind sshbind,
|
||||
int rsa_already_set,
|
||||
int dsa_already_set,
|
||||
int ecdsa_already_set) {
|
||||
if (!rsa_already_set) {
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY,
|
||||
KEYS_FOLDER "ssh_host_rsa_key");
|
||||
}
|
||||
if (!dsa_already_set) {
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY,
|
||||
KEYS_FOLDER "ssh_host_dsa_key");
|
||||
}
|
||||
if (!ecdsa_already_set) {
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY,
|
||||
KEYS_FOLDER "ssh_host_ecdsa_key");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
const char *argp_program_version = "libssh server example "
|
||||
SSH_STRINGIFY(LIBSSH_VERSION);
|
||||
const char *argp_program_bug_address = "<libssh@libssh.org>";
|
||||
|
||||
/* Program documentation. */
|
||||
static char doc[] = "libssh -- a Secure Shell protocol implementation";
|
||||
|
||||
/* A description of the arguments we accept. */
|
||||
static char args_doc[] = "BINDADDR";
|
||||
|
||||
/* The options we understand. */
|
||||
static struct argp_option options[] = {
|
||||
{
|
||||
.name = "port",
|
||||
.key = 'p',
|
||||
.arg = "PORT",
|
||||
.flags = 0,
|
||||
.doc = "Set the port to bind.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "hostkey",
|
||||
.key = 'k',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set a host key. Can be used multiple times. "
|
||||
"Implies no default keys.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "dsakey",
|
||||
.key = 'd',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the dsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "rsakey",
|
||||
.key = 'r',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the rsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "ecdsakey",
|
||||
.key = 'e',
|
||||
.arg = "FILE",
|
||||
.flags = 0,
|
||||
.doc = "Set the ecdsa key.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "no-default-keys",
|
||||
.key = 'n',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Do not set default key locations.",
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.key = 'v',
|
||||
.arg = NULL,
|
||||
.flags = 0,
|
||||
.doc = "Get verbose output.",
|
||||
.group = 0
|
||||
},
|
||||
{NULL, 0, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Parse a single option. */
|
||||
static error_t parse_opt (int key, char *arg, struct argp_state *state) {
|
||||
/* Get the input argument from argp_parse, which we
|
||||
* know is a pointer to our arguments structure. */
|
||||
ssh_bind sshbind = state->input;
|
||||
static int no_default_keys = 0;
|
||||
static int rsa_already_set = 0, dsa_already_set = 0, ecdsa_already_set = 0;
|
||||
|
||||
switch (key) {
|
||||
case 'n':
|
||||
no_default_keys = 1;
|
||||
break;
|
||||
case 'p':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDPORT_STR, arg);
|
||||
break;
|
||||
case 'd':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_DSAKEY, arg);
|
||||
dsa_already_set = 1;
|
||||
break;
|
||||
case 'k':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_HOSTKEY, arg);
|
||||
/* We can't track the types of keys being added with this
|
||||
option, so let's ensure we keep the keys we're adding
|
||||
by just not setting the default keys */
|
||||
no_default_keys = 1;
|
||||
break;
|
||||
case 'r':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_RSAKEY, arg);
|
||||
rsa_already_set = 1;
|
||||
break;
|
||||
case 'e':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_ECDSAKEY, arg);
|
||||
ecdsa_already_set = 1;
|
||||
break;
|
||||
case 'v':
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
||||
"3");
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num >= 1) {
|
||||
/* Too many arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
ssh_bind_options_set(sshbind, SSH_BIND_OPTIONS_BINDADDR, arg);
|
||||
break;
|
||||
case ARGP_KEY_END:
|
||||
if (state->arg_num < 1) {
|
||||
/* Not enough arguments. */
|
||||
argp_usage (state);
|
||||
}
|
||||
|
||||
if (!no_default_keys) {
|
||||
set_default_keys(sshbind,
|
||||
rsa_already_set,
|
||||
dsa_already_set,
|
||||
ecdsa_already_set);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
return ARGP_ERR_UNKNOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Our argp parser. */
|
||||
static struct argp argp = {options, parse_opt, args_doc, doc, NULL, NULL, NULL};
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
/* A userdata struct for channel. */
|
||||
struct channel_data_struct {
|
||||
/* pid of the child process the channel will spawn. */
|
||||
pid_t pid;
|
||||
/* For PTY allocation */
|
||||
socket_t pty_master;
|
||||
socket_t pty_slave;
|
||||
/* For communication with the child process. */
|
||||
socket_t stdin;
|
||||
socket_t stdout;
|
||||
/* Only used for subsystem and exec requests. */
|
||||
socket_t stderr;
|
||||
/* Event which is used to poll the above descriptors. */
|
||||
ssh_event event;
|
||||
/* Terminal size struct. */
|
||||
struct winsize *winsize;
|
||||
};
|
||||
|
||||
/* A userdata struct for session. */
|
||||
struct session_data_struct {
|
||||
/* Pointer to the channel the session will allocate. */
|
||||
ssh_channel channel;
|
||||
int auth_attempts;
|
||||
int authenticated;
|
||||
};
|
||||
|
||||
static int data_function(ssh_session session, ssh_channel channel, void *data,
|
||||
uint32_t len, int is_stderr, void *userdata) {
|
||||
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
|
||||
|
||||
(void) session;
|
||||
(void) channel;
|
||||
(void) is_stderr;
|
||||
|
||||
if (len == 0 || cdata->pid < 1 || kill(cdata->pid, 0) < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return write(cdata->stdin, (char *) data, len);
|
||||
}
|
||||
|
||||
static int pty_request(ssh_session session, ssh_channel channel,
|
||||
const char *term, int cols, int rows, int py, int px,
|
||||
void *userdata) {
|
||||
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||
|
||||
(void) session;
|
||||
(void) channel;
|
||||
(void) term;
|
||||
|
||||
cdata->winsize->ws_row = rows;
|
||||
cdata->winsize->ws_col = cols;
|
||||
cdata->winsize->ws_xpixel = px;
|
||||
cdata->winsize->ws_ypixel = py;
|
||||
|
||||
if (openpty(&cdata->pty_master, &cdata->pty_slave, NULL, NULL,
|
||||
cdata->winsize) != 0) {
|
||||
fprintf(stderr, "Failed to open pty\n");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static int pty_resize(ssh_session session, ssh_channel channel, int cols,
|
||||
int rows, int py, int px, void *userdata) {
|
||||
struct channel_data_struct *cdata = (struct channel_data_struct *)userdata;
|
||||
|
||||
(void) session;
|
||||
(void) channel;
|
||||
|
||||
cdata->winsize->ws_row = rows;
|
||||
cdata->winsize->ws_col = cols;
|
||||
cdata->winsize->ws_xpixel = px;
|
||||
cdata->winsize->ws_ypixel = py;
|
||||
|
||||
if (cdata->pty_master != -1) {
|
||||
return ioctl(cdata->pty_master, TIOCSWINSZ, cdata->winsize);
|
||||
}
|
||||
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int exec_pty(const char *mode, const char *command,
|
||||
struct channel_data_struct *cdata) {
|
||||
switch(cdata->pid = fork()) {
|
||||
case -1:
|
||||
close(cdata->pty_master);
|
||||
close(cdata->pty_slave);
|
||||
fprintf(stderr, "Failed to fork\n");
|
||||
return SSH_ERROR;
|
||||
case 0:
|
||||
close(cdata->pty_master);
|
||||
if (login_tty(cdata->pty_slave) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
execl("/bin/sh", "sh", mode, command, NULL);
|
||||
exit(0);
|
||||
default:
|
||||
close(cdata->pty_slave);
|
||||
/* pty fd is bi-directional */
|
||||
cdata->stdout = cdata->stdin = cdata->pty_master;
|
||||
}
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static int exec_nopty(const char *command, struct channel_data_struct *cdata) {
|
||||
int in[2], out[2], err[2];
|
||||
|
||||
/* Do the plumbing to be able to talk with the child process. */
|
||||
if (pipe(in) != 0) {
|
||||
goto stdin_failed;
|
||||
}
|
||||
if (pipe(out) != 0) {
|
||||
goto stdout_failed;
|
||||
}
|
||||
if (pipe(err) != 0) {
|
||||
goto stderr_failed;
|
||||
}
|
||||
|
||||
switch(cdata->pid = fork()) {
|
||||
case -1:
|
||||
goto fork_failed;
|
||||
case 0:
|
||||
/* Finish the plumbing in the child process. */
|
||||
close(in[1]);
|
||||
close(out[0]);
|
||||
close(err[0]);
|
||||
dup2(in[0], STDIN_FILENO);
|
||||
dup2(out[1], STDOUT_FILENO);
|
||||
dup2(err[1], STDERR_FILENO);
|
||||
close(in[0]);
|
||||
close(out[1]);
|
||||
close(err[1]);
|
||||
/* exec the requested command. */
|
||||
execl("/bin/sh", "sh", "-c", command, NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
close(in[0]);
|
||||
close(out[1]);
|
||||
close(err[1]);
|
||||
|
||||
cdata->stdin = in[1];
|
||||
cdata->stdout = out[0];
|
||||
cdata->stderr = err[0];
|
||||
|
||||
return SSH_OK;
|
||||
|
||||
fork_failed:
|
||||
close(err[0]);
|
||||
close(err[1]);
|
||||
stderr_failed:
|
||||
close(out[0]);
|
||||
close(out[1]);
|
||||
stdout_failed:
|
||||
close(in[0]);
|
||||
close(in[1]);
|
||||
stdin_failed:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int exec_request(ssh_session session, ssh_channel channel,
|
||||
const char *command, void *userdata) {
|
||||
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
|
||||
|
||||
|
||||
(void) session;
|
||||
(void) channel;
|
||||
|
||||
if(cdata->pid > 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (cdata->pty_master != -1 && cdata->pty_slave != -1) {
|
||||
return exec_pty("-c", command, cdata);
|
||||
}
|
||||
return exec_nopty(command, cdata);
|
||||
}
|
||||
|
||||
static int shell_request(ssh_session session, ssh_channel channel,
|
||||
void *userdata) {
|
||||
struct channel_data_struct *cdata = (struct channel_data_struct *) userdata;
|
||||
|
||||
(void) session;
|
||||
(void) channel;
|
||||
|
||||
if(cdata->pid > 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (cdata->pty_master != -1 && cdata->pty_slave != -1) {
|
||||
return exec_pty("-l", NULL, cdata);
|
||||
}
|
||||
/* Client requested a shell without a pty, let's pretend we allow that */
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
static int subsystem_request(ssh_session session, ssh_channel channel,
|
||||
const char *subsystem, void *userdata) {
|
||||
/* subsystem requests behave simillarly to exec requests. */
|
||||
if (strcmp(subsystem, "sftp") == 0) {
|
||||
return exec_request(session, channel, SFTP_SERVER_PATH, userdata);
|
||||
}
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
static int auth_password(ssh_session session, const char *user,
|
||||
const char *pass, void *userdata) {
|
||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
||||
|
||||
(void) session;
|
||||
|
||||
if (strcmp(user, USER) == 0 && strcmp(pass, PASS) == 0) {
|
||||
sdata->authenticated = 1;
|
||||
return SSH_AUTH_SUCCESS;
|
||||
}
|
||||
|
||||
sdata->auth_attempts++;
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
static ssh_channel channel_open(ssh_session session, void *userdata) {
|
||||
struct session_data_struct *sdata = (struct session_data_struct *) userdata;
|
||||
|
||||
sdata->channel = ssh_channel_new(session);
|
||||
return sdata->channel;
|
||||
}
|
||||
|
||||
static int process_stdout(socket_t fd, int revents, void *userdata) {
|
||||
char buf[BUF_SIZE];
|
||||
int n = -1;
|
||||
ssh_channel channel = (ssh_channel) userdata;
|
||||
|
||||
if (channel != NULL && (revents & POLLIN) != 0) {
|
||||
n = read(fd, buf, BUF_SIZE);
|
||||
if (n > 0) {
|
||||
ssh_channel_write(channel, buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int process_stderr(socket_t fd, int revents, void *userdata) {
|
||||
char buf[BUF_SIZE];
|
||||
int n = -1;
|
||||
ssh_channel channel = (ssh_channel) userdata;
|
||||
|
||||
if (channel != NULL && (revents & POLLIN) != 0) {
|
||||
n = read(fd, buf, BUF_SIZE);
|
||||
if (n > 0) {
|
||||
ssh_channel_write_stderr(channel, buf, n);
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static void handle_session(ssh_event event, ssh_session session) {
|
||||
int n, rc;
|
||||
|
||||
/* Structure for storing the pty size. */
|
||||
struct winsize wsize = {
|
||||
.ws_row = 0,
|
||||
.ws_col = 0,
|
||||
.ws_xpixel = 0,
|
||||
.ws_ypixel = 0
|
||||
};
|
||||
|
||||
/* Our struct holding information about the channel. */
|
||||
struct channel_data_struct cdata = {
|
||||
.pid = 0,
|
||||
.pty_master = -1,
|
||||
.pty_slave = -1,
|
||||
.stdin = -1,
|
||||
.stdout = -1,
|
||||
.stderr = -1,
|
||||
.event = NULL,
|
||||
.winsize = &wsize
|
||||
};
|
||||
|
||||
/* Our struct holding information about the session. */
|
||||
struct session_data_struct sdata = {
|
||||
.channel = NULL,
|
||||
.auth_attempts = 0,
|
||||
.authenticated = 0
|
||||
};
|
||||
|
||||
struct ssh_channel_callbacks_struct channel_cb = {
|
||||
.userdata = &cdata,
|
||||
.channel_pty_request_function = pty_request,
|
||||
.channel_pty_window_change_function = pty_resize,
|
||||
.channel_shell_request_function = shell_request,
|
||||
.channel_exec_request_function = exec_request,
|
||||
.channel_data_function = data_function,
|
||||
.channel_subsystem_request_function = subsystem_request
|
||||
};
|
||||
|
||||
struct ssh_server_callbacks_struct server_cb = {
|
||||
.userdata = &sdata,
|
||||
.auth_password_function = auth_password,
|
||||
.channel_open_request_session_function = channel_open,
|
||||
};
|
||||
|
||||
ssh_callbacks_init(&server_cb);
|
||||
ssh_callbacks_init(&channel_cb);
|
||||
|
||||
ssh_set_server_callbacks(session, &server_cb);
|
||||
|
||||
if (ssh_handle_key_exchange(session) != SSH_OK) {
|
||||
fprintf(stderr, "%s\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
|
||||
ssh_set_auth_methods(session, SSH_AUTH_METHOD_PASSWORD);
|
||||
ssh_event_add_session(event, session);
|
||||
|
||||
n = 0;
|
||||
while (sdata.authenticated == 0 || sdata.channel == NULL) {
|
||||
/* If the user has used up all attempts, or if he hasn't been able to
|
||||
* authenticate in 10 seconds (n * 100ms), disconnect. */
|
||||
if (sdata.auth_attempts >= 3 || n >= 100) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssh_event_dopoll(event, 100) == SSH_ERROR) {
|
||||
fprintf(stderr, "%s\n", ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
|
||||
ssh_set_channel_callbacks(sdata.channel, &channel_cb);
|
||||
|
||||
do {
|
||||
/* Poll the main event which takes care of the session, the channel and
|
||||
* even our child process's stdout/stderr (once it's started). */
|
||||
if (ssh_event_dopoll(event, -1) == SSH_ERROR) {
|
||||
ssh_channel_close(sdata.channel);
|
||||
}
|
||||
|
||||
/* If child process's stdout/stderr has been registered with the event,
|
||||
* or the child process hasn't started yet, continue. */
|
||||
if (cdata.event != NULL || cdata.pid == 0) {
|
||||
continue;
|
||||
}
|
||||
/* Executed only once, once the child process starts. */
|
||||
cdata.event = event;
|
||||
/* If stdout valid, add stdout to be monitored by the poll event. */
|
||||
if (cdata.stdout != -1) {
|
||||
if (ssh_event_add_fd(event, cdata.stdout, POLLIN, process_stdout,
|
||||
sdata.channel) != SSH_OK) {
|
||||
fprintf(stderr, "Failed to register stdout to poll context\n");
|
||||
ssh_channel_close(sdata.channel);
|
||||
}
|
||||
}
|
||||
|
||||
/* If stderr valid, add stderr to be monitored by the poll event. */
|
||||
if (cdata.stderr != -1){
|
||||
if (ssh_event_add_fd(event, cdata.stderr, POLLIN, process_stderr,
|
||||
sdata.channel) != SSH_OK) {
|
||||
fprintf(stderr, "Failed to register stderr to poll context\n");
|
||||
ssh_channel_close(sdata.channel);
|
||||
}
|
||||
}
|
||||
} while(ssh_channel_is_open(sdata.channel) &&
|
||||
(cdata.pid == 0 || waitpid(cdata.pid, &rc, WNOHANG) == 0));
|
||||
|
||||
close(cdata.pty_master);
|
||||
close(cdata.stdin);
|
||||
close(cdata.stdout);
|
||||
close(cdata.stderr);
|
||||
|
||||
/* Remove the descriptors from the polling context, since they are now
|
||||
* closed, they will always trigger during the poll calls. */
|
||||
ssh_event_remove_fd(event, cdata.stdout);
|
||||
ssh_event_remove_fd(event, cdata.stderr);
|
||||
|
||||
/* If the child process exited. */
|
||||
if (kill(cdata.pid, 0) < 0 && WIFEXITED(rc)) {
|
||||
rc = WEXITSTATUS(rc);
|
||||
ssh_channel_request_send_exit_status(sdata.channel, rc);
|
||||
/* If client terminated the channel or the process did not exit nicely,
|
||||
* but only if something has been forked. */
|
||||
} else if (cdata.pid > 0) {
|
||||
kill(cdata.pid, SIGKILL);
|
||||
}
|
||||
|
||||
ssh_channel_send_eof(sdata.channel);
|
||||
ssh_channel_close(sdata.channel);
|
||||
|
||||
/* Wait up to 5 seconds for the client to terminate the session. */
|
||||
for (n = 0; n < 50 && (ssh_get_status(session) & SESSION_END) == 0; n++) {
|
||||
ssh_event_dopoll(event, 100);
|
||||
}
|
||||
}
|
||||
|
||||
/* SIGCHLD handler for cleaning up dead children. */
|
||||
static void sigchld_handler(int signo) {
|
||||
(void) signo;
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
ssh_bind sshbind;
|
||||
ssh_session session;
|
||||
ssh_event event;
|
||||
struct sigaction sa;
|
||||
|
||||
/* Set up SIGCHLD handler. */
|
||||
sa.sa_handler = sigchld_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
|
||||
if (sigaction(SIGCHLD, &sa, NULL) != 0) {
|
||||
fprintf(stderr, "Failed to register SIGCHLD handler\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ssh_init();
|
||||
sshbind = ssh_bind_new();
|
||||
|
||||
#ifdef HAVE_ARGP_H
|
||||
argp_parse(&argp, argc, argv, 0, 0, sshbind);
|
||||
#else
|
||||
(void) argc;
|
||||
(void) argv;
|
||||
|
||||
set_default_keys(sshbind, 0, 0, 0);
|
||||
#endif /* HAVE_ARGP_H */
|
||||
|
||||
if(ssh_bind_listen(sshbind) < 0) {
|
||||
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
session = ssh_new();
|
||||
if (session == NULL) {
|
||||
fprintf(stderr, "Failed to allocate session\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Blocks until there is a new incoming connection. */
|
||||
if(ssh_bind_accept(sshbind, session) != SSH_ERROR) {
|
||||
switch(fork()) {
|
||||
case 0:
|
||||
/* Remove the SIGCHLD handler inherited from parent. */
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigaction(SIGCHLD, &sa, NULL);
|
||||
/* Remove socket binding, which allows us to restart the
|
||||
* parent process, without terminating existing sessions. */
|
||||
ssh_bind_free(sshbind);
|
||||
|
||||
event = ssh_event_new();
|
||||
if (event != NULL) {
|
||||
/* Blocks until the SSH session ends by either
|
||||
* child process exiting, or client disconnecting. */
|
||||
handle_session(event, session);
|
||||
ssh_event_free(event);
|
||||
} else {
|
||||
fprintf(stderr, "Could not create polling context\n");
|
||||
}
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
|
||||
exit(0);
|
||||
case -1:
|
||||
fprintf(stderr, "Failed to fork\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s\n", ssh_get_error(sshbind));
|
||||
}
|
||||
/* Since the session has been passed to a child fork, do some cleaning
|
||||
* up at the parent process. */
|
||||
ssh_disconnect(session);
|
||||
ssh_free(session);
|
||||
}
|
||||
|
||||
ssh_bind_free(sshbind);
|
||||
ssh_finalize();
|
||||
return 0;
|
||||
}
|
@ -87,13 +87,23 @@ static void select_loop(ssh_session session,ssh_channel channel){
|
||||
int ret;
|
||||
while(channel){
|
||||
do{
|
||||
int fd;
|
||||
|
||||
FD_ZERO(&fds);
|
||||
if(!eof)
|
||||
FD_SET(0,&fds);
|
||||
timeout.tv_sec=30;
|
||||
timeout.tv_usec=0;
|
||||
FD_SET(ssh_get_fd(session),&fds);
|
||||
maxfd=ssh_get_fd(session)+1;
|
||||
|
||||
fd = ssh_get_fd(session);
|
||||
if (fd == -1) {
|
||||
fprintf(stderr, "Error getting the session file descriptor: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
FD_SET(fd, &fds);
|
||||
maxfd = fd + 1;
|
||||
|
||||
channels[0]=channel; // set the first channel we want to read from
|
||||
channels[1]=NULL;
|
||||
ret=ssh_select(channels,outchannels,maxfd,&fds,&timeout);
|
||||
@ -102,27 +112,27 @@ static void select_loop(ssh_session session,ssh_channel channel){
|
||||
if(FD_ISSET(0,&fds)){
|
||||
lus=read(0,buffer,sizeof(buffer));
|
||||
if(lus)
|
||||
channel_write(channel,buffer,lus);
|
||||
ssh_channel_write(channel,buffer,lus);
|
||||
else {
|
||||
eof=1;
|
||||
channel_send_eof(channel);
|
||||
ssh_channel_send_eof(channel);
|
||||
}
|
||||
}
|
||||
if(channel && channel_is_closed(channel)){
|
||||
channel_free(channel);
|
||||
if(channel && ssh_channel_is_closed(channel)){
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
channels[0]=NULL;
|
||||
}
|
||||
if(outchannels[0]){
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,0)){
|
||||
lus=channel_read(channel,buffer,sizeof(buffer),0);
|
||||
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,0)){
|
||||
lus = ssh_channel_read(channel,buffer,sizeof(buffer),0);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
channel_free(channel);
|
||||
ssh_channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else {
|
||||
ret = write(1, buffer, lus);
|
||||
@ -133,27 +143,28 @@ static void select_loop(ssh_session session,ssh_channel channel){
|
||||
}
|
||||
}
|
||||
}
|
||||
while(channel && channel_is_open(channel) && channel_poll(channel,1)){ /* stderr */
|
||||
lus=channel_read(channel,buffer,sizeof(buffer),1);
|
||||
while(channel && ssh_channel_is_open(channel) && ssh_channel_poll(channel,1)){ /* stderr */
|
||||
lus = ssh_channel_read(channel, buffer, sizeof(buffer), 1);
|
||||
if(lus==-1){
|
||||
fprintf(stderr, "Error reading channel: %s\n",
|
||||
ssh_get_error(session));
|
||||
return;
|
||||
}
|
||||
if(lus==0){
|
||||
channel_free(channel);
|
||||
ssh_channel_free(channel);
|
||||
channel=channels[0]=NULL;
|
||||
} else
|
||||
} else {
|
||||
ret = write(2, buffer, lus);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error writing to stderr: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(channel && channel_is_closed(channel)){
|
||||
channel_free(channel);
|
||||
if(channel && ssh_channel_is_closed(channel)){
|
||||
ssh_channel_free(channel);
|
||||
channel=NULL;
|
||||
}
|
||||
} while (ret==EINTR || ret==SSH_EINTR);
|
||||
@ -164,8 +175,8 @@ static void select_loop(ssh_session session,ssh_channel channel){
|
||||
static void forwarding(ssh_session session){
|
||||
ssh_channel channel;
|
||||
int r;
|
||||
channel=channel_new(session);
|
||||
r=channel_open_forward(channel,desthost,atoi(port),"localhost",22);
|
||||
channel = ssh_channel_new(session);
|
||||
r = ssh_channel_open_forward(channel, desthost, atoi(port), "localhost", 22);
|
||||
if(r<0) {
|
||||
printf("error forwarding port : %s\n",ssh_get_error(session));
|
||||
return;
|
||||
|
32
libssh/include/libssh/bignum.h
Normal file
32
libssh/include/libssh/bignum.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2014 by Aris Adamantiadis <aris@badcode.be>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BIGNUM_H_
|
||||
#define BIGNUM_H_
|
||||
|
||||
#include "libssh/libcrypto.h"
|
||||
#include "libssh/libgcrypt.h"
|
||||
|
||||
bignum make_string_bn(ssh_string string);
|
||||
ssh_string make_bignum_string(bignum num);
|
||||
void ssh_print_bignum(const char *which,bignum num);
|
||||
|
||||
|
||||
#endif /* BIGNUM_H_ */
|
@ -21,6 +21,8 @@
|
||||
#ifndef BUFFER_H_
|
||||
#define BUFFER_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "libssh/libssh.h"
|
||||
/*
|
||||
* Describes a buffer state
|
||||
@ -34,21 +36,32 @@ struct ssh_buffer_struct {
|
||||
uint32_t used;
|
||||
uint32_t allocated;
|
||||
uint32_t pos;
|
||||
int secure;
|
||||
};
|
||||
|
||||
#define SSH_BUFFER_PACK_END ((uint32_t) 0x4f65feb3)
|
||||
|
||||
LIBSSH_API void ssh_buffer_free(ssh_buffer buffer);
|
||||
LIBSSH_API void *ssh_buffer_get_begin(ssh_buffer buffer);
|
||||
LIBSSH_API uint32_t ssh_buffer_get_len(ssh_buffer buffer);
|
||||
LIBSSH_API ssh_buffer ssh_buffer_new(void);
|
||||
void ssh_buffer_set_secure(ssh_buffer buffer);
|
||||
int buffer_add_ssh_string(ssh_buffer buffer, ssh_string string);
|
||||
int buffer_add_u8(ssh_buffer buffer, uint8_t data);
|
||||
int buffer_add_u16(ssh_buffer buffer, uint16_t data);
|
||||
int buffer_add_u32(ssh_buffer buffer, uint32_t data);
|
||||
int buffer_add_u64(ssh_buffer buffer, uint64_t data);
|
||||
int buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||
int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap);
|
||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer, const char *format, ...);
|
||||
#define ssh_buffer_pack(buffer, format, ...) _ssh_buffer_pack((buffer),(format), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap);
|
||||
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer, const char *format, ...);
|
||||
#define ssh_buffer_unpack(buffer, format, ...) _ssh_buffer_unpack((buffer),(format), __VA_ARGS__, SSH_BUFFER_PACK_END)
|
||||
|
||||
int buffer_prepend_data(ssh_buffer buffer, const void *data, uint32_t len);
|
||||
int buffer_add_buffer(ssh_buffer buffer, ssh_buffer source);
|
||||
int buffer_reinit(ssh_buffer buffer);
|
||||
int ssh_buffer_reinit(ssh_buffer buffer);
|
||||
|
||||
/* buffer_get_rest returns a pointer to the current position into the buffer */
|
||||
void *buffer_get_rest(ssh_buffer buffer);
|
||||
|
@ -495,6 +495,8 @@ LIBSSH_API int ssh_set_callbacks(ssh_session session, ssh_callbacks cb);
|
||||
* @param len the length of the data
|
||||
* @param is_stderr is 0 for stdout or 1 for stderr
|
||||
* @param userdata Userdata to be passed to the callback function.
|
||||
* @returns number of bytes processed by the callee. The remaining bytes will
|
||||
* be sent in the next callback message, when more data is available.
|
||||
*/
|
||||
typedef int (*ssh_channel_data_callback) (ssh_session session,
|
||||
ssh_channel channel,
|
||||
@ -801,6 +803,8 @@ struct ssh_threads_callbacks_struct {
|
||||
*
|
||||
* @see ssh_threads_callbacks_struct
|
||||
* @see SSH_THREADS_PTHREAD
|
||||
* @bug libgcrypt 1.6 and bigger backend does not support custom callback.
|
||||
* Using anything else than pthreads here will fail.
|
||||
*/
|
||||
LIBSSH_API int ssh_threads_set_callbacks(struct ssh_threads_callbacks_struct
|
||||
*cb);
|
||||
|
@ -75,6 +75,8 @@ struct ssh_channel_struct {
|
||||
int exit_status;
|
||||
enum ssh_channel_request_state_e request_state;
|
||||
ssh_channel_callbacks callbacks;
|
||||
/* counters */
|
||||
ssh_counter counter;
|
||||
};
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open_conf);
|
||||
|
@ -46,6 +46,8 @@
|
||||
#include "libssh/kex.h"
|
||||
#include "libssh/curve25519.h"
|
||||
|
||||
#define DIGEST_MAX_LEN 64
|
||||
|
||||
enum ssh_key_exchange_e {
|
||||
/* diffie-hellman-group1-sha1 */
|
||||
SSH_KEX_DH_GROUP1_SHA1=1,
|
||||
@ -79,8 +81,10 @@ struct ssh_crypto_struct {
|
||||
unsigned char *encryptkey;
|
||||
unsigned char *encryptMAC;
|
||||
unsigned char *decryptMAC;
|
||||
unsigned char hmacbuf[EVP_MAX_MD_SIZE];
|
||||
unsigned char hmacbuf[DIGEST_MAX_LEN];
|
||||
struct ssh_cipher_struct *in_cipher, *out_cipher; /* the cipher structures/objects */
|
||||
enum ssh_hmac_e in_hmac, out_hmac; /* the MAC algorithms used */
|
||||
|
||||
ssh_string server_pubkey;
|
||||
const char *server_pubkey_type;
|
||||
int do_compress_out; /* idem */
|
||||
@ -111,9 +115,9 @@ struct ssh_cipher_struct {
|
||||
/* sets the new key for immediate use */
|
||||
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
|
||||
void (*cbc_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
void (*cbc_decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||
unsigned long len);
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,10 @@ int crypto_scalarmult_base(unsigned char *q, const unsigned char *n);
|
||||
int crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
|
||||
#endif /* WITH_NACL */
|
||||
|
||||
#define HAVE_CURVE25519
|
||||
#ifdef HAVE_ECC
|
||||
#define HAVE_CURVE25519 1
|
||||
#endif
|
||||
|
||||
typedef unsigned char ssh_curve25519_pubkey[CURVE25519_PUBKEY_SIZE];
|
||||
typedef unsigned char ssh_curve25519_privkey[CURVE25519_PRIVKEY_SIZE];
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
void ssh_print_bignum(const char *which,bignum num);
|
||||
int dh_generate_e(ssh_session session);
|
||||
int dh_generate_f(ssh_session session);
|
||||
int dh_generate_x(ssh_session session);
|
||||
@ -48,8 +47,5 @@ int make_sessionid(ssh_session session);
|
||||
int hashbufin_add_cookie(ssh_session session, unsigned char *cookie);
|
||||
int hashbufout_add_cookie(ssh_session session);
|
||||
int generate_session_keys(ssh_session session);
|
||||
bignum make_string_bn(ssh_string string);
|
||||
ssh_string make_bignum_string(bignum num);
|
||||
|
||||
|
||||
#endif /* DH_H_ */
|
||||
|
@ -26,7 +26,9 @@
|
||||
#ifdef HAVE_LIBCRYPTO
|
||||
#ifdef HAVE_OPENSSL_ECDH_H
|
||||
|
||||
#define HAVE_ECDH
|
||||
#ifdef HAVE_ECC
|
||||
#define HAVE_ECDH 1
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_OPENSSL_ECDH_H */
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
79
libssh/include/libssh/ed25519.h
Normal file
79
libssh/include/libssh/ed25519.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2014 by Aris Adamantiadis
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef ED25519_H_
|
||||
#define ED25519_H_
|
||||
#include "libssh/priv.h"
|
||||
|
||||
/**
|
||||
* @defgroup ed25519 ed25519 API
|
||||
* @internal
|
||||
* @brief API for DJB's ed25519
|
||||
*
|
||||
* @{ */
|
||||
|
||||
#define ED25519_PK_LEN 32
|
||||
#define ED25519_SK_LEN 64
|
||||
#define ED25519_SIG_LEN 64
|
||||
|
||||
typedef uint8_t ed25519_pubkey[ED25519_PK_LEN];
|
||||
typedef uint8_t ed25519_privkey[ED25519_SK_LEN];
|
||||
typedef uint8_t ed25519_signature[ED25519_SIG_LEN];
|
||||
|
||||
/** @internal
|
||||
* @brief generate an ed25519 key pair
|
||||
* @param[out] pk generated public key
|
||||
* @param[out] sk generated secret key
|
||||
* @return 0 on success, -1 on error.
|
||||
* */
|
||||
int crypto_sign_ed25519_keypair(ed25519_pubkey pk, ed25519_privkey sk);
|
||||
|
||||
/** @internal
|
||||
* @brief sign a message with ed25519
|
||||
* @param[out] sm location to store the signed message.
|
||||
* Its length should be mlen + 64.
|
||||
* @param[out] smlen pointer to the size of the signed message
|
||||
* @param[in] m message to be signed
|
||||
* @param[in] mlen length of the message to be signed
|
||||
* @param[in] sk secret key to sign the message with
|
||||
* @return 0 on success.
|
||||
*/
|
||||
int crypto_sign_ed25519(
|
||||
unsigned char *sm,unsigned long long *smlen,
|
||||
const unsigned char *m,unsigned long long mlen,
|
||||
const ed25519_privkey sk);
|
||||
|
||||
/** @internal
|
||||
* @brief "open" and verify the signature of a signed message
|
||||
* @param[out] m location to store the verified message.
|
||||
* Its length should be equal to smlen.
|
||||
* @param[out] mlen pointer to the size of the verified message
|
||||
* @param[in] sm signed message to verify
|
||||
* @param[in] smlen length of the signed message to verify
|
||||
* @param[in] pk public key used to sign the message
|
||||
* @returns 0 on success (supposedly).
|
||||
*/
|
||||
int crypto_sign_ed25519_open(
|
||||
unsigned char *m,unsigned long long *mlen,
|
||||
const unsigned char *sm,unsigned long long smlen,
|
||||
const ed25519_pubkey pk);
|
||||
|
||||
/** @} */
|
||||
#endif /* ED25519_H_ */
|
68
libssh/include/libssh/fe25519.h
Normal file
68
libssh/include/libssh/fe25519.h
Normal file
@ -0,0 +1,68 @@
|
||||
/* $OpenBSD: fe25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.h
|
||||
*/
|
||||
|
||||
#ifndef FE25519_H
|
||||
#define FE25519_H
|
||||
|
||||
#include "libssh/priv.h"
|
||||
|
||||
#define fe25519 crypto_sign_ed25519_ref_fe25519
|
||||
#define fe25519_freeze crypto_sign_ed25519_ref_fe25519_freeze
|
||||
#define fe25519_unpack crypto_sign_ed25519_ref_fe25519_unpack
|
||||
#define fe25519_pack crypto_sign_ed25519_ref_fe25519_pack
|
||||
#define fe25519_iszero crypto_sign_ed25519_ref_fe25519_iszero
|
||||
#define fe25519_iseq_vartime crypto_sign_ed25519_ref_fe25519_iseq_vartime
|
||||
#define fe25519_cmov crypto_sign_ed25519_ref_fe25519_cmov
|
||||
#define fe25519_setone crypto_sign_ed25519_ref_fe25519_setone
|
||||
#define fe25519_setzero crypto_sign_ed25519_ref_fe25519_setzero
|
||||
#define fe25519_neg crypto_sign_ed25519_ref_fe25519_neg
|
||||
#define fe25519_getparity crypto_sign_ed25519_ref_fe25519_getparity
|
||||
#define fe25519_add crypto_sign_ed25519_ref_fe25519_add
|
||||
#define fe25519_sub crypto_sign_ed25519_ref_fe25519_sub
|
||||
#define fe25519_mul crypto_sign_ed25519_ref_fe25519_mul
|
||||
#define fe25519_square crypto_sign_ed25519_ref_fe25519_square
|
||||
#define fe25519_invert crypto_sign_ed25519_ref_fe25519_invert
|
||||
#define fe25519_pow2523 crypto_sign_ed25519_ref_fe25519_pow2523
|
||||
|
||||
typedef struct {
|
||||
uint32_t v[32];
|
||||
} fe25519;
|
||||
|
||||
void fe25519_freeze(fe25519 *r);
|
||||
|
||||
void fe25519_unpack(fe25519 *r, const unsigned char x[32]);
|
||||
|
||||
void fe25519_pack(unsigned char r[32], const fe25519 *x);
|
||||
|
||||
int fe25519_iszero(const fe25519 *x);
|
||||
|
||||
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y);
|
||||
|
||||
void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b);
|
||||
|
||||
void fe25519_setone(fe25519 *r);
|
||||
|
||||
void fe25519_setzero(fe25519 *r);
|
||||
|
||||
void fe25519_neg(fe25519 *r, const fe25519 *x);
|
||||
|
||||
unsigned char fe25519_getparity(const fe25519 *x);
|
||||
|
||||
void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y);
|
||||
|
||||
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y);
|
||||
|
||||
void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y);
|
||||
|
||||
void fe25519_square(fe25519 *r, const fe25519 *x);
|
||||
|
||||
void fe25519_invert(fe25519 *r, const fe25519 *x);
|
||||
|
||||
void fe25519_pow2523(fe25519 *r, const fe25519 *x);
|
||||
|
||||
#endif
|
43
libssh/include/libssh/ge25519.h
Normal file
43
libssh/include/libssh/ge25519.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* $OpenBSD: ge25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.h
|
||||
*/
|
||||
|
||||
#ifndef GE25519_H
|
||||
#define GE25519_H
|
||||
|
||||
#include "fe25519.h"
|
||||
#include "sc25519.h"
|
||||
|
||||
#define ge25519 crypto_sign_ed25519_ref_ge25519
|
||||
#define ge25519_base crypto_sign_ed25519_ref_ge25519_base
|
||||
#define ge25519_unpackneg_vartime crypto_sign_ed25519_ref_unpackneg_vartime
|
||||
#define ge25519_pack crypto_sign_ed25519_ref_pack
|
||||
#define ge25519_isneutral_vartime crypto_sign_ed25519_ref_isneutral_vartime
|
||||
#define ge25519_double_scalarmult_vartime crypto_sign_ed25519_ref_double_scalarmult_vartime
|
||||
#define ge25519_scalarmult_base crypto_sign_ed25519_ref_scalarmult_base
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fe25519 x;
|
||||
fe25519 y;
|
||||
fe25519 z;
|
||||
fe25519 t;
|
||||
} ge25519;
|
||||
|
||||
const ge25519 ge25519_base;
|
||||
|
||||
int ge25519_unpackneg_vartime(ge25519 *r, const unsigned char p[32]);
|
||||
|
||||
void ge25519_pack(unsigned char r[32], const ge25519 *p);
|
||||
|
||||
int ge25519_isneutral_vartime(const ge25519 *p);
|
||||
|
||||
void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const sc25519 *s1, const ge25519 *p2, const sc25519 *s2);
|
||||
|
||||
void ge25519_scalarmult_base(ge25519 *r, const sc25519 *s);
|
||||
|
||||
#endif
|
27
libssh/include/libssh/knownhosts.h
Normal file
27
libssh/include/libssh/knownhosts.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 20014 by Aris Adamantiadis <aris@badcode.be>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KNOWNHOSTS_H_
|
||||
#define KNOWNHOSTS_H_
|
||||
|
||||
char **ssh_knownhosts_algorithms(ssh_session session);
|
||||
|
||||
#endif /* KNOWNHOSTS_H_ */
|
@ -42,51 +42,51 @@ LIBSSH_API int ssh_userauth_autopubkey(ssh_session session, const char *passphra
|
||||
LIBSSH_API int ssh_userauth_privatekey_file(ssh_session session, const char *username,
|
||||
const char *filename, const char *passphrase);
|
||||
|
||||
LIBSSH_API void buffer_free(ssh_buffer buffer);
|
||||
LIBSSH_API void *buffer_get(ssh_buffer buffer);
|
||||
LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer);
|
||||
LIBSSH_API ssh_buffer buffer_new(void);
|
||||
SSH_DEPRECATED LIBSSH_API void buffer_free(ssh_buffer buffer);
|
||||
SSH_DEPRECATED LIBSSH_API void *buffer_get(ssh_buffer buffer);
|
||||
SSH_DEPRECATED LIBSSH_API uint32_t buffer_get_len(ssh_buffer buffer);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_buffer buffer_new(void);
|
||||
|
||||
LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
|
||||
LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows);
|
||||
LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms);
|
||||
LIBSSH_API int channel_close(ssh_channel channel);
|
||||
LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port);
|
||||
LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
LIBSSH_API void channel_free(ssh_channel channel);
|
||||
LIBSSH_API int channel_get_exit_status(ssh_channel channel);
|
||||
LIBSSH_API ssh_session channel_get_session(ssh_channel channel);
|
||||
LIBSSH_API int channel_is_closed(ssh_channel channel);
|
||||
LIBSSH_API int channel_is_eof(ssh_channel channel);
|
||||
LIBSSH_API int channel_is_open(ssh_channel channel);
|
||||
LIBSSH_API ssh_channel channel_new(ssh_session session);
|
||||
LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
SSH_DEPRECATED LIBSSH_API ssh_channel channel_accept_x11(ssh_channel channel, int timeout_ms);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_change_pty_size(ssh_channel channel,int cols,int rows);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_channel channel_forward_accept(ssh_session session, int timeout_ms);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_close(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_forward_cancel(ssh_session session, const char *address, int port);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
SSH_DEPRECATED LIBSSH_API void channel_free(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_get_exit_status(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_session channel_get_session(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_is_closed(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_is_eof(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_is_open(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_channel channel_new(ssh_session session);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_open_forward(ssh_channel channel, const char *remotehost,
|
||||
int remoteport, const char *sourcehost, int localport);
|
||||
LIBSSH_API int channel_open_session(ssh_channel channel);
|
||||
LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr);
|
||||
LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_open_session(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_poll(ssh_channel channel, int is_stderr);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
|
||||
|
||||
LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
||||
SSH_DEPRECATED LIBSSH_API int channel_read_buffer(ssh_channel channel, ssh_buffer buffer, uint32_t count,
|
||||
int is_stderr);
|
||||
|
||||
LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
SSH_DEPRECATED LIBSSH_API int channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
int is_stderr);
|
||||
LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value);
|
||||
LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd);
|
||||
LIBSSH_API int channel_request_pty(ssh_channel channel);
|
||||
LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term,
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_env(ssh_channel channel, const char *name, const char *value);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_exec(ssh_channel channel, const char *cmd);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_pty(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_pty_size(ssh_channel channel, const char *term,
|
||||
int cols, int rows);
|
||||
LIBSSH_API int channel_request_shell(ssh_channel channel);
|
||||
LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum);
|
||||
LIBSSH_API int channel_request_sftp(ssh_channel channel);
|
||||
LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem);
|
||||
LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_shell(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_send_signal(ssh_channel channel, const char *signum);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_sftp(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_subsystem(ssh_channel channel, const char *subsystem);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_request_x11(ssh_channel channel, int single_connection, const char *protocol,
|
||||
const char *cookie, int screen_number);
|
||||
LIBSSH_API int channel_send_eof(ssh_channel channel);
|
||||
LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
||||
SSH_DEPRECATED LIBSSH_API int channel_send_eof(ssh_channel channel);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
||||
timeval * timeout);
|
||||
LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
|
||||
LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||
SSH_DEPRECATED LIBSSH_API void channel_set_blocking(ssh_channel channel, int blocking);
|
||||
SSH_DEPRECATED LIBSSH_API int channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||
|
||||
LIBSSH_API void privatekey_free(ssh_private_key prv);
|
||||
LIBSSH_API ssh_private_key privatekey_from_file(ssh_session session, const char *filename,
|
||||
@ -107,14 +107,14 @@ LIBSSH_API ssh_string ssh_get_pubkey(ssh_session session);
|
||||
LIBSSH_API ssh_message ssh_message_retrieve(ssh_session session, uint32_t packettype);
|
||||
LIBSSH_API ssh_public_key ssh_message_auth_publickey(ssh_message msg);
|
||||
|
||||
LIBSSH_API void string_burn(ssh_string str);
|
||||
LIBSSH_API ssh_string string_copy(ssh_string str);
|
||||
LIBSSH_API void *string_data(ssh_string str);
|
||||
LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len);
|
||||
LIBSSH_API void string_free(ssh_string str);
|
||||
LIBSSH_API ssh_string string_from_char(const char *what);
|
||||
LIBSSH_API size_t string_len(ssh_string str);
|
||||
LIBSSH_API ssh_string string_new(size_t size);
|
||||
LIBSSH_API char *string_to_char(ssh_string str);
|
||||
SSH_DEPRECATED LIBSSH_API void string_burn(ssh_string str);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_string string_copy(ssh_string str);
|
||||
SSH_DEPRECATED LIBSSH_API void *string_data(ssh_string str);
|
||||
SSH_DEPRECATED LIBSSH_API int string_fill(ssh_string str, const void *data, size_t len);
|
||||
SSH_DEPRECATED LIBSSH_API void string_free(ssh_string str);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_string string_from_char(const char *what);
|
||||
SSH_DEPRECATED LIBSSH_API size_t string_len(ssh_string str);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_string string_new(size_t size);
|
||||
SSH_DEPRECATED LIBSSH_API char *string_to_char(ssh_string str);
|
||||
|
||||
#endif /* LEGACY_H_ */
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
typedef SHA_CTX* SHACTX;
|
||||
typedef SHA256_CTX* SHA256CTX;
|
||||
typedef SHA512_CTX* SHA384CTX;
|
||||
typedef SHA512_CTX* SHA512CTX;
|
||||
typedef MD5_CTX* MD5CTX;
|
||||
typedef HMAC_CTX* HMACCTX;
|
||||
#ifdef HAVE_ECC
|
||||
@ -45,6 +47,9 @@ typedef void *EVPCTX;
|
||||
#endif
|
||||
|
||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
|
||||
#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH
|
||||
#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH
|
||||
#ifdef MD5_DIGEST_LEN
|
||||
#undef MD5_DIGEST_LEN
|
||||
#endif
|
||||
@ -84,6 +89,14 @@ SHA256CTX sha256_init(void);
|
||||
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
|
||||
void sha256_final(unsigned char *md, SHA256CTX c);
|
||||
|
||||
SHA384CTX sha384_init(void);
|
||||
void sha384_update(SHA384CTX c, const void *data, unsigned long len);
|
||||
void sha384_final(unsigned char *md, SHA384CTX c);
|
||||
|
||||
SHA512CTX sha512_init(void);
|
||||
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
|
||||
void sha512_final(unsigned char *md, SHA512CTX c);
|
||||
|
||||
struct ssh_cipher_struct *ssh_get_ciphertab(void);
|
||||
|
||||
#endif /* HAVE_LIBCRYPTO */
|
||||
|
@ -27,6 +27,9 @@
|
||||
|
||||
#include <gcrypt.h>
|
||||
typedef gcry_md_hd_t SHACTX;
|
||||
typedef gcry_md_hd_t SHA256CTX;
|
||||
typedef gcry_md_hd_t SHA384CTX;
|
||||
typedef gcry_md_hd_t SHA512CTX;
|
||||
typedef gcry_md_hd_t MD5CTX;
|
||||
typedef gcry_md_hd_t HMACCTX;
|
||||
typedef void *EVPCTX;
|
||||
@ -34,11 +37,14 @@ typedef void *EVPCTX;
|
||||
#define SHA_DIGEST_LEN SHA_DIGEST_LENGTH
|
||||
#define MD5_DIGEST_LEN 16
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA256_DIGEST_LEN SHA256_DIGEST_LENGTH
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA384_DIGEST_LEN SHA384_DIGEST_LENGTH
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
#define SHA512_DIGEST_LEN SHA512_DIGEST_LENGTH
|
||||
|
||||
#ifndef EVP_MAX_MD_SIZE
|
||||
#define EVP_MAX_MD_SIZE 36
|
||||
#define EVP_MAX_MD_SIZE 64
|
||||
#endif
|
||||
|
||||
#define EVP_DIGEST_LEN EVP_MAX_MD_SIZE
|
||||
|
@ -104,6 +104,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ssh_counter_struct {
|
||||
uint64_t in_bytes;
|
||||
uint64_t out_bytes;
|
||||
uint64_t in_packets;
|
||||
uint64_t out_packets;
|
||||
};
|
||||
typedef struct ssh_counter_struct *ssh_counter;
|
||||
|
||||
typedef struct ssh_agent_struct* ssh_agent;
|
||||
typedef struct ssh_buffer_struct* ssh_buffer;
|
||||
@ -245,7 +252,8 @@ enum ssh_keytypes_e{
|
||||
SSH_KEYTYPE_DSS=1,
|
||||
SSH_KEYTYPE_RSA,
|
||||
SSH_KEYTYPE_RSA1,
|
||||
SSH_KEYTYPE_ECDSA
|
||||
SSH_KEYTYPE_ECDSA,
|
||||
SSH_KEYTYPE_ED25519
|
||||
};
|
||||
|
||||
enum ssh_keycmp_e {
|
||||
@ -331,7 +339,12 @@ enum ssh_options_e {
|
||||
SSH_OPTIONS_COMPRESSION,
|
||||
SSH_OPTIONS_COMPRESSION_LEVEL,
|
||||
SSH_OPTIONS_KEY_EXCHANGE,
|
||||
SSH_OPTIONS_HOSTKEYS
|
||||
SSH_OPTIONS_HOSTKEYS,
|
||||
SSH_OPTIONS_GSSAPI_SERVER_IDENTITY,
|
||||
SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY,
|
||||
SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS,
|
||||
SSH_OPTIONS_HMAC_C_S,
|
||||
SSH_OPTIONS_HMAC_S_C,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -374,6 +387,7 @@ LIBSSH_API int ssh_channel_open_x11(ssh_channel channel, const char *orig_addr,
|
||||
LIBSSH_API int ssh_channel_poll(ssh_channel channel, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_poll_timeout(ssh_channel channel, int timeout, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_read(ssh_channel channel, void *dest, uint32_t count, int is_stderr);
|
||||
LIBSSH_API int ssh_channel_read_timeout(ssh_channel channel, void *dest, uint32_t count, int is_stderr, int timeout_ms);
|
||||
LIBSSH_API int ssh_channel_read_nonblocking(ssh_channel channel, void *dest, uint32_t count,
|
||||
int is_stderr);
|
||||
LIBSSH_API int ssh_channel_request_env(ssh_channel channel, const char *name, const char *value);
|
||||
@ -391,6 +405,8 @@ LIBSSH_API int ssh_channel_send_eof(ssh_channel channel);
|
||||
LIBSSH_API int ssh_channel_select(ssh_channel *readchans, ssh_channel *writechans, ssh_channel *exceptchans, struct
|
||||
timeval * timeout);
|
||||
LIBSSH_API void ssh_channel_set_blocking(ssh_channel channel, int blocking);
|
||||
LIBSSH_API void ssh_channel_set_counter(ssh_channel channel,
|
||||
ssh_counter counter);
|
||||
LIBSSH_API int ssh_channel_write(ssh_channel channel, const void *data, uint32_t len);
|
||||
LIBSSH_API uint32_t ssh_channel_window_size(ssh_channel channel);
|
||||
|
||||
@ -401,9 +417,19 @@ LIBSSH_API const char *ssh_copyright(void);
|
||||
LIBSSH_API void ssh_disconnect(ssh_session session);
|
||||
LIBSSH_API char *ssh_dirname (const char *path);
|
||||
LIBSSH_API int ssh_finalize(void);
|
||||
LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms);
|
||||
LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
||||
LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
|
||||
/* REVERSE PORT FORWARDING */
|
||||
LIBSSH_API ssh_channel ssh_channel_accept_forward(ssh_session session,
|
||||
int timeout_ms,
|
||||
int *destination_port);
|
||||
LIBSSH_API int ssh_channel_cancel_forward(ssh_session session,
|
||||
const char *address,
|
||||
int port);
|
||||
LIBSSH_API int ssh_channel_listen_forward(ssh_session session,
|
||||
const char *address,
|
||||
int port,
|
||||
int *bound_port);
|
||||
|
||||
LIBSSH_API void ssh_free(ssh_session session);
|
||||
LIBSSH_API const char *ssh_get_disconnect_message(ssh_session session);
|
||||
LIBSSH_API const char *ssh_get_error(void *error);
|
||||
@ -424,11 +450,17 @@ LIBSSH_API int ssh_get_publickey_hash(const ssh_key key,
|
||||
unsigned char **hash,
|
||||
size_t *hlen);
|
||||
|
||||
/* DEPRECATED FUNCTIONS */
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash);
|
||||
SSH_DEPRECATED LIBSSH_API ssh_channel ssh_forward_accept(ssh_session session, int timeout_ms);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_cancel(ssh_session session, const char *address, int port);
|
||||
SSH_DEPRECATED LIBSSH_API int ssh_forward_listen(ssh_session session, const char *address, int port, int *bound_port);
|
||||
|
||||
|
||||
LIBSSH_API int ssh_get_random(void *where,int len,int strong);
|
||||
LIBSSH_API int ssh_get_version(ssh_session session);
|
||||
LIBSSH_API int ssh_get_status(ssh_session session);
|
||||
LIBSSH_API int ssh_get_poll_flags(ssh_session session);
|
||||
LIBSSH_API int ssh_init(void);
|
||||
LIBSSH_API int ssh_is_blocking(ssh_session session);
|
||||
LIBSSH_API int ssh_is_connected(ssh_session session);
|
||||
@ -509,6 +541,11 @@ LIBSSH_API int ssh_pki_import_privkey_file(const char *filename,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data,
|
||||
ssh_key *pkey);
|
||||
LIBSSH_API int ssh_pki_export_privkey_file(const ssh_key privkey,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data,
|
||||
const char *filename);
|
||||
|
||||
LIBSSH_API int ssh_pki_import_pubkey_base64(const char *b64_key,
|
||||
enum ssh_keytypes_e type,
|
||||
@ -523,6 +560,8 @@ LIBSSH_API int ssh_pki_export_pubkey_base64(const ssh_key key,
|
||||
LIBSSH_API int ssh_pki_export_pubkey_file(const ssh_key key,
|
||||
const char *filename);
|
||||
|
||||
LIBSSH_API const char *ssh_pki_key_ecdsa_name(const ssh_key key);
|
||||
|
||||
LIBSSH_API void ssh_print_hexa(const char *descr, const unsigned char *what, size_t len);
|
||||
LIBSSH_API int ssh_send_ignore (ssh_session session, const char *data);
|
||||
LIBSSH_API int ssh_send_debug (ssh_session session, const char *message, int always_display);
|
||||
@ -550,6 +589,8 @@ LIBSSH_API int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socke
|
||||
LIBSSH_API int ssh_service_request(ssh_session session, const char *service);
|
||||
LIBSSH_API int ssh_set_agent_channel(ssh_session session, ssh_channel channel);
|
||||
LIBSSH_API void ssh_set_blocking(ssh_session session, int blocking);
|
||||
LIBSSH_API void ssh_set_counters(ssh_session session, ssh_counter scounter,
|
||||
ssh_counter rcounter);
|
||||
LIBSSH_API void ssh_set_fd_except(ssh_session session);
|
||||
LIBSSH_API void ssh_set_fd_toread(ssh_session session);
|
||||
LIBSSH_API void ssh_set_fd_towrite(ssh_session session);
|
||||
@ -615,7 +656,12 @@ LIBSSH_API int ssh_event_dopoll(ssh_event event, int timeout);
|
||||
LIBSSH_API int ssh_event_remove_fd(ssh_event event, socket_t fd);
|
||||
LIBSSH_API int ssh_event_remove_session(ssh_event event, ssh_session session);
|
||||
LIBSSH_API void ssh_event_free(ssh_event event);
|
||||
LIBSSH_API const char* ssh_get_clientbanner(ssh_session session);
|
||||
LIBSSH_API const char* ssh_get_serverbanner(ssh_session session);
|
||||
LIBSSH_API const char* ssh_get_cipher_in(ssh_session session);
|
||||
LIBSSH_API const char* ssh_get_cipher_out(ssh_session session);
|
||||
LIBSSH_API const char* ssh_get_hmac_in(ssh_session session);
|
||||
LIBSSH_API const char* ssh_get_hmac_out(ssh_session session);
|
||||
|
||||
#ifndef LIBSSH_LEGACY_0_4
|
||||
#include "libssh/legacy.h"
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
namespace ssh {
|
||||
|
||||
@ -361,18 +362,18 @@ public:
|
||||
* @see ssh_channel_forward_accept
|
||||
* @see Session::listenForward
|
||||
*/
|
||||
Channel *acceptForward(int timeout_ms);
|
||||
/* acceptForward is implemented later in this file */
|
||||
inline Channel *acceptForward(int timeout_ms);
|
||||
/* implemented outside the class due Channel references */
|
||||
|
||||
void_throwable cancelForward(const char *address, int port){
|
||||
int err=ssh_forward_cancel(c_session, address, port);
|
||||
int err=ssh_channel_cancel_forward(c_session, address, port);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
|
||||
void_throwable listenForward(const char *address, int port,
|
||||
int &boundport){
|
||||
int err=ssh_forward_listen(c_session, address, port, &boundport);
|
||||
int err=ssh_channel_listen_forward(c_session, address, port, &boundport);
|
||||
ssh_throw(err);
|
||||
return_throwable;
|
||||
}
|
||||
@ -480,12 +481,30 @@ public:
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, bool is_stderr=false){
|
||||
int read(void *dest, size_t count, bool is_stderr){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read(channel,dest,count,is_stderr);
|
||||
err=ssh_channel_read_timeout(channel,dest,count,is_stderr,-1);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, int timeout){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read_timeout(channel,dest,count,false,timeout);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
int read(void *dest, size_t count, bool is_stderr=false, int timeout=-1){
|
||||
int err;
|
||||
/* handle int overflow */
|
||||
if(count > 0x7fffffff)
|
||||
count = 0x7fffffff;
|
||||
err=ssh_channel_read_timeout(channel,dest,count,is_stderr,timeout);
|
||||
ssh_throw(err);
|
||||
return err;
|
||||
}
|
||||
@ -581,10 +600,9 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/* This code cannot be put inline due to references to Channel */
|
||||
Channel *Session::acceptForward(int timeout_ms){
|
||||
ssh_channel forward = ssh_forward_accept(c_session,
|
||||
timeout_ms);
|
||||
inline Channel *Session::acceptForward(int timeout_ms){
|
||||
ssh_channel forward =
|
||||
ssh_channel_accept_forward(c_session, timeout_ms, NULL);
|
||||
ssh_throw_null(c_session,forward);
|
||||
Channel *newchan = new Channel(*this,forward);
|
||||
return newchan;
|
||||
|
@ -21,6 +21,8 @@
|
||||
#ifndef PACKET_H_
|
||||
#define PACKET_H_
|
||||
|
||||
#include "libssh/wrapper.h"
|
||||
|
||||
struct ssh_socket_struct;
|
||||
|
||||
/* this structure should go someday */
|
||||
@ -82,6 +84,6 @@ unsigned char *packet_encrypt(ssh_session session,
|
||||
void *packet,
|
||||
unsigned int len);
|
||||
int packet_hmac_verify(ssh_session session,ssh_buffer buffer,
|
||||
unsigned char *mac);
|
||||
unsigned char *mac, enum ssh_hmac_e type);
|
||||
|
||||
#endif /* PACKET_H_ */
|
||||
|
@ -21,6 +21,7 @@
|
||||
#ifndef PKI_H_
|
||||
#define PKI_H_
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#ifdef HAVE_OPENSSL_EC_H
|
||||
#include <openssl/ec.h>
|
||||
#endif
|
||||
@ -29,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/ed25519.h"
|
||||
|
||||
#define MAX_PUBKEY_SIZE 0x100000 /* 1M */
|
||||
#define MAX_PRIVKEY_SIZE 0x400000 /* 4M */
|
||||
@ -55,6 +57,8 @@ struct ssh_key_struct {
|
||||
void *ecdsa;
|
||||
#endif /* HAVE_OPENSSL_EC_H */
|
||||
#endif
|
||||
ed25519_pubkey *ed25519_pubkey;
|
||||
ed25519_privkey *ed25519_privkey;
|
||||
void *cert;
|
||||
};
|
||||
|
||||
@ -74,6 +78,7 @@ struct ssh_signature_struct {
|
||||
void *ecdsa_sig;
|
||||
# endif
|
||||
#endif
|
||||
ed25519_signature *ed25519_sig;
|
||||
};
|
||||
|
||||
typedef struct ssh_signature_struct *ssh_signature;
|
||||
|
@ -34,12 +34,15 @@ void _ssh_pki_log(const char *function,
|
||||
const char *format, ...) PRINTF_ATTRIBUTE(2, 3);
|
||||
|
||||
int pki_key_ecdsa_nid_from_name(const char *name);
|
||||
const char *pki_key_ecdsa_nid_to_name(int nid);
|
||||
|
||||
/* SSH Key Functions */
|
||||
ssh_key pki_key_dup(const ssh_key key, int demote);
|
||||
int pki_key_generate_rsa(ssh_key key, int parameter);
|
||||
int pki_key_generate_dss(ssh_key key, int parameter);
|
||||
int pki_key_generate_ecdsa(ssh_key key, int parameter);
|
||||
int pki_key_generate_ed25519(ssh_key key);
|
||||
|
||||
int pki_key_compare(const ssh_key k1,
|
||||
const ssh_key k2,
|
||||
enum ssh_keycmp_e what);
|
||||
@ -51,6 +54,11 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data);
|
||||
|
||||
ssh_string pki_private_key_to_pem(const ssh_key key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data);
|
||||
|
||||
/* SSH Public Key Functions */
|
||||
int pki_pubkey_build_dss(ssh_key key,
|
||||
ssh_string p,
|
||||
@ -85,4 +93,16 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
const unsigned char *hash,
|
||||
size_t hlen);
|
||||
int pki_ed25519_sign(const ssh_key privkey, ssh_signature sig,
|
||||
const unsigned char *hash, size_t hlen);
|
||||
int pki_ed25519_verify(const ssh_key pubkey, ssh_signature sig,
|
||||
const unsigned char *hash, size_t hlen);
|
||||
int pki_ed25519_key_cmp(const ssh_key k1,
|
||||
const ssh_key k2,
|
||||
enum ssh_keycmp_e what);
|
||||
int pki_ed25519_key_dup(ssh_key new, const ssh_key key);
|
||||
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key);
|
||||
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig);
|
||||
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob);
|
||||
|
||||
#endif /* PKI_PRIV_H_ */
|
||||
|
@ -120,11 +120,24 @@ int gettimeofday(struct timeval *__p, void *__t);
|
||||
#include "libssh/callbacks.h"
|
||||
|
||||
/* some constants */
|
||||
#ifndef MAX_PACKAT_LEN
|
||||
#define MAX_PACKET_LEN 262144
|
||||
#endif
|
||||
#ifndef ERROR_BUFFERLEN
|
||||
#define ERROR_BUFFERLEN 1024
|
||||
#endif
|
||||
#ifndef CLIENTBANNER1
|
||||
#define CLIENTBANNER1 "SSH-1.5-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#endif
|
||||
#ifndef CLIENTBANNER2
|
||||
#define CLIENTBANNER2 "SSH-2.0-libssh-" SSH_STRINGIFY(LIBSSH_VERSION)
|
||||
#endif
|
||||
#ifndef KBDINT_MAX_PROMPT
|
||||
#define KBDINT_MAX_PROMPT 256 /* more than openssh's :) */
|
||||
#endif
|
||||
#ifndef MAX_BUF_SIZE
|
||||
#define MAX_BUF_SIZE 4096
|
||||
#endif
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#if defined(__SUNPRO_C)
|
||||
@ -155,16 +168,6 @@ int gettimeofday(struct timeval *__p, void *__t);
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get rid of deprecacy warnings on OSX when using OpenSSL
|
||||
*/
|
||||
#if defined(__APPLE__)
|
||||
#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#undef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
#endif
|
||||
#define MAC_OS_X_VERSION_MIN_REQUIRED MAC_OS_X_VERSION_10_6
|
||||
#endif
|
||||
|
||||
/* forward declarations */
|
||||
struct ssh_common_struct;
|
||||
struct ssh_kex_struct;
|
||||
@ -275,7 +278,7 @@ int match_hostname(const char *host, const char *pattern, unsigned int len);
|
||||
/** Overwrite the buffer with '\0' */
|
||||
# define BURN_BUFFER(x, size) do { \
|
||||
if ((x) != NULL) \
|
||||
memset((x), '\0', (size)); __asm__ volatile("" : : "r"(&(x)) : "memory"); \
|
||||
memset((x), '\0', (size)); \
|
||||
} while(0)
|
||||
#endif /* HAVE_GCC_VOLATILE_MEMORY_PROTECTION */
|
||||
|
||||
|
74
libssh/include/libssh/sc25519.h
Normal file
74
libssh/include/libssh/sc25519.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* $OpenBSD: sc25519.h,v 1.3 2013/12/09 11:03:45 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/sc25519.h
|
||||
*/
|
||||
|
||||
#ifndef SC25519_H
|
||||
#define SC25519_H
|
||||
|
||||
#define sc25519 crypto_sign_ed25519_ref_sc25519
|
||||
#define shortsc25519 crypto_sign_ed25519_ref_shortsc25519
|
||||
#define sc25519_from32bytes crypto_sign_ed25519_ref_sc25519_from32bytes
|
||||
#define shortsc25519_from16bytes crypto_sign_ed25519_ref_shortsc25519_from16bytes
|
||||
#define sc25519_from64bytes crypto_sign_ed25519_ref_sc25519_from64bytes
|
||||
#define sc25519_from_shortsc crypto_sign_ed25519_ref_sc25519_from_shortsc
|
||||
#define sc25519_to32bytes crypto_sign_ed25519_ref_sc25519_to32bytes
|
||||
#define sc25519_iszero_vartime crypto_sign_ed25519_ref_sc25519_iszero_vartime
|
||||
#define sc25519_isshort_vartime crypto_sign_ed25519_ref_sc25519_isshort_vartime
|
||||
#define sc25519_lt_vartime crypto_sign_ed25519_ref_sc25519_lt_vartime
|
||||
#define sc25519_add crypto_sign_ed25519_ref_sc25519_add
|
||||
#define sc25519_sub_nored crypto_sign_ed25519_ref_sc25519_sub_nored
|
||||
#define sc25519_mul crypto_sign_ed25519_ref_sc25519_mul
|
||||
#define sc25519_mul_shortsc crypto_sign_ed25519_ref_sc25519_mul_shortsc
|
||||
#define sc25519_window3 crypto_sign_ed25519_ref_sc25519_window3
|
||||
#define sc25519_window5 crypto_sign_ed25519_ref_sc25519_window5
|
||||
#define sc25519_2interleave2 crypto_sign_ed25519_ref_sc25519_2interleave2
|
||||
|
||||
typedef struct {
|
||||
uint32_t v[32];
|
||||
} sc25519;
|
||||
|
||||
typedef struct {
|
||||
uint32_t v[16];
|
||||
} shortsc25519;
|
||||
|
||||
void sc25519_from32bytes(sc25519 *r, const unsigned char x[32]);
|
||||
|
||||
void shortsc25519_from16bytes(shortsc25519 *r, const unsigned char x[16]);
|
||||
|
||||
void sc25519_from64bytes(sc25519 *r, const unsigned char x[64]);
|
||||
|
||||
void sc25519_from_shortsc(sc25519 *r, const shortsc25519 *x);
|
||||
|
||||
void sc25519_to32bytes(unsigned char r[32], const sc25519 *x);
|
||||
|
||||
int sc25519_iszero_vartime(const sc25519 *x);
|
||||
|
||||
int sc25519_isshort_vartime(const sc25519 *x);
|
||||
|
||||
int sc25519_lt_vartime(const sc25519 *x, const sc25519 *y);
|
||||
|
||||
void sc25519_add(sc25519 *r, const sc25519 *x, const sc25519 *y);
|
||||
|
||||
void sc25519_sub_nored(sc25519 *r, const sc25519 *x, const sc25519 *y);
|
||||
|
||||
void sc25519_mul(sc25519 *r, const sc25519 *x, const sc25519 *y);
|
||||
|
||||
void sc25519_mul_shortsc(sc25519 *r, const sc25519 *x, const shortsc25519 *y);
|
||||
|
||||
/* Convert s into a representation of the form \sum_{i=0}^{84}r[i]2^3
|
||||
* with r[i] in {-4,...,3}
|
||||
*/
|
||||
void sc25519_window3(signed char r[85], const sc25519 *s);
|
||||
|
||||
/* Convert s into a representation of the form \sum_{i=0}^{50}r[i]2^5
|
||||
* with r[i] in {-16,...,15}
|
||||
*/
|
||||
void sc25519_window5(signed char r[51], const sc25519 *s);
|
||||
|
||||
void sc25519_2interleave2(unsigned char r[127], const sc25519 *s1, const sc25519 *s2);
|
||||
|
||||
#endif
|
@ -44,7 +44,8 @@ enum ssh_bind_options_e {
|
||||
SSH_BIND_OPTIONS_RSAKEY,
|
||||
SSH_BIND_OPTIONS_BANNER,
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY,
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR
|
||||
SSH_BIND_OPTIONS_LOG_VERBOSITY_STR,
|
||||
SSH_BIND_OPTIONS_ECDSAKEY
|
||||
};
|
||||
|
||||
typedef struct ssh_bind_struct* ssh_bind;
|
||||
@ -80,69 +81,6 @@ typedef struct ssh_bind_callbacks_struct *ssh_bind_callbacks;
|
||||
*/
|
||||
LIBSSH_API ssh_bind ssh_bind_new(void);
|
||||
|
||||
/**
|
||||
* @brief Set the options for the current SSH server bind.
|
||||
*
|
||||
* @param sshbind The ssh server bind to configure.
|
||||
*
|
||||
* @param type The option type to set. This could be one of the
|
||||
* following:
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BINDADDR
|
||||
* The ip address to bind (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BINDPORT
|
||||
* The port to bind (unsigned int).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BINDPORT_STR
|
||||
* The port to bind (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_HOSTKEY
|
||||
* This specifies the file containing the private host key used
|
||||
* by SSHv1. (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_DSAKEY
|
||||
* This specifies the file containing the private host dsa key
|
||||
* used by SSHv2. (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_RSAKEY
|
||||
* This specifies the file containing the private host dsa key
|
||||
* used by SSHv2. (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_BANNER
|
||||
* That the server banner (version string) for SSH.
|
||||
* (const char *).
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY
|
||||
* Set the session logging verbosity (int).\n
|
||||
* \n
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* - SSH_LOG_NOLOG: No logging
|
||||
* - SSH_LOG_RARE: Rare conditions or warnings
|
||||
* - SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* - SSH_LOG_PACKET: Packet id and size
|
||||
* - SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
*
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR
|
||||
* Set the session logging verbosity (const char *).\n
|
||||
* \n
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* - SSH_LOG_NOLOG: No logging
|
||||
* - SSH_LOG_RARE: Rare conditions or warnings
|
||||
* - SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* - SSH_LOG_PACKET: Packet id and size
|
||||
* - SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
* \n
|
||||
* See the corresponding numbers in libssh.h.
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
*
|
||||
* @returns SSH_OK on success, SSH_ERROR on invalid option or parameter.
|
||||
*/
|
||||
LIBSSH_API int ssh_bind_options_set(ssh_bind sshbind,
|
||||
enum ssh_bind_options_e type, const void *value);
|
||||
|
||||
|
@ -127,6 +127,15 @@ struct ssh_session_struct {
|
||||
struct ssh_agent_state_struct *agent_state;
|
||||
struct ssh_auth_auto_state_struct *auth_auto_state;
|
||||
|
||||
/*
|
||||
* RFC 4253, 7.1: if the first_kex_packet_follows flag was set in
|
||||
* the received SSH_MSG_KEXINIT, but the guess was wrong, this
|
||||
* field will be set such that the following guessed packet will
|
||||
* be ignored. Once that packet has been received and ignored,
|
||||
* this field is cleared.
|
||||
*/
|
||||
int first_kex_follows_guess_wrong;
|
||||
|
||||
ssh_buffer in_hashbuf;
|
||||
ssh_buffer out_hashbuf;
|
||||
struct ssh_crypto_struct *current_crypto;
|
||||
@ -175,6 +184,7 @@ struct ssh_session_struct {
|
||||
char *knownhosts;
|
||||
char *wanted_methods[10];
|
||||
char *ProxyCommand;
|
||||
char *custombanner;
|
||||
unsigned long timeout; /* seconds */
|
||||
unsigned long timeout_usec;
|
||||
unsigned int port;
|
||||
@ -183,7 +193,13 @@ struct ssh_session_struct {
|
||||
int ssh2;
|
||||
int ssh1;
|
||||
char compressionlevel;
|
||||
char *gss_server_identity;
|
||||
char *gss_client_identity;
|
||||
int gss_delegate_creds;
|
||||
} opts;
|
||||
/* counters */
|
||||
ssh_counter socket_counter;
|
||||
ssh_counter raw_counter;
|
||||
};
|
||||
|
||||
/** @internal
|
||||
|
@ -143,10 +143,10 @@ struct sftp_request_queue_struct {
|
||||
|
||||
/* SSH_FXP_MESSAGE described into .7 page 26 */
|
||||
struct sftp_status_message_struct {
|
||||
uint32_t id;
|
||||
uint32_t status;
|
||||
ssh_string error;
|
||||
ssh_string lang;
|
||||
uint32_t id;
|
||||
uint32_t status;
|
||||
ssh_string error_unused; /* not used anymore */
|
||||
ssh_string lang_unused; /* not used anymore */
|
||||
char *errormsg;
|
||||
char *langmsg;
|
||||
};
|
||||
|
@ -52,6 +52,7 @@ void ssh_socket_set_write_wontblock(ssh_socket s);
|
||||
void ssh_socket_set_read_wontblock(ssh_socket s);
|
||||
void ssh_socket_set_except(ssh_socket s);
|
||||
int ssh_socket_get_status(ssh_socket s);
|
||||
int ssh_socket_get_poll_flags(ssh_socket s);
|
||||
int ssh_socket_buffered_write_bytes(ssh_socket s);
|
||||
int ssh_socket_data_available(ssh_socket s);
|
||||
int ssh_socket_data_writable(ssh_socket s);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define WRAPPER_H_
|
||||
|
||||
#include "config.h"
|
||||
#include "libssh/libssh.h"
|
||||
#include "libssh/libcrypto.h"
|
||||
#include "libssh/libgcrypt.h"
|
||||
|
||||
@ -34,6 +35,9 @@ enum ssh_mac_e {
|
||||
|
||||
enum ssh_hmac_e {
|
||||
SSH_HMAC_SHA1 = 1,
|
||||
SSH_HMAC_SHA256,
|
||||
SSH_HMAC_SHA384,
|
||||
SSH_HMAC_SHA512,
|
||||
SSH_HMAC_MD5
|
||||
};
|
||||
|
||||
@ -42,16 +46,36 @@ enum ssh_des_e {
|
||||
SSH_DES
|
||||
};
|
||||
|
||||
struct ssh_hmac_struct {
|
||||
const char* name;
|
||||
enum ssh_hmac_e hmac_type;
|
||||
};
|
||||
|
||||
typedef struct ssh_mac_ctx_struct *ssh_mac_ctx;
|
||||
MD5CTX md5_init(void);
|
||||
void md5_update(MD5CTX c, const void *data, unsigned long len);
|
||||
void md5_final(unsigned char *md,MD5CTX c);
|
||||
|
||||
SHACTX sha1_init(void);
|
||||
void sha1_update(SHACTX c, const void *data, unsigned long len);
|
||||
void sha1_final(unsigned char *md,SHACTX c);
|
||||
void sha1(unsigned char *digest,int len,unsigned char *hash);
|
||||
|
||||
SHA256CTX sha256_init(void);
|
||||
void sha256_update(SHA256CTX c, const void *data, unsigned long len);
|
||||
void sha256_final(unsigned char *md,SHA256CTX c);
|
||||
void sha256(unsigned char *digest, int len, unsigned char *hash);
|
||||
|
||||
SHA384CTX sha384_init(void);
|
||||
void sha384_update(SHA384CTX c, const void *data, unsigned long len);
|
||||
void sha384_final(unsigned char *md,SHA384CTX c);
|
||||
void sha384(unsigned char *digest, int len, unsigned char *hash);
|
||||
|
||||
SHA512CTX sha512_init(void);
|
||||
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
|
||||
void sha512_final(unsigned char *md,SHA512CTX c);
|
||||
void sha512(unsigned char *digest, int len, unsigned char *hash);
|
||||
|
||||
void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen);
|
||||
EVPCTX evp_init(int nid);
|
||||
void evp_update(EVPCTX ctx, const void *data, unsigned long len);
|
||||
@ -64,11 +88,16 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx);
|
||||
HMACCTX hmac_init(const void *key,int len, enum ssh_hmac_e type);
|
||||
void hmac_update(HMACCTX c, const void *data, unsigned long len);
|
||||
void hmac_final(HMACCTX ctx,unsigned char *hashmacbuf,unsigned int *len);
|
||||
size_t hmac_digest_len(enum ssh_hmac_e type);
|
||||
|
||||
int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type);
|
||||
int crypt_set_algorithms_server(ssh_session session);
|
||||
struct ssh_crypto_struct *crypto_new(void);
|
||||
void crypto_free(struct ssh_crypto_struct *crypto);
|
||||
|
||||
void ssh_reseed(void);
|
||||
|
||||
struct ssh_hmac_struct *ssh_get_hmactab(void);
|
||||
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type);
|
||||
|
||||
#endif /* WRAPPER_H_ */
|
||||
|
@ -7,5 +7,7 @@ else()
|
||||
set(LIBSSH_INCLUDE_DIR @INCLUDE_INSTALL_DIR@)
|
||||
endif()
|
||||
|
||||
set(LIBSSH_LIRBARY @LIB_INSTALL_DIR@/libssh.so)
|
||||
set(LIBSSH_LIRBARIES @LIB_INSTALL_DIR@/libssh.so)
|
||||
set(LIBSSH_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
set(LIBSSH_LIBRARIES @LIB_INSTALL_DIR@/@LIBSSH_LIBRARY_NAME@)
|
||||
|
||||
set(LIBSSH_THREADS_LIBRARY @LIB_INSTALL_DIR@/@LIBSSH_THREADS_LIBRARY_NAME@)
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
# Script to build libssh on UNIX.
|
||||
#
|
||||
# Copyright (c) 2006-2007 Andreas Schneider <mail@cynapses.org>
|
||||
# Copyright (c) 2006-2007 Andreas Schneider <asn@cryptomilk.org>
|
||||
#
|
||||
|
||||
SOURCE_DIR=".."
|
@ -28,7 +28,7 @@ if (HAVE_LIBSOCKET)
|
||||
)
|
||||
endif (HAVE_LIBSOCKET)
|
||||
|
||||
if (OPENSSL_LIBRARIES)
|
||||
if (OPENSSL_CRYPTO_LIBRARIES)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
${LIBSSH_PRIVATE_INCLUDE_DIRS}
|
||||
${OPENSSL_INCLUDE_DIRS}
|
||||
@ -36,9 +36,9 @@ if (OPENSSL_LIBRARIES)
|
||||
|
||||
set(LIBSSH_LINK_LIBRARIES
|
||||
${LIBSSH_LINK_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${OPENSSL_CRYPTO_LIBRARIES}
|
||||
)
|
||||
endif (OPENSSL_LIBRARIES)
|
||||
endif (OPENSSL_CRYPTO_LIBRARIES)
|
||||
|
||||
if (GCRYPT_LIBRARY)
|
||||
set(LIBSSH_PRIVATE_INCLUDE_DIRS
|
||||
@ -109,6 +109,7 @@ set(libssh_SRCS
|
||||
agent.c
|
||||
auth.c
|
||||
base64.c
|
||||
bignum.c
|
||||
buffer.c
|
||||
callbacks.c
|
||||
channels.c
|
||||
@ -118,7 +119,10 @@ set(libssh_SRCS
|
||||
curve25519.c
|
||||
dh.c
|
||||
ecdh.c
|
||||
ed25519.c
|
||||
error.c
|
||||
fe25519.c
|
||||
ge25519.c
|
||||
getpass.c
|
||||
init.c
|
||||
kex.c
|
||||
@ -135,8 +139,10 @@ set(libssh_SRCS
|
||||
packet_crypt.c
|
||||
pcap.c
|
||||
pki.c
|
||||
pki_ed25519.c
|
||||
poll.c
|
||||
session.c
|
||||
sc25519.c
|
||||
scp.c
|
||||
socket.c
|
||||
string.c
|
||||
@ -288,6 +294,6 @@ if (WITH_STATIC_LIB)
|
||||
)
|
||||
endif (WITH_STATIC_LIB)
|
||||
|
||||
if (CMAKE_HAVE_THREADS_LIBRARY)
|
||||
if (Threads_FOUND)
|
||||
add_subdirectory(threads)
|
||||
endif (CMAKE_HAVE_THREADS_LIBRARY)
|
||||
endif (Threads_FOUND)
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2008-2009 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2008-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -300,7 +300,7 @@ static int agent_talk(struct ssh_session_struct *session,
|
||||
"Error reading response from authentication socket.");
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_data(reply, payload, n) < 0) {
|
||||
if (ssh_buffer_add_data(reply, payload, n) < 0) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Not enough space");
|
||||
return -1;
|
||||
}
|
||||
@ -393,7 +393,7 @@ int ssh_agent_get_ident_count(struct ssh_session_struct *session) {
|
||||
}
|
||||
|
||||
if (session->agent->ident) {
|
||||
buffer_reinit(session->agent->ident);
|
||||
ssh_buffer_reinit(session->agent->ident);
|
||||
}
|
||||
session->agent->ident = reply;
|
||||
|
||||
@ -526,7 +526,7 @@ ssh_string ssh_agent_sign_data(ssh_session session,
|
||||
ssh_buffer_free(request);
|
||||
return NULL;
|
||||
}
|
||||
if (buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
|
||||
if (ssh_buffer_add_data(request, buffer_get_rest(data), dlen) < 0) {
|
||||
ssh_buffer_free(request);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2011 by Aris Adamantiadis <aris@0xbadc0de.be>
|
||||
* Copyright (c) 2008-2011 Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis <aris@0xbadc0de.be>
|
||||
* Copyright (c) 2008-2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -182,25 +182,19 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_banner){
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){
|
||||
char *auth_methods = NULL;
|
||||
ssh_string auth;
|
||||
uint8_t partial = 0;
|
||||
int rc;
|
||||
(void) type;
|
||||
(void) user;
|
||||
|
||||
auth = buffer_get_ssh_string(packet);
|
||||
if (auth == NULL || buffer_get_u8(packet, &partial) != 1) {
|
||||
rc = ssh_buffer_unpack(packet, "sb", &auth_methods, &partial);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Invalid SSH_MSG_USERAUTH_FAILURE message");
|
||||
session->auth_state=SSH_AUTH_STATE_ERROR;
|
||||
goto end;
|
||||
}
|
||||
|
||||
auth_methods = ssh_string_to_char(auth);
|
||||
if (auth_methods == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (partial) {
|
||||
session->auth_state=SSH_AUTH_STATE_PARTIAL;
|
||||
SSH_LOG(SSH_LOG_INFO,
|
||||
@ -234,7 +228,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_failure){
|
||||
}
|
||||
|
||||
end:
|
||||
ssh_string_free(auth);
|
||||
SAFE_FREE(auth_methods);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
@ -359,7 +352,6 @@ int ssh_userauth_list(ssh_session session, const char *username)
|
||||
* before you connect to the server.
|
||||
*/
|
||||
int ssh_userauth_none(ssh_session session, const char *username) {
|
||||
ssh_string str;
|
||||
int rc;
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
@ -387,47 +379,12 @@ int ssh_userauth_none(ssh_session session, const char *username) {
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* username */
|
||||
if (username) {
|
||||
str = ssh_string_from_char(username);
|
||||
} else {
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
}
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* method */
|
||||
str = ssh_string_from_char("none");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsss",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
username ? username : session->opts.username,
|
||||
"ssh-connection",
|
||||
"none"
|
||||
);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -448,7 +405,7 @@ pending:
|
||||
return rc;
|
||||
fail:
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -485,7 +442,7 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
const char *username,
|
||||
const ssh_key pubkey)
|
||||
{
|
||||
ssh_string str;
|
||||
ssh_string pubkey_s = NULL;
|
||||
int rc;
|
||||
|
||||
if (session == NULL) {
|
||||
@ -522,82 +479,28 @@ int ssh_userauth_try_publickey(ssh_session session,
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* username */
|
||||
if (username) {
|
||||
str = ssh_string_from_char(username);
|
||||
} else {
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
}
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* method */
|
||||
str = ssh_string_from_char("publickey");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* private key? */
|
||||
rc = buffer_add_u8(session->out_buffer, 0);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* algo */
|
||||
str = ssh_string_from_char(pubkey->type_c);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* public key */
|
||||
rc = ssh_pki_export_pubkey_blob(pubkey, &str);
|
||||
rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
/* request */
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
username ? username : session->opts.username,
|
||||
"ssh-connection",
|
||||
"publickey",
|
||||
0, /* private key ? */
|
||||
pubkey->type_c, /* algo */
|
||||
pubkey_s /* public key */
|
||||
);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ssh_string_free(pubkey_s);
|
||||
|
||||
session->auth_state = SSH_AUTH_STATE_NONE;
|
||||
session->pending_call_state = SSH_PENDING_CALL_AUTH_OFFER_PUBKEY;
|
||||
rc = packet_send(session);
|
||||
@ -613,8 +516,9 @@ pending:
|
||||
|
||||
return rc;
|
||||
fail:
|
||||
ssh_string_free(pubkey_s);
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -647,7 +551,7 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
const char *username,
|
||||
const ssh_key privkey)
|
||||
{
|
||||
ssh_string str;
|
||||
ssh_string str = NULL;
|
||||
int rc;
|
||||
|
||||
if (session == NULL) {
|
||||
@ -684,81 +588,26 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* username */
|
||||
if (username) {
|
||||
str = ssh_string_from_char(username);
|
||||
} else {
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
}
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* method */
|
||||
str = ssh_string_from_char("publickey");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* private key? */
|
||||
rc = buffer_add_u8(session->out_buffer, 1);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* algo */
|
||||
str = ssh_string_from_char(privkey->type_c);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* public key */
|
||||
rc = ssh_pki_export_pubkey_blob(privkey, &str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
/* request */
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
username ? username : session->opts.username,
|
||||
"ssh-connection",
|
||||
"publickey",
|
||||
1, /* private key */
|
||||
privkey->type_c, /* algo */
|
||||
str /* public key */
|
||||
);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
|
||||
/* sign the buffer with the private key */
|
||||
str = ssh_pki_do_sign(session, session->out_buffer, privkey);
|
||||
@ -768,6 +617,7 @@ int ssh_userauth_publickey(ssh_session session,
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
str = NULL;
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -787,8 +637,9 @@ pending:
|
||||
|
||||
return rc;
|
||||
fail:
|
||||
ssh_string_free(str);
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -798,7 +649,7 @@ static int ssh_userauth_agent_publickey(ssh_session session,
|
||||
const char *username,
|
||||
ssh_key pubkey)
|
||||
{
|
||||
ssh_string str;
|
||||
ssh_string str = NULL;
|
||||
int rc;
|
||||
|
||||
switch(session->pending_call_state) {
|
||||
@ -820,69 +671,6 @@ static int ssh_userauth_agent_publickey(ssh_session session,
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* username */
|
||||
if (username) {
|
||||
str = ssh_string_from_char(username);
|
||||
} else {
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
}
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* method */
|
||||
str = ssh_string_from_char("publickey");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* private key? */
|
||||
rc = buffer_add_u8(session->out_buffer, 1);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* algo */
|
||||
str = ssh_string_from_char(pubkey->type_c);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* public key */
|
||||
rc = ssh_pki_export_pubkey_blob(pubkey, &str);
|
||||
@ -890,12 +678,22 @@ static int ssh_userauth_agent_publickey(ssh_session session,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
/* request */
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsssbsS",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
username ? username : session->opts.username,
|
||||
"ssh-connection",
|
||||
"publickey",
|
||||
1, /* private key */
|
||||
pubkey->type_c, /* algo */
|
||||
str /* public key */
|
||||
);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ssh_string_free(str);
|
||||
|
||||
/* sign the buffer with the private key */
|
||||
str = ssh_pki_do_sign_agent(session, session->out_buffer, pubkey);
|
||||
if (str == NULL) {
|
||||
@ -924,7 +722,8 @@ pending:
|
||||
return rc;
|
||||
fail:
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
ssh_string_free(str);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -1306,7 +1105,6 @@ int ssh_userauth_publickey_auto(ssh_session session,
|
||||
int ssh_userauth_password(ssh_session session,
|
||||
const char *username,
|
||||
const char *password) {
|
||||
ssh_string str;
|
||||
int rc;
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
@ -1336,65 +1134,14 @@ int ssh_userauth_password(ssh_session session,
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* username */
|
||||
if (username) {
|
||||
str = ssh_string_from_char(username);
|
||||
} else {
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
}
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* method */
|
||||
str = ssh_string_from_char("password");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* FALSE */
|
||||
rc = buffer_add_u8(session->out_buffer, 0);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* password */
|
||||
str = ssh_string_from_char(password);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsssbs",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
username ? username : session->opts.username,
|
||||
"ssh-connection",
|
||||
"password",
|
||||
0, /* false */
|
||||
password
|
||||
);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -1415,7 +1162,7 @@ pending:
|
||||
return rc;
|
||||
fail:
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -1536,7 +1283,6 @@ static int ssh_userauth_kbdint_init(ssh_session session,
|
||||
const char *username,
|
||||
const char *submethods)
|
||||
{
|
||||
ssh_string str;
|
||||
int rc;
|
||||
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_INIT)
|
||||
goto pending;
|
||||
@ -1552,78 +1298,18 @@ static int ssh_userauth_kbdint_init(ssh_session session,
|
||||
}
|
||||
|
||||
/* request */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bsssss",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
username ? username : session->opts.username,
|
||||
"ssh-connection",
|
||||
"keyboard-interactive",
|
||||
"", /* lang (ignore it) */
|
||||
submethods ? submethods : ""
|
||||
);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* username */
|
||||
if (username) {
|
||||
str = ssh_string_from_char(username);
|
||||
} else {
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
}
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* method */
|
||||
str = ssh_string_from_char("keyboard-interactive");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* lang string (ignore it) */
|
||||
str = ssh_string_from_char("");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* submethods */
|
||||
if (submethods == NULL) {
|
||||
submethods = "";
|
||||
}
|
||||
|
||||
str = ssh_string_from_char(submethods);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
session->auth_state = SSH_AUTH_STATE_KBDINT_SENT;
|
||||
session->pending_call_state = SSH_PENDING_CALL_AUTH_KBDINT_INIT;
|
||||
@ -1642,7 +1328,7 @@ pending:
|
||||
return rc;
|
||||
fail:
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -1660,7 +1346,6 @@ fail:
|
||||
*/
|
||||
static int ssh_userauth_kbdint_send(ssh_session session)
|
||||
{
|
||||
ssh_string answer;
|
||||
uint32_t i;
|
||||
int rc;
|
||||
if (session->pending_call_state == SSH_PENDING_CALL_AUTH_KBDINT_SEND)
|
||||
@ -1669,29 +1354,17 @@ static int ssh_userauth_kbdint_send(ssh_session session)
|
||||
ssh_set_error_invalid(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_INFO_RESPONSE);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->out_buffer, htonl(session->kbdint->nprompts));
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bd",
|
||||
SSH2_MSG_USERAUTH_INFO_RESPONSE,
|
||||
session->kbdint->nprompts);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < session->kbdint->nprompts; i++) {
|
||||
if (session->kbdint->answers && session->kbdint->answers[i]) {
|
||||
answer = ssh_string_from_char(session->kbdint->answers[i]);
|
||||
} else {
|
||||
answer = ssh_string_from_char("");
|
||||
}
|
||||
if (answer == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, answer);
|
||||
string_burn(answer);
|
||||
string_free(answer);
|
||||
rc = ssh_buffer_pack(session->out_buffer, "s",
|
||||
session->kbdint->answers && session->kbdint->answers[i] ?
|
||||
session->kbdint->answers[i]:"");
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -1716,7 +1389,7 @@ pending:
|
||||
return rc;
|
||||
fail:
|
||||
ssh_set_error_oom(session);
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
@ -1728,64 +1401,41 @@ fail:
|
||||
* authentication state.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
|
||||
ssh_string name; /* name of the "asking" window showed to client */
|
||||
ssh_string instruction;
|
||||
ssh_string tmp;
|
||||
ssh_string tmp = NULL;
|
||||
uint32_t nprompts;
|
||||
uint32_t i;
|
||||
int rc;
|
||||
(void)user;
|
||||
(void)type;
|
||||
|
||||
name = buffer_get_ssh_string(packet);
|
||||
instruction = buffer_get_ssh_string(packet);
|
||||
tmp = buffer_get_ssh_string(packet);
|
||||
buffer_get_u32(packet, &nprompts);
|
||||
|
||||
/* We don't care about tmp */
|
||||
ssh_string_free(tmp);
|
||||
|
||||
if (name == NULL || instruction == NULL) {
|
||||
ssh_string_free(name);
|
||||
ssh_string_free(instruction);
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
if (session->kbdint == NULL) {
|
||||
session->kbdint = ssh_kbdint_new();
|
||||
if (session->kbdint == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(name);
|
||||
ssh_string_free(instruction);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
} else {
|
||||
ssh_kbdint_clean(session->kbdint);
|
||||
}
|
||||
|
||||
session->kbdint->name = ssh_string_to_char(name);
|
||||
ssh_string_free(name);
|
||||
if (session->kbdint->name == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_kbdint_free(session->kbdint);
|
||||
ssh_string_free(instruction);
|
||||
rc = ssh_buffer_unpack(packet, "ssSd",
|
||||
&session->kbdint->name, /* name of the "asking" window shown to client */
|
||||
&session->kbdint->instruction,
|
||||
&tmp, /* to ignore */
|
||||
&nprompts
|
||||
);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
/* We don't care about tmp */
|
||||
ssh_string_free(tmp);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid USERAUTH_INFO_REQUEST msg");
|
||||
ssh_kbdint_free(session->kbdint);
|
||||
session->kbdint = NULL;
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
session->kbdint->instruction = ssh_string_to_char(instruction);
|
||||
ssh_string_free(instruction);
|
||||
if (session->kbdint->instruction == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_kbdint_free(session->kbdint);
|
||||
session->kbdint = NULL;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
nprompts = ntohl(nprompts);
|
||||
SSH_LOG(SSH_LOG_DEBUG,
|
||||
"%d keyboard-interactive prompts", nprompts);
|
||||
if (nprompts > KBDINT_MAX_PROMPT) {
|
||||
@ -1823,23 +1473,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_request) {
|
||||
memset(session->kbdint->echo, 0, nprompts);
|
||||
|
||||
for (i = 0; i < nprompts; i++) {
|
||||
tmp = buffer_get_ssh_string(packet);
|
||||
buffer_get_u8(packet, &session->kbdint->echo[i]);
|
||||
if (tmp == NULL) {
|
||||
rc = ssh_buffer_unpack(packet, "sb",
|
||||
&session->kbdint->prompts[i],
|
||||
&session->kbdint->echo[i]);
|
||||
if (rc == SSH_ERROR) {
|
||||
ssh_set_error(session, SSH_FATAL, "Short INFO_REQUEST packet");
|
||||
ssh_kbdint_free(session->kbdint);
|
||||
session->kbdint = NULL;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
session->kbdint->prompts[i] = ssh_string_to_char(tmp);
|
||||
ssh_string_free(tmp);
|
||||
if (session->kbdint->prompts[i] == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
session->kbdint->nprompts = i;
|
||||
ssh_kbdint_free(session->kbdint);
|
||||
session->kbdint = NULL;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
}
|
||||
|
@ -82,13 +82,18 @@ ssh_buffer base64_to_bin(const char *source) {
|
||||
SAFE_FREE(base64);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* The base64 buffer often contains sensitive data. Make sure we don't leak
|
||||
* sensitive data
|
||||
*/
|
||||
ssh_buffer_set_secure(buffer);
|
||||
|
||||
len = strlen(ptr);
|
||||
while (len > 4) {
|
||||
if (_base64_to_bin(block, ptr, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer, block, 3) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
len -= 4;
|
||||
@ -112,7 +117,7 @@ ssh_buffer base64_to_bin(const char *source) {
|
||||
if (_base64_to_bin(block, ptr, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer, block, 3) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, block, 3) < 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(base64);
|
||||
@ -131,7 +136,7 @@ ssh_buffer base64_to_bin(const char *source) {
|
||||
if (_base64_to_bin(block, ptr, 1) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer, block, 1) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, block, 1) < 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(base64);
|
||||
@ -149,7 +154,7 @@ ssh_buffer base64_to_bin(const char *source) {
|
||||
if (_base64_to_bin(block, ptr, 2) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buffer,block,2) < 0) {
|
||||
if (ssh_buffer_add_data(buffer,block,2) < 0) {
|
||||
goto error;
|
||||
}
|
||||
SAFE_FREE(base64);
|
||||
|
96
libssh/src/bignum.c
Normal file
96
libssh/src/bignum.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2014 by Aris Adamantiadis <aris@badcode.be>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/bignum.h"
|
||||
#include "libssh/string.h"
|
||||
|
||||
ssh_string make_bignum_string(bignum num) {
|
||||
ssh_string ptr = NULL;
|
||||
int pad = 0;
|
||||
unsigned int len = bignum_num_bytes(num);
|
||||
unsigned int bits = bignum_num_bits(num);
|
||||
|
||||
if (len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the first bit is set we have a negative number */
|
||||
if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) {
|
||||
pad++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
ptr = ssh_string_new(len + pad);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We have a negative number so we need a leading zero */
|
||||
if (pad) {
|
||||
ptr->data[0] = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bn2bin(num, len, ptr->data + pad);
|
||||
#elif HAVE_LIBCRYPTO
|
||||
bignum_bn2bin(num, ptr->data + pad);
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bignum make_string_bn(ssh_string string){
|
||||
bignum bn = NULL;
|
||||
unsigned int len = ssh_string_len(string);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
|
||||
len * 8, len);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bin2bn(string->data, len, &bn);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bn = bignum_bin2bn(string->data, len, NULL);
|
||||
#endif
|
||||
|
||||
return bn;
|
||||
}
|
||||
|
||||
/* prints the bignum on stderr */
|
||||
void ssh_print_bignum(const char *which, bignum num) {
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
unsigned char *hex = NULL;
|
||||
bignum_bn2hex(num, &hex);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
char *hex = NULL;
|
||||
hex = bignum_bn2hex(num);
|
||||
#endif
|
||||
fprintf(stderr, "%s value: ", which);
|
||||
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
|
||||
SAFE_FREE(hex);
|
||||
}
|
@ -144,26 +144,19 @@ ssh_bind ssh_bind_new(void) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int ssh_bind_listen(ssh_bind sshbind) {
|
||||
const char *host;
|
||||
socket_t fd;
|
||||
static int ssh_bind_import_keys(ssh_bind sshbind) {
|
||||
int rc;
|
||||
|
||||
if (ssh_init() < 0) {
|
||||
ssh_set_error(sshbind, SSH_FATAL, "ssh_init() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sshbind->ecdsakey == NULL &&
|
||||
sshbind->dsakey == NULL &&
|
||||
sshbind->rsakey == NULL) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"DSA or RSA host key file must be set before listen()");
|
||||
"ECDSA, DSA, or RSA host key file must be set");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
if (sshbind->ecdsakey) {
|
||||
if (sshbind->ecdsa == NULL && sshbind->ecdsakey != NULL) {
|
||||
rc = ssh_pki_import_privkey_file(sshbind->ecdsakey,
|
||||
NULL,
|
||||
NULL,
|
||||
@ -179,12 +172,13 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"The ECDSA host key has the wrong type");
|
||||
ssh_key_free(sshbind->ecdsa);
|
||||
sshbind->ecdsa = NULL;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sshbind->dsakey) {
|
||||
if (sshbind->dsa == NULL && sshbind->dsakey != NULL) {
|
||||
rc = ssh_pki_import_privkey_file(sshbind->dsakey,
|
||||
NULL,
|
||||
NULL,
|
||||
@ -201,11 +195,12 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
"The DSA host key has the wrong type: %d",
|
||||
ssh_key_type(sshbind->dsa));
|
||||
ssh_key_free(sshbind->dsa);
|
||||
sshbind->dsa = NULL;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (sshbind->rsakey) {
|
||||
if (sshbind->rsa == NULL && sshbind->rsakey != NULL) {
|
||||
rc = ssh_pki_import_privkey_file(sshbind->rsakey,
|
||||
NULL,
|
||||
NULL,
|
||||
@ -222,10 +217,29 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"The RSA host key has the wrong type");
|
||||
ssh_key_free(sshbind->rsa);
|
||||
sshbind->rsa = NULL;
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_bind_listen(ssh_bind sshbind) {
|
||||
const char *host;
|
||||
socket_t fd;
|
||||
int rc;
|
||||
|
||||
if (ssh_init() < 0) {
|
||||
ssh_set_error(sshbind, SSH_FATAL, "ssh_init() failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = ssh_bind_import_keys(sshbind);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (sshbind->bindfd == SSH_INVALID_SOCKET) {
|
||||
host = sshbind->bindaddr;
|
||||
if (host == NULL) {
|
||||
@ -235,10 +249,11 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
fd = bind_socket(sshbind, host, sshbind->bindport);
|
||||
if (fd == SSH_INVALID_SOCKET) {
|
||||
ssh_key_free(sshbind->dsa);
|
||||
sshbind->dsa = NULL;
|
||||
ssh_key_free(sshbind->rsa);
|
||||
sshbind->rsa = NULL;
|
||||
return -1;
|
||||
}
|
||||
sshbind->bindfd = fd;
|
||||
|
||||
if (listen(fd, 10) < 0) {
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
@ -246,9 +261,13 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
fd, strerror(errno));
|
||||
close(fd);
|
||||
ssh_key_free(sshbind->dsa);
|
||||
sshbind->dsa = NULL;
|
||||
ssh_key_free(sshbind->rsa);
|
||||
sshbind->rsa = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sshbind->bindfd = fd;
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_INFO, "Using app-provided bind socket");
|
||||
}
|
||||
@ -341,11 +360,18 @@ void ssh_bind_free(ssh_bind sshbind){
|
||||
|
||||
/* options */
|
||||
SAFE_FREE(sshbind->banner);
|
||||
SAFE_FREE(sshbind->bindaddr);
|
||||
|
||||
SAFE_FREE(sshbind->dsakey);
|
||||
SAFE_FREE(sshbind->rsakey);
|
||||
SAFE_FREE(sshbind->dsa);
|
||||
SAFE_FREE(sshbind->rsa);
|
||||
SAFE_FREE(sshbind->bindaddr);
|
||||
SAFE_FREE(sshbind->ecdsakey);
|
||||
|
||||
ssh_key_free(sshbind->dsa);
|
||||
sshbind->dsa = NULL;
|
||||
ssh_key_free(sshbind->rsa);
|
||||
sshbind->rsa = NULL;
|
||||
ssh_key_free(sshbind->ecdsa);
|
||||
sshbind->ecdsa = NULL;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (sshbind->wanted_methods[i]) {
|
||||
@ -357,7 +383,7 @@ void ssh_bind_free(ssh_bind sshbind){
|
||||
}
|
||||
|
||||
int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
int i;
|
||||
int i, rc;
|
||||
|
||||
if (session == NULL){
|
||||
ssh_set_error(sshbind, SSH_FATAL,"session is null");
|
||||
@ -368,7 +394,7 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
session->version = 2;
|
||||
|
||||
/* copy options */
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (sshbind->wanted_methods[i]) {
|
||||
session->opts.wanted_methods[i] = strdup(sshbind->wanted_methods[i]);
|
||||
if (session->opts.wanted_methods[i] == NULL) {
|
||||
@ -388,7 +414,8 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
}
|
||||
|
||||
session->common.log_verbosity = sshbind->common.log_verbosity;
|
||||
|
||||
if(sshbind->banner != NULL)
|
||||
session->opts.custombanner = strdup(sshbind->banner);
|
||||
ssh_socket_free(session->socket);
|
||||
session->socket = ssh_socket_new(session);
|
||||
if (session->socket == NULL) {
|
||||
@ -399,6 +426,16 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
ssh_socket_set_fd(session->socket, fd);
|
||||
ssh_socket_get_poll_handle_out(session->socket);
|
||||
|
||||
/* We must try to import any keys that could be imported in case
|
||||
* we are not using ssh_bind_listen (which is the other place
|
||||
* where keys can be imported) on this ssh_bind and are instead
|
||||
* only using ssh_bind_accept_fd to manage sockets ourselves.
|
||||
*/
|
||||
rc = ssh_bind_import_keys(sshbind);
|
||||
if (rc != SSH_OK) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECC
|
||||
if (sshbind->ecdsa) {
|
||||
session->srv.ecdsa_key = ssh_key_dup(sshbind->ecdsa);
|
||||
@ -422,6 +459,8 @@ int ssh_bind_accept_fd(ssh_bind sshbind, ssh_session session, socket_t fd){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
}
|
||||
/* force PRNG to change state in case we fork after ssh_bind_accept */
|
||||
ssh_reseed();
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <netinet/in.h>
|
||||
@ -32,6 +33,8 @@
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
/**
|
||||
* @defgroup libssh_buffer The SSH buffer functions.
|
||||
@ -104,13 +107,25 @@ void ssh_buffer_free(struct ssh_buffer_struct *buffer) {
|
||||
|
||||
if (buffer->data) {
|
||||
/* burn the data */
|
||||
memset(buffer->data, 0, buffer->allocated);
|
||||
BURN_BUFFER(buffer->data, buffer->allocated);
|
||||
SAFE_FREE(buffer->data);
|
||||
}
|
||||
memset(buffer, 'X', sizeof(*buffer));
|
||||
BURN_BUFFER(buffer, sizeof(struct ssh_buffer_struct));
|
||||
SAFE_FREE(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the buffer as secure.
|
||||
*
|
||||
* A secure buffer will never leave cleartext data in the heap
|
||||
* after being reallocated or freed.
|
||||
*
|
||||
* @param[in] buffer buffer to set secure.
|
||||
*/
|
||||
void ssh_buffer_set_secure(ssh_buffer buffer){
|
||||
buffer->secure = 1;
|
||||
}
|
||||
|
||||
static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
|
||||
size_t smallest = 1;
|
||||
char *new;
|
||||
@ -125,9 +140,20 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
|
||||
smallest <<= 1;
|
||||
}
|
||||
needed = smallest;
|
||||
new = realloc(buffer->data, needed);
|
||||
if (new == NULL) {
|
||||
return -1;
|
||||
if (buffer->secure){
|
||||
new = malloc(needed);
|
||||
if (new == NULL) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(new, buffer->data,buffer->used);
|
||||
BURN_BUFFER(buffer->data, buffer->used);
|
||||
SAFE_FREE(buffer->data);
|
||||
} else {
|
||||
new = realloc(buffer->data, needed);
|
||||
if (new == NULL) {
|
||||
buffer->data = NULL;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buffer->data = new;
|
||||
buffer->allocated = needed;
|
||||
@ -140,12 +166,20 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
|
||||
* @param buffer SSH buffer
|
||||
*/
|
||||
static void buffer_shift(ssh_buffer buffer){
|
||||
uint32_t burn_pos = buffer->pos;
|
||||
|
||||
buffer_verify(buffer);
|
||||
if(buffer->pos==0)
|
||||
return;
|
||||
memmove(buffer->data, buffer->data + buffer->pos, buffer->used - buffer->pos);
|
||||
buffer->used -= buffer->pos;
|
||||
buffer->pos=0;
|
||||
|
||||
if (buffer->secure){
|
||||
void *ptr = buffer->data + buffer->used;
|
||||
BURN_BUFFER(ptr, burn_pos);
|
||||
}
|
||||
|
||||
buffer_verify(buffer);
|
||||
}
|
||||
|
||||
@ -158,9 +192,10 @@ static void buffer_shift(ssh_buffer buffer){
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int buffer_reinit(struct ssh_buffer_struct *buffer) {
|
||||
int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
|
||||
{
|
||||
buffer_verify(buffer);
|
||||
memset(buffer->data, 0, buffer->used);
|
||||
BURN_BUFFER(buffer->data, buffer->used);
|
||||
buffer->used = 0;
|
||||
buffer->pos = 0;
|
||||
if(buffer->allocated > 127) {
|
||||
@ -185,7 +220,8 @@ int buffer_reinit(struct ssh_buffer_struct *buffer) {
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
*/
|
||||
int buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len) {
|
||||
int ssh_buffer_add_data(struct ssh_buffer_struct *buffer, const void *data, uint32_t len)
|
||||
{
|
||||
buffer_verify(buffer);
|
||||
|
||||
if (buffer->used + len < len) {
|
||||
@ -222,7 +258,7 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
|
||||
uint32_t len = 0;
|
||||
|
||||
len = ssh_string_len(string);
|
||||
if (buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, string, len + sizeof(uint32_t)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -240,12 +276,16 @@ int buffer_add_ssh_string(struct ssh_buffer_struct *buffer,
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
return 0;
|
||||
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,12 +299,16 @@ int buffer_add_u32(struct ssh_buffer_struct *buffer,uint32_t data){
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
return 0;
|
||||
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -278,12 +322,16 @@ int buffer_add_u16(struct ssh_buffer_struct *buffer,uint16_t data){
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(data)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
return 0;
|
||||
rc = ssh_buffer_add_data(buffer, &data, sizeof(data));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -297,12 +345,16 @@ int buffer_add_u64(struct ssh_buffer_struct *buffer, uint64_t data){
|
||||
*
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int buffer_add_u8(struct ssh_buffer_struct *buffer,uint8_t data){
|
||||
if (buffer_add_data(buffer, &data, sizeof(uint8_t)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
int buffer_add_u8(struct ssh_buffer_struct *buffer,uint8_t data)
|
||||
{
|
||||
int rc;
|
||||
|
||||
return 0;
|
||||
rc = ssh_buffer_add_data(buffer, &data, sizeof(uint8_t));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -360,12 +412,18 @@ int buffer_prepend_data(struct ssh_buffer_struct *buffer, const void *data,
|
||||
* @return 0 on success, -1 on error.
|
||||
*/
|
||||
int buffer_add_buffer(struct ssh_buffer_struct *buffer,
|
||||
struct ssh_buffer_struct *source) {
|
||||
if (buffer_add_data(buffer, buffer_get_rest(source), buffer_get_rest_len(source)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
struct ssh_buffer_struct *source)
|
||||
{
|
||||
int rc;
|
||||
|
||||
return 0;
|
||||
rc = ssh_buffer_add_data(buffer,
|
||||
buffer_get_rest(source),
|
||||
buffer_get_rest_len(source));
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -621,6 +679,318 @@ struct ssh_string_struct *buffer_get_mpint(struct ssh_buffer_struct *buffer) {
|
||||
return str;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief Add multiple values in a buffer on a single function call
|
||||
* @param[in] buffer The buffer to add to
|
||||
* @param[in] format A format string of arguments.
|
||||
* @param[in] ap A va_list of arguments.
|
||||
* @returns SSH_OK on success
|
||||
* SSH_ERROR on error
|
||||
* @see ssh_buffer_add_format() for format list values.
|
||||
*/
|
||||
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap){
|
||||
int rc = SSH_ERROR;
|
||||
const char *p;
|
||||
union {
|
||||
uint8_t byte;
|
||||
uint16_t word;
|
||||
uint32_t dword;
|
||||
uint64_t qword;
|
||||
ssh_string string;
|
||||
void *data;
|
||||
} o;
|
||||
char *cstring;
|
||||
bignum b;
|
||||
size_t len;
|
||||
|
||||
for (p = format; *p != '\0'; p++) {
|
||||
switch(*p) {
|
||||
case 'b':
|
||||
o.byte = (uint8_t)va_arg(ap, unsigned int);
|
||||
rc = buffer_add_u8(buffer, o.byte);
|
||||
break;
|
||||
case 'w':
|
||||
o.word = (uint16_t)va_arg(ap, unsigned int);
|
||||
o.word = htons(o.word);
|
||||
rc = buffer_add_u16(buffer, o.word);
|
||||
break;
|
||||
case 'd':
|
||||
o.dword = va_arg(ap, uint32_t);
|
||||
o.dword = htonl(o.dword);
|
||||
rc = buffer_add_u32(buffer, o.dword);
|
||||
break;
|
||||
case 'q':
|
||||
o.qword = va_arg(ap, uint64_t);
|
||||
o.qword = htonll(o.qword);
|
||||
rc = buffer_add_u64(buffer, o.qword);
|
||||
break;
|
||||
case 'S':
|
||||
o.string = va_arg(ap, ssh_string);
|
||||
rc = buffer_add_ssh_string(buffer, o.string);
|
||||
o.string = NULL;
|
||||
break;
|
||||
case 's':
|
||||
cstring = va_arg(ap, char *);
|
||||
len = strlen(cstring);
|
||||
rc = buffer_add_u32(buffer, htonl(len));
|
||||
if (rc == SSH_OK){
|
||||
rc = ssh_buffer_add_data(buffer, cstring, len);
|
||||
}
|
||||
cstring = NULL;
|
||||
break;
|
||||
case 'P':
|
||||
len = va_arg(ap, size_t);
|
||||
o.data = va_arg(ap, void *);
|
||||
rc = ssh_buffer_add_data(buffer, o.data, len);
|
||||
o.data = NULL;
|
||||
break;
|
||||
case 'B':
|
||||
b = va_arg(ap, bignum);
|
||||
o.string = make_bignum_string(b);
|
||||
if(o.string == NULL){
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buffer, o.string);
|
||||
SAFE_FREE(o.string);
|
||||
break;
|
||||
case 't':
|
||||
cstring = va_arg(ap, char *);
|
||||
len = strlen(cstring);
|
||||
rc = ssh_buffer_add_data(buffer, cstring, len);
|
||||
cstring = NULL;
|
||||
break;
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
if (rc != SSH_OK){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != SSH_ERROR){
|
||||
/* verify that the last hidden argument is correct */
|
||||
o.dword = va_arg(ap, uint32_t);
|
||||
if (o.dword != SSH_BUFFER_PACK_END){
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief Add multiple values in a buffer on a single function call
|
||||
* @param[in] buffer The buffer to add to
|
||||
* @param[in] format A format string of arguments. This string contains single
|
||||
* letters describing the order and type of arguments:
|
||||
* 'b': uint8_t (pushed in network byte order)
|
||||
* 'w': uint16_t (pushed in network byte order)
|
||||
* 'd': uint32_t (pushed in network byte order)
|
||||
* 'q': uint64_t (pushed in network byte order)
|
||||
* 'S': ssh_string
|
||||
* 's': char * (C string, pushed as SSH string)
|
||||
* 't': char * (C string, pushed as free text)
|
||||
* 'P': size_t, void * (len of data, pointer to data)
|
||||
* only pushes data.
|
||||
* 'B': bignum (pushed as SSH string)
|
||||
* @returns SSH_OK on success
|
||||
* SSH_ERROR on error
|
||||
* @warning when using 'P' with a constant size (e.g. 8), do not
|
||||
* forget to cast to (size_t).
|
||||
*/
|
||||
int _ssh_buffer_pack(struct ssh_buffer_struct *buffer, const char *format, ...){
|
||||
va_list ap;
|
||||
int rc;
|
||||
|
||||
va_start(ap, format);
|
||||
rc = ssh_buffer_pack_va(buffer, format, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief Get multiple values from a buffer on a single function call
|
||||
* @param[in] buffer The buffer to get from
|
||||
* @param[in] format A format string of arguments.
|
||||
* @param[in] ap A va_list of arguments.
|
||||
* @returns SSH_OK on success
|
||||
* SSH_ERROR on error
|
||||
* @see ssh_buffer_get_format() for format list values.
|
||||
*/
|
||||
int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer, const char *format, va_list ap){
|
||||
int rc = SSH_ERROR;
|
||||
const char *p, *last;
|
||||
union {
|
||||
uint8_t *byte;
|
||||
uint16_t *word;
|
||||
uint32_t *dword;
|
||||
uint64_t *qword;
|
||||
ssh_string *string;
|
||||
char **cstring;
|
||||
void **data;
|
||||
} o;
|
||||
size_t len, rlen;
|
||||
uint32_t u32len;
|
||||
va_list ap_copy;
|
||||
|
||||
/* copy the argument list in case a rollback is needed */
|
||||
va_copy(ap_copy, ap);
|
||||
|
||||
for (p = format; *p != '\0'; p++) {
|
||||
switch (*p) {
|
||||
case 'b':
|
||||
o.byte = va_arg(ap, uint8_t *);
|
||||
rlen = buffer_get_u8(buffer, o.byte);
|
||||
rc = rlen==1 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'w':
|
||||
o.word = va_arg(ap, uint16_t *);
|
||||
rlen = buffer_get_data(buffer, o.word, sizeof(uint16_t));
|
||||
*o.word = ntohs(*o.word);
|
||||
rc = rlen==2 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'd':
|
||||
o.dword = va_arg(ap, uint32_t *);
|
||||
rlen = buffer_get_u32(buffer, o.dword);
|
||||
*o.dword = ntohl(*o.dword);
|
||||
rc = rlen==4 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'q':
|
||||
o.qword = va_arg(ap, uint64_t*);
|
||||
rlen = buffer_get_u64(buffer, o.qword);
|
||||
*o.qword = ntohll(*o.qword);
|
||||
rc = rlen==8 ? SSH_OK : SSH_ERROR;
|
||||
break;
|
||||
case 'S':
|
||||
o.string = va_arg(ap, ssh_string *);
|
||||
*o.string = buffer_get_ssh_string(buffer);
|
||||
rc = *o.string != NULL ? SSH_OK : SSH_ERROR;
|
||||
o.string = NULL;
|
||||
break;
|
||||
case 's':
|
||||
o.cstring = va_arg(ap, char **);
|
||||
*o.cstring = NULL;
|
||||
rc = buffer_get_u32(buffer, &u32len);
|
||||
if (rc != 4){
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
len = ntohl(u32len);
|
||||
if (len > UINT_MAX - 1){
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
*o.cstring = malloc(len + 1);
|
||||
if (*o.cstring == NULL){
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
rlen = buffer_get_data(buffer, *o.cstring, len);
|
||||
if (rlen != len){
|
||||
SAFE_FREE(*o.cstring);
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
(*o.cstring)[len] = '\0';
|
||||
o.cstring = NULL;
|
||||
rc = SSH_OK;
|
||||
break;
|
||||
case 'P':
|
||||
len = va_arg(ap, size_t);
|
||||
o.data = va_arg(ap, void **);
|
||||
*o.data = malloc(len);
|
||||
if(*o.data == NULL){
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
rlen = buffer_get_data(buffer, *o.data, len);
|
||||
if (rlen != len){
|
||||
SAFE_FREE(*o.data);
|
||||
rc = SSH_ERROR;
|
||||
break;
|
||||
}
|
||||
o.data = NULL;
|
||||
rc = SSH_OK;
|
||||
break;
|
||||
default:
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid buffer format %c", *p);
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
if (rc != SSH_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc != SSH_ERROR){
|
||||
/* verify that the last hidden argument is correct */
|
||||
uint32_t canary = va_arg(ap, uint32_t);
|
||||
if (canary != SSH_BUFFER_PACK_END){
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
}
|
||||
if (rc != SSH_OK){
|
||||
/* Reset the format string and erase everything that was allocated */
|
||||
last = p;
|
||||
for(p=format;p<last;++p){
|
||||
switch(*p){
|
||||
case 'b':
|
||||
case 'w':
|
||||
case 'd':
|
||||
case 'q':
|
||||
(void)va_arg(ap_copy, void *);
|
||||
break;
|
||||
case 'S':
|
||||
o.string=va_arg(ap_copy, ssh_string *);
|
||||
SAFE_FREE(*o.string);
|
||||
break;
|
||||
case 's':
|
||||
o.cstring=va_arg(ap_copy, char **);
|
||||
SAFE_FREE(*o.cstring);
|
||||
break;
|
||||
case 'P':
|
||||
(void)va_arg(ap_copy, size_t);
|
||||
o.data = va_arg(ap_copy, void **);
|
||||
SAFE_FREE(*o.data);
|
||||
break;
|
||||
default:
|
||||
(void)va_arg(ap_copy, void *);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
va_end(ap_copy);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief Get multiple values from a buffer on a single function call
|
||||
* @param[in] buffer The buffer to get from
|
||||
* @param[in] format A format string of arguments. This string contains single
|
||||
* letters describing the order and type of arguments:
|
||||
* 'b': uint8_t * (pulled in network byte order)
|
||||
* 'w': uint16_t * (pulled in network byte order)
|
||||
* 'd': uint32_t * (pulled in network byte order)
|
||||
* 'q': uint64_t * (pulled in network byte order)
|
||||
* 'S': ssh_string *
|
||||
* 's': char ** (C string, pulled as SSH string)
|
||||
* 'P': size_t, void ** (len of data, pointer to data)
|
||||
* only pulls data.
|
||||
* @returns SSH_OK on success
|
||||
* SSH_ERROR on error
|
||||
* @warning when using 'P' with a constant size (e.g. 8), do not
|
||||
* forget to cast to (size_t).
|
||||
*/
|
||||
int _ssh_buffer_unpack(struct ssh_buffer_struct *buffer, const char *format, ...){
|
||||
va_list ap;
|
||||
int rc;
|
||||
|
||||
va_start(ap, format);
|
||||
rc = ssh_buffer_unpack_va(buffer, format, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/* vim: set ts=4 sw=4 et cindent: */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2009 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -356,7 +356,7 @@ int channel_write1(ssh_channel channel, const void *data, int len) {
|
||||
effectivelen = len > 32000 ? 32000 : len;
|
||||
|
||||
if (buffer_add_u32(session->out_buffer, htonl(effectivelen)) < 0 ||
|
||||
buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
|
||||
ssh_buffer_add_data(session->out_buffer, ptr, effectivelen) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -367,6 +367,9 @@ int channel_write1(ssh_channel channel, const void *data, int len) {
|
||||
return -1;
|
||||
}
|
||||
ssh_handle_packets(session, SSH_TIMEOUT_NONBLOCKING);
|
||||
if (channel->counter != NULL) {
|
||||
channel->counter->out_bytes += effectivelen;
|
||||
}
|
||||
}
|
||||
if (ssh_blocking_flush(session,SSH_TIMEOUT_USER) == SSH_ERROR)
|
||||
return -1;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -60,12 +60,15 @@
|
||||
static void socket_callback_connected(int code, int errno_code, void *user){
|
||||
ssh_session session=(ssh_session)user;
|
||||
|
||||
if(session->session_state != SSH_SESSION_STATE_CONNECTING){
|
||||
if (session->session_state != SSH_SESSION_STATE_CONNECTING &&
|
||||
session->session_state != SSH_SESSION_STATE_SOCKET_CONNECTED)
|
||||
{
|
||||
ssh_set_error(session,SSH_FATAL, "Wrong state in socket_callback_connected : %d",
|
||||
session->session_state);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE,"Socket connection callback: %d (%d)",code, errno_code);
|
||||
if(code == SSH_SOCKET_CONNECTED_OK)
|
||||
session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
@ -152,19 +155,27 @@ int ssh_send_banner(ssh_session session, int server) {
|
||||
banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2;
|
||||
|
||||
if (server) {
|
||||
session->serverbanner = strdup(banner);
|
||||
if(session->opts.custombanner == NULL){
|
||||
session->serverbanner = strdup(banner);
|
||||
} else {
|
||||
session->serverbanner = malloc(strlen(session->opts.custombanner) + 9);
|
||||
if(!session->serverbanner)
|
||||
goto end;
|
||||
strcpy(session->serverbanner, "SSH-2.0-");
|
||||
strcat(session->serverbanner, session->opts.custombanner);
|
||||
}
|
||||
if (session->serverbanner == NULL) {
|
||||
goto end;
|
||||
}
|
||||
snprintf(buffer, 128, "%s\n", session->serverbanner);
|
||||
} else {
|
||||
session->clientbanner = strdup(banner);
|
||||
if (session->clientbanner == NULL) {
|
||||
goto end;
|
||||
}
|
||||
snprintf(buffer, 128, "%s\n", session->clientbanner);
|
||||
}
|
||||
|
||||
snprintf(buffer, 128, "%s\n", banner);
|
||||
|
||||
if (ssh_socket_write(session->socket, buffer, strlen(buffer)) == SSH_ERROR) {
|
||||
goto end;
|
||||
}
|
||||
@ -258,24 +269,19 @@ static int ssh_service_request_termination(void *s){
|
||||
* @bug actually only works with ssh-userauth
|
||||
*/
|
||||
int ssh_service_request(ssh_session session, const char *service) {
|
||||
ssh_string service_s = NULL;
|
||||
int rc=SSH_ERROR;
|
||||
|
||||
if(session->auth_service_state != SSH_AUTH_SERVICE_NONE)
|
||||
goto pending;
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_SERVICE_REQUEST) < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
service_s = ssh_string_from_char(service);
|
||||
if (service_s == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(session->out_buffer,service_s) < 0) {
|
||||
ssh_string_free(service_s);
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bs",
|
||||
SSH2_MSG_SERVICE_REQUEST,
|
||||
service);
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ssh_string_free(service_s);
|
||||
session->auth_service_state=SSH_AUTH_SERVICE_SENT;
|
||||
if (packet_send(session) == SSH_ERROR) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
@ -495,7 +501,12 @@ int ssh_connect(ssh_session session) {
|
||||
ssh_set_error(session, SSH_FATAL, "Couldn't apply options");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
SSH_LOG(SSH_LOG_RARE,"libssh %s, using threading %s", ssh_copyright(), ssh_threads_get_type());
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,
|
||||
"libssh %s, using threading %s",
|
||||
ssh_copyright(),
|
||||
ssh_threads_get_type());
|
||||
|
||||
session->ssh_connection_callback = ssh_client_connection_callback;
|
||||
session->session_state=SSH_SESSION_STATE_CONNECTING;
|
||||
ssh_socket_set_callbacks(session->socket,&session->socket_callbacks);
|
||||
@ -504,6 +515,7 @@ int ssh_connect(ssh_session session) {
|
||||
session->socket_callbacks.exception=ssh_socket_exception_callback;
|
||||
session->socket_callbacks.userdata=session;
|
||||
if (session->opts.fd != SSH_INVALID_SOCKET) {
|
||||
session->session_state=SSH_SESSION_STATE_SOCKET_CONNECTED;
|
||||
ssh_socket_set_fd(session->socket, session->opts.fd);
|
||||
ret=SSH_OK;
|
||||
#ifndef _WIN32
|
||||
@ -535,7 +547,8 @@ pending:
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET,"Actual timeout : %d", timeout);
|
||||
ret = ssh_handle_packets_termination(session, timeout, ssh_connect_termination, session);
|
||||
if (ret == SSH_ERROR || !ssh_connect_termination(session)) {
|
||||
if (session->session_state != SSH_SESSION_STATE_ERROR &&
|
||||
(ret == SSH_ERROR || !ssh_connect_termination(session))) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Timeout connecting to %s", session->opts.host);
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
@ -612,32 +625,23 @@ int ssh_get_openssh_version(ssh_session session) {
|
||||
* @param[in] session The SSH session to use.
|
||||
*/
|
||||
void ssh_disconnect(ssh_session session) {
|
||||
ssh_string str = NULL;
|
||||
struct ssh_iterator *it;
|
||||
int rc;
|
||||
|
||||
if (session == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (session->socket != NULL && ssh_socket_is_open(session->socket)) {
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_DISCONNECT) < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bds",
|
||||
SSH2_MSG_DISCONNECT,
|
||||
SSH2_DISCONNECT_BY_APPLICATION,
|
||||
"Bye Bye");
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer,
|
||||
htonl(SSH2_DISCONNECT_BY_APPLICATION)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
str = ssh_string_from_char("Bye Bye");
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(session->out_buffer,str) < 0) {
|
||||
ssh_string_free(str);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
|
||||
packet_send(session);
|
||||
ssh_socket_close(session->socket);
|
||||
@ -651,21 +655,25 @@ error:
|
||||
session->session_state=SSH_SESSION_STATE_DISCONNECTED;
|
||||
|
||||
while ((it=ssh_list_get_iterator(session->channels)) != NULL) {
|
||||
ssh_channel_free(ssh_iterator_value(ssh_channel,it));
|
||||
ssh_channel_do_free(ssh_iterator_value(ssh_channel,it));
|
||||
ssh_list_remove(session->channels, it);
|
||||
}
|
||||
if(session->current_crypto){
|
||||
crypto_free(session->current_crypto);
|
||||
session->current_crypto=NULL;
|
||||
}
|
||||
if(session->in_buffer)
|
||||
buffer_reinit(session->in_buffer);
|
||||
if(session->out_buffer)
|
||||
buffer_reinit(session->out_buffer);
|
||||
if(session->in_hashbuf)
|
||||
buffer_reinit(session->in_hashbuf);
|
||||
if(session->out_hashbuf)
|
||||
buffer_reinit(session->out_hashbuf);
|
||||
if (session->in_buffer) {
|
||||
ssh_buffer_reinit(session->in_buffer);
|
||||
}
|
||||
if (session->out_buffer) {
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
}
|
||||
if (session->in_hashbuf) {
|
||||
ssh_buffer_reinit(session->in_hashbuf);
|
||||
}
|
||||
if (session->out_hashbuf) {
|
||||
ssh_buffer_reinit(session->out_hashbuf);
|
||||
}
|
||||
session->auth_methods = 0;
|
||||
SAFE_FREE(session->serverbanner);
|
||||
SAFE_FREE(session->clientbanner);
|
||||
@ -687,8 +695,8 @@ error:
|
||||
}
|
||||
|
||||
const char *ssh_copyright(void) {
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2010 Aris Adamantiadis "
|
||||
"(aris@0xbadc0de.be) Distributed under the LGPL, please refer to COPYING "
|
||||
return SSH_STRINGIFY(LIBSSH_VERSION) " (c) 2003-2014 Aris Adamantiadis, Andreas Schneider, "
|
||||
"and libssh contributors. Distributed under the LGPL, please refer to COPYING "
|
||||
"file for information about your rights";
|
||||
}
|
||||
/** @} */
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -46,7 +46,10 @@ enum ssh_config_opcode_e {
|
||||
SOC_PROTOCOL,
|
||||
SOC_STRICTHOSTKEYCHECK,
|
||||
SOC_KNOWNHOSTS,
|
||||
SOC_PROXYCOMMAND
|
||||
SOC_PROXYCOMMAND,
|
||||
SOC_GSSAPISERVERIDENTITY,
|
||||
SOC_GSSAPICLIENTIDENTITY,
|
||||
SOC_GSSAPIDELEGATECREDENTIALS,
|
||||
};
|
||||
|
||||
struct ssh_config_keyword_table_s {
|
||||
@ -67,6 +70,9 @@ static struct ssh_config_keyword_table_s ssh_config_keyword_table[] = {
|
||||
{ "stricthostkeychecking", SOC_STRICTHOSTKEYCHECK },
|
||||
{ "userknownhostsfile", SOC_KNOWNHOSTS },
|
||||
{ "proxycommand", SOC_PROXYCOMMAND },
|
||||
{ "gssapiserveridentity", SOC_GSSAPISERVERIDENTITY },
|
||||
{ "gssapiserveridentity", SOC_GSSAPICLIENTIDENTITY },
|
||||
{ "gssapidelegatecredentials", SOC_GSSAPIDELEGATECREDENTIALS },
|
||||
{ NULL, SOC_UNSUPPORTED }
|
||||
};
|
||||
|
||||
@ -213,16 +219,25 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
|
||||
switch (opcode) {
|
||||
case SOC_HOST:
|
||||
*parsing = 0;
|
||||
lowerhost = (session->opts.host) ? ssh_lowercase(session->opts.host) : NULL;
|
||||
for (p = ssh_config_get_str_tok(&s, NULL); p && *p;
|
||||
p = ssh_config_get_str_tok(&s, NULL)) {
|
||||
if (match_hostname(lowerhost, p, strlen(p))) {
|
||||
*parsing = 1;
|
||||
*parsing = 0;
|
||||
lowerhost = (session->opts.host) ? ssh_lowercase(session->opts.host) : NULL;
|
||||
for (p = ssh_config_get_str_tok(&s, NULL);
|
||||
p != NULL && p[0] != '\0';
|
||||
p = ssh_config_get_str_tok(&s, NULL)) {
|
||||
char *z = ssh_path_expand_escape(session, p);
|
||||
int ok;
|
||||
|
||||
if (z == NULL) {
|
||||
z = strdup(p);
|
||||
}
|
||||
ok = match_hostname(lowerhost, z, strlen(z));
|
||||
if (ok) {
|
||||
*parsing = 1;
|
||||
}
|
||||
free(z);
|
||||
}
|
||||
}
|
||||
SAFE_FREE(lowerhost);
|
||||
break;
|
||||
SAFE_FREE(lowerhost);
|
||||
break;
|
||||
case SOC_HOSTNAME:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
@ -323,6 +338,24 @@ static int ssh_config_parse_line(ssh_session session, const char *line,
|
||||
ssh_options_set(session, SSH_OPTIONS_PROXYCOMMAND, p);
|
||||
}
|
||||
break;
|
||||
case SOC_GSSAPISERVERIDENTITY:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
ssh_options_set(session, SSH_OPTIONS_GSSAPI_SERVER_IDENTITY, p);
|
||||
}
|
||||
break;
|
||||
case SOC_GSSAPICLIENTIDENTITY:
|
||||
p = ssh_config_get_str_tok(&s, NULL);
|
||||
if (p && *parsing) {
|
||||
ssh_options_set(session, SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY, p);
|
||||
}
|
||||
break;
|
||||
case SOC_GSSAPIDELEGATECREDENTIALS:
|
||||
i = ssh_config_get_yesno(&s, -1);
|
||||
if (i >=0 && *parsing) {
|
||||
ssh_options_set(session, SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS, &i);
|
||||
}
|
||||
break;
|
||||
case SOC_UNSUPPORTED:
|
||||
SSH_LOG(SSH_LOG_RARE, "Unsupported option: %s, line: %d\n",
|
||||
keyword, count);
|
||||
@ -350,7 +383,7 @@ int ssh_config_parse_file(ssh_session session, const char *filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE, "Reading configuration data from %s", filename);
|
||||
SSH_LOG(SSH_LOG_PACKET, "Reading configuration data from %s", filename);
|
||||
|
||||
parsing = 1;
|
||||
while (fgets(line, sizeof(line), f)) {
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -382,7 +382,15 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
||||
continue;
|
||||
}
|
||||
|
||||
connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||
if (rc == -1 && (errno != EINPROGRESS)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Failed to connect: %s", strerror(errno));
|
||||
ssh_connect_socket_close(s);
|
||||
s = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -421,7 +429,7 @@ static int ssh_select_cb (socket_t fd, int revents, void *userdata){
|
||||
* @param[in] readfds A fd_set of file descriptors to be select'ed for
|
||||
* reading.
|
||||
*
|
||||
* @param[in] timeout A timeout for the select.
|
||||
* @param[in] timeout The timeout in milliseconds.
|
||||
*
|
||||
* @return SSH_OK on success,
|
||||
* SSH_ERROR on error,
|
||||
|
@ -37,19 +37,14 @@
|
||||
#include "libssh/crypto.h"
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
/** @internal
|
||||
* @brief Starts curve25519-sha256@libssh.org key exchange
|
||||
*/
|
||||
int ssh_client_curve25519_init(ssh_session session){
|
||||
ssh_string client_pubkey;
|
||||
int rc;
|
||||
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
|
||||
if (rc == 0){
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
@ -58,15 +53,14 @@ int ssh_client_curve25519_init(ssh_session session){
|
||||
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
client_pubkey = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||
if (client_pubkey == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
ssh_string_fill(client_pubkey, session->next_crypto->curve25519_client_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
rc = buffer_add_ssh_string(session->out_buffer,client_pubkey);
|
||||
if (rc < 0) {
|
||||
ssh_string_free(client_pubkey);
|
||||
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_KEX_ECDH_INIT,
|
||||
CURVE25519_PUBKEY_SIZE,
|
||||
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@ -90,7 +84,7 @@ static int ssh_curve25519_build_k(ssh_session session) {
|
||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||
session->next_crypto->curve25519_server_pubkey);
|
||||
|
||||
BN_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, session->next_crypto->k);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Session server cookie",
|
||||
@ -133,6 +127,7 @@ int ssh_client_curve25519_reply(ssh_session session, ssh_buffer packet){
|
||||
goto error;
|
||||
}
|
||||
memcpy(session->next_crypto->curve25519_server_pubkey, ssh_string_data(q_s_string), CURVE25519_PUBKEY_SIZE);
|
||||
ssh_string_free(q_s_string);
|
||||
|
||||
signature = buffer_get_ssh_string(packet);
|
||||
if (signature == NULL) {
|
||||
@ -194,44 +189,36 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
||||
|
||||
rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
|
||||
if (rc == 0){
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
return SSH_ERROR;
|
||||
ssh_set_error(session, SSH_FATAL, "PRNG error");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
|
||||
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||
if (q_s_string == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
ssh_string_fill(q_s_string, session->next_crypto->curve25519_server_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* build k and session_id */
|
||||
rc = ssh_curve25519_build_k(session);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Cannot build k number");
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* privkey is not allocated */
|
||||
rc = ssh_get_key_params(session, &privkey);
|
||||
if (rc == SSH_ERROR) {
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = make_sessionid(session);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not create a session id");
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* add host's public key */
|
||||
@ -239,29 +226,37 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
||||
session->next_crypto->server_pubkey);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* add ecdh public key */
|
||||
q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
|
||||
if (q_s_string == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_string_fill(q_s_string,
|
||||
session->next_crypto->curve25519_server_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, q_s_string);
|
||||
ssh_string_free(q_s_string);
|
||||
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
/* add signature blob */
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, sig_blob);
|
||||
ssh_string_free(sig_blob);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_ECDH_REPLY sent");
|
||||
@ -273,7 +268,7 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
||||
/* Send the MSG_NEWKEYS */
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;;
|
||||
goto error;
|
||||
}
|
||||
|
||||
session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
|
||||
@ -281,6 +276,9 @@ int ssh_server_curve25519_init(ssh_session session, ssh_buffer packet){
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
|
||||
|
||||
return rc;
|
||||
error:
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
|
532
libssh/src/dh.c
532
libssh/src/dh.c
@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2012 by Dmitriy Kuznetsov <dk@yandex.ru>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
@ -60,6 +60,7 @@
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
/* todo: remove it */
|
||||
#include "libssh/string.h"
|
||||
@ -170,7 +171,7 @@ int ssh_crypto_init(void) {
|
||||
return -1;
|
||||
}
|
||||
bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &p_group14);
|
||||
if (p_group1 == NULL) {
|
||||
if (p_group14 == NULL) {
|
||||
bignum_free(g);
|
||||
bignum_free(p_group1);
|
||||
g = NULL;
|
||||
@ -225,20 +226,6 @@ void ssh_crypto_finalize(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* prints the bignum on stderr */
|
||||
void ssh_print_bignum(const char *which, bignum num) {
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
unsigned char *hex = NULL;
|
||||
bignum_bn2hex(num, &hex);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
char *hex = NULL;
|
||||
hex = bignum_bn2hex(num);
|
||||
#endif
|
||||
fprintf(stderr, "%s value: ", which);
|
||||
fprintf(stderr, "%s\n", (hex == NULL) ? "(null)" : (char *) hex);
|
||||
SAFE_FREE(hex);
|
||||
}
|
||||
|
||||
int dh_generate_x(ssh_session session) {
|
||||
session->next_crypto->x = bignum_new();
|
||||
if (session->next_crypto->x == NULL) {
|
||||
@ -351,62 +338,6 @@ int dh_generate_f(ssh_session session) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssh_string make_bignum_string(bignum num) {
|
||||
ssh_string ptr = NULL;
|
||||
int pad = 0;
|
||||
unsigned int len = bignum_num_bytes(num);
|
||||
unsigned int bits = bignum_num_bits(num);
|
||||
|
||||
if (len == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the first bit is set we have a negative number */
|
||||
if (!(bits % 8) && bignum_is_bit_set(num, bits - 1)) {
|
||||
pad++;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "%d bits, %d bytes, %d padding\n", bits, len, pad);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
ptr = ssh_string_new(len + pad);
|
||||
if (ptr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We have a negative number so we need a leading zero */
|
||||
if (pad) {
|
||||
ptr->data[0] = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bn2bin(num, len, ptr->data + pad);
|
||||
#elif HAVE_LIBCRYPTO
|
||||
bignum_bn2bin(num, ptr->data + pad);
|
||||
#endif
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bignum make_string_bn(ssh_string string){
|
||||
bignum bn = NULL;
|
||||
unsigned int len = ssh_string_len(string);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
fprintf(stderr, "Importing a %d bits, %d bytes object ...\n",
|
||||
len * 8, len);
|
||||
#endif /* DEBUG_CRYPTO */
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bin2bn(string->data, len, &bn);
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bn = bignum_bin2bn(string->data, len, NULL);
|
||||
#endif
|
||||
|
||||
return bn;
|
||||
}
|
||||
|
||||
ssh_string dh_get_e(ssh_session session) {
|
||||
return make_bignum_string(session->next_crypto->e);
|
||||
}
|
||||
@ -504,10 +435,6 @@ int ssh_client_dh_init(ssh_session session){
|
||||
ssh_string e = NULL;
|
||||
int rc;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_INIT) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dh_generate_x(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
@ -520,9 +447,11 @@ int ssh_client_dh_init(ssh_session session){
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(session->out_buffer, e) < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer, "bS", SSH2_MSG_KEXDH_INIT, e);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_string_burn(e);
|
||||
ssh_string_free(e);
|
||||
e=NULL;
|
||||
@ -587,218 +516,180 @@ error:
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
static void sha_add(ssh_string str,SHACTX ctx){
|
||||
sha1_update(ctx,str,string_len(str)+4);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("partial hashed sessionid",str,string_len(str)+4);
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
int make_sessionid(ssh_session session) {
|
||||
ssh_string num = NULL;
|
||||
ssh_string str = NULL;
|
||||
ssh_buffer server_hash = NULL;
|
||||
ssh_buffer client_hash = NULL;
|
||||
ssh_buffer buf = NULL;
|
||||
uint32_t len;
|
||||
int rc = SSH_ERROR;
|
||||
ssh_string num = NULL;
|
||||
ssh_buffer server_hash = NULL;
|
||||
ssh_buffer client_hash = NULL;
|
||||
ssh_buffer buf = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
buf = ssh_buffer_new();
|
||||
if (buf == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
str = ssh_string_from_char(session->clientbanner);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(buf, str) < 0) {
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
|
||||
str = ssh_string_from_char(session->serverbanner);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(buf, str) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (session->client) {
|
||||
server_hash = session->in_hashbuf;
|
||||
client_hash = session->out_hashbuf;
|
||||
} else {
|
||||
server_hash = session->out_hashbuf;
|
||||
client_hash = session->in_hashbuf;
|
||||
}
|
||||
|
||||
if (buffer_add_u32(server_hash, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u8(server_hash, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u32(client_hash, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u8(client_hash, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
len = ntohl(buffer_get_rest_len(client_hash));
|
||||
if (buffer_add_u32(buf,len) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buf, buffer_get_rest(client_hash),
|
||||
buffer_get_rest_len(client_hash)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
len = ntohl(buffer_get_rest_len(server_hash));
|
||||
if (buffer_add_u32(buf, len) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(buf, buffer_get_rest(server_hash),
|
||||
buffer_get_rest_len(server_hash)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
len = ssh_string_len(session->next_crypto->server_pubkey) + 4;
|
||||
if (buffer_add_data(buf, session->next_crypto->server_pubkey, len) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if(session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1 ||
|
||||
session->next_crypto->kex_type == SSH_KEX_DH_GROUP14_SHA1) {
|
||||
|
||||
num = make_bignum_string(session->next_crypto->e);
|
||||
if (num == NULL) {
|
||||
goto error;
|
||||
buf = ssh_buffer_new();
|
||||
if (buf == NULL) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
len = ssh_string_len(num) + 4;
|
||||
if (buffer_add_data(buf, num, len) < 0) {
|
||||
goto error;
|
||||
rc = ssh_buffer_pack(buf,
|
||||
"ss",
|
||||
session->clientbanner,
|
||||
session->serverbanner);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_string_free(num);
|
||||
num = make_bignum_string(session->next_crypto->f);
|
||||
if (num == NULL) {
|
||||
goto error;
|
||||
if (session->client) {
|
||||
server_hash = session->in_hashbuf;
|
||||
client_hash = session->out_hashbuf;
|
||||
} else {
|
||||
server_hash = session->out_hashbuf;
|
||||
client_hash = session->in_hashbuf;
|
||||
}
|
||||
|
||||
len = ssh_string_len(num) + 4;
|
||||
if (buffer_add_data(buf, num, len) < 0) {
|
||||
goto error;
|
||||
/*
|
||||
* Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
|
||||
*
|
||||
* boolean first_kex_packet_follows
|
||||
* uint32 0 (reserved for future extension)
|
||||
*/
|
||||
rc = buffer_add_u8(server_hash, 0);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
rc = buffer_add_u32(server_hash, 0);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
ssh_string_free(num);
|
||||
/* These fields are handled for the server case in ssh_packet_kexinit. */
|
||||
if (session->client) {
|
||||
rc = buffer_add_u8(client_hash, 0);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
rc = buffer_add_u32(client_hash, 0);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(buf,
|
||||
"dPdPS",
|
||||
buffer_get_rest_len(client_hash),
|
||||
buffer_get_rest_len(client_hash),
|
||||
buffer_get_rest(client_hash),
|
||||
buffer_get_rest_len(server_hash),
|
||||
buffer_get_rest_len(server_hash),
|
||||
buffer_get_rest(server_hash),
|
||||
session->next_crypto->server_pubkey);
|
||||
|
||||
if(rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1 ||
|
||||
session->next_crypto->kex_type == SSH_KEX_DH_GROUP14_SHA1) {
|
||||
rc = ssh_buffer_pack(buf,
|
||||
"BB",
|
||||
session->next_crypto->e,
|
||||
session->next_crypto->f);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef HAVE_ECDH
|
||||
} else if (session->next_crypto->kex_type == SSH_KEX_ECDH_SHA2_NISTP256){
|
||||
if(session->next_crypto->ecdh_client_pubkey == NULL ||
|
||||
session->next_crypto->ecdh_server_pubkey == NULL){
|
||||
SSH_LOG(SSH_LOG_WARNING, "ECDH parameted missing");
|
||||
goto error;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buf,session->next_crypto->ecdh_client_pubkey);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buf,session->next_crypto->ecdh_server_pubkey);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else if (session->next_crypto->kex_type == SSH_KEX_ECDH_SHA2_NISTP256) {
|
||||
if (session->next_crypto->ecdh_client_pubkey == NULL ||
|
||||
session->next_crypto->ecdh_server_pubkey == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "ECDH parameted missing");
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_buffer_pack(buf,
|
||||
"SS",
|
||||
session->next_crypto->ecdh_client_pubkey,
|
||||
session->next_crypto->ecdh_server_pubkey);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_CURVE25519
|
||||
} else if(session->next_crypto->kex_type == SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG){
|
||||
rc = buffer_add_u32(buf, htonl(CURVE25519_PUBKEY_SIZE));
|
||||
rc += buffer_add_data(buf, session->next_crypto->curve25519_client_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
rc += buffer_add_u32(buf, htonl(CURVE25519_PUBKEY_SIZE));
|
||||
rc += buffer_add_data(buf, session->next_crypto->curve25519_server_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
num = make_bignum_string(session->next_crypto->k);
|
||||
if (num == NULL) {
|
||||
goto error;
|
||||
}
|
||||
} else if (session->next_crypto->kex_type == SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG) {
|
||||
rc = ssh_buffer_pack(buf,
|
||||
"dPdP",
|
||||
CURVE25519_PUBKEY_SIZE,
|
||||
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_client_pubkey,
|
||||
CURVE25519_PUBKEY_SIZE,
|
||||
(size_t)CURVE25519_PUBKEY_SIZE, session->next_crypto->curve25519_server_pubkey);
|
||||
|
||||
len = ssh_string_len(num) + 4;
|
||||
if (buffer_add_data(buf, num, len) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
rc = ssh_buffer_pack(buf, "B", session->next_crypto->k);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf));
|
||||
ssh_print_hexa("hash buffer", ssh_buffer_get_begin(buf), ssh_buffer_get_len(buf));
|
||||
#endif
|
||||
|
||||
switch(session->next_crypto->kex_type){
|
||||
switch (session->next_crypto->kex_type) {
|
||||
case SSH_KEX_DH_GROUP1_SHA1:
|
||||
case SSH_KEX_DH_GROUP14_SHA1:
|
||||
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
|
||||
session->next_crypto->mac_type = SSH_MAC_SHA1;
|
||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||
if(session->next_crypto->secret_hash == NULL){
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
sha1(buffer_get_rest(buf), buffer_get_rest_len(buf),
|
||||
session->next_crypto->secret_hash);
|
||||
break;
|
||||
session->next_crypto->digest_len = SHA_DIGEST_LENGTH;
|
||||
session->next_crypto->mac_type = SSH_MAC_SHA1;
|
||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||
if (session->next_crypto->secret_hash == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
sha1(buffer_get_rest(buf), buffer_get_rest_len(buf),
|
||||
session->next_crypto->secret_hash);
|
||||
break;
|
||||
case SSH_KEX_ECDH_SHA2_NISTP256:
|
||||
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
||||
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
|
||||
session->next_crypto->mac_type = SSH_MAC_SHA256;
|
||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||
if(session->next_crypto->secret_hash == NULL){
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
sha256(buffer_get_rest(buf), buffer_get_rest_len(buf),
|
||||
session->next_crypto->secret_hash);
|
||||
break;
|
||||
}
|
||||
/* During the first kex, secret hash and session ID are equal. However, after
|
||||
* a key re-exchange, a new secret hash is calculated. This hash will not replace
|
||||
* but complement existing session id.
|
||||
*/
|
||||
if (!session->next_crypto->session_id){
|
||||
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
|
||||
if (session->next_crypto->session_id == NULL){
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
|
||||
session->next_crypto->digest_len);
|
||||
}
|
||||
session->next_crypto->digest_len = SHA256_DIGEST_LENGTH;
|
||||
session->next_crypto->mac_type = SSH_MAC_SHA256;
|
||||
session->next_crypto->secret_hash = malloc(session->next_crypto->digest_len);
|
||||
if (session->next_crypto->secret_hash == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
sha256(buffer_get_rest(buf), buffer_get_rest_len(buf),
|
||||
session->next_crypto->secret_hash);
|
||||
break;
|
||||
}
|
||||
/* During the first kex, secret hash and session ID are equal. However, after
|
||||
* a key re-exchange, a new secret hash is calculated. This hash will not replace
|
||||
* but complement existing session id.
|
||||
*/
|
||||
if (!session->next_crypto->session_id) {
|
||||
session->next_crypto->session_id = malloc(session->next_crypto->digest_len);
|
||||
if (session->next_crypto->session_id == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
memcpy(session->next_crypto->session_id, session->next_crypto->secret_hash,
|
||||
session->next_crypto->digest_len);
|
||||
}
|
||||
#ifdef DEBUG_CRYPTO
|
||||
printf("Session hash: \n");
|
||||
ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
|
||||
ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
|
||||
printf("Session hash: \n");
|
||||
ssh_print_hexa("secret hash", session->next_crypto->secret_hash, session->next_crypto->digest_len);
|
||||
ssh_print_hexa("session id", session->next_crypto->session_id, session->next_crypto->digest_len);
|
||||
#endif
|
||||
|
||||
rc = SSH_OK;
|
||||
rc = SSH_OK;
|
||||
error:
|
||||
ssh_buffer_free(buf);
|
||||
ssh_buffer_free(client_hash);
|
||||
ssh_buffer_free(server_hash);
|
||||
ssh_buffer_free(buf);
|
||||
ssh_buffer_free(client_hash);
|
||||
ssh_buffer_free(server_hash);
|
||||
|
||||
session->in_hashbuf = NULL;
|
||||
session->out_hashbuf = NULL;
|
||||
session->in_hashbuf = NULL;
|
||||
session->out_hashbuf = NULL;
|
||||
|
||||
ssh_string_free(str);
|
||||
ssh_string_free(num);
|
||||
ssh_string_free(num);
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hashbufout_add_cookie(ssh_session session) {
|
||||
@ -808,20 +699,20 @@ int hashbufout_add_cookie(ssh_session session) {
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_hashbuf, 20) < 0) {
|
||||
buffer_reinit(session->out_hashbuf);
|
||||
ssh_buffer_reinit(session->out_hashbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (session->server) {
|
||||
if (buffer_add_data(session->out_hashbuf,
|
||||
if (ssh_buffer_add_data(session->out_hashbuf,
|
||||
session->next_crypto->server_kex.cookie, 16) < 0) {
|
||||
buffer_reinit(session->out_hashbuf);
|
||||
ssh_buffer_reinit(session->out_hashbuf);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (buffer_add_data(session->out_hashbuf,
|
||||
if (ssh_buffer_add_data(session->out_hashbuf,
|
||||
session->next_crypto->client_kex.cookie, 16) < 0) {
|
||||
buffer_reinit(session->out_hashbuf);
|
||||
ssh_buffer_reinit(session->out_hashbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -836,11 +727,11 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) {
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->in_hashbuf, 20) < 0) {
|
||||
buffer_reinit(session->in_hashbuf);
|
||||
ssh_buffer_reinit(session->in_hashbuf);
|
||||
return -1;
|
||||
}
|
||||
if (buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
|
||||
buffer_reinit(session->in_hashbuf);
|
||||
if (ssh_buffer_add_data(session->in_hashbuf,cookie, 16) < 0) {
|
||||
ssh_buffer_reinit(session->in_hashbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -848,8 +739,10 @@ int hashbufin_add_cookie(ssh_session session, unsigned char *cookie) {
|
||||
}
|
||||
|
||||
static int generate_one_key(ssh_string k,
|
||||
struct ssh_crypto_struct *crypto, unsigned char *output, char letter) {
|
||||
struct ssh_crypto_struct *crypto, unsigned char **output, char letter, size_t requested_size) {
|
||||
ssh_mac_ctx ctx;
|
||||
unsigned char *tmp;
|
||||
size_t size = crypto->digest_len;
|
||||
ctx=ssh_mac_ctx_init(crypto->mac_type);
|
||||
|
||||
if (ctx == NULL) {
|
||||
@ -860,14 +753,32 @@ static int generate_one_key(ssh_string k,
|
||||
ssh_mac_update(ctx, crypto->secret_hash, crypto->digest_len);
|
||||
ssh_mac_update(ctx, &letter, 1);
|
||||
ssh_mac_update(ctx, crypto->session_id, crypto->digest_len);
|
||||
ssh_mac_final(output, ctx);
|
||||
ssh_mac_final(*output, ctx);
|
||||
|
||||
while(requested_size > size) {
|
||||
tmp = realloc(*output, size + crypto->digest_len);
|
||||
if (tmp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
*output = tmp;
|
||||
|
||||
ctx = ssh_mac_ctx_init(crypto->mac_type);
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ssh_mac_update(ctx, k, ssh_string_len(k) + 4);
|
||||
ssh_mac_update(ctx, crypto->secret_hash,
|
||||
crypto->digest_len);
|
||||
ssh_mac_update(ctx, tmp, size);
|
||||
ssh_mac_final(tmp + size, ctx);
|
||||
size += crypto->digest_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int generate_session_keys(ssh_session session) {
|
||||
ssh_string k_string = NULL;
|
||||
ssh_mac_ctx ctx = NULL;
|
||||
struct ssh_crypto_struct *crypto = session->next_crypto;
|
||||
int rc = -1;
|
||||
|
||||
@ -892,88 +803,71 @@ int generate_session_keys(ssh_session session) {
|
||||
|
||||
/* IV */
|
||||
if (session->client) {
|
||||
if (generate_one_key(k_string, crypto, crypto->encryptIV, 'A') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'A', crypto->digest_len);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (generate_one_key(k_string, crypto, crypto->decryptIV, 'B') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'B', crypto->digest_len);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (generate_one_key(k_string, crypto, crypto->decryptIV, 'A') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->decryptIV, 'A', crypto->digest_len);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (generate_one_key(k_string, crypto, crypto->encryptIV, 'B') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->encryptIV, 'B', crypto->digest_len);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (session->client) {
|
||||
if (generate_one_key(k_string, crypto, crypto->encryptkey, 'C') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'C', crypto->out_cipher->keysize / 8);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (generate_one_key(k_string, crypto, crypto->decryptkey, 'D') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'D', crypto->in_cipher->keysize / 8);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (generate_one_key(k_string, crypto, crypto->decryptkey, 'C') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->decryptkey, 'C', crypto->in_cipher->keysize / 8);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (generate_one_key(k_string, crypto, crypto->encryptkey, 'D') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->encryptkey, 'D', crypto->out_cipher->keysize / 8);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* some ciphers need more than DIGEST_LEN bytes of input key */
|
||||
if (crypto->out_cipher->keysize > crypto->digest_len * 8) {
|
||||
crypto->encryptkey = realloc(crypto->encryptkey, crypto->digest_len * 2);
|
||||
if(crypto->encryptkey == NULL)
|
||||
goto error;
|
||||
ctx = ssh_mac_ctx_init(crypto->mac_type);
|
||||
if (ctx == NULL) {
|
||||
goto error;
|
||||
}
|
||||
ssh_mac_update(ctx, k_string, ssh_string_len(k_string) + 4);
|
||||
ssh_mac_update(ctx, crypto->secret_hash,
|
||||
crypto->digest_len);
|
||||
ssh_mac_update(ctx, crypto->encryptkey, crypto->digest_len);
|
||||
ssh_mac_final(crypto->encryptkey + crypto->digest_len, ctx);
|
||||
}
|
||||
|
||||
if (crypto->in_cipher->keysize > crypto->digest_len * 8) {
|
||||
crypto->decryptkey = realloc(crypto->decryptkey, crypto->digest_len *2);
|
||||
if(crypto->decryptkey == NULL)
|
||||
goto error;
|
||||
ctx = ssh_mac_ctx_init(crypto->mac_type);
|
||||
ssh_mac_update(ctx, k_string, ssh_string_len(k_string) + 4);
|
||||
ssh_mac_update(ctx, crypto->secret_hash,
|
||||
crypto->digest_len);
|
||||
ssh_mac_update(ctx, crypto->decryptkey, crypto->digest_len);
|
||||
ssh_mac_final(crypto->decryptkey + crypto->digest_len, ctx);
|
||||
}
|
||||
if(session->client) {
|
||||
if (generate_one_key(k_string, crypto, crypto->encryptMAC, 'E') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'E', hmac_digest_len(crypto->out_hmac));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (generate_one_key(k_string, crypto, crypto->decryptMAC, 'F') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'F', hmac_digest_len(crypto->in_hmac));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (generate_one_key(k_string, crypto, crypto->decryptMAC, 'E') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->decryptMAC, 'E', hmac_digest_len(crypto->in_hmac));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (generate_one_key(k_string, crypto, crypto->encryptMAC, 'F') < 0) {
|
||||
rc = generate_one_key(k_string, crypto, &crypto->encryptMAC, 'F', hmac_digest_len(crypto->out_hmac));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Encrypt IV", crypto->encryptIV, SHA_DIGEST_LEN);
|
||||
ssh_print_hexa("Decrypt IV", crypto->decryptIV, SHA_DIGEST_LEN);
|
||||
ssh_print_hexa("Encryption key", crypto->encryptkey,
|
||||
crypto->out_cipher->keysize);
|
||||
ssh_print_hexa("Decryption key", crypto->decryptkey,
|
||||
crypto->in_cipher->keysize);
|
||||
ssh_print_hexa("Encryption MAC", crypto->encryptMAC, SHA_DIGEST_LEN);
|
||||
ssh_print_hexa("Decryption MAC", crypto->decryptMAC, 20);
|
||||
ssh_print_hexa("Encrypt IV", crypto->encryptIV, crypto->digest_len);
|
||||
ssh_print_hexa("Decrypt IV", crypto->decryptIV, crypto->digest_len);
|
||||
ssh_print_hexa("Encryption key", crypto->encryptkey, crypto->out_cipher->keysize / 8);
|
||||
ssh_print_hexa("Decryption key", crypto->decryptkey, crypto->in_cipher->keysize / 8);
|
||||
ssh_print_hexa("Encryption MAC", crypto->encryptMAC, hmac_digest_len(crypto->out_hmac));
|
||||
ssh_print_hexa("Decryption MAC", crypto->decryptMAC, hmac_digest_len(crypto->in_hmac));
|
||||
#endif
|
||||
|
||||
rc = 0;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2011 by Aris Adamantiadis
|
||||
* Copyright (c) 2011-2013 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -26,6 +26,7 @@
|
||||
#include "libssh/buffer.h"
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
#ifdef HAVE_ECDH
|
||||
#include <openssl/ecdh.h>
|
||||
@ -154,7 +155,7 @@ static int ecdh_build_k(ssh_session session) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
BN_bin2bn(buffer, len, session->next_crypto->k);
|
||||
bignum_bin2bn(buffer, len, session->next_crypto->k);
|
||||
free(buffer);
|
||||
|
||||
EC_KEY_free(session->next_crypto->ecdh_privkey);
|
||||
@ -285,12 +286,6 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
|
||||
session->next_crypto->ecdh_privkey = ecdh_key;
|
||||
session->next_crypto->ecdh_server_pubkey = q_s_string;
|
||||
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEXDH_REPLY);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* build k and session_id */
|
||||
rc = ecdh_build_k(session);
|
||||
if (rc < 0) {
|
||||
@ -310,30 +305,22 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* add host's public key */
|
||||
rc = buffer_add_ssh_string(session->out_buffer,
|
||||
session->next_crypto->server_pubkey);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/* add ecdh public key */
|
||||
rc = buffer_add_ssh_string(session->out_buffer, q_s_string);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* add signature blob */
|
||||
sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
|
||||
if (sig_blob == NULL) {
|
||||
ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(session->out_buffer, sig_blob);
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bSSS",
|
||||
SSH2_MSG_KEXDH_REPLY,
|
||||
session->next_crypto->server_pubkey, /* host's pubkey */
|
||||
q_s_string, /* ecdh public key */
|
||||
sig_blob); /* signature blob */
|
||||
|
||||
ssh_string_free(sig_blob);
|
||||
if (rc < 0) {
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
222
libssh/src/ed25519.c
Normal file
222
libssh/src/ed25519.c
Normal file
@ -0,0 +1,222 @@
|
||||
/* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libssh/libcrypto.h"
|
||||
#include "libssh/wrapper.h"
|
||||
#include "libssh/ge25519.h"
|
||||
#include "libssh/sc25519.h"
|
||||
#include "libssh/ed25519.h"
|
||||
|
||||
/*
|
||||
* Public Domain, Author: Daniel J. Bernstein
|
||||
* Copied from nacl-20110221/crypto_verify/32/ref/verify.c
|
||||
*/
|
||||
|
||||
static int crypto_verify_32(const unsigned char *x,const unsigned char *y)
|
||||
{
|
||||
unsigned int differentbits = 0;
|
||||
#define F(i) differentbits |= x[i] ^ y[i];
|
||||
F(0)
|
||||
F(1)
|
||||
F(2)
|
||||
F(3)
|
||||
F(4)
|
||||
F(5)
|
||||
F(6)
|
||||
F(7)
|
||||
F(8)
|
||||
F(9)
|
||||
F(10)
|
||||
F(11)
|
||||
F(12)
|
||||
F(13)
|
||||
F(14)
|
||||
F(15)
|
||||
F(16)
|
||||
F(17)
|
||||
F(18)
|
||||
F(19)
|
||||
F(20)
|
||||
F(21)
|
||||
F(22)
|
||||
F(23)
|
||||
F(24)
|
||||
F(25)
|
||||
F(26)
|
||||
F(27)
|
||||
F(28)
|
||||
F(29)
|
||||
F(30)
|
||||
F(31)
|
||||
|
||||
return (1 & ((differentbits - 1) >> 8)) - 1;
|
||||
}
|
||||
|
||||
static void get_hram(unsigned char *hram,
|
||||
const unsigned char *sm,
|
||||
const unsigned char *pk,
|
||||
unsigned char *playground,
|
||||
unsigned long long smlen)
|
||||
{
|
||||
unsigned long long i;
|
||||
SHA512CTX ctx;
|
||||
for (i = 0;i < 32;++i) playground[i] = sm[i];
|
||||
for (i = 32;i < 64;++i) playground[i] = pk[i-32];
|
||||
for (i = 64;i < smlen;++i) playground[i] = sm[i];
|
||||
|
||||
ctx = sha512_init();
|
||||
sha512_update(ctx, playground, smlen);
|
||||
sha512_final(hram, ctx);
|
||||
}
|
||||
|
||||
|
||||
int crypto_sign_ed25519_keypair(unsigned char *pk,
|
||||
unsigned char *sk)
|
||||
{
|
||||
sc25519 scsk;
|
||||
ge25519 gepk;
|
||||
SHA512CTX ctx;
|
||||
unsigned char extsk[64];
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
rc = ssh_get_random(sk, 32, 0);
|
||||
if (rc < 0){
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx = sha512_init();
|
||||
sha512_update(ctx, sk, 32);
|
||||
sha512_final(extsk, ctx);
|
||||
extsk[0] &= 248;
|
||||
extsk[31] &= 127;
|
||||
extsk[31] |= 64;
|
||||
|
||||
sc25519_from32bytes(&scsk,extsk);
|
||||
|
||||
ge25519_scalarmult_base(&gepk, &scsk);
|
||||
ge25519_pack(pk, &gepk);
|
||||
for(i=0;i<32;i++) {
|
||||
sk[32 + i] = pk[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sign_ed25519(unsigned char *sm,
|
||||
unsigned long long *smlen,
|
||||
const unsigned char *m,
|
||||
unsigned long long mlen,
|
||||
const unsigned char *sk)
|
||||
{
|
||||
sc25519 sck, scs, scsk;
|
||||
ge25519 ger;
|
||||
SHA512CTX ctx;
|
||||
unsigned char r[32];
|
||||
unsigned char s[32];
|
||||
unsigned char extsk[64];
|
||||
unsigned long long i;
|
||||
unsigned char hmg[SHA512_DIGEST_LEN];
|
||||
unsigned char hram[SHA512_DIGEST_LEN];
|
||||
|
||||
ctx = sha512_init();
|
||||
sha512_update(ctx, sk, 32);
|
||||
sha512_final(extsk, ctx);
|
||||
|
||||
extsk[0] &= 248;
|
||||
extsk[31] &= 127;
|
||||
extsk[31] |= 64;
|
||||
|
||||
*smlen = mlen + 64;
|
||||
for (i = 0;i < mlen; i++) {
|
||||
sm[64 + i] = m[i];
|
||||
}
|
||||
for (i = 0;i < 32; i++) {
|
||||
sm[32 + i] = extsk[32+i];
|
||||
}
|
||||
|
||||
/* Generate k as h(extsk[32],...,extsk[63],m) */
|
||||
ctx = sha512_init();
|
||||
sha512_update(ctx, sm + 32, mlen + 32);
|
||||
sha512_final(hmg, ctx);
|
||||
|
||||
/* Computation of R */
|
||||
sc25519_from64bytes(&sck, hmg);
|
||||
ge25519_scalarmult_base(&ger, &sck);
|
||||
ge25519_pack(r, &ger);
|
||||
|
||||
/* Computation of s */
|
||||
for (i = 0; i < 32; i++) {
|
||||
sm[i] = r[i];
|
||||
}
|
||||
|
||||
get_hram(hram, sm, sk+32, sm, mlen+64);
|
||||
|
||||
sc25519_from64bytes(&scs, hram);
|
||||
sc25519_from32bytes(&scsk, extsk);
|
||||
sc25519_mul(&scs, &scs, &scsk);
|
||||
|
||||
sc25519_add(&scs, &scs, &sck);
|
||||
|
||||
sc25519_to32bytes(s,&scs); /* cat s */
|
||||
for (i = 0;i < 32; i++) {
|
||||
sm[32 + i] = s[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sign_ed25519_open(unsigned char *m,
|
||||
unsigned long long *mlen,
|
||||
const unsigned char *sm,
|
||||
unsigned long long smlen,
|
||||
const unsigned char *pk)
|
||||
{
|
||||
unsigned int i;
|
||||
int ret;
|
||||
unsigned char t2[32];
|
||||
ge25519 get1, get2;
|
||||
sc25519 schram, scs;
|
||||
unsigned char hram[SHA512_DIGEST_LEN];
|
||||
|
||||
*mlen = (unsigned long long) -1;
|
||||
if (smlen < 64) return -1;
|
||||
|
||||
if (ge25519_unpackneg_vartime(&get1, pk)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
get_hram(hram,sm,pk,m,smlen);
|
||||
|
||||
sc25519_from64bytes(&schram, hram);
|
||||
|
||||
sc25519_from32bytes(&scs, sm+32);
|
||||
|
||||
ge25519_double_scalarmult_vartime(&get2,
|
||||
&get1,
|
||||
&schram,
|
||||
&ge25519_base,
|
||||
&scs);
|
||||
ge25519_pack(t2, &get2);
|
||||
|
||||
ret = crypto_verify_32(sm, t2);
|
||||
if (ret != 0) {
|
||||
for (i = 0; i < smlen - 64; i++) {
|
||||
m[i] = sm[i + 64];
|
||||
}
|
||||
*mlen = smlen-64;
|
||||
} else {
|
||||
for (i = 0; i < smlen - 64; i++) {
|
||||
m[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -104,7 +104,7 @@ void _ssh_set_error_invalid(void *error, const char *function)
|
||||
/**
|
||||
* @brief Retrieve the error text message from the last error.
|
||||
*
|
||||
* @param error The SSH session pointer.
|
||||
* @param error An ssh_session or ssh_bind.
|
||||
*
|
||||
* @return A static string describing the error.
|
||||
*/
|
||||
@ -117,7 +117,7 @@ const char *ssh_get_error(void *error) {
|
||||
/**
|
||||
* @brief Retrieve the error code from the last error.
|
||||
*
|
||||
* @param error The SSH session pointer.
|
||||
* @param error An ssh_session or ssh_bind.
|
||||
*
|
||||
* \return SSH_NO_ERROR No error occurred\n
|
||||
* SSH_REQUEST_DENIED The last request was denied but situation is
|
||||
|
416
libssh/src/fe25519.c
Normal file
416
libssh/src/fe25519.c
Normal file
@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/fe25519.c
|
||||
*/
|
||||
|
||||
#define WINDOWSIZE 1 /* Should be 1,2, or 4 */
|
||||
#define WINDOWMASK ((1<<WINDOWSIZE)-1)
|
||||
|
||||
#include "libssh/fe25519.h"
|
||||
|
||||
static uint32_t equal(uint32_t a,uint32_t b) /* 16-bit inputs */
|
||||
{
|
||||
uint32_t x = a ^ b; /* 0: yes; 1..65535: no */
|
||||
x -= 1; /* 4294967295: yes; 0..65534: no */
|
||||
x >>= 31; /* 1: yes; 0: no */
|
||||
return x;
|
||||
}
|
||||
|
||||
static uint32_t ge(uint32_t a,uint32_t b) /* 16-bit inputs */
|
||||
{
|
||||
unsigned int x = a;
|
||||
|
||||
x -= (unsigned int) b; /* 0..65535: yes; 4294901761..4294967295: no */
|
||||
x >>= 31; /* 0: yes; 1: no */
|
||||
x ^= 1; /* 1: yes; 0: no */
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static uint32_t times19(uint32_t a)
|
||||
{
|
||||
return (a << 4) + (a << 1) + a;
|
||||
}
|
||||
|
||||
static uint32_t times38(uint32_t a)
|
||||
{
|
||||
return (a << 5) + (a << 2) + (a << 1);
|
||||
}
|
||||
|
||||
static void reduce_add_sub(fe25519 *r)
|
||||
{
|
||||
uint32_t t;
|
||||
int i,rep;
|
||||
|
||||
for(rep = 0; rep < 4; rep++) {
|
||||
t = r->v[31] >> 7;
|
||||
r->v[31] &= 127;
|
||||
t = times19(t);
|
||||
r->v[0] += t;
|
||||
for(i = 0; i < 31; i++) {
|
||||
t = r->v[i] >> 8;
|
||||
r->v[i+1] += t;
|
||||
r->v[i] &= 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void reduce_mul(fe25519 *r)
|
||||
{
|
||||
uint32_t t;
|
||||
int i,rep;
|
||||
|
||||
for(rep = 0; rep < 2; rep++) {
|
||||
t = r->v[31] >> 7;
|
||||
r->v[31] &= 127;
|
||||
t = times19(t);
|
||||
r->v[0] += t;
|
||||
for(i = 0; i < 31; i++) {
|
||||
t = r->v[i] >> 8;
|
||||
r->v[i+1] += t;
|
||||
r->v[i] &= 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* reduction modulo 2^255-19 */
|
||||
void fe25519_freeze(fe25519 *r)
|
||||
{
|
||||
int i;
|
||||
uint32_t m = equal(r->v[31],127);
|
||||
|
||||
for (i = 30; i > 0; i--) {
|
||||
m &= equal(r->v[i],255);
|
||||
}
|
||||
m &= ge(r->v[0],237);
|
||||
|
||||
m = -m;
|
||||
|
||||
r->v[31] -= m&127;
|
||||
for (i = 30; i > 0; i--) {
|
||||
r->v[i] -= m&255;
|
||||
}
|
||||
r->v[0] -= m&237;
|
||||
}
|
||||
|
||||
void fe25519_unpack(fe25519 *r, const unsigned char x[32])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;i < 32; i++) {
|
||||
r->v[i] = x[i];
|
||||
}
|
||||
|
||||
r->v[31] &= 127;
|
||||
}
|
||||
|
||||
/* Assumes input x being reduced below 2^255 */
|
||||
void fe25519_pack(unsigned char r[32], const fe25519 *x)
|
||||
{
|
||||
int i;
|
||||
|
||||
fe25519 y = *x;
|
||||
fe25519_freeze(&y);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
r[i] = y.v[i];
|
||||
}
|
||||
}
|
||||
|
||||
int fe25519_iszero(const fe25519 *x)
|
||||
{
|
||||
int i;
|
||||
int r;
|
||||
|
||||
fe25519 t = *x;
|
||||
fe25519_freeze(&t);
|
||||
|
||||
r = equal(t.v[0],0);
|
||||
for (i = 1; i < 32; i++) {
|
||||
r &= equal(t.v[i],0);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int fe25519_iseq_vartime(const fe25519 *x, const fe25519 *y)
|
||||
{
|
||||
int i;
|
||||
|
||||
fe25519 t1 = *x;
|
||||
fe25519 t2 = *y;
|
||||
fe25519_freeze(&t1);
|
||||
fe25519_freeze(&t2);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if(t1.v[i] != t2.v[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void fe25519_cmov(fe25519 *r, const fe25519 *x, unsigned char b)
|
||||
{
|
||||
int i;
|
||||
uint32_t mask = b;
|
||||
|
||||
mask = -mask;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
r->v[i] ^= mask & (x->v[i] ^ r->v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char fe25519_getparity(const fe25519 *x)
|
||||
{
|
||||
fe25519 t = *x;
|
||||
fe25519_freeze(&t);
|
||||
|
||||
return t.v[0] & 1;
|
||||
}
|
||||
|
||||
void fe25519_setone(fe25519 *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
r->v[0] = 1;
|
||||
for (i = 1; i < 32; i++) {
|
||||
r->v[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
void fe25519_setzero(fe25519 *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
r->v[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
void fe25519_neg(fe25519 *r, const fe25519 *x)
|
||||
{
|
||||
fe25519 t;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
t.v[i]=x->v[i];
|
||||
}
|
||||
|
||||
fe25519_setzero(r);
|
||||
fe25519_sub(r, r, &t);
|
||||
}
|
||||
|
||||
void fe25519_add(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
r->v[i] = x->v[i] + y->v[i];
|
||||
}
|
||||
|
||||
reduce_add_sub(r);
|
||||
}
|
||||
|
||||
void fe25519_sub(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
||||
{
|
||||
int i;
|
||||
uint32_t t[32];
|
||||
|
||||
t[0] = x->v[0] + 0x1da;
|
||||
t[31] = x->v[31] + 0xfe;
|
||||
|
||||
for (i = 1; i < 31; i++) {
|
||||
t[i] = x->v[i] + 0x1fe;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
r->v[i] = t[i] - y->v[i];
|
||||
}
|
||||
|
||||
reduce_add_sub(r);
|
||||
}
|
||||
|
||||
void fe25519_mul(fe25519 *r, const fe25519 *x, const fe25519 *y)
|
||||
{
|
||||
int i,j;
|
||||
uint32_t t[63];
|
||||
|
||||
for (i = 0; i < 63; i++) {
|
||||
t[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
for (j = 0; j < 32; j++) {
|
||||
t[i+j] += x->v[i] * y->v[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 32; i < 63; i++) {
|
||||
r->v[i-32] = t[i-32] + times38(t[i]);
|
||||
}
|
||||
r->v[31] = t[31]; /* result now in r[0]...r[31] */
|
||||
|
||||
reduce_mul(r);
|
||||
}
|
||||
|
||||
void fe25519_square(fe25519 *r, const fe25519 *x)
|
||||
{
|
||||
fe25519_mul(r, x, x);
|
||||
}
|
||||
|
||||
void fe25519_invert(fe25519 *r, const fe25519 *x)
|
||||
{
|
||||
fe25519 z2;
|
||||
fe25519 z9;
|
||||
fe25519 z11;
|
||||
fe25519 z2_5_0;
|
||||
fe25519 z2_10_0;
|
||||
fe25519 z2_20_0;
|
||||
fe25519 z2_50_0;
|
||||
fe25519 z2_100_0;
|
||||
fe25519 t0;
|
||||
fe25519 t1;
|
||||
int i;
|
||||
|
||||
/* 2 */ fe25519_square(&z2, x);
|
||||
/* 4 */ fe25519_square(&t1, &z2);
|
||||
/* 8 */ fe25519_square(&t0, &t1);
|
||||
/* 9 */ fe25519_mul(&z9, &t0, x);
|
||||
/* 11 */ fe25519_mul(&z11, &z9, &z2);
|
||||
/* 22 */ fe25519_square(&t0, &z11);
|
||||
/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t0, &z9);
|
||||
|
||||
/* 2^6 - 2^1 */ fe25519_square(&t0, &z2_5_0);
|
||||
/* 2^7 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^8 - 2^3 */ fe25519_square(&t0, &t1);
|
||||
/* 2^9 - 2^4 */ fe25519_square(&t1, &t0);
|
||||
/* 2^10 - 2^5 */ fe25519_square(&t0, &t1);
|
||||
/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t0, &z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ fe25519_square(&t0, &z2_10_0);
|
||||
/* 2^12 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1, &t0);
|
||||
}
|
||||
/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t1, &z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fe25519_square(&t0, &z2_20_0);
|
||||
/* 2^22 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1,&t0);
|
||||
}
|
||||
/* 2^40 - 2^0 */ fe25519_mul(&t0, &t1, &z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fe25519_square(&t1, &t0);
|
||||
/* 2^42 - 2^2 */ fe25519_square(&t0, &t1);
|
||||
/* 2^50 - 2^10 */ for (i = 2; i < 10;i += 2) {
|
||||
fe25519_square(&t1, &t0);
|
||||
fe25519_square(&t0, &t1);
|
||||
}
|
||||
/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t0,&z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fe25519_square(&t0, &z2_50_0);
|
||||
/* 2^52 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^100 - 2^50 */ for (i = 2; i < 50; i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1,&t0);
|
||||
}
|
||||
/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t1, &z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fe25519_square(&t1, &z2_100_0);
|
||||
/* 2^102 - 2^2 */ fe25519_square(&t0, &t1);
|
||||
/* 2^200 - 2^100 */ for (i = 2; i < 100; i += 2) {
|
||||
fe25519_square(&t1, &t0);
|
||||
fe25519_square(&t0,&t1);
|
||||
}
|
||||
/* 2^200 - 2^0 */ fe25519_mul(&t1, &t0, &z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fe25519_square(&t0, &t1);
|
||||
/* 2^202 - 2^2 */ fe25519_square(&t1, &t0);
|
||||
/* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) {
|
||||
fe25519_square(&t0, &t1);
|
||||
fe25519_square(&t1,&t0);
|
||||
}
|
||||
/* 2^250 - 2^0 */ fe25519_mul(&t0, &t1, &z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fe25519_square(&t1, &t0);
|
||||
/* 2^252 - 2^2 */ fe25519_square(&t0, &t1);
|
||||
/* 2^253 - 2^3 */ fe25519_square(&t1, &t0);
|
||||
/* 2^254 - 2^4 */ fe25519_square(&t0, &t1);
|
||||
/* 2^255 - 2^5 */ fe25519_square(&t1, &t0);
|
||||
/* 2^255 - 21 */ fe25519_mul(r, &t1, &z11);
|
||||
}
|
||||
|
||||
void fe25519_pow2523(fe25519 *r, const fe25519 *x)
|
||||
{
|
||||
fe25519 z2;
|
||||
fe25519 z9;
|
||||
fe25519 z11;
|
||||
fe25519 z2_5_0;
|
||||
fe25519 z2_10_0;
|
||||
fe25519 z2_20_0;
|
||||
fe25519 z2_50_0;
|
||||
fe25519 z2_100_0;
|
||||
fe25519 t;
|
||||
int i;
|
||||
|
||||
/* 2 */ fe25519_square(&z2, x);
|
||||
/* 4 */ fe25519_square(&t, &z2);
|
||||
/* 8 */ fe25519_square(&t, &t);
|
||||
/* 9 */ fe25519_mul(&z9, &t, x);
|
||||
/* 11 */ fe25519_mul(&z11, &z9, &z2);
|
||||
/* 22 */ fe25519_square(&t, &z11);
|
||||
/* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0, &t, &z9);
|
||||
|
||||
/* 2^6 - 2^1 */ fe25519_square(&t, &z2_5_0);
|
||||
/* 2^10 - 2^5 */ for (i = 1; i < 5; i++) {
|
||||
fe25519_square(&t,&t);
|
||||
}
|
||||
/* 2^10 - 2^0 */ fe25519_mul(&z2_10_0, &t, &z2_5_0);
|
||||
|
||||
/* 2^11 - 2^1 */ fe25519_square(&t, &z2_10_0);
|
||||
/* 2^20 - 2^10 */ for (i = 1; i < 10; i++) {
|
||||
fe25519_square(&t, &t);
|
||||
}
|
||||
/* 2^20 - 2^0 */ fe25519_mul(&z2_20_0, &t, &z2_10_0);
|
||||
|
||||
/* 2^21 - 2^1 */ fe25519_square(&t, &z2_20_0);
|
||||
/* 2^40 - 2^20 */ for (i = 1; i < 20; i++) {
|
||||
fe25519_square(&t,&t);
|
||||
}
|
||||
/* 2^40 - 2^0 */ fe25519_mul(&t, &t, &z2_20_0);
|
||||
|
||||
/* 2^41 - 2^1 */ fe25519_square(&t, &t);
|
||||
/* 2^50 - 2^10 */ for (i = 1; i < 10; i++) {
|
||||
fe25519_square(&t,&t);
|
||||
}
|
||||
/* 2^50 - 2^0 */ fe25519_mul(&z2_50_0, &t, &z2_10_0);
|
||||
|
||||
/* 2^51 - 2^1 */ fe25519_square(&t, &z2_50_0);
|
||||
/* 2^100 - 2^50 */ for (i = 1; i < 50; i++) {
|
||||
fe25519_square(&t, &t);
|
||||
}
|
||||
/* 2^100 - 2^0 */ fe25519_mul(&z2_100_0, &t, &z2_50_0);
|
||||
|
||||
/* 2^101 - 2^1 */ fe25519_square(&t, &z2_100_0);
|
||||
/* 2^200 - 2^100 */ for (i = 1; i < 100; i++) {
|
||||
fe25519_square(&t, &t);
|
||||
}
|
||||
/* 2^200 - 2^0 */ fe25519_mul(&t, &t, &z2_100_0);
|
||||
|
||||
/* 2^201 - 2^1 */ fe25519_square(&t, &t);
|
||||
/* 2^250 - 2^50 */ for (i = 1; i < 50; i++) {
|
||||
fe25519_square(&t, &t);
|
||||
}
|
||||
/* 2^250 - 2^0 */ fe25519_mul(&t, &t, &z2_50_0);
|
||||
|
||||
/* 2^251 - 2^1 */ fe25519_square(&t, &t);
|
||||
/* 2^252 - 2^2 */ fe25519_square(&t, &t);
|
||||
/* 2^252 - 3 */ fe25519_mul(r, &t, x);
|
||||
}
|
367
libssh/src/ge25519.c
Normal file
367
libssh/src/ge25519.c
Normal file
@ -0,0 +1,367 @@
|
||||
/* $OpenBSD: ge25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519.c
|
||||
*/
|
||||
|
||||
#include "libssh/fe25519.h"
|
||||
#include "libssh/sc25519.h"
|
||||
#include "libssh/ge25519.h"
|
||||
|
||||
/*
|
||||
* Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2
|
||||
* with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555
|
||||
* Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960);
|
||||
*/
|
||||
|
||||
/* d */
|
||||
static const fe25519 ge25519_ecd = {
|
||||
{0xA3, 0x78, 0x59, 0x13, 0xCA, 0x4D, 0xEB, 0x75,
|
||||
0xAB, 0xD8, 0x41, 0x41, 0x4D, 0x0A, 0x70, 0x00,
|
||||
0x98, 0xE8, 0x79, 0x77, 0x79, 0x40, 0xC7, 0x8C,
|
||||
0x73, 0xFE, 0x6F, 0x2B, 0xEE, 0x6C, 0x03, 0x52}
|
||||
};
|
||||
|
||||
/* 2*d */
|
||||
static const fe25519 ge25519_ec2d = {
|
||||
{0x59, 0xF1, 0xB2, 0x26, 0x94, 0x9B, 0xD6, 0xEB,
|
||||
0x56, 0xB1, 0x83, 0x82, 0x9A, 0x14, 0xE0, 0x00,
|
||||
0x30, 0xD1, 0xF3, 0xEE, 0xF2, 0x80, 0x8E, 0x19,
|
||||
0xE7, 0xFC, 0xDF, 0x56, 0xDC, 0xD9, 0x06, 0x24}
|
||||
};
|
||||
|
||||
/* sqrt(-1) */
|
||||
static const fe25519 ge25519_sqrtm1 = {
|
||||
{0xB0, 0xA0, 0x0E, 0x4A, 0x27, 0x1B, 0xEE, 0xC4,
|
||||
0x78, 0xE4, 0x2F, 0xAD, 0x06, 0x18, 0x43, 0x2F,
|
||||
0xA7, 0xD7, 0xFB, 0x3D, 0x99, 0x00, 0x4D, 0x2B,
|
||||
0x0B, 0xDF, 0xC1, 0x4F, 0x80, 0x24, 0x83, 0x2B}
|
||||
};
|
||||
|
||||
#define ge25519_p3 ge25519
|
||||
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 z;
|
||||
fe25519 y;
|
||||
fe25519 t;
|
||||
} ge25519_p1p1;
|
||||
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 y;
|
||||
fe25519 z;
|
||||
} ge25519_p2;
|
||||
|
||||
typedef struct {
|
||||
fe25519 x;
|
||||
fe25519 y;
|
||||
} ge25519_aff;
|
||||
|
||||
|
||||
/* Packed coordinates of the base point */
|
||||
const ge25519 ge25519_base = {
|
||||
{{0x1A, 0xD5, 0x25, 0x8F, 0x60, 0x2D, 0x56, 0xC9,
|
||||
0xB2, 0xA7, 0x25, 0x95, 0x60, 0xC7, 0x2C, 0x69,
|
||||
0x5C, 0xDC, 0xD6, 0xFD, 0x31, 0xE2, 0xA4, 0xC0,
|
||||
0xFE, 0x53, 0x6E, 0xCD, 0xD3, 0x36, 0x69, 0x21}},
|
||||
{{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0xA3, 0xDD, 0xB7, 0xA5, 0xB3, 0x8A, 0xDE, 0x6D,
|
||||
0xF5, 0x52, 0x51, 0x77, 0x80, 0x9F, 0xF0, 0x20,
|
||||
0x7D, 0xE3, 0xAB, 0x64, 0x8E, 0x4E, 0xEA, 0x66,
|
||||
0x65, 0x76, 0x8B, 0xD7, 0x0F, 0x5F, 0x87, 0x67}}
|
||||
};
|
||||
|
||||
/* Multiples of the base point in affine representation */
|
||||
static const ge25519_aff ge25519_base_multiples_affine[425] = {
|
||||
#include "ge25519_base.data"
|
||||
};
|
||||
|
||||
static void p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p)
|
||||
{
|
||||
fe25519_mul(&r->x, &p->x, &p->t);
|
||||
fe25519_mul(&r->y, &p->y, &p->z);
|
||||
fe25519_mul(&r->z, &p->z, &p->t);
|
||||
}
|
||||
|
||||
static void p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p)
|
||||
{
|
||||
p1p1_to_p2((ge25519_p2 *)r, p);
|
||||
fe25519_mul(&r->t, &p->x, &p->y);
|
||||
}
|
||||
|
||||
static void ge25519_mixadd2(ge25519_p3 *r, const ge25519_aff *q)
|
||||
{
|
||||
fe25519 a,b,t1,t2,c,d,e,f,g,h,qt;
|
||||
fe25519_mul(&qt, &q->x, &q->y);
|
||||
fe25519_sub(&a, &r->y, &r->x); /* A = (Y1-X1)*(Y2-X2) */
|
||||
fe25519_add(&b, &r->y, &r->x); /* B = (Y1+X1)*(Y2+X2) */
|
||||
fe25519_sub(&t1, &q->y, &q->x);
|
||||
fe25519_add(&t2, &q->y, &q->x);
|
||||
fe25519_mul(&a, &a, &t1);
|
||||
fe25519_mul(&b, &b, &t2);
|
||||
fe25519_sub(&e, &b, &a); /* E = B-A */
|
||||
fe25519_add(&h, &b, &a); /* H = B+A */
|
||||
fe25519_mul(&c, &r->t, &qt); /* C = T1*k*T2 */
|
||||
fe25519_mul(&c, &c, &ge25519_ec2d);
|
||||
fe25519_add(&d, &r->z, &r->z); /* D = Z1*2 */
|
||||
fe25519_sub(&f, &d, &c); /* F = D-C */
|
||||
fe25519_add(&g, &d, &c); /* G = D+C */
|
||||
fe25519_mul(&r->x, &e, &f);
|
||||
fe25519_mul(&r->y, &h, &g);
|
||||
fe25519_mul(&r->z, &g, &f);
|
||||
fe25519_mul(&r->t, &e, &h);
|
||||
}
|
||||
|
||||
static void add_p1p1(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_p3 *q)
|
||||
{
|
||||
fe25519 a, b, c, d, t;
|
||||
|
||||
fe25519_sub(&a, &p->y, &p->x); /* A = (Y1-X1)*(Y2-X2) */
|
||||
fe25519_sub(&t, &q->y, &q->x);
|
||||
fe25519_mul(&a, &a, &t);
|
||||
fe25519_add(&b, &p->x, &p->y); /* B = (Y1+X1)*(Y2+X2) */
|
||||
fe25519_add(&t, &q->x, &q->y);
|
||||
fe25519_mul(&b, &b, &t);
|
||||
fe25519_mul(&c, &p->t, &q->t); /* C = T1*k*T2 */
|
||||
fe25519_mul(&c, &c, &ge25519_ec2d);
|
||||
fe25519_mul(&d, &p->z, &q->z); /* D = Z1*2*Z2 */
|
||||
fe25519_add(&d, &d, &d);
|
||||
fe25519_sub(&r->x, &b, &a); /* E = B-A */
|
||||
fe25519_sub(&r->t, &d, &c); /* F = D-C */
|
||||
fe25519_add(&r->z, &d, &c); /* G = D+C */
|
||||
fe25519_add(&r->y, &b, &a); /* H = B+A */
|
||||
}
|
||||
|
||||
/* See http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#doubling-dbl-2008-hwcd */
|
||||
static void dbl_p1p1(ge25519_p1p1 *r, const ge25519_p2 *p)
|
||||
{
|
||||
fe25519 a,b,c,d;
|
||||
fe25519_square(&a, &p->x);
|
||||
fe25519_square(&b, &p->y);
|
||||
fe25519_square(&c, &p->z);
|
||||
fe25519_add(&c, &c, &c);
|
||||
fe25519_neg(&d, &a);
|
||||
|
||||
fe25519_add(&r->x, &p->x, &p->y);
|
||||
fe25519_square(&r->x, &r->x);
|
||||
fe25519_sub(&r->x, &r->x, &a);
|
||||
fe25519_sub(&r->x, &r->x, &b);
|
||||
fe25519_add(&r->z, &d, &b);
|
||||
fe25519_sub(&r->t, &r->z, &c);
|
||||
fe25519_sub(&r->y, &d, &b);
|
||||
}
|
||||
|
||||
/* Constant-time version of: if(b) r = p */
|
||||
static void cmov_aff(ge25519_aff *r, const ge25519_aff *p, unsigned char b)
|
||||
{
|
||||
fe25519_cmov(&r->x, &p->x, b);
|
||||
fe25519_cmov(&r->y, &p->y, b);
|
||||
}
|
||||
|
||||
static unsigned char equal(signed char b,signed char c)
|
||||
{
|
||||
unsigned char ub = b;
|
||||
unsigned char uc = c;
|
||||
unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */
|
||||
uint32_t y = x; /* 0: yes; 1..255: no */
|
||||
|
||||
y -= 1; /* 4294967295: yes; 0..254: no */
|
||||
y >>= 31; /* 1: yes; 0: no */
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static unsigned char negative(signed char b)
|
||||
{
|
||||
unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */
|
||||
|
||||
x >>= 63; /* 1: yes; 0: no */
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
static void choose_t(ge25519_aff *t, unsigned long long pos, signed char b)
|
||||
{
|
||||
/* constant time */
|
||||
fe25519 v;
|
||||
|
||||
*t = ge25519_base_multiples_affine[5 * pos + 0];
|
||||
|
||||
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 1],
|
||||
equal(b,1) | equal(b,-1));
|
||||
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 2],
|
||||
equal(b,2) | equal(b,-2));
|
||||
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 3],
|
||||
equal(b,3) | equal(b,-3));
|
||||
cmov_aff(t, &ge25519_base_multiples_affine[5 * pos + 4],
|
||||
equal(b,-4));
|
||||
|
||||
fe25519_neg(&v, &t->x);
|
||||
fe25519_cmov(&t->x, &v, negative(b));
|
||||
}
|
||||
|
||||
static void setneutral(ge25519 *r)
|
||||
{
|
||||
fe25519_setzero(&r->x);
|
||||
fe25519_setone(&r->y);
|
||||
fe25519_setone(&r->z);
|
||||
fe25519_setzero(&r->t);
|
||||
}
|
||||
|
||||
/* ********************************************************************
|
||||
* EXPORTED FUNCTIONS
|
||||
******************************************************************** */
|
||||
|
||||
/* return 0 on success, -1 otherwise */
|
||||
int ge25519_unpackneg_vartime(ge25519_p3 *r, const unsigned char p[32])
|
||||
{
|
||||
unsigned char par;
|
||||
|
||||
fe25519 t, chk, num, den, den2, den4, den6;
|
||||
fe25519_setone(&r->z);
|
||||
par = p[31] >> 7;
|
||||
fe25519_unpack(&r->y, p);
|
||||
fe25519_square(&num, &r->y); /* x = y^2 */
|
||||
fe25519_mul(&den, &num, &ge25519_ecd); /* den = dy^2 */
|
||||
fe25519_sub(&num, &num, &r->z); /* x = y^2-1 */
|
||||
fe25519_add(&den, &r->z, &den); /* den = dy^2+1 */
|
||||
|
||||
/* Computation of sqrt(num/den) */
|
||||
/* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */
|
||||
fe25519_square(&den2, &den);
|
||||
fe25519_square(&den4, &den2);
|
||||
fe25519_mul(&den6, &den4, &den2);
|
||||
fe25519_mul(&t, &den6, &num);
|
||||
fe25519_mul(&t, &t, &den);
|
||||
|
||||
fe25519_pow2523(&t, &t);
|
||||
/* 2. computation of r->x = t * num * den^3 */
|
||||
fe25519_mul(&t, &t, &num);
|
||||
fe25519_mul(&t, &t, &den);
|
||||
fe25519_mul(&t, &t, &den);
|
||||
fe25519_mul(&r->x, &t, &den);
|
||||
|
||||
/* 3. Check whether sqrt computation gave correct result, multiply by sqrt(-1) if not: */
|
||||
fe25519_square(&chk, &r->x);
|
||||
fe25519_mul(&chk, &chk, &den);
|
||||
if (!fe25519_iseq_vartime(&chk, &num)) {
|
||||
fe25519_mul(&r->x, &r->x, &ge25519_sqrtm1);
|
||||
}
|
||||
|
||||
/* 4. Now we have one of the two square roots, except if input was not a square */
|
||||
fe25519_square(&chk, &r->x);
|
||||
fe25519_mul(&chk, &chk, &den);
|
||||
if (!fe25519_iseq_vartime(&chk, &num)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 5. Choose the desired square root according to parity: */
|
||||
if(fe25519_getparity(&r->x) != (1-par)) {
|
||||
fe25519_neg(&r->x, &r->x);
|
||||
}
|
||||
|
||||
fe25519_mul(&r->t, &r->x, &r->y);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ge25519_pack(unsigned char r[32], const ge25519_p3 *p)
|
||||
{
|
||||
fe25519 tx, ty, zi;
|
||||
|
||||
fe25519_invert(&zi, &p->z);
|
||||
fe25519_mul(&tx, &p->x, &zi);
|
||||
fe25519_mul(&ty, &p->y, &zi);
|
||||
fe25519_pack(r, &ty);
|
||||
|
||||
r[31] ^= fe25519_getparity(&tx) << 7;
|
||||
}
|
||||
|
||||
int ge25519_isneutral_vartime(const ge25519_p3 *p)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (!fe25519_iszero(&p->x)) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (!fe25519_iseq_vartime(&p->y, &p->z)) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* computes [s1]p1 + [s2]p2 */
|
||||
void ge25519_double_scalarmult_vartime(ge25519_p3 *r, const ge25519_p3 *p1, const sc25519 *s1, const ge25519_p3 *p2, const sc25519 *s2)
|
||||
{
|
||||
ge25519_p1p1 tp1p1;
|
||||
ge25519_p3 pre[16];
|
||||
unsigned char b[127];
|
||||
int i;
|
||||
|
||||
/* precomputation s2 s1 */
|
||||
setneutral(pre); /* 00 00 */
|
||||
pre[1] = *p1; /* 00 01 */
|
||||
dbl_p1p1(&tp1p1,(ge25519_p2 *)p1); p1p1_to_p3( &pre[2], &tp1p1); /* 00 10 */
|
||||
add_p1p1(&tp1p1,&pre[1], &pre[2]); p1p1_to_p3( &pre[3], &tp1p1); /* 00 11 */
|
||||
pre[4] = *p2; /* 01 00 */
|
||||
add_p1p1(&tp1p1,&pre[1], &pre[4]); p1p1_to_p3( &pre[5], &tp1p1); /* 01 01 */
|
||||
add_p1p1(&tp1p1,&pre[2], &pre[4]); p1p1_to_p3( &pre[6], &tp1p1); /* 01 10 */
|
||||
add_p1p1(&tp1p1,&pre[3], &pre[4]); p1p1_to_p3( &pre[7], &tp1p1); /* 01 11 */
|
||||
dbl_p1p1(&tp1p1,(ge25519_p2 *)p2); p1p1_to_p3( &pre[8], &tp1p1); /* 10 00 */
|
||||
add_p1p1(&tp1p1,&pre[1], &pre[8]); p1p1_to_p3( &pre[9], &tp1p1); /* 10 01 */
|
||||
dbl_p1p1(&tp1p1,(ge25519_p2 *)&pre[5]); p1p1_to_p3(&pre[10], &tp1p1); /* 10 10 */
|
||||
add_p1p1(&tp1p1,&pre[3], &pre[8]); p1p1_to_p3(&pre[11], &tp1p1); /* 10 11 */
|
||||
add_p1p1(&tp1p1,&pre[4], &pre[8]); p1p1_to_p3(&pre[12], &tp1p1); /* 11 00 */
|
||||
add_p1p1(&tp1p1,&pre[1],&pre[12]); p1p1_to_p3(&pre[13], &tp1p1); /* 11 01 */
|
||||
add_p1p1(&tp1p1,&pre[2],&pre[12]); p1p1_to_p3(&pre[14], &tp1p1); /* 11 10 */
|
||||
add_p1p1(&tp1p1,&pre[3],&pre[12]); p1p1_to_p3(&pre[15], &tp1p1); /* 11 11 */
|
||||
|
||||
sc25519_2interleave2(b,s1,s2);
|
||||
|
||||
/* scalar multiplication */
|
||||
*r = pre[b[126]];
|
||||
|
||||
for (i = 125; i >= 0; i--) {
|
||||
dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
|
||||
p1p1_to_p2((ge25519_p2 *) r, &tp1p1);
|
||||
dbl_p1p1(&tp1p1, (ge25519_p2 *)r);
|
||||
if(b[i] != 0) {
|
||||
p1p1_to_p3(r, &tp1p1);
|
||||
add_p1p1(&tp1p1, r, &pre[b[i]]);
|
||||
}
|
||||
if (i != 0) {
|
||||
p1p1_to_p2((ge25519_p2 *)r, &tp1p1);
|
||||
} else {
|
||||
p1p1_to_p3(r, &tp1p1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ge25519_scalarmult_base(ge25519_p3 *r, const sc25519 *s)
|
||||
{
|
||||
signed char b[85];
|
||||
int i;
|
||||
ge25519_aff t;
|
||||
|
||||
sc25519_window3(b,s);
|
||||
|
||||
choose_t((ge25519_aff *)r, 0, b[0]);
|
||||
fe25519_setone(&r->z);
|
||||
fe25519_mul(&r->t, &r->x, &r->y);
|
||||
for (i = 1; i < 85; i++) {
|
||||
choose_t(&t, (unsigned long long) i, b[i]);
|
||||
ge25519_mixadd2(r, &t);
|
||||
}
|
||||
}
|
858
libssh/src/ge25519_base.data
Normal file
858
libssh/src/ge25519_base.data
Normal file
@ -0,0 +1,858 @@
|
||||
/* $OpenBSD: ge25519_base.data,v 1.3 2013/12/09 11:03:45 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
|
||||
* Peter Schwabe, Bo-Yin Yang.
|
||||
* Copied from supercop-20130419/crypto_sign/ed25519/ref/ge25519_base.data
|
||||
*/
|
||||
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21}} ,
|
||||
{{0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}}},
|
||||
{{{0x0e, 0xce, 0x43, 0x28, 0x4e, 0xa1, 0xc5, 0x83, 0x5f, 0xa4, 0xd7, 0x15, 0x45, 0x8e, 0x0d, 0x08, 0xac, 0xe7, 0x33, 0x18, 0x7d, 0x3b, 0x04, 0x3d, 0x6c, 0x04, 0x5a, 0x9f, 0x4c, 0x38, 0xab, 0x36}} ,
|
||||
{{0xc9, 0xa3, 0xf8, 0x6a, 0xae, 0x46, 0x5f, 0x0e, 0x56, 0x51, 0x38, 0x64, 0x51, 0x0f, 0x39, 0x97, 0x56, 0x1f, 0xa2, 0xc9, 0xe8, 0x5e, 0xa2, 0x1d, 0xc2, 0x29, 0x23, 0x09, 0xf3, 0xcd, 0x60, 0x22}}},
|
||||
{{{0x5c, 0xe2, 0xf8, 0xd3, 0x5f, 0x48, 0x62, 0xac, 0x86, 0x48, 0x62, 0x81, 0x19, 0x98, 0x43, 0x63, 0x3a, 0xc8, 0xda, 0x3e, 0x74, 0xae, 0xf4, 0x1f, 0x49, 0x8f, 0x92, 0x22, 0x4a, 0x9c, 0xae, 0x67}} ,
|
||||
{{0xd4, 0xb4, 0xf5, 0x78, 0x48, 0x68, 0xc3, 0x02, 0x04, 0x03, 0x24, 0x67, 0x17, 0xec, 0x16, 0x9f, 0xf7, 0x9e, 0x26, 0x60, 0x8e, 0xa1, 0x26, 0xa1, 0xab, 0x69, 0xee, 0x77, 0xd1, 0xb1, 0x67, 0x12}}},
|
||||
{{{0x70, 0xf8, 0xc9, 0xc4, 0x57, 0xa6, 0x3a, 0x49, 0x47, 0x15, 0xce, 0x93, 0xc1, 0x9e, 0x73, 0x1a, 0xf9, 0x20, 0x35, 0x7a, 0xb8, 0xd4, 0x25, 0x83, 0x46, 0xf1, 0xcf, 0x56, 0xdb, 0xa8, 0x3d, 0x20}} ,
|
||||
{{0x2f, 0x11, 0x32, 0xca, 0x61, 0xab, 0x38, 0xdf, 0xf0, 0x0f, 0x2f, 0xea, 0x32, 0x28, 0xf2, 0x4c, 0x6c, 0x71, 0xd5, 0x80, 0x85, 0xb8, 0x0e, 0x47, 0xe1, 0x95, 0x15, 0xcb, 0x27, 0xe8, 0xd0, 0x47}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xc8, 0x84, 0xa5, 0x08, 0xbc, 0xfd, 0x87, 0x3b, 0x99, 0x8b, 0x69, 0x80, 0x7b, 0xc6, 0x3a, 0xeb, 0x93, 0xcf, 0x4e, 0xf8, 0x5c, 0x2d, 0x86, 0x42, 0xb6, 0x71, 0xd7, 0x97, 0x5f, 0xe1, 0x42, 0x67}} ,
|
||||
{{0xb4, 0xb9, 0x37, 0xfc, 0xa9, 0x5b, 0x2f, 0x1e, 0x93, 0xe4, 0x1e, 0x62, 0xfc, 0x3c, 0x78, 0x81, 0x8f, 0xf3, 0x8a, 0x66, 0x09, 0x6f, 0xad, 0x6e, 0x79, 0x73, 0xe5, 0xc9, 0x00, 0x06, 0xd3, 0x21}}},
|
||||
{{{0xf8, 0xf9, 0x28, 0x6c, 0x6d, 0x59, 0xb2, 0x59, 0x74, 0x23, 0xbf, 0xe7, 0x33, 0x8d, 0x57, 0x09, 0x91, 0x9c, 0x24, 0x08, 0x15, 0x2b, 0xe2, 0xb8, 0xee, 0x3a, 0xe5, 0x27, 0x06, 0x86, 0xa4, 0x23}} ,
|
||||
{{0xeb, 0x27, 0x67, 0xc1, 0x37, 0xab, 0x7a, 0xd8, 0x27, 0x9c, 0x07, 0x8e, 0xff, 0x11, 0x6a, 0xb0, 0x78, 0x6e, 0xad, 0x3a, 0x2e, 0x0f, 0x98, 0x9f, 0x72, 0xc3, 0x7f, 0x82, 0xf2, 0x96, 0x96, 0x70}}},
|
||||
{{{0x81, 0x6b, 0x88, 0xe8, 0x1e, 0xc7, 0x77, 0x96, 0x0e, 0xa1, 0xa9, 0x52, 0xe0, 0xd8, 0x0e, 0x61, 0x9e, 0x79, 0x2d, 0x95, 0x9c, 0x8d, 0x96, 0xe0, 0x06, 0x40, 0x5d, 0x87, 0x28, 0x5f, 0x98, 0x70}} ,
|
||||
{{0xf1, 0x79, 0x7b, 0xed, 0x4f, 0x44, 0xb2, 0xe7, 0x08, 0x0d, 0xc2, 0x08, 0x12, 0xd2, 0x9f, 0xdf, 0xcd, 0x93, 0x20, 0x8a, 0xcf, 0x33, 0xca, 0x6d, 0x89, 0xb9, 0x77, 0xc8, 0x93, 0x1b, 0x4e, 0x60}}},
|
||||
{{{0x26, 0x4f, 0x7e, 0x97, 0xf6, 0x40, 0xdd, 0x4f, 0xfc, 0x52, 0x78, 0xf9, 0x90, 0x31, 0x03, 0xe6, 0x7d, 0x56, 0x39, 0x0b, 0x1d, 0x56, 0x82, 0x85, 0xf9, 0x1a, 0x42, 0x17, 0x69, 0x6c, 0xcf, 0x39}} ,
|
||||
{{0x69, 0xd2, 0x06, 0x3a, 0x4f, 0x39, 0x2d, 0xf9, 0x38, 0x40, 0x8c, 0x4c, 0xe7, 0x05, 0x12, 0xb4, 0x78, 0x8b, 0xf8, 0xc0, 0xec, 0x93, 0xde, 0x7a, 0x6b, 0xce, 0x2c, 0xe1, 0x0e, 0xa9, 0x34, 0x44}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x0b, 0xa4, 0x3c, 0xb0, 0x0f, 0x7a, 0x51, 0xf1, 0x78, 0xd6, 0xd9, 0x6a, 0xfd, 0x46, 0xe8, 0xb8, 0xa8, 0x79, 0x1d, 0x87, 0xf9, 0x90, 0xf2, 0x9c, 0x13, 0x29, 0xf8, 0x0b, 0x20, 0x64, 0xfa, 0x05}} ,
|
||||
{{0x26, 0x09, 0xda, 0x17, 0xaf, 0x95, 0xd6, 0xfb, 0x6a, 0x19, 0x0d, 0x6e, 0x5e, 0x12, 0xf1, 0x99, 0x4c, 0xaa, 0xa8, 0x6f, 0x79, 0x86, 0xf4, 0x72, 0x28, 0x00, 0x26, 0xf9, 0xea, 0x9e, 0x19, 0x3d}}},
|
||||
{{{0x87, 0xdd, 0xcf, 0xf0, 0x5b, 0x49, 0xa2, 0x5d, 0x40, 0x7a, 0x23, 0x26, 0xa4, 0x7a, 0x83, 0x8a, 0xb7, 0x8b, 0xd2, 0x1a, 0xbf, 0xea, 0x02, 0x24, 0x08, 0x5f, 0x7b, 0xa9, 0xb1, 0xbe, 0x9d, 0x37}} ,
|
||||
{{0xfc, 0x86, 0x4b, 0x08, 0xee, 0xe7, 0xa0, 0xfd, 0x21, 0x45, 0x09, 0x34, 0xc1, 0x61, 0x32, 0x23, 0xfc, 0x9b, 0x55, 0x48, 0x53, 0x99, 0xf7, 0x63, 0xd0, 0x99, 0xce, 0x01, 0xe0, 0x9f, 0xeb, 0x28}}},
|
||||
{{{0x47, 0xfc, 0xab, 0x5a, 0x17, 0xf0, 0x85, 0x56, 0x3a, 0x30, 0x86, 0x20, 0x28, 0x4b, 0x8e, 0x44, 0x74, 0x3a, 0x6e, 0x02, 0xf1, 0x32, 0x8f, 0x9f, 0x3f, 0x08, 0x35, 0xe9, 0xca, 0x16, 0x5f, 0x6e}} ,
|
||||
{{0x1c, 0x59, 0x1c, 0x65, 0x5d, 0x34, 0xa4, 0x09, 0xcd, 0x13, 0x9c, 0x70, 0x7d, 0xb1, 0x2a, 0xc5, 0x88, 0xaf, 0x0b, 0x60, 0xc7, 0x9f, 0x34, 0x8d, 0xd6, 0xb7, 0x7f, 0xea, 0x78, 0x65, 0x8d, 0x77}}},
|
||||
{{{0x56, 0xa5, 0xc2, 0x0c, 0xdd, 0xbc, 0xb8, 0x20, 0x6d, 0x57, 0x61, 0xb5, 0xfb, 0x78, 0xb5, 0xd4, 0x49, 0x54, 0x90, 0x26, 0xc1, 0xcb, 0xe9, 0xe6, 0xbf, 0xec, 0x1d, 0x4e, 0xed, 0x07, 0x7e, 0x5e}} ,
|
||||
{{0xc7, 0xf6, 0x6c, 0x56, 0x31, 0x20, 0x14, 0x0e, 0xa8, 0xd9, 0x27, 0xc1, 0x9a, 0x3d, 0x1b, 0x7d, 0x0e, 0x26, 0xd3, 0x81, 0xaa, 0xeb, 0xf5, 0x6b, 0x79, 0x02, 0xf1, 0x51, 0x5c, 0x75, 0x55, 0x0f}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x0a, 0x34, 0xcd, 0x82, 0x3c, 0x33, 0x09, 0x54, 0xd2, 0x61, 0x39, 0x30, 0x9b, 0xfd, 0xef, 0x21, 0x26, 0xd4, 0x70, 0xfa, 0xee, 0xf9, 0x31, 0x33, 0x73, 0x84, 0xd0, 0xb3, 0x81, 0xbf, 0xec, 0x2e}} ,
|
||||
{{0xe8, 0x93, 0x8b, 0x00, 0x64, 0xf7, 0x9c, 0xb8, 0x74, 0xe0, 0xe6, 0x49, 0x48, 0x4d, 0x4d, 0x48, 0xb6, 0x19, 0xa1, 0x40, 0xb7, 0xd9, 0x32, 0x41, 0x7c, 0x82, 0x37, 0xa1, 0x2d, 0xdc, 0xd2, 0x54}}},
|
||||
{{{0x68, 0x2b, 0x4a, 0x5b, 0xd5, 0xc7, 0x51, 0x91, 0x1d, 0xe1, 0x2a, 0x4b, 0xc4, 0x47, 0xf1, 0xbc, 0x7a, 0xb3, 0xcb, 0xc8, 0xb6, 0x7c, 0xac, 0x90, 0x05, 0xfd, 0xf3, 0xf9, 0x52, 0x3a, 0x11, 0x6b}} ,
|
||||
{{0x3d, 0xc1, 0x27, 0xf3, 0x59, 0x43, 0x95, 0x90, 0xc5, 0x96, 0x79, 0xf5, 0xf4, 0x95, 0x65, 0x29, 0x06, 0x9c, 0x51, 0x05, 0x18, 0xda, 0xb8, 0x2e, 0x79, 0x7e, 0x69, 0x59, 0x71, 0x01, 0xeb, 0x1a}}},
|
||||
{{{0x15, 0x06, 0x49, 0xb6, 0x8a, 0x3c, 0xea, 0x2f, 0x34, 0x20, 0x14, 0xc3, 0xaa, 0xd6, 0xaf, 0x2c, 0x3e, 0xbd, 0x65, 0x20, 0xe2, 0x4d, 0x4b, 0x3b, 0xeb, 0x9f, 0x4a, 0xc3, 0xad, 0xa4, 0x3b, 0x60}} ,
|
||||
{{0xbc, 0x58, 0xe6, 0xc0, 0x95, 0x2a, 0x2a, 0x81, 0x9a, 0x7a, 0xf3, 0xd2, 0x06, 0xbe, 0x48, 0xbc, 0x0c, 0xc5, 0x46, 0xe0, 0x6a, 0xd4, 0xac, 0x0f, 0xd9, 0xcc, 0x82, 0x34, 0x2c, 0xaf, 0xdb, 0x1f}}},
|
||||
{{{0xf7, 0x17, 0x13, 0xbd, 0xfb, 0xbc, 0xd2, 0xec, 0x45, 0xb3, 0x15, 0x31, 0xe9, 0xaf, 0x82, 0x84, 0x3d, 0x28, 0xc6, 0xfc, 0x11, 0xf5, 0x41, 0xb5, 0x8b, 0xd3, 0x12, 0x76, 0x52, 0xe7, 0x1a, 0x3c}} ,
|
||||
{{0x4e, 0x36, 0x11, 0x07, 0xa2, 0x15, 0x20, 0x51, 0xc4, 0x2a, 0xc3, 0x62, 0x8b, 0x5e, 0x7f, 0xa6, 0x0f, 0xf9, 0x45, 0x85, 0x6c, 0x11, 0x86, 0xb7, 0x7e, 0xe5, 0xd7, 0xf9, 0xc3, 0x91, 0x1c, 0x05}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xea, 0xd6, 0xde, 0x29, 0x3a, 0x00, 0xb9, 0x02, 0x59, 0xcb, 0x26, 0xc4, 0xba, 0x99, 0xb1, 0x97, 0x2f, 0x8e, 0x00, 0x92, 0x26, 0x4f, 0x52, 0xeb, 0x47, 0x1b, 0x89, 0x8b, 0x24, 0xc0, 0x13, 0x7d}} ,
|
||||
{{0xd5, 0x20, 0x5b, 0x80, 0xa6, 0x80, 0x20, 0x95, 0xc3, 0xe9, 0x9f, 0x8e, 0x87, 0x9e, 0x1e, 0x9e, 0x7a, 0xc7, 0xcc, 0x75, 0x6c, 0xa5, 0xf1, 0x91, 0x1a, 0xa8, 0x01, 0x2c, 0xab, 0x76, 0xa9, 0x59}}},
|
||||
{{{0xde, 0xc9, 0xb1, 0x31, 0x10, 0x16, 0xaa, 0x35, 0x14, 0x6a, 0xd4, 0xb5, 0x34, 0x82, 0x71, 0xd2, 0x4a, 0x5d, 0x9a, 0x1f, 0x53, 0x26, 0x3c, 0xe5, 0x8e, 0x8d, 0x33, 0x7f, 0xff, 0xa9, 0xd5, 0x17}} ,
|
||||
{{0x89, 0xaf, 0xf6, 0xa4, 0x64, 0xd5, 0x10, 0xe0, 0x1d, 0xad, 0xef, 0x44, 0xbd, 0xda, 0x83, 0xac, 0x7a, 0xa8, 0xf0, 0x1c, 0x07, 0xf9, 0xc3, 0x43, 0x6c, 0x3f, 0xb7, 0xd3, 0x87, 0x22, 0x02, 0x73}}},
|
||||
{{{0x64, 0x1d, 0x49, 0x13, 0x2f, 0x71, 0xec, 0x69, 0x87, 0xd0, 0x42, 0xee, 0x13, 0xec, 0xe3, 0xed, 0x56, 0x7b, 0xbf, 0xbd, 0x8c, 0x2f, 0x7d, 0x7b, 0x9d, 0x28, 0xec, 0x8e, 0x76, 0x2f, 0x6f, 0x08}} ,
|
||||
{{0x22, 0xf5, 0x5f, 0x4d, 0x15, 0xef, 0xfc, 0x4e, 0x57, 0x03, 0x36, 0x89, 0xf0, 0xeb, 0x5b, 0x91, 0xd6, 0xe2, 0xca, 0x01, 0xa5, 0xee, 0x52, 0xec, 0xa0, 0x3c, 0x8f, 0x33, 0x90, 0x5a, 0x94, 0x72}}},
|
||||
{{{0x8a, 0x4b, 0xe7, 0x38, 0xbc, 0xda, 0xc2, 0xb0, 0x85, 0xe1, 0x4a, 0xfe, 0x2d, 0x44, 0x84, 0xcb, 0x20, 0x6b, 0x2d, 0xbf, 0x11, 0x9c, 0xd7, 0xbe, 0xd3, 0x3e, 0x5f, 0xbf, 0x68, 0xbc, 0xa8, 0x07}} ,
|
||||
{{0x01, 0x89, 0x28, 0x22, 0x6a, 0x78, 0xaa, 0x29, 0x03, 0xc8, 0x74, 0x95, 0x03, 0x3e, 0xdc, 0xbd, 0x07, 0x13, 0xa8, 0xa2, 0x20, 0x2d, 0xb3, 0x18, 0x70, 0x42, 0xfd, 0x7a, 0xc4, 0xd7, 0x49, 0x72}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x02, 0xff, 0x32, 0x2b, 0x5c, 0x93, 0x54, 0x32, 0xe8, 0x57, 0x54, 0x1a, 0x8b, 0x33, 0x60, 0x65, 0xd3, 0x67, 0xa4, 0xc1, 0x26, 0xc4, 0xa4, 0x34, 0x1f, 0x9b, 0xa7, 0xa9, 0xf4, 0xd9, 0x4f, 0x5b}} ,
|
||||
{{0x46, 0x8d, 0xb0, 0x33, 0x54, 0x26, 0x5b, 0x68, 0xdf, 0xbb, 0xc5, 0xec, 0xc2, 0xf9, 0x3c, 0x5a, 0x37, 0xc1, 0x8e, 0x27, 0x47, 0xaa, 0x49, 0x5a, 0xf8, 0xfb, 0x68, 0x04, 0x23, 0xd1, 0xeb, 0x40}}},
|
||||
{{{0x65, 0xa5, 0x11, 0x84, 0x8a, 0x67, 0x9d, 0x9e, 0xd1, 0x44, 0x68, 0x7a, 0x34, 0xe1, 0x9f, 0xa3, 0x54, 0xcd, 0x07, 0xca, 0x79, 0x1f, 0x54, 0x2f, 0x13, 0x70, 0x4e, 0xee, 0xa2, 0xfa, 0xe7, 0x5d}} ,
|
||||
{{0x36, 0xec, 0x54, 0xf8, 0xce, 0xe4, 0x85, 0xdf, 0xf6, 0x6f, 0x1d, 0x90, 0x08, 0xbc, 0xe8, 0xc0, 0x92, 0x2d, 0x43, 0x6b, 0x92, 0xa9, 0x8e, 0xab, 0x0a, 0x2e, 0x1c, 0x1e, 0x64, 0x23, 0x9f, 0x2c}}},
|
||||
{{{0xa7, 0xd6, 0x2e, 0xd5, 0xcc, 0xd4, 0xcb, 0x5a, 0x3b, 0xa7, 0xf9, 0x46, 0x03, 0x1d, 0xad, 0x2b, 0x34, 0x31, 0x90, 0x00, 0x46, 0x08, 0x82, 0x14, 0xc4, 0xe0, 0x9c, 0xf0, 0xe3, 0x55, 0x43, 0x31}} ,
|
||||
{{0x60, 0xd6, 0xdd, 0x78, 0xe6, 0xd4, 0x22, 0x42, 0x1f, 0x00, 0xf9, 0xb1, 0x6a, 0x63, 0xe2, 0x92, 0x59, 0xd1, 0x1a, 0xb7, 0x00, 0x54, 0x29, 0xc9, 0xc1, 0xf6, 0x6f, 0x7a, 0xc5, 0x3c, 0x5f, 0x65}}},
|
||||
{{{0x27, 0x4f, 0xd0, 0x72, 0xb1, 0x11, 0x14, 0x27, 0x15, 0x94, 0x48, 0x81, 0x7e, 0x74, 0xd8, 0x32, 0xd5, 0xd1, 0x11, 0x28, 0x60, 0x63, 0x36, 0x32, 0x37, 0xb5, 0x13, 0x1c, 0xa0, 0x37, 0xe3, 0x74}} ,
|
||||
{{0xf1, 0x25, 0x4e, 0x11, 0x96, 0x67, 0xe6, 0x1c, 0xc2, 0xb2, 0x53, 0xe2, 0xda, 0x85, 0xee, 0xb2, 0x9f, 0x59, 0xf3, 0xba, 0xbd, 0xfa, 0xcf, 0x6e, 0xf9, 0xda, 0xa4, 0xb3, 0x02, 0x8f, 0x64, 0x08}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x34, 0x94, 0xf2, 0x64, 0x54, 0x47, 0x37, 0x07, 0x40, 0x8a, 0x20, 0xba, 0x4a, 0x55, 0xd7, 0x3f, 0x47, 0xba, 0x25, 0x23, 0x14, 0xb0, 0x2c, 0xe8, 0x55, 0xa8, 0xa6, 0xef, 0x51, 0xbd, 0x6f, 0x6a}} ,
|
||||
{{0x71, 0xd6, 0x16, 0x76, 0xb2, 0x06, 0xea, 0x79, 0xf5, 0xc4, 0xc3, 0x52, 0x7e, 0x61, 0xd1, 0xe1, 0xad, 0x70, 0x78, 0x1d, 0x16, 0x11, 0xf8, 0x7c, 0x2b, 0xfc, 0x55, 0x9f, 0x52, 0xf8, 0xf5, 0x16}}},
|
||||
{{{0x34, 0x96, 0x9a, 0xf6, 0xc5, 0xe0, 0x14, 0x03, 0x24, 0x0e, 0x4c, 0xad, 0x9e, 0x9a, 0x70, 0x23, 0x96, 0xb2, 0xf1, 0x2e, 0x9d, 0xc3, 0x32, 0x9b, 0x54, 0xa5, 0x73, 0xde, 0x88, 0xb1, 0x3e, 0x24}} ,
|
||||
{{0xf6, 0xe2, 0x4c, 0x1f, 0x5b, 0xb2, 0xaf, 0x82, 0xa5, 0xcf, 0x81, 0x10, 0x04, 0xef, 0xdb, 0xa2, 0xcc, 0x24, 0xb2, 0x7e, 0x0b, 0x7a, 0xeb, 0x01, 0xd8, 0x52, 0xf4, 0x51, 0x89, 0x29, 0x79, 0x37}}},
|
||||
{{{0x74, 0xde, 0x12, 0xf3, 0x68, 0xb7, 0x66, 0xc3, 0xee, 0x68, 0xdc, 0x81, 0xb5, 0x55, 0x99, 0xab, 0xd9, 0x28, 0x63, 0x6d, 0x8b, 0x40, 0x69, 0x75, 0x6c, 0xcd, 0x5c, 0x2a, 0x7e, 0x32, 0x7b, 0x29}} ,
|
||||
{{0x02, 0xcc, 0x22, 0x74, 0x4d, 0x19, 0x07, 0xc0, 0xda, 0xb5, 0x76, 0x51, 0x2a, 0xaa, 0xa6, 0x0a, 0x5f, 0x26, 0xd4, 0xbc, 0xaf, 0x48, 0x88, 0x7f, 0x02, 0xbc, 0xf2, 0xe1, 0xcf, 0xe9, 0xdd, 0x15}}},
|
||||
{{{0xed, 0xb5, 0x9a, 0x8c, 0x9a, 0xdd, 0x27, 0xf4, 0x7f, 0x47, 0xd9, 0x52, 0xa7, 0xcd, 0x65, 0xa5, 0x31, 0x22, 0xed, 0xa6, 0x63, 0x5b, 0x80, 0x4a, 0xad, 0x4d, 0xed, 0xbf, 0xee, 0x49, 0xb3, 0x06}} ,
|
||||
{{0xf8, 0x64, 0x8b, 0x60, 0x90, 0xe9, 0xde, 0x44, 0x77, 0xb9, 0x07, 0x36, 0x32, 0xc2, 0x50, 0xf5, 0x65, 0xdf, 0x48, 0x4c, 0x37, 0xaa, 0x68, 0xab, 0x9a, 0x1f, 0x3e, 0xff, 0x89, 0x92, 0xa0, 0x07}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x7d, 0x4f, 0x9c, 0x19, 0xc0, 0x4a, 0x31, 0xec, 0xf9, 0xaa, 0xeb, 0xb2, 0x16, 0x9c, 0xa3, 0x66, 0x5f, 0xd1, 0xd4, 0xed, 0xb8, 0x92, 0x1c, 0xab, 0xda, 0xea, 0xd9, 0x57, 0xdf, 0x4c, 0x2a, 0x48}} ,
|
||||
{{0x4b, 0xb0, 0x4e, 0x6e, 0x11, 0x3b, 0x51, 0xbd, 0x6a, 0xfd, 0xe4, 0x25, 0xa5, 0x5f, 0x11, 0x3f, 0x98, 0x92, 0x51, 0x14, 0xc6, 0x5f, 0x3c, 0x0b, 0xa8, 0xf7, 0xc2, 0x81, 0x43, 0xde, 0x91, 0x73}}},
|
||||
{{{0x3c, 0x8f, 0x9f, 0x33, 0x2a, 0x1f, 0x43, 0x33, 0x8f, 0x68, 0xff, 0x1f, 0x3d, 0x73, 0x6b, 0xbf, 0x68, 0xcc, 0x7d, 0x13, 0x6c, 0x24, 0x4b, 0xcc, 0x4d, 0x24, 0x0d, 0xfe, 0xde, 0x86, 0xad, 0x3b}} ,
|
||||
{{0x79, 0x51, 0x81, 0x01, 0xdc, 0x73, 0x53, 0xe0, 0x6e, 0x9b, 0xea, 0x68, 0x3f, 0x5c, 0x14, 0x84, 0x53, 0x8d, 0x4b, 0xc0, 0x9f, 0x9f, 0x89, 0x2b, 0x8c, 0xba, 0x86, 0xfa, 0xf2, 0xcd, 0xe3, 0x2d}}},
|
||||
{{{0x06, 0xf9, 0x29, 0x5a, 0xdb, 0x3d, 0x84, 0x52, 0xab, 0xcc, 0x6b, 0x60, 0x9d, 0xb7, 0x4a, 0x0e, 0x36, 0x63, 0x91, 0xad, 0xa0, 0x95, 0xb0, 0x97, 0x89, 0x4e, 0xcf, 0x7d, 0x3c, 0xe5, 0x7c, 0x28}} ,
|
||||
{{0x2e, 0x69, 0x98, 0xfd, 0xc6, 0xbd, 0xcc, 0xca, 0xdf, 0x9a, 0x44, 0x7e, 0x9d, 0xca, 0x89, 0x6d, 0xbf, 0x27, 0xc2, 0xf8, 0xcd, 0x46, 0x00, 0x2b, 0xb5, 0x58, 0x4e, 0xb7, 0x89, 0x09, 0xe9, 0x2d}}},
|
||||
{{{0x54, 0xbe, 0x75, 0xcb, 0x05, 0xb0, 0x54, 0xb7, 0xe7, 0x26, 0x86, 0x4a, 0xfc, 0x19, 0xcf, 0x27, 0x46, 0xd4, 0x22, 0x96, 0x5a, 0x11, 0xe8, 0xd5, 0x1b, 0xed, 0x71, 0xc5, 0x5d, 0xc8, 0xaf, 0x45}} ,
|
||||
{{0x40, 0x7b, 0x77, 0x57, 0x49, 0x9e, 0x80, 0x39, 0x23, 0xee, 0x81, 0x0b, 0x22, 0xcf, 0xdb, 0x7a, 0x2f, 0x14, 0xb8, 0x57, 0x8f, 0xa1, 0x39, 0x1e, 0x77, 0xfc, 0x0b, 0xa6, 0xbf, 0x8a, 0x0c, 0x6c}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x77, 0x3a, 0xd4, 0xd8, 0x27, 0xcf, 0xe8, 0xa1, 0x72, 0x9d, 0xca, 0xdd, 0x0d, 0x96, 0xda, 0x79, 0xed, 0x56, 0x42, 0x15, 0x60, 0xc7, 0x1c, 0x6b, 0x26, 0x30, 0xf6, 0x6a, 0x95, 0x67, 0xf3, 0x0a}} ,
|
||||
{{0xc5, 0x08, 0xa4, 0x2b, 0x2f, 0xbd, 0x31, 0x81, 0x2a, 0xa6, 0xb6, 0xe4, 0x00, 0x91, 0xda, 0x3d, 0xb2, 0xb0, 0x96, 0xce, 0x8a, 0xd2, 0x8d, 0x70, 0xb3, 0xd3, 0x34, 0x01, 0x90, 0x8d, 0x10, 0x21}}},
|
||||
{{{0x33, 0x0d, 0xe7, 0xba, 0x4f, 0x07, 0xdf, 0x8d, 0xea, 0x7d, 0xa0, 0xc5, 0xd6, 0xb1, 0xb0, 0xe5, 0x57, 0x1b, 0x5b, 0xf5, 0x45, 0x13, 0x14, 0x64, 0x5a, 0xeb, 0x5c, 0xfc, 0x54, 0x01, 0x76, 0x2b}} ,
|
||||
{{0x02, 0x0c, 0xc2, 0xaf, 0x96, 0x36, 0xfe, 0x4a, 0xe2, 0x54, 0x20, 0x6a, 0xeb, 0xb2, 0x9f, 0x62, 0xd7, 0xce, 0xa2, 0x3f, 0x20, 0x11, 0x34, 0x37, 0xe0, 0x42, 0xed, 0x6f, 0xf9, 0x1a, 0xc8, 0x7d}}},
|
||||
{{{0xd8, 0xb9, 0x11, 0xe8, 0x36, 0x3f, 0x42, 0xc1, 0xca, 0xdc, 0xd3, 0xf1, 0xc8, 0x23, 0x3d, 0x4f, 0x51, 0x7b, 0x9d, 0x8d, 0xd8, 0xe4, 0xa0, 0xaa, 0xf3, 0x04, 0xd6, 0x11, 0x93, 0xc8, 0x35, 0x45}} ,
|
||||
{{0x61, 0x36, 0xd6, 0x08, 0x90, 0xbf, 0xa7, 0x7a, 0x97, 0x6c, 0x0f, 0x84, 0xd5, 0x33, 0x2d, 0x37, 0xc9, 0x6a, 0x80, 0x90, 0x3d, 0x0a, 0xa2, 0xaa, 0xe1, 0xb8, 0x84, 0xba, 0x61, 0x36, 0xdd, 0x69}}},
|
||||
{{{0x6b, 0xdb, 0x5b, 0x9c, 0xc6, 0x92, 0xbc, 0x23, 0xaf, 0xc5, 0xb8, 0x75, 0xf8, 0x42, 0xfa, 0xd6, 0xb6, 0x84, 0x94, 0x63, 0x98, 0x93, 0x48, 0x78, 0x38, 0xcd, 0xbb, 0x18, 0x34, 0xc3, 0xdb, 0x67}} ,
|
||||
{{0x96, 0xf3, 0x3a, 0x09, 0x56, 0xb0, 0x6f, 0x7c, 0x51, 0x1e, 0x1b, 0x39, 0x48, 0xea, 0xc9, 0x0c, 0x25, 0xa2, 0x7a, 0xca, 0xe7, 0x92, 0xfc, 0x59, 0x30, 0xa3, 0x89, 0x85, 0xdf, 0x6f, 0x43, 0x38}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x79, 0x84, 0x44, 0x19, 0xbd, 0xe9, 0x54, 0xc4, 0xc0, 0x6e, 0x2a, 0xa8, 0xa8, 0x9b, 0x43, 0xd5, 0x71, 0x22, 0x5f, 0xdc, 0x01, 0xfa, 0xdf, 0xb3, 0xb8, 0x47, 0x4b, 0x0a, 0xa5, 0x44, 0xea, 0x29}} ,
|
||||
{{0x05, 0x90, 0x50, 0xaf, 0x63, 0x5f, 0x9d, 0x9e, 0xe1, 0x9d, 0x38, 0x97, 0x1f, 0x6c, 0xac, 0x30, 0x46, 0xb2, 0x6a, 0x19, 0xd1, 0x4b, 0xdb, 0xbb, 0x8c, 0xda, 0x2e, 0xab, 0xc8, 0x5a, 0x77, 0x6c}}},
|
||||
{{{0x2b, 0xbe, 0xaf, 0xa1, 0x6d, 0x2f, 0x0b, 0xb1, 0x8f, 0xe3, 0xe0, 0x38, 0xcd, 0x0b, 0x41, 0x1b, 0x4a, 0x15, 0x07, 0xf3, 0x6f, 0xdc, 0xb8, 0xe9, 0xde, 0xb2, 0xa3, 0x40, 0x01, 0xa6, 0x45, 0x1e}} ,
|
||||
{{0x76, 0x0a, 0xda, 0x8d, 0x2c, 0x07, 0x3f, 0x89, 0x7d, 0x04, 0xad, 0x43, 0x50, 0x6e, 0xd2, 0x47, 0xcb, 0x8a, 0xe6, 0x85, 0x1a, 0x24, 0xf3, 0xd2, 0x60, 0xfd, 0xdf, 0x73, 0xa4, 0x0d, 0x73, 0x0e}}},
|
||||
{{{0xfd, 0x67, 0x6b, 0x71, 0x9b, 0x81, 0x53, 0x39, 0x39, 0xf4, 0xb8, 0xd5, 0xc3, 0x30, 0x9b, 0x3b, 0x7c, 0xa3, 0xf0, 0xd0, 0x84, 0x21, 0xd6, 0xbf, 0xb7, 0x4c, 0x87, 0x13, 0x45, 0x2d, 0xa7, 0x55}} ,
|
||||
{{0x5d, 0x04, 0xb3, 0x40, 0x28, 0x95, 0x2d, 0x30, 0x83, 0xec, 0x5e, 0xe4, 0xff, 0x75, 0xfe, 0x79, 0x26, 0x9d, 0x1d, 0x36, 0xcd, 0x0a, 0x15, 0xd2, 0x24, 0x14, 0x77, 0x71, 0xd7, 0x8a, 0x1b, 0x04}}},
|
||||
{{{0x5d, 0x93, 0xc9, 0xbe, 0xaa, 0x90, 0xcd, 0x9b, 0xfb, 0x73, 0x7e, 0xb0, 0x64, 0x98, 0x57, 0x44, 0x42, 0x41, 0xb1, 0xaf, 0xea, 0xc1, 0xc3, 0x22, 0xff, 0x60, 0x46, 0xcb, 0x61, 0x81, 0x70, 0x61}} ,
|
||||
{{0x0d, 0x82, 0xb9, 0xfe, 0x21, 0xcd, 0xc4, 0xf5, 0x98, 0x0c, 0x4e, 0x72, 0xee, 0x87, 0x49, 0xf8, 0xa1, 0x95, 0xdf, 0x8f, 0x2d, 0xbd, 0x21, 0x06, 0x7c, 0x15, 0xe8, 0x12, 0x6d, 0x93, 0xd6, 0x38}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x91, 0xf7, 0x51, 0xd9, 0xef, 0x7d, 0x42, 0x01, 0x13, 0xe9, 0xb8, 0x7f, 0xa6, 0x49, 0x17, 0x64, 0x21, 0x80, 0x83, 0x2c, 0x63, 0x4c, 0x60, 0x09, 0x59, 0x91, 0x92, 0x77, 0x39, 0x51, 0xf4, 0x48}} ,
|
||||
{{0x60, 0xd5, 0x22, 0x83, 0x08, 0x2f, 0xff, 0x99, 0x3e, 0x69, 0x6d, 0x88, 0xda, 0xe7, 0x5b, 0x52, 0x26, 0x31, 0x2a, 0xe5, 0x89, 0xde, 0x68, 0x90, 0xb6, 0x22, 0x5a, 0xbd, 0xd3, 0x85, 0x53, 0x31}}},
|
||||
{{{0xd8, 0xce, 0xdc, 0xf9, 0x3c, 0x4b, 0xa2, 0x1d, 0x2c, 0x2f, 0x36, 0xbe, 0x7a, 0xfc, 0xcd, 0xbc, 0xdc, 0xf9, 0x30, 0xbd, 0xff, 0x05, 0xc7, 0xe4, 0x8e, 0x17, 0x62, 0xf8, 0x4d, 0xa0, 0x56, 0x79}} ,
|
||||
{{0x82, 0xe7, 0xf6, 0xba, 0x53, 0x84, 0x0a, 0xa3, 0x34, 0xff, 0x3c, 0xa3, 0x6a, 0xa1, 0x37, 0xea, 0xdd, 0xb6, 0x95, 0xb3, 0x78, 0x19, 0x76, 0x1e, 0x55, 0x2f, 0x77, 0x2e, 0x7f, 0xc1, 0xea, 0x5e}}},
|
||||
{{{0x83, 0xe1, 0x6e, 0xa9, 0x07, 0x33, 0x3e, 0x83, 0xff, 0xcb, 0x1c, 0x9f, 0xb1, 0xa3, 0xb4, 0xc9, 0xe1, 0x07, 0x97, 0xff, 0xf8, 0x23, 0x8f, 0xce, 0x40, 0xfd, 0x2e, 0x5e, 0xdb, 0x16, 0x43, 0x2d}} ,
|
||||
{{0xba, 0x38, 0x02, 0xf7, 0x81, 0x43, 0x83, 0xa3, 0x20, 0x4f, 0x01, 0x3b, 0x8a, 0x04, 0x38, 0x31, 0xc6, 0x0f, 0xc8, 0xdf, 0xd7, 0xfa, 0x2f, 0x88, 0x3f, 0xfc, 0x0c, 0x76, 0xc4, 0xa6, 0x45, 0x72}}},
|
||||
{{{0xbb, 0x0c, 0xbc, 0x6a, 0xa4, 0x97, 0x17, 0x93, 0x2d, 0x6f, 0xde, 0x72, 0x10, 0x1c, 0x08, 0x2c, 0x0f, 0x80, 0x32, 0x68, 0x27, 0xd4, 0xab, 0xdd, 0xc5, 0x58, 0x61, 0x13, 0x6d, 0x11, 0x1e, 0x4d}} ,
|
||||
{{0x1a, 0xb9, 0xc9, 0x10, 0xfb, 0x1e, 0x4e, 0xf4, 0x84, 0x4b, 0x8a, 0x5e, 0x7b, 0x4b, 0xe8, 0x43, 0x8c, 0x8f, 0x00, 0xb5, 0x54, 0x13, 0xc5, 0x5c, 0xb6, 0x35, 0x4e, 0x9d, 0xe4, 0x5b, 0x41, 0x6d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x15, 0x7d, 0x12, 0x48, 0x82, 0x14, 0x42, 0xcd, 0x32, 0xd4, 0x4b, 0xc1, 0x72, 0x61, 0x2a, 0x8c, 0xec, 0xe2, 0xf8, 0x24, 0x45, 0x94, 0xe3, 0xbe, 0xdd, 0x67, 0xa8, 0x77, 0x5a, 0xae, 0x5b, 0x4b}} ,
|
||||
{{0xcb, 0x77, 0x9a, 0x20, 0xde, 0xb8, 0x23, 0xd9, 0xa0, 0x0f, 0x8c, 0x7b, 0xa5, 0xcb, 0xae, 0xb6, 0xec, 0x42, 0x67, 0x0e, 0x58, 0xa4, 0x75, 0x98, 0x21, 0x71, 0x84, 0xb3, 0xe0, 0x76, 0x94, 0x73}}},
|
||||
{{{0xdf, 0xfc, 0x69, 0x28, 0x23, 0x3f, 0x5b, 0xf8, 0x3b, 0x24, 0x37, 0xf3, 0x1d, 0xd5, 0x22, 0x6b, 0xd0, 0x98, 0xa8, 0x6c, 0xcf, 0xff, 0x06, 0xe1, 0x13, 0xdf, 0xb9, 0xc1, 0x0c, 0xa9, 0xbf, 0x33}} ,
|
||||
{{0xd9, 0x81, 0xda, 0xb2, 0x4f, 0x82, 0x9d, 0x43, 0x81, 0x09, 0xf1, 0xd2, 0x01, 0xef, 0xac, 0xf4, 0x2d, 0x7d, 0x01, 0x09, 0xf1, 0xff, 0xa5, 0x9f, 0xe5, 0xca, 0x27, 0x63, 0xdb, 0x20, 0xb1, 0x53}}},
|
||||
{{{0x67, 0x02, 0xe8, 0xad, 0xa9, 0x34, 0xd4, 0xf0, 0x15, 0x81, 0xaa, 0xc7, 0x4d, 0x87, 0x94, 0xea, 0x75, 0xe7, 0x4c, 0x94, 0x04, 0x0e, 0x69, 0x87, 0xe7, 0x51, 0x91, 0x10, 0x03, 0xc7, 0xbe, 0x56}} ,
|
||||
{{0x32, 0xfb, 0x86, 0xec, 0x33, 0x6b, 0x2e, 0x51, 0x2b, 0xc8, 0xfa, 0x6c, 0x70, 0x47, 0x7e, 0xce, 0x05, 0x0c, 0x71, 0xf3, 0xb4, 0x56, 0xa6, 0xdc, 0xcc, 0x78, 0x07, 0x75, 0xd0, 0xdd, 0xb2, 0x6a}}},
|
||||
{{{0xc6, 0xef, 0xb9, 0xc0, 0x2b, 0x22, 0x08, 0x1e, 0x71, 0x70, 0xb3, 0x35, 0x9c, 0x7a, 0x01, 0x92, 0x44, 0x9a, 0xf6, 0xb0, 0x58, 0x95, 0xc1, 0x9b, 0x02, 0xed, 0x2d, 0x7c, 0x34, 0x29, 0x49, 0x44}} ,
|
||||
{{0x45, 0x62, 0x1d, 0x2e, 0xff, 0x2a, 0x1c, 0x21, 0xa4, 0x25, 0x7b, 0x0d, 0x8c, 0x15, 0x39, 0xfc, 0x8f, 0x7c, 0xa5, 0x7d, 0x1e, 0x25, 0xa3, 0x45, 0xd6, 0xab, 0xbd, 0xcb, 0xc5, 0x5e, 0x78, 0x77}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xd0, 0xd3, 0x42, 0xed, 0x1d, 0x00, 0x3c, 0x15, 0x2c, 0x9c, 0x77, 0x81, 0xd2, 0x73, 0xd1, 0x06, 0xd5, 0xc4, 0x7f, 0x94, 0xbb, 0x92, 0x2d, 0x2c, 0x4b, 0x45, 0x4b, 0xe9, 0x2a, 0x89, 0x6b, 0x2b}} ,
|
||||
{{0xd2, 0x0c, 0x88, 0xc5, 0x48, 0x4d, 0xea, 0x0d, 0x4a, 0xc9, 0x52, 0x6a, 0x61, 0x79, 0xe9, 0x76, 0xf3, 0x85, 0x52, 0x5c, 0x1b, 0x2c, 0xe1, 0xd6, 0xc4, 0x0f, 0x18, 0x0e, 0x4e, 0xf6, 0x1c, 0x7f}}},
|
||||
{{{0xb4, 0x04, 0x2e, 0x42, 0xcb, 0x1f, 0x2b, 0x11, 0x51, 0x7b, 0x08, 0xac, 0xaa, 0x3e, 0x9e, 0x52, 0x60, 0xb7, 0xc2, 0x61, 0x57, 0x8c, 0x84, 0xd5, 0x18, 0xa6, 0x19, 0xfc, 0xb7, 0x75, 0x91, 0x1b}} ,
|
||||
{{0xe8, 0x68, 0xca, 0x44, 0xc8, 0x38, 0x38, 0xcc, 0x53, 0x0a, 0x32, 0x35, 0xcc, 0x52, 0xcb, 0x0e, 0xf7, 0xc5, 0xe7, 0xec, 0x3d, 0x85, 0xcc, 0x58, 0xe2, 0x17, 0x47, 0xff, 0x9f, 0xa5, 0x30, 0x17}}},
|
||||
{{{0xe3, 0xae, 0xc8, 0xc1, 0x71, 0x75, 0x31, 0x00, 0x37, 0x41, 0x5c, 0x0e, 0x39, 0xda, 0x73, 0xa0, 0xc7, 0x97, 0x36, 0x6c, 0x5b, 0xf2, 0xee, 0x64, 0x0a, 0x3d, 0x89, 0x1e, 0x1d, 0x49, 0x8c, 0x37}} ,
|
||||
{{0x4c, 0xe6, 0xb0, 0xc1, 0xa5, 0x2a, 0x82, 0x09, 0x08, 0xad, 0x79, 0x9c, 0x56, 0xf6, 0xf9, 0xc1, 0xd7, 0x7c, 0x39, 0x7f, 0x93, 0xca, 0x11, 0x55, 0xbf, 0x07, 0x1b, 0x82, 0x29, 0x69, 0x95, 0x5c}}},
|
||||
{{{0x87, 0xee, 0xa6, 0x56, 0x9e, 0xc2, 0x9a, 0x56, 0x24, 0x42, 0x85, 0x4d, 0x98, 0x31, 0x1e, 0x60, 0x4d, 0x87, 0x85, 0x04, 0xae, 0x46, 0x12, 0xf9, 0x8e, 0x7f, 0xe4, 0x7f, 0xf6, 0x1c, 0x37, 0x01}} ,
|
||||
{{0x73, 0x4c, 0xb6, 0xc5, 0xc4, 0xe9, 0x6c, 0x85, 0x48, 0x4a, 0x5a, 0xac, 0xd9, 0x1f, 0x43, 0xf8, 0x62, 0x5b, 0xee, 0x98, 0x2a, 0x33, 0x8e, 0x79, 0xce, 0x61, 0x06, 0x35, 0xd8, 0xd7, 0xca, 0x71}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x72, 0xd3, 0xae, 0xa6, 0xca, 0x8f, 0xcd, 0xcc, 0x78, 0x8e, 0x19, 0x4d, 0xa7, 0xd2, 0x27, 0xe9, 0xa4, 0x3c, 0x16, 0x5b, 0x84, 0x80, 0xf9, 0xd0, 0xcc, 0x6a, 0x1e, 0xca, 0x1e, 0x67, 0xbd, 0x63}} ,
|
||||
{{0x7b, 0x6e, 0x2a, 0xd2, 0x87, 0x48, 0xff, 0xa1, 0xca, 0xe9, 0x15, 0x85, 0xdc, 0xdb, 0x2c, 0x39, 0x12, 0x91, 0xa9, 0x20, 0xaa, 0x4f, 0x29, 0xf4, 0x15, 0x7a, 0xd2, 0xf5, 0x32, 0xcc, 0x60, 0x04}}},
|
||||
{{{0xe5, 0x10, 0x47, 0x3b, 0xfa, 0x90, 0xfc, 0x30, 0xb5, 0xea, 0x6f, 0x56, 0x8f, 0xfb, 0x0e, 0xa7, 0x3b, 0xc8, 0xb2, 0xff, 0x02, 0x7a, 0x33, 0x94, 0x93, 0x2a, 0x03, 0xe0, 0x96, 0x3a, 0x6c, 0x0f}} ,
|
||||
{{0x5a, 0x63, 0x67, 0xe1, 0x9b, 0x47, 0x78, 0x9f, 0x38, 0x79, 0xac, 0x97, 0x66, 0x1d, 0x5e, 0x51, 0xee, 0x24, 0x42, 0xe8, 0x58, 0x4b, 0x8a, 0x03, 0x75, 0x86, 0x37, 0x86, 0xe2, 0x97, 0x4e, 0x3d}}},
|
||||
{{{0x3f, 0x75, 0x8e, 0xb4, 0xff, 0xd8, 0xdd, 0xd6, 0x37, 0x57, 0x9d, 0x6d, 0x3b, 0xbd, 0xd5, 0x60, 0x88, 0x65, 0x9a, 0xb9, 0x4a, 0x68, 0x84, 0xa2, 0x67, 0xdd, 0x17, 0x25, 0x97, 0x04, 0x8b, 0x5e}} ,
|
||||
{{0xbb, 0x40, 0x5e, 0xbc, 0x16, 0x92, 0x05, 0xc4, 0xc0, 0x4e, 0x72, 0x90, 0x0e, 0xab, 0xcf, 0x8a, 0xed, 0xef, 0xb9, 0x2d, 0x3b, 0xf8, 0x43, 0x5b, 0xba, 0x2d, 0xeb, 0x2f, 0x52, 0xd2, 0xd1, 0x5a}}},
|
||||
{{{0x40, 0xb4, 0xab, 0xe6, 0xad, 0x9f, 0x46, 0x69, 0x4a, 0xb3, 0x8e, 0xaa, 0xea, 0x9c, 0x8a, 0x20, 0x16, 0x5d, 0x8c, 0x13, 0xbd, 0xf6, 0x1d, 0xc5, 0x24, 0xbd, 0x90, 0x2a, 0x1c, 0xc7, 0x13, 0x3b}} ,
|
||||
{{0x54, 0xdc, 0x16, 0x0d, 0x18, 0xbe, 0x35, 0x64, 0x61, 0x52, 0x02, 0x80, 0xaf, 0x05, 0xf7, 0xa6, 0x42, 0xd3, 0x8f, 0x2e, 0x79, 0x26, 0xa8, 0xbb, 0xb2, 0x17, 0x48, 0xb2, 0x7a, 0x0a, 0x89, 0x14}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x20, 0xa8, 0x88, 0xe3, 0x91, 0xc0, 0x6e, 0xbb, 0x8a, 0x27, 0x82, 0x51, 0x83, 0xb2, 0x28, 0xa9, 0x83, 0xeb, 0xa6, 0xa9, 0x4d, 0x17, 0x59, 0x22, 0x54, 0x00, 0x50, 0x45, 0xcb, 0x48, 0x4b, 0x18}} ,
|
||||
{{0x33, 0x7c, 0xe7, 0x26, 0xba, 0x4d, 0x32, 0xfe, 0x53, 0xf4, 0xfa, 0x83, 0xe3, 0xa5, 0x79, 0x66, 0x73, 0xef, 0x80, 0x23, 0x68, 0xc2, 0x60, 0xdd, 0xa9, 0x33, 0xdc, 0x03, 0x7a, 0xe0, 0xe0, 0x3e}}},
|
||||
{{{0x34, 0x5c, 0x13, 0xfb, 0xc0, 0xe3, 0x78, 0x2b, 0x54, 0x58, 0x22, 0x9b, 0x76, 0x81, 0x7f, 0x93, 0x9c, 0x25, 0x3c, 0xd2, 0xe9, 0x96, 0x21, 0x26, 0x08, 0xf5, 0xed, 0x95, 0x11, 0xae, 0x04, 0x5a}} ,
|
||||
{{0xb9, 0xe8, 0xc5, 0x12, 0x97, 0x1f, 0x83, 0xfe, 0x3e, 0x94, 0x99, 0xd4, 0x2d, 0xf9, 0x52, 0x59, 0x5c, 0x82, 0xa6, 0xf0, 0x75, 0x7e, 0xe8, 0xec, 0xcc, 0xac, 0x18, 0x21, 0x09, 0x67, 0x66, 0x67}}},
|
||||
{{{0xb3, 0x40, 0x29, 0xd1, 0xcb, 0x1b, 0x08, 0x9e, 0x9c, 0xb7, 0x53, 0xb9, 0x3b, 0x71, 0x08, 0x95, 0x12, 0x1a, 0x58, 0xaf, 0x7e, 0x82, 0x52, 0x43, 0x4f, 0x11, 0x39, 0xf4, 0x93, 0x1a, 0x26, 0x05}} ,
|
||||
{{0x6e, 0x44, 0xa3, 0xf9, 0x64, 0xaf, 0xe7, 0x6d, 0x7d, 0xdf, 0x1e, 0xac, 0x04, 0xea, 0x3b, 0x5f, 0x9b, 0xe8, 0x24, 0x9d, 0x0e, 0xe5, 0x2e, 0x3e, 0xdf, 0xa9, 0xf7, 0xd4, 0x50, 0x71, 0xf0, 0x78}}},
|
||||
{{{0x3e, 0xa8, 0x38, 0xc2, 0x57, 0x56, 0x42, 0x9a, 0xb1, 0xe2, 0xf8, 0x45, 0xaa, 0x11, 0x48, 0x5f, 0x17, 0xc4, 0x54, 0x27, 0xdc, 0x5d, 0xaa, 0xdd, 0x41, 0xbc, 0xdf, 0x81, 0xb9, 0x53, 0xee, 0x52}} ,
|
||||
{{0xc3, 0xf1, 0xa7, 0x6d, 0xb3, 0x5f, 0x92, 0x6f, 0xcc, 0x91, 0xb8, 0x95, 0x05, 0xdf, 0x3c, 0x64, 0x57, 0x39, 0x61, 0x51, 0xad, 0x8c, 0x38, 0x7b, 0xc8, 0xde, 0x00, 0x34, 0xbe, 0xa1, 0xb0, 0x7e}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x25, 0x24, 0x1d, 0x8a, 0x67, 0x20, 0xee, 0x42, 0xeb, 0x38, 0xed, 0x0b, 0x8b, 0xcd, 0x46, 0x9d, 0x5e, 0x6b, 0x1e, 0x24, 0x9d, 0x12, 0x05, 0x1a, 0xcc, 0x05, 0x4e, 0x92, 0x38, 0xe1, 0x1f, 0x50}} ,
|
||||
{{0x4e, 0xee, 0x1c, 0x91, 0xe6, 0x11, 0xbd, 0x8e, 0x55, 0x1a, 0x18, 0x75, 0x66, 0xaf, 0x4d, 0x7b, 0x0f, 0xae, 0x6d, 0x85, 0xca, 0x82, 0x58, 0x21, 0x9c, 0x18, 0xe0, 0xed, 0xec, 0x22, 0x80, 0x2f}}},
|
||||
{{{0x68, 0x3b, 0x0a, 0x39, 0x1d, 0x6a, 0x15, 0x57, 0xfc, 0xf0, 0x63, 0x54, 0xdb, 0x39, 0xdb, 0xe8, 0x5c, 0x64, 0xff, 0xa0, 0x09, 0x4f, 0x3b, 0xb7, 0x32, 0x60, 0x99, 0x94, 0xfd, 0x94, 0x82, 0x2d}} ,
|
||||
{{0x24, 0xf6, 0x5a, 0x44, 0xf1, 0x55, 0x2c, 0xdb, 0xea, 0x7c, 0x84, 0x7c, 0x01, 0xac, 0xe3, 0xfd, 0xc9, 0x27, 0xc1, 0x5a, 0xb9, 0xde, 0x4f, 0x5a, 0x90, 0xdd, 0xc6, 0x67, 0xaa, 0x6f, 0x8a, 0x3a}}},
|
||||
{{{0x78, 0x52, 0x87, 0xc9, 0x97, 0x63, 0xb1, 0xdd, 0x54, 0x5f, 0xc1, 0xf8, 0xf1, 0x06, 0xa6, 0xa8, 0xa3, 0x88, 0x82, 0xd4, 0xcb, 0xa6, 0x19, 0xdd, 0xd1, 0x11, 0x87, 0x08, 0x17, 0x4c, 0x37, 0x2a}} ,
|
||||
{{0xa1, 0x0c, 0xf3, 0x08, 0x43, 0xd9, 0x24, 0x1e, 0x83, 0xa7, 0xdf, 0x91, 0xca, 0xbd, 0x69, 0x47, 0x8d, 0x1b, 0xe2, 0xb9, 0x4e, 0xb5, 0xe1, 0x76, 0xb3, 0x1c, 0x93, 0x03, 0xce, 0x5f, 0xb3, 0x5a}}},
|
||||
{{{0x1d, 0xda, 0xe4, 0x61, 0x03, 0x50, 0xa9, 0x8b, 0x68, 0x18, 0xef, 0xb2, 0x1c, 0x84, 0x3b, 0xa2, 0x44, 0x95, 0xa3, 0x04, 0x3b, 0xd6, 0x99, 0x00, 0xaf, 0x76, 0x42, 0x67, 0x02, 0x7d, 0x85, 0x56}} ,
|
||||
{{0xce, 0x72, 0x0e, 0x29, 0x84, 0xb2, 0x7d, 0xd2, 0x45, 0xbe, 0x57, 0x06, 0xed, 0x7f, 0xcf, 0xed, 0xcd, 0xef, 0x19, 0xd6, 0xbc, 0x15, 0x79, 0x64, 0xd2, 0x18, 0xe3, 0x20, 0x67, 0x3a, 0x54, 0x0b}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x52, 0xfd, 0x04, 0xc5, 0xfb, 0x99, 0xe7, 0xe8, 0xfb, 0x8c, 0xe1, 0x42, 0x03, 0xef, 0x9d, 0xd9, 0x9e, 0x4d, 0xf7, 0x80, 0xcf, 0x2e, 0xcc, 0x9b, 0x45, 0xc9, 0x7b, 0x7a, 0xbc, 0x37, 0xa8, 0x52}} ,
|
||||
{{0x96, 0x11, 0x41, 0x8a, 0x47, 0x91, 0xfe, 0xb6, 0xda, 0x7a, 0x54, 0x63, 0xd1, 0x14, 0x35, 0x05, 0x86, 0x8c, 0xa9, 0x36, 0x3f, 0xf2, 0x85, 0x54, 0x4e, 0x92, 0xd8, 0x85, 0x01, 0x46, 0xd6, 0x50}}},
|
||||
{{{0x53, 0xcd, 0xf3, 0x86, 0x40, 0xe6, 0x39, 0x42, 0x95, 0xd6, 0xcb, 0x45, 0x1a, 0x20, 0xc8, 0x45, 0x4b, 0x32, 0x69, 0x04, 0xb1, 0xaf, 0x20, 0x46, 0xc7, 0x6b, 0x23, 0x5b, 0x69, 0xee, 0x30, 0x3f}} ,
|
||||
{{0x70, 0x83, 0x47, 0xc0, 0xdb, 0x55, 0x08, 0xa8, 0x7b, 0x18, 0x6d, 0xf5, 0x04, 0x5a, 0x20, 0x0c, 0x4a, 0x8c, 0x60, 0xae, 0xae, 0x0f, 0x64, 0x55, 0x55, 0x2e, 0xd5, 0x1d, 0x53, 0x31, 0x42, 0x41}}},
|
||||
{{{0xca, 0xfc, 0x88, 0x6b, 0x96, 0x78, 0x0a, 0x8b, 0x83, 0xdc, 0xbc, 0xaf, 0x40, 0xb6, 0x8d, 0x7f, 0xef, 0xb4, 0xd1, 0x3f, 0xcc, 0xa2, 0x74, 0xc9, 0xc2, 0x92, 0x55, 0x00, 0xab, 0xdb, 0xbf, 0x4f}} ,
|
||||
{{0x93, 0x1c, 0x06, 0x2d, 0x66, 0x65, 0x02, 0xa4, 0x97, 0x18, 0xfd, 0x00, 0xe7, 0xab, 0x03, 0xec, 0xce, 0xc1, 0xbf, 0x37, 0xf8, 0x13, 0x53, 0xa5, 0xe5, 0x0c, 0x3a, 0xa8, 0x55, 0xb9, 0xff, 0x68}}},
|
||||
{{{0xe4, 0xe6, 0x6d, 0x30, 0x7d, 0x30, 0x35, 0xc2, 0x78, 0x87, 0xf9, 0xfc, 0x6b, 0x5a, 0xc3, 0xb7, 0x65, 0xd8, 0x2e, 0xc7, 0xa5, 0x0c, 0xc6, 0xdc, 0x12, 0xaa, 0xd6, 0x4f, 0xc5, 0x38, 0xbc, 0x0e}} ,
|
||||
{{0xe2, 0x3c, 0x76, 0x86, 0x38, 0xf2, 0x7b, 0x2c, 0x16, 0x78, 0x8d, 0xf5, 0xa4, 0x15, 0xda, 0xdb, 0x26, 0x85, 0xa0, 0x56, 0xdd, 0x1d, 0xe3, 0xb3, 0xfd, 0x40, 0xef, 0xf2, 0xd9, 0xa1, 0xb3, 0x04}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xdb, 0x49, 0x0e, 0xe6, 0x58, 0x10, 0x7a, 0x52, 0xda, 0xb5, 0x7d, 0x37, 0x6a, 0x3e, 0xa1, 0x78, 0xce, 0xc7, 0x1c, 0x24, 0x23, 0xdb, 0x7d, 0xfb, 0x8c, 0x8d, 0xdc, 0x30, 0x67, 0x69, 0x75, 0x3b}} ,
|
||||
{{0xa9, 0xea, 0x6d, 0x16, 0x16, 0x60, 0xf4, 0x60, 0x87, 0x19, 0x44, 0x8c, 0x4a, 0x8b, 0x3e, 0xfb, 0x16, 0x00, 0x00, 0x54, 0xa6, 0x9e, 0x9f, 0xef, 0xcf, 0xd9, 0xd2, 0x4c, 0x74, 0x31, 0xd0, 0x34}}},
|
||||
{{{0xa4, 0xeb, 0x04, 0xa4, 0x8c, 0x8f, 0x71, 0x27, 0x95, 0x85, 0x5d, 0x55, 0x4b, 0xb1, 0x26, 0x26, 0xc8, 0xae, 0x6a, 0x7d, 0xa2, 0x21, 0xca, 0xce, 0x38, 0xab, 0x0f, 0xd0, 0xd5, 0x2b, 0x6b, 0x00}} ,
|
||||
{{0xe5, 0x67, 0x0c, 0xf1, 0x3a, 0x9a, 0xea, 0x09, 0x39, 0xef, 0xd1, 0x30, 0xbc, 0x33, 0xba, 0xb1, 0x6a, 0xc5, 0x27, 0x08, 0x7f, 0x54, 0x80, 0x3d, 0xab, 0xf6, 0x15, 0x7a, 0xc2, 0x40, 0x73, 0x72}}},
|
||||
{{{0x84, 0x56, 0x82, 0xb6, 0x12, 0x70, 0x7f, 0xf7, 0xf0, 0xbd, 0x5b, 0xa9, 0xd5, 0xc5, 0x5f, 0x59, 0xbf, 0x7f, 0xb3, 0x55, 0x22, 0x02, 0xc9, 0x44, 0x55, 0x87, 0x8f, 0x96, 0x98, 0x64, 0x6d, 0x15}} ,
|
||||
{{0xb0, 0x8b, 0xaa, 0x1e, 0xec, 0xc7, 0xa5, 0x8f, 0x1f, 0x92, 0x04, 0xc6, 0x05, 0xf6, 0xdf, 0xa1, 0xcc, 0x1f, 0x81, 0xf5, 0x0e, 0x9c, 0x57, 0xdc, 0xe3, 0xbb, 0x06, 0x87, 0x1e, 0xfe, 0x23, 0x6c}}},
|
||||
{{{0xd8, 0x2b, 0x5b, 0x16, 0xea, 0x20, 0xf1, 0xd3, 0x68, 0x8f, 0xae, 0x5b, 0xd0, 0xa9, 0x1a, 0x19, 0xa8, 0x36, 0xfb, 0x2b, 0x57, 0x88, 0x7d, 0x90, 0xd5, 0xa6, 0xf3, 0xdc, 0x38, 0x89, 0x4e, 0x1f}} ,
|
||||
{{0xcc, 0x19, 0xda, 0x9b, 0x3b, 0x43, 0x48, 0x21, 0x2e, 0x23, 0x4d, 0x3d, 0xae, 0xf8, 0x8c, 0xfc, 0xdd, 0xa6, 0x74, 0x37, 0x65, 0xca, 0xee, 0x1a, 0x19, 0x8e, 0x9f, 0x64, 0x6f, 0x0c, 0x8b, 0x5a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x25, 0xb9, 0xc2, 0xf0, 0x72, 0xb8, 0x15, 0x16, 0xcc, 0x8d, 0x3c, 0x6f, 0x25, 0xed, 0xf4, 0x46, 0x2e, 0x0c, 0x60, 0x0f, 0xe2, 0x84, 0x34, 0x55, 0x89, 0x59, 0x34, 0x1b, 0xf5, 0x8d, 0xfe, 0x08}} ,
|
||||
{{0xf8, 0xab, 0x93, 0xbc, 0x44, 0xba, 0x1b, 0x75, 0x4b, 0x49, 0x6f, 0xd0, 0x54, 0x2e, 0x63, 0xba, 0xb5, 0xea, 0xed, 0x32, 0x14, 0xc9, 0x94, 0xd8, 0xc5, 0xce, 0xf4, 0x10, 0x68, 0xe0, 0x38, 0x27}}},
|
||||
{{{0x74, 0x1c, 0x14, 0x9b, 0xd4, 0x64, 0x61, 0x71, 0x5a, 0xb6, 0x21, 0x33, 0x4f, 0xf7, 0x8e, 0xba, 0xa5, 0x48, 0x9a, 0xc7, 0xfa, 0x9a, 0xf0, 0xb4, 0x62, 0xad, 0xf2, 0x5e, 0xcc, 0x03, 0x24, 0x1a}} ,
|
||||
{{0xf5, 0x76, 0xfd, 0xe4, 0xaf, 0xb9, 0x03, 0x59, 0xce, 0x63, 0xd2, 0x3b, 0x1f, 0xcd, 0x21, 0x0c, 0xad, 0x44, 0xa5, 0x97, 0xac, 0x80, 0x11, 0x02, 0x9b, 0x0c, 0xe5, 0x8b, 0xcd, 0xfb, 0x79, 0x77}}},
|
||||
{{{0x15, 0xbe, 0x9a, 0x0d, 0xba, 0x38, 0x72, 0x20, 0x8a, 0xf5, 0xbe, 0x59, 0x93, 0x79, 0xb7, 0xf6, 0x6a, 0x0c, 0x38, 0x27, 0x1a, 0x60, 0xf4, 0x86, 0x3b, 0xab, 0x5a, 0x00, 0xa0, 0xce, 0x21, 0x7d}} ,
|
||||
{{0x6c, 0xba, 0x14, 0xc5, 0xea, 0x12, 0x9e, 0x2e, 0x82, 0x63, 0xce, 0x9b, 0x4a, 0xe7, 0x1d, 0xec, 0xf1, 0x2e, 0x51, 0x1c, 0xf4, 0xd0, 0x69, 0x15, 0x42, 0x9d, 0xa3, 0x3f, 0x0e, 0xbf, 0xe9, 0x5c}}},
|
||||
{{{0xe4, 0x0d, 0xf4, 0xbd, 0xee, 0x31, 0x10, 0xed, 0xcb, 0x12, 0x86, 0xad, 0xd4, 0x2f, 0x90, 0x37, 0x32, 0xc3, 0x0b, 0x73, 0xec, 0x97, 0x85, 0xa4, 0x01, 0x1c, 0x76, 0x35, 0xfe, 0x75, 0xdd, 0x71}} ,
|
||||
{{0x11, 0xa4, 0x88, 0x9f, 0x3e, 0x53, 0x69, 0x3b, 0x1b, 0xe0, 0xf7, 0xba, 0x9b, 0xad, 0x4e, 0x81, 0x5f, 0xb5, 0x5c, 0xae, 0xbe, 0x67, 0x86, 0x37, 0x34, 0x8e, 0x07, 0x32, 0x45, 0x4a, 0x67, 0x39}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x90, 0x70, 0x58, 0x20, 0x03, 0x1e, 0x67, 0xb2, 0xc8, 0x9b, 0x58, 0xc5, 0xb1, 0xeb, 0x2d, 0x4a, 0xde, 0x82, 0x8c, 0xf2, 0xd2, 0x14, 0xb8, 0x70, 0x61, 0x4e, 0x73, 0xd6, 0x0b, 0x6b, 0x0d, 0x30}} ,
|
||||
{{0x81, 0xfc, 0x55, 0x5c, 0xbf, 0xa7, 0xc4, 0xbd, 0xe2, 0xf0, 0x4b, 0x8f, 0xe9, 0x7d, 0x99, 0xfa, 0xd3, 0xab, 0xbc, 0xc7, 0x83, 0x2b, 0x04, 0x7f, 0x0c, 0x19, 0x43, 0x03, 0x3d, 0x07, 0xca, 0x40}}},
|
||||
{{{0xf9, 0xc8, 0xbe, 0x8c, 0x16, 0x81, 0x39, 0x96, 0xf6, 0x17, 0x58, 0xc8, 0x30, 0x58, 0xfb, 0xc2, 0x03, 0x45, 0xd2, 0x52, 0x76, 0xe0, 0x6a, 0x26, 0x28, 0x5c, 0x88, 0x59, 0x6a, 0x5a, 0x54, 0x42}} ,
|
||||
{{0x07, 0xb5, 0x2e, 0x2c, 0x67, 0x15, 0x9b, 0xfb, 0x83, 0x69, 0x1e, 0x0f, 0xda, 0xd6, 0x29, 0xb1, 0x60, 0xe0, 0xb2, 0xba, 0x69, 0xa2, 0x9e, 0xbd, 0xbd, 0xe0, 0x1c, 0xbd, 0xcd, 0x06, 0x64, 0x70}}},
|
||||
{{{0x41, 0xfa, 0x8c, 0xe1, 0x89, 0x8f, 0x27, 0xc8, 0x25, 0x8f, 0x6f, 0x5f, 0x55, 0xf8, 0xde, 0x95, 0x6d, 0x2f, 0x75, 0x16, 0x2b, 0x4e, 0x44, 0xfd, 0x86, 0x6e, 0xe9, 0x70, 0x39, 0x76, 0x97, 0x7e}} ,
|
||||
{{0x17, 0x62, 0x6b, 0x14, 0xa1, 0x7c, 0xd0, 0x79, 0x6e, 0xd8, 0x8a, 0xa5, 0x6d, 0x8c, 0x93, 0xd2, 0x3f, 0xec, 0x44, 0x8d, 0x6e, 0x91, 0x01, 0x8c, 0x8f, 0xee, 0x01, 0x8f, 0xc0, 0xb4, 0x85, 0x0e}}},
|
||||
{{{0x02, 0x3a, 0x70, 0x41, 0xe4, 0x11, 0x57, 0x23, 0xac, 0xe6, 0xfc, 0x54, 0x7e, 0xcd, 0xd7, 0x22, 0xcb, 0x76, 0x9f, 0x20, 0xce, 0xa0, 0x73, 0x76, 0x51, 0x3b, 0xa4, 0xf8, 0xe3, 0x62, 0x12, 0x6c}} ,
|
||||
{{0x7f, 0x00, 0x9c, 0x26, 0x0d, 0x6f, 0x48, 0x7f, 0x3a, 0x01, 0xed, 0xc5, 0x96, 0xb0, 0x1f, 0x4f, 0xa8, 0x02, 0x62, 0x27, 0x8a, 0x50, 0x8d, 0x9a, 0x8b, 0x52, 0x0f, 0x1e, 0xcf, 0x41, 0x38, 0x19}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xf5, 0x6c, 0xd4, 0x2f, 0x0f, 0x69, 0x0f, 0x87, 0x3f, 0x61, 0x65, 0x1e, 0x35, 0x34, 0x85, 0xba, 0x02, 0x30, 0xac, 0x25, 0x3d, 0xe2, 0x62, 0xf1, 0xcc, 0xe9, 0x1b, 0xc2, 0xef, 0x6a, 0x42, 0x57}} ,
|
||||
{{0x34, 0x1f, 0x2e, 0xac, 0xd1, 0xc7, 0x04, 0x52, 0x32, 0x66, 0xb2, 0x33, 0x73, 0x21, 0x34, 0x54, 0xf7, 0x71, 0xed, 0x06, 0xb0, 0xff, 0xa6, 0x59, 0x6f, 0x8a, 0x4e, 0xfb, 0x02, 0xb0, 0x45, 0x6b}}},
|
||||
{{{0xf5, 0x48, 0x0b, 0x03, 0xc5, 0x22, 0x7d, 0x80, 0x08, 0x53, 0xfe, 0x32, 0xb1, 0xa1, 0x8a, 0x74, 0x6f, 0xbd, 0x3f, 0x85, 0xf4, 0xcf, 0xf5, 0x60, 0xaf, 0x41, 0x7e, 0x3e, 0x46, 0xa3, 0x5a, 0x20}} ,
|
||||
{{0xaa, 0x35, 0x87, 0x44, 0x63, 0x66, 0x97, 0xf8, 0x6e, 0x55, 0x0c, 0x04, 0x3e, 0x35, 0x50, 0xbf, 0x93, 0x69, 0xd2, 0x8b, 0x05, 0x55, 0x99, 0xbe, 0xe2, 0x53, 0x61, 0xec, 0xe8, 0x08, 0x0b, 0x32}}},
|
||||
{{{0xb3, 0x10, 0x45, 0x02, 0x69, 0x59, 0x2e, 0x97, 0xd9, 0x64, 0xf8, 0xdb, 0x25, 0x80, 0xdc, 0xc4, 0xd5, 0x62, 0x3c, 0xed, 0x65, 0x91, 0xad, 0xd1, 0x57, 0x81, 0x94, 0xaa, 0xa1, 0x29, 0xfc, 0x68}} ,
|
||||
{{0xdd, 0xb5, 0x7d, 0xab, 0x5a, 0x21, 0x41, 0x53, 0xbb, 0x17, 0x79, 0x0d, 0xd1, 0xa8, 0x0c, 0x0c, 0x20, 0x88, 0x09, 0xe9, 0x84, 0xe8, 0x25, 0x11, 0x67, 0x7a, 0x8b, 0x1a, 0xe4, 0x5d, 0xe1, 0x5d}}},
|
||||
{{{0x37, 0xea, 0xfe, 0x65, 0x3b, 0x25, 0xe8, 0xe1, 0xc2, 0xc5, 0x02, 0xa4, 0xbe, 0x98, 0x0a, 0x2b, 0x61, 0xc1, 0x9b, 0xe2, 0xd5, 0x92, 0xe6, 0x9e, 0x7d, 0x1f, 0xca, 0x43, 0x88, 0x8b, 0x2c, 0x59}} ,
|
||||
{{0xe0, 0xb5, 0x00, 0x1d, 0x2a, 0x6f, 0xaf, 0x79, 0x86, 0x2f, 0xa6, 0x5a, 0x93, 0xd1, 0xfe, 0xae, 0x3a, 0xee, 0xdb, 0x7c, 0x61, 0xbe, 0x7c, 0x01, 0xf9, 0xfe, 0x52, 0xdc, 0xd8, 0x52, 0xa3, 0x42}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x22, 0xaf, 0x13, 0x37, 0xbd, 0x37, 0x71, 0xac, 0x04, 0x46, 0x63, 0xac, 0xa4, 0x77, 0xed, 0x25, 0x38, 0xe0, 0x15, 0xa8, 0x64, 0x00, 0x0d, 0xce, 0x51, 0x01, 0xa9, 0xbc, 0x0f, 0x03, 0x1c, 0x04}} ,
|
||||
{{0x89, 0xf9, 0x80, 0x07, 0xcf, 0x3f, 0xb3, 0xe9, 0xe7, 0x45, 0x44, 0x3d, 0x2a, 0x7c, 0xe9, 0xe4, 0x16, 0x5c, 0x5e, 0x65, 0x1c, 0xc7, 0x7d, 0xc6, 0x7a, 0xfb, 0x43, 0xee, 0x25, 0x76, 0x46, 0x72}}},
|
||||
{{{0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62}} ,
|
||||
{{0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03}}},
|
||||
{{{0x51, 0x16, 0x50, 0x7c, 0xd5, 0x5d, 0xf6, 0x99, 0xe8, 0x77, 0x72, 0x4e, 0xfa, 0x62, 0xcb, 0x76, 0x75, 0x0c, 0xe2, 0x71, 0x98, 0x92, 0xd5, 0xfa, 0x45, 0xdf, 0x5c, 0x6f, 0x1e, 0x9e, 0x28, 0x69}} ,
|
||||
{{0x0d, 0xac, 0x66, 0x6d, 0xc3, 0x8b, 0xba, 0x16, 0xb5, 0xe2, 0xa0, 0x0d, 0x0c, 0xbd, 0xa4, 0x8e, 0x18, 0x6c, 0xf2, 0xdc, 0xf9, 0xdc, 0x4a, 0x86, 0x25, 0x95, 0x14, 0xcb, 0xd8, 0x1a, 0x04, 0x0f}}},
|
||||
{{{0x97, 0xa5, 0xdb, 0x8b, 0x2d, 0xaa, 0x42, 0x11, 0x09, 0xf2, 0x93, 0xbb, 0xd9, 0x06, 0x84, 0x4e, 0x11, 0xa8, 0xa0, 0x25, 0x2b, 0xa6, 0x5f, 0xae, 0xc4, 0xb4, 0x4c, 0xc8, 0xab, 0xc7, 0x3b, 0x02}} ,
|
||||
{{0xee, 0xc9, 0x29, 0x0f, 0xdf, 0x11, 0x85, 0xed, 0xce, 0x0d, 0x62, 0x2c, 0x8f, 0x4b, 0xf9, 0x04, 0xe9, 0x06, 0x72, 0x1d, 0x37, 0x20, 0x50, 0xc9, 0x14, 0xeb, 0xec, 0x39, 0xa7, 0x97, 0x2b, 0x4d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x69, 0xd1, 0x39, 0xbd, 0xfb, 0x33, 0xbe, 0xc4, 0xf0, 0x5c, 0xef, 0xf0, 0x56, 0x68, 0xfc, 0x97, 0x47, 0xc8, 0x72, 0xb6, 0x53, 0xa4, 0x0a, 0x98, 0xa5, 0xb4, 0x37, 0x71, 0xcf, 0x66, 0x50, 0x6d}} ,
|
||||
{{0x17, 0xa4, 0x19, 0x52, 0x11, 0x47, 0xb3, 0x5c, 0x5b, 0xa9, 0x2e, 0x22, 0xb4, 0x00, 0x52, 0xf9, 0x57, 0x18, 0xb8, 0xbe, 0x5a, 0xe3, 0xab, 0x83, 0xc8, 0x87, 0x0a, 0x2a, 0xd8, 0x8c, 0xbb, 0x54}}},
|
||||
{{{0xa9, 0x62, 0x93, 0x85, 0xbe, 0xe8, 0x73, 0x4a, 0x0e, 0xb0, 0xb5, 0x2d, 0x94, 0x50, 0xaa, 0xd3, 0xb2, 0xea, 0x9d, 0x62, 0x76, 0x3b, 0x07, 0x34, 0x4e, 0x2d, 0x70, 0xc8, 0x9a, 0x15, 0x66, 0x6b}} ,
|
||||
{{0xc5, 0x96, 0xca, 0xc8, 0x22, 0x1a, 0xee, 0x5f, 0xe7, 0x31, 0x60, 0x22, 0x83, 0x08, 0x63, 0xce, 0xb9, 0x32, 0x44, 0x58, 0x5d, 0x3a, 0x9b, 0xe4, 0x04, 0xd5, 0xef, 0x38, 0xef, 0x4b, 0xdd, 0x19}}},
|
||||
{{{0x4d, 0xc2, 0x17, 0x75, 0xa1, 0x68, 0xcd, 0xc3, 0xc6, 0x03, 0x44, 0xe3, 0x78, 0x09, 0x91, 0x47, 0x3f, 0x0f, 0xe4, 0x92, 0x58, 0xfa, 0x7d, 0x1f, 0x20, 0x94, 0x58, 0x5e, 0xbc, 0x19, 0x02, 0x6f}} ,
|
||||
{{0x20, 0xd6, 0xd8, 0x91, 0x54, 0xa7, 0xf3, 0x20, 0x4b, 0x34, 0x06, 0xfa, 0x30, 0xc8, 0x6f, 0x14, 0x10, 0x65, 0x74, 0x13, 0x4e, 0xf0, 0x69, 0x26, 0xce, 0xcf, 0x90, 0xf4, 0xd0, 0xc5, 0xc8, 0x64}}},
|
||||
{{{0x26, 0xa2, 0x50, 0x02, 0x24, 0x72, 0xf1, 0xf0, 0x4e, 0x2d, 0x93, 0xd5, 0x08, 0xe7, 0xae, 0x38, 0xf7, 0x18, 0xa5, 0x32, 0x34, 0xc2, 0xf0, 0xa6, 0xec, 0xb9, 0x61, 0x7b, 0x64, 0x99, 0xac, 0x71}} ,
|
||||
{{0x25, 0xcf, 0x74, 0x55, 0x1b, 0xaa, 0xa9, 0x38, 0x41, 0x40, 0xd5, 0x95, 0x95, 0xab, 0x1c, 0x5e, 0xbc, 0x41, 0x7e, 0x14, 0x30, 0xbe, 0x13, 0x89, 0xf4, 0xe5, 0xeb, 0x28, 0xc0, 0xc2, 0x96, 0x3a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x2b, 0x77, 0x45, 0xec, 0x67, 0x76, 0x32, 0x4c, 0xb9, 0xdf, 0x25, 0x32, 0x6b, 0xcb, 0xe7, 0x14, 0x61, 0x43, 0xee, 0xba, 0x9b, 0x71, 0xef, 0xd2, 0x48, 0x65, 0xbb, 0x1b, 0x8a, 0x13, 0x1b, 0x22}} ,
|
||||
{{0x84, 0xad, 0x0c, 0x18, 0x38, 0x5a, 0xba, 0xd0, 0x98, 0x59, 0xbf, 0x37, 0xb0, 0x4f, 0x97, 0x60, 0x20, 0xb3, 0x9b, 0x97, 0xf6, 0x08, 0x6c, 0xa4, 0xff, 0xfb, 0xb7, 0xfa, 0x95, 0xb2, 0x51, 0x79}}},
|
||||
{{{0x28, 0x5c, 0x3f, 0xdb, 0x6b, 0x18, 0x3b, 0x5c, 0xd1, 0x04, 0x28, 0xde, 0x85, 0x52, 0x31, 0xb5, 0xbb, 0xf6, 0xa9, 0xed, 0xbe, 0x28, 0x4f, 0xb3, 0x7e, 0x05, 0x6a, 0xdb, 0x95, 0x0d, 0x1b, 0x1c}} ,
|
||||
{{0xd5, 0xc5, 0xc3, 0x9a, 0x0a, 0xd0, 0x31, 0x3e, 0x07, 0x36, 0x8e, 0xc0, 0x8a, 0x62, 0xb1, 0xca, 0xd6, 0x0e, 0x1e, 0x9d, 0xef, 0xab, 0x98, 0x4d, 0xbb, 0x6c, 0x05, 0xe0, 0xe4, 0x5d, 0xbd, 0x57}}},
|
||||
{{{0xcc, 0x21, 0x27, 0xce, 0xfd, 0xa9, 0x94, 0x8e, 0xe1, 0xab, 0x49, 0xe0, 0x46, 0x26, 0xa1, 0xa8, 0x8c, 0xa1, 0x99, 0x1d, 0xb4, 0x27, 0x6d, 0x2d, 0xc8, 0x39, 0x30, 0x5e, 0x37, 0x52, 0xc4, 0x6e}} ,
|
||||
{{0xa9, 0x85, 0xf4, 0xe7, 0xb0, 0x15, 0x33, 0x84, 0x1b, 0x14, 0x1a, 0x02, 0xd9, 0x3b, 0xad, 0x0f, 0x43, 0x6c, 0xea, 0x3e, 0x0f, 0x7e, 0xda, 0xdd, 0x6b, 0x4c, 0x7f, 0x6e, 0xd4, 0x6b, 0xbf, 0x0f}}},
|
||||
{{{0x47, 0x9f, 0x7c, 0x56, 0x7c, 0x43, 0x91, 0x1c, 0xbb, 0x4e, 0x72, 0x3e, 0x64, 0xab, 0xa0, 0xa0, 0xdf, 0xb4, 0xd8, 0x87, 0x3a, 0xbd, 0xa8, 0x48, 0xc9, 0xb8, 0xef, 0x2e, 0xad, 0x6f, 0x84, 0x4f}} ,
|
||||
{{0x2d, 0x2d, 0xf0, 0x1b, 0x7e, 0x2a, 0x6c, 0xf8, 0xa9, 0x6a, 0xe1, 0xf0, 0x99, 0xa1, 0x67, 0x9a, 0xd4, 0x13, 0xca, 0xca, 0xba, 0x27, 0x92, 0xaa, 0xa1, 0x5d, 0x50, 0xde, 0xcc, 0x40, 0x26, 0x0a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x9f, 0x3e, 0xf2, 0xb2, 0x90, 0xce, 0xdb, 0x64, 0x3e, 0x03, 0xdd, 0x37, 0x36, 0x54, 0x70, 0x76, 0x24, 0xb5, 0x69, 0x03, 0xfc, 0xa0, 0x2b, 0x74, 0xb2, 0x05, 0x0e, 0xcc, 0xd8, 0x1f, 0x6a, 0x1f}} ,
|
||||
{{0x19, 0x5e, 0x60, 0x69, 0x58, 0x86, 0xa0, 0x31, 0xbd, 0x32, 0xe9, 0x2c, 0x5c, 0xd2, 0x85, 0xba, 0x40, 0x64, 0xa8, 0x74, 0xf8, 0x0e, 0x1c, 0xb3, 0xa9, 0x69, 0xe8, 0x1e, 0x40, 0x64, 0x99, 0x77}}},
|
||||
{{{0x6c, 0x32, 0x4f, 0xfd, 0xbb, 0x5c, 0xbb, 0x8d, 0x64, 0x66, 0x4a, 0x71, 0x1f, 0x79, 0xa3, 0xad, 0x8d, 0xf9, 0xd4, 0xec, 0xcf, 0x67, 0x70, 0xfa, 0x05, 0x4a, 0x0f, 0x6e, 0xaf, 0x87, 0x0a, 0x6f}} ,
|
||||
{{0xc6, 0x36, 0x6e, 0x6c, 0x8c, 0x24, 0x09, 0x60, 0xbe, 0x26, 0xd2, 0x4c, 0x5e, 0x17, 0xca, 0x5f, 0x1d, 0xcc, 0x87, 0xe8, 0x42, 0x6a, 0xcb, 0xcb, 0x7d, 0x92, 0x05, 0x35, 0x81, 0x13, 0x60, 0x6b}}},
|
||||
{{{0xf4, 0x15, 0xcd, 0x0f, 0x0a, 0xaf, 0x4e, 0x6b, 0x51, 0xfd, 0x14, 0xc4, 0x2e, 0x13, 0x86, 0x74, 0x44, 0xcb, 0x66, 0x6b, 0xb6, 0x9d, 0x74, 0x56, 0x32, 0xac, 0x8d, 0x8e, 0x8c, 0x8c, 0x8c, 0x39}} ,
|
||||
{{0xca, 0x59, 0x74, 0x1a, 0x11, 0xef, 0x6d, 0xf7, 0x39, 0x5c, 0x3b, 0x1f, 0xfa, 0xe3, 0x40, 0x41, 0x23, 0x9e, 0xf6, 0xd1, 0x21, 0xa2, 0xbf, 0xad, 0x65, 0x42, 0x6b, 0x59, 0x8a, 0xe8, 0xc5, 0x7f}}},
|
||||
{{{0x64, 0x05, 0x7a, 0x84, 0x4a, 0x13, 0xc3, 0xf6, 0xb0, 0x6e, 0x9a, 0x6b, 0x53, 0x6b, 0x32, 0xda, 0xd9, 0x74, 0x75, 0xc4, 0xba, 0x64, 0x3d, 0x3b, 0x08, 0xdd, 0x10, 0x46, 0xef, 0xc7, 0x90, 0x1f}} ,
|
||||
{{0x7b, 0x2f, 0x3a, 0xce, 0xc8, 0xa1, 0x79, 0x3c, 0x30, 0x12, 0x44, 0x28, 0xf6, 0xbc, 0xff, 0xfd, 0xf4, 0xc0, 0x97, 0xb0, 0xcc, 0xc3, 0x13, 0x7a, 0xb9, 0x9a, 0x16, 0xe4, 0xcb, 0x4c, 0x34, 0x63}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x07, 0x4e, 0xd3, 0x2d, 0x09, 0x33, 0x0e, 0xd2, 0x0d, 0xbe, 0x3e, 0xe7, 0xe4, 0xaa, 0xb7, 0x00, 0x8b, 0xe8, 0xad, 0xaa, 0x7a, 0x8d, 0x34, 0x28, 0xa9, 0x81, 0x94, 0xc5, 0xe7, 0x42, 0xac, 0x47}} ,
|
||||
{{0x24, 0x89, 0x7a, 0x8f, 0xb5, 0x9b, 0xf0, 0xc2, 0x03, 0x64, 0xd0, 0x1e, 0xf5, 0xa4, 0xb2, 0xf3, 0x74, 0xe9, 0x1a, 0x16, 0xfd, 0xcb, 0x15, 0xea, 0xeb, 0x10, 0x6c, 0x35, 0xd1, 0xc1, 0xa6, 0x28}}},
|
||||
{{{0xcc, 0xd5, 0x39, 0xfc, 0xa5, 0xa4, 0xad, 0x32, 0x15, 0xce, 0x19, 0xe8, 0x34, 0x2b, 0x1c, 0x60, 0x91, 0xfc, 0x05, 0xa9, 0xb3, 0xdc, 0x80, 0x29, 0xc4, 0x20, 0x79, 0x06, 0x39, 0xc0, 0xe2, 0x22}} ,
|
||||
{{0xbb, 0xa8, 0xe1, 0x89, 0x70, 0x57, 0x18, 0x54, 0x3c, 0xf6, 0x0d, 0x82, 0x12, 0x05, 0x87, 0x96, 0x06, 0x39, 0xe3, 0xf8, 0xb3, 0x95, 0xe5, 0xd7, 0x26, 0xbf, 0x09, 0x5a, 0x94, 0xf9, 0x1c, 0x63}}},
|
||||
{{{0x2b, 0x8c, 0x2d, 0x9a, 0x8b, 0x84, 0xf2, 0x56, 0xfb, 0xad, 0x2e, 0x7f, 0xb7, 0xfc, 0x30, 0xe1, 0x35, 0x89, 0xba, 0x4d, 0xa8, 0x6d, 0xce, 0x8c, 0x8b, 0x30, 0xe0, 0xda, 0x29, 0x18, 0x11, 0x17}} ,
|
||||
{{0x19, 0xa6, 0x5a, 0x65, 0x93, 0xc3, 0xb5, 0x31, 0x22, 0x4f, 0xf3, 0xf6, 0x0f, 0xeb, 0x28, 0xc3, 0x7c, 0xeb, 0xce, 0x86, 0xec, 0x67, 0x76, 0x6e, 0x35, 0x45, 0x7b, 0xd8, 0x6b, 0x92, 0x01, 0x65}}},
|
||||
{{{0x3d, 0xd5, 0x9a, 0x64, 0x73, 0x36, 0xb1, 0xd6, 0x86, 0x98, 0x42, 0x3f, 0x8a, 0xf1, 0xc7, 0xf5, 0x42, 0xa8, 0x9c, 0x52, 0xa8, 0xdc, 0xf9, 0x24, 0x3f, 0x4a, 0xa1, 0xa4, 0x5b, 0xe8, 0x62, 0x1a}} ,
|
||||
{{0xc5, 0xbd, 0xc8, 0x14, 0xd5, 0x0d, 0xeb, 0xe1, 0xa5, 0xe6, 0x83, 0x11, 0x09, 0x00, 0x1d, 0x55, 0x83, 0x51, 0x7e, 0x75, 0x00, 0x81, 0xb9, 0xcb, 0xd8, 0xc5, 0xe5, 0xa1, 0xd9, 0x17, 0x6d, 0x1f}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xea, 0xf9, 0xe4, 0xe9, 0xe1, 0x52, 0x3f, 0x51, 0x19, 0x0d, 0xdd, 0xd9, 0x9d, 0x93, 0x31, 0x87, 0x23, 0x09, 0xd5, 0x83, 0xeb, 0x92, 0x09, 0x76, 0x6e, 0xe3, 0xf8, 0xc0, 0xa2, 0x66, 0xb5, 0x36}} ,
|
||||
{{0x3a, 0xbb, 0x39, 0xed, 0x32, 0x02, 0xe7, 0x43, 0x7a, 0x38, 0x14, 0x84, 0xe3, 0x44, 0xd2, 0x5e, 0x94, 0xdd, 0x78, 0x89, 0x55, 0x4c, 0x73, 0x9e, 0xe1, 0xe4, 0x3e, 0x43, 0xd0, 0x4a, 0xde, 0x1b}}},
|
||||
{{{0xb2, 0xe7, 0x8f, 0xe3, 0xa3, 0xc5, 0xcb, 0x72, 0xee, 0x79, 0x41, 0xf8, 0xdf, 0xee, 0x65, 0xc5, 0x45, 0x77, 0x27, 0x3c, 0xbd, 0x58, 0xd3, 0x75, 0xe2, 0x04, 0x4b, 0xbb, 0x65, 0xf3, 0xc8, 0x0f}} ,
|
||||
{{0x24, 0x7b, 0x93, 0x34, 0xb5, 0xe2, 0x74, 0x48, 0xcd, 0xa0, 0x0b, 0x92, 0x97, 0x66, 0x39, 0xf4, 0xb0, 0xe2, 0x5d, 0x39, 0x6a, 0x5b, 0x45, 0x17, 0x78, 0x1e, 0xdb, 0x91, 0x81, 0x1c, 0xf9, 0x16}}},
|
||||
{{{0x16, 0xdf, 0xd1, 0x5a, 0xd5, 0xe9, 0x4e, 0x58, 0x95, 0x93, 0x5f, 0x51, 0x09, 0xc3, 0x2a, 0xc9, 0xd4, 0x55, 0x48, 0x79, 0xa4, 0xa3, 0xb2, 0xc3, 0x62, 0xaa, 0x8c, 0xe8, 0xad, 0x47, 0x39, 0x1b}} ,
|
||||
{{0x46, 0xda, 0x9e, 0x51, 0x3a, 0xe6, 0xd1, 0xa6, 0xbb, 0x4d, 0x7b, 0x08, 0xbe, 0x8c, 0xd5, 0xf3, 0x3f, 0xfd, 0xf7, 0x44, 0x80, 0x2d, 0x53, 0x4b, 0xd0, 0x87, 0x68, 0xc1, 0xb5, 0xd8, 0xf7, 0x07}}},
|
||||
{{{0xf4, 0x10, 0x46, 0xbe, 0xb7, 0xd2, 0xd1, 0xce, 0x5e, 0x76, 0xa2, 0xd7, 0x03, 0xdc, 0xe4, 0x81, 0x5a, 0xf6, 0x3c, 0xde, 0xae, 0x7a, 0x9d, 0x21, 0x34, 0xa5, 0xf6, 0xa9, 0x73, 0xe2, 0x8d, 0x60}} ,
|
||||
{{0xfa, 0x44, 0x71, 0xf6, 0x41, 0xd8, 0xc6, 0x58, 0x13, 0x37, 0xeb, 0x84, 0x0f, 0x96, 0xc7, 0xdc, 0xc8, 0xa9, 0x7a, 0x83, 0xb2, 0x2f, 0x31, 0xb1, 0x1a, 0xd8, 0x98, 0x3f, 0x11, 0xd0, 0x31, 0x3b}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x81, 0xd5, 0x34, 0x16, 0x01, 0xa3, 0x93, 0xea, 0x52, 0x94, 0xec, 0x93, 0xb7, 0x81, 0x11, 0x2d, 0x58, 0xf9, 0xb5, 0x0a, 0xaa, 0x4f, 0xf6, 0x2e, 0x3f, 0x36, 0xbf, 0x33, 0x5a, 0xe7, 0xd1, 0x08}} ,
|
||||
{{0x1a, 0xcf, 0x42, 0xae, 0xcc, 0xb5, 0x77, 0x39, 0xc4, 0x5b, 0x5b, 0xd0, 0x26, 0x59, 0x27, 0xd0, 0x55, 0x71, 0x12, 0x9d, 0x88, 0x3d, 0x9c, 0xea, 0x41, 0x6a, 0xf0, 0x50, 0x93, 0x93, 0xdd, 0x47}}},
|
||||
{{{0x6f, 0xc9, 0x51, 0x6d, 0x1c, 0xaa, 0xf5, 0xa5, 0x90, 0x3f, 0x14, 0xe2, 0x6e, 0x8e, 0x64, 0xfd, 0xac, 0xe0, 0x4e, 0x22, 0xe5, 0xc1, 0xbc, 0x29, 0x0a, 0x6a, 0x9e, 0xa1, 0x60, 0xcb, 0x2f, 0x0b}} ,
|
||||
{{0xdc, 0x39, 0x32, 0xf3, 0xa1, 0x44, 0xe9, 0xc5, 0xc3, 0x78, 0xfb, 0x95, 0x47, 0x34, 0x35, 0x34, 0xe8, 0x25, 0xde, 0x93, 0xc6, 0xb4, 0x76, 0x6d, 0x86, 0x13, 0xc6, 0xe9, 0x68, 0xb5, 0x01, 0x63}}},
|
||||
{{{0x1f, 0x9a, 0x52, 0x64, 0x97, 0xd9, 0x1c, 0x08, 0x51, 0x6f, 0x26, 0x9d, 0xaa, 0x93, 0x33, 0x43, 0xfa, 0x77, 0xe9, 0x62, 0x9b, 0x5d, 0x18, 0x75, 0xeb, 0x78, 0xf7, 0x87, 0x8f, 0x41, 0xb4, 0x4d}} ,
|
||||
{{0x13, 0xa8, 0x82, 0x3e, 0xe9, 0x13, 0xad, 0xeb, 0x01, 0xca, 0xcf, 0xda, 0xcd, 0xf7, 0x6c, 0xc7, 0x7a, 0xdc, 0x1e, 0x6e, 0xc8, 0x4e, 0x55, 0x62, 0x80, 0xea, 0x78, 0x0c, 0x86, 0xb9, 0x40, 0x51}}},
|
||||
{{{0x27, 0xae, 0xd3, 0x0d, 0x4c, 0x8f, 0x34, 0xea, 0x7d, 0x3c, 0xe5, 0x8a, 0xcf, 0x5b, 0x92, 0xd8, 0x30, 0x16, 0xb4, 0xa3, 0x75, 0xff, 0xeb, 0x27, 0xc8, 0x5c, 0x6c, 0xc2, 0xee, 0x6c, 0x21, 0x0b}} ,
|
||||
{{0xc3, 0xba, 0x12, 0x53, 0x2a, 0xaa, 0x77, 0xad, 0x19, 0x78, 0x55, 0x8a, 0x2e, 0x60, 0x87, 0xc2, 0x6e, 0x91, 0x38, 0x91, 0x3f, 0x7a, 0xc5, 0x24, 0x8f, 0x51, 0xc5, 0xde, 0xb0, 0x53, 0x30, 0x56}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x02, 0xfe, 0x54, 0x12, 0x18, 0xca, 0x7d, 0xa5, 0x68, 0x43, 0xa3, 0x6d, 0x14, 0x2a, 0x6a, 0xa5, 0x8e, 0x32, 0xe7, 0x63, 0x4f, 0xe3, 0xc6, 0x44, 0x3e, 0xab, 0x63, 0xca, 0x17, 0x86, 0x74, 0x3f}} ,
|
||||
{{0x1e, 0x64, 0xc1, 0x7d, 0x52, 0xdc, 0x13, 0x5a, 0xa1, 0x9c, 0x4e, 0xee, 0x99, 0x28, 0xbb, 0x4c, 0xee, 0xac, 0xa9, 0x1b, 0x89, 0xa2, 0x38, 0x39, 0x7b, 0xc4, 0x0f, 0x42, 0xe6, 0x89, 0xed, 0x0f}}},
|
||||
{{{0xf3, 0x3c, 0x8c, 0x80, 0x83, 0x10, 0x8a, 0x37, 0x50, 0x9c, 0xb4, 0xdf, 0x3f, 0x8c, 0xf7, 0x23, 0x07, 0xd6, 0xff, 0xa0, 0x82, 0x6c, 0x75, 0x3b, 0xe4, 0xb5, 0xbb, 0xe4, 0xe6, 0x50, 0xf0, 0x08}} ,
|
||||
{{0x62, 0xee, 0x75, 0x48, 0x92, 0x33, 0xf2, 0xf4, 0xad, 0x15, 0x7a, 0xa1, 0x01, 0x46, 0xa9, 0x32, 0x06, 0x88, 0xb6, 0x36, 0x47, 0x35, 0xb9, 0xb4, 0x42, 0x85, 0x76, 0xf0, 0x48, 0x00, 0x90, 0x38}}},
|
||||
{{{0x51, 0x15, 0x9d, 0xc3, 0x95, 0xd1, 0x39, 0xbb, 0x64, 0x9d, 0x15, 0x81, 0xc1, 0x68, 0xd0, 0xb6, 0xa4, 0x2c, 0x7d, 0x5e, 0x02, 0x39, 0x00, 0xe0, 0x3b, 0xa4, 0xcc, 0xca, 0x1d, 0x81, 0x24, 0x10}} ,
|
||||
{{0xe7, 0x29, 0xf9, 0x37, 0xd9, 0x46, 0x5a, 0xcd, 0x70, 0xfe, 0x4d, 0x5b, 0xbf, 0xa5, 0xcf, 0x91, 0xf4, 0xef, 0xee, 0x8a, 0x29, 0xd0, 0xe7, 0xc4, 0x25, 0x92, 0x8a, 0xff, 0x36, 0xfc, 0xe4, 0x49}}},
|
||||
{{{0xbd, 0x00, 0xb9, 0x04, 0x7d, 0x35, 0xfc, 0xeb, 0xd0, 0x0b, 0x05, 0x32, 0x52, 0x7a, 0x89, 0x24, 0x75, 0x50, 0xe1, 0x63, 0x02, 0x82, 0x8e, 0xe7, 0x85, 0x0c, 0xf2, 0x56, 0x44, 0x37, 0x83, 0x25}} ,
|
||||
{{0x8f, 0xa1, 0xce, 0xcb, 0x60, 0xda, 0x12, 0x02, 0x1e, 0x29, 0x39, 0x2a, 0x03, 0xb7, 0xeb, 0x77, 0x40, 0xea, 0xc9, 0x2b, 0x2c, 0xd5, 0x7d, 0x7e, 0x2c, 0xc7, 0x5a, 0xfd, 0xff, 0xc4, 0xd1, 0x62}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x1d, 0x88, 0x98, 0x5b, 0x4e, 0xfc, 0x41, 0x24, 0x05, 0xe6, 0x50, 0x2b, 0xae, 0x96, 0x51, 0xd9, 0x6b, 0x72, 0xb2, 0x33, 0x42, 0x98, 0x68, 0xbb, 0x10, 0x5a, 0x7a, 0x8c, 0x9d, 0x07, 0xb4, 0x05}} ,
|
||||
{{0x2f, 0x61, 0x9f, 0xd7, 0xa8, 0x3f, 0x83, 0x8c, 0x10, 0x69, 0x90, 0xe6, 0xcf, 0xd2, 0x63, 0xa3, 0xe4, 0x54, 0x7e, 0xe5, 0x69, 0x13, 0x1c, 0x90, 0x57, 0xaa, 0xe9, 0x53, 0x22, 0x43, 0x29, 0x23}}},
|
||||
{{{0xe5, 0x1c, 0xf8, 0x0a, 0xfd, 0x2d, 0x7e, 0xf5, 0xf5, 0x70, 0x7d, 0x41, 0x6b, 0x11, 0xfe, 0xbe, 0x99, 0xd1, 0x55, 0x29, 0x31, 0xbf, 0xc0, 0x97, 0x6c, 0xd5, 0x35, 0xcc, 0x5e, 0x8b, 0xd9, 0x69}} ,
|
||||
{{0x8e, 0x4e, 0x9f, 0x25, 0xf8, 0x81, 0x54, 0x2d, 0x0e, 0xd5, 0x54, 0x81, 0x9b, 0xa6, 0x92, 0xce, 0x4b, 0xe9, 0x8f, 0x24, 0x3b, 0xca, 0xe0, 0x44, 0xab, 0x36, 0xfe, 0xfb, 0x87, 0xd4, 0x26, 0x3e}}},
|
||||
{{{0x0f, 0x93, 0x9c, 0x11, 0xe7, 0xdb, 0xf1, 0xf0, 0x85, 0x43, 0x28, 0x15, 0x37, 0xdd, 0xde, 0x27, 0xdf, 0xad, 0x3e, 0x49, 0x4f, 0xe0, 0x5b, 0xf6, 0x80, 0x59, 0x15, 0x3c, 0x85, 0xb7, 0x3e, 0x12}} ,
|
||||
{{0xf5, 0xff, 0xcc, 0xf0, 0xb4, 0x12, 0x03, 0x5f, 0xc9, 0x84, 0xcb, 0x1d, 0x17, 0xe0, 0xbc, 0xcc, 0x03, 0x62, 0xa9, 0x8b, 0x94, 0xa6, 0xaa, 0x18, 0xcb, 0x27, 0x8d, 0x49, 0xa6, 0x17, 0x15, 0x07}}},
|
||||
{{{0xd9, 0xb6, 0xd4, 0x9d, 0xd4, 0x6a, 0xaf, 0x70, 0x07, 0x2c, 0x10, 0x9e, 0xbd, 0x11, 0xad, 0xe4, 0x26, 0x33, 0x70, 0x92, 0x78, 0x1c, 0x74, 0x9f, 0x75, 0x60, 0x56, 0xf4, 0x39, 0xa8, 0xa8, 0x62}} ,
|
||||
{{0x3b, 0xbf, 0x55, 0x35, 0x61, 0x8b, 0x44, 0x97, 0xe8, 0x3a, 0x55, 0xc1, 0xc8, 0x3b, 0xfd, 0x95, 0x29, 0x11, 0x60, 0x96, 0x1e, 0xcb, 0x11, 0x9d, 0xc2, 0x03, 0x8a, 0x1b, 0xc6, 0xd6, 0x45, 0x3d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x7e, 0x0e, 0x50, 0xb2, 0xcc, 0x0d, 0x6b, 0xa6, 0x71, 0x5b, 0x42, 0xed, 0xbd, 0xaf, 0xac, 0xf0, 0xfc, 0x12, 0xa2, 0x3f, 0x4e, 0xda, 0xe8, 0x11, 0xf3, 0x23, 0xe1, 0x04, 0x62, 0x03, 0x1c, 0x4e}} ,
|
||||
{{0xc8, 0xb1, 0x1b, 0x6f, 0x73, 0x61, 0x3d, 0x27, 0x0d, 0x7d, 0x7a, 0x25, 0x5f, 0x73, 0x0e, 0x2f, 0x93, 0xf6, 0x24, 0xd8, 0x4f, 0x90, 0xac, 0xa2, 0x62, 0x0a, 0xf0, 0x61, 0xd9, 0x08, 0x59, 0x6a}}},
|
||||
{{{0x6f, 0x2d, 0x55, 0xf8, 0x2f, 0x8e, 0xf0, 0x18, 0x3b, 0xea, 0xdd, 0x26, 0x72, 0xd1, 0xf5, 0xfe, 0xe5, 0xb8, 0xe6, 0xd3, 0x10, 0x48, 0x46, 0x49, 0x3a, 0x9f, 0x5e, 0x45, 0x6b, 0x90, 0xe8, 0x7f}} ,
|
||||
{{0xd3, 0x76, 0x69, 0x33, 0x7b, 0xb9, 0x40, 0x70, 0xee, 0xa6, 0x29, 0x6b, 0xdd, 0xd0, 0x5d, 0x8d, 0xc1, 0x3e, 0x4a, 0xea, 0x37, 0xb1, 0x03, 0x02, 0x03, 0x35, 0xf1, 0x28, 0x9d, 0xff, 0x00, 0x13}}},
|
||||
{{{0x7a, 0xdb, 0x12, 0xd2, 0x8a, 0x82, 0x03, 0x1b, 0x1e, 0xaf, 0xf9, 0x4b, 0x9c, 0xbe, 0xae, 0x7c, 0xe4, 0x94, 0x2a, 0x23, 0xb3, 0x62, 0x86, 0xe7, 0xfd, 0x23, 0xaa, 0x99, 0xbd, 0x2b, 0x11, 0x6c}} ,
|
||||
{{0x8d, 0xa6, 0xd5, 0xac, 0x9d, 0xcc, 0x68, 0x75, 0x7f, 0xc3, 0x4d, 0x4b, 0xdd, 0x6c, 0xbb, 0x11, 0x5a, 0x60, 0xe5, 0xbd, 0x7d, 0x27, 0x8b, 0xda, 0xb4, 0x95, 0xf6, 0x03, 0x27, 0xa4, 0x92, 0x3f}}},
|
||||
{{{0x22, 0xd6, 0xb5, 0x17, 0x84, 0xbf, 0x12, 0xcc, 0x23, 0x14, 0x4a, 0xdf, 0x14, 0x31, 0xbc, 0xa1, 0xac, 0x6e, 0xab, 0xfa, 0x57, 0x11, 0x53, 0xb3, 0x27, 0xe6, 0xf9, 0x47, 0x33, 0x44, 0x34, 0x1e}} ,
|
||||
{{0x79, 0xfc, 0xa6, 0xb4, 0x0b, 0x35, 0x20, 0xc9, 0x4d, 0x22, 0x84, 0xc4, 0xa9, 0x20, 0xec, 0x89, 0x94, 0xba, 0x66, 0x56, 0x48, 0xb9, 0x87, 0x7f, 0xca, 0x1e, 0x06, 0xed, 0xa5, 0x55, 0x59, 0x29}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x56, 0xe1, 0xf5, 0xf1, 0xd5, 0xab, 0xa8, 0x2b, 0xae, 0x89, 0xf3, 0xcf, 0x56, 0x9f, 0xf2, 0x4b, 0x31, 0xbc, 0x18, 0xa9, 0x06, 0x5b, 0xbe, 0xb4, 0x61, 0xf8, 0xb2, 0x06, 0x9c, 0x81, 0xab, 0x4c}} ,
|
||||
{{0x1f, 0x68, 0x76, 0x01, 0x16, 0x38, 0x2b, 0x0f, 0x77, 0x97, 0x92, 0x67, 0x4e, 0x86, 0x6a, 0x8b, 0xe5, 0xe8, 0x0c, 0xf7, 0x36, 0x39, 0xb5, 0x33, 0xe6, 0xcf, 0x5e, 0xbd, 0x18, 0xfb, 0x10, 0x1f}}},
|
||||
{{{0x83, 0xf0, 0x0d, 0x63, 0xef, 0x53, 0x6b, 0xb5, 0x6b, 0xf9, 0x83, 0xcf, 0xde, 0x04, 0x22, 0x9b, 0x2c, 0x0a, 0xe0, 0xa5, 0xd8, 0xc7, 0x9c, 0xa5, 0xa3, 0xf6, 0x6f, 0xcf, 0x90, 0x6b, 0x68, 0x7c}} ,
|
||||
{{0x33, 0x15, 0xd7, 0x7f, 0x1a, 0xd5, 0x21, 0x58, 0xc4, 0x18, 0xa5, 0xf0, 0xcc, 0x73, 0xa8, 0xfd, 0xfa, 0x18, 0xd1, 0x03, 0x91, 0x8d, 0x52, 0xd2, 0xa3, 0xa4, 0xd3, 0xb1, 0xea, 0x1d, 0x0f, 0x00}}},
|
||||
{{{0xcc, 0x48, 0x83, 0x90, 0xe5, 0xfd, 0x3f, 0x84, 0xaa, 0xf9, 0x8b, 0x82, 0x59, 0x24, 0x34, 0x68, 0x4f, 0x1c, 0x23, 0xd9, 0xcc, 0x71, 0xe1, 0x7f, 0x8c, 0xaf, 0xf1, 0xee, 0x00, 0xb6, 0xa0, 0x77}} ,
|
||||
{{0xf5, 0x1a, 0x61, 0xf7, 0x37, 0x9d, 0x00, 0xf4, 0xf2, 0x69, 0x6f, 0x4b, 0x01, 0x85, 0x19, 0x45, 0x4d, 0x7f, 0x02, 0x7c, 0x6a, 0x05, 0x47, 0x6c, 0x1f, 0x81, 0x20, 0xd4, 0xe8, 0x50, 0x27, 0x72}}},
|
||||
{{{0x2c, 0x3a, 0xe5, 0xad, 0xf4, 0xdd, 0x2d, 0xf7, 0x5c, 0x44, 0xb5, 0x5b, 0x21, 0xa3, 0x89, 0x5f, 0x96, 0x45, 0xca, 0x4d, 0xa4, 0x21, 0x99, 0x70, 0xda, 0xc4, 0xc4, 0xa0, 0xe5, 0xf4, 0xec, 0x0a}} ,
|
||||
{{0x07, 0x68, 0x21, 0x65, 0xe9, 0x08, 0xa0, 0x0b, 0x6a, 0x4a, 0xba, 0xb5, 0x80, 0xaf, 0xd0, 0x1b, 0xc5, 0xf5, 0x4b, 0x73, 0x50, 0x60, 0x2d, 0x71, 0x69, 0x61, 0x0e, 0xc0, 0x20, 0x40, 0x30, 0x19}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xd0, 0x75, 0x57, 0x3b, 0xeb, 0x5c, 0x14, 0x56, 0x50, 0xc9, 0x4f, 0xb8, 0xb8, 0x1e, 0xa3, 0xf4, 0xab, 0xf5, 0xa9, 0x20, 0x15, 0x94, 0x82, 0xda, 0x96, 0x1c, 0x9b, 0x59, 0x8c, 0xff, 0xf4, 0x51}} ,
|
||||
{{0xc1, 0x3a, 0x86, 0xd7, 0xb0, 0x06, 0x84, 0x7f, 0x1b, 0xbd, 0xd4, 0x07, 0x78, 0x80, 0x2e, 0xb1, 0xb4, 0xee, 0x52, 0x38, 0xee, 0x9a, 0xf9, 0xf6, 0xf3, 0x41, 0x6e, 0xd4, 0x88, 0x95, 0xac, 0x35}}},
|
||||
{{{0x41, 0x97, 0xbf, 0x71, 0x6a, 0x9b, 0x72, 0xec, 0xf3, 0xf8, 0x6b, 0xe6, 0x0e, 0x6c, 0x69, 0xa5, 0x2f, 0x68, 0x52, 0xd8, 0x61, 0x81, 0xc0, 0x63, 0x3f, 0xa6, 0x3c, 0x13, 0x90, 0xe6, 0x8d, 0x56}} ,
|
||||
{{0xe8, 0x39, 0x30, 0x77, 0x23, 0xb1, 0xfd, 0x1b, 0x3d, 0x3e, 0x74, 0x4d, 0x7f, 0xae, 0x5b, 0x3a, 0xb4, 0x65, 0x0e, 0x3a, 0x43, 0xdc, 0xdc, 0x41, 0x47, 0xe6, 0xe8, 0x92, 0x09, 0x22, 0x48, 0x4c}}},
|
||||
{{{0x85, 0x57, 0x9f, 0xb5, 0xc8, 0x06, 0xb2, 0x9f, 0x47, 0x3f, 0xf0, 0xfa, 0xe6, 0xa9, 0xb1, 0x9b, 0x6f, 0x96, 0x7d, 0xf9, 0xa4, 0x65, 0x09, 0x75, 0x32, 0xa6, 0x6c, 0x7f, 0x47, 0x4b, 0x2f, 0x4f}} ,
|
||||
{{0x34, 0xe9, 0x59, 0x93, 0x9d, 0x26, 0x80, 0x54, 0xf2, 0xcc, 0x3c, 0xc2, 0x25, 0x85, 0xe3, 0x6a, 0xc1, 0x62, 0x04, 0xa7, 0x08, 0x32, 0x6d, 0xa1, 0x39, 0x84, 0x8a, 0x3b, 0x87, 0x5f, 0x11, 0x13}}},
|
||||
{{{0xda, 0x03, 0x34, 0x66, 0xc4, 0x0c, 0x73, 0x6e, 0xbc, 0x24, 0xb5, 0xf9, 0x70, 0x81, 0x52, 0xe9, 0xf4, 0x7c, 0x23, 0xdd, 0x9f, 0xb8, 0x46, 0xef, 0x1d, 0x22, 0x55, 0x7d, 0x71, 0xc4, 0x42, 0x33}} ,
|
||||
{{0xc5, 0x37, 0x69, 0x5b, 0xa8, 0xc6, 0x9d, 0xa4, 0xfc, 0x61, 0x6e, 0x68, 0x46, 0xea, 0xd7, 0x1c, 0x67, 0xd2, 0x7d, 0xfa, 0xf1, 0xcc, 0x54, 0x8d, 0x36, 0x35, 0xc9, 0x00, 0xdf, 0x6c, 0x67, 0x50}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x9a, 0x4d, 0x42, 0x29, 0x5d, 0xa4, 0x6b, 0x6f, 0xa8, 0x8a, 0x4d, 0x91, 0x7b, 0xd2, 0xdf, 0x36, 0xef, 0x01, 0x22, 0xc5, 0xcc, 0x8d, 0xeb, 0x58, 0x3d, 0xb3, 0x50, 0xfc, 0x8b, 0x97, 0x96, 0x33}} ,
|
||||
{{0x93, 0x33, 0x07, 0xc8, 0x4a, 0xca, 0xd0, 0xb1, 0xab, 0xbd, 0xdd, 0xa7, 0x7c, 0xac, 0x3e, 0x45, 0xcb, 0xcc, 0x07, 0x91, 0xbf, 0x35, 0x9d, 0xcb, 0x7d, 0x12, 0x3c, 0x11, 0x59, 0x13, 0xcf, 0x5c}}},
|
||||
{{{0x45, 0xb8, 0x41, 0xd7, 0xab, 0x07, 0x15, 0x00, 0x8e, 0xce, 0xdf, 0xb2, 0x43, 0x5c, 0x01, 0xdc, 0xf4, 0x01, 0x51, 0x95, 0x10, 0x5a, 0xf6, 0x24, 0x24, 0xa0, 0x19, 0x3a, 0x09, 0x2a, 0xaa, 0x3f}} ,
|
||||
{{0xdc, 0x8e, 0xeb, 0xc6, 0xbf, 0xdd, 0x11, 0x7b, 0xe7, 0x47, 0xe6, 0xce, 0xe7, 0xb6, 0xc5, 0xe8, 0x8a, 0xdc, 0x4b, 0x57, 0x15, 0x3b, 0x66, 0xca, 0x89, 0xa3, 0xfd, 0xac, 0x0d, 0xe1, 0x1d, 0x7a}}},
|
||||
{{{0x89, 0xef, 0xbf, 0x03, 0x75, 0xd0, 0x29, 0x50, 0xcb, 0x7d, 0xd6, 0xbe, 0xad, 0x5f, 0x7b, 0x00, 0x32, 0xaa, 0x98, 0xed, 0x3f, 0x8f, 0x92, 0xcb, 0x81, 0x56, 0x01, 0x63, 0x64, 0xa3, 0x38, 0x39}} ,
|
||||
{{0x8b, 0xa4, 0xd6, 0x50, 0xb4, 0xaa, 0x5d, 0x64, 0x64, 0x76, 0x2e, 0xa1, 0xa6, 0xb3, 0xb8, 0x7c, 0x7a, 0x56, 0xf5, 0x5c, 0x4e, 0x84, 0x5c, 0xfb, 0xdd, 0xca, 0x48, 0x8b, 0x48, 0xb9, 0xba, 0x34}}},
|
||||
{{{0xc5, 0xe3, 0xe8, 0xae, 0x17, 0x27, 0xe3, 0x64, 0x60, 0x71, 0x47, 0x29, 0x02, 0x0f, 0x92, 0x5d, 0x10, 0x93, 0xc8, 0x0e, 0xa1, 0xed, 0xba, 0xa9, 0x96, 0x1c, 0xc5, 0x76, 0x30, 0xcd, 0xf9, 0x30}} ,
|
||||
{{0x95, 0xb0, 0xbd, 0x8c, 0xbc, 0xa7, 0x4f, 0x7e, 0xfd, 0x4e, 0x3a, 0xbf, 0x5f, 0x04, 0x79, 0x80, 0x2b, 0x5a, 0x9f, 0x4f, 0x68, 0x21, 0x19, 0x71, 0xc6, 0x20, 0x01, 0x42, 0xaa, 0xdf, 0xae, 0x2c}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x90, 0x6e, 0x7e, 0x4b, 0x71, 0x93, 0xc0, 0x72, 0xed, 0xeb, 0x71, 0x24, 0x97, 0x26, 0x9c, 0xfe, 0xcb, 0x3e, 0x59, 0x19, 0xa8, 0x0f, 0x75, 0x7d, 0xbe, 0x18, 0xe6, 0x96, 0x1e, 0x95, 0x70, 0x60}} ,
|
||||
{{0x89, 0x66, 0x3e, 0x1d, 0x4c, 0x5f, 0xfe, 0xc0, 0x04, 0x43, 0xd6, 0x44, 0x19, 0xb5, 0xad, 0xc7, 0x22, 0xdc, 0x71, 0x28, 0x64, 0xde, 0x41, 0x38, 0x27, 0x8f, 0x2c, 0x6b, 0x08, 0xb8, 0xb8, 0x7b}}},
|
||||
{{{0x3d, 0x70, 0x27, 0x9d, 0xd9, 0xaf, 0xb1, 0x27, 0xaf, 0xe3, 0x5d, 0x1e, 0x3a, 0x30, 0x54, 0x61, 0x60, 0xe8, 0xc3, 0x26, 0x3a, 0xbc, 0x7e, 0xf5, 0x81, 0xdd, 0x64, 0x01, 0x04, 0xeb, 0xc0, 0x1e}} ,
|
||||
{{0xda, 0x2c, 0xa4, 0xd1, 0xa1, 0xc3, 0x5c, 0x6e, 0x32, 0x07, 0x1f, 0xb8, 0x0e, 0x19, 0x9e, 0x99, 0x29, 0x33, 0x9a, 0xae, 0x7a, 0xed, 0x68, 0x42, 0x69, 0x7c, 0x07, 0xb3, 0x38, 0x2c, 0xf6, 0x3d}}},
|
||||
{{{0x64, 0xaa, 0xb5, 0x88, 0x79, 0x65, 0x38, 0x8c, 0x94, 0xd6, 0x62, 0x37, 0x7d, 0x64, 0xcd, 0x3a, 0xeb, 0xff, 0xe8, 0x81, 0x09, 0xc7, 0x6a, 0x50, 0x09, 0x0d, 0x28, 0x03, 0x0d, 0x9a, 0x93, 0x0a}} ,
|
||||
{{0x42, 0xa3, 0xf1, 0xc5, 0xb4, 0x0f, 0xd8, 0xc8, 0x8d, 0x15, 0x31, 0xbd, 0xf8, 0x07, 0x8b, 0xcd, 0x08, 0x8a, 0xfb, 0x18, 0x07, 0xfe, 0x8e, 0x52, 0x86, 0xef, 0xbe, 0xec, 0x49, 0x52, 0x99, 0x08}}},
|
||||
{{{0x0f, 0xa9, 0xd5, 0x01, 0xaa, 0x48, 0x4f, 0x28, 0x66, 0x32, 0x1a, 0xba, 0x7c, 0xea, 0x11, 0x80, 0x17, 0x18, 0x9b, 0x56, 0x88, 0x25, 0x06, 0x69, 0x12, 0x2c, 0xea, 0x56, 0x69, 0x41, 0x24, 0x19}} ,
|
||||
{{0xde, 0x21, 0xf0, 0xda, 0x8a, 0xfb, 0xb1, 0xb8, 0xcd, 0xc8, 0x6a, 0x82, 0x19, 0x73, 0xdb, 0xc7, 0xcf, 0x88, 0xeb, 0x96, 0xee, 0x6f, 0xfb, 0x06, 0xd2, 0xcd, 0x7d, 0x7b, 0x12, 0x28, 0x8e, 0x0c}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x93, 0x44, 0x97, 0xce, 0x28, 0xff, 0x3a, 0x40, 0xc4, 0xf5, 0xf6, 0x9b, 0xf4, 0x6b, 0x07, 0x84, 0xfb, 0x98, 0xd8, 0xec, 0x8c, 0x03, 0x57, 0xec, 0x49, 0xed, 0x63, 0xb6, 0xaa, 0xff, 0x98, 0x28}} ,
|
||||
{{0x3d, 0x16, 0x35, 0xf3, 0x46, 0xbc, 0xb3, 0xf4, 0xc6, 0xb6, 0x4f, 0xfa, 0xf4, 0xa0, 0x13, 0xe6, 0x57, 0x45, 0x93, 0xb9, 0xbc, 0xd6, 0x59, 0xe7, 0x77, 0x94, 0x6c, 0xab, 0x96, 0x3b, 0x4f, 0x09}}},
|
||||
{{{0x5a, 0xf7, 0x6b, 0x01, 0x12, 0x4f, 0x51, 0xc1, 0x70, 0x84, 0x94, 0x47, 0xb2, 0x01, 0x6c, 0x71, 0xd7, 0xcc, 0x17, 0x66, 0x0f, 0x59, 0x5d, 0x5d, 0x10, 0x01, 0x57, 0x11, 0xf5, 0xdd, 0xe2, 0x34}} ,
|
||||
{{0x26, 0xd9, 0x1f, 0x5c, 0x58, 0xac, 0x8b, 0x03, 0xd2, 0xc3, 0x85, 0x0f, 0x3a, 0xc3, 0x7f, 0x6d, 0x8e, 0x86, 0xcd, 0x52, 0x74, 0x8f, 0x55, 0x77, 0x17, 0xb7, 0x8e, 0xb7, 0x88, 0xea, 0xda, 0x1b}}},
|
||||
{{{0xb6, 0xea, 0x0e, 0x40, 0x93, 0x20, 0x79, 0x35, 0x6a, 0x61, 0x84, 0x5a, 0x07, 0x6d, 0xf9, 0x77, 0x6f, 0xed, 0x69, 0x1c, 0x0d, 0x25, 0x76, 0xcc, 0xf0, 0xdb, 0xbb, 0xc5, 0xad, 0xe2, 0x26, 0x57}} ,
|
||||
{{0xcf, 0xe8, 0x0e, 0x6b, 0x96, 0x7d, 0xed, 0x27, 0xd1, 0x3c, 0xa9, 0xd9, 0x50, 0xa9, 0x98, 0x84, 0x5e, 0x86, 0xef, 0xd6, 0xf0, 0xf8, 0x0e, 0x89, 0x05, 0x2f, 0xd9, 0x5f, 0x15, 0x5f, 0x73, 0x79}}},
|
||||
{{{0xc8, 0x5c, 0x16, 0xfe, 0xed, 0x9f, 0x26, 0x56, 0xf6, 0x4b, 0x9f, 0xa7, 0x0a, 0x85, 0xfe, 0xa5, 0x8c, 0x87, 0xdd, 0x98, 0xce, 0x4e, 0xc3, 0x58, 0x55, 0xb2, 0x7b, 0x3d, 0xd8, 0x6b, 0xb5, 0x4c}} ,
|
||||
{{0x65, 0x38, 0xa0, 0x15, 0xfa, 0xa7, 0xb4, 0x8f, 0xeb, 0xc4, 0x86, 0x9b, 0x30, 0xa5, 0x5e, 0x4d, 0xea, 0x8a, 0x9a, 0x9f, 0x1a, 0xd8, 0x5b, 0x53, 0x14, 0x19, 0x25, 0x63, 0xb4, 0x6f, 0x1f, 0x5d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xac, 0x8f, 0xbc, 0x1e, 0x7d, 0x8b, 0x5a, 0x0b, 0x8d, 0xaf, 0x76, 0x2e, 0x71, 0xe3, 0x3b, 0x6f, 0x53, 0x2f, 0x3e, 0x90, 0x95, 0xd4, 0x35, 0x14, 0x4f, 0x8c, 0x3c, 0xce, 0x57, 0x1c, 0x76, 0x49}} ,
|
||||
{{0xa8, 0x50, 0xe1, 0x61, 0x6b, 0x57, 0x35, 0xeb, 0x44, 0x0b, 0x0c, 0x6e, 0xf9, 0x25, 0x80, 0x74, 0xf2, 0x8f, 0x6f, 0x7a, 0x3e, 0x7f, 0x2d, 0xf3, 0x4e, 0x09, 0x65, 0x10, 0x5e, 0x03, 0x25, 0x32}}},
|
||||
{{{0xa9, 0x60, 0xdc, 0x0f, 0x64, 0xe5, 0x1d, 0xe2, 0x8d, 0x4f, 0x79, 0x2f, 0x0e, 0x24, 0x02, 0x00, 0x05, 0x77, 0x43, 0x25, 0x3d, 0x6a, 0xc7, 0xb7, 0xbf, 0x04, 0x08, 0x65, 0xf4, 0x39, 0x4b, 0x65}} ,
|
||||
{{0x96, 0x19, 0x12, 0x6b, 0x6a, 0xb7, 0xe3, 0xdc, 0x45, 0x9b, 0xdb, 0xb4, 0xa8, 0xae, 0xdc, 0xa8, 0x14, 0x44, 0x65, 0x62, 0xce, 0x34, 0x9a, 0x84, 0x18, 0x12, 0x01, 0xf1, 0xe2, 0x7b, 0xce, 0x50}}},
|
||||
{{{0x41, 0x21, 0x30, 0x53, 0x1b, 0x47, 0x01, 0xb7, 0x18, 0xd8, 0x82, 0x57, 0xbd, 0xa3, 0x60, 0xf0, 0x32, 0xf6, 0x5b, 0xf0, 0x30, 0x88, 0x91, 0x59, 0xfd, 0x90, 0xa2, 0xb9, 0x55, 0x93, 0x21, 0x34}} ,
|
||||
{{0x97, 0x67, 0x9e, 0xeb, 0x6a, 0xf9, 0x6e, 0xd6, 0x73, 0xe8, 0x6b, 0x29, 0xec, 0x63, 0x82, 0x00, 0xa8, 0x99, 0x1c, 0x1d, 0x30, 0xc8, 0x90, 0x52, 0x90, 0xb6, 0x6a, 0x80, 0x4e, 0xff, 0x4b, 0x51}}},
|
||||
{{{0x0f, 0x7d, 0x63, 0x8c, 0x6e, 0x5c, 0xde, 0x30, 0xdf, 0x65, 0xfa, 0x2e, 0xb0, 0xa3, 0x25, 0x05, 0x54, 0xbd, 0x25, 0xba, 0x06, 0xae, 0xdf, 0x8b, 0xd9, 0x1b, 0xea, 0x38, 0xb3, 0x05, 0x16, 0x09}} ,
|
||||
{{0xc7, 0x8c, 0xbf, 0x64, 0x28, 0xad, 0xf8, 0xa5, 0x5a, 0x6f, 0xc9, 0xba, 0xd5, 0x7f, 0xd5, 0xd6, 0xbd, 0x66, 0x2f, 0x3d, 0xaa, 0x54, 0xf6, 0xba, 0x32, 0x22, 0x9a, 0x1e, 0x52, 0x05, 0xf4, 0x1d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xaa, 0x1f, 0xbb, 0xeb, 0xfe, 0xe4, 0x87, 0xfc, 0xb1, 0x2c, 0xb7, 0x88, 0xf4, 0xc6, 0xb9, 0xf5, 0x24, 0x46, 0xf2, 0xa5, 0x9f, 0x8f, 0x8a, 0x93, 0x70, 0x69, 0xd4, 0x56, 0xec, 0xfd, 0x06, 0x46}} ,
|
||||
{{0x4e, 0x66, 0xcf, 0x4e, 0x34, 0xce, 0x0c, 0xd9, 0xa6, 0x50, 0xd6, 0x5e, 0x95, 0xaf, 0xe9, 0x58, 0xfa, 0xee, 0x9b, 0xb8, 0xa5, 0x0f, 0x35, 0xe0, 0x43, 0x82, 0x6d, 0x65, 0xe6, 0xd9, 0x00, 0x0f}}},
|
||||
{{{0x7b, 0x75, 0x3a, 0xfc, 0x64, 0xd3, 0x29, 0x7e, 0xdd, 0x49, 0x9a, 0x59, 0x53, 0xbf, 0xb4, 0xa7, 0x52, 0xb3, 0x05, 0xab, 0xc3, 0xaf, 0x16, 0x1a, 0x85, 0x42, 0x32, 0xa2, 0x86, 0xfa, 0x39, 0x43}} ,
|
||||
{{0x0e, 0x4b, 0xa3, 0x63, 0x8a, 0xfe, 0xa5, 0x58, 0xf1, 0x13, 0xbd, 0x9d, 0xaa, 0x7f, 0x76, 0x40, 0x70, 0x81, 0x10, 0x75, 0x99, 0xbb, 0xbe, 0x0b, 0x16, 0xe9, 0xba, 0x62, 0x34, 0xcc, 0x07, 0x6d}}},
|
||||
{{{0xc3, 0xf1, 0xc6, 0x93, 0x65, 0xee, 0x0b, 0xbc, 0xea, 0x14, 0xf0, 0xc1, 0xf8, 0x84, 0x89, 0xc2, 0xc9, 0xd7, 0xea, 0x34, 0xca, 0xa7, 0xc4, 0x99, 0xd5, 0x50, 0x69, 0xcb, 0xd6, 0x21, 0x63, 0x7c}} ,
|
||||
{{0x99, 0xeb, 0x7c, 0x31, 0x73, 0x64, 0x67, 0x7f, 0x0c, 0x66, 0xaa, 0x8c, 0x69, 0x91, 0xe2, 0x26, 0xd3, 0x23, 0xe2, 0x76, 0x5d, 0x32, 0x52, 0xdf, 0x5d, 0xc5, 0x8f, 0xb7, 0x7c, 0x84, 0xb3, 0x70}}},
|
||||
{{{0xeb, 0x01, 0xc7, 0x36, 0x97, 0x4e, 0xb6, 0xab, 0x5f, 0x0d, 0x2c, 0xba, 0x67, 0x64, 0x55, 0xde, 0xbc, 0xff, 0xa6, 0xec, 0x04, 0xd3, 0x8d, 0x39, 0x56, 0x5e, 0xee, 0xf8, 0xe4, 0x2e, 0x33, 0x62}} ,
|
||||
{{0x65, 0xef, 0xb8, 0x9f, 0xc8, 0x4b, 0xa7, 0xfd, 0x21, 0x49, 0x9b, 0x92, 0x35, 0x82, 0xd6, 0x0a, 0x9b, 0xf2, 0x79, 0xf1, 0x47, 0x2f, 0x6a, 0x7e, 0x9f, 0xcf, 0x18, 0x02, 0x3c, 0xfb, 0x1b, 0x3e}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x2f, 0x8b, 0xc8, 0x40, 0x51, 0xd1, 0xac, 0x1a, 0x0b, 0xe4, 0xa9, 0xa2, 0x42, 0x21, 0x19, 0x2f, 0x7b, 0x97, 0xbf, 0xf7, 0x57, 0x6d, 0x3f, 0x3d, 0x4f, 0x0f, 0xe2, 0xb2, 0x81, 0x00, 0x9e, 0x7b}} ,
|
||||
{{0x8c, 0x85, 0x2b, 0xc4, 0xfc, 0xf1, 0xab, 0xe8, 0x79, 0x22, 0xc4, 0x84, 0x17, 0x3a, 0xfa, 0x86, 0xa6, 0x7d, 0xf9, 0xf3, 0x6f, 0x03, 0x57, 0x20, 0x4d, 0x79, 0xf9, 0x6e, 0x71, 0x54, 0x38, 0x09}}},
|
||||
{{{0x40, 0x29, 0x74, 0xa8, 0x2f, 0x5e, 0xf9, 0x79, 0xa4, 0xf3, 0x3e, 0xb9, 0xfd, 0x33, 0x31, 0xac, 0x9a, 0x69, 0x88, 0x1e, 0x77, 0x21, 0x2d, 0xf3, 0x91, 0x52, 0x26, 0x15, 0xb2, 0xa6, 0xcf, 0x7e}} ,
|
||||
{{0xc6, 0x20, 0x47, 0x6c, 0xa4, 0x7d, 0xcb, 0x63, 0xea, 0x5b, 0x03, 0xdf, 0x3e, 0x88, 0x81, 0x6d, 0xce, 0x07, 0x42, 0x18, 0x60, 0x7e, 0x7b, 0x55, 0xfe, 0x6a, 0xf3, 0xda, 0x5c, 0x8b, 0x95, 0x10}}},
|
||||
{{{0x62, 0xe4, 0x0d, 0x03, 0xb4, 0xd7, 0xcd, 0xfa, 0xbd, 0x46, 0xdf, 0x93, 0x71, 0x10, 0x2c, 0xa8, 0x3b, 0xb6, 0x09, 0x05, 0x70, 0x84, 0x43, 0x29, 0xa8, 0x59, 0xf5, 0x8e, 0x10, 0xe4, 0xd7, 0x20}} ,
|
||||
{{0x57, 0x82, 0x1c, 0xab, 0xbf, 0x62, 0x70, 0xe8, 0xc4, 0xcf, 0xf0, 0x28, 0x6e, 0x16, 0x3c, 0x08, 0x78, 0x89, 0x85, 0x46, 0x0f, 0xf6, 0x7f, 0xcf, 0xcb, 0x7e, 0xb8, 0x25, 0xe9, 0x5a, 0xfa, 0x03}}},
|
||||
{{{0xfb, 0x95, 0x92, 0x63, 0x50, 0xfc, 0x62, 0xf0, 0xa4, 0x5e, 0x8c, 0x18, 0xc2, 0x17, 0x24, 0xb7, 0x78, 0xc2, 0xa9, 0xe7, 0x6a, 0x32, 0xd6, 0x29, 0x85, 0xaf, 0xcb, 0x8d, 0x91, 0x13, 0xda, 0x6b}} ,
|
||||
{{0x36, 0x0a, 0xc2, 0xb6, 0x4b, 0xa5, 0x5d, 0x07, 0x17, 0x41, 0x31, 0x5f, 0x62, 0x46, 0xf8, 0x92, 0xf9, 0x66, 0x48, 0x73, 0xa6, 0x97, 0x0d, 0x7d, 0x88, 0xee, 0x62, 0xb1, 0x03, 0xa8, 0x3f, 0x2c}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x4a, 0xb1, 0x70, 0x8a, 0xa9, 0xe8, 0x63, 0x79, 0x00, 0xe2, 0x25, 0x16, 0xca, 0x4b, 0x0f, 0xa4, 0x66, 0xad, 0x19, 0x9f, 0x88, 0x67, 0x0c, 0x8b, 0xc2, 0x4a, 0x5b, 0x2b, 0x6d, 0x95, 0xaf, 0x19}} ,
|
||||
{{0x8b, 0x9d, 0xb6, 0xcc, 0x60, 0xb4, 0x72, 0x4f, 0x17, 0x69, 0x5a, 0x4a, 0x68, 0x34, 0xab, 0xa1, 0x45, 0x32, 0x3c, 0x83, 0x87, 0x72, 0x30, 0x54, 0x77, 0x68, 0xae, 0xfb, 0xb5, 0x8b, 0x22, 0x5e}}},
|
||||
{{{0xf1, 0xb9, 0x87, 0x35, 0xc5, 0xbb, 0xb9, 0xcf, 0xf5, 0xd6, 0xcd, 0xd5, 0x0c, 0x7c, 0x0e, 0xe6, 0x90, 0x34, 0xfb, 0x51, 0x42, 0x1e, 0x6d, 0xac, 0x9a, 0x46, 0xc4, 0x97, 0x29, 0x32, 0xbf, 0x45}} ,
|
||||
{{0x66, 0x9e, 0xc6, 0x24, 0xc0, 0xed, 0xa5, 0x5d, 0x88, 0xd4, 0xf0, 0x73, 0x97, 0x7b, 0xea, 0x7f, 0x42, 0xff, 0x21, 0xa0, 0x9b, 0x2f, 0x9a, 0xfd, 0x53, 0x57, 0x07, 0x84, 0x48, 0x88, 0x9d, 0x52}}},
|
||||
{{{0xc6, 0x96, 0x48, 0x34, 0x2a, 0x06, 0xaf, 0x94, 0x3d, 0xf4, 0x1a, 0xcf, 0xf2, 0xc0, 0x21, 0xc2, 0x42, 0x5e, 0xc8, 0x2f, 0x35, 0xa2, 0x3e, 0x29, 0xfa, 0x0c, 0x84, 0xe5, 0x89, 0x72, 0x7c, 0x06}} ,
|
||||
{{0x32, 0x65, 0x03, 0xe5, 0x89, 0xa6, 0x6e, 0xb3, 0x5b, 0x8e, 0xca, 0xeb, 0xfe, 0x22, 0x56, 0x8b, 0x5d, 0x14, 0x4b, 0x4d, 0xf9, 0xbe, 0xb5, 0xf5, 0xe6, 0x5c, 0x7b, 0x8b, 0xf4, 0x13, 0x11, 0x34}}},
|
||||
{{{0x07, 0xc6, 0x22, 0x15, 0xe2, 0x9c, 0x60, 0xa2, 0x19, 0xd9, 0x27, 0xae, 0x37, 0x4e, 0xa6, 0xc9, 0x80, 0xa6, 0x91, 0x8f, 0x12, 0x49, 0xe5, 0x00, 0x18, 0x47, 0xd1, 0xd7, 0x28, 0x22, 0x63, 0x39}} ,
|
||||
{{0xe8, 0xe2, 0x00, 0x7e, 0xf2, 0x9e, 0x1e, 0x99, 0x39, 0x95, 0x04, 0xbd, 0x1e, 0x67, 0x7b, 0xb2, 0x26, 0xac, 0xe6, 0xaa, 0xe2, 0x46, 0xd5, 0xe4, 0xe8, 0x86, 0xbd, 0xab, 0x7c, 0x55, 0x59, 0x6f}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x24, 0x64, 0x6e, 0x9b, 0x35, 0x71, 0x78, 0xce, 0x33, 0x03, 0x21, 0x33, 0x36, 0xf1, 0x73, 0x9b, 0xb9, 0x15, 0x8b, 0x2c, 0x69, 0xcf, 0x4d, 0xed, 0x4f, 0x4d, 0x57, 0x14, 0x13, 0x82, 0xa4, 0x4d}} ,
|
||||
{{0x65, 0x6e, 0x0a, 0xa4, 0x59, 0x07, 0x17, 0xf2, 0x6b, 0x4a, 0x1f, 0x6e, 0xf6, 0xb5, 0xbc, 0x62, 0xe4, 0xb6, 0xda, 0xa2, 0x93, 0xbc, 0x29, 0x05, 0xd2, 0xd2, 0x73, 0x46, 0x03, 0x16, 0x40, 0x31}}},
|
||||
{{{0x4c, 0x73, 0x6d, 0x15, 0xbd, 0xa1, 0x4d, 0x5c, 0x13, 0x0b, 0x24, 0x06, 0x98, 0x78, 0x1c, 0x5b, 0xeb, 0x1f, 0x18, 0x54, 0x43, 0xd9, 0x55, 0x66, 0xda, 0x29, 0x21, 0xe8, 0xb8, 0x3c, 0x42, 0x22}} ,
|
||||
{{0xb4, 0xcd, 0x08, 0x6f, 0x15, 0x23, 0x1a, 0x0b, 0x22, 0xed, 0xd1, 0xf1, 0xa7, 0xc7, 0x73, 0x45, 0xf3, 0x9e, 0xce, 0x76, 0xb7, 0xf6, 0x39, 0xb6, 0x8e, 0x79, 0xbe, 0xe9, 0x9b, 0xcf, 0x7d, 0x62}}},
|
||||
{{{0x92, 0x5b, 0xfc, 0x72, 0xfd, 0xba, 0xf1, 0xfd, 0xa6, 0x7c, 0x95, 0xe3, 0x61, 0x3f, 0xe9, 0x03, 0xd4, 0x2b, 0xd4, 0x20, 0xd9, 0xdb, 0x4d, 0x32, 0x3e, 0xf5, 0x11, 0x64, 0xe3, 0xb4, 0xbe, 0x32}} ,
|
||||
{{0x86, 0x17, 0x90, 0xe7, 0xc9, 0x1f, 0x10, 0xa5, 0x6a, 0x2d, 0x39, 0xd0, 0x3b, 0xc4, 0xa6, 0xe9, 0x59, 0x13, 0xda, 0x1a, 0xe6, 0xa0, 0xb9, 0x3c, 0x50, 0xb8, 0x40, 0x7c, 0x15, 0x36, 0x5a, 0x42}}},
|
||||
{{{0xb4, 0x0b, 0x32, 0xab, 0xdc, 0x04, 0x51, 0x55, 0x21, 0x1e, 0x0b, 0x75, 0x99, 0x89, 0x73, 0x35, 0x3a, 0x91, 0x2b, 0xfe, 0xe7, 0x49, 0xea, 0x76, 0xc1, 0xf9, 0x46, 0xb9, 0x53, 0x02, 0x23, 0x04}} ,
|
||||
{{0xfc, 0x5a, 0x1e, 0x1d, 0x74, 0x58, 0x95, 0xa6, 0x8f, 0x7b, 0x97, 0x3e, 0x17, 0x3b, 0x79, 0x2d, 0xa6, 0x57, 0xef, 0x45, 0x02, 0x0b, 0x4d, 0x6e, 0x9e, 0x93, 0x8d, 0x2f, 0xd9, 0x9d, 0xdb, 0x04}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xc0, 0xd7, 0x56, 0x97, 0x58, 0x91, 0xde, 0x09, 0x4f, 0x9f, 0xbe, 0x63, 0xb0, 0x83, 0x86, 0x43, 0x5d, 0xbc, 0xe0, 0xf3, 0xc0, 0x75, 0xbf, 0x8b, 0x8e, 0xaa, 0xf7, 0x8b, 0x64, 0x6e, 0xb0, 0x63}} ,
|
||||
{{0x16, 0xae, 0x8b, 0xe0, 0x9b, 0x24, 0x68, 0x5c, 0x44, 0xc2, 0xd0, 0x08, 0xb7, 0x7b, 0x62, 0xfd, 0x7f, 0xd8, 0xd4, 0xb7, 0x50, 0xfd, 0x2c, 0x1b, 0xbf, 0x41, 0x95, 0xd9, 0x8e, 0xd8, 0x17, 0x1b}}},
|
||||
{{{0x86, 0x55, 0x37, 0x8e, 0xc3, 0x38, 0x48, 0x14, 0xb5, 0x97, 0xd2, 0xa7, 0x54, 0x45, 0xf1, 0x35, 0x44, 0x38, 0x9e, 0xf1, 0x1b, 0xb6, 0x34, 0x00, 0x3c, 0x96, 0xee, 0x29, 0x00, 0xea, 0x2c, 0x0b}} ,
|
||||
{{0xea, 0xda, 0x99, 0x9e, 0x19, 0x83, 0x66, 0x6d, 0xe9, 0x76, 0x87, 0x50, 0xd1, 0xfd, 0x3c, 0x60, 0x87, 0xc6, 0x41, 0xd9, 0x8e, 0xdb, 0x5e, 0xde, 0xaa, 0x9a, 0xd3, 0x28, 0xda, 0x95, 0xea, 0x47}}},
|
||||
{{{0xd0, 0x80, 0xba, 0x19, 0xae, 0x1d, 0xa9, 0x79, 0xf6, 0x3f, 0xac, 0x5d, 0x6f, 0x96, 0x1f, 0x2a, 0xce, 0x29, 0xb2, 0xff, 0x37, 0xf1, 0x94, 0x8f, 0x0c, 0xb5, 0x28, 0xba, 0x9a, 0x21, 0xf6, 0x66}} ,
|
||||
{{0x02, 0xfb, 0x54, 0xb8, 0x05, 0xf3, 0x81, 0x52, 0x69, 0x34, 0x46, 0x9d, 0x86, 0x76, 0x8f, 0xd7, 0xf8, 0x6a, 0x66, 0xff, 0xe6, 0xa7, 0x90, 0xf7, 0x5e, 0xcd, 0x6a, 0x9b, 0x55, 0xfc, 0x9d, 0x48}}},
|
||||
{{{0xbd, 0xaa, 0x13, 0xe6, 0xcd, 0x45, 0x4a, 0xa4, 0x59, 0x0a, 0x64, 0xb1, 0x98, 0xd6, 0x34, 0x13, 0x04, 0xe6, 0x97, 0x94, 0x06, 0xcb, 0xd4, 0x4e, 0xbb, 0x96, 0xcd, 0xd1, 0x57, 0xd1, 0xe3, 0x06}} ,
|
||||
{{0x7a, 0x6c, 0x45, 0x27, 0xc4, 0x93, 0x7f, 0x7d, 0x7c, 0x62, 0x50, 0x38, 0x3a, 0x6b, 0xb5, 0x88, 0xc6, 0xd9, 0xf1, 0x78, 0x19, 0xb9, 0x39, 0x93, 0x3d, 0xc9, 0xe0, 0x9c, 0x3c, 0xce, 0xf5, 0x72}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x24, 0xea, 0x23, 0x7d, 0x56, 0x2c, 0xe2, 0x59, 0x0e, 0x85, 0x60, 0x04, 0x88, 0x5a, 0x74, 0x1e, 0x4b, 0xef, 0x13, 0xda, 0x4c, 0xff, 0x83, 0x45, 0x85, 0x3f, 0x08, 0x95, 0x2c, 0x20, 0x13, 0x1f}} ,
|
||||
{{0x48, 0x5f, 0x27, 0x90, 0x5c, 0x02, 0x42, 0xad, 0x78, 0x47, 0x5c, 0xb5, 0x7e, 0x08, 0x85, 0x00, 0xfa, 0x7f, 0xfd, 0xfd, 0xe7, 0x09, 0x11, 0xf2, 0x7e, 0x1b, 0x38, 0x6c, 0x35, 0x6d, 0x33, 0x66}}},
|
||||
{{{0x93, 0x03, 0x36, 0x81, 0xac, 0xe4, 0x20, 0x09, 0x35, 0x4c, 0x45, 0xb2, 0x1e, 0x4c, 0x14, 0x21, 0xe6, 0xe9, 0x8a, 0x7b, 0x8d, 0xfe, 0x1e, 0xc6, 0x3e, 0xc1, 0x35, 0xfa, 0xe7, 0x70, 0x4e, 0x1d}} ,
|
||||
{{0x61, 0x2e, 0xc2, 0xdd, 0x95, 0x57, 0xd1, 0xab, 0x80, 0xe8, 0x63, 0x17, 0xb5, 0x48, 0xe4, 0x8a, 0x11, 0x9e, 0x72, 0xbe, 0x85, 0x8d, 0x51, 0x0a, 0xf2, 0x9f, 0xe0, 0x1c, 0xa9, 0x07, 0x28, 0x7b}}},
|
||||
{{{0xbb, 0x71, 0x14, 0x5e, 0x26, 0x8c, 0x3d, 0xc8, 0xe9, 0x7c, 0xd3, 0xd6, 0xd1, 0x2f, 0x07, 0x6d, 0xe6, 0xdf, 0xfb, 0x79, 0xd6, 0x99, 0x59, 0x96, 0x48, 0x40, 0x0f, 0x3a, 0x7b, 0xb2, 0xa0, 0x72}} ,
|
||||
{{0x4e, 0x3b, 0x69, 0xc8, 0x43, 0x75, 0x51, 0x6c, 0x79, 0x56, 0xe4, 0xcb, 0xf7, 0xa6, 0x51, 0xc2, 0x2c, 0x42, 0x0b, 0xd4, 0x82, 0x20, 0x1c, 0x01, 0x08, 0x66, 0xd7, 0xbf, 0x04, 0x56, 0xfc, 0x02}}},
|
||||
{{{0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c}} ,
|
||||
{{0x6b, 0xa6, 0xf5, 0x4b, 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, 0xe6, 0x99, 0x2c, 0x5f}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x85, 0xe0, 0x24, 0x32, 0xb4, 0xd1, 0xef, 0xfc, 0x69, 0xa2, 0xbf, 0x8f, 0x72, 0x2c, 0x95, 0xf6, 0xe4, 0x6e, 0x7d, 0x90, 0xf7, 0x57, 0x81, 0xa0, 0xf7, 0xda, 0xef, 0x33, 0x07, 0xe3, 0x6b, 0x78}} ,
|
||||
{{0x36, 0x27, 0x3e, 0xc6, 0x12, 0x07, 0xab, 0x4e, 0xbe, 0x69, 0x9d, 0xb3, 0xbe, 0x08, 0x7c, 0x2a, 0x47, 0x08, 0xfd, 0xd4, 0xcd, 0x0e, 0x27, 0x34, 0x5b, 0x98, 0x34, 0x2f, 0x77, 0x5f, 0x3a, 0x65}}},
|
||||
{{{0x13, 0xaa, 0x2e, 0x4c, 0xf0, 0x22, 0xb8, 0x6c, 0xb3, 0x19, 0x4d, 0xeb, 0x6b, 0xd0, 0xa4, 0xc6, 0x9c, 0xdd, 0xc8, 0x5b, 0x81, 0x57, 0x89, 0xdf, 0x33, 0xa9, 0x68, 0x49, 0x80, 0xe4, 0xfe, 0x21}} ,
|
||||
{{0x00, 0x17, 0x90, 0x30, 0xe9, 0xd3, 0x60, 0x30, 0x31, 0xc2, 0x72, 0x89, 0x7a, 0x36, 0xa5, 0xbd, 0x39, 0x83, 0x85, 0x50, 0xa1, 0x5d, 0x6c, 0x41, 0x1d, 0xb5, 0x2c, 0x07, 0x40, 0x77, 0x0b, 0x50}}},
|
||||
{{{0x64, 0x34, 0xec, 0xc0, 0x9e, 0x44, 0x41, 0xaf, 0xa0, 0x36, 0x05, 0x6d, 0xea, 0x30, 0x25, 0x46, 0x35, 0x24, 0x9d, 0x86, 0xbd, 0x95, 0xf1, 0x6a, 0x46, 0xd7, 0x94, 0x54, 0xf9, 0x3b, 0xbd, 0x5d}} ,
|
||||
{{0x77, 0x5b, 0xe2, 0x37, 0xc7, 0xe1, 0x7c, 0x13, 0x8c, 0x9f, 0x7b, 0x7b, 0x2a, 0xce, 0x42, 0xa3, 0xb9, 0x2a, 0x99, 0xa8, 0xc0, 0xd8, 0x3c, 0x86, 0xb0, 0xfb, 0xe9, 0x76, 0x77, 0xf7, 0xf5, 0x56}}},
|
||||
{{{0xdf, 0xb3, 0x46, 0x11, 0x6e, 0x13, 0xb7, 0x28, 0x4e, 0x56, 0xdd, 0xf1, 0xac, 0xad, 0x58, 0xc3, 0xf8, 0x88, 0x94, 0x5e, 0x06, 0x98, 0xa1, 0xe4, 0x6a, 0xfb, 0x0a, 0x49, 0x5d, 0x8a, 0xfe, 0x77}} ,
|
||||
{{0x46, 0x02, 0xf5, 0xa5, 0xaf, 0xc5, 0x75, 0x6d, 0xba, 0x45, 0x35, 0x0a, 0xfe, 0xc9, 0xac, 0x22, 0x91, 0x8d, 0x21, 0x95, 0x33, 0x03, 0xc0, 0x8a, 0x16, 0xf3, 0x39, 0xe0, 0x01, 0x0f, 0x53, 0x3c}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x34, 0x75, 0x37, 0x1f, 0x34, 0x4e, 0xa9, 0x1d, 0x68, 0x67, 0xf8, 0x49, 0x98, 0x96, 0xfc, 0x4c, 0x65, 0x97, 0xf7, 0x02, 0x4a, 0x52, 0x6c, 0x01, 0xbd, 0x48, 0xbb, 0x1b, 0xed, 0xa4, 0xe2, 0x53}} ,
|
||||
{{0x59, 0xd5, 0x9b, 0x5a, 0xa2, 0x90, 0xd3, 0xb8, 0x37, 0x4c, 0x55, 0x82, 0x28, 0x08, 0x0f, 0x7f, 0xaa, 0x81, 0x65, 0xe0, 0x0c, 0x52, 0xc9, 0xa3, 0x32, 0x27, 0x64, 0xda, 0xfd, 0x34, 0x23, 0x5a}}},
|
||||
{{{0xb5, 0xb0, 0x0c, 0x4d, 0xb3, 0x7b, 0x23, 0xc8, 0x1f, 0x8a, 0x39, 0x66, 0xe6, 0xba, 0x4c, 0x10, 0x37, 0xca, 0x9c, 0x7c, 0x05, 0x9e, 0xff, 0xc0, 0xf8, 0x8e, 0xb1, 0x8f, 0x6f, 0x67, 0x18, 0x26}} ,
|
||||
{{0x4b, 0x41, 0x13, 0x54, 0x23, 0x1a, 0xa4, 0x4e, 0xa9, 0x8b, 0x1e, 0x4b, 0xfc, 0x15, 0x24, 0xbb, 0x7e, 0xcb, 0xb6, 0x1e, 0x1b, 0xf5, 0xf2, 0xc8, 0x56, 0xec, 0x32, 0xa2, 0x60, 0x5b, 0xa0, 0x2a}}},
|
||||
{{{0xa4, 0x29, 0x47, 0x86, 0x2e, 0x92, 0x4f, 0x11, 0x4f, 0xf3, 0xb2, 0x5c, 0xd5, 0x3e, 0xa6, 0xb9, 0xc8, 0xe2, 0x33, 0x11, 0x1f, 0x01, 0x8f, 0xb0, 0x9b, 0xc7, 0xa5, 0xff, 0x83, 0x0f, 0x1e, 0x28}} ,
|
||||
{{0x1d, 0x29, 0x7a, 0xa1, 0xec, 0x8e, 0xb5, 0xad, 0xea, 0x02, 0x68, 0x60, 0x74, 0x29, 0x1c, 0xa5, 0xcf, 0xc8, 0x3b, 0x7d, 0x8b, 0x2b, 0x7c, 0xad, 0xa4, 0x40, 0x17, 0x51, 0x59, 0x7c, 0x2e, 0x5d}}},
|
||||
{{{0x0a, 0x6c, 0x4f, 0xbc, 0x3e, 0x32, 0xe7, 0x4a, 0x1a, 0x13, 0xc1, 0x49, 0x38, 0xbf, 0xf7, 0xc2, 0xd3, 0x8f, 0x6b, 0xad, 0x52, 0xf7, 0xcf, 0xbc, 0x27, 0xcb, 0x40, 0x67, 0x76, 0xcd, 0x6d, 0x56}} ,
|
||||
{{0xe5, 0xb0, 0x27, 0xad, 0xbe, 0x9b, 0xf2, 0xb5, 0x63, 0xde, 0x3a, 0x23, 0x95, 0xb7, 0x0a, 0x7e, 0xf3, 0x9e, 0x45, 0x6f, 0x19, 0x39, 0x75, 0x8f, 0x39, 0x3d, 0x0f, 0xc0, 0x9f, 0xf1, 0xe9, 0x51}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x88, 0xaa, 0x14, 0x24, 0x86, 0x94, 0x11, 0x12, 0x3e, 0x1a, 0xb5, 0xcc, 0xbb, 0xe0, 0x9c, 0xd5, 0x9c, 0x6d, 0xba, 0x58, 0x72, 0x8d, 0xfb, 0x22, 0x7b, 0x9f, 0x7c, 0x94, 0x30, 0xb3, 0x51, 0x21}} ,
|
||||
{{0xf6, 0x74, 0x3d, 0xf2, 0xaf, 0xd0, 0x1e, 0x03, 0x7c, 0x23, 0x6b, 0xc9, 0xfc, 0x25, 0x70, 0x90, 0xdc, 0x9a, 0xa4, 0xfb, 0x49, 0xfc, 0x3d, 0x0a, 0x35, 0x38, 0x6f, 0xe4, 0x7e, 0x50, 0x01, 0x2a}}},
|
||||
{{{0xd6, 0xe3, 0x96, 0x61, 0x3a, 0xfd, 0xef, 0x9b, 0x1f, 0x90, 0xa4, 0x24, 0x14, 0x5b, 0xc8, 0xde, 0x50, 0xb1, 0x1d, 0xaf, 0xe8, 0x55, 0x8a, 0x87, 0x0d, 0xfe, 0xaa, 0x3b, 0x82, 0x2c, 0x8d, 0x7b}} ,
|
||||
{{0x85, 0x0c, 0xaf, 0xf8, 0x83, 0x44, 0x49, 0xd9, 0x45, 0xcf, 0xf7, 0x48, 0xd9, 0x53, 0xb4, 0xf1, 0x65, 0xa0, 0xe1, 0xc3, 0xb3, 0x15, 0xed, 0x89, 0x9b, 0x4f, 0x62, 0xb3, 0x57, 0xa5, 0x45, 0x1c}}},
|
||||
{{{0x8f, 0x12, 0xea, 0xaf, 0xd1, 0x1f, 0x79, 0x10, 0x0b, 0xf6, 0xa3, 0x7b, 0xea, 0xac, 0x8b, 0x57, 0x32, 0x62, 0xe7, 0x06, 0x12, 0x51, 0xa0, 0x3b, 0x43, 0x5e, 0xa4, 0x20, 0x78, 0x31, 0xce, 0x0d}} ,
|
||||
{{0x84, 0x7c, 0xc2, 0xa6, 0x91, 0x23, 0xce, 0xbd, 0xdc, 0xf9, 0xce, 0xd5, 0x75, 0x30, 0x22, 0xe6, 0xf9, 0x43, 0x62, 0x0d, 0xf7, 0x75, 0x9d, 0x7f, 0x8c, 0xff, 0x7d, 0xe4, 0x72, 0xac, 0x9f, 0x1c}}},
|
||||
{{{0x88, 0xc1, 0x99, 0xd0, 0x3c, 0x1c, 0x5d, 0xb4, 0xef, 0x13, 0x0f, 0x90, 0xb9, 0x36, 0x2f, 0x95, 0x95, 0xc6, 0xdc, 0xde, 0x0a, 0x51, 0xe2, 0x8d, 0xf3, 0xbc, 0x51, 0xec, 0xdf, 0xb1, 0xa2, 0x5f}} ,
|
||||
{{0x2e, 0x68, 0xa1, 0x23, 0x7d, 0x9b, 0x40, 0x69, 0x85, 0x7b, 0x42, 0xbf, 0x90, 0x4b, 0xd6, 0x40, 0x2f, 0xd7, 0x52, 0x52, 0xb2, 0x21, 0xde, 0x64, 0xbd, 0x88, 0xc3, 0x6d, 0xa5, 0xfa, 0x81, 0x3f}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xfb, 0xfd, 0x47, 0x7b, 0x8a, 0x66, 0x9e, 0x79, 0x2e, 0x64, 0x82, 0xef, 0xf7, 0x21, 0xec, 0xf6, 0xd8, 0x86, 0x09, 0x31, 0x7c, 0xdd, 0x03, 0x6a, 0x58, 0xa0, 0x77, 0xb7, 0x9b, 0x8c, 0x87, 0x1f}} ,
|
||||
{{0x55, 0x47, 0xe4, 0xa8, 0x3d, 0x55, 0x21, 0x34, 0xab, 0x1d, 0xae, 0xe0, 0xf4, 0xea, 0xdb, 0xc5, 0xb9, 0x58, 0xbf, 0xc4, 0x2a, 0x89, 0x31, 0x1a, 0xf4, 0x2d, 0xe1, 0xca, 0x37, 0x99, 0x47, 0x59}}},
|
||||
{{{0xc7, 0xca, 0x63, 0xc1, 0x49, 0xa9, 0x35, 0x45, 0x55, 0x7e, 0xda, 0x64, 0x32, 0x07, 0x50, 0xf7, 0x32, 0xac, 0xde, 0x75, 0x58, 0x9b, 0x11, 0xb2, 0x3a, 0x1f, 0xf5, 0xf7, 0x79, 0x04, 0xe6, 0x08}} ,
|
||||
{{0x46, 0xfa, 0x22, 0x4b, 0xfa, 0xe1, 0xfe, 0x96, 0xfc, 0x67, 0xba, 0x67, 0x97, 0xc4, 0xe7, 0x1b, 0x86, 0x90, 0x5f, 0xee, 0xf4, 0x5b, 0x11, 0xb2, 0xcd, 0xad, 0xee, 0xc2, 0x48, 0x6c, 0x2b, 0x1b}}},
|
||||
{{{0xe3, 0x39, 0x62, 0xb4, 0x4f, 0x31, 0x04, 0xc9, 0xda, 0xd5, 0x73, 0x51, 0x57, 0xc5, 0xb8, 0xf3, 0xa3, 0x43, 0x70, 0xe4, 0x61, 0x81, 0x84, 0xe2, 0xbb, 0xbf, 0x4f, 0x9e, 0xa4, 0x5e, 0x74, 0x06}} ,
|
||||
{{0x29, 0xac, 0xff, 0x27, 0xe0, 0x59, 0xbe, 0x39, 0x9c, 0x0d, 0x83, 0xd7, 0x10, 0x0b, 0x15, 0xb7, 0xe1, 0xc2, 0x2c, 0x30, 0x73, 0x80, 0x3a, 0x7d, 0x5d, 0xab, 0x58, 0x6b, 0xc1, 0xf0, 0xf4, 0x22}}},
|
||||
{{{0xfe, 0x7f, 0xfb, 0x35, 0x7d, 0xc6, 0x01, 0x23, 0x28, 0xc4, 0x02, 0xac, 0x1f, 0x42, 0xb4, 0x9d, 0xfc, 0x00, 0x94, 0xa5, 0xee, 0xca, 0xda, 0x97, 0x09, 0x41, 0x77, 0x87, 0x5d, 0x7b, 0x87, 0x78}} ,
|
||||
{{0xf5, 0xfb, 0x90, 0x2d, 0x81, 0x19, 0x9e, 0x2f, 0x6d, 0x85, 0x88, 0x8c, 0x40, 0x5c, 0x77, 0x41, 0x4d, 0x01, 0x19, 0x76, 0x60, 0xe8, 0x4c, 0x48, 0xe4, 0x33, 0x83, 0x32, 0x6c, 0xb4, 0x41, 0x03}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xff, 0x10, 0xc2, 0x09, 0x4f, 0x6e, 0xf4, 0xd2, 0xdf, 0x7e, 0xca, 0x7b, 0x1c, 0x1d, 0xba, 0xa3, 0xb6, 0xda, 0x67, 0x33, 0xd4, 0x87, 0x36, 0x4b, 0x11, 0x20, 0x05, 0xa6, 0x29, 0xc1, 0x87, 0x17}} ,
|
||||
{{0xf6, 0x96, 0xca, 0x2f, 0xda, 0x38, 0xa7, 0x1b, 0xfc, 0xca, 0x7d, 0xfe, 0x08, 0x89, 0xe2, 0x47, 0x2b, 0x6a, 0x5d, 0x4b, 0xfa, 0xa1, 0xb4, 0xde, 0xb6, 0xc2, 0x31, 0x51, 0xf5, 0xe0, 0xa4, 0x0b}}},
|
||||
{{{0x5c, 0xe5, 0xc6, 0x04, 0x8e, 0x2b, 0x57, 0xbe, 0x38, 0x85, 0x23, 0xcb, 0xb7, 0xbe, 0x4f, 0xa9, 0xd3, 0x6e, 0x12, 0xaa, 0xd5, 0xb2, 0x2e, 0x93, 0x29, 0x9a, 0x4a, 0x88, 0x18, 0x43, 0xf5, 0x01}} ,
|
||||
{{0x50, 0xfc, 0xdb, 0xa2, 0x59, 0x21, 0x8d, 0xbd, 0x7e, 0x33, 0xae, 0x2f, 0x87, 0x1a, 0xd0, 0x97, 0xc7, 0x0d, 0x4d, 0x63, 0x01, 0xef, 0x05, 0x84, 0xec, 0x40, 0xdd, 0xa8, 0x0a, 0x4f, 0x70, 0x0b}}},
|
||||
{{{0x41, 0x69, 0x01, 0x67, 0x5c, 0xd3, 0x8a, 0xc5, 0xcf, 0x3f, 0xd1, 0x57, 0xd1, 0x67, 0x3e, 0x01, 0x39, 0xb5, 0xcb, 0x81, 0x56, 0x96, 0x26, 0xb6, 0xc2, 0xe7, 0x5c, 0xfb, 0x63, 0x97, 0x58, 0x06}} ,
|
||||
{{0x0c, 0x0e, 0xf3, 0xba, 0xf0, 0xe5, 0xba, 0xb2, 0x57, 0x77, 0xc6, 0x20, 0x9b, 0x89, 0x24, 0xbe, 0xf2, 0x9c, 0x8a, 0xba, 0x69, 0xc1, 0xf1, 0xb0, 0x4f, 0x2a, 0x05, 0x9a, 0xee, 0x10, 0x7e, 0x36}}},
|
||||
{{{0x3f, 0x26, 0xe9, 0x40, 0xe9, 0x03, 0xad, 0x06, 0x69, 0x91, 0xe0, 0xd1, 0x89, 0x60, 0x84, 0x79, 0xde, 0x27, 0x6d, 0xe6, 0x76, 0xbd, 0xea, 0xe6, 0xae, 0x48, 0xc3, 0x67, 0xc0, 0x57, 0xcd, 0x2f}} ,
|
||||
{{0x7f, 0xc1, 0xdc, 0xb9, 0xc7, 0xbc, 0x86, 0x3d, 0x55, 0x4b, 0x28, 0x7a, 0xfb, 0x4d, 0xc7, 0xf8, 0xbc, 0x67, 0x2a, 0x60, 0x4d, 0x8f, 0x07, 0x0b, 0x1a, 0x17, 0xbf, 0xfa, 0xac, 0xa7, 0x3d, 0x1a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x91, 0x3f, 0xed, 0x5e, 0x18, 0x78, 0x3f, 0x23, 0x2c, 0x0d, 0x8c, 0x44, 0x00, 0xe8, 0xfb, 0xe9, 0x8e, 0xd6, 0xd1, 0x36, 0x58, 0x57, 0x9e, 0xae, 0x4b, 0x5c, 0x0b, 0x07, 0xbc, 0x6b, 0x55, 0x2b}} ,
|
||||
{{0x6f, 0x4d, 0x17, 0xd7, 0xe1, 0x84, 0xd9, 0x78, 0xb1, 0x90, 0xfd, 0x2e, 0xb3, 0xb5, 0x19, 0x3f, 0x1b, 0xfa, 0xc0, 0x68, 0xb3, 0xdd, 0x00, 0x2e, 0x89, 0xbd, 0x7e, 0x80, 0x32, 0x13, 0xa0, 0x7b}}},
|
||||
{{{0x1a, 0x6f, 0x40, 0xaf, 0x44, 0x44, 0xb0, 0x43, 0x8f, 0x0d, 0xd0, 0x1e, 0xc4, 0x0b, 0x19, 0x5d, 0x8e, 0xfe, 0xc1, 0xf3, 0xc5, 0x5c, 0x91, 0xf8, 0x04, 0x4e, 0xbe, 0x90, 0xb4, 0x47, 0x5c, 0x3f}} ,
|
||||
{{0xb0, 0x3b, 0x2c, 0xf3, 0xfe, 0x32, 0x71, 0x07, 0x3f, 0xaa, 0xba, 0x45, 0x60, 0xa8, 0x8d, 0xea, 0x54, 0xcb, 0x39, 0x10, 0xb4, 0xf2, 0x8b, 0xd2, 0x14, 0x82, 0x42, 0x07, 0x8e, 0xe9, 0x7c, 0x53}}},
|
||||
{{{0xb0, 0xae, 0xc1, 0x8d, 0xc9, 0x8f, 0xb9, 0x7a, 0x77, 0xef, 0xba, 0x79, 0xa0, 0x3c, 0xa8, 0xf5, 0x6a, 0xe2, 0x3f, 0x5d, 0x00, 0xe3, 0x4b, 0x45, 0x24, 0x7b, 0x43, 0x78, 0x55, 0x1d, 0x2b, 0x1e}} ,
|
||||
{{0x01, 0xb8, 0xd6, 0x16, 0x67, 0xa0, 0x15, 0xb9, 0xe1, 0x58, 0xa4, 0xa7, 0x31, 0x37, 0x77, 0x2f, 0x8b, 0x12, 0x9f, 0xf4, 0x3f, 0xc7, 0x36, 0x66, 0xd2, 0xa8, 0x56, 0xf7, 0x7f, 0x74, 0xc6, 0x41}}},
|
||||
{{{0x5d, 0xf8, 0xb4, 0xa8, 0x30, 0xdd, 0xcc, 0x38, 0xa5, 0xd3, 0xca, 0xd8, 0xd1, 0xf8, 0xb2, 0x31, 0x91, 0xd4, 0x72, 0x05, 0x57, 0x4a, 0x3b, 0x82, 0x4a, 0xc6, 0x68, 0x20, 0xe2, 0x18, 0x41, 0x61}} ,
|
||||
{{0x19, 0xd4, 0x8d, 0x47, 0x29, 0x12, 0x65, 0xb0, 0x11, 0x78, 0x47, 0xb5, 0xcb, 0xa3, 0xa5, 0xfa, 0x05, 0x85, 0x54, 0xa9, 0x33, 0x97, 0x8d, 0x2b, 0xc2, 0xfe, 0x99, 0x35, 0x28, 0xe5, 0xeb, 0x63}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xb1, 0x3f, 0x3f, 0xef, 0xd8, 0xf4, 0xfc, 0xb3, 0xa0, 0x60, 0x50, 0x06, 0x2b, 0x29, 0x52, 0x70, 0x15, 0x0b, 0x24, 0x24, 0xf8, 0x5f, 0x79, 0x18, 0xcc, 0xff, 0x89, 0x99, 0x84, 0xa1, 0xae, 0x13}} ,
|
||||
{{0x44, 0x1f, 0xb8, 0xc2, 0x01, 0xc1, 0x30, 0x19, 0x55, 0x05, 0x60, 0x10, 0xa4, 0x6c, 0x2d, 0x67, 0x70, 0xe5, 0x25, 0x1b, 0xf2, 0xbf, 0xdd, 0xfb, 0x70, 0x2b, 0xa1, 0x8c, 0x9c, 0x94, 0x84, 0x08}}},
|
||||
{{{0xe7, 0xc4, 0x43, 0x4d, 0xc9, 0x2b, 0x69, 0x5d, 0x1d, 0x3c, 0xaf, 0xbb, 0x43, 0x38, 0x4e, 0x98, 0x3d, 0xed, 0x0d, 0x21, 0x03, 0xfd, 0xf0, 0x99, 0x47, 0x04, 0xb0, 0x98, 0x69, 0x55, 0x72, 0x0f}} ,
|
||||
{{0x5e, 0xdf, 0x15, 0x53, 0x3b, 0x86, 0x80, 0xb0, 0xf1, 0x70, 0x68, 0x8f, 0x66, 0x7c, 0x0e, 0x49, 0x1a, 0xd8, 0x6b, 0xfe, 0x4e, 0xef, 0xca, 0x47, 0xd4, 0x03, 0xc1, 0x37, 0x50, 0x9c, 0xc1, 0x16}}},
|
||||
{{{0xcd, 0x24, 0xc6, 0x3e, 0x0c, 0x82, 0x9b, 0x91, 0x2b, 0x61, 0x4a, 0xb2, 0x0f, 0x88, 0x55, 0x5f, 0x5a, 0x57, 0xff, 0xe5, 0x74, 0x0b, 0x13, 0x43, 0x00, 0xd8, 0x6b, 0xcf, 0xd2, 0x15, 0x03, 0x2c}} ,
|
||||
{{0xdc, 0xff, 0x15, 0x61, 0x2f, 0x4a, 0x2f, 0x62, 0xf2, 0x04, 0x2f, 0xb5, 0x0c, 0xb7, 0x1e, 0x3f, 0x74, 0x1a, 0x0f, 0xd7, 0xea, 0xcd, 0xd9, 0x7d, 0xf6, 0x12, 0x0e, 0x2f, 0xdb, 0x5a, 0x3b, 0x16}}},
|
||||
{{{0x1b, 0x37, 0x47, 0xe3, 0xf5, 0x9e, 0xea, 0x2c, 0x2a, 0xe7, 0x82, 0x36, 0xf4, 0x1f, 0x81, 0x47, 0x92, 0x4b, 0x69, 0x0e, 0x11, 0x8c, 0x5d, 0x53, 0x5b, 0x81, 0x27, 0x08, 0xbc, 0xa0, 0xae, 0x25}} ,
|
||||
{{0x69, 0x32, 0xa1, 0x05, 0x11, 0x42, 0x00, 0xd2, 0x59, 0xac, 0x4d, 0x62, 0x8b, 0x13, 0xe2, 0x50, 0x5d, 0xa0, 0x9d, 0x9b, 0xfd, 0xbb, 0x12, 0x41, 0x75, 0x41, 0x9e, 0xcc, 0xdc, 0xc7, 0xdc, 0x5d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xd9, 0xe3, 0x38, 0x06, 0x46, 0x70, 0x82, 0x5e, 0x28, 0x49, 0x79, 0xff, 0x25, 0xd2, 0x4e, 0x29, 0x8d, 0x06, 0xb0, 0x23, 0xae, 0x9b, 0x66, 0xe4, 0x7d, 0xc0, 0x70, 0x91, 0xa3, 0xfc, 0xec, 0x4e}} ,
|
||||
{{0x62, 0x12, 0x37, 0x6a, 0x30, 0xf6, 0x1e, 0xfb, 0x14, 0x5c, 0x0d, 0x0e, 0xb7, 0x81, 0x6a, 0xe7, 0x08, 0x05, 0xac, 0xaa, 0x38, 0x46, 0xe2, 0x73, 0xea, 0x4b, 0x07, 0x81, 0x43, 0x7c, 0x9e, 0x5e}}},
|
||||
{{{0xfc, 0xf9, 0x21, 0x4f, 0x2e, 0x76, 0x9b, 0x1f, 0x28, 0x60, 0x77, 0x43, 0x32, 0x9d, 0xbe, 0x17, 0x30, 0x2a, 0xc6, 0x18, 0x92, 0x66, 0x62, 0x30, 0x98, 0x40, 0x11, 0xa6, 0x7f, 0x18, 0x84, 0x28}} ,
|
||||
{{0x3f, 0xab, 0xd3, 0xf4, 0x8a, 0x76, 0xa1, 0x3c, 0xca, 0x2d, 0x49, 0xc3, 0xea, 0x08, 0x0b, 0x85, 0x17, 0x2a, 0xc3, 0x6c, 0x08, 0xfd, 0x57, 0x9f, 0x3d, 0x5f, 0xdf, 0x67, 0x68, 0x42, 0x00, 0x32}}},
|
||||
{{{0x51, 0x60, 0x1b, 0x06, 0x4f, 0x8a, 0x21, 0xba, 0x38, 0xa8, 0xba, 0xd6, 0x40, 0xf6, 0xe9, 0x9b, 0x76, 0x4d, 0x56, 0x21, 0x5b, 0x0a, 0x9b, 0x2e, 0x4f, 0x3d, 0x81, 0x32, 0x08, 0x9f, 0x97, 0x5b}} ,
|
||||
{{0xe5, 0x44, 0xec, 0x06, 0x9d, 0x90, 0x79, 0x9f, 0xd3, 0xe0, 0x79, 0xaf, 0x8f, 0x10, 0xfd, 0xdd, 0x04, 0xae, 0x27, 0x97, 0x46, 0x33, 0x79, 0xea, 0xb8, 0x4e, 0xca, 0x5a, 0x59, 0x57, 0xe1, 0x0e}}},
|
||||
{{{0x1a, 0xda, 0xf3, 0xa5, 0x41, 0x43, 0x28, 0xfc, 0x7e, 0xe7, 0x71, 0xea, 0xc6, 0x3b, 0x59, 0xcc, 0x2e, 0xd3, 0x40, 0xec, 0xb3, 0x13, 0x6f, 0x44, 0xcd, 0x13, 0xb2, 0x37, 0xf2, 0x6e, 0xd9, 0x1c}} ,
|
||||
{{0xe3, 0xdb, 0x60, 0xcd, 0x5c, 0x4a, 0x18, 0x0f, 0xef, 0x73, 0x36, 0x71, 0x8c, 0xf6, 0x11, 0xb4, 0xd8, 0xce, 0x17, 0x5e, 0x4f, 0x26, 0x77, 0x97, 0x5f, 0xcb, 0xef, 0x91, 0xeb, 0x6a, 0x62, 0x7a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x18, 0x4a, 0xa2, 0x97, 0x08, 0x81, 0x2d, 0x83, 0xc4, 0xcc, 0xf0, 0x83, 0x7e, 0xec, 0x0d, 0x95, 0x4c, 0x5b, 0xfb, 0xfa, 0x98, 0x80, 0x4a, 0x66, 0x56, 0x0c, 0x51, 0xb3, 0xf2, 0x04, 0x5d, 0x27}} ,
|
||||
{{0x3b, 0xb9, 0xb8, 0x06, 0x5a, 0x2e, 0xfe, 0xc3, 0x82, 0x37, 0x9c, 0xa3, 0x11, 0x1f, 0x9c, 0xa6, 0xda, 0x63, 0x48, 0x9b, 0xad, 0xde, 0x2d, 0xa6, 0xbc, 0x6e, 0x32, 0xda, 0x27, 0x65, 0xdd, 0x57}}},
|
||||
{{{0x84, 0x4f, 0x37, 0x31, 0x7d, 0x2e, 0xbc, 0xad, 0x87, 0x07, 0x2a, 0x6b, 0x37, 0xfc, 0x5f, 0xeb, 0x4e, 0x75, 0x35, 0xa6, 0xde, 0xab, 0x0a, 0x19, 0x3a, 0xb7, 0xb1, 0xef, 0x92, 0x6a, 0x3b, 0x3c}} ,
|
||||
{{0x3b, 0xb2, 0x94, 0x6d, 0x39, 0x60, 0xac, 0xee, 0xe7, 0x81, 0x1a, 0x3b, 0x76, 0x87, 0x5c, 0x05, 0x94, 0x2a, 0x45, 0xb9, 0x80, 0xe9, 0x22, 0xb1, 0x07, 0xcb, 0x40, 0x9e, 0x70, 0x49, 0x6d, 0x12}}},
|
||||
{{{0xfd, 0x18, 0x78, 0x84, 0xa8, 0x4c, 0x7d, 0x6e, 0x59, 0xa6, 0xe5, 0x74, 0xf1, 0x19, 0xa6, 0x84, 0x2e, 0x51, 0xc1, 0x29, 0x13, 0xf2, 0x14, 0x6b, 0x5d, 0x53, 0x51, 0xf7, 0xef, 0xbf, 0x01, 0x22}} ,
|
||||
{{0xa4, 0x4b, 0x62, 0x4c, 0xe6, 0xfd, 0x72, 0x07, 0xf2, 0x81, 0xfc, 0xf2, 0xbd, 0x12, 0x7c, 0x68, 0x76, 0x2a, 0xba, 0xf5, 0x65, 0xb1, 0x1f, 0x17, 0x0a, 0x38, 0xb0, 0xbf, 0xc0, 0xf8, 0xf4, 0x2a}}},
|
||||
{{{0x55, 0x60, 0x55, 0x5b, 0xe4, 0x1d, 0x71, 0x4c, 0x9d, 0x5b, 0x9f, 0x70, 0xa6, 0x85, 0x9a, 0x2c, 0xa0, 0xe2, 0x32, 0x48, 0xce, 0x9e, 0x2a, 0xa5, 0x07, 0x3b, 0xc7, 0x6c, 0x86, 0x77, 0xde, 0x3c}} ,
|
||||
{{0xf7, 0x18, 0x7a, 0x96, 0x7e, 0x43, 0x57, 0xa9, 0x55, 0xfc, 0x4e, 0xb6, 0x72, 0x00, 0xf2, 0xe4, 0xd7, 0x52, 0xd3, 0xd3, 0xb6, 0x85, 0xf6, 0x71, 0xc7, 0x44, 0x3f, 0x7f, 0xd7, 0xb3, 0xf2, 0x79}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x46, 0xca, 0xa7, 0x55, 0x7b, 0x79, 0xf3, 0xca, 0x5a, 0x65, 0xf6, 0xed, 0x50, 0x14, 0x7b, 0xe4, 0xc4, 0x2a, 0x65, 0x9e, 0xe2, 0xf9, 0xca, 0xa7, 0x22, 0x26, 0x53, 0xcb, 0x21, 0x5b, 0xa7, 0x31}} ,
|
||||
{{0x90, 0xd7, 0xc5, 0x26, 0x08, 0xbd, 0xb0, 0x53, 0x63, 0x58, 0xc3, 0x31, 0x5e, 0x75, 0x46, 0x15, 0x91, 0xa6, 0xf8, 0x2f, 0x1a, 0x08, 0x65, 0x88, 0x2f, 0x98, 0x04, 0xf1, 0x7c, 0x6e, 0x00, 0x77}}},
|
||||
{{{0x81, 0x21, 0x61, 0x09, 0xf6, 0x4e, 0xf1, 0x92, 0xee, 0x63, 0x61, 0x73, 0x87, 0xc7, 0x54, 0x0e, 0x42, 0x4b, 0xc9, 0x47, 0xd1, 0xb8, 0x7e, 0x91, 0x75, 0x37, 0x99, 0x28, 0xb8, 0xdd, 0x7f, 0x50}} ,
|
||||
{{0x89, 0x8f, 0xc0, 0xbe, 0x5d, 0xd6, 0x9f, 0xa0, 0xf0, 0x9d, 0x81, 0xce, 0x3a, 0x7b, 0x98, 0x58, 0xbb, 0xd7, 0x78, 0xc8, 0x3f, 0x13, 0xf1, 0x74, 0x19, 0xdf, 0xf8, 0x98, 0x89, 0x5d, 0xfa, 0x5f}}},
|
||||
{{{0x9e, 0x35, 0x85, 0x94, 0x47, 0x1f, 0x90, 0x15, 0x26, 0xd0, 0x84, 0xed, 0x8a, 0x80, 0xf7, 0x63, 0x42, 0x86, 0x27, 0xd7, 0xf4, 0x75, 0x58, 0xdc, 0x9c, 0xc0, 0x22, 0x7e, 0x20, 0x35, 0xfd, 0x1f}} ,
|
||||
{{0x68, 0x0e, 0x6f, 0x97, 0xba, 0x70, 0xbb, 0xa3, 0x0e, 0xe5, 0x0b, 0x12, 0xf4, 0xa2, 0xdc, 0x47, 0xf8, 0xe6, 0xd0, 0x23, 0x6c, 0x33, 0xa8, 0x99, 0x46, 0x6e, 0x0f, 0x44, 0xba, 0x76, 0x48, 0x0f}}},
|
||||
{{{0xa3, 0x2a, 0x61, 0x37, 0xe2, 0x59, 0x12, 0x0e, 0x27, 0xba, 0x64, 0x43, 0xae, 0xc0, 0x42, 0x69, 0x79, 0xa4, 0x1e, 0x29, 0x8b, 0x15, 0xeb, 0xf8, 0xaf, 0xd4, 0xa2, 0x68, 0x33, 0xb5, 0x7a, 0x24}} ,
|
||||
{{0x2c, 0x19, 0x33, 0xdd, 0x1b, 0xab, 0xec, 0x01, 0xb0, 0x23, 0xf8, 0x42, 0x2b, 0x06, 0x88, 0xea, 0x3d, 0x2d, 0x00, 0x2a, 0x78, 0x45, 0x4d, 0x38, 0xed, 0x2e, 0x2e, 0x44, 0x49, 0xed, 0xcb, 0x33}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xa0, 0x68, 0xe8, 0x41, 0x8f, 0x91, 0xf8, 0x11, 0x13, 0x90, 0x2e, 0xa7, 0xab, 0x30, 0xef, 0xad, 0xa0, 0x61, 0x00, 0x88, 0xef, 0xdb, 0xce, 0x5b, 0x5c, 0xbb, 0x62, 0xc8, 0x56, 0xf9, 0x00, 0x73}} ,
|
||||
{{0x3f, 0x60, 0xc1, 0x82, 0x2d, 0xa3, 0x28, 0x58, 0x24, 0x9e, 0x9f, 0xe3, 0x70, 0xcc, 0x09, 0x4e, 0x1a, 0x3f, 0x11, 0x11, 0x15, 0x07, 0x3c, 0xa4, 0x41, 0xe0, 0x65, 0xa3, 0x0a, 0x41, 0x6d, 0x11}}},
|
||||
{{{0x31, 0x40, 0x01, 0x52, 0x56, 0x94, 0x5b, 0x28, 0x8a, 0xaa, 0x52, 0xee, 0xd8, 0x0a, 0x05, 0x8d, 0xcd, 0xb5, 0xaa, 0x2e, 0x38, 0xaa, 0xb7, 0x87, 0xf7, 0x2b, 0xfb, 0x04, 0xcb, 0x84, 0x3d, 0x54}} ,
|
||||
{{0x20, 0xef, 0x59, 0xde, 0xa4, 0x2b, 0x93, 0x6e, 0x2e, 0xec, 0x42, 0x9a, 0xd4, 0x2d, 0xf4, 0x46, 0x58, 0x27, 0x2b, 0x18, 0x8f, 0x83, 0x3d, 0x69, 0x9e, 0xd4, 0x3e, 0xb6, 0xc5, 0xfd, 0x58, 0x03}}},
|
||||
{{{0x33, 0x89, 0xc9, 0x63, 0x62, 0x1c, 0x17, 0xb4, 0x60, 0xc4, 0x26, 0x68, 0x09, 0xc3, 0x2e, 0x37, 0x0f, 0x7b, 0xb4, 0x9c, 0xb6, 0xf9, 0xfb, 0xd4, 0x51, 0x78, 0xc8, 0x63, 0xea, 0x77, 0x47, 0x07}} ,
|
||||
{{0x32, 0xb4, 0x18, 0x47, 0x79, 0xcb, 0xd4, 0x5a, 0x07, 0x14, 0x0f, 0xa0, 0xd5, 0xac, 0xd0, 0x41, 0x40, 0xab, 0x61, 0x23, 0xe5, 0x2a, 0x2a, 0x6f, 0xf7, 0xa8, 0xd4, 0x76, 0xef, 0xe7, 0x45, 0x6c}}},
|
||||
{{{0xa1, 0x5e, 0x60, 0x4f, 0xfb, 0xe1, 0x70, 0x6a, 0x1f, 0x55, 0x4f, 0x09, 0xb4, 0x95, 0x33, 0x36, 0xc6, 0x81, 0x01, 0x18, 0x06, 0x25, 0x27, 0xa4, 0xb4, 0x24, 0xa4, 0x86, 0x03, 0x4c, 0xac, 0x02}} ,
|
||||
{{0x77, 0x38, 0xde, 0xd7, 0x60, 0x48, 0x07, 0xf0, 0x74, 0xa8, 0xff, 0x54, 0xe5, 0x30, 0x43, 0xff, 0x77, 0xfb, 0x21, 0x07, 0xff, 0xb2, 0x07, 0x6b, 0xe4, 0xe5, 0x30, 0xfc, 0x19, 0x6c, 0xa3, 0x01}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x13, 0xc5, 0x2c, 0xac, 0xd3, 0x83, 0x82, 0x7c, 0x29, 0xf7, 0x05, 0xa5, 0x00, 0xb6, 0x1f, 0x86, 0x55, 0xf4, 0xd6, 0x2f, 0x0c, 0x99, 0xd0, 0x65, 0x9b, 0x6b, 0x46, 0x0d, 0x43, 0xf8, 0x16, 0x28}} ,
|
||||
{{0x1e, 0x7f, 0xb4, 0x74, 0x7e, 0xb1, 0x89, 0x4f, 0x18, 0x5a, 0xab, 0x64, 0x06, 0xdf, 0x45, 0x87, 0xe0, 0x6a, 0xc6, 0xf0, 0x0e, 0xc9, 0x24, 0x35, 0x38, 0xea, 0x30, 0x54, 0xb4, 0xc4, 0x52, 0x54}}},
|
||||
{{{0xe9, 0x9f, 0xdc, 0x3f, 0xc1, 0x89, 0x44, 0x74, 0x27, 0xe4, 0xc1, 0x90, 0xff, 0x4a, 0xa7, 0x3c, 0xee, 0xcd, 0xf4, 0x1d, 0x25, 0x94, 0x7f, 0x63, 0x16, 0x48, 0xbc, 0x64, 0xfe, 0x95, 0xc4, 0x0c}} ,
|
||||
{{0x8b, 0x19, 0x75, 0x6e, 0x03, 0x06, 0x5e, 0x6a, 0x6f, 0x1a, 0x8c, 0xe3, 0xd3, 0x28, 0xf2, 0xe0, 0xb9, 0x7a, 0x43, 0x69, 0xe6, 0xd3, 0xc0, 0xfe, 0x7e, 0x97, 0xab, 0x6c, 0x7b, 0x8e, 0x13, 0x42}}},
|
||||
{{{0xd4, 0xca, 0x70, 0x3d, 0xab, 0xfb, 0x5f, 0x5e, 0x00, 0x0c, 0xcc, 0x77, 0x22, 0xf8, 0x78, 0x55, 0xae, 0x62, 0x35, 0xfb, 0x9a, 0xc6, 0x03, 0xe4, 0x0c, 0xee, 0xab, 0xc7, 0xc0, 0x89, 0x87, 0x54}} ,
|
||||
{{0x32, 0xad, 0xae, 0x85, 0x58, 0x43, 0xb8, 0xb1, 0xe6, 0x3e, 0x00, 0x9c, 0x78, 0x88, 0x56, 0xdb, 0x9c, 0xfc, 0x79, 0xf6, 0xf9, 0x41, 0x5f, 0xb7, 0xbc, 0x11, 0xf9, 0x20, 0x36, 0x1c, 0x53, 0x2b}}},
|
||||
{{{0x5a, 0x20, 0x5b, 0xa1, 0xa5, 0x44, 0x91, 0x24, 0x02, 0x63, 0x12, 0x64, 0xb8, 0x55, 0xf6, 0xde, 0x2c, 0xdb, 0x47, 0xb8, 0xc6, 0x0a, 0xc3, 0x00, 0x78, 0x93, 0xd8, 0xf5, 0xf5, 0x18, 0x28, 0x0a}} ,
|
||||
{{0xd6, 0x1b, 0x9a, 0x6c, 0xe5, 0x46, 0xea, 0x70, 0x96, 0x8d, 0x4e, 0x2a, 0x52, 0x21, 0x26, 0x4b, 0xb1, 0xbb, 0x0f, 0x7c, 0xa9, 0x9b, 0x04, 0xbb, 0x51, 0x08, 0xf1, 0x9a, 0xa4, 0x76, 0x7c, 0x18}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xfa, 0x94, 0xf7, 0x40, 0xd0, 0xd7, 0xeb, 0xa9, 0x82, 0x36, 0xd5, 0x15, 0xb9, 0x33, 0x7a, 0xbf, 0x8a, 0xf2, 0x63, 0xaa, 0x37, 0xf5, 0x59, 0xac, 0xbd, 0xbb, 0x32, 0x36, 0xbe, 0x73, 0x99, 0x38}} ,
|
||||
{{0x2c, 0xb3, 0xda, 0x7a, 0xd8, 0x3d, 0x99, 0xca, 0xd2, 0xf4, 0xda, 0x99, 0x8e, 0x4f, 0x98, 0xb7, 0xf4, 0xae, 0x3e, 0x9f, 0x8e, 0x35, 0x60, 0xa4, 0x33, 0x75, 0xa4, 0x04, 0x93, 0xb1, 0x6b, 0x4d}}},
|
||||
{{{0x97, 0x9d, 0xa8, 0xcd, 0x97, 0x7b, 0x9d, 0xb9, 0xe7, 0xa5, 0xef, 0xfd, 0xa8, 0x42, 0x6b, 0xc3, 0x62, 0x64, 0x7d, 0xa5, 0x1b, 0xc9, 0x9e, 0xd2, 0x45, 0xb9, 0xee, 0x03, 0xb0, 0xbf, 0xc0, 0x68}} ,
|
||||
{{0xed, 0xb7, 0x84, 0x2c, 0xf6, 0xd3, 0xa1, 0x6b, 0x24, 0x6d, 0x87, 0x56, 0x97, 0x59, 0x79, 0x62, 0x9f, 0xac, 0xed, 0xf3, 0xc9, 0x89, 0x21, 0x2e, 0x04, 0xb3, 0xcc, 0x2f, 0xbe, 0xd6, 0x0a, 0x4b}}},
|
||||
{{{0x39, 0x61, 0x05, 0xed, 0x25, 0x89, 0x8b, 0x5d, 0x1b, 0xcb, 0x0c, 0x55, 0xf4, 0x6a, 0x00, 0x8a, 0x46, 0xe8, 0x1e, 0xc6, 0x83, 0xc8, 0x5a, 0x76, 0xdb, 0xcc, 0x19, 0x7a, 0xcc, 0x67, 0x46, 0x0b}} ,
|
||||
{{0x53, 0xcf, 0xc2, 0xa1, 0xad, 0x6a, 0xf3, 0xcd, 0x8f, 0xc9, 0xde, 0x1c, 0xf8, 0x6c, 0x8f, 0xf8, 0x76, 0x42, 0xe7, 0xfe, 0xb2, 0x72, 0x21, 0x0a, 0x66, 0x74, 0x8f, 0xb7, 0xeb, 0xe4, 0x6f, 0x01}}},
|
||||
{{{0x22, 0x8c, 0x6b, 0xbe, 0xfc, 0x4d, 0x70, 0x62, 0x6e, 0x52, 0x77, 0x99, 0x88, 0x7e, 0x7b, 0x57, 0x7a, 0x0d, 0xfe, 0xdc, 0x72, 0x92, 0xf1, 0x68, 0x1d, 0x97, 0xd7, 0x7c, 0x8d, 0x53, 0x10, 0x37}} ,
|
||||
{{0x53, 0x88, 0x77, 0x02, 0xca, 0x27, 0xa8, 0xe5, 0x45, 0xe2, 0xa8, 0x48, 0x2a, 0xab, 0x18, 0xca, 0xea, 0x2d, 0x2a, 0x54, 0x17, 0x37, 0x32, 0x09, 0xdc, 0xe0, 0x4a, 0xb7, 0x7d, 0x82, 0x10, 0x7d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x8a, 0x64, 0x1e, 0x14, 0x0a, 0x57, 0xd4, 0xda, 0x5c, 0x96, 0x9b, 0x01, 0x4c, 0x67, 0xbf, 0x8b, 0x30, 0xfe, 0x08, 0xdb, 0x0d, 0xd5, 0xa8, 0xd7, 0x09, 0x11, 0x85, 0xa2, 0xd3, 0x45, 0xfb, 0x7e}} ,
|
||||
{{0xda, 0x8c, 0xc2, 0xd0, 0xac, 0x18, 0xe8, 0x52, 0x36, 0xd4, 0x21, 0xa3, 0xdd, 0x57, 0x22, 0x79, 0xb7, 0xf8, 0x71, 0x9d, 0xc6, 0x91, 0x70, 0x86, 0x56, 0xbf, 0xa1, 0x11, 0x8b, 0x19, 0xe1, 0x0f}}},
|
||||
{{{0x18, 0x32, 0x98, 0x2c, 0x8f, 0x91, 0xae, 0x12, 0xf0, 0x8c, 0xea, 0xf3, 0x3c, 0xb9, 0x5d, 0xe4, 0x69, 0xed, 0xb2, 0x47, 0x18, 0xbd, 0xce, 0x16, 0x52, 0x5c, 0x23, 0xe2, 0xa5, 0x25, 0x52, 0x5d}} ,
|
||||
{{0xb9, 0xb1, 0xe7, 0x5d, 0x4e, 0xbc, 0xee, 0xbb, 0x40, 0x81, 0x77, 0x82, 0x19, 0xab, 0xb5, 0xc6, 0xee, 0xab, 0x5b, 0x6b, 0x63, 0x92, 0x8a, 0x34, 0x8d, 0xcd, 0xee, 0x4f, 0x49, 0xe5, 0xc9, 0x7e}}},
|
||||
{{{0x21, 0xac, 0x8b, 0x22, 0xcd, 0xc3, 0x9a, 0xe9, 0x5e, 0x78, 0xbd, 0xde, 0xba, 0xad, 0xab, 0xbf, 0x75, 0x41, 0x09, 0xc5, 0x58, 0xa4, 0x7d, 0x92, 0xb0, 0x7f, 0xf2, 0xa1, 0xd1, 0xc0, 0xb3, 0x6d}} ,
|
||||
{{0x62, 0x4f, 0xd0, 0x75, 0x77, 0xba, 0x76, 0x77, 0xd7, 0xb8, 0xd8, 0x92, 0x6f, 0x98, 0x34, 0x3d, 0xd6, 0x4e, 0x1c, 0x0f, 0xf0, 0x8f, 0x2e, 0xf1, 0xb3, 0xbd, 0xb1, 0xb9, 0xec, 0x99, 0xb4, 0x07}}},
|
||||
{{{0x60, 0x57, 0x2e, 0x9a, 0x72, 0x1d, 0x6b, 0x6e, 0x58, 0x33, 0x24, 0x8c, 0x48, 0x39, 0x46, 0x8e, 0x89, 0x6a, 0x88, 0x51, 0x23, 0x62, 0xb5, 0x32, 0x09, 0x36, 0xe3, 0x57, 0xf5, 0x98, 0xde, 0x6f}} ,
|
||||
{{0x8b, 0x2c, 0x00, 0x48, 0x4a, 0xf9, 0x5b, 0x87, 0x69, 0x52, 0xe5, 0x5b, 0xd1, 0xb1, 0xe5, 0x25, 0x25, 0xe0, 0x9c, 0xc2, 0x13, 0x44, 0xe8, 0xb9, 0x0a, 0x70, 0xad, 0xbd, 0x0f, 0x51, 0x94, 0x69}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xa2, 0xdc, 0xab, 0xa9, 0x25, 0x2d, 0xac, 0x5f, 0x03, 0x33, 0x08, 0xe7, 0x7e, 0xfe, 0x95, 0x36, 0x3c, 0x5b, 0x3a, 0xd3, 0x05, 0x82, 0x1c, 0x95, 0x2d, 0xd8, 0x77, 0x7e, 0x02, 0xd9, 0x5b, 0x70}} ,
|
||||
{{0xc2, 0xfe, 0x1b, 0x0c, 0x67, 0xcd, 0xd6, 0xe0, 0x51, 0x8e, 0x2c, 0xe0, 0x79, 0x88, 0xf0, 0xcf, 0x41, 0x4a, 0xad, 0x23, 0xd4, 0x46, 0xca, 0x94, 0xa1, 0xc3, 0xeb, 0x28, 0x06, 0xfa, 0x17, 0x14}}},
|
||||
{{{0x7b, 0xaa, 0x70, 0x0a, 0x4b, 0xfb, 0xf5, 0xbf, 0x80, 0xc5, 0xcf, 0x08, 0x7a, 0xdd, 0xa1, 0xf4, 0x9d, 0x54, 0x50, 0x53, 0x23, 0x77, 0x23, 0xf5, 0x34, 0xa5, 0x22, 0xd1, 0x0d, 0x96, 0x2e, 0x47}} ,
|
||||
{{0xcc, 0xb7, 0x32, 0x89, 0x57, 0xd0, 0x98, 0x75, 0xe4, 0x37, 0x99, 0xa9, 0xe8, 0xba, 0xed, 0xba, 0xeb, 0xc7, 0x4f, 0x15, 0x76, 0x07, 0x0c, 0x4c, 0xef, 0x9f, 0x52, 0xfc, 0x04, 0x5d, 0x58, 0x10}}},
|
||||
{{{0xce, 0x82, 0xf0, 0x8f, 0x79, 0x02, 0xa8, 0xd1, 0xda, 0x14, 0x09, 0x48, 0xee, 0x8a, 0x40, 0x98, 0x76, 0x60, 0x54, 0x5a, 0xde, 0x03, 0x24, 0xf5, 0xe6, 0x2f, 0xe1, 0x03, 0xbf, 0x68, 0x82, 0x7f}} ,
|
||||
{{0x64, 0xe9, 0x28, 0xc7, 0xa4, 0xcf, 0x2a, 0xf9, 0x90, 0x64, 0x72, 0x2c, 0x8b, 0xeb, 0xec, 0xa0, 0xf2, 0x7d, 0x35, 0xb5, 0x90, 0x4d, 0x7f, 0x5b, 0x4a, 0x49, 0xe4, 0xb8, 0x3b, 0xc8, 0xa1, 0x2f}}},
|
||||
{{{0x8b, 0xc5, 0xcc, 0x3d, 0x69, 0xa6, 0xa1, 0x18, 0x44, 0xbc, 0x4d, 0x77, 0x37, 0xc7, 0x86, 0xec, 0x0c, 0xc9, 0xd6, 0x44, 0xa9, 0x23, 0x27, 0xb9, 0x03, 0x34, 0xa7, 0x0a, 0xd5, 0xc7, 0x34, 0x37}} ,
|
||||
{{0xf9, 0x7e, 0x3e, 0x66, 0xee, 0xf9, 0x99, 0x28, 0xff, 0xad, 0x11, 0xd8, 0xe2, 0x66, 0xc5, 0xcd, 0x0f, 0x0d, 0x0b, 0x6a, 0xfc, 0x7c, 0x24, 0xa8, 0x4f, 0xa8, 0x5e, 0x80, 0x45, 0x8b, 0x6c, 0x41}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xef, 0x1e, 0xec, 0xf7, 0x8d, 0x77, 0xf2, 0xea, 0xdb, 0x60, 0x03, 0x21, 0xc0, 0xff, 0x5e, 0x67, 0xc3, 0x71, 0x0b, 0x21, 0xb4, 0x41, 0xa0, 0x68, 0x38, 0xc6, 0x01, 0xa3, 0xd3, 0x51, 0x3c, 0x3c}} ,
|
||||
{{0x92, 0xf8, 0xd6, 0x4b, 0xef, 0x42, 0x13, 0xb2, 0x4a, 0xc4, 0x2e, 0x72, 0x3f, 0xc9, 0x11, 0xbd, 0x74, 0x02, 0x0e, 0xf5, 0x13, 0x9d, 0x83, 0x1a, 0x1b, 0xd5, 0x54, 0xde, 0xc4, 0x1e, 0x16, 0x6c}}},
|
||||
{{{0x27, 0x52, 0xe4, 0x63, 0xaa, 0x94, 0xe6, 0xc3, 0x28, 0x9c, 0xc6, 0x56, 0xac, 0xfa, 0xb6, 0xbd, 0xe2, 0xcc, 0x76, 0xc6, 0x27, 0x27, 0xa2, 0x8e, 0x78, 0x2b, 0x84, 0x72, 0x10, 0xbd, 0x4e, 0x2a}} ,
|
||||
{{0xea, 0xa7, 0x23, 0xef, 0x04, 0x61, 0x80, 0x50, 0xc9, 0x6e, 0xa5, 0x96, 0xd1, 0xd1, 0xc8, 0xc3, 0x18, 0xd7, 0x2d, 0xfd, 0x26, 0xbd, 0xcb, 0x7b, 0x92, 0x51, 0x0e, 0x4a, 0x65, 0x57, 0xb8, 0x49}}},
|
||||
{{{0xab, 0x55, 0x36, 0xc3, 0xec, 0x63, 0x55, 0x11, 0x55, 0xf6, 0xa5, 0xc7, 0x01, 0x5f, 0xfe, 0x79, 0xd8, 0x0a, 0xf7, 0x03, 0xd8, 0x98, 0x99, 0xf5, 0xd0, 0x00, 0x54, 0x6b, 0x66, 0x28, 0xf5, 0x25}} ,
|
||||
{{0x7a, 0x8d, 0xa1, 0x5d, 0x70, 0x5d, 0x51, 0x27, 0xee, 0x30, 0x65, 0x56, 0x95, 0x46, 0xde, 0xbd, 0x03, 0x75, 0xb4, 0x57, 0x59, 0x89, 0xeb, 0x02, 0x9e, 0xcc, 0x89, 0x19, 0xa7, 0xcb, 0x17, 0x67}}},
|
||||
{{{0x6a, 0xeb, 0xfc, 0x9a, 0x9a, 0x10, 0xce, 0xdb, 0x3a, 0x1c, 0x3c, 0x6a, 0x9d, 0xea, 0x46, 0xbc, 0x45, 0x49, 0xac, 0xe3, 0x41, 0x12, 0x7c, 0xf0, 0xf7, 0x4f, 0xf9, 0xf7, 0xff, 0x2c, 0x89, 0x04}} ,
|
||||
{{0x30, 0x31, 0x54, 0x1a, 0x46, 0xca, 0xe6, 0xc6, 0xcb, 0xe2, 0xc3, 0xc1, 0x8b, 0x75, 0x81, 0xbe, 0xee, 0xf8, 0xa3, 0x11, 0x1c, 0x25, 0xa3, 0xa7, 0x35, 0x51, 0x55, 0xe2, 0x25, 0xaa, 0xe2, 0x3a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xb4, 0x48, 0x10, 0x9f, 0x8a, 0x09, 0x76, 0xfa, 0xf0, 0x7a, 0xb0, 0x70, 0xf7, 0x83, 0x80, 0x52, 0x84, 0x2b, 0x26, 0xa2, 0xc4, 0x5d, 0x4f, 0xba, 0xb1, 0xc8, 0x40, 0x0d, 0x78, 0x97, 0xc4, 0x60}} ,
|
||||
{{0xd4, 0xb1, 0x6c, 0x08, 0xc7, 0x40, 0x38, 0x73, 0x5f, 0x0b, 0xf3, 0x76, 0x5d, 0xb2, 0xa5, 0x2f, 0x57, 0x57, 0x07, 0xed, 0x08, 0xa2, 0x6c, 0x4f, 0x08, 0x02, 0xb5, 0x0e, 0xee, 0x44, 0xfa, 0x22}}},
|
||||
{{{0x0f, 0x00, 0x3f, 0xa6, 0x04, 0x19, 0x56, 0x65, 0x31, 0x7f, 0x8b, 0xeb, 0x0d, 0xe1, 0x47, 0x89, 0x97, 0x16, 0x53, 0xfa, 0x81, 0xa7, 0xaa, 0xb2, 0xbf, 0x67, 0xeb, 0x72, 0x60, 0x81, 0x0d, 0x48}} ,
|
||||
{{0x7e, 0x13, 0x33, 0xcd, 0xa8, 0x84, 0x56, 0x1e, 0x67, 0xaf, 0x6b, 0x43, 0xac, 0x17, 0xaf, 0x16, 0xc0, 0x52, 0x99, 0x49, 0x5b, 0x87, 0x73, 0x7e, 0xb5, 0x43, 0xda, 0x6b, 0x1d, 0x0f, 0x2d, 0x55}}},
|
||||
{{{0xe9, 0x58, 0x1f, 0xff, 0x84, 0x3f, 0x93, 0x1c, 0xcb, 0xe1, 0x30, 0x69, 0xa5, 0x75, 0x19, 0x7e, 0x14, 0x5f, 0xf8, 0xfc, 0x09, 0xdd, 0xa8, 0x78, 0x9d, 0xca, 0x59, 0x8b, 0xd1, 0x30, 0x01, 0x13}} ,
|
||||
{{0xff, 0x76, 0x03, 0xc5, 0x4b, 0x89, 0x99, 0x70, 0x00, 0x59, 0x70, 0x9c, 0xd5, 0xd9, 0x11, 0x89, 0x5a, 0x46, 0xfe, 0xef, 0xdc, 0xd9, 0x55, 0x2b, 0x45, 0xa7, 0xb0, 0x2d, 0xfb, 0x24, 0xc2, 0x29}}},
|
||||
{{{0x38, 0x06, 0xf8, 0x0b, 0xac, 0x82, 0xc4, 0x97, 0x2b, 0x90, 0xe0, 0xf7, 0xa8, 0xab, 0x6c, 0x08, 0x80, 0x66, 0x90, 0x46, 0xf7, 0x26, 0x2d, 0xf8, 0xf1, 0xc4, 0x6b, 0x4a, 0x82, 0x98, 0x8e, 0x37}} ,
|
||||
{{0x8e, 0xb4, 0xee, 0xb8, 0xd4, 0x3f, 0xb2, 0x1b, 0xe0, 0x0a, 0x3d, 0x75, 0x34, 0x28, 0xa2, 0x8e, 0xc4, 0x92, 0x7b, 0xfe, 0x60, 0x6e, 0x6d, 0xb8, 0x31, 0x1d, 0x62, 0x0d, 0x78, 0x14, 0x42, 0x11}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x5e, 0xa8, 0xd8, 0x04, 0x9b, 0x73, 0xc9, 0xc9, 0xdc, 0x0d, 0x73, 0xbf, 0x0a, 0x0a, 0x73, 0xff, 0x18, 0x1f, 0x9c, 0x51, 0xaa, 0xc6, 0xf1, 0x83, 0x25, 0xfd, 0xab, 0xa3, 0x11, 0xd3, 0x01, 0x24}} ,
|
||||
{{0x4d, 0xe3, 0x7e, 0x38, 0x62, 0x5e, 0x64, 0xbb, 0x2b, 0x53, 0xb5, 0x03, 0x68, 0xc4, 0xf2, 0x2b, 0x5a, 0x03, 0x32, 0x99, 0x4a, 0x41, 0x9a, 0xe1, 0x1a, 0xae, 0x8c, 0x48, 0xf3, 0x24, 0x32, 0x65}}},
|
||||
{{{0xe8, 0xdd, 0xad, 0x3a, 0x8c, 0xea, 0xf4, 0xb3, 0xb2, 0xe5, 0x73, 0xf2, 0xed, 0x8b, 0xbf, 0xed, 0xb1, 0x0c, 0x0c, 0xfb, 0x2b, 0xf1, 0x01, 0x48, 0xe8, 0x26, 0x03, 0x8e, 0x27, 0x4d, 0x96, 0x72}} ,
|
||||
{{0xc8, 0x09, 0x3b, 0x60, 0xc9, 0x26, 0x4d, 0x7c, 0xf2, 0x9c, 0xd4, 0xa1, 0x3b, 0x26, 0xc2, 0x04, 0x33, 0x44, 0x76, 0x3c, 0x02, 0xbb, 0x11, 0x42, 0x0c, 0x22, 0xb7, 0xc6, 0xe1, 0xac, 0xb4, 0x0e}}},
|
||||
{{{0x6f, 0x85, 0xe7, 0xef, 0xde, 0x67, 0x30, 0xfc, 0xbf, 0x5a, 0xe0, 0x7b, 0x7a, 0x2a, 0x54, 0x6b, 0x5d, 0x62, 0x85, 0xa1, 0xf8, 0x16, 0x88, 0xec, 0x61, 0xb9, 0x96, 0xb5, 0xef, 0x2d, 0x43, 0x4d}} ,
|
||||
{{0x7c, 0x31, 0x33, 0xcc, 0xe4, 0xcf, 0x6c, 0xff, 0x80, 0x47, 0x77, 0xd1, 0xd8, 0xe9, 0x69, 0x97, 0x98, 0x7f, 0x20, 0x57, 0x1d, 0x1d, 0x4f, 0x08, 0x27, 0xc8, 0x35, 0x57, 0x40, 0xc6, 0x21, 0x0c}}},
|
||||
{{{0xd2, 0x8e, 0x9b, 0xfa, 0x42, 0x8e, 0xdf, 0x8f, 0xc7, 0x86, 0xf9, 0xa4, 0xca, 0x70, 0x00, 0x9d, 0x21, 0xbf, 0xec, 0x57, 0x62, 0x30, 0x58, 0x8c, 0x0d, 0x35, 0xdb, 0x5d, 0x8b, 0x6a, 0xa0, 0x5a}} ,
|
||||
{{0xc1, 0x58, 0x7c, 0x0d, 0x20, 0xdd, 0x11, 0x26, 0x5f, 0x89, 0x3b, 0x97, 0x58, 0xf8, 0x8b, 0xe3, 0xdf, 0x32, 0xe2, 0xfc, 0xd8, 0x67, 0xf2, 0xa5, 0x37, 0x1e, 0x6d, 0xec, 0x7c, 0x27, 0x20, 0x79}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xd0, 0xe9, 0xc0, 0xfa, 0x95, 0x45, 0x23, 0x96, 0xf1, 0x2c, 0x79, 0x25, 0x14, 0xce, 0x40, 0x14, 0x44, 0x2c, 0x36, 0x50, 0xd9, 0x63, 0x56, 0xb7, 0x56, 0x3b, 0x9e, 0xa7, 0xef, 0x89, 0xbb, 0x0e}} ,
|
||||
{{0xce, 0x7f, 0xdc, 0x0a, 0xcc, 0x82, 0x1c, 0x0a, 0x78, 0x71, 0xe8, 0x74, 0x8d, 0x01, 0x30, 0x0f, 0xa7, 0x11, 0x4c, 0xdf, 0x38, 0xd7, 0xa7, 0x0d, 0xf8, 0x48, 0x52, 0x00, 0x80, 0x7b, 0x5f, 0x0e}}},
|
||||
{{{0x25, 0x83, 0xe6, 0x94, 0x7b, 0x81, 0xb2, 0x91, 0xae, 0x0e, 0x05, 0xc9, 0xa3, 0x68, 0x2d, 0xd9, 0x88, 0x25, 0x19, 0x2a, 0x61, 0x61, 0x21, 0x97, 0x15, 0xa1, 0x35, 0xa5, 0x46, 0xc8, 0xa2, 0x0e}} ,
|
||||
{{0x1b, 0x03, 0x0d, 0x8b, 0x5a, 0x1b, 0x97, 0x4b, 0xf2, 0x16, 0x31, 0x3d, 0x1f, 0x33, 0xa0, 0x50, 0x3a, 0x18, 0xbe, 0x13, 0xa1, 0x76, 0xc1, 0xba, 0x1b, 0xf1, 0x05, 0x7b, 0x33, 0xa8, 0x82, 0x3b}}},
|
||||
{{{0xba, 0x36, 0x7b, 0x6d, 0xa9, 0xea, 0x14, 0x12, 0xc5, 0xfa, 0x91, 0x00, 0xba, 0x9b, 0x99, 0xcc, 0x56, 0x02, 0xe9, 0xa0, 0x26, 0x40, 0x66, 0x8c, 0xc4, 0xf8, 0x85, 0x33, 0x68, 0xe7, 0x03, 0x20}} ,
|
||||
{{0x50, 0x5b, 0xff, 0xa9, 0xb2, 0xf1, 0xf1, 0x78, 0xcf, 0x14, 0xa4, 0xa9, 0xfc, 0x09, 0x46, 0x94, 0x54, 0x65, 0x0d, 0x9c, 0x5f, 0x72, 0x21, 0xe2, 0x97, 0xa5, 0x2d, 0x81, 0xce, 0x4a, 0x5f, 0x79}}},
|
||||
{{{0x3d, 0x5f, 0x5c, 0xd2, 0xbc, 0x7d, 0x77, 0x0e, 0x2a, 0x6d, 0x22, 0x45, 0x84, 0x06, 0xc4, 0xdd, 0xc6, 0xa6, 0xc6, 0xd7, 0x49, 0xad, 0x6d, 0x87, 0x91, 0x0e, 0x3a, 0x67, 0x1d, 0x2c, 0x1d, 0x56}} ,
|
||||
{{0xfe, 0x7a, 0x74, 0xcf, 0xd4, 0xd2, 0xe5, 0x19, 0xde, 0xd0, 0xdb, 0x70, 0x23, 0x69, 0xe6, 0x6d, 0xec, 0xec, 0xcc, 0x09, 0x33, 0x6a, 0x77, 0xdc, 0x6b, 0x22, 0x76, 0x5d, 0x92, 0x09, 0xac, 0x2d}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x23, 0x15, 0x17, 0xeb, 0xd3, 0xdb, 0x12, 0x5e, 0x01, 0xf0, 0x91, 0xab, 0x2c, 0x41, 0xce, 0xac, 0xed, 0x1b, 0x4b, 0x2d, 0xbc, 0xdb, 0x17, 0x66, 0x89, 0x46, 0xad, 0x4b, 0x1e, 0x6f, 0x0b, 0x14}} ,
|
||||
{{0x11, 0xce, 0xbf, 0xb6, 0x77, 0x2d, 0x48, 0x22, 0x18, 0x4f, 0xa3, 0x5d, 0x4a, 0xb0, 0x70, 0x12, 0x3e, 0x54, 0xd7, 0xd8, 0x0e, 0x2b, 0x27, 0xdc, 0x53, 0xff, 0xca, 0x8c, 0x59, 0xb3, 0x4e, 0x44}}},
|
||||
{{{0x07, 0x76, 0x61, 0x0f, 0x66, 0xb2, 0x21, 0x39, 0x7e, 0xc0, 0xec, 0x45, 0x28, 0x82, 0xa1, 0x29, 0x32, 0x44, 0x35, 0x13, 0x5e, 0x61, 0x5e, 0x54, 0xcb, 0x7c, 0xef, 0xf6, 0x41, 0xcf, 0x9f, 0x0a}} ,
|
||||
{{0xdd, 0xf9, 0xda, 0x84, 0xc3, 0xe6, 0x8a, 0x9f, 0x24, 0xd2, 0x96, 0x5d, 0x39, 0x6f, 0x58, 0x8c, 0xc1, 0x56, 0x93, 0xab, 0xb5, 0x79, 0x3b, 0xd2, 0xa8, 0x73, 0x16, 0xed, 0xfa, 0xb4, 0x2f, 0x73}}},
|
||||
{{{0x8b, 0xb1, 0x95, 0xe5, 0x92, 0x50, 0x35, 0x11, 0x76, 0xac, 0xf4, 0x4d, 0x24, 0xc3, 0x32, 0xe6, 0xeb, 0xfe, 0x2c, 0x87, 0xc4, 0xf1, 0x56, 0xc4, 0x75, 0x24, 0x7a, 0x56, 0x85, 0x5a, 0x3a, 0x13}} ,
|
||||
{{0x0d, 0x16, 0xac, 0x3c, 0x4a, 0x58, 0x86, 0x3a, 0x46, 0x7f, 0x6c, 0xa3, 0x52, 0x6e, 0x37, 0xe4, 0x96, 0x9c, 0xe9, 0x5c, 0x66, 0x41, 0x67, 0xe4, 0xfb, 0x79, 0x0c, 0x05, 0xf6, 0x64, 0xd5, 0x7c}}},
|
||||
{{{0x28, 0xc1, 0xe1, 0x54, 0x73, 0xf2, 0xbf, 0x76, 0x74, 0x19, 0x19, 0x1b, 0xe4, 0xb9, 0xa8, 0x46, 0x65, 0x73, 0xf3, 0x77, 0x9b, 0x29, 0x74, 0x5b, 0xc6, 0x89, 0x6c, 0x2c, 0x7c, 0xf8, 0xb3, 0x0f}} ,
|
||||
{{0xf7, 0xd5, 0xe9, 0x74, 0x5d, 0xb8, 0x25, 0x16, 0xb5, 0x30, 0xbc, 0x84, 0xc5, 0xf0, 0xad, 0xca, 0x12, 0x28, 0xbc, 0x9d, 0xd4, 0xfa, 0x82, 0xe6, 0xe3, 0xbf, 0xa2, 0x15, 0x2c, 0xd4, 0x34, 0x10}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x61, 0xb1, 0x46, 0xba, 0x0e, 0x31, 0xa5, 0x67, 0x6c, 0x7f, 0xd6, 0xd9, 0x27, 0x85, 0x0f, 0x79, 0x14, 0xc8, 0x6c, 0x2f, 0x5f, 0x5b, 0x9c, 0x35, 0x3d, 0x38, 0x86, 0x77, 0x65, 0x55, 0x6a, 0x7b}} ,
|
||||
{{0xd3, 0xb0, 0x3a, 0x66, 0x60, 0x1b, 0x43, 0xf1, 0x26, 0x58, 0x99, 0x09, 0x8f, 0x2d, 0xa3, 0x14, 0x71, 0x85, 0xdb, 0xed, 0xf6, 0x26, 0xd5, 0x61, 0x9a, 0x73, 0xac, 0x0e, 0xea, 0xac, 0xb7, 0x0c}}},
|
||||
{{{0x5e, 0xf4, 0xe5, 0x17, 0x0e, 0x10, 0x9f, 0xe7, 0x43, 0x5f, 0x67, 0x5c, 0xac, 0x4b, 0xe5, 0x14, 0x41, 0xd2, 0xbf, 0x48, 0xf5, 0x14, 0xb0, 0x71, 0xc6, 0x61, 0xc1, 0xb2, 0x70, 0x58, 0xd2, 0x5a}} ,
|
||||
{{0x2d, 0xba, 0x16, 0x07, 0x92, 0x94, 0xdc, 0xbd, 0x50, 0x2b, 0xc9, 0x7f, 0x42, 0x00, 0xba, 0x61, 0xed, 0xf8, 0x43, 0xed, 0xf5, 0xf9, 0x40, 0x60, 0xb2, 0xb0, 0x82, 0xcb, 0xed, 0x75, 0xc7, 0x65}}},
|
||||
{{{0x80, 0xba, 0x0d, 0x09, 0x40, 0xa7, 0x39, 0xa6, 0x67, 0x34, 0x7e, 0x66, 0xbe, 0x56, 0xfb, 0x53, 0x78, 0xc4, 0x46, 0xe8, 0xed, 0x68, 0x6c, 0x7f, 0xce, 0xe8, 0x9f, 0xce, 0xa2, 0x64, 0x58, 0x53}} ,
|
||||
{{0xe8, 0xc1, 0xa9, 0xc2, 0x7b, 0x59, 0x21, 0x33, 0xe2, 0x43, 0x73, 0x2b, 0xac, 0x2d, 0xc1, 0x89, 0x3b, 0x15, 0xe2, 0xd5, 0xc0, 0x97, 0x8a, 0xfd, 0x6f, 0x36, 0x33, 0xb7, 0xb9, 0xc3, 0x88, 0x09}}},
|
||||
{{{0xd0, 0xb6, 0x56, 0x30, 0x5c, 0xae, 0xb3, 0x75, 0x44, 0xa4, 0x83, 0x51, 0x6e, 0x01, 0x65, 0xef, 0x45, 0x76, 0xe6, 0xf5, 0xa2, 0x0d, 0xd4, 0x16, 0x3b, 0x58, 0x2f, 0xf2, 0x2f, 0x36, 0x18, 0x3f}} ,
|
||||
{{0xfd, 0x2f, 0xe0, 0x9b, 0x1e, 0x8c, 0xc5, 0x18, 0xa9, 0xca, 0xd4, 0x2b, 0x35, 0xb6, 0x95, 0x0a, 0x9f, 0x7e, 0xfb, 0xc4, 0xef, 0x88, 0x7b, 0x23, 0x43, 0xec, 0x2f, 0x0d, 0x0f, 0x7a, 0xfc, 0x5c}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b}} ,
|
||||
{{0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61}}},
|
||||
{{{0x54, 0x83, 0x02, 0x18, 0x82, 0x93, 0x99, 0x07, 0xd0, 0xa7, 0xda, 0xd8, 0x75, 0x89, 0xfa, 0xf2, 0xd9, 0xa3, 0xb8, 0x6b, 0x5a, 0x35, 0x28, 0xd2, 0x6b, 0x59, 0xc2, 0xf8, 0x45, 0xe2, 0xbc, 0x06}} ,
|
||||
{{0x65, 0xc0, 0xa3, 0x88, 0x51, 0x95, 0xfc, 0x96, 0x94, 0x78, 0xe8, 0x0d, 0x8b, 0x41, 0xc9, 0xc2, 0x58, 0x48, 0x75, 0x10, 0x2f, 0xcd, 0x2a, 0xc9, 0xa0, 0x6d, 0x0f, 0xdd, 0x9c, 0x98, 0x26, 0x3d}}},
|
||||
{{{0x2f, 0x66, 0x29, 0x1b, 0x04, 0x89, 0xbd, 0x7e, 0xee, 0x6e, 0xdd, 0xb7, 0x0e, 0xef, 0xb0, 0x0c, 0xb4, 0xfc, 0x7f, 0xc2, 0xc9, 0x3a, 0x3c, 0x64, 0xef, 0x45, 0x44, 0xaf, 0x8a, 0x90, 0x65, 0x76}} ,
|
||||
{{0xa1, 0x4c, 0x70, 0x4b, 0x0e, 0xa0, 0x83, 0x70, 0x13, 0xa4, 0xaf, 0xb8, 0x38, 0x19, 0x22, 0x65, 0x09, 0xb4, 0x02, 0x4f, 0x06, 0xf8, 0x17, 0xce, 0x46, 0x45, 0xda, 0x50, 0x7c, 0x8a, 0xd1, 0x4e}}},
|
||||
{{{0xf7, 0xd4, 0x16, 0x6c, 0x4e, 0x95, 0x9d, 0x5d, 0x0f, 0x91, 0x2b, 0x52, 0xfe, 0x5c, 0x34, 0xe5, 0x30, 0xe6, 0xa4, 0x3b, 0xf3, 0xf3, 0x34, 0x08, 0xa9, 0x4a, 0xa0, 0xb5, 0x6e, 0xb3, 0x09, 0x0a}} ,
|
||||
{{0x26, 0xd9, 0x5e, 0xa3, 0x0f, 0xeb, 0xa2, 0xf3, 0x20, 0x3b, 0x37, 0xd4, 0xe4, 0x9e, 0xce, 0x06, 0x3d, 0x53, 0xed, 0xae, 0x2b, 0xeb, 0xb6, 0x24, 0x0a, 0x11, 0xa3, 0x0f, 0xd6, 0x7f, 0xa4, 0x3a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xdb, 0x9f, 0x2c, 0xfc, 0xd6, 0xb2, 0x1e, 0x2e, 0x52, 0x7a, 0x06, 0x87, 0x2d, 0x86, 0x72, 0x2b, 0x6d, 0x90, 0x77, 0x46, 0x43, 0xb5, 0x7a, 0xf8, 0x60, 0x7d, 0x91, 0x60, 0x5b, 0x9d, 0x9e, 0x07}} ,
|
||||
{{0x97, 0x87, 0xc7, 0x04, 0x1c, 0x38, 0x01, 0x39, 0x58, 0xc7, 0x85, 0xa3, 0xfc, 0x64, 0x00, 0x64, 0x25, 0xa2, 0xbf, 0x50, 0x94, 0xca, 0x26, 0x31, 0x45, 0x0a, 0x24, 0xd2, 0x51, 0x29, 0x51, 0x16}}},
|
||||
{{{0x4d, 0x4a, 0xd7, 0x98, 0x71, 0x57, 0xac, 0x7d, 0x8b, 0x37, 0xbd, 0x63, 0xff, 0x87, 0xb1, 0x49, 0x95, 0x20, 0x7c, 0xcf, 0x7c, 0x59, 0xc4, 0x91, 0x9c, 0xef, 0xd0, 0xdb, 0x60, 0x09, 0x9d, 0x46}} ,
|
||||
{{0xcb, 0x78, 0x94, 0x90, 0xe4, 0x45, 0xb3, 0xf6, 0xd9, 0xf6, 0x57, 0x74, 0xd5, 0xf8, 0x83, 0x4f, 0x39, 0xc9, 0xbd, 0x88, 0xc2, 0x57, 0x21, 0x1f, 0x24, 0x32, 0x68, 0xf8, 0xc7, 0x21, 0x5f, 0x0b}}},
|
||||
{{{0x2a, 0x36, 0x68, 0xfc, 0x5f, 0xb6, 0x4f, 0xa5, 0xe3, 0x9d, 0x24, 0x2f, 0xc0, 0x93, 0x61, 0xcf, 0xf8, 0x0a, 0xed, 0xe1, 0xdb, 0x27, 0xec, 0x0e, 0x14, 0x32, 0x5f, 0x8e, 0xa1, 0x62, 0x41, 0x16}} ,
|
||||
{{0x95, 0x21, 0x01, 0xce, 0x95, 0x5b, 0x0e, 0x57, 0xc7, 0xb9, 0x62, 0xb5, 0x28, 0xca, 0x11, 0xec, 0xb4, 0x46, 0x06, 0x73, 0x26, 0xff, 0xfb, 0x66, 0x7d, 0xee, 0x5f, 0xb2, 0x56, 0xfd, 0x2a, 0x08}}},
|
||||
{{{0x92, 0x67, 0x77, 0x56, 0xa1, 0xff, 0xc4, 0xc5, 0x95, 0xf0, 0xe3, 0x3a, 0x0a, 0xca, 0x94, 0x4d, 0x9e, 0x7e, 0x3d, 0xb9, 0x6e, 0xb6, 0xb0, 0xce, 0xa4, 0x30, 0x89, 0x99, 0xe9, 0xad, 0x11, 0x59}} ,
|
||||
{{0xf6, 0x48, 0x95, 0xa1, 0x6f, 0x5f, 0xb7, 0xa5, 0xbb, 0x30, 0x00, 0x1c, 0xd2, 0x8a, 0xd6, 0x25, 0x26, 0x1b, 0xb2, 0x0d, 0x37, 0x6a, 0x05, 0xf4, 0x9d, 0x3e, 0x17, 0x2a, 0x43, 0xd2, 0x3a, 0x06}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x32, 0x99, 0x93, 0xd1, 0x9a, 0x72, 0xf3, 0xa9, 0x16, 0xbd, 0xb4, 0x4c, 0xdd, 0xf9, 0xd4, 0xb2, 0x64, 0x9a, 0xd3, 0x05, 0xe4, 0xa3, 0x73, 0x1c, 0xcb, 0x7e, 0x57, 0x67, 0xff, 0x04, 0xb3, 0x10}} ,
|
||||
{{0xb9, 0x4b, 0xa4, 0xad, 0xd0, 0x6d, 0x61, 0x23, 0xb4, 0xaf, 0x34, 0xa9, 0xaa, 0x65, 0xec, 0xd9, 0x69, 0xe3, 0x85, 0xcd, 0xcc, 0xe7, 0xb0, 0x9b, 0x41, 0xc1, 0x1c, 0xf9, 0xa0, 0xfa, 0xb7, 0x13}}},
|
||||
{{{0x04, 0xfd, 0x88, 0x3c, 0x0c, 0xd0, 0x09, 0x52, 0x51, 0x4f, 0x06, 0x19, 0xcc, 0xc3, 0xbb, 0xde, 0x80, 0xc5, 0x33, 0xbc, 0xf9, 0xf3, 0x17, 0x36, 0xdd, 0xc6, 0xde, 0xe8, 0x9b, 0x5d, 0x79, 0x1b}} ,
|
||||
{{0x65, 0x0a, 0xbe, 0x51, 0x57, 0xad, 0x50, 0x79, 0x08, 0x71, 0x9b, 0x07, 0x95, 0x8f, 0xfb, 0xae, 0x4b, 0x38, 0xba, 0xcf, 0x53, 0x2a, 0x86, 0x1e, 0xc0, 0x50, 0x5c, 0x67, 0x1b, 0xf6, 0x87, 0x6c}}},
|
||||
{{{0x4f, 0x00, 0xb2, 0x66, 0x55, 0xed, 0x4a, 0xed, 0x8d, 0xe1, 0x66, 0x18, 0xb2, 0x14, 0x74, 0x8d, 0xfd, 0x1a, 0x36, 0x0f, 0x26, 0x5c, 0x8b, 0x89, 0xf3, 0xab, 0xf2, 0xf3, 0x24, 0x67, 0xfd, 0x70}} ,
|
||||
{{0xfd, 0x4e, 0x2a, 0xc1, 0x3a, 0xca, 0x8f, 0x00, 0xd8, 0xec, 0x74, 0x67, 0xef, 0x61, 0xe0, 0x28, 0xd0, 0x96, 0xf4, 0x48, 0xde, 0x81, 0xe3, 0xef, 0xdc, 0xaa, 0x7d, 0xf3, 0xb6, 0x55, 0xa6, 0x65}}},
|
||||
{{{0xeb, 0xcb, 0xc5, 0x70, 0x91, 0x31, 0x10, 0x93, 0x0d, 0xc8, 0xd0, 0xef, 0x62, 0xe8, 0x6f, 0x82, 0xe3, 0x69, 0x3d, 0x91, 0x7f, 0x31, 0xe1, 0x26, 0x35, 0x3c, 0x4a, 0x2f, 0xab, 0xc4, 0x9a, 0x5e}} ,
|
||||
{{0xab, 0x1b, 0xb5, 0xe5, 0x2b, 0xc3, 0x0e, 0x29, 0xb0, 0xd0, 0x73, 0xe6, 0x4f, 0x64, 0xf2, 0xbc, 0xe4, 0xe4, 0xe1, 0x9a, 0x52, 0x33, 0x2f, 0xbd, 0xcc, 0x03, 0xee, 0x8a, 0xfa, 0x00, 0x5f, 0x50}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xf6, 0xdb, 0x0d, 0x22, 0x3d, 0xb5, 0x14, 0x75, 0x31, 0xf0, 0x81, 0xe2, 0xb9, 0x37, 0xa2, 0xa9, 0x84, 0x11, 0x9a, 0x07, 0xb5, 0x53, 0x89, 0x78, 0xa9, 0x30, 0x27, 0xa1, 0xf1, 0x4e, 0x5c, 0x2e}} ,
|
||||
{{0x8b, 0x00, 0x54, 0xfb, 0x4d, 0xdc, 0xcb, 0x17, 0x35, 0x40, 0xff, 0xb7, 0x8c, 0xfe, 0x4a, 0xe4, 0x4e, 0x99, 0x4e, 0xa8, 0x74, 0x54, 0x5d, 0x5c, 0x96, 0xa3, 0x12, 0x55, 0x36, 0x31, 0x17, 0x5c}}},
|
||||
{{{0xce, 0x24, 0xef, 0x7b, 0x86, 0xf2, 0x0f, 0x77, 0xe8, 0x5c, 0x7d, 0x87, 0x38, 0x2d, 0xef, 0xaf, 0xf2, 0x8c, 0x72, 0x2e, 0xeb, 0xb6, 0x55, 0x4b, 0x6e, 0xf1, 0x4e, 0x8a, 0x0e, 0x9a, 0x6c, 0x4c}} ,
|
||||
{{0x25, 0xea, 0x86, 0xc2, 0xd1, 0x4f, 0xb7, 0x3e, 0xa8, 0x5c, 0x8d, 0x66, 0x81, 0x25, 0xed, 0xc5, 0x4c, 0x05, 0xb9, 0xd8, 0xd6, 0x70, 0xbe, 0x73, 0x82, 0xe8, 0xa1, 0xe5, 0x1e, 0x71, 0xd5, 0x26}}},
|
||||
{{{0x4e, 0x6d, 0xc3, 0xa7, 0x4f, 0x22, 0x45, 0x26, 0xa2, 0x7e, 0x16, 0xf7, 0xf7, 0x63, 0xdc, 0x86, 0x01, 0x2a, 0x71, 0x38, 0x5c, 0x33, 0xc3, 0xce, 0x30, 0xff, 0xf9, 0x2c, 0x91, 0x71, 0x8a, 0x72}} ,
|
||||
{{0x8c, 0x44, 0x09, 0x28, 0xd5, 0x23, 0xc9, 0x8f, 0xf3, 0x84, 0x45, 0xc6, 0x9a, 0x5e, 0xff, 0xd2, 0xc7, 0x57, 0x93, 0xa3, 0xc1, 0x69, 0xdd, 0x62, 0x0f, 0xda, 0x5c, 0x30, 0x59, 0x5d, 0xe9, 0x4c}}},
|
||||
{{{0x92, 0x7e, 0x50, 0x27, 0x72, 0xd7, 0x0c, 0xd6, 0x69, 0x96, 0x81, 0x35, 0x84, 0x94, 0x35, 0x8b, 0x6c, 0xaa, 0x62, 0x86, 0x6e, 0x1c, 0x15, 0xf3, 0x6c, 0xb3, 0xff, 0x65, 0x1b, 0xa2, 0x9b, 0x59}} ,
|
||||
{{0xe2, 0xa9, 0x65, 0x88, 0xc4, 0x50, 0xfa, 0xbb, 0x3b, 0x6e, 0x5f, 0x44, 0x01, 0xca, 0x97, 0xd4, 0xdd, 0xf6, 0xcd, 0x3f, 0x3f, 0xe5, 0x97, 0x67, 0x2b, 0x8c, 0x66, 0x0f, 0x35, 0x9b, 0xf5, 0x07}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xf1, 0x59, 0x27, 0xd8, 0xdb, 0x5a, 0x11, 0x5e, 0x82, 0xf3, 0x38, 0xff, 0x1c, 0xed, 0xfe, 0x3f, 0x64, 0x54, 0x3f, 0x7f, 0xd1, 0x81, 0xed, 0xef, 0x65, 0xc5, 0xcb, 0xfd, 0xe1, 0x80, 0xcd, 0x11}} ,
|
||||
{{0xe0, 0xdb, 0x22, 0x28, 0xe6, 0xff, 0x61, 0x9d, 0x41, 0x14, 0x2d, 0x3b, 0x26, 0x22, 0xdf, 0xf1, 0x34, 0x81, 0xe9, 0x45, 0xee, 0x0f, 0x98, 0x8b, 0xa6, 0x3f, 0xef, 0xf7, 0x43, 0x19, 0xf1, 0x43}}},
|
||||
{{{0xee, 0xf3, 0x00, 0xa1, 0x50, 0xde, 0xc0, 0xb6, 0x01, 0xe3, 0x8c, 0x3c, 0x4d, 0x31, 0xd2, 0xb0, 0x58, 0xcd, 0xed, 0x10, 0x4a, 0x7a, 0xef, 0x80, 0xa9, 0x19, 0x32, 0xf3, 0xd8, 0x33, 0x8c, 0x06}} ,
|
||||
{{0xcb, 0x7d, 0x4f, 0xff, 0x30, 0xd8, 0x12, 0x3b, 0x39, 0x1c, 0x06, 0xf9, 0x4c, 0x34, 0x35, 0x71, 0xb5, 0x16, 0x94, 0x67, 0xdf, 0xee, 0x11, 0xde, 0xa4, 0x1d, 0x88, 0x93, 0x35, 0xa9, 0x32, 0x10}}},
|
||||
{{{0xe9, 0xc3, 0xbc, 0x7b, 0x5c, 0xfc, 0xb2, 0xf9, 0xc9, 0x2f, 0xe5, 0xba, 0x3a, 0x0b, 0xab, 0x64, 0x38, 0x6f, 0x5b, 0x4b, 0x93, 0xda, 0x64, 0xec, 0x4d, 0x3d, 0xa0, 0xf5, 0xbb, 0xba, 0x47, 0x48}} ,
|
||||
{{0x60, 0xbc, 0x45, 0x1f, 0x23, 0xa2, 0x3b, 0x70, 0x76, 0xe6, 0x97, 0x99, 0x4f, 0x77, 0x54, 0x67, 0x30, 0x9a, 0xe7, 0x66, 0xd6, 0xcd, 0x2e, 0x51, 0x24, 0x2c, 0x42, 0x4a, 0x11, 0xfe, 0x6f, 0x7e}}},
|
||||
{{{0x87, 0xc0, 0xb1, 0xf0, 0xa3, 0x6f, 0x0c, 0x93, 0xa9, 0x0a, 0x72, 0xef, 0x5c, 0xbe, 0x65, 0x35, 0xa7, 0x6a, 0x4e, 0x2c, 0xbf, 0x21, 0x23, 0xe8, 0x2f, 0x97, 0xc7, 0x3e, 0xc8, 0x17, 0xac, 0x1e}} ,
|
||||
{{0x7b, 0xef, 0x21, 0xe5, 0x40, 0xcc, 0x1e, 0xdc, 0xd6, 0xbd, 0x97, 0x7a, 0x7c, 0x75, 0x86, 0x7a, 0x25, 0x5a, 0x6e, 0x7c, 0xe5, 0x51, 0x3c, 0x1b, 0x5b, 0x82, 0x9a, 0x07, 0x60, 0xa1, 0x19, 0x04}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x96, 0x88, 0xa6, 0xab, 0x8f, 0xe3, 0x3a, 0x49, 0xf8, 0xfe, 0x34, 0xe7, 0x6a, 0xb2, 0xfe, 0x40, 0x26, 0x74, 0x57, 0x4c, 0xf6, 0xd4, 0x99, 0xce, 0x5d, 0x7b, 0x2f, 0x67, 0xd6, 0x5a, 0xe4, 0x4e}} ,
|
||||
{{0x5c, 0x82, 0xb3, 0xbd, 0x55, 0x25, 0xf6, 0x6a, 0x93, 0xa4, 0x02, 0xc6, 0x7d, 0x5c, 0xb1, 0x2b, 0x5b, 0xff, 0xfb, 0x56, 0xf8, 0x01, 0x41, 0x90, 0xc6, 0xb6, 0xac, 0x4f, 0xfe, 0xa7, 0x41, 0x70}}},
|
||||
{{{0xdb, 0xfa, 0x9b, 0x2c, 0xd4, 0x23, 0x67, 0x2c, 0x8a, 0x63, 0x6c, 0x07, 0x26, 0x48, 0x4f, 0xc2, 0x03, 0xd2, 0x53, 0x20, 0x28, 0xed, 0x65, 0x71, 0x47, 0xa9, 0x16, 0x16, 0x12, 0xbc, 0x28, 0x33}} ,
|
||||
{{0x39, 0xc0, 0xfa, 0xfa, 0xcd, 0x33, 0x43, 0xc7, 0x97, 0x76, 0x9b, 0x93, 0x91, 0x72, 0xeb, 0xc5, 0x18, 0x67, 0x4c, 0x11, 0xf0, 0xf4, 0xe5, 0x73, 0xb2, 0x5c, 0x1b, 0xc2, 0x26, 0x3f, 0xbf, 0x2b}}},
|
||||
{{{0x86, 0xe6, 0x8c, 0x1d, 0xdf, 0xca, 0xfc, 0xd5, 0xf8, 0x3a, 0xc3, 0x44, 0x72, 0xe6, 0x78, 0x9d, 0x2b, 0x97, 0xf8, 0x28, 0x45, 0xb4, 0x20, 0xc9, 0x2a, 0x8c, 0x67, 0xaa, 0x11, 0xc5, 0x5b, 0x2f}} ,
|
||||
{{0x17, 0x0f, 0x86, 0x52, 0xd7, 0x9d, 0xc3, 0x44, 0x51, 0x76, 0x32, 0x65, 0xb4, 0x37, 0x81, 0x99, 0x46, 0x37, 0x62, 0xed, 0xcf, 0x64, 0x9d, 0x72, 0x40, 0x7a, 0x4c, 0x0b, 0x76, 0x2a, 0xfb, 0x56}}},
|
||||
{{{0x33, 0xa7, 0x90, 0x7c, 0xc3, 0x6f, 0x17, 0xa5, 0xa0, 0x67, 0x72, 0x17, 0xea, 0x7e, 0x63, 0x14, 0x83, 0xde, 0xc1, 0x71, 0x2d, 0x41, 0x32, 0x7a, 0xf3, 0xd1, 0x2b, 0xd8, 0x2a, 0xa6, 0x46, 0x36}} ,
|
||||
{{0xac, 0xcc, 0x6b, 0x7c, 0xf9, 0xb8, 0x8b, 0x08, 0x5c, 0xd0, 0x7d, 0x8f, 0x73, 0xea, 0x20, 0xda, 0x86, 0xca, 0x00, 0xc7, 0xad, 0x73, 0x4d, 0xe9, 0xe8, 0xa9, 0xda, 0x1f, 0x03, 0x06, 0xdd, 0x24}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x9c, 0xb2, 0x61, 0x0a, 0x98, 0x2a, 0xa5, 0xd7, 0xee, 0xa9, 0xac, 0x65, 0xcb, 0x0a, 0x1e, 0xe2, 0xbe, 0xdc, 0x85, 0x59, 0x0f, 0x9c, 0xa6, 0x57, 0x34, 0xa5, 0x87, 0xeb, 0x7b, 0x1e, 0x0c, 0x3c}} ,
|
||||
{{0x2f, 0xbd, 0x84, 0x63, 0x0d, 0xb5, 0xa0, 0xf0, 0x4b, 0x9e, 0x93, 0xc6, 0x34, 0x9a, 0x34, 0xff, 0x73, 0x19, 0x2f, 0x6e, 0x54, 0x45, 0x2c, 0x92, 0x31, 0x76, 0x34, 0xf1, 0xb2, 0x26, 0xe8, 0x74}}},
|
||||
{{{0x0a, 0x67, 0x90, 0x6d, 0x0c, 0x4c, 0xcc, 0xc0, 0xe6, 0xbd, 0xa7, 0x5e, 0x55, 0x8c, 0xcd, 0x58, 0x9b, 0x11, 0xa2, 0xbb, 0x4b, 0xb1, 0x43, 0x04, 0x3c, 0x55, 0xed, 0x23, 0xfe, 0xcd, 0xb1, 0x53}} ,
|
||||
{{0x05, 0xfb, 0x75, 0xf5, 0x01, 0xaf, 0x38, 0x72, 0x58, 0xfc, 0x04, 0x29, 0x34, 0x7a, 0x67, 0xa2, 0x08, 0x50, 0x6e, 0xd0, 0x2b, 0x73, 0xd5, 0xb8, 0xe4, 0x30, 0x96, 0xad, 0x45, 0xdf, 0xa6, 0x5c}}},
|
||||
{{{0x0d, 0x88, 0x1a, 0x90, 0x7e, 0xdc, 0xd8, 0xfe, 0xc1, 0x2f, 0x5d, 0x67, 0xee, 0x67, 0x2f, 0xed, 0x6f, 0x55, 0x43, 0x5f, 0x87, 0x14, 0x35, 0x42, 0xd3, 0x75, 0xae, 0xd5, 0xd3, 0x85, 0x1a, 0x76}} ,
|
||||
{{0x87, 0xc8, 0xa0, 0x6e, 0xe1, 0xb0, 0xad, 0x6a, 0x4a, 0x34, 0x71, 0xed, 0x7c, 0xd6, 0x44, 0x03, 0x65, 0x4a, 0x5c, 0x5c, 0x04, 0xf5, 0x24, 0x3f, 0xb0, 0x16, 0x5e, 0x8c, 0xb2, 0xd2, 0xc5, 0x20}}},
|
||||
{{{0x98, 0x83, 0xc2, 0x37, 0xa0, 0x41, 0xa8, 0x48, 0x5c, 0x5f, 0xbf, 0xc8, 0xfa, 0x24, 0xe0, 0x59, 0x2c, 0xbd, 0xf6, 0x81, 0x7e, 0x88, 0xe6, 0xca, 0x04, 0xd8, 0x5d, 0x60, 0xbb, 0x74, 0xa7, 0x0b}} ,
|
||||
{{0x21, 0x13, 0x91, 0xbf, 0x77, 0x7a, 0x33, 0xbc, 0xe9, 0x07, 0x39, 0x0a, 0xdd, 0x7d, 0x06, 0x10, 0x9a, 0xee, 0x47, 0x73, 0x1b, 0x15, 0x5a, 0xfb, 0xcd, 0x4d, 0xd0, 0xd2, 0x3a, 0x01, 0xba, 0x54}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x48, 0xd5, 0x39, 0x4a, 0x0b, 0x20, 0x6a, 0x43, 0xa0, 0x07, 0x82, 0x5e, 0x49, 0x7c, 0xc9, 0x47, 0xf1, 0x7c, 0x37, 0xb9, 0x23, 0xef, 0x6b, 0x46, 0x45, 0x8c, 0x45, 0x76, 0xdf, 0x14, 0x6b, 0x6e}} ,
|
||||
{{0x42, 0xc9, 0xca, 0x29, 0x4c, 0x76, 0x37, 0xda, 0x8a, 0x2d, 0x7c, 0x3a, 0x58, 0xf2, 0x03, 0xb4, 0xb5, 0xb9, 0x1a, 0x13, 0x2d, 0xde, 0x5f, 0x6b, 0x9d, 0xba, 0x52, 0xc9, 0x5d, 0xb3, 0xf3, 0x30}}},
|
||||
{{{0x4c, 0x6f, 0xfe, 0x6b, 0x0c, 0x62, 0xd7, 0x48, 0x71, 0xef, 0xb1, 0x85, 0x79, 0xc0, 0xed, 0x24, 0xb1, 0x08, 0x93, 0x76, 0x8e, 0xf7, 0x38, 0x8e, 0xeb, 0xfe, 0x80, 0x40, 0xaf, 0x90, 0x64, 0x49}} ,
|
||||
{{0x4a, 0x88, 0xda, 0xc1, 0x98, 0x44, 0x3c, 0x53, 0x4e, 0xdb, 0x4b, 0xb9, 0x12, 0x5f, 0xcd, 0x08, 0x04, 0xef, 0x75, 0xe7, 0xb1, 0x3a, 0xe5, 0x07, 0xfa, 0xca, 0x65, 0x7b, 0x72, 0x10, 0x64, 0x7f}}},
|
||||
{{{0x3d, 0x81, 0xf0, 0xeb, 0x16, 0xfd, 0x58, 0x33, 0x8d, 0x7c, 0x1a, 0xfb, 0x20, 0x2c, 0x8a, 0xee, 0x90, 0xbb, 0x33, 0x6d, 0x45, 0xe9, 0x8e, 0x99, 0x85, 0xe1, 0x08, 0x1f, 0xc5, 0xf1, 0xb5, 0x46}} ,
|
||||
{{0xe4, 0xe7, 0x43, 0x4b, 0xa0, 0x3f, 0x2b, 0x06, 0xba, 0x17, 0xae, 0x3d, 0xe6, 0xce, 0xbd, 0xb8, 0xed, 0x74, 0x11, 0x35, 0xec, 0x96, 0xfe, 0x31, 0xe3, 0x0e, 0x7a, 0x4e, 0xc9, 0x1d, 0xcb, 0x20}}},
|
||||
{{{0xe0, 0x67, 0xe9, 0x7b, 0xdb, 0x96, 0x5c, 0xb0, 0x32, 0xd0, 0x59, 0x31, 0x90, 0xdc, 0x92, 0x97, 0xac, 0x09, 0x38, 0x31, 0x0f, 0x7e, 0xd6, 0x5d, 0xd0, 0x06, 0xb6, 0x1f, 0xea, 0xf0, 0x5b, 0x07}} ,
|
||||
{{0x81, 0x9f, 0xc7, 0xde, 0x6b, 0x41, 0x22, 0x35, 0x14, 0x67, 0x77, 0x3e, 0x90, 0x81, 0xb0, 0xd9, 0x85, 0x4c, 0xca, 0x9b, 0x3f, 0x04, 0x59, 0xd6, 0xaa, 0x17, 0xc3, 0x88, 0x34, 0x37, 0xba, 0x43}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x4c, 0xb6, 0x69, 0xc8, 0x81, 0x95, 0x94, 0x33, 0x92, 0x34, 0xe9, 0x3c, 0x84, 0x0d, 0x3d, 0x5a, 0x37, 0x9c, 0x22, 0xa0, 0xaa, 0x65, 0xce, 0xb4, 0xc2, 0x2d, 0x66, 0x67, 0x02, 0xff, 0x74, 0x10}} ,
|
||||
{{0x22, 0xb0, 0xd5, 0xe6, 0xc7, 0xef, 0xb1, 0xa7, 0x13, 0xda, 0x60, 0xb4, 0x80, 0xc1, 0x42, 0x7d, 0x10, 0x70, 0x97, 0x04, 0x4d, 0xda, 0x23, 0x89, 0xc2, 0x0e, 0x68, 0xcb, 0xde, 0xe0, 0x9b, 0x29}}},
|
||||
{{{0x33, 0xfe, 0x42, 0x2a, 0x36, 0x2b, 0x2e, 0x36, 0x64, 0x5c, 0x8b, 0xcc, 0x81, 0x6a, 0x15, 0x08, 0xa1, 0x27, 0xe8, 0x57, 0xe5, 0x78, 0x8e, 0xf2, 0x58, 0x19, 0x12, 0x42, 0xae, 0xc4, 0x63, 0x3e}} ,
|
||||
{{0x78, 0x96, 0x9c, 0xa7, 0xca, 0x80, 0xae, 0x02, 0x85, 0xb1, 0x7c, 0x04, 0x5c, 0xc1, 0x5b, 0x26, 0xc1, 0xba, 0xed, 0xa5, 0x59, 0x70, 0x85, 0x8c, 0x8c, 0xe8, 0x87, 0xac, 0x6a, 0x28, 0x99, 0x35}}},
|
||||
{{{0x9f, 0x04, 0x08, 0x28, 0xbe, 0x87, 0xda, 0x80, 0x28, 0x38, 0xde, 0x9f, 0xcd, 0xe4, 0xe3, 0x62, 0xfb, 0x2e, 0x46, 0x8d, 0x01, 0xb3, 0x06, 0x51, 0xd4, 0x19, 0x3b, 0x11, 0xfa, 0xe2, 0xad, 0x1e}} ,
|
||||
{{0xa0, 0x20, 0x99, 0x69, 0x0a, 0xae, 0xa3, 0x70, 0x4e, 0x64, 0x80, 0xb7, 0x85, 0x9c, 0x87, 0x54, 0x43, 0x43, 0x55, 0x80, 0x6d, 0x8d, 0x7c, 0xa9, 0x64, 0xca, 0x6c, 0x2e, 0x21, 0xd8, 0xc8, 0x6c}}},
|
||||
{{{0x91, 0x4a, 0x07, 0xad, 0x08, 0x75, 0xc1, 0x4f, 0xa4, 0xb2, 0xc3, 0x6f, 0x46, 0x3e, 0xb1, 0xce, 0x52, 0xab, 0x67, 0x09, 0x54, 0x48, 0x6b, 0x6c, 0xd7, 0x1d, 0x71, 0x76, 0xcb, 0xff, 0xdd, 0x31}} ,
|
||||
{{0x36, 0x88, 0xfa, 0xfd, 0xf0, 0x36, 0x6f, 0x07, 0x74, 0x88, 0x50, 0xd0, 0x95, 0x38, 0x4a, 0x48, 0x2e, 0x07, 0x64, 0x97, 0x11, 0x76, 0x01, 0x1a, 0x27, 0x4d, 0x8e, 0x25, 0x9a, 0x9b, 0x1c, 0x22}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xbe, 0x57, 0xbd, 0x0e, 0x0f, 0xac, 0x5e, 0x76, 0xa3, 0x71, 0xad, 0x2b, 0x10, 0x45, 0x02, 0xec, 0x59, 0xd5, 0x5d, 0xa9, 0x44, 0xcc, 0x25, 0x4c, 0xb3, 0x3c, 0x5b, 0x69, 0x07, 0x55, 0x26, 0x6b}} ,
|
||||
{{0x30, 0x6b, 0xd4, 0xa7, 0x51, 0x29, 0xe3, 0xf9, 0x7a, 0x75, 0x2a, 0x82, 0x2f, 0xd6, 0x1d, 0x99, 0x2b, 0x80, 0xd5, 0x67, 0x1e, 0x15, 0x9d, 0xca, 0xfd, 0xeb, 0xac, 0x97, 0x35, 0x09, 0x7f, 0x3f}}},
|
||||
{{{0x35, 0x0d, 0x34, 0x0a, 0xb8, 0x67, 0x56, 0x29, 0x20, 0xf3, 0x19, 0x5f, 0xe2, 0x83, 0x42, 0x73, 0x53, 0xa8, 0xc5, 0x02, 0x19, 0x33, 0xb4, 0x64, 0xbd, 0xc3, 0x87, 0x8c, 0xd7, 0x76, 0xed, 0x25}} ,
|
||||
{{0x47, 0x39, 0x37, 0x76, 0x0d, 0x1d, 0x0c, 0xf5, 0x5a, 0x6d, 0x43, 0x88, 0x99, 0x15, 0xb4, 0x52, 0x0f, 0x2a, 0xb3, 0xb0, 0x3f, 0xa6, 0xb3, 0x26, 0xb3, 0xc7, 0x45, 0xf5, 0x92, 0x5f, 0x9b, 0x17}}},
|
||||
{{{0x9d, 0x23, 0xbd, 0x15, 0xfe, 0x52, 0x52, 0x15, 0x26, 0x79, 0x86, 0xba, 0x06, 0x56, 0x66, 0xbb, 0x8c, 0x2e, 0x10, 0x11, 0xd5, 0x4a, 0x18, 0x52, 0xda, 0x84, 0x44, 0xf0, 0x3e, 0xe9, 0x8c, 0x35}} ,
|
||||
{{0xad, 0xa0, 0x41, 0xec, 0xc8, 0x4d, 0xb9, 0xd2, 0x6e, 0x96, 0x4e, 0x5b, 0xc5, 0xc2, 0xa0, 0x1b, 0xcf, 0x0c, 0xbf, 0x17, 0x66, 0x57, 0xc1, 0x17, 0x90, 0x45, 0x71, 0xc2, 0xe1, 0x24, 0xeb, 0x27}}},
|
||||
{{{0x2c, 0xb9, 0x42, 0xa4, 0xaf, 0x3b, 0x42, 0x0e, 0xc2, 0x0f, 0xf2, 0xea, 0x83, 0xaf, 0x9a, 0x13, 0x17, 0xb0, 0xbd, 0x89, 0x17, 0xe3, 0x72, 0xcb, 0x0e, 0x76, 0x7e, 0x41, 0x63, 0x04, 0x88, 0x71}} ,
|
||||
{{0x75, 0x78, 0x38, 0x86, 0x57, 0xdd, 0x9f, 0xee, 0x54, 0x70, 0x65, 0xbf, 0xf1, 0x2c, 0xe0, 0x39, 0x0d, 0xe3, 0x89, 0xfd, 0x8e, 0x93, 0x4f, 0x43, 0xdc, 0xd5, 0x5b, 0xde, 0xf9, 0x98, 0xe5, 0x7b}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xe7, 0x3b, 0x65, 0x11, 0xdf, 0xb2, 0xf2, 0x63, 0x94, 0x12, 0x6f, 0x5c, 0x9e, 0x77, 0xc1, 0xb6, 0xd8, 0xab, 0x58, 0x7a, 0x1d, 0x95, 0x73, 0xdd, 0xe7, 0xe3, 0x6f, 0xf2, 0x03, 0x1d, 0xdb, 0x76}} ,
|
||||
{{0xae, 0x06, 0x4e, 0x2c, 0x52, 0x1b, 0xbc, 0x5a, 0x5a, 0xa5, 0xbe, 0x27, 0xbd, 0xeb, 0xe1, 0x14, 0x17, 0x68, 0x26, 0x07, 0x03, 0xd1, 0x18, 0x0b, 0xdf, 0xf1, 0x06, 0x5c, 0xa6, 0x1b, 0xb9, 0x24}}},
|
||||
{{{0xc5, 0x66, 0x80, 0x13, 0x0e, 0x48, 0x8c, 0x87, 0x31, 0x84, 0xb4, 0x60, 0xed, 0xc5, 0xec, 0xb6, 0xc5, 0x05, 0x33, 0x5f, 0x2f, 0x7d, 0x40, 0xb6, 0x32, 0x1d, 0x38, 0x74, 0x1b, 0xf1, 0x09, 0x3d}} ,
|
||||
{{0xd4, 0x69, 0x82, 0xbc, 0x8d, 0xf8, 0x34, 0x36, 0x75, 0x55, 0x18, 0x55, 0x58, 0x3c, 0x79, 0xaf, 0x26, 0x80, 0xab, 0x9b, 0x95, 0x00, 0xf1, 0xcb, 0xda, 0xc1, 0x9f, 0xf6, 0x2f, 0xa2, 0xf4, 0x45}}},
|
||||
{{{0x17, 0xbe, 0xeb, 0x85, 0xed, 0x9e, 0xcd, 0x56, 0xf5, 0x17, 0x45, 0x42, 0xb4, 0x1f, 0x44, 0x4c, 0x05, 0x74, 0x15, 0x47, 0x00, 0xc6, 0x6a, 0x3d, 0x24, 0x09, 0x0d, 0x58, 0xb1, 0x42, 0xd7, 0x04}} ,
|
||||
{{0x8d, 0xbd, 0xa3, 0xc4, 0x06, 0x9b, 0x1f, 0x90, 0x58, 0x60, 0x74, 0xb2, 0x00, 0x3b, 0x3c, 0xd2, 0xda, 0x82, 0xbb, 0x10, 0x90, 0x69, 0x92, 0xa9, 0xb4, 0x30, 0x81, 0xe3, 0x7c, 0xa8, 0x89, 0x45}}},
|
||||
{{{0x3f, 0xdc, 0x05, 0xcb, 0x41, 0x3c, 0xc8, 0x23, 0x04, 0x2c, 0x38, 0x99, 0xe3, 0x68, 0x55, 0xf9, 0xd3, 0x32, 0xc7, 0xbf, 0xfa, 0xd4, 0x1b, 0x5d, 0xde, 0xdc, 0x10, 0x42, 0xc0, 0x42, 0xd9, 0x75}} ,
|
||||
{{0x2d, 0xab, 0x35, 0x4e, 0x87, 0xc4, 0x65, 0x97, 0x67, 0x24, 0xa4, 0x47, 0xad, 0x3f, 0x8e, 0xf3, 0xcb, 0x31, 0x17, 0x77, 0xc5, 0xe2, 0xd7, 0x8f, 0x3c, 0xc1, 0xcd, 0x56, 0x48, 0xc1, 0x6c, 0x69}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x14, 0xae, 0x5f, 0x88, 0x7b, 0xa5, 0x90, 0xdf, 0x10, 0xb2, 0x8b, 0x5e, 0x24, 0x17, 0xc3, 0xa3, 0xd4, 0x0f, 0x92, 0x61, 0x1a, 0x19, 0x5a, 0xad, 0x76, 0xbd, 0xd8, 0x1c, 0xdd, 0xe0, 0x12, 0x6d}} ,
|
||||
{{0x8e, 0xbd, 0x70, 0x8f, 0x02, 0xa3, 0x24, 0x4d, 0x5a, 0x67, 0xc4, 0xda, 0xf7, 0x20, 0x0f, 0x81, 0x5b, 0x7a, 0x05, 0x24, 0x67, 0x83, 0x0b, 0x2a, 0x80, 0xe7, 0xfd, 0x74, 0x4b, 0x9e, 0x5c, 0x0d}}},
|
||||
{{{0x94, 0xd5, 0x5f, 0x1f, 0xa2, 0xfb, 0xeb, 0xe1, 0x07, 0x34, 0xf8, 0x20, 0xad, 0x81, 0x30, 0x06, 0x2d, 0xa1, 0x81, 0x95, 0x36, 0xcf, 0x11, 0x0b, 0xaf, 0xc1, 0x2b, 0x9a, 0x6c, 0x55, 0xc1, 0x16}} ,
|
||||
{{0x36, 0x4f, 0xf1, 0x5e, 0x74, 0x35, 0x13, 0x28, 0xd7, 0x11, 0xcf, 0xb8, 0xde, 0x93, 0xb3, 0x05, 0xb8, 0xb5, 0x73, 0xe9, 0xeb, 0xad, 0x19, 0x1e, 0x89, 0x0f, 0x8b, 0x15, 0xd5, 0x8c, 0xe3, 0x23}}},
|
||||
{{{0x33, 0x79, 0xe7, 0x18, 0xe6, 0x0f, 0x57, 0x93, 0x15, 0xa0, 0xa7, 0xaa, 0xc4, 0xbf, 0x4f, 0x30, 0x74, 0x95, 0x5e, 0x69, 0x4a, 0x5b, 0x45, 0xe4, 0x00, 0xeb, 0x23, 0x74, 0x4c, 0xdf, 0x6b, 0x45}} ,
|
||||
{{0x97, 0x29, 0x6c, 0xc4, 0x42, 0x0b, 0xdd, 0xc0, 0x29, 0x5c, 0x9b, 0x34, 0x97, 0xd0, 0xc7, 0x79, 0x80, 0x63, 0x74, 0xe4, 0x8e, 0x37, 0xb0, 0x2b, 0x7c, 0xe8, 0x68, 0x6c, 0xc3, 0x82, 0x97, 0x57}}},
|
||||
{{{0x22, 0xbe, 0x83, 0xb6, 0x4b, 0x80, 0x6b, 0x43, 0x24, 0x5e, 0xef, 0x99, 0x9b, 0xa8, 0xfc, 0x25, 0x8d, 0x3b, 0x03, 0x94, 0x2b, 0x3e, 0xe7, 0x95, 0x76, 0x9b, 0xcc, 0x15, 0xdb, 0x32, 0xe6, 0x66}} ,
|
||||
{{0x84, 0xf0, 0x4a, 0x13, 0xa6, 0xd6, 0xfa, 0x93, 0x46, 0x07, 0xf6, 0x7e, 0x5c, 0x6d, 0x5e, 0xf6, 0xa6, 0xe7, 0x48, 0xf0, 0x06, 0xea, 0xff, 0x90, 0xc1, 0xcc, 0x4c, 0x19, 0x9c, 0x3c, 0x4e, 0x53}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x2a, 0x50, 0xe3, 0x07, 0x15, 0x59, 0xf2, 0x8b, 0x81, 0xf2, 0xf3, 0xd3, 0x6c, 0x99, 0x8c, 0x70, 0x67, 0xec, 0xcc, 0xee, 0x9e, 0x59, 0x45, 0x59, 0x7d, 0x47, 0x75, 0x69, 0xf5, 0x24, 0x93, 0x5d}} ,
|
||||
{{0x6a, 0x4f, 0x1b, 0xbe, 0x6b, 0x30, 0xcf, 0x75, 0x46, 0xe3, 0x7b, 0x9d, 0xfc, 0xcd, 0xd8, 0x5c, 0x1f, 0xb4, 0xc8, 0xe2, 0x24, 0xec, 0x1a, 0x28, 0x05, 0x32, 0x57, 0xfd, 0x3c, 0x5a, 0x98, 0x10}}},
|
||||
{{{0xa3, 0xdb, 0xf7, 0x30, 0xd8, 0xc2, 0x9a, 0xe1, 0xd3, 0xce, 0x22, 0xe5, 0x80, 0x1e, 0xd9, 0xe4, 0x1f, 0xab, 0xc0, 0x71, 0x1a, 0x86, 0x0e, 0x27, 0x99, 0x5b, 0xfa, 0x76, 0x99, 0xb0, 0x08, 0x3c}} ,
|
||||
{{0x2a, 0x93, 0xd2, 0x85, 0x1b, 0x6a, 0x5d, 0xa6, 0xee, 0xd1, 0xd1, 0x33, 0xbd, 0x6a, 0x36, 0x73, 0x37, 0x3a, 0x44, 0xb4, 0xec, 0xa9, 0x7a, 0xde, 0x83, 0x40, 0xd7, 0xdf, 0x28, 0xba, 0xa2, 0x30}}},
|
||||
{{{0xd3, 0xb5, 0x6d, 0x05, 0x3f, 0x9f, 0xf3, 0x15, 0x8d, 0x7c, 0xca, 0xc9, 0xfc, 0x8a, 0x7c, 0x94, 0xb0, 0x63, 0x36, 0x9b, 0x78, 0xd1, 0x91, 0x1f, 0x93, 0xd8, 0x57, 0x43, 0xde, 0x76, 0xa3, 0x43}} ,
|
||||
{{0x9b, 0x35, 0xe2, 0xa9, 0x3d, 0x32, 0x1e, 0xbb, 0x16, 0x28, 0x70, 0xe9, 0x45, 0x2f, 0x8f, 0x70, 0x7f, 0x08, 0x7e, 0x53, 0xc4, 0x7a, 0xbf, 0xf7, 0xe1, 0xa4, 0x6a, 0xd8, 0xac, 0x64, 0x1b, 0x11}}},
|
||||
{{{0xb2, 0xeb, 0x47, 0x46, 0x18, 0x3e, 0x1f, 0x99, 0x0c, 0xcc, 0xf1, 0x2c, 0xe0, 0xe7, 0x8f, 0xe0, 0x01, 0x7e, 0x65, 0xb8, 0x0c, 0xd0, 0xfb, 0xc8, 0xb9, 0x90, 0x98, 0x33, 0x61, 0x3b, 0xd8, 0x27}} ,
|
||||
{{0xa0, 0xbe, 0x72, 0x3a, 0x50, 0x4b, 0x74, 0xab, 0x01, 0xc8, 0x93, 0xc5, 0xe4, 0xc7, 0x08, 0x6c, 0xb4, 0xca, 0xee, 0xeb, 0x8e, 0xd7, 0x4e, 0x26, 0xc6, 0x1d, 0xe2, 0x71, 0xaf, 0x89, 0xa0, 0x2a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x98, 0x0b, 0xe4, 0xde, 0xdb, 0xa8, 0xfa, 0x82, 0x74, 0x06, 0x52, 0x6d, 0x08, 0x52, 0x8a, 0xff, 0x62, 0xc5, 0x6a, 0x44, 0x0f, 0x51, 0x8c, 0x1f, 0x6e, 0xb6, 0xc6, 0x2c, 0x81, 0xd3, 0x76, 0x46}} ,
|
||||
{{0xf4, 0x29, 0x74, 0x2e, 0x80, 0xa7, 0x1a, 0x8f, 0xf6, 0xbd, 0xd6, 0x8e, 0xbf, 0xc1, 0x95, 0x2a, 0xeb, 0xa0, 0x7f, 0x45, 0xa0, 0x50, 0x14, 0x05, 0xb1, 0x57, 0x4c, 0x74, 0xb7, 0xe2, 0x89, 0x7d}}},
|
||||
{{{0x07, 0xee, 0xa7, 0xad, 0xb7, 0x09, 0x0b, 0x49, 0x4e, 0xbf, 0xca, 0xe5, 0x21, 0xe6, 0xe6, 0xaf, 0xd5, 0x67, 0xf3, 0xce, 0x7e, 0x7c, 0x93, 0x7b, 0x5a, 0x10, 0x12, 0x0e, 0x6c, 0x06, 0x11, 0x75}} ,
|
||||
{{0xd5, 0xfc, 0x86, 0xa3, 0x3b, 0xa3, 0x3e, 0x0a, 0xfb, 0x0b, 0xf7, 0x36, 0xb1, 0x5b, 0xda, 0x70, 0xb7, 0x00, 0xa7, 0xda, 0x88, 0x8f, 0x84, 0xa8, 0xbc, 0x1c, 0x39, 0xb8, 0x65, 0xf3, 0x4d, 0x60}}},
|
||||
{{{0x96, 0x9d, 0x31, 0xf4, 0xa2, 0xbe, 0x81, 0xb9, 0xa5, 0x59, 0x9e, 0xba, 0x07, 0xbe, 0x74, 0x58, 0xd8, 0xeb, 0xc5, 0x9f, 0x3d, 0xd1, 0xf4, 0xae, 0xce, 0x53, 0xdf, 0x4f, 0xc7, 0x2a, 0x89, 0x4d}} ,
|
||||
{{0x29, 0xd8, 0xf2, 0xaa, 0xe9, 0x0e, 0xf7, 0x2e, 0x5f, 0x9d, 0x8a, 0x5b, 0x09, 0xed, 0xc9, 0x24, 0x22, 0xf4, 0x0f, 0x25, 0x8f, 0x1c, 0x84, 0x6e, 0x34, 0x14, 0x6c, 0xea, 0xb3, 0x86, 0x5d, 0x04}}},
|
||||
{{{0x07, 0x98, 0x61, 0xe8, 0x6a, 0xd2, 0x81, 0x49, 0x25, 0xd5, 0x5b, 0x18, 0xc7, 0x35, 0x52, 0x51, 0xa4, 0x46, 0xad, 0x18, 0x0d, 0xc9, 0x5f, 0x18, 0x91, 0x3b, 0xb4, 0xc0, 0x60, 0x59, 0x8d, 0x66}} ,
|
||||
{{0x03, 0x1b, 0x79, 0x53, 0x6e, 0x24, 0xae, 0x57, 0xd9, 0x58, 0x09, 0x85, 0x48, 0xa2, 0xd3, 0xb5, 0xe2, 0x4d, 0x11, 0x82, 0xe6, 0x86, 0x3c, 0xe9, 0xb1, 0x00, 0x19, 0xc2, 0x57, 0xf7, 0x66, 0x7a}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x0f, 0xe3, 0x89, 0x03, 0xd7, 0x22, 0x95, 0x9f, 0xca, 0xb4, 0x8d, 0x9e, 0x6d, 0x97, 0xff, 0x8d, 0x21, 0x59, 0x07, 0xef, 0x03, 0x2d, 0x5e, 0xf8, 0x44, 0x46, 0xe7, 0x85, 0x80, 0xc5, 0x89, 0x50}} ,
|
||||
{{0x8b, 0xd8, 0x53, 0x86, 0x24, 0x86, 0x29, 0x52, 0x01, 0xfa, 0x20, 0xc3, 0x4e, 0x95, 0xcb, 0xad, 0x7b, 0x34, 0x94, 0x30, 0xb7, 0x7a, 0xfa, 0x96, 0x41, 0x60, 0x2b, 0xcb, 0x59, 0xb9, 0xca, 0x50}}},
|
||||
{{{0xc2, 0x5b, 0x9b, 0x78, 0x23, 0x1b, 0x3a, 0x88, 0x94, 0x5f, 0x0a, 0x9b, 0x98, 0x2b, 0x6e, 0x53, 0x11, 0xf6, 0xff, 0xc6, 0x7d, 0x42, 0xcc, 0x02, 0x80, 0x40, 0x0d, 0x1e, 0xfb, 0xaf, 0x61, 0x07}} ,
|
||||
{{0xb0, 0xe6, 0x2f, 0x81, 0x70, 0xa1, 0x2e, 0x39, 0x04, 0x7c, 0xc4, 0x2c, 0x87, 0x45, 0x4a, 0x5b, 0x69, 0x97, 0xac, 0x6d, 0x2c, 0x10, 0x42, 0x7c, 0x3b, 0x15, 0x70, 0x60, 0x0e, 0x11, 0x6d, 0x3a}}},
|
||||
{{{0x9b, 0x18, 0x80, 0x5e, 0xdb, 0x05, 0xbd, 0xc6, 0xb7, 0x3c, 0xc2, 0x40, 0x4d, 0x5d, 0xce, 0x97, 0x8a, 0x34, 0x15, 0xab, 0x28, 0x5d, 0x10, 0xf0, 0x37, 0x0c, 0xcc, 0x16, 0xfa, 0x1f, 0x33, 0x0d}} ,
|
||||
{{0x19, 0xf9, 0x35, 0xaa, 0x59, 0x1a, 0x0c, 0x5c, 0x06, 0xfc, 0x6a, 0x0b, 0x97, 0x53, 0x36, 0xfc, 0x2a, 0xa5, 0x5a, 0x9b, 0x30, 0xef, 0x23, 0xaf, 0x39, 0x5d, 0x9a, 0x6b, 0x75, 0x57, 0x48, 0x0b}}},
|
||||
{{{0x26, 0xdc, 0x76, 0x3b, 0xfc, 0xf9, 0x9c, 0x3f, 0x89, 0x0b, 0x62, 0x53, 0xaf, 0x83, 0x01, 0x2e, 0xbc, 0x6a, 0xc6, 0x03, 0x0d, 0x75, 0x2a, 0x0d, 0xe6, 0x94, 0x54, 0xcf, 0xb3, 0xe5, 0x96, 0x25}} ,
|
||||
{{0xfe, 0x82, 0xb1, 0x74, 0x31, 0x8a, 0xa7, 0x6f, 0x56, 0xbd, 0x8d, 0xf4, 0xe0, 0x94, 0x51, 0x59, 0xde, 0x2c, 0x5a, 0xf4, 0x84, 0x6b, 0x4a, 0x88, 0x93, 0xc0, 0x0c, 0x9a, 0xac, 0xa7, 0xa0, 0x68}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x25, 0x0d, 0xd6, 0xc7, 0x23, 0x47, 0x10, 0xad, 0xc7, 0x08, 0x5c, 0x87, 0x87, 0x93, 0x98, 0x18, 0xb8, 0xd3, 0x9c, 0xac, 0x5a, 0x3d, 0xc5, 0x75, 0xf8, 0x49, 0x32, 0x14, 0xcc, 0x51, 0x96, 0x24}} ,
|
||||
{{0x65, 0x9c, 0x5d, 0xf0, 0x37, 0x04, 0xf0, 0x34, 0x69, 0x2a, 0xf0, 0xa5, 0x64, 0xca, 0xde, 0x2b, 0x5b, 0x15, 0x10, 0xd2, 0xab, 0x06, 0xdd, 0xc4, 0xb0, 0xb6, 0x5b, 0xc1, 0x17, 0xdf, 0x8f, 0x02}}},
|
||||
{{{0xbd, 0x59, 0x3d, 0xbf, 0x5c, 0x31, 0x44, 0x2c, 0x32, 0x94, 0x04, 0x60, 0x84, 0x0f, 0xad, 0x00, 0xb6, 0x8f, 0xc9, 0x1d, 0xcc, 0x5c, 0xa2, 0x49, 0x0e, 0x50, 0x91, 0x08, 0x9a, 0x43, 0x55, 0x05}} ,
|
||||
{{0x5d, 0x93, 0x55, 0xdf, 0x9b, 0x12, 0x19, 0xec, 0x93, 0x85, 0x42, 0x9e, 0x66, 0x0f, 0x9d, 0xaf, 0x99, 0xaf, 0x26, 0x89, 0xbc, 0x61, 0xfd, 0xff, 0xce, 0x4b, 0xf4, 0x33, 0x95, 0xc9, 0x35, 0x58}}},
|
||||
{{{0x12, 0x55, 0xf9, 0xda, 0xcb, 0x44, 0xa7, 0xdc, 0x57, 0xe2, 0xf9, 0x9a, 0xe6, 0x07, 0x23, 0x60, 0x54, 0xa7, 0x39, 0xa5, 0x9b, 0x84, 0x56, 0x6e, 0xaa, 0x8b, 0x8f, 0xb0, 0x2c, 0x87, 0xaf, 0x67}} ,
|
||||
{{0x00, 0xa9, 0x4c, 0xb2, 0x12, 0xf8, 0x32, 0xa8, 0x7a, 0x00, 0x4b, 0x49, 0x32, 0xba, 0x1f, 0x5d, 0x44, 0x8e, 0x44, 0x7a, 0xdc, 0x11, 0xfb, 0x39, 0x08, 0x57, 0x87, 0xa5, 0x12, 0x42, 0x93, 0x0e}}},
|
||||
{{{0x17, 0xb4, 0xae, 0x72, 0x59, 0xd0, 0xaa, 0xa8, 0x16, 0x8b, 0x63, 0x11, 0xb3, 0x43, 0x04, 0xda, 0x0c, 0xa8, 0xb7, 0x68, 0xdd, 0x4e, 0x54, 0xe7, 0xaf, 0x5d, 0x5d, 0x05, 0x76, 0x36, 0xec, 0x0d}} ,
|
||||
{{0x6d, 0x7c, 0x82, 0x32, 0x38, 0x55, 0x57, 0x74, 0x5b, 0x7d, 0xc3, 0xc4, 0xfb, 0x06, 0x29, 0xf0, 0x13, 0x55, 0x54, 0xc6, 0xa7, 0xdc, 0x4c, 0x9f, 0x98, 0x49, 0x20, 0xa8, 0xc3, 0x8d, 0xfa, 0x48}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x87, 0x47, 0x9d, 0xe9, 0x25, 0xd5, 0xe3, 0x47, 0x78, 0xdf, 0x85, 0xa7, 0x85, 0x5e, 0x7a, 0x4c, 0x5f, 0x79, 0x1a, 0xf3, 0xa2, 0xb2, 0x28, 0xa0, 0x9c, 0xdd, 0x30, 0x40, 0xd4, 0x38, 0xbd, 0x28}} ,
|
||||
{{0xfc, 0xbb, 0xd5, 0x78, 0x6d, 0x1d, 0xd4, 0x99, 0xb4, 0xaa, 0x44, 0x44, 0x7a, 0x1b, 0xd8, 0xfe, 0xb4, 0x99, 0xb9, 0xcc, 0xe7, 0xc4, 0xd3, 0x3a, 0x73, 0x83, 0x41, 0x5c, 0x40, 0xd7, 0x2d, 0x55}}},
|
||||
{{{0x26, 0xe1, 0x7b, 0x5f, 0xe5, 0xdc, 0x3f, 0x7d, 0xa1, 0xa7, 0x26, 0x44, 0x22, 0x23, 0xc0, 0x8f, 0x7d, 0xf1, 0xb5, 0x11, 0x47, 0x7b, 0x19, 0xd4, 0x75, 0x6f, 0x1e, 0xa5, 0x27, 0xfe, 0xc8, 0x0e}} ,
|
||||
{{0xd3, 0x11, 0x3d, 0xab, 0xef, 0x2c, 0xed, 0xb1, 0x3d, 0x7c, 0x32, 0x81, 0x6b, 0xfe, 0xf8, 0x1c, 0x3c, 0x7b, 0xc0, 0x61, 0xdf, 0xb8, 0x75, 0x76, 0x7f, 0xaa, 0xd8, 0x93, 0xaf, 0x3d, 0xe8, 0x3d}}},
|
||||
{{{0xfd, 0x5b, 0x4e, 0x8d, 0xb6, 0x7e, 0x82, 0x9b, 0xef, 0xce, 0x04, 0x69, 0x51, 0x52, 0xff, 0xef, 0xa0, 0x52, 0xb5, 0x79, 0x17, 0x5e, 0x2f, 0xde, 0xd6, 0x3c, 0x2d, 0xa0, 0x43, 0xb4, 0x0b, 0x19}} ,
|
||||
{{0xc0, 0x61, 0x48, 0x48, 0x17, 0xf4, 0x9e, 0x18, 0x51, 0x2d, 0xea, 0x2f, 0xf2, 0xf2, 0xe0, 0xa3, 0x14, 0xb7, 0x8b, 0x3a, 0x30, 0xf5, 0x81, 0xc1, 0x5d, 0x71, 0x39, 0x62, 0x55, 0x1f, 0x60, 0x5a}}},
|
||||
{{{0xe5, 0x89, 0x8a, 0x76, 0x6c, 0xdb, 0x4d, 0x0a, 0x5b, 0x72, 0x9d, 0x59, 0x6e, 0x63, 0x63, 0x18, 0x7c, 0xe3, 0xfa, 0xe2, 0xdb, 0xa1, 0x8d, 0xf4, 0xa5, 0xd7, 0x16, 0xb2, 0xd0, 0xb3, 0x3f, 0x39}} ,
|
||||
{{0xce, 0x60, 0x09, 0x6c, 0xf5, 0x76, 0x17, 0x24, 0x80, 0x3a, 0x96, 0xc7, 0x94, 0x2e, 0xf7, 0x6b, 0xef, 0xb5, 0x05, 0x96, 0xef, 0xd3, 0x7b, 0x51, 0xda, 0x05, 0x44, 0x67, 0xbc, 0x07, 0x21, 0x4e}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xe9, 0x73, 0x6f, 0x21, 0xb9, 0xde, 0x22, 0x7d, 0xeb, 0x97, 0x31, 0x10, 0xa3, 0xea, 0xe1, 0xc6, 0x37, 0xeb, 0x8f, 0x43, 0x58, 0xde, 0x41, 0x64, 0x0e, 0x3e, 0x07, 0x99, 0x3d, 0xf1, 0xdf, 0x1e}} ,
|
||||
{{0xf8, 0xad, 0x43, 0xc2, 0x17, 0x06, 0xe2, 0xe4, 0xa9, 0x86, 0xcd, 0x18, 0xd7, 0x78, 0xc8, 0x74, 0x66, 0xd2, 0x09, 0x18, 0xa5, 0xf1, 0xca, 0xa6, 0x62, 0x92, 0xc1, 0xcb, 0x00, 0xeb, 0x42, 0x2e}}},
|
||||
{{{0x7b, 0x34, 0x24, 0x4c, 0xcf, 0x38, 0xe5, 0x6c, 0x0a, 0x01, 0x2c, 0x22, 0x0b, 0x24, 0x38, 0xad, 0x24, 0x7e, 0x19, 0xf0, 0x6c, 0xf9, 0x31, 0xf4, 0x35, 0x11, 0xf6, 0x46, 0x33, 0x3a, 0x23, 0x59}} ,
|
||||
{{0x20, 0x0b, 0xa1, 0x08, 0x19, 0xad, 0x39, 0x54, 0xea, 0x3e, 0x23, 0x09, 0xb6, 0xe2, 0xd2, 0xbc, 0x4d, 0xfc, 0x9c, 0xf0, 0x13, 0x16, 0x22, 0x3f, 0xb9, 0xd2, 0x11, 0x86, 0x90, 0x55, 0xce, 0x3c}}},
|
||||
{{{0xc4, 0x0b, 0x4b, 0x62, 0x99, 0x37, 0x84, 0x3f, 0x74, 0xa2, 0xf9, 0xce, 0xe2, 0x0b, 0x0f, 0x2a, 0x3d, 0xa3, 0xe3, 0xdb, 0x5a, 0x9d, 0x93, 0xcc, 0xa5, 0xef, 0x82, 0x91, 0x1d, 0xe6, 0x6c, 0x68}} ,
|
||||
{{0xa3, 0x64, 0x17, 0x9b, 0x8b, 0xc8, 0x3a, 0x61, 0xe6, 0x9d, 0xc6, 0xed, 0x7b, 0x03, 0x52, 0x26, 0x9d, 0x3a, 0xb3, 0x13, 0xcc, 0x8a, 0xfd, 0x2c, 0x1a, 0x1d, 0xed, 0x13, 0xd0, 0x55, 0x57, 0x0e}}},
|
||||
{{{0x1a, 0xea, 0xbf, 0xfd, 0x4a, 0x3c, 0x8e, 0xec, 0x29, 0x7e, 0x77, 0x77, 0x12, 0x99, 0xd7, 0x84, 0xf9, 0x55, 0x7f, 0xf1, 0x8b, 0xb4, 0xd2, 0x95, 0xa3, 0x8d, 0xf0, 0x8a, 0xa7, 0xeb, 0x82, 0x4b}} ,
|
||||
{{0x2c, 0x28, 0xf4, 0x3a, 0xf6, 0xde, 0x0a, 0xe0, 0x41, 0x44, 0x23, 0xf8, 0x3f, 0x03, 0x64, 0x9f, 0xc3, 0x55, 0x4c, 0xc6, 0xc1, 0x94, 0x1c, 0x24, 0x5d, 0x5f, 0x92, 0x45, 0x96, 0x57, 0x37, 0x14}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xc1, 0xcd, 0x90, 0x66, 0xb9, 0x76, 0xa0, 0x5b, 0xa5, 0x85, 0x75, 0x23, 0xf9, 0x89, 0xa5, 0x82, 0xb2, 0x6f, 0xb1, 0xeb, 0xc4, 0x69, 0x6f, 0x18, 0x5a, 0xed, 0x94, 0x3d, 0x9d, 0xd9, 0x2c, 0x1a}} ,
|
||||
{{0x35, 0xb0, 0xe6, 0x73, 0x06, 0xb7, 0x37, 0xe0, 0xf8, 0xb0, 0x22, 0xe8, 0xd2, 0xed, 0x0b, 0xef, 0xe6, 0xc6, 0x5a, 0x99, 0x9e, 0x1a, 0x9f, 0x04, 0x97, 0xe4, 0x4d, 0x0b, 0xbe, 0xba, 0x44, 0x40}}},
|
||||
{{{0xc1, 0x56, 0x96, 0x91, 0x5f, 0x1f, 0xbb, 0x54, 0x6f, 0x88, 0x89, 0x0a, 0xb2, 0xd6, 0x41, 0x42, 0x6a, 0x82, 0xee, 0x14, 0xaa, 0x76, 0x30, 0x65, 0x0f, 0x67, 0x39, 0xa6, 0x51, 0x7c, 0x49, 0x24}} ,
|
||||
{{0x35, 0xa3, 0x78, 0xd1, 0x11, 0x0f, 0x75, 0xd3, 0x70, 0x46, 0xdb, 0x20, 0x51, 0xcb, 0x92, 0x80, 0x54, 0x10, 0x74, 0x36, 0x86, 0xa9, 0xd7, 0xa3, 0x08, 0x78, 0xf1, 0x01, 0x29, 0xf8, 0x80, 0x3b}}},
|
||||
{{{0xdb, 0xa7, 0x9d, 0x9d, 0xbf, 0xa0, 0xcc, 0xed, 0x53, 0xa2, 0xa2, 0x19, 0x39, 0x48, 0x83, 0x19, 0x37, 0x58, 0xd1, 0x04, 0x28, 0x40, 0xf7, 0x8a, 0xc2, 0x08, 0xb7, 0xa5, 0x42, 0xcf, 0x53, 0x4c}} ,
|
||||
{{0xa7, 0xbb, 0xf6, 0x8e, 0xad, 0xdd, 0xf7, 0x90, 0xdd, 0x5f, 0x93, 0x89, 0xae, 0x04, 0x37, 0xe6, 0x9a, 0xb7, 0xe8, 0xc0, 0xdf, 0x16, 0x2a, 0xbf, 0xc4, 0x3a, 0x3c, 0x41, 0xd5, 0x89, 0x72, 0x5a}}},
|
||||
{{{0x1f, 0x96, 0xff, 0x34, 0x2c, 0x13, 0x21, 0xcb, 0x0a, 0x89, 0x85, 0xbe, 0xb3, 0x70, 0x9e, 0x1e, 0xde, 0x97, 0xaf, 0x96, 0x30, 0xf7, 0x48, 0x89, 0x40, 0x8d, 0x07, 0xf1, 0x25, 0xf0, 0x30, 0x58}} ,
|
||||
{{0x1e, 0xd4, 0x93, 0x57, 0xe2, 0x17, 0xe7, 0x9d, 0xab, 0x3c, 0x55, 0x03, 0x82, 0x2f, 0x2b, 0xdb, 0x56, 0x1e, 0x30, 0x2e, 0x24, 0x47, 0x6e, 0xe6, 0xff, 0x33, 0x24, 0x2c, 0x75, 0x51, 0xd4, 0x67}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0x2b, 0x06, 0xd9, 0xa1, 0x5d, 0xe1, 0xf4, 0xd1, 0x1e, 0x3c, 0x9a, 0xc6, 0x29, 0x2b, 0x13, 0x13, 0x78, 0xc0, 0xd8, 0x16, 0x17, 0x2d, 0x9e, 0xa9, 0xc9, 0x79, 0x57, 0xab, 0x24, 0x91, 0x92, 0x19}} ,
|
||||
{{0x69, 0xfb, 0xa1, 0x9c, 0xa6, 0x75, 0x49, 0x7d, 0x60, 0x73, 0x40, 0x42, 0xc4, 0x13, 0x0a, 0x95, 0x79, 0x1e, 0x04, 0x83, 0x94, 0x99, 0x9b, 0x1e, 0x0c, 0xe8, 0x1f, 0x54, 0xef, 0xcb, 0xc0, 0x52}}},
|
||||
{{{0x14, 0x89, 0x73, 0xa1, 0x37, 0x87, 0x6a, 0x7a, 0xcf, 0x1d, 0xd9, 0x2e, 0x1a, 0x67, 0xed, 0x74, 0xc0, 0xf0, 0x9c, 0x33, 0xdd, 0xdf, 0x08, 0xbf, 0x7b, 0xd1, 0x66, 0xda, 0xe6, 0xc9, 0x49, 0x08}} ,
|
||||
{{0xe9, 0xdd, 0x5e, 0x55, 0xb0, 0x0a, 0xde, 0x21, 0x4c, 0x5a, 0x2e, 0xd4, 0x80, 0x3a, 0x57, 0x92, 0x7a, 0xf1, 0xc4, 0x2c, 0x40, 0xaf, 0x2f, 0xc9, 0x92, 0x03, 0xe5, 0x5a, 0xbc, 0xdc, 0xf4, 0x09}}},
|
||||
{{{0xf3, 0xe1, 0x2b, 0x7c, 0x05, 0x86, 0x80, 0x93, 0x4a, 0xad, 0xb4, 0x8f, 0x7e, 0x99, 0x0c, 0xfd, 0xcd, 0xef, 0xd1, 0xff, 0x2c, 0x69, 0x34, 0x13, 0x41, 0x64, 0xcf, 0x3b, 0xd0, 0x90, 0x09, 0x1e}} ,
|
||||
{{0x9d, 0x45, 0xd6, 0x80, 0xe6, 0x45, 0xaa, 0xf4, 0x15, 0xaa, 0x5c, 0x34, 0x87, 0x99, 0xa2, 0x8c, 0x26, 0x84, 0x62, 0x7d, 0xb6, 0x29, 0xc0, 0x52, 0xea, 0xf5, 0x81, 0x18, 0x0f, 0x35, 0xa9, 0x0e}}},
|
||||
{{{0xe7, 0x20, 0x72, 0x7c, 0x6d, 0x94, 0x5f, 0x52, 0x44, 0x54, 0xe3, 0xf1, 0xb2, 0xb0, 0x36, 0x46, 0x0f, 0xae, 0x92, 0xe8, 0x70, 0x9d, 0x6e, 0x79, 0xb1, 0xad, 0x37, 0xa9, 0x5f, 0xc0, 0xde, 0x03}} ,
|
||||
{{0x15, 0x55, 0x37, 0xc6, 0x1c, 0x27, 0x1c, 0x6d, 0x14, 0x4f, 0xca, 0xa4, 0xc4, 0x88, 0x25, 0x46, 0x39, 0xfc, 0x5a, 0xe5, 0xfe, 0x29, 0x11, 0x69, 0xf5, 0x72, 0x84, 0x4d, 0x78, 0x9f, 0x94, 0x15}}},
|
||||
{{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
|
||||
{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
|
||||
{{{0xec, 0xd3, 0xff, 0x57, 0x0b, 0xb0, 0xb2, 0xdc, 0xf8, 0x4f, 0xe2, 0x12, 0xd5, 0x36, 0xbe, 0x6b, 0x09, 0x43, 0x6d, 0xa3, 0x4d, 0x90, 0x2d, 0xb8, 0x74, 0xe8, 0x71, 0x45, 0x19, 0x8b, 0x0c, 0x6a}} ,
|
||||
{{0xb8, 0x42, 0x1c, 0x03, 0xad, 0x2c, 0x03, 0x8e, 0xac, 0xd7, 0x98, 0x29, 0x13, 0xc6, 0x02, 0x29, 0xb5, 0xd4, 0xe7, 0xcf, 0xcc, 0x8b, 0x83, 0xec, 0x35, 0xc7, 0x9c, 0x74, 0xb7, 0xad, 0x85, 0x5f}}},
|
||||
{{{0x78, 0x84, 0xe1, 0x56, 0x45, 0x69, 0x68, 0x5a, 0x4f, 0xb8, 0xb1, 0x29, 0xff, 0x33, 0x03, 0x31, 0xb7, 0xcb, 0x96, 0x25, 0xe6, 0xe6, 0x41, 0x98, 0x1a, 0xbb, 0x03, 0x56, 0xf2, 0xb2, 0x91, 0x34}} ,
|
||||
{{0x2c, 0x6c, 0xf7, 0x66, 0xa4, 0x62, 0x6b, 0x39, 0xb3, 0xba, 0x65, 0xd3, 0x1c, 0xf8, 0x11, 0xaa, 0xbe, 0xdc, 0x80, 0x59, 0x87, 0xf5, 0x7b, 0xe5, 0xe3, 0xb3, 0x3e, 0x39, 0xda, 0xbe, 0x88, 0x09}}},
|
||||
{{{0x8b, 0xf1, 0xa0, 0xf5, 0xdc, 0x29, 0xb4, 0xe2, 0x07, 0xc6, 0x7a, 0x00, 0xd0, 0x89, 0x17, 0x51, 0xd4, 0xbb, 0xd4, 0x22, 0xea, 0x7e, 0x7d, 0x7c, 0x24, 0xea, 0xf2, 0xe8, 0x22, 0x12, 0x95, 0x06}} ,
|
||||
{{0xda, 0x7c, 0xa4, 0x0c, 0xf4, 0xba, 0x6e, 0xe1, 0x89, 0xb5, 0x59, 0xca, 0xf1, 0xc0, 0x29, 0x36, 0x09, 0x44, 0xe2, 0x7f, 0xd1, 0x63, 0x15, 0x99, 0xea, 0x25, 0xcf, 0x0c, 0x9d, 0xc0, 0x44, 0x6f}}},
|
||||
{{{0x1d, 0x86, 0x4e, 0xcf, 0xf7, 0x37, 0x10, 0x25, 0x8f, 0x12, 0xfb, 0x19, 0xfb, 0xe0, 0xed, 0x10, 0xc8, 0xe2, 0xf5, 0x75, 0xb1, 0x33, 0xc0, 0x96, 0x0d, 0xfb, 0x15, 0x6c, 0x0d, 0x07, 0x5f, 0x05}} ,
|
||||
{{0x69, 0x3e, 0x47, 0x97, 0x2c, 0xaf, 0x52, 0x7c, 0x78, 0x83, 0xad, 0x1b, 0x39, 0x82, 0x2f, 0x02, 0x6f, 0x47, 0xdb, 0x2a, 0xb0, 0xe1, 0x91, 0x99, 0x55, 0xb8, 0x99, 0x3a, 0xa0, 0x44, 0x11, 0x51}}}
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2011 by Andreas Schneider <mail@cryptomilk.org>
|
||||
* Copyright (c) 2011-2013 by Andreas Schneider <mail@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -49,7 +49,7 @@ struct ssh_gssapi_struct{
|
||||
enum ssh_gssapi_state_e state; /* current state */
|
||||
struct gss_OID_desc_struct mech; /* mechanism being elected for auth */
|
||||
gss_cred_id_t server_creds; /* credentials of server */
|
||||
gss_cred_id_t client_creds; /* creds of the client */
|
||||
gss_cred_id_t client_creds; /* creds delegated by the client */
|
||||
gss_ctx_id_t ctx; /* the authentication context */
|
||||
gss_name_t client_name; /* Identity of the client */
|
||||
char *user; /* username of client */
|
||||
@ -57,7 +57,9 @@ struct ssh_gssapi_struct{
|
||||
char *service; /* name of the service */
|
||||
struct {
|
||||
gss_name_t server_name; /* identity of server */
|
||||
OM_uint32 flags; /* flags used for init context */
|
||||
gss_OID oid; /* mech being used for authentication */
|
||||
gss_cred_id_t creds; /* creds used to initialize context */
|
||||
gss_cred_id_t client_deleg_creds; /* delegated creds (const, not freeable) */
|
||||
} client;
|
||||
};
|
||||
@ -89,12 +91,13 @@ static void ssh_gssapi_free(ssh_session session){
|
||||
OM_uint32 min;
|
||||
if (session->gssapi == NULL)
|
||||
return;
|
||||
if (session->gssapi->mech.elements)
|
||||
SAFE_FREE(session->gssapi->mech.elements);
|
||||
if (session->gssapi->user)
|
||||
SAFE_FREE(session->gssapi->user);
|
||||
if (session->gssapi->server_creds)
|
||||
gss_release_cred(&min,&session->gssapi->server_creds);
|
||||
SAFE_FREE(session->gssapi->user);
|
||||
SAFE_FREE(session->gssapi->mech.elements);
|
||||
gss_release_cred(&min,&session->gssapi->server_creds);
|
||||
if (session->gssapi->client.creds !=
|
||||
session->gssapi->client.client_deleg_creds) {
|
||||
gss_release_cred(&min, &session->gssapi->client.creds);
|
||||
}
|
||||
SAFE_FREE(session->gssapi);
|
||||
}
|
||||
|
||||
@ -208,8 +211,8 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
||||
maj_stat = gss_import_name(&min_stat, &name_buf,
|
||||
(gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &server_name);
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
SSH_LOG(0, "importing name %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(0, "importing name", maj_stat);
|
||||
SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -220,13 +223,13 @@ int ssh_gssapi_handle_userauth(ssh_session session, const char *user, uint32_t n
|
||||
gss_release_oid_set(&min_stat, &both_supported);
|
||||
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
SSH_LOG(0, "error acquiring credentials %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(0, "acquiring creds", maj_stat);
|
||||
SSH_LOG(SSH_LOG_WARNING, "error acquiring credentials %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING, "acquiring creds", maj_stat);
|
||||
ssh_auth_reply_default(session,0);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(0, "acquiring credentials %d, %d", maj_stat, min_stat);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "acquiring credentials %d, %d", maj_stat, min_stat);
|
||||
|
||||
/* finding which OID from client we selected */
|
||||
for (i=0 ; i< n_oid ; ++i){
|
||||
@ -263,7 +266,7 @@ static char *ssh_gssapi_name_to_char(gss_name_t name){
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
char *ptr;
|
||||
maj_stat = gss_display_name(&min_stat, name, &buffer, NULL);
|
||||
ssh_gssapi_log_error(0, "converting name", maj_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING, "converting name", maj_stat);
|
||||
ptr=malloc(buffer.length + 1);
|
||||
memcpy(ptr, buffer.value, buffer.length);
|
||||
ptr[buffer.length] = '\0';
|
||||
@ -308,14 +311,11 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
if (ssh_string_len(out_token) != 0){
|
||||
rc = buffer_add_u8(session->out_buffer,
|
||||
SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
rc = buffer_add_ssh_string(session->out_buffer, out_token);
|
||||
if (rc < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bS",
|
||||
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
|
||||
out_token);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
@ -335,14 +335,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
||||
maj_stat = gss_accept_sec_context(&min_stat, &session->gssapi->ctx, session->gssapi->server_creds,
|
||||
&input_token, input_bindings, &client_name, NULL /*mech_oid*/, &output_token, &ret_flags,
|
||||
NULL /*time*/, &session->gssapi->client_creds);
|
||||
ssh_gssapi_log_error(0, "accepting token", maj_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat);
|
||||
ssh_string_free(token);
|
||||
if (client_name != GSS_C_NO_NAME){
|
||||
session->gssapi->client_name = client_name;
|
||||
session->gssapi->canonic_user = ssh_gssapi_name_to_char(client_name);
|
||||
}
|
||||
if (GSS_ERROR(maj_stat)){
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "Gssapi error", maj_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING, "Gssapi error", maj_stat);
|
||||
ssh_auth_reply_default(session,0);
|
||||
ssh_gssapi_free(session);
|
||||
session->gssapi=NULL;
|
||||
@ -353,12 +353,12 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
||||
hexa = ssh_get_hexa(output_token.value, output_token.length);
|
||||
SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa);
|
||||
SAFE_FREE(hexa);
|
||||
token = ssh_string_new(output_token.length);
|
||||
ssh_string_fill(token, output_token.value, output_token.length);
|
||||
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||
buffer_add_ssh_string(session->out_buffer,token);
|
||||
ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
|
||||
output_token.length,
|
||||
(size_t)output_token.length, output_token.value);
|
||||
packet_send(session);
|
||||
ssh_string_free(token);
|
||||
}
|
||||
if(maj_stat == GSS_S_COMPLETE){
|
||||
session->gssapi->state = SSH_GSSAPI_STATE_RCV_MIC;
|
||||
@ -370,69 +370,24 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_server){
|
||||
|
||||
static ssh_buffer ssh_gssapi_build_mic(ssh_session session){
|
||||
ssh_buffer mic_buffer;
|
||||
ssh_string str;
|
||||
int rc;
|
||||
|
||||
str = ssh_string_new(session->current_crypto->digest_len);
|
||||
if (str == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(str, session->current_crypto->session_id,
|
||||
session->current_crypto->digest_len);
|
||||
|
||||
mic_buffer = ssh_buffer_new();
|
||||
if (mic_buffer == NULL) {
|
||||
ssh_string_free(str);
|
||||
ssh_set_error_oom(session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(mic_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = buffer_add_u8(mic_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = ssh_string_from_char(session->gssapi->user);
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(mic_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
rc = buffer_add_ssh_string(mic_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
str = ssh_string_from_char("gssapi-with-mic");
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(mic_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
rc = ssh_buffer_pack(mic_buffer,
|
||||
"dPbsss",
|
||||
session->current_crypto->digest_len,
|
||||
(size_t)session->current_crypto->digest_len, session->current_crypto->session_id,
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
session->gssapi->user,
|
||||
"ssh-connection",
|
||||
"gssapi-with-mic");
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(mic_buffer);
|
||||
return NULL;
|
||||
}
|
||||
@ -484,8 +439,8 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_mic)
|
||||
mic_token_buf.value = ssh_string_data(mic_token);
|
||||
|
||||
maj_stat = gss_verify_mic(&min_stat, session->gssapi->ctx, &mic_buf, &mic_token_buf, NULL);
|
||||
ssh_gssapi_log_error(0, "verifying MIC", maj_stat);
|
||||
ssh_gssapi_log_error(0, "verifying MIC (min stat)", min_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC", maj_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "verifying MIC (min stat)", min_stat);
|
||||
if (maj_stat == GSS_S_DEFECTIVE_TOKEN || GSS_ERROR(maj_stat)) {
|
||||
goto error;
|
||||
}
|
||||
@ -536,8 +491,12 @@ ssh_gssapi_creds ssh_gssapi_get_creds(ssh_session session){
|
||||
return (ssh_gssapi_creds)session->gssapi->client_creds;
|
||||
}
|
||||
|
||||
#endif /* SERVER */
|
||||
|
||||
/**
|
||||
* @brief Set the forwadable ticket to be given to the server for authentication.
|
||||
* Unlike ssh_gssapi_get_creds() this is called on the client side of an ssh
|
||||
* connection.
|
||||
*
|
||||
* @param[in] creds gssapi credentials handle.
|
||||
*/
|
||||
@ -556,49 +515,20 @@ void ssh_gssapi_set_creds(ssh_session session, const ssh_gssapi_creds creds)
|
||||
session->gssapi->client.client_deleg_creds = (gss_cred_id_t)creds;
|
||||
}
|
||||
|
||||
#endif /* SERVER */
|
||||
|
||||
static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, int n_oid){
|
||||
ssh_string str;
|
||||
int rc;
|
||||
int i;
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
/* username */
|
||||
str = ssh_string_from_char(session->opts.username);
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
/* service */
|
||||
str = ssh_string_from_char("ssh-connection");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
/* method */
|
||||
str = ssh_string_from_char("gssapi-with-mic");
|
||||
if (str == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
rc = buffer_add_ssh_string(session->out_buffer, str);
|
||||
ssh_string_free(str);
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->out_buffer, htonl(n_oid));
|
||||
if (rc < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bsssd",
|
||||
SSH2_MSG_USERAUTH_REQUEST,
|
||||
session->opts.username,
|
||||
"ssh-connection",
|
||||
"gssapi-with-mic",
|
||||
n_oid);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -612,92 +542,79 @@ static int ssh_gssapi_send_auth_mic(ssh_session session, ssh_string *oid_set, in
|
||||
session->auth_state = SSH_AUTH_STATE_GSSAPI_REQUEST_SENT;
|
||||
return packet_send(session);
|
||||
fail:
|
||||
buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/** @brief returns the OIDs of the mechs that work with both
|
||||
* hostname and username
|
||||
/** @brief returns the OIDs of the mechs that have usable credentials
|
||||
*/
|
||||
static int ssh_gssapi_match(ssh_session session, char *hostname, char *username, gss_OID_set *valid_oids, int deleg){
|
||||
gss_buffer_desc host_namebuf, user_namebuf;
|
||||
gss_name_t host_name, user_name;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
gss_OID_set supported;
|
||||
static int ssh_gssapi_match(ssh_session session, gss_OID_set *valid_oids)
|
||||
{
|
||||
OM_uint32 maj_stat, min_stat, lifetime;
|
||||
gss_OID_set actual_mechs;
|
||||
gss_buffer_desc namebuf;
|
||||
gss_name_t client_id = GSS_C_NO_NAME;
|
||||
gss_OID oid;
|
||||
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_cred_id_t client_creds = GSS_C_NO_CREDENTIAL;
|
||||
unsigned int i;
|
||||
char *ptr;
|
||||
char hostname_buf[256];
|
||||
int ret;
|
||||
|
||||
if (session->gssapi->client.client_deleg_creds == NULL) {
|
||||
if (session->opts.gss_client_identity != NULL) {
|
||||
namebuf.value = (void *)session->opts.gss_client_identity;
|
||||
namebuf.length = strlen(session->opts.gss_client_identity);
|
||||
|
||||
gss_create_empty_oid_set(&min_stat, valid_oids);
|
||||
maj_stat = gss_indicate_mechs(&min_stat, &supported);
|
||||
for (i=0; i < supported->count; ++i){
|
||||
ptr=ssh_get_hexa(supported->elements[i].elements, supported->elements[i].length);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "GSSAPI oid supported %d : %s\n",i, ptr);
|
||||
SAFE_FREE(ptr);
|
||||
}
|
||||
|
||||
user_namebuf.value = username;
|
||||
user_namebuf.length = strlen(username) + 1;
|
||||
maj_stat = gss_import_name(&min_stat, &user_namebuf,
|
||||
(gss_OID) GSS_C_NT_USER_NAME, &user_name);
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
SSH_LOG(SSH_LOG_DEBUG, "importing name %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_DEBUG, "importing name", maj_stat);
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(hostname_buf, sizeof(hostname_buf),"host@%s", hostname);
|
||||
host_namebuf.value = hostname_buf;
|
||||
host_namebuf.length = strlen(hostname_buf) + 1;
|
||||
maj_stat = gss_import_name(&min_stat, &host_namebuf,
|
||||
(gss_OID) GSS_C_NT_HOSTBASED_SERVICE, &host_name);
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
SSH_LOG(0, "importing name %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(0, "importing name", maj_stat);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssh_gssapi_init(session);
|
||||
session->gssapi->client_name = user_name;
|
||||
session->gssapi->client.server_name = host_name;
|
||||
session->gssapi->user = strdup(username);
|
||||
for (i=0; i<supported->count; ++i){
|
||||
oid = &supported->elements[i];
|
||||
maj_stat = gss_init_sec_context(&min_stat,
|
||||
session->gssapi->client.client_deleg_creds, &ctx, host_name, oid,
|
||||
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0),
|
||||
0, NULL, &input_token, NULL, &output_token, NULL, NULL);
|
||||
if (!GSS_ERROR(maj_stat)){
|
||||
gss_OID_set tmp;
|
||||
if (session->gssapi->client.client_deleg_creds != GSS_C_NO_CREDENTIAL){
|
||||
/* we know the oid is ok since init_sec_context worked */
|
||||
gss_add_oid_set_member(&min_stat, oid, valid_oids);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Matched oid %u for server (with forwarding)", i);
|
||||
} else {
|
||||
gss_create_empty_oid_set(&min_stat, &tmp);
|
||||
gss_add_oid_set_member(&min_stat, oid, &tmp);
|
||||
maj_stat = gss_acquire_cred(&min_stat, user_name, 0,
|
||||
tmp, GSS_C_INITIATE,
|
||||
&client_creds, NULL, NULL);
|
||||
gss_release_oid_set(&min_stat, &tmp);
|
||||
if (!GSS_ERROR(maj_stat)){
|
||||
gss_release_cred(&min_stat, &client_creds);
|
||||
gss_add_oid_set_member(&min_stat,oid,valid_oids);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Matched oid %u for server", i);
|
||||
}
|
||||
maj_stat = gss_import_name(&min_stat, &namebuf,
|
||||
GSS_C_NT_USER_NAME, &client_id);
|
||||
if (GSS_ERROR(maj_stat)) {
|
||||
ret = SSH_ERROR;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
gss_delete_sec_context(&min_stat,&ctx, &output_token);
|
||||
ctx = GSS_C_NO_CONTEXT;
|
||||
|
||||
maj_stat = gss_acquire_cred(&min_stat, client_id, GSS_C_INDEFINITE,
|
||||
GSS_C_NO_OID_SET, GSS_C_INITIATE,
|
||||
&session->gssapi->client.creds,
|
||||
&actual_mechs, NULL);
|
||||
if (GSS_ERROR(maj_stat)) {
|
||||
ret = SSH_ERROR;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
session->gssapi->client.creds =
|
||||
session->gssapi->client.client_deleg_creds;
|
||||
|
||||
maj_stat = gss_inquire_cred(&min_stat, session->gssapi->client.creds,
|
||||
&client_id, NULL, NULL, &actual_mechs);
|
||||
if (GSS_ERROR(maj_stat)) {
|
||||
ret = SSH_ERROR;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
gss_create_empty_oid_set(&min_stat, valid_oids);
|
||||
|
||||
/* double check each single cred */
|
||||
for (i = 0; i < actual_mechs->count; i++) {
|
||||
/* check lifetime is not 0 or skip */
|
||||
lifetime = 0;
|
||||
oid = &actual_mechs->elements[i];
|
||||
maj_stat = gss_inquire_cred_by_mech(&min_stat,
|
||||
session->gssapi->client.creds,
|
||||
oid, NULL, &lifetime, NULL, NULL);
|
||||
if (maj_stat == GSS_S_COMPLETE && lifetime > 0) {
|
||||
gss_add_oid_set_member(&min_stat, oid, valid_oids);
|
||||
ptr = ssh_get_hexa(oid->elements, oid->length);
|
||||
SSH_LOG(SSH_LOG_DEBUG, "GSSAPI valid oid %d : %s\n", i, ptr);
|
||||
SAFE_FREE(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
ret = SSH_OK;
|
||||
|
||||
end:
|
||||
gss_release_name(&min_stat, &client_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -713,21 +630,55 @@ int ssh_gssapi_auth_mic(ssh_session session){
|
||||
ssh_string *oids;
|
||||
int rc;
|
||||
int n_oids = 0;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
char name_buf[256];
|
||||
gss_buffer_desc hostname;
|
||||
const char *gss_host = session->opts.host;
|
||||
|
||||
if (ssh_gssapi_init(session) == SSH_ERROR)
|
||||
rc = ssh_gssapi_init(session);
|
||||
if (rc == SSH_ERROR) {
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
if (session->opts.gss_server_identity != NULL) {
|
||||
gss_host = session->opts.gss_server_identity;
|
||||
}
|
||||
/* import target host name */
|
||||
snprintf(name_buf, sizeof(name_buf), "host@%s", gss_host);
|
||||
|
||||
hostname.value = name_buf;
|
||||
hostname.length = strlen(name_buf) + 1;
|
||||
maj_stat = gss_import_name(&min_stat, &hostname,
|
||||
(gss_OID)GSS_C_NT_HOSTBASED_SERVICE,
|
||||
&session->gssapi->client.server_name);
|
||||
if (maj_stat != GSS_S_COMPLETE) {
|
||||
SSH_LOG(SSH_LOG_WARNING, "importing name %d, %d", maj_stat, min_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING, "importing name", maj_stat);
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
/* copy username */
|
||||
session->gssapi->user = strdup(session->opts.username);
|
||||
if (session->gssapi->user == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Authenticating with gssapi to host %s with user %s",
|
||||
session->opts.host, session->opts.username);
|
||||
rc = ssh_gssapi_match(session,session->opts.host, session->opts.username, &selected, 0);
|
||||
if (rc == SSH_ERROR)
|
||||
session->opts.host, session->gssapi->user);
|
||||
rc = ssh_gssapi_match(session, &selected);
|
||||
if (rc == SSH_ERROR) {
|
||||
return SSH_AUTH_DENIED;
|
||||
}
|
||||
|
||||
n_oids = selected->count;
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Sending %d oids", n_oids);
|
||||
|
||||
oids = calloc(n_oids, sizeof(ssh_string));
|
||||
if (oids == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_AUTH_ERROR;
|
||||
}
|
||||
|
||||
for (i=0; i<n_oids; ++i){
|
||||
oids[i] = ssh_string_new(selected->elements[i].length + 2);
|
||||
@ -769,15 +720,10 @@ static gss_OID ssh_gssapi_oid_from_string(ssh_string oid_s){
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
|
||||
ssh_string oid_s;
|
||||
gss_OID oid;
|
||||
gss_uint32 maj_stat, min_stat;
|
||||
int deleg = 0;
|
||||
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_OID_set tmp;
|
||||
char *hexa;
|
||||
ssh_string token;
|
||||
gss_cred_id_t creds = GSS_C_NO_CREDENTIAL;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
@ -791,31 +737,27 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
|
||||
ssh_set_error(session, SSH_FATAL, "Missing OID");
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
oid = ssh_gssapi_oid_from_string(oid_s);
|
||||
session->gssapi->client.oid = ssh_gssapi_oid_from_string(oid_s);
|
||||
ssh_string_free(oid_s);
|
||||
if (!oid) {
|
||||
if (!session->gssapi->client.oid) {
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid OID");
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
if (session->gssapi->client.client_deleg_creds != GSS_C_NO_CREDENTIAL)
|
||||
creds = session->gssapi->client.client_deleg_creds;
|
||||
if (creds == GSS_C_NO_CREDENTIAL){
|
||||
gss_create_empty_oid_set(&min_stat, &tmp);
|
||||
gss_add_oid_set_member(&min_stat, oid, &tmp);
|
||||
maj_stat = gss_acquire_cred(&min_stat, session->gssapi->client_name, 0,
|
||||
tmp, GSS_C_INITIATE,
|
||||
&session->gssapi->client_creds, NULL, NULL);
|
||||
gss_release_oid_set(&min_stat, &tmp);
|
||||
if (GSS_ERROR(maj_stat)){
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING,"Error acquiring credentials",maj_stat);
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
session->gssapi->client.flags = GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG;
|
||||
if (session->opts.gss_delegate_creds) {
|
||||
session->gssapi->client.flags |= GSS_C_DELEG_FLAG;
|
||||
}
|
||||
|
||||
/* prepare the first TOKEN response */
|
||||
maj_stat = gss_init_sec_context(&min_stat,
|
||||
creds, &session->gssapi->ctx, session->gssapi->client.server_name, oid,
|
||||
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0),
|
||||
0, NULL, &input_token, NULL, &output_token, NULL, NULL);
|
||||
session->gssapi->client.creds,
|
||||
&session->gssapi->ctx,
|
||||
session->gssapi->client.server_name,
|
||||
session->gssapi->client.oid,
|
||||
session->gssapi->client.flags,
|
||||
0, NULL, &input_token, NULL,
|
||||
&output_token, NULL, NULL);
|
||||
if(GSS_ERROR(maj_stat)){
|
||||
ssh_gssapi_log_error(SSH_LOG_WARNING, "Initializing gssapi context", maj_stat);
|
||||
return SSH_PACKET_USED;
|
||||
@ -824,15 +766,14 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_response){
|
||||
hexa = ssh_get_hexa(output_token.value, output_token.length);
|
||||
SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa);
|
||||
SAFE_FREE(hexa);
|
||||
token = ssh_string_new(output_token.length);
|
||||
ssh_string_fill(token, output_token.value, output_token.length);
|
||||
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||
buffer_add_ssh_string(session->out_buffer,token);
|
||||
ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
|
||||
output_token.length,
|
||||
(size_t)output_token.length, output_token.value);
|
||||
packet_send(session);
|
||||
ssh_string_free(token);
|
||||
session->auth_state = SSH_AUTH_STATE_GSSAPI_TOKEN;
|
||||
}
|
||||
session->gssapi->client.oid = oid;
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
@ -856,31 +797,21 @@ static int ssh_gssapi_send_mic(ssh_session session){
|
||||
maj_stat = gss_get_mic(&min_stat,session->gssapi->ctx, GSS_C_QOP_DEFAULT, &mic_buf, &mic_token_buf);
|
||||
if (GSS_ERROR(maj_stat)){
|
||||
ssh_buffer_free(mic_buffer);
|
||||
ssh_gssapi_log_error(0, "generating MIC", maj_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "generating MIC", maj_stat);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_MIC);
|
||||
if (rc < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_USERAUTH_GSSAPI_MIC,
|
||||
mic_token_buf.length,
|
||||
(size_t)mic_token_buf.length, mic_token_buf.value);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->out_buffer, htonl(mic_token_buf.length));
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(mic_buffer);
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_data(session->out_buffer, mic_token_buf.value, mic_token_buf.length);
|
||||
ssh_buffer_free(mic_buffer);
|
||||
if (rc < 0) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
return packet_send(session);
|
||||
}
|
||||
|
||||
@ -889,8 +820,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
|
||||
char *hexa;
|
||||
OM_uint32 maj_stat, min_stat;
|
||||
gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER;
|
||||
gss_cred_id_t creds = GSS_C_NO_CREDENTIAL;
|
||||
int deleg = 0;
|
||||
(void)user;
|
||||
(void)type;
|
||||
|
||||
@ -910,16 +839,16 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
|
||||
SAFE_FREE(hexa);
|
||||
input_token.length = ssh_string_len(token);
|
||||
input_token.value = ssh_string_data(token);
|
||||
if (session->gssapi->client.client_deleg_creds != GSS_C_NO_CREDENTIAL)
|
||||
creds = session->gssapi->client.client_deleg_creds;
|
||||
else
|
||||
creds = session->gssapi->client_creds;
|
||||
maj_stat = gss_init_sec_context(&min_stat,
|
||||
creds, &session->gssapi->ctx, session->gssapi->client.server_name, session->gssapi->client.oid,
|
||||
GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | (deleg ? GSS_C_DELEG_FLAG : 0),
|
||||
0, NULL, &input_token, NULL, &output_token, NULL, NULL);
|
||||
session->gssapi->client.creds,
|
||||
&session->gssapi->ctx,
|
||||
session->gssapi->client.server_name,
|
||||
session->gssapi->client.oid,
|
||||
session->gssapi->client.flags,
|
||||
0, NULL, &input_token, NULL,
|
||||
&output_token, NULL, NULL);
|
||||
|
||||
ssh_gssapi_log_error(0, "accepting token", maj_stat);
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "accepting token", maj_stat);
|
||||
ssh_string_free(token);
|
||||
if (GSS_ERROR(maj_stat)){
|
||||
ssh_gssapi_log_error(SSH_LOG_PROTOCOL, "Gssapi error", maj_stat);
|
||||
@ -932,12 +861,12 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_gssapi_token_client){
|
||||
hexa = ssh_get_hexa(output_token.value, output_token.length);
|
||||
SSH_LOG(SSH_LOG_PACKET, "GSSAPI: sending token %s",hexa);
|
||||
SAFE_FREE(hexa);
|
||||
token = ssh_string_new(output_token.length);
|
||||
ssh_string_fill(token, output_token.value, output_token.length);
|
||||
buffer_add_u8(session->out_buffer, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
|
||||
buffer_add_ssh_string(session->out_buffer,token);
|
||||
ssh_buffer_pack(session->out_buffer,
|
||||
"bdP",
|
||||
SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
|
||||
output_token.length,
|
||||
(size_t)output_token.length, output_token.value);
|
||||
packet_send(session);
|
||||
ssh_string_free(token);
|
||||
}
|
||||
if(maj_stat == GSS_S_COMPLETE){
|
||||
session->auth_state = SSH_AUTH_STATE_NONE;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2009 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -90,7 +90,7 @@ static ssh_buffer gzip_compress(ssh_session session,ssh_buffer source,int level)
|
||||
return NULL;
|
||||
}
|
||||
len = BLOCKSIZE - zout->avail_out;
|
||||
if (buffer_add_data(dest, out_buf, len) < 0) {
|
||||
if (ssh_buffer_add_data(dest, out_buf, len) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
return NULL;
|
||||
}
|
||||
@ -108,12 +108,12 @@ int compress_buffer(ssh_session session, ssh_buffer buf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_reinit(buf) < 0) {
|
||||
if (ssh_buffer_reinit(buf) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
|
||||
if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
return -1;
|
||||
}
|
||||
@ -181,7 +181,7 @@ static ssh_buffer gzip_decompress(ssh_session session, ssh_buffer source, size_t
|
||||
}
|
||||
|
||||
len = BLOCKSIZE - zin->avail_out;
|
||||
if (buffer_add_data(dest,out_buf,len) < 0) {
|
||||
if (ssh_buffer_add_data(dest,out_buf,len) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
return NULL;
|
||||
}
|
||||
@ -204,12 +204,12 @@ int decompress_buffer(ssh_session session,ssh_buffer buf, size_t maxlen){
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_reinit(buf) < 0) {
|
||||
if (ssh_buffer_reinit(buf) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
|
||||
if (ssh_buffer_add_data(buf, buffer_get_rest(dest), buffer_get_rest_len(dest)) < 0) {
|
||||
ssh_buffer_free(dest);
|
||||
return -1;
|
||||
}
|
||||
|
322
libssh/src/kex.c
322
libssh/src/kex.c
@ -35,6 +35,7 @@
|
||||
#include "libssh/ssh2.h"
|
||||
#include "libssh/string.h"
|
||||
#include "libssh/curve25519.h"
|
||||
#include "libssh/knownhosts.h"
|
||||
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
# define BLOWFISH "blowfish-cbc,"
|
||||
@ -72,7 +73,7 @@
|
||||
|
||||
#ifdef HAVE_ECDH
|
||||
#define ECDH "ecdh-sha2-nistp256,"
|
||||
#define HOSTKEYS "ecdsa-sha2-nistp256,ssh-rsa,ssh-dss"
|
||||
#define HOSTKEYS "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-rsa,ssh-dss"
|
||||
#else
|
||||
#define HOSTKEYS "ssh-rsa,ssh-dss"
|
||||
#define ECDH ""
|
||||
@ -87,8 +88,8 @@ static const char *default_methods[] = {
|
||||
HOSTKEYS,
|
||||
AES BLOWFISH DES,
|
||||
AES BLOWFISH DES,
|
||||
"hmac-sha1",
|
||||
"hmac-sha1",
|
||||
"hmac-sha1,hmac-sha2-256,hmac-sha2-512",
|
||||
"hmac-sha1,hmac-sha2-256,hmac-sha2-512",
|
||||
"none",
|
||||
"none",
|
||||
"",
|
||||
@ -102,8 +103,8 @@ static const char *supported_methods[] = {
|
||||
HOSTKEYS,
|
||||
AES BLOWFISH DES,
|
||||
AES BLOWFISH DES,
|
||||
"hmac-sha1",
|
||||
"hmac-sha1",
|
||||
"hmac-sha1,hmac-sha2-256,hmac-sha2-512",
|
||||
"hmac-sha1,hmac-sha2-256,hmac-sha2-512",
|
||||
ZLIB,
|
||||
ZLIB,
|
||||
"",
|
||||
@ -274,87 +275,180 @@ char *ssh_find_matching(const char *available_d, const char *preferred_d){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief returns whether the first client key exchange algorithm matches
|
||||
* the first server key exchange algorithm
|
||||
* @returns whether the first client key exchange algorithm matches
|
||||
* the first server key exchange algorithm
|
||||
*/
|
||||
static int is_first_kex_packet_follows_guess_wrong(const char *client_kex,
|
||||
const char *server_kex) {
|
||||
int is_wrong = 1;
|
||||
char **server_kex_tokens = NULL;
|
||||
char **client_kex_tokens = NULL;
|
||||
|
||||
if ((client_kex == NULL) || (server_kex == NULL)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
client_kex_tokens = tokenize(client_kex);
|
||||
|
||||
if (client_kex_tokens == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (client_kex_tokens[0] == NULL) {
|
||||
goto freeout;
|
||||
}
|
||||
|
||||
server_kex_tokens = tokenize(server_kex);
|
||||
if (server_kex_tokens == NULL) {
|
||||
goto freeout;
|
||||
}
|
||||
|
||||
is_wrong = (strcmp(client_kex_tokens[0], server_kex_tokens[0]) != 0);
|
||||
|
||||
SAFE_FREE(server_kex_tokens[0]);
|
||||
SAFE_FREE(server_kex_tokens);
|
||||
freeout:
|
||||
SAFE_FREE(client_kex_tokens[0]);
|
||||
SAFE_FREE(client_kex_tokens);
|
||||
out:
|
||||
return is_wrong;
|
||||
}
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_kexinit){
|
||||
int server_kex=session->server;
|
||||
ssh_string str = NULL;
|
||||
char *strings[KEX_METHODS_SIZE];
|
||||
int i;
|
||||
int i;
|
||||
int server_kex=session->server;
|
||||
ssh_string str = NULL;
|
||||
char *strings[KEX_METHODS_SIZE];
|
||||
int rc = SSH_ERROR;
|
||||
|
||||
(void)type;
|
||||
(void)user;
|
||||
memset(strings, 0, sizeof(strings));
|
||||
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
|
||||
SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange");
|
||||
} else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
|
||||
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
|
||||
goto error;
|
||||
}
|
||||
if (server_kex) {
|
||||
if (buffer_get_data(packet,session->next_crypto->client_kex.cookie,16) != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
|
||||
uint8_t first_kex_packet_follows = 0;
|
||||
uint32_t kexinit_reserved = 0;
|
||||
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
memset(strings, 0, sizeof(strings));
|
||||
if (session->session_state == SSH_SESSION_STATE_AUTHENTICATED){
|
||||
SSH_LOG(SSH_LOG_WARNING, "Other side initiating key re-exchange");
|
||||
} else if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
|
||||
ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (buffer_get_data(packet,session->next_crypto->server_kex.cookie,16) != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
str = buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (buffer_add_ssh_string(session->in_hashbuf, str) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer");
|
||||
goto error;
|
||||
if (server_kex) {
|
||||
rc = buffer_get_data(packet,session->next_crypto->client_kex.cookie, 16);
|
||||
if (rc != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = hashbufin_add_cookie(session, session->next_crypto->client_kex.cookie);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
rc = buffer_get_data(packet,session->next_crypto->server_kex.cookie, 16);
|
||||
if (rc != 16) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: no cookie in packet");
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = hashbufin_add_cookie(session, session->next_crypto->server_kex.cookie);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "ssh_packet_kexinit: adding cookie failed");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
strings[i] = ssh_string_to_char(str);
|
||||
if (strings[i] == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
str = NULL;
|
||||
}
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
str = buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* copy the server kex info into an array of strings */
|
||||
if (server_kex) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
session->next_crypto->client_kex.methods[i] = strings[i];
|
||||
}
|
||||
} else { /* client */
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
session->next_crypto->server_kex.methods[i] = strings[i];
|
||||
}
|
||||
}
|
||||
rc = buffer_add_ssh_string(session->in_hashbuf, str);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Error adding string in hash buffer");
|
||||
goto error;
|
||||
}
|
||||
|
||||
strings[i] = ssh_string_to_char(str);
|
||||
if (strings[i] == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(str);
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
/* copy the server kex info into an array of strings */
|
||||
if (server_kex) {
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
session->next_crypto->client_kex.methods[i] = strings[i];
|
||||
}
|
||||
} else { /* client */
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
session->next_crypto->server_kex.methods[i] = strings[i];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
|
||||
*
|
||||
* boolean first_kex_packet_follows
|
||||
* uint32 0 (reserved for future extension)
|
||||
*
|
||||
* Notably if clients set 'first_kex_packet_follows', it is expected
|
||||
* that its value is included when computing the session ID (see
|
||||
* 'make_sessionid').
|
||||
*/
|
||||
if (server_kex) {
|
||||
rc = buffer_get_u8(packet, &first_kex_packet_follows);
|
||||
if (rc != 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = buffer_add_u8(session->in_hashbuf, first_kex_packet_follows);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->in_hashbuf, kexinit_reserved);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remember whether 'first_kex_packet_follows' was set and the client
|
||||
* guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
|
||||
* must be ignored.
|
||||
*/
|
||||
if (first_kex_packet_follows) {
|
||||
session->first_kex_follows_guess_wrong =
|
||||
is_first_kex_packet_follows_guess_wrong(session->next_crypto->client_kex.methods[SSH_KEX],
|
||||
session->next_crypto->server_kex.methods[SSH_KEX]);
|
||||
}
|
||||
}
|
||||
|
||||
session->session_state = SSH_SESSION_STATE_KEXINIT_RECEIVED;
|
||||
session->dh_handshake_state = DH_STATE_INIT;
|
||||
session->ssh_connection_callback(session);
|
||||
return SSH_PACKET_USED;
|
||||
|
||||
session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED;
|
||||
session->dh_handshake_state=DH_STATE_INIT;
|
||||
session->ssh_connection_callback(session);
|
||||
return SSH_PACKET_USED;
|
||||
error:
|
||||
ssh_string_free(str);
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
SAFE_FREE(strings[i]);
|
||||
}
|
||||
ssh_string_free(str);
|
||||
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
||||
SAFE_FREE(strings[i]);
|
||||
}
|
||||
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
void ssh_list_kex(struct ssh_kex_struct *kex) {
|
||||
@ -373,6 +467,53 @@ void ssh_list_kex(struct ssh_kex_struct *kex) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief selects the hostkey mechanisms to be chosen for the key exchange,
|
||||
* as some hostkey mechanisms may be present in known_hosts file and preferred
|
||||
* @returns a cstring containing a comma-separated list of hostkey methods.
|
||||
* NULL if no method matches
|
||||
*/
|
||||
static char *ssh_client_select_hostkeys(ssh_session session){
|
||||
char methods_buffer[128]={0};
|
||||
static const char *preferred_hostkeys[]={"ecdsa-sha2-nistp521","ecdsa-sha2-nistp384",
|
||||
"ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss", "ssh-rsa1", NULL};
|
||||
char **methods;
|
||||
int i,j;
|
||||
int needcoma=0;
|
||||
|
||||
methods = ssh_knownhosts_algorithms(session);
|
||||
if (methods == NULL || methods[0] == NULL){
|
||||
SAFE_FREE(methods);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0;preferred_hostkeys[i] != NULL; ++i){
|
||||
for (j=0; methods[j] != NULL; ++j){
|
||||
if(strcmp(preferred_hostkeys[i], methods[j]) == 0){
|
||||
if (verify_existing_algo(SSH_HOSTKEYS, methods[j])){
|
||||
if(needcoma)
|
||||
strncat(methods_buffer,",",sizeof(methods_buffer)-strlen(methods_buffer)-1);
|
||||
strncat(methods_buffer, methods[j], sizeof(methods_buffer)-strlen(methods_buffer)-1);
|
||||
needcoma = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(i=0;methods[i]!= NULL; ++i){
|
||||
SAFE_FREE(methods[i]);
|
||||
}
|
||||
SAFE_FREE(methods);
|
||||
|
||||
if(strlen(methods_buffer) > 0){
|
||||
SSH_LOG(SSH_LOG_DEBUG, "Changing host key method to \"%s\"", methods_buffer);
|
||||
return strdup(methods_buffer);
|
||||
} else {
|
||||
SSH_LOG(SSH_LOG_DEBUG, "No supported kex method for existing key in known_hosts file");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief sets the key exchange parameters to be sent to the server,
|
||||
* in function of the options and available methods.
|
||||
@ -385,6 +526,13 @@ int set_client_kex(ssh_session session){
|
||||
ssh_get_random(client->cookie, 16, 0);
|
||||
|
||||
memset(client->methods, 0, KEX_METHODS_SIZE * sizeof(char **));
|
||||
/* first check if we have specific host key methods */
|
||||
if(session->opts.wanted_methods[SSH_HOSTKEYS] == NULL){
|
||||
/* Only if no override */
|
||||
session->opts.wanted_methods[SSH_HOSTKEYS] =
|
||||
ssh_client_select_hostkeys(session);
|
||||
}
|
||||
|
||||
for (i = 0; i < KEX_METHODS_SIZE; i++) {
|
||||
wanted = session->opts.wanted_methods[i];
|
||||
if (wanted == NULL)
|
||||
@ -434,14 +582,15 @@ int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
&session->next_crypto->client_kex);
|
||||
ssh_string str = NULL;
|
||||
int i;
|
||||
int rc;
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, SSH2_MSG_KEXINIT) < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bP",
|
||||
SSH2_MSG_KEXINIT,
|
||||
16,
|
||||
kex->cookie); /* cookie */
|
||||
if (rc != SSH_OK)
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, kex->cookie, 16) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (hashbufout_add_cookie(session) < 0) {
|
||||
goto error;
|
||||
}
|
||||
@ -464,10 +613,11 @@ int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
str = NULL;
|
||||
}
|
||||
|
||||
if (buffer_add_u8(session->out_buffer, 0) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_u32(session->out_buffer, 0) < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
0,
|
||||
0);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -477,8 +627,8 @@ int ssh_send_kex(ssh_session session, int server_kex) {
|
||||
|
||||
return 0;
|
||||
error:
|
||||
buffer_reinit(session->out_buffer);
|
||||
buffer_reinit(session->out_hashbuf);
|
||||
ssh_buffer_reinit(session->out_buffer);
|
||||
ssh_buffer_reinit(session->out_hashbuf);
|
||||
ssh_string_free(str);
|
||||
|
||||
return -1;
|
||||
|
@ -417,7 +417,7 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
|
||||
if (buffer_add_u8(session->out_buffer, support_3DES ? SSH_CIPHER_3DES : SSH_CIPHER_DES) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
|
||||
if (ssh_buffer_add_data(session->out_buffer, session->next_crypto->server_kex.cookie, 8) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -431,10 +431,10 @@ SSH_PACKET_CALLBACK(ssh_packet_publickey1){
|
||||
bits, ssh_string_len(enc_session));
|
||||
bits = htons(bits);
|
||||
/* the encrypted mpint */
|
||||
if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
|
||||
if (ssh_buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, ssh_string_data(enc_session),
|
||||
if (ssh_buffer_add_data(session->out_buffer, ssh_string_data(enc_session),
|
||||
ssh_string_len(enc_session)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2009 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -34,7 +34,7 @@
|
||||
#include "libssh/misc.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/options.h"
|
||||
|
||||
#include "libssh/knownhosts.h"
|
||||
/*todo: remove this include */
|
||||
#include "libssh/string.h"
|
||||
|
||||
@ -239,9 +239,9 @@ static int check_public_key(ssh_session session, char **tokens) {
|
||||
/* TODO: fix the hardcoding */
|
||||
tmpstring->size = htonl(len);
|
||||
#ifdef HAVE_LIBGCRYPT
|
||||
bignum_bn2bin(tmpbn, len, string_data(tmpstring));
|
||||
bignum_bn2bin(tmpbn, len, ssh_string_data(tmpstring));
|
||||
#elif defined HAVE_LIBCRYPTO
|
||||
bignum_bn2bin(tmpbn, string_data(tmpstring));
|
||||
bignum_bn2bin(tmpbn, ssh_string_data(tmpstring));
|
||||
#endif
|
||||
bignum_free(tmpbn);
|
||||
if (buffer_add_ssh_string(pubkey_buffer, tmpstring) < 0) {
|
||||
@ -647,6 +647,102 @@ int ssh_write_knownhost(ssh_session session) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define KNOWNHOSTS_MAXTYPES 10
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @brief Check which kind of host keys should be preferred for connection
|
||||
* by reading the known_hosts file.
|
||||
*
|
||||
* @param[in] session The SSH session to use.
|
||||
*
|
||||
* @returns array of supported key types
|
||||
* NULL on error
|
||||
*/
|
||||
char **ssh_knownhosts_algorithms(ssh_session session) {
|
||||
FILE *file = NULL;
|
||||
char **tokens;
|
||||
char *host;
|
||||
char *hostport;
|
||||
const char *type;
|
||||
int match;
|
||||
char **array;
|
||||
int i=0, j;
|
||||
|
||||
if (session->opts.knownhosts == NULL) {
|
||||
if (ssh_options_apply(session) < 0) {
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED,
|
||||
"Can't find a known_hosts file");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (session->opts.host == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
host = ssh_lowercase(session->opts.host);
|
||||
hostport = ssh_hostport(host, session->opts.port);
|
||||
array = malloc(sizeof(char *) * KNOWNHOSTS_MAXTYPES);
|
||||
|
||||
if (host == NULL || hostport == NULL || array == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(hostport);
|
||||
SAFE_FREE(array);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do {
|
||||
tokens = ssh_get_knownhost_line(&file,
|
||||
session->opts.knownhosts, &type);
|
||||
|
||||
/* End of file, return the current state */
|
||||
if (tokens == NULL) {
|
||||
break;
|
||||
}
|
||||
match = match_hashed_host(host, tokens[0]);
|
||||
if (match == 0){
|
||||
match = match_hostname(hostport, tokens[0], strlen(tokens[0]));
|
||||
}
|
||||
if (match == 0) {
|
||||
match = match_hostname(host, tokens[0], strlen(tokens[0]));
|
||||
}
|
||||
if (match == 0) {
|
||||
match = match_hashed_host(hostport, tokens[0]);
|
||||
}
|
||||
if (match) {
|
||||
/* We got a match. Now check the key type */
|
||||
SSH_LOG(SSH_LOG_DEBUG, "server %s:%d has %s in known_hosts",
|
||||
host, session->opts.port, type);
|
||||
/* don't copy more than once */
|
||||
for(j=0;j<i && match;++j){
|
||||
if(strcmp(array[j], type)==0)
|
||||
match=0;
|
||||
}
|
||||
if (match){
|
||||
array[i] = strdup(type);
|
||||
i++;
|
||||
if(i>= KNOWNHOSTS_MAXTYPES-1){
|
||||
tokens_free(tokens);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
tokens_free(tokens);
|
||||
} while (1);
|
||||
|
||||
array[i]=NULL;
|
||||
SAFE_FREE(host);
|
||||
SAFE_FREE(hostport);
|
||||
if (file != NULL) {
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
/* Return the current state at end of file */
|
||||
return array;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/* vim: set ts=4 sw=4 et cindent: */
|
||||
|
@ -163,7 +163,7 @@ int channel_change_pty_size(ssh_channel channel,int cols,int rows){
|
||||
}
|
||||
|
||||
ssh_channel channel_forward_accept(ssh_session session, int timeout_ms){
|
||||
return ssh_forward_accept(session,timeout_ms);
|
||||
return ssh_channel_accept_forward(session, timeout_ms, NULL);
|
||||
}
|
||||
|
||||
int channel_close(ssh_channel channel){
|
||||
@ -171,12 +171,12 @@ int channel_close(ssh_channel channel){
|
||||
}
|
||||
|
||||
int channel_forward_cancel(ssh_session session, const char *address, int port){
|
||||
return ssh_forward_cancel(session, address, port);
|
||||
return ssh_channel_cancel_forward(session, address, port);
|
||||
}
|
||||
|
||||
int channel_forward_listen(ssh_session session, const char *address,
|
||||
int port, int *bound_port){
|
||||
return ssh_forward_listen(session, address, port, bound_port);
|
||||
return ssh_channel_listen_forward(session, address, port, bound_port);
|
||||
}
|
||||
|
||||
void channel_free(ssh_channel channel){
|
||||
@ -580,7 +580,7 @@ int ssh_publickey_to_file(ssh_session session,
|
||||
ssh_set_error(session, SSH_FATAL, "Invalid parameters");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
pubkey_64 = bin_to_base64(string_data(pubkey), ssh_string_len(pubkey));
|
||||
pubkey_64 = bin_to_base64(ssh_string_data(pubkey), ssh_string_len(pubkey));
|
||||
if (pubkey_64 == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "libssh/priv.h"
|
||||
#include "libssh/session.h"
|
||||
@ -38,6 +39,8 @@
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#ifdef HAVE_OPENSSL_AES_H
|
||||
#define HAS_AES
|
||||
#include <openssl/aes.h>
|
||||
@ -62,6 +65,8 @@ struct ssh_mac_ctx_struct {
|
||||
union {
|
||||
SHACTX sha1_ctx;
|
||||
SHA256CTX sha256_ctx;
|
||||
SHA384CTX sha384_ctx;
|
||||
SHA512CTX sha512_ctx;
|
||||
} ctx;
|
||||
};
|
||||
|
||||
@ -74,6 +79,12 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ssh_reseed(void){
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
RAND_add(&tv, sizeof(tv), 0.0);
|
||||
}
|
||||
|
||||
SHACTX sha1_init(void) {
|
||||
SHACTX c = malloc(sizeof(*c));
|
||||
if (c == NULL) {
|
||||
@ -172,6 +183,52 @@ void sha256(unsigned char *digest, int len, unsigned char *hash) {
|
||||
SHA256(digest, len, hash);
|
||||
}
|
||||
|
||||
SHA384CTX sha384_init(void){
|
||||
SHA384CTX c = malloc(sizeof(*c));
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
SHA384_Init(c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void sha384_update(SHA384CTX c, const void *data, unsigned long len){
|
||||
SHA384_Update(c,data,len);
|
||||
}
|
||||
|
||||
void sha384_final(unsigned char *md, SHA384CTX c) {
|
||||
SHA384_Final(md, c);
|
||||
SAFE_FREE(c);
|
||||
}
|
||||
|
||||
void sha384(unsigned char *digest, int len, unsigned char *hash) {
|
||||
SHA384(digest, len, hash);
|
||||
}
|
||||
|
||||
SHA512CTX sha512_init(void){
|
||||
SHA512CTX c = malloc(sizeof(*c));
|
||||
if (c == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
SHA512_Init(c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void sha512_update(SHA512CTX c, const void *data, unsigned long len){
|
||||
SHA512_Update(c,data,len);
|
||||
}
|
||||
|
||||
void sha512_final(unsigned char *md, SHA512CTX c) {
|
||||
SHA512_Final(md, c);
|
||||
SAFE_FREE(c);
|
||||
}
|
||||
|
||||
void sha512(unsigned char *digest, int len, unsigned char *hash) {
|
||||
SHA512(digest, len, hash);
|
||||
}
|
||||
|
||||
MD5CTX md5_init(void) {
|
||||
MD5CTX c = malloc(sizeof(*c));
|
||||
if (c == NULL) {
|
||||
@ -193,7 +250,11 @@ void md5_final(unsigned char *md, MD5CTX c) {
|
||||
}
|
||||
|
||||
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
|
||||
ssh_mac_ctx ctx=malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mac_type=type;
|
||||
switch(type){
|
||||
case SSH_MAC_SHA1:
|
||||
@ -203,7 +264,11 @@ ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
|
||||
ctx->ctx.sha256_ctx = sha256_init();
|
||||
return ctx;
|
||||
case SSH_MAC_SHA384:
|
||||
ctx->ctx.sha384_ctx = sha384_init();
|
||||
return ctx;
|
||||
case SSH_MAC_SHA512:
|
||||
ctx->ctx.sha512_ctx = sha512_init();
|
||||
return ctx;
|
||||
default:
|
||||
SAFE_FREE(ctx);
|
||||
return NULL;
|
||||
@ -219,7 +284,11 @@ void ssh_mac_update(ssh_mac_ctx ctx, const void *data, unsigned long len) {
|
||||
sha256_update(ctx->ctx.sha256_ctx, data, len);
|
||||
break;
|
||||
case SSH_MAC_SHA384:
|
||||
sha384_update(ctx->ctx.sha384_ctx, data, len);
|
||||
break;
|
||||
case SSH_MAC_SHA512:
|
||||
sha512_update(ctx->ctx.sha512_ctx, data, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -234,7 +303,11 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
|
||||
sha256_final(md,ctx->ctx.sha256_ctx);
|
||||
break;
|
||||
case SSH_MAC_SHA384:
|
||||
sha384_final(md,ctx->ctx.sha384_ctx);
|
||||
break;
|
||||
case SSH_MAC_SHA512:
|
||||
sha512_final(md,ctx->ctx.sha512_ctx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -257,6 +330,15 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
case SSH_HMAC_SHA1:
|
||||
HMAC_Init(ctx, key, len, EVP_sha1());
|
||||
break;
|
||||
case SSH_HMAC_SHA256:
|
||||
HMAC_Init(ctx, key, len, EVP_sha256());
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
HMAC_Init(ctx, key, len, EVP_sha384());
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
HMAC_Init(ctx, key, len, EVP_sha512());
|
||||
break;
|
||||
case SSH_HMAC_MD5:
|
||||
HMAC_Init(ctx, key, len, EVP_md5());
|
||||
break;
|
||||
|
@ -45,6 +45,9 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ssh_reseed(void){
|
||||
}
|
||||
|
||||
SHACTX sha1_init(void) {
|
||||
SHACTX ctx = NULL;
|
||||
gcry_md_open(&ctx, GCRY_MD_SHA1, 0);
|
||||
@ -66,10 +69,69 @@ void sha1(unsigned char *digest, int len, unsigned char *hash) {
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len);
|
||||
}
|
||||
|
||||
SHA256CTX sha256_init(void) {
|
||||
SHA256CTX ctx = NULL;
|
||||
gcry_md_open(&ctx, GCRY_MD_SHA256, 0);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void sha256_update(SHACTX c, const void *data, unsigned long len) {
|
||||
gcry_md_write(c, data, len);
|
||||
}
|
||||
|
||||
void sha256_final(unsigned char *md, SHACTX c) {
|
||||
gcry_md_final(c);
|
||||
memcpy(md, gcry_md_read(c, 0), SHA256_DIGEST_LEN);
|
||||
gcry_md_close(c);
|
||||
}
|
||||
|
||||
void sha256(unsigned char *digest, int len, unsigned char *hash){
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA256, hash, digest, len);
|
||||
}
|
||||
|
||||
SHA384CTX sha384_init(void) {
|
||||
SHA384CTX ctx = NULL;
|
||||
gcry_md_open(&ctx, GCRY_MD_SHA384, 0);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void sha384_update(SHACTX c, const void *data, unsigned long len) {
|
||||
gcry_md_write(c, data, len);
|
||||
}
|
||||
|
||||
void sha384_final(unsigned char *md, SHACTX c) {
|
||||
gcry_md_final(c);
|
||||
memcpy(md, gcry_md_read(c, 0), SHA384_DIGEST_LEN);
|
||||
gcry_md_close(c);
|
||||
}
|
||||
|
||||
void sha384(unsigned char *digest, int len, unsigned char *hash) {
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA384, hash, digest, len);
|
||||
}
|
||||
|
||||
SHA512CTX sha512_init(void) {
|
||||
SHA512CTX ctx = NULL;
|
||||
gcry_md_open(&ctx, GCRY_MD_SHA512, 0);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void sha512_update(SHACTX c, const void *data, unsigned long len) {
|
||||
gcry_md_write(c, data, len);
|
||||
}
|
||||
|
||||
void sha512_final(unsigned char *md, SHACTX c) {
|
||||
gcry_md_final(c);
|
||||
memcpy(md, gcry_md_read(c, 0), SHA512_DIGEST_LEN);
|
||||
gcry_md_close(c);
|
||||
}
|
||||
|
||||
void sha512(unsigned char *digest, int len, unsigned char *hash) {
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA512, hash, digest, len);
|
||||
}
|
||||
|
||||
MD5CTX md5_init(void) {
|
||||
MD5CTX c = NULL;
|
||||
gcry_md_open(&c, GCRY_MD_MD5, 0);
|
||||
@ -88,7 +150,11 @@ void md5_final(unsigned char *md, MD5CTX c) {
|
||||
}
|
||||
|
||||
ssh_mac_ctx ssh_mac_ctx_init(enum ssh_mac_e type){
|
||||
ssh_mac_ctx ctx=malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
ssh_mac_ctx ctx = malloc(sizeof(struct ssh_mac_ctx_struct));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->mac_type=type;
|
||||
switch(type){
|
||||
case SSH_MAC_SHA1:
|
||||
@ -121,13 +187,13 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) {
|
||||
len=SHA_DIGEST_LEN;
|
||||
break;
|
||||
case SSH_MAC_SHA256:
|
||||
len=SHA256_DIGEST_LENGTH;
|
||||
len=SHA256_DIGEST_LEN;
|
||||
break;
|
||||
case SSH_MAC_SHA384:
|
||||
len=SHA384_DIGEST_LENGTH;
|
||||
len=SHA384_DIGEST_LEN;
|
||||
break;
|
||||
case SSH_MAC_SHA512:
|
||||
len=SHA512_DIGEST_LENGTH;
|
||||
len=SHA512_DIGEST_LEN;
|
||||
break;
|
||||
}
|
||||
gcry_md_final(ctx->ctx);
|
||||
@ -143,6 +209,15 @@ HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) {
|
||||
case SSH_HMAC_SHA1:
|
||||
gcry_md_open(&c, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA256:
|
||||
gcry_md_open(&c, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA384:
|
||||
gcry_md_open(&c, GCRY_MD_SHA384, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_SHA512:
|
||||
gcry_md_open(&c, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
case SSH_HMAC_MD5:
|
||||
gcry_md_open(&c, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
|
||||
break;
|
||||
@ -403,8 +478,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 128,
|
||||
.set_encrypt_key = blowfish_set_key,
|
||||
.set_decrypt_key = blowfish_set_key,
|
||||
.cbc_encrypt = blowfish_encrypt,
|
||||
.cbc_decrypt = blowfish_decrypt
|
||||
.encrypt = blowfish_encrypt,
|
||||
.decrypt = blowfish_decrypt
|
||||
},
|
||||
{
|
||||
.name = "aes128-ctr",
|
||||
@ -414,8 +489,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 128,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.cbc_encrypt = aes_encrypt,
|
||||
.cbc_decrypt = aes_encrypt
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_encrypt
|
||||
},
|
||||
{
|
||||
.name = "aes192-ctr",
|
||||
@ -425,8 +500,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.cbc_encrypt = aes_encrypt,
|
||||
.cbc_decrypt = aes_encrypt
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_encrypt
|
||||
},
|
||||
{
|
||||
.name = "aes256-ctr",
|
||||
@ -436,8 +511,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 256,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.cbc_encrypt = aes_encrypt,
|
||||
.cbc_decrypt = aes_encrypt
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_encrypt
|
||||
},
|
||||
{
|
||||
.name = "aes128-cbc",
|
||||
@ -447,8 +522,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 128,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.cbc_encrypt = aes_encrypt,
|
||||
.cbc_decrypt = aes_decrypt
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_decrypt
|
||||
},
|
||||
{
|
||||
.name = "aes192-cbc",
|
||||
@ -458,8 +533,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.cbc_encrypt = aes_encrypt,
|
||||
.cbc_decrypt = aes_decrypt
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_decrypt
|
||||
},
|
||||
{
|
||||
.name = "aes256-cbc",
|
||||
@ -469,8 +544,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 256,
|
||||
.set_encrypt_key = aes_set_key,
|
||||
.set_decrypt_key = aes_set_key,
|
||||
.cbc_encrypt = aes_encrypt,
|
||||
.cbc_decrypt = aes_decrypt
|
||||
.encrypt = aes_encrypt,
|
||||
.decrypt = aes_decrypt
|
||||
},
|
||||
{
|
||||
.name = "3des-cbc",
|
||||
@ -480,8 +555,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = des3_set_key,
|
||||
.set_decrypt_key = des3_set_key,
|
||||
.cbc_encrypt = des3_encrypt,
|
||||
.cbc_decrypt = des3_decrypt
|
||||
.encrypt = des3_encrypt,
|
||||
.decrypt = des3_decrypt
|
||||
},
|
||||
{
|
||||
.name = "3des-cbc-ssh1",
|
||||
@ -491,8 +566,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 192,
|
||||
.set_encrypt_key = des3_1_set_key,
|
||||
.set_decrypt_key = des3_1_set_key,
|
||||
.cbc_encrypt = des3_1_encrypt,
|
||||
.cbc_decrypt = des3_1_decrypt
|
||||
.encrypt = des3_1_encrypt,
|
||||
.decrypt = des3_1_decrypt
|
||||
},
|
||||
{
|
||||
.name = "des-cbc-ssh1",
|
||||
@ -502,8 +577,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 64,
|
||||
.set_encrypt_key = des1_set_key,
|
||||
.set_decrypt_key = des1_set_key,
|
||||
.cbc_encrypt = des1_1_encrypt,
|
||||
.cbc_decrypt = des1_1_decrypt
|
||||
.encrypt = des1_1_encrypt,
|
||||
.decrypt = des1_1_decrypt
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
@ -513,8 +588,8 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||
.keysize = 0,
|
||||
.set_encrypt_key = NULL,
|
||||
.set_decrypt_key = NULL,
|
||||
.cbc_encrypt = NULL,
|
||||
.cbc_decrypt = NULL
|
||||
.encrypt = NULL,
|
||||
.decrypt = NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2008-2013 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -215,6 +215,10 @@ ssh_logging_callback ssh_get_log_callback(void) {
|
||||
*/
|
||||
void *ssh_get_log_userdata(void)
|
||||
{
|
||||
if (ssh_log_userdata == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ssh_log_userdata;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -208,8 +208,8 @@ static int ssh_execute_server_request(ssh_session session, ssh_message msg)
|
||||
ssh_callbacks_exists(channel->callbacks, channel_pty_window_change_function)) {
|
||||
rc = channel->callbacks->channel_pty_window_change_function(session,
|
||||
channel,
|
||||
msg->channel_request.height, msg->channel_request.width,
|
||||
msg->channel_request.pxheight, msg->channel_request.pxwidth,
|
||||
msg->channel_request.width, msg->channel_request.height,
|
||||
msg->channel_request.pxwidth, msg->channel_request.pxheight,
|
||||
channel->callbacks->userdata);
|
||||
} else if (msg->channel_request.type == SSH_CHANNEL_REQUEST_EXEC &&
|
||||
ssh_callbacks_exists(channel->callbacks, channel_exec_request_function)) {
|
||||
@ -508,8 +508,7 @@ void ssh_message_free(ssh_message msg){
|
||||
case SSH_REQUEST_AUTH:
|
||||
SAFE_FREE(msg->auth_request.username);
|
||||
if (msg->auth_request.password) {
|
||||
memset(msg->auth_request.password, 0,
|
||||
strlen(msg->auth_request.password));
|
||||
BURN_STRING(msg->auth_request.password);
|
||||
SAFE_FREE(msg->auth_request.password);
|
||||
}
|
||||
ssh_key_free(msg->auth_request.pubkey);
|
||||
@ -586,104 +585,34 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
|
||||
session->current_crypto ? session->current_crypto :
|
||||
session->next_crypto;
|
||||
ssh_buffer buffer;
|
||||
ssh_string str;
|
||||
ssh_string str=NULL;
|
||||
int rc;
|
||||
|
||||
buffer = ssh_buffer_new();
|
||||
if (buffer == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add session id */
|
||||
str = ssh_string_new(crypto->digest_len);
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(str, crypto->session_id, crypto->digest_len);
|
||||
|
||||
rc = buffer_add_ssh_string(buffer, str);
|
||||
string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the type */
|
||||
rc = buffer_add_u8(buffer, SSH2_MSG_USERAUTH_REQUEST);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the username */
|
||||
str = ssh_string_from_char(msg->auth_request.username);
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buffer, str);
|
||||
string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the service name */
|
||||
str = ssh_string_from_char(service);
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buffer, str);
|
||||
string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the method (publickey) */
|
||||
str = ssh_string_from_char("publickey");
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buffer, str);
|
||||
string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Has been signed (TRUE) */
|
||||
rc = buffer_add_u8(buffer, 1);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the public key algorithm */
|
||||
str = ssh_string_from_char(msg->auth_request.pubkey->type_c);
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buffer, str);
|
||||
string_free(str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the publickey as blob */
|
||||
rc = ssh_pki_export_pubkey_blob(msg->auth_request.pubkey, &str);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
rc = buffer_add_ssh_string(buffer, str);
|
||||
string_free(str);
|
||||
if (rc < 0) {
|
||||
|
||||
rc = ssh_buffer_pack(buffer,
|
||||
"dPbsssbsS",
|
||||
crypto->digest_len, /* session ID string */
|
||||
(size_t)crypto->digest_len, crypto->session_id,
|
||||
SSH2_MSG_USERAUTH_REQUEST, /* type */
|
||||
msg->auth_request.username,
|
||||
service,
|
||||
"publickey", /* method */
|
||||
1, /* has to be signed (true) */
|
||||
msg->auth_request.pubkey->type_c, /* pubkey algorithm */
|
||||
str); /* public key as a blob */
|
||||
|
||||
ssh_string_free(str);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
@ -698,11 +627,10 @@ static ssh_buffer ssh_msg_userauth_build_digest(ssh_session session,
|
||||
* SSH Message
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
ssh_string str;
|
||||
ssh_message msg = NULL;
|
||||
char *service = NULL;
|
||||
char *method = NULL;
|
||||
uint32_t method_size = 0;
|
||||
int rc;
|
||||
|
||||
(void)user;
|
||||
(void)type;
|
||||
@ -713,35 +641,13 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
goto error;
|
||||
}
|
||||
msg->type = SSH_REQUEST_AUTH;
|
||||
rc = ssh_buffer_unpack(packet,
|
||||
"sss",
|
||||
&msg->auth_request.username,
|
||||
&service,
|
||||
&method);
|
||||
|
||||
str = buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
msg->auth_request.username = ssh_string_to_char(str);
|
||||
ssh_string_free(str);
|
||||
if (msg->auth_request.username == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
str = buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
service = ssh_string_to_char(str);
|
||||
ssh_string_free(str);
|
||||
if (service == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
str = buffer_get_ssh_string(packet);
|
||||
if (str == NULL) {
|
||||
goto error;
|
||||
}
|
||||
method = ssh_string_to_char(str);
|
||||
method_size = ssh_string_len(str);
|
||||
ssh_string_free(str);
|
||||
if (method == NULL) {
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -751,32 +657,23 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
msg->auth_request.username);
|
||||
|
||||
|
||||
if (strncmp(method, "none", method_size) == 0) {
|
||||
if (strcmp(method, "none") == 0) {
|
||||
msg->auth_request.method = SSH_AUTH_METHOD_NONE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strncmp(method, "password", method_size) == 0) {
|
||||
ssh_string pass = NULL;
|
||||
if (strcmp(method, "password") == 0) {
|
||||
uint8_t tmp;
|
||||
|
||||
msg->auth_request.method = SSH_AUTH_METHOD_PASSWORD;
|
||||
buffer_get_u8(packet, &tmp);
|
||||
pass = buffer_get_ssh_string(packet);
|
||||
if (pass == NULL) {
|
||||
goto error;
|
||||
}
|
||||
msg->auth_request.password = ssh_string_to_char(pass);
|
||||
ssh_string_burn(pass);
|
||||
ssh_string_free(pass);
|
||||
pass = NULL;
|
||||
if (msg->auth_request.password == NULL) {
|
||||
rc = ssh_buffer_unpack(packet, "bs", &tmp, &msg->auth_request.password);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strncmp(method, "keyboard-interactive", method_size) == 0) {
|
||||
if (strcmp(method, "keyboard-interactive") == 0) {
|
||||
ssh_string lang = NULL;
|
||||
ssh_string submethods = NULL;
|
||||
|
||||
@ -806,23 +703,20 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strncmp(method, "publickey", method_size) == 0) {
|
||||
if (strcmp(method, "publickey") == 0) {
|
||||
ssh_string algo = NULL;
|
||||
ssh_string pubkey_blob = NULL;
|
||||
uint8_t has_sign;
|
||||
int rc;
|
||||
|
||||
msg->auth_request.method = SSH_AUTH_METHOD_PUBLICKEY;
|
||||
SAFE_FREE(method);
|
||||
buffer_get_u8(packet, &has_sign);
|
||||
algo = buffer_get_ssh_string(packet);
|
||||
if (algo == NULL) {
|
||||
goto error;
|
||||
}
|
||||
pubkey_blob = buffer_get_ssh_string(packet);
|
||||
if (pubkey_blob == NULL) {
|
||||
ssh_string_free(algo);
|
||||
algo = NULL;
|
||||
rc = ssh_buffer_unpack(packet, "bSS",
|
||||
&has_sign,
|
||||
&algo,
|
||||
&pubkey_blob
|
||||
);
|
||||
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(algo);
|
||||
@ -877,7 +771,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_request){
|
||||
goto end;
|
||||
}
|
||||
#ifdef WITH_GSSAPI
|
||||
if (strncmp(method, "gssapi-with-mic", method_size) == 0) {
|
||||
if (strcmp(method, "gssapi-with-mic") == 0) {
|
||||
uint32_t n_oid;
|
||||
ssh_string *oids;
|
||||
ssh_string oid;
|
||||
@ -966,6 +860,7 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
|
||||
uint32_t nanswers;
|
||||
uint32_t i;
|
||||
ssh_string tmp;
|
||||
int rc;
|
||||
|
||||
ssh_message msg = NULL;
|
||||
|
||||
@ -993,7 +888,11 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
|
||||
msg->auth_request.username = NULL;
|
||||
#endif
|
||||
|
||||
buffer_get_u32(packet, &nanswers);
|
||||
rc = ssh_buffer_unpack(packet, "d", &nanswers);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_invalid(session);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (session->kbdint == NULL) {
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Warning: Got a keyboard-interactive "
|
||||
@ -1007,7 +906,6 @@ SSH_PACKET_CALLBACK(ssh_packet_userauth_info_response){
|
||||
}
|
||||
}
|
||||
|
||||
nanswers = ntohl(nanswers);
|
||||
SSH_LOG(SSH_LOG_PACKET,"kbdint: %d answers",nanswers);
|
||||
if (nanswers > KBDINT_MAX_PROMPT) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
@ -1071,9 +969,9 @@ error:
|
||||
|
||||
SSH_PACKET_CALLBACK(ssh_packet_channel_open){
|
||||
ssh_message msg = NULL;
|
||||
ssh_string type_s = NULL, originator = NULL, destination = NULL;
|
||||
char *type_c = NULL;
|
||||
uint32_t sender, window, packet_size, originator_port, destination_port;
|
||||
uint32_t originator_port, destination_port;
|
||||
int rc;
|
||||
|
||||
(void)type;
|
||||
(void)user;
|
||||
@ -1084,30 +982,18 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
|
||||
}
|
||||
|
||||
msg->type = SSH_REQUEST_CHANNEL_OPEN;
|
||||
|
||||
type_s = buffer_get_ssh_string(packet);
|
||||
if (type_s == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
type_c = ssh_string_to_char(type_s);
|
||||
if (type_c == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
rc = ssh_buffer_unpack(packet, "s", &type_c);
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Clients wants to open a %s channel", type_c);
|
||||
ssh_string_free(type_s);
|
||||
type_s=NULL;
|
||||
|
||||
buffer_get_u32(packet, &sender);
|
||||
buffer_get_u32(packet, &window);
|
||||
buffer_get_u32(packet, &packet_size);
|
||||
|
||||
msg->channel_request_open.sender = ntohl(sender);
|
||||
msg->channel_request_open.window = ntohl(window);
|
||||
msg->channel_request_open.packet_size = ntohl(packet_size);
|
||||
ssh_buffer_unpack(packet,"ddd",
|
||||
&msg->channel_request_open.sender,
|
||||
&msg->channel_request_open.window,
|
||||
&msg->channel_request_open.packet_size);
|
||||
|
||||
if (session->session_state != SSH_SESSION_STATE_AUTHENTICATED){
|
||||
ssh_set_error(session,SSH_FATAL, "Invalid state when receiving channel open request (must be authenticated)");
|
||||
@ -1121,96 +1007,46 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_open){
|
||||
}
|
||||
|
||||
if (strcmp(type_c,"direct-tcpip") == 0) {
|
||||
destination = buffer_get_ssh_string(packet);
|
||||
if (destination == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
rc = ssh_buffer_unpack(packet,
|
||||
"sdsd",
|
||||
&msg->channel_request_open.destination,
|
||||
&destination_port,
|
||||
&msg->channel_request_open.originator,
|
||||
&originator_port);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.destination = ssh_string_to_char(destination);
|
||||
if (msg->channel_request_open.destination == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(destination);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(destination);
|
||||
|
||||
buffer_get_u32(packet, &destination_port);
|
||||
msg->channel_request_open.destination_port = (uint16_t) ntohl(destination_port);
|
||||
|
||||
originator = buffer_get_ssh_string(packet);
|
||||
if (originator == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.originator = ssh_string_to_char(originator);
|
||||
if (msg->channel_request_open.originator == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(originator);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(originator);
|
||||
|
||||
buffer_get_u32(packet, &originator_port);
|
||||
msg->channel_request_open.originator_port = (uint16_t) ntohl(originator_port);
|
||||
|
||||
msg->channel_request_open.destination_port = (uint16_t) destination_port;
|
||||
msg->channel_request_open.originator_port = (uint16_t) originator_port;
|
||||
msg->channel_request_open.type = SSH_CHANNEL_DIRECT_TCPIP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp(type_c,"forwarded-tcpip") == 0) {
|
||||
destination = buffer_get_ssh_string(packet);
|
||||
if (destination == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.destination = ssh_string_to_char(destination);
|
||||
if (msg->channel_request_open.destination == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(destination);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(destination);
|
||||
|
||||
buffer_get_u32(packet, &destination_port);
|
||||
msg->channel_request_open.destination_port = (uint16_t) ntohl(destination_port);
|
||||
|
||||
originator = buffer_get_ssh_string(packet);
|
||||
if (originator == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.originator = ssh_string_to_char(originator);
|
||||
if (msg->channel_request_open.originator == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(originator);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(originator);
|
||||
|
||||
buffer_get_u32(packet, &originator_port);
|
||||
msg->channel_request_open.originator_port = (uint16_t) ntohl(originator_port);
|
||||
|
||||
rc = ssh_buffer_unpack(packet, "sdsd",
|
||||
&msg->channel_request_open.destination,
|
||||
&destination_port,
|
||||
&msg->channel_request_open.originator,
|
||||
&originator_port
|
||||
);
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.destination_port = (uint16_t) destination_port;
|
||||
msg->channel_request_open.originator_port = (uint16_t) originator_port;
|
||||
msg->channel_request_open.type = SSH_CHANNEL_FORWARDED_TCPIP;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp(type_c,"x11") == 0) {
|
||||
originator = buffer_get_ssh_string(packet);
|
||||
if (originator == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.originator = ssh_string_to_char(originator);
|
||||
if (msg->channel_request_open.originator == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(originator);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(originator);
|
||||
|
||||
buffer_get_u32(packet, &originator_port);
|
||||
msg->channel_request_open.originator_port = (uint16_t) ntohl(originator_port);
|
||||
|
||||
rc = ssh_buffer_unpack(packet, "sd",
|
||||
&msg->channel_request_open.originator,
|
||||
&originator_port);
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
msg->channel_request_open.originator_port = (uint16_t) originator_port;
|
||||
msg->channel_request_open.type = SSH_CHANNEL_X11;
|
||||
goto end;
|
||||
}
|
||||
@ -1222,8 +1058,6 @@ error:
|
||||
ssh_message_free(msg);
|
||||
msg=NULL;
|
||||
end:
|
||||
if(type_s != NULL)
|
||||
ssh_string_free(type_s);
|
||||
SAFE_FREE(type_c);
|
||||
if(msg != NULL)
|
||||
ssh_message_queue(session,msg);
|
||||
@ -1249,28 +1083,15 @@ int ssh_message_channel_request_open_reply_accept_channel(ssh_message msg, ssh_c
|
||||
chan->remote_window = msg->channel_request_open.window;
|
||||
chan->state = SSH_CHANNEL_STATE_OPEN;
|
||||
|
||||
rc = buffer_add_u8(session->out_buffer, SSH2_MSG_CHANNEL_OPEN_CONFIRMATION);
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->out_buffer, htonl(chan->remote_channel));
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc =buffer_add_u32(session->out_buffer, htonl(chan->local_channel));
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->out_buffer, htonl(chan->local_window));
|
||||
if (rc < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_u32(session->out_buffer, htonl(chan->local_maxpacket));
|
||||
if (rc < 0) {
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bdddd",
|
||||
SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
|
||||
chan->remote_channel,
|
||||
chan->local_channel,
|
||||
chan->local_window,
|
||||
chan->local_maxpacket);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@ -1327,6 +1148,7 @@ ssh_channel ssh_message_channel_request_open_reply_accept(ssh_message msg) {
|
||||
int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel, ssh_buffer packet,
|
||||
const char *request, uint8_t want_reply) {
|
||||
ssh_message msg = NULL;
|
||||
int rc;
|
||||
|
||||
msg = ssh_message_new(session);
|
||||
if (msg == NULL) {
|
||||
@ -1343,36 +1165,18 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
|
||||
msg->channel_request.want_reply = want_reply;
|
||||
|
||||
if (strcmp(request, "pty-req") == 0) {
|
||||
ssh_string term = NULL;
|
||||
char *term_c = NULL;
|
||||
term = buffer_get_ssh_string(packet);
|
||||
if (term == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
term_c = ssh_string_to_char(term);
|
||||
if (term_c == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(term);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(term);
|
||||
rc = ssh_buffer_unpack(packet, "sddddS",
|
||||
&msg->channel_request.TERM,
|
||||
&msg->channel_request.width,
|
||||
&msg->channel_request.height,
|
||||
&msg->channel_request.pxwidth,
|
||||
&msg->channel_request.pxheight,
|
||||
&msg->channel_request.modes
|
||||
);
|
||||
|
||||
msg->channel_request.type = SSH_CHANNEL_REQUEST_PTY;
|
||||
msg->channel_request.TERM = term_c;
|
||||
|
||||
buffer_get_u32(packet, &msg->channel_request.width);
|
||||
buffer_get_u32(packet, &msg->channel_request.height);
|
||||
buffer_get_u32(packet, &msg->channel_request.pxwidth);
|
||||
buffer_get_u32(packet, &msg->channel_request.pxheight);
|
||||
|
||||
msg->channel_request.width = ntohl(msg->channel_request.width);
|
||||
msg->channel_request.height = ntohl(msg->channel_request.height);
|
||||
msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
|
||||
msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
|
||||
msg->channel_request.modes = buffer_get_ssh_string(packet);
|
||||
if (msg->channel_request.modes == NULL) {
|
||||
SAFE_FREE(term_c);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
goto end;
|
||||
@ -1380,39 +1184,24 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
|
||||
|
||||
if (strcmp(request, "window-change") == 0) {
|
||||
msg->channel_request.type = SSH_CHANNEL_REQUEST_WINDOW_CHANGE;
|
||||
|
||||
buffer_get_u32(packet, &msg->channel_request.width);
|
||||
buffer_get_u32(packet, &msg->channel_request.height);
|
||||
buffer_get_u32(packet, &msg->channel_request.pxwidth);
|
||||
buffer_get_u32(packet, &msg->channel_request.pxheight);
|
||||
|
||||
msg->channel_request.width = ntohl(msg->channel_request.width);
|
||||
msg->channel_request.height = ntohl(msg->channel_request.height);
|
||||
msg->channel_request.pxwidth = ntohl(msg->channel_request.pxwidth);
|
||||
msg->channel_request.pxheight = ntohl(msg->channel_request.pxheight);
|
||||
|
||||
rc = ssh_buffer_unpack(packet, "dddd",
|
||||
&msg->channel_request.width,
|
||||
&msg->channel_request.height,
|
||||
&msg->channel_request.pxwidth,
|
||||
&msg->channel_request.pxheight);
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp(request, "subsystem") == 0) {
|
||||
ssh_string subsys = NULL;
|
||||
char *subsys_c = NULL;
|
||||
subsys = buffer_get_ssh_string(packet);
|
||||
if (subsys == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
subsys_c = ssh_string_to_char(subsys);
|
||||
if (subsys_c == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(subsys);
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(subsys);
|
||||
|
||||
rc = ssh_buffer_unpack(packet, "s",
|
||||
&msg->channel_request.subsystem);
|
||||
msg->channel_request.type = SSH_CHANNEL_REQUEST_SUBSYSTEM;
|
||||
msg->channel_request.subsystem = subsys_c;
|
||||
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
@ -1422,82 +1211,37 @@ int ssh_message_handle_channel_request(ssh_session session, ssh_channel channel,
|
||||
}
|
||||
|
||||
if (strcmp(request, "exec") == 0) {
|
||||
ssh_string cmd = NULL;
|
||||
cmd = buffer_get_ssh_string(packet);
|
||||
if (cmd == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_buffer_unpack(packet, "s",
|
||||
&msg->channel_request.command);
|
||||
msg->channel_request.type = SSH_CHANNEL_REQUEST_EXEC;
|
||||
msg->channel_request.command = ssh_string_to_char(cmd);
|
||||
ssh_string_free(cmd);
|
||||
if (msg->channel_request.command == NULL) {
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp(request, "env") == 0) {
|
||||
ssh_string name = NULL;
|
||||
ssh_string value = NULL;
|
||||
name = buffer_get_ssh_string(packet);
|
||||
if (name == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
value = buffer_get_ssh_string(packet);
|
||||
if (value == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_unpack(packet, "ss",
|
||||
&msg->channel_request.var_name,
|
||||
&msg->channel_request.var_value);
|
||||
msg->channel_request.type = SSH_CHANNEL_REQUEST_ENV;
|
||||
msg->channel_request.var_name = ssh_string_to_char(name);
|
||||
msg->channel_request.var_value = ssh_string_to_char(value);
|
||||
if (msg->channel_request.var_name == NULL ||
|
||||
msg->channel_request.var_value == NULL) {
|
||||
ssh_string_free(name);
|
||||
ssh_string_free(value);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(name);
|
||||
ssh_string_free(value);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strcmp(request, "x11-req") == 0) {
|
||||
ssh_string auth_protocol = NULL;
|
||||
ssh_string auth_cookie = NULL;
|
||||
|
||||
buffer_get_u8(packet, &msg->channel_request.x11_single_connection);
|
||||
|
||||
auth_protocol = buffer_get_ssh_string(packet);
|
||||
if (auth_protocol == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
auth_cookie = buffer_get_ssh_string(packet);
|
||||
if (auth_cookie == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
ssh_string_free(auth_protocol);
|
||||
goto error;
|
||||
}
|
||||
rc = ssh_buffer_unpack(packet, "bssd",
|
||||
&msg->channel_request.x11_single_connection,
|
||||
&msg->channel_request.x11_auth_protocol,
|
||||
&msg->channel_request.x11_auth_cookie,
|
||||
&msg->channel_request.x11_screen_number);
|
||||
|
||||
msg->channel_request.type = SSH_CHANNEL_REQUEST_X11;
|
||||
msg->channel_request.x11_auth_protocol = ssh_string_to_char(auth_protocol);
|
||||
msg->channel_request.x11_auth_cookie = ssh_string_to_char(auth_cookie);
|
||||
if (msg->channel_request.x11_auth_protocol == NULL ||
|
||||
msg->channel_request.x11_auth_cookie == NULL) {
|
||||
ssh_string_free(auth_protocol);
|
||||
ssh_string_free(auth_cookie);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
ssh_string_free(auth_protocol);
|
||||
ssh_string_free(auth_cookie);
|
||||
|
||||
buffer_get_u32(packet, &msg->channel_request.x11_screen_number);
|
||||
|
||||
goto end;
|
||||
}
|
||||
@ -1515,6 +1259,7 @@ error:
|
||||
|
||||
int ssh_message_channel_request_reply_success(ssh_message msg) {
|
||||
uint32_t channel;
|
||||
int rc;
|
||||
|
||||
if (msg == NULL) {
|
||||
return SSH_ERROR;
|
||||
@ -1526,10 +1271,12 @@ int ssh_message_channel_request_reply_success(ssh_message msg) {
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Sending a channel_request success to channel %d", channel);
|
||||
|
||||
if (buffer_add_u8(msg->session->out_buffer, SSH2_MSG_CHANNEL_SUCCESS) < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
if (buffer_add_u32(msg->session->out_buffer, htonl(channel)) < 0) {
|
||||
rc = ssh_buffer_pack(msg->session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_CHANNEL_SUCCESS,
|
||||
channel);
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error_oom(msg->session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
@ -1545,72 +1292,65 @@ int ssh_message_channel_request_reply_success(ssh_message msg) {
|
||||
#ifdef WITH_SERVER
|
||||
SSH_PACKET_CALLBACK(ssh_packet_global_request){
|
||||
ssh_message msg = NULL;
|
||||
ssh_string request_s=NULL;
|
||||
char *request=NULL;
|
||||
ssh_string bind_addr_s=NULL;
|
||||
char *bind_addr=NULL;
|
||||
uint32_t bind_port;
|
||||
uint8_t want_reply;
|
||||
int rc = SSH_PACKET_USED;
|
||||
int r;
|
||||
(void)user;
|
||||
(void)type;
|
||||
(void)packet;
|
||||
|
||||
request_s = buffer_get_ssh_string(packet);
|
||||
if (request_s != NULL) {
|
||||
request = ssh_string_to_char(request_s);
|
||||
ssh_string_free(request_s);
|
||||
}
|
||||
|
||||
buffer_get_u8(packet, &want_reply);
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL,"Received SSH_MSG_GLOBAL_REQUEST packet");
|
||||
r = ssh_buffer_unpack(packet, "sb",
|
||||
&request,
|
||||
&want_reply);
|
||||
if (r != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
|
||||
msg = ssh_message_new(session);
|
||||
if (msg == NULL) {
|
||||
ssh_string_free_char(request);
|
||||
return SSH_PACKET_NOT_USED;
|
||||
ssh_set_error_oom(session);
|
||||
goto error;
|
||||
}
|
||||
msg->type = SSH_REQUEST_GLOBAL;
|
||||
|
||||
if (request && strcmp(request, "tcpip-forward") == 0) {
|
||||
bind_addr_s = buffer_get_ssh_string(packet);
|
||||
if (bind_addr_s != NULL) {
|
||||
bind_addr = ssh_string_to_char(bind_addr_s);
|
||||
ssh_string_free(bind_addr_s);
|
||||
if (strcmp(request, "tcpip-forward") == 0) {
|
||||
r = ssh_buffer_unpack(packet, "sd",
|
||||
&msg->global_request.bind_address,
|
||||
&msg->global_request.bind_port
|
||||
);
|
||||
if (r != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
|
||||
buffer_get_u32(packet, &bind_port);
|
||||
bind_port = ntohl(bind_port);
|
||||
|
||||
msg->global_request.type = SSH_GLOBAL_REQUEST_TCPIP_FORWARD;
|
||||
msg->global_request.want_reply = want_reply;
|
||||
msg->global_request.bind_address = bind_addr;
|
||||
msg->global_request.bind_port = bind_port;
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply,
|
||||
msg->global_request.bind_address,
|
||||
msg->global_request.bind_port);
|
||||
|
||||
if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) {
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Calling callback for SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request,
|
||||
want_reply, msg->global_request.bind_address,
|
||||
msg->global_request.bind_port);
|
||||
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
|
||||
} else {
|
||||
ssh_message_reply_default(msg);
|
||||
}
|
||||
} else if (request && strcmp(request, "cancel-tcpip-forward") == 0) {
|
||||
bind_addr_s = buffer_get_ssh_string(packet);
|
||||
if (bind_addr_s != NULL) {
|
||||
bind_addr = ssh_string_to_char(bind_addr_s);
|
||||
ssh_string_free(bind_addr_s);
|
||||
} else if (strcmp(request, "cancel-tcpip-forward") == 0) {
|
||||
r = ssh_buffer_unpack(packet, "sd",
|
||||
&msg->global_request.bind_address,
|
||||
&msg->global_request.bind_port);
|
||||
if (r != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
buffer_get_u32(packet, &bind_port);
|
||||
bind_port = ntohl(bind_port);
|
||||
|
||||
msg->global_request.type = SSH_GLOBAL_REQUEST_CANCEL_TCPIP_FORWARD;
|
||||
msg->global_request.want_reply = want_reply;
|
||||
msg->global_request.bind_address = bind_addr;
|
||||
msg->global_request.bind_port = bind_port;
|
||||
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply, bind_addr, bind_port);
|
||||
SSH_LOG(SSH_LOG_PROTOCOL, "Received SSH_MSG_GLOBAL_REQUEST %s %d %s:%d", request, want_reply,
|
||||
msg->global_request.bind_address,
|
||||
msg->global_request.bind_port);
|
||||
|
||||
if(ssh_callbacks_exists(session->common.callbacks, global_request_function)) {
|
||||
session->common.callbacks->global_request_function(session, msg, session->common.callbacks->userdata);
|
||||
@ -1624,9 +1364,12 @@ SSH_PACKET_CALLBACK(ssh_packet_global_request){
|
||||
|
||||
SAFE_FREE(msg);
|
||||
SAFE_FREE(request);
|
||||
SAFE_FREE(bind_addr);
|
||||
|
||||
return rc;
|
||||
error:
|
||||
SAFE_FREE(msg);
|
||||
SAFE_FREE(request);
|
||||
SSH_LOG(SSH_LOG_WARNING, "Invalid SSH_MSG_GLOBAL_REQUEST packet");
|
||||
return SSH_PACKET_NOT_USED;
|
||||
}
|
||||
|
||||
#endif /* WITH_SERVER */
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2008-2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2008-2009 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -697,7 +697,6 @@ char *ssh_path_expand_tilde(const char *d) {
|
||||
}
|
||||
|
||||
char *ssh_path_expand_escape(ssh_session session, const char *s) {
|
||||
#define MAX_BUF_SIZE 4096
|
||||
char host[NI_MAXHOST];
|
||||
char buf[MAX_BUF_SIZE];
|
||||
char *r, *x = NULL;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -136,7 +136,7 @@ int ssh_options_copy(ssh_session src, ssh_session *dest) {
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (src->opts.wanted_methods[i]) {
|
||||
new->opts.wanted_methods[i] = strdup(src->opts.wanted_methods[i]);
|
||||
if (new->opts.wanted_methods[i] == NULL) {
|
||||
@ -367,6 +367,18 @@ int ssh_options_set_algo(ssh_session session, int algo,
|
||||
* Set the command to be executed in order to connect to
|
||||
* server (const char *).
|
||||
*
|
||||
* - SSH_OPTIONS_GSSAPI_SERVER_IDENTITY
|
||||
* Set it to specify the GSSAPI server identity that libssh
|
||||
* should expect when connecting to the server (const char *).
|
||||
*
|
||||
* - SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY
|
||||
* Set it to specify the GSSAPI client identity that libssh
|
||||
* should expect when connecting to the server (const char *).
|
||||
*
|
||||
* - SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS
|
||||
* Set it to specify that GSSAPI should delegate credentials
|
||||
* to the server (int, 0 = false).
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
@ -661,6 +673,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
}
|
||||
|
||||
session->common.log_verbosity = i & 0xffff;
|
||||
ssh_set_log_level(i & 0xffff);
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_CIPHERS_C_S:
|
||||
@ -703,6 +716,26 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_HMAC_C_S:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
if (ssh_options_set_algo(session, SSH_MAC_C_S, v) < 0)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_HMAC_S_C:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
if (ssh_options_set_algo(session, SSH_MAC_S_C, v) < 0)
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_COMPRESSION_C_S:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
@ -792,6 +825,45 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_GSSAPI_SERVER_IDENTITY:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(session->opts.gss_server_identity);
|
||||
session->opts.gss_server_identity = strdup(v);
|
||||
if (session->opts.gss_server_identity == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_GSSAPI_CLIENT_IDENTITY:
|
||||
v = value;
|
||||
if (v == NULL || v[0] == '\0') {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(session->opts.gss_client_identity);
|
||||
session->opts.gss_client_identity = strdup(v);
|
||||
if (session->opts.gss_client_identity == NULL) {
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SSH_OPTIONS_GSSAPI_DELEGATE_CREDENTIALS:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(session);
|
||||
return -1;
|
||||
} else {
|
||||
int x = *(int *)value;
|
||||
|
||||
session->opts.gss_delegate_creds = (x & 0xff);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||
return -1;
|
||||
@ -1232,84 +1304,93 @@ int ssh_options_apply(ssh_session session) {
|
||||
* @addtogroup libssh_server
|
||||
* @{
|
||||
*/
|
||||
static int ssh_bind_options_set_algo(ssh_bind sshbind, int algo,
|
||||
const char *list) {
|
||||
if (!verify_existing_algo(algo, list)) {
|
||||
ssh_set_error(sshbind, SSH_REQUEST_DENIED,
|
||||
"Setting method: no algorithm for method \"%s\" (%s)\n",
|
||||
ssh_kex_get_description(algo), list);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SAFE_FREE(sshbind->wanted_methods[algo]);
|
||||
sshbind->wanted_methods[algo] = strdup(list);
|
||||
if (sshbind->wanted_methods[algo] == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
static int ssh_bind_set_key(ssh_bind sshbind, char **key_loc,
|
||||
const void *value) {
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(*key_loc);
|
||||
*key_loc = strdup(value);
|
||||
if (*key_loc == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function can set all possible ssh bind options.
|
||||
* @brief Set options for an SSH server bind.
|
||||
*
|
||||
* @param sshbind An allocated ssh bind structure.
|
||||
* @param sshbind The ssh server bind to configure.
|
||||
*
|
||||
* @param type The option type to set. This could be one of the
|
||||
* @param type The option type to set. This should be one of the
|
||||
* following:
|
||||
*
|
||||
* SSH_BIND_OPTIONS_LOG_VERBOSITY:
|
||||
* Set the session logging verbosity (integer).
|
||||
* - SSH_BIND_OPTIONS_HOSTKEY:
|
||||
* Set the path to an ssh host key, regardless
|
||||
* of type. Only one key from per key type
|
||||
* (RSA, DSA, ECDSA) is allowed in an ssh_bind
|
||||
* at a time, and later calls to this function
|
||||
* with this option for the same key type will
|
||||
* override prior calls (const char *).
|
||||
*
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* SSH_LOG_NOLOG: No logging
|
||||
* SSH_LOG_RARE: Rare conditions or warnings
|
||||
* SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* SSH_LOG_PACKET: Packet id and size
|
||||
* SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
* - SSH_BIND_OPTIONS_BINDADDR:
|
||||
* Set the IP address to bind (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
|
||||
* Set the session logging verbosity (integer).
|
||||
* - SSH_BIND_OPTIONS_BINDPORT:
|
||||
* Set the port to bind (unsigned int *).
|
||||
*
|
||||
* The verbosity of the messages. Every log smaller or
|
||||
* equal to verbosity will be shown.
|
||||
* SSH_LOG_NOLOG: No logging
|
||||
* SSH_LOG_RARE: Rare conditions or warnings
|
||||
* SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* SSH_LOG_PACKET: Packet id and size
|
||||
* SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
* - SSH_BIND_OPTIONS_BINDPORT_STR:
|
||||
* Set the port to bind (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_BINDADDR:
|
||||
* Set the bind address.
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY:
|
||||
* Set the session logging verbosity (int *).
|
||||
* The logging verbosity should have one of the
|
||||
* following values, which are listed in order
|
||||
* of increasing verbosity. Every log message
|
||||
* with verbosity less than or equal to the
|
||||
* logging verbosity will be shown.
|
||||
* - SSH_LOG_NOLOG: No logging
|
||||
* - SSH_LOG_RARE: Rare conditions or warnings
|
||||
* - SSH_LOG_ENTRY: API-accessible entrypoints
|
||||
* - SSH_LOG_PACKET: Packet id and size
|
||||
* - SSH_LOG_FUNCTIONS: Function entering and leaving
|
||||
*
|
||||
* SSH_BIND_OPTIONS_BINDPORT:
|
||||
* Set the bind port, default is 22.
|
||||
* - SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
|
||||
* Set the session logging verbosity via a
|
||||
* string that will be converted to a numerical
|
||||
* value (e.g. "3") and interpreted according
|
||||
* to the values of
|
||||
* SSH_BIND_OPTIONS_LOG_VERBOSITY above (const
|
||||
* char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_HOSTKEY:
|
||||
* Set the server public key type: ssh-rsa or ssh-dss
|
||||
* (string).
|
||||
* - SSH_BIND_OPTIONS_DSAKEY:
|
||||
* Set the path to the ssh host dsa key, SSHv2
|
||||
* only (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_DSAKEY:
|
||||
* Set the path to the dsa ssh host key (string).
|
||||
* - SSH_BIND_OPTIONS_RSAKEY:
|
||||
* Set the path to the ssh host rsa key, SSHv2
|
||||
* only (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_RSAKEY:
|
||||
* Set the path to the ssh host rsa key (string).
|
||||
* - SSH_BIND_OPTIONS_ECDSAKEY:
|
||||
* Set the path to the ssh host ecdsa key,
|
||||
* SSHv2 only (const char *).
|
||||
*
|
||||
* SSH_BIND_OPTIONS_BANNER:
|
||||
* Set the server banner sent to clients (string).
|
||||
* - SSH_BIND_OPTIONS_BANNER:
|
||||
* Set the server banner sent to clients (const char *).
|
||||
*
|
||||
* @param value The value to set. This is a generic pointer and the
|
||||
* datatype which is used should be set according to the
|
||||
* type set.
|
||||
* datatype which should be used is described at the
|
||||
* corresponding value of type above.
|
||||
*
|
||||
* @return 0 on success, < 0 on error.
|
||||
* @return 0 on success, < 0 on error, invalid option, or parameter.
|
||||
*/
|
||||
int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
const void *value) {
|
||||
char *p, *q;
|
||||
int i;
|
||||
int i, rc;
|
||||
|
||||
if (sshbind == NULL) {
|
||||
return -1;
|
||||
@ -1321,8 +1402,57 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
if (ssh_bind_options_set_algo(sshbind, SSH_HOSTKEYS, value) < 0)
|
||||
return -1;
|
||||
int key_type;
|
||||
ssh_key key;
|
||||
ssh_key *bind_key_loc = NULL;
|
||||
char **bind_key_path_loc;
|
||||
|
||||
rc = ssh_pki_import_privkey_file(value, NULL, NULL, NULL, &key);
|
||||
if (rc != SSH_OK) {
|
||||
return -1;
|
||||
}
|
||||
key_type = ssh_key_type(key);
|
||||
switch (key_type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
bind_key_loc = &sshbind->dsa;
|
||||
bind_key_path_loc = &sshbind->dsakey;
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_ECC
|
||||
bind_key_loc = &sshbind->ecdsa;
|
||||
bind_key_path_loc = &sshbind->ecdsakey;
|
||||
#else
|
||||
ssh_set_error(sshbind,
|
||||
SSH_FATAL,
|
||||
"ECDSA key used and libssh compiled "
|
||||
"without ECDSA support");
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
bind_key_loc = &sshbind->rsa;
|
||||
bind_key_path_loc = &sshbind->rsakey;
|
||||
break;
|
||||
default:
|
||||
ssh_set_error(sshbind,
|
||||
SSH_FATAL,
|
||||
"Unsupported key type %d", key_type);
|
||||
}
|
||||
|
||||
if (bind_key_loc == NULL) {
|
||||
ssh_key_free(key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set the location of the key on disk even though we don't
|
||||
need it in case some other function wants it */
|
||||
rc = ssh_bind_set_key(sshbind, bind_key_path_loc, value);
|
||||
if (rc < 0) {
|
||||
ssh_key_free(key);
|
||||
return -1;
|
||||
}
|
||||
ssh_key_free(*bind_key_loc);
|
||||
*bind_key_loc = key;
|
||||
}
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_BINDADDR:
|
||||
@ -1376,7 +1506,7 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_LOG_VERBOSITY_STR:
|
||||
if (value == NULL) {
|
||||
sshbind->common.log_verbosity = 0;
|
||||
ssh_set_log_level(0);
|
||||
} else {
|
||||
q = strdup(value);
|
||||
if (q == NULL) {
|
||||
@ -1389,35 +1519,27 @@ int ssh_bind_options_set(ssh_bind sshbind, enum ssh_bind_options_e type,
|
||||
}
|
||||
SAFE_FREE(q);
|
||||
|
||||
sshbind->common.log_verbosity = i & 0xffff;
|
||||
ssh_set_log_level(i & 0xffff);
|
||||
}
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_DSAKEY:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(sshbind->dsakey);
|
||||
sshbind->dsakey = strdup(value);
|
||||
if (sshbind->dsakey == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
rc = ssh_bind_set_key(sshbind, &sshbind->dsakey, value);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_RSAKEY:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
return -1;
|
||||
} else {
|
||||
SAFE_FREE(sshbind->rsakey);
|
||||
sshbind->rsakey = strdup(value);
|
||||
if (sshbind->rsakey == NULL) {
|
||||
ssh_set_error_oom(sshbind);
|
||||
return -1;
|
||||
rc = ssh_bind_set_key(sshbind, &sshbind->rsakey, value);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_ECDSAKEY:
|
||||
rc = ssh_bind_set_key(sshbind, &sshbind->ecdsakey, value);
|
||||
if (rc < 0) {
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case SSH_BIND_OPTIONS_BANNER:
|
||||
if (value == NULL) {
|
||||
ssh_set_error_invalid(sshbind);
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2008 by Aris Adamantiadis
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -48,8 +48,6 @@
|
||||
#include "libssh/auth.h"
|
||||
#include "libssh/gssapi.h"
|
||||
|
||||
#define MACSIZE SHA_DIGEST_LEN
|
||||
|
||||
static ssh_packet_callback default_packet_handlers[]= {
|
||||
ssh_packet_disconnect_callback, // SSH2_MSG_DISCONNECT 1
|
||||
ssh_packet_ignore_callback, // SSH2_MSG_IGNORE 2
|
||||
@ -141,174 +139,225 @@ static ssh_packet_callback default_packet_handlers[]= {
|
||||
* @len length of data received. It might not be enough for a complete packet
|
||||
* @returns number of bytes read and processed.
|
||||
*/
|
||||
int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user){
|
||||
ssh_session session=(ssh_session) user;
|
||||
unsigned int blocksize = (session->current_crypto ?
|
||||
session->current_crypto->in_cipher->blocksize : 8);
|
||||
int current_macsize = session->current_crypto ? MACSIZE : 0;
|
||||
unsigned char mac[30] = {0};
|
||||
char buffer[16] = {0};
|
||||
const void *packet = NULL;
|
||||
int to_be_read;
|
||||
int rc;
|
||||
uint32_t len, compsize, payloadsize;
|
||||
uint8_t padding;
|
||||
size_t processed=0; /* number of byte processed from the callback */
|
||||
int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
|
||||
{
|
||||
ssh_session session= (ssh_session) user;
|
||||
unsigned int blocksize = (session->current_crypto ?
|
||||
session->current_crypto->in_cipher->blocksize : 8);
|
||||
unsigned char mac[DIGEST_MAX_LEN] = {0};
|
||||
char buffer[16] = {0};
|
||||
size_t current_macsize = 0;
|
||||
const uint8_t *packet;
|
||||
int to_be_read;
|
||||
int rc;
|
||||
uint32_t len, compsize, payloadsize;
|
||||
uint8_t padding;
|
||||
size_t processed = 0; /* number of byte processed from the callback */
|
||||
|
||||
if (data == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if(session->current_crypto != NULL) {
|
||||
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
|
||||
}
|
||||
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR)
|
||||
goto error;
|
||||
switch(session->packet_state) {
|
||||
case PACKET_STATE_INIT:
|
||||
if(receivedlen < blocksize){
|
||||
/* We didn't receive enough data to read at least one block size, give up */
|
||||
return 0;
|
||||
}
|
||||
memset(&session->in_packet, 0, sizeof(PACKET));
|
||||
|
||||
if (session->in_buffer) {
|
||||
if (buffer_reinit(session->in_buffer) < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
session->in_buffer = ssh_buffer_new();
|
||||
if (session->in_buffer == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(buffer,data,blocksize);
|
||||
processed += blocksize;
|
||||
len = packet_decrypt_len(session, buffer);
|
||||
|
||||
if (buffer_add_data(session->in_buffer, buffer, blocksize) < 0) {
|
||||
if (data == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if(len > MAX_PACKET_LEN) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"read_packet(): Packet len too high(%u %.4x)", len, len);
|
||||
if (session->session_state == SSH_SESSION_STATE_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
to_be_read = len - blocksize + sizeof(uint32_t);
|
||||
if (to_be_read < 0) {
|
||||
/* remote sshd sends invalid sizes? */
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"given numbers of bytes left to be read < 0 (%d)!", to_be_read);
|
||||
goto error;
|
||||
}
|
||||
switch(session->packet_state) {
|
||||
case PACKET_STATE_INIT:
|
||||
if (receivedlen < blocksize) {
|
||||
/*
|
||||
* We didn't receive enough data to read at least one
|
||||
* block size, give up
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* saves the status of the current operations */
|
||||
session->in_packet.len = len;
|
||||
session->packet_state = PACKET_STATE_SIZEREAD;
|
||||
/* FALL TROUGH */
|
||||
case PACKET_STATE_SIZEREAD:
|
||||
len = session->in_packet.len;
|
||||
to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize;
|
||||
/* if to_be_read is zero, the whole packet was blocksize bytes. */
|
||||
if (to_be_read != 0) {
|
||||
if(receivedlen - processed < (unsigned int)to_be_read){
|
||||
/* give up, not enough data in buffer */
|
||||
SSH_LOG(SSH_LOG_PACKET,"packet: partial packet (read len) [len=%d]",len);
|
||||
return processed;
|
||||
}
|
||||
memset(&session->in_packet, 0, sizeof(PACKET));
|
||||
|
||||
packet = ((unsigned char *)data) + processed;
|
||||
// ssh_socket_read(session->socket,packet,to_be_read-current_macsize);
|
||||
if (session->in_buffer) {
|
||||
rc = ssh_buffer_reinit(session->in_buffer);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
session->in_buffer = ssh_buffer_new();
|
||||
if (session->in_buffer == NULL) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer_add_data(session->in_buffer, packet,
|
||||
to_be_read - current_macsize) < 0) {
|
||||
goto error;
|
||||
}
|
||||
processed += to_be_read - current_macsize;
|
||||
}
|
||||
memcpy(buffer, data, blocksize);
|
||||
processed += blocksize;
|
||||
len = packet_decrypt_len(session, buffer);
|
||||
|
||||
if (session->current_crypto) {
|
||||
/*
|
||||
* decrypt the rest of the packet (blocksize bytes already
|
||||
* have been decrypted)
|
||||
*/
|
||||
if (packet_decrypt(session,
|
||||
((uint8_t*)buffer_get_rest(session->in_buffer) + blocksize),
|
||||
buffer_get_rest_len(session->in_buffer) - blocksize) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Decrypt error");
|
||||
goto error;
|
||||
}
|
||||
/* copy the last part from the incoming buffer */
|
||||
memcpy(mac,(unsigned char *)packet + to_be_read - current_macsize, MACSIZE);
|
||||
rc = ssh_buffer_add_data(session->in_buffer, buffer, blocksize);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (packet_hmac_verify(session, session->in_buffer, mac) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
||||
goto error;
|
||||
}
|
||||
processed += current_macsize;
|
||||
}
|
||||
if (len > MAX_PACKET_LEN) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"read_packet(): Packet len too high(%u %.4x)",
|
||||
len, len);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* skip the size field which has been processed before */
|
||||
buffer_pass_bytes(session->in_buffer, sizeof(uint32_t));
|
||||
to_be_read = len - blocksize + sizeof(uint32_t);
|
||||
if (to_be_read < 0) {
|
||||
/* remote sshd sends invalid sizes? */
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Given numbers of bytes left to be read < 0 (%d)!",
|
||||
to_be_read);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (buffer_get_u8(session->in_buffer, &padding) == 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Packet too short to read padding");
|
||||
goto error;
|
||||
}
|
||||
/* Saves the status of the current operations */
|
||||
session->in_packet.len = len;
|
||||
session->packet_state = PACKET_STATE_SIZEREAD;
|
||||
/* FALL TROUGH */
|
||||
case PACKET_STATE_SIZEREAD:
|
||||
len = session->in_packet.len;
|
||||
to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize;
|
||||
/* if to_be_read is zero, the whole packet was blocksize bytes. */
|
||||
if (to_be_read != 0) {
|
||||
if (receivedlen - processed < (unsigned int)to_be_read) {
|
||||
/* give up, not enough data in buffer */
|
||||
SSH_LOG(SSH_LOG_PACKET,"packet: partial packet (read len) [len=%d]",len);
|
||||
return processed;
|
||||
}
|
||||
|
||||
if (padding > buffer_get_rest_len(session->in_buffer)) {
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Invalid padding: %d (%d left)",
|
||||
padding,
|
||||
buffer_get_rest_len(session->in_buffer));
|
||||
goto error;
|
||||
}
|
||||
buffer_pass_bytes_end(session->in_buffer, padding);
|
||||
compsize = buffer_get_rest_len(session->in_buffer);
|
||||
packet = ((uint8_t*)data) + processed;
|
||||
#if 0
|
||||
ssh_socket_read(session->socket,
|
||||
packet,
|
||||
to_be_read - current_macsize);
|
||||
#endif
|
||||
|
||||
rc = ssh_buffer_add_data(session->in_buffer,
|
||||
packet,
|
||||
to_be_read - current_macsize);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
processed += to_be_read - current_macsize;
|
||||
}
|
||||
|
||||
if (session->current_crypto) {
|
||||
/*
|
||||
* Decrypt the rest of the packet (blocksize bytes already
|
||||
* have been decrypted)
|
||||
*/
|
||||
uint32_t buffer_len = buffer_get_rest_len(session->in_buffer);
|
||||
|
||||
/* The following check avoids decrypting zero bytes */
|
||||
if (buffer_len > blocksize) {
|
||||
uint8_t *payload = ((uint8_t*)buffer_get_rest(session->in_buffer) + blocksize);
|
||||
uint32_t plen = buffer_len - blocksize;
|
||||
|
||||
rc = packet_decrypt(session, payload, plen);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Decrypt error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy the last part from the incoming buffer */
|
||||
packet = ((uint8_t *)data) + processed;
|
||||
memcpy(mac, packet, current_macsize);
|
||||
|
||||
rc = packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
||||
goto error;
|
||||
}
|
||||
processed += current_macsize;
|
||||
}
|
||||
|
||||
/* skip the size field which has been processed before */
|
||||
buffer_pass_bytes(session->in_buffer, sizeof(uint32_t));
|
||||
|
||||
rc = buffer_get_u8(session->in_buffer, &padding);
|
||||
if (rc == 0) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Packet too short to read padding");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (padding > buffer_get_rest_len(session->in_buffer)) {
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Invalid padding: %d (%d left)",
|
||||
padding,
|
||||
buffer_get_rest_len(session->in_buffer));
|
||||
goto error;
|
||||
}
|
||||
buffer_pass_bytes_end(session->in_buffer, padding);
|
||||
compsize = buffer_get_rest_len(session->in_buffer);
|
||||
|
||||
#ifdef WITH_ZLIB
|
||||
if (session->current_crypto
|
||||
&& session->current_crypto->do_compress_in
|
||||
&& buffer_get_rest_len(session->in_buffer)) {
|
||||
if (decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN) < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
if (session->current_crypto
|
||||
&& session->current_crypto->do_compress_in
|
||||
&& buffer_get_rest_len(session->in_buffer) > 0) {
|
||||
rc = decompress_buffer(session, session->in_buffer,MAX_PACKET_LEN);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
#endif /* WITH_ZLIB */
|
||||
payloadsize=buffer_get_rest_len(session->in_buffer);
|
||||
session->recv_seq++;
|
||||
/* We don't want to rewrite a new packet while still executing the packet callbacks */
|
||||
session->packet_state = PACKET_STATE_PROCESSING;
|
||||
ssh_packet_parse_type(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
|
||||
session->in_packet.type, len, padding, compsize, payloadsize);
|
||||
/* execute callbacks */
|
||||
ssh_packet_process(session, session->in_packet.type);
|
||||
session->packet_state = PACKET_STATE_INIT;
|
||||
if(processed < receivedlen){
|
||||
/* Handle a potential packet left in socket buffer */
|
||||
SSH_LOG(SSH_LOG_PACKET,"Processing %" PRIdS " bytes left in socket buffer",
|
||||
receivedlen-processed);
|
||||
rc = ssh_packet_socket_callback(((unsigned char *)data) + processed,
|
||||
receivedlen - processed,user);
|
||||
processed += rc;
|
||||
}
|
||||
payloadsize = buffer_get_rest_len(session->in_buffer);
|
||||
session->recv_seq++;
|
||||
if (session->raw_counter != NULL) {
|
||||
session->raw_counter->in_bytes += payloadsize;
|
||||
session->raw_counter->in_packets++;
|
||||
}
|
||||
|
||||
return processed;
|
||||
case PACKET_STATE_PROCESSING:
|
||||
SSH_LOG(SSH_LOG_RARE, "Nested packet processing. Delaying.");
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* We don't want to rewrite a new packet while still executing the
|
||||
* packet callbacks
|
||||
*/
|
||||
session->packet_state = PACKET_STATE_PROCESSING;
|
||||
ssh_packet_parse_type(session);
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
|
||||
session->in_packet.type, len, padding, compsize, payloadsize);
|
||||
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Invalid state into packet_read2(): %d",
|
||||
session->packet_state);
|
||||
/* Execute callbacks */
|
||||
ssh_packet_process(session, session->in_packet.type);
|
||||
session->packet_state = PACKET_STATE_INIT;
|
||||
if (processed < receivedlen) {
|
||||
/* Handle a potential packet left in socket buffer */
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"Processing %" PRIdS " bytes left in socket buffer",
|
||||
receivedlen-processed);
|
||||
|
||||
packet = ((uint8_t*)data) + processed;
|
||||
|
||||
rc = ssh_packet_socket_callback(packet, receivedlen - processed,user);
|
||||
processed += rc;
|
||||
}
|
||||
|
||||
return processed;
|
||||
case PACKET_STATE_PROCESSING:
|
||||
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"Invalid state into packet_read2(): %d",
|
||||
session->packet_state);
|
||||
|
||||
error:
|
||||
session->session_state= SSH_SESSION_STATE_ERROR;
|
||||
session->session_state= SSH_SESSION_STATE_ERROR;
|
||||
|
||||
return processed;
|
||||
return processed;
|
||||
}
|
||||
|
||||
void ssh_packet_register_socket_callback(ssh_session session, ssh_socket s){
|
||||
@ -393,34 +442,42 @@ void ssh_packet_process(ssh_session session, uint8_t type){
|
||||
* @return SSH_ERROR on error, else SSH_OK
|
||||
*/
|
||||
int ssh_packet_send_unimplemented(ssh_session session, uint32_t seqnum){
|
||||
int r;
|
||||
int rc;
|
||||
|
||||
r = buffer_add_u8(session->out_buffer, SSH2_MSG_UNIMPLEMENTED);
|
||||
if (r < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
r = buffer_add_u32(session->out_buffer, htonl(seqnum));
|
||||
if (r < 0) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
r = packet_send(session);
|
||||
rc = ssh_buffer_pack(session->out_buffer,
|
||||
"bd",
|
||||
SSH2_MSG_UNIMPLEMENTED,
|
||||
seqnum);
|
||||
if (rc != SSH_OK) {
|
||||
ssh_set_error_oom(session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
rc = packet_send(session);
|
||||
|
||||
return r;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
* @brief handles a SSH_MSG_UNIMPLEMENTED packet
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_unimplemented){
|
||||
uint32_t seq;
|
||||
uint32_t seq;
|
||||
int rc;
|
||||
|
||||
(void)session; /* unused */
|
||||
(void)type;
|
||||
(void)user;
|
||||
buffer_get_u32(packet,&seq);
|
||||
seq=ntohl(seq);
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"Received SSH_MSG_UNIMPLEMENTED (sequence number %d)",seq);
|
||||
return SSH_PACKET_USED;
|
||||
(void)type;
|
||||
(void)user;
|
||||
|
||||
rc = ssh_buffer_unpack(packet, "d", &seq);
|
||||
if (rc != SSH_OK) {
|
||||
SSH_LOG(SSH_LOG_WARNING,
|
||||
"Could not unpack SSH_MSG_UNIMPLEMENTED packet");
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_RARE,
|
||||
"Received SSH_MSG_UNIMPLEMENTED (sequence number %d)",seq);
|
||||
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
/** @internal
|
||||
@ -459,13 +516,17 @@ static int ssh_packet_write(ssh_session session) {
|
||||
static int packet_send2(ssh_session session) {
|
||||
unsigned int blocksize = (session->current_crypto ?
|
||||
session->current_crypto->out_cipher->blocksize : 8);
|
||||
enum ssh_hmac_e hmac_type = (session->current_crypto ?
|
||||
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
|
||||
uint32_t currentlen = buffer_get_rest_len(session->out_buffer);
|
||||
unsigned char *hmac = NULL;
|
||||
char padstring[32] = {0};
|
||||
char padstring[32] = { 0 };
|
||||
int rc = SSH_ERROR;
|
||||
uint32_t finallen,payloadsize,compsize;
|
||||
uint8_t padding;
|
||||
|
||||
uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 };
|
||||
|
||||
payloadsize = currentlen;
|
||||
#ifdef WITH_ZLIB
|
||||
if (session->current_crypto
|
||||
@ -485,19 +546,18 @@ static int packet_send2(ssh_session session) {
|
||||
|
||||
if (session->current_crypto) {
|
||||
ssh_get_random(padstring, padding, 0);
|
||||
} else {
|
||||
memset(padstring,0,padding);
|
||||
}
|
||||
|
||||
finallen = htonl(currentlen + padding + 1);
|
||||
|
||||
if (buffer_prepend_data(session->out_buffer, &padding, sizeof(uint8_t)) < 0) {
|
||||
memcpy(&header[0], &finallen, sizeof(finallen));
|
||||
header[sizeof(finallen)] = padding;
|
||||
rc = buffer_prepend_data(session->out_buffer, &header, sizeof(header));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (buffer_add_data(session->out_buffer, padstring, padding) < 0) {
|
||||
rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
#ifdef WITH_PCAP
|
||||
@ -510,18 +570,23 @@ static int packet_send2(ssh_session session) {
|
||||
hmac = packet_encrypt(session, buffer_get_rest(session->out_buffer),
|
||||
buffer_get_rest_len(session->out_buffer));
|
||||
if (hmac) {
|
||||
if (buffer_add_data(session->out_buffer, hmac, 20) < 0) {
|
||||
rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_packet_write(session);
|
||||
session->send_seq++;
|
||||
if (session->raw_counter != NULL) {
|
||||
session->raw_counter->out_bytes += payloadsize;
|
||||
session->raw_counter->out_packets++;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_PACKET,
|
||||
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
|
||||
ntohl(finallen), padding, compsize, payloadsize);
|
||||
if (buffer_reinit(session->out_buffer) < 0) {
|
||||
if (ssh_buffer_reinit(session->out_buffer) < 0) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
error:
|
||||
|
@ -106,7 +106,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
|
||||
size_t processed=0;
|
||||
uint32_t padding;
|
||||
uint32_t crc;
|
||||
uint32_t len;
|
||||
uint32_t len, buffer_len;
|
||||
ssh_session session=(ssh_session)user;
|
||||
|
||||
switch (session->packet_state){
|
||||
@ -114,7 +114,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
|
||||
memset(&session->in_packet, 0, sizeof(PACKET));
|
||||
|
||||
if (session->in_buffer) {
|
||||
if (buffer_reinit(session->in_buffer) < 0) {
|
||||
if (ssh_buffer_reinit(session->in_buffer) < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
@ -155,7 +155,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
|
||||
/* it is _not_ possible that to_be_read be < 8. */
|
||||
packet = (char *)data + processed;
|
||||
|
||||
if (buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
|
||||
if (ssh_buffer_add_data(session->in_buffer,packet,to_be_read) < 0) {
|
||||
goto error;
|
||||
}
|
||||
processed += to_be_read;
|
||||
@ -168,11 +168,16 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
|
||||
* We decrypt everything, missing the lenght part (which was
|
||||
* previously read, unencrypted, and is not part of the buffer
|
||||
*/
|
||||
if (packet_decrypt(session,
|
||||
ssh_buffer_get_begin(session->in_buffer),
|
||||
ssh_buffer_get_len(session->in_buffer)) < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Packet decrypt error");
|
||||
goto error;
|
||||
buffer_len = ssh_buffer_get_len(session->in_buffer);
|
||||
if (buffer_len > 0) {
|
||||
int rc;
|
||||
rc = packet_decrypt(session,
|
||||
ssh_buffer_get_begin(session->in_buffer),
|
||||
buffer_len);
|
||||
if (rc < 0) {
|
||||
ssh_set_error(session, SSH_FATAL, "Packet decrypt error");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_CRYPTO
|
||||
@ -236,7 +241,7 @@ int ssh_packet_socket_callback1(const void *data, size_t receivedlen, void *user
|
||||
|
||||
return processed;
|
||||
case PACKET_STATE_PROCESSING:
|
||||
SSH_LOG(SSH_LOG_RARE, "Nested packet processing. Delaying.");
|
||||
SSH_LOG(SSH_LOG_PACKET, "Nested packet processing. Delaying.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -300,6 +305,8 @@ int packet_send1(ssh_session session) {
|
||||
ssh_buffer_get_len(session->out_buffer));
|
||||
#endif
|
||||
|
||||
/* session->out_buffer should have more than sizeof(uint32_t) bytes
|
||||
in it as required for packet_encrypt */
|
||||
packet_encrypt(session, (unsigned char *)ssh_buffer_get_begin(session->out_buffer) + sizeof(uint32_t),
|
||||
ssh_buffer_get_len(session->out_buffer) - sizeof(uint32_t));
|
||||
|
||||
@ -315,7 +322,7 @@ int packet_send1(ssh_session session) {
|
||||
|
||||
session->send_seq++;
|
||||
|
||||
if (buffer_reinit(session->out_buffer) < 0) {
|
||||
if (ssh_buffer_reinit(session->out_buffer) < 0) {
|
||||
rc = SSH_ERROR;
|
||||
}
|
||||
error:
|
||||
|
@ -43,29 +43,35 @@
|
||||
* @brief Handle a SSH_DISCONNECT packet.
|
||||
*/
|
||||
SSH_PACKET_CALLBACK(ssh_packet_disconnect_callback){
|
||||
uint32_t code;
|
||||
char *error=NULL;
|
||||
ssh_string error_s;
|
||||
(void)user;
|
||||
(void)type;
|
||||
buffer_get_u32(packet, &code);
|
||||
int rc;
|
||||
uint32_t code = 0;
|
||||
char *error = NULL;
|
||||
ssh_string error_s;
|
||||
(void)user;
|
||||
(void)type;
|
||||
|
||||
rc = buffer_get_u32(packet, &code);
|
||||
if (rc != 0) {
|
||||
code = ntohl(code);
|
||||
}
|
||||
|
||||
error_s = buffer_get_ssh_string(packet);
|
||||
if (error_s != NULL) {
|
||||
error = ssh_string_to_char(error_s);
|
||||
ssh_string_free(error_s);
|
||||
}
|
||||
SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s",code,
|
||||
error != NULL ? error : "no error");
|
||||
SSH_LOG(SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT %d:%s",
|
||||
code, error != NULL ? error : "no error");
|
||||
ssh_set_error(session, SSH_FATAL,
|
||||
"Received SSH_MSG_DISCONNECT: %d:%s",code,
|
||||
error != NULL ? error : "no error");
|
||||
"Received SSH_MSG_DISCONNECT: %d:%s",
|
||||
code, error != NULL ? error : "no error");
|
||||
SAFE_FREE(error);
|
||||
|
||||
ssh_socket_close(session->socket);
|
||||
session->alive = 0;
|
||||
session->session_state= SSH_SESSION_STATE_ERROR;
|
||||
/* TODO: handle a graceful disconnect */
|
||||
return SSH_PACKET_USED;
|
||||
session->session_state = SSH_SESSION_STATE_ERROR;
|
||||
/* TODO: handle a graceful disconnect */
|
||||
return SSH_PACKET_USED;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -59,6 +60,9 @@ uint32_t packet_decrypt_len(ssh_session session, char *crypted){
|
||||
int packet_decrypt(ssh_session session, void *data,uint32_t len) {
|
||||
struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher;
|
||||
char *out = NULL;
|
||||
|
||||
assert(len);
|
||||
|
||||
if(len % session->current_crypto->in_cipher->blocksize != 0){
|
||||
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
|
||||
return SSH_ERROR;
|
||||
@ -73,11 +77,10 @@ int packet_decrypt(ssh_session session, void *data,uint32_t len) {
|
||||
SAFE_FREE(out);
|
||||
return -1;
|
||||
}
|
||||
crypto->cbc_decrypt(crypto,data,out,len);
|
||||
crypto->decrypt(crypto,data,out,len);
|
||||
|
||||
memcpy(data,out,len);
|
||||
memset(out,0,len);
|
||||
|
||||
BURN_BUFFER(out, len);
|
||||
SAFE_FREE(out);
|
||||
return 0;
|
||||
}
|
||||
@ -88,6 +91,9 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
|
||||
char *out = NULL;
|
||||
unsigned int finallen;
|
||||
uint32_t seq;
|
||||
enum ssh_hmac_e type;
|
||||
|
||||
assert(len);
|
||||
|
||||
if (!session->current_crypto) {
|
||||
return NULL; /* nothing to do here */
|
||||
@ -101,6 +107,7 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = session->current_crypto->out_hmac;
|
||||
seq = ntohl(session->send_seq);
|
||||
crypto = session->current_crypto->out_cipher;
|
||||
|
||||
@ -111,7 +118,7 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
|
||||
}
|
||||
|
||||
if (session->version == 2) {
|
||||
ctx = hmac_init(session->current_crypto->encryptMAC,20,SSH_HMAC_SHA1);
|
||||
ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
|
||||
if (ctx == NULL) {
|
||||
SAFE_FREE(out);
|
||||
return NULL;
|
||||
@ -120,18 +127,18 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
|
||||
hmac_update(ctx,data,len);
|
||||
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("mac: ",data,len);
|
||||
if (finallen != 20) {
|
||||
ssh_print_hexa("mac: ",data,hmac_digest_len(type));
|
||||
if (finallen != hmac_digest_len(type)) {
|
||||
printf("Final len is %d\n",finallen);
|
||||
}
|
||||
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, 20);
|
||||
ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
|
||||
#endif
|
||||
}
|
||||
|
||||
crypto->cbc_encrypt(crypto, data, out, len);
|
||||
crypto->encrypt(crypto, data, out, len);
|
||||
|
||||
memcpy(data, out, len);
|
||||
memset(out, 0, len);
|
||||
BURN_BUFFER(out, len);
|
||||
SAFE_FREE(out);
|
||||
|
||||
if (session->version == 2) {
|
||||
@ -154,13 +161,13 @@ unsigned char *packet_encrypt(ssh_session session, void *data, uint32_t len) {
|
||||
* occurred.
|
||||
*/
|
||||
int packet_hmac_verify(ssh_session session, ssh_buffer buffer,
|
||||
unsigned char *mac) {
|
||||
unsigned char hmacbuf[EVP_MAX_MD_SIZE] = {0};
|
||||
unsigned char *mac, enum ssh_hmac_e type) {
|
||||
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
||||
HMACCTX ctx;
|
||||
unsigned int len;
|
||||
uint32_t seq;
|
||||
|
||||
ctx = hmac_init(session->current_crypto->decryptMAC, 20, SSH_HMAC_SHA1);
|
||||
ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type);
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ static int ssh_pcap_context_connect(ssh_pcap_context ctx){
|
||||
int ssh_pcap_context_write(ssh_pcap_context ctx,enum ssh_pcap_direction direction
|
||||
, void *data, uint32_t len, uint32_t origlen){
|
||||
ssh_buffer ip;
|
||||
int err;
|
||||
int rc;
|
||||
if(ctx==NULL || ctx->file ==NULL)
|
||||
return SSH_ERROR;
|
||||
if(ctx->connected==0)
|
||||
@ -353,147 +353,104 @@ int ssh_pcap_context_write(ssh_pcap_context ctx,enum ssh_pcap_direction directio
|
||||
ssh_set_error_oom(ctx->session);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
/* build an IP packet */
|
||||
/* V4, 20 bytes */
|
||||
err = buffer_add_u8(ip,4 << 4 | 5);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* tos */
|
||||
err = buffer_add_u8(ip,0);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* total len */
|
||||
err = buffer_add_u16(ip,htons(origlen + TCPIPHDR_LEN));
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* IP id number */
|
||||
err = buffer_add_u16(ip,htons(ctx->file->ipsequence));
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* build an IP packet */
|
||||
rc = ssh_buffer_pack(ip,
|
||||
"bbwwwbbw",
|
||||
4 << 4 | 5, /* V4, 20 bytes */
|
||||
0, /* tos */
|
||||
origlen + TCPIPHDR_LEN, /* total len */
|
||||
ctx->file->ipsequence, /* IP id number */
|
||||
0, /* fragment offset */
|
||||
64, /* TTL */
|
||||
6, /* protocol TCP=6 */
|
||||
0); /* checksum */
|
||||
|
||||
ctx->file->ipsequence++;
|
||||
/* fragment offset */
|
||||
err = buffer_add_u16(ip,htons(0));
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* TTL */
|
||||
err = buffer_add_u8(ip,64);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* protocol TCP=6 */
|
||||
err = buffer_add_u8(ip,6);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* checksum */
|
||||
err = buffer_add_u16(ip,0);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
if (rc != SSH_OK){
|
||||
goto error;
|
||||
}
|
||||
if(direction==SSH_PCAP_DIR_OUT){
|
||||
err = buffer_add_u32(ip,ctx->ipsource);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u32(ip,ctx->ipsource);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
err = buffer_add_u32(ip,ctx->ipdest);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u32(ip,ctx->ipdest);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
err = buffer_add_u32(ip,ctx->ipdest);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u32(ip,ctx->ipdest);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
err = buffer_add_u32(ip,ctx->ipsource);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u32(ip,ctx->ipsource);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* TCP */
|
||||
if(direction==SSH_PCAP_DIR_OUT){
|
||||
err = buffer_add_u16(ip,ctx->portsource);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u16(ip,ctx->portsource);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
err = buffer_add_u16(ip,ctx->portdest);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u16(ip,ctx->portdest);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
err = buffer_add_u16(ip,ctx->portdest);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u16(ip,ctx->portdest);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
err = buffer_add_u16(ip,ctx->portsource);
|
||||
if (err < 0) {
|
||||
rc = buffer_add_u16(ip,ctx->portsource);
|
||||
if (rc < 0) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* sequence number */
|
||||
if(direction==SSH_PCAP_DIR_OUT){
|
||||
err = buffer_add_u32(ip,ntohl(ctx->outsequence));
|
||||
if (err < 0) {
|
||||
rc = ssh_buffer_pack(ip, "d", ctx->outsequence);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
ctx->outsequence+=origlen;
|
||||
} else {
|
||||
err = buffer_add_u32(ip,ntohl(ctx->insequence));
|
||||
if (err < 0) {
|
||||
rc = ssh_buffer_pack(ip, "d", ctx->insequence);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
ctx->insequence+=origlen;
|
||||
}
|
||||
/* ack number */
|
||||
if(direction==SSH_PCAP_DIR_OUT){
|
||||
err = buffer_add_u32(ip,ntohl(ctx->insequence));
|
||||
if (err < 0) {
|
||||
rc = ssh_buffer_pack(ip, "d", ctx->insequence);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
err = buffer_add_u32(ip,ntohl(ctx->outsequence));
|
||||
if (err < 0) {
|
||||
rc = ssh_buffer_pack(ip, "d", ctx->outsequence);
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
/* header len = 20 = 5 * 32 bits, at offset 4*/
|
||||
err = buffer_add_u8(ip,5 << 4);
|
||||
if (err < 0) {
|
||||
|
||||
rc = ssh_buffer_pack(ip,
|
||||
"bbwwwP",
|
||||
5 << 4, /* header len = 20 = 5 * 32 bits, at offset 4*/
|
||||
TH_PUSH | TH_ACK, /* flags */
|
||||
65535, /* window */
|
||||
0, /* checksum */
|
||||
0, /* urgent data ptr */
|
||||
(size_t)len, data); /* actual data */
|
||||
if (rc != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* flags */
|
||||
err = buffer_add_u8(ip,TH_PUSH | TH_ACK);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* window */
|
||||
err = buffer_add_u16(ip,htons(65535));
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* checksum */
|
||||
err = buffer_add_u16(ip,htons(0));
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* urgent data ptr */
|
||||
err = buffer_add_u16(ip,0);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
/* actual data */
|
||||
err = buffer_add_data(ip,data,len);
|
||||
if (err < 0) {
|
||||
goto error;
|
||||
}
|
||||
err=ssh_pcap_file_write_packet(ctx->file,ip,origlen + TCPIPHDR_LEN);
|
||||
rc=ssh_pcap_file_write_packet(ctx->file,ip,origlen + TCPIPHDR_LEN);
|
||||
error:
|
||||
ssh_buffer_free(ip);
|
||||
return err;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** @brief sets the pcap file used to trace the session
|
||||
|
249
libssh/src/pki.c
249
libssh/src/pki.c
@ -3,7 +3,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2010 by Aris Adamantiadis
|
||||
* Copyright (c) 2011-2012 Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2011-2013 Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -98,6 +98,25 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey) {
|
||||
return SSH_KEYTYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
|
||||
*
|
||||
* @param[in] key the ssh_key whose ECDSA name to get
|
||||
*
|
||||
* @returns the ECDSA key name ("ecdsa-sha2-nistp256" for example)
|
||||
*
|
||||
* @returns "unknown" if the ECDSA key name is not known
|
||||
*/
|
||||
const char *ssh_pki_key_ecdsa_name(const ssh_key key)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL_ECC /* FIXME Better ECC check needed */
|
||||
return pki_key_ecdsa_nid_to_name(key->ecdsa_nid);
|
||||
#else
|
||||
(void) key; /* unused */
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief creates a new empty SSH key
|
||||
* @returns an empty ssh_key handle, or NULL on error.
|
||||
@ -138,6 +157,11 @@ void ssh_key_clean (ssh_key key){
|
||||
if(key->ecdsa) EC_KEY_free(key->ecdsa);
|
||||
#endif /* HAVE_OPENSSL_ECC */
|
||||
#endif
|
||||
if (key->ed25519_privkey != NULL){
|
||||
BURN_BUFFER(key->ed25519_privkey, sizeof(ed25519_privkey));
|
||||
SAFE_FREE(key->ed25519_privkey);
|
||||
}
|
||||
SAFE_FREE(key->ed25519_pubkey);
|
||||
key->flags=SSH_KEY_FLAG_EMPTY;
|
||||
key->type=SSH_KEYTYPE_UNKNOWN;
|
||||
key->ecdsa_nid = 0;
|
||||
@ -188,6 +212,8 @@ const char *ssh_key_type_to_char(enum ssh_keytypes_e type) {
|
||||
return "ssh-rsa1";
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
return "ssh-ecdsa";
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
return "ssh-ed25519";
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
return NULL;
|
||||
}
|
||||
@ -226,6 +252,8 @@ enum ssh_keytypes_e ssh_key_type_from_name(const char *name) {
|
||||
|| strcmp(name, "ecdsa-sha2-nistp384") == 0
|
||||
|| strcmp(name, "ecdsa-sha2-nistp521") == 0) {
|
||||
return SSH_KEYTYPE_ECDSA;
|
||||
} else if (strcmp(name, "ssh-ed25519") == 0){
|
||||
return SSH_KEYTYPE_ED25519;
|
||||
}
|
||||
|
||||
return SSH_KEYTYPE_UNKNOWN;
|
||||
@ -281,7 +309,7 @@ int ssh_key_cmp(const ssh_key k1,
|
||||
}
|
||||
|
||||
if (k1->type != k2->type) {
|
||||
ssh_pki_log("key types don't macth!");
|
||||
ssh_pki_log("key types don't match!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -292,6 +320,10 @@ int ssh_key_cmp(const ssh_key k1,
|
||||
}
|
||||
}
|
||||
|
||||
if (k1->type == SSH_KEYTYPE_ED25519) {
|
||||
return pki_ed25519_key_cmp(k1, k2, what);
|
||||
}
|
||||
|
||||
return pki_key_compare(k1, k2, what);
|
||||
}
|
||||
|
||||
@ -331,6 +363,13 @@ void ssh_signature_free(ssh_signature sig)
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ECC)
|
||||
ECDSA_SIG_free(sig->ecdsa_sig);
|
||||
#endif
|
||||
break;
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
SAFE_FREE(sig->ed25519_sig);
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
break;
|
||||
}
|
||||
@ -476,6 +515,65 @@ int ssh_pki_import_privkey_file(const char *filename,
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Export a private key to a pam file on disk.
|
||||
*
|
||||
* @param[in] privkey The private key to export.
|
||||
*
|
||||
* @param[in] passphrase The passphrase to use to encrypt the key with or
|
||||
* NULL. An empty string means no passphrase.
|
||||
*
|
||||
* @param[in] auth_fn An auth function you may want to use or NULL.
|
||||
*
|
||||
* @param[in] auth_data Private data passed to the auth function.
|
||||
*
|
||||
* @param[in] filename The path where to store the pem file.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
*/
|
||||
int ssh_pki_export_privkey_file(const ssh_key privkey,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data,
|
||||
const char *filename)
|
||||
{
|
||||
ssh_string blob;
|
||||
FILE *fp;
|
||||
int rc;
|
||||
|
||||
if (privkey == NULL || !ssh_key_is_private(privkey)) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
fp = fopen(filename, "wb");
|
||||
if (fp == NULL) {
|
||||
SSH_LOG(SSH_LOG_FUNCTIONS, "Error opening %s: %s",
|
||||
filename, strerror(errno));
|
||||
return SSH_EOF;
|
||||
}
|
||||
|
||||
|
||||
blob = pki_private_key_to_pem(privkey,
|
||||
passphrase,
|
||||
auth_fn,
|
||||
auth_data);
|
||||
if (blob == NULL) {
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fwrite(ssh_string_data(blob), ssh_string_len(blob), 1, fp);
|
||||
ssh_string_free(blob);
|
||||
if (rc != 1 || ferror(fp)) {
|
||||
fclose(fp);
|
||||
unlink(filename);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/* temporary function to migrate seemlessly to ssh_key */
|
||||
ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key) {
|
||||
ssh_public_key pub;
|
||||
@ -661,10 +759,36 @@ static int pki_import_pubkey_buffer(ssh_buffer buffer,
|
||||
if (rc < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Update key type */
|
||||
key->type_c = ssh_pki_key_ecdsa_name(key);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
{
|
||||
ssh_string pubkey = buffer_get_ssh_string(buffer);
|
||||
if (ssh_string_len(pubkey) != ED25519_PK_LEN) {
|
||||
ssh_pki_log("Invalid public key length");
|
||||
ssh_string_burn(pubkey);
|
||||
ssh_string_free(pubkey);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
key->ed25519_pubkey = malloc(ED25519_PK_LEN);
|
||||
if (key->ed25519_pubkey == NULL) {
|
||||
ssh_string_burn(pubkey);
|
||||
ssh_string_free(pubkey);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memcpy(key->ed25519_pubkey, ssh_string_data(pubkey), ED25519_PK_LEN);
|
||||
ssh_string_burn(pubkey);
|
||||
ssh_string_free(pubkey);
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_pki_log("Unknown public key protocol %d", type);
|
||||
goto fail;
|
||||
}
|
||||
@ -752,7 +876,7 @@ int ssh_pki_import_pubkey_blob(const ssh_string key_blob,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_data(buffer, ssh_string_data(key_blob),
|
||||
rc = ssh_buffer_add_data(buffer, ssh_string_data(key_blob),
|
||||
ssh_string_len(key_blob));
|
||||
if (rc < 0) {
|
||||
ssh_pki_log("Out of memory!");
|
||||
@ -917,10 +1041,20 @@ int ssh_pki_generate(enum ssh_keytypes_e type, int parameter,
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_ECC
|
||||
rc = pki_key_generate_ecdsa(key, parameter);
|
||||
if(rc == SSH_ERROR)
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Update key type */
|
||||
key->type_c = ssh_pki_key_ecdsa_name(key);
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_key_generate_ed25519(key);
|
||||
if (rc == SSH_ERROR) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
goto error;
|
||||
}
|
||||
@ -999,11 +1133,11 @@ int ssh_pki_export_pubkey_blob(const ssh_key key,
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert a public key to a base64 hased key.
|
||||
* @brief Convert a public key to a base64 encoded key.
|
||||
*
|
||||
* @param[in] key The key to hash
|
||||
*
|
||||
* @param[out] b64_key A pointer to store the allocated base64 hashed key. You
|
||||
* @param[out] b64_key A pointer to store the allocated base64 encoded key. You
|
||||
* need to free the buffer.
|
||||
*
|
||||
* @return SSH_OK on success, SSH_ERROR on error.
|
||||
@ -1177,9 +1311,9 @@ int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_data(buf,
|
||||
ssh_string_data(sig_blob),
|
||||
ssh_string_len(sig_blob));
|
||||
rc = ssh_buffer_add_data(buf,
|
||||
ssh_string_data(sig_blob),
|
||||
ssh_string_len(sig_blob));
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buf);
|
||||
return SSH_ERROR;
|
||||
@ -1236,12 +1370,19 @@ int ssh_pki_signature_verify_blob(ssh_session session,
|
||||
|
||||
evp(key->ecdsa_nid, digest, dlen, ehash, &elen);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash to be verified with ecdsa",
|
||||
ehash, elen);
|
||||
#endif
|
||||
|
||||
rc = pki_signature_verify(session,
|
||||
sig,
|
||||
key,
|
||||
ehash,
|
||||
elen);
|
||||
#endif
|
||||
} else if (key->type == SSH_KEYTYPE_ED25519) {
|
||||
rc = pki_signature_verify(session, sig, key, digest, dlen);
|
||||
} else {
|
||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||
|
||||
@ -1302,8 +1443,36 @@ ssh_string ssh_pki_do_sign(ssh_session session,
|
||||
evp_update(ctx, buffer_get_rest(sigbuf), buffer_get_rest_len(sigbuf));
|
||||
evp_final(ctx, ehash, &elen);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash being signed", ehash, elen);
|
||||
#endif
|
||||
|
||||
sig = pki_do_sign(privkey, ehash, elen);
|
||||
#endif
|
||||
} else if (privkey->type == SSH_KEYTYPE_ED25519){
|
||||
ssh_buffer buf;
|
||||
|
||||
buf = ssh_buffer_new();
|
||||
if (buf == NULL) {
|
||||
ssh_string_free(session_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_buffer_set_secure(buf);
|
||||
rc = ssh_buffer_pack(buf,
|
||||
"SP",
|
||||
session_id,
|
||||
buffer_get_rest_len(sigbuf), buffer_get_rest(sigbuf));
|
||||
if (rc != SSH_OK) {
|
||||
ssh_string_free(session_id);
|
||||
ssh_buffer_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig = pki_do_sign(privkey,
|
||||
ssh_buffer_get_begin(buf),
|
||||
ssh_buffer_get_len(buf));
|
||||
ssh_buffer_free(buf);
|
||||
} else {
|
||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||
SHACTX ctx;
|
||||
@ -1395,10 +1564,8 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
const ssh_key privkey)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto;
|
||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||
ssh_signature sig;
|
||||
ssh_string sig_blob;
|
||||
SHACTX ctx;
|
||||
int rc;
|
||||
|
||||
if (session == NULL || privkey == NULL || !ssh_key_is_private(privkey)) {
|
||||
@ -1407,24 +1574,64 @@ ssh_string ssh_srv_pki_do_sign_sessionid(ssh_session session,
|
||||
crypto = session->next_crypto ? session->next_crypto :
|
||||
session->current_crypto;
|
||||
|
||||
ctx = sha1_init();
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (crypto->secret_hash == NULL){
|
||||
ssh_set_error(session,SSH_FATAL,"Missing secret_hash");
|
||||
return NULL;
|
||||
}
|
||||
sha1_update(ctx, crypto->secret_hash, crypto->digest_len);
|
||||
sha1_final(hash, ctx);
|
||||
|
||||
if (privkey->type == SSH_KEYTYPE_ECDSA) {
|
||||
#ifdef HAVE_ECC
|
||||
unsigned char ehash[EVP_DIGEST_LEN] = {0};
|
||||
uint32_t elen;
|
||||
|
||||
evp(privkey->ecdsa_nid, crypto->secret_hash, crypto->digest_len,
|
||||
ehash, &elen);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
|
||||
ssh_print_hexa("Hash being signed", ehash, elen);
|
||||
#endif
|
||||
|
||||
sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
sig = pki_do_sign_sessionid(privkey, ehash, elen);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
} else if (privkey->type == SSH_KEYTYPE_ED25519) {
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig->type = privkey->type;
|
||||
sig->type_c = privkey->type_c;
|
||||
|
||||
rc = pki_ed25519_sign(privkey,
|
||||
sig,
|
||||
crypto->secret_hash,
|
||||
crypto->digest_len);
|
||||
if (rc != SSH_OK){
|
||||
ssh_signature_free(sig);
|
||||
sig = NULL;
|
||||
}
|
||||
} else {
|
||||
unsigned char hash[SHA_DIGEST_LEN] = {0};
|
||||
SHACTX ctx;
|
||||
|
||||
ctx = sha1_init();
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
sha1_update(ctx, crypto->secret_hash, crypto->digest_len);
|
||||
sha1_final(hash, ctx);
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("Hash being signed", hash, SHA_DIGEST_LEN);
|
||||
#endif
|
||||
|
||||
sig = pki_do_sign_sessionid(privkey, hash, SHA_DIGEST_LEN);
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rc = ssh_pki_export_signature_blob(sig, &sig_blob);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2009-2012 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
@ -44,7 +44,7 @@
|
||||
#include "libssh/session.h"
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/pki_priv.h"
|
||||
#include "libssh/dh.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
struct pem_get_password_struct {
|
||||
ssh_auth_callback fn;
|
||||
@ -89,7 +89,7 @@ static int pki_key_ecdsa_to_nid(EC_KEY *k)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *pki_key_ecdsa_nid_to_name(int nid)
|
||||
const char *pki_key_ecdsa_nid_to_name(int nid)
|
||||
{
|
||||
switch (nid) {
|
||||
case NID_X9_62_prime256v1:
|
||||
@ -200,9 +200,11 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* EC_KEY_set_public_key duplicates p */
|
||||
ok = EC_KEY_set_public_key(key->ecdsa, p);
|
||||
EC_POINT_free(p);
|
||||
if (!ok) {
|
||||
EC_POINT_free(p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -212,6 +214,7 @@ int pki_pubkey_build_ecdsa(ssh_key key, int nid, ssh_string e)
|
||||
ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
{
|
||||
ssh_key new;
|
||||
int rc;
|
||||
|
||||
new = ssh_key_new();
|
||||
if (new == NULL) {
|
||||
@ -343,13 +346,13 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
new->ecdsa_nid = key->ecdsa_nid;
|
||||
|
||||
/* privkey -> pubkey */
|
||||
if (demote && ssh_key_is_private(key)) {
|
||||
const EC_POINT *p;
|
||||
int ok;
|
||||
|
||||
new->ecdsa_nid = key->ecdsa_nid;
|
||||
|
||||
new->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid);
|
||||
if (new->ecdsa == NULL) {
|
||||
goto fail;
|
||||
@ -369,7 +372,14 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_ed25519_key_dup(new, key);
|
||||
if (rc != SSH_OK) {
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_key_free(new);
|
||||
return NULL;
|
||||
}
|
||||
@ -381,10 +391,20 @@ fail:
|
||||
}
|
||||
|
||||
int pki_key_generate_rsa(ssh_key key, int parameter){
|
||||
key->rsa = RSA_generate_key(parameter, 65537, NULL, NULL);
|
||||
if(key->rsa == NULL)
|
||||
return SSH_ERROR;
|
||||
return SSH_OK;
|
||||
BIGNUM *e;
|
||||
int rc;
|
||||
|
||||
e = BN_new();
|
||||
key->rsa = RSA_new();
|
||||
|
||||
BN_set_word(e, 65537);
|
||||
rc = RSA_generate_key_ex(key->rsa, parameter, e, NULL);
|
||||
|
||||
BN_free(e);
|
||||
|
||||
if (rc == -1 || key->rsa == NULL)
|
||||
return SSH_ERROR;
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int pki_key_generate_dss(ssh_key key, int parameter){
|
||||
@ -521,13 +541,135 @@ int pki_key_compare(const ssh_key k1,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
/* ed25519 keys handled globaly */
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssh_string pki_private_key_to_pem(const ssh_key key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data)
|
||||
{
|
||||
ssh_string blob;
|
||||
BUF_MEM *buf;
|
||||
BIO *mem;
|
||||
int rc;
|
||||
|
||||
/* needed for openssl initialization */
|
||||
if (ssh_init() < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mem = BIO_new(BIO_s_mem());
|
||||
if (mem == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
if (passphrase == NULL) {
|
||||
struct pem_get_password_struct pgp = { auth_fn, auth_data };
|
||||
|
||||
rc = PEM_write_bio_DSAPrivateKey(mem,
|
||||
key->dsa,
|
||||
NULL, /* cipher */
|
||||
NULL, /* kstr */
|
||||
0, /* klen */
|
||||
pem_get_password,
|
||||
&pgp);
|
||||
} else {
|
||||
rc = PEM_write_bio_DSAPrivateKey(mem,
|
||||
key->dsa,
|
||||
NULL, /* cipher */
|
||||
NULL, /* kstr */
|
||||
0, /* klen */
|
||||
NULL, /* auth_fn */
|
||||
(void*) passphrase);
|
||||
}
|
||||
if (rc != 1) {
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
if (passphrase == NULL) {
|
||||
struct pem_get_password_struct pgp = { auth_fn, auth_data };
|
||||
|
||||
rc = PEM_write_bio_RSAPrivateKey(mem,
|
||||
key->rsa,
|
||||
NULL, /* cipher */
|
||||
NULL, /* kstr */
|
||||
0, /* klen */
|
||||
pem_get_password,
|
||||
&pgp);
|
||||
} else {
|
||||
rc = PEM_write_bio_RSAPrivateKey(mem,
|
||||
key->rsa,
|
||||
NULL, /* cipher */
|
||||
NULL, /* kstr */
|
||||
0, /* klen */
|
||||
NULL, /* auth_fn */
|
||||
(void*) passphrase);
|
||||
}
|
||||
if (rc != 1) {
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_ECC
|
||||
if (passphrase == NULL) {
|
||||
struct pem_get_password_struct pgp = { auth_fn, auth_data };
|
||||
|
||||
rc = PEM_write_bio_ECPrivateKey(mem,
|
||||
key->ecdsa,
|
||||
NULL, /* cipher */
|
||||
NULL, /* kstr */
|
||||
0, /* klen */
|
||||
pem_get_password,
|
||||
&pgp);
|
||||
} else {
|
||||
rc = PEM_write_bio_ECPrivateKey(mem,
|
||||
key->ecdsa,
|
||||
NULL, /* cipher */
|
||||
NULL, /* kstr */
|
||||
0, /* klen */
|
||||
NULL, /* auth_fn */
|
||||
(void*) passphrase);
|
||||
}
|
||||
if (rc != 1) {
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
BIO_free(mem);
|
||||
ssh_pki_log("Unkown or invalid private key type %d", key->type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIO_get_mem_ptr(mem, &buf);
|
||||
|
||||
blob = ssh_string_new(buf->length);
|
||||
if (blob == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
ssh_string_fill(blob, buf->data, buf->length);
|
||||
BIO_free(mem);
|
||||
|
||||
return blob;
|
||||
err:
|
||||
BIO_free(mem);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
@ -629,6 +771,7 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
BIO_free(mem);
|
||||
ssh_pki_log("Unkown or invalid private key type %d", type);
|
||||
@ -817,7 +960,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
rc = buffer_reinit(buffer);
|
||||
rc = ssh_buffer_reinit(buffer);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
@ -867,7 +1010,14 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||||
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_ed25519_public_key_to_blob(buffer, key);
|
||||
if (rc == SSH_ERROR){
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -976,41 +1126,63 @@ static ssh_string _RSA_do_sign(const unsigned char *digest,
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig)
|
||||
{
|
||||
char buffer[40] = { 0 };
|
||||
ssh_string sig_blob = NULL;
|
||||
|
||||
ssh_string r;
|
||||
int r_len, r_offset_in, r_offset_out;
|
||||
|
||||
ssh_string s;
|
||||
int s_len, s_offset_in, s_offset_out;
|
||||
|
||||
r = make_bignum_string(sig->dsa_sig->r);
|
||||
if (r == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = make_bignum_string(sig->dsa_sig->s);
|
||||
if (s == NULL) {
|
||||
ssh_string_free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r_len = ssh_string_len(r);
|
||||
r_offset_in = (r_len > 20) ? (r_len - 20) : 0;
|
||||
r_offset_out = (r_len < 20) ? (20 - r_len) : 0;
|
||||
|
||||
s_len = ssh_string_len(s);
|
||||
s_offset_in = (s_len > 20) ? (s_len - 20) : 0;
|
||||
s_offset_out = (s_len < 20) ? (20 - s_len) : 0;
|
||||
|
||||
memcpy(buffer + r_offset_out,
|
||||
((char *)ssh_string_data(r)) + r_offset_in,
|
||||
r_len - r_offset_in);
|
||||
memcpy(buffer + 20 + s_offset_out,
|
||||
((char *)ssh_string_data(s)) + s_offset_in,
|
||||
s_len - s_offset_in);
|
||||
|
||||
ssh_string_free(r);
|
||||
ssh_string_free(s);
|
||||
|
||||
sig_blob = ssh_string_new(40);
|
||||
if (sig_blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_string_fill(sig_blob, buffer, 40);
|
||||
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
{
|
||||
char buffer[40] = {0};
|
||||
ssh_string sig_blob = NULL;
|
||||
ssh_string r;
|
||||
ssh_string s;
|
||||
|
||||
switch(sig->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
r = make_bignum_string(sig->dsa_sig->r);
|
||||
if (r == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
s = make_bignum_string(sig->dsa_sig->s);
|
||||
if (s == NULL) {
|
||||
ssh_string_free(r);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(buffer,
|
||||
((char *)ssh_string_data(r)) + ssh_string_len(r) - 20,
|
||||
20);
|
||||
memcpy(buffer + 20,
|
||||
((char *)ssh_string_data(s)) + ssh_string_len(s) - 20,
|
||||
20);
|
||||
|
||||
ssh_string_free(r);
|
||||
ssh_string_free(s);
|
||||
|
||||
sig_blob = ssh_string_new(40);
|
||||
if (sig_blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_string_fill(sig_blob, buffer, 40);
|
||||
sig_blob = pki_dsa_signature_to_blob(sig);
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
@ -1019,6 +1191,8 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
{
|
||||
ssh_string r;
|
||||
ssh_string s;
|
||||
ssh_buffer b;
|
||||
int rc;
|
||||
|
||||
@ -1062,6 +1236,10 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
sig_blob = pki_ed25519_sig_to_blob(sig);
|
||||
break;
|
||||
default:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
ssh_pki_log("Unknown signature key type: %s", sig->type_c);
|
||||
return NULL;
|
||||
@ -1070,6 +1248,67 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
static ssh_signature pki_signature_from_rsa_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
ssh_signature sig)
|
||||
{
|
||||
uint32_t pad_len = 0;
|
||||
char *blob_orig;
|
||||
char *blob_padded_data;
|
||||
ssh_string sig_blob_padded;
|
||||
|
||||
size_t rsalen = 0;
|
||||
size_t len = ssh_string_len(sig_blob);
|
||||
|
||||
if (pubkey->rsa == NULL) {
|
||||
ssh_pki_log("Pubkey RSA field NULL");
|
||||
goto errout;
|
||||
}
|
||||
|
||||
rsalen = RSA_size(pubkey->rsa);
|
||||
if (len > rsalen) {
|
||||
ssh_pki_log("Signature is too big: %lu > %lu",
|
||||
(unsigned long)len, (unsigned long)rsalen);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_pki_log("RSA signature len: %lu", (unsigned long)len);
|
||||
ssh_print_hexa("RSA signature", ssh_string_data(sig_blob), len);
|
||||
#endif
|
||||
|
||||
if (len == rsalen) {
|
||||
sig->rsa_sig = ssh_string_copy(sig_blob);
|
||||
} else {
|
||||
/* pad the blob to the expected rsalen size */
|
||||
ssh_pki_log("RSA signature len %lu < %lu",
|
||||
(unsigned long)len, (unsigned long)rsalen);
|
||||
|
||||
pad_len = rsalen - len;
|
||||
|
||||
sig_blob_padded = ssh_string_new(rsalen);
|
||||
if (sig_blob_padded == NULL) {
|
||||
goto errout;
|
||||
}
|
||||
|
||||
blob_padded_data = (char *) ssh_string_data(sig_blob_padded);
|
||||
blob_orig = (char *) ssh_string_data(sig_blob);
|
||||
|
||||
/* front-pad the buffer with zeroes */
|
||||
BURN_BUFFER(blob_padded_data, pad_len);
|
||||
/* fill the rest with the actual signature blob */
|
||||
memcpy(blob_padded_data + pad_len, blob_orig, len);
|
||||
|
||||
sig->rsa_sig = sig_blob_padded;
|
||||
}
|
||||
|
||||
return sig;
|
||||
|
||||
errout:
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
enum ssh_keytypes_e type)
|
||||
@ -1078,7 +1317,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
ssh_string r;
|
||||
ssh_string s;
|
||||
size_t len;
|
||||
size_t rsalen;
|
||||
int rc;
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
@ -1142,29 +1381,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rsalen = RSA_size(pubkey->rsa);
|
||||
|
||||
if (len > rsalen) {
|
||||
ssh_pki_log("Signature is to big size: %lu",
|
||||
(unsigned long)len);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < rsalen) {
|
||||
ssh_pki_log("RSA signature len %lu < %lu",
|
||||
(unsigned long)len, (unsigned long)rsalen);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_pki_log("RSA signature len: %lu", (unsigned long)len);
|
||||
ssh_print_hexa("RSA signature", ssh_string_data(sig_blob), len);
|
||||
#endif
|
||||
sig->rsa_sig = ssh_string_copy(sig_blob);
|
||||
if (sig->rsa_sig == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig);
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
@ -1177,7 +1394,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
{ /* build ecdsa siganature */
|
||||
ssh_buffer b;
|
||||
uint32_t rlen;
|
||||
int rc;
|
||||
|
||||
b = ssh_buffer_new();
|
||||
if (b == NULL) {
|
||||
@ -1185,9 +1401,9 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = buffer_add_data(b,
|
||||
ssh_string_data(sig_blob),
|
||||
ssh_string_len(sig_blob));
|
||||
rc = ssh_buffer_add_data(b,
|
||||
ssh_string_data(sig_blob),
|
||||
ssh_string_len(sig_blob));
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(b);
|
||||
ssh_signature_free(sig);
|
||||
@ -1245,6 +1461,14 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_ed25519_sig_from_blob(sig, sig_blob);
|
||||
if (rc == SSH_ERROR){
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
ssh_pki_log("Unknown signature type");
|
||||
ssh_signature_free(sig);
|
||||
@ -1292,6 +1516,15 @@ int pki_signature_verify(ssh_session session,
|
||||
return SSH_ERROR;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_ed25519_verify(key, sig, hash, hlen);
|
||||
if (rc != SSH_OK){
|
||||
ssh_set_error(session,
|
||||
SSH_FATAL,
|
||||
"ed25519 signature verification error");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
rc = ECDSA_do_verify(hash,
|
||||
@ -1308,6 +1541,7 @@ int pki_signature_verify(ssh_session session,
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_set_error(session, SSH_FATAL, "Unknown public key type");
|
||||
return SSH_ERROR;
|
||||
}
|
||||
@ -1319,6 +1553,7 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
const unsigned char *hash,
|
||||
size_t hlen) {
|
||||
ssh_signature sig;
|
||||
int rc;
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
@ -1366,7 +1601,15 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
|
||||
break;
|
||||
#endif /* HAVE_OPENSSL_ECC */
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
rc = pki_ed25519_sign(privkey, sig, hash, hlen);
|
||||
if (rc != SSH_OK){
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
@ -1413,7 +1656,10 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
/* ED25519 handled in caller */
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
default:
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
305
libssh/src/pki_ed25519.c
Normal file
305
libssh/src/pki_ed25519.c
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* pki_ed25519 .c - PKI infrastructure using ed25519
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2014 by Aris Adamantiadis
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* The SSH Library is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
* License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with the SSH Library; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
||||
* MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/pki_priv.h"
|
||||
#include "libssh/ed25519.h"
|
||||
#include "libssh/buffer.h"
|
||||
|
||||
int pki_key_generate_ed25519(ssh_key key)
|
||||
{
|
||||
int rc;
|
||||
|
||||
key->ed25519_privkey = malloc(sizeof (ed25519_privkey));
|
||||
if (key->ed25519_privkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
key->ed25519_pubkey = malloc(sizeof (ed25519_privkey));
|
||||
if (key->ed25519_privkey == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = crypto_sign_ed25519_keypair(*key->ed25519_pubkey,
|
||||
*key->ed25519_privkey);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return SSH_OK;
|
||||
error:
|
||||
SAFE_FREE(key->ed25519_privkey);
|
||||
SAFE_FREE(key->ed25519_pubkey);
|
||||
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
int pki_ed25519_sign(const ssh_key privkey,
|
||||
ssh_signature sig,
|
||||
const unsigned char *hash,
|
||||
size_t hlen)
|
||||
{
|
||||
int rc;
|
||||
uint8_t *buffer;
|
||||
unsigned long long dlen = 0;
|
||||
|
||||
buffer = malloc(hlen + ED25519_SIG_LEN);
|
||||
if (buffer == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = crypto_sign_ed25519(buffer,
|
||||
&dlen,
|
||||
hash,
|
||||
hlen,
|
||||
*privkey->ed25519_privkey);
|
||||
if (rc != 0) {
|
||||
goto error;
|
||||
}
|
||||
sig->ed25519_sig = malloc(ED25519_SIG_LEN);
|
||||
if (sig->ed25519_sig == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* This shouldn't happen */
|
||||
if (dlen - hlen != ED25519_SIG_LEN) {
|
||||
goto error;
|
||||
}
|
||||
memcpy(sig->ed25519_sig, buffer, dlen - hlen);
|
||||
SAFE_FREE(buffer);
|
||||
|
||||
return SSH_OK;
|
||||
error:
|
||||
SAFE_FREE(buffer);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
int pki_ed25519_verify(const ssh_key pubkey,
|
||||
ssh_signature sig,
|
||||
const unsigned char *hash,
|
||||
size_t hlen)
|
||||
{
|
||||
unsigned long long mlen = 0;
|
||||
uint8_t *buffer;
|
||||
uint8_t *buffer2;
|
||||
int rc;
|
||||
|
||||
if (pubkey == NULL || sig == NULL ||
|
||||
hash == NULL || sig->ed25519_sig == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
buffer = malloc(hlen + ED25519_SIG_LEN);
|
||||
if (buffer == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
buffer2 = malloc(hlen + ED25519_SIG_LEN);
|
||||
if (buffer2 == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(buffer, sig->ed25519_sig, ED25519_SIG_LEN);
|
||||
memcpy(buffer + ED25519_SIG_LEN, hash, hlen);
|
||||
|
||||
rc = crypto_sign_ed25519_open(buffer2,
|
||||
&mlen,
|
||||
buffer,
|
||||
hlen + ED25519_SIG_LEN,
|
||||
*pubkey->ed25519_pubkey);
|
||||
|
||||
BURN_BUFFER(buffer, hlen + ED25519_SIG_LEN);
|
||||
BURN_BUFFER(buffer2, hlen);
|
||||
SAFE_FREE(buffer);
|
||||
SAFE_FREE(buffer2);
|
||||
if (rc == 0) {
|
||||
return SSH_OK;
|
||||
} else {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
error:
|
||||
SAFE_FREE(buffer);
|
||||
SAFE_FREE(buffer2);
|
||||
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Compare ed25519 keys if they are equal.
|
||||
*
|
||||
* @param[in] k1 The first key to compare.
|
||||
*
|
||||
* @param[in] k2 The second key to compare.
|
||||
*
|
||||
* @param[in] what What part or type of the key do you want to compare.
|
||||
*
|
||||
* @return 0 if equal, 1 if not.
|
||||
*/
|
||||
int pki_ed25519_key_cmp(const ssh_key k1,
|
||||
const ssh_key k2,
|
||||
enum ssh_keycmp_e what)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
switch(what) {
|
||||
case SSH_KEY_CMP_PRIVATE:
|
||||
if (k1->ed25519_privkey == NULL || k2->ed25519_privkey == NULL) {
|
||||
return 1;
|
||||
}
|
||||
cmp = memcmp(k1->ed25519_privkey, k2->ed25519_privkey, ED25519_SK_LEN);
|
||||
if (cmp != 0) {
|
||||
return 1;
|
||||
}
|
||||
/* FALL THROUGH */
|
||||
case SSH_KEY_CMP_PUBLIC:
|
||||
if (k1->ed25519_pubkey == NULL || k2->ed25519_pubkey == NULL) {
|
||||
return 1;
|
||||
}
|
||||
cmp = memcmp(k1->ed25519_pubkey, k2->ed25519_pubkey, ED25519_PK_LEN);
|
||||
if (cmp != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief duplicate an ed25519 key
|
||||
*
|
||||
* @param[out\ new preinitialized output ssh_ke
|
||||
*
|
||||
* @param[in] key key to copy
|
||||
*
|
||||
* @return SSH_ERROR on error, SSH_OK on success
|
||||
*/
|
||||
int pki_ed25519_key_dup(ssh_key new, const ssh_key key)
|
||||
{
|
||||
if (key->ed25519_privkey == NULL || key->ed25519_pubkey == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
new->ed25519_privkey = malloc(ED25519_SK_LEN);
|
||||
if (new->ed25519_privkey == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
new->ed25519_pubkey = malloc(ED25519_PK_LEN);
|
||||
if (new->ed25519_privkey == NULL || new->ed25519_pubkey == NULL){
|
||||
SAFE_FREE(new->ed25519_privkey);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
memcpy(new->ed25519_privkey, key->ed25519_privkey, ED25519_SK_LEN);
|
||||
memcpy(new->ed25519_pubkey, key->ed25519_pubkey, ED25519_PK_LEN);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief outputs an ed25519 public key in a blob buffer.
|
||||
*
|
||||
* @param[out] buffer output buffer
|
||||
*
|
||||
* @param[in] key key to output
|
||||
*
|
||||
* @return SSH_ERROR on error, SSH_OK on success
|
||||
*/
|
||||
int pki_ed25519_public_key_to_blob(ssh_buffer buffer, ssh_key key)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (key->ed25519_pubkey == NULL){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = ssh_buffer_pack(buffer,
|
||||
"dP",
|
||||
(uint32_t)ED25519_PK_LEN,
|
||||
(size_t)ED25519_PK_LEN, key->ed25519_pubkey);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief output a signature blob from an ed25519 signature
|
||||
*
|
||||
* @param[in] sig signature to convert
|
||||
*
|
||||
* @return Signature blob in SSH string, or NULL on error
|
||||
*/
|
||||
ssh_string pki_ed25519_sig_to_blob(ssh_signature sig)
|
||||
{
|
||||
ssh_string sig_blob;
|
||||
|
||||
if (sig->ed25519_sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig_blob = ssh_string_new(ED25519_SIG_LEN);
|
||||
if (sig_blob == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(sig_blob, sig->ed25519_sig, ED25519_SIG_LEN);
|
||||
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @brief Convert a signature blob in an ed25519 signature.
|
||||
*
|
||||
* @param[out] sig a preinitialized signature
|
||||
*
|
||||
* @param[in] sig_blob a signature blob
|
||||
*
|
||||
* @return SSH_ERROR on error, SSH_OK on success
|
||||
*/
|
||||
int pki_ed25519_sig_from_blob(ssh_signature sig, ssh_string sig_blob)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
len = ssh_string_len(sig_blob);
|
||||
if (len != ED25519_SIG_LEN){
|
||||
ssh_pki_log("Invalid ssh-ed25519 signature len: %zu", len);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
sig->ed25519_sig = malloc(ED25519_SIG_LEN);
|
||||
if (sig->ed25519_sig == NULL){
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
memcpy(sig->ed25519_sig, ssh_string_data(sig_blob), ED25519_SIG_LEN);
|
||||
|
||||
return SSH_OK;
|
||||
}
|
@ -388,7 +388,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
}
|
||||
} else {
|
||||
if(len > 0) {
|
||||
if (buffer_add_data(buffer, p, len) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, p, len) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
return NULL;
|
||||
@ -398,7 +398,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
|
||||
get_next_line(p, len);
|
||||
while(len > 0 && strncmp(p, header_end, header_end_size) != 0) {
|
||||
if (buffer_add_data(buffer, p, len) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, p, len) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
return NULL;
|
||||
@ -412,7 +412,7 @@ static ssh_buffer privatekey_string_to_buffer(const char *pkey, int type,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buffer_add_data(buffer, "\0", 1) < 0) {
|
||||
if (ssh_buffer_add_data(buffer, "\0", 1) < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
SAFE_FREE(iv);
|
||||
return NULL;
|
||||
@ -591,6 +591,19 @@ int pki_key_ecdsa_nid_from_name(const char *name)
|
||||
}
|
||||
#endif
|
||||
|
||||
ssh_string pki_private_key_to_pem(const ssh_key key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
void *auth_data)
|
||||
{
|
||||
(void) key;
|
||||
(void) passphrase;
|
||||
(void) auth_fn;
|
||||
(void) auth_data;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
const char *passphrase,
|
||||
ssh_auth_callback auth_fn,
|
||||
@ -1141,7 +1154,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key)
|
||||
}
|
||||
|
||||
rc = buffer_add_ssh_string(buffer, type_s);
|
||||
string_free(type_s);
|
||||
ssh_string_free(type_s);
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buffer);
|
||||
return NULL;
|
||||
@ -1577,7 +1590,7 @@ ssh_signature pki_do_sign(const ssh_key privkey,
|
||||
return NULL;
|
||||
}
|
||||
sig->type = privkey->type;
|
||||
|
||||
sig->type_c = privkey->type_c;
|
||||
switch (privkey->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
/* That is to mark the number as positive */
|
||||
@ -1644,6 +1657,7 @@ ssh_signature pki_do_sign_sessionid(const ssh_key key,
|
||||
return NULL;
|
||||
}
|
||||
sig->type = key->type;
|
||||
sig->type_c = key->type_c;
|
||||
|
||||
switch(key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
|
@ -3,8 +3,8 @@
|
||||
*
|
||||
* This file is part of the SSH Library
|
||||
*
|
||||
* Copyright (c) 2009-2010 by Andreas Schneider <mail@cynapses.org>
|
||||
* Copyright (c) 2003-2009 by Aris Adamantiadis
|
||||
* Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
|
||||
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
||||
* Copyright (c) 2009 Aleksandar Kanchev
|
||||
*
|
||||
* The SSH Library is free software; you can redistribute it and/or modify
|
||||
@ -64,6 +64,7 @@
|
||||
|
||||
struct ssh_poll_handle_struct {
|
||||
ssh_poll_ctx ctx;
|
||||
ssh_session session;
|
||||
union {
|
||||
socket_t fd;
|
||||
size_t idx;
|
||||
@ -472,14 +473,18 @@ static int ssh_poll_ctx_resize(ssh_poll_ctx ctx, size_t new_size) {
|
||||
if (pollptrs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ctx->pollptrs = pollptrs;
|
||||
|
||||
pollfds = realloc(ctx->pollfds, sizeof(ssh_pollfd_t) * new_size);
|
||||
if (pollfds == NULL) {
|
||||
ctx->pollptrs = realloc(pollptrs, sizeof(ssh_poll_handle) * ctx->polls_allocated);
|
||||
pollptrs = realloc(ctx->pollptrs, sizeof(ssh_poll_handle) * ctx->polls_allocated);
|
||||
if (pollptrs == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ctx->pollptrs = pollptrs;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->pollptrs = pollptrs;
|
||||
ctx->pollfds = pollfds;
|
||||
ctx->polls_allocated = new_size;
|
||||
|
||||
@ -786,6 +791,10 @@ int ssh_event_add_session(ssh_event event, ssh_session session) {
|
||||
p = session->default_poll_ctx->pollptrs[i];
|
||||
ssh_poll_ctx_remove(session->default_poll_ctx, p);
|
||||
ssh_poll_ctx_add(event->ctx, p);
|
||||
/* associate the pollhandler with a session so we can put it back
|
||||
* at ssh_event_free()
|
||||
*/
|
||||
p->session = session;
|
||||
}
|
||||
#ifdef WITH_SERVER
|
||||
iterator = ssh_list_get_iterator(event->sessions);
|
||||
@ -848,12 +857,22 @@ int ssh_event_remove_fd(ssh_event event, socket_t fd) {
|
||||
for (i = 0; i < used; i++) {
|
||||
if(fd == event->ctx->pollfds[i].fd) {
|
||||
ssh_poll_handle p = event->ctx->pollptrs[i];
|
||||
struct ssh_event_fd_wrapper *pw = p->cb_data;
|
||||
if (p->session != NULL){
|
||||
/* we cannot free that handle, it's owned by its session */
|
||||
continue;
|
||||
}
|
||||
if (p->cb == ssh_event_fd_wrapper_callback) {
|
||||
struct ssh_event_fd_wrapper *pw = p->cb_data;
|
||||
SAFE_FREE(pw);
|
||||
}
|
||||
|
||||
ssh_poll_ctx_remove(event->ctx, p);
|
||||
free(pw);
|
||||
/*
|
||||
* The free function calls ssh_poll_ctx_remove() and decrements
|
||||
* event->ctx->polls_used.
|
||||
*/
|
||||
ssh_poll_free(p);
|
||||
rc = SSH_OK;
|
||||
|
||||
/* restart the loop */
|
||||
used = event->ctx->polls_used;
|
||||
i = 0;
|
||||
@ -876,7 +895,6 @@ int ssh_event_remove_session(ssh_event event, ssh_session session) {
|
||||
ssh_poll_handle p;
|
||||
register size_t i, used;
|
||||
int rc = SSH_ERROR;
|
||||
socket_t session_fd;
|
||||
#ifdef WITH_SERVER
|
||||
struct ssh_iterator *iterator;
|
||||
#endif
|
||||
@ -885,14 +903,15 @@ int ssh_event_remove_session(ssh_event event, ssh_session session) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
session_fd = ssh_get_fd(session);
|
||||
used = event->ctx->polls_used;
|
||||
for(i = 0; i < used; i++) {
|
||||
if(session_fd == event->ctx->pollfds[i].fd) {
|
||||
p = event->ctx->pollptrs[i];
|
||||
p = event->ctx->pollptrs[i];
|
||||
if(p->session == session){
|
||||
ssh_poll_ctx_remove(event->ctx, p);
|
||||
p->session = NULL;
|
||||
ssh_poll_ctx_add(session->default_poll_ctx, p);
|
||||
rc = SSH_OK;
|
||||
used = 0;
|
||||
}
|
||||
}
|
||||
#ifdef WITH_SERVER
|
||||
@ -919,10 +938,23 @@ int ssh_event_remove_session(ssh_event event, ssh_session session) {
|
||||
*
|
||||
*/
|
||||
void ssh_event_free(ssh_event event) {
|
||||
if(event == NULL) {
|
||||
int used, i;
|
||||
ssh_poll_handle p;
|
||||
if(event == NULL) {
|
||||
return;
|
||||
}
|
||||
if(event->ctx != NULL) {
|
||||
used = event->ctx->polls_used;
|
||||
for(i = 0; i < used; i++) {
|
||||
p = event->ctx->pollptrs[i];
|
||||
if(p->session != NULL){
|
||||
ssh_poll_ctx_remove(event->ctx, p);
|
||||
ssh_poll_ctx_add(p->session->default_poll_ctx, p);
|
||||
p->session = NULL;
|
||||
used = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ssh_poll_ctx_free(event->ctx);
|
||||
}
|
||||
#ifdef WITH_SERVER
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user