From cfe9285adf391ab66faeb5def811fe08e47a221a Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Mon, 29 Dec 2014 22:57:18 +0100 Subject: [PATCH] Allow tinc to be compiled without OpenSSL. The option "--disable-legacy-protocol" was added to the configure script. The new protocol does not depend on any external crypto libraries, so when the option is used tinc is no longer linked to OpenSSL's libcrypto. --- configure.ac | 24 +++++++++++++------ src/Makefile.am | 56 +++++++++++++++++++++++++++------------------ src/cipher.h | 4 ++++ src/connection.c | 4 +++- src/connection.h | 5 +++- src/digest.h | 4 ++++ src/invitation.c | 26 +++++++++------------ src/meta.c | 8 +++++++ src/net_packet.c | 12 ++++++++++ src/net_setup.c | 14 ++++++++++++ src/net_socket.c | 4 ++++ src/node.c | 25 ++++++++++++-------- src/node.h | 2 ++ src/protocol_auth.c | 34 ++++++++++++++++++++++----- src/protocol_key.c | 11 +++++++++ src/tincctl.c | 31 +++++++++++++++++++++++-- 16 files changed, 200 insertions(+), 64 deletions(-) diff --git a/configure.ac b/configure.ac index 6fd2621..9a9bf01 100644 --- a/configure.ac +++ b/configure.ac @@ -211,23 +211,33 @@ AC_CHECK_DECLS([res_init], [AC_CHECK_LIB(resolv, res_init)], [], [ AC_CACHE_SAVE +AC_ARG_ENABLE(legacy-protocol, + AS_HELP_STRING([--disable-legacy-protocol], [disable support for the legacy (tinc 1.0) protocol]), + [ AS_IF([test "x$enable_legacy_protocol" = "xno"], + [ AC_DEFINE(DISABLE_LEGACY, 1, [Disable support for the legacy (tinc 1.0) protocol]) ]) + ] +) + dnl These are defined in files in m4/ dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], []) +dnl AC_ARG_WITH(openssl, AC_HELP_STRING([--without-openssl], [disable support for OpenSSL])], []) tinc_CURSES tinc_READLINE tinc_ZLIB tinc_LZO -if test -n "$with_libgcrypt"; then - gcrypt=true - tinc_LIBGCRYPT -else - openssl=true - tinc_OPENSSL +if test "x$enable_legacy_protocol" != "xno"; then + if test -n "$with_libgcrypt"; then + gcrypt=true + tinc_LIBGCRYPT + else + openssl=true + tinc_OPENSSL + fi fi - + AM_CONDITIONAL(OPENSSL, test -n "$openssl") AM_CONDITIONAL(GCRYPT, test -n "$gcrypt") diff --git a/src/Makefile.am b/src/Makefile.am index cd84f3a..5c8a841 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -92,6 +92,8 @@ tincd_SOURCES = \ utils.c utils.h \ xalloc.h \ version.c version.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) @@ -111,6 +113,9 @@ tinc_SOURCES = \ top.c top.h \ utils.c utils.h \ version.c version.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + ed25519/ecdsagen.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) @@ -119,12 +124,15 @@ sptps_test_SOURCES = \ sptps.c sptps.h \ sptps_test.c \ utils.c utils.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) sptps_keypair_SOURCES = \ sptps_keypair.c \ utils.c utils.h \ + ed25519/ecdsagen.c \ $(ed25519_SOURCES) sptps_speed_SOURCES = \ @@ -132,6 +140,9 @@ sptps_speed_SOURCES = \ sptps.c sptps.h \ sptps_speed.c \ utils.c utils.h \ + ed25519/ecdh.c \ + ed25519/ecdsa.c \ + ed25519/ecdsagen.c \ $(ed25519_SOURCES) \ $(chacha_poly1305_SOURCES) @@ -173,54 +184,36 @@ tincd_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ openssl/prf.c \ openssl/rsa.c tinc_SOURCES += \ openssl/cipher.c \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - ed25519/ecdsagen.c \ openssl/prf.c \ openssl/rsa.c \ openssl/rsagen.c sptps_test_SOURCES += \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ openssl/prf.c sptps_keypair_SOURCES += \ - openssl/crypto.c \ - ed25519/ecdsagen.c + openssl/crypto.c sptps_speed_SOURCES += \ openssl/crypto.c \ openssl/digest.c openssl/digest.h \ - ed25519/ecdh.c \ - ed25519/ecdsa.c \ - ed25519/ecdsagen.c \ openssl/prf.c -endif - -if GCRYPT +elif GCRYPT tincd_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ gcrypt/prf.c \ gcrypt/rsa.c tinc_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ - gcrypt/ecdsagen.c \ gcrypt/prf.c \ gcrypt/rsa.c \ gcrypt/rsagen.c @@ -228,9 +221,28 @@ sptps_test_SOURCES += \ gcrypt/cipher.c \ gcrypt/crypto.c \ gcrypt/digest.c gcrypt/digest.h \ - gcrypt/ecdh.c \ - gcrypt/ecdsa.c \ gcrypt/prf.c +sptps_keypair_SOURCES += \ + openssl/crypto.c +sptps_speed_SOURCES += \ + openssl/crypto.c \ + openssl/digest.c openssl/digest.h \ + openssl/prf.c +else +tincd_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +tinc_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +sptps_test_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c +sptps_keypair_SOURCES += \ + nolegacy/crypto.c +sptps_speed_SOURCES += \ + nolegacy/crypto.c \ + nolegacy/prf.c endif tinc_LDADD = $(READLINE_LIBS) $(CURSES_LIBS) diff --git a/src/cipher.h b/src/cipher.h index 47cd1cd..f194c0d 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -24,6 +24,8 @@ #define CIPHER_MAX_IV_SIZE 16 #define CIPHER_MAX_KEY_SIZE 32 +#ifndef DISABLE_LEGACY + typedef struct cipher cipher_t; extern cipher_t *cipher_open_by_name(const char *) __attribute__ ((__malloc__)); @@ -40,3 +42,5 @@ extern int cipher_get_nid(const cipher_t *); extern bool cipher_active(const cipher_t *); #endif + +#endif diff --git a/src/connection.c b/src/connection.c index 496f674..0e61132 100644 --- a/src/connection.c +++ b/src/connection.c @@ -55,14 +55,16 @@ void free_connection(connection_t *c) { if(!c) return; +#ifndef DISABLE_LEGACY cipher_close(c->incipher); digest_close(c->indigest); cipher_close(c->outcipher); digest_close(c->outdigest); + rsa_free(c->rsa); +#endif sptps_stop(&c->sptps); ecdsa_free(c->ecdsa); - rsa_free(c->rsa); free(c->hischallenge); diff --git a/src/connection.h b/src/connection.h index b74b582..30c6598 100644 --- a/src/connection.h +++ b/src/connection.h @@ -75,12 +75,15 @@ typedef struct connection_t { struct node_t *node; /* node associated with the other end */ struct edge_t *edge; /* edge associated with this connection */ +#ifndef DISABLE_LEGACY 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; +#endif + + ecdsa_t *ecdsa; /* his public ECDSA key */ sptps_t sptps; int inmaclength; diff --git a/src/digest.h b/src/digest.h index 1e14945..204048a 100644 --- a/src/digest.h +++ b/src/digest.h @@ -22,6 +22,8 @@ #define DIGEST_MAX_SIZE 64 +#ifndef DISABLE_LEGACY + typedef struct digest digest_t; extern digest_t *digest_open_by_name(const char *name, int maclength) __attribute__ ((__malloc__)); @@ -37,3 +39,5 @@ extern size_t digest_length(const digest_t *); extern bool digest_active(const digest_t *); #endif + +#endif diff --git a/src/invitation.c b/src/invitation.c index dff8d5f..3863488 100644 --- a/src/invitation.c +++ b/src/invitation.c @@ -33,6 +33,8 @@ #include "utils.h" #include "xalloc.h" +#include "ed25519/sha512.h" + int addressfamily = AF_UNSPEC; static void scan_for_hostname(const char *filename, char **hostname, char **port) { @@ -270,8 +272,6 @@ int cmd_invite(int argc, char *argv[]) { } } - char hash[25]; - xasprintf(&filename, "%s" SLASH "invitations", confbase); if(mkdir(filename, 0700) && errno != EEXIST) { fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno)); @@ -365,11 +365,9 @@ int cmd_invite(int argc, char *argv[]) { return 1; // Create a hash of the key. + char hash[64]; char *fingerprint = ecdsa_get_base64_public_key(key); - digest_t *digest = digest_open_by_name("sha256", 18); - if(!digest) - abort(); - digest_create(digest, fingerprint, strlen(fingerprint), hash); + sha512(fingerprint, strlen(fingerprint), hash); b64encode_urlsafe(hash, hash, 18); // Create a random cookie for this invitation. @@ -378,10 +376,10 @@ int cmd_invite(int argc, char *argv[]) { // Create a filename that doesn't reveal the cookie itself char buf[18 + strlen(fingerprint)]; - char cookiehash[25]; + char cookiehash[64]; memcpy(buf, cookie, 18); memcpy(buf + 18, fingerprint, sizeof buf - 18); - digest_create(digest, buf, sizeof buf, cookiehash); + sha512(buf, sizeof buf, cookiehash); b64encode_urlsafe(cookiehash, cookiehash, 18); b64encode_urlsafe(cookie, cookie, 18); @@ -739,8 +737,9 @@ make_names: sptps_send_record(&sptps, 1, b64key, strlen(b64key)); free(b64key); + ecdsa_free(key); - +#ifndef DISABLE_LEGACY rsa_t *rsa = rsa_generate(2048, 0x1001); xasprintf(&filename, "%s" SLASH "rsa_key.priv", confbase); f = fopenmask(filename, "w", 0600); @@ -751,8 +750,8 @@ make_names: rsa_write_pem_public_key(rsa, fh); fclose(fh); - ecdsa_free(key); rsa_free(rsa); +#endif check_port(name); @@ -958,11 +957,8 @@ int cmd_join(int argc, char *argv[]) { // Check if the hash of the key he gave us matches the hash in the URL. char *fingerprint = line + 2; - digest_t *digest = digest_open_by_name("sha256", 18); - if(!digest) - abort(); - char hishash[18]; - if(!digest_create(digest, fingerprint, strlen(fingerprint), hishash)) { + char hishash[64]; + if(sha512(fingerprint, strlen(fingerprint), hishash)) { fprintf(stderr, "Could not create digest\n%s\n", line + 2); return 1; } diff --git a/src/meta.c b/src/meta.c index 73769d9..1c29fe9 100644 --- a/src/meta.c +++ b/src/meta.c @@ -58,6 +58,9 @@ bool send_meta(connection_t *c, const char *buffer, int length) { /* Add our data to buffer */ if(c->status.encryptout) { +#ifdef DISABLE_LEGACY + return false; +#else size_t outlen = length; if(!cipher_encrypt(c->outcipher, buffer, length, buffer_prepare(&c->outbuf, length), &outlen, false) || outlen != length) { @@ -65,6 +68,7 @@ bool send_meta(connection_t *c, const char *buffer, int length) { c->name, c->hostname); return false; } +#endif } else { buffer_add(&c->outbuf, buffer, length); } @@ -170,6 +174,9 @@ bool receive_meta(connection_t *c) { inlen -= endp - bufp; bufp = endp; } else { +#ifdef DISABLE_LEGACY + return false; +#else size_t outlen = inlen; if(!cipher_decrypt(c->incipher, bufp, inlen, buffer_prepare(&c->inbuf, inlen), &outlen, false) || inlen != outlen) { @@ -179,6 +186,7 @@ bool receive_meta(connection_t *c) { } inlen = 0; +#endif } while(c->inbuf.len) { diff --git a/src/net_packet.c b/src/net_packet.c index c146109..c07dd1a 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -351,10 +351,14 @@ static bool try_mac(node_t *n, const vpn_packet_t *inpkt) { if(n->status.sptps) return sptps_verify_datagram(&n->sptps, DATA(inpkt), inpkt->len); +#ifdef DISABLE_LEGACY + return false; +#else if(!digest_active(n->indigest) || inpkt->len < sizeof(seqno_t) + digest_length(n->indigest)) return false; return digest_verify(n->indigest, SEQNO(inpkt), inpkt->len - digest_length(n->indigest), DATA(inpkt) + inpkt->len - digest_length(n->indigest)); +#endif } static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { @@ -383,6 +387,9 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { return true; } +#ifdef DISABLE_LEGACY + return false; +#else if(!n->status.validkey) { logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet", n->name, n->hostname); return false; @@ -491,6 +498,7 @@ static bool receive_udppacket(node_t *n, vpn_packet_t *inpkt) { else receive_packet(n, inpkt); return true; +#endif } void receive_tcppacket(connection_t *c, const char *buffer, int len) { @@ -681,6 +689,9 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { if(n->status.sptps) return send_sptps_packet(n, origpkt); +#ifdef DISABLE_LEGACY + return; +#else /* Make sure we have a valid key */ if(!n->status.validkey) { @@ -789,6 +800,7 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) { end: origpkt->len = origlen; +#endif } static bool send_sptps_data_priv(node_t *to, node_t *from, int type, const void *data, size_t len) { diff --git a/src/net_setup.c b/src/net_setup.c index 29f1212..1007f69 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -145,6 +145,7 @@ bool read_ecdsa_public_key(connection_t *c) { return c->ecdsa; } +#ifndef DISABLE_LEGACY bool read_rsa_public_key(connection_t *c) { if(ecdsa_active(c->ecdsa)) return true; @@ -182,6 +183,7 @@ bool read_rsa_public_key(connection_t *c) { free(fname); return c->rsa; } +#endif static bool read_ecdsa_private_key(void) { FILE *fp; @@ -248,6 +250,7 @@ static bool read_invitation_key(void) { return invitation_key; } +#ifndef DISABLE_LEGACY static bool read_rsa_private_key(void) { FILE *fp; char *fname; @@ -304,6 +307,7 @@ static bool read_rsa_private_key(void) { free(fname); return myself->connection->rsa; } +#endif static timeout_t keyexpire_timeout; @@ -773,6 +777,13 @@ static bool setup_myself(void) { myself->options |= PROT_MINOR << 24; +#ifdef DISABLE_LEGACY + experimental = read_ecdsa_private_key(); + if(!experimental) { + logger(DEBUG_ALWAYS, LOG_ERR, "No private key available, cannot start tinc!"); + return false; + } +#else if(!get_config_bool(lookup_config(config_tree, "ExperimentalProtocol"), &experimental)) { experimental = read_ecdsa_private_key(); if(!experimental) @@ -790,6 +801,7 @@ static bool setup_myself(void) { return false; } } +#endif /* Ensure myport is numeric */ @@ -854,6 +866,7 @@ static bool setup_myself(void) { sptps_replaywin = replaywin; } +#ifndef DISABLE_LEGACY /* Generate packet encryption key */ if(!get_config_string(lookup_config(config_tree, "Cipher"), &cipher)) @@ -891,6 +904,7 @@ static bool setup_myself(void) { } free(digest); +#endif /* Compression */ diff --git a/src/net_socket.c b/src/net_socket.c index 1bf9d16..85bc4df 100644 --- a/src/net_socket.c +++ b/src/net_socket.c @@ -549,8 +549,10 @@ begin: c->status.connecting = true; c->name = xstrdup(outgoing->name); +#ifndef DISABLE_LEGACY c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; +#endif c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; c->last_ping_time = now.tv_sec; @@ -696,8 +698,10 @@ void handle_new_meta_connection(void *data, int flags) { c = new_connection(); c->name = xstrdup(""); +#ifndef DISABLE_LEGACY c->outcipher = myself->connection->outcipher; c->outdigest = myself->connection->outdigest; +#endif c->outmaclength = myself->connection->outmaclength; c->outcompression = myself->connection->outcompression; diff --git a/src/node.c b/src/node.c index e97bfaf..71f55b8 100644 --- a/src/node.c +++ b/src/node.c @@ -30,7 +30,7 @@ #include "utils.h" #include "xalloc.h" -static digest_t *sha256; +#include "ed25519/sha512.h" splay_tree_t *node_tree; static splay_tree_t *node_id_tree; @@ -48,8 +48,6 @@ static int node_id_compare(const node_t *a, const node_t *b) { } void init_nodes(void) { - sha256 = digest_open_by_name("sha256", sizeof(node_id_t)); - node_tree = splay_alloc_tree((splay_compare_t) node_compare, (splay_action_t) free_node); node_id_tree = splay_alloc_tree((splay_compare_t) node_id_compare, NULL); node_udp_cache = hash_alloc(0x100, sizeof(sockaddr_t)); @@ -61,8 +59,6 @@ void exit_nodes(void) { hash_free(node_udp_cache); splay_delete_tree(node_id_tree); splay_delete_tree(node_tree); - - digest_close(sha256); } node_t *new_node(void) { @@ -86,10 +82,12 @@ void free_node(node_t *n) { sockaddrfree(&n->address); +#ifndef DISABLE_LEGACY cipher_close(n->incipher); digest_close(n->indigest); cipher_close(n->outcipher); digest_close(n->outdigest); +#endif ecdsa_free(n->ecdsa); sptps_stop(&n->sptps); @@ -109,7 +107,9 @@ void free_node(node_t *n) { } void node_add(node_t *n) { - digest_create(sha256, n->name, strlen(n->name), &n->id); + unsigned char buf[64]; + sha512(n->name, strlen(n->name),buf); + memcpy(&n->id, buf, sizeof n->id); splay_insert(node_tree, n); splay_insert(node_id_tree, n); @@ -191,10 +191,15 @@ bool dump_nodes(connection_t *c) { sprintf(id + 2 * c, "%02hhx", n->id.x[c]); id[sizeof id - 1] = 0; send_request(c, "%d %d %s %s %s %d %d %d %d %x %x %s %s %d %hd %hd %hd %ld", CONTROL, REQ_DUMP_NODES, - n->name, id, 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); + n->name, id, n->hostname ?: "unknown port unknown", +#ifdef DISABLE_LEGACY + 0, 0, 0, +#else + cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (int)digest_length(n->outdigest), +#endif + 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); } return send_request(c, "%d %d", CONTROL, REQ_DUMP_NODES); diff --git a/src/node.h b/src/node.h index b6db18b..bd10add 100644 --- a/src/node.h +++ b/src/node.h @@ -57,11 +57,13 @@ typedef struct node_t { ecdsa_t *ecdsa; /* His public ECDSA key */ sptps_t sptps; +#ifndef DISABLE_LEGACY 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 */ +#endif int incompression; /* Compressionlevel, 0 = no compression */ int outcompression; /* Compressionlevel, 0 = no compression */ diff --git a/src/protocol_auth.c b/src/protocol_auth.c index cd39f28..0882ddf 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -45,6 +45,8 @@ #include "utils.h" #include "xalloc.h" +#include "ed25519/sha512.h" + ecdsa_t *invitation_key = NULL; static bool send_proxyrequest(connection_t *c) { @@ -211,17 +213,13 @@ static bool receive_invitation_sptps(void *handle, uint8_t type, const void *dat return false; // Recover the filename from the cookie and the key - digest_t *digest = digest_open_by_name("sha256", 18); - if(!digest) - abort(); char *fingerprint = ecdsa_get_base64_public_key(invitation_key); char hashbuf[18 + strlen(fingerprint)]; - char cookie[25]; + char cookie[64]; memcpy(hashbuf, data, 18); memcpy(hashbuf + 18, fingerprint, sizeof hashbuf - 18); - digest_create(digest, hashbuf, sizeof hashbuf, cookie); + sha512(hashbuf, sizeof hashbuf, cookie); b64encode_urlsafe(cookie, cookie, 18); - digest_close(digest); free(fingerprint); char filename[PATH_MAX], usedname[PATH_MAX]; @@ -412,6 +410,9 @@ bool id_h(connection_t *c, const char *request) { } bool send_metakey(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else if(!myself->connection->rsa) { logger(DEBUG_CONNECTIONS, LOG_ERR, "Peer %s (%s) uses legacy protocol which we don't support", c->name, c->hostname); return false; @@ -480,9 +481,13 @@ bool send_metakey(connection_t *c) { c->status.encryptout = true; return result; +#endif } bool metakey_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else if(!myself->connection->rsa) return false; @@ -545,9 +550,13 @@ bool metakey_h(connection_t *c, const char *request) { c->allow_request = CHALLENGE; return send_challenge(c); +#endif } bool send_challenge(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else const size_t len = rsa_size(c->rsa); char buffer[len * 2 + 1]; @@ -565,9 +574,13 @@ bool send_challenge(connection_t *c) { /* Send the challenge */ return send_request(c, "%d %s", CHALLENGE, buffer); +#endif } bool challenge_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else if(!myself->connection->rsa) return false; @@ -606,9 +619,13 @@ bool challenge_h(connection_t *c, const char *request) { c->allow_request = CHAL_REPLY; return send_request(c, "%d %s", CHAL_REPLY, buffer); +#endif } bool chal_reply_h(connection_t *c, const char *request) { +#ifdef DISABLE_LEGACY + return false; +#else char hishash[MAX_STRING_SIZE]; if(sscanf(request, "%*d " MAX_STRING, hishash) != 1) { @@ -645,9 +662,13 @@ bool chal_reply_h(connection_t *c, const char *request) { c->allow_request = ACK; return send_ack(c); +#endif } static bool send_upgrade(connection_t *c) { +#ifdef DISABLE_LEGACY + return false; +#else /* Special case when protocol_minor is 1: the other end is Ed25519 capable, * but doesn't know our key yet. So send it now. */ @@ -659,6 +680,7 @@ static bool send_upgrade(connection_t *c) { bool result = send_request(c, "%d %s", ACK, pubkey); free(pubkey); return result; +#endif } bool send_ack(connection_t *c) { diff --git a/src/protocol_key.c b/src/protocol_key.c index 8b19d90..cfa2f53 100644 --- a/src/protocol_key.c +++ b/src/protocol_key.c @@ -266,6 +266,9 @@ bool send_ans_key(node_t *to) { if(to->status.sptps) abort(); +#ifdef DISABLE_LEGACY + return false; +#else size_t keylen = myself->incipher ? cipher_keylength(myself->incipher) : 1; char key[keylen * 2 + 1]; @@ -306,6 +309,7 @@ bool send_ans_key(node_t *to) { digest_get_nid(to->indigest), (int)digest_length(to->indigest), to->incompression); +#endif } bool ans_key_h(connection_t *c, const char *request) { @@ -371,9 +375,11 @@ bool ans_key_h(connection_t *c, const char *request) { return send_request(to->nexthop->connection, "%s", request); } +#ifndef DISABLE_LEGACY /* Don't use key material until every check has passed. */ cipher_close(from->outcipher); digest_close(from->outdigest); +#endif from->status.validkey = false; if(compression < 0 || compression > 11) { @@ -408,6 +414,10 @@ bool ans_key_h(connection_t *c, const char *request) { return true; } +#ifdef DISABLE_LEGACY + logger(DEBUG_ALWAYS, LOG_ERR, "Node %s (%) uses legacy protocol!", from->name, from->hostname); + return false; +#else /* Check and lookup cipher and digest algorithms */ if(cipher) { @@ -462,4 +472,5 @@ bool ans_key_h(connection_t *c, const char *request) { send_mtu_probe(from); return true; +#endif } diff --git a/src/tincctl.c b/src/tincctl.c index abaf6ee..0eb3a25 100644 --- a/src/tincctl.c +++ b/src/tincctl.c @@ -119,8 +119,12 @@ static void usage(bool status) { " restart [tincd options] Restart tincd.\n" " reload Partially reload configuration of running tincd.\n" " pid Show PID of currently running tincd.\n" +#ifdef DISABLE_LEGACY + " generate-keys Generate a new Ed25519 public/private keypair.\n" +#else " generate-keys [bits] Generate new RSA and Ed25519 public/private keypairs.\n" " generate-rsa-keys [bits] Generate a new RSA public/private keypair.\n" +#endif " generate-ed25519-keys Generate a new Ed25519 public/private keypair.\n" " dump Dump a list of one of the following things:\n" " [reachable] nodes - all known nodes in the VPN\n" @@ -415,6 +419,7 @@ static bool ed25519_keygen(bool ask) { return true; } +#ifndef DISABLE_LEGACY /* Generate a public/private RSA keypair, and ask for a file to store them in. @@ -480,6 +485,7 @@ static bool rsa_keygen(int bits, bool ask) { return true; } +#endif char buffer[4096]; size_t blen = 0; @@ -1800,7 +1806,12 @@ static int cmd_init(int argc, char *argv[]) { fprintf(f, "Name = %s\n", name); fclose(f); - if(!rsa_keygen(2048, false) || !ed25519_keygen(false)) +#ifndef DISABLE_LEGACY + if(!rsa_keygen(2048, false)) + return 1; +#endif + + if(!ed25519_keygen(false)) return 1; check_port(name); @@ -1824,7 +1835,11 @@ static int cmd_init(int argc, char *argv[]) { } static int cmd_generate_keys(int argc, char *argv[]) { +#ifdef DISABLE_LEGACY + if(argc > 1) { +#else if(argc > 2) { +#endif fprintf(stderr, "Too many arguments!\n"); return 1; } @@ -1832,9 +1847,18 @@ static int cmd_generate_keys(int argc, char *argv[]) { if(!name) name = get_my_name(false); - return !(rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) && ed25519_keygen(true)); +#ifndef DISABLE_LEGACY + if(!rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true) + return 1; +#endif + + if(!ed25519_keygen(true)) + return 1; + + return 0; } +#ifndef DISABLE_LEGACY static int cmd_generate_rsa_keys(int argc, char *argv[]) { if(argc > 2) { fprintf(stderr, "Too many arguments!\n"); @@ -1846,6 +1870,7 @@ static int cmd_generate_rsa_keys(int argc, char *argv[]) { return !rsa_keygen(argc > 1 ? atoi(argv[1]) : 2048, true); } +#endif static int cmd_generate_ed25519_keys(int argc, char *argv[]) { if(argc > 1) { @@ -2196,7 +2221,9 @@ static const struct { {"set", cmd_config}, {"init", cmd_init}, {"generate-keys", cmd_generate_keys}, +#ifndef DISABLE_LEGACY {"generate-rsa-keys", cmd_generate_rsa_keys}, +#endif {"generate-ed25519-keys", cmd_generate_ed25519_keys}, {"help", cmd_help}, {"version", cmd_version}, -- 2.25.1