- tinc now really does public/private key encryption! It even works, whee!
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 20 Oct 2000 15:34:38 +0000 (15:34 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 20 Oct 2000 15:34:38 +0000 (15:34 +0000)
src/connlist.c
src/connlist.h
src/genauth.c
src/net.c
src/protocol.c
src/protocol.h

index 38c7c8b3529e90cc113bbe83b7f343740374a4f9..9da2d6d1021f87bd0107fcc9b118b9555e8bb07c 100644 (file)
@@ -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)
index 96a194748b6efc5b0a4b3c3bc4f1e495329ff059..0c81e06e83d2b3887b076d4f3fa6764396f65bfb 100644 (file)
@@ -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 */
index ad910b1e20ada5eb162f539969250998f7a02446..78c567d0dc2fc8b9c0a5ed5497c7656d980a8d08 100644 (file)
@@ -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 */
 
index 00254e059fac37f7ef7fe035aeb13c983e26bb7b..81318e3e446575faf058398dc8745f47f95c7eee 100644 (file)
--- a/src/net.c
+++ b/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
index 20f66447c2a8ddc79f9a284b5522aa8513b1615f..3c596398e91013716a4f963e46cceebabc33ad38 100644 (file)
@@ -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);
+  RAND_bytes(cl->hischallenge, len);
+
+  /* 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 random data to a hexadecimal formatted string */
+  /* Convert the encrypted random data to a hexadecimal formatted string */
 
-  bin2hex(cl->hischallenge, buffer, CHAL_LENGTH);
-  buffer[CHAL_LENGTH*2] = '\0';
+  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 */
 
index 27372587a1cab35415a5a46236379ccba83b6019..c3147a761cd07fc00b65016b2aa31faf4bcd3c8e 100644 (file)
@@ -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__
 
 #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 {