Revision: 9210 https://osdn.net/projects/ttssh2/scm/svn/commits/9210 Author: nmaya Date: 2021-04-17 17:36:59 +0900 (Sat, 17 Apr 2021) Log Message: ----------- ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート - OpenSSH からインポート cipher-3des1.c from OpenSSH-7.5p1 ssherr.c from OpenSSH-8.5p1 ssherr.h from OpenSSH-8.5p1 Modified Paths: -------------- branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj Added Paths: ----------- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h -------------- next part -------------- Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -94,7 +94,7 @@ } static LRESULT CALLBACK password_wnd_proc(HWND control, UINT msg, - WPARAM wParam, LPARAM lParam) + WPARAM wParam, LPARAM lParam) { LRESULT result; TPasswordControlData *data = (TPasswordControlData *)GetWindowLongPtr(control, GWLP_USERDATA); @@ -797,7 +797,7 @@ static INT_PTR CALLBACK auth_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam) { const int IDC_TIMER1 = 300; // \x8E\xA9\x93\xAE\x83\x8D\x83O\x83C\x83\x93\x82\xAA\x97L\x8C\xF8\x82ȂƂ\xAB const int IDC_TIMER2 = 301; // \x83T\x83|\x81[\x83g\x82\xB3\x82\xEA\x82Ă\xA2\x82郁\x83\\x83b\x83h\x82\xF0\x8E\xA9\x93\xAE\x83`\x83F\x83b\x83N(CheckAuthListFirst) @@ -1406,7 +1406,7 @@ } static INT_PTR CALLBACK TIS_dlg_proc(HWND dlg, UINT msg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam) { PTInstVar pvar; @@ -1618,7 +1618,7 @@ } static INT_PTR CALLBACK default_auth_dlg_proc(HWND dlg, UINT msg, - WPARAM wParam, LPARAM lParam) + WPARAM wParam, LPARAM lParam) { PTInstVar pvar; @@ -1811,7 +1811,7 @@ s[key_len] = '\0'; UTIL_get_lang_msg("DLG_ABOUT_AUTH_INFO3", pvar, " with %s key from Pageant"); _snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg, - ssh_key_type(get_keytype_from_name(s))); + ssh_key_type(get_hostkey_type_from_name(s))); strncat_s(dest, len, buf, _TRUNCATE); free(s); Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -41,7 +41,7 @@ SSHAuthMethod method; char *password; char *rhosts_client_user; - struct Key *key_pair; + Key *key_pair; } AUTHCred; typedef enum { GENERIC_AUTH_MODE, TIS_AUTH_MODE } AuthMode; Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,172 @@ +/* Imported from OpenSSH-7.5p1, TeraTerm Project */ + +/* $OpenBSD: cipher-3des1.c,v 1.12 2015/01/14 10:24:42 markus Exp $ */ +/* + * Copyright (c) 2003 Markus Friedl. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// #include "includes.h" + +#include <sys/types.h> +#include <string.h> +#include <openssl/evp.h> +#include <windows.h> + +typedef unsigned int u_int; +typedef unsigned char u_char; + +#include "ssherr.h" + +/* + * This is used by SSH1: + * + * What kind of triple DES are these 2 routines? + * + * Why is there a redundant initialization vector? + * + * If only iv3 was used, then, this would till effect have been + * outer-cbc. However, there is also a private iv1 == iv2 which + * perhaps makes differential analysis easier. On the other hand, the + * private iv1 probably makes the CRC-32 attack ineffective. This is a + * result of that there is no longer any known iv1 to use when + * choosing the X block. + */ +struct ssh1_3des_ctx +{ + EVP_CIPHER_CTX *k1, *k2, *k3; +}; + +const EVP_CIPHER * evp_ssh1_3des(void); +int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); + +static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc) +{ + struct ssh1_3des_ctx *c; + u_char *k1, *k2, *k3; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + if ((c = calloc(1, sizeof(*c))) == NULL) + return 0; + EVP_CIPHER_CTX_set_app_data(ctx, c); + } + if (key == NULL) + return 1; + if (enc == -1) + enc = EVP_CIPHER_CTX_encrypting(ctx); // ctx->encrypt + k1 = k2 = k3 = (u_char *) key; + k2 += 8; + if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { + if (enc) + k3 += 16; + else + k1 += 16; + } + c->k1 = EVP_CIPHER_CTX_new(); + c->k2 = EVP_CIPHER_CTX_new(); + c->k3 = EVP_CIPHER_CTX_new(); + /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/ + if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || + EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || + EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { + EVP_CIPHER_CTX_free(c->k1); + EVP_CIPHER_CTX_free(c->k2); + EVP_CIPHER_CTX_free(c->k3); + SecureZeroMemory(c, sizeof(*c)); + free(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + return 0; + } + return 1; +} + +static int ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len) +{ + struct ssh1_3des_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { + //error("ssh1_3des_cbc: no context"); + return 0; + } + if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 || + EVP_Cipher(c->k2, dest, dest, len) == 0 || + EVP_Cipher(c->k3, dest, dest, len) == 0) + return 0; + return 1; +} + +static int ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) +{ + struct ssh1_3des_ctx *c; + + if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { + EVP_CIPHER_CTX_free(c->k1); + EVP_CIPHER_CTX_free(c->k2); + EVP_CIPHER_CTX_free(c->k3); + SecureZeroMemory(c, sizeof(*c)); + free(c); + EVP_CIPHER_CTX_set_app_data(ctx, NULL); + } + return 1; +} + +// ssh1_3des_iv \x82͖\xA2\x8Eg\x97p\x81B +int ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) +{ + struct ssh1_3des_ctx *c; + + if (len != 24) { + //fatal("%s: bad 3des iv length: %d", __func__, len); + return SSH_ERR_INVALID_ARGUMENT; + } + + if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) { + //fatal("%s: no 3des context", __func__); + return SSH_ERR_INTERNAL_ERROR; + } + + if (doset) { + //debug3("%s: Installed 3DES IV", __func__); + memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); + memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); + memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); + } else { + //debug3("%s: Copying 3DES IV", __func__); + memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); + memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); + memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); + } + return 0; +} + +const EVP_CIPHER *evp_ssh1_3des(void) +{ + static EVP_CIPHER *p = NULL; + + if (p == NULL) { + p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/8, /*key_len*/16); + /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/ + } + if (p) { + EVP_CIPHER_meth_set_iv_length(p, 0); + EVP_CIPHER_meth_set_init(p, ssh1_3des_init); + EVP_CIPHER_meth_set_cleanup(p, ssh1_3des_cleanup); + EVP_CIPHER_meth_set_do_cipher(p, ssh1_3des_cbc); + EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); + } + return (p); +} Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,558 @@ +/* + * Copyright (c) 1998-2001, Robert O'Callahan + * (C) 2004- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ttxssh.h" +#include "ssh.h" +#include "ssherr.h" +#include "cipher.h" +#include "kex.h" + +#include <openssl/evp.h> + +// from cipher-3des.c +extern const EVP_CIPHER* evp_ssh1_3des(void); + +static const struct ssh2cipher ssh2_ciphers[] = { + {SSH2_CIPHER_3DES_CBC, "3des-cbc", 8, 24, 0, 0, 0, EVP_des_ede3_cbc}, // RFC4253 + {SSH2_CIPHER_AES128_CBC, "aes128-cbc", 16, 16, 0, 0, 0, EVP_aes_128_cbc}, // RFC4253 + {SSH2_CIPHER_AES192_CBC, "aes192-cbc", 16, 24, 0, 0, 0, EVP_aes_192_cbc}, // RFC4253 + {SSH2_CIPHER_AES256_CBC, "aes256-cbc", 16, 32, 0, 0, 0, EVP_aes_256_cbc}, // RFC4253 + {SSH2_CIPHER_BLOWFISH_CBC, "blowfish-cbc", 8, 16, 0, 0, 0, EVP_bf_cbc}, // RFC4253 + {SSH2_CIPHER_AES128_CTR, "aes128-ctr", 16, 16, 0, 0, 0, evp_aes_128_ctr}, // RFC4344 + {SSH2_CIPHER_AES192_CTR, "aes192-ctr", 16, 24, 0, 0, 0, evp_aes_128_ctr}, // RFC4344 + {SSH2_CIPHER_AES256_CTR, "aes256-ctr", 16, 32, 0, 0, 0, evp_aes_128_ctr}, // RFC4344 + {SSH2_CIPHER_ARCFOUR, "arcfour", 8, 16, 0, 0, 0, EVP_rc4}, // RFC4253 + {SSH2_CIPHER_ARCFOUR128, "arcfour128", 8, 16, 1536, 0, 0, EVP_rc4}, // RFC4345 + {SSH2_CIPHER_ARCFOUR256, "arcfour256", 8, 32, 1536, 0, 0, EVP_rc4}, // RFC4345 + {SSH2_CIPHER_CAST128_CBC, "cast128-cbc", 8, 16, 0, 0, 0, EVP_cast5_cbc}, // RFC4253 + {SSH2_CIPHER_3DES_CTR, "3des-ctr", 8, 24, 0, 0, 0, evp_des3_ctr}, // RFC4344 + {SSH2_CIPHER_BLOWFISH_CTR, "blowfish-ctr", 8, 32, 0, 0, 0, evp_bf_ctr}, // RFC4344 + {SSH2_CIPHER_CAST128_CTR, "cast128-ctr", 8, 16, 0, 0, 0, evp_cast5_ctr}, // RFC4344 + {SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc", 16, 16, 0, 0, 0, EVP_camellia_128_cbc}, // draft-kanno-secsh-camellia-02 + {SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc", 16, 24, 0, 0, 0, EVP_camellia_192_cbc}, // draft-kanno-secsh-camellia-02 + {SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc", 16, 32, 0, 0, 0, EVP_camellia_256_cbc}, // draft-kanno-secsh-camellia-02 + {SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr", 16, 16, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02 + {SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr", 16, 24, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02 + {SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr", 16, 32, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02 +#ifdef WITH_CAMELLIA_PRIVATE + {SSH2_CIPHER_CAMELLIA128_CBC, "camel****@opens*****", 16, 16, 0, 0, 0, EVP_camellia_128_cbc}, + {SSH2_CIPHER_CAMELLIA192_CBC, "camel****@opens*****", 16, 24, 0, 0, 0, EVP_camellia_192_cbc}, + {SSH2_CIPHER_CAMELLIA256_CBC, "camel****@opens*****", 16, 32, 0, 0, 0, EVP_camellia_256_cbc}, + {SSH2_CIPHER_CAMELLIA128_CTR, "camel****@opens*****", 16, 16, 0, 0, 0, evp_camellia_128_ctr}, + {SSH2_CIPHER_CAMELLIA192_CTR, "camel****@opens*****", 16, 24, 0, 0, 0, evp_camellia_128_ctr}, + {SSH2_CIPHER_CAMELLIA256_CTR, "camel****@opens*****", 16, 32, 0, 0, 0, evp_camellia_128_ctr}, +#endif // WITH_CAMELLIA_PRIVATE + {SSH2_CIPHER_AES128_GCM, "aes12****@opens*****", 16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH + {SSH2_CIPHER_AES256_GCM, "aes25****@opens*****", 16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH + {SSH_CIPHER_NONE, NULL, 0, 0, 0, 0, 0, NULL}, +}; + + +int get_cipher_id(const struct ssh2cipher *cipher) +{ + if (cipher) { + return cipher->id; + } + else { + return 0; + } +} + +u_int get_cipher_block_size(const struct ssh2cipher *cipher) +{ + u_int blocksize = 0; + + if (cipher) { + blocksize = cipher->block_size; + } + + return max(blocksize, 8); +} + +u_int get_cipher_key_len(const struct ssh2cipher *cipher) +{ + if (cipher) { + return cipher->key_len; + } + else { + return 0; + } +} + +u_int get_cipher_discard_len(const struct ssh2cipher *cipher) +{ + if (cipher) { + return cipher->discard_len; + } + else { + return 0; + } +} + +u_int get_cipher_iv_len(const struct ssh2cipher *cipher) +{ + if (cipher) { + if (cipher->iv_len != 0) { + return cipher->iv_len; + } + else { + return cipher->block_size; + } + } + else { + return 8; // block_size + } +} + +u_int get_cipher_auth_len(const struct ssh2cipher *cipher) +{ + if (cipher) { + return cipher->auth_len; + } + else { + return 0; + } +} + +const EVP_CIPHER *get_cipher_EVP_CIPHER(const struct ssh2cipher *cipher) +{ + if (cipher) { + return cipher->func(); + } + else { + return EVP_enc_null(); + } +} + +char *get_cipher_string(const struct ssh2cipher *cipher) +{ + if (cipher) { + return cipher->name; + } + else { + return "unknown"; + } +} + +// \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x96\xBC\x82\xA9\x82猟\x8D\x{142DC2}\xE9\x81B +const struct ssh2cipher *get_cipher_by_name(char *name) +{ + const struct ssh2cipher *ptr = ssh2_ciphers; + + if (name == NULL || name[0] == '\0') + return NULL; + + while (ptr->name != NULL) { + if (strcmp(ptr->name, name) == 0) { + return ptr; + } + ptr++; + } + + // not found. + return NULL; +} + +// \x95\\x8E\xA6\x96\xBC +char *get_cipher_name(int cipher_id) +{ + switch (cipher_id) { + case SSH_CIPHER_NONE: + return "None"; + case SSH_CIPHER_3DES: + return "3DES (168 key bits)"; + case SSH_CIPHER_DES: + return "DES (56 key bits)"; + case SSH_CIPHER_BLOWFISH: + return "Blowfish (256 key bits)"; + + // SSH2 + case SSH2_CIPHER_3DES_CBC: + return "3des-cbc"; + case SSH2_CIPHER_AES128_CBC: + return "aes128-cbc"; + case SSH2_CIPHER_AES192_CBC: + return "aes192-cbc"; + case SSH2_CIPHER_AES256_CBC: + return "aes256-cbc"; + case SSH2_CIPHER_BLOWFISH_CBC: + return "blowfish-cbc"; + case SSH2_CIPHER_AES128_CTR: + return "aes128-ctr"; + case SSH2_CIPHER_AES192_CTR: + return "aes192-ctr"; + case SSH2_CIPHER_AES256_CTR: + return "aes256-ctr"; + case SSH2_CIPHER_ARCFOUR: + return "arcfour"; + case SSH2_CIPHER_ARCFOUR128: + return "arcfour128"; + case SSH2_CIPHER_ARCFOUR256: + return "arcfour256"; + case SSH2_CIPHER_CAST128_CBC: + return "cast-128-cbc"; + case SSH2_CIPHER_3DES_CTR: + return "3des-ctr"; + case SSH2_CIPHER_BLOWFISH_CTR: + return "blowfish-ctr"; + case SSH2_CIPHER_CAST128_CTR: + return "cast-128-ctr"; + case SSH2_CIPHER_CAMELLIA128_CBC: + return "camellia128-cbc"; + case SSH2_CIPHER_CAMELLIA192_CBC: + return "camellia192-cbc"; + case SSH2_CIPHER_CAMELLIA256_CBC: + return "camellia256-cbc"; + case SSH2_CIPHER_CAMELLIA128_CTR: + return "camellia128-ctr"; + case SSH2_CIPHER_CAMELLIA192_CTR: + return "camellia192-ctr"; + case SSH2_CIPHER_CAMELLIA256_CTR: + return "camellia256-ctr"; + case SSH2_CIPHER_AES128_GCM: + return "aes12****@opens*****"; + case SSH2_CIPHER_AES256_GCM: + return "aes25****@opens*****"; + + default: + return "Unknown"; + } +} + +// \x83\x8A\x83X\x83g\x83{\x83b\x83N\x83X\x95\\x8E\xA6\x96\xBC +char *get_listbox_cipher_name(int cipher_id, PTInstVar pvar) +{ + switch (cipher_id) { + case SSH_CIPHER_NONE: + UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar, + "<ciphers below this line are disabled>"); + return pvar->ts->UIMsg; + case SSH_CIPHER_3DES: + return "3DES(SSH1)"; + case SSH_CIPHER_DES: + return "DES(SSH1)"; + case SSH_CIPHER_BLOWFISH: + return "Blowfish(SSH1)"; + + // for SSH2(yutaka) + case SSH2_CIPHER_AES128_CBC: + return "aes128-cbc(SSH2)"; + case SSH2_CIPHER_AES192_CBC: + return "aes192-cbc(SSH2)"; + case SSH2_CIPHER_AES256_CBC: + return "aes256-cbc(SSH2)"; + case SSH2_CIPHER_3DES_CBC: + return "3des-cbc(SSH2)"; + case SSH2_CIPHER_BLOWFISH_CBC: + return "blowfish-cbc(SSH2)"; + case SSH2_CIPHER_AES128_CTR: + return "aes128-ctr(SSH2)"; + case SSH2_CIPHER_AES192_CTR: + return "aes192-ctr(SSH2)"; + case SSH2_CIPHER_AES256_CTR: + return "aes256-ctr(SSH2)"; + case SSH2_CIPHER_ARCFOUR: + return "arcfour(SSH2)"; + case SSH2_CIPHER_ARCFOUR128: + return "arcfour128(SSH2)"; + case SSH2_CIPHER_ARCFOUR256: + return "arcfour256(SSH2)"; + case SSH2_CIPHER_CAST128_CBC: + return "cast128-cbc(SSH2)"; + case SSH2_CIPHER_3DES_CTR: + return "3des-ctr(SSH2)"; + case SSH2_CIPHER_BLOWFISH_CTR: + return "blowfish-ctr(SSH2)"; + case SSH2_CIPHER_CAST128_CTR: + return "cast128-ctr(SSH2)"; + case SSH2_CIPHER_CAMELLIA128_CBC: + return "camellia128-cbc(SSH2)"; + case SSH2_CIPHER_CAMELLIA192_CBC: + return "camellia192-cbc(SSH2)"; + case SSH2_CIPHER_CAMELLIA256_CBC: + return "camellia256-cbc(SSH2)"; + case SSH2_CIPHER_CAMELLIA128_CTR: + return "camellia128-ctr(SSH2)"; + case SSH2_CIPHER_CAMELLIA192_CTR: + return "camellia192-ctr(SSH2)"; + case SSH2_CIPHER_CAMELLIA256_CTR: + return "camellia256-ctr(SSH2)"; + case SSH2_CIPHER_AES128_GCM: + return "aes12****@opens*****(SSH2)"; + case SSH2_CIPHER_AES256_GCM: + return "aes25****@opens*****(SSH2)"; + + default: + return NULL; + } +} + +/* + * Remove unsupported cipher or duplicated cipher. + * Add unspecified ciphers at the end of list. + */ +void normalize_cipher_order(char *buf) +{ + /* SSH_CIPHER_NONE means that all ciphers below that one are disabled. + We *never* allow no encryption. */ + static char default_strings[] = { + SSH2_CIPHER_AES256_GCM, + SSH2_CIPHER_CAMELLIA256_CTR, + SSH2_CIPHER_AES256_CTR, + SSH2_CIPHER_CAMELLIA256_CBC, + SSH2_CIPHER_AES256_CBC, + SSH2_CIPHER_CAMELLIA192_CTR, + SSH2_CIPHER_AES192_CTR, + SSH2_CIPHER_CAMELLIA192_CBC, + SSH2_CIPHER_AES192_CBC, + SSH2_CIPHER_AES128_GCM, + SSH2_CIPHER_CAMELLIA128_CTR, + SSH2_CIPHER_AES128_CTR, + SSH2_CIPHER_CAMELLIA128_CBC, + SSH2_CIPHER_AES128_CBC, + SSH2_CIPHER_3DES_CTR, + SSH2_CIPHER_3DES_CBC, + SSH2_CIPHER_BLOWFISH_CTR, + SSH2_CIPHER_BLOWFISH_CBC, + SSH2_CIPHER_CAST128_CTR, + SSH2_CIPHER_CAST128_CBC, + SSH_CIPHER_3DES, + SSH_CIPHER_NONE, + SSH2_CIPHER_ARCFOUR256, + SSH2_CIPHER_ARCFOUR128, + SSH2_CIPHER_ARCFOUR, + SSH_CIPHER_BLOWFISH, + SSH_CIPHER_DES, + 0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4 + }; + + normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); +} + +const struct ssh2cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) +{ + char str_cipher[32]; + const struct ssh2cipher *ptr = ssh2_ciphers; + + choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); + return get_cipher_by_name(str_cipher); +} + +void SSH2_update_cipher_myproposal(PTInstVar pvar) +{ + static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB + int cipher; + int len, i; + char *c_str; + + // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) + if (pvar->socket != INVALID_SOCKET) { + return; + } + + // \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2004.11.6 yutaka) + buf[0] = '\0'; + for (i = 0 ; pvar->settings.CipherOrder[i] != 0 ; i++) { + cipher = pvar->settings.CipherOrder[i] - '0'; + if (cipher == 0) // disabled line + break; + switch (cipher) { + case SSH2_CIPHER_3DES_CBC: + c_str = "3des-cbc,"; + break; + case SSH2_CIPHER_3DES_CTR: + c_str = "3des-ctr,"; + break; + case SSH2_CIPHER_BLOWFISH_CBC: + c_str = "blowfish-cbc,"; + break; + case SSH2_CIPHER_BLOWFISH_CTR: + c_str = "blowfish-ctr,"; + break; + case SSH2_CIPHER_AES128_CBC: + c_str = "aes128-cbc,"; + break; + case SSH2_CIPHER_AES192_CBC: + c_str = "aes192-cbc,"; + break; + case SSH2_CIPHER_AES256_CBC: + c_str = "aes256-cbc,"; + break; + case SSH2_CIPHER_AES128_CTR: + c_str = "aes128-ctr,"; + break; + case SSH2_CIPHER_AES192_CTR: + c_str = "aes192-ctr,"; + break; + case SSH2_CIPHER_AES256_CTR: + c_str = "aes256-ctr,"; + break; + case SSH2_CIPHER_ARCFOUR: + c_str = "arcfour,"; + break; + case SSH2_CIPHER_ARCFOUR128: + c_str = "arcfour128,"; + break; + case SSH2_CIPHER_ARCFOUR256: + c_str = "arcfour256,"; + break; + case SSH2_CIPHER_CAST128_CBC: + c_str = "cast128-cbc,"; + break; + case SSH2_CIPHER_CAST128_CTR: + c_str = "cast128-ctr,"; + break; +#ifdef WITH_CAMELLIA_PRIVATE + case SSH2_CIPHER_CAMELLIA128_CBC: + c_str = "camellia128-cbc,camel****@opens*****,"; + break; + case SSH2_CIPHER_CAMELLIA192_CBC: + c_str = "camellia192-cbc,camel****@opens*****,"; + break; + case SSH2_CIPHER_CAMELLIA256_CBC: + c_str = "camellia256-cbc,camel****@opens*****,"; + break; + case SSH2_CIPHER_CAMELLIA128_CTR: + c_str = "camellia128-ctr,camel****@opens*****,"; + break; + case SSH2_CIPHER_CAMELLIA192_CTR: + c_str = "camellia192-ctr,camel****@opens*****,"; + break; + case SSH2_CIPHER_CAMELLIA256_CTR: + c_str = "camellia256-ctr,camel****@opens*****,"; + break; +#endif // WITH_CAMELLIA_PRIVATE + case SSH2_CIPHER_CAMELLIA128_CBC: + c_str = "camellia128-cbc,"; + break; + case SSH2_CIPHER_CAMELLIA192_CBC: + c_str = "camellia192-cbc,"; + break; + case SSH2_CIPHER_CAMELLIA256_CBC: + c_str = "camellia256-cbc,"; + break; + case SSH2_CIPHER_CAMELLIA128_CTR: + c_str = "camellia128-ctr,"; + break; + case SSH2_CIPHER_CAMELLIA192_CTR: + c_str = "camellia192-ctr,"; + break; + case SSH2_CIPHER_CAMELLIA256_CTR: + c_str = "camellia256-ctr,"; + break; + case SSH2_CIPHER_AES128_GCM: + c_str = "aes12****@opens*****,"; + break; + case SSH2_CIPHER_AES256_GCM: + c_str = "aes25****@opens*****,"; + break; + default: + continue; + } + strncat_s(buf, sizeof(buf), c_str, _TRUNCATE); + } + len = strlen(buf); + if (len > 0) + buf[len - 1] = '\0'; // get rid of comma + myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server + myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client +} + + +// +// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̏\x89\x8A\xFA\x89\xBB +// +void cipher_init_SSH2(EVP_CIPHER_CTX *evp, + const u_char *key, u_int keylen, + const u_char *iv, u_int ivlen, + int do_encrypt, + const EVP_CIPHER *type, + int discard_len, + unsigned int authlen, + PTInstVar pvar) +{ + int klen; + unsigned char *junk = NULL, *discard = NULL; + char tmp[80]; + + EVP_CIPHER_CTX_reset(evp); + + if (EVP_CipherInit(evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) { + UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 1); + notify_fatal_error(pvar, tmp, TRUE); + return; + } + if (authlen && + !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) { + UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 2); + notify_fatal_error(pvar, tmp, TRUE); + return; + } + klen = EVP_CIPHER_CTX_key_length(evp); + if (klen > 0 && keylen != (u_int)klen) { + if (EVP_CIPHER_CTX_set_key_length(evp, keylen) == 0) { + UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 3); + notify_fatal_error(pvar, tmp, TRUE); + return; + } + } + if (EVP_CipherInit(evp, NULL, (u_char *)key, NULL, -1) == 0) { + UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 4); + notify_fatal_error(pvar, tmp, TRUE); + return; + } + + if (discard_len > 0) { + junk = malloc(discard_len); + discard = malloc(discard_len); + if (junk == NULL || discard == NULL || + EVP_Cipher(evp, discard, junk, discard_len) == 0) { + UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5); + notify_fatal_error(pvar, tmp, TRUE); + } + else { + SecureZeroMemory(discard, discard_len); + } + free(junk); + free(discard); + } +} + +// +// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̔j\x8A\xFC +/// +void cipher_free_SSH2(EVP_CIPHER_CTX *evp) +{ + EVP_CIPHER_CTX_free(evp); +} Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -1,5 +1,7 @@ -/* $OpenBSD: cipher.h,v 1.34 2003/11/10 16:23:41 jakob Exp $ */ +/* Imported from OpenSSH-8.5p1, TeraTerm Project */ +/* $OpenBSD: cipher.h,v 1.44 2014/01/25 10:12:50 dtucker Exp $ */ + /* * Author: Tatu Ylonen <ylo****@cs*****> * Copyright (c) 1995 Tatu Ylonen <ylo****@cs*****>, Espoo, Finland @@ -37,6 +39,9 @@ #ifndef CIPHER_H #define CIPHER_H +typedef unsigned int u_int; +typedef unsigned char u_char; + #include <openssl/evp.h> /* * Cipher types for SSH-1. New types can be added, but old types should not @@ -45,49 +50,78 @@ #define SSH_CIPHER_SSH2 -3 #define SSH_CIPHER_ILLEGAL -2 /* No valid cipher selected. */ #define SSH_CIPHER_NOT_SET -1 /* None selected (invalid number). */ -#define SSH_CIPHER_NONE 0 /* no encryption */ -#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ -#define SSH_CIPHER_DES 2 /* DES CBC */ -#define SSH_CIPHER_3DES 3 /* 3DES CBC */ -#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ -#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ -#define SSH_CIPHER_BLOWFISH 6 -#define SSH_CIPHER_RESERVED 7 +//#define SSH_CIPHER_NONE 0 /* no encryption */ +//#define SSH_CIPHER_IDEA 1 /* IDEA CFB */ +//#define SSH_CIPHER_DES 2 /* DES CBC */ +//#define SSH_CIPHER_3DES 3 /* 3DES CBC */ +//#define SSH_CIPHER_BROKEN_TSS 4 /* TRI's Simple Stream encryption CBC */ +//#define SSH_CIPHER_BROKEN_RC4 5 /* Alleged RC4 */ +//#define SSH_CIPHER_BLOWFISH 6 +//#define SSH_CIPHER_RESERVED 7 #define CIPHER_ENCRYPT 1 #define CIPHER_DECRYPT 0 -typedef struct Cipher Cipher; -typedef struct CipherContext CipherContext; -struct Cipher; -struct CipherContext { - int plaintext; +typedef enum { + // SSH1 + SSH_CIPHER_NONE, SSH_CIPHER_IDEA, SSH_CIPHER_DES, SSH_CIPHER_3DES, + SSH_CIPHER_TSS, SSH_CIPHER_RC4, SSH_CIPHER_BLOWFISH, + // SSH2 + SSH2_CIPHER_3DES_CBC, SSH2_CIPHER_AES128_CBC, + SSH2_CIPHER_AES192_CBC, SSH2_CIPHER_AES256_CBC, + SSH2_CIPHER_BLOWFISH_CBC, SSH2_CIPHER_AES128_CTR, + SSH2_CIPHER_AES192_CTR, SSH2_CIPHER_AES256_CTR, + SSH2_CIPHER_ARCFOUR, SSH2_CIPHER_ARCFOUR128, SSH2_CIPHER_ARCFOUR256, + SSH2_CIPHER_CAST128_CBC, + SSH2_CIPHER_3DES_CTR, SSH2_CIPHER_BLOWFISH_CTR, SSH2_CIPHER_CAST128_CTR, + SSH2_CIPHER_CAMELLIA128_CBC, SSH2_CIPHER_CAMELLIA192_CBC, SSH2_CIPHER_CAMELLIA256_CBC, + SSH2_CIPHER_CAMELLIA128_CTR, SSH2_CIPHER_CAMELLIA192_CTR, SSH2_CIPHER_CAMELLIA256_CTR, + SSH2_CIPHER_AES128_GCM, SSH2_CIPHER_AES256_GCM, SSH2_CIPHER_CHACHAPOLY, + SSH_CIPHER_MAX = SSH2_CIPHER_CHACHAPOLY, +} SSHCipherId; + +struct ssh2cipher { + SSHCipherId id; + char *name; + u_int block_size; + u_int key_len; + u_int discard_len; + u_int iv_len; + u_int auth_len; + const EVP_CIPHER *(*func)(void); +}; + +struct sshcipher_ctx { + // TTSSH \x82ł\xCD SSH_CIPHER_NONE \x82\xAA\x96\xB3\x8C\xF8\x82Ȃ̂ŁAplaintext \x82͎g\x97p\x82\xB3\x82\xEA\x82Ȃ\xA2 + // int plaintext; + // TTSSH \x82ł\xCD CRYPT_encrypt_aead(), CRYPT_decrypt_aead() \x82\xAA\x95ʂ\xEA\x82Ă\xA2\x82\xC4 encrypt \x82Ő\xE8\x91ւ\xA6\x82Ȃ\xA2\x82̂Ŏg\x97p\x82\xB3\x82\xEA\x82Ȃ\xA2 + // int encrypt; EVP_CIPHER_CTX *evp; - Cipher *cipher; + // struct chachapoly_ctx *cp_ctx; + // OpenSSH \x82\xC5 ifndef WITH_OPENSSL \x82̎\x9E\x82Ɏg\x97p\x82\xB3\x82\xEA\x82\xE9\x82\xE0\x82̂Ȃ̂ŁAac_ctx \x82͎g\x97p\x82\xB3\x82\xEA\x82Ȃ\xA2 + // aesctr_ctx ac_ctx; /* XXX union with evp? */ + // OpenSSH \x82ł\xCD const struct sshcipher *cipher; + const struct ssh2cipher *cipher; }; -u_int cipher_mask_ssh1(int); -Cipher *cipher_by_name(const char *); -Cipher *cipher_by_number(int); -int cipher_number(const char *); -char *cipher_name(int); -int ciphers_valid(const char *); -void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, - const u_char *, u_int, int); -void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int); -void cipher_cleanup(CipherContext *); -void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); -u_int cipher_blocksize(const Cipher *); -u_int cipher_keylen(const Cipher *); -u_int cipher_get_number(const Cipher *); -void cipher_get_keyiv(CipherContext *, u_char *, u_int); -void cipher_set_keyiv(CipherContext *, u_char *); -int cipher_get_keyiv_len(const CipherContext *); -int cipher_get_keycontext(const CipherContext *, u_char *); -void cipher_set_keycontext(CipherContext *, u_char *); +int get_cipher_id(const struct ssh2cipher *cipher); +u_int get_cipher_block_size(const struct ssh2cipher *cipher); +u_int get_cipher_key_len(const struct ssh2cipher *cipher); +u_int get_cipher_discard_len(const struct ssh2cipher *cipher); +u_int get_cipher_iv_len(const struct ssh2cipher *cipher); +u_int get_cipher_auth_len(const struct ssh2cipher *cipher); +const EVP_CIPHER *get_cipher_EVP_CIPHER(const struct ssh2cipher *cipher); +char *get_cipher_string(const struct ssh2cipher *cipher); +const struct ssh2cipher* get_cipher_by_name(char *name); +char *get_cipher_name(int cipher_id); +char *get_listbox_cipher_name(int cipher_id, PTInstVar pvar); +void normalize_cipher_order(char *buf); +const struct ssh2cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal); +void SSH2_update_cipher_myproposal(PTInstVar pvar); + void cipher_init_SSH2( EVP_CIPHER_CTX *evp, const u_char *key, u_int keylen, @@ -98,7 +132,6 @@ unsigned int authlen, PTInstVar pvar ); - void cipher_free_SSH2(EVP_CIPHER_CTX *evp); #endif /* CIPHER_H */ Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,129 @@ +/* + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ttxssh.h" +#include "comp.h" +#include "kex.h" + + +struct ssh2_comp_t { + compression_type type; + char *name; +}; + +static const struct ssh2_comp_t ssh2_comps[] = { + {COMP_NOCOMP, "none"}, // RFC4253 + {COMP_ZLIB, "zlib"}, // RFC4253 + {COMP_DELAYED, "zlib****@opens*****"}, + {COMP_NONE, NULL}, +}; + + +char* get_ssh2_comp_name(compression_type type) +{ + const struct ssh2_comp_t *ptr = ssh2_comps; + + while (ptr->name != NULL) { + if (type == ptr->type) { + return ptr->name; + } + ptr++; + } + + // not found. + return "unknown"; +} + +void normalize_comp_order(char *buf) +{ + static char default_strings[] = { + COMP_DELAYED, + COMP_ZLIB, + COMP_NOCOMP, + COMP_NONE, + }; + + normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); +} + +compression_type choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal) +{ + compression_type type = COMP_UNKNOWN; + char str_comp[20]; + const struct ssh2_comp_t *ptr = ssh2_comps; + + choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp)); + + while (ptr->name != NULL) { + if (strcmp(ptr->name, str_comp) == 0) { + type = ptr->type; + break; + } + ptr++; + } + + return (type); +} + +void SSH2_update_compression_myproposal(PTInstVar pvar) +{ + static char buf[128]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB + int index; + int len, i; + + // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) + if (pvar->socket != INVALID_SOCKET) { + return; + } + + // \x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82ɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2005.7.9 yutaka) + buf[0] = '\0'; + for (i = 0 ; pvar->settings.CompOrder[i] != 0 ; i++) { + index = pvar->settings.CompOrder[i] - '0'; + if (index == COMP_NONE) // disabled line + break; + strncat_s(buf, sizeof(buf), get_ssh2_comp_name(index), _TRUNCATE); + strncat_s(buf, sizeof(buf), ",", _TRUNCATE); + } + len = strlen(buf); + if (len > 0) + buf[len - 1] = '\0'; // get rid of comma + + // \x88\xB3\x8Fk\x8Ew\x92肪\x82Ȃ\xA2\x8Fꍇ\x82́A\x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82\xF0\x8C\x8F\x82Ƀ[\x83\x8D\x82ɂ\xB7\x82\xE9\x81B + if (buf[0] == '\0') { + pvar->settings.CompressionLevel = 0; + } + + if (pvar->settings.CompressionLevel == 0) { + _snprintf_s(buf, sizeof(buf), _TRUNCATE, get_ssh2_comp_name(COMP_NOCOMP)); + } + if (buf[0] != '\0') { + myproposal[PROPOSAL_COMP_ALGS_CTOS] = buf; // Client To Server + myproposal[PROPOSAL_COMP_ALGS_STOC] = buf; // Server To Client + } +} Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,49 @@ +/* + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SSHCOMP_H +#define SSHCOMP_H + +#include "ttxssh.h" + +typedef enum { + COMP_NONE, /* disabled line */ + COMP_NOCOMP, + COMP_ZLIB, + COMP_DELAYED, + COMP_UNKNOWN, + COMP_MAX = COMP_UNKNOWN, +} compression_type; + +char* get_ssh2_comp_name(compression_type type); + +void normalize_comp_order(char *buf); +compression_type choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal); +void SSH2_update_compression_myproposal(PTInstVar pvar); + +#endif /* SSHCOMP_H */ Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -75,8 +75,6 @@ static unsigned char *encbuff = NULL; static unsigned int encbufflen = 0; -static char *get_cipher_name(int cipher); - static void crc_update(uint32 *a, uint32 b) { b ^= *a; @@ -296,10 +294,10 @@ memcpy(data+aadlen, encbuff, bytes); if (EVP_Cipher(evp, NULL, NULL, 0) < 0) - return FALSE; - else - return TRUE; + goto err; + return TRUE; + err: UTIL_get_lang_msg("MSG_DECRYPT_ERROR2", pvar, "%s decrypt error(2)"); _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, @@ -802,13 +800,13 @@ pvar->crypt_state.sender_cipher = SSH_CIPHER_NONE; } else { - pvar->crypt_state.sender_cipher = pvar->ciphers[MODE_OUT]->id; + pvar->crypt_state.sender_cipher = get_cipher_id(pvar->ciphers[MODE_OUT]); } if (pvar->ciphers[MODE_IN] == NULL) { pvar->crypt_state.receiver_cipher = SSH_CIPHER_NONE; } else { - pvar->crypt_state.receiver_cipher = pvar->ciphers[MODE_IN]->id; + pvar->crypt_state.receiver_cipher = get_cipher_id(pvar->ciphers[MODE_IN]); } } @@ -1046,98 +1044,12 @@ SecureZeroMemory(state->ivec, 8); } - -// -// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̏\x89\x8A\xFA\x89\xBB -// -void cipher_init_SSH2(EVP_CIPHER_CTX *evp, - const u_char *key, u_int keylen, - const u_char *iv, u_int ivlen, - int encrypt, - const EVP_CIPHER *type, - int discard_len, - unsigned int authlen, - PTInstVar pvar) -{ - int klen; - char tmp[80]; - unsigned char *junk = NULL, *discard = NULL; - - EVP_CIPHER_CTX_reset(evp); - if (EVP_CipherInit(evp, type, NULL, NULL, (encrypt == CIPHER_ENCRYPT)) == 0) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 1); - notify_fatal_error(pvar, tmp, TRUE); - return; - } - - if (authlen > 0 && !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL)) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 2); - notify_fatal_error(pvar, tmp, TRUE); - return; - } - if (EVP_CipherInit(evp, NULL, NULL, (u_char *)iv, -1) == 0) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 3); - notify_fatal_error(pvar, tmp, TRUE); - return; - } - if (authlen > 0 && !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 4); - notify_fatal_error(pvar, tmp, TRUE); - return; - } - - klen = EVP_CIPHER_CTX_key_length(evp); - if (klen > 0 && keylen != klen) { - if (EVP_CIPHER_CTX_set_key_length(evp, keylen) == 0) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5); - notify_fatal_error(pvar, tmp, TRUE); - return; - } - } - if (EVP_CipherInit(evp, NULL, (u_char *)key, NULL, -1) == 0) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 6); - notify_fatal_error(pvar, tmp, TRUE); - return; - } - - if (discard_len > 0) { - junk = malloc(discard_len); - discard = malloc(discard_len); - if (junk == NULL || discard == NULL || - EVP_Cipher(evp, discard, junk, discard_len) == 0) { - UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)"); - _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 7); - notify_fatal_error(pvar, tmp, TRUE); - } - else { - SecureZeroMemory(discard, discard_len); - } - free(junk); - free(discard); - } -} - -// -// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̔j\x8A\xFC -// -void cipher_free_SSH2(EVP_CIPHER_CTX *evp) -{ - EVP_CIPHER_CTX_free(evp); -} - - BOOL CRYPT_start_encryption(PTInstVar pvar, int sender_flag, int receiver_flag) { struct Enc *enc; char *encryption_key = pvar->crypt_state.sender_cipher_key; char *decryption_key = pvar->crypt_state.receiver_cipher_key; - SSH2Cipher *cipher; + const struct ssh2cipher *cipher; BOOL isOK = TRUE; if (sender_flag) { @@ -1262,71 +1174,6 @@ HASH_MINSIZE / HASH_ENTRYSIZE; } -static char *get_cipher_name(int cipher) -{ - switch (cipher) { - case SSH_CIPHER_NONE: - return "None"; - case SSH_CIPHER_3DES: - return "3DES (168 key bits)"; - case SSH_CIPHER_DES: - return "DES (56 key bits)"; - case SSH_CIPHER_BLOWFISH: - return "Blowfish (256 key bits)"; - - // SSH2 - case SSH2_CIPHER_3DES_CBC: - return "3des-cbc"; - case SSH2_CIPHER_AES128_CBC: - return "aes128-cbc"; - case SSH2_CIPHER_AES192_CBC: - return "aes192-cbc"; - case SSH2_CIPHER_AES256_CBC: - return "aes256-cbc"; - case SSH2_CIPHER_BLOWFISH_CBC: - return "blowfish-cbc"; - case SSH2_CIPHER_AES128_CTR: - return "aes128-ctr"; - case SSH2_CIPHER_AES192_CTR: - return "aes192-ctr"; - case SSH2_CIPHER_AES256_CTR: - return "aes256-ctr"; - case SSH2_CIPHER_ARCFOUR: - return "arcfour"; - case SSH2_CIPHER_ARCFOUR128: - return "arcfour128"; - case SSH2_CIPHER_ARCFOUR256: - return "arcfour256"; - case SSH2_CIPHER_CAST128_CBC: - return "cast-128-cbc"; - case SSH2_CIPHER_3DES_CTR: - return "3des-ctr"; - case SSH2_CIPHER_BLOWFISH_CTR: - return "blowfish-ctr"; - case SSH2_CIPHER_CAST128_CTR: - return "cast-128-ctr"; - case SSH2_CIPHER_CAMELLIA128_CBC: - return "camellia128-cbc"; - case SSH2_CIPHER_CAMELLIA192_CBC: - return "camellia192-cbc"; - case SSH2_CIPHER_CAMELLIA256_CBC: - return "camellia256-cbc"; - case SSH2_CIPHER_CAMELLIA128_CTR: - return "camellia128-ctr"; - case SSH2_CIPHER_CAMELLIA192_CTR: - return "camellia192-ctr"; - case SSH2_CIPHER_CAMELLIA256_CTR: - return "camellia256-ctr"; - case SSH2_CIPHER_AES128_GCM: - return "aes12****@opens*****"; - case SSH2_CIPHER_AES256_GCM: - return "aes25****@opens*****"; - - default: - return "Unknown"; - } -} - void CRYPT_get_cipher_info(PTInstVar pvar, char *dest, int len) { UTIL_get_lang_msg("DLG_ABOUT_CIPHER_INFO", pvar, Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,186 @@ +/* + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ttxssh.h" +#include "hostkey.h" +#include "kex.h" + + +struct ssh2_host_key_t { + ssh_keytype type; + char *name; +}; + +static const struct ssh2_host_key_t ssh2_host_key[] = { + {KEY_RSA1, "ssh-rsa1"}, // for SSH1 only + {KEY_RSA, "ssh-rsa"}, // RFC4253 + {KEY_DSA, "ssh-dss"}, // RFC4253 + {KEY_ECDSA256, "ecdsa-sha2-nistp256"}, // RFC5656 + {KEY_ECDSA384, "ecdsa-sha2-nistp384"}, // RFC5656 + {KEY_ECDSA521, "ecdsa-sha2-nistp521"}, // RFC5656 + {KEY_ED25519, "ssh-ed25519"}, // draft-bjh21-ssh-ed25519-02 + {KEY_UNSPEC, "ssh-unknown"}, + {KEY_NONE, NULL}, +}; + +struct ssh_digest_t { + digest_algorithm id; + char *name; +}; + +/* NB. Indexed directly by algorithm number */ +static const struct ssh_digest_t ssh_digests[] = { + { SSH_DIGEST_MD5, "MD5" }, + { SSH_DIGEST_RIPEMD160, "RIPEMD160" }, + { SSH_DIGEST_SHA1, "SHA1" }, + { SSH_DIGEST_SHA256, "SHA256" }, + { SSH_DIGEST_SHA384, "SHA384" }, + { SSH_DIGEST_SHA512, "SHA512" }, + { SSH_DIGEST_MAX, NULL }, +}; + + +ssh_keytype get_hostkey_type_from_name(char *name) +{ + if (strcmp(name, "rsa1") == 0) { + return KEY_RSA1; + } else if (strcmp(name, "rsa") == 0) { + return KEY_RSA; + } else if (strcmp(name, "dsa") == 0) { + return KEY_DSA; + } else if (strcmp(name, "ssh-rsa") == 0) { + return KEY_RSA; + } else if (strcmp(name, "ssh-dss") == 0) { + return KEY_DSA; + } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) { + return KEY_ECDSA256; + } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) { + return KEY_ECDSA384; + } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) { + return KEY_ECDSA521; + } else if (strcmp(name, "ssh-ed25519") == 0) { + return KEY_ED25519; + } + return KEY_UNSPEC; +} + +char* get_ssh2_hostkey_type_name(ssh_keytype type) +{ + const struct ssh2_host_key_t *ptr = ssh2_host_key; + + while (ptr->name != NULL) { + if (type == ptr->type) { + return ptr->name; + } + ptr++; + } + + // not found. + return "ssh-unknown"; +} + +char *get_ssh2_hostkey_type_name_from_key(Key *key) +{ + return get_ssh2_hostkey_type_name(key->type); +} + +char* get_digest_algorithm_name(digest_algorithm id) +{ + const struct ssh_digest_t *ptr = ssh_digests; + + while (ptr->name != NULL) { + if (id == ptr->id) { + return ptr->name; + } + ptr++; + } + + // not found. + return "unknown"; +} + +void normalize_host_key_order(char *buf) +{ + static char default_strings[] = { + KEY_ECDSA256, + KEY_ECDSA384, + KEY_ECDSA521, + KEY_ED25519, + KEY_RSA, + KEY_DSA, + KEY_NONE, + }; + + normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); +} + +ssh_keytype choose_SSH2_host_key_algorithm(char *server_proposal, char *my_proposal) +{ + ssh_keytype type = KEY_UNSPEC; + char str_keytype[20]; + const struct ssh2_host_key_t *ptr = ssh2_host_key; + + choose_SSH2_proposal(server_proposal, my_proposal, str_keytype, sizeof(str_keytype)); + + while (ptr->name != NULL) { + if (strcmp(ptr->name, str_keytype) == 0) { + type = ptr->type; + break; + } + ptr++; + } + + return (type); +} + +// Host Key\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B +// (2011.2.28 yutaka) +void SSH2_update_host_key_myproposal(PTInstVar pvar) +{ + static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB + int index; + int len, i; + + // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) + if (pvar->socket != INVALID_SOCKET) { + return; + } + + buf[0] = '\0'; + for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) { + index = pvar->settings.HostKeyOrder[i] - '0'; + if (index == KEY_NONE) // disabled line + break; + strncat_s(buf, sizeof(buf), get_ssh2_hostkey_type_name(index), _TRUNCATE); + strncat_s(buf, sizeof(buf), ",", _TRUNCATE); + } + len = strlen(buf); + if (len > 0) + buf[len - 1] = '\0'; // get rid of comma + myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf; +} Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,85 @@ +/* + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HOSTKEY_H +#define HOSTKEY_H + +typedef struct Key Key; + +typedef enum { + KEY_NONE, + KEY_RSA1, + KEY_RSA, + KEY_DSA, + KEY_ECDSA256, + KEY_ECDSA384, + KEY_ECDSA521, + KEY_ED25519, + KEY_UNSPEC, + KEY_MAX = KEY_UNSPEC, +} ssh_keytype; +#define isFixedLengthKey(type) ((type) >= KEY_DSA && (type) <= KEY_ED25519) + +// fingerprint\x82̎\xED\x95\xCA +typedef enum { + SSH_FP_DEFAULT = 0, + SSH_FP_HEX, + SSH_FP_BASE64, + SSH_FP_BUBBLEBABBLE, + SSH_FP_RANDOMART +} fp_rep; + +/* +enum fp_type { + SSH_FP_MD5, + SSH_FP_SHA1, + SSH_FP_SHA256 +}; +*/ + +typedef enum { + SSH_DIGEST_MD5, + SSH_DIGEST_RIPEMD160, + SSH_DIGEST_SHA1, + SSH_DIGEST_SHA256, + SSH_DIGEST_SHA384, + SSH_DIGEST_SHA512, + SSH_DIGEST_MAX, +} digest_algorithm; + + +ssh_keytype get_hostkey_type_from_name(char *name); +char* get_ssh2_hostkey_type_name(ssh_keytype type); +char *get_ssh2_hostkey_type_name_from_key(Key *key); +char* get_digest_algorithm_name(digest_algorithm id); + +void normalize_host_key_order(char *buf); +ssh_keytype choose_SSH2_host_key_algorithm(char *server_proposal, char *my_proposal); +void SSH2_update_host_key_myproposal(PTInstVar pvar); + +#endif /* SSHCMAC_H */ Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -485,7 +485,7 @@ } index += (p - cp); // setup index *p = '\0'; - key_type = get_keytype_from_name(cp); + key_type = get_hostkey_type_from_name(cp); *p = ' '; index += eat_spaces(data + index); // update index @@ -763,7 +763,7 @@ } index += (p - cp); // setup index *p = '\0'; - ktype = get_keytype_from_name(cp); + ktype = get_hostkey_type_from_name(cp); *p = ' '; index += eat_spaces(data + index); // update index @@ -1117,13 +1117,13 @@ if (pvar->ssh_state.tcpport == 22) { _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n", pvar->hosts_state.prefetched_hostname, - get_sshname_from_key(key), + get_ssh2_hostkey_type_name_from_key(key), uu); } else { _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n", pvar->hosts_state.prefetched_hostname, pvar->ssh_state.tcpport, - get_sshname_from_key(key), + get_ssh2_hostkey_type_name_from_key(key), uu); } } @@ -1213,7 +1213,7 @@ if (tcpport == 22) { _snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n", hostname, - get_sshname_from_key(key), + get_ssh2_hostkey_type_name_from_key(key), uu); } else { @@ -1220,7 +1220,7 @@ _snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n", hostname, tcpport, - get_sshname_from_key(key), + get_ssh2_hostkey_type_name_from_key(key), uu); } } Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -29,8 +29,140 @@ #include "ttxssh.h" #include "kex.h" + +char *myproposal[PROPOSAL_MAX] = { + KEX_DEFAULT_KEX, + KEX_DEFAULT_PK_ALG, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_ENCRYPT, + KEX_DEFAULT_MAC, + KEX_DEFAULT_MAC, + KEX_DEFAULT_COMP, + KEX_DEFAULT_COMP, + KEX_DEFAULT_LANG, + KEX_DEFAULT_LANG, +}; + +struct ssh2_kex_algorithm_t { + kex_algorithm kextype; + char *name; + const EVP_MD *(*evp_md)(void); +}; + +static const struct ssh2_kex_algorithm_t ssh2_kex_algorithms[] = { + {KEX_DH_GRP1_SHA1, "diffie-hellman-group1-sha1", EVP_sha1}, // RFC4253 + {KEX_DH_GRP14_SHA1, "diffie-hellman-group14-sha1", EVP_sha1}, // RFC4253 + {KEX_DH_GEX_SHA1, "diffie-hellman-group-exchange-sha1", EVP_sha1}, // RFC4419 + {KEX_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256", EVP_sha256}, // RFC4419 + {KEX_ECDH_SHA2_256, "ecdh-sha2-nistp256", EVP_sha256}, // RFC5656 + {KEX_ECDH_SHA2_384, "ecdh-sha2-nistp384", EVP_sha384}, // RFC5656 + {KEX_ECDH_SHA2_521, "ecdh-sha2-nistp521", EVP_sha512}, // RFC5656 + {KEX_DH_GRP14_SHA256, "diffie-hellman-group14-sha256", EVP_sha256}, // RFC8268 + {KEX_DH_GRP16_SHA512, "diffie-hellman-group16-sha512", EVP_sha512}, // RFC8268 + {KEX_DH_GRP18_SHA512, "diffie-hellman-group18-sha512", EVP_sha512}, // RFC8268 + {KEX_DH_NONE , NULL, NULL}, +}; + + extern SSHKeys current_keys[MODE_MAX]; + +char* get_kex_algorithm_name(kex_algorithm kextype) +{ + const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; + + while (ptr->name != NULL) { + if (kextype == ptr->kextype) { + return ptr->name; + } + ptr++; + } + + // not found. + return "unknown"; +} + +const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype) +{ + const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; + + while (ptr->name != NULL) { + if (kextype == ptr->kextype) { + return ptr->evp_md(); + } + ptr++; + } + + // not found. + return EVP_md_null(); +} + +void normalize_kex_order(char *buf) +{ + static char default_strings[] = { + KEX_ECDH_SHA2_256, + KEX_ECDH_SHA2_384, + KEX_ECDH_SHA2_521, + KEX_DH_GRP18_SHA512, + KEX_DH_GRP16_SHA512, + KEX_DH_GRP14_SHA256, + KEX_DH_GEX_SHA256, + KEX_DH_GEX_SHA1, + KEX_DH_GRP14_SHA1, + KEX_DH_GRP1_SHA1, + KEX_DH_NONE, + }; + + normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); +} + +kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal) +{ + kex_algorithm type = KEX_DH_UNKNOWN; + char str_kextype[40]; + const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; + + choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype)); + + while (ptr->name != NULL) { + if (strcmp(ptr->name, str_kextype) == 0) { + type = ptr->kextype; + break; + } + ptr++; + } + + return (type); +} + +// KEX\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B +// (2011.2.28 yutaka) +void SSH2_update_kex_myproposal(PTInstVar pvar) +{ + static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB + int index; + int len, i; + + // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) + if (pvar->socket != INVALID_SOCKET) { + return; + } + + buf[0] = '\0'; + for (i = 0 ; pvar->settings.KexOrder[i] != 0 ; i++) { + index = pvar->settings.KexOrder[i] - '0'; + if (index == KEX_DH_NONE) // disabled line + break; + strncat_s(buf, sizeof(buf), get_kex_algorithm_name(index), _TRUNCATE); + strncat_s(buf, sizeof(buf), ",", _TRUNCATE); + } + len = strlen(buf); + if (len > 0) + buf[len - 1] = '\0'; // get rid of comma + myproposal[PROPOSAL_KEX_ALGS] = buf; +} + + static DH *dh_new_group_asc(const char *gen, const char *modulus) { DH *dh = NULL; Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -26,8 +26,59 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef KEX_H +#define KEX_H + #include "ttxssh.h" +// \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x83T\x81[\x83o\x82ւ̒\xF1\x88Ď\x96\x8D\x80 +enum kex_init_proposals { + PROPOSAL_KEX_ALGS, + PROPOSAL_SERVER_HOST_KEY_ALGS, + PROPOSAL_ENC_ALGS_CTOS, + PROPOSAL_ENC_ALGS_STOC, + PROPOSAL_MAC_ALGS_CTOS, + PROPOSAL_MAC_ALGS_STOC, + PROPOSAL_COMP_ALGS_CTOS, + PROPOSAL_COMP_ALGS_STOC, + PROPOSAL_LANG_CTOS, + PROPOSAL_LANG_STOC, + PROPOSAL_MAX +}; + +#define KEX_DEFAULT_KEX "" +#define KEX_DEFAULT_PK_ALG "" +#define KEX_DEFAULT_ENCRYPT "" +#define KEX_DEFAULT_MAC "" +#define KEX_DEFAULT_COMP "" +#define KEX_DEFAULT_LANG "" + +extern char *myproposal[PROPOSAL_MAX]; + +typedef enum { + KEX_DH_NONE, /* disabled line */ + KEX_DH_GRP1_SHA1, + KEX_DH_GRP14_SHA1, + KEX_DH_GEX_SHA1, + KEX_DH_GEX_SHA256, + KEX_ECDH_SHA2_256, + KEX_ECDH_SHA2_384, + KEX_ECDH_SHA2_521, + KEX_DH_GRP14_SHA256, + KEX_DH_GRP16_SHA512, + KEX_DH_GRP18_SHA512, + KEX_DH_UNKNOWN, + KEX_DH_MAX = KEX_DH_UNKNOWN, +} kex_algorithm; + +char* get_kex_algorithm_name(kex_algorithm kextype); +const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype); + +void normalize_kex_order(char *buf); +kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal); +void SSH2_update_kex_myproposal(PTInstVar pvar); + + // SSH_MSG_KEY_DH_GEX_REQUEST \x82ł\xCC min, n, max \x82\xAA\x82Ƃ蓾\x82\xE9\x94͈͂̏\xE3\x8C\xC0/\x89\xBA\x8C\xC0 (RFC 4419) #define GEX_GRP_LIMIT_MIN 1024 #define GEX_GRP_LIMIT_MAX 8192 @@ -85,3 +136,5 @@ int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub); void kex_derive_keys(PTInstVar pvar, int need, u_char *hash, BIGNUM *shared_secret, char *session_id, int session_id_len); + +#endif /* KEX_H */ Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -392,7 +392,7 @@ len = get_uint32_MSBfirst(ptr); ptr += 4; - if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) { + if (strncmp(get_ssh2_hostkey_type_name(keytype), ptr, len) != 0) { ret = -3; goto error; } @@ -448,7 +448,7 @@ } static int ssh_ed25519_verify(Key *key, unsigned char *signature, unsigned int signaturelen, - unsigned char *data, unsigned int datalen) + unsigned char *data, unsigned int datalen) { buffer_t *b; char *ktype = NULL; @@ -979,7 +979,7 @@ // // fingerprint\x81i\x8Ew\x96\xE4\x81F\x83z\x83X\x83g\x8C\xF6\x8AJ\x8C\xAE\x82̃n\x83b\x83V\x83\x85\x81j\x82\xAC\x82\xB7\x82\xE9 // -char *key_fingerprint(Key *key, enum fp_rep dgst_rep, digest_algorithm dgst_alg) +char *key_fingerprint(Key *key, fp_rep dgst_rep, digest_algorithm dgst_alg) { char *retval = NULL, *alg; unsigned char *dgst_raw; @@ -1240,42 +1240,6 @@ } } -// -// \x83L\x81[\x82\xA9\x82當\x8E\x9A\x97\xF1\x82\xF0\x95ԋp\x82\xB7\x82\xE9 -// -char *get_sshname_from_key(Key *key) -{ - return get_ssh_keytype_name(key->type); -} - -// -// \x83L\x81[\x95\xB6\x8E\x9A\x97\xE7\x8E\xED\x95ʂ肷\x82\xE9 -// -ssh_keytype get_keytype_from_name(char *name) -{ - if (strcmp(name, "rsa1") == 0) { - return KEY_RSA1; - } else if (strcmp(name, "rsa") == 0) { - return KEY_RSA; - } else if (strcmp(name, "dsa") == 0) { - return KEY_DSA; - } else if (strcmp(name, "ssh-rsa") == 0) { - return KEY_RSA; - } else if (strcmp(name, "ssh-dss") == 0) { - return KEY_DSA; - } else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) { - return KEY_ECDSA256; - } else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) { - return KEY_ECDSA384; - } else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) { - return KEY_ECDSA521; - } else if (strcmp(name, "ssh-ed25519") == 0) { - return KEY_ED25519; - } - return KEY_UNSPEC; -} - - ssh_keytype key_curve_name_to_keytype(char *name) { if (strcmp(name, "nistp256") == 0) { @@ -1318,7 +1282,7 @@ BIGNUM *p, *q, *g, *pub_key; b = buffer_init(); - sshname = get_sshname_from_key(key); + sshname = get_ssh2_hostkey_type_name_from_key(key); switch (key->type) { case KEY_RSA: @@ -1411,7 +1375,7 @@ key[keynamelen] = 0; data += keynamelen; - type = get_keytype_from_name(key); + type = get_hostkey_type_from_name(key); switch (type) { case KEY_RSA: // RSA key @@ -1618,7 +1582,7 @@ } - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_append_length(msg, sig, slen); len = buffer_len(msg); @@ -1676,7 +1640,7 @@ DSA_SIG_free(sig); // setting - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_append_length(msg, sigblob, sizeof(sigblob)); len = buffer_len(msg); @@ -1735,7 +1699,7 @@ buffer_put_bignum2(buf2, bs); ECDSA_SIG_free(sig); - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2)); buffer_free(buf2); @@ -1791,7 +1755,7 @@ switch (keypair->type) { case KEY_RSA: // RSA - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); RSA_get0_key(keypair->rsa, &n, &e, NULL); buffer_put_string(msg, s, strlen(s)); buffer_put_bignum2(msg, e); // \x8C\xF6\x8AJ\x8Ew\x90\x94 @@ -1800,7 +1764,7 @@ case KEY_DSA: // DSA DSA_get0_pqg(keypair->dsa, &p, &q, &g); DSA_get0_key(keypair->dsa, &pub_key, NULL); - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); buffer_put_string(msg, s, strlen(s)); buffer_put_bignum2(msg, p); // \x91f\x90\x94 buffer_put_bignum2(msg, q); // (p-1)\x82̑f\x88\xF6\x90\x94 @@ -1810,7 +1774,7 @@ case KEY_ECDSA256: // ECDSA case KEY_ECDSA384: case KEY_ECDSA521: - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); buffer_put_string(msg, s, strlen(s)); tmp = curve_keytype_to_name(keypair->type); buffer_put_string(msg, tmp, strlen(tmp)); @@ -1818,7 +1782,7 @@ EC_KEY_get0_public_key(keypair->ecdsa)); break; case KEY_ED25519: - s = get_sshname_from_key(keypair); + s = get_ssh2_hostkey_type_name_from_key(keypair); buffer_put_cstring(msg, s); buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ); break; @@ -1890,7 +1854,7 @@ BIGNUM *e, *n, *d, *iqmp, *p, *q; BIGNUM *g, *pub_key, *priv_key; - s = get_sshname_from_key(key); + s = get_ssh2_hostkey_type_name_from_key(key); buffer_put_cstring(b, s); switch (key->type) { @@ -1978,7 +1942,7 @@ type_name = buffer_get_string_msg(blob, NULL); if (type_name == NULL) goto error; - type = get_keytype_from_name(type_name); + type = get_hostkey_type_from_name(type_name); k = key_new_private(type); @@ -2242,7 +2206,8 @@ if (index == KEY_NONE) // disabled line break; - if (strcmp(get_sshname_from_key(key), get_ssh_keytype_name(index)) == 0) + if (strcmp(get_ssh2_hostkey_type_name_from_key(key), + get_ssh2_hostkey_type_name(index)) == 0) return 1; } @@ -2314,7 +2279,7 @@ fp = key_fingerprint(ctx->keys[i], SSH_FP_BASE64, SSH_DIGEST_SHA256); break; } - strncat_s(buf, buf_len, get_sshname_from_key(ctx->keys[i]), _TRUNCATE); + strncat_s(buf, buf_len, get_ssh2_hostkey_type_name_from_key(ctx->keys[i]), _TRUNCATE); strncat_s(buf, buf_len, " ", _TRUNCATE); if (fp != NULL) { strncat_s(buf, buf_len, fp, _TRUNCATE); @@ -2342,7 +2307,7 @@ fp = key_fingerprint(ctx->old_keys[i], SSH_FP_BASE64, SSH_DIGEST_SHA256); break; } - strncat_s(buf, buf_len, get_sshname_from_key(ctx->old_keys[i]), _TRUNCATE); + strncat_s(buf, buf_len, get_ssh2_hostkey_type_name_from_key(ctx->old_keys[i]), _TRUNCATE); strncat_s(buf, buf_len, " ", _TRUNCATE); if (fp != NULL) { strncat_s(buf, buf_len, fp, _TRUNCATE); @@ -2557,7 +2522,7 @@ if (ret != 1) { logprintf(LOG_LEVEL_ERROR, "server gave bad signature for %s key %u", - get_sshname_from_key(ctx->keys[i]), i); + get_ssh2_hostkey_type_name_from_key(ctx->keys[i]), i); goto error; } ndone++; @@ -2628,13 +2593,14 @@ blob = NULL; fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5); - logprintf(LOG_LEVEL_VERBOSE, "Received %s host key %s", get_sshname_from_key(key), fp); + logprintf(LOG_LEVEL_VERBOSE, "Received %s host key %s", + get_ssh2_hostkey_type_name_from_key(key), fp); free(fp); // \x8B\x96\x89\xB3\x82ꂽ\x83z\x83X\x83g\x83L\x81[\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82\xA9\x82\xF0\x83`\x83F\x83b\x83N\x82\xB7\x82\xE9\x81B if (check_hostkey_algorithm(pvar, key) == 0) { logprintf(LOG_LEVEL_VERBOSE, "%s host key is not permitted by ts.HostKeyOrder", - get_sshname_from_key(key)); + get_ssh2_hostkey_type_name_from_key(key)); continue; } @@ -2644,7 +2610,7 @@ for (i = 0; i < ctx->nkeys; i++) { if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) { logprintf(LOG_LEVEL_ERROR, "Received duplicated %s host key", - get_sshname_from_key(key)); + get_ssh2_hostkey_type_name_from_key(key)); goto error; } } Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -44,11 +44,9 @@ BOOL key_copy(Key *dest, Key *src); char *key_fingerprint_raw(Key *k, digest_algorithm dgst_alg, int *dgst_raw_length); -char *key_fingerprint(Key *key, enum fp_rep dgst_rep, digest_algorithm dgst_alg); +char *key_fingerprint(Key *key, fp_rep dgst_rep, digest_algorithm dgst_alg); const char *ssh_key_type(ssh_keytype type); -char *get_sshname_from_key(Key *key); -ssh_keytype get_keytype_from_name(char *name); char *curve_keytype_to_name(ssh_keytype type); ssh_keytype key_curve_name_to_keytype(char *name); @@ -74,4 +72,4 @@ int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen); -#endif +#endif /* __KEY_H_ */ Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -379,7 +379,7 @@ unsigned int len, klen, nkeys, blocksize, keylen, ivlen, slen, rounds; unsigned int check1, check2, m1len, m2len; int dlen, i; - SSH2Cipher *cipher; + const struct ssh2cipher *cipher; size_t authlen; EVP_CIPHER_CTX *cipher_ctx = NULL; int ret; @@ -982,9 +982,9 @@ macdata = buffer_init(); - len = strlen(get_ssh_keytype_name(result->type)); + len = strlen(get_ssh2_hostkey_type_name(result->type)); buffer_put_int(macdata, len); - buffer_append(macdata, get_ssh_keytype_name(result->type), len); + buffer_append(macdata, get_ssh2_hostkey_type_name(result->type), len); len = strlen(encname); buffer_put_int(macdata, len); buffer_append(macdata, encname, len); Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,191 @@ +/* + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ttxssh.h" +#include "mac.h" +#include "kex.h" + + +struct SSH2Mac { + SSH2MacId id; + char *name; + const EVP_MD *(*evp_md)(void); + int truncatebits; + int etm; +}; + +static const struct SSH2Mac ssh2_macs[] = { + {HMAC_SHA1, "hmac-sha1", EVP_sha1, 0, 0}, // RFC4253 + {HMAC_MD5, "hmac-md5", EVP_md5, 0, 0}, // RFC4253 + {HMAC_SHA1_96, "hmac-sha1-96", EVP_sha1, 96, 0}, // RFC4253 + {HMAC_MD5_96, "hmac-md5-96", EVP_md5, 96, 0}, // RFC4253 + {HMAC_RIPEMD160, "hmac-****@opens*****", EVP_ripemd160, 0, 0}, + {HMAC_SHA2_256, "hmac-sha2-256", EVP_sha256, 0, 0}, // RFC6668 +// {HMAC_SHA2_256_96, "hmac-sha2-256-96", EVP_sha256, 96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06 + {HMAC_SHA2_512, "hmac-sha2-512", EVP_sha512, 0, 0}, // RFC6668 +// {HMAC_SHA2_512_96, "hmac-sha2-512-96", EVP_sha512, 96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06 + {HMAC_SHA1_EtM, "hmac-****@opens*****", EVP_sha1, 0, 1}, + {HMAC_MD5_EtM, "hmac-****@opens*****", EVP_md5, 0, 1}, + {HMAC_SHA1_96_EtM, "hmac-****@opens*****", EVP_sha1, 96, 1}, + {HMAC_MD5_96_EtM, "hmac-****@opens*****", EVP_md5, 96, 1}, + {HMAC_RIPEMD160_EtM,"hmac-****@opens*****",EVP_ripemd160, 0, 1}, + {HMAC_SHA2_256_EtM, "hmac-****@opens*****", EVP_sha256, 0, 1}, + {HMAC_SHA2_512_EtM, "hmac-****@opens*****", EVP_sha512, 0, 1}, + {HMAC_IMPLICIT, "<implicit>", EVP_md_null, 0, 0}, // for AEAD cipher + {HMAC_NONE, NULL, NULL, 0, 0}, +}; + + +char* get_ssh2_mac_name(const struct SSH2Mac *mac) +{ + if (mac) { + return mac->name; + } + else { + return "unknown"; + } +} + +char* get_ssh2_mac_name_by_id(const SSH2MacId id) +{ + return get_ssh2_mac_name(get_ssh2_mac(id)); +} + +const EVP_MD* get_ssh2_mac_EVP_MD(const struct SSH2Mac *mac) +{ + if (mac) { + return mac->evp_md(); + } + else { + return EVP_md_null(); + } +} + +const struct SSH2Mac *get_ssh2_mac(SSH2MacId id) +{ + const struct SSH2Mac *ptr = ssh2_macs; + + while (ptr->name != NULL) { + if (ptr->id == id) { + return ptr; + } + ptr++; + } + + return NULL; +} + +int get_ssh2_mac_truncatebits(const struct SSH2Mac *mac) +{ + if (mac) { + return mac->truncatebits; + } + else { + return 0; + } +} + +int get_ssh2_mac_etm(const struct SSH2Mac *mac) +{ + if (mac) { + return mac->etm; + } + else { + return 0; + } +} + +void normalize_mac_order(char *buf) +{ + static char default_strings[] = { + HMAC_SHA2_512_EtM, + HMAC_SHA2_256_EtM, + HMAC_SHA1_EtM, + HMAC_SHA2_512, + HMAC_SHA2_256, + HMAC_SHA1, + HMAC_RIPEMD160_EtM, + HMAC_RIPEMD160, + HMAC_MD5_EtM, + HMAC_MD5, + HMAC_NONE, + HMAC_SHA1_96_EtM, + HMAC_MD5_96_EtM, + HMAC_SHA1_96, + HMAC_MD5_96, + 0, // Dummy for HMAC_SHA2_512_96, + 0, // Dummy for HMAC_SHA2_256_96, + }; + + normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); +} + +const struct SSH2Mac *choose_SSH2_mac_algorithm(char *server_proposal, char *my_proposal) +{ + char str_hmac[64]; + const struct SSH2Mac *ptr = ssh2_macs; + + choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac)); + + while (ptr->name != NULL) { + if (strcmp(ptr->name, str_hmac) == 0) { + return ptr; + } + ptr++; + } + + return (NULL); +} + +// HMAC\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B +// (2011.2.28 yutaka) +void SSH2_update_hmac_myproposal(PTInstVar pvar) +{ + static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB + int index; + int len, i; + + // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) + if (pvar->socket != INVALID_SOCKET) { + return; + } + + buf[0] = '\0'; + for (i = 0 ; pvar->settings.MacOrder[i] != 0 ; i++) { + index = pvar->settings.MacOrder[i] - '0'; + if (index == HMAC_NONE) // disabled line + break; + strncat_s(buf, sizeof(buf), get_ssh2_mac_name_by_id(index), _TRUNCATE); + strncat_s(buf, sizeof(buf), ",", _TRUNCATE); + } + len = strlen(buf); + if (len > 0) + buf[len - 1] = '\0'; // get rid of comma + myproposal[PROPOSAL_MAC_ALGS_CTOS] = buf; + myproposal[PROPOSAL_MAC_ALGS_STOC] = buf; +} Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,69 @@ +/* + * (C) 2021- TeraTerm Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SSHMAC_H +#define SSHMAC_H + +#include "ttxssh.h" + +struct SSH2Mac; + +typedef enum { + HMAC_NONE, /* disabled line */ + HMAC_SHA1, + HMAC_MD5, + HMAC_SHA1_96, + HMAC_MD5_96, + HMAC_RIPEMD160, + HMAC_SHA2_256, + HMAC_SHA2_256_96, + HMAC_SHA2_512, + HMAC_SHA2_512_96, + HMAC_SHA1_EtM, + HMAC_MD5_EtM, + HMAC_SHA1_96_EtM, + HMAC_MD5_96_EtM, + HMAC_RIPEMD160_EtM, + HMAC_SHA2_256_EtM, + HMAC_SHA2_512_EtM, + HMAC_IMPLICIT, + HMAC_UNKNOWN, + HMAC_MAX = HMAC_UNKNOWN, +} SSH2MacId; + +char* get_ssh2_mac_name(const struct SSH2Mac *mac); +char* get_ssh2_mac_name_by_id(SSH2MacId id); +const EVP_MD* get_ssh2_mac_EVP_MD(const struct SSH2Mac *mac); +const struct SSH2Mac *get_ssh2_mac(SSH2MacId id); +int get_ssh2_mac_truncatebits(const struct SSH2Mac *mac); +int get_ssh2_mac_etm(const struct SSH2Mac *mac); +void normalize_mac_order(char *buf); +const struct SSH2Mac *choose_SSH2_mac_algorithm(char *server_proposal, char *my_proposal); +void SSH2_update_hmac_myproposal(PTInstVar pvar); + +#endif /* SSHCMAC_H */ Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -4339,239 +4339,6 @@ #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__) -// -// general -// - -int get_cipher_block_size(SSH2Cipher *cipher) -{ - int blocksize = 0; - - if (cipher) { - blocksize = cipher->block_size; - } - - return max(blocksize, 8); -} - -int get_cipher_key_len(SSH2Cipher *cipher) -{ - if (cipher) { - return cipher->key_len; - } - else { - return 0; - } -} - -int get_cipher_discard_len(SSH2Cipher *cipher) -{ - if (cipher) { - return cipher->discard_len; - } - else { - return 0; - } -} - -int get_cipher_iv_len(SSH2Cipher *cipher) -{ - if (cipher) { - if (cipher->iv_len != 0) { - return cipher->iv_len; - } - else { - return cipher->block_size; - } - } - else { - return 8; // block_size - } -} - -int get_cipher_auth_len(SSH2Cipher *cipher) -{ - if (cipher) { - return cipher->auth_len; - } - else { - return 0; - } -} - -// \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x96\xBC\x82\xA9\x82猟\x8D\x{142DC2}\xE9\x81B -SSH2Cipher *get_cipher_by_name(char *name) -{ - SSH2Cipher *ptr = ssh2_ciphers; - - if (name == NULL || name[0] == '\0') - return NULL; - - while (ptr->name != NULL) { - if (strcmp(ptr->name, name) == 0) { - return ptr; - } - ptr++; - } - - // not found. - return NULL; -} - -static char * get_cipher_string(SSH2Cipher *cipher) -{ - if (cipher) { - return cipher->name; - } - else { - return "unknown"; - } -} - -const EVP_CIPHER* get_cipher_EVP_CIPHER(SSH2Cipher *cipher) -{ - if (cipher) { - return cipher->func(); - } - else { - return EVP_enc_null(); - } -} - -char* get_kex_algorithm_name(kex_algorithm kextype) -{ - ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; - - while (ptr->name != NULL) { - if (kextype == ptr->kextype) { - return ptr->name; - } - ptr++; - } - - // not found. - return "unknown"; -} - -const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype) -{ - ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; - - while (ptr->name != NULL) { - if (kextype == ptr->kextype) { - return ptr->evp_md(); - } - ptr++; - } - - // not found. - return EVP_md_null(); -} - -SSH2Mac *get_ssh2_mac(SSH2MacId id) -{ - SSH2Mac *ptr = ssh2_macs; - - while (ptr->name != NULL) { - if (ptr->id == id) { - return ptr; - } - ptr++; - } - - return NULL; -} - -char* get_ssh2_mac_name(SSH2Mac *mac) -{ - if (mac) { - return mac->name; - } - else { - return "unknown"; - } -} - -char* get_ssh2_mac_name_by_id(SSH2MacId id) -{ - return get_ssh2_mac_name(get_ssh2_mac(id)); -} - -const EVP_MD* get_ssh2_mac_EVP_MD(SSH2Mac *mac) -{ - if (mac) { - return mac->evp_md(); - } - else { - return EVP_md_null(); - } -} - -int get_ssh2_mac_truncatebits(SSH2Mac *mac) -{ - if (mac) { - return mac->truncatebits; - } - else { - return 0; - } -} - -int get_ssh2_mac_etm(SSH2Mac *mac) -{ - if (mac) { - return mac->etm; - } - else { - return 0; - } -} - -char* get_ssh2_comp_name(compression_type type) -{ - ssh2_comp_t *ptr = ssh2_comps; - - while (ptr->name != NULL) { - if (type == ptr->type) { - return ptr->name; - } - ptr++; - } - - // not found. - return "unknown"; -} - -char* get_ssh_keytype_name(ssh_keytype type) -{ - ssh2_host_key_t *ptr = ssh2_host_key; - - while (ptr->name != NULL) { - if (type == ptr->type) { - return ptr->name; - } - ptr++; - } - - // not found. - return "ssh-unknown"; -} - -char* get_digest_algorithm_name(digest_algorithm id) -{ - ssh_digest_t *ptr = ssh_digests; - - while (ptr->name != NULL) { - if (id == ptr->id) { - return ptr->name; - } - ptr++; - } - - // not found. - return "unknown"; -} - static void do_write_buffer_file(void *buf, int len, char *file, int lineno) { FILE *fp; @@ -4599,248 +4366,6 @@ buffer_append(msg, buf, len); } -// the caller is normalize_cipher_order() -void SSH2_update_cipher_myproposal(PTInstVar pvar) -{ - static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB - int cipher; - int len, i; - char *c_str; - - // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) - if (pvar->socket != INVALID_SOCKET) { - return; - } - - // \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2004.11.6 yutaka) - buf[0] = '\0'; - for (i = 0 ; pvar->settings.CipherOrder[i] != 0 ; i++) { - cipher = pvar->settings.CipherOrder[i] - '0'; - if (cipher == 0) // disabled line - break; - switch (cipher) { - case SSH2_CIPHER_3DES_CBC: - c_str = "3des-cbc,"; - break; - case SSH2_CIPHER_3DES_CTR: - c_str = "3des-ctr,"; - break; - case SSH2_CIPHER_BLOWFISH_CBC: - c_str = "blowfish-cbc,"; - break; - case SSH2_CIPHER_BLOWFISH_CTR: - c_str = "blowfish-ctr,"; - break; - case SSH2_CIPHER_AES128_CBC: - c_str = "aes128-cbc,"; - break; - case SSH2_CIPHER_AES192_CBC: - c_str = "aes192-cbc,"; - break; - case SSH2_CIPHER_AES256_CBC: - c_str = "aes256-cbc,"; - break; - case SSH2_CIPHER_AES128_CTR: - c_str = "aes128-ctr,"; - break; - case SSH2_CIPHER_AES192_CTR: - c_str = "aes192-ctr,"; - break; - case SSH2_CIPHER_AES256_CTR: - c_str = "aes256-ctr,"; - break; - case SSH2_CIPHER_ARCFOUR: - c_str = "arcfour,"; - break; - case SSH2_CIPHER_ARCFOUR128: - c_str = "arcfour128,"; - break; - case SSH2_CIPHER_ARCFOUR256: - c_str = "arcfour256,"; - break; - case SSH2_CIPHER_CAST128_CBC: - c_str = "cast128-cbc,"; - break; - case SSH2_CIPHER_CAST128_CTR: - c_str = "cast128-ctr,"; - break; -#ifdef WITH_CAMELLIA_PRIVATE - case SSH2_CIPHER_CAMELLIA128_CBC: - c_str = "camellia128-cbc,camel****@opens*****,"; - break; - case SSH2_CIPHER_CAMELLIA192_CBC: - c_str = "camellia192-cbc,camel****@opens*****,"; - break; - case SSH2_CIPHER_CAMELLIA256_CBC: - c_str = "camellia256-cbc,camel****@opens*****,"; - break; - case SSH2_CIPHER_CAMELLIA128_CTR: - c_str = "camellia128-ctr,camel****@opens*****,"; - break; - case SSH2_CIPHER_CAMELLIA192_CTR: - c_str = "camellia192-ctr,camel****@opens*****,"; - break; - case SSH2_CIPHER_CAMELLIA256_CTR: - c_str = "camellia256-ctr,camel****@opens*****,"; - break; -#endif // WITH_CAMELLIA_PRIVATE - case SSH2_CIPHER_CAMELLIA128_CBC: - c_str = "camellia128-cbc,"; - break; - case SSH2_CIPHER_CAMELLIA192_CBC: - c_str = "camellia192-cbc,"; - break; - case SSH2_CIPHER_CAMELLIA256_CBC: - c_str = "camellia256-cbc,"; - break; - case SSH2_CIPHER_CAMELLIA128_CTR: - c_str = "camellia128-ctr,"; - break; - case SSH2_CIPHER_CAMELLIA192_CTR: - c_str = "camellia192-ctr,"; - break; - case SSH2_CIPHER_CAMELLIA256_CTR: - c_str = "camellia256-ctr,"; - break; - case SSH2_CIPHER_AES128_GCM: - c_str = "aes12****@opens*****,"; - break; - case SSH2_CIPHER_AES256_GCM: - c_str = "aes25****@opens*****,"; - break; - default: - continue; - } - strncat_s(buf, sizeof(buf), c_str, _TRUNCATE); - } - len = strlen(buf); - if (len > 0) - buf[len - 1] = '\0'; // get rid of comma - myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf; // Client To Server - myproposal[PROPOSAL_ENC_ALGS_STOC] = buf; // Server To Client -} - - -void SSH2_update_compression_myproposal(PTInstVar pvar) -{ - static char buf[128]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB - int index; - int len, i; - - // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) - if (pvar->socket != INVALID_SOCKET) { - return; - } - - // \x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82ɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2005.7.9 yutaka) - buf[0] = '\0'; - for (i = 0 ; pvar->settings.CompOrder[i] != 0 ; i++) { - index = pvar->settings.CompOrder[i] - '0'; - if (index == COMP_NONE) // disabled line - break; - strncat_s(buf, sizeof(buf), get_ssh2_comp_name(index), _TRUNCATE); - strncat_s(buf, sizeof(buf), ",", _TRUNCATE); - } - len = strlen(buf); - if (len > 0) - buf[len - 1] = '\0'; // get rid of comma - - // \x88\xB3\x8Fk\x8Ew\x92肪\x82Ȃ\xA2\x8Fꍇ\x82́A\x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82\xF0\x8C\x8F\x82Ƀ[\x83\x8D\x82ɂ\xB7\x82\xE9\x81B - if (buf[0] == '\0') { - pvar->settings.CompressionLevel = 0; - } - - if (pvar->settings.CompressionLevel == 0) { - _snprintf_s(buf, sizeof(buf), _TRUNCATE, get_ssh2_comp_name(COMP_NOCOMP)); - } - if (buf[0] != '\0') { - myproposal[PROPOSAL_COMP_ALGS_CTOS] = buf; // Client To Server - myproposal[PROPOSAL_COMP_ALGS_STOC] = buf; // Server To Client - } -} - -// KEX\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B -// (2011.2.28 yutaka) -void SSH2_update_kex_myproposal(PTInstVar pvar) -{ - static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB - int index; - int len, i; - - // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) - if (pvar->socket != INVALID_SOCKET) { - return; - } - - buf[0] = '\0'; - for (i = 0 ; pvar->settings.KexOrder[i] != 0 ; i++) { - index = pvar->settings.KexOrder[i] - '0'; - if (index == KEX_DH_NONE) // disabled line - break; - strncat_s(buf, sizeof(buf), get_kex_algorithm_name(index), _TRUNCATE); - strncat_s(buf, sizeof(buf), ",", _TRUNCATE); - } - len = strlen(buf); - if (len > 0) - buf[len - 1] = '\0'; // get rid of comma - myproposal[PROPOSAL_KEX_ALGS] = buf; -} - -// Host Key\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B -// (2011.2.28 yutaka) -void SSH2_update_host_key_myproposal(PTInstVar pvar) -{ - static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB - int index; - int len, i; - - // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) - if (pvar->socket != INVALID_SOCKET) { - return; - } - - buf[0] = '\0'; - for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) { - index = pvar->settings.HostKeyOrder[i] - '0'; - if (index == KEY_NONE) // disabled line - break; - strncat_s(buf, sizeof(buf), get_ssh_keytype_name(index), _TRUNCATE); - strncat_s(buf, sizeof(buf), ",", _TRUNCATE); - } - len = strlen(buf); - if (len > 0) - buf[len - 1] = '\0'; // get rid of comma - myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf; -} - -// HMAC\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B -// (2011.2.28 yutaka) -void SSH2_update_hmac_myproposal(PTInstVar pvar) -{ - static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB - int index; - int len, i; - - // \x92ʐM\x92\x86\x82ɂ͌Ă\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya) - if (pvar->socket != INVALID_SOCKET) { - return; - } - - buf[0] = '\0'; - for (i = 0 ; pvar->settings.MacOrder[i] != 0 ; i++) { - index = pvar->settings.MacOrder[i] - '0'; - if (index == HMAC_NONE) // disabled line - break; - strncat_s(buf, sizeof(buf), get_ssh2_mac_name_by_id(index), _TRUNCATE); - strncat_s(buf, sizeof(buf), ",", _TRUNCATE); - } - len = strlen(buf); - if (len > 0) - buf[len - 1] = '\0'; // get rid of comma - myproposal[PROPOSAL_MAC_ALGS_CTOS] = buf; - myproposal[PROPOSAL_MAC_ALGS_STOC] = buf; -} - // \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x83T\x81[\x83o\x82ւ̃L\x81[\x8C\xF0\x8A\xB7\x8AJ\x8En\x97v\x8B\x81 void SSH2_send_kexinit(PTInstVar pvar) { @@ -4920,11 +4445,99 @@ } -static void choose_SSH2_proposal(char *server_proposal, - char *my_proposal, - char *dest, - int dest_len) +void normalize_generic_order(char *buf, char default_strings[], int default_strings_len) { + char listed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1]; + char allowed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1]; + int i, j, k=-1; + + memset(listed, 0, sizeof(listed)); + memset(allowed, 0, sizeof(allowed)); + + // \x8B\x96\x89\xB3\x82\xEA\x82Ă\xA2\x82镶\x8E\x9A\x82̃\x8A\x83X\x83g\x82\xF0\x8D\xEC\x82\xE9\x81B + for (i = 0; i < default_strings_len ; i++) { + allowed[default_strings[i]] = 1; + } + + // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82𑖍\xB8\x82\xB5\x81A\x8B\x96\x89\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x81A\x8Fd\x95\xA1\x82\xB7\x82镶\x8E\x9A\x82͍폜\x82\xB7\x82\xE9\x81B + // + // ex. (i=5 \x82̕\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9) + // i=012345 + // >:=9<87;A@?B3026(\0) + // i+1 + // <------------> + // \x81\xAB + // >:=9<7;A@?B3026(\0) + // + for (i = 0; buf[i] != 0; i++) { + int num = buf[i] - '0'; + + if (num < 0 || num > default_strings_len + || !allowed[num] + || listed[num]) { + memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1); + i--; + } else { + listed[num] = 1; + } + + // disabled line\x82\xAA\x82\xA0\x82\xEA\x82A\x88ʒu\x82\xF0\x8Ao\x82\xA6\x82Ă\xA8\x82\xAD\x81B + if (num == 0) { + k = i; + } + } + + // \x8Ew\x92肳\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x82\xAA\x82\xA0\x82\xEA\x82Adisabled line\x82̒\xBC\x91O\x82ɑ}\x93\xFC\x82\xB7\x82\xE9\x81B + // + // ex. (Z\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9) + // k + // >:=9<87;A@?B3026(\0) + // k+1 + // <----> + // \x81\xAB k + // >:=9<87;A@?B30026(\0) + // \x81\xAB k + // >:=9<87;A@?B3Z026(\0) + // + for (j = 0; j < default_strings_len && default_strings[j] != 0; j++) { + int num = default_strings[j]; + + if (!listed[num] && k >= 0) { + int copylen = strlen(buf + k + 1) + 1; + + memmove(buf + k + 1, buf + k, copylen); + buf[k + 1 + copylen] = '\0'; // \x8FI\x92[\x82\xF0\x96Y\x82ꂸ\x82ɕt\x82\xAF\x82\xE9\x81B + buf[k] = num + '0'; + k++; + i++; + } + } + if (k < 0) { + j = 0; + } + else { + j++; + } + + // disabled line\x82\xAA\x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x8Fꍇ\x82́A\x82\xBB\x82̂܂ܖ\x96\x94\xF6\x82ɒlj\xC1\x82\xB7\x82\xE9\x81B + for (; j < default_strings_len ; j++) { + int num = default_strings[j]; + + if (!listed[num]) { + buf[i] = num + '0'; + listed[num] = 1; + i++; + } + } + + buf[i] = 0; +} + +void choose_SSH2_proposal(char *server_proposal, + char *my_proposal, + char *dest, + int dest_len) +{ char tmp_cli[1024], *ptr_cli, *ctc_cli; char tmp_svr[1024], *ptr_svr, *ctc_svr; @@ -4952,79 +4565,6 @@ } } -static kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal) -{ - kex_algorithm type = KEX_DH_UNKNOWN; - char str_kextype[40]; - ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms; - - choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype)); - - while (ptr->name != NULL) { - if (strcmp(ptr->name, str_kextype) == 0) { - type = ptr->kextype; - break; - } - ptr++; - } - - return (type); -} - -static SSH2Cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal) -{ - char str_cipher[32]; - SSH2Cipher *ptr = ssh2_ciphers; - - choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher)); - return get_cipher_by_name(str_cipher); -} - - -static SSH2Mac *choose_SSH2_mac_algorithm(char *server_proposal, char *my_proposal) -{ - char str_hmac[64]; - SSH2Mac *ptr = ssh2_macs; - - choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac)); - - while (ptr->name != NULL) { - if (strcmp(ptr->name, str_hmac) == 0) { - return ptr; - } - ptr++; - } - - return (NULL); -} - - -static compression_type choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal) -{ - compression_type type = COMP_UNKNOWN; - char str_comp[20]; - ssh2_comp_t *ptr = ssh2_comps; - - // OpenSSH 4.3\x82ł͒x\x89\x84\x83p\x83P\x83b\x83g\x88\xB3\x8Fk("zlib****@opens*****")\x82\xAA\x90V\x8BK\x92lj\xC1\x82\xB3\x82\xEA\x82Ă\xA2\x82邽\x82߁A - // \x83}\x83b\x83`\x82\xB5\x82Ȃ\xA2\x82悤\x82ɏC\x90\xB3\x82\xB5\x82\xBD\x81B - // \x8C\xBBTera Term\x82ł͒x\x89\x84\x83p\x83P\x83b\x83g\x88\xB3\x8Fk\x82͏\xAB\x97\x88\x93I\x82ɃT\x83|\x81[\x83g\x82\xB7\x82\xE9\x97\\x92\xE8\x81B - // (2006.6.14 yutaka) - // \x92x\x89\x84\x83p\x83P\x83b\x83g\x88\xB3\x8Fk\x82ɑΉ\x9E\x81B - // (2006.6.23 maya) - - choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp)); - - while (ptr->name != NULL) { - if (strcmp(ptr->name, str_comp) == 0) { - type = ptr->type; - break; - } - ptr++; - } - - return (type); -} - // \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̃L\x81[\x83T\x83C\x83Y\x81A\x83u\x83\x8D\x83b\x83N\x83T\x83C\x83Y\x81AMAC\x83T\x83C\x83Y\x82̂\xA4\x82\xBF\x8Dő\xE5\x92l(we_need)\x82\xF0\x8C\x88\x92肷\x82\xE9\x81B static void choose_SSH2_key_maxlength(PTInstVar pvar) { @@ -5031,8 +4571,8 @@ int mode, val; unsigned int need = 0; const EVP_MD *md; - SSH2Cipher *cipher; - SSH2Mac *mac; + const struct ssh2cipher *cipher; + const struct SSH2Mac *mac; for (mode = 0; mode < MODE_MAX; mode++) { cipher = pvar->ciphers[mode]; @@ -5097,7 +4637,6 @@ int len, size; char *msg = NULL; char tmp[1024+512]; - char str_keytype[20]; logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEXINIT was received."); @@ -5181,15 +4720,7 @@ logprintf(LOG_LEVEL_VERBOSE, "server proposal: server host key algorithm: %s", buf); - pvar->hostkey_type = KEY_UNSPEC; - choose_SSH2_proposal(buf, myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], str_keytype, sizeof(str_keytype)); - if (strlen(str_keytype) == 0) { // not match - strncpy_s(tmp, sizeof(tmp), "unknown host KEY type: ", _TRUNCATE); - strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); - msg = tmp; - goto error; - } - pvar->hostkey_type = get_keytype_from_name(str_keytype); + pvar->hostkey_type = choose_SSH2_host_key_algorithm(buf, myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]); if (pvar->hostkey_type == KEY_UNSPEC) { strncpy_s(tmp, sizeof(tmp), "unknown host KEY type: ", _TRUNCATE); strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE); @@ -5255,7 +4786,7 @@ logprintf(LOG_LEVEL_VERBOSE, "server proposal: MAC algorithm client to server: %s", buf); - if (pvar->ciphers[MODE_OUT]->auth_len > 0) { + if (get_cipher_auth_len(pvar->ciphers[MODE_OUT]) > 0) { logputs(LOG_LEVEL_VERBOSE, "AEAD cipher is selected, ignoring MAC algorithms. (client to server)"); pvar->macs[MODE_OUT] = get_ssh2_mac(HMAC_IMPLICIT); } @@ -5283,7 +4814,7 @@ logprintf(LOG_LEVEL_VERBOSE, "server proposal: MAC algorithm server to client: %s", buf); - if (pvar->ciphers[MODE_IN]->auth_len > 0) { + if (get_cipher_auth_len(pvar->ciphers[MODE_IN]) > 0) { logputs(LOG_LEVEL_VERBOSE, "AEAD cipher is selected, ignoring MAC algorithms. (server to client)"); pvar->macs[MODE_IN] = get_ssh2_mac(HMAC_IMPLICIT); } @@ -5400,7 +4931,7 @@ get_kex_algorithm_name(pvar->kex_type)); logprintf(LOG_LEVEL_VERBOSE, "server host key algorithm: %s", - get_ssh_keytype_name(pvar->hostkey_type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type)); logprintf(LOG_LEVEL_VERBOSE, "encryption algorithm client to server: %s", get_cipher_string(pvar->ciphers[MODE_OUT])); @@ -6028,7 +5559,7 @@ if (hostkey->type != pvar->hostkey_type) { // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar _snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_kex_reply", - get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type)); emsg = emsg_tmp; goto error; } @@ -6130,7 +5661,7 @@ if (hostkey->type != pvar->hostkey_type) { // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar _snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_kex_reply", - get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type)); emsg = emsg_tmp; goto error; } @@ -6293,7 +5824,7 @@ if (hostkey->type != pvar->hostkey_type) { // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar _snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_gex_reply", - get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type)); emsg = emsg_tmp; goto error; } @@ -6402,7 +5933,7 @@ if (hostkey->type != pvar->hostkey_type) { // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar _snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_gex_reply", - get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type)); emsg = emsg_tmp; goto error; } @@ -6566,7 +6097,7 @@ if (hostkey->type != pvar->hostkey_type) { // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar _snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_ecdh_kex_reply", - get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type)); emsg = emsg_tmp; goto error; } @@ -6674,7 +6205,7 @@ if (hostkey->type != pvar->hostkey_type) { // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar _snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE, "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_ecdh_kex_reply", - get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type)); + get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type)); emsg = emsg_tmp; goto error; } @@ -7091,7 +6622,7 @@ s = "publickey"; buffer_put_string(signbuf, s, strlen(s)); buffer_put_char(signbuf, 1); // true - s = get_sshname_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82\xE9 + s = get_ssh2_hostkey_type_name_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82\xE9 buffer_put_string(signbuf, s, strlen(s)); s = buffer_ptr(blob); buffer_append_length(signbuf, s, bloblen); @@ -7109,7 +6640,7 @@ s = "publickey"; buffer_put_string(msg, s, strlen(s)); buffer_put_char(msg, 1); // true - s = get_sshname_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82\xE9 + s = get_ssh2_hostkey_type_name_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82\xE9 buffer_put_string(msg, s, strlen(s)); s = buffer_ptr(blob); buffer_append_length(msg, s, bloblen); Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -40,6 +40,10 @@ #include "buffer.h" #include "config.h" +#include "cipher.h" +#include "hostkey.h" +#include "mac.h" +#include "comp.h" #include <sys/types.h> #include <sys/stat.h> @@ -82,24 +86,6 @@ } SSHMessage; typedef enum { - // SSH1 - SSH_CIPHER_NONE, SSH_CIPHER_IDEA, SSH_CIPHER_DES, SSH_CIPHER_3DES, - SSH_CIPHER_TSS, SSH_CIPHER_RC4, SSH_CIPHER_BLOWFISH, - // SSH2 - SSH2_CIPHER_3DES_CBC, SSH2_CIPHER_AES128_CBC, - SSH2_CIPHER_AES192_CBC, SSH2_CIPHER_AES256_CBC, - SSH2_CIPHER_BLOWFISH_CBC, SSH2_CIPHER_AES128_CTR, - SSH2_CIPHER_AES192_CTR, SSH2_CIPHER_AES256_CTR, - SSH2_CIPHER_ARCFOUR, SSH2_CIPHER_ARCFOUR128, SSH2_CIPHER_ARCFOUR256, - SSH2_CIPHER_CAST128_CBC, - SSH2_CIPHER_3DES_CTR, SSH2_CIPHER_BLOWFISH_CTR, SSH2_CIPHER_CAST128_CTR, - SSH2_CIPHER_CAMELLIA128_CBC, SSH2_CIPHER_CAMELLIA192_CBC, SSH2_CIPHER_CAMELLIA256_CBC, - SSH2_CIPHER_CAMELLIA128_CTR, SSH2_CIPHER_CAMELLIA192_CTR, SSH2_CIPHER_CAMELLIA256_CTR, - SSH2_CIPHER_AES128_GCM, SSH2_CIPHER_AES256_GCM, - SSH_CIPHER_MAX = SSH2_CIPHER_AES256_GCM, -} SSHCipherId; - -typedef enum { SSH_AUTH_NONE, SSH_AUTH_RHOSTS, SSH_AUTH_RSA, SSH_AUTH_PASSWORD, SSH_AUTH_RHOSTS_RSA, SSH_AUTH_TIS, SSH_AUTH_KERBEROS, SSH_AUTH_PAGEANT = 16, @@ -298,73 +284,8 @@ } SSH2TTYMode; -// \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x83T\x81[\x83o\x82ւ̒\xF1\x88Ď\x96\x8D\x80 -enum kex_init_proposals { - PROPOSAL_KEX_ALGS, - PROPOSAL_SERVER_HOST_KEY_ALGS, - PROPOSAL_ENC_ALGS_CTOS, - PROPOSAL_ENC_ALGS_STOC, - PROPOSAL_MAC_ALGS_CTOS, - PROPOSAL_MAC_ALGS_STOC, - PROPOSAL_COMP_ALGS_CTOS, - PROPOSAL_COMP_ALGS_STOC, - PROPOSAL_LANG_CTOS, - PROPOSAL_LANG_STOC, - PROPOSAL_MAX -}; - -#define KEX_DEFAULT_KEX "" -#define KEX_DEFAULT_PK_ALG "" -#define KEX_DEFAULT_ENCRYPT "" -#define KEX_DEFAULT_MAC "" -#define KEX_DEFAULT_COMP "" -#define KEX_DEFAULT_LANG "" - -static char *myproposal[PROPOSAL_MAX] = { - KEX_DEFAULT_KEX, - KEX_DEFAULT_PK_ALG, - KEX_DEFAULT_ENCRYPT, - KEX_DEFAULT_ENCRYPT, - KEX_DEFAULT_MAC, - KEX_DEFAULT_MAC, - KEX_DEFAULT_COMP, - KEX_DEFAULT_COMP, - KEX_DEFAULT_LANG, - KEX_DEFAULT_LANG, -}; - - -typedef enum { - KEY_NONE, - KEY_RSA1, - KEY_RSA, - KEY_DSA, - KEY_ECDSA256, - KEY_ECDSA384, - KEY_ECDSA521, - KEY_ED25519, - KEY_UNSPEC, - KEY_MAX = KEY_UNSPEC, -} ssh_keytype; #define isFixedLengthKey(type) ((type) >= KEY_DSA && (type) <= KEY_ED25519) -typedef struct ssh2_host_key { - ssh_keytype type; - char *name; -} ssh2_host_key_t; - -static ssh2_host_key_t ssh2_host_key[] = { - {KEY_RSA1, "ssh-rsa1"}, // for SSH1 only - {KEY_RSA, "ssh-rsa"}, // RFC4253 - {KEY_DSA, "ssh-dss"}, // RFC4253 - {KEY_ECDSA256, "ecdsa-sha2-nistp256"}, // RFC5656 - {KEY_ECDSA384, "ecdsa-sha2-nistp384"}, // RFC5656 - {KEY_ECDSA521, "ecdsa-sha2-nistp521"}, // RFC5656 - {KEY_ED25519, "ssh-ed25519"}, // draft-bjh21-ssh-ed25519-02 - {KEY_UNSPEC, "ssh-unknown"}, - {KEY_NONE, NULL}, -}; - /* Minimum modulus size (n) for RSA keys. */ #define SSH_RSA_MINIMUM_MODULUS_SIZE 768 @@ -376,165 +297,6 @@ #define SSH_KEYGEN_MAXIMUM_ROUNDS INT_MAX -typedef struct ssh2_cipher { - SSHCipherId id; - char *name; - int block_size; - int key_len; - int discard_len; - int iv_len; - int auth_len; - const EVP_CIPHER *(*func)(void); -} SSH2Cipher; - -static SSH2Cipher ssh2_ciphers[] = { - {SSH2_CIPHER_3DES_CBC, "3des-cbc", 8, 24, 0, 0, 0, EVP_des_ede3_cbc}, // RFC4253 - {SSH2_CIPHER_AES128_CBC, "aes128-cbc", 16, 16, 0, 0, 0, EVP_aes_128_cbc}, // RFC4253 - {SSH2_CIPHER_AES192_CBC, "aes192-cbc", 16, 24, 0, 0, 0, EVP_aes_192_cbc}, // RFC4253 - {SSH2_CIPHER_AES256_CBC, "aes256-cbc", 16, 32, 0, 0, 0, EVP_aes_256_cbc}, // RFC4253 - {SSH2_CIPHER_BLOWFISH_CBC, "blowfish-cbc", 8, 16, 0, 0, 0, EVP_bf_cbc}, // RFC4253 - {SSH2_CIPHER_AES128_CTR, "aes128-ctr", 16, 16, 0, 0, 0, evp_aes_128_ctr}, // RFC4344 - {SSH2_CIPHER_AES192_CTR, "aes192-ctr", 16, 24, 0, 0, 0, evp_aes_128_ctr}, // RFC4344 - {SSH2_CIPHER_AES256_CTR, "aes256-ctr", 16, 32, 0, 0, 0, evp_aes_128_ctr}, // RFC4344 - {SSH2_CIPHER_ARCFOUR, "arcfour", 8, 16, 0, 0, 0, EVP_rc4}, // RFC4253 - {SSH2_CIPHER_ARCFOUR128, "arcfour128", 8, 16, 1536, 0, 0, EVP_rc4}, // RFC4345 - {SSH2_CIPHER_ARCFOUR256, "arcfour256", 8, 32, 1536, 0, 0, EVP_rc4}, // RFC4345 - {SSH2_CIPHER_CAST128_CBC, "cast128-cbc", 8, 16, 0, 0, 0, EVP_cast5_cbc}, // RFC4253 - {SSH2_CIPHER_3DES_CTR, "3des-ctr", 8, 24, 0, 0, 0, evp_des3_ctr}, // RFC4344 - {SSH2_CIPHER_BLOWFISH_CTR, "blowfish-ctr", 8, 32, 0, 0, 0, evp_bf_ctr}, // RFC4344 - {SSH2_CIPHER_CAST128_CTR, "cast128-ctr", 8, 16, 0, 0, 0, evp_cast5_ctr}, // RFC4344 - {SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc", 16, 16, 0, 0, 0, EVP_camellia_128_cbc}, // draft-kanno-secsh-camellia-02 - {SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc", 16, 24, 0, 0, 0, EVP_camellia_192_cbc}, // draft-kanno-secsh-camellia-02 - {SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc", 16, 32, 0, 0, 0, EVP_camellia_256_cbc}, // draft-kanno-secsh-camellia-02 - {SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr", 16, 16, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02 - {SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr", 16, 24, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02 - {SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr", 16, 32, 0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02 -#ifdef WITH_CAMELLIA_PRIVATE - {SSH2_CIPHER_CAMELLIA128_CBC, "camel****@opens*****", 16, 16, 0, 0, 0, EVP_camellia_128_cbc}, - {SSH2_CIPHER_CAMELLIA192_CBC, "camel****@opens*****", 16, 24, 0, 0, 0, EVP_camellia_192_cbc}, - {SSH2_CIPHER_CAMELLIA256_CBC, "camel****@opens*****", 16, 32, 0, 0, 0, EVP_camellia_256_cbc}, - {SSH2_CIPHER_CAMELLIA128_CTR, "camel****@opens*****", 16, 16, 0, 0, 0, evp_camellia_128_ctr}, - {SSH2_CIPHER_CAMELLIA192_CTR, "camel****@opens*****", 16, 24, 0, 0, 0, evp_camellia_128_ctr}, - {SSH2_CIPHER_CAMELLIA256_CTR, "camel****@opens*****", 16, 32, 0, 0, 0, evp_camellia_128_ctr}, -#endif // WITH_CAMELLIA_PRIVATE - {SSH2_CIPHER_AES128_GCM, "aes12****@opens*****", 16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH - {SSH2_CIPHER_AES256_GCM, "aes25****@opens*****", 16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH - {SSH_CIPHER_NONE, NULL, 0, 0, 0, 0, 0, NULL}, -}; - - -typedef enum { - KEX_DH_NONE, /* disabled line */ - KEX_DH_GRP1_SHA1, - KEX_DH_GRP14_SHA1, - KEX_DH_GEX_SHA1, - KEX_DH_GEX_SHA256, - KEX_ECDH_SHA2_256, - KEX_ECDH_SHA2_384, - KEX_ECDH_SHA2_521, - KEX_DH_GRP14_SHA256, - KEX_DH_GRP16_SHA512, - KEX_DH_GRP18_SHA512, - KEX_DH_UNKNOWN, - KEX_DH_MAX = KEX_DH_UNKNOWN, -} kex_algorithm; - -typedef struct ssh2_kex_algorithm { - kex_algorithm kextype; - char *name; - const EVP_MD *(*evp_md)(void); -} ssh2_kex_algorithm_t; - -static ssh2_kex_algorithm_t ssh2_kex_algorithms[] = { - {KEX_DH_GRP1_SHA1, "diffie-hellman-group1-sha1", EVP_sha1}, // RFC4253 - {KEX_DH_GRP14_SHA1, "diffie-hellman-group14-sha1", EVP_sha1}, // RFC4253 - {KEX_DH_GEX_SHA1, "diffie-hellman-group-exchange-sha1", EVP_sha1}, // RFC4419 - {KEX_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256", EVP_sha256}, // RFC4419 - {KEX_ECDH_SHA2_256, "ecdh-sha2-nistp256", EVP_sha256}, // RFC5656 - {KEX_ECDH_SHA2_384, "ecdh-sha2-nistp384", EVP_sha384}, // RFC5656 - {KEX_ECDH_SHA2_521, "ecdh-sha2-nistp521", EVP_sha512}, // RFC5656 - {KEX_DH_GRP14_SHA256, "diffie-hellman-group14-sha256", EVP_sha256}, // RFC8268 - {KEX_DH_GRP16_SHA512, "diffie-hellman-group16-sha512", EVP_sha512}, // RFC8268 - {KEX_DH_GRP18_SHA512, "diffie-hellman-group18-sha512", EVP_sha512}, // RFC8268 - {KEX_DH_NONE , NULL, NULL}, -}; - - -typedef enum { - HMAC_NONE, /* disabled line */ - HMAC_SHA1, - HMAC_MD5, - HMAC_SHA1_96, - HMAC_MD5_96, - HMAC_RIPEMD160, - HMAC_SHA2_256, - HMAC_SHA2_256_96, - HMAC_SHA2_512, - HMAC_SHA2_512_96, - HMAC_SHA1_EtM, - HMAC_MD5_EtM, - HMAC_SHA1_96_EtM, - HMAC_MD5_96_EtM, - HMAC_RIPEMD160_EtM, - HMAC_SHA2_256_EtM, - HMAC_SHA2_512_EtM, - HMAC_IMPLICIT, - HMAC_UNKNOWN, - HMAC_MAX = HMAC_UNKNOWN, -} SSH2MacId; - -typedef struct ssh2_mac { - SSH2MacId id; - char *name; - const EVP_MD *(*evp_md)(void); - int truncatebits; - int etm; -} SSH2Mac; - -static SSH2Mac ssh2_macs[] = { - {HMAC_SHA1, "hmac-sha1", EVP_sha1, 0, 0}, // RFC4253 - {HMAC_MD5, "hmac-md5", EVP_md5, 0, 0}, // RFC4253 - {HMAC_SHA1_96, "hmac-sha1-96", EVP_sha1, 96, 0}, // RFC4253 - {HMAC_MD5_96, "hmac-md5-96", EVP_md5, 96, 0}, // RFC4253 - {HMAC_RIPEMD160, "hmac-****@opens*****", EVP_ripemd160, 0, 0}, - {HMAC_SHA2_256, "hmac-sha2-256", EVP_sha256, 0, 0}, // RFC6668 -// {HMAC_SHA2_256_96, "hmac-sha2-256-96", EVP_sha256, 96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06 - {HMAC_SHA2_512, "hmac-sha2-512", EVP_sha512, 0, 0}, // RFC6668 -// {HMAC_SHA2_512_96, "hmac-sha2-512-96", EVP_sha512, 96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06 - {HMAC_SHA1_EtM, "hmac-****@opens*****", EVP_sha1, 0, 1}, - {HMAC_MD5_EtM, "hmac-****@opens*****", EVP_md5, 0, 1}, - {HMAC_SHA1_96_EtM, "hmac-****@opens*****", EVP_sha1, 96, 1}, - {HMAC_MD5_96_EtM, "hmac-****@opens*****", EVP_md5, 96, 1}, - {HMAC_RIPEMD160_EtM,"hmac-****@opens*****",EVP_ripemd160, 0, 1}, - {HMAC_SHA2_256_EtM, "hmac-****@opens*****", EVP_sha256, 0, 1}, - {HMAC_SHA2_512_EtM, "hmac-****@opens*****", EVP_sha512, 0, 1}, - {HMAC_IMPLICIT, "<implicit>", EVP_md_null, 0, 0}, // for AEAD cipher - {HMAC_NONE, NULL, NULL, 0, 0}, -}; - - -typedef enum { - COMP_NONE, /* disabled line */ - COMP_NOCOMP, - COMP_ZLIB, - COMP_DELAYED, - COMP_UNKNOWN, - COMP_MAX = COMP_UNKNOWN, -} compression_type; - -typedef struct ssh2_comp { - compression_type type; - char *name; -} ssh2_comp_t; - -static ssh2_comp_t ssh2_comps[] = { - {COMP_NOCOMP, "none"}, // RFC4253 - {COMP_ZLIB, "zlib"}, // RFC4253 - {COMP_DELAYED, "zlib****@opens*****"}, - {COMP_NONE, NULL}, -}; - - struct Enc { u_char *key; u_char *iv; @@ -595,47 +357,7 @@ int bcrypt_kdf; } Key; -// fingerprint\x82̎\xED\x95\xCA -enum fp_rep { - SSH_FP_DEFAULT = 0, - SSH_FP_HEX, - SSH_FP_BASE64, - SSH_FP_BUBBLEBABBLE, - SSH_FP_RANDOMART -}; -/* -enum fp_type { - SSH_FP_MD5, - SSH_FP_SHA1, - SSH_FP_SHA256 -}; -*/ -typedef enum { - SSH_DIGEST_MD5, - SSH_DIGEST_RIPEMD160, - SSH_DIGEST_SHA1, - SSH_DIGEST_SHA256, - SSH_DIGEST_SHA384, - SSH_DIGEST_SHA512, - SSH_DIGEST_MAX, -} digest_algorithm; -typedef struct ssh_digest { - digest_algorithm id; - char *name; -} ssh_digest_t; - -/* NB. Indexed directly by algorithm number */ -static ssh_digest_t ssh_digests[] = { - { SSH_DIGEST_MD5, "MD5" }, - { SSH_DIGEST_RIPEMD160, "RIPEMD160" }, - { SSH_DIGEST_SHA1, "SHA1" }, - { SSH_DIGEST_SHA256, "SHA256" }, - { SSH_DIGEST_SHA384, "SHA384" }, - { SSH_DIGEST_SHA512, "SHA512" }, - { SSH_DIGEST_MAX, NULL }, -}; - enum scp_dir { TOREMOTE, FROMREMOTE, }; @@ -777,23 +499,6 @@ BOOL do_SSH2_userauth(PTInstVar pvar); BOOL do_SSH2_authrequest(PTInstVar pvar); void debug_print(int no, char *msg, int len); -int get_cipher_block_size(SSH2Cipher *cipher); -int get_cipher_key_len(SSH2Cipher *cipher); -int get_cipher_iv_len(SSH2Cipher *cipher); -int get_cipher_auth_len(SSH2Cipher *cipher); -SSH2Cipher *get_cipher_by_name(char *name); -char* get_kex_algorithm_name(kex_algorithm kextype); -const EVP_CIPHER* get_cipher_EVP_CIPHER(SSH2Cipher *cipher); -const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype); -SSH2Mac *get_ssh2_mac(SSH2MacId id); -char* get_ssh2_mac_name(SSH2Mac *mac); -char* get_ssh2_mac_name_by_id(SSH2MacId id); -const EVP_MD* get_ssh2_mac_EVP_MD(SSH2Mac *mac); -int get_ssh2_mac_truncatebits(SSH2Mac *mac); -char* get_ssh2_comp_name(compression_type type); -char* get_ssh_keytype_name(ssh_keytype type); -char* get_digest_algorithm_name(digest_algorithm id); -int get_cipher_discard_len(SSH2Cipher *cipher); void ssh_heartbeat_lock_initialize(void); void ssh_heartbeat_lock_finalize(void); void ssh_heartbeat_lock(void); @@ -804,11 +509,6 @@ BOOL handle_SSH2_userauth_inforeq(PTInstVar pvar); BOOL handle_SSH2_userauth_pkok(PTInstVar pvar); BOOL handle_SSH2_userauth_passwd_changereq(PTInstVar pvar); -void SSH2_update_compression_myproposal(PTInstVar pvar); -void SSH2_update_cipher_myproposal(PTInstVar pvar); -void SSH2_update_kex_myproposal(PTInstVar pvar); -void SSH2_update_host_key_myproposal(PTInstVar pvar); -void SSH2_update_hmac_myproposal(PTInstVar pvar); int SSH_notify_break_signal(PTInstVar pvar); /// @@ -896,6 +596,8 @@ void finish_send_packet_special(PTInstVar pvar, int skip_compress); void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char *buf, unsigned int buflen, int retry); Channel_t* ssh2_local_channel_lookup(int local_num); +void normalize_generic_order(char *buf, char default_strings[], int default_strings_len); +void choose_SSH2_proposal(char* server_proposal, char* my_proposal,char* dest, int dest_len); #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0) #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset)) @@ -944,4 +646,4 @@ BOOL handle_SSH2_dh_gex_reply_after_known_hosts(PTInstVar pvar); BOOL handle_SSH2_ecdh_kex_reply_after_known_hosts(PTInstVar pvar); -#endif +#endif /* __SSH_H */ Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,153 @@ +/* Imported via OpenSSH-8.5p1, TeraTerm Project */ + +/* $OpenBSD: ssherr.c,v 1.10 2020/01/25 23:13:09 djm Exp $ */ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <errno.h> +#include <string.h> +#include "ssherr.h" + +const char * +ssh_err(int n) +{ + switch (n) { + case SSH_ERR_SUCCESS: + return "success"; + case SSH_ERR_INTERNAL_ERROR: + return "unexpected internal error"; + case SSH_ERR_ALLOC_FAIL: + return "memory allocation failed"; + case SSH_ERR_MESSAGE_INCOMPLETE: + return "incomplete message"; + case SSH_ERR_INVALID_FORMAT: + return "invalid format"; + case SSH_ERR_BIGNUM_IS_NEGATIVE: + return "bignum is negative"; + case SSH_ERR_STRING_TOO_LARGE: + return "string is too large"; + case SSH_ERR_BIGNUM_TOO_LARGE: + return "bignum is too large"; + case SSH_ERR_ECPOINT_TOO_LARGE: + return "elliptic curve point is too large"; + case SSH_ERR_NO_BUFFER_SPACE: + return "insufficient buffer space"; + case SSH_ERR_INVALID_ARGUMENT: + return "invalid argument"; + case SSH_ERR_KEY_BITS_MISMATCH: + return "key bits do not match"; + case SSH_ERR_EC_CURVE_INVALID: + return "invalid elliptic curve"; + case SSH_ERR_KEY_TYPE_MISMATCH: + return "key type does not match"; + case SSH_ERR_KEY_TYPE_UNKNOWN: + return "unknown or unsupported key type"; + case SSH_ERR_EC_CURVE_MISMATCH: + return "elliptic curve does not match"; + case SSH_ERR_EXPECTED_CERT: + return "plain key provided where certificate required"; + case SSH_ERR_KEY_LACKS_CERTBLOB: + return "key lacks certificate data"; + case SSH_ERR_KEY_CERT_UNKNOWN_TYPE: + return "unknown/unsupported certificate type"; + case SSH_ERR_KEY_CERT_INVALID_SIGN_KEY: + return "invalid certificate signing key"; + case SSH_ERR_KEY_INVALID_EC_VALUE: + return "invalid elliptic curve value"; + case SSH_ERR_SIGNATURE_INVALID: + return "incorrect signature"; + case SSH_ERR_LIBCRYPTO_ERROR: + return "error in libcrypto"; /* XXX fetch and return */ + case SSH_ERR_UNEXPECTED_TRAILING_DATA: + return "unexpected bytes remain after decoding"; + case SSH_ERR_SYSTEM_ERROR: + return strerror(errno); + case SSH_ERR_KEY_CERT_INVALID: + return "invalid certificate"; + case SSH_ERR_AGENT_COMMUNICATION: + return "communication with agent failed"; + case SSH_ERR_AGENT_FAILURE: + return "agent refused operation"; + case SSH_ERR_DH_GEX_OUT_OF_RANGE: + return "DH GEX group out of range"; + case SSH_ERR_DISCONNECTED: + return "disconnected"; + case SSH_ERR_MAC_INVALID: + return "message authentication code incorrect"; + case SSH_ERR_NO_CIPHER_ALG_MATCH: + return "no matching cipher found"; + case SSH_ERR_NO_MAC_ALG_MATCH: + return "no matching MAC found"; + case SSH_ERR_NO_COMPRESS_ALG_MATCH: + return "no matching compression method found"; + case SSH_ERR_NO_KEX_ALG_MATCH: + return "no matching key exchange method found"; + case SSH_ERR_NO_HOSTKEY_ALG_MATCH: + return "no matching host key type found"; + case SSH_ERR_PROTOCOL_MISMATCH: + return "protocol version mismatch"; + case SSH_ERR_NO_PROTOCOL_VERSION: + return "could not read protocol version"; + case SSH_ERR_NO_HOSTKEY_LOADED: + return "could not load host key"; + case SSH_ERR_NEED_REKEY: + return "rekeying not supported by peer"; + case SSH_ERR_PASSPHRASE_TOO_SHORT: + return "passphrase is too short (minimum five characters)"; + case SSH_ERR_FILE_CHANGED: + return "file changed while reading"; + case SSH_ERR_KEY_UNKNOWN_CIPHER: + return "key encrypted using unsupported cipher"; + case SSH_ERR_KEY_WRONG_PASSPHRASE: + return "incorrect passphrase supplied to decrypt private key"; + case SSH_ERR_KEY_BAD_PERMISSIONS: + return "bad permissions"; + case SSH_ERR_KEY_CERT_MISMATCH: + return "certificate does not match key"; + case SSH_ERR_KEY_NOT_FOUND: + return "key not found"; + case SSH_ERR_AGENT_NOT_PRESENT: + return "agent not present"; + case SSH_ERR_AGENT_NO_IDENTITIES: + return "agent contains no identities"; + case SSH_ERR_BUFFER_READ_ONLY: + return "internal error: buffer is read-only"; + case SSH_ERR_KRL_BAD_MAGIC: + return "KRL file has invalid magic number"; + case SSH_ERR_KEY_REVOKED: + return "Key is revoked"; + case SSH_ERR_CONN_CLOSED: + return "Connection closed"; + case SSH_ERR_CONN_TIMEOUT: + return "Connection timed out"; + case SSH_ERR_CONN_CORRUPT: + return "Connection corrupted"; + case SSH_ERR_PROTOCOL_ERROR: + return "Protocol error"; + case SSH_ERR_KEY_LENGTH: + return "Invalid key length"; + case SSH_ERR_NUMBER_TOO_LARGE: + return "number is too large"; + case SSH_ERR_SIGN_ALG_UNSUPPORTED: + return "signature algorithm not supported"; + case SSH_ERR_FEATURE_UNSUPPORTED: + return "requested feature not supported"; + case SSH_ERR_DEVICE_NOT_FOUND: + return "device not found"; + default: + return "unknown error"; + } +} Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h (rev 0) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -0,0 +1,91 @@ +/* Imported via OpenSSH-8.5p1, TeraTerm Project */ + +/* $OpenBSD: ssherr.h,v 1.8 2020/01/25 23:13:09 djm Exp $ */ +/* + * Copyright (c) 2011 Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SSHERR_H +#define _SSHERR_H + +/* XXX are these too granular? not granular enough? I can't decide - djm */ + +/* Error codes */ +#define SSH_ERR_SUCCESS 0 +#define SSH_ERR_INTERNAL_ERROR -1 +#define SSH_ERR_ALLOC_FAIL -2 +#define SSH_ERR_MESSAGE_INCOMPLETE -3 +#define SSH_ERR_INVALID_FORMAT -4 +#define SSH_ERR_BIGNUM_IS_NEGATIVE -5 +#define SSH_ERR_STRING_TOO_LARGE -6 +#define SSH_ERR_BIGNUM_TOO_LARGE -7 +#define SSH_ERR_ECPOINT_TOO_LARGE -8 +#define SSH_ERR_NO_BUFFER_SPACE -9 +#define SSH_ERR_INVALID_ARGUMENT -10 +#define SSH_ERR_KEY_BITS_MISMATCH -11 +#define SSH_ERR_EC_CURVE_INVALID -12 +#define SSH_ERR_KEY_TYPE_MISMATCH -13 +#define SSH_ERR_KEY_TYPE_UNKNOWN -14 /* XXX UNSUPPORTED? */ +#define SSH_ERR_EC_CURVE_MISMATCH -15 +#define SSH_ERR_EXPECTED_CERT -16 +#define SSH_ERR_KEY_LACKS_CERTBLOB -17 +#define SSH_ERR_KEY_CERT_UNKNOWN_TYPE -18 +#define SSH_ERR_KEY_CERT_INVALID_SIGN_KEY -19 +#define SSH_ERR_KEY_INVALID_EC_VALUE -20 +#define SSH_ERR_SIGNATURE_INVALID -21 +#define SSH_ERR_LIBCRYPTO_ERROR -22 +#define SSH_ERR_UNEXPECTED_TRAILING_DATA -23 +#define SSH_ERR_SYSTEM_ERROR -24 +#define SSH_ERR_KEY_CERT_INVALID -25 +#define SSH_ERR_AGENT_COMMUNICATION -26 +#define SSH_ERR_AGENT_FAILURE -27 +#define SSH_ERR_DH_GEX_OUT_OF_RANGE -28 +#define SSH_ERR_DISCONNECTED -29 +#define SSH_ERR_MAC_INVALID -30 +#define SSH_ERR_NO_CIPHER_ALG_MATCH -31 +#define SSH_ERR_NO_MAC_ALG_MATCH -32 +#define SSH_ERR_NO_COMPRESS_ALG_MATCH -33 +#define SSH_ERR_NO_KEX_ALG_MATCH -34 +#define SSH_ERR_NO_HOSTKEY_ALG_MATCH -35 +#define SSH_ERR_NO_HOSTKEY_LOADED -36 +#define SSH_ERR_PROTOCOL_MISMATCH -37 +#define SSH_ERR_NO_PROTOCOL_VERSION -38 +#define SSH_ERR_NEED_REKEY -39 +#define SSH_ERR_PASSPHRASE_TOO_SHORT -40 +#define SSH_ERR_FILE_CHANGED -41 +#define SSH_ERR_KEY_UNKNOWN_CIPHER -42 +#define SSH_ERR_KEY_WRONG_PASSPHRASE -43 +#define SSH_ERR_KEY_BAD_PERMISSIONS -44 +#define SSH_ERR_KEY_CERT_MISMATCH -45 +#define SSH_ERR_KEY_NOT_FOUND -46 +#define SSH_ERR_AGENT_NOT_PRESENT -47 +#define SSH_ERR_AGENT_NO_IDENTITIES -48 +#define SSH_ERR_BUFFER_READ_ONLY -49 +#define SSH_ERR_KRL_BAD_MAGIC -50 +#define SSH_ERR_KEY_REVOKED -51 +#define SSH_ERR_CONN_CLOSED -52 +#define SSH_ERR_CONN_TIMEOUT -53 +#define SSH_ERR_CONN_CORRUPT -54 +#define SSH_ERR_PROTOCOL_ERROR -55 +#define SSH_ERR_KEY_LENGTH -56 +#define SSH_ERR_NUMBER_TOO_LARGE -57 +#define SSH_ERR_SIGN_ALG_UNSUPPORTED -58 +#define SSH_ERR_FEATURE_UNSUPPORTED -59 +#define SSH_ERR_DEVICE_NOT_FOUND -60 + +/* Translate a numeric error code to a human-readable error string */ +const char *ssh_err(int n); + +#endif /* _SSHERR_H */ Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c 2021-04-17 08:36:59 UTC (rev 9210) @@ -78,6 +78,9 @@ #include "buffer.h" #include "cipher.h" #include "key.h" +#include "kex.h" +#include "mac.h" +#include "comp.h" #include "dlglib.h" #include "sftp.h" @@ -87,6 +90,9 @@ #include "libputty.h" +// from cipher-3des.c +extern const EVP_CIPHER* evp_ssh1_3des(void); + #undef DialogBoxParam #define DialogBoxParam(p1,p2,p3,p4,p5) \ TTDialogBoxParam(p1,p2,p3,p4,p5) @@ -207,208 +213,6 @@ init_TTSSH(pvar); } -static void normalize_generic_order(char *buf, char default_strings[], int default_strings_len) -{ - char listed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1]; - char allowed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1]; - int i, j, k=-1; - - memset(listed, 0, sizeof(listed)); - memset(allowed, 0, sizeof(allowed)); - - // \x8B\x96\x89\xB3\x82\xEA\x82Ă\xA2\x82镶\x8E\x9A\x82̃\x8A\x83X\x83g\x82\xF0\x8D\xEC\x82\xE9\x81B - for (i = 0; i < default_strings_len ; i++) { - allowed[default_strings[i]] = 1; - } - - // \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82𑖍\xB8\x82\xB5\x81A\x8B\x96\x89\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x81A\x8Fd\x95\xA1\x82\xB7\x82镶\x8E\x9A\x82͍폜\x82\xB7\x82\xE9\x81B - // - // ex. (i=5 \x82̕\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9) - // i=012345 - // >:=9<87;A@?B3026(\0) - // i+1 - // <------------> - // \x81\xAB - // >:=9<7;A@?B3026(\0) - // - for (i = 0; buf[i] != 0; i++) { - int num = buf[i] - '0'; - - if (num < 0 || num > default_strings_len - || !allowed[num] - || listed[num]) { - memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1); - i--; - } else { - listed[num] = 1; - } - - // disabled line\x82\xAA\x82\xA0\x82\xEA\x82A\x88ʒu\x82\xF0\x8Ao\x82\xA6\x82Ă\xA8\x82\xAD\x81B - if (num == 0) { - k = i; - } - } - - // \x8Ew\x92肳\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x82\xAA\x82\xA0\x82\xEA\x82Adisabled line\x82̒\xBC\x91O\x82ɑ}\x93\xFC\x82\xB7\x82\xE9\x81B - // - // ex. (Z\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9) - // k - // >:=9<87;A@?B3026(\0) - // k+1 - // <----> - // \x81\xAB k - // >:=9<87;A@?B30026(\0) - // \x81\xAB k - // >:=9<87;A@?B3Z026(\0) - // - for (j = 0; j < default_strings_len && default_strings[j] != 0; j++) { - int num = default_strings[j]; - - if (!listed[num] && k >= 0) { - int copylen = strlen(buf + k + 1) + 1; - - memmove(buf + k + 1, buf + k, copylen); - buf[k + 1 + copylen] = '\0'; // \x8FI\x92[\x82\xF0\x96Y\x82ꂸ\x82ɕt\x82\xAF\x82\xE9\x81B - buf[k] = num + '0'; - k++; - i++; - } - } - if (k < 0) { - j = 0; - } - else { - j++; - } - - // disabled line\x82\xAA\x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x8Fꍇ\x82́A\x82\xBB\x82̂܂ܖ\x96\x94\xF6\x82ɒlj\xC1\x82\xB7\x82\xE9\x81B - for (; j < default_strings_len ; j++) { - int num = default_strings[j]; - - if (!listed[num]) { - buf[i] = num + '0'; - listed[num] = 1; - i++; - } - } - - buf[i] = 0; -} - -/* - * Remove unsupported cipher or duplicated cipher. - * Add unspecified ciphers at the end of list. - */ -static void normalize_cipher_order(char *buf) -{ - /* SSH_CIPHER_NONE means that all ciphers below that one are disabled. - We *never* allow no encryption. */ - static char default_strings[] = { - SSH2_CIPHER_AES256_GCM, - SSH2_CIPHER_CAMELLIA256_CTR, - SSH2_CIPHER_AES256_CTR, - SSH2_CIPHER_CAMELLIA256_CBC, - SSH2_CIPHER_AES256_CBC, - SSH2_CIPHER_CAMELLIA192_CTR, - SSH2_CIPHER_AES192_CTR, - SSH2_CIPHER_CAMELLIA192_CBC, - SSH2_CIPHER_AES192_CBC, - SSH2_CIPHER_AES128_GCM, - SSH2_CIPHER_CAMELLIA128_CTR, - SSH2_CIPHER_AES128_CTR, - SSH2_CIPHER_CAMELLIA128_CBC, - SSH2_CIPHER_AES128_CBC, - SSH2_CIPHER_3DES_CTR, - SSH2_CIPHER_3DES_CBC, - SSH2_CIPHER_BLOWFISH_CTR, - SSH2_CIPHER_BLOWFISH_CBC, - SSH2_CIPHER_CAST128_CTR, - SSH2_CIPHER_CAST128_CBC, - SSH_CIPHER_3DES, - SSH_CIPHER_NONE, - SSH2_CIPHER_ARCFOUR256, - SSH2_CIPHER_ARCFOUR128, - SSH2_CIPHER_ARCFOUR, - SSH_CIPHER_BLOWFISH, - SSH_CIPHER_DES, - 0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4 - }; - - normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); -} - -static void normalize_kex_order(char *buf) -{ - static char default_strings[] = { - KEX_ECDH_SHA2_256, - KEX_ECDH_SHA2_384, - KEX_ECDH_SHA2_521, - KEX_DH_GRP18_SHA512, - KEX_DH_GRP16_SHA512, - KEX_DH_GRP14_SHA256, - KEX_DH_GEX_SHA256, - KEX_DH_GEX_SHA1, - KEX_DH_GRP14_SHA1, - KEX_DH_GRP1_SHA1, - KEX_DH_NONE, - }; - - normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); -} - -static void normalize_host_key_order(char *buf) -{ - static char default_strings[] = { - KEY_ECDSA256, - KEY_ECDSA384, - KEY_ECDSA521, - KEY_ED25519, - KEY_RSA, - KEY_DSA, - KEY_NONE, - }; - - normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); -} - -static void normalize_mac_order(char *buf) -{ - static char default_strings[] = { - HMAC_SHA2_512_EtM, - HMAC_SHA2_256_EtM, - HMAC_SHA1_EtM, - HMAC_SHA2_512, - HMAC_SHA2_256, - HMAC_SHA1, - HMAC_RIPEMD160_EtM, - HMAC_RIPEMD160, - HMAC_MD5_EtM, - HMAC_MD5, - HMAC_NONE, - HMAC_SHA1_96_EtM, - HMAC_MD5_96_EtM, - HMAC_SHA1_96, - HMAC_MD5_96, - 0, // Dummy for HMAC_SHA2_512_96, - 0, // Dummy for HMAC_SHA2_256_96, - }; - - normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); -} - -static void normalize_comp_order(char *buf) -{ - static char default_strings[] = { - COMP_DELAYED, - COMP_ZLIB, - COMP_NOCOMP, - COMP_NONE, - }; - - normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings)); -} - - /* Remove local settings from the shared memory block. */ static void clear_local_settings(PTInstVar pvar) { @@ -1145,7 +949,7 @@ HOSTS_open(pvar); FWDUI_open(pvar); - // \x90ݒ\xE8\x82\xF0 myproposal \x82ɔ\xBD\x89f\x82\xB7\x82\xE9\x82̂́A\x90ڑ\xB1\x92\xBC\x91O\x82̂\xB1\x82\xB1\x82\xBE\x82\xAF\x81B (2006.6.26 maya) + // \x90ݒ\xE8\x82\xF0 myproposal \x82ɔ\xBD\x89f\x82\xB7\x82\xE9\x82̂́A\x90ڑ\xB1\x92\xBC\x91O\x82̂\xB1\x82\xB1\x82\xBE\x82\xAF\x81B SSH2_update_kex_myproposal(pvar); SSH2_update_host_key_myproposal(pvar); SSH2_update_cipher_myproposal(pvar); @@ -2292,7 +2096,7 @@ UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:"); strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE); strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE); - strncat_s(buf2, sizeof(buf2), get_ssh_keytype_name(pvar->hostkey_type), _TRUNCATE); + strncat_s(buf2, sizeof(buf2), get_ssh2_hostkey_type_name(pvar->hostkey_type), _TRUNCATE); strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE); UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:"); @@ -2531,73 +2335,6 @@ return FALSE; } -static char *get_cipher_name(int cipher) -{ - switch (cipher) { - case SSH_CIPHER_NONE: - UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar, - "<ciphers below this line are disabled>"); - return pvar->ts->UIMsg; - case SSH_CIPHER_3DES: - return "3DES(SSH1)"; - case SSH_CIPHER_DES: - return "DES(SSH1)"; - case SSH_CIPHER_BLOWFISH: - return "Blowfish(SSH1)"; - - // for SSH2(yutaka) - case SSH2_CIPHER_AES128_CBC: - return "aes128-cbc(SSH2)"; - case SSH2_CIPHER_AES192_CBC: - return "aes192-cbc(SSH2)"; - case SSH2_CIPHER_AES256_CBC: - return "aes256-cbc(SSH2)"; - case SSH2_CIPHER_3DES_CBC: - return "3des-cbc(SSH2)"; - case SSH2_CIPHER_BLOWFISH_CBC: - return "blowfish-cbc(SSH2)"; - case SSH2_CIPHER_AES128_CTR: - return "aes128-ctr(SSH2)"; - case SSH2_CIPHER_AES192_CTR: - return "aes192-ctr(SSH2)"; - case SSH2_CIPHER_AES256_CTR: - return "aes256-ctr(SSH2)"; - case SSH2_CIPHER_ARCFOUR: - return "arcfour(SSH2)"; - case SSH2_CIPHER_ARCFOUR128: - return "arcfour128(SSH2)"; - case SSH2_CIPHER_ARCFOUR256: - return "arcfour256(SSH2)"; - case SSH2_CIPHER_CAST128_CBC: - return "cast128-cbc(SSH2)"; - case SSH2_CIPHER_3DES_CTR: - return "3des-ctr(SSH2)"; - case SSH2_CIPHER_BLOWFISH_CTR: - return "blowfish-ctr(SSH2)"; - case SSH2_CIPHER_CAST128_CTR: - return "cast128-ctr(SSH2)"; - case SSH2_CIPHER_CAMELLIA128_CBC: - return "camellia128-cbc(SSH2)"; - case SSH2_CIPHER_CAMELLIA192_CBC: - return "camellia192-cbc(SSH2)"; - case SSH2_CIPHER_CAMELLIA256_CBC: - return "camellia256-cbc(SSH2)"; - case SSH2_CIPHER_CAMELLIA128_CTR: - return "camellia128-ctr(SSH2)"; - case SSH2_CIPHER_CAMELLIA192_CTR: - return "camellia192-ctr(SSH2)"; - case SSH2_CIPHER_CAMELLIA256_CTR: - return "camellia256-ctr(SSH2)"; - case SSH2_CIPHER_AES128_GCM: - return "aes12****@opens*****(SSH2)"; - case SSH2_CIPHER_AES256_GCM: - return "aes25****@opens*****(SSH2)"; - - default: - return NULL; - } -} - static void set_move_button_status(HWND dlg, int type, int up, int down) { HWND cipherControl = GetDlgItem(dlg, type); @@ -2690,7 +2427,7 @@ for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) { int cipher = pvar->settings.CipherOrder[i] - '0'; - char *name = get_cipher_name(cipher); + char *name = get_listbox_cipher_name(cipher, pvar); if (name != NULL) { SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name); @@ -2732,7 +2469,7 @@ "<Host Keys below this line are disabled>"); name = pvar->ts->UIMsg; } else { - name = get_ssh_keytype_name(index); + name = get_ssh2_hostkey_type_name(index); } if (name != NULL) { @@ -2941,7 +2678,7 @@ buf[0] = 0; SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf); for (j = 0; j <= SSH_CIPHER_MAX; j++) { - char *cipher_name = get_cipher_name(j); + char *cipher_name = get_listbox_cipher_name(j, pvar); if (cipher_name != NULL && strcmp(buf, cipher_name) == 0) { break; } @@ -2995,7 +2732,7 @@ SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf); for (j = 0; j <= KEY_MAX - && strcmp(buf, get_ssh_keytype_name(j)) != 0; j++) { + && strcmp(buf, get_ssh2_hostkey_type_name(j)) != 0; j++) { } if (j <= KEY_MAX) { buf2[buf2index] = '0' + j; @@ -3538,141 +3275,6 @@ } -// -// SSH1 3DES -// -/* - * This is used by SSH1: - * - * What kind of triple DES are these 2 routines? - * - * Why is there a redundant initialization vector? - * - * If only iv3 was used, then, this would till effect have been - * outer-cbc. However, there is also a private iv1 == iv2 which - * perhaps makes differential analysis easier. On the other hand, the - * private iv1 probably makes the CRC-32 attack ineffective. This is a - * result of that there is no longer any known iv1 to use when - * choosing the X block. - */ -struct ssh1_3des_ctx -{ - EVP_CIPHER_CTX *k1, *k2, *k3; -}; - -static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc) -{ - struct ssh1_3des_ctx *c; - u_char *k1, *k2, *k3; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { - c = malloc(sizeof(*c)); - c->k1 = EVP_CIPHER_CTX_new(); - c->k2 = EVP_CIPHER_CTX_new(); - c->k3 = EVP_CIPHER_CTX_new(); - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/ - EVP_CIPHER_CTX_set_app_data(ctx, c); - } - if (key == NULL) - return (1); - if (enc == -1) - enc = EVP_CIPHER_CTX_encrypting(ctx); // ctx->encrypt - k1 = k2 = k3 = (u_char *) key; - k2 += 8; - if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) { - if (enc) - k3 += 16; - else - k1 += 16; - } - if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || - EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || - EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { - EVP_CIPHER_CTX_free(c->k1); - EVP_CIPHER_CTX_free(c->k2); - EVP_CIPHER_CTX_free(c->k3); - SecureZeroMemory(c, sizeof(*c)); - free(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); - return (0); - } - return (1); -} - -static int ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len) -{ - struct ssh1_3des_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { - //error("ssh1_3des_cbc: no context"); - return (0); - } - if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 || - EVP_Cipher(c->k2, dest, dest, len) == 0 || - EVP_Cipher(c->k3, dest, dest, len) == 0) - return (0); - return (1); -} - -static int ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) -{ - struct ssh1_3des_ctx *c; - - if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) { - EVP_CIPHER_CTX_free(c->k1); - EVP_CIPHER_CTX_free(c->k2); - EVP_CIPHER_CTX_free(c->k3); - SecureZeroMemory(c, sizeof(*c)); - free(c); - EVP_CIPHER_CTX_set_app_data(ctx, NULL); - } - return (1); -} - -// \x89\xBA\x8BL\x8A\x94\x82͖\xA2\x8Eg\x97p\x81B -void ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) -{ - struct ssh1_3des_ctx *c; - - if (len != 24) - //fatal("%s: bad 3des iv length: %d", __func__, len); - ; - - if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) - //fatal("%s: no 3des context", __func__); - ; - - if (doset) { - //debug3("%s: Installed 3DES IV", __func__); - memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8); - memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8); - memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8); - } else { - //debug3("%s: Copying 3DES IV", __func__); - memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8); - memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8); - memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8); - } -} - -const EVP_CIPHER *evp_ssh1_3des(void) -{ - static EVP_CIPHER *p = NULL; - - if (p == NULL) { - p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/8, /*key_len*/16); - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/ - } - if (p) { - EVP_CIPHER_meth_set_iv_length(p, 0); - EVP_CIPHER_meth_set_init(p, ssh1_3des_init); - EVP_CIPHER_meth_set_cleanup(p, ssh1_3des_cleanup); - EVP_CIPHER_meth_set_do_cipher(p, ssh1_3des_cbc); - EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH); - } - return (p); -} - static void ssh_make_comment(char *comment, int maxlen) { char user[UNLEN + 1], host[128]; @@ -4032,7 +3634,7 @@ // based on OpenSSH 6.5:key_save_private(), key_private_to_blob2() static void save_bcrypt_private_key(char *passphrase, char *filename, char *comment, HWND dlg, PTInstVar pvar, int rounds) { - SSH2Cipher *cipher = NULL; + const struct ssh2cipher *cipher = NULL; char *ciphername = DEFAULT_CIPHERNAME; buffer_t *b = NULL; buffer_t *kdf = NULL; @@ -4630,7 +4232,7 @@ case KEY_ECDSA256: // ECDSA case KEY_ECDSA384: case KEY_ECDSA521: - keyname = get_ssh_keytype_name(public_key.type); + keyname = get_ssh2_hostkey_type_name(public_key.type); buffer_put_string(b, keyname, strlen(keyname)); s = curve_keytype_to_name(public_key.type); buffer_put_string(b, s, strlen(s)); @@ -4639,7 +4241,7 @@ break; case KEY_ED25519: - keyname = get_ssh_keytype_name(public_key.type); + keyname = get_ssh2_hostkey_type_name(public_key.type); buffer_put_cstring(b, keyname); buffer_put_string(b, public_key.ed25519_pk, ED25519_PK_SZ); break; Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h 2021-04-17 08:36:59 UTC (rev 9210) @@ -74,6 +74,11 @@ #include "ssh.h" #include "auth.h" #include "crypt.h" +#include "cipher.h" +#include "comp.h" +#include "kex.h" +#include "hostkey.h" +#include "key.h" #include "hosts.h" #include "fwd.h" @@ -268,8 +273,8 @@ buffer_t *peer_kex; kex_algorithm kex_type; // KEX algorithm ssh_keytype hostkey_type; - SSH2Cipher *ciphers[MODE_MAX]; - SSH2Mac *macs[MODE_MAX]; + const struct ssh2cipher *ciphers[MODE_MAX]; + const struct SSH2Mac *macs[MODE_MAX]; compression_type ctos_compression; compression_type stoc_compression; int we_need; Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj 2021-04-17 08:36:59 UTC (rev 9210) @@ -153,7 +153,10 @@ <ClCompile Include="auth.c" /> <ClCompile Include="buffer.c" /> <ClCompile Include="chacha.c" /> + <ClCompile Include="cipher.c" /> + <ClCompile Include="cipher-3des1.c" /> <ClCompile Include="cipher-ctr.c" /> + <ClCompile Include="comp.c" /> <ClCompile Include="crypt.c" /> <ClCompile Include="dns.c" /> <ClCompile Include="ed25519.c" /> @@ -168,13 +171,16 @@ <ClCompile Include="fwd-socks.c" /> <ClCompile Include="fwd.c" /> <ClCompile Include="fwdui.c" /> + <ClCompile Include="hostkey.c" /> <ClCompile Include="hosts.c" /> <ClCompile Include="kex.c" /> <ClCompile Include="key.c" /> <ClCompile Include="keyfiles.c" /> + <ClCompile Include="mac.c" /> <ClCompile Include="pkt.c" /> <ClCompile Include="sftp.c" /> <ClCompile Include="ssh.c" /> + <ClCompile Include="ssherr.c" /> <ClCompile Include="ttxssh.c" /> <ClCompile Include="util.c" /> <ClCompile Include="x11util.c" /> @@ -186,6 +192,7 @@ <ClInclude Include="buffer.h" /> <ClInclude Include="chacha.h" /> <ClInclude Include="cipher.h" /> + <ClInclude Include="comp.h" /> <ClInclude Include="config.h" /> <ClInclude Include="crypt.h" /> <ClInclude Include="dns.h" /> @@ -197,14 +204,17 @@ <ClInclude Include="fwd-socks.h" /> <ClInclude Include="fwd.h" /> <ClInclude Include="fwdui.h" /> + <ClInclude Include="hostkey.h" /> <ClInclude Include="hosts.h" /> <ClInclude Include="kex.h" /> <ClInclude Include="key.h" /> <ClInclude Include="keyfiles.h" /> + <ClInclude Include="mac.h" /> <ClInclude Include="pkt.h" /> <ClInclude Include="resource.h" /> <ClInclude Include="sftp.h" /> <ClInclude Include="ssh.h" /> + <ClInclude Include="ssherr.h" /> <ClInclude Include="ttxssh-version.h" /> <ClInclude Include="ttxssh.h" /> <ClInclude Include="util.h" /> Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters 2021-04-17 08:36:59 UTC (rev 9210) @@ -13,9 +13,18 @@ <ClCompile Include="chacha.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="cipher.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="cipher-3des1.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="cipher-ctr.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="comp.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="crypt.c"> <Filter>Source Files</Filter> </ClCompile> @@ -58,6 +67,9 @@ <ClCompile Include="fwdui.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="hostkey.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="hosts.c"> <Filter>Source Files</Filter> </ClCompile> @@ -70,6 +82,9 @@ <ClCompile Include="keyfiles.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="mac.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="..\matcher\matcher.c"> <Filter>Source Files</Filter> </ClCompile> @@ -82,6 +97,9 @@ <ClCompile Include="ssh.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="ssherr.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="ttxssh.c"> <Filter>Source Files</Filter> </ClCompile> @@ -144,6 +162,9 @@ <ClInclude Include="config.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="comp.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="crypt.h"> <Filter>Header Files</Filter> </ClInclude> @@ -171,6 +192,9 @@ <ClInclude Include="fwdui.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="hostkey.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="hosts.h"> <Filter>Header Files</Filter> </ClInclude> @@ -183,6 +207,9 @@ <ClInclude Include="keyfiles.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="mac.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="pkt.h"> <Filter>Header Files</Filter> </ClInclude> @@ -192,6 +219,9 @@ <ClInclude Include="ssh.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="ssherr.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="util.h"> <Filter>Header Files</Filter> </ClInclude> Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj 2021-04-17 06:32:42 UTC (rev 9209) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj 2021-04-17 08:36:59 UTC (rev 9210) @@ -240,6 +240,10 @@ > </File> <File + RelativePath="comp.h" + > + </File> + <File RelativePath="config.h" > </File> @@ -284,6 +288,10 @@ > </File> <File + RelativePath="hostkey.h" + > + </File> + <File RelativePath="hosts.h" > </File> @@ -300,6 +308,10 @@ > </File> <File + RelativePath="mac.h" + > + </File> + <File RelativePath="pkt.h" > </File> @@ -316,6 +328,10 @@ > </File> <File + RelativePath="ssherr.h" + > + </File> + <File RelativePath="ttxssh-version.h" > </File> @@ -352,6 +368,14 @@ > </File> <File + RelativePath="cipher.c" + > + </File> + <File + RelativePath="cipher-3des1.c" + > + </File> + <File RelativePath="cipher-ctr.c" > </File> @@ -360,6 +384,10 @@ > </File> <File + RelativePath="comp.c" + > + </File> + <File RelativePath="crypt.c" > </File> @@ -428,6 +456,10 @@ > </File> <File + RelativePath="hostkey.c" + > + </File> + <File RelativePath="hosts.c" > </File> @@ -444,6 +476,10 @@ > </File> <File + RelativePath="mac.c" + > + </File> + <File RelativePath="..\matcher\matcher.c" > </File> @@ -460,6 +496,10 @@ > </File> <File + RelativePath="ssherr.c" + > + </File> + <File RelativePath="..\..\teraterm\common\tipwin.cpp" > </File>