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.
This commit is contained in:
parent
8d32b283b0
commit
cfe9285adf
16 changed files with 200 additions and 64 deletions
24
configure.ac
24
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")
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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("<unknown>");
|
||||
#ifndef DISABLE_LEGACY
|
||||
c->outcipher = myself->connection->outcipher;
|
||||
c->outdigest = myself->connection->outdigest;
|
||||
#endif
|
||||
c->outmaclength = myself->connection->outmaclength;
|
||||
c->outcompression = myself->connection->outcompression;
|
||||
|
||||
|
|
25
src/node.c
25
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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
|
|
Loading…
Reference in a new issue