X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fnet_setup.c;h=2371f7ee099c5390800ec484387867d874bf0c75;hp=121b989279bff7a810d316cc9737396bb33ff43e;hb=5c344f297682cf11793407fca4547968aee22d95;hpb=09d60499af3acef2ba9bd7be15e8d1c44249f8d5 diff --git a/src/net_setup.c b/src/net_setup.c index 121b9892..2371f7ee 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -1,7 +1,7 @@ /* net_setup.c -- Setup. Copyright (C) 1998-2005 Ivo Timmermans, - 2000-2014 Guus Sliepen + 2000-2017 Guus Sliepen 2006 Scott Lamb 2010 Brandon Black @@ -39,6 +39,7 @@ #include "netutl.h" #include "process.h" #include "protocol.h" +#include "proxy.h" #include "route.h" #include "subnet.h" #include "utils.h" @@ -47,17 +48,22 @@ char *myport; devops_t devops; -char *proxyhost; -char *proxyport; -char *proxyuser; -char *proxypass; -proxytype_t proxytype; +#ifndef HAVE_RSA_SET0_KEY +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + BN_free(r->n); r->n = n; + BN_free(r->e); r->e = e; + BN_free(r->d); r->d = d; + return 1; +} +#endif bool read_rsa_public_key(connection_t *c) { FILE *fp; char *pubname; char *hcfname; char *key; + BIGNUM *n = NULL; + BIGNUM *e = NULL; if(!c->rsa_key) { c->rsa_key = RSA_new(); @@ -67,12 +73,19 @@ bool read_rsa_public_key(connection_t *c) { /* First, check for simple PublicKey statement */ if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) { - if(BN_hex2bn(&c->rsa_key->n, key) != strlen(key)) { + if(BN_hex2bn(&n, key) != strlen(key)) { + free(key); logger(LOG_ERR, "Invalid PublicKey for %s!", c->name); return false; } - BN_hex2bn(&c->rsa_key->e, "FFFF"); free(key); + BN_hex2bn(&e, "FFFF"); + if(!n || !e || RSA_set0_key(c->rsa_key, n, e, NULL) != 1) { + BN_free(e); + BN_free(n); + logger(LOG_ERR, "RSA_set0_key() failed with PublicKey for %s!", c->name); + return false; + } return true; } @@ -163,27 +176,39 @@ bool read_rsa_public_key(connection_t *c) { static bool read_rsa_private_key(void) { FILE *fp; char *fname, *key, *pubkey; + BIGNUM *n = NULL; + BIGNUM *e = NULL; + BIGNUM *d = NULL; if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) { myself->connection->rsa_key = RSA_new(); // RSA_blinding_on(myself->connection->rsa_key, NULL); - if(BN_hex2bn(&myself->connection->rsa_key->d, key) != strlen(key)) { + if(BN_hex2bn(&d, key) != strlen(key)) { logger(LOG_ERR, "Invalid PrivateKey for myself!"); free(key); return false; } free(key); if(!get_config_string(lookup_config(config_tree, "PublicKey"), &pubkey)) { + BN_free(d); logger(LOG_ERR, "PrivateKey used but no PublicKey found!"); return false; } - if(BN_hex2bn(&myself->connection->rsa_key->n, pubkey) != strlen(pubkey)) { - logger(LOG_ERR, "Invalid PublicKey for myself!"); + if(BN_hex2bn(&n, pubkey) != strlen(pubkey)) { free(pubkey); + BN_free(d); + logger(LOG_ERR, "Invalid PublicKey for myself!"); return false; } free(pubkey); - BN_hex2bn(&myself->connection->rsa_key->e, "FFFF"); + BN_hex2bn(&e, "FFFF"); + if(!n || !e || !d || RSA_set0_key(myself->connection->rsa_key, n, e, d) != 1) { + BN_free(d); + BN_free(e); + BN_free(n); + logger(LOG_ERR, "RSA_set0_key() failed with PrivateKey for myself!"); + return false; + } return true; } @@ -625,14 +650,28 @@ static bool setup_myself(void) { } free(cipher); } else - myself->incipher = EVP_bf_cbc(); + myself->incipher = EVP_aes_256_cbc(); if(myself->incipher) - myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len; + myself->inkeylength = EVP_CIPHER_key_length(myself->incipher) + EVP_CIPHER_iv_length(myself->incipher); else myself->inkeylength = 1; - myself->connection->outcipher = EVP_bf_ofb(); + /* We need to use a stream mode for the meta protocol. Use AES for this, + but try to match the key size with the one from the cipher selected + by Cipher. + + If Cipher is set to none, still use a low level of encryption for the + meta protocol. + */ + + int keylen = myself->incipher ? EVP_CIPHER_key_length(myself->incipher) : 0; + if(keylen <= 16) + myself->connection->outcipher = EVP_aes_128_cfb(); + else if(keylen <= 24) + myself->connection->outcipher = EVP_aes_192_cfb(); + else + myself->connection->outcipher = EVP_aes_256_cfb(); if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) keylifetime = 3600; @@ -656,13 +695,13 @@ static bool setup_myself(void) { free(digest); } else - myself->indigest = EVP_sha1(); + myself->indigest = EVP_sha256(); - myself->connection->outdigest = EVP_sha1(); + myself->connection->outdigest = EVP_sha256(); if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) { if(myself->indigest) { - if(myself->inmaclength > myself->indigest->md_size) { + if(myself->inmaclength > EVP_MD_size(myself->indigest)) { logger(LOG_ERR, "MAC length exceeds size of digest!"); return false; } else if(myself->inmaclength < 0) { @@ -813,7 +852,7 @@ static bool setup_myself(void) { hint.ai_protocol = IPPROTO_TCP; hint.ai_flags = AI_PASSIVE; -#ifdef HAVE_DECL_RES_INIT +#if HAVE_DECL_RES_INIT // ensure glibc reloads /etc/resolv.conf. res_init(); #endif