X-Git-Url: https://www.tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fprotocol_key.c;h=6caba591135d5cde1c359cd319bd2b8781711a20;hb=refs%2Fheads%2F1.0-gnutls;hp=cb652c1e197c49e5bb45a8f25ca4b9324b9ece2b;hpb=83263b74460656ba557fd9bb84dc27258549e9cd;p=tinc diff --git a/src/protocol_key.c b/src/protocol_key.c index cb652c1e..6caba591 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -17,11 +17,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - $Id: protocol_key.c,v 1.1.4.22 2003/07/24 12:08:16 guus Exp $ + $Id: protocol_key.c,v 1.1.4.26 2003/12/20 21:25:17 guus Exp $ */ #include "system.h" +#include +#include + #include "avl_tree.h" #include "connection.h" #include "logger.h" @@ -77,7 +80,8 @@ bool key_changed_h(connection_t *c) /* Tell the others */ - forward_request(c); + if(!tunnelserver) + forward_request(c); return true; } @@ -125,43 +129,50 @@ bool req_key_h(connection_t *c) mykeyused = true; from->received_seqno = 0; memset(from->late, 0, sizeof(from->late)); - send_ans_key(c, myself, from); + send_ans_key(c, from); } else { + if(tunnelserver) + return false; + send_req_key(to->nexthop->connection, from, to); } return true; } -bool send_ans_key(connection_t *c, const node_t *from, const node_t *to) +bool send_ans_key(connection_t *c, const node_t *to) { - char key[MAX_STRING_SIZE]; + char cipherkey[myself->cipherkeylen * 2 + 1]; + char digestkey[myself->digestlen * 2 + 1]; cp(); - bin2hex(from->key, key, from->keylength); - key[from->keylength * 2] = '\0'; + bin2hex(myself->cipherkey, cipherkey, myself->cipherkeylen); + cipherkey[myself->cipherkeylen * 2] = '\0'; - return send_request(c, "%d %s %s %s %d %d %d %d", ANS_KEY, - from->name, to->name, key, - from->cipher ? from->cipher->nid : 0, - from->digest ? from->digest->type : 0, from->maclength, - from->compression); + bin2hex(myself->digestkey, digestkey, myself->digestlen); + digestkey[myself->digestlen * 2] = '\0'; + + return send_request(c, "%d %s %s %s %s %d %d %d %d", ANS_KEY, + myself->name, to->name, cipherkey, digestkey, + myself->cipher, + myself->digest, myself->maclength, + myself->compression); } bool ans_key_h(connection_t *c) { char from_name[MAX_STRING_SIZE]; char to_name[MAX_STRING_SIZE]; - char key[MAX_STRING_SIZE]; + char cipherkey[MAX_STRING_SIZE]; + char digestkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; node_t *from, *to; cp(); - if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", - from_name, to_name, key, &cipher, &digest, &maclength, - &compression) != 7) { + if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %d %d", + from_name, to_name, cipherkey, digestkey, &cipher, &digest, &maclength, &compression) != 8) { logger(LOG_ERR, _("Got bad %s from %s (%s)"), "ANS_KEY", c->name, c->hostname); return false; @@ -186,61 +197,47 @@ bool ans_key_h(connection_t *c) /* Forward it if necessary */ if(to != myself) { + if(tunnelserver) + return false; + return send_request(to->nexthop->connection, "%s", c->buffer); } - /* Update our copy of the origin's packet key */ - - if(from->key) - free(from->key); - - from->key = xstrdup(key); - from->keylength = strlen(key) / 2; - hex2bin(from->key, from->key, from->keylength); - from->key[from->keylength] = '\0'; - - from->status.validkey = true; - from->status.waitingforkey = false; - from->sent_seqno = 0; - /* Check and lookup cipher and digest algorithms */ if(cipher) { - from->cipher = EVP_get_cipherbynid(cipher); - - if(!from->cipher) { + from->cipher = cipher; + if(!*gcry_cipher_algo_name(from->cipher)) { logger(LOG_ERR, _("Node %s (%s) uses unknown cipher!"), from->name, from->hostname); return false; } - if(from->keylength != from->cipher->key_len + from->cipher->iv_len) { - logger(LOG_ERR, _("Node %s (%s) uses wrong keylength!"), from->name, - from->hostname); - return false; - } + from->cipherblklen = gcry_cipher_get_algo_blklen(from->cipher); } else { - from->cipher = NULL; + from->cipher = GCRY_CIPHER_NONE; } from->maclength = maclength; if(digest) { - from->digest = EVP_get_digestbynid(digest); + from->digest = digest; - if(!from->digest) { + if(!*gcry_md_algo_name(from->digest)) { logger(LOG_ERR, _("Node %s (%s) uses unknown digest!"), from->name, from->hostname); return false; } - if(from->maclength > from->digest->md_size || from->maclength < 0) { + from->digestlen = gcry_md_get_algo_dlen(from->digest); + + if(from->maclength > from->digestlen || from->maclength < 0) { logger(LOG_ERR, _("Node %s (%s) uses bogus MAC length!"), from->name, from->hostname); return false; } } else { - from->digest = NULL; + from->digest = GCRY_MD_NONE; } if(compression < 0 || compression > 11) { @@ -250,8 +247,56 @@ bool ans_key_h(connection_t *c) from->compression = compression; - if(from->cipher) - EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, from->key, from->key + from->cipher->key_len); + /* Update our copy of the origin's packet key */ + + if(from->cipherkey) + free(from->cipherkey); + + from->cipherkeylen = strlen(cipherkey) / 2; + from->cipherkey = xmalloc(from->cipherkeylen); + hex2bin(cipherkey, from->cipherkey, from->cipherkeylen); + + if(from->cipherkeylen != gcry_cipher_get_algo_keylen(from->cipher)) { + logger(LOG_ERR, _("Node %s (%s) uses wrong keylength %d instead of %d!"), from->name, + from->hostname, from->cipherkeylen, gcry_cipher_get_algo_keylen(from->cipher) ); + return false; + } + + if(from->digestkey) + free(from->digestkey); + + from->digestlen = strlen(digestkey) / 2; + from->digestkey = xmalloc(from->digestlen); + hex2bin(digestkey, from->digestkey, from->digestlen); + + if(from->cipher) { + int result; + result = gcry_cipher_open(&from->cipher_ctx, from->cipher, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE); + gcry_cipher_setkey(from->cipher_ctx, from->cipherkey, from->cipherkeylen); + if(result) { + logger(LOG_ERR, _("Error during initialisation of key from %s (%s): %s"), + from->name, from->hostname, gcry_strerror(result)); + return false; + } + } + + if(from->digest) { + int result; + result = gcry_md_open(&from->digest_ctx, from->digest, GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC); + gcry_md_setkey(from->digest_ctx, from->digestkey, from->digestlen); + if(result) { + logger(LOG_ERR, _("Error during initialisation of key from %s (%s): %s"), + from->name, from->hostname, gcry_strerror(result)); + return false; + } + } + + from->status.validkey = true; + from->status.waitingforkey = false; + from->sent_seqno = 0; + + if(from->options & OPTION_PMTU_DISCOVERY && !from->mtuprobes) + send_mtu_probe(from); flush_queue(from);