- tinc now really does public/private key encryption! It even works, whee!

This commit is contained in:
Guus Sliepen 2000-10-20 15:34:38 +00:00
parent 430e141629
commit 9f64499e40
6 changed files with 101 additions and 34 deletions

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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> #include <syslog.h>
@ -57,8 +57,8 @@ cp
free(p->name); free(p->name);
if(p->hostname) if(p->hostname)
free(p->hostname); free(p->hostname);
if(p->public_key) if(p->rsa_key)
RSA_free(p->public_key); RSA_free(p->rsa_key);
if(p->cipher_pktkey) if(p->cipher_pktkey)
free(p->cipher_pktkey); free(p->cipher_pktkey);
if(p->buffer) if(p->buffer)

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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__ #ifndef __TINC_CONNLIST_H__
@ -44,7 +44,7 @@ typedef struct conn_list_t {
packet_queue_t *sq; /* pending outgoing packets */ packet_queue_t *sq; /* pending outgoing packets */
packet_queue_t *rq; /* pending incoming packets (they have no packet_queue_t *rq; /* pending incoming packets (they have no
valid key to be decrypted with) */ 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_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 */ EVP_CIPHER_CTX *cipher_outctx; /* Context of encrypted meta data that will be sent from us to him */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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" #include "config.h"
@ -105,6 +105,7 @@ int main(int argc, char **argv)
printf(_("Public key: %s\n"), BN_bn2hex(key->n)); printf(_("Public key: %s\n"), BN_bn2hex(key->n));
printf(_("Private key: %s\n"), BN_bn2hex(key->d)); 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 */ fflush(stdin); /* Flush any input caused by random keypresses */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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" #include "config.h"
@ -637,13 +637,41 @@ cp
syslog(LOG_ERR, _("Invalid name for myself!")); syslog(LOG_ERR, _("Invalid name for myself!"));
return -1; 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)) if(read_host_config(myself))
{ {
syslog(LOG_ERR, _("Cannot open host configuration file for myself!")); syslog(LOG_ERR, _("Cannot open host configuration file for myself!"));
return -1; 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))) if(!(cfg = get_config_val(myself->config, port)))
myself->port = 655; myself->port = 655;
else else

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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" #include "config.h"
@ -163,6 +163,7 @@ cp
int id_h(conn_list_t *cl) int id_h(conn_list_t *cl)
{ {
conn_list_t *old; conn_list_t *old;
config_t *cfg;
cp cp
if(sscanf(cl->buffer, "%*d %as %d %lx %hd", &cl->name, &cl->protocol_version, &cl->options, &cl->port) != 4) 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 */ /* Load information about peer */
cp
if(read_host_config(cl)) if(read_host_config(cl))
{ {
syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name); syslog(LOG_ERR, _("Peer %s had unknown identity (%s)"), cl->hostname, cl->name);
return -1; return -1;
} }
/* First check if the host we connected to is already in our /* First check if the host we connected to is already in our
connection list. If so, we are probably making a loop, which connection list. If so, we are probably making a loop, which
is not desirable. is not desirable.
*/ */
cp
if(cl->status.outgoing) if(cl->status.outgoing)
{ {
if((old = lookup_id(cl->name))) if((old = lookup_id(cl->name)))
@ -213,38 +213,71 @@ cp
return 0; 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 cp
return send_challenge(cl); return send_challenge(cl);
} }
int send_challenge(conn_list_t *cl) int send_challenge(conn_list_t *cl)
{ {
char buffer[CHAL_LENGTH*2+1]; char *buffer;
int len, x;
cp cp
len = RSA_size(cl->rsa_key);
/* Allocate buffers for the challenge */ /* Allocate buffers for the challenge */
if(!cl->hischallenge) buffer = xmalloc(len*2+1);
cl->hischallenge = xmalloc(CHAL_LENGTH);
if(cl->hischallenge)
free(cl->hischallenge);
cl->hischallenge = xmalloc(len);
cp cp
/* Copy random data to the buffer */ /* Copy random data to the buffer */
RAND_bytes(cl->hischallenge, CHAL_LENGTH); RAND_bytes(cl->hischallenge, len);
cp
/* Convert the random data to a hexadecimal formatted string */
bin2hex(cl->hischallenge, buffer, CHAL_LENGTH); /* Encrypt the random data */
buffer[CHAL_LENGTH*2] = '\0';
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 */ /* Send the challenge */
cl->allow_request = CHAL_REPLY; cl->allow_request = CHAL_REPLY;
x = send_request(cl, "%d %s", CHALLENGE, buffer);
free(buffer);
cp cp
return send_request(cl, "%d %s", CHALLENGE, buffer); return x;
} }
int challenge_h(conn_list_t *cl) int challenge_h(conn_list_t *cl)
{ {
char *buffer; char *buffer;
int len;
cp cp
if(sscanf(cl->buffer, "%*d %as", &buffer) != 1) if(sscanf(cl->buffer, "%*d %as", &buffer) != 1)
{ {
@ -252,9 +285,11 @@ cp
return -1; return -1;
} }
len = RSA_size(myself->rsa_key);
/* Check if the length of the challenge is all right */ /* 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); syslog(LOG_ERR, _("Intruder: wrong challenge length from %s (%s)"), cl->name, cl->hostname);
free(buffer); free(buffer);
@ -264,11 +299,21 @@ cp
/* Allocate buffers for the challenge */ /* Allocate buffers for the challenge */
if(!cl->mychallenge) if(!cl->mychallenge)
cl->mychallenge = xmalloc(CHAL_LENGTH); cl->mychallenge = xmalloc(len);
/* Convert the challenge from hexadecimal back to binary */ /* 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); free(buffer);
/* Rest is done by send_chal_reply() */ /* Rest is done by send_chal_reply() */
@ -288,7 +333,7 @@ cp
/* Calculate the hash from the challenge we received */ /* 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 */ /* Convert the hash to a hexadecimal formatted string */
@ -333,7 +378,7 @@ cp
/* Calculate the hash from the challenge we sent */ /* 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 */ /* Verify the incoming hash with the calculated hash */

View file

@ -17,7 +17,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 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__ #ifndef __TINC_PROTOCOL_H__
@ -32,13 +32,6 @@
#define PROT_CURRENT 8 #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 */ /* Request numbers */
enum { enum {