Finish crypto wrapping. Also provide wrappers for OpenSSL.
[tinc] / src / net_packet.c
index 84b2707..eee3972 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 "avl_tree.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,8 +49,6 @@
 #endif
 
 int keylifetime = 0;
-int keyexpires = 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 *);
@@ -86,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);
@@ -115,8 +110,7 @@ void mtu_probe_h(node_t *n, vpn_packet_t *packet) {
        }
 }
 
-static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
-{
+static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
        if(level == 10) {
                lzo_uint lzolen = MAXSIZE;
                lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem);
@@ -136,8 +130,7 @@ static length_t compress_packet(uint8_t *dest, const uint8_t *source, length_t l
        return -1;
 }
 
-static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level)
-{
+static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
        if(level > 9) {
                lzo_uint lzolen = MAXSIZE;
                if(lzo1x_decompress_safe(source, len, dest, &lzolen, NULL) == LZO_E_OK)
@@ -157,8 +150,7 @@ static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t
 
 /* VPN packet I/O */
 
-static void receive_packet(node_t *n, vpn_packet_t *packet)
-{
+static void receive_packet(node_t *n, vpn_packet_t *packet) {
        cp();
 
        ifdebug(TRAFFIC) logger(LOG_DEBUG, _("Received packet of %d bytes from %s (%s)"),
@@ -167,21 +159,19 @@ static void receive_packet(node_t *n, vpn_packet_t *packet)
        route(n, packet);
 }
 
-static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
-{
+static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
        vpn_packet_t pkt1, pkt2;
        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;
@@ -189,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;
        }
 
@@ -248,7 +228,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
                n->received_seqno = inpkt->seqno;
                        
        if(n->received_seqno > MAX_SEQNO)
-               keyexpires = 0;
+               regenerate_key();
 
        /* Decompress the packet */
 
@@ -264,17 +244,13 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt)
                inpkt = outpkt;
        }
 
-       if(n->connection)
-               n->connection->last_ping_time = now;
-
        if(!inpkt->data[12] && !inpkt->data[13])
                mtu_probe_h(n, inpkt);
        else
                receive_packet(n, inpkt);
 }
 
-void receive_tcppacket(connection_t *c, char *buffer, int len)
-{
+void receive_tcppacket(connection_t *c, char *buffer, int len) {
        vpn_packet_t outpkt;
 
        cp();
@@ -285,15 +261,14 @@ void receive_tcppacket(connection_t *c, char *buffer, int len)
        receive_packet(c->node, &outpkt);
 }
 
-static void send_udppacket(node_t *n, vpn_packet_t *origpkt)
-{
+static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        vpn_packet_t pkt1, pkt2;
        vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
        vpn_packet_t *inpkt = 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;
@@ -349,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 */
@@ -411,8 +382,7 @@ end:
 /*
   send a packet to the given vpn ip.
 */
-void send_packet(const node_t *n, vpn_packet_t *packet)
-{
+void send_packet(const node_t *n, vpn_packet_t *packet) {
        node_t *via;
 
        cp();
@@ -448,9 +418,8 @@ void send_packet(const node_t *n, vpn_packet_t *packet)
 
 /* Broadcast a packet using the minimum spanning tree */
 
-void broadcast_packet(const node_t *from, vpn_packet_t *packet)
-{
-       avl_node_t *node;
+void broadcast_packet(const node_t *from, vpn_packet_t *packet) {
+       splay_node_t *node;
        connection_t *c;
 
        cp();
@@ -469,8 +438,7 @@ void broadcast_packet(const node_t *from, vpn_packet_t *packet)
        }
 }
 
-void flush_queue(node_t *n)
-{
+void flush_queue(node_t *n) {
        list_node_t *node, *next;
 
        cp();
@@ -484,8 +452,7 @@ void flush_queue(node_t *n)
        }
 }
 
-void handle_incoming_vpn_data(int sock, short events, void *data)
-{
+void handle_incoming_vpn_data(int sock, short events, void *data) {
        vpn_packet_t pkt;
        char *hostname;
        sockaddr_t from;
@@ -516,8 +483,7 @@ void handle_incoming_vpn_data(int sock, short events, void *data)
        receive_udppacket(n, &pkt);
 }
 
-void handle_device_data(int sock, short events, void *data)
-{
+void handle_device_data(int sock, short events, void *data) {
        vpn_packet_t packet;
 
        if(read_packet(&packet))