- tinc now really does public/private key encryption! It even works, whee!
This commit is contained in:
		
							parent
							
								
									430e141629
								
							
						
					
					
						commit
						9f64499e40
					
				
					 6 changed files with 101 additions and 34 deletions
				
			
		| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 | 
			
		||||
    $Id: connlist.c,v 1.1.2.6 2000/10/16 19:04:46 guus Exp $
 | 
			
		||||
    $Id: connlist.c,v 1.1.2.7 2000/10/20 15:34:34 guus Exp $
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <syslog.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -57,8 +57,8 @@ cp
 | 
			
		|||
    free(p->name);
 | 
			
		||||
  if(p->hostname)
 | 
			
		||||
    free(p->hostname);
 | 
			
		||||
  if(p->public_key)
 | 
			
		||||
    RSA_free(p->public_key);
 | 
			
		||||
  if(p->rsa_key)
 | 
			
		||||
    RSA_free(p->rsa_key);
 | 
			
		||||
  if(p->cipher_pktkey)
 | 
			
		||||
    free(p->cipher_pktkey);
 | 
			
		||||
  if(p->buffer)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 | 
			
		||||
    $Id: connlist.h,v 1.1.2.3 2000/10/14 17:04:13 guus Exp $
 | 
			
		||||
    $Id: connlist.h,v 1.1.2.4 2000/10/20 15:34:34 guus Exp $
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __TINC_CONNLIST_H__
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ typedef struct conn_list_t {
 | 
			
		|||
  packet_queue_t *sq;              /* pending outgoing packets */
 | 
			
		||||
  packet_queue_t *rq;              /* pending incoming packets (they have no
 | 
			
		||||
				      valid key to be decrypted with) */
 | 
			
		||||
  RSA *public_key;                 /* the other party's public key */
 | 
			
		||||
  RSA *rsa_key;                    /* the public/private key */
 | 
			
		||||
 | 
			
		||||
  EVP_CIPHER_CTX *cipher_inctx;    /* Context of encrypted meta data that will come from him to us */
 | 
			
		||||
  EVP_CIPHER_CTX *cipher_outctx;   /* Context of encrypted meta data that will be sent from us to him */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 | 
			
		||||
    $Id: genauth.c,v 1.7.4.3 2000/10/19 14:42:00 guus Exp $
 | 
			
		||||
    $Id: genauth.c,v 1.7.4.4 2000/10/20 15:34:35 guus Exp $
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -105,6 +105,7 @@ int main(int argc, char **argv)
 | 
			
		|||
 | 
			
		||||
  printf(_("Public key:  %s\n"), BN_bn2hex(key->n));
 | 
			
		||||
  printf(_("Private key: %s\n"), BN_bn2hex(key->d));
 | 
			
		||||
  printf(_("Public exp:  %s\n"), BN_bn2hex(key->e));
 | 
			
		||||
 | 
			
		||||
  fflush(stdin);	/* Flush any input caused by random keypresses */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								src/net.c
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								src/net.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 | 
			
		||||
    $Id: net.c,v 1.35.4.40 2000/10/16 19:04:46 guus Exp $
 | 
			
		||||
    $Id: net.c,v 1.35.4.41 2000/10/20 15:34:35 guus Exp $
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -637,13 +637,41 @@ cp
 | 
			
		|||
      syslog(LOG_ERR, _("Invalid name for myself!"));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
cp
 | 
			
		||||
  if(!(cfg = get_config_val(config, privatekey)))
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Private key for tinc daemon required!"));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      myself->rsa_key = RSA_new();
 | 
			
		||||
      BN_hex2bn(&myself->rsa_key->d, cfg->data.ptr);
 | 
			
		||||
      BN_hex2bn(&myself->rsa_key->e, "FFFF");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if(read_host_config(myself))
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Cannot open host configuration file for myself!"));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
cp  
 | 
			
		||||
  if(!(cfg = get_config_val(myself->config, publickey)))
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Public key for tinc daemon required!"));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      BN_hex2bn(&myself->rsa_key->n, cfg->data.ptr);
 | 
			
		||||
    }
 | 
			
		||||
/*
 | 
			
		||||
  if(RSA_check_key(myself->rsa_key) != 1)
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Invalid public/private keypair!"));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
*/
 | 
			
		||||
  if(!(cfg = get_config_val(myself->config, port)))
 | 
			
		||||
    myself->port = 655;
 | 
			
		||||
  else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 | 
			
		||||
    $Id: protocol.c,v 1.28.4.42 2000/10/16 19:04:47 guus Exp $
 | 
			
		||||
    $Id: protocol.c,v 1.28.4.43 2000/10/20 15:34:37 guus Exp $
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -163,6 +163,7 @@ cp
 | 
			
		|||
int id_h(conn_list_t *cl)
 | 
			
		||||
{
 | 
			
		||||
  conn_list_t *old;
 | 
			
		||||
  config_t *cfg;
 | 
			
		||||
cp
 | 
			
		||||
  if(sscanf(cl->buffer, "%*d %as %d %lx %hd", &cl->name, &cl->protocol_version, &cl->options, &cl->port) != 4)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -188,19 +189,18 @@ cp
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
  /* Load information about peer */
 | 
			
		||||
 | 
			
		||||
cp
 | 
			
		||||
  if(read_host_config(cl))
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* First check if the host we connected to is already in our
 | 
			
		||||
     connection list. If so, we are probably making a loop, which
 | 
			
		||||
     is not desirable.
 | 
			
		||||
   */
 | 
			
		||||
 | 
			
		||||
cp
 | 
			
		||||
  if(cl->status.outgoing)
 | 
			
		||||
    {
 | 
			
		||||
      if((old = lookup_id(cl->name)))
 | 
			
		||||
| 
						 | 
				
			
			@ -213,38 +213,71 @@ cp
 | 
			
		|||
          return 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
cp    
 | 
			
		||||
  if(!(cfg = get_config_val(cl->config, publickey)))
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("No public key known for %s (%s)"), cl->name, cl->hostname);
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
cp
 | 
			
		||||
      cl->rsa_key = RSA_new();
 | 
			
		||||
      BN_hex2bn(&cl->rsa_key->n, cfg->data.ptr);
 | 
			
		||||
      BN_hex2bn(&cl->rsa_key->e, "FFFF");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
cp
 | 
			
		||||
  return send_challenge(cl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int send_challenge(conn_list_t *cl)
 | 
			
		||||
{
 | 
			
		||||
  char buffer[CHAL_LENGTH*2+1];
 | 
			
		||||
  char *buffer;
 | 
			
		||||
  int len, x;
 | 
			
		||||
cp
 | 
			
		||||
  len = RSA_size(cl->rsa_key);
 | 
			
		||||
 | 
			
		||||
  /* Allocate buffers for the challenge */
 | 
			
		||||
 | 
			
		||||
  if(!cl->hischallenge)
 | 
			
		||||
    cl->hischallenge = xmalloc(CHAL_LENGTH);
 | 
			
		||||
  buffer = xmalloc(len*2+1);
 | 
			
		||||
 | 
			
		||||
  if(cl->hischallenge)
 | 
			
		||||
    free(cl->hischallenge);
 | 
			
		||||
    
 | 
			
		||||
  cl->hischallenge = xmalloc(len);
 | 
			
		||||
cp
 | 
			
		||||
  /* Copy random data to the buffer */
 | 
			
		||||
 | 
			
		||||
  RAND_bytes(cl->hischallenge, CHAL_LENGTH);
 | 
			
		||||
cp
 | 
			
		||||
  /* Convert the random data to a hexadecimal formatted string */
 | 
			
		||||
  RAND_bytes(cl->hischallenge, len);
 | 
			
		||||
 | 
			
		||||
  bin2hex(cl->hischallenge, buffer, CHAL_LENGTH);
 | 
			
		||||
  buffer[CHAL_LENGTH*2] = '\0';
 | 
			
		||||
  /* Encrypt the random data */
 | 
			
		||||
  
 | 
			
		||||
  if(RSA_public_encrypt(len, cl->hischallenge, buffer, cl->rsa_key, RSA_NO_PADDING) != len)	/* NO_PADDING because the message size equals the RSA key size and it is totally random */
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Error during encryption of challenge for %s (%s)"), cl->name, cl->hostname);
 | 
			
		||||
      free(buffer);
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
cp
 | 
			
		||||
  /* Convert the encrypted random data to a hexadecimal formatted string */
 | 
			
		||||
 | 
			
		||||
  bin2hex(buffer, buffer, len);
 | 
			
		||||
  buffer[len*2] = '\0';
 | 
			
		||||
 | 
			
		||||
  /* Send the challenge */
 | 
			
		||||
 | 
			
		||||
  cl->allow_request = CHAL_REPLY;
 | 
			
		||||
  x = send_request(cl, "%d %s", CHALLENGE, buffer);
 | 
			
		||||
  free(buffer);
 | 
			
		||||
cp
 | 
			
		||||
  return send_request(cl, "%d %s", CHALLENGE, buffer);
 | 
			
		||||
  return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int challenge_h(conn_list_t *cl)
 | 
			
		||||
{
 | 
			
		||||
  char *buffer;
 | 
			
		||||
  int len;
 | 
			
		||||
cp
 | 
			
		||||
  if(sscanf(cl->buffer, "%*d %as", &buffer) != 1)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -252,9 +285,11 @@ cp
 | 
			
		|||
       return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  len = RSA_size(myself->rsa_key);
 | 
			
		||||
 | 
			
		||||
  /* Check if the length of the challenge is all right */
 | 
			
		||||
 | 
			
		||||
  if(strlen(buffer) != CHAL_LENGTH*2)
 | 
			
		||||
  if(strlen(buffer) != len*2)
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
 | 
			
		||||
      free(buffer);
 | 
			
		||||
| 
						 | 
				
			
			@ -264,11 +299,21 @@ cp
 | 
			
		|||
  /* Allocate buffers for the challenge */
 | 
			
		||||
 | 
			
		||||
  if(!cl->mychallenge)
 | 
			
		||||
    cl->mychallenge = xmalloc(CHAL_LENGTH);
 | 
			
		||||
    cl->mychallenge = xmalloc(len);
 | 
			
		||||
 | 
			
		||||
  /* Convert the challenge from hexadecimal back to binary */
 | 
			
		||||
 | 
			
		||||
  hex2bin(buffer,cl->mychallenge,CHAL_LENGTH);
 | 
			
		||||
  hex2bin(buffer,buffer,len);
 | 
			
		||||
 | 
			
		||||
  /* Decrypt the challenge */
 | 
			
		||||
  
 | 
			
		||||
  if(RSA_private_decrypt(len, buffer, cl->mychallenge, myself->rsa_key, RSA_NO_PADDING) != len)	/* See challenge() */
 | 
			
		||||
    {
 | 
			
		||||
      syslog(LOG_ERR, _("Error during encryption of challenge for %s (%s)"), cl->name, cl->hostname);
 | 
			
		||||
      free(buffer);
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  free(buffer);
 | 
			
		||||
    
 | 
			
		||||
  /* Rest is done by send_chal_reply() */
 | 
			
		||||
| 
						 | 
				
			
			@ -288,7 +333,7 @@ cp
 | 
			
		|||
     
 | 
			
		||||
  /* Calculate the hash from the challenge we received */
 | 
			
		||||
 | 
			
		||||
  SHA1(cl->mychallenge, CHAL_LENGTH, hash);
 | 
			
		||||
  SHA1(cl->mychallenge, RSA_size(myself->rsa_key), hash);
 | 
			
		||||
 | 
			
		||||
  /* Convert the hash to a hexadecimal formatted string */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -333,7 +378,7 @@ cp
 | 
			
		|||
 | 
			
		||||
  /* Calculate the hash from the challenge we sent */
 | 
			
		||||
 | 
			
		||||
  SHA1(cl->hischallenge, CHAL_LENGTH, myhash);
 | 
			
		||||
  SHA1(cl->hischallenge, RSA_size(cl->rsa_key), myhash);
 | 
			
		||||
 | 
			
		||||
  /* Verify the incoming hash with the calculated hash */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@
 | 
			
		|||
    along with this program; if not, write to the Free Software
 | 
			
		||||
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
			
		||||
 | 
			
		||||
    $Id: protocol.h,v 1.5.4.11 2000/10/15 00:59:36 guus Exp $
 | 
			
		||||
    $Id: protocol.h,v 1.5.4.12 2000/10/20 15:34:38 guus Exp $
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __TINC_PROTOCOL_H__
 | 
			
		||||
| 
						 | 
				
			
			@ -32,13 +32,6 @@
 | 
			
		|||
 | 
			
		||||
#define PROT_CURRENT 8
 | 
			
		||||
 | 
			
		||||
/* Length of the challenge. Since the challenge will also
 | 
			
		||||
   contain the key for the symmetric cipher, it must be
 | 
			
		||||
   quite large.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define CHAL_LENGTH 1024 /* Okay, this is probably waaaaaaaaaaay too large */
 | 
			
		||||
 | 
			
		||||
/* Request numbers */
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue