Use conditional compilation for cryptographic functions.
authorGuus Sliepen <guus@tinc-vpn.org>
Wed, 1 May 2013 15:17:22 +0000 (17:17 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Wed, 1 May 2013 15:17:22 +0000 (17:17 +0200)
This gets rid of the rest of the symbolic links. However, as a consequence, the
crypto header files have now moved to src/, and can no longer contain
library-specific declarations. Therefore, cipher_t, digest_t, ecdh_t, ecdsa_t
and rsa_t are now all opaque types, and only pointers to those types can be
used.

38 files changed:
Makefile.am
configure.ac
src/Makefile.am
src/connection.c
src/connection.h
src/gcrypt/ecdh.c [new file with mode: 0644]
src/gcrypt/ecdsa.c [new file with mode: 0644]
src/gcrypt/ecdsagen.c [new file with mode: 0644]
src/gcrypt/prf.c [new file with mode: 0644]
src/meta.c
src/net_packet.c
src/net_setup.c
src/node.c
src/node.h
src/openssl/cipher.c
src/openssl/cipher.h [deleted file]
src/openssl/crypto.c
src/openssl/crypto.h [deleted file]
src/openssl/digest.c
src/openssl/digest.h
src/openssl/ecdh.c
src/openssl/ecdh.h [deleted file]
src/openssl/ecdsa.c
src/openssl/ecdsa.h [deleted file]
src/openssl/ecdsagen.c
src/openssl/ecdsagen.h [deleted file]
src/openssl/prf.c
src/openssl/prf.h [deleted file]
src/openssl/rsa.c
src/openssl/rsa.h [deleted file]
src/openssl/rsagen.c
src/openssl/rsagen.h [deleted file]
src/protocol_auth.c
src/protocol_key.c
src/sptps.c
src/sptps.h
src/sptps_test.c
src/tincctl.c

index 130cd6ef8f8bc7dc861e3ba403655b9d8b2ae8e3..d2e6f3fa568c424c51810bcf024443e451006b54 100644 (file)
@@ -6,7 +6,7 @@ SUBDIRS =  m4 src doc gui
 
 ACLOCAL_AMFLAGS = -I m4 
 
-EXTRA_DIST = have.h system.h COPYING.README README.android
+EXTRA_DIST = COPYING.README README.android
 
 ChangeLog:
        git log > ChangeLog
index a988154c83cce26e39db9a334f2867c39f97dd3c..5f6bfecdcd266940ee126ed1dbdd00f45b013ef8 100644 (file)
@@ -192,13 +192,15 @@ tinc_ZLIB
 tinc_LZO
 
 if test "$with_libgcrypt" = yes; then
+       gcrypt=true
        AM_PATH_LIBGCRYPT([1.4.0], [], [])
-       ln -sf gcrypt/cipher.c gcrypt/cipher.h gcrypt/crypto.c gcrypt/crypto.h gcrypt/digest.c gcrypt/digest.h gcrypt/ecdh.c gcrypt/ecdh.h gcrypt/ecdsa.c gcrypt/ecdsa.h gcrypt/ecdsagen.c gcrypt/ecdsagen.h gcrypt/prf.c gcrypt/prf.h gcrypt/rsa.c gcrypt/rsa.h gcrypt/rsagen.c gcrypt/rsagen.h src/
 else
+       openssl=true
        tinc_OPENSSL
-       ln -sf openssl/cipher.c openssl/cipher.h openssl/crypto.c openssl/crypto.h openssl/digest.c openssl/digest.h openssl/ecdh.c openssl/ecdh.h openssl/ecdsa.c openssl/ecdsa.h openssl/ecdsagen.c openssl/ecdsagen.h openssl/prf.c openssl/prf.h openssl/rsa.c openssl/rsa.h openssl/rsagen.c openssl/rsagen.h src/
 fi
        
+AM_CONDITIONAL(OPENSSL, test "$openssl" = true)
+AM_CONDITIONAL(GCRYPT, test "$grypt" = true)
 
 dnl Check if support for jumbograms is requested 
 AC_ARG_ENABLE(jumbograms,
index c1f51f102ed8fa6cf6a695fffeb34815878932de..3361e3dd9a20ba138fcde8c3e5eb1739f876a6a2 100644 (file)
@@ -11,6 +11,13 @@ tincd_SOURCES = \
        protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c event.c tincd.c \
        dummy_device.c raw_socket_device.c multicast_device.c names.c
 
+tinc_SOURCES = \
+       utils.c getopt.c getopt1.c dropin.c \
+       info.c list.c subnet_parse.c tincctl.c top.c names.c
+
+sptps_test_SOURCES = \
+       logger.c sptps.c sptps_test.c utils.c
+
 ## Conditionally compile device drivers
        
 if LINUX
@@ -19,6 +26,9 @@ endif
 
 if BSD
 tincd_SOURCES += bsd/device.c
+if TUNEMU
+tincd_SOURCES += bsd/tunemu.c
+endif
 endif
 
 if SOLARIS
@@ -41,22 +51,50 @@ if VDE
 tincd_SOURCES += vde_device.c
 endif
 
-nodist_tincd_SOURCES = \
-       cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c rsa.c
-
-tinc_SOURCES = \
-       utils.c getopt.c getopt1.c dropin.c \
-       info.c list.c subnet_parse.c tincctl.c top.c names.c
-
-nodist_tinc_SOURCES = \
-       ecdsagen.c rsagen.c
-
-sptps_test_SOURCES = \
-       logger.c cipher.c crypto.c ecdh.c ecdsa.c digest.c prf.c \
-       sptps.c sptps_test.c utils.c
+if OPENSSL
+tincd_SOURCES += \
+       openssl/cipher.c \
+       openssl/crypto.c \
+       openssl/ecdh.c \
+       openssl/ecdsa.c \
+       openssl/digest.c \
+       openssl/prf.c \
+       openssl/rsa.c
+tinc_SOURCES += \
+       openssl/ecdsa.c \
+       openssl/ecdsagen.c \
+       openssl/rsa.c \
+       openssl/rsagen.c
+sptps_test_SOURCES += \
+       openssl/cipher.c \
+       openssl/crypto.c \
+       openssl/ecdh.c \
+       openssl/ecdsa.c \
+       openssl/digest.c \
+       openssl/prf.c
+endif
 
-if TUNEMU
-tincd_SOURCES += bsd/tunemu.c
+if GCRYPT
+tincd_SOURCES += \
+       gcrypt/cipher.c \
+       gcrypt/crypto.c \
+       gcrypt/ecdh.c \
+       gcrypt/ecdsa.c \
+       gcrypt/digest.c \
+       gcrypt/prf.c \
+       gcrypt/rsa.c
+tinc_SOURCES += \
+       gcrypt/ecdsa.c \
+       gcrypt/ecdsagen.c \
+       gcrypt/rsa.c \
+       gcrypt/rsagen.c
+sptps_test_SOURCES += \
+       gcrypt/cipher.c \
+       gcrypt/crypto.c \
+       gcrypt/ecdh.c \
+       gcrypt/ecdsa.c \
+       gcrypt/digest.c \
+       gcrypt/prf.c
 endif
 
 tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS)
@@ -68,10 +106,7 @@ INCLUDES = @INCLUDES@
 noinst_HEADERS = \
        xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
        buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \
-       protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h names.h
-
-nodist_noinst_HEADERS = \
-       cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h
+       protocol.h route.h subnet.h sptps.h tincctl.h top.h hash.h event.h names.h have.h system.h
 
 LIBS = @LIBS@ @LIBGCRYPT_LIBS@
 
index 4798c5a4867b3b5f1a6294d91662f72652f1bc63..9c459787eabbb5bc94a200a2dc01e3effbc1be58 100644 (file)
@@ -1,6 +1,6 @@
 /*
     connection.c -- connection list management
-    Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
                   2000-2005 Ivo Timmermans
                   2008      Max Rijevski <maksuf@gmail.com>
 
@@ -27,6 +27,7 @@
 #include "control_common.h"
 #include "list.h"
 #include "logger.h"
+#include "rsa.h"
 #include "subnet.h"
 #include "utils.h"
 #include "xalloc.h"
@@ -54,14 +55,14 @@ void free_connection(connection_t *c) {
        if(!c)
                return;
 
-       cipher_close(&c->incipher);
-       digest_close(&c->indigest);
-       cipher_close(&c->outcipher);
-       digest_close(&c->outdigest);
+       cipher_close(c->incipher);
+       digest_close(c->indigest);
+       cipher_close(c->outcipher);
+       digest_close(c->outdigest);
 
        sptps_stop(&c->sptps);
-       ecdsa_free(&c->ecdsa);
-       rsa_free(&c->rsa);
+       ecdsa_free(c->ecdsa);
+       rsa_free(c->rsa);
 
        free(c->hischallenge);
 
index 10f4a76a924ee9dd8064e477fbf92d0f3703fa43..5b6a94c46c39ba8ebb4c34b1098df01970ae6a6c 100644 (file)
@@ -1,6 +1,6 @@
 /*
     connection.h -- header for connection.c
-    Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
                   2000-2005 Ivo Timmermans
 
     This program is free software; you can redistribute it and/or modify
@@ -73,12 +73,12 @@ typedef struct connection_t {
        struct node_t *node;            /* node associated with the other end */
        struct edge_t *edge;            /* edge associated with this connection */
 
-       rsa_t rsa;                      /* his public RSA key */
-       ecdsa_t ecdsa;                  /* his public ECDSA 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;
+       rsa_t *rsa;                     /* his public RSA key */
+       ecdsa_t *ecdsa;                 /* his public ECDSA 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;
        sptps_t sptps;
 
        int inmaclength;
diff --git a/src/gcrypt/ecdh.c b/src/gcrypt/ecdh.c
new file mode 100644 (file)
index 0000000..4e30733
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+    ecdh.c -- Diffie-Hellman key exchange handling
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "../system.h"
+
+#include "../ecdh.h"
+#include "../logger.h"
+#include "../utils.h"
+#include "../xalloc.h"
+
+ecdh_t *ecdh_generate_public(void *pubkey) {
+       logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
+       return NULL;
+}
+
+bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) {
+       return false
+}
+
+void ecdh_free(ecdh_t *ecdh) {
+}
diff --git a/src/gcrypt/ecdsa.c b/src/gcrypt/ecdsa.c
new file mode 100644 (file)
index 0000000..ee19aec
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+    ecdsa.c -- ECDSA key handling
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "../system.h"
+
+#include "../logger.h"
+#include "../ecdsa.h"
+#include "../utils.h"
+#include "../xalloc.h"
+
+// Get and set ECDSA keys
+//
+ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
+       logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
+       return NULL;
+}
+
+char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
+       return NULL;
+}
+
+// Read PEM ECDSA keys
+
+ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
+       logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
+       return NULL;
+}
+
+ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
+       logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
+       return NULL;
+}
+
+size_t ecdsa_size(ecdsa_t *ecdsa) {
+       return 0;
+}
+
+bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) {
+       return false;
+}
+
+bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) {
+       return false;
+}
+
+bool ecdsa_active(ecdsa_t *ecdsa) {
+       return false;
+}
+
+void ecdsa_free(ecdsa_t *ecdsa) {
+}
diff --git a/src/gcrypt/ecdsagen.c b/src/gcrypt/ecdsagen.c
new file mode 100644 (file)
index 0000000..2d4912d
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+    ecdsagen.c -- ECDSA key generation and export
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "../system.h"
+
+#include "../ecdsagen.h"
+#include "../utils.h"
+#include "../xalloc.h"
+
+// Generate ECDSA key
+
+ecdsa_t *ecdsa_generate(void) {
+       logger(DEBUG_ALWAYS, LOG_ERR, "EC support using libgcrypt not implemented");
+       return NULL;
+}
+
+// Write PEM ECDSA keys
+
+bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) {
+       return false;
+}
+
+bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) {
+       return false;
+}
diff --git a/src/gcrypt/prf.c b/src/gcrypt/prf.c
new file mode 100644 (file)
index 0000000..f9a2112
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+    prf.c -- Pseudo-Random Function for key material generation
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "../system.h"
+
+#include "digest.h"
+#include "../digest.h"
+#include "../prf.h"
+
+bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) {
+       logger(DEBUG_ALWAYS, LOG_ERR, "PRF support using libgcrypt not implemented");
+       return false;
+}
index fafba653c4d014f237585d7b704e4e56f642121c..887da4a85ae9532d7e89ce9848f93f5356a49a36 100644 (file)
@@ -1,6 +1,6 @@
 /*
     meta.c -- handle the meta communication
-    Copyright (C) 2000-2012 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2000-2013 Guus Sliepen <guus@tinc-vpn.org>,
                   2000-2005 Ivo Timmermans
                   2006      Scott Lamb <slamb@slamb.org>
 
@@ -60,7 +60,7 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
        if(c->status.encryptout) {
                size_t outlen = length;
 
-               if(!cipher_encrypt(&c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) {
+               if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) {
                        logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting metadata to %s (%s)",
                                        c->name, c->hostname);
                        return false;
@@ -171,7 +171,7 @@ bool receive_meta(connection_t *c) {
                } else {
                        size_t outlen = inlen;
 
-                       if(!cipher_decrypt(&c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) {
+                       if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) {
                                logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting metadata from %s (%s)",
                                           c->name, c->hostname);
                                return false;
index 27ca71480e247c39d0bc5d31c45a4d2819ac9ba5..c2552619857c89f7f53df2a7d7c6a82f27ff6dea 100644 (file)
@@ -318,10 +318,10 @@ static bool try_mac(node_t *n, const vpn_packet_t *inpkt) {
        if(n->status.sptps)
                return sptps_verify_datagram(&n->sptps, (char *)&inpkt->seqno, inpkt->len);
 
-       if(!digest_active(&n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest))
+       if(!digest_active(n->indigest) || inpkt->len < sizeof inpkt->seqno + digest_length(n->indigest))
                return false;
 
-       return digest_verify(&n->indigest, &inpkt->seqno, inpkt->len - n->indigest.maclength, (const char *)&inpkt->seqno + inpkt->len - n->indigest.maclength);
+       return digest_verify(n->indigest, &inpkt->seqno, inpkt->len - digest_length(n->indigest), (const char *)&inpkt->seqno + inpkt->len - digest_length(n->indigest));
 }
 
 static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
@@ -336,7 +336,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
                return;
        }
 
-       if(!cipher_active(&n->incipher)) {
+       if(!cipher_active(n->incipher)) {
                logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet",
                                        n->name, n->hostname);
                return;
@@ -344,7 +344,7 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
 
        /* Check packet length */
 
-       if(inpkt->len < sizeof inpkt->seqno + digest_length(&n->indigest)) {
+       if(inpkt->len < sizeof inpkt->seqno + digest_length(n->indigest)) {
                logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got too short packet from %s (%s)",
                                        n->name, n->hostname);
                return;
@@ -352,20 +352,20 @@ static void receive_udppacket(node_t *n, vpn_packet_t *inpkt) {
 
        /* Check the message authentication code */
 
-       if(digest_active(&n->indigest)) {
-               inpkt->len -= n->indigest.maclength;
-               if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) {
+       if(digest_active(n->indigest)) {
+               inpkt->len -= digest_length(n->indigest);
+               if(!digest_verify(n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) {
                        logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname);
                        return;
                }
        }
        /* Decrypt the packet */
 
-       if(cipher_active(&n->incipher)) {
+       if(cipher_active(n->incipher)) {
                outpkt = pkt[nextpkt++];
                outlen = MAXSIZE;
 
-               if(!cipher_decrypt(&n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
+               if(!cipher_decrypt(n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
                        logger(DEBUG_TRAFFIC, LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname);
                        return;
                }
@@ -653,11 +653,11 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
 
        /* Encrypt the packet */
 
-       if(cipher_active(&n->outcipher)) {
+       if(cipher_active(n->outcipher)) {
                outpkt = pkt[nextpkt++];
                outlen = MAXSIZE;
 
-               if(!cipher_encrypt(&n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
+               if(!cipher_encrypt(n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
                        logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname);
                        goto end;
                }
@@ -668,9 +668,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
 
        /* Add the message authentication code */
 
-       if(digest_active(&n->outdigest)) {
-               digest_create(&n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len);
-               inpkt->len += digest_length(&n->outdigest);
+       if(digest_active(n->outdigest)) {
+               digest_create(n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len);
+               inpkt->len += digest_length(n->outdigest);
        }
 
        /* Send the packet */
index bf0c5a5086eda8931d0a9f9aa1c23978307835f6..a9947aad1a9eca0205afc82b4b910db0657eb457 100644 (file)
@@ -58,14 +58,13 @@ char *scriptinterpreter;
 char *scriptextension;
 
 bool node_read_ecdsa_public_key(node_t *n) {
-       if(ecdsa_active(&n->ecdsa))
+       if(ecdsa_active(n->ecdsa))
                return true;
 
        splay_tree_t *config_tree;
        FILE *fp;
        char *pubname = NULL, *hcfname = NULL;
        char *p;
-       bool result = false;
 
        xasprintf(&hcfname, "%s" SLASH "hosts" SLASH "%s", confbase, n->name);
 
@@ -76,7 +75,7 @@ bool node_read_ecdsa_public_key(node_t *n) {
        /* First, check for simple ECDSAPublicKey statement */
 
        if(get_config_string(lookup_config(config_tree, "ECDSAPublicKey"), &p)) {
-               result = ecdsa_set_base64_public_key(&n->ecdsa, p);
+               n->ecdsa = ecdsa_set_base64_public_key(p);
                free(p);
                goto exit;
        }
@@ -93,28 +92,30 @@ bool node_read_ecdsa_public_key(node_t *n) {
                goto exit;
        }
 
-       result = ecdsa_read_pem_public_key(&n->ecdsa, fp);
+       n->ecdsa = ecdsa_read_pem_public_key(fp);
        fclose(fp);
 
 exit:
        exit_configuration(&config_tree);
        free(hcfname);
        free(pubname);
-       return result;
+       return n->ecdsa;
 }
 
 bool read_ecdsa_public_key(connection_t *c) {
+       if(ecdsa_active(c->ecdsa))
+               return true;
+
        FILE *fp;
        char *fname;
        char *p;
-       bool result;
 
        /* First, check for simple ECDSAPublicKey statement */
 
        if(get_config_string(lookup_config(c->config_tree, "ECDSAPublicKey"), &p)) {
-               result = ecdsa_set_base64_public_key(&c->ecdsa, p);
+               c->ecdsa = ecdsa_set_base64_public_key(p);
                free(p);
-               return result;
+               return c->ecdsa;
        }
 
        /* Else, check for ECDSAPublicKeyFile statement and read it */
@@ -131,27 +132,29 @@ bool read_ecdsa_public_key(connection_t *c) {
                return false;
        }
 
-       result = ecdsa_read_pem_public_key(&c->ecdsa, fp);
+       c->ecdsa = ecdsa_read_pem_public_key(fp);
        fclose(fp);
 
-       if(!result)
+       if(!c->ecdsa)
                logger(DEBUG_ALWAYS, LOG_ERR, "Parsing ECDSA public key file `%s' failed.", fname);
        free(fname);
-       return result;
+       return c->ecdsa;
 }
 
 bool read_rsa_public_key(connection_t *c) {
+       if(ecdsa_active(c->ecdsa))
+               return true;
+
        FILE *fp;
        char *fname;
        char *n;
-       bool result;
 
        /* First, check for simple PublicKey statement */
 
        if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &n)) {
-               result = rsa_set_hex_public_key(&c->rsa, n, "FFFF");
+               c->rsa = rsa_set_hex_public_key(n, "FFFF");
                free(n);
-               return result;
+               return c->rsa;
        }
 
        /* Else, check for PublicKeyFile statement and read it */
@@ -167,19 +170,18 @@ bool read_rsa_public_key(connection_t *c) {
                return false;
        }
 
-       result = rsa_read_pem_public_key(&c->rsa, fp);
+       c->rsa = rsa_read_pem_public_key(fp);
        fclose(fp);
 
-       if(!result)
+       if(!c->rsa)
                logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno));
        free(fname);
-       return result;
+       return c->rsa;
 }
 
 static bool read_ecdsa_private_key(void) {
        FILE *fp;
        char *fname;
-       bool result;
 
        /* Check for PrivateKeyFile statement and read it */
 
@@ -207,20 +209,19 @@ static bool read_ecdsa_private_key(void) {
                logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname);
 #endif
 
-       result = ecdsa_read_pem_private_key(&myself->connection->ecdsa, fp);
+       myself->connection->ecdsa = ecdsa_read_pem_private_key(fp);
        fclose(fp);
 
-       if(!result)
+       if(!myself->connection->ecdsa)
                logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno));
        free(fname);
-       return result;
+       return myself->connection->ecdsa;
 }
 
 static bool read_rsa_private_key(void) {
        FILE *fp;
        char *fname;
        char *n, *d;
-       bool result;
 
        /* First, check for simple PrivateKey statement */
 
@@ -230,10 +231,10 @@ static bool read_rsa_private_key(void) {
                        free(d);
                        return false;
                }
-               result = rsa_set_hex_private_key(&myself->connection->rsa, n, "FFFF", d);
+               myself->connection->rsa = rsa_set_hex_private_key(n, "FFFF", d);
                free(n);
                free(d);
-               return result;
+               return myself->connection->rsa;
        }
 
        /* Else, check for PrivateKeyFile statement and read it */
@@ -263,13 +264,13 @@ static bool read_rsa_private_key(void) {
                logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname);
 #endif
 
-       result = rsa_read_pem_private_key(&myself->connection->rsa, fp);
+       myself->connection->rsa = rsa_read_pem_private_key(fp);
        fclose(fp);
 
-       if(!result)
+       if(!myself->connection->rsa)
                logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno));
        free(fname);
-       return result;
+       return myself->connection->rsa;
 }
 
 static timeout_t keyexpire_timeout;
@@ -707,7 +708,7 @@ static bool setup_myself(void) {
        if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher))
                cipher = xstrdup("blowfish");
 
-       if(!cipher_open_by_name(&myself->incipher, cipher)) {
+       if(!(myself->incipher = cipher_open_by_name(cipher))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized cipher type!");
                return false;
        }
@@ -730,7 +731,7 @@ static bool setup_myself(void) {
        if(!get_config_string(lookup_config(config_tree, "Digest"), &digest))
                digest = xstrdup("sha1");
 
-       if(!digest_open_by_name(&myself->indigest, digest, maclength)) {
+       if(!(myself->indigest = digest_open_by_name(digest, maclength))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unrecognized digest type!");
                return false;
        }
index 465a48a8c0f7db6abce86880f530ebc4deffaf15..2f517446f717fd40b928e5df6d23b5a7e877355d 100644 (file)
@@ -1,6 +1,6 @@
 /*
     node.c -- node tree management
-    Copyright (C) 2001-2012 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2001-2013 Guus Sliepen <guus@tinc-vpn.org>,
                   2001-2005 Ivo Timmermans
 
     This program is free software; you can redistribute it and/or modify
@@ -70,12 +70,12 @@ void free_node(node_t *n) {
 
        sockaddrfree(&n->address);
 
-       cipher_close(&n->incipher);
-       digest_close(&n->indigest);
-       cipher_close(&n->outcipher);
-       digest_close(&n->outdigest);
+       cipher_close(n->incipher);
+       digest_close(n->indigest);
+       cipher_close(n->outcipher);
+       digest_close(n->outdigest);
 
-       ecdsa_free(&n->ecdsa);
+       ecdsa_free(n->ecdsa);
        sptps_stop(&n->sptps);
 
        timeout_del(&n->mtutimeout);
@@ -145,8 +145,8 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
 bool dump_nodes(connection_t *c) {
        for splay_each(node_t, n, node_tree)
                send_request(c, "%d %d %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES,
-                          n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(&n->outcipher),
-                          digest_get_nid(&n->outdigest), (int)digest_length(&n->outdigest), n->outcompression,
+                          n->name, n->hostname ?: "unknown port unknown", cipher_get_nid(n->outcipher),
+                          digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), n->outcompression,
                           n->options, bitfield_to_int(&n->status, sizeof n->status), n->nexthop ? n->nexthop->name : "-",
                           n->via ? n->via->name ?: "-" : "-", n->distance, n->mtu, n->minmtu, n->maxmtu, (long)n->last_state_change);
 
index e4b47b3872173fa4ea1dd01b21c476600ed66a2f..e704ba82f56e10ed5fe412ffdcbaf6baa7f13d62 100644 (file)
@@ -52,14 +52,14 @@ typedef struct node_t {
        time_t last_state_change;
        time_t last_req_key;
 
-       ecdsa_t ecdsa;                          /* His public ECDSA key */
+       ecdsa_t *ecdsa;                         /* His public ECDSA key */
        sptps_t sptps;
 
-       cipher_t incipher;                      /* Cipher for UDP packets */
-       digest_t indigest;                      /* Digest for UDP packets */
+       cipher_t *incipher;                     /* Cipher for UDP packets */
+       digest_t *indigest;                     /* Digest for UDP packets */
 
-       cipher_t outcipher;                     /* Cipher for UDP packets */
-       digest_t outdigest;                     /* Digest for UDP packets */
+       cipher_t *outcipher;                    /* Cipher for UDP packets */
+       digest_t *outdigest;                    /* Digest for UDP packets */
 
        int incompression;                      /* Compressionlevel, 0 = no compression */
        int outcompression;                     /* Compressionlevel, 0 = no compression */
index 553b4adb4e2a6fc823ab51753283806a6336e01d..32cb5ce2d138a491f0dfeae8fadfe4571da09ff8 100644 (file)
@@ -1,6 +1,6 @@
 /*
     cipher.c -- Symmetric block cipher handling
-    Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/rand.h>
 #include <openssl/err.h>
+#include <openssl/evp.h>
 
-#include "cipher.h"
-#include "logger.h"
-#include "xalloc.h"
+#include "../cipher.h"
+#include "../logger.h"
+#include "../xalloc.h"
+
+struct cipher {
+       EVP_CIPHER_CTX ctx;
+       const EVP_CIPHER *cipher;
+       struct cipher_counter *counter;
+};
 
 typedef struct cipher_counter {
-       unsigned char counter[EVP_MAX_IV_LENGTH];
-       unsigned char block[EVP_MAX_IV_LENGTH];
+       unsigned char counter[CIPHER_MAX_IV_SIZE];
+       unsigned char block[CIPHER_MAX_IV_SIZE];
        int n;
 } cipher_counter_t;
 
-static bool cipher_open(cipher_t *cipher) {
+static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) {
+       cipher_t *cipher = xmalloc_and_zero(sizeof *cipher);
+       cipher->cipher = evp_cipher;
        EVP_CIPHER_CTX_init(&cipher->ctx);
 
-       return true;
+       return cipher;
 }
 
-bool cipher_open_by_name(cipher_t *cipher, const char *name) {
-       cipher->cipher = EVP_get_cipherbyname(name);
-
-       if(cipher->cipher)
-               return cipher_open(cipher);
+cipher_t *cipher_open_by_name(const char *name) {
+       const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name);
+       if(!evp_cipher) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name);
+               return NULL;
+       }
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name);
-       return false;
+       return cipher_open(evp_cipher);
 }
 
-bool cipher_open_by_nid(cipher_t *cipher, int nid) {
-       cipher->cipher = EVP_get_cipherbynid(nid);
-
-       if(cipher->cipher)
-               return cipher_open(cipher);
+cipher_t *cipher_open_by_nid(int nid) {
+       const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid);
+       if(!evp_cipher) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid);
+               return NULL;
+       }
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid);
-       return false;
+       return cipher_open(evp_cipher);
 }
 
-bool cipher_open_blowfish_ofb(cipher_t *cipher) {
-       cipher->cipher = EVP_bf_ofb();
-       return cipher_open(cipher);
+cipher_t *cipher_open_blowfish_ofb(void) {
+       return cipher_open(EVP_bf_ofb());
 }
 
 void cipher_close(cipher_t *cipher) {
+       if(!cipher)
+               return;
+
        EVP_CIPHER_CTX_cleanup(&cipher->ctx);
        free(cipher->counter);
-       cipher->counter = NULL;
+       free(cipher);
 }
 
 size_t cipher_keylength(const cipher_t *cipher) {
@@ -214,5 +225,5 @@ int cipher_get_nid(const cipher_t *cipher) {
 }
 
 bool cipher_active(const cipher_t *cipher) {
-       return cipher->cipher && cipher->cipher->nid != 0;
+       return cipher && cipher->cipher && cipher->cipher->nid != 0;
 }
diff --git a/src/openssl/cipher.h b/src/openssl/cipher.h
deleted file mode 100644 (file)
index c9f89eb..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-    cipher.h -- header file cipher.c
-    Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_CIPHER_H__
-#define __TINC_CIPHER_H__
-
-#include <openssl/evp.h>
-
-#define CIPHER_MAX_BLOCK_SIZE EVP_MAX_BLOCK_LENGTH
-#define CIPHER_MAX_KEY_SIZE EVP_MAX_KEY_LENGTH
-#define CIPHER_MAX_IV_SIZE EVP_MAX_IV_LENGTH
-
-typedef struct cipher {
-       EVP_CIPHER_CTX ctx;
-       const EVP_CIPHER *cipher;
-       struct cipher_counter *counter;
-} cipher_t;
-
-extern bool cipher_open_by_name(cipher_t *, const char *);
-extern bool cipher_open_by_nid(cipher_t *, int);
-extern bool cipher_open_blowfish_ofb(cipher_t *);
-extern void cipher_close(cipher_t *);
-extern size_t cipher_keylength(const cipher_t *);
-extern bool cipher_set_key(cipher_t *, void *, bool);
-extern bool cipher_set_key_from_rsa(cipher_t *, void *, size_t, bool);
-extern bool cipher_set_counter(cipher_t *, const void *, size_t);
-extern bool cipher_set_counter_key(cipher_t *, void *);
-extern bool cipher_encrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool);
-extern bool cipher_decrypt(cipher_t *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool);
-extern bool cipher_counter_xor(cipher_t *, const void *indata, size_t inlen, void *outdata);
-extern int cipher_get_nid(const cipher_t *);
-extern bool cipher_active(const cipher_t *);
-
-#endif
index c695be8875ca64d2e39f5fa5dfa6cfe6aaa8791f..ece7f059eb9c1a4ea6fdf5ad82f34d56a62eeb82 100644 (file)
@@ -1,6 +1,6 @@
 /*
     crypto.c -- Cryptographic miscellaneous functions and initialisation
-    Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/rand.h>
 #include <openssl/evp.h>
 #include <openssl/engine.h>
 
-#include "crypto.h"
+#include "../crypto.h"
 
 void crypto_init(void) {
        RAND_load_file("/dev/urandom", 1024);
diff --git a/src/openssl/crypto.h b/src/openssl/crypto.h
deleted file mode 100644 (file)
index 8047bfb..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-    crypto.h -- header for crypto.c
-    Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_CRYPTO_H__
-#define __TINC_CRYPTO_H__
-
-extern void crypto_init();
-extern void crypto_exit();
-extern void randomize(void *, size_t);
-
-#endif
index 79db491d67fd1bcc4838494f56f84f247dbb6025..9406701b8c3b5a7f224ad149ba5fcf4819db92b7 100644 (file)
@@ -1,6 +1,6 @@
 /*
     digest.c -- Digest handling
-    Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
-#include "utils.h"
-#include "xalloc.h"
+#include "../system.h"
+#include "../utils.h"
+#include "../xalloc.h"
 
 #include <openssl/err.h>
 #include <openssl/hmac.h>
 
 #include "digest.h"
-#include "logger.h"
+#include "../digest.h"
+#include "../logger.h"
+
+static digest_t *digest_open(const EVP_MD *evp_md, int maclength) {
+       digest_t *digest = xmalloc_and_zero(sizeof *digest);
+       digest->digest = evp_md;
 
-static void set_maclength(digest_t *digest, int maclength) {
        int digestlen = EVP_MD_size(digest->digest);
 
        if(maclength > digestlen || maclength < 0)
                digest->maclength = digestlen;
        else
                digest->maclength = maclength;
+
+       return digest;
 }
 
-bool digest_open_by_name(digest_t *digest, const char *name, int maclength) {
-       digest->digest = EVP_get_digestbyname(name);
-       digest->key = NULL;
+digest_t *digest_open_by_name(const char *name, int maclength) {
+       const EVP_MD *evp_md = EVP_get_digestbyname(name);
 
-       if(!digest->digest) {
+       if(!evp_md) {
                logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name);
                return false;
        }
 
-       set_maclength(digest, maclength);
-       return true;
+       return digest_open(evp_md, maclength);
 }
 
-bool digest_open_by_nid(digest_t *digest, int nid, int maclength) {
-       digest->digest = EVP_get_digestbynid(nid);
-       digest->key = NULL;
+digest_t *digest_open_by_nid(int nid, int maclength) {
+       const EVP_MD *evp_md = EVP_get_digestbynid(nid);
 
-       if(!digest->digest) {
+       if(!evp_md) {
                logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid);
                return false;
        }
 
-       set_maclength(digest, maclength);
-       return true;
+       return digest_open(evp_md, maclength);
 }
 
-bool digest_open_sha1(digest_t *digest, int maclength) {
-       digest->digest = EVP_sha1();
-       digest->key = NULL;
-
-       set_maclength(digest, maclength);
-       return true;
+digest_t *digest_open_sha1(int maclength) {
+       return digest_open(EVP_sha1(), maclength);
 }
 
 bool digest_set_key(digest_t *digest, const void *key, size_t len) {
@@ -78,8 +76,11 @@ bool digest_set_key(digest_t *digest, const void *key, size_t len) {
 }
 
 void digest_close(digest_t *digest) {
+       if(!digest)
+               return;
+
        free(digest->key);
-       digest->key = NULL;
+       free(digest);
 }
 
 bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) {
@@ -123,5 +124,5 @@ size_t digest_length(const digest_t *digest) {
 }
 
 bool digest_active(const digest_t *digest) {
-       return digest->digest && digest->digest->type != 0;
+       return digest && digest->digest && digest->digest->type != 0;
 }
index c1922492a0ab3527f82bb9a9a5850a35263fb0c1..542c63cbaa6e93c8b84f999e67b18631020dee69 100644 (file)
@@ -1,6 +1,6 @@
 /*
     digest.h -- header file digest.c
-    Copyright (C) 2007-2011 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#ifndef __TINC_DIGEST_H__
-#define __TINC_DIGEST_H__
+#ifndef __TINC_OPENSSL_DIGEST_H__
+#define __TINC_OPENSSL_DIGEST_H__
 
 #include <openssl/evp.h>
 
-#define DIGEST_MAX_SIZE EVP_MAX_MD_SIZE
-
 typedef struct digest {
        const EVP_MD *digest;
        int maclength;
@@ -31,16 +29,4 @@ typedef struct digest {
        char *key;
 } digest_t;
 
-extern bool digest_open_by_name(struct digest *, const char *name, int maclength);
-extern bool digest_open_by_nid(struct digest *, int nid, int maclength);
-extern bool digest_open_sha1(struct digest *, int maclength);
-extern void digest_close(struct digest *);
-extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata);
-extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata);
-extern bool digest_set_key(struct digest *, const void *key, size_t len);
-extern int digest_get_nid(const struct digest *);
-extern size_t digest_keylength(const struct digest *);
-extern size_t digest_length(const struct digest *);
-extern bool digest_active(const struct digest *);
-
 #endif
index f94555dbd7cdb6cf5c43229ca591dca644da96a4..d997007f0c6d65634805751a934e1bfa55b1decf 100644 (file)
@@ -1,6 +1,6 @@
 /*
     ecdh.c -- Diffie-Hellman key exchange handling
-    Copyright (C) 2011-2012 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
-#include "utils.h"
-#include "xalloc.h"
+#include "../system.h"
 
 #include <openssl/err.h>
 #include <openssl/ec.h>
+#include <openssl/ecdh.h>
 #include <openssl/obj_mac.h>
 
-#include "ecdh.h"
-#include "logger.h"
+#define __TINC_ECDH_INTERNAL__
+typedef EC_KEY ecdh_t;
 
-bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey) {
-       *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
-       if(!*ecdh) {
+#include "../ecdh.h"
+#include "../logger.h"
+#include "../utils.h"
+#include "../xalloc.h"
+
+ecdh_t *ecdh_generate_public(void *pubkey) {
+       ecdh_t *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1);
+       if(!ecdh) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL));
                return false;
        }
 
-       if(!EC_KEY_generate_key(*ecdh)) {
-               EC_KEY_free(*ecdh);
-               *ecdh = NULL;
+       if(!EC_KEY_generate_key(ecdh)) {
+               EC_KEY_free(ecdh);
                logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL));
-               return false;
+               return NULL;
        }
 
-       const EC_POINT *point = EC_KEY_get0_public_key(*ecdh);
+       const EC_POINT *point = EC_KEY_get0_public_key(ecdh);
        if(!point) {
-               EC_KEY_free(*ecdh);
-               *ecdh = NULL;
+               EC_KEY_free(ecdh);
                logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL));
-               return false;
+               return NULL;
        }
 
-       size_t result = EC_POINT_point2oct(EC_KEY_get0_group(*ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL);
+       size_t result = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL);
        if(!result) {
-               EC_KEY_free(*ecdh);
-               *ecdh = NULL;
+               EC_KEY_free(ecdh);
                logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL));
-               return false;
+               return NULL;
        }
 
-       return true;
+       return ecdh;
 }
 
 bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) {
-       EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(*ecdh));
+       EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(ecdh));
        if(!point) {
                logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL));
+               EC_KEY_free(ecdh);
                return false;
        }
 
-       int result = EC_POINT_oct2point(EC_KEY_get0_group(*ecdh), point, pubkey, ECDH_SIZE, NULL);
+       int result = EC_POINT_oct2point(EC_KEY_get0_group(ecdh), point, pubkey, ECDH_SIZE, NULL);
        if(!result) {
                EC_POINT_free(point);
+               EC_KEY_free(ecdh);
                logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL));
                return false;
        }
 
-       result = ECDH_compute_key(shared, ECDH_SIZE, point, *ecdh, NULL);
+       result = ECDH_compute_key(shared, ECDH_SIZE, point, ecdh, NULL);
        EC_POINT_free(point);
-       EC_KEY_free(*ecdh);
-       *ecdh = NULL;
+       EC_KEY_free(ecdh);
 
        if(!result) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL));
@@ -89,8 +91,6 @@ bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) {
 }
 
 void ecdh_free(ecdh_t *ecdh) {
-       if(*ecdh) {
-               EC_KEY_free(*ecdh);
-               *ecdh = NULL;
-       }
+       if(ecdh)
+               EC_KEY_free(ecdh);
 }
diff --git a/src/openssl/ecdh.h b/src/openssl/ecdh.h
deleted file mode 100644 (file)
index ef7de6e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-    ecdh.h -- header file for ecdh.c
-    Copyright (C) 2011 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_ECDH_H__
-#define __TINC_ECDH_H__
-
-#include <openssl/ecdh.h>
-
-#define ECDH_SIZE 67
-#define ECDH_SHARED_SIZE 66
-
-typedef EC_KEY *ecdh_t;
-
-extern bool ecdh_generate_public(ecdh_t *ecdh, void *pubkey);
-extern bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared);
-extern void ecdh_free(ecdh_t *ecdh);
-
-#endif
index e2af6f9cddbdc581256a630bcd937be298452fbf..bca89fc5623719e77d69b93a77206124be84dfcb 100644 (file)
@@ -1,6 +1,6 @@
 /*
     ecdsa.c -- ECDSA key handling
-    Copyright (C) 2011-2012 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
-#include "logger.h"
-#include "ecdsa.h"
-#include "utils.h"
+#define __TINC_ECDSA_INTERNAL__
+typedef EC_KEY ecdsa_t;
+
+#include "../logger.h"
+#include "../ecdsa.h"
+#include "../utils.h"
+#include "../xalloc.h"
 
 // Get and set ECDSA keys
 //
-bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) {
-       *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1);
-       if(!*ecdsa) {
+ecdsa_t *ecdsa_set_base64_public_key(const char *p) {
+       ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1);
+       if(!ecdsa) {
                logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL));
-               return false;
+               return NULL;
        }
 
        int len = strlen(p);
@@ -40,19 +44,20 @@ bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p) {
        const unsigned char *ppubkey = pubkey;
        len = b64decode(p, (char *)pubkey, len);
 
-       if(!o2i_ECPublicKey(ecdsa, &ppubkey, len)) {
+       if(!o2i_ECPublicKey(&ecdsa, &ppubkey, len)) {
                logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL));
-               return false;
+               EC_KEY_free(ecdsa);
+               return NULL;
        }
 
-       return true;
+       return ecdsa;
 }
 
 char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
        unsigned char *pubkey = NULL;
-       int len = i2o_ECPublicKey(*ecdsa, &pubkey);
+       int len = i2o_ECPublicKey(ecdsa, &pubkey);
 
-       char *base64 = malloc(len * 4 / 3 + 5);
+       char *base64 = xmalloc(len * 4 / 3 + 5);
        b64encode((char *)pubkey, base64, len);
 
        free(pubkey);
@@ -62,41 +67,39 @@ char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
 
 // Read PEM ECDSA keys
 
-bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp) {
-       *ecdsa = PEM_read_EC_PUBKEY(fp, ecdsa, NULL, NULL);
+ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) {
+       ecdsa_t *ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL);
 
-       if(*ecdsa)
-               return true;
+       if(!ecdsa)
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL));
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL));
-       return false;
+       return ecdsa;
 }
 
-bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp) {
-       *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL);
+ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) {
+       ecdsa_t *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL);
 
-       if(*ecdsa)
-               return true;
+       if(!ecdsa)
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
-       return false;
+       return ecdsa;
 }
 
 size_t ecdsa_size(ecdsa_t *ecdsa) {
-       return ECDSA_size(*ecdsa);
+       return ECDSA_size(ecdsa);
 }
 
 // TODO: standardise output format?
 
 bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) {
-       unsigned int siglen = ECDSA_size(*ecdsa);
+       unsigned int siglen = ECDSA_size(ecdsa);
 
        unsigned char hash[SHA512_DIGEST_LENGTH];
        SHA512(in, len, hash);
 
        memset(sig, 0, siglen);
 
-       if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, *ecdsa)) {
+       if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, ecdsa)) {
                logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL));
                return false;
        }
@@ -105,12 +108,12 @@ bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) {
 }
 
 bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) {
-       unsigned int siglen = ECDSA_size(*ecdsa);
+       unsigned int siglen = ECDSA_size(ecdsa);
 
        unsigned char hash[SHA512_DIGEST_LENGTH];
        SHA512(in, len, hash);
 
-       if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, *ecdsa)) {
+       if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, ecdsa)) {
                logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL));
                return false;
        }
@@ -119,12 +122,10 @@ bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) {
 }
 
 bool ecdsa_active(ecdsa_t *ecdsa) {
-       return *ecdsa;
+       return ecdsa;
 }
 
 void ecdsa_free(ecdsa_t *ecdsa) {
-       if(*ecdsa) {
-               EC_KEY_free(*ecdsa);
-               *ecdsa = NULL;
-       }
+       if(ecdsa)
+               EC_KEY_free(ecdsa);
 }
diff --git a/src/openssl/ecdsa.h b/src/openssl/ecdsa.h
deleted file mode 100644 (file)
index 04f9eb9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-    ecdsa.h -- ECDSA key handling
-    Copyright (C) 2011 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_ECDSA_H__
-#define __TINC_ECDSA_H__
-
-#include <openssl/ec.h>
-
-typedef EC_KEY *ecdsa_t;
-
-extern bool ecdsa_set_base64_public_key(ecdsa_t *ecdsa, const char *p);
-extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa);
-extern bool ecdsa_read_pem_public_key(ecdsa_t *ecdsa, FILE *fp);
-extern bool ecdsa_read_pem_private_key(ecdsa_t *ecdsa, FILE *fp);
-extern size_t ecdsa_size(ecdsa_t *ecdsa);
-extern bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t inlen, void *out);
-extern bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t inlen, const void *out);
-extern bool ecdsa_active(ecdsa_t *ecdsa);
-extern void ecdsa_free(ecdsa_t *ecdsa);
-
-#endif
index 883c77e719fd1476a668f6fa945b2d82628018f4..35795f39bba632b3d6aa6f727f1637e367d0153a 100644 (file)
@@ -1,6 +1,6 @@
 /*
     ecdsagen.c -- ECDSA key generation and export
-    Copyright (C) 2011 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/obj_mac.h>
 
-#include "ecdsagen.h"
-#include "utils.h"
+#define __TINC_ECDSA_INTERNAL__
+typedef EC_KEY ecdsa_t;
+
+#include "../ecdsagen.h"
+#include "../utils.h"
+#include "../xalloc.h"
 
 // Generate ECDSA key
 
-bool ecdsa_generate(ecdsa_t *ecdsa) {
-       *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1);
+ecdsa_t *ecdsa_generate(void) {
+       ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1);
 
-       if(!EC_KEY_generate_key(*ecdsa)) {
+       if(!ecdsa || !EC_KEY_generate_key(ecdsa)) {
                fprintf(stderr, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL));
+               ecdsa_free(ecdsa);
                return false;
        }
 
-       EC_KEY_set_asn1_flag(*ecdsa, OPENSSL_EC_NAMED_CURVE);
-       EC_KEY_set_conv_form(*ecdsa, POINT_CONVERSION_COMPRESSED);
+       EC_KEY_set_asn1_flag(ecdsa, OPENSSL_EC_NAMED_CURVE);
+       EC_KEY_set_conv_form(ecdsa, POINT_CONVERSION_COMPRESSED);
 
-       return true;
+       return ecdsa;
 }
 
 // Write PEM ECDSA keys
 
 bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) {
        BIO *out = BIO_new(BIO_s_file());
-       BIO_set_fp(out,fp,BIO_NOCLOSE);
-       PEM_write_bio_EC_PUBKEY(out, *ecdsa);
+       BIO_set_fp(out, fp, BIO_NOCLOSE);
+       PEM_write_bio_EC_PUBKEY(out, ecdsa);
        BIO_free(out);
        return true;
 }
 
 bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) {
        BIO *out = BIO_new(BIO_s_file());
-       BIO_set_fp(out,fp,BIO_NOCLOSE);
-       PEM_write_bio_ECPrivateKey(out, *ecdsa, NULL, NULL, 0, NULL, NULL);
+       BIO_set_fp(out, fp, BIO_NOCLOSE);
+       PEM_write_bio_ECPrivateKey(out, ecdsa, NULL, NULL, 0, NULL, NULL);
        BIO_free(out);
        return true;
 }
-
-// Convert ECDSA public key to base64 format
-
-char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) {
-       unsigned char *pubkey = NULL;
-       int len = i2o_ECPublicKey(*ecdsa, &pubkey);
-
-       char *base64 = malloc(len * 4 / 3 + 5);
-       b64encode((char *)pubkey, base64, len);
-
-       free(pubkey);
-
-       return base64;
-}
diff --git a/src/openssl/ecdsagen.h b/src/openssl/ecdsagen.h
deleted file mode 100644 (file)
index 8a40e45..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-    ecdsagen.h -- ECDSA key generation and export
-    Copyright (C) 2011 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_ECDSAGEN_H__
-#define __TINC_ECDSAGEN_H__
-
-#include "ecdsa.h"
-
-extern bool ecdsa_generate(ecdsa_t *ecdsa);
-extern bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp);
-extern bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp);
-extern char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa);
-
-#endif
index b37efdf04be864ae28eba1dab1bf164d4ba724cb..943bd6207fed171b751533a6ba584841c20ff3c6 100644 (file)
@@ -1,6 +1,6 @@
 /*
     prf.c -- Pseudo-Random Function for key material generation
-    Copyright (C) 2011-2012 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/obj_mac.h>
 
 #include "digest.h"
-#include "prf.h"
+#include "../digest.h"
+#include "../prf.h"
 
 /* Generate key material from a master secret and a seed, based on RFC 4346 section 5.
    We use SHA512 instead of MD5 and SHA1.
  */
 
 static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) {
-       digest_t digest;
+       digest_t *digest = digest_open_by_nid(nid, -1);
 
-       if(!digest_open_by_nid(&digest, nid, -1))
+       if(!digest)
                return false;
 
-       if(!digest_set_key(&digest, secret, secretlen))
+       if(!digest_set_key(digest, secret, secretlen)) {
+               digest_close(digest);
                return false;
+       }
 
-       size_t len = digest_length(&digest);
+       size_t len = digest_length(digest);
 
        /* Data is what the "inner" HMAC function processes.
           It consists of the previous HMAC result plus the seed.
@@ -51,10 +54,10 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s
 
        while(outlen > 0) {
                /* Inner HMAC */
-               digest_create(&digest, data, len + seedlen, data);
+               digest_create(digest, data, len + seedlen, data);
 
                /* Outer HMAC */
-               digest_create(&digest, data, len + seedlen, hash);
+               digest_create(digest, data, len + seedlen, hash);
 
                /* XOR the results of the outer HMAC into the out buffer */
                for(int i = 0; i < len && i < outlen; i++)
@@ -63,7 +66,7 @@ static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, s
                outlen -= len;
        }
 
-       digest_close(&digest);
+       digest_close(digest);
        return true;
 }
 
diff --git a/src/openssl/prf.h b/src/openssl/prf.h
deleted file mode 100644 (file)
index 6525505..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-    prf.h -- header file for prf.c
-    Copyright (C) 2011 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_PRF_H__
-#define __TINC_PRF_H__
-
-extern bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen);
-
-#endif
index 1b5ce5638a61941ff8925ddec96a0a33b76280fc..20bfb65a072b2926e26a1e21191c32dcd3c0aa2b 100644 (file)
@@ -1,6 +1,6 @@
 /*
     rsa.c -- RSA key handling
-    Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
-#include "logger.h"
-#include "rsa.h"
+#define __TINC_RSA_INTERNAL__
+typedef RSA rsa_t;
+
+#include "../logger.h"
+#include "../rsa.h"
 
 // Set RSA keys
 
-bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e) {
-       *rsa = RSA_new();
-       if(BN_hex2bn(&(*rsa)->n, n) != strlen(n))
-               return false;
-       if(BN_hex2bn(&(*rsa)->e, e) != strlen(e))
+rsa_t *rsa_set_hex_public_key(char *n, char *e) {
+       rsa_t *rsa = RSA_new();
+       if(!rsa)
+               return NULL;
+
+       if(BN_hex2bn(&rsa->n, n) != strlen(n) || BN_hex2bn(&rsa->e, e) != strlen(e)) {
+               RSA_free(rsa);
                return false;
-       return true;
+       }
+
+       return rsa;
 }
 
-bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d) {
-       *rsa = RSA_new();
-       if(BN_hex2bn(&(*rsa)->n, n) != strlen(n))
-               return false;
-       if(BN_hex2bn(&(*rsa)->e, e) != strlen(e))
-               return false;
-       if(BN_hex2bn(&(*rsa)->d, d) != strlen(d))
+rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) {
+       rsa_t *rsa = RSA_new();
+       if(!rsa)
+               return NULL;
+
+       if(BN_hex2bn(&rsa->n, n) != strlen(n) || BN_hex2bn(&rsa->e, e) != strlen(e) || BN_hex2bn(&rsa->d, d) != strlen(d)) {
+               RSA_free(rsa);
                return false;
-       return true;
+       }
+
+       return rsa;
 }
 
 // Read PEM RSA keys
 
-bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp) {
-       *rsa = PEM_read_RSAPublicKey(fp, rsa, NULL, NULL);
-
-       if(*rsa)
-               return true;
+rsa_t *rsa_read_pem_public_key(FILE *fp) {
+       rsa_t *rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
 
-       *rsa = PEM_read_RSA_PUBKEY(fp, rsa, NULL, NULL);
+       if(!rsa)
+               rsa = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
 
-       if(*rsa)
-               return true;
+       if(!rsa)
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL));
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA public key: %s", ERR_error_string(ERR_get_error(), NULL));
-       return false;
+       return rsa;
 }
 
-bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp) {
-       *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
+rsa_t *rsa_read_pem_private_key(FILE *fp) {
+       rsa_t *rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
 
-       if(*rsa)
-               return true;
+       if(!rsa)
+               logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
 
-       logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
-       return false;
+       return rsa;
 }
 
 size_t rsa_size(rsa_t *rsa) {
-       return RSA_size(*rsa);
+       return RSA_size(rsa);
 }
 
 bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
-       if(RSA_public_encrypt(len, in, out, *rsa, RSA_NO_PADDING) == len)
+       if(RSA_public_encrypt(len, in, out, rsa, RSA_NO_PADDING) == len)
                return true;
 
        logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL));
@@ -87,7 +92,7 @@ bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
 }
 
 bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
-       if(RSA_private_decrypt(len, in, out, *rsa, RSA_NO_PADDING) == len)
+       if(RSA_private_decrypt(len, in, out, rsa, RSA_NO_PADDING) == len)
                return true;
 
        logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL));
@@ -95,12 +100,10 @@ bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
 }
 
 bool rsa_active(rsa_t *rsa) {
-       return *rsa;
+       return rsa;
 }
 
 void rsa_free(rsa_t *rsa) {
-       if(*rsa) {
-               RSA_free(*rsa);
-               *rsa = NULL;
-       }
+       if(rsa)
+               RSA_free(rsa);
 }
diff --git a/src/openssl/rsa.h b/src/openssl/rsa.h
deleted file mode 100644 (file)
index 9a826cb..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-    rsa.h -- RSA key handling
-    Copyright (C) 2007-2011 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_RSA_H__
-#define __TINC_RSA_H__
-
-#include <openssl/rsa.h>
-
-typedef RSA *rsa_t;
-
-extern bool rsa_set_hex_public_key(rsa_t *rsa, char *n, char *e);
-extern bool rsa_set_hex_private_key(rsa_t *rsa, char *n, char *e, char *d);
-extern bool rsa_read_pem_public_key(rsa_t *rsa, FILE *fp);
-extern bool rsa_read_pem_private_key(rsa_t *rsa, FILE *fp);
-extern size_t rsa_size(rsa_t *rsa);
-extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t inlen, void *out);
-extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t inlen, void *out);
-extern bool rsa_active(rsa_t *rsa);
-extern void rsa_free(rsa_t *rsa);
-
-
-#endif
index 0f4a4fa19733f37cbfcd7e394f2e77d6ea51af33..3a8c8ad2efbfba49524a567a5d93f148a2db787f 100644 (file)
@@ -1,6 +1,6 @@
 /*
     rsagen.c -- RSA key generation and export
-    Copyright (C) 2008 Guus Sliepen <guus@tinc-vpn.org>
+    Copyright (C) 2008-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <openssl/pem.h>
 #include <openssl/err.h>
 
-#include "logger.h"
-#include "rsagen.h"
+#define __TINC_RSA_INTERNAL__
+typedef RSA rsa_t;
+
+#include "../logger.h"
+#include "../rsagen.h"
 
 /* This function prettyprints the key generation process */
 
@@ -63,21 +66,16 @@ static void indicator(int a, int b, void *p) {
 
 // Generate RSA key
 
-bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent) {
-       *rsa = RSA_generate_key(bits, exponent, indicator, NULL);
-
-       return *rsa;
+rsa_t *rsa_generate(size_t bits, unsigned long exponent) {
+       return RSA_generate_key(bits, exponent, indicator, NULL);
 }
 
 // Write PEM RSA keys
 
 bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp) {
-       PEM_write_RSAPublicKey(fp, *rsa);
-
-       return true;
+       return PEM_write_RSAPublicKey(fp, rsa);
 }
 
 bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp) {
-       PEM_write_RSAPrivateKey(fp, *rsa, NULL, NULL, 0, NULL, NULL);
-       return true;
+       return PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL);
 }
diff --git a/src/openssl/rsagen.h b/src/openssl/rsagen.h
deleted file mode 100644 (file)
index 422d156..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
-    rsagen.h -- RSA key generation and export
-    Copyright (C) 2008 Guus Sliepen <guus@tinc-vpn.org>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef __TINC_RSAGEN_H__
-#define __TINC_RSAGEN_H__
-
-#include "rsa.h"
-
-extern bool rsa_generate(rsa_t *rsa, size_t bits, unsigned long exponent);
-extern bool rsa_write_pem_public_key(rsa_t *rsa, FILE *fp);
-extern bool rsa_write_pem_private_key(rsa_t *rsa, FILE *fp);
-
-#endif
index 5f2dcaa2d67f32594ebfb34fddeaea3b823ac1a0..7940ab8064976ef6ba15cc628c12f52064356ed4 100644 (file)
@@ -1,7 +1,7 @@
 /*
     protocol_auth.c -- handle the meta-protocol, authentication
     Copyright (C) 1999-2005 Ivo Timmermans,
-                  2000-2012 Guus Sliepen <guus@tinc-vpn.org>
+                  2000-2013 Guus Sliepen <guus@tinc-vpn.org>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -221,7 +221,7 @@ bool id_h(connection_t *c, const char *request) {
                                return false;
                }
        } else {
-               if(c->protocol_minor && !ecdsa_active(&c->ecdsa))
+               if(c->protocol_minor && !ecdsa_active(c->ecdsa))
                        c->protocol_minor = 1;
        }
 
@@ -246,13 +246,13 @@ bool send_metakey(connection_t *c) {
        if(!read_rsa_public_key(c))
                return false;
 
-       if(!cipher_open_blowfish_ofb(&c->outcipher))
+       if(!(c->outcipher = cipher_open_blowfish_ofb()))
                return false;
 
-       if(!digest_open_sha1(&c->outdigest, -1))
+       if(!(c->outdigest = digest_open_sha1(-1)))
                return false;
 
-       size_t len = rsa_size(&c->rsa);
+       size_t len = rsa_size(c->rsa);
        char key[len];
        char enckey[len];
        char hexkey[2 * len + 1];
@@ -273,7 +273,7 @@ bool send_metakey(connection_t *c) {
 
        key[0] &= 0x7F;
 
-       cipher_set_key_from_rsa(&c->outcipher, key, len, true);
+       cipher_set_key_from_rsa(c->outcipher, key, len, true);
 
        if(debug_level >= DEBUG_SCARY_THINGS) {
                bin2hex(key, hexkey, len);
@@ -287,7 +287,7 @@ bool send_metakey(connection_t *c) {
           with a length equal to that of the modulus of the RSA key.
         */
 
-       if(!rsa_public_encrypt(&c->rsa, key, len, enckey)) {
+       if(!rsa_public_encrypt(c->rsa, key, len, enckey)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Error during encryption of meta key for %s (%s)", c->name, c->hostname);
                return false;
        }
@@ -299,8 +299,8 @@ bool send_metakey(connection_t *c) {
        /* Send the meta key */
 
        bool result = send_request(c, "%d %d %d %d %d %s", METAKEY,
-                        cipher_get_nid(&c->outcipher),
-                        digest_get_nid(&c->outdigest), c->outmaclength,
+                        cipher_get_nid(c->outcipher),
+                        digest_get_nid(c->outdigest), c->outmaclength,
                         c->outcompression, hexkey);
 
        c->status.encryptout = true;
@@ -310,7 +310,7 @@ bool send_metakey(connection_t *c) {
 bool metakey_h(connection_t *c, const char *request) {
        char hexkey[MAX_STRING_SIZE];
        int cipher, digest, maclength, compression;
-       size_t len = rsa_size(&myself->connection->rsa);
+       size_t len = rsa_size(myself->connection->rsa);
        char enckey[len];
        char key[len];
 
@@ -332,7 +332,7 @@ bool metakey_h(connection_t *c, const char *request) {
 
        /* Decrypt the meta key */
 
-       if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) {
+       if(!rsa_private_decrypt(myself->connection->rsa, enckey, len, key)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname);
                return false;
        }
@@ -344,12 +344,12 @@ bool metakey_h(connection_t *c, const char *request) {
 
        /* Check and lookup cipher and digest algorithms */
 
-       if(!cipher_open_by_nid(&c->incipher, cipher) || !cipher_set_key_from_rsa(&c->incipher, key, len, false)) {
+       if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname);
                return false;
        }
 
-       if(!digest_open_by_nid(&c->indigest, digest, -1)) {
+       if(!(c->indigest = digest_open_by_nid(digest, -1))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname);
                return false;
        }
@@ -362,7 +362,7 @@ bool metakey_h(connection_t *c, const char *request) {
 }
 
 bool send_challenge(connection_t *c) {
-       size_t len = rsa_size(&c->rsa);
+       size_t len = rsa_size(c->rsa);
        char buffer[len * 2 + 1];
 
        if(!c->hischallenge)
@@ -383,8 +383,8 @@ bool send_challenge(connection_t *c) {
 
 bool challenge_h(connection_t *c, const char *request) {
        char buffer[MAX_STRING_SIZE];
-       size_t len = rsa_size(&myself->connection->rsa);
-       size_t digestlen = digest_length(&c->indigest);
+       size_t len = rsa_size(myself->connection->rsa);
+       size_t digestlen = digest_length(c->indigest);
        char digest[digestlen];
 
        if(sscanf(request, "%*d " MAX_STRING, buffer) != 1) {
@@ -407,7 +407,7 @@ bool challenge_h(connection_t *c, const char *request) {
 
        /* Calculate the hash from the challenge we received */
 
-       digest_create(&c->indigest, buffer, len, digest);
+       digest_create(c->indigest, buffer, len, digest);
 
        /* Convert the hash to a hexadecimal formatted string */
 
@@ -433,7 +433,7 @@ bool chal_reply_h(connection_t *c, const char *request) {
 
        /* Check if the length of the hash is all right */
 
-       if(inlen != digest_length(&c->outdigest)) {
+       if(inlen != digest_length(c->outdigest)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length");
                return false;
        }
@@ -441,7 +441,7 @@ bool chal_reply_h(connection_t *c, const char *request) {
 
        /* Verify the hash */
 
-       if(!digest_verify(&c->outdigest, c->hischallenge, rsa_size(&c->rsa), hishash)) {
+       if(!digest_verify(c->outdigest, c->hischallenge, rsa_size(c->rsa), hishash)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply");
                return false;
        }
@@ -461,7 +461,7 @@ static bool send_upgrade(connection_t *c) {
        /* Special case when protocol_minor is 1: the other end is ECDSA capable,
         * but doesn't know our key yet. So send it now. */
 
-       char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa);
+       char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
 
        if(!pubkey)
                return false;
@@ -545,7 +545,7 @@ static bool upgrade_h(connection_t *c, const char *request) {
                return false;
        }
 
-       if(ecdsa_active(&c->ecdsa) || read_ecdsa_public_key(c)) {
+       if(ecdsa_active(c->ecdsa) || read_ecdsa_public_key(c)) {
                logger(DEBUG_ALWAYS, LOG_INFO, "Already have ECDSA public key from %s (%s), not upgrading.", c->name, c->hostname);
                return false;
        }
index 57377b2fb22e55ec14b2486a1873007d6e0c0641..7f6e1653e4e7c71436fda21567d6ab33f2ca1663 100644 (file)
@@ -124,7 +124,7 @@ bool send_req_key(node_t *to) {
 static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, int reqno) {
        switch(reqno) {
                case REQ_PUBKEY: {
-                       char *pubkey = ecdsa_get_base64_public_key(&myself->connection->ecdsa);
+                       char *pubkey = ecdsa_get_base64_public_key(myself->connection->ecdsa);
                        send_request(from->nexthop->connection, "%d %s %s %d %s", REQ_KEY, myself->name, from->name, ANS_PUBKEY, pubkey);
                        free(pubkey);
                        return true;
@@ -137,7 +137,7 @@ static bool req_key_ext_h(connection_t *c, const char *request, node_t *from, in
                        }
 
                        char pubkey[MAX_STRING_SIZE];
-                       if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !ecdsa_set_base64_public_key(&from->ecdsa, pubkey)) {
+                       if(sscanf(request, "%*d %*s %*s %*d " MAX_STRING, pubkey) != 1 || !(from->ecdsa = ecdsa_set_base64_public_key(pubkey))) {
                                logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s): %s", "ANS_PUBKEY", from->name, from->hostname, "invalid pubkey");
                                return true;
                        }
@@ -259,19 +259,22 @@ bool send_ans_key(node_t *to) {
        if(to->status.sptps)
                abort();
 
-       size_t keylen = cipher_keylength(&myself->incipher);
+       size_t keylen = cipher_keylength(myself->incipher);
        char key[keylen * 2 + 1];
 
-       cipher_close(&to->incipher);
-       digest_close(&to->indigest);
+       cipher_close(to->incipher);
+       digest_close(to->indigest);
 
-       cipher_open_by_nid(&to->incipher, cipher_get_nid(&myself->incipher));
-       digest_open_by_nid(&to->indigest, digest_get_nid(&myself->indigest), digest_length(&myself->indigest));
+       to->incipher = cipher_open_by_nid(cipher_get_nid(myself->incipher));
+       to->indigest = digest_open_by_nid(digest_get_nid(myself->indigest), digest_length(myself->indigest));
        to->incompression = myself->incompression;
 
+       if(!to->incipher || !to->indigest)
+               abort();
+
        randomize(key, keylen);
-       cipher_set_key(&to->incipher, key, false);
-       digest_set_key(&to->indigest, key, keylen);
+       cipher_set_key(to->incipher, key, false);
+       digest_set_key(to->indigest, key, keylen);
 
        bin2hex(key, key, keylen);
 
@@ -283,9 +286,9 @@ bool send_ans_key(node_t *to) {
 
        return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
                                                myself->name, to->name, key,
-                                               cipher_get_nid(&to->incipher),
-                                               digest_get_nid(&to->indigest),
-                                               (int)digest_length(&to->indigest),
+                                               cipher_get_nid(to->incipher),
+                                               digest_get_nid(to->indigest),
+                                               (int)digest_length(to->indigest),
                                                to->incompression);
 }
 
@@ -353,8 +356,8 @@ bool ans_key_h(connection_t *c, const char *request) {
        }
 
        /* Don't use key material until every check has passed. */
-       cipher_close(&from->outcipher);
-       digest_close(&from->outdigest);
+       cipher_close(from->outcipher);
+       digest_close(from->outdigest);
        from->status.validkey = false;
 
        if(compression < 0 || compression > 11) {
@@ -389,17 +392,17 @@ bool ans_key_h(connection_t *c, const char *request) {
 
        /* Check and lookup cipher and digest algorithms */
 
-       if(!cipher_open_by_nid(&from->outcipher, cipher)) {
+       if(!(from->outcipher = cipher_open_by_nid(cipher))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown cipher!", from->name, from->hostname);
                return false;
        }
 
-       if(!digest_open_by_nid(&from->outdigest, digest, maclength)) {
+       if(!(from->outdigest = digest_open_by_nid(digest, maclength))) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses unknown digest!", from->name, from->hostname);
                return false;
        }
 
-       if(maclength != digest_length(&from->outdigest)) {
+       if(maclength != digest_length(from->outdigest)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses bogus MAC length!", from->name, from->hostname);
                return false;
        }
@@ -408,15 +411,15 @@ bool ans_key_h(connection_t *c, const char *request) {
 
        keylen = hex2bin(key, key, sizeof key);
 
-       if(keylen != cipher_keylength(&from->outcipher)) {
+       if(keylen != cipher_keylength(from->outcipher)) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
                return true;
        }
 
        /* Update our copy of the origin's packet key */
 
-       cipher_set_key(&from->outcipher, key, true);
-       digest_set_key(&from->outdigest, key, keylen);
+       cipher_set_key(from->outcipher, key, true);
+       digest_set_key(from->outdigest, key, keylen);
 
        from->status.validkey = true;
        from->sent_seqno = 0;
index 8242cadf096875a202d894c423ac122bd8fd1057..1699b97f2758d00f6444c40d223de0e0afc1bbf3 100644 (file)
@@ -98,11 +98,11 @@ static bool send_record_priv_datagram(sptps_t *s, uint8_t type, const char *data
 
        if(s->outstate) {
                // If first handshake has finished, encrypt and HMAC
-               cipher_set_counter(&s->outcipher, &seqno, sizeof seqno);
-               if(!cipher_counter_xor(&s->outcipher, buffer + 6, len + 1UL, buffer + 6))
+               cipher_set_counter(s->outcipher, &seqno, sizeof seqno);
+               if(!cipher_counter_xor(s->outcipher, buffer + 6, len + 1UL, buffer + 6))
                        return false;
 
-               if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
+               if(!digest_create(s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
                        return false;
 
                return s->send_data(s->handle, type, buffer + 2, len + 21UL);
@@ -131,10 +131,10 @@ static bool send_record_priv(sptps_t *s, uint8_t type, const char *data, uint16_
 
        if(s->outstate) {
                // If first handshake has finished, encrypt and HMAC
-               if(!cipher_counter_xor(&s->outcipher, buffer + 4, len + 3UL, buffer + 4))
+               if(!cipher_counter_xor(s->outcipher, buffer + 4, len + 3UL, buffer + 4))
                        return false;
 
-               if(!digest_create(&s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
+               if(!digest_create(s->outdigest, buffer, len + 7UL, buffer + 7UL + len))
                        return false;
 
                return s->send_data(s->handle, type, buffer + 4, len + 19UL);
@@ -175,7 +175,7 @@ static bool send_kex(sptps_t *s) {
        randomize(s->mykex + 1, 32);
 
        // Create a new ECDH public key.
-       if(!ecdh_generate_public(&s->ecdh, s->mykex + 1 + 32))
+       if(!(s->ecdh = ecdh_generate_public(s->mykex + 1 + 32)))
                return false;
 
        return send_record_priv(s, SPTPS_HANDSHAKE, s->mykex, 1 + 32 + keylen);
@@ -184,7 +184,7 @@ static bool send_kex(sptps_t *s) {
 // Send a SIGnature record, containing an ECDSA signature over both KEX records.
 static bool send_sig(sptps_t *s) {
        size_t keylen = ECDH_SIZE;
-       size_t siglen = ecdsa_size(&s->mykey);
+       size_t siglen = ecdsa_size(s->mykey);
 
        // Concatenate both KEX messages, plus tag indicating if it is from the connection originator, plus label
        char msg[(1 + 32 + keylen) * 2 + 1 + s->labellen];
@@ -196,7 +196,7 @@ static bool send_sig(sptps_t *s) {
        memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);
 
        // Sign the result.
-       if(!ecdsa_sign(&s->mykey, msg, sizeof msg, sig))
+       if(!ecdsa_sign(s->mykey, msg, sizeof msg, sig))
                return false;
 
        // Send the SIG exchange record.
@@ -207,17 +207,16 @@ static bool send_sig(sptps_t *s) {
 static bool generate_key_material(sptps_t *s, const char *shared, size_t len) {
        // Initialise cipher and digest structures if necessary
        if(!s->outstate) {
-               bool result
-                       =  cipher_open_by_name(&s->incipher, "aes-256-ecb")
-                       && cipher_open_by_name(&s->outcipher, "aes-256-ecb")
-                       && digest_open_by_name(&s->indigest, "sha256", 16)
-                       && digest_open_by_name(&s->outdigest, "sha256", 16);
-               if(!result)
+               s->incipher = cipher_open_by_name("aes-256-ecb");
+               s->outcipher = cipher_open_by_name("aes-256-ecb");
+               s->indigest = digest_open_by_name("sha256", 16);
+               s->outdigest = digest_open_by_name("sha256", 16);
+               if(!s->incipher || !s->outcipher || !s->indigest || !s->outdigest)
                        return false;
        }
 
        // Allocate memory for key material
-       size_t keylen = digest_keylength(&s->indigest) + digest_keylength(&s->outdigest) + cipher_keylength(&s->incipher) + cipher_keylength(&s->outcipher);
+       size_t keylen = digest_keylength(s->indigest) + digest_keylength(s->outdigest) + cipher_keylength(s->incipher) + cipher_keylength(s->outcipher);
 
        s->key = realloc(s->key, keylen);
        if(!s->key)
@@ -254,14 +253,14 @@ static bool receive_ack(sptps_t *s, const char *data, uint16_t len) {
 
        if(s->initiator) {
                bool result
-                       = cipher_set_counter_key(&s->incipher, s->key)
-                       && digest_set_key(&s->indigest, s->key + cipher_keylength(&s->incipher), digest_keylength(&s->indigest));
+                       = cipher_set_counter_key(s->incipher, s->key)
+                       && digest_set_key(s->indigest, s->key + cipher_keylength(s->incipher), digest_keylength(s->indigest));
                if(!result)
                        return false;
        } else {
                bool result
-                       = cipher_set_counter_key(&s->incipher, s->key + cipher_keylength(&s->outcipher) + digest_keylength(&s->outdigest))
-                       && digest_set_key(&s->indigest, s->key + cipher_keylength(&s->outcipher) + digest_keylength(&s->outdigest) + cipher_keylength(&s->incipher), digest_keylength(&s->indigest));
+                       = cipher_set_counter_key(s->incipher, s->key + cipher_keylength(s->outcipher) + digest_keylength(s->outdigest))
+                       && digest_set_key(s->indigest, s->key + cipher_keylength(s->outcipher) + digest_keylength(s->outdigest) + cipher_keylength(s->incipher), digest_keylength(s->indigest));
                if(!result)
                        return false;
        }
@@ -296,7 +295,7 @@ static bool receive_kex(sptps_t *s, const char *data, uint16_t len) {
 // Receive a SIGnature record, verify it, if it passed, compute the shared secret and calculate the session keys.
 static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
        size_t keylen = ECDH_SIZE;
-       size_t siglen = ecdsa_size(&s->hiskey);
+       size_t siglen = ecdsa_size(s->hiskey);
 
        // Verify length of KEX record.
        if(len != siglen)
@@ -311,12 +310,12 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
        memcpy(msg + 1 + 2 * (33 + keylen), s->label, s->labellen);
 
        // Verify signature.
-       if(!ecdsa_verify(&s->hiskey, msg, sizeof msg, data))
+       if(!ecdsa_verify(s->hiskey, msg, sizeof msg, data))
                return false;
 
        // Compute shared secret.
        char shared[ECDH_SHARED_SIZE];
-       if(!ecdh_compute_shared(&s->ecdh, s->hiskex + 1 + 32, shared))
+       if(!ecdh_compute_shared(s->ecdh, s->hiskex + 1 + 32, shared))
                return false;
 
        // Generate key material from shared secret.
@@ -336,14 +335,14 @@ static bool receive_sig(sptps_t *s, const char *data, uint16_t len) {
        // TODO: only set new keys after ACK has been set/received
        if(s->initiator) {
                bool result
-                       = cipher_set_counter_key(&s->outcipher, s->key + cipher_keylength(&s->incipher) + digest_keylength(&s->indigest))
-                       && digest_set_key(&s->outdigest, s->key + cipher_keylength(&s->incipher) + digest_keylength(&s->indigest) + cipher_keylength(&s->outcipher), digest_keylength(&s->outdigest));
+                       = cipher_set_counter_key(s->outcipher, s->key + cipher_keylength(s->incipher) + digest_keylength(s->indigest))
+                       && digest_set_key(s->outdigest, s->key + cipher_keylength(s->incipher) + digest_keylength(s->indigest) + cipher_keylength(s->outcipher), digest_keylength(s->outdigest));
                if(!result)
                        return false;
        } else {
                bool result
-                       =  cipher_set_counter_key(&s->outcipher, s->key)
-                       && digest_set_key(&s->outdigest, s->key + cipher_keylength(&s->outcipher), digest_keylength(&s->outdigest));
+                       =  cipher_set_counter_key(s->outcipher, s->key)
+                       && digest_set_key(s->outdigest, s->key + cipher_keylength(s->outcipher), digest_keylength(s->outdigest));
                if(!result)
                        return false;
        }
@@ -413,7 +412,7 @@ bool sptps_verify_datagram(sptps_t *s, const char *data, size_t len) {
        memcpy(buffer, &netlen, 2);
        memcpy(buffer + 2, data, len);
 
-       return digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14);
+       return digest_verify(s->indigest, buffer, len - 14, buffer + len - 14);
 }
 
 // Receive incoming data, datagram version.
@@ -447,7 +446,7 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len
        memcpy(buffer, &netlen, 2);
        memcpy(buffer + 2, data, len);
 
-       if(!digest_verify(&s->indigest, buffer, len - 14, buffer + len - 14))
+       if(!digest_verify(s->indigest, buffer, len - 14, buffer + len - 14))
                return error(s, EIO, "Invalid HMAC");
 
        // Replay protection using a sliding window of configurable size.
@@ -491,8 +490,8 @@ static bool sptps_receive_data_datagram(sptps_t *s, const char *data, size_t len
 
        // Decrypt.
        memcpy(&seqno, buffer + 2, 4);
-       cipher_set_counter(&s->incipher, &seqno, sizeof seqno);
-       if(!cipher_counter_xor(&s->incipher, buffer + 6, len - 4, buffer + 6))
+       cipher_set_counter(s->incipher, &seqno, sizeof seqno);
+       if(!cipher_counter_xor(s->incipher, buffer + 6, len - 4, buffer + 6))
                return false;
 
        // Append a NULL byte for safety.
@@ -540,7 +539,7 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) {
                        // Decrypt the length bytes
 
                        if(s->instate) {
-                               if(!cipher_counter_xor(&s->incipher, s->inbuf + 4, 2, &s->reclen))
+                               if(!cipher_counter_xor(s->incipher, s->inbuf + 4, 2, &s->reclen))
                                        return false;
                        } else {
                                memcpy(&s->reclen, s->inbuf + 4, 2);
@@ -578,10 +577,10 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) {
 
                // Check HMAC and decrypt.
                if(s->instate) {
-                       if(!digest_verify(&s->indigest, s->inbuf, s->reclen + 7UL, s->inbuf + s->reclen + 7UL))
+                       if(!digest_verify(s->indigest, s->inbuf, s->reclen + 7UL, s->inbuf + s->reclen + 7UL))
                                return error(s, EIO, "Invalid HMAC");
 
-                       if(!cipher_counter_xor(&s->incipher, s->inbuf + 6UL, s->reclen + 1UL, s->inbuf + 6UL))
+                       if(!cipher_counter_xor(s->incipher, s->inbuf + 6UL, s->reclen + 1UL, s->inbuf + 6UL))
                                return false;
                }
 
@@ -609,7 +608,7 @@ bool sptps_receive_data(sptps_t *s, const char *data, size_t len) {
 }
 
 // Start a SPTPS session.
-bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) {
+bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record) {
        // Initialise struct sptps
        memset(s, 0, sizeof *s);
 
@@ -651,11 +650,11 @@ bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_
 // Stop a SPTPS session.
 bool sptps_stop(sptps_t *s) {
        // Clean up any resources.
-       cipher_close(&s->incipher);
-       cipher_close(&s->outcipher);
-       digest_close(&s->indigest);
-       digest_close(&s->outdigest);
-       ecdh_free(&s->ecdh);
+       cipher_close(s->incipher);
+       cipher_close(s->outcipher);
+       digest_close(s->indigest);
+       digest_close(s->outdigest);
+       ecdh_free(s->ecdh);
        free(s->inbuf);
        free(s->mykex);
        free(s->hiskex);
index 1fead07a0a4391a8a36916cddd1fa2bce3a30410..ee41f46f6257bfd573e6838448286c3967ac7b88 100644 (file)
@@ -53,8 +53,8 @@ typedef struct sptps {
        uint16_t reclen;
 
        bool instate;
-       cipher_t incipher;
-       digest_t indigest;
+       cipher_t *incipher;
+       digest_t *indigest;
        uint32_t inseqno;
        uint32_t received;
        unsigned int replaywin;
@@ -62,13 +62,13 @@ typedef struct sptps {
        char *late;
 
        bool outstate;
-       cipher_t outcipher;
-       digest_t outdigest;
+       cipher_t *outcipher;
+       digest_t *outdigest;
        uint32_t outseqno;
 
-       ecdsa_t mykey;
-       ecdsa_t hiskey;
-       ecdh_t ecdh;
+       ecdsa_t *mykey;
+       ecdsa_t *hiskey;
+       ecdh_t *ecdh;
 
        char *mykex;
        char *hiskex;
@@ -85,7 +85,7 @@ extern unsigned int sptps_replaywin;
 extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap);
 extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap);
 extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap);
-extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t mykey, ecdsa_t hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record);
+extern bool sptps_start(sptps_t *s, void *handle, bool initiator, bool datagram, ecdsa_t *mykey, ecdsa_t *hiskey, const char *label, size_t labellen, send_data_t send_data, receive_record_t receive_record);
 extern bool sptps_stop(sptps_t *s);
 extern bool sptps_send_record(sptps_t *s, uint8_t type, const char *data, uint16_t len);
 extern bool sptps_receive_data(sptps_t *s, const char *data, size_t len);
index 2a9fca0c48d6172012df1f00f67bf3ba9dc0d73c..2ce980441b43b3e281803e2590e718968ea890f0 100644 (file)
@@ -1,6 +1,6 @@
 /*
     sptps_test.c -- Simple Peer-to-Peer Security test program
-    Copyright (C) 2011-2012 Guus Sliepen <guus@tinc-vpn.org>,
+    Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>,
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -31,7 +31,7 @@ bool send_meta(void *c, const char *msg , int len) { return false; }
 char *logfilename = NULL;
 struct timeval now;
 
-ecdsa_t mykey, hiskey;
+ecdsa_t *mykey, *hiskey;
 
 static bool send_data(void *handle, uint8_t type, const char *data, size_t len) {
        char hex[len * 2 + 1];
@@ -143,12 +143,12 @@ int main(int argc, char *argv[]) {
        crypto_init();
 
        FILE *fp = fopen(argv[1], "r");
-       if(!ecdsa_read_pem_private_key(&mykey, fp))
+       if(!(mykey = ecdsa_read_pem_private_key(fp)))
                return 1;
        fclose(fp);
 
        fp = fopen(argv[2], "r");
-       if(!ecdsa_read_pem_public_key(&hiskey, fp))
+       if(!(hiskey = ecdsa_read_pem_public_key(fp)))
                return 1;
        fclose(fp);
 
index bc64031490140d5ab36562ba5eaf9c53d645f53d..a8930fe1d9d8d678f457f4afa85d7fa133616b2e 100644 (file)
@@ -346,13 +346,13 @@ static FILE *ask_and_open(const char *filename, const char *what, const char *mo
   them in.
 */
 static bool ecdsa_keygen(bool ask) {
-       ecdsa_t key;
+       ecdsa_t *key;
        FILE *f;
        char *pubname, *privname;
 
        fprintf(stderr, "Generating ECDSA keypair:\n");
 
-       if(!ecdsa_generate(&key)) {
+       if(!(key = ecdsa_generate())) {
                fprintf(stderr, "Error during key generation!\n");
                return false;
        } else
@@ -370,7 +370,12 @@ static bool ecdsa_keygen(bool ask) {
        fchmod(fileno(f), 0600);
 #endif
 
-       ecdsa_write_pem_private_key(&key, f);
+       if(!ecdsa_write_pem_private_key(key, f)) {
+               fprintf(stderr, "Error writing private key!\n");
+               ecdsa_free(key);
+               fclose(f);
+               return false;
+       }
 
        fclose(f);
 
@@ -385,11 +390,12 @@ static bool ecdsa_keygen(bool ask) {
        if(!f)
                return false;
 
-       char *pubkey = ecdsa_get_base64_public_key(&key);
+       char *pubkey = ecdsa_get_base64_public_key(key);
        fprintf(f, "ECDSAPublicKey = %s\n", pubkey);
        free(pubkey);
 
        fclose(f);
+       ecdsa_free(key);
 
        return true;
 }
@@ -399,13 +405,13 @@ static bool ecdsa_keygen(bool ask) {
   them in.
 */
 static bool rsa_keygen(int bits, bool ask) {
-       rsa_t key;
+       rsa_t *key;
        FILE *f;
        char *pubname, *privname;
 
        fprintf(stderr, "Generating %d bits keys:\n", bits);
 
-       if(!rsa_generate(&key, bits, 0x10001)) {
+       if(!(key = rsa_generate(bits, 0x10001))) {
                fprintf(stderr, "Error during key generation!\n");
                return false;
        } else
@@ -423,7 +429,12 @@ static bool rsa_keygen(int bits, bool ask) {
        fchmod(fileno(f), 0600);
 #endif
 
-       rsa_write_pem_private_key(&key, f);
+       if(!rsa_write_pem_private_key(key, f)) {
+               fprintf(stderr, "Error writing private key!\n");
+               fclose(f);
+               rsa_free(key);
+               return false;
+       }
 
        fclose(f);
 
@@ -438,9 +449,15 @@ static bool rsa_keygen(int bits, bool ask) {
        if(!f)
                return false;
 
-       rsa_write_pem_public_key(&key, f);
+       if(!rsa_write_pem_public_key(key, f)) {
+               fprintf(stderr, "Error writing public key!\n");
+               fclose(f);
+               rsa_free(key);
+               return false;
+       }
 
        fclose(f);
+       rsa_free(key);
 
        return true;
 }