]> git.meshlink.io Git - meshlink/commitdiff
Use the crypto wrappers again instead of calling OpenSSL directly.
authorGuus Sliepen <guus@tinc-vpn.org>
Thu, 11 Dec 2008 14:44:44 +0000 (14:44 +0000)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 11 Dec 2008 14:44:44 +0000 (14:44 +0000)
This theoretically allows other cryptographic libraries to be used,
and it improves the readability of the code.

src/connection.c
src/connection.h
src/meta.c
src/net_packet.c
src/net_setup.c
src/node.c
src/node.h
src/protocol_auth.c
src/protocol_key.c
src/tincd.c

index 06f51b50aac3e4b55dfe14ffa89d7c0321a83ee6..84d2ac4de2f743fa6f106507794d35756266dd3e 100644 (file)
@@ -23,6 +23,7 @@
 #include "system.h"
 
 #include "splay_tree.h"
+#include "cipher.h"
 #include "conf.h"
 #include "list.h"
 #include "logger.h"
@@ -73,14 +74,8 @@ void free_connection(connection_t *c) {
        if(c->hostname)
                free(c->hostname);
 
-       if(c->inkey)
-               free(c->inkey);
-
-       if(c->outkey)
-               free(c->outkey);
-
-       if(c->mychallenge)
-               free(c->mychallenge);
+       cipher_close(&c->incipher);
+       cipher_close(&c->outcipher);
 
        if(c->hischallenge)
                free(c->hischallenge);
index ddff03bbd7a7081510b3717aba08dee9d8f1d71a..ca71cad9711c416959ac63c3f5f1b8d6ce2391fa 100644 (file)
 #ifndef __TINC_CONNECTION_H__
 #define __TINC_CONNECTION_H__
 
-#include <openssl/rsa.h>
-#include <openssl/evp.h>
-
 #include <event.h>
 
+#include "cipher.h"
+#include "digest.h"
+#include "rsa.h"
 #include "splay_tree.h"
 
 #define OPTION_INDIRECT                0x0001
@@ -72,23 +72,18 @@ typedef struct connection_t {
        struct node_t *node;            /* node associated with the other end */
        struct edge_t *edge;            /* edge associated with this connection */
 
-       RSA *rsa_key;                           /* his public/private key */
-       const EVP_CIPHER *incipher;     /* Cipher he will use to send data to us */
-       const EVP_CIPHER *outcipher;    /* Cipher we will use to send data to him */
-       EVP_CIPHER_CTX *inctx;          /* Context of encrypted meta data that will come from him to us */
-       EVP_CIPHER_CTX *outctx;         /* Context of encrypted meta data that will be sent from us to him */
-       char *inkey;                            /* His symmetric meta key + iv */
-       char *outkey;                           /* Our symmetric meta key + iv */
-       int inkeylength;                        /* Length of his key + iv */
-       int outkeylength;                       /* Length of our key + iv */
-       const EVP_MD *indigest;
-       const EVP_MD *outdigest;
+       rsa_t rsa;                      /* his public/private key */
+       cipher_t incipher;              /* Cipher he will use to send data to us */
+       cipher_t outcipher;             /* Cipher we will use to send data to him */
+       digest_t indigest;
+       digest_t outdigest;
+
        int inmaclength;
        int outmaclength;
        int incompression;
        int outcompression;
-       char *mychallenge;                      /* challenge we received from him */
-       char *hischallenge;                     /* challenge we sent to him */
+
+       char *hischallenge;             /* The challenge we sent to him */
 
        struct bufferevent *buffer;                     /* buffer events on this metadata connection */
        struct event inevent;                           /* input event on this metadata connection */
index cb4b03e163eee94bd1fff6cf1727b5fc66783f84..aaa5c30cc313f9e7572f188d71be627893bc9dc7 100644 (file)
 
 #include "system.h"
 
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
 #include "splay_tree.h"
+#include "cipher.h"
 #include "connection.h"
 #include "logger.h"
 #include "meta.h"
@@ -35,8 +33,6 @@
 #include "xalloc.h"
 
 bool send_meta(connection_t *c, const char *buffer, int length) {
-       int outlen;
-       int result;
        cp();
 
        ifdebug(META) logger(LOG_DEBUG, _("Sending %d bytes of metadata to %s (%s)"), length,
@@ -45,11 +41,11 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
        /* Add our data to buffer */
        if(c->status.encryptout) {
                char outbuf[length];
+               size_t outlen = length;
 
-               result = EVP_EncryptUpdate(c->outctx, (unsigned char *)outbuf, &outlen, (unsigned char *)buffer, length);
-               if(!result || outlen != length) {
-                       logger(LOG_ERR, _("Error while encrypting metadata to %s (%s): %s"),
-                                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+               if(!cipher_encrypt(&c->outcipher, buffer, length, outbuf, &outlen, false) || outlen != length) {
+                       logger(LOG_ERR, _("Error while encrypting metadata to %s (%s)"),
+                                       c->name, c->hostname);
                        return false;
                }
                
@@ -80,7 +76,7 @@ void broadcast_meta(connection_t *from, const char *buffer, int length) {
 }
 
 bool receive_meta(connection_t *c) {
-       int result, inlen, outlen;
+       size_t inlen;
        char inbuf[MAXBUFSIZE];
        char *bufp = inbuf, *endp;
 
@@ -115,12 +111,13 @@ bool receive_meta(connection_t *c) {
                        inlen -= endp - bufp;
                        bufp = endp;
                } else {
+                       size_t outlen = inlen;
                        ifdebug(META) logger(LOG_DEBUG, _("Received encrypted %d bytes"), inlen);
                        evbuffer_expand(c->buffer->input, c->buffer->input->off + inlen);
-                       result = EVP_DecryptUpdate(c->inctx, (unsigned char *)c->buffer->input->buffer + c->buffer->input->off, &outlen, (unsigned char *)bufp, inlen);
-                       if(!result || outlen != inlen) {
-                               logger(LOG_ERR, _("Error while decrypting metadata from %s (%s): %s"),
-                                          c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
+
+                       if(!cipher_decrypt(&c->incipher, bufp, inlen, c->buffer->input->buffer + c->buffer->input->off, &outlen, false) || inlen != outlen) {
+                               logger(LOG_ERR, _("Error while decrypting metadata from %s (%s)"),
+                                          c->name, c->hostname);
                                return false;
                        }
                        c->buffer->input->off += inlen;
@@ -146,8 +143,10 @@ bool receive_meta(connection_t *c) {
 
                        char *request = evbuffer_readline(c->buffer->input);
                        if(request) {
-                               receive_request(c, request);
+                               bool result = receive_request(c, request);
                                free(request);
+                               if(!result)
+                                       return false;
                                continue;
                        } else {
                                break;
index 2a86d657e35e783b827f3e927829fb528ce67aa4..eee3972e16135a54bb0fcc72f89ac29b971d167c 100644 (file)
 
 #include "system.h"
 
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/pem.h>
-#include <openssl/hmac.h>
-
 #include <zlib.h>
 #include LZO1X_H
 
 #include "splay_tree.h"
+#include "cipher.h"
 #include "conf.h"
 #include "connection.h"
+#include "crypto.h"
+#include "digest.h"
 #include "device.h"
 #include "ethernet.h"
 #include "graph.h"
@@ -52,7 +49,6 @@
 #endif
 
 int keylifetime = 0;
-EVP_CIPHER_CTX packet_ctx;
 static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
 
 static void send_udppacket(node_t *, vpn_packet_t *);
@@ -85,7 +81,7 @@ static void send_mtu_probe_handler(int fd, short events, void *data) {
                        len = 64;
                
                memset(packet.data, 0, 14);
-               RAND_pseudo_bytes(packet.data + 14, len - 14);
+               randomize(packet.data + 14, len - 14);
                packet.len = len;
 
                ifdebug(TRAFFIC) logger(LOG_INFO, _("Sending MTU probe length %d to %s (%s)"), len, n->name, n->hostname);
@@ -168,15 +164,14 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
        int nextpkt = 0;
        vpn_packet_t *outpkt = pkt[0];
-       int outlen, outpad;
-       unsigned char hmac[EVP_MAX_MD_SIZE];
+       size_t outlen;
        int i;
 
        cp();
 
        /* Check packet length */
 
-       if(inpkt->len < sizeof(inpkt->seqno) + myself->maclength) {
+       if(inpkt->len < sizeof(inpkt->seqno) + digest_length(&myself->digest)) {
                ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got too short packet from %s (%s)"),
                                        n->name, n->hostname);
                return;
@@ -184,33 +179,23 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
 
        /* Check the message authentication code */
 
-       if(myself->digest && myself->maclength) {
-               inpkt->len -= myself->maclength;
-               HMAC(myself->digest, myself->key, myself->keylength,
-                        (unsigned char *) &inpkt->seqno, inpkt->len, (unsigned char *)hmac, NULL);
-
-               if(memcmp(hmac, (char *) &inpkt->seqno + inpkt->len, myself->maclength)) {
-                       ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"),
-                                          n->name, n->hostname);
-                       return;
-               }
+       if(digest_active(&myself->digest) && !digest_verify(&myself->digest, &inpkt->seqno, inpkt->len, &inpkt->seqno + inpkt->len)) {
+               ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Got unauthenticated packet from %s (%s)"), n->name, n->hostname);
+               return;
        }
 
        /* Decrypt the packet */
 
-       if(myself->cipher) {
+       if(cipher_active(&myself->cipher)) {
                outpkt = pkt[nextpkt++];
+               outlen = MAXSIZE;
 
-               if(!EVP_DecryptInit_ex(&packet_ctx, NULL, NULL, NULL, NULL)
-                               || !EVP_DecryptUpdate(&packet_ctx, (unsigned char *) &outpkt->seqno, &outlen,
-                                       (unsigned char *) &inpkt->seqno, inpkt->len)
-                               || !EVP_DecryptFinal_ex(&packet_ctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
-                       ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Error decrypting packet from %s (%s): %s"),
-                                               n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
+               if(!cipher_decrypt(&myself->cipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
+                       ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Error decrypting packet from %s (%s)"), n->name, n->hostname);
                        return;
                }
                
-               outpkt->len = outlen + outpad;
+               outpkt->len = outlen;
                inpkt = outpkt;
        }
 
@@ -283,7 +268,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        int nextpkt = 0;
        vpn_packet_t *outpkt;
        int origlen;
-       int outlen, outpad;
+       size_t outlen;
        vpn_packet_t *copy;
        static int priority = 0;
        int origpriority;
@@ -339,28 +324,24 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
 
        /* Encrypt the packet */
 
-       if(n->cipher) {
+       if(cipher_active(&n->cipher)) {
                outpkt = pkt[nextpkt++];
+               outlen = MAXSIZE;
 
-               if(!EVP_EncryptInit_ex(&n->packet_ctx, NULL, NULL, NULL, NULL)
-                               || !EVP_EncryptUpdate(&n->packet_ctx, (unsigned char *) &outpkt->seqno, &outlen,
-                                       (unsigned char *) &inpkt->seqno, inpkt->len)
-                               || !EVP_EncryptFinal_ex(&n->packet_ctx, (unsigned char *) &outpkt->seqno + outlen, &outpad)) {
-                       ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while encrypting packet to %s (%s): %s"),
-                                               n->name, n->hostname, ERR_error_string(ERR_get_error(), NULL));
+               if(!cipher_encrypt(&n->cipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
+                       ifdebug(TRAFFIC) logger(LOG_ERR, _("Error while encrypting packet to %s (%s)"), n->name, n->hostname);
                        goto end;
                }
 
-               outpkt->len = outlen + outpad;
+               outpkt->len = outlen;
                inpkt = outpkt;
        }
 
        /* Add the message authentication code */
 
-       if(n->digest && n->maclength) {
-               HMAC(n->digest, n->key, n->keylength, (unsigned char *) &inpkt->seqno,
-                        inpkt->len, (unsigned char *) &inpkt->seqno + inpkt->len, NULL);
-               inpkt->len += n->maclength;
+       if(digest_active(&n->digest)) {
+               digest_create(&n->digest, &inpkt->seqno, inpkt->len, &inpkt->seqno + inpkt->len);
+               inpkt->len += digest_length(&n->digest);
        }
 
        /* Determine which socket we have to use */
index b8fb4f0205d3f174cd04147a5a6c142f76fd3888..033bf3761eb773bd728e4827cf30de6ec72de723 100644 (file)
 
 #include "system.h"
 
-#include <openssl/pem.h>
-#include <openssl/rsa.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
 #include "splay_tree.h"
+#include "cipher.h"
 #include "conf.h"
 #include "connection.h"
 #include "control.h"
 #include "device.h"
+#include "digest.h"
 #include "graph.h"
 #include "logger.h"
 #include "net.h"
@@ -40,6 +36,7 @@
 #include "process.h"
 #include "protocol.h"
 #include "route.h"
+#include "rsa.h"
 #include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
@@ -50,125 +47,66 @@ static struct event device_ev;
 bool read_rsa_public_key(connection_t *c) {
        FILE *fp;
        char *fname;
-       char *key;
+       char *n;
+       bool result;
 
        cp();
 
-       if(!c->rsa_key) {
-               c->rsa_key = RSA_new();
-//             RSA_blinding_on(c->rsa_key, NULL);
-       }
-
        /* First, check for simple PublicKey statement */
 
-       if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) {
-               BN_hex2bn(&c->rsa_key->n, key);
-               BN_hex2bn(&c->rsa_key->e, "FFFF");
-               free(key);
-               return true;
+       if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &n)) {
+               result = rsa_set_hex_public_key(&c->rsa, n, "FFFF");
+               free(n);
+               return result;
        }
 
        /* Else, check for PublicKeyFile statement and read it */
 
-       if(get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname)) {
-               fp = fopen(fname, "r");
-
-               if(!fp) {
-                       logger(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
-                                  fname, strerror(errno));
-                       free(fname);
-                       return false;
-               }
-
-               free(fname);
-               c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
-               fclose(fp);
-
-               if(c->rsa_key)
-                       return true;            /* Woohoo. */
+       if(!get_config_string(lookup_config(c->config_tree, "PublicKeyFile"), &fname))
+               asprintf(&fname, "%s/hosts/%s", confbase, c->name);
 
-               /* If it fails, try PEM_read_RSA_PUBKEY. */
-               fp = fopen(fname, "r");
-
-               if(!fp) {
-                       logger(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
-                                  fname, strerror(errno));
-                       free(fname);
-                       return false;
-               }
-
-               free(fname);
-               c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
-               fclose(fp);
-
-               if(c->rsa_key) {
-//                             RSA_blinding_on(c->rsa_key, NULL);
-                       return true;
-               }
+       fp = fopen(fname, "r");
 
-               logger(LOG_ERR, _("Reading RSA public key file `%s' failed: %s"),
+       if(!fp) {
+               logger(LOG_ERR, _("Error reading RSA public key file `%s': %s"),
                           fname, strerror(errno));
+               free(fname);
                return false;
        }
 
-       /* Else, check if a harnessed public key is in the config file */
-
-       asprintf(&fname, "%s/hosts/%s", confbase, c->name);
-       fp = fopen(fname, "r");
-
-       if(fp) {
-               c->rsa_key = PEM_read_RSAPublicKey(fp, &c->rsa_key, NULL, NULL);
-               fclose(fp);
-       }
-
-       free(fname);
-
-       if(c->rsa_key)
-               return true;
-
-       /* Try again with PEM_read_RSA_PUBKEY. */
-
-       asprintf(&fname, "%s/hosts/%s", confbase, c->name);
-       fp = fopen(fname, "r");
-
-       if(fp) {
-               c->rsa_key = PEM_read_RSA_PUBKEY(fp, &c->rsa_key, NULL, NULL);
-//             RSA_blinding_on(c->rsa_key, NULL);
-               fclose(fp);
-       }
+       result = rsa_read_pem_public_key(&c->rsa, fp);
+       fclose(fp);
 
+       if(!result) 
+               logger(LOG_ERR, _("Reading RSA public key file `%s' failed: %s"), fname, strerror(errno));
        free(fname);
-
-       if(c->rsa_key)
-               return true;
-
-       logger(LOG_ERR, _("No public key for %s specified!"), c->name);
-
-       return false;
+       return result;
 }
 
-bool read_rsa_private_key(void) {
+bool read_rsa_private_key() {
        FILE *fp;
-       char *fname, *key, *pubkey;
-       struct stat s;
+       char *fname;
+       char *n, *d;
+       bool result;
 
        cp();
 
-       if(get_config_string(lookup_config(config_tree, "PrivateKey"), &key)) {
-               if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &pubkey)) {
+       /* First, check for simple PrivateKey statement */
+
+       if(get_config_string(lookup_config(config_tree, "PrivateKey"), &d)) {
+               if(!get_config_string(lookup_config(myself->connection->config_tree, "PublicKey"), &n)) {
                        logger(LOG_ERR, _("PrivateKey used but no PublicKey found!"));
+                       free(d);
                        return false;
                }
-               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->n, pubkey);
-               BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
-               free(key);
-               free(pubkey);
+               result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d);
+               free(n);
+               free(d);
                return true;
        }
 
+       /* Else, check for PrivateKeyFile statement and read it */
+
        if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname))
                asprintf(&fname, "%s/rsa_key.priv", confbase);
 
@@ -182,9 +120,10 @@ bool read_rsa_private_key(void) {
        }
 
 #if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN)
+       struct stat s;
+
        if(fstat(fileno(fp), &s)) {
-               logger(LOG_ERR, _("Could not stat RSA private key file `%s': %s'"),
-                               fname, strerror(errno));
+               logger(LOG_ERR, _("Could not stat RSA private key file `%s': %s'"), fname, strerror(errno));
                free(fname);
                return false;
        }
@@ -193,18 +132,13 @@ bool read_rsa_private_key(void) {
                logger(LOG_WARNING, _("Warning: insecure file permissions for RSA private key file `%s'!"), fname);
 #endif
 
-       myself->connection->rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
+       result = rsa_read_pem_private_key(&myself->connection->rsa, fp);
        fclose(fp);
 
-       if(!myself->connection->rsa_key) {
-               logger(LOG_ERR, _("Reading RSA private key file `%s' failed: %s"),
-                          fname, strerror(errno));
-               free(fname);
-               return false;
-       }
-
+       if(!result) 
+               logger(LOG_ERR, _("Reading RSA private key file `%s' failed: %s"), fname, strerror(errno));
        free(fname);
-       return true;
+       return result;
 }
 
 static struct event keyexpire_event;
@@ -214,10 +148,14 @@ static void keyexpire_handler(int fd, short events, void *data) {
 }
 
 void regenerate_key() {
-       RAND_pseudo_bytes((unsigned char *)myself->key, myself->keylength);
+       ifdebug(STATUS) logger(LOG_INFO, _("Regenerating symmetric key"));
+
+       if(!cipher_regenerate_key(&myself->cipher, true)) {
+               logger(LOG_ERR, _("Error regenerating key!"));
+               abort();
+       }
 
        if(timeout_initialized(&keyexpire_event)) {
-               ifdebug(STATUS) logger(LOG_INFO, _("Regenerating symmetric key"));
                event_del(&keyexpire_event);
                send_key_changed(broadcast, myself);
        } else {
@@ -225,16 +163,6 @@ void regenerate_key() {
        }
 
        event_add(&keyexpire_event, &(struct timeval){keylifetime, 0});
-
-       if(myself->cipher) {
-               EVP_CIPHER_CTX_init(&packet_ctx);
-               if(!EVP_DecryptInit_ex(&packet_ctx, myself->cipher, NULL, (unsigned char *)myself->key, (unsigned char *)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));
-                       abort();
-               }
-
-       }
 }
 
 /*
@@ -373,73 +301,44 @@ bool setup_myself(void) {
 
        /* Generate packet encryption key */
 
-       if(get_config_string
-          (lookup_config(myself->connection->config_tree, "Cipher"), &cipher)) {
-               if(!strcasecmp(cipher, "none")) {
-                       myself->cipher = NULL;
-               } else {
-                       myself->cipher = EVP_get_cipherbyname(cipher);
-
-                       if(!myself->cipher) {
-                               logger(LOG_ERR, _("Unrecognized cipher type!"));
-                               return false;
-                       }
-               }
-       } else
-               myself->cipher = EVP_bf_cbc();
-
-       if(myself->cipher)
-               myself->keylength = myself->cipher->key_len + myself->cipher->iv_len;
-       else
-               myself->keylength = 1;
-
-       myself->connection->outcipher = EVP_bf_ofb();
+       if(!get_config_string(lookup_config(myself->connection->config_tree, "Cipher"), &cipher))
+               cipher = xstrdup("blowfish");
 
-       myself->key = xmalloc(myself->keylength);
+       if(!cipher_open_by_name(&myself->cipher, cipher)) {
+               logger(LOG_ERR, _("Unrecognized cipher type!"));
+               return false;
+       }
 
        if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime))
                keylifetime = 3600;
 
        regenerate_key();
+
        /* Check if we want to use message authentication codes... */
 
-       if(get_config_string
-          (lookup_config(myself->connection->config_tree, "Digest"), &digest)) {
-               if(!strcasecmp(digest, "none")) {
-                       myself->digest = NULL;
-               } else {
-                       myself->digest = EVP_get_digestbyname(digest);
-
-                       if(!myself->digest) {
-                               logger(LOG_ERR, _("Unrecognized digest type!"));
-                               return false;
-                       }
-               }
-       } else
-               myself->digest = EVP_sha1();
-
-       myself->connection->outdigest = EVP_sha1();
-
-       if(get_config_int(lookup_config(myself->connection->config_tree, "MACLength"),
-               &myself->maclength)) {
-               if(myself->digest) {
-                       if(myself->maclength > myself->digest->md_size) {
-                               logger(LOG_ERR, _("MAC length exceeds size of digest!"));
-                               return false;
-                       } else if(myself->maclength < 0) {
-                               logger(LOG_ERR, _("Bogus MAC length!"));
-                               return false;
-                       }
-               }
-       } else
-               myself->maclength = 4;
+       if(!get_config_string(lookup_config(myself->connection->config_tree, "Digest"), &digest))
+               digest = xstrdup("sha1");
 
-       myself->connection->outmaclength = 0;
+       if(!digest_open_by_name(&myself->digest, digest)) {
+               logger(LOG_ERR, _("Unrecognized digest type!"));
+               return false;
+       }
+
+       if(!get_config_int(lookup_config(myself->connection->config_tree, "MACLength"), &myself->maclength))
+
+       if(digest_active(&myself->digest)) {
+               if(myself->maclength > digest_length(&myself->digest)) {
+                       logger(LOG_ERR, _("MAC length exceeds size of digest!"));
+                       return false;
+               } else if(myself->maclength < 0) {
+                       logger(LOG_ERR, _("Bogus MAC length!"));
+                       return false;
+               }
+       }
 
        /* Compression */
 
-       if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"),
-               &myself->compression)) {
+       if(get_config_int(lookup_config(myself->connection->config_tree, "Compression"), &myself->compression)) {
                if(myself->compression < 0 || myself->compression > 11) {
                        logger(LOG_ERR, _("Bogus compression level!"));
                        return false;
@@ -463,8 +362,8 @@ bool setup_myself(void) {
        if(!setup_device())
                return false;
 
-       event_set(&device_ev, device_fd, EV_READ|EV_PERSIST,
-                         handle_device_data, NULL);
+       event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL);
+
        if (event_add(&device_ev, NULL) < 0) {
                logger(LOG_ERR, _("event_add failed: %s"), strerror(errno));
                close_device();
index 0960ca761c32595b940103091459c0a8ec852090..99bbb6db1cf200bca7f940b033e20a6948d4d718 100644 (file)
@@ -74,7 +74,6 @@ node_t *new_node(void) {
        n->subnet_tree = new_subnet_tree();
        n->edge_tree = new_edge_tree();
        n->queue = list_alloc((list_action_t) free);
-       EVP_CIPHER_CTX_init(&n->packet_ctx);
        n->mtu = MTU;
        n->maxmtu = MTU;
 
@@ -87,9 +86,6 @@ void free_node(node_t *n) {
        if(n->queue)
                list_delete_list(n->queue);
 
-       if(n->key)
-               free(n->key);
-
        if(n->subnet_tree)
                free_subnet_tree(n->subnet_tree);
 
@@ -98,7 +94,8 @@ void free_node(node_t *n) {
 
        sockaddrfree(&n->address);
 
-       EVP_CIPHER_CTX_cleanup(&n->packet_ctx);
+       cipher_close(&n->cipher);
+       digest_close(&n->digest);
 
        event_del(&n->mtuevent);
        
@@ -169,8 +166,8 @@ int dump_nodes(struct evbuffer *out) {
        for(node = node_tree->head; node; node = node->next) {
                n = node->data;
                if(evbuffer_add_printf(out, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s pmtu %d (min %d max %d)\n"),
-                          n->name, n->hostname, n->cipher ? n->cipher->nid : 0,
-                          n->digest ? n->digest->type : 0, n->maclength, n->compression,
+                          n->name, n->hostname, cipher_get_nid(&n->cipher),
+                          digest_get_nid(&n->digest), n->maclength, n->compression,
                           n->options, *(uint32_t *)&n->status, n->nexthop ? n->nexthop->name : "-",
                           n->via ? n->via->name : "-", n->mtu, n->minmtu, n->maxmtu) == -1)
                        return errno;
index 0476cdb062430de506dce3c01e124e2b73874d5d..fee68593eafc86bd88ed266119d8cfa16f40343e 100644 (file)
@@ -24,7 +24,9 @@
 #define __TINC_NODE_H__
 
 #include "splay_tree.h"
+#include "cipher.h"
 #include "connection.h"
+#include "digest.h"
 #include "list.h"
 #include "subnet.h"
 
@@ -50,13 +52,9 @@ typedef struct node_t {
 
        node_status_t status;
 
-       const EVP_CIPHER *cipher;               /* Cipher type for UDP packets */
-       char *key;                              /* Cipher key and iv */
-       int keylength;                          /* Cipher key and iv length */
-       EVP_CIPHER_CTX packet_ctx;              /* Cipher context */
-       
-       const EVP_MD *digest;                   /* Digest type for MAC */
-       int maclength;                          /* Length of MAC */
+       cipher_t cipher;                        /* Cipher for UDP packets */
+       digest_t digest;                        /* Digest for UDP packets */    
+       int maclength;                          /* Portion of digest to use */
 
        int compression;                        /* Compressionlevel, 0 = no compression */
 
index 49dfd2817d3ebd9e19e017ef8235dc8c9e962ef6..0471932a2c33a51da91658ac88846bc05ad14a7d 100644 (file)
 
 #include "system.h"
 
-#include <openssl/sha.h>
-#include <openssl/rand.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-
 #include "splay_tree.h"
 #include "conf.h"
 #include "connection.h"
+#include "crypto.h"
 #include "edge.h"
 #include "graph.h"
 #include "logger.h"
@@ -37,6 +33,7 @@
 #include "netutl.h"
 #include "node.h"
 #include "protocol.h"
+#include "rsa.h"
 #include "utils.h"
 #include "xalloc.h"
 
@@ -117,27 +114,22 @@ bool id_h(connection_t *c, char *request) {
 }
 
 bool send_metakey(connection_t *c) {
-       char *buffer;
-       int len;
-       bool x;
+       size_t len = rsa_size(&c->rsa);
+       char key[len];
+       char enckey[len];
+       char hexkey[2 * len + 1];
 
        cp();
 
-       len = RSA_size(c->rsa_key);
-
-       /* Allocate buffers for the meta key */
-
-       buffer = alloca(2 * len + 1);
+       if(!cipher_open_blowfish_ofb(&c->outcipher))
+               return false;
        
-       if(!c->outkey)
-               c->outkey = xmalloc(len);
+       if(!digest_open_sha1(&c->outdigest))
+               return false;
 
-       if(!c->outctx)
-               c->outctx = xmalloc_and_zero(sizeof(*c->outctx));
-       cp();
-       /* Copy random data to the buffer */
+       /* Create a random key */
 
-       RAND_pseudo_bytes((unsigned char *)c->outkey, len);
+       randomize(key, len);
 
        /* The message we send must be smaller than the modulus of the RSA key.
           By definition, for a key of k bits, the following formula holds:
@@ -149,13 +141,14 @@ bool send_metakey(connection_t *c) {
           This can be done by setting the most significant bit to zero.
         */
 
-       c->outkey[0] &= 0x7F;
+       key[0] &= 0x7F;
+
+       cipher_set_key_from_rsa(&c->outcipher, key, len, true);
 
        ifdebug(SCARY_THINGS) {
-               bin2hex(c->outkey, buffer, len);
-               buffer[len * 2] = '\0';
-               logger(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"),
-                          buffer);
+               bin2hex(key, hexkey, len);
+               hexkey[len * 2] = '\0';
+               logger(LOG_DEBUG, _("Generated random meta key (unencrypted): %s"), hexkey);
        }
 
        /* Encrypt the random data
@@ -165,135 +158,78 @@ bool send_metakey(connection_t *c) {
           with a length equal to that of the modulus of the RSA key.
         */
 
-       if(RSA_public_encrypt(len, (unsigned char *)c->outkey, (unsigned char *)buffer, c->rsa_key, RSA_NO_PADDING) != len) {
-               logger(LOG_ERR, _("Error during encryption of meta key for %s (%s)"),
-                          c->name, c->hostname);
+       if(!rsa_public_encrypt(&c->rsa, key, len, enckey)) {
+               logger(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), c->name, c->hostname);
                return false;
        }
 
        /* Convert the encrypted random data to a hexadecimal formatted string */
 
-       bin2hex(buffer, buffer, len);
-       buffer[len * 2] = '\0';
+       bin2hex(enckey, hexkey, len);
+       hexkey[len * 2] = '\0';
 
        /* Send the meta key */
 
-       x = send_request(c, "%d %d %d %d %d %s", METAKEY,
-                                        c->outcipher ? c->outcipher->nid : 0,
-                                        c->outdigest ? c->outdigest->type : 0, c->outmaclength,
-                                        c->outcompression, buffer);
-
-       /* Further outgoing requests are encrypted with the key we just generated */
-
-       if(c->outcipher) {
-               if(!EVP_EncryptInit(c->outctx, c->outcipher,
-                                       (unsigned char *)c->outkey + len - c->outcipher->key_len,
-                                       (unsigned char *)c->outkey + len - c->outcipher->key_len -
-                                       c->outcipher->iv_len)) {
-                       logger(LOG_ERR, _("Error during initialisation of cipher for %s (%s): %s"),
-                                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
-                       return false;
-               }
-
-               c->status.encryptout = true;
-       }
-
-       return x;
+       bool result = send_request(c, "%d %d %d %d %d %s", METAKEY,
+                        cipher_get_nid(&c->outcipher),
+                        digest_get_nid(&c->outdigest), c->outmaclength,
+                        c->outcompression, hexkey);
+       
+       c->status.encryptout = true;
+       return result;
 }
 
 bool metakey_h(connection_t *c, char *request) {
-       char buffer[MAX_STRING_SIZE];
+       char hexkey[MAX_STRING_SIZE];
        int cipher, digest, maclength, compression;
-       int len;
+       size_t len = rsa_size(&myself->connection->rsa);
+       char enckey[len];
+       char key[len];
 
        cp();
 
-       if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, buffer) != 5) {
-               logger(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name,
-                          c->hostname);
+       if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, hexkey) != 5) {
+               logger(LOG_ERR, _("Got bad %s from %s (%s)"), "METAKEY", c->name, c->hostname);
                return false;
        }
 
-       len = RSA_size(myself->connection->rsa_key);
-
        /* Check if the length of the meta key is all right */
 
-       if(strlen(buffer) != len * 2) {
+       if(strlen(hexkey) != len * 2) {
                logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, "wrong keylength");
                return false;
        }
 
-       /* Allocate buffers for the meta key */
-
-       if(!c->inkey)
-               c->inkey = xmalloc(len);
-
-       if(!c->inctx)
-               c->inctx = xmalloc_and_zero(sizeof(*c->inctx));
-
        /* Convert the challenge from hexadecimal back to binary */
 
-       hex2bin(buffer, buffer, len);
+       hex2bin(hexkey, enckey, len);
 
        /* Decrypt the meta key */
 
-       if(RSA_private_decrypt(len, (unsigned char *)buffer, (unsigned char *)c->inkey, myself->connection->rsa_key, RSA_NO_PADDING) != len) {  /* See challenge() */
-               logger(LOG_ERR, _("Error during encryption of meta key for %s (%s)"),
-                          c->name, c->hostname);
+       if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) {
+               logger(LOG_ERR, _("Error during encryption of meta key for %s (%s)"), c->name, c->hostname);
                return false;
        }
 
        ifdebug(SCARY_THINGS) {
-               bin2hex(c->inkey, buffer, len);
-               buffer[len * 2] = '\0';
-               logger(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), buffer);
+               bin2hex(key, hexkey, len);
+               hexkey[len * 2] = '\0';
+               logger(LOG_DEBUG, _("Received random meta key (unencrypted): %s"), hexkey);
        }
 
-       /* All incoming requests will now be encrypted. */
-
        /* Check and lookup cipher and digest algorithms */
 
-       if(cipher) {
-               c->incipher = EVP_get_cipherbynid(cipher);
-               
-               if(!c->incipher) {
-                       logger(LOG_ERR, _("%s (%s) uses unknown cipher!"), c->name, c->hostname);
-                       return false;
-               }
-
-               if(!EVP_DecryptInit(c->inctx, c->incipher,
-                                       (unsigned char *)c->inkey + len - c->incipher->key_len,
-                                       (unsigned char *)c->inkey + len - c->incipher->key_len -
-                                       c->incipher->iv_len)) {
-                       logger(LOG_ERR, _("Error during initialisation of cipher from %s (%s): %s"),
-                                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
-                       return false;
-               }
-
-               c->status.decryptin = true;
-       } else {
-               c->incipher = NULL;
+       if(!cipher_open_by_nid(&c->incipher, cipher) || !cipher_set_key_from_rsa(&c->incipher, key, len, false)) {
+               logger(LOG_ERR, _("Error during initialisation of cipher from %s (%s)"), c->name, c->hostname);
+               return false;
        }
 
-       c->inmaclength = maclength;
-
-       if(digest) {
-               c->indigest = EVP_get_digestbynid(digest);
-
-               if(!c->indigest) {
-                       logger(LOG_ERR, _("Node %s (%s) uses unknown digest!"), c->name, c->hostname);
-                       return false;
-               }
-
-               if(c->inmaclength > c->indigest->md_size || c->inmaclength < 0) {
-                       logger(LOG_ERR, _("%s (%s) uses bogus MAC length!"), c->name, c->hostname);
-                       return false;
-               }
-       } else {
-               c->indigest = NULL;
+       if(!digest_open_by_nid(&c->indigest, digest)) {
+               logger(LOG_ERR, _("Error during initialisation of digest from %s (%s)"), c->name, c->hostname);
+               return false;
        }
 
-       c->incompression = compression;
+       c->status.decryptin = true;
 
        c->allow_request = CHALLENGE;
 
@@ -301,25 +237,17 @@ bool metakey_h(connection_t *c, char *request) {
 }
 
 bool send_challenge(connection_t *c) {
-       char *buffer;
-       int len;
+       size_t len = rsa_size(&c->rsa);
+       char buffer[len * 2 + 1];
 
        cp();
 
-       /* CHECKME: what is most reasonable value for len? */
-
-       len = RSA_size(c->rsa_key);
-
-       /* Allocate buffers for the challenge */
-
-       buffer = alloca(2 * len + 1);
-
        if(!c->hischallenge)
                c->hischallenge = xmalloc(len);
 
        /* Copy random data to the buffer */
 
-       RAND_pseudo_bytes((unsigned char *)c->hischallenge, len);
+       randomize(c->hischallenge, len);
 
        /* Convert to hex */
 
@@ -333,72 +261,48 @@ bool send_challenge(connection_t *c) {
 
 bool challenge_h(connection_t *c, char *request) {
        char buffer[MAX_STRING_SIZE];
-       int len;
+       size_t len = rsa_size(&myself->connection->rsa);
+       size_t digestlen = digest_length(&c->outdigest);
+       char digest[digestlen];
 
        cp();
 
        if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) {
-               logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name,
-                          c->hostname);
+               logger(LOG_ERR, _("Got bad %s from %s (%s)"), "CHALLENGE", c->name, c->hostname);
                return false;
        }
 
-       len = RSA_size(myself->connection->rsa_key);
-
        /* Check if the length of the challenge is all right */
 
        if(strlen(buffer) != len * 2) {
-               logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
-                          c->hostname, "wrong challenge length");
+               logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, "wrong challenge length");
                return false;
        }
 
-       /* Allocate buffers for the challenge */
-
-       if(!c->mychallenge)
-               c->mychallenge = xmalloc(len);
-
        /* Convert the challenge from hexadecimal back to binary */
 
-       hex2bin(buffer, c->mychallenge, len);
+       hex2bin(buffer, buffer, len);
 
        c->allow_request = CHAL_REPLY;
 
-       /* Rest is done by send_chal_reply() */
-
-       return send_chal_reply(c);
-}
-
-bool send_chal_reply(connection_t *c) {
-       char hash[EVP_MAX_MD_SIZE * 2 + 1];
-       EVP_MD_CTX ctx;
-
        cp();
 
        /* Calculate the hash from the challenge we received */
 
-       if(!EVP_DigestInit(&ctx, c->indigest)
-                       || !EVP_DigestUpdate(&ctx, c->mychallenge, RSA_size(myself->connection->rsa_key))
-                       || !EVP_DigestFinal(&ctx, (unsigned char *)hash, NULL)) {
-               logger(LOG_ERR, _("Error during calculation of response for %s (%s): %s"),
-                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
-               return false;
-       }
+       digest_create(&c->indigest, buffer, len, digest);
 
        /* Convert the hash to a hexadecimal formatted string */
 
-       bin2hex(hash, hash, c->indigest->md_size);
-       hash[c->indigest->md_size * 2] = '\0';
+       bin2hex(digest, buffer, digestlen);
+       buffer[digestlen * 2] = '\0';
 
        /* Send the reply */
 
-       return send_request(c, "%d %s", CHAL_REPLY, hash);
+       return send_request(c, "%d %s", CHAL_REPLY, buffer);
 }
 
 bool chal_reply_h(connection_t *c, char *request) {
        char hishash[MAX_STRING_SIZE];
-       char myhash[EVP_MAX_MD_SIZE];
-       EVP_MD_CTX ctx;
 
        cp();
 
@@ -410,38 +314,19 @@ bool chal_reply_h(connection_t *c, char *request) {
 
        /* Check if the length of the hash is all right */
 
-       if(strlen(hishash) != c->outdigest->md_size * 2) {
-               logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
-                          c->hostname, _("wrong challenge reply length"));
+       if(strlen(hishash) != digest_length(&c->outdigest) * 2) {
+               logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, _("wrong challenge reply length"));
                return false;
        }
 
        /* Convert the hash to binary format */
 
-       hex2bin(hishash, hishash, c->outdigest->md_size);
-
-       /* Calculate the hash from the challenge we sent */
-
-       if(!EVP_DigestInit(&ctx, c->outdigest)
-                       || !EVP_DigestUpdate(&ctx, c->hischallenge, RSA_size(c->rsa_key))
-                       || !EVP_DigestFinal(&ctx, (unsigned char *)myhash, NULL)) {
-               logger(LOG_ERR, _("Error during calculation of response from %s (%s): %s"),
-                       c->name, c->hostname, ERR_error_string(ERR_get_error(), NULL));
-               return false;
-       }
-
-       /* Verify the incoming hash with the calculated hash */
+       hex2bin(hishash, hishash, digest_length(&c->outdigest));
 
-       if(memcmp(hishash, myhash, c->outdigest->md_size)) {
-               logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name,
-                          c->hostname, _("wrong challenge reply"));
-
-               ifdebug(SCARY_THINGS) {
-                       bin2hex(myhash, hishash, SHA_DIGEST_LENGTH);
-                       hishash[SHA_DIGEST_LENGTH * 2] = '\0';
-                       logger(LOG_DEBUG, _("Expected challenge reply: %s"), hishash);
-               }
+       /* Verify the hash */
 
+       if(!digest_verify(&c->outdigest, c->hischallenge, rsa_size(&c->rsa), hishash)) {
+               logger(LOG_ERR, _("Possible intruder %s (%s): %s"), c->name, c->hostname, _("wrong challenge reply"));
                return false;
        }
 
@@ -449,6 +334,8 @@ bool chal_reply_h(connection_t *c, char *request) {
           Send an acknowledgement with the rest of the information needed.
         */
 
+       free(c->hischallenge);
+       c->hischallenge = NULL;
        c->allow_request = ACK;
 
        return send_ack(c);
index 05bc97ba0dbcecc33f10c72b519ef6a35f045dda..52666d998698d2d1f6d89f01f67836bf067aa51a 100644 (file)
 
 #include "system.h"
 
-#include <openssl/evp.h>
-#include <openssl/err.h>
-
 #include "splay_tree.h"
+#include "cipher.h"
 #include "connection.h"
 #include "logger.h"
 #include "net.h"
@@ -35,7 +33,7 @@
 #include "utils.h"
 #include "xalloc.h"
 
-bool mykeyused = false;
+static bool mykeyused = false;
 
 bool send_key_changed(connection_t *c, const node_t *n) {
        cp();
@@ -137,18 +135,19 @@ bool req_key_h(connection_t *c, char *request) {
 }
 
 bool send_ans_key(connection_t *c, const node_t *from, const node_t *to) {
-       char *key;
+       size_t keylen = cipher_keylength(&from->cipher);
+       char key[keylen * 2 + 1];
 
        cp();
 
-       key = alloca(2 * from->keylength + 1);
-       bin2hex(from->key, key, from->keylength);
-       key[from->keylength * 2] = '\0';
+       cipher_get_key(&from->cipher, key);
+       bin2hex(key, key, keylen);
+       key[keylen * 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,
+                                               cipher_get_nid(&from->cipher),
+                                               digest_get_nid(&from->digest), from->maclength,
                                                from->compression);
 }
 
@@ -194,58 +193,28 @@ bool ans_key_h(connection_t *c, char *request) {
                return send_request(to->nexthop->connection, "%s", request);
        }
 
-       /* 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) {
-                       logger(LOG_ERR, _("Node %s (%s) uses unknown cipher!"), from->name,
-                                  from->hostname);
-                       return false;
-               }
+       if(!cipher_open_by_nid(&from->cipher, 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;
-               }
-       } else {
-               from->cipher = NULL;
+       if(strlen(key) / 2 != cipher_keylength(&from->cipher)) {
+               logger(LOG_ERR, _("Node %s (%s) uses wrong keylength!"), from->name, from->hostname);
+               return false;
        }
 
        from->maclength = maclength;
 
-       if(digest) {
-               from->digest = EVP_get_digestbynid(digest);
-
-               if(!from->digest) {
-                       logger(LOG_ERR, _("Node %s (%s) uses unknown digest!"), from->name,
-                                  from->hostname);
-                       return false;
-               }
+       if(!digest_open_by_nid(&from->digest, 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) {
-                       logger(LOG_ERR, _("Node %s (%s) uses bogus MAC length!"),
-                                  from->name, from->hostname);
-                       return false;
-               }
-       } else {
-               from->digest = NULL;
+       if(from->maclength > digest_length(&from->digest) || from->maclength < 0) {
+               logger(LOG_ERR, _("Node %s (%s) uses bogus MAC length!"), from->name, from->hostname);
+               return false;
        }
 
        if(compression < 0 || compression > 11) {
@@ -255,12 +224,14 @@ bool ans_key_h(connection_t *c, char *request) {
        
        from->compression = compression;
 
-       if(from->cipher)
-               if(!EVP_EncryptInit_ex(&from->packet_ctx, from->cipher, NULL, (unsigned char *)from->key, (unsigned char *)from->key + from->cipher->key_len)) {
-                       logger(LOG_ERR, _("Error during initialisation of key from %s (%s): %s"),
-                                       from->name, from->hostname, ERR_error_string(ERR_get_error(), NULL));
-                       return false;
-               }
+       /* Update our copy of the origin's packet key */
+
+       hex2bin(key, key, cipher_keylength(&from->cipher));
+       cipher_set_key(&from->cipher, key, 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);
index 20443101a369c690ecd82f1cc1586b0b36cdd74c..0f78e45a6239e3a02625d7309d04eb44e6be9cdd 100644 (file)
 #include <sys/mman.h>
 #endif
 
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/pem.h>
-#include <openssl/evp.h>
-#include <openssl/engine.h>
-
 #include LZO1X_H
 
 #include <getopt.h>
 
 #include "conf.h"
 #include "control.h"
+#include "crypto.h"
 #include "device.h"
 #include "logger.h"
 #include "net.h"
@@ -295,12 +290,7 @@ int main(int argc, char **argv)
        /* Slllluuuuuuurrrrp! */
 
        srand(time(NULL));
-       RAND_load_file("/dev/urandom", 1024);
-
-       ENGINE_load_builtin_engines();
-       ENGINE_register_all_complete();
-
-       OpenSSL_add_all_algorithms();
+       crypto_init();
 
        if(!read_server_config())
                return 1;
@@ -353,7 +343,7 @@ end:
        exit_control();
 #endif
 
-       EVP_cleanup();
-       
+       crypto_exit();
+
        return status;
 }