[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.33.2.3 and 1.34

version 1.33.2.3, 2002/06/02 22:56:10 version 1.34, 2001/04/30 15:50:46
Line 1 
Line 1 
 /*  /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.   * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *   *
  * Redistribution and use in source and binary forms, with or without   * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions   * modification, are permitted provided that the following conditions
Line 40 
Line 40 
 #include "mac.h"  #include "mac.h"
 #include "match.h"  #include "match.h"
 #include "dispatch.h"  #include "dispatch.h"
 #include "monitor.h"  
   
 #define KEX_COOKIE_LEN  16  #define KEX_COOKIE_LEN  16
   
 /* Use privilege separation for sshd */  void    kex_kexinit_finish(Kex *kex);
 int use_privsep;  void    kex_choose_conf(Kex *k);
 struct monitor *pmonitor;  
   
   
 /* prototype */  
 static void kex_kexinit_finish(Kex *);  
 static void kex_choose_conf(Kex *);  
   
 /* put algorithm proposal into buffer */  /* put algorithm proposal into buffer */
 static void  void
 kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])  kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
 {  {
           u_int32_t rand = 0;
         int i;          int i;
   
         buffer_clear(b);          buffer_clear(b);
         /*          for (i = 0; i < KEX_COOKIE_LEN; i++) {
          * add a dummy cookie, the cookie will be overwritten by                  if (i % 4 == 0)
          * kex_send_kexinit(), each time a kexinit is set                          rand = arc4random();
          */                  buffer_put_char(b, rand & 0xff);
         for (i = 0; i < KEX_COOKIE_LEN; i++)                  rand >>= 8;
                 buffer_put_char(b, 0);          }
         for (i = 0; i < PROPOSAL_MAX; i++)          for (i = 0; i < PROPOSAL_MAX; i++)
                 buffer_put_cstring(b, proposal[i]);                  buffer_put_cstring(b, proposal[i]);
         buffer_put_char(b, 0);                  /* first_kex_packet_follows */          buffer_put_char(b, 0);                  /* first_kex_packet_follows */
Line 73 
Line 67 
 }  }
   
 /* parse buffer and return algorithm proposal */  /* parse buffer and return algorithm proposal */
 static char **  char **
 kex_buf2prop(Buffer *raw)  kex_buf2prop(Buffer *raw)
 {  {
         Buffer b;          Buffer b;
Line 101 
Line 95 
         return proposal;          return proposal;
 }  }
   
 static void  void
 kex_prop_free(char **proposal)  kex_prop_free(char **proposal)
 {  {
         int i;          int i;
Line 111 
Line 105 
         xfree(proposal);          xfree(proposal);
 }  }
   
 static void  void
 kex_protocol_error(int type, u_int32_t seq, void *ctxt)  kex_protocol_error(int type, int plen, void *ctxt)
 {  {
         error("Hm, kex protocol error: type %d seq %u", type, seq);          error("Hm, kex protocol error: type %d plen %d", type, plen);
 }  }
   
 static void  void
 kex_reset_dispatch(void)  kex_clear_dispatch(void)
 {  {
         dispatch_range(SSH2_MSG_TRANSPORT_MIN,          int i;
             SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);  
         dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);          /* Numbers 30-49 are used for kex packets */
           for (i = 30; i <= 49; i++)
                   dispatch_set(i, &kex_protocol_error);
 }  }
   
 void  void
 kex_finish(Kex *kex)  kex_finish(Kex *kex)
 {  {
         kex_reset_dispatch();          int plen;
   
           kex_clear_dispatch();
   
         packet_start(SSH2_MSG_NEWKEYS);          packet_start(SSH2_MSG_NEWKEYS);
         packet_send();          packet_send();
         /* packet_write_wait(); */          /* packet_write_wait(); */
         debug("SSH2_MSG_NEWKEYS sent");          debug("SSH2_MSG_NEWKEYS sent");
   
         debug("waiting for SSH2_MSG_NEWKEYS");          debug("waiting for SSH2_MSG_NEWKEYS");
         packet_read_expect(SSH2_MSG_NEWKEYS);          packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
         packet_check_eom();  
         debug("SSH2_MSG_NEWKEYS received");          debug("SSH2_MSG_NEWKEYS received");
   
         kex->done = 1;          kex->done = 1;
Line 151 
Line 148 
 void  void
 kex_send_kexinit(Kex *kex)  kex_send_kexinit(Kex *kex)
 {  {
         u_int32_t rand = 0;  
         u_char *cookie;  
         int i;  
   
         if (kex == NULL) {          if (kex == NULL) {
                 error("kex_send_kexinit: no kex, cannot rekey");                  error("kex_send_kexinit: no kex, cannot rekey");
                 return;                  return;
Line 164 
Line 157 
                 return;                  return;
         }          }
         kex->done = 0;          kex->done = 0;
   
         /* generate a random cookie */  
         if (buffer_len(&kex->my) < KEX_COOKIE_LEN)  
                 fatal("kex_send_kexinit: kex proposal too short");  
         cookie = buffer_ptr(&kex->my);  
         for (i = 0; i < KEX_COOKIE_LEN; i++) {  
                 if (i % 4 == 0)  
                         rand = arc4random();  
                 cookie[i] = rand;  
                 rand >>= 8;  
         }  
         packet_start(SSH2_MSG_KEXINIT);          packet_start(SSH2_MSG_KEXINIT);
         packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));          packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
         packet_send();          packet_send();
Line 183 
Line 165 
 }  }
   
 void  void
 kex_input_kexinit(int type, u_int32_t seq, void *ctxt)  kex_input_kexinit(int type, int plen, void *ctxt)
 {  {
         char *ptr;          char *ptr;
         int dlen;          int dlen;
Line 204 
Line 186 
                 xfree(packet_get_string(NULL));                  xfree(packet_get_string(NULL));
         packet_get_char();          packet_get_char();
         packet_get_int();          packet_get_int();
         packet_check_eom();          packet_done();
   
         kex_kexinit_finish(kex);          kex_kexinit_finish(kex);
 }  }
Line 222 
Line 204 
         kex->done = 0;          kex->done = 0;
   
         kex_send_kexinit(kex);                                  /* we start */          kex_send_kexinit(kex);                                  /* we start */
         kex_reset_dispatch();          kex_clear_dispatch();
           dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
   
         return kex;          return kex;
 }  }
   
 static void  void
 kex_kexinit_finish(Kex *kex)  kex_kexinit_finish(Kex *kex)
 {  {
         if (!(kex->flags & KEX_INIT_SENT))          if (!(kex->flags & KEX_INIT_SENT))
Line 235 
Line 218 
   
         kex_choose_conf(kex);          kex_choose_conf(kex);
   
         switch (kex->kex_type) {          switch(kex->kex_type) {
         case DH_GRP1_SHA1:          case DH_GRP1_SHA1:
                 kexdh(kex);                  kexdh(kex);
                 break;                  break;
Line 247 
Line 230 
         }          }
 }  }
   
 static void  void
 choose_enc(Enc *enc, char *client, char *server)  choose_enc(Enc *enc, char *client, char *server)
 {  {
         char *name = match_list(client, server, NULL);          char *name = match_list(client, server, NULL);
         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);
         if ((enc->cipher = cipher_by_name(name)) == NULL)          enc->cipher = cipher_by_name(name);
           if (enc->cipher == NULL)
                 fatal("matching cipher is not supported: %s", name);                  fatal("matching cipher is not supported: %s", name);
         enc->name = name;          enc->name = name;
         enc->enabled = 0;          enc->enabled = 0;
         enc->iv = NULL;          enc->iv = NULL;
         enc->key = NULL;          enc->key = NULL;
         enc->key_len = cipher_keylen(enc->cipher);  
         enc->block_size = cipher_blocksize(enc->cipher);  
 }  }
 static void  void
 choose_mac(Mac *mac, char *client, char *server)  choose_mac(Mac *mac, char *client, char *server)
 {  {
         char *name = match_list(client, server, NULL);          char *name = match_list(client, server, NULL);
Line 277 
Line 259 
         mac->key = NULL;          mac->key = NULL;
         mac->enabled = 0;          mac->enabled = 0;
 }  }
 static void  void
 choose_comp(Comp *comp, char *client, char *server)  choose_comp(Comp *comp, char *client, char *server)
 {  {
         char *name = match_list(client, server, NULL);          char *name = match_list(client, server, NULL);
Line 292 
Line 274 
         }          }
         comp->name = name;          comp->name = name;
 }  }
 static void  void
 choose_kex(Kex *k, char *client, char *server)  choose_kex(Kex *k, char *client, char *server)
 {  {
         k->name = match_list(client, server, NULL);          k->name = match_list(client, server, NULL);
Line 305 
Line 287 
         } else          } else
                 fatal("bad kex alg %s", k->name);                  fatal("bad kex alg %s", k->name);
 }  }
 static void  void
 choose_hostkeyalg(Kex *k, char *client, char *server)  choose_hostkeyalg(Kex *k, char *client, char *server)
 {  {
         char *hostkeyalg = match_list(client, server, NULL);          char *hostkeyalg = match_list(client, server, NULL);
Line 317 
Line 299 
         xfree(hostkeyalg);          xfree(hostkeyalg);
 }  }
   
 static void  void
 kex_choose_conf(Kex *kex)  kex_choose_conf(Kex *kex)
 {  {
         Newkeys *newkeys;          Newkeys *newkeys;
Line 363 
Line 345 
         need = 0;          need = 0;
         for (mode = 0; mode < MODE_MAX; mode++) {          for (mode = 0; mode < MODE_MAX; mode++) {
                 newkeys = kex->newkeys[mode];                  newkeys = kex->newkeys[mode];
                 if (need < newkeys->enc.key_len)                  if (need < newkeys->enc.cipher->key_len)
                         need = newkeys->enc.key_len;                          need = newkeys->enc.cipher->key_len;
                 if (need < newkeys->enc.block_size)                  if (need < newkeys->enc.cipher->block_size)
                         need = newkeys->enc.block_size;                          need = newkeys->enc.cipher->block_size;
                 if (need < newkeys->mac.key_len)                  if (need < newkeys->mac.key_len)
                         need = newkeys->mac.key_len;                          need = newkeys->mac.key_len;
         }          }
Line 377 
Line 359 
         kex_prop_free(peer);          kex_prop_free(peer);
 }  }
   
 static u_char *  u_char *
 derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)  derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
 {  {
         Buffer b;          Buffer b;
         const EVP_MD *evp_md = EVP_sha1();          EVP_MD *evp_md = EVP_sha1();
         EVP_MD_CTX md;          EVP_MD_CTX md;
         char c = id;          char c = id;
         int have;          int have;
         int mdsz = EVP_MD_size(evp_md);          int mdsz = evp_md->md_size;
         u_char *digest = xmalloc(roundup(need, mdsz));          u_char *digest = xmalloc(roundup(need, mdsz));
   
         buffer_init(&b);          buffer_init(&b);
Line 461 
Line 443 
         int i;          int i;
   
         fprintf(stderr, "%s\n", msg);          fprintf(stderr, "%s\n", msg);
         for (i = 0; i< len; i++) {          for (i = 0; i< len; i++){
                 fprintf(stderr, "%02x", digest[i]);                  fprintf(stderr, "%02x", digest[i]);
                 if (i%32 == 31)                  if (i%32 == 31)
                         fprintf(stderr, "\n");                          fprintf(stderr, "\n");

Legend:
Removed from v.1.33.2.3  
changed lines
  Added in v.1.34