From: Guus Sliepen Date: Fri, 20 Oct 2000 15:34:38 +0000 (+0000) Subject: - tinc now really does public/private key encryption! It even works, whee! X-Git-Tag: release-1.0pre3~75 X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=commitdiff_plain;h=9f64499e40a95a8c05c82924219517aa017fc411 - tinc now really does public/private key encryption! It even works, whee! --- diff --git a/src/connlist.c b/src/connlist.c index 38c7c8b3..9da2d6d1 100644 --- a/src/connlist.c +++ b/src/connlist.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: 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 @@ -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) diff --git a/src/connlist.h b/src/connlist.h index 96a19474..0c81e06e 100644 --- a/src/connlist.h +++ b/src/connlist.h @@ -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 */ diff --git a/src/genauth.c b/src/genauth.c index ad910b1e..78c567d0 100644 --- a/src/genauth.c +++ b/src/genauth.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: 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 */ diff --git a/src/net.c b/src/net.c index 00254e05..81318e3e 100644 --- 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 diff --git a/src/protocol.c b/src/protocol.c index 20f66447..3c596398 100644 --- a/src/protocol.c +++ b/src/protocol.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: 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 */ diff --git a/src/protocol.h b/src/protocol.h index 27372587..c3147a76 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -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 {