mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
Compare commits
39 Commits
39a62cef44
...
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:
|
||||
BUILD_IMAGES_PROJECT: libssh/build-images
|
||||
CENTOS7_BUILD: buildenv-centos7
|
||||
CENTOS9_BUILD: buildenv-c9s
|
||||
COVERITY_BUILD: buildenv-coverity
|
||||
FEDORA_BUILD: buildenv-fedora
|
||||
MINGW_BUILD: buildenv-mingw
|
||||
TUMBLEWEED_BUILD: buildenv-tumbleweed
|
||||
UBUNTU_BUILD: buildenv-ubuntu
|
||||
RAWHIDE_BUILD: buildenv-rawhide
|
||||
|
||||
stages:
|
||||
- build
|
||||
@@ -61,14 +61,6 @@ stages:
|
||||
variables:
|
||||
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:
|
||||
extends: .tests
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$TUMBLEWEED_BUILD
|
||||
@@ -86,6 +78,15 @@ centos7/openssl_1.0.x/x86_64:
|
||||
make -j$(nproc) &&
|
||||
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 #
|
||||
@@ -106,10 +107,10 @@ fedora/ninja:
|
||||
script:
|
||||
- cmake -G Ninja $CMAKE_OPTIONS ../ && ninja && ninja test
|
||||
|
||||
fedora/openssl_1.1.x/x86_64:
|
||||
fedora/openssl_3.0.x/x86_64:
|
||||
extends: .fedora
|
||||
|
||||
fedora/openssl_1.1.x/x86_64/fips:
|
||||
fedora/openssl_3.0.x/x86_64/fips:
|
||||
extends: .fedora
|
||||
before_script:
|
||||
- echo "# userspace fips" > /etc/system-fips
|
||||
@@ -134,7 +135,7 @@ fedora/openssl_1.1.x/x86_64/fips:
|
||||
make -j$(nproc) &&
|
||||
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
|
||||
variables:
|
||||
script:
|
||||
@@ -149,49 +150,6 @@ fedora/openssl_1.1.x/x86_64/minimal:
|
||||
-DWITH_GEX=OFF .. &&
|
||||
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
|
||||
# so, this is only enabled for unit tests right now.
|
||||
# TODO: add -DCLIENT_TESTING=ON -DSERVER_TESTING=ON
|
||||
@@ -316,19 +274,8 @@ fedora/mingw32:
|
||||
paths:
|
||||
- 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:
|
||||
extends: .csbuild
|
||||
image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$RAWHIDE_BUILD
|
||||
script:
|
||||
- csbuild
|
||||
--build-dir=obj-csbuild
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 mbedTLS 3
|
||||
* 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
|
||||
* Avoided some needless large stack buffers to minimize memory footprint
|
||||
* 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)
|
||||
* 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})
|
||||
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_LIBRARIES ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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)
|
||||
set(HAVE_ECC 1)
|
||||
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 ()
|
||||
|
||||
if (WITH_DSA)
|
||||
@@ -468,6 +477,10 @@ if (WITH_PKCS11_URI)
|
||||
message(FATAL_ERROR "PKCS #11 is not supported for mbedcrypto")
|
||||
set(WITH_PKCS11_URI 0)
|
||||
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()
|
||||
|
||||
if (WITH_MBEDTLS)
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
/* Define to 1 if you have the `EVP_chacha20' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_CHACHA20 1
|
||||
|
||||
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID 1
|
||||
/* Define to 1 if you have the `EVP_KDF_CTX_new_id' or `EVP_KDF_CTX_new` function. */
|
||||
#cmakedefine HAVE_OPENSSL_EVP_KDF_CTX 1
|
||||
|
||||
/* Define to 1 if you have the `FIPS_mode' function. */
|
||||
#cmakedefine HAVE_OPENSSL_FIPS_MODE 1
|
||||
|
||||
@@ -38,6 +38,7 @@ struct arguments_st {
|
||||
unsigned long bits;
|
||||
char *file;
|
||||
char *passphrase;
|
||||
int action_list;
|
||||
};
|
||||
|
||||
static struct argp_option options[] = {
|
||||
@@ -88,6 +89,14 @@ static struct argp_option options[] = {
|
||||
"\"rsa\", \"ecdsa\", \"ed25519\", and \"dsa\".\n",
|
||||
.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 */
|
||||
0
|
||||
@@ -160,6 +169,9 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state)
|
||||
goto end;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
arguments->action_list = 1;
|
||||
break;
|
||||
case ARGP_KEY_ARG:
|
||||
if (state->arg_num > 0) {
|
||||
/* Too many arguments. */
|
||||
@@ -185,98 +197,103 @@ static int validate_args(struct arguments_st *args)
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
switch(args->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
switch(args->bits) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* no other arguments needed for listing key fingerprints */
|
||||
if (args->action_list) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (args->type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
switch (args->bits) {
|
||||
case 0:
|
||||
/* If not provided, use default value */
|
||||
args->bits = 3072;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
case 1024:
|
||||
case 2048:
|
||||
case 3072:
|
||||
case 4096:
|
||||
case 8192:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Error: unknown key type\n");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -289,6 +306,31 @@ static char doc[] = "Generate an SSH key pair. "
|
||||
/* Our argp parser */
|
||||
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[])
|
||||
{
|
||||
ssh_key key = NULL;
|
||||
@@ -302,6 +344,7 @@ int main(int argc, char *argv[])
|
||||
.bits = 0,
|
||||
.file = NULL,
|
||||
.passphrase = NULL,
|
||||
.action_list = 0,
|
||||
};
|
||||
|
||||
if (argc < 2) {
|
||||
@@ -319,6 +362,11 @@ int main(int argc, char *argv[])
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (arguments.action_list && arguments.file) {
|
||||
list_fingerprint(arguments.file);
|
||||
goto end;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
rc = open(arguments.file, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
if (rc < 0) {
|
||||
|
||||
@@ -92,7 +92,7 @@ cleanup_push(struct cleanup_node_struct** head_ref,
|
||||
// Allocate memory for node
|
||||
struct cleanup_node_struct *new_node = malloc(sizeof *new_node);
|
||||
|
||||
if (head_ref != NULL) {
|
||||
if (*head_ref != NULL) {
|
||||
new_node->next = *head_ref;
|
||||
} else {
|
||||
new_node->next = NULL;
|
||||
|
||||
@@ -223,5 +223,8 @@ int sshkdf_derive_key(struct ssh_crypto_struct *crypto,
|
||||
size_t requested_len);
|
||||
|
||||
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_ */
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#endif
|
||||
#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
|
||||
* defined in libssh/ed25519.h otherwise */
|
||||
#define ED25519_SIG_LEN 64
|
||||
@@ -78,9 +78,11 @@ struct ssh_key_struct {
|
||||
# else
|
||||
void *ecdsa;
|
||||
# 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 */
|
||||
#ifdef HAVE_OPENSSL_ED25519
|
||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_ED25519)
|
||||
uint8_t *ed25519_pubkey;
|
||||
uint8_t *ed25519_privkey;
|
||||
#else
|
||||
@@ -104,7 +106,7 @@ struct ssh_signature_struct {
|
||||
ssh_string rsa_sig;
|
||||
struct mbedtls_ecdsa_sig ecdsa_sig;
|
||||
#endif /* HAVE_LIBGCRYPT */
|
||||
#ifndef HAVE_OPENSSL_ED25519
|
||||
#if !defined(HAVE_LIBCRYPTO) || !defined(HAVE_OPENSSL_ED25519)
|
||||
ed25519_signature *ed25519_sig;
|
||||
#endif
|
||||
ssh_string raw_sig;
|
||||
|
||||
@@ -49,6 +49,8 @@ enum ssh_key_e {
|
||||
SSH_KEY_PRIVATE
|
||||
};
|
||||
|
||||
void pki_key_clean(ssh_key key);
|
||||
|
||||
int pki_key_ecdsa_nid_from_name(const char *name);
|
||||
const char *pki_key_ecdsa_nid_to_name(int nid);
|
||||
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 */
|
||||
|
||||
struct timeval;
|
||||
int gettimeofday(struct timeval *__p, void *__t);
|
||||
int ssh_gettimeofday(struct timeval *__p, void *__t);
|
||||
|
||||
#define gettimeofday ssh_gettimeofday
|
||||
|
||||
#define _XCLOSESOCKET closesocket
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ struct ssh_session_struct {
|
||||
char *agent_socket;
|
||||
unsigned long timeout; /* seconds */
|
||||
unsigned long timeout_usec;
|
||||
unsigned int port;
|
||||
uint16_t port;
|
||||
socket_t fd;
|
||||
int StrictHostKeyChecking;
|
||||
char compressionlevel;
|
||||
|
||||
@@ -184,6 +184,8 @@ if (WITH_GCRYPT)
|
||||
gcrypt_missing.c
|
||||
pki_gcrypt.c
|
||||
ecdh_gcrypt.c
|
||||
getrandom_gcrypt.c
|
||||
md_gcrypt.c
|
||||
dh_key.c
|
||||
pki_ed25519.c
|
||||
external/ed25519.c
|
||||
@@ -207,6 +209,8 @@ elseif (WITH_MBEDTLS)
|
||||
mbedcrypto_missing.c
|
||||
pki_mbedcrypto.c
|
||||
ecdh_mbedcrypto.c
|
||||
getrandom_mbedcrypto.c
|
||||
md_mbedcrypto.c
|
||||
dh_key.c
|
||||
pki_ed25519.c
|
||||
external/ed25519.c
|
||||
@@ -229,6 +233,8 @@ else (WITH_GCRYPT)
|
||||
threads/libcrypto.c
|
||||
pki_crypto.c
|
||||
ecdh_crypto.c
|
||||
getrandom_crypto.c
|
||||
md_crypto.c
|
||||
libcrypto.c
|
||||
dh_crypto.c
|
||||
)
|
||||
@@ -300,12 +306,12 @@ if (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
endif (WITH_GSSAPI AND GSSAPI_FOUND)
|
||||
|
||||
if (NOT WITH_NACL)
|
||||
if (NOT HAVE_OPENSSL_ED25519)
|
||||
if (NOT HAVE_LIBCRYPTO OR NOT HAVE_OPENSSL_ED25519)
|
||||
set(libssh_SRCS
|
||||
${libssh_SRCS}
|
||||
external/curve25519_ref.c
|
||||
)
|
||||
endif (NOT HAVE_OPENSSL_ED25519)
|
||||
endif()
|
||||
endif (NOT WITH_NACL)
|
||||
|
||||
# Set the path to the default map file
|
||||
|
||||
@@ -282,7 +282,7 @@ int ssh_bind_listen(ssh_bind sshbind) {
|
||||
}
|
||||
|
||||
if (listen(fd, 10) < 0) {
|
||||
char err_msg[] = {0};
|
||||
char err_msg[SSH_ERRNO_MSG_MAX] = {0};
|
||||
ssh_set_error(sshbind, SSH_FATAL,
|
||||
"Listening to socket %d: %s",
|
||||
fd, ssh_strerror(errno, err_msg, SSH_ERRNO_MSG_MAX));
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#include "libssh/pki.h"
|
||||
#include "libssh/bignum.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519)
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
@@ -59,7 +59,7 @@ static struct ssh_packet_callbacks_struct ssh_curve25519_client_callbacks = {
|
||||
static int ssh_curve25519_init(ssh_session session)
|
||||
{
|
||||
int rc;
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519)
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
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,
|
||||
session->next_crypto->curve25519_privkey);
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_X25519 */
|
||||
#endif /* defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519) */
|
||||
|
||||
return SSH_OK;
|
||||
}
|
||||
@@ -176,7 +176,7 @@ static int ssh_curve25519_build_k(ssh_session session)
|
||||
{
|
||||
ssh_curve25519_pubkey k;
|
||||
|
||||
#ifdef HAVE_OPENSSL_X25519
|
||||
#if defined(HAVE_LIBCRYPTO) && defined(HAVE_OPENSSL_X25519)
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = NULL, *pubkey = NULL;
|
||||
size_t shared_key_len = sizeof(k);
|
||||
@@ -255,7 +255,7 @@ out:
|
||||
crypto_scalarmult(k, session->next_crypto->curve25519_privkey,
|
||||
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);
|
||||
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) {
|
||||
_ssh_initialized--;
|
||||
goto _ret;
|
||||
ssh_mutex_unlock(&ssh_init_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_ssh_initialized == 1) {
|
||||
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;
|
||||
|
||||
_ret:
|
||||
if (!destructor) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
342
src/libcrypto.c
342
src/libcrypto.c
@@ -73,14 +73,20 @@
|
||||
|
||||
#include "libssh/crypto.h"
|
||||
|
||||
#ifdef HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID
|
||||
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
|
||||
#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"
|
||||
|
||||
static int libcrypto_initialized = 0;
|
||||
|
||||
static ENGINE *engine = NULL;
|
||||
|
||||
void ssh_reseed(void){
|
||||
#ifndef _WIN32
|
||||
struct timeval tv;
|
||||
@@ -89,69 +95,34 @@ void ssh_reseed(void){
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
ENGINE *pki_get_engine(void)
|
||||
{
|
||||
#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);
|
||||
}
|
||||
|
||||
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);
|
||||
int ok;
|
||||
|
||||
if (engine == NULL) {
|
||||
ENGINE_load_builtin_engines();
|
||||
|
||||
engine = ENGINE_by_id("pkcs11");
|
||||
if (engine == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Could not load the engine: %s",
|
||||
ERR_error_string(ERR_get_error(), NULL));
|
||||
return NULL;
|
||||
}
|
||||
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 NULL;
|
||||
}
|
||||
|
||||
SSH_LOG(SSH_LOG_INFO, "Engine init success");
|
||||
}
|
||||
return engine;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
@@ -208,146 +179,8 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
||||
}
|
||||
#endif /* HAVE_OPENSSL_ECC */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENSSL_EVP_KDF_CTX_NEW_ID
|
||||
#ifdef HAVE_OPENSSL_EVP_KDF_CTX
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
static const EVP_MD *sshkdf_digest_to_md(enum ssh_kdf_digest 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;
|
||||
}
|
||||
#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,
|
||||
unsigned char *key, size_t key_len,
|
||||
int key_type, unsigned char *output,
|
||||
size_t requested_len)
|
||||
{
|
||||
int rc = -1;
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
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;
|
||||
}
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
|
||||
if (ctx == NULL) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
rc = EVP_KDF_ctrl(ctx, EVP_KDF_CTRL_SET_MD,
|
||||
sshkdf_digest_to_md(crypto->digest_type));
|
||||
if (rc != 1) {
|
||||
@@ -402,8 +266,60 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||
if (rc != 1) {
|
||||
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:
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
OSSL_PARAM_BLD_free(param_bld);
|
||||
OSSL_PARAM_free(params);
|
||||
#endif
|
||||
EVP_KDF_CTX_free(ctx);
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
@@ -420,7 +336,8 @@ int ssh_kdf(struct ssh_crypto_struct *crypto,
|
||||
return sshkdf_derive_key(crypto, key, key_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 ctx = NULL;
|
||||
@@ -1508,8 +1425,19 @@ void ssh_crypto_finalize(void)
|
||||
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
|
||||
ENGINE_cleanup();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
#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){
|
||||
}
|
||||
|
||||
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
|
||||
static int nid_to_md_algo(int nid)
|
||||
{
|
||||
@@ -154,86 +122,6 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
||||
}
|
||||
#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,
|
||||
unsigned char *key, size_t key_len,
|
||||
int key_type, unsigned char *output,
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#endif /* MBEDTLS_GCM_C */
|
||||
|
||||
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;
|
||||
|
||||
@@ -51,65 +51,6 @@ void ssh_reseed(void)
|
||||
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)
|
||||
{
|
||||
switch (nid) {
|
||||
@@ -184,211 +125,6 @@ void evp_final(EVPCTX ctx, unsigned char *md, unsigned int *mdlen)
|
||||
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,
|
||||
unsigned char *key, size_t key_len,
|
||||
int key_type, unsigned char *output,
|
||||
@@ -1438,22 +1174,6 @@ int ssh_crypto_init(void)
|
||||
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)
|
||||
{
|
||||
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_SECONDS_SINCE_1601 11644473600LL
|
||||
|
||||
int gettimeofday(struct timeval *__p, void *__t)
|
||||
int ssh_gettimeofday(struct timeval *__p, void *__t)
|
||||
{
|
||||
union {
|
||||
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;
|
||||
case 'p':
|
||||
if (session->opts.port < 65536) {
|
||||
char tmp[6];
|
||||
if (session->opts.port > 0) {
|
||||
char tmp[6];
|
||||
|
||||
snprintf(tmp,
|
||||
sizeof(tmp),
|
||||
"%u",
|
||||
session->opts.port > 0 ? session->opts.port : 22);
|
||||
x = strdup(tmp);
|
||||
snprintf(tmp, sizeof(tmp), "%hu",
|
||||
(uint16_t)(session->opts.port > 0 ? session->opts.port
|
||||
: 22));
|
||||
x = strdup(tmp);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -513,7 +513,7 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
||||
ssh_set_error_oom(session);
|
||||
return -1;
|
||||
}
|
||||
p = strchr(q, '@');
|
||||
p = strrchr(q, '@');
|
||||
|
||||
SAFE_FREE(session->opts.host);
|
||||
|
||||
|
||||
@@ -260,42 +260,71 @@ int ssh_packet_hmac_verify(ssh_session session,
|
||||
uint8_t *mac,
|
||||
enum ssh_hmac_e type)
|
||||
{
|
||||
struct ssh_crypto_struct *crypto = NULL;
|
||||
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
||||
HMACCTX ctx;
|
||||
size_t hmaclen = DIGEST_MAX_LEN;
|
||||
uint32_t seq;
|
||||
struct ssh_crypto_struct *crypto = NULL;
|
||||
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
|
||||
HMACCTX ctx;
|
||||
size_t hmaclen = DIGEST_MAX_LEN;
|
||||
uint32_t seq;
|
||||
int cmp;
|
||||
int rc;
|
||||
|
||||
/* AEAD types have no mac checking */
|
||||
if (type == SSH_HMAC_AEAD_POLY1305 ||
|
||||
type == SSH_HMAC_AEAD_GCM) {
|
||||
return SSH_OK;
|
||||
}
|
||||
/* AEAD types have no mac checking */
|
||||
if (type == SSH_HMAC_AEAD_POLY1305 ||
|
||||
type == SSH_HMAC_AEAD_GCM) {
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
crypto = ssh_packet_get_current_crypto(session, SSH_DIRECTION_IN);
|
||||
if (crypto == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
crypto = ssh_packet_get_current_crypto(session,
|
||||
SSH_DIRECTION_IN);
|
||||
if (crypto == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
ctx = hmac_init(crypto->decryptMAC, hmac_digest_len(type), type);
|
||||
if (ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ctx = hmac_init(crypto->decryptMAC,
|
||||
hmac_digest_len(type),
|
||||
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));
|
||||
hmac_update(ctx, data, len);
|
||||
hmac_final(ctx, hmacbuf, &hmaclen);
|
||||
rc = hmac_update(ctx,
|
||||
(unsigned char *) &seq,
|
||||
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
|
||||
ssh_log_hexdump("received mac",mac,hmaclen);
|
||||
ssh_log_hexdump("Computed mac",hmacbuf,hmaclen);
|
||||
ssh_log_hexdump("seq",(unsigned char *)&seq,sizeof(uint32_t));
|
||||
ssh_log_hexdump("received mac",
|
||||
mac,
|
||||
hmaclen);
|
||||
ssh_log_hexdump("Computed mac",
|
||||
hmacbuf,
|
||||
hmaclen);
|
||||
ssh_log_hexdump("seq",
|
||||
(unsigned char *)&seq,
|
||||
sizeof(uint32_t));
|
||||
#endif
|
||||
if (secure_memcmp(mac, hmacbuf, hmaclen) == 0) {
|
||||
return 0;
|
||||
}
|
||||
cmp = secure_memcmp(mac,
|
||||
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;
|
||||
|
||||
#ifdef HAVE_DSA
|
||||
start = strstr(privkey, DSA_HEADER_BEGIN);
|
||||
if (start != NULL) {
|
||||
return SSH_KEYTYPE_DSS;
|
||||
}
|
||||
#endif /* HAVE_DSA */
|
||||
|
||||
start = strstr(privkey, RSA_HEADER_BEGIN);
|
||||
if (start != NULL) {
|
||||
@@ -152,37 +154,9 @@ void ssh_key_clean (ssh_key key)
|
||||
{
|
||||
if (key == NULL)
|
||||
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) {
|
||||
mbedtls_ecdsa_free(key->ecdsa);
|
||||
SAFE_FREE(key->ecdsa);
|
||||
}
|
||||
#endif
|
||||
pki_key_clean(key);
|
||||
|
||||
if (key->ed25519_privkey != NULL){
|
||||
#ifdef HAVE_OPENSSL_ED25519
|
||||
/* 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);
|
||||
}
|
||||
key->cert_type = SSH_KEYTYPE_UNKNOWN;
|
||||
key->flags=SSH_KEY_FLAG_EMPTY;
|
||||
key->type=SSH_KEYTYPE_UNKNOWN;
|
||||
key->flags = SSH_KEY_FLAG_EMPTY;
|
||||
key->type = SSH_KEYTYPE_UNKNOWN;
|
||||
key->ecdsa_nid = 0;
|
||||
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;
|
||||
key->type_c = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1124,7 +1087,7 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
|
||||
ssh_public_key pub;
|
||||
ssh_key tmp;
|
||||
|
||||
if(key == NULL) {
|
||||
if (key == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1133,12 +1096,11 @@ ssh_public_key ssh_pki_convert_key_to_publickey(const ssh_key key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pub = malloc(sizeof(struct ssh_public_key_struct));
|
||||
pub = calloc(1, sizeof(struct ssh_public_key_struct));
|
||||
if (pub == NULL) {
|
||||
ssh_key_free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
ZERO_STRUCTP(pub);
|
||||
|
||||
pub->type = tmp->type;
|
||||
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;
|
||||
|
||||
privkey = malloc(sizeof(struct ssh_private_key_struct));
|
||||
privkey = calloc(1, sizeof(struct ssh_private_key_struct));
|
||||
if (privkey == NULL) {
|
||||
ssh_key_free(key);
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||||
* 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 new;
|
||||
ssh_key new = NULL;
|
||||
int rc;
|
||||
|
||||
new = ssh_key_new();
|
||||
@@ -434,12 +458,6 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
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_c = key->type_c;
|
||||
if (demote) {
|
||||
@@ -523,6 +541,19 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
const BIGNUM *n = NULL, *e = NULL, *d = NULL;
|
||||
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();
|
||||
if (new->rsa == NULL) {
|
||||
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
|
||||
* 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) {
|
||||
BN_free(ndmp1);
|
||||
BN_free(ndmq1);
|
||||
@@ -629,6 +660,22 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
case SSH_KEYTYPE_ECDSA_P521:
|
||||
#ifdef HAVE_OPENSSL_ECC
|
||||
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
|
||||
* https://github.com/openssl/openssl/pull/16624
|
||||
* #if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
@@ -654,7 +701,11 @@ ssh_key pki_key_dup(const ssh_key key, int demote)
|
||||
goto fail;
|
||||
}
|
||||
} 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
|
||||
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
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
pkey = key->key;
|
||||
if (pkey == NULL) {
|
||||
rc = EVP_PKEY_up_ref(key->key);
|
||||
if (rc != 1) {
|
||||
goto err;
|
||||
}
|
||||
pkey = key->key;
|
||||
|
||||
/* Mark the operation as successful as for the other key types */
|
||||
rc = 1;
|
||||
@@ -1125,10 +1177,11 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
||||
* #if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
*/
|
||||
#if 0
|
||||
pkey = key->key;
|
||||
if (pkey == NULL) {
|
||||
rc = EVP_PKEY_up_ref(key->key);
|
||||
if (rc != 1) {
|
||||
goto err;
|
||||
}
|
||||
pkey = key->key;
|
||||
|
||||
/* Mark the operation as successful as for the other key types */
|
||||
rc = 1;
|
||||
@@ -1192,9 +1245,7 @@ ssh_string pki_private_key_to_pem(const ssh_key key,
|
||||
NULL, /* auth_fn */
|
||||
(void*) passphrase);
|
||||
}
|
||||
if (pkey != key->key) {
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
EVP_PKEY_free(pkey);
|
||||
pkey = NULL;
|
||||
|
||||
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
|
||||
* Remove these three lines
|
||||
*/
|
||||
/* the EVP_PKEY is not saved to the ssh_key struct */
|
||||
EVP_PKEY_free(pkey);
|
||||
pkey = NULL;
|
||||
|
||||
break;
|
||||
#endif /* HAVE_OPENSSL_ECC */
|
||||
#ifdef HAVE_OPENSSL_ED25519
|
||||
@@ -1373,11 +1420,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
}
|
||||
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;
|
||||
#endif /* HAVE_OPENSSL_ED25519 */
|
||||
@@ -1387,10 +1429,6 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
EVP_PKEY_free(pkey);
|
||||
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();
|
||||
if (key == NULL) {
|
||||
@@ -1403,9 +1441,8 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
key->dsa = dsa;
|
||||
key->rsa = rsa;
|
||||
#else
|
||||
key->key = pkey;
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
key->key = pkey;
|
||||
/* TODO Change to new API when the OpenSSL will support export of uncompressed EC keys
|
||||
* https://github.com/openssl/openssl/pull/16624
|
||||
* 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)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
#ifdef WITH_PKCS11_URI
|
||||
if (key->flags & SSH_KEY_FLAG_PKCS11_URI) {
|
||||
pkey = key->key;
|
||||
return pkey;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
int rc = 0;
|
||||
#endif
|
||||
|
||||
switch(key->type) {
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
case SSH_KEYTYPE_DSS_CERT01:
|
||||
#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");
|
||||
goto error;
|
||||
}
|
||||
pkey = EVP_PKEY_dup(key->key);
|
||||
if (pkey == NULL) {
|
||||
SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
||||
rc = EVP_PKEY_up_ref(key->key);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE, "Failed to reference EVP_PKEY");
|
||||
return NULL;
|
||||
}
|
||||
pkey = key->key;
|
||||
break;
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
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");
|
||||
goto error;
|
||||
}
|
||||
pkey = EVP_PKEY_dup(key->key);
|
||||
if (pkey == NULL) {
|
||||
SSH_LOG(SSH_LOG_TRACE, "Out of memory");
|
||||
rc = EVP_PKEY_uo_ref(key->key);
|
||||
if (rc != 1) {
|
||||
SSH_LOG(SSH_LOG_TRACE, "Failed to reference EVP_PKEY");
|
||||
return NULL;
|
||||
}
|
||||
pkey = key->key;
|
||||
break;
|
||||
#endif /* OPENSSL_VERSION_NUMBER */
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
@@ -3102,9 +3137,7 @@ out:
|
||||
explicit_bzero(raw_sig_data, raw_sig_len);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -3230,16 +3263,14 @@ out:
|
||||
if (ctx != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
int ssh_key_size(ssh_key key)
|
||||
{
|
||||
int bits = 0;
|
||||
EVP_PKEY *pkey;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
switch (key->type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
@@ -3260,17 +3291,7 @@ int ssh_key_size(ssh_key key)
|
||||
return SSH_ERROR;
|
||||
}
|
||||
bits = EVP_PKEY_bits(pkey);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
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;
|
||||
case SSH_KEYTYPE_ED25519:
|
||||
case SSH_KEYTYPE_ED25519_CERT01:
|
||||
@@ -3437,29 +3458,13 @@ int pki_uri_import(const char *uri_name,
|
||||
#endif
|
||||
ssh_key key = NULL;
|
||||
enum ssh_keytypes_e type = SSH_KEYTYPE_UNKNOWN;
|
||||
int ok;
|
||||
|
||||
ENGINE_load_builtin_engines();
|
||||
|
||||
engine = ENGINE_by_id("pkcs11");
|
||||
/* Do the init only once */
|
||||
engine = pki_get_engine();
|
||||
if (engine == NULL) {
|
||||
SSH_LOG(SSH_LOG_WARN,
|
||||
"Could not load the engine: %s",
|
||||
ERR_error_string(ERR_get_error(),NULL));
|
||||
return SSH_ERROR;
|
||||
SSH_LOG(SSH_LOG_WARN, "Failed to initialize engine");
|
||||
goto fail;
|
||||
}
|
||||
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) {
|
||||
case SSH_KEY_PRIVATE:
|
||||
@@ -3541,10 +3546,9 @@ int pki_uri_import(const char *uri_name,
|
||||
key->key = pkey;
|
||||
key->type = 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) {
|
||||
key->flags = SSH_KEY_FLAG_PUBLIC | SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PKCS11_URI;
|
||||
} else {
|
||||
key->flags = SSH_KEY_FLAG_PUBLIC | SSH_KEY_FLAG_PKCS11_URI;
|
||||
key->flags |= SSH_KEY_FLAG_PRIVATE;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
key->rsa = rsa;
|
||||
@@ -3569,14 +3573,10 @@ int pki_uri_import(const char *uri_name,
|
||||
#endif
|
||||
|
||||
*nkey = key;
|
||||
ENGINE_finish(engine);
|
||||
ENGINE_free(engine);
|
||||
|
||||
return SSH_OK;
|
||||
|
||||
fail:
|
||||
ENGINE_finish(engine);
|
||||
ENGINE_free(engine);
|
||||
EVP_PKEY_free(pkey);
|
||||
ssh_key_free(key);
|
||||
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
||||
|
||||
@@ -283,6 +283,23 @@ static int passphrase_to_key(char *data, unsigned int datalen,
|
||||
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,
|
||||
unsigned char *iv, unsigned int iv_len,
|
||||
ssh_buffer data, ssh_auth_callback cb,
|
||||
|
||||
@@ -38,6 +38,22 @@
|
||||
#define MAX_PASSPHRASE_SIZE 1024
|
||||
#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_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_key key = NULL;
|
||||
mbedtls_pk_context *rsa = NULL;
|
||||
mbedtls_pk_context *ecdsa = NULL;
|
||||
ed25519_privkey *ed25519 = NULL;
|
||||
enum ssh_keytypes_e type;
|
||||
mbedtls_pk_context *pk = NULL;
|
||||
mbedtls_pk_type_t mbed_type;
|
||||
int valid;
|
||||
/* mbedtls pk_parse_key expects strlen to count the 0 byte */
|
||||
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();
|
||||
#endif
|
||||
|
||||
type = pki_privatekey_type_from_string(b64_key);
|
||||
if (type == SSH_KEYTYPE_UNKNOWN) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Unknown or invalid private key.");
|
||||
return NULL;
|
||||
pk = malloc(sizeof(mbedtls_pk_context));
|
||||
if (pk == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
mbedtls_pk_init(pk);
|
||||
|
||||
switch (type) {
|
||||
case SSH_KEYTYPE_RSA:
|
||||
rsa = malloc(sizeof(mbedtls_pk_context));
|
||||
if (rsa == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mbedtls_pk_init(rsa);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA_P256:
|
||||
case SSH_KEYTYPE_ECDSA_P384:
|
||||
case SSH_KEYTYPE_ECDSA_P521:
|
||||
#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
|
||||
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
|
||||
if (ecdsa == NULL) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
#if MBEDTLS_VERSION_MAJOR > 2
|
||||
valid = mbedtls_pk_parse_key(ecdsa,
|
||||
(const unsigned char *) b64_key,
|
||||
b64len, tmp,
|
||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE),
|
||||
mbedtls_ctr_drbg_random, ctr_drbg);
|
||||
valid = mbedtls_pk_parse_key(pk,
|
||||
(const unsigned char *)b64_key,
|
||||
b64len,
|
||||
NULL,
|
||||
0,
|
||||
mbedtls_ctr_drbg_random,
|
||||
ctr_drbg);
|
||||
#else
|
||||
valid = mbedtls_pk_parse_key(ecdsa,
|
||||
(const unsigned char *) b64_key,
|
||||
b64len, tmp,
|
||||
strnlen((const char *) tmp, MAX_PASSPHRASE_SIZE));
|
||||
valid = mbedtls_pk_parse_key(pk,
|
||||
(const unsigned char *)b64_key,
|
||||
b64len,
|
||||
NULL,
|
||||
0);
|
||||
#endif
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
#if MBEDTLS_VERSION_MAJOR > 2
|
||||
valid = mbedtls_pk_parse_key(ecdsa,
|
||||
(const unsigned char *) b64_key,
|
||||
b64len, NULL,
|
||||
0, mbedtls_ctr_drbg_random, ctr_drbg);
|
||||
valid = mbedtls_pk_parse_key(pk,
|
||||
(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, NULL,
|
||||
0);
|
||||
valid = mbedtls_pk_parse_key(pk,
|
||||
(const unsigned char *)b64_key,
|
||||
b64len,
|
||||
(const unsigned char *)passphrase,
|
||||
strnlen(passphrase, MAX_PASSPHRASE_SIZE));
|
||||
#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();
|
||||
if (key == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ecdsa != NULL) {
|
||||
mbedtls_ecp_keypair *keypair = mbedtls_pk_ec(*ecdsa);
|
||||
switch (mbed_type) {
|
||||
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));
|
||||
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_from_keypair(key->ecdsa, keypair);
|
||||
mbedtls_pk_free(ecdsa);
|
||||
SAFE_FREE(ecdsa);
|
||||
mbedtls_pk_free(pk);
|
||||
SAFE_FREE(pk);
|
||||
|
||||
key->ecdsa_nid = pki_key_ecdsa_to_nid(key->ecdsa);
|
||||
|
||||
/* pki_privatekey_type_from_string always returns P256 for ECDSA
|
||||
* keys, so we need to figure out the correct type here */
|
||||
type = pki_key_ecdsa_to_key_type(key->ecdsa);
|
||||
if (type == SSH_KEYTYPE_UNKNOWN) {
|
||||
* keys, so we need to figure out the correct type here */
|
||||
key->type = pki_key_ecdsa_to_key_type(key->ecdsa);
|
||||
if (key->type == SSH_KEYTYPE_UNKNOWN) {
|
||||
SSH_LOG(SSH_LOG_WARN, "Invalid private key.");
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
key->ecdsa = NULL;
|
||||
break;
|
||||
}
|
||||
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(type);
|
||||
key->type_c = ssh_key_type_to_char(key->type);
|
||||
key->flags = SSH_KEY_FLAG_PRIVATE | SSH_KEY_FLAG_PUBLIC;
|
||||
key->rsa = rsa;
|
||||
key->ed25519_privkey = ed25519;
|
||||
rsa = NULL;
|
||||
ecdsa = NULL;
|
||||
|
||||
return key;
|
||||
fail:
|
||||
ssh_key_free(key);
|
||||
if (rsa != NULL) {
|
||||
mbedtls_pk_free(rsa);
|
||||
SAFE_FREE(rsa);
|
||||
}
|
||||
if (ecdsa != NULL) {
|
||||
mbedtls_pk_free(ecdsa);
|
||||
SAFE_FREE(ecdsa);
|
||||
if (pk != NULL) {
|
||||
mbedtls_pk_free(pk);
|
||||
SAFE_FREE(pk);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -361,7 +361,6 @@ static void ssh_server_connection_callback(ssh_session session){
|
||||
}
|
||||
|
||||
/* 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_set_default_callbacks(session);
|
||||
|
||||
@@ -301,6 +301,7 @@ void ssh_free(ssh_session session)
|
||||
SAFE_FREE(session->banner);
|
||||
SAFE_FREE(session->disconnect_message);
|
||||
|
||||
SAFE_FREE(session->opts.agent_socket);
|
||||
SAFE_FREE(session->opts.bindaddr);
|
||||
SAFE_FREE(session->opts.custombanner);
|
||||
SAFE_FREE(session->opts.moduli_file);
|
||||
@@ -1126,7 +1127,7 @@ int ssh_get_publickey_hash(const ssh_key key,
|
||||
size_t *hlen)
|
||||
{
|
||||
ssh_string blob;
|
||||
unsigned char *h;
|
||||
unsigned char *h = NULL;
|
||||
int rc;
|
||||
|
||||
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_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 LSAN_OPTIONS=suppressions=${CMAKE_CURRENT_SOURCE_DIR}/suppressions/lsan.supp)
|
||||
|
||||
# Give bob some keys
|
||||
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 ALICE_HOME BINARYDIR "/tests/home/alice"
|
||||
|
||||
/* store the original umask */
|
||||
mode_t old;
|
||||
|
||||
struct scp_st {
|
||||
struct torture_state *s;
|
||||
char *tmp_dir;
|
||||
@@ -99,6 +102,9 @@ static int session_setup(void **state)
|
||||
|
||||
s = ts->s;
|
||||
|
||||
/* store the original umask and set a new one */
|
||||
old = umask(0022);
|
||||
|
||||
/* Create temporary directory for alice */
|
||||
tmp_dir = torture_make_temp_dir(TEMPLATE);
|
||||
assert_non_null(tmp_dir);
|
||||
@@ -135,6 +141,9 @@ static int session_teardown(void **state)
|
||||
assert_non_null(ts->s);
|
||||
s = ts->s;
|
||||
|
||||
/* restore the umask */
|
||||
umask(old);
|
||||
|
||||
ssh_disconnect(s->ssh.session);
|
||||
ssh_free(s->ssh.session);
|
||||
|
||||
|
||||
@@ -22,26 +22,58 @@ add_library(poly1305_override SHARED
|
||||
set(POLY1305_OVERRIDE_LIBRARY
|
||||
${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
|
||||
add_library(ed25519_override SHARED
|
||||
ed25519_override.c
|
||||
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
||||
)
|
||||
ed25519_override.c
|
||||
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
||||
${override_src}
|
||||
)
|
||||
target_link_libraries(ed25519_override
|
||||
PRIVATE ${override_libs})
|
||||
set(ED25519_OVERRIDE_LIBRARY
|
||||
${libssh_BINARY_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}ed25519_override${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
|
||||
# curve25519_override
|
||||
add_library(curve25519_override SHARED
|
||||
curve25519_override.c
|
||||
${libssh_SOURCE_DIR}/src/external/curve25519_ref.c
|
||||
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
||||
)
|
||||
curve25519_override.c
|
||||
${libssh_SOURCE_DIR}/src/external/curve25519_ref.c
|
||||
${libssh_SOURCE_DIR}/src/external/fe25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ge25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/sc25519.c
|
||||
${libssh_SOURCE_DIR}/src/external/ed25519.c
|
||||
${override_src}
|
||||
)
|
||||
target_link_libraries(curve25519_override
|
||||
PRIVATE ${override_libs})
|
||||
set(CURVE25519_OVERRIDE_LIBRARY
|
||||
${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 */
|
||||
/* OPENSSL variable is needed to enable SHA1 */
|
||||
printed = snprintf(env, sizeof(env),
|
||||
"SOCKET_WRAPPER_DIR=%s "
|
||||
"SOCKET_WRAPPER_DEFAULT_IFACE=10 "
|
||||
"LD_PRELOAD=%s "
|
||||
"%s",
|
||||
"%s "
|
||||
"OPENSSL_ENABLE_SHA1_SIGNATURES=1",
|
||||
s->socket_dir, ld_preload, force_fips);
|
||||
if (printed < 0) {
|
||||
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}
|
||||
LINK_LIBRARIES ${TEST_TARGET_LIBRARIES}
|
||||
)
|
||||
|
||||
set_property(TEST ${_UNIT_TEST}
|
||||
PROPERTY
|
||||
ENVIRONMENT LSAN_OPTIONS=suppressions=${libssh-tests_SOURCE_DIR}/suppressions/lsan.supp)
|
||||
endforeach()
|
||||
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
@@ -110,6 +114,10 @@ if (CMAKE_USE_PTHREADS_INIT)
|
||||
COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS}
|
||||
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()
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -66,6 +66,13 @@ static void torture_options_set_host(void **state) {
|
||||
assert_string_equal(session->opts.host, "meditation");
|
||||
assert_non_null(session->opts.username);
|
||||
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) {
|
||||
|
||||
@@ -93,6 +93,7 @@ static int setup_directory_structure(void **state)
|
||||
|
||||
rc = torture_change_dir(temp_dir);
|
||||
assert_int_equal(rc, 0);
|
||||
SAFE_FREE(temp_dir);
|
||||
|
||||
test_state->temp_dir = torture_get_current_working_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_true(rc == SSH_OK);
|
||||
assert_non_null(pblob);
|
||||
ssh_string_free(pblob);
|
||||
|
||||
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
assert_int_not_equal(rc, 0);
|
||||
assert_null(pblob);
|
||||
ssh_string_free(pblob);
|
||||
|
||||
rc = ssh_pki_export_privkey_to_pubkey(privkey, &pubkey);
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
etype_char = ssh_pki_key_ecdsa_name(privkey);
|
||||
|
||||
switch(dig_type) {
|
||||
switch (dig_type) {
|
||||
case SSH_DIGEST_SHA256:
|
||||
assert_true(type == SSH_KEYTYPE_ECDSA_P256);
|
||||
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);
|
||||
}
|
||||
|
||||
ssh_free(session);
|
||||
ssh_signature_free(sign);
|
||||
SSH_KEY_FREE(privkey);
|
||||
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_521),
|
||||
};
|
||||
|
||||
ssh_session session = ssh_new();
|
||||
int verbosity = SSH_LOG_FUNCTIONS;
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
|
||||
ssh_init();
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
|
||||
torture_filter_tests(tests);
|
||||
rc = cmocka_run_group_tests(tests, setup_directory_structure, teardown_directory_structure);
|
||||
|
||||
ssh_free(session);
|
||||
ssh_finalize();
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -541,9 +541,13 @@ static void torture_pki_rsa_generate_key(void **state)
|
||||
int rc;
|
||||
ssh_key key = NULL, pubkey = NULL;
|
||||
ssh_signature sign = NULL;
|
||||
ssh_session session=ssh_new();
|
||||
ssh_session session = ssh_new();
|
||||
int verbosity = torture_libssh_verbosity();
|
||||
|
||||
(void) state;
|
||||
|
||||
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
|
||||
|
||||
if (!ssh_fips_mode()) {
|
||||
rc = ssh_pki_generate(SSH_KEYTYPE_RSA, 1024, &key);
|
||||
assert_true(rc == SSH_OK);
|
||||
|
||||
Reference in New Issue
Block a user