From: Guus Sliepen Date: Wed, 1 May 2013 15:17:22 +0000 (+0200) Subject: Use conditional compilation for cryptographic functions. X-Git-Tag: import-tinc-1.1~159 X-Git-Url: https://git.meshlink.io/?a=commitdiff_plain;h=9b9230a0a79c670b86f54fadd2807b864ff9d91f;p=meshlink Use conditional compilation for cryptographic functions. 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. --- diff --git a/Makefile.am b/Makefile.am index 130cd6ef..d2e6f3fa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.ac b/configure.ac index a988154c..5f6bfecd 100644 --- a/configure.ac +++ b/configure.ac @@ -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, diff --git a/src/Makefile.am b/src/Makefile.am index c1f51f10..3361e3dd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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@ diff --git a/src/connection.c b/src/connection.c index 4798c5a4..9c459787 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1,6 +1,6 @@ /* connection.c -- connection list management - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans 2008 Max Rijevski @@ -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); diff --git a/src/connection.h b/src/connection.h index 10f4a76a..5b6a94c4 100644 --- a/src/connection.h +++ b/src/connection.h @@ -1,6 +1,6 @@ /* connection.h -- header for connection.c - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 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 index 00000000..4e30733f --- /dev/null +++ b/src/gcrypt/ecdh.c @@ -0,0 +1,37 @@ +/* + ecdh.c -- Diffie-Hellman key exchange handling + Copyright (C) 2011-2013 Guus Sliepen + + 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 index 00000000..ee19aec3 --- /dev/null +++ b/src/gcrypt/ecdsa.c @@ -0,0 +1,67 @@ +/* + ecdsa.c -- ECDSA key handling + Copyright (C) 2011-2013 Guus Sliepen + + 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 index 00000000..2d4912d5 --- /dev/null +++ b/src/gcrypt/ecdsagen.c @@ -0,0 +1,41 @@ +/* + ecdsagen.c -- ECDSA key generation and export + Copyright (C) 2011-2013 Guus Sliepen + + 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 index 00000000..f9a21121 --- /dev/null +++ b/src/gcrypt/prf.c @@ -0,0 +1,29 @@ +/* + prf.c -- Pseudo-Random Function for key material generation + Copyright (C) 2011-2013 Guus Sliepen + + 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; +} diff --git a/src/meta.c b/src/meta.c index fafba653..887da4a8 100644 --- a/src/meta.c +++ b/src/meta.c @@ -1,6 +1,6 @@ /* meta.c -- handle the meta communication - Copyright (C) 2000-2012 Guus Sliepen , + Copyright (C) 2000-2013 Guus Sliepen , 2000-2005 Ivo Timmermans 2006 Scott Lamb @@ -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; diff --git a/src/net_packet.c b/src/net_packet.c index 27ca7148..c2552619 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -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 */ diff --git a/src/net_setup.c b/src/net_setup.c index bf0c5a50..a9947aad 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -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; } diff --git a/src/node.c b/src/node.c index 465a48a8..2f517446 100644 --- a/src/node.c +++ b/src/node.c @@ -1,6 +1,6 @@ /* node.c -- node tree management - Copyright (C) 2001-2012 Guus Sliepen , + Copyright (C) 2001-2013 Guus Sliepen , 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); diff --git a/src/node.h b/src/node.h index e4b47b38..e704ba82 100644 --- a/src/node.h +++ b/src/node.h @@ -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 */ diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c index 553b4adb..32cb5ce2 100644 --- a/src/openssl/cipher.c +++ b/src/openssl/cipher.c @@ -1,6 +1,6 @@ /* cipher.c -- Symmetric block cipher handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 Guus Sliepen 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 @@ -17,56 +17,67 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include +#include -#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 index c9f89eb5..00000000 --- a/src/openssl/cipher.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - cipher.h -- header file cipher.c - Copyright (C) 2007-2012 Guus Sliepen - - 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 - -#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 diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c index c695be88..ece7f059 100644 --- a/src/openssl/crypto.c +++ b/src/openssl/crypto.c @@ -1,6 +1,6 @@ /* crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2007 Guus Sliepen + Copyright (C) 2007-2013 Guus Sliepen 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 @@ -17,13 +17,13 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include #include -#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 index 8047bfbe..00000000 --- a/src/openssl/crypto.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - crypto.h -- header for crypto.c - Copyright (C) 2007 Guus Sliepen - - 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 diff --git a/src/openssl/digest.c b/src/openssl/digest.c index 79db491d..9406701b 100644 --- a/src/openssl/digest.c +++ b/src/openssl/digest.c @@ -1,6 +1,6 @@ /* digest.c -- Digest handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 Guus Sliepen 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 @@ -17,57 +17,55 @@ 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 #include #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; } diff --git a/src/openssl/digest.h b/src/openssl/digest.h index c1922492..542c63cb 100644 --- a/src/openssl/digest.h +++ b/src/openssl/digest.h @@ -1,6 +1,6 @@ /* digest.h -- header file digest.c - Copyright (C) 2007-2011 Guus Sliepen + Copyright (C) 2013 Guus Sliepen 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 @@ -17,13 +17,11 @@ 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 -#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 diff --git a/src/openssl/ecdh.c b/src/openssl/ecdh.c index f94555db..d997007f 100644 --- a/src/openssl/ecdh.c +++ b/src/openssl/ecdh.c @@ -1,6 +1,6 @@ /* ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 Guus Sliepen 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 @@ -17,68 +17,70 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" -#include "utils.h" -#include "xalloc.h" +#include "../system.h" #include #include +#include #include -#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 index ef7de6e9..00000000 --- a/src/openssl/ecdh.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - ecdh.h -- header file for ecdh.c - Copyright (C) 2011 Guus Sliepen - - 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 - -#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 diff --git a/src/openssl/ecdsa.c b/src/openssl/ecdsa.c index e2af6f9c..bca89fc5 100644 --- a/src/openssl/ecdsa.c +++ b/src/openssl/ecdsa.c @@ -1,6 +1,6 @@ /* ecdsa.c -- ECDSA key handling - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 Guus Sliepen 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 @@ -17,22 +17,26 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#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 index 04f9eb98..00000000 --- a/src/openssl/ecdsa.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - ecdsa.h -- ECDSA key handling - Copyright (C) 2011 Guus Sliepen - - 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 - -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 diff --git a/src/openssl/ecdsagen.c b/src/openssl/ecdsagen.c index 883c77e7..35795f39 100644 --- a/src/openssl/ecdsagen.c +++ b/src/openssl/ecdsagen.c @@ -1,6 +1,6 @@ /* ecdsagen.c -- ECDSA key generation and export - Copyright (C) 2011 Guus Sliepen + Copyright (C) 2011-2013 Guus Sliepen 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 @@ -17,59 +17,50 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include #include -#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 index 8a40e451..00000000 --- a/src/openssl/ecdsagen.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - ecdsagen.h -- ECDSA key generation and export - Copyright (C) 2011 Guus Sliepen - - 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 diff --git a/src/openssl/prf.c b/src/openssl/prf.c index b37efdf0..943bd620 100644 --- a/src/openssl/prf.c +++ b/src/openssl/prf.c @@ -1,6 +1,6 @@ /* prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2011-2012 Guus Sliepen + Copyright (C) 2011-2013 Guus Sliepen 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 @@ -17,27 +17,30 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #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 index 6525505e..00000000 --- a/src/openssl/prf.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - prf.h -- header file for prf.c - Copyright (C) 2011 Guus Sliepen - - 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 diff --git a/src/openssl/rsa.c b/src/openssl/rsa.c index 1b5ce563..20bfb65a 100644 --- a/src/openssl/rsa.c +++ b/src/openssl/rsa.c @@ -1,6 +1,6 @@ /* rsa.c -- RSA key handling - Copyright (C) 2007-2012 Guus Sliepen + Copyright (C) 2007-2013 Guus Sliepen 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 @@ -17,69 +17,74 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#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 index 9a826cbd..00000000 --- a/src/openssl/rsa.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - rsa.h -- RSA key handling - Copyright (C) 2007-2011 Guus Sliepen - - 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 - -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 diff --git a/src/openssl/rsagen.c b/src/openssl/rsagen.c index 0f4a4fa1..3a8c8ad2 100644 --- a/src/openssl/rsagen.c +++ b/src/openssl/rsagen.c @@ -1,6 +1,6 @@ /* rsagen.c -- RSA key generation and export - Copyright (C) 2008 Guus Sliepen + Copyright (C) 2008-2013 Guus Sliepen 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 @@ -17,13 +17,16 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "system.h" +#include "../system.h" #include #include -#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 index 422d1560..00000000 --- a/src/openssl/rsagen.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - rsagen.h -- RSA key generation and export - Copyright (C) 2008 Guus Sliepen - - 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 diff --git a/src/protocol_auth.c b/src/protocol_auth.c index 5f2dcaa2..7940ab80 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -1,7 +1,7 @@ /* protocol_auth.c -- handle the meta-protocol, authentication Copyright (C) 1999-2005 Ivo Timmermans, - 2000-2012 Guus Sliepen + 2000-2013 Guus Sliepen 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; } diff --git a/src/protocol_key.c b/src/protocol_key.c index 57377b2f..7f6e1653 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -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; diff --git a/src/sptps.c b/src/sptps.c index 8242cadf..1699b97f 100644 --- a/src/sptps.c +++ b/src/sptps.c @@ -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); diff --git a/src/sptps.h b/src/sptps.h index 1fead07a..ee41f46f 100644 --- a/src/sptps.h +++ b/src/sptps.h @@ -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); diff --git a/src/sptps_test.c b/src/sptps_test.c index 2a9fca0c..2ce98044 100644 --- a/src/sptps_test.c +++ b/src/sptps_test.c @@ -1,6 +1,6 @@ /* sptps_test.c -- Simple Peer-to-Peer Security test program - Copyright (C) 2011-2012 Guus Sliepen , + Copyright (C) 2011-2013 Guus Sliepen , 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); diff --git a/src/tincctl.c b/src/tincctl.c index bc640314..a8930fe1 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -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; }