mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-12-08 03:42:12 +03:00
The previous code created private key curve25519 in OpenSSL, then exported private key and during key generation, created a new OpenSSL private key object. This is needless amount of copying potentially sensitive data back and forth and this will not work when the private key would be backed with external OpenSSL provider, such as pkcs11 provider or different crypto accelerator handling the private key operations for us. Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Sahana Prasad <sahana@redhat.com>
616 lines
19 KiB
C
616 lines
19 KiB
C
/*
|
|
* wrapper.c - wrapper for crypto functions
|
|
*
|
|
* This file is part of the SSH Library
|
|
*
|
|
* Copyright (c) 2003-2013 by Aris Adamantiadis
|
|
*
|
|
* The SSH Library is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* Why a wrapper?
|
|
*
|
|
* Let's say you want to port libssh from libcrypto of openssl to libfoo
|
|
* you are going to spend hours removing every reference to SHA1_Update()
|
|
* to libfoo_sha1_update after the work is finished, you're going to have
|
|
* only this file to modify it's not needed to say that your modifications
|
|
* are welcome.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#ifdef WITH_ZLIB
|
|
#include <zlib.h>
|
|
#endif
|
|
|
|
#include "libssh/priv.h"
|
|
#include "libssh/session.h"
|
|
#include "libssh/crypto.h"
|
|
#include "libssh/wrapper.h"
|
|
#include "libssh/pki.h"
|
|
#include "libssh/poly1305.h"
|
|
#include "libssh/dh.h"
|
|
#ifdef WITH_GEX
|
|
#include "libssh/dh-gex.h"
|
|
#endif /* WITH_GEX */
|
|
#include "libssh/ecdh.h"
|
|
#include "libssh/curve25519.h"
|
|
|
|
static struct ssh_hmac_struct ssh_hmac_tab[] = {
|
|
{ "hmac-sha1", SSH_HMAC_SHA1, false },
|
|
{ "hmac-sha2-256", SSH_HMAC_SHA256, false },
|
|
{ "hmac-sha2-512", SSH_HMAC_SHA512, false },
|
|
{ "hmac-md5", SSH_HMAC_MD5, false },
|
|
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305, false },
|
|
{ "aead-gcm", SSH_HMAC_AEAD_GCM, false },
|
|
{ "hmac-sha1-etm@openssh.com", SSH_HMAC_SHA1, true },
|
|
{ "hmac-sha2-256-etm@openssh.com", SSH_HMAC_SHA256, true },
|
|
{ "hmac-sha2-512-etm@openssh.com", SSH_HMAC_SHA512, true },
|
|
{ "hmac-md5-etm@openssh.com", SSH_HMAC_MD5, true },
|
|
#ifdef WITH_INSECURE_NONE
|
|
{ "none", SSH_HMAC_NONE, false },
|
|
#endif /* WITH_INSECURE_NONE */
|
|
{ NULL, 0, false }
|
|
};
|
|
|
|
struct ssh_hmac_struct *ssh_get_hmactab(void) {
|
|
return ssh_hmac_tab;
|
|
}
|
|
|
|
size_t hmac_digest_len(enum ssh_hmac_e type) {
|
|
switch(type) {
|
|
case SSH_HMAC_SHA1:
|
|
return SHA_DIGEST_LEN;
|
|
case SSH_HMAC_SHA256:
|
|
return SHA256_DIGEST_LEN;
|
|
case SSH_HMAC_SHA512:
|
|
return SHA512_DIGEST_LEN;
|
|
case SSH_HMAC_MD5:
|
|
return MD5_DIGEST_LEN;
|
|
case SSH_HMAC_AEAD_POLY1305:
|
|
return POLY1305_TAGLEN;
|
|
case SSH_HMAC_AEAD_GCM:
|
|
return AES_GCM_TAGLEN;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type, bool etm)
|
|
{
|
|
int i = 0;
|
|
struct ssh_hmac_struct *ssh_hmactab = ssh_get_hmactab();
|
|
while (ssh_hmactab[i].name &&
|
|
((ssh_hmactab[i].hmac_type != hmac_type) ||
|
|
(ssh_hmactab[i].etm != etm))) {
|
|
i++;
|
|
}
|
|
return ssh_hmactab[i].name;
|
|
}
|
|
|
|
/* it allocates a new cipher structure based on its offset into the global table */
|
|
static struct ssh_cipher_struct *cipher_new(uint8_t offset) {
|
|
struct ssh_cipher_struct *cipher = NULL;
|
|
|
|
cipher = malloc(sizeof(struct ssh_cipher_struct));
|
|
if (cipher == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
/* note the memcpy will copy the pointers : so, you shouldn't free them */
|
|
memcpy(cipher, &ssh_get_ciphertab()[offset], sizeof(*cipher));
|
|
|
|
return cipher;
|
|
}
|
|
|
|
void ssh_cipher_clear(struct ssh_cipher_struct *cipher){
|
|
#ifdef HAVE_LIBGCRYPT
|
|
unsigned int i;
|
|
#endif
|
|
|
|
if (cipher == NULL) {
|
|
return;
|
|
}
|
|
|
|
#ifdef HAVE_LIBGCRYPT
|
|
if (cipher->key) {
|
|
for (i = 0; i < (cipher->keylen / sizeof(gcry_cipher_hd_t)); i++) {
|
|
gcry_cipher_close(cipher->key[i]);
|
|
}
|
|
SAFE_FREE(cipher->key);
|
|
}
|
|
#endif
|
|
|
|
if (cipher->cleanup != NULL) {
|
|
cipher->cleanup(cipher);
|
|
}
|
|
}
|
|
|
|
static void cipher_free(struct ssh_cipher_struct *cipher) {
|
|
ssh_cipher_clear(cipher);
|
|
SAFE_FREE(cipher);
|
|
}
|
|
|
|
struct ssh_crypto_struct *crypto_new(void)
|
|
{
|
|
struct ssh_crypto_struct *crypto;
|
|
|
|
crypto = calloc(1, sizeof(struct ssh_crypto_struct));
|
|
if (crypto == NULL) {
|
|
return NULL;
|
|
}
|
|
return crypto;
|
|
}
|
|
|
|
void crypto_free(struct ssh_crypto_struct *crypto)
|
|
{
|
|
size_t i;
|
|
|
|
if (crypto == NULL) {
|
|
return;
|
|
}
|
|
|
|
ssh_key_free(crypto->server_pubkey);
|
|
|
|
ssh_dh_cleanup(crypto);
|
|
bignum_safe_free(crypto->shared_secret);
|
|
#ifdef HAVE_ECDH
|
|
SAFE_FREE(crypto->ecdh_client_pubkey);
|
|
SAFE_FREE(crypto->ecdh_server_pubkey);
|
|
if (crypto->ecdh_privkey != NULL) {
|
|
#ifdef HAVE_OPENSSL_ECC
|
|
#if OPENSSL_VERSION_NUMBER < 0x30000000L
|
|
EC_KEY_free(crypto->ecdh_privkey);
|
|
#else
|
|
EVP_PKEY_free(crypto->ecdh_privkey);
|
|
#endif /* OPENSSL_VERSION_NUMBER */
|
|
#elif defined HAVE_GCRYPT_ECC
|
|
gcry_sexp_release(crypto->ecdh_privkey);
|
|
#endif
|
|
crypto->ecdh_privkey = NULL;
|
|
}
|
|
#endif
|
|
#ifdef HAVE_LIBCRYPTO
|
|
EVP_PKEY_free(crypto->curve25519_privkey);
|
|
#endif
|
|
SAFE_FREE(crypto->dh_server_signature);
|
|
if (crypto->session_id != NULL) {
|
|
explicit_bzero(crypto->session_id, crypto->session_id_len);
|
|
SAFE_FREE(crypto->session_id);
|
|
}
|
|
if (crypto->secret_hash != NULL) {
|
|
explicit_bzero(crypto->secret_hash, crypto->digest_len);
|
|
SAFE_FREE(crypto->secret_hash);
|
|
}
|
|
#ifdef WITH_ZLIB
|
|
if (crypto->compress_out_ctx) {
|
|
deflateEnd(crypto->compress_out_ctx);
|
|
}
|
|
SAFE_FREE(crypto->compress_out_ctx);
|
|
|
|
if (crypto->compress_in_ctx) {
|
|
inflateEnd(crypto->compress_in_ctx);
|
|
}
|
|
SAFE_FREE(crypto->compress_in_ctx);
|
|
#endif /* WITH_ZLIB */
|
|
SAFE_FREE(crypto->encryptIV);
|
|
SAFE_FREE(crypto->decryptIV);
|
|
SAFE_FREE(crypto->encryptMAC);
|
|
SAFE_FREE(crypto->decryptMAC);
|
|
if (crypto->encryptkey != NULL) {
|
|
explicit_bzero(crypto->encryptkey, crypto->out_cipher->keysize / 8);
|
|
SAFE_FREE(crypto->encryptkey);
|
|
}
|
|
if (crypto->decryptkey != NULL) {
|
|
explicit_bzero(crypto->decryptkey, crypto->in_cipher->keysize / 8);
|
|
SAFE_FREE(crypto->decryptkey);
|
|
}
|
|
|
|
cipher_free(crypto->in_cipher);
|
|
cipher_free(crypto->out_cipher);
|
|
|
|
for (i = 0; i < SSH_KEX_METHODS; i++) {
|
|
SAFE_FREE(crypto->client_kex.methods[i]);
|
|
SAFE_FREE(crypto->server_kex.methods[i]);
|
|
SAFE_FREE(crypto->kex_methods[i]);
|
|
}
|
|
|
|
explicit_bzero(crypto, sizeof(struct ssh_crypto_struct));
|
|
|
|
SAFE_FREE(crypto);
|
|
}
|
|
|
|
static void
|
|
compression_enable(ssh_session session,
|
|
enum ssh_crypto_direction_e direction,
|
|
bool delayed)
|
|
{
|
|
/* The delayed compression is turned on AFTER authentication. This means
|
|
* that we need to turn it on immediately in case of rekeying */
|
|
if (delayed && !(session->flags & SSH_SESSION_FLAG_AUTHENTICATED)) {
|
|
if (direction == SSH_DIRECTION_IN) {
|
|
session->next_crypto->delayed_compress_in = 1;
|
|
} else { /* SSH_DIRECTION_OUT */
|
|
session->next_crypto->delayed_compress_out = 1;
|
|
}
|
|
} else {
|
|
if (direction == SSH_DIRECTION_IN) {
|
|
session->next_crypto->do_compress_in = 1;
|
|
} else { /* SSH_DIRECTION_OUT */
|
|
session->next_crypto->do_compress_out = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static int crypt_set_algorithms2(ssh_session session)
|
|
{
|
|
const char *wanted = NULL;
|
|
const char *method = NULL;
|
|
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
|
|
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
|
|
uint8_t i = 0;
|
|
int cmp;
|
|
|
|
/*
|
|
* We must scan the kex entries to find crypto algorithms and set their
|
|
* appropriate structure.
|
|
*/
|
|
|
|
/* out */
|
|
wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
|
|
for (i = 0; i < 64 && ssh_ciphertab[i].name != NULL; ++i) {
|
|
cmp = strcmp(wanted, ssh_ciphertab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_ciphertab[i].name == NULL) {
|
|
ssh_set_error(session, SSH_FATAL,
|
|
"crypt_set_algorithms2: no crypto algorithm function found for %s",
|
|
wanted);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET, "Set output algorithm to %s", wanted);
|
|
|
|
session->next_crypto->out_cipher = cipher_new(i);
|
|
if (session->next_crypto->out_cipher == NULL) {
|
|
ssh_set_error_oom(session);
|
|
return SSH_ERROR;
|
|
}
|
|
|
|
if (session->next_crypto->out_cipher->aead_encrypt != NULL) {
|
|
/* this cipher has integrated MAC */
|
|
if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
|
wanted = "aead-poly1305";
|
|
} else {
|
|
wanted = "aead-gcm";
|
|
}
|
|
} else {
|
|
/*
|
|
* We must scan the kex entries to find hmac algorithms and set their
|
|
* appropriate structure.
|
|
*/
|
|
|
|
/* out */
|
|
wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
|
|
}
|
|
|
|
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
|
cmp = strcmp(wanted, ssh_hmactab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_hmactab[i].name == NULL) {
|
|
ssh_set_error(session, SSH_FATAL,
|
|
"crypt_set_algorithms2: no hmac algorithm function found for %s",
|
|
wanted);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
|
|
|
|
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
|
|
session->next_crypto->out_hmac_etm = ssh_hmactab[i].etm;
|
|
|
|
/* in */
|
|
wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
|
|
|
|
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
|
|
cmp = strcmp(wanted, ssh_ciphertab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_ciphertab[i].name == NULL) {
|
|
ssh_set_error(session, SSH_FATAL,
|
|
"Crypt_set_algorithms: no crypto algorithm function found for %s",
|
|
wanted);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET, "Set input algorithm to %s", wanted);
|
|
|
|
session->next_crypto->in_cipher = cipher_new(i);
|
|
if (session->next_crypto->in_cipher == NULL) {
|
|
ssh_set_error_oom(session);
|
|
return SSH_ERROR;
|
|
}
|
|
|
|
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
|
/* this cipher has integrated MAC */
|
|
if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
|
wanted = "aead-poly1305";
|
|
} else {
|
|
wanted = "aead-gcm";
|
|
}
|
|
} else {
|
|
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
|
wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
|
|
}
|
|
|
|
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
|
cmp = strcmp(wanted, ssh_hmactab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_hmactab[i].name == NULL) {
|
|
ssh_set_error(session, SSH_FATAL,
|
|
"crypt_set_algorithms2: no hmac algorithm function found for %s",
|
|
wanted);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", wanted);
|
|
|
|
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
|
|
session->next_crypto->in_hmac_etm = ssh_hmactab[i].etm;
|
|
|
|
/* compression: client */
|
|
method = session->next_crypto->kex_methods[SSH_COMP_C_S];
|
|
cmp = strcmp(method, "zlib");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling C->S compression");
|
|
compression_enable(session, SSH_DIRECTION_OUT, false);
|
|
}
|
|
cmp = strcmp(method, "zlib@openssh.com");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling C->S delayed compression");
|
|
compression_enable(session, SSH_DIRECTION_OUT, true);
|
|
}
|
|
|
|
method = session->next_crypto->kex_methods[SSH_COMP_S_C];
|
|
cmp = strcmp(method, "zlib");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression");
|
|
compression_enable(session, SSH_DIRECTION_IN, false);
|
|
}
|
|
cmp = strcmp(method, "zlib@openssh.com");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling S->C delayed compression");
|
|
compression_enable(session, SSH_DIRECTION_IN, true);
|
|
}
|
|
|
|
return SSH_OK;
|
|
}
|
|
|
|
int crypt_set_algorithms_client(ssh_session session)
|
|
{
|
|
return crypt_set_algorithms2(session);
|
|
}
|
|
|
|
#ifdef WITH_SERVER
|
|
int crypt_set_algorithms_server(ssh_session session){
|
|
const char *method = NULL;
|
|
uint8_t i = 0;
|
|
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
|
|
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
|
|
int cmp;
|
|
|
|
if (session == NULL) {
|
|
return SSH_ERROR;
|
|
}
|
|
|
|
/*
|
|
* We must scan the kex entries to find crypto algorithms and set their
|
|
* appropriate structure
|
|
*/
|
|
/* out */
|
|
method = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
|
|
|
|
for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
|
|
cmp = strcmp(method, ssh_ciphertab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_ciphertab[i].name == NULL) {
|
|
ssh_set_error(session,SSH_FATAL,"crypt_set_algorithms_server : "
|
|
"no crypto algorithm function found for %s",method);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET,"Set output algorithm %s",method);
|
|
|
|
session->next_crypto->out_cipher = cipher_new(i);
|
|
if (session->next_crypto->out_cipher == NULL) {
|
|
ssh_set_error_oom(session);
|
|
return SSH_ERROR;
|
|
}
|
|
|
|
if (session->next_crypto->out_cipher->aead_encrypt != NULL){
|
|
/* this cipher has integrated MAC */
|
|
if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
|
method = "aead-poly1305";
|
|
} else {
|
|
method = "aead-gcm";
|
|
}
|
|
} else {
|
|
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
|
/* out */
|
|
method = session->next_crypto->kex_methods[SSH_MAC_S_C];
|
|
}
|
|
/* HMAC algorithm selection */
|
|
|
|
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
|
cmp = strcmp(method, ssh_hmactab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_hmactab[i].name == NULL) {
|
|
ssh_set_error(session, SSH_FATAL,
|
|
"crypt_set_algorithms_server: no hmac algorithm function found for %s",
|
|
method);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", method);
|
|
|
|
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
|
|
session->next_crypto->out_hmac_etm = ssh_hmactab[i].etm;
|
|
|
|
/* in */
|
|
method = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
|
|
|
|
for (i = 0; ssh_ciphertab[i].name; i++) {
|
|
cmp = strcmp(method, ssh_ciphertab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_ciphertab[i].name == NULL) {
|
|
ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server :"
|
|
"no crypto algorithm function found for %s",method);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET,"Set input algorithm %s",method);
|
|
|
|
session->next_crypto->in_cipher = cipher_new(i);
|
|
if (session->next_crypto->in_cipher == NULL) {
|
|
ssh_set_error_oom(session);
|
|
return SSH_ERROR;
|
|
}
|
|
|
|
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
|
/* this cipher has integrated MAC */
|
|
if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
|
method = "aead-poly1305";
|
|
} else {
|
|
method = "aead-gcm";
|
|
}
|
|
} else {
|
|
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
|
method = session->next_crypto->kex_methods[SSH_MAC_C_S];
|
|
}
|
|
|
|
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
|
|
cmp = strcmp(method, ssh_hmactab[i].name);
|
|
if (cmp == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ssh_hmactab[i].name == NULL) {
|
|
ssh_set_error(session, SSH_FATAL,
|
|
"crypt_set_algorithms_server: no hmac algorithm function found for %s",
|
|
method);
|
|
return SSH_ERROR;
|
|
}
|
|
SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", method);
|
|
|
|
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
|
|
session->next_crypto->in_hmac_etm = ssh_hmactab[i].etm;
|
|
|
|
/* compression */
|
|
method = session->next_crypto->kex_methods[SSH_COMP_C_S];
|
|
cmp = strcmp(method, "zlib");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling C->S compression");
|
|
compression_enable(session, SSH_DIRECTION_IN, false);
|
|
}
|
|
cmp = strcmp(method, "zlib@openssh.com");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling C->S delayed compression");
|
|
compression_enable(session, SSH_DIRECTION_IN, true);
|
|
}
|
|
|
|
method = session->next_crypto->kex_methods[SSH_COMP_S_C];
|
|
cmp = strcmp(method, "zlib");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling S->C compression");
|
|
compression_enable(session, SSH_DIRECTION_OUT, false);
|
|
}
|
|
cmp = strcmp(method, "zlib@openssh.com");
|
|
if (cmp == 0) {
|
|
SSH_LOG(SSH_LOG_PACKET, "enabling S->C delayed compression");
|
|
compression_enable(session, SSH_DIRECTION_OUT, true);
|
|
}
|
|
|
|
method = session->next_crypto->kex_methods[SSH_HOSTKEYS];
|
|
session->srv.hostkey = ssh_key_type_from_signature_name(method);
|
|
session->srv.hostkey_digest = ssh_key_hash_from_name(method);
|
|
|
|
/* setup DH key exchange type */
|
|
switch (session->next_crypto->kex_type) {
|
|
case SSH_KEX_DH_GROUP1_SHA1:
|
|
case SSH_KEX_DH_GROUP14_SHA1:
|
|
case SSH_KEX_DH_GROUP14_SHA256:
|
|
case SSH_KEX_DH_GROUP16_SHA512:
|
|
case SSH_KEX_DH_GROUP18_SHA512:
|
|
ssh_server_dh_init(session);
|
|
break;
|
|
#ifdef WITH_GEX
|
|
case SSH_KEX_DH_GEX_SHA1:
|
|
case SSH_KEX_DH_GEX_SHA256:
|
|
ssh_server_dhgex_init(session);
|
|
break;
|
|
#endif /* WITH_GEX */
|
|
#ifdef HAVE_ECDH
|
|
case SSH_KEX_ECDH_SHA2_NISTP256:
|
|
case SSH_KEX_ECDH_SHA2_NISTP384:
|
|
case SSH_KEX_ECDH_SHA2_NISTP521:
|
|
ssh_server_ecdh_init(session);
|
|
break;
|
|
#endif
|
|
#ifdef HAVE_CURVE25519
|
|
case SSH_KEX_CURVE25519_SHA256:
|
|
case SSH_KEX_CURVE25519_SHA256_LIBSSH_ORG:
|
|
ssh_server_curve25519_init(session);
|
|
break;
|
|
#endif
|
|
default:
|
|
ssh_set_error(session,
|
|
SSH_FATAL,
|
|
"crypt_set_algorithms_server: could not find init "
|
|
"handler for kex type %d",
|
|
session->next_crypto->kex_type);
|
|
return SSH_ERROR;
|
|
}
|
|
return SSH_OK;
|
|
}
|
|
|
|
#endif /* WITH_SERVER */
|