]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Add a config option to emulate the HMAC bug in commercial SSH v2.3.x
authorSimon Tatham <anakin@pobox.com>
Thu, 12 Oct 2000 12:39:44 +0000 (12:39 +0000)
committerSimon Tatham <anakin@pobox.com>
Thu, 12 Oct 2000 12:39:44 +0000 (12:39 +0000)
and earlier (namely, it uses only 16 bytes of key rather than 20).

[originally from svn r706]

putty.h
settings.c
ssh.c
sshsha.c
windlg.c

diff --git a/putty.h b/putty.h
index 4f9151b93a41a09a03d420d62593efc891d4c758..af5b75550aeabfd168b8434dd98191e9e5e29769 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -147,6 +147,7 @@ typedef struct {
     enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher;
     char keyfile[FILENAME_MAX];
     int sshprot;                       /* use v1 or v2 when both available */
+    int buggymac;                      /* MAC bug commmercial <=v2.3.x SSH2 */
     int try_tis_auth;
     /* Telnet options */
     char termtype[32];
index 181708e3cab62479f08d7aec63fba2534700607c..66128a45c84ce52d3ecf1d7e501b622ef57ee385 100644 (file)
@@ -78,6 +78,7 @@ void save_settings (char *section, int do_host, Config *cfg) {
                              cfg->cipher == CIPHER_DES ? "des" : "3des");
     write_setting_i (sesskey, "AuthTIS", cfg->try_tis_auth);
     write_setting_i (sesskey, "SshProt", cfg->sshprot);
+    write_setting_i (sesskey, "BuggyMAC", cfg->buggymac);
     write_setting_s (sesskey, "PublicKeyFile", cfg->keyfile);
     write_setting_s (sesskey, "RemoteCommand", cfg->remote_cmd);
     write_setting_i (sesskey, "RFCEnviron", cfg->rfc_environ);
@@ -198,6 +199,7 @@ void load_settings (char *section, int do_host, Config *cfg) {
            cfg->cipher = CIPHER_3DES;
     }
     gppi (sesskey, "SshProt", 1, &cfg->sshprot);
+    gppi (sesskey, "BuggyMAC", 0, &cfg->buggymac);
     gppi (sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
     gpps (sesskey, "PublicKeyFile", "", cfg->keyfile, sizeof(cfg->keyfile));
     gpps (sesskey, "RemoteCommand", "", cfg->remote_cmd,
diff --git a/ssh.c b/ssh.c
index 509ea3ab8e4816dfee63a90d8bef05988022856f..7d1ce260e8f2fc54d249acccb1d7b063e1b286a5 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -167,7 +167,7 @@ const static struct ssh_kex *kex_algs[] = { &ssh_diffiehellman };
 extern const struct ssh_hostkey ssh_dss;
 const static struct ssh_hostkey *hostkey_algs[] = { &ssh_dss };
 
-extern const struct ssh_mac ssh_sha1;
+extern const struct ssh_mac ssh_sha1, ssh_sha1_buggy;
 
 static void nullmac_key(unsigned char *key) { }
 static void nullmac_generate(unsigned char *blk, int len, unsigned long seq) { }
@@ -176,6 +176,7 @@ const static struct ssh_mac ssh_mac_none = {
     nullmac_key, nullmac_key, nullmac_generate, nullmac_verify, "none", 0
 };
 const static struct ssh_mac *macs[] = { &ssh_sha1, &ssh_mac_none };
+const static struct ssh_mac *buggymacs[] = { &ssh_sha1_buggy, &ssh_mac_none };
 
 const static struct ssh_compress ssh_comp_none = {
     "none"
@@ -1828,6 +1829,7 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
     static int i, len;
     static char *str;
     static Bignum e, f, K;
+    static const struct ssh_mac **maclist;
     static const struct ssh_cipher *cscipher_tobe = NULL;
     static const struct ssh_cipher *sccipher_tobe = NULL;
     static const struct ssh_mac *csmac_tobe = NULL;
@@ -1858,6 +1860,14 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
         preferred_cipher = &ssh_3des_ssh2;
     }
 
+    /*
+     * Be prepared to work around the buggy MAC problem.
+     */
+    if (cfg.buggymac)
+        maclist = buggymacs;
+    else
+        maclist = macs;
+
     begin_key_exchange:
     /*
      * Construct and send our key exchange packet.
@@ -1897,16 +1907,16 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
     }
     /* List client->server MAC algorithms. */
     ssh2_pkt_addstring_start();
-    for (i = 0; i < lenof(macs); i++) {
-        ssh2_pkt_addstring_str(macs[i]->name);
-        if (i < lenof(macs)-1)
+    for (i = 0; i < lenof(maclist); i++) {
+        ssh2_pkt_addstring_str(maclist[i]->name);
+        if (i < lenof(maclist)-1)
             ssh2_pkt_addstring_str(",");
     }
     /* List server->client MAC algorithms. */
     ssh2_pkt_addstring_start();
-    for (i = 0; i < lenof(macs); i++) {
-        ssh2_pkt_addstring_str(macs[i]->name);
-        if (i < lenof(macs)-1)
+    for (i = 0; i < lenof(maclist); i++) {
+        ssh2_pkt_addstring_str(maclist[i]->name);
+        if (i < lenof(maclist)-1)
             ssh2_pkt_addstring_str(",");
     }
     /* List client->server compression algorithms. */
@@ -1979,16 +1989,16 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt)
         }
     }
     ssh2_pkt_getstring(&str, &len);    /* client->server mac */
-    for (i = 0; i < lenof(macs); i++) {
-        if (in_commasep_string(macs[i]->name, str, len)) {
-            csmac_tobe = macs[i];
+    for (i = 0; i < lenof(maclist); i++) {
+        if (in_commasep_string(maclist[i]->name, str, len)) {
+            csmac_tobe = maclist[i];
             break;
         }
     }
     ssh2_pkt_getstring(&str, &len);    /* server->client mac */
-    for (i = 0; i < lenof(macs); i++) {
-        if (in_commasep_string(macs[i]->name, str, len)) {
-            scmac_tobe = macs[i];
+    for (i = 0; i < lenof(maclist); i++) {
+        if (in_commasep_string(maclist[i]->name, str, len)) {
+            scmac_tobe = maclist[i];
             break;
         }
     }
index 95d5259e352d87537f196f8335958033f5a536dd..48cabb5c5c38c2f9383b016502b8579272eacb79 100644 (file)
--- a/sshsha.c
+++ b/sshsha.c
@@ -199,6 +199,14 @@ static void sha1_sckey(unsigned char *key) {
     sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 20);
 }
 
+static void sha1_cskey_buggy(unsigned char *key) {
+    sha1_key(&sha1_cs_mac_s1, &sha1_cs_mac_s2, key, 16);
+}
+
+static void sha1_sckey_buggy(unsigned char *key) {
+    sha1_key(&sha1_sc_mac_s1, &sha1_sc_mac_s2, key, 16);
+}
+
 static void sha1_do_hmac(SHA_State *s1, SHA_State *s2,
                          unsigned char *blk, int len, unsigned long seq,
                          unsigned char *hmac) {
@@ -236,3 +244,11 @@ struct ssh_mac ssh_sha1 = {
     "hmac-sha1",
     20
 };
+
+struct ssh_mac ssh_sha1_buggy = {
+    sha1_cskey_buggy, sha1_sckey_buggy,
+    sha1_generate,
+    sha1_verify,
+    "hmac-sha1",
+    20
+};
index c9e130b70c7061abb8d05011661aa9d438fd45b3..e012b3d02f5758dbbcc0c0ea5582e0ef28c36b54 100644 (file)
--- a/windlg.c
+++ b/windlg.c
@@ -945,6 +945,7 @@ enum { IDCX_ABOUT = IDC_ABOUT, IDCX_TVSTATIC, IDCX_TREEVIEW, controlstartvalue,
     IDC_CIPHER3DES,
     IDC_CIPHERBLOWF,
     IDC_CIPHERDES,
+    IDC_BUGGYMAC,
     IDC_AUTHTIS,
     IDC_PKSTATIC,
     IDC_PKEDIT,
@@ -1109,6 +1110,7 @@ static void init_dlg_ctrls(HWND hwnd) {
     SetDlgItemText (hwnd, IDC_TTEDIT, cfg.termtype);
     SetDlgItemText (hwnd, IDC_LOGEDIT, cfg.username);
     CheckDlgButton (hwnd, IDC_NOPTY, cfg.nopty);
+    CheckDlgButton (hwnd, IDC_BUGGYMAC, cfg.buggymac);
     CheckDlgButton (hwnd, IDC_AGENTFWD, cfg.agentfwd);
     CheckRadioButton (hwnd, IDC_CIPHER3DES, IDC_CIPHERDES,
                      cfg.cipher == CIPHER_BLOWFISH ? IDC_CIPHERBLOWF :
@@ -1575,6 +1577,8 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
                          "&3DES", IDC_CIPHER3DES,
                          "&Blowfish", IDC_CIPHERBLOWF,
                          "&DES", IDC_CIPHERDES, NULL);
+               checkbox(&cp, "Imitate SSH 2 MAC bug in commercial <= v2.3.x",
+                         IDC_BUGGYMAC);
                 endbox(&cp);
 
                 treeview_insert(&tvfaff, 1, "SSH");
@@ -2059,6 +2063,11 @@ static int GenericMainDlgProc (HWND hwnd, UINT msg,
                HIWORD(wParam) == BN_DOUBLECLICKED)
                cfg.nopty = IsDlgButtonChecked (hwnd, IDC_NOPTY);
            break;
+         case IDC_BUGGYMAC:
+           if (HIWORD(wParam) == BN_CLICKED ||
+               HIWORD(wParam) == BN_DOUBLECLICKED)
+               cfg.buggymac = IsDlgButtonChecked (hwnd, IDC_BUGGYMAC);
+           break;
          case IDC_AGENTFWD:
            if (HIWORD(wParam) == BN_CLICKED ||
                HIWORD(wParam) == BN_DOUBLECLICKED)