[BACK]Return to kex.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/kex.c between version 1.6.2.2 and 1.6.2.3

version 1.6.2.2, 2000/09/01 18:23:20 version 1.6.2.3, 2000/11/08 21:30:51
Line 9 
Line 9 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software  
  *    must display the following acknowledgement:  
  *      This product includes software developed by Markus Friedl.  
  * 4. 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
Line 36 
Line 31 
 #include "buffer.h"  #include "buffer.h"
 #include "bufaux.h"  #include "bufaux.h"
 #include "packet.h"  #include "packet.h"
 #include "cipher.h"  
 #include "compat.h"  #include "compat.h"
   
 #include <openssl/bn.h>  #include <openssl/bn.h>
Line 128 
Line 122 
         int n = BN_num_bits(dh_pub);          int n = BN_num_bits(dh_pub);
         int bits_set = 0;          int bits_set = 0;
   
         /* we only accept g==2 */  
         if (!BN_is_word(dh->g, 2)) {  
                 log("invalid DH base != 2");  
                 return 0;  
         }  
         if (dh_pub->neg) {          if (dh_pub->neg) {
                 log("invalid public DH value: negativ");                  log("invalid public DH value: negativ");
                 return 0;                  return 0;
Line 150 
Line 139 
 }  }
   
 DH *  DH *
 dh_new_group1()  dh_gen_key(DH *dh)
 {  {
         static char *group1 =          int tries = 0;
             "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"  
             "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"  
             "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"  
             "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"  
             "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"  
             "FFFFFFFF" "FFFFFFFF";  
         DH *dh;  
         int ret, tries = 0;  
         dh = DH_new();  
         if(dh == NULL)  
                 fatal("DH_new");  
         ret = BN_hex2bn(&dh->p, group1);  
         if(ret<0)  
                 fatal("BN_hex2bn");  
         dh->g = BN_new();  
         if(dh->g == NULL)  
                 fatal("DH_new g");  
         BN_set_word(dh->g, 2);  
         do {          do {
                 if (DH_generate_key(dh) == 0)                  if (DH_generate_key(dh) == 0)
                         fatal("DH_generate_key");                          fatal("DH_generate_key");
Line 180 
Line 152 
         return dh;          return dh;
 }  }
   
   DH *
   dh_new_group_asc(const char *gen, const char *modulus)
   {
           DH *dh;
           int ret;
   
           dh = DH_new();
           if (dh == NULL)
                   fatal("DH_new");
   
           if ((ret = BN_hex2bn(&dh->p, modulus)) < 0)
                   fatal("BN_hex2bn p");
           if ((ret = BN_hex2bn(&dh->g, gen)) < 0)
                   fatal("BN_hex2bn g");
   
           return (dh_gen_key(dh));
   }
   
   DH *
   dh_new_group(BIGNUM *gen, BIGNUM *modulus)
   {
           DH *dh;
   
           dh = DH_new();
           if (dh == NULL)
                   fatal("DH_new");
           dh->p = modulus;
           dh->g = gen;
   
           return (dh_gen_key(dh));
   }
   
   DH *
   dh_new_group1()
   {
           static char *gen = "2", *group1 =
               "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
               "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
               "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
               "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
               "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
               "FFFFFFFF" "FFFFFFFF";
   
           return (dh_new_group_asc(gen, group1));
   }
   
 void  void
 dump_digest(unsigned char *digest, int len)  dump_digest(unsigned char *digest, int len)
 {  {
Line 242 
Line 260 
 }  }
   
 unsigned char *  unsigned char *
   kex_hash_gex(
       char *client_version_string,
       char *server_version_string,
       char *ckexinit, int ckexinitlen,
       char *skexinit, int skexinitlen,
       char *serverhostkeyblob, int sbloblen,
       int minbits, BIGNUM *prime, BIGNUM *gen,
       BIGNUM *client_dh_pub,
       BIGNUM *server_dh_pub,
       BIGNUM *shared_secret)
   {
           Buffer b;
           static unsigned char digest[EVP_MAX_MD_SIZE];
           EVP_MD *evp_md = EVP_sha1();
           EVP_MD_CTX md;
   
           buffer_init(&b);
           buffer_put_string(&b, client_version_string, strlen(client_version_string));
           buffer_put_string(&b, server_version_string, strlen(server_version_string));
   
           /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
           buffer_put_int(&b, ckexinitlen+1);
           buffer_put_char(&b, SSH2_MSG_KEXINIT);
           buffer_append(&b, ckexinit, ckexinitlen);
           buffer_put_int(&b, skexinitlen+1);
           buffer_put_char(&b, SSH2_MSG_KEXINIT);
           buffer_append(&b, skexinit, skexinitlen);
   
           buffer_put_string(&b, serverhostkeyblob, sbloblen);
           buffer_put_int(&b, minbits);
           buffer_put_bignum2(&b, prime);
           buffer_put_bignum2(&b, gen);
           buffer_put_bignum2(&b, client_dh_pub);
           buffer_put_bignum2(&b, server_dh_pub);
           buffer_put_bignum2(&b, shared_secret);
   
   #ifdef DEBUG_KEX
           buffer_dump(&b);
   #endif
   
           EVP_DigestInit(&md, evp_md);
           EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
           EVP_DigestFinal(&md, digest, NULL);
   
           buffer_free(&b);
   
   #ifdef DEBUG_KEX
           dump_digest(digest, evp_md->md_size);
   #endif
           return digest;
   }
   
   unsigned char *
 derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret)  derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret)
 {  {
         Buffer b;          Buffer b;
Line 323 
Line 394 
         char *name = get_match(client, server);          char *name = get_match(client, server);
         if (name == NULL)          if (name == NULL)
                 fatal("no matching cipher found: client %s server %s", client, server);                  fatal("no matching cipher found: client %s server %s", client, server);
         enc->type = cipher_number(name);          enc->cipher = cipher_by_name(name);
           if (enc->cipher == NULL)
         switch (enc->type) {                  fatal("matching cipher is not supported: %s", name);
         case SSH_CIPHER_3DES_CBC:  
                 enc->key_len = 24;  
                 enc->iv_len = 8;  
                 enc->block_size = 8;  
                 break;  
         case SSH_CIPHER_BLOWFISH_CBC:  
         case SSH_CIPHER_CAST128_CBC:  
                 enc->key_len = 16;  
                 enc->iv_len = 8;  
                 enc->block_size = 8;  
                 break;  
         case SSH_CIPHER_ARCFOUR:  
                 enc->key_len = 16;  
                 enc->iv_len = 0;  
                 enc->block_size = 8;  
                 break;  
         default:  
                 fatal("unsupported cipher %s", name);  
         }  
         enc->name = name;          enc->name = name;
         enc->enabled = 0;          enc->enabled = 0;
         enc->iv = NULL;          enc->iv = NULL;
Line 392 
Line 444 
         k->name = get_match(client, server);          k->name = get_match(client, server);
         if (k->name == NULL)          if (k->name == NULL)
                 fatal("no kex alg");                  fatal("no kex alg");
         if (strcmp(k->name, KEX_DH1) != 0)          if (strcmp(k->name, KEX_DH1) == 0) {
                   k->kex_type = DH_GRP1_SHA1;
           } else if (strcmp(k->name, KEX_DHGEX) == 0) {
                   k->kex_type = DH_GEX_SHA1;
           } else
                 fatal("bad kex alg %s", k->name);                  fatal("bad kex alg %s", k->name);
 }  }
 void  void
Line 437 
Line 493 
             sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);              sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
         need = 0;          need = 0;
         for (mode = 0; mode < MODE_MAX; mode++) {          for (mode = 0; mode < MODE_MAX; mode++) {
             if (need < k->enc[mode].key_len)              if (need < k->enc[mode].cipher->key_len)
                     need = k->enc[mode].key_len;                      need = k->enc[mode].cipher->key_len;
             if (need < k->enc[mode].iv_len)              if (need < k->enc[mode].cipher->block_size)
                     need = k->enc[mode].iv_len;                      need = k->enc[mode].cipher->block_size;
             if (need < k->mac[mode].key_len)              if (need < k->mac[mode].key_len)
                     need = k->mac[mode].key_len;                      need = k->mac[mode].key_len;
         }          }

Legend:
Removed from v.1.6.2.2  
changed lines
  Added in v.1.6.2.3