along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- $Id: net_setup.c,v 1.1.2.46 2003/11/17 15:30:17 guus Exp $
+ $Id: net_setup.c,v 1.1.2.50 2003/12/20 21:25:17 guus Exp $
*/
#include "system.h"
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gcrypt.h>
#include "avl_tree.h"
#include "conf.h"
char *myport;
+#if 0
bool read_rsa_public_key(connection_t *c)
{
FILE *fp;
return false;
}
+#endif
-bool read_rsa_private_key(void)
+bool setup_credentials(void)
{
- FILE *fp;
- char *fname, *key;
- struct stat s;
+ char *trust = NULL, *crl = NULL;
+ char *key = NULL, *cert = NULL;
+ int result;
cp();
- if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
- myself->connection->rsa_key = RSA_new();
-// RSA_blinding_on(myself->connection->rsa_key, NULL);
- BN_hex2bn(&myself->connection->rsa_key->d, key);
- BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
- free(key);
- return true;
- }
-
- if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname))
- asprintf(&fname, "%s/rsa_key.priv", confbase);
-
- fp = fopen(fname, "r");
+ gnutls_certificate_allocate_credentials(&myself->connection->credentials);
- if(!fp) {
- logger(LOG_ERR, _("Error reading RSA private key file `%s': %s"),
- fname, strerror(errno));
- free(fname);
- return false;
+ if(get_config_string(lookup_config(config_tree, "TrustFile"), &trust)) {
+ result = gnutls_certificate_set_x509_trust_file(myself->connection->credentials, trust, GNUTLS_X509_FMT_PEM);
+ if(result < 0) {
+ logger(LOG_ERR, _("Error reading trust file '%s': %s"), trust, gnutls_strerror(result));
+ free(trust);
+ return false;
+ }
+ free(trust);
}
-#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
- if(fstat(fileno(fp), &s)) {
- logger(LOG_ERR, _("Could not stat RSA private key file `%s': %s'"),
- fname, strerror(errno));
- free(fname);
- return false;
+ if(get_config_string(lookup_config(config_tree, "CRLFile"), &crl)) {
+ result = gnutls_certificate_set_x509_crl_file(myself->connection->credentials, crl, GNUTLS_X509_FMT_PEM);
+ if(result) {
+ logger(LOG_ERR, _("Error reading CRL file '%s': %s"), crl, gnutls_strerror(result));
+ free(crl);
+ return false;
+ }
+ free(crl);
}
- if(s.st_mode & ~0100700)
- logger(LOG_WARNING, _("Warning: insecure file permissions for RSA private key file `%s'!"), fname);
-#endif
+ if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &key))
+ asprintf(&key, "%s/rsa_key.priv", confbase);
- myself->connection->rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
- fclose(fp);
+ if(!get_config_string(lookup_config(config_tree, "CertificateFile"), &cert))
+ asprintf(&cert, "%s/hosts/%s", confbase, myself->name);
- if(!myself->connection->rsa_key) {
- logger(LOG_ERR, _("Reading RSA private key file `%s' failed: %s"),
- fname, strerror(errno));
- free(fname);
+
+ gnutls_certificate_set_x509_trust_file(myself->connection->credentials, cert, GNUTLS_X509_FMT_PEM);
+ logger(LOG_DEBUG, _("JOEHOE"));
+ gnutls_certificate_set_verify_flags(myself->connection->credentials, GNUTLS_VERIFY_DISABLE_CA_SIGN);
+
+ result = gnutls_certificate_set_x509_key_file(myself->connection->credentials, cert, key, GNUTLS_X509_FMT_PEM);
+
+ if(result) {
+ logger(LOG_ERR, _("Error reading credentials from %s and %s: %s"), cert, key, gnutls_strerror(result));
+ free(key);
+ free(cert);
return false;
}
- free(fname);
+ free(key);
+ free(cert);
+
return true;
}
char *envp[5];
struct addrinfo *ai, *aip, hint = {0};
bool choice;
- int i, err;
+ int i, err, result;
cp();
myself->name = name;
myself->connection->name = xstrdup(name);
- if(!read_rsa_private_key())
+ if(!setup_credentials())
return false;
if(!read_connection_config(myself->connection)) {
return false;
}
- if(!read_rsa_public_key(myself->connection))
- return false;
-
- if(!get_config_string
- (lookup_config(myself->connection->config_tree, "Port"), &myport))
+ if(!get_config_string (lookup_config(myself->connection->config_tree, "Port"), &myport))
asprintf(&myport, "655");
/* Read in all the subnets specified in the host configuration file */
/* Check some options */
- if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice))
- if(choice)
- myself->options |= OPTION_INDIRECT;
+ if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice)
+ myself->options |= OPTION_INDIRECT;
+
+ if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice)
+ myself->options |= OPTION_TCPONLY;
- if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice))
- if(choice)
- myself->options |= OPTION_TCPONLY;
+ if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice) && choice)
+ myself->options |= OPTION_INDIRECT;
- if(get_config_bool(lookup_config(myself->connection->config_tree, "IndirectData"), &choice))
- if(choice)
- myself->options |= OPTION_INDIRECT;
+ if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice) && choice)
+ myself->options |= OPTION_TCPONLY;
- if(get_config_bool(lookup_config(myself->connection->config_tree, "TCPOnly"), &choice))
- if(choice)
- myself->options |= OPTION_TCPONLY;
+ if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice)
+ myself->options |= OPTION_PMTU_DISCOVERY;
if(myself->options & OPTION_TCPONLY)
myself->options |= OPTION_INDIRECT;
if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire))
macexpire = 600;
- if(get_config_int(lookup_config(myself->connection->config_tree, "MaxTimeout"), &maxtimeout)) {
+ if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) {
if(maxtimeout <= 0) {
logger(LOG_ERR, _("Bogus maximum timeout!"));
return false;
/* Generate packet encryption key */
- if(get_config_string
- (lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) {
+ if(get_config_string (lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) {
if(!strcasecmp(cipher, "none")) {
- myself->cipher = NULL;
+ myself->cipher = GCRY_CIPHER_NONE;
} else {
- myself->cipher = EVP_get_cipherbyname(cipher);
+ myself->cipher = gcry_cipher_map_name(cipher);
if(!myself->cipher) {
logger(LOG_ERR, _("Unrecognized cipher type!"));
}
}
} else
- myself->cipher = EVP_bf_cbc();
+ myself->cipher = GCRY_CIPHER_AES;
- if(myself->cipher)
- myself->keylength = myself->cipher->key_len + myself->cipher->iv_len;
- else
- myself->keylength = 1;
+ if(myself->cipher) {
+ result = gcry_cipher_open(&myself->cipher_ctx, myself->cipher, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_SECURE);
- myself->connection->outcipher = EVP_bf_ofb();
+ if(result) {
+ logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
+ myself->name, myself->hostname, gcry_strerror(result));
+ return false;
+ }
- myself->key = xmalloc(myself->keylength);
- RAND_pseudo_bytes(myself->key, myself->keylength);
+ }
+
+ if(myself->cipher) {
+ myself->cipherkeylen = gcry_cipher_get_algo_keylen(myself->cipher);
+ myself->cipherblklen = gcry_cipher_get_algo_blklen(myself->cipher);
+ } else {
+ myself->cipherkeylen = 1;
+ }
+
+ logger(LOG_DEBUG, _("Key %s len %d"), gcry_cipher_algo_name(myself->cipher), myself->cipherkeylen);
+ myself->cipherkey = xmalloc(myself->cipherkeylen);
+ gcry_randomize(myself->cipherkey, myself->cipherkeylen, GCRY_STRONG_RANDOM);
+ if(myself->cipher)
+ gcry_cipher_setkey(myself->cipher_ctx, myself->cipherkey, myself->cipherkeylen);
if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
keylifetime = 3600;
keyexpires = now + keylifetime;
- if(myself->cipher) {
- EVP_CIPHER_CTX_init(&packet_ctx);
- if(!EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, myself->key, myself->key + myself->cipher->key_len)) {
- logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
- myself->name, myself->hostname, ERR_error_string(ERR_get_error(), NULL));
- return false;
- }
-
- }
-
/* Check if we want to use message authentication codes... */
- if(get_config_string
- (lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
+ if(get_config_string (lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
if(!strcasecmp(digest, "none")) {
- myself->digest = NULL;
+ myself->digest = GCRY_MD_NONE;
} else {
- myself->digest = EVP_get_digestbyname(digest);
+ myself->digest = gcry_md_map_name(digest);
if(!myself->digest) {
logger(LOG_ERR, _("Unrecognized digest type!"));
}
}
} else
- myself->digest = EVP_sha1();
+ myself->digest = GCRY_MD_SHA1;
- myself->connection->outdigest = EVP_sha1();
- if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"),
- &myself->maclength)) {
+ if(myself->digest) {
+ result = gcry_md_open(&myself->digest_ctx, myself->digest, GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC);
+
+ if(result) {
+ logger(LOG_ERR, _("Error during initialisation of digest for %s (%s): %s"),
+ myself->name, myself->hostname, gcry_strerror(result));
+ return false;
+ }
+
+ }
+
+ if(myself->digest) {
+ myself->digestlen = gcry_md_get_algo_dlen(myself->digest);
+ } else {
+ myself->digestlen = 1;
+ }
+
+ myself->digestkey = xmalloc(myself->digestlen);
+ gcry_randomize(myself->digestkey, myself->digestlen, GCRY_STRONG_RANDOM);
+ if(myself->digest)
+ gcry_md_setkey(myself->digest_ctx, myself->digestkey, myself->digestlen);
+
+ if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->maclength)) {
if(myself->digest) {
- if(myself->maclength > myself->digest->md_size) {
+ if(myself->maclength > myself->digestlen) {
logger(LOG_ERR, _("MAC length exceeds size of digest!"));
return false;
} else if(myself->maclength < 0) {
} else
myself->maclength = 4;
- myself->connection->outmaclength = 0;
-
/* Compression */
if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"),
} else
myself->compression = 0;
- myself->connection->outcompression = 0;
-
/* Done */
myself->nexthop = myself;