mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Compare commits
39 Commits
stable-0.1
...
libssh-0.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f6b3fab4e | ||
|
|
cd7ccf93f0 | ||
|
|
5944124428 | ||
|
|
8c40b2491d | ||
|
|
3331b794bc | ||
|
|
02f1873b9e | ||
|
|
5da93db25a | ||
|
|
b18495b56b | ||
|
|
a96763b195 | ||
|
|
540257b421 | ||
|
|
b657eeb65e | ||
|
|
4a87515026 | ||
|
|
886ed379d8 | ||
|
|
9b9197d86b | ||
|
|
64e89affeb | ||
|
|
2c1ad3262a | ||
|
|
14ff31490f | ||
|
|
3db3511467 | ||
|
|
4c5da86f91 | ||
|
|
2564246024 | ||
|
|
146d1a620d | ||
|
|
19c43ff6b7 | ||
|
|
58a2943d42 | ||
|
|
54c5472b53 | ||
|
|
17e9cd70a5 | ||
|
|
cee5c9f404 | ||
|
|
43fb1d7c8d | ||
|
|
5c629f22f6 | ||
|
|
46e0703c6e | ||
|
|
cffa103378 | ||
|
|
ea6558b3a6 | ||
|
|
33e12317c3 | ||
|
|
d17c635617 | ||
|
|
dde5fd8d38 | ||
|
|
46e78aaa3a | ||
|
|
3107133d10 | ||
|
|
b9ccaf6e23 | ||
|
|
38b17e6e6e | ||
|
|
db0a1d6811 |
@@ -2,12 +2,12 @@
|
|||||||
variables:
|
variables:
|
||||||
BUILD_IMAGES_PROJECT: libssh/build-images
|
BUILD_IMAGES_PROJECT: libssh/build-images
|
||||||
CENTOS7_BUILD: buildenv-centos7
|
CENTOS7_BUILD: buildenv-centos7
|
||||||
|
CENTOS9_BUILD: buildenv-c9s
|
||||||
COVERITY_BUILD: buildenv-coverity
|
COVERITY_BUILD: buildenv-coverity
|
||||||
FEDORA_BUILD: buildenv-fedora
|
FEDORA_BUILD: buildenv-fedora
|
||||||
MINGW_BUILD: buildenv-mingw
|
MINGW_BUILD: buildenv-mingw
|
||||||
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
||||||
UBUNTU_BUILD: buildenv-ubuntu
|
UBUNTU_BUILD: buildenv-ubuntu
|
||||||
RAWHIDE_BUILD: buildenv-rawhide
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
@@ -61,14 +61,6 @@ stages:
|
|||||||
variables:
|
variables:
|
||||||
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
|
CMAKE_ADDITIONAL_OPTIONS: -DWITH_PKCS11_URI=ON
|
||||||
|
|
||||||
.fedora_rawhide:
|
|
||||||
extends: .fedora
|
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$RAWHIDE_BUILD
|
|
||||||
before_script:
|
|
||||||
- *build
|
|
||||||
# Legacy cp is needed for SHA1 tests to pass
|
|
||||||
- update-crypto-policies --set LEGACY
|
|
||||||
|
|
||||||
.tumbleweed:
|
.tumbleweed:
|
||||||
extends: .tests
|
extends: .tests
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||||
@@ -86,6 +78,15 @@ centos7/openssl_1.0.x/x86_64:
|
|||||||
make -j$(nproc) &&
|
make -j$(nproc) &&
|
||||||
ctest --output-on-failure
|
ctest --output-on-failure
|
||||||
|
|
||||||
|
centos9s/openssl_3.0.x/x86_64:
|
||||||
|
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$CENTOS9_BUILD
|
||||||
|
extends: .tests
|
||||||
|
script:
|
||||||
|
- export OPENSSL_ENABLE_SHA1_SIGNATURES=1
|
||||||
|
- cmake3 $CMAKE_OPTIONS .. &&
|
||||||
|
make -j$(nproc) &&
|
||||||
|
ctest --output-on-failure
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Fedora builds #
|
# Fedora builds #
|
||||||
@@ -106,10 +107,10 @@ fedora/ninja:
|
|||||||
script:
|
script:
|
||||||
- cmake -G Ninja $CMAKE_OPTIONS ../ && ninja && ninja test
|
- cmake -G Ninja $CMAKE_OPTIONS ../ && ninja && ninja test
|
||||||
|
|
||||||
fedora/openssl_1.1.x/x86_64:
|
fedora/openssl_3.0.x/x86_64:
|
||||||
extends: .fedora
|
extends: .fedora
|
||||||
|
|
||||||
fedora/openssl_1.1.x/x86_64/fips:
|
fedora/openssl_3.0.x/x86_64/fips:
|
||||||
extends: .fedora
|
extends: .fedora
|
||||||
before_script:
|
before_script:
|
||||||
- echo "# userspace fips" > /etc/system-fips
|
- echo "# userspace fips" > /etc/system-fips
|
||||||
@@ -134,7 +135,7 @@ fedora/openssl_1.1.x/x86_64/fips:
|
|||||||
make -j$(nproc) &&
|
make -j$(nproc) &&
|
||||||
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
|
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
|
||||||
|
|
||||||
fedora/openssl_1.1.x/x86_64/minimal:
|
fedora/openssl_3.0.x/x86_64/minimal:
|
||||||
extends: .fedora
|
extends: .fedora
|
||||||
variables:
|
variables:
|
||||||
script:
|
script:
|
||||||
@@ -149,49 +150,6 @@ fedora/openssl_1.1.x/x86_64/minimal:
|
|||||||
-DWITH_GEX=OFF .. &&
|
-DWITH_GEX=OFF .. &&
|
||||||
make -j$(nproc)
|
make -j$(nproc)
|
||||||
|
|
||||||
fedora/openssl_3.0/x86_64:
|
|
||||||
extends: .fedora_rawhide
|
|
||||||
|
|
||||||
fedora/openssl_3.0/x86_64/fips:
|
|
||||||
extends: .fedora_rawhide
|
|
||||||
before_script:
|
|
||||||
- echo "# userspace fips" > /etc/system-fips
|
|
||||||
# We do not need the kernel part, but in case we ever do:
|
|
||||||
# mkdir -p /var/tmp/userspace-fips
|
|
||||||
# echo 1 > /var/tmp/userspace-fips/fips_enabled
|
|
||||||
# mount --bind /var/tmp/userspace-fips/fips_enabled \
|
|
||||||
# /proc/sys/crypto/fips_enabled
|
|
||||||
- update-crypto-policies --show
|
|
||||||
- update-crypto-policies --set FIPS
|
|
||||||
- update-crypto-policies --show
|
|
||||||
- mkdir -p obj && cd obj && cmake
|
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo
|
|
||||||
-DPICKY_DEVELOPER=ON
|
|
||||||
-DWITH_BLOWFISH_CIPHER=ON
|
|
||||||
-DWITH_SFTP=ON -DWITH_SERVER=ON -DWITH_ZLIB=ON -DWITH_PCAP=ON
|
|
||||||
-DWITH_DEBUG_CRYPTO=ON -DWITH_DEBUG_PACKET=ON -DWITH_DEBUG_CALLTRACE=ON
|
|
||||||
-DWITH_DSA=ON
|
|
||||||
-DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON ..
|
|
||||||
script:
|
|
||||||
- cmake $CMAKE_OPTIONS .. &&
|
|
||||||
make -j$(nproc) &&
|
|
||||||
OPENSSL_FORCE_FIPS_MODE=1 ctest --output-on-failure
|
|
||||||
|
|
||||||
fedora/openssl_3.0/x86_64/minimal:
|
|
||||||
extends: .fedora_rawhide
|
|
||||||
variables:
|
|
||||||
script:
|
|
||||||
- cmake $CMAKE_DEFAULT_OPTIONS
|
|
||||||
-DWITH_SFTP=OFF
|
|
||||||
-DWITH_SERVER=OFF
|
|
||||||
-DWITH_ZLIB=OFF
|
|
||||||
-DWITH_PCAP=OFF
|
|
||||||
-DWITH_DSA=OFF
|
|
||||||
-DUNIT_TESTING=ON
|
|
||||||
-DCLIENT_TESTING=ON
|
|
||||||
-DWITH_GEX=OFF .. &&
|
|
||||||
make -j$(nproc)
|
|
||||||
|
|
||||||
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
|
# Address sanitizer doesn't mix well with LD_PRELOAD used in the testsuite
|
||||||
# so, this is only enabled for unit tests right now.
|
# so, this is only enabled for unit tests right now.
|
||||||
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||||
@@ -316,19 +274,8 @@ fedora/mingw32:
|
|||||||
paths:
|
paths:
|
||||||
- obj-csbuild/
|
- obj-csbuild/
|
||||||
|
|
||||||
fedora/csbuild/openssl_1.1.x:
|
|
||||||
extends: .csbuild
|
|
||||||
script:
|
|
||||||
- csbuild
|
|
||||||
--build-dir=obj-csbuild
|
|
||||||
--build-cmd "rm -rf CMakeFiles CMakeCache.txt && cmake -DCMAKE_BUILD_TYPE=Debug -DPICKY_DEVELOPER=ON -DUNIT_TESTING=ON -DCLIENT_TESTING=ON -DSERVER_TESTING=ON -DFUZZ_TESTING=ON -DWITH_DSA=ON @SRCDIR@ && make clean && make -j$(nproc)"
|
|
||||||
--git-commit-range $CI_COMMIT_RANGE
|
|
||||||
--color
|
|
||||||
--print-current --print-fixed
|
|
||||||
|
|
||||||
fedora/csbuild/openssl_3.0.x:
|
fedora/csbuild/openssl_3.0.x:
|
||||||
extends: .csbuild
|
extends: .csbuild
|
||||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$RAWHIDE_BUILD
|
|
||||||
script:
|
script:
|
||||||
- csbuild
|
- csbuild
|
||||||
--build-dir=obj-csbuild
|
--build-dir=obj-csbuild
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
version 0.10.0 (released 2022-07-xx)
|
version 0.10.0 (released 2022-08-26)
|
||||||
* Added support for OpenSSL 3.0
|
* Added support for OpenSSL 3.0
|
||||||
* Added support for mbedTLS 3
|
* Added support for mbedTLS 3
|
||||||
* Added support for Smart Cards (through openssl pkcs11 engine)
|
* Added support for Smart Cards (through openssl pkcs11 engine)
|
||||||
@@ -25,6 +25,9 @@ version 0.10.0 (released 2022-07-xx)
|
|||||||
* Deprecated old pubkey, privatekey API
|
* Deprecated old pubkey, privatekey API
|
||||||
* Avoided some needless large stack buffers to minimize memory footprint
|
* Avoided some needless large stack buffers to minimize memory footprint
|
||||||
* Removed support for OpenSSL < 1.0.1
|
* Removed support for OpenSSL < 1.0.1
|
||||||
|
* Fixed parsing username@host in login name
|
||||||
|
* Free global init mutex in the destructor on Windows
|
||||||
|
* Fixed PEM parsing in mbedtls to support both legacy and new PKCS8 formats
|
||||||
|
|
||||||
version 0.9.6 (released 2021-08-26)
|
version 0.9.6 (released 2021-08-26)
|
||||||
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with
|
* CVE-2021-3634: Fix possible heap-buffer overflow when rekeying with
|
||||||
|
|||||||
@@ -104,6 +104,10 @@ if (OPENSSL_FOUND)
|
|||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||||
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
|
check_function_exists(EVP_KDF_CTX_new_id HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||||
|
check_function_exists(EVP_KDF_CTX_new HAVE_OPENSSL_EVP_KDF_CTX_NEW)
|
||||||
|
|
||||||
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||||
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
|
check_function_exists(FIPS_mode HAVE_OPENSSL_FIPS_MODE)
|
||||||
@@ -159,6 +163,11 @@ if (NOT WITH_GCRYPT AND NOT WITH_MBEDTLS)
|
|||||||
if (HAVE_OPENSSL_ECC)
|
if (HAVE_OPENSSL_ECC)
|
||||||
set(HAVE_ECC 1)
|
set(HAVE_ECC 1)
|
||||||
endif (HAVE_OPENSSL_ECC)
|
endif (HAVE_OPENSSL_ECC)
|
||||||
|
|
||||||
|
if (HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID OR HAVE_OPENSSL_EVP_KDF_CTX_NEW)
|
||||||
|
set(HAVE_OPENSSL_EVP_KDF_CTX 1)
|
||||||
|
endif (HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID OR HAVE_OPENSSL_EVP_KDF_CTX_NEW)
|
||||||
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
if (WITH_DSA)
|
if (WITH_DSA)
|
||||||
@@ -468,6 +477,10 @@ if (WITH_PKCS11_URI)
|
|||||||
message(FATAL_ERROR "PKCS #11 is not supported for mbedcrypto")
|
message(FATAL_ERROR "PKCS #11 is not supported for mbedcrypto")
|
||||||
set(WITH_PKCS11_URI 0)
|
set(WITH_PKCS11_URI 0)
|
||||||
endif()
|
endif()
|
||||||
|
if (HAVE_OPENSSL AND NOT OPENSSL_VERSION VERSION_GREATER_EQUAL "1.1.1")
|
||||||
|
message(FATAL_ERROR "PKCS #11 requires at least OpenSSL 1.1.1")
|
||||||
|
set(WITH_PKCS11_URI 0)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WITH_MBEDTLS)
|
if (WITH_MBEDTLS)
|
||||||
|
|||||||
@@ -114,8 +114,8 @@
|
|||||||
/* Define to 1 if you have the `EVP_chacha20' function. */
|
/* Define to 1 if you have the `EVP_chacha20' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_CHACHA20 1
|
#cmakedefine HAVE_OPENSSL_EVP_CHACHA20 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' function. */
|
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' or `EVP_KDF_CTX_new` function. */
|
||||||
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID 1
|
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX 1
|
||||||
|
|
||||||
/* Define to 1 if you have the `FIPS_mode' function. */
|
/* Define to 1 if you have the `FIPS_mode' function. */
|
||||||
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
|
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ struct arguments_st {
|
|||||||
unsigned long bits;
|
unsigned long bits;
|
||||||
char *file;
|
char *file;
|
||||||
char *passphrase;
|
char *passphrase;
|
||||||
|
int action_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct argp_option options[] = {
|
static struct argp_option options[] = {
|
||||||
@@ -88,6 +89,14 @@ static struct argp_option options[] = {
|
|||||||
"\"rsa\", \"ecdsa\", \"ed25519\", and \"dsa\".\n",
|
"\"rsa\", \"ecdsa\", \"ed25519\", and \"dsa\".\n",
|
||||||
.group = 0
|
.group = 0
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "list",
|
||||||
|
.key = 'l',
|
||||||
|
.arg = NULL,
|
||||||
|
.flags = 0,
|
||||||
|
.doc = "List the Fingerprint of the given key\n",
|
||||||
|
.group = 0
|
||||||
|
},
|
||||||
{
|
{
|
||||||
/* End of the options */
|
/* End of the options */
|
||||||
0
|
0
|
||||||
@@ -160,6 +169,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
arguments->action_list = 1;
|
||||||
|
break;
|
||||||
case ARGP_KEY_ARG:
|
case ARGP_KEY_ARG:
|
||||||
if (state->arg_num > 0) {
|
if (state->arg_num > 0) {
|
||||||
/* Too many arguments. */
|
/* Too many arguments. */
|
||||||
@@ -185,98 +197,103 @@ static int validate_args(struct arguments_st *args)
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(args->type) {
|
/* no other arguments needed for listing key fingerprints */
|
||||||
case SSH_KEYTYPE_RSA:
|
if (args->action_list) {
|
||||||
switch(args->bits) {
|
return 0;
|
||||||
case 0:
|
}
|
||||||
/* If not provided, use default value */
|
|
||||||
args->bits = 3072;
|
|
||||||
break;
|
|
||||||
case 1024:
|
|
||||||
case 2048:
|
|
||||||
case 3072:
|
|
||||||
case 4096:
|
|
||||||
case 8192:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_rsa");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (args->type) {
|
||||||
|
case SSH_KEYTYPE_RSA:
|
||||||
|
switch (args->bits) {
|
||||||
|
case 0:
|
||||||
|
/* If not provided, use default value */
|
||||||
|
args->bits = 3072;
|
||||||
break;
|
break;
|
||||||
case SSH_KEYTYPE_ECDSA:
|
case 1024:
|
||||||
switch(args->bits) {
|
case 2048:
|
||||||
case 0:
|
case 3072:
|
||||||
/* If not provided, use default value */
|
case 4096:
|
||||||
args->bits = 256;
|
case 8192:
|
||||||
break;
|
|
||||||
case 256:
|
|
||||||
case 384:
|
|
||||||
case 521:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_ecdsa");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_DSS:
|
|
||||||
switch(args->bits) {
|
|
||||||
case 0:
|
|
||||||
/* If not provided, use default value */
|
|
||||||
args->bits = 1024;
|
|
||||||
break;
|
|
||||||
case 1024:
|
|
||||||
case 2048:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
|
||||||
rc = EINVAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_dsa");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_ED25519:
|
|
||||||
/* Ignore value and overwrite with a zero */
|
|
||||||
args->bits = 0;
|
|
||||||
|
|
||||||
if (args->file == NULL) {
|
|
||||||
args->file = strdup("id_ed25519");
|
|
||||||
if (args->file == NULL) {
|
|
||||||
rc = ENOMEM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Error: unknown key type\n");
|
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
||||||
rc = EINVAL;
|
rc = EINVAL;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->file == NULL) {
|
||||||
|
args->file = strdup("id_rsa");
|
||||||
|
if (args->file == NULL) {
|
||||||
|
rc = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSH_KEYTYPE_ECDSA:
|
||||||
|
switch (args->bits) {
|
||||||
|
case 0:
|
||||||
|
/* If not provided, use default value */
|
||||||
|
args->bits = 256;
|
||||||
|
break;
|
||||||
|
case 256:
|
||||||
|
case 384:
|
||||||
|
case 521:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
||||||
|
rc = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (args->file == NULL) {
|
||||||
|
args->file = strdup("id_ecdsa");
|
||||||
|
if (args->file == NULL) {
|
||||||
|
rc = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSH_KEYTYPE_DSS:
|
||||||
|
switch (args->bits) {
|
||||||
|
case 0:
|
||||||
|
/* If not provided, use default value */
|
||||||
|
args->bits = 1024;
|
||||||
|
break;
|
||||||
|
case 1024:
|
||||||
|
case 2048:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: Invalid bits parameter provided\n");
|
||||||
|
rc = EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (args->file == NULL) {
|
||||||
|
args->file = strdup("id_dsa");
|
||||||
|
if (args->file == NULL) {
|
||||||
|
rc = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSH_KEYTYPE_ED25519:
|
||||||
|
/* Ignore value and overwrite with a zero */
|
||||||
|
args->bits = 0;
|
||||||
|
|
||||||
|
if (args->file == NULL) {
|
||||||
|
args->file = strdup("id_ed25519");
|
||||||
|
if (args->file == NULL) {
|
||||||
|
rc = ENOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Error: unknown key type\n");
|
||||||
|
rc = EINVAL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
@@ -289,6 +306,31 @@ static char doc[] = "Generate an SSH key pair. "
|
|||||||
/* Our argp parser */
|
/* Our argp parser */
|
||||||
static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL};
|
static struct argp argp = {options, parse_opt, NULL, doc, NULL, NULL, NULL};
|
||||||
|
|
||||||
|
static void
|
||||||
|
list_fingerprint(char *file)
|
||||||
|
{
|
||||||
|
ssh_key key = NULL;
|
||||||
|
unsigned char *hash = NULL;
|
||||||
|
size_t hlen = 0;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_pki_import_privkey_file(file, NULL, NULL, NULL, &key);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
fprintf(stderr, "Failed to import private key %s\n", file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_get_publickey_hash(key, SSH_PUBLICKEY_HASH_SHA256, &hash, &hlen);
|
||||||
|
if (rc != SSH_OK) {
|
||||||
|
fprintf(stderr, "Failed to get key fingerprint\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
|
||||||
|
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
ssh_key_free(key);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
ssh_key key = NULL;
|
ssh_key key = NULL;
|
||||||
@@ -302,6 +344,7 @@ int main(int argc, char *argv[])
|
|||||||
.bits = 0,
|
.bits = 0,
|
||||||
.file = NULL,
|
.file = NULL,
|
||||||
.passphrase = NULL,
|
.passphrase = NULL,
|
||||||
|
.action_list = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
@@ -319,6 +362,11 @@ int main(int argc, char *argv[])
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arguments.action_list && arguments.file) {
|
||||||
|
list_fingerprint(arguments.file);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
rc = open(arguments.file, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
|
rc = open(arguments.file, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ cleanup_push(struct cleanup_node_struct** head_ref,
|
|||||||
// Allocate memory for node
|
// Allocate memory for node
|
||||||
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
|
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
|
||||||
|
|
||||||
if (head_ref != NULL) {
|
if (*head_ref != NULL) {
|
||||||
new_node->next = *head_ref;
|
new_node->next = *head_ref;
|
||||||
} else {
|
} else {
|
||||||
new_node->next = NULL;
|
new_node->next = NULL;
|
||||||
|
|||||||
@@ -223,5 +223,8 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
|
|||||||
size_t requested_len);
|
size_t requested_len);
|
||||||
|
|
||||||
int secure_memcmp(const void *s1, const void *s2, size_t n);
|
int secure_memcmp(const void *s1, const void *s2, size_t n);
|
||||||
|
#ifdef HAVE_LIBCRYPTO
|
||||||
|
ENGINE *pki_get_engine(void);
|
||||||
|
#endif /* HAVE_LIBCRYPTO */
|
||||||
|
|
||||||
#endif /* _CRYPTO_H_ */
|
#endif /* _CRYPTO_H_ */
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#endif
|
#endif
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
#ifdef HAVE_OPENSSL_ED25519
|
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
|
||||||
/* If using OpenSSL implementation, define the signature lenght which would be
|
/* If using OpenSSL implementation, define the signature lenght which would be
|
||||||
* defined in libssh/ed25519.h otherwise */
|
* defined in libssh/ed25519.h otherwise */
|
||||||
#define ED25519_SIG_LEN 64
|
#define ED25519_SIG_LEN 64
|
||||||
@@ -78,9 +78,11 @@ struct ssh_key_struct {
|
|||||||
# else
|
# else
|
||||||
void *ecdsa;
|
void *ecdsa;
|
||||||
# endif /* HAVE_OPENSSL_EC_H */
|
# endif /* HAVE_OPENSSL_EC_H */
|
||||||
EVP_PKEY *key; /* Saving the OpenSSL context here to save time while converting*/
|
/* This holds either ENGINE key for PKCS#11 support or just key in
|
||||||
|
* high-level format required by OpenSSL 3.0 */
|
||||||
|
EVP_PKEY *key;
|
||||||
#endif /* HAVE_LIBGCRYPT */
|
#endif /* HAVE_LIBGCRYPT */
|
||||||
#ifdef HAVE_OPENSSL_ED25519
|
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
|
||||||
uint8_t *ed25519_pubkey;
|
uint8_t *ed25519_pubkey;
|
||||||
uint8_t *ed25519_privkey;
|
uint8_t *ed25519_privkey;
|
||||||
#else
|
#else
|
||||||
@@ -104,7 +106,7 @@ struct ssh_signature_struct {
|
|||||||
ssh_string rsa_sig;
|
ssh_string rsa_sig;
|
||||||
struct mbedtls_ecdsa_sig ecdsa_sig;
|
struct mbedtls_ecdsa_sig ecdsa_sig;
|
||||||
#endif /* HAVE_LIBGCRYPT */
|
#endif /* HAVE_LIBGCRYPT */
|
||||||
#ifndef HAVE_OPENSSL_ED25519
|
#if !defined(HAVE_LIBCRYPTO) || !defined(HAVE_OPENSSL_ED25519)
|
||||||
ed25519_signature *ed25519_sig;
|
ed25519_signature *ed25519_sig;
|
||||||
#endif
|
#endif
|
||||||
ssh_string raw_sig;
|
ssh_string raw_sig;
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ enum ssh_key_e {
|
|||||||
SSH_KEY_PRIVATE
|
SSH_KEY_PRIVATE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void pki_key_clean(ssh_key key);
|
||||||
|
|
||||||
int pki_key_ecdsa_nid_from_name(const char *name);
|
int pki_key_ecdsa_nid_from_name(const char *name);
|
||||||
const char *pki_key_ecdsa_nid_to_name(int nid);
|
const char *pki_key_ecdsa_nid_to_name(int nid);
|
||||||
const char *ssh_key_signature_to_char(enum ssh_keytypes_e type,
|
const char *ssh_key_signature_to_char(enum ssh_keytypes_e type,
|
||||||
|
|||||||
@@ -152,7 +152,9 @@ char *strndup(const char *s, size_t n);
|
|||||||
# endif /* _MSC_VER */
|
# endif /* _MSC_VER */
|
||||||
|
|
||||||
struct timeval;
|
struct timeval;
|
||||||
int gettimeofday(struct timeval *__p, void *__t);
|
int ssh_gettimeofday(struct timeval *__p, void *__t);
|
||||||
|
|
||||||
|
#define gettimeofday ssh_gettimeofday
|
||||||
|
|
||||||
#define _XCLOSESOCKET closesocket
|
#define _XCLOSESOCKET closesocket
|
||||||
|
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ struct ssh_session_struct {
|
|||||||
char *agent_socket;
|
char *agent_socket;
|
||||||
unsigned long timeout; /* seconds */
|
unsigned long timeout; /* seconds */
|
||||||
unsigned long timeout_usec;
|
unsigned long timeout_usec;
|
||||||
unsigned int port;
|
uint16_t port;
|
||||||
socket_t fd;
|
socket_t fd;
|
||||||
int StrictHostKeyChecking;
|
int StrictHostKeyChecking;
|
||||||
char compressionlevel;
|
char compressionlevel;
|
||||||
|
|||||||
@@ -184,6 +184,8 @@ if (WITH_GCRYPT)
|
|||||||
gcrypt_missing.c
|
gcrypt_missing.c
|
||||||
pki_gcrypt.c
|
pki_gcrypt.c
|
||||||
ecdh_gcrypt.c
|
ecdh_gcrypt.c
|
||||||
|
getrandom_gcrypt.c
|
||||||
|
md_gcrypt.c
|
||||||
dh_key.c
|
dh_key.c
|
||||||
pki_ed25519.c
|
pki_ed25519.c
|
||||||
external/ed25519.c
|
external/ed25519.c
|
||||||
@@ -207,6 +209,8 @@ elseif (WITH_MBEDTLS)
|
|||||||
mbedcrypto_missing.c
|
mbedcrypto_missing.c
|
||||||
pki_mbedcrypto.c
|
pki_mbedcrypto.c
|
||||||
ecdh_mbedcrypto.c
|
ecdh_mbedcrypto.c
|
||||||
|
getrandom_mbedcrypto.c
|
||||||
|
md_mbedcrypto.c
|
||||||
dh_key.c
|
dh_key.c
|
||||||
pki_ed25519.c
|
pki_ed25519.c
|
||||||
external/ed25519.c
|
external/ed25519.c
|
||||||
@@ -229,6 +233,8 @@ else (WITH_GCRYPT)
|
|||||||
threads/libcrypto.c
|
threads/libcrypto.c
|
||||||
pki_crypto.c
|
pki_crypto.c
|
||||||
ecdh_crypto.c
|
ecdh_crypto.c
|
||||||
|
getrandom_crypto.c
|
||||||
|
md_crypto.c
|
||||||
libcrypto.c
|
libcrypto.c
|
||||||
dh_crypto.c
|
dh_crypto.c
|
||||||
)
|
)
|
||||||
@@ -300,12 +306,12 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
|||||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||||
|
|
||||||
if (NOT WITH_NACL)
|
if (NOT WITH_NACL)
|
||||||
if (NOT HAVE_OPENSSL_ED25519)
|
if (NOT HAVE_LIBCRYPTO OR NOT HAVE_OPENSSL_ED25519)
|
||||||
set(libssh_SRCS
|
set(libssh_SRCS
|
||||||
${libssh_SRCS}
|
${libssh_SRCS}
|
||||||
external/curve25519_ref.c
|
external/curve25519_ref.c
|
||||||
)
|
)
|
||||||
endif (NOT HAVE_OPENSSL_ED25519)
|
endif()
|
||||||
endif (NOT WITH_NACL)
|
endif (NOT WITH_NACL)
|
||||||
|
|
||||||
# Set the path to the default map file
|
# Set the path to the default map file
|
||||||
|
|||||||
@@ -282,7 +282,7 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (listen(fd, 10) < 0) {
|
if (listen(fd, 10) < 0) {
|
||||||
char err_msg[] = {0};
|
char err_msg[SSH_ERRNO_MSG_MAX] = {0};
|
||||||
ssh_set_error(sshbind, SSH_FATAL,
|
ssh_set_error(sshbind, SSH_FATAL,
|
||||||
"Listening to socket %d: %s",
|
"Listening to socket %d: %s",
|
||||||
fd, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
fd, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
#include "libssh/pki.h"
|
#include "libssh/pki.h"
|
||||||
#include "libssh/bignum.h"
|
#include "libssh/bignum.h"
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_X25519
|
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519)
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ static struct ssh_packet_callbacks_struct ssh_curve25519_client_callbacks = {
|
|||||||
static int ssh_curve25519_init(ssh_session session)
|
static int ssh_curve25519_init(ssh_session session)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
#ifdef HAVE_OPENSSL_X25519
|
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519)
|
||||||
EVP_PKEY_CTX *pctx = NULL;
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
size_t pubkey_len = CURVE25519_PUBKEY_SIZE;
|
size_t pubkey_len = CURVE25519_PUBKEY_SIZE;
|
||||||
@@ -136,7 +136,7 @@ static int ssh_curve25519_init(ssh_session session)
|
|||||||
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
|
||||||
session->next_crypto->curve25519_privkey);
|
session->next_crypto->curve25519_privkey);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL_X25519 */
|
#endif /* defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519) */
|
||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
@@ -176,7 +176,7 @@ static int ssh_curve25519_build_k(ssh_session session)
|
|||||||
{
|
{
|
||||||
ssh_curve25519_pubkey k;
|
ssh_curve25519_pubkey k;
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_X25519
|
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519)
|
||||||
EVP_PKEY_CTX *pctx = NULL;
|
EVP_PKEY_CTX *pctx = NULL;
|
||||||
EVP_PKEY *pkey = NULL, *pubkey = NULL;
|
EVP_PKEY *pkey = NULL, *pubkey = NULL;
|
||||||
size_t shared_key_len = sizeof(k);
|
size_t shared_key_len = sizeof(k);
|
||||||
@@ -255,7 +255,7 @@ out:
|
|||||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||||
session->next_crypto->curve25519_server_pubkey);
|
session->next_crypto->curve25519_server_pubkey);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL_X25519 */
|
#endif /* defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519) */
|
||||||
|
|
||||||
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->shared_secret);
|
bignum_bin2bn(k, CURVE25519_PUBKEY_SIZE, &session->next_crypto->shared_secret);
|
||||||
if (session->next_crypto->shared_secret == NULL) {
|
if (session->next_crypto->shared_secret == NULL) {
|
||||||
|
|||||||
54
src/getrandom_crypto.c
Normal file
54
src/getrandom_crypto.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 "config.h"
|
||||||
|
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get random bytes
|
||||||
|
*
|
||||||
|
* Make sure to always check the return code of this function!
|
||||||
|
*
|
||||||
|
* @param[in] where The buffer to fill with random bytes
|
||||||
|
*
|
||||||
|
* @param[in] len The size of the buffer to fill.
|
||||||
|
*
|
||||||
|
* @param[in] strong Use a strong or private RNG source.
|
||||||
|
*
|
||||||
|
* @return 1 on success, 0 on error.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ssh_get_random(void *where, int len, int strong)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_OPENSSL_RAND_PRIV_BYTES
|
||||||
|
if (strong) {
|
||||||
|
/* Returns -1 when not supported, 0 on error, 1 on success */
|
||||||
|
return !!RAND_priv_bytes(where, len);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)strong;
|
||||||
|
#endif /* HAVE_RAND_PRIV_BYTES */
|
||||||
|
|
||||||
|
/* Returns -1 when not supported, 0 on error, 1 on success */
|
||||||
|
return !!RAND_bytes(where, len);
|
||||||
|
}
|
||||||
38
src/getrandom_gcrypt.c
Normal file
38
src/getrandom_gcrypt.c
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 by Aris Adamantiadis
|
||||||
|
* Copyright (C) 2016 g10 Code GmbH
|
||||||
|
*
|
||||||
|
* 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 "config.h"
|
||||||
|
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include <gcrypt.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
ssh_get_random(void *where, int len, int strong)
|
||||||
|
{
|
||||||
|
/* variable not used in gcrypt */
|
||||||
|
(void)strong;
|
||||||
|
|
||||||
|
/* not using GCRY_VERY_STRONG_RANDOM which is a bit overkill */
|
||||||
|
gcry_randomize(where, len, GCRY_STRONG_RANDOM);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
52
src/getrandom_mbedcrypto.c
Normal file
52
src/getrandom_mbedcrypto.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Sartura d.o.o.
|
||||||
|
*
|
||||||
|
* Author: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
|
||||||
|
*
|
||||||
|
* 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 "config.h"
|
||||||
|
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include "mbedcrypto-compat.h"
|
||||||
|
|
||||||
|
mbedtls_ctr_drbg_context ssh_mbedtls_ctr_drbg;
|
||||||
|
|
||||||
|
int
|
||||||
|
ssh_mbedtls_random(void *where, int len, int strong)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
if (strong) {
|
||||||
|
mbedtls_ctr_drbg_set_prediction_resistance(&ssh_mbedtls_ctr_drbg,
|
||||||
|
MBEDTLS_CTR_DRBG_PR_ON);
|
||||||
|
rc = mbedtls_ctr_drbg_random(&ssh_mbedtls_ctr_drbg, where, len);
|
||||||
|
mbedtls_ctr_drbg_set_prediction_resistance(&ssh_mbedtls_ctr_drbg,
|
||||||
|
MBEDTLS_CTR_DRBG_PR_OFF);
|
||||||
|
} else {
|
||||||
|
rc = mbedtls_ctr_drbg_random(&ssh_mbedtls_ctr_drbg, where, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
ssh_get_random(void *where, int len, int strong)
|
||||||
|
{
|
||||||
|
return ssh_mbedtls_random(where, len, strong);
|
||||||
|
}
|
||||||
15
src/init.c
15
src/init.c
@@ -161,12 +161,14 @@ static int _ssh_finalize(unsigned destructor) {
|
|||||||
|
|
||||||
if (_ssh_initialized > 1) {
|
if (_ssh_initialized > 1) {
|
||||||
_ssh_initialized--;
|
_ssh_initialized--;
|
||||||
goto _ret;
|
ssh_mutex_unlock(&ssh_init_mutex);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_ssh_initialized == 1) {
|
if (_ssh_initialized == 1) {
|
||||||
if (_ssh_init_ret < 0) {
|
if (_ssh_init_ret < 0) {
|
||||||
goto _ret;
|
ssh_mutex_unlock(&ssh_init_mutex);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,10 +183,17 @@ static int _ssh_finalize(unsigned destructor) {
|
|||||||
|
|
||||||
_ssh_initialized = 0;
|
_ssh_initialized = 0;
|
||||||
|
|
||||||
_ret:
|
|
||||||
if (!destructor) {
|
if (!destructor) {
|
||||||
ssh_mutex_unlock(&ssh_init_mutex);
|
ssh_mutex_unlock(&ssh_init_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(_WIN32) && !defined(HAVE_PTHREAD))
|
||||||
|
if (ssh_init_mutex != NULL) {
|
||||||
|
DeleteCriticalSection(ssh_init_mutex);
|
||||||
|
SAFE_FREE(ssh_init_mutex);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
342
src/libcrypto.c
342
src/libcrypto.c
@@ -73,14 +73,20 @@
|
|||||||
|
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID
|
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
|
||||||
#include <openssl/kdf.h>
|
#include <openssl/kdf.h>
|
||||||
#endif
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
#include <openssl/param_build.h>
|
||||||
|
#include <openssl/core_names.h>
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
#endif /* HAVE_OPENSSL_EVP_KDF_CTX */
|
||||||
|
|
||||||
#include "libssh/crypto.h"
|
#include "libssh/crypto.h"
|
||||||
|
|
||||||
static int libcrypto_initialized = 0;
|
static int libcrypto_initialized = 0;
|
||||||
|
|
||||||
|
static ENGINE *engine = NULL;
|
||||||
|
|
||||||
void ssh_reseed(void){
|
void ssh_reseed(void){
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@@ -89,69 +95,34 @@ void ssh_reseed(void){
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
ENGINE *pki_get_engine(void)
|
||||||
* @brief Get random bytes
|
|
||||||
*
|
|
||||||
* Make sure to always check the return code of this function!
|
|
||||||
*
|
|
||||||
* @param[in] where The buffer to fill with random bytes
|
|
||||||
*
|
|
||||||
* @param[in] len The size of the buffer to fill.
|
|
||||||
*
|
|
||||||
* @param[in] strong Use a strong or private RNG source.
|
|
||||||
*
|
|
||||||
* @return 1 on success, 0 on error.
|
|
||||||
*/
|
|
||||||
int ssh_get_random(void *where, int len, int strong)
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_OPENSSL_RAND_PRIV_BYTES
|
int ok;
|
||||||
if (strong) {
|
|
||||||
/* Returns -1 when not supported, 0 on error, 1 on success */
|
if (engine == NULL) {
|
||||||
return !!RAND_priv_bytes(where, len);
|
ENGINE_load_builtin_engines();
|
||||||
}
|
|
||||||
#else
|
engine = ENGINE_by_id("pkcs11");
|
||||||
(void)strong;
|
if (engine == NULL) {
|
||||||
#endif /* HAVE_RAND_PRIV_BYTES */
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
|
"Could not load the engine: %s",
|
||||||
/* Returns -1 when not supported, 0 on error, 1 on success */
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
return !!RAND_bytes(where, len);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
SSH_LOG(SSH_LOG_INFO, "Engine loaded successfully");
|
||||||
SHACTX sha1_init(void)
|
|
||||||
{
|
ok = ENGINE_init(engine);
|
||||||
int rc;
|
if (!ok) {
|
||||||
SHACTX c = EVP_MD_CTX_new();
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
if (c == NULL) {
|
"Could not initialize the engine: %s",
|
||||||
return NULL;
|
ERR_error_string(ERR_get_error(), NULL));
|
||||||
}
|
ENGINE_free(engine);
|
||||||
rc = EVP_DigestInit_ex(c, EVP_sha1(), NULL);
|
return NULL;
|
||||||
if (rc == 0) {
|
}
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
c = NULL;
|
SSH_LOG(SSH_LOG_INFO, "Engine init success");
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1_update(SHACTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
EVP_DigestUpdate(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1_final(unsigned char *md, SHACTX c)
|
|
||||||
{
|
|
||||||
unsigned int mdlen = 0;
|
|
||||||
|
|
||||||
EVP_DigestFinal(c, md, &mdlen);
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
SHACTX c = sha1_init();
|
|
||||||
if (c != NULL) {
|
|
||||||
sha1_update(c, digest, len);
|
|
||||||
sha1_final(hash, c);
|
|
||||||
}
|
}
|
||||||
|
return engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
@@ -208,146 +179,8 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL_ECC */
|
#endif /* HAVE_OPENSSL_ECC */
|
||||||
|
|
||||||
SHA256CTX sha256_init(void)
|
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
|
||||||
{
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
int rc;
|
|
||||||
SHA256CTX c = EVP_MD_CTX_new();
|
|
||||||
if (c == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rc = EVP_DigestInit_ex(c, EVP_sha256(), NULL);
|
|
||||||
if (rc == 0) {
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
c = NULL;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha256_update(SHA256CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
EVP_DigestUpdate(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha256_final(unsigned char *md, SHA256CTX c)
|
|
||||||
{
|
|
||||||
unsigned int mdlen = 0;
|
|
||||||
|
|
||||||
EVP_DigestFinal(c, md, &mdlen);
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha256(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
SHA256CTX c = sha256_init();
|
|
||||||
if (c != NULL) {
|
|
||||||
sha256_update(c, digest, len);
|
|
||||||
sha256_final(hash, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SHA384CTX sha384_init(void)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
SHA384CTX c = EVP_MD_CTX_new();
|
|
||||||
if (c == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rc = EVP_DigestInit_ex(c, EVP_sha384(), NULL);
|
|
||||||
if (rc == 0) {
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
c = NULL;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha384_update(SHA384CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
EVP_DigestUpdate(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha384_final(unsigned char *md, SHA384CTX c)
|
|
||||||
{
|
|
||||||
unsigned int mdlen = 0;
|
|
||||||
|
|
||||||
EVP_DigestFinal(c, md, &mdlen);
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha384(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
SHA384CTX c = sha384_init();
|
|
||||||
if (c != NULL) {
|
|
||||||
sha384_update(c, digest, len);
|
|
||||||
sha384_final(hash, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SHA512CTX sha512_init(void)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
SHA512CTX c = EVP_MD_CTX_new();
|
|
||||||
if (c == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rc = EVP_DigestInit_ex(c, EVP_sha512(), NULL);
|
|
||||||
if (rc == 0) {
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
c = NULL;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512_update(SHA512CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
EVP_DigestUpdate(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512_final(unsigned char *md, SHA512CTX c)
|
|
||||||
{
|
|
||||||
unsigned int mdlen = 0;
|
|
||||||
|
|
||||||
EVP_DigestFinal(c, md, &mdlen);
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
SHA512CTX c = sha512_init();
|
|
||||||
if (c != NULL) {
|
|
||||||
sha512_update(c, digest, len);
|
|
||||||
sha512_final(hash, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MD5CTX md5_init(void)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
MD5CTX c = EVP_MD_CTX_new();
|
|
||||||
if (c == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
rc = EVP_DigestInit_ex(c, EVP_md5(), NULL);
|
|
||||||
if(rc == 0) {
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
c = NULL;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void md5_update(MD5CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
EVP_DigestUpdate(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void md5_final(unsigned char *md, MD5CTX c)
|
|
||||||
{
|
|
||||||
unsigned int mdlen = 0;
|
|
||||||
|
|
||||||
EVP_DigestFinal(c, md, &mdlen);
|
|
||||||
EVP_MD_CTX_free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID
|
|
||||||
static const EVP_MD *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type)
|
static const EVP_MD *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type)
|
||||||
{
|
{
|
||||||
switch (digest_type) {
|
switch (digest_type) {
|
||||||
@@ -362,19 +195,50 @@ static const EVP_MD *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
static const char *sshkdf_digest_to_md(enum ssh_kdf_digest digest_type)
|
||||||
|
{
|
||||||
|
switch (digest_type) {
|
||||||
|
case SSH_KDF_SHA1:
|
||||||
|
return SN_sha1;
|
||||||
|
case SSH_KDF_SHA256:
|
||||||
|
return SN_sha256;
|
||||||
|
case SSH_KDF_SHA384:
|
||||||
|
return SN_sha384;
|
||||||
|
case SSH_KDF_SHA512:
|
||||||
|
return SN_sha512;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||||
unsigned char *key, size_t key_len,
|
unsigned char *key, size_t key_len,
|
||||||
int key_type, unsigned char *output,
|
int key_type, unsigned char *output,
|
||||||
size_t requested_len)
|
size_t requested_len)
|
||||||
{
|
{
|
||||||
|
int rc = -1;
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
EVP_KDF_CTX *ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
|
EVP_KDF_CTX *ctx = EVP_KDF_CTX_new_id(EVP_KDF_SSHKDF);
|
||||||
int rc;
|
#else
|
||||||
|
EVP_KDF *kdf = EVP_KDF_fetch(NULL, "SSHKDF", NULL);
|
||||||
|
EVP_KDF_CTX *ctx = EVP_KDF_CTX_new(kdf);
|
||||||
|
OSSL_PARAM_BLD *param_bld = OSSL_PARAM_BLD_new();
|
||||||
|
OSSL_PARAM *params = NULL;
|
||||||
|
const char *md = sshkdf_digest_to_md(crypto->digest_type);
|
||||||
|
|
||||||
if (ctx == NULL) {
|
EVP_KDF_free(kdf);
|
||||||
|
if (param_bld == NULL) {
|
||||||
|
EVP_KDF_CTX_free(ctx);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
|
if (ctx == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD,
|
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD,
|
||||||
sshkdf_digest_to_md(crypto->digest_type));
|
sshkdf_digest_to_md(crypto->digest_type));
|
||||||
if (rc != 1) {
|
if (rc != 1) {
|
||||||
@@ -402,8 +266,60 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
|
|||||||
if (rc != 1) {
|
if (rc != 1) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_DIGEST,
|
||||||
|
md, strlen(md));
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rc = OSSL_PARAM_BLD_push_octet_string(param_bld, OSSL_KDF_PARAM_KEY,
|
||||||
|
key, key_len);
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rc = OSSL_PARAM_BLD_push_octet_string(param_bld,
|
||||||
|
OSSL_KDF_PARAM_SSHKDF_XCGHASH,
|
||||||
|
crypto->secret_hash,
|
||||||
|
crypto->digest_len);
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rc = OSSL_PARAM_BLD_push_octet_string(param_bld,
|
||||||
|
OSSL_KDF_PARAM_SSHKDF_SESSION_ID,
|
||||||
|
crypto->session_id,
|
||||||
|
crypto->session_id_len);
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rc = OSSL_PARAM_BLD_push_utf8_string(param_bld, OSSL_KDF_PARAM_SSHKDF_TYPE,
|
||||||
|
(const char*)&key_type, 1);
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
params = OSSL_PARAM_BLD_to_param(param_bld);
|
||||||
|
if (params == NULL) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = EVP_KDF_derive(ctx, output, requested_len, params);
|
||||||
|
if (rc != 1) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
|
OSSL_PARAM_BLD_free(param_bld);
|
||||||
|
OSSL_PARAM_free(params);
|
||||||
|
#endif
|
||||||
EVP_KDF_CTX_free(ctx);
|
EVP_KDF_CTX_free(ctx);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return rc;
|
return rc;
|
||||||
@@ -420,7 +336,8 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
|
|||||||
return sshkdf_derive_key(crypto, key, key_len,
|
return sshkdf_derive_key(crypto, key, key_len,
|
||||||
key_type, output, requested_len);
|
key_type, output, requested_len);
|
||||||
}
|
}
|
||||||
#endif /* HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID */
|
#endif /* HAVE_OPENSSL_EVP_KDF_CTX */
|
||||||
|
|
||||||
HMACCTX hmac_init(const void *key, size_t len, enum ssh_hmac_e type)
|
HMACCTX hmac_init(const void *key, size_t len, enum ssh_hmac_e type)
|
||||||
{
|
{
|
||||||
HMACCTX ctx = NULL;
|
HMACCTX ctx = NULL;
|
||||||
@@ -1508,8 +1425,19 @@ void ssh_crypto_finalize(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ENGINE_cleanup();
|
/* TODO this should finalize engine if it was started, but during atexit calls,
|
||||||
|
* we are crashing. AFAIK this is related to the dlopened pkcs11 modules calling
|
||||||
|
* the crypto cleanups earlier. */
|
||||||
|
#if 0
|
||||||
|
if (engine != NULL) {
|
||||||
|
ENGINE_finish(engine);
|
||||||
|
ENGINE_free(engine);
|
||||||
|
engine = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
ENGINE_cleanup();
|
||||||
EVP_cleanup();
|
EVP_cleanup();
|
||||||
CRYPTO_cleanup_all_ex_data();
|
CRYPTO_cleanup_all_ex_data();
|
||||||
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
|
#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
|
||||||
|
|||||||
112
src/libgcrypt.c
112
src/libgcrypt.c
@@ -69,38 +69,6 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
|
|||||||
void ssh_reseed(void){
|
void ssh_reseed(void){
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_get_random(void *where, int len, int strong)
|
|
||||||
{
|
|
||||||
/* variable not used in gcrypt */
|
|
||||||
(void) strong;
|
|
||||||
|
|
||||||
/* not using GCRY_VERY_STRONG_RANDOM which is a bit overkill */
|
|
||||||
gcry_randomize(where,len,GCRY_STRONG_RANDOM);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
SHACTX sha1_init(void) {
|
|
||||||
SHACTX ctx = NULL;
|
|
||||||
gcry_md_open(&ctx, GCRY_MD_SHA1, 0);
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1_update(SHACTX c, const void *data, size_t len) {
|
|
||||||
gcry_md_write(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1_final(unsigned char *md, SHACTX c) {
|
|
||||||
gcry_md_final(c);
|
|
||||||
memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN);
|
|
||||||
gcry_md_close(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1(const unsigned char *digest, size_t len, unsigned char *hash) {
|
|
||||||
gcry_md_hash_buffer(GCRY_MD_SHA1, hash, digest, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_GCRYPT_ECC
|
#ifdef HAVE_GCRYPT_ECC
|
||||||
static int nid_to_md_algo(int nid)
|
static int nid_to_md_algo(int nid)
|
||||||
{
|
{
|
||||||
@@ -154,86 +122,6 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
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, size_t 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(const unsigned char *digest, size_t 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, size_t 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(const unsigned char *digest, size_t 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, size_t 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(const unsigned char *digest, size_t 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);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void md5_update(MD5CTX c, const void *data, size_t len) {
|
|
||||||
gcry_md_write(c,data,len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void md5_final(unsigned char *md, MD5CTX c) {
|
|
||||||
gcry_md_final(c);
|
|
||||||
memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN);
|
|
||||||
gcry_md_close(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||||
unsigned char *key, size_t key_len,
|
unsigned char *key, size_t key_len,
|
||||||
int key_type, unsigned char *output,
|
int key_type, unsigned char *output,
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
#endif /* MBEDTLS_GCM_C */
|
#endif /* MBEDTLS_GCM_C */
|
||||||
|
|
||||||
static mbedtls_entropy_context ssh_mbedtls_entropy;
|
static mbedtls_entropy_context ssh_mbedtls_entropy;
|
||||||
static mbedtls_ctr_drbg_context ssh_mbedtls_ctr_drbg;
|
extern mbedtls_ctr_drbg_context ssh_mbedtls_ctr_drbg;
|
||||||
|
|
||||||
static int libmbedcrypto_initialized = 0;
|
static int libmbedcrypto_initialized = 0;
|
||||||
|
|
||||||
@@ -51,65 +51,6 @@ void ssh_reseed(void)
|
|||||||
mbedtls_ctr_drbg_reseed(&ssh_mbedtls_ctr_drbg, NULL, 0);
|
mbedtls_ctr_drbg_reseed(&ssh_mbedtls_ctr_drbg, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_get_random(void *where, int len, int strong)
|
|
||||||
{
|
|
||||||
return ssh_mbedtls_random(where, len, strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
SHACTX sha1_init(void)
|
|
||||||
{
|
|
||||||
SHACTX ctx = NULL;
|
|
||||||
int rc;
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
|
||||||
|
|
||||||
if (md_info == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = malloc(sizeof(mbedtls_md_context_t));
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_init(ctx);
|
|
||||||
|
|
||||||
rc = mbedtls_md_setup(ctx, md_info, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_md_starts(ctx);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1_update(SHACTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
mbedtls_md_update(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1_final(unsigned char *md, SHACTX c)
|
|
||||||
{
|
|
||||||
mbedtls_md_finish(c, md);
|
|
||||||
mbedtls_md_free(c);
|
|
||||||
SAFE_FREE(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha1(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
|
||||||
if (md_info != NULL) {
|
|
||||||
mbedtls_md(md_info, digest, len, hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static mbedtls_md_type_t nid_to_md_algo(int nid)
|
static mbedtls_md_type_t nid_to_md_algo(int nid)
|
||||||
{
|
{
|
||||||
switch (nid) {
|
switch (nid) {
|
||||||
@@ -184,211 +125,6 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
|||||||
SAFE_FREE(ctx);
|
SAFE_FREE(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
SHA256CTX sha256_init(void)
|
|
||||||
{
|
|
||||||
SHA256CTX ctx = NULL;
|
|
||||||
int rc;
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
|
||||||
|
|
||||||
if (md_info == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = malloc(sizeof(mbedtls_md_context_t));
|
|
||||||
if(ctx == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_init(ctx);
|
|
||||||
|
|
||||||
rc = mbedtls_md_setup(ctx, md_info, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_md_starts(ctx);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha256_update(SHA256CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
mbedtls_md_update(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha256_final(unsigned char *md, SHA256CTX c)
|
|
||||||
{
|
|
||||||
mbedtls_md_finish(c, md);
|
|
||||||
mbedtls_md_free(c);
|
|
||||||
SAFE_FREE(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha256(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
|
||||||
if (md_info != NULL) {
|
|
||||||
mbedtls_md(md_info, digest, len, hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SHA384CTX sha384_init(void)
|
|
||||||
{
|
|
||||||
SHA384CTX ctx = NULL;
|
|
||||||
int rc;
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
|
||||||
|
|
||||||
if (md_info == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = malloc(sizeof(mbedtls_md_context_t));
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_init(ctx);
|
|
||||||
|
|
||||||
rc = mbedtls_md_setup(ctx, md_info, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_md_starts(ctx);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha384_update(SHA384CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
mbedtls_md_update(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha384_final(unsigned char *md, SHA384CTX c)
|
|
||||||
{
|
|
||||||
mbedtls_md_finish(c, md);
|
|
||||||
mbedtls_md_free(c);
|
|
||||||
SAFE_FREE(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha384(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
|
||||||
if (md_info != NULL) {
|
|
||||||
mbedtls_md(md_info, digest, len, hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SHA512CTX sha512_init(void)
|
|
||||||
{
|
|
||||||
SHA512CTX ctx = NULL;
|
|
||||||
int rc;
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
|
||||||
if (md_info == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = malloc(sizeof(mbedtls_md_context_t));
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_init(ctx);
|
|
||||||
|
|
||||||
rc = mbedtls_md_setup(ctx, md_info, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_md_starts(ctx);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512_update(SHA512CTX c, const void *data, size_t len)
|
|
||||||
{
|
|
||||||
mbedtls_md_update(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512_final(unsigned char *md, SHA512CTX c)
|
|
||||||
{
|
|
||||||
mbedtls_md_finish(c, md);
|
|
||||||
mbedtls_md_free(c);
|
|
||||||
SAFE_FREE(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sha512(const unsigned char *digest, size_t len, unsigned char *hash)
|
|
||||||
{
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
|
||||||
if (md_info != NULL) {
|
|
||||||
mbedtls_md(md_info, digest, len, hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MD5CTX md5_init(void)
|
|
||||||
{
|
|
||||||
MD5CTX ctx = NULL;
|
|
||||||
int rc;
|
|
||||||
const mbedtls_md_info_t *md_info =
|
|
||||||
mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
|
||||||
if (md_info == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = malloc(sizeof(mbedtls_md_context_t));
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_md_init(ctx);
|
|
||||||
|
|
||||||
rc = mbedtls_md_setup(ctx, md_info, 0);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = mbedtls_md_starts(ctx);
|
|
||||||
if (rc != 0) {
|
|
||||||
SAFE_FREE(ctx);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void md5_update(MD5CTX c, const void *data, size_t len) {
|
|
||||||
mbedtls_md_update(c, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void md5_final(unsigned char *md, MD5CTX c)
|
|
||||||
{
|
|
||||||
mbedtls_md_finish(c, md);
|
|
||||||
mbedtls_md_free(c);
|
|
||||||
SAFE_FREE(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||||
unsigned char *key, size_t key_len,
|
unsigned char *key, size_t key_len,
|
||||||
int key_type, unsigned char *output,
|
int key_type, unsigned char *output,
|
||||||
@@ -1438,22 +1174,6 @@ int ssh_crypto_init(void)
|
|||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_mbedtls_random(void *where, int len, int strong)
|
|
||||||
{
|
|
||||||
int rc = 0;
|
|
||||||
if (strong) {
|
|
||||||
mbedtls_ctr_drbg_set_prediction_resistance(&ssh_mbedtls_ctr_drbg,
|
|
||||||
MBEDTLS_CTR_DRBG_PR_ON);
|
|
||||||
rc = mbedtls_ctr_drbg_random(&ssh_mbedtls_ctr_drbg, where, len);
|
|
||||||
mbedtls_ctr_drbg_set_prediction_resistance(&ssh_mbedtls_ctr_drbg,
|
|
||||||
MBEDTLS_CTR_DRBG_PR_OFF);
|
|
||||||
} else {
|
|
||||||
rc = mbedtls_ctr_drbg_random(&ssh_mbedtls_ctr_drbg, where, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
return !rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void)
|
mbedtls_ctr_drbg_context *ssh_get_mbedtls_ctr_drbg_context(void)
|
||||||
{
|
{
|
||||||
return &ssh_mbedtls_ctr_drbg;
|
return &ssh_mbedtls_ctr_drbg;
|
||||||
|
|||||||
225
src/md_crypto.c
Normal file
225
src/md_crypto.c
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 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 "config.h"
|
||||||
|
|
||||||
|
#include "libcrypto-compat.h"
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include "libssh/wrapper.h"
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/md5.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
|
||||||
|
SHACTX
|
||||||
|
sha1_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
SHACTX c = EVP_MD_CTX_new();
|
||||||
|
if (c == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rc = EVP_DigestInit_ex(c, EVP_sha1(), NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
c = NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_update(SHACTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
EVP_DigestUpdate(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_final(unsigned char *md, SHACTX c)
|
||||||
|
{
|
||||||
|
unsigned int mdlen = 0;
|
||||||
|
|
||||||
|
EVP_DigestFinal(c, md, &mdlen);
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
SHACTX c = sha1_init();
|
||||||
|
if (c != NULL) {
|
||||||
|
sha1_update(c, digest, len);
|
||||||
|
sha1_final(hash, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA256CTX
|
||||||
|
sha256_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
SHA256CTX c = EVP_MD_CTX_new();
|
||||||
|
if (c == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rc = EVP_DigestInit_ex(c, EVP_sha256(), NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
c = NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha256_update(SHA256CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
EVP_DigestUpdate(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha256_final(unsigned char *md, SHA256CTX c)
|
||||||
|
{
|
||||||
|
unsigned int mdlen = 0;
|
||||||
|
|
||||||
|
EVP_DigestFinal(c, md, &mdlen);
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha256(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
SHA256CTX c = sha256_init();
|
||||||
|
if (c != NULL) {
|
||||||
|
sha256_update(c, digest, len);
|
||||||
|
sha256_final(hash, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA384CTX
|
||||||
|
sha384_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
SHA384CTX c = EVP_MD_CTX_new();
|
||||||
|
if (c == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rc = EVP_DigestInit_ex(c, EVP_sha384(), NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
c = NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha384_update(SHA384CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
EVP_DigestUpdate(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha384_final(unsigned char *md, SHA384CTX c)
|
||||||
|
{
|
||||||
|
unsigned int mdlen = 0;
|
||||||
|
|
||||||
|
EVP_DigestFinal(c, md, &mdlen);
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha384(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
SHA384CTX c = sha384_init();
|
||||||
|
if (c != NULL) {
|
||||||
|
sha384_update(c, digest, len);
|
||||||
|
sha384_final(hash, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA512CTX
|
||||||
|
sha512_init(void)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
SHA512CTX c = EVP_MD_CTX_new();
|
||||||
|
if (c == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rc = EVP_DigestInit_ex(c, EVP_sha512(), NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
c = NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha512_update(SHA512CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
EVP_DigestUpdate(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha512_final(unsigned char *md, SHA512CTX c)
|
||||||
|
{
|
||||||
|
unsigned int mdlen = 0;
|
||||||
|
|
||||||
|
EVP_DigestFinal(c, md, &mdlen);
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha512(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
SHA512CTX c = sha512_init();
|
||||||
|
if (c != NULL) {
|
||||||
|
sha512_update(c, digest, len);
|
||||||
|
sha512_final(hash, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MD5CTX
|
||||||
|
md5_init(void)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
MD5CTX c = EVP_MD_CTX_new();
|
||||||
|
if (c == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
rc = EVP_DigestInit_ex(c, EVP_md5(), NULL);
|
||||||
|
if (rc == 0) {
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
c = NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_update(MD5CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
EVP_DigestUpdate(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_final(unsigned char *md, MD5CTX c)
|
||||||
|
{
|
||||||
|
unsigned int mdlen = 0;
|
||||||
|
|
||||||
|
EVP_DigestFinal(c, md, &mdlen);
|
||||||
|
EVP_MD_CTX_free(c);
|
||||||
|
}
|
||||||
167
src/md_gcrypt.c
Normal file
167
src/md_gcrypt.c
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2009 by Aris Adamantiadis
|
||||||
|
* Copyright (C) 2016 g10 Code GmbH
|
||||||
|
*
|
||||||
|
* 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 "config.h"
|
||||||
|
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include "libssh/wrapper.h"
|
||||||
|
|
||||||
|
#include <gcrypt.h>
|
||||||
|
|
||||||
|
SHACTX
|
||||||
|
sha1_init(void)
|
||||||
|
{
|
||||||
|
SHACTX ctx = NULL;
|
||||||
|
gcry_md_open(&ctx, GCRY_MD_SHA1, 0);
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_update(SHACTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
gcry_md_write(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_final(unsigned char *md, SHACTX c)
|
||||||
|
{
|
||||||
|
gcry_md_final(c);
|
||||||
|
memcpy(md, gcry_md_read(c, 0), SHA_DIGEST_LEN);
|
||||||
|
gcry_md_close(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1(const unsigned char *digest, size_t 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, size_t 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(const unsigned char *digest, size_t 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, size_t 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(const unsigned char *digest, size_t 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, size_t 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(const unsigned char *digest, size_t 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);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_update(MD5CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
gcry_md_write(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_final(unsigned char *md, MD5CTX c)
|
||||||
|
{
|
||||||
|
gcry_md_final(c);
|
||||||
|
memcpy(md, gcry_md_read(c, 0), MD5_DIGEST_LEN);
|
||||||
|
gcry_md_close(c);
|
||||||
|
}
|
||||||
308
src/md_mbedcrypto.c
Normal file
308
src/md_mbedcrypto.c
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the SSH Library
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017 Sartura d.o.o.
|
||||||
|
*
|
||||||
|
* Author: Juraj Vijtiuk <juraj.vijtiuk@sartura.hr>
|
||||||
|
*
|
||||||
|
* 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 "config.h"
|
||||||
|
|
||||||
|
#include "libssh/crypto.h"
|
||||||
|
#include "libssh/wrapper.h"
|
||||||
|
#include "mbedcrypto-compat.h"
|
||||||
|
|
||||||
|
#include <mbedtls/md.h>
|
||||||
|
|
||||||
|
SHACTX
|
||||||
|
sha1_init(void)
|
||||||
|
{
|
||||||
|
SHACTX ctx = NULL;
|
||||||
|
int rc;
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||||
|
|
||||||
|
if (md_info == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = malloc(sizeof(mbedtls_md_context_t));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(ctx);
|
||||||
|
|
||||||
|
rc = mbedtls_md_setup(ctx, md_info, 0);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_md_starts(ctx);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_update(SHACTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
mbedtls_md_update(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1_final(unsigned char *md, SHACTX c)
|
||||||
|
{
|
||||||
|
mbedtls_md_finish(c, md);
|
||||||
|
mbedtls_md_free(c);
|
||||||
|
SAFE_FREE(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha1(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||||
|
if (md_info != NULL) {
|
||||||
|
mbedtls_md(md_info, digest, len, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA256CTX
|
||||||
|
sha256_init(void)
|
||||||
|
{
|
||||||
|
SHA256CTX ctx = NULL;
|
||||||
|
int rc;
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
|
|
||||||
|
if (md_info == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = malloc(sizeof(mbedtls_md_context_t));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(ctx);
|
||||||
|
|
||||||
|
rc = mbedtls_md_setup(ctx, md_info, 0);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_md_starts(ctx);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha256_update(SHA256CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
mbedtls_md_update(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha256_final(unsigned char *md, SHA256CTX c)
|
||||||
|
{
|
||||||
|
mbedtls_md_finish(c, md);
|
||||||
|
mbedtls_md_free(c);
|
||||||
|
SAFE_FREE(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha256(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
|
if (md_info != NULL) {
|
||||||
|
mbedtls_md(md_info, digest, len, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA384CTX
|
||||||
|
sha384_init(void)
|
||||||
|
{
|
||||||
|
SHA384CTX ctx = NULL;
|
||||||
|
int rc;
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
||||||
|
|
||||||
|
if (md_info == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = malloc(sizeof(mbedtls_md_context_t));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(ctx);
|
||||||
|
|
||||||
|
rc = mbedtls_md_setup(ctx, md_info, 0);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_md_starts(ctx);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha384_update(SHA384CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
mbedtls_md_update(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha384_final(unsigned char *md, SHA384CTX c)
|
||||||
|
{
|
||||||
|
mbedtls_md_finish(c, md);
|
||||||
|
mbedtls_md_free(c);
|
||||||
|
SAFE_FREE(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha384(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA384);
|
||||||
|
if (md_info != NULL) {
|
||||||
|
mbedtls_md(md_info, digest, len, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHA512CTX
|
||||||
|
sha512_init(void)
|
||||||
|
{
|
||||||
|
SHA512CTX ctx = NULL;
|
||||||
|
int rc;
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
||||||
|
if (md_info == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = malloc(sizeof(mbedtls_md_context_t));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(ctx);
|
||||||
|
|
||||||
|
rc = mbedtls_md_setup(ctx, md_info, 0);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_md_starts(ctx);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha512_update(SHA512CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
mbedtls_md_update(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha512_final(unsigned char *md, SHA512CTX c)
|
||||||
|
{
|
||||||
|
mbedtls_md_finish(c, md);
|
||||||
|
mbedtls_md_free(c);
|
||||||
|
SAFE_FREE(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
sha512(const unsigned char *digest, size_t len, unsigned char *hash)
|
||||||
|
{
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
|
||||||
|
if (md_info != NULL) {
|
||||||
|
mbedtls_md(md_info, digest, len, hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MD5CTX
|
||||||
|
md5_init(void)
|
||||||
|
{
|
||||||
|
MD5CTX ctx = NULL;
|
||||||
|
int rc;
|
||||||
|
const mbedtls_md_info_t *md_info =
|
||||||
|
mbedtls_md_info_from_type(MBEDTLS_MD_MD5);
|
||||||
|
if (md_info == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = malloc(sizeof(mbedtls_md_context_t));
|
||||||
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_md_init(ctx);
|
||||||
|
|
||||||
|
rc = mbedtls_md_setup(ctx, md_info, 0);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = mbedtls_md_starts(ctx);
|
||||||
|
if (rc != 0) {
|
||||||
|
SAFE_FREE(ctx);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_update(MD5CTX c, const void *data, size_t len)
|
||||||
|
{
|
||||||
|
mbedtls_md_update(c, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
md5_final(unsigned char *md, MD5CTX c)
|
||||||
|
{
|
||||||
|
mbedtls_md_finish(c, md);
|
||||||
|
mbedtls_md_free(c);
|
||||||
|
SAFE_FREE(c);
|
||||||
|
}
|
||||||
15
src/misc.c
15
src/misc.c
@@ -160,7 +160,7 @@ int ssh_dir_writeable(const char *path)
|
|||||||
#define SSH_USEC_IN_SEC 1000000LL
|
#define SSH_USEC_IN_SEC 1000000LL
|
||||||
#define SSH_SECONDS_SINCE_1601 11644473600LL
|
#define SSH_SECONDS_SINCE_1601 11644473600LL
|
||||||
|
|
||||||
int gettimeofday(struct timeval *__p, void *__t)
|
int ssh_gettimeofday(struct timeval *__p, void *__t)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
unsigned long long ns100; /* time since 1 Jan 1601 in 100ns units */
|
unsigned long long ns100; /* time since 1 Jan 1601 in 100ns units */
|
||||||
@@ -1237,14 +1237,13 @@ char *ssh_path_expand_escape(ssh_session session, const char *s)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (session->opts.port < 65536) {
|
if (session->opts.port > 0) {
|
||||||
char tmp[6];
|
char tmp[6];
|
||||||
|
|
||||||
snprintf(tmp,
|
snprintf(tmp, sizeof(tmp), "%hu",
|
||||||
sizeof(tmp),
|
(uint16_t)(session->opts.port > 0 ? session->opts.port
|
||||||
"%u",
|
: 22));
|
||||||
session->opts.port > 0 ? session->opts.port : 22);
|
x = strdup(tmp);
|
||||||
x = strdup(tmp);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -513,7 +513,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
ssh_set_error_oom(session);
|
ssh_set_error_oom(session);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
p = strchr(q, '@');
|
p = strrchr(q, '@');
|
||||||
|
|
||||||
SAFE_FREE(session->opts.host);
|
SAFE_FREE(session->opts.host);
|
||||||
|
|
||||||
|
|||||||
@@ -260,42 +260,71 @@ int ssh_packet_hmac_verify(ssh_session session,
|
|||||||
uint8_t *mac,
|
uint8_t *mac,
|
||||||
enum ssh_hmac_e type)
|
enum ssh_hmac_e type)
|
||||||
{
|
{
|
||||||
struct ssh_crypto_struct *crypto = NULL;
|
struct ssh_crypto_struct *crypto = NULL;
|
||||||
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
||||||
HMACCTX ctx;
|
HMACCTX ctx;
|
||||||
size_t hmaclen = DIGEST_MAX_LEN;
|
size_t hmaclen = DIGEST_MAX_LEN;
|
||||||
uint32_t seq;
|
uint32_t seq;
|
||||||
|
int cmp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* AEAD types have no mac checking */
|
/* AEAD types have no mac checking */
|
||||||
if (type == SSH_HMAC_AEAD_POLY1305 ||
|
if (type == SSH_HMAC_AEAD_POLY1305 ||
|
||||||
type == SSH_HMAC_AEAD_GCM) {
|
type == SSH_HMAC_AEAD_GCM) {
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
crypto = ssh_packet_get_current_crypto(session,
|
||||||
if (crypto == NULL) {
|
SSH_DIRECTION_IN);
|
||||||
return SSH_ERROR;
|
if (crypto == NULL) {
|
||||||
}
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
ctx = hmac_init(crypto->decryptMAC, hmac_digest_len(type), type);
|
ctx = hmac_init(crypto->decryptMAC,
|
||||||
if (ctx == NULL) {
|
hmac_digest_len(type),
|
||||||
return -1;
|
type);
|
||||||
}
|
if (ctx == NULL) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
seq = htonl(session->recv_seq);
|
seq = htonl(session->recv_seq);
|
||||||
|
|
||||||
hmac_update(ctx, (unsigned char *) &seq, sizeof(uint32_t));
|
rc = hmac_update(ctx,
|
||||||
hmac_update(ctx, data, len);
|
(unsigned char *) &seq,
|
||||||
hmac_final(ctx, hmacbuf, &hmaclen);
|
sizeof(uint32_t));
|
||||||
|
if (rc != 1) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
rc = hmac_update(ctx,
|
||||||
|
data,
|
||||||
|
len);
|
||||||
|
if (rc != 1) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
rc = hmac_final(ctx,
|
||||||
|
hmacbuf,
|
||||||
|
&hmaclen);
|
||||||
|
if (rc != 1) {
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_CRYPTO
|
#ifdef DEBUG_CRYPTO
|
||||||
ssh_log_hexdump("received mac",mac,hmaclen);
|
ssh_log_hexdump("received mac",
|
||||||
ssh_log_hexdump("Computed mac",hmacbuf,hmaclen);
|
mac,
|
||||||
ssh_log_hexdump("seq",(unsigned char *)&seq,sizeof(uint32_t));
|
hmaclen);
|
||||||
|
ssh_log_hexdump("Computed mac",
|
||||||
|
hmacbuf,
|
||||||
|
hmaclen);
|
||||||
|
ssh_log_hexdump("seq",
|
||||||
|
(unsigned char *)&seq,
|
||||||
|
sizeof(uint32_t));
|
||||||
#endif
|
#endif
|
||||||
if (secure_memcmp(mac, hmacbuf, hmaclen) == 0) {
|
cmp = secure_memcmp(mac,
|
||||||
return 0;
|
hmacbuf,
|
||||||
}
|
hmaclen);
|
||||||
|
if (cmp == 0) {
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
58
src/pki.c
58
src/pki.c
@@ -77,10 +77,12 @@ enum ssh_keytypes_e pki_privatekey_type_from_string(const char *privkey)
|
|||||||
{
|
{
|
||||||
char *start = NULL;
|
char *start = NULL;
|
||||||
|
|
||||||
|
#ifdef HAVE_DSA
|
||||||
start = strstr(privkey, DSA_HEADER_BEGIN);
|
start = strstr(privkey, DSA_HEADER_BEGIN);
|
||||||
if (start != NULL) {
|
if (start != NULL) {
|
||||||
return SSH_KEYTYPE_DSS;
|
return SSH_KEYTYPE_DSS;
|
||||||
}
|
}
|
||||||
|
#endif /* HAVE_DSA */
|
||||||
|
|
||||||
start = strstr(privkey, RSA_HEADER_BEGIN);
|
start = strstr(privkey, RSA_HEADER_BEGIN);
|
||||||
if (start != NULL) {
|
if (start != NULL) {
|
||||||
@@ -152,37 +154,9 @@ void ssh_key_clean (ssh_key key)
|
|||||||
{
|
{
|
||||||
if (key == NULL)
|
if (key == NULL)
|
||||||
return;
|
return;
|
||||||
#ifdef HAVE_LIBGCRYPT
|
|
||||||
if(key->dsa) gcry_sexp_release(key->dsa);
|
|
||||||
if(key->rsa) gcry_sexp_release(key->rsa);
|
|
||||||
if(key->ecdsa) gcry_sexp_release(key->ecdsa);
|
|
||||||
#elif defined HAVE_LIBCRYPTO
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
if(key->dsa) DSA_free(key->dsa);
|
|
||||||
if(key->rsa) RSA_free(key->rsa);
|
|
||||||
#else
|
|
||||||
if(key->key) EVP_PKEY_free(key->key);
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
|
||||||
* Move whole HAVE_OPENSSL_EC into #if < 0x3 above
|
|
||||||
*/
|
|
||||||
#if 1
|
|
||||||
if(key->ecdsa) EC_KEY_free(key->ecdsa);
|
|
||||||
#endif
|
|
||||||
#endif /* HAVE_OPENSSL_ECC */
|
|
||||||
#elif defined HAVE_LIBMBEDCRYPTO
|
|
||||||
if (key->rsa != NULL) {
|
|
||||||
mbedtls_pk_free(key->rsa);
|
|
||||||
SAFE_FREE(key->rsa);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key->ecdsa != NULL) {
|
pki_key_clean(key);
|
||||||
mbedtls_ecdsa_free(key->ecdsa);
|
|
||||||
SAFE_FREE(key->ecdsa);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (key->ed25519_privkey != NULL){
|
if (key->ed25519_privkey != NULL){
|
||||||
#ifdef HAVE_OPENSSL_ED25519
|
#ifdef HAVE_OPENSSL_ED25519
|
||||||
/* In OpenSSL implementation the private key is only the private
|
/* In OpenSSL implementation the private key is only the private
|
||||||
@@ -206,21 +180,10 @@ void ssh_key_clean (ssh_key key)
|
|||||||
ssh_string_free(key->sk_application);
|
ssh_string_free(key->sk_application);
|
||||||
}
|
}
|
||||||
key->cert_type = SSH_KEYTYPE_UNKNOWN;
|
key->cert_type = SSH_KEYTYPE_UNKNOWN;
|
||||||
key->flags=SSH_KEY_FLAG_EMPTY;
|
key->flags = SSH_KEY_FLAG_EMPTY;
|
||||||
key->type=SSH_KEYTYPE_UNKNOWN;
|
key->type = SSH_KEYTYPE_UNKNOWN;
|
||||||
key->ecdsa_nid = 0;
|
key->ecdsa_nid = 0;
|
||||||
key->type_c=NULL;
|
key->type_c = NULL;
|
||||||
#if !defined(HAVE_LIBCRYPTO) || OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
key->dsa = NULL;
|
|
||||||
key->rsa = NULL;
|
|
||||||
#else
|
|
||||||
key->key = NULL;
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
|
||||||
* Move into #if OPENSSL_VERSION_NUMBER < 0x3 above
|
|
||||||
*/
|
|
||||||
key->ecdsa = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1124,7 +1087,7 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
|
|||||||
ssh_public_key pub;
|
ssh_public_key pub;
|
||||||
ssh_key tmp;
|
ssh_key tmp;
|
||||||
|
|
||||||
if(key == NULL) {
|
if (key == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1133,12 +1096,11 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub = malloc(sizeof(struct ssh_public_key_struct));
|
pub = calloc(1, sizeof(struct ssh_public_key_struct));
|
||||||
if (pub == NULL) {
|
if (pub == NULL) {
|
||||||
ssh_key_free(tmp);
|
ssh_key_free(tmp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ZERO_STRUCTP(pub);
|
|
||||||
|
|
||||||
pub->type = tmp->type;
|
pub->type = tmp->type;
|
||||||
pub->type_c = tmp->type_c;
|
pub->type_c = tmp->type_c;
|
||||||
@@ -1162,7 +1124,7 @@ ssh_private_key ssh_pki_convert_key_to_privatekey(const ssh_key key)
|
|||||||
{
|
{
|
||||||
ssh_private_key privkey;
|
ssh_private_key privkey;
|
||||||
|
|
||||||
privkey = malloc(sizeof(struct ssh_private_key_struct));
|
privkey = calloc(1, sizeof(struct ssh_private_key_struct));
|
||||||
if (privkey == NULL) {
|
if (privkey == NULL) {
|
||||||
ssh_key_free(key);
|
ssh_key_free(key);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
176
src/pki_crypto.c
176
src/pki_crypto.c
@@ -87,6 +87,30 @@ static int pem_get_password(char *buf, int size, int rwflag, void *userdata) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pki_key_clean(ssh_key key)
|
||||||
|
{
|
||||||
|
if (key == NULL)
|
||||||
|
return;
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
|
DSA_free(key->dsa);
|
||||||
|
key->dsa = NULL;
|
||||||
|
RSA_free(key->rsa);
|
||||||
|
key->rsa = NULL;
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
|
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||||||
|
* https://github.com/openssl/openssl/pull/16624
|
||||||
|
* Move whole HAVE_OPENSSL_ECC into #if < 0x3 above
|
||||||
|
*/
|
||||||
|
#if 1
|
||||||
|
EC_KEY_free(key->ecdsa);
|
||||||
|
key->ecdsa = NULL;
|
||||||
|
#endif
|
||||||
|
#endif /* HAVE_OPENSSL_ECC */
|
||||||
|
EVP_PKEY_free(key->key);
|
||||||
|
key->key = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
* https://github.com/openssl/openssl/pull/16624
|
||||||
@@ -426,7 +450,7 @@ err:
|
|||||||
|
|
||||||
ssh_key pki_key_dup(const ssh_key key, int demote)
|
ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||||
{
|
{
|
||||||
ssh_key new;
|
ssh_key new = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
new = ssh_key_new();
|
new = ssh_key_new();
|
||||||
@@ -434,12 +458,6 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_PKCS11_URI
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
new->key = key->key;
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
#endif /* WITH_PKCS11_URI */
|
|
||||||
|
|
||||||
new->type = key->type;
|
new->type = key->type;
|
||||||
new->type_c = key->type_c;
|
new->type_c = key->type_c;
|
||||||
if (demote) {
|
if (demote) {
|
||||||
@@ -523,6 +541,19 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
const BIGNUM *n = NULL, *e = NULL, *d = NULL;
|
const BIGNUM *n = NULL, *e = NULL, *d = NULL;
|
||||||
BIGNUM *nn, *ne, *nd;
|
BIGNUM *nn, *ne, *nd;
|
||||||
|
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */
|
||||||
|
#ifdef WITH_PKCS11_URI
|
||||||
|
/* Take the PKCS#11 keys as they are */
|
||||||
|
if (key->flags & SSH_KEY_FLAG_PKCS11_URI && !demote) {
|
||||||
|
rc = EVP_PKEY_up_ref(key->key);
|
||||||
|
if (rc != 1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
new->key = key->key;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
#endif /* WITH_PKCS11_URI */
|
||||||
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
new->rsa = RSA_new();
|
new->rsa = RSA_new();
|
||||||
if (new->rsa == NULL) {
|
if (new->rsa == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
@@ -607,7 +638,7 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
|
|
||||||
/* Memory management of ndmp1, ndmq1 and niqmp is transferred
|
/* Memory management of ndmp1, ndmq1 and niqmp is transferred
|
||||||
* to RSA object */
|
* to RSA object */
|
||||||
rc = RSA_set0_crt_params(new->rsa, ndmp1, ndmq1, niqmp);
|
rc = RSA_set0_crt_params(new->rsa, ndmp1, ndmq1, niqmp);
|
||||||
if (rc == 0) {
|
if (rc == 0) {
|
||||||
BN_free(ndmp1);
|
BN_free(ndmp1);
|
||||||
BN_free(ndmq1);
|
BN_free(ndmq1);
|
||||||
@@ -629,6 +660,22 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
case SSH_KEYTYPE_ECDSA_P521:
|
case SSH_KEYTYPE_ECDSA_P521:
|
||||||
#ifdef HAVE_OPENSSL_ECC
|
#ifdef HAVE_OPENSSL_ECC
|
||||||
new->ecdsa_nid = key->ecdsa_nid;
|
new->ecdsa_nid = key->ecdsa_nid;
|
||||||
|
#ifdef WITH_PKCS11_URI
|
||||||
|
/* Take the PKCS#11 keys as they are */
|
||||||
|
if (key->flags & SSH_KEY_FLAG_PKCS11_URI && !demote) {
|
||||||
|
rc = EVP_PKEY_up_ref(key->key);
|
||||||
|
if (rc != 1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
new->key = key->key;
|
||||||
|
rc = EC_KEY_up_ref(key->ecdsa);
|
||||||
|
if (rc != 1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
new->ecdsa = key->ecdsa;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
#endif /* WITH_PKCS11_URI */
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
* https://github.com/openssl/openssl/pull/16624
|
||||||
* #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
* #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
@@ -654,7 +701,11 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
new->ecdsa = EC_KEY_dup(key->ecdsa);
|
rc = EC_KEY_up_ref(key->ecdsa);
|
||||||
|
if (rc != 1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
new->ecdsa = key->ecdsa;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
rc = evp_dup_ecdsa_pkey(key, new, demote);
|
rc = evp_dup_ecdsa_pkey(key, new, demote);
|
||||||
@@ -1092,10 +1143,11 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
|||||||
* Delete this part, because it is done below HAVE_ECC
|
* Delete this part, because it is done below HAVE_ECC
|
||||||
*/
|
*/
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
pkey = key->key;
|
rc = EVP_PKEY_up_ref(key->key);
|
||||||
if (pkey == NULL) {
|
if (rc != 1) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
pkey = key->key;
|
||||||
|
|
||||||
/* Mark the operation as successful as for the other key types */
|
/* Mark the operation as successful as for the other key types */
|
||||||
rc = 1;
|
rc = 1;
|
||||||
@@ -1125,10 +1177,11 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
|||||||
* #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
* #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
pkey = key->key;
|
rc = EVP_PKEY_up_ref(key->key);
|
||||||
if (pkey == NULL) {
|
if (rc != 1) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
pkey = key->key;
|
||||||
|
|
||||||
/* Mark the operation as successful as for the other key types */
|
/* Mark the operation as successful as for the other key types */
|
||||||
rc = 1;
|
rc = 1;
|
||||||
@@ -1192,9 +1245,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
|||||||
NULL, /* auth_fn */
|
NULL, /* auth_fn */
|
||||||
(void*) passphrase);
|
(void*) passphrase);
|
||||||
}
|
}
|
||||||
if (pkey != key->key) {
|
EVP_PKEY_free(pkey);
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
}
|
|
||||||
pkey = NULL;
|
pkey = NULL;
|
||||||
|
|
||||||
if (rc != 1) {
|
if (rc != 1) {
|
||||||
@@ -1332,10 +1383,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
|||||||
* https://github.com/openssl/openssl/pull/16624
|
* https://github.com/openssl/openssl/pull/16624
|
||||||
* Remove these three lines
|
* Remove these three lines
|
||||||
*/
|
*/
|
||||||
/* the EVP_PKEY is not saved to the ssh_key struct */
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
pkey = NULL;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_OPENSSL_ECC */
|
#endif /* HAVE_OPENSSL_ECC */
|
||||||
#ifdef HAVE_OPENSSL_ED25519
|
#ifdef HAVE_OPENSSL_ED25519
|
||||||
@@ -1373,11 +1420,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
|||||||
}
|
}
|
||||||
type = SSH_KEYTYPE_ED25519;
|
type = SSH_KEYTYPE_ED25519;
|
||||||
|
|
||||||
/* the EVP_PKEY is not saved to the ssh_key struct */
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
pkey = NULL;
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_OPENSSL_ED25519 */
|
#endif /* HAVE_OPENSSL_ED25519 */
|
||||||
@@ -1387,10 +1429,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
|||||||
EVP_PKEY_free(pkey);
|
EVP_PKEY_free(pkey);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* at later version the pkey is saved to ssh_key struct */
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
|
|
||||||
key = ssh_key_new();
|
key = ssh_key_new();
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
@@ -1403,9 +1441,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
|||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
key->dsa = dsa;
|
key->dsa = dsa;
|
||||||
key->rsa = rsa;
|
key->rsa = rsa;
|
||||||
#else
|
|
||||||
key->key = pkey;
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
|
key->key = pkey;
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
* https://github.com/openssl/openssl/pull/16624
|
||||||
* Move key->ecdsa line into the #if above this
|
* Move key->ecdsa line into the #if above this
|
||||||
@@ -2805,15 +2842,11 @@ static const EVP_MD *pki_digest_to_md(enum ssh_digest_e hash_type)
|
|||||||
static EVP_PKEY *pki_key_to_pkey(ssh_key key)
|
static EVP_PKEY *pki_key_to_pkey(ssh_key key)
|
||||||
{
|
{
|
||||||
EVP_PKEY *pkey = NULL;
|
EVP_PKEY *pkey = NULL;
|
||||||
|
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
#ifdef WITH_PKCS11_URI
|
int rc = 0;
|
||||||
if (key->flags & SSH_KEY_FLAG_PKCS11_URI) {
|
|
||||||
pkey = key->key;
|
|
||||||
return pkey;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch(key->type) {
|
switch (key->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
case SSH_KEYTYPE_DSS_CERT01:
|
case SSH_KEYTYPE_DSS_CERT01:
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
@@ -2855,11 +2888,12 @@ static EVP_PKEY *pki_key_to_pkey(ssh_key key)
|
|||||||
SSH_LOG(SSH_LOG_TRACE, "NULL key->key");
|
SSH_LOG(SSH_LOG_TRACE, "NULL key->key");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
pkey = EVP_PKEY_dup(key->key);
|
rc = EVP_PKEY_up_ref(key->key);
|
||||||
if (pkey == NULL) {
|
if (rc != 1) {
|
||||||
SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
SSH_LOG(SSH_LOG_TRACE, "Failed to reference EVP_PKEY");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
pkey = key->key;
|
||||||
break;
|
break;
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
case SSH_KEYTYPE_ECDSA_P256:
|
case SSH_KEYTYPE_ECDSA_P256:
|
||||||
@@ -2899,11 +2933,12 @@ static EVP_PKEY *pki_key_to_pkey(ssh_key key)
|
|||||||
SSH_LOG(SSH_LOG_TRACE, "NULL key->key");
|
SSH_LOG(SSH_LOG_TRACE, "NULL key->key");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
pkey = EVP_PKEY_dup(key->key);
|
rc = EVP_PKEY_uo_ref(key->key);
|
||||||
if (pkey == NULL) {
|
if (rc != 1) {
|
||||||
SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
SSH_LOG(SSH_LOG_TRACE, "Failed to reference EVP_PKEY");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
pkey = key->key;
|
||||||
break;
|
break;
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
#endif /* OPENSSL_VERSION_NUMBER */
|
||||||
case SSH_KEYTYPE_ED25519:
|
case SSH_KEYTYPE_ED25519:
|
||||||
@@ -3102,9 +3137,7 @@ out:
|
|||||||
explicit_bzero(raw_sig_data, raw_sig_len);
|
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||||
}
|
}
|
||||||
SAFE_FREE(raw_sig_data);
|
SAFE_FREE(raw_sig_data);
|
||||||
if (pkey != NULL && !(privkey->flags & SSH_KEY_FLAG_PKCS11_URI)) {
|
EVP_PKEY_free(pkey);
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
}
|
|
||||||
return sig;
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3230,16 +3263,14 @@ out:
|
|||||||
if (ctx != NULL) {
|
if (ctx != NULL) {
|
||||||
EVP_MD_CTX_free(ctx);
|
EVP_MD_CTX_free(ctx);
|
||||||
}
|
}
|
||||||
if (pkey != NULL && !(pubkey->flags & SSH_KEY_FLAG_PKCS11_URI)) {
|
EVP_PKEY_free(pkey);
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
}
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ssh_key_size(ssh_key key)
|
int ssh_key_size(ssh_key key)
|
||||||
{
|
{
|
||||||
int bits = 0;
|
int bits = 0;
|
||||||
EVP_PKEY *pkey;
|
EVP_PKEY *pkey = NULL;
|
||||||
|
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case SSH_KEYTYPE_DSS:
|
case SSH_KEYTYPE_DSS:
|
||||||
@@ -3260,17 +3291,7 @@ int ssh_key_size(ssh_key key)
|
|||||||
return SSH_ERROR;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
bits = EVP_PKEY_bits(pkey);
|
bits = EVP_PKEY_bits(pkey);
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
||||||
EVP_PKEY_free(pkey);
|
EVP_PKEY_free(pkey);
|
||||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
|
||||||
* https://github.com/openssl/openssl/pull/16624
|
|
||||||
* no need of this free
|
|
||||||
*/
|
|
||||||
#else
|
|
||||||
if (is_ecdsa_key_type(key->type)) {
|
|
||||||
EVP_PKEY_free(pkey);
|
|
||||||
}
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER */
|
|
||||||
return bits;
|
return bits;
|
||||||
case SSH_KEYTYPE_ED25519:
|
case SSH_KEYTYPE_ED25519:
|
||||||
case SSH_KEYTYPE_ED25519_CERT01:
|
case SSH_KEYTYPE_ED25519_CERT01:
|
||||||
@@ -3437,29 +3458,13 @@ int pki_uri_import(const char *uri_name,
|
|||||||
#endif
|
#endif
|
||||||
ssh_key key = NULL;
|
ssh_key key = NULL;
|
||||||
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
|
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
|
||||||
int ok;
|
|
||||||
|
|
||||||
ENGINE_load_builtin_engines();
|
/* Do the init only once */
|
||||||
|
engine = pki_get_engine();
|
||||||
engine = ENGINE_by_id("pkcs11");
|
|
||||||
if (engine == NULL) {
|
if (engine == NULL) {
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
SSH_LOG(SSH_LOG_WARN, "Failed to initialize engine");
|
||||||
"Could not load the engine: %s",
|
goto fail;
|
||||||
ERR_error_string(ERR_get_error(),NULL));
|
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
}
|
||||||
SSH_LOG(SSH_LOG_INFO, "Engine loaded successfully");
|
|
||||||
|
|
||||||
ok = ENGINE_init(engine);
|
|
||||||
if (!ok) {
|
|
||||||
SSH_LOG(SSH_LOG_WARN,
|
|
||||||
"Could not initialize the engine: %s",
|
|
||||||
ERR_error_string(ERR_get_error(),NULL));
|
|
||||||
ENGINE_free(engine);
|
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSH_LOG(SSH_LOG_INFO, "Engine init success");
|
|
||||||
|
|
||||||
switch (key_type) {
|
switch (key_type) {
|
||||||
case SSH_KEY_PRIVATE:
|
case SSH_KEY_PRIVATE:
|
||||||
@@ -3541,10 +3546,9 @@ int pki_uri_import(const char *uri_name,
|
|||||||
key->key = pkey;
|
key->key = pkey;
|
||||||
key->type = type;
|
key->type = type;
|
||||||
key->type_c = ssh_key_type_to_char(type);
|
key->type_c = ssh_key_type_to_char(type);
|
||||||
|
key->flags = SSH_KEY_FLAG_PUBLIC | SSH_KEY_FLAG_PKCS11_URI;
|
||||||
if (key_type == SSH_KEY_PRIVATE) {
|
if (key_type == SSH_KEY_PRIVATE) {
|
||||||
key->flags = SSH_KEY_FLAG_PUBLIC | SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PKCS11_URI;
|
key->flags |= SSH_KEY_FLAG_PRIVATE;
|
||||||
} else {
|
|
||||||
key->flags = SSH_KEY_FLAG_PUBLIC | SSH_KEY_FLAG_PKCS11_URI;
|
|
||||||
}
|
}
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
key->rsa = rsa;
|
key->rsa = rsa;
|
||||||
@@ -3569,14 +3573,10 @@ int pki_uri_import(const char *uri_name,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
*nkey = key;
|
*nkey = key;
|
||||||
ENGINE_finish(engine);
|
|
||||||
ENGINE_free(engine);
|
|
||||||
|
|
||||||
return SSH_OK;
|
return SSH_OK;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
ENGINE_finish(engine);
|
|
||||||
ENGINE_free(engine);
|
|
||||||
EVP_PKEY_free(pkey);
|
EVP_PKEY_free(pkey);
|
||||||
ssh_key_free(key);
|
ssh_key_free(key);
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||||
|
|||||||
@@ -283,6 +283,23 @@ static int passphrase_to_key(char *data, unsigned int datalen,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pki_key_clean(ssh_key key)
|
||||||
|
{
|
||||||
|
if (key == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (key->dsa)
|
||||||
|
gcry_sexp_release(key->dsa);
|
||||||
|
if (key->rsa)
|
||||||
|
gcry_sexp_release(key->rsa);
|
||||||
|
if (key->ecdsa)
|
||||||
|
gcry_sexp_release(key->ecdsa);
|
||||||
|
|
||||||
|
key->dsa = NULL;
|
||||||
|
key->rsa = NULL;
|
||||||
|
key->ecdsa = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int privatekey_decrypt(int algo, int mode, unsigned int key_len,
|
static int privatekey_decrypt(int algo, int mode, unsigned int key_len,
|
||||||
unsigned char *iv, unsigned int iv_len,
|
unsigned char *iv, unsigned int iv_len,
|
||||||
ssh_buffer data, ssh_auth_callback cb,
|
ssh_buffer data, ssh_auth_callback cb,
|
||||||
|
|||||||
@@ -38,6 +38,22 @@
|
|||||||
#define MAX_PASSPHRASE_SIZE 1024
|
#define MAX_PASSPHRASE_SIZE 1024
|
||||||
#define MAX_KEY_SIZE 32
|
#define MAX_KEY_SIZE 32
|
||||||
|
|
||||||
|
void pki_key_clean(ssh_key key)
|
||||||
|
{
|
||||||
|
if (key == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (key->rsa != NULL) {
|
||||||
|
mbedtls_pk_free(key->rsa);
|
||||||
|
SAFE_FREE(key->rsa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key->ecdsa != NULL) {
|
||||||
|
mbedtls_ecdsa_free(key->ecdsa);
|
||||||
|
SAFE_FREE(key->ecdsa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ssh_string pki_private_key_to_pem(const ssh_key key, const char *passphrase,
|
ssh_string pki_private_key_to_pem(const ssh_key key, const char *passphrase,
|
||||||
ssh_auth_callback auth_fn, void *auth_data)
|
ssh_auth_callback auth_fn, void *auth_data)
|
||||||
{
|
{
|
||||||
@@ -85,10 +101,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
ssh_auth_callback auth_fn, void *auth_data)
|
ssh_auth_callback auth_fn, void *auth_data)
|
||||||
{
|
{
|
||||||
ssh_key key = NULL;
|
ssh_key key = NULL;
|
||||||
mbedtls_pk_context *rsa = NULL;
|
mbedtls_pk_context *pk = NULL;
|
||||||
mbedtls_pk_context *ecdsa = NULL;
|
mbedtls_pk_type_t mbed_type;
|
||||||
ed25519_privkey *ed25519 = NULL;
|
|
||||||
enum ssh_keytypes_e type;
|
|
||||||
int valid;
|
int valid;
|
||||||
/* mbedtls pk_parse_key expects strlen to count the 0 byte */
|
/* mbedtls pk_parse_key expects strlen to count the 0 byte */
|
||||||
size_t b64len = strlen(b64_key) + 1;
|
size_t b64len = strlen(b64_key) + 1;
|
||||||
@@ -97,159 +111,100 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
mbedtls_ctr_drbg_context *ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
mbedtls_ctr_drbg_context *ctr_drbg = ssh_get_mbedtls_ctr_drbg_context();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
type = pki_privatekey_type_from_string(b64_key);
|
pk = malloc(sizeof(mbedtls_pk_context));
|
||||||
if (type == SSH_KEYTYPE_UNKNOWN) {
|
if (pk == NULL) {
|
||||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
|
goto fail;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
mbedtls_pk_init(pk);
|
||||||
|
|
||||||
switch (type) {
|
if (passphrase == NULL) {
|
||||||
case SSH_KEYTYPE_RSA:
|
if (auth_fn) {
|
||||||
rsa = malloc(sizeof(mbedtls_pk_context));
|
valid = auth_fn("Passphrase for private key:",
|
||||||
if (rsa == NULL) {
|
(char *)tmp,
|
||||||
return NULL;
|
MAX_PASSPHRASE_SIZE,
|
||||||
}
|
0,
|
||||||
|
0,
|
||||||
mbedtls_pk_init(rsa);
|
auth_data);
|
||||||
|
if (valid < 0) {
|
||||||
if (passphrase == NULL) {
|
|
||||||
if (auth_fn) {
|
|
||||||
valid = auth_fn("Passphrase for private key:", (char *) tmp,
|
|
||||||
MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
|
|
||||||
if (valid < 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
/* TODO fix signedness and strlen */
|
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
|
||||||
(const unsigned char *) b64_key,
|
|
||||||
b64len, tmp,
|
|
||||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE),
|
|
||||||
mbedtls_ctr_drbg_random, ctr_drbg);
|
|
||||||
#else
|
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
|
||||||
(const unsigned char *) b64_key,
|
|
||||||
b64len, tmp,
|
|
||||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
|
||||||
(const unsigned char *) b64_key,
|
|
||||||
b64len, NULL,
|
|
||||||
0, mbedtls_ctr_drbg_random, ctr_drbg);
|
|
||||||
#else
|
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
|
||||||
(const unsigned char *) b64_key,
|
|
||||||
b64len, NULL,
|
|
||||||
0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
|
||||||
(const unsigned char *) b64_key, b64len,
|
|
||||||
(const unsigned char *) passphrase,
|
|
||||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE),
|
|
||||||
mbedtls_ctr_drbg_random, ctr_drbg);
|
|
||||||
#else
|
|
||||||
valid = mbedtls_pk_parse_key(rsa,
|
|
||||||
(const unsigned char *) b64_key, b64len,
|
|
||||||
(const unsigned char *) passphrase,
|
|
||||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid != 0) {
|
|
||||||
char error_buf[100];
|
|
||||||
mbedtls_strerror(valid, error_buf, 100);
|
|
||||||
SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
|
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_ECDSA_P256:
|
|
||||||
case SSH_KEYTYPE_ECDSA_P384:
|
|
||||||
case SSH_KEYTYPE_ECDSA_P521:
|
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
|
valid = mbedtls_pk_parse_key(
|
||||||
|
pk,
|
||||||
|
(const unsigned char *)b64_key,
|
||||||
|
b64len,
|
||||||
|
tmp,
|
||||||
|
strnlen((const char *)tmp, MAX_PASSPHRASE_SIZE),
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
#else
|
#else
|
||||||
ecdsa = malloc(sizeof(mbedtls_pk_context));
|
valid = mbedtls_pk_parse_key(
|
||||||
|
pk,
|
||||||
|
(const unsigned char *)b64_key,
|
||||||
|
b64len,
|
||||||
|
tmp,
|
||||||
|
strnlen((const char *)tmp, MAX_PASSPHRASE_SIZE));
|
||||||
#endif
|
#endif
|
||||||
if (ecdsa == NULL) {
|
} else {
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_pk_init(ecdsa);
|
|
||||||
|
|
||||||
if (passphrase == NULL) {
|
|
||||||
if (auth_fn) {
|
|
||||||
valid = auth_fn("Passphrase for private key:", (char *) tmp,
|
|
||||||
MAX_PASSPHRASE_SIZE, 0, 0, auth_data);
|
|
||||||
if (valid < 0) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(pk,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *)b64_key,
|
||||||
b64len, tmp,
|
b64len,
|
||||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE),
|
NULL,
|
||||||
mbedtls_ctr_drbg_random, ctr_drbg);
|
0,
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
#else
|
#else
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(pk,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *)b64_key,
|
||||||
b64len, tmp,
|
b64len,
|
||||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
NULL,
|
||||||
|
0);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
}
|
||||||
|
} else {
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
#if MBEDTLS_VERSION_MAJOR > 2
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(pk,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *)b64_key,
|
||||||
b64len, NULL,
|
b64len,
|
||||||
0, mbedtls_ctr_drbg_random, ctr_drbg);
|
(const unsigned char *)passphrase,
|
||||||
|
strnlen(passphrase, MAX_PASSPHRASE_SIZE),
|
||||||
|
mbedtls_ctr_drbg_random,
|
||||||
|
ctr_drbg);
|
||||||
#else
|
#else
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
valid = mbedtls_pk_parse_key(pk,
|
||||||
(const unsigned char *) b64_key,
|
(const unsigned char *)b64_key,
|
||||||
b64len, NULL,
|
b64len,
|
||||||
0);
|
(const unsigned char *)passphrase,
|
||||||
|
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#if MBEDTLS_VERSION_MAJOR > 2
|
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
|
||||||
(const unsigned char *) b64_key, b64len,
|
|
||||||
(const unsigned char *) passphrase,
|
|
||||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE),
|
|
||||||
mbedtls_ctr_drbg_random, ctr_drbg);
|
|
||||||
#else
|
|
||||||
valid = mbedtls_pk_parse_key(ecdsa,
|
|
||||||
(const unsigned char *) b64_key, b64len,
|
|
||||||
(const unsigned char *) passphrase,
|
|
||||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valid != 0) {
|
|
||||||
char error_buf[100];
|
|
||||||
mbedtls_strerror(valid, error_buf, 100);
|
|
||||||
SSH_LOG(SSH_LOG_WARN,"Parsing private key %s", error_buf);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SSH_KEYTYPE_ED25519:
|
|
||||||
/* Cannot open ed25519 keys with libmbedcrypto */
|
|
||||||
default:
|
|
||||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key type %d",
|
|
||||||
type);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
if (valid != 0) {
|
||||||
|
char error_buf[100];
|
||||||
|
mbedtls_strerror(valid, error_buf, 100);
|
||||||
|
SSH_LOG(SSH_LOG_WARN, "Parsing private key %s", error_buf);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbed_type = mbedtls_pk_get_type(pk);
|
||||||
|
|
||||||
key = ssh_key_new();
|
key = ssh_key_new();
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ecdsa != NULL) {
|
switch (mbed_type) {
|
||||||
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*ecdsa);
|
case MBEDTLS_PK_RSA:
|
||||||
|
case MBEDTLS_PK_RSA_ALT:
|
||||||
|
key->rsa = pk;
|
||||||
|
pk = NULL;
|
||||||
|
key->type = SSH_KEYTYPE_RSA;
|
||||||
|
break;
|
||||||
|
case MBEDTLS_PK_ECKEY:
|
||||||
|
case MBEDTLS_PK_ECDSA: {
|
||||||
|
/* type will be set later */
|
||||||
|
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*pk);
|
||||||
|
pk = NULL;
|
||||||
|
|
||||||
key->ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
|
key->ecdsa = malloc(sizeof(mbedtls_ecdsa_context));
|
||||||
if (key->ecdsa == NULL) {
|
if (key->ecdsa == NULL) {
|
||||||
@@ -258,40 +213,36 @@ ssh_key pki_private_key_from_base64(const char *b64_key, const char *passphrase,
|
|||||||
|
|
||||||
mbedtls_ecdsa_init(key->ecdsa);
|
mbedtls_ecdsa_init(key->ecdsa);
|
||||||
mbedtls_ecdsa_from_keypair(key->ecdsa, keypair);
|
mbedtls_ecdsa_from_keypair(key->ecdsa, keypair);
|
||||||
mbedtls_pk_free(ecdsa);
|
mbedtls_pk_free(pk);
|
||||||
SAFE_FREE(ecdsa);
|
SAFE_FREE(pk);
|
||||||
|
|
||||||
key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
|
key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
|
||||||
|
|
||||||
/* pki_privatekey_type_from_string always returns P256 for ECDSA
|
/* pki_privatekey_type_from_string always returns P256 for ECDSA
|
||||||
* keys, so we need to figure out the correct type here */
|
* keys, so we need to figure out the correct type here */
|
||||||
type = pki_key_ecdsa_to_key_type(key->ecdsa);
|
key->type = pki_key_ecdsa_to_key_type(key->ecdsa);
|
||||||
if (type == SSH_KEYTYPE_UNKNOWN) {
|
if (key->type == SSH_KEYTYPE_UNKNOWN) {
|
||||||
SSH_LOG(SSH_LOG_WARN, "Invalid private key.");
|
SSH_LOG(SSH_LOG_WARN, "Invalid private key.");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
key->ecdsa = NULL;
|
}
|
||||||
|
default:
|
||||||
|
SSH_LOG(SSH_LOG_WARN,
|
||||||
|
"Unknown or invalid private key type %d",
|
||||||
|
mbed_type);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
key->type = type;
|
key->type_c = ssh_key_type_to_char(key->type);
|
||||||
key->type_c = ssh_key_type_to_char(type);
|
|
||||||
key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
|
key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
|
||||||
key->rsa = rsa;
|
|
||||||
key->ed25519_privkey = ed25519;
|
|
||||||
rsa = NULL;
|
|
||||||
ecdsa = NULL;
|
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
fail:
|
fail:
|
||||||
ssh_key_free(key);
|
ssh_key_free(key);
|
||||||
if (rsa != NULL) {
|
if (pk != NULL) {
|
||||||
mbedtls_pk_free(rsa);
|
mbedtls_pk_free(pk);
|
||||||
SAFE_FREE(rsa);
|
SAFE_FREE(pk);
|
||||||
}
|
|
||||||
if (ecdsa != NULL) {
|
|
||||||
mbedtls_pk_free(ecdsa);
|
|
||||||
SAFE_FREE(ecdsa);
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -361,7 +361,6 @@ static void ssh_server_connection_callback(ssh_session session){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* from now, the packet layer is handling incoming packets */
|
/* from now, the packet layer is handling incoming packets */
|
||||||
session->socket_callbacks.data=ssh_packet_socket_callback;
|
|
||||||
ssh_packet_register_socket_callback(session, session->socket);
|
ssh_packet_register_socket_callback(session, session->socket);
|
||||||
|
|
||||||
ssh_packet_set_default_callbacks(session);
|
ssh_packet_set_default_callbacks(session);
|
||||||
|
|||||||
@@ -301,6 +301,7 @@ void ssh_free(ssh_session session)
|
|||||||
SAFE_FREE(session->banner);
|
SAFE_FREE(session->banner);
|
||||||
SAFE_FREE(session->disconnect_message);
|
SAFE_FREE(session->disconnect_message);
|
||||||
|
|
||||||
|
SAFE_FREE(session->opts.agent_socket);
|
||||||
SAFE_FREE(session->opts.bindaddr);
|
SAFE_FREE(session->opts.bindaddr);
|
||||||
SAFE_FREE(session->opts.custombanner);
|
SAFE_FREE(session->opts.custombanner);
|
||||||
SAFE_FREE(session->opts.moduli_file);
|
SAFE_FREE(session->opts.moduli_file);
|
||||||
@@ -1126,7 +1127,7 @@ int ssh_get_publickey_hash(const ssh_key key,
|
|||||||
size_t *hlen)
|
size_t *hlen)
|
||||||
{
|
{
|
||||||
ssh_string blob;
|
ssh_string blob;
|
||||||
unsigned char *h;
|
unsigned char *h = NULL;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ssh_pki_export_pubkey_blob(key, &blob);
|
rc = ssh_pki_export_pubkey_blob(key, &blob);
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ if (CLIENT_TESTING OR SERVER_TESTING)
|
|||||||
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_SHADOW=${CMAKE_CURRENT_BINARY_DIR}/etc/shadow)
|
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_SHADOW=${CMAKE_CURRENT_BINARY_DIR}/etc/shadow)
|
||||||
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_GROUP=${CMAKE_CURRENT_BINARY_DIR}/etc/group)
|
list(APPEND TORTURE_ENVIRONMENT NSS_WRAPPER_GROUP=${CMAKE_CURRENT_BINARY_DIR}/etc/group)
|
||||||
list(APPEND TORTURE_ENVIRONMENT PAM_WRAPPER_SERVICE_DIR=${CMAKE_CURRENT_BINARY_DIR}/etc/pam.d)
|
list(APPEND TORTURE_ENVIRONMENT PAM_WRAPPER_SERVICE_DIR=${CMAKE_CURRENT_BINARY_DIR}/etc/pam.d)
|
||||||
|
list(APPEND TORTURE_ENVIRONMENT LSAN_OPTIONS=suppressions=${CMAKE_CURRENT_SOURCE_DIR}/suppressions/lsan.supp)
|
||||||
|
|
||||||
# Give bob some keys
|
# Give bob some keys
|
||||||
file(COPY keys/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
file(COPY keys/id_rsa DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/home/bob/.ssh/ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
|
||||||
|
|||||||
@@ -39,6 +39,9 @@
|
|||||||
#define TEMPLATE BINARYDIR "/tests/home/alice/temp_dir_XXXXXX"
|
#define TEMPLATE BINARYDIR "/tests/home/alice/temp_dir_XXXXXX"
|
||||||
#define ALICE_HOME BINARYDIR "/tests/home/alice"
|
#define ALICE_HOME BINARYDIR "/tests/home/alice"
|
||||||
|
|
||||||
|
/* store the original umask */
|
||||||
|
mode_t old;
|
||||||
|
|
||||||
struct scp_st {
|
struct scp_st {
|
||||||
struct torture_state *s;
|
struct torture_state *s;
|
||||||
char *tmp_dir;
|
char *tmp_dir;
|
||||||
@@ -99,6 +102,9 @@ static int session_setup(void **state)
|
|||||||
|
|
||||||
s = ts->s;
|
s = ts->s;
|
||||||
|
|
||||||
|
/* store the original umask and set a new one */
|
||||||
|
old = umask(0022);
|
||||||
|
|
||||||
/* Create temporary directory for alice */
|
/* Create temporary directory for alice */
|
||||||
tmp_dir = torture_make_temp_dir(TEMPLATE);
|
tmp_dir = torture_make_temp_dir(TEMPLATE);
|
||||||
assert_non_null(tmp_dir);
|
assert_non_null(tmp_dir);
|
||||||
@@ -135,6 +141,9 @@ static int session_teardown(void **state)
|
|||||||
assert_non_null(ts->s);
|
assert_non_null(ts->s);
|
||||||
s = ts->s;
|
s = ts->s;
|
||||||
|
|
||||||
|
/* restore the umask */
|
||||||
|
umask(old);
|
||||||
|
|
||||||
ssh_disconnect(s->ssh.session);
|
ssh_disconnect(s->ssh.session);
|
||||||
ssh_free(s->ssh.session);
|
ssh_free(s->ssh.session);
|
||||||
|
|
||||||
|
|||||||
@@ -22,26 +22,58 @@ add_library(poly1305_override SHARED
|
|||||||
set(POLY1305_OVERRIDE_LIBRARY
|
set(POLY1305_OVERRIDE_LIBRARY
|
||||||
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}poly1305_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}poly1305_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||||
|
|
||||||
|
if (WITH_GCRYPT)
|
||||||
|
set (override_src
|
||||||
|
${libssh_SOURCE_DIR}/src/getrandom_gcrypt.c
|
||||||
|
${libssh_SOURCE_DIR}/src/md_gcrypt.c
|
||||||
|
)
|
||||||
|
set(override_libs
|
||||||
|
${GCRYPT_LIBRARIES}
|
||||||
|
)
|
||||||
|
elseif (WITH_MBEDTLS)
|
||||||
|
set (override_src
|
||||||
|
${libssh_SOURCE_DIR}/src/getrandom_mbedcrypto.c
|
||||||
|
${libssh_SOURCE_DIR}/src/md_mbedcrypto.c
|
||||||
|
)
|
||||||
|
set(override_libs
|
||||||
|
${MBEDTLS_CRYPTO_LIBRARY}
|
||||||
|
)
|
||||||
|
else ()
|
||||||
|
set (override_src
|
||||||
|
${libssh_SOURCE_DIR}/src/getrandom_crypto.c
|
||||||
|
${libssh_SOURCE_DIR}/src/md_crypto.c
|
||||||
|
)
|
||||||
|
set(override_libs
|
||||||
|
${OPENSSL_CRYPTO_LIBRARIES}
|
||||||
|
)
|
||||||
|
endif (WITH_GCRYPT)
|
||||||
|
|
||||||
# ed25519_override
|
# ed25519_override
|
||||||
add_library(ed25519_override SHARED
|
add_library(ed25519_override SHARED
|
||||||
ed25519_override.c
|
ed25519_override.c
|
||||||
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
||||||
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
||||||
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
||||||
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
||||||
)
|
${override_src}
|
||||||
|
)
|
||||||
|
target_link_libraries(ed25519_override
|
||||||
|
PRIVATE ${override_libs})
|
||||||
set(ED25519_OVERRIDE_LIBRARY
|
set(ED25519_OVERRIDE_LIBRARY
|
||||||
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}ed25519_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}ed25519_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||||
|
|
||||||
# curve25519_override
|
# curve25519_override
|
||||||
add_library(curve25519_override SHARED
|
add_library(curve25519_override SHARED
|
||||||
curve25519_override.c
|
curve25519_override.c
|
||||||
${libssh_SOURCE_DIR}/src/external/curve25519_ref.c
|
${libssh_SOURCE_DIR}/src/external/curve25519_ref.c
|
||||||
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
||||||
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
||||||
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
||||||
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
||||||
)
|
${override_src}
|
||||||
|
)
|
||||||
|
target_link_libraries(curve25519_override
|
||||||
|
PRIVATE ${override_libs})
|
||||||
set(CURVE25519_OVERRIDE_LIBRARY
|
set(CURVE25519_OVERRIDE_LIBRARY
|
||||||
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}curve25519_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}curve25519_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||||
|
|
||||||
|
|||||||
1
tests/suppressions/lsan.supp
Normal file
1
tests/suppressions/lsan.supp
Normal file
@@ -0,0 +1 @@
|
|||||||
|
leak:libcrypto.so
|
||||||
@@ -1033,11 +1033,13 @@ void torture_setup_libssh_server(void **state, const char *server_path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write the environment setting */
|
/* Write the environment setting */
|
||||||
|
/* OPENSSL variable is needed to enable SHA1 */
|
||||||
printed = snprintf(env, sizeof(env),
|
printed = snprintf(env, sizeof(env),
|
||||||
"SOCKET_WRAPPER_DIR=%s "
|
"SOCKET_WRAPPER_DIR=%s "
|
||||||
"SOCKET_WRAPPER_DEFAULT_IFACE=10 "
|
"SOCKET_WRAPPER_DEFAULT_IFACE=10 "
|
||||||
"LD_PRELOAD=%s "
|
"LD_PRELOAD=%s "
|
||||||
"%s",
|
"%s "
|
||||||
|
"OPENSSL_ENABLE_SHA1_SIGNATURES=1",
|
||||||
s->socket_dir, ld_preload, force_fips);
|
s->socket_dir, ld_preload, force_fips);
|
||||||
if (printed < 0) {
|
if (printed < 0) {
|
||||||
fail_msg("Failed to print env!");
|
fail_msg("Failed to print env!");
|
||||||
|
|||||||
1574
tests/torture_key.c
1574
tests/torture_key.c
File diff suppressed because it is too large
Load Diff
@@ -101,6 +101,10 @@ foreach(_UNIT_TEST ${LIBSSH_UNIT_TESTS})
|
|||||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
||||||
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES}
|
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set_property(TEST ${_UNIT_TEST}
|
||||||
|
PROPERTY
|
||||||
|
ENVIRONMENT LSAN_OPTIONS=suppressions=${libssh-tests_SOURCE_DIR}/suppressions/lsan.supp)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if (CMAKE_USE_PTHREADS_INIT)
|
if (CMAKE_USE_PTHREADS_INIT)
|
||||||
@@ -110,6 +114,10 @@ if (CMAKE_USE_PTHREADS_INIT)
|
|||||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
||||||
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES} Threads::Threads
|
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES} Threads::Threads
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set_property(TEST ${_UNIT_TEST}
|
||||||
|
PROPERTY
|
||||||
|
ENVIRONMENT LSAN_OPTIONS=suppressions=${libssh-tests_SOURCE_DIR}/suppressions/lsan.supp)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ static void torture_options_set_host(void **state) {
|
|||||||
assert_string_equal(session->opts.host, "meditation");
|
assert_string_equal(session->opts.host, "meditation");
|
||||||
assert_non_null(session->opts.username);
|
assert_non_null(session->opts.username);
|
||||||
assert_string_equal(session->opts.username, "guru");
|
assert_string_equal(session->opts.username, "guru");
|
||||||
|
|
||||||
|
rc = ssh_options_set(session, SSH_OPTIONS_HOST, "at@login@hostname");
|
||||||
|
assert_true(rc == 0);
|
||||||
|
assert_non_null(session->opts.host);
|
||||||
|
assert_string_equal(session->opts.host, "hostname");
|
||||||
|
assert_non_null(session->opts.username);
|
||||||
|
assert_string_equal(session->opts.username, "at@login");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void torture_options_set_ciphers(void **state) {
|
static void torture_options_set_ciphers(void **state) {
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ static int setup_directory_structure(void **state)
|
|||||||
|
|
||||||
rc = torture_change_dir(temp_dir);
|
rc = torture_change_dir(temp_dir);
|
||||||
assert_int_equal(rc, 0);
|
assert_int_equal(rc, 0);
|
||||||
|
SAFE_FREE(temp_dir);
|
||||||
|
|
||||||
test_state->temp_dir = torture_get_current_working_dir();
|
test_state->temp_dir = torture_get_current_working_dir();
|
||||||
assert_non_null(test_state->temp_dir);
|
assert_non_null(test_state->temp_dir);
|
||||||
@@ -188,6 +189,7 @@ static void torture_pki_ecdsa_publickey_from_privatekey_uri(void **state, const
|
|||||||
assert_return_code(rc, errno);
|
assert_return_code(rc, errno);
|
||||||
assert_true(rc == SSH_OK);
|
assert_true(rc == SSH_OK);
|
||||||
assert_non_null(pblob);
|
assert_non_null(pblob);
|
||||||
|
ssh_string_free(pblob);
|
||||||
|
|
||||||
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||||||
assert_return_code(rc, errno);
|
assert_return_code(rc, errno);
|
||||||
@@ -227,6 +229,21 @@ static void torture_pki_ecdsa_publickey_from_privatekey_uri(void **state, const
|
|||||||
SSH_KEY_FREE(pubkey);
|
SSH_KEY_FREE(pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void torture_pki_ecdsa_publickey_from_privatekey_uri_256(void **state)
|
||||||
|
{
|
||||||
|
torture_pki_ecdsa_publickey_from_privatekey_uri(state, PRIV_URI_FMT_256, "ecdsa256");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_pki_ecdsa_publickey_from_privatekey_uri_384(void **state)
|
||||||
|
{
|
||||||
|
torture_pki_ecdsa_publickey_from_privatekey_uri(state, PRIV_URI_FMT_384, "ecdsa384");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void torture_pki_ecdsa_publickey_from_privatekey_uri_521(void **state)
|
||||||
|
{
|
||||||
|
torture_pki_ecdsa_publickey_from_privatekey_uri(state, PRIV_URI_FMT_521, "ecdsa521");
|
||||||
|
}
|
||||||
|
|
||||||
static void import_pubkey_without_loading_public_uri(void **state, const char *uri, const char *type)
|
static void import_pubkey_without_loading_public_uri(void **state, const char *uri, const char *type)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
@@ -246,6 +263,7 @@ static void import_pubkey_without_loading_public_uri(void **state, const char *u
|
|||||||
rc = ssh_pki_export_pubkey_blob(privkey, &pblob);
|
rc = ssh_pki_export_pubkey_blob(privkey, &pblob);
|
||||||
assert_int_not_equal(rc, 0);
|
assert_int_not_equal(rc, 0);
|
||||||
assert_null(pblob);
|
assert_null(pblob);
|
||||||
|
ssh_string_free(pblob);
|
||||||
|
|
||||||
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||||||
assert_int_not_equal(rc, 0);
|
assert_int_not_equal(rc, 0);
|
||||||
@@ -255,21 +273,6 @@ static void import_pubkey_without_loading_public_uri(void **state, const char *u
|
|||||||
SSH_KEY_FREE(pubkey);
|
SSH_KEY_FREE(pubkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void torture_pki_ecdsa_publickey_from_privatekey_uri_256(void **state)
|
|
||||||
{
|
|
||||||
torture_pki_ecdsa_publickey_from_privatekey_uri(state, PRIV_URI_FMT_256, "ecdsa256");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void torture_pki_ecdsa_publickey_from_privatekey_uri_384(void **state)
|
|
||||||
{
|
|
||||||
torture_pki_ecdsa_publickey_from_privatekey_uri(state, PRIV_URI_FMT_384, "ecdsa384");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void torture_pki_ecdsa_publickey_from_privatekey_uri_521(void **state)
|
|
||||||
{
|
|
||||||
torture_pki_ecdsa_publickey_from_privatekey_uri(state, PRIV_URI_FMT_521, "ecdsa521");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void torture_pki_ecdsa_import_pubkey_without_loading_public_uri_256(void **state)
|
static void torture_pki_ecdsa_import_pubkey_without_loading_public_uri_256(void **state)
|
||||||
{
|
{
|
||||||
import_pubkey_without_loading_public_uri(state, PRIV_URI_FMT_256_NO_PUB, "ecdsa256_no_pub_uri");
|
import_pubkey_without_loading_public_uri(state, PRIV_URI_FMT_256_NO_PUB, "ecdsa256_no_pub_uri");
|
||||||
@@ -320,7 +323,7 @@ static void torture_ecdsa_sign_verify_uri(void **state, const char *uri, enum ss
|
|||||||
type_char = ssh_key_type_to_char(type);
|
type_char = ssh_key_type_to_char(type);
|
||||||
etype_char = ssh_pki_key_ecdsa_name(privkey);
|
etype_char = ssh_pki_key_ecdsa_name(privkey);
|
||||||
|
|
||||||
switch(dig_type) {
|
switch (dig_type) {
|
||||||
case SSH_DIGEST_SHA256:
|
case SSH_DIGEST_SHA256:
|
||||||
assert_true(type == SSH_KEYTYPE_ECDSA_P256);
|
assert_true(type == SSH_KEYTYPE_ECDSA_P256);
|
||||||
assert_string_equal(type_char, "ecdsa-sha2-nistp256");
|
assert_string_equal(type_char, "ecdsa-sha2-nistp256");
|
||||||
@@ -340,6 +343,7 @@ static void torture_ecdsa_sign_verify_uri(void **state, const char *uri, enum ss
|
|||||||
printf("Invalid hash type: %d\n", dig_type);
|
printf("Invalid hash type: %d\n", dig_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssh_free(session);
|
||||||
ssh_signature_free(sign);
|
ssh_signature_free(sign);
|
||||||
SSH_KEY_FREE(privkey);
|
SSH_KEY_FREE(privkey);
|
||||||
SSH_KEY_FREE(pubkey);
|
SSH_KEY_FREE(pubkey);
|
||||||
@@ -540,15 +544,16 @@ int torture_run_tests(void) {
|
|||||||
cmocka_unit_test(torture_pki_ecdsa_import_pubkey_without_loading_public_uri_384),
|
cmocka_unit_test(torture_pki_ecdsa_import_pubkey_without_loading_public_uri_384),
|
||||||
cmocka_unit_test(torture_pki_ecdsa_import_pubkey_without_loading_public_uri_521),
|
cmocka_unit_test(torture_pki_ecdsa_import_pubkey_without_loading_public_uri_521),
|
||||||
};
|
};
|
||||||
|
|
||||||
ssh_session session = ssh_new();
|
ssh_session session = ssh_new();
|
||||||
int verbosity = SSH_LOG_FUNCTIONS;
|
int verbosity = SSH_LOG_FUNCTIONS;
|
||||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
|
||||||
ssh_init();
|
ssh_init();
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||||
|
|
||||||
torture_filter_tests(tests);
|
torture_filter_tests(tests);
|
||||||
rc = cmocka_run_group_tests(tests, setup_directory_structure, teardown_directory_structure);
|
rc = cmocka_run_group_tests(tests, setup_directory_structure, teardown_directory_structure);
|
||||||
|
|
||||||
|
ssh_free(session);
|
||||||
ssh_finalize();
|
ssh_finalize();
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
|||||||
@@ -541,9 +541,13 @@ static void torture_pki_rsa_generate_key(void **state)
|
|||||||
int rc;
|
int rc;
|
||||||
ssh_key key = NULL, pubkey = NULL;
|
ssh_key key = NULL, pubkey = NULL;
|
||||||
ssh_signature sign = NULL;
|
ssh_signature sign = NULL;
|
||||||
ssh_session session=ssh_new();
|
ssh_session session = ssh_new();
|
||||||
|
int verbosity = torture_libssh_verbosity();
|
||||||
|
|
||||||
(void) state;
|
(void) state;
|
||||||
|
|
||||||
|
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||||
|
|
||||||
if (!ssh_fips_mode()) {
|
if (!ssh_fips_mode()) {
|
||||||
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 1024, &key);
|
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 1024, &key);
|
||||||
assert_true(rc == SSH_OK);
|
assert_true(rc == SSH_OK);
|
||||||
|
|||||||
Reference in New Issue
Block a user