From: Guus Sliepen Date: Thu, 7 Jul 2011 20:28:25 +0000 (+0200) Subject: Read ECDSA keys. X-Git-Tag: release-1.1pre2~23 X-Git-Url: https://git.tinc-vpn.org/git/browse?a=commitdiff_plain;h=210b5ceeeebdf742a74dcf95a0a13d69623ee001;p=tinc Read ECDSA keys. --- diff --git a/src/connection.h b/src/connection.h index 21edf110..26aa3f0c 100644 --- a/src/connection.h +++ b/src/connection.h @@ -47,6 +47,8 @@ typedef struct connection_status_t { unsigned int unused:21; } connection_status_t; +#include "ecdh.h" +#include "ecdsa.h" #include "edge.h" #include "net.h" #include "node.h" @@ -69,7 +71,9 @@ 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/private key */ + rsa_t rsa; /* his public RSA key */ + ecdsa_t ecdsa; /* his public ECDSA key */ + ecdsa_t ecdh; /* state for ECDH key exchange */ 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; diff --git a/src/net.h b/src/net.h index b24d2d4d..a4ac430d 100644 --- a/src/net.h +++ b/src/net.h @@ -141,6 +141,7 @@ extern void close_network_connections(void); extern int main_loop(void); extern void terminate_connection(struct connection_t *, bool); extern void flush_queue(struct node_t *); +extern bool read_ecdsa_public_key(struct connection_t *); extern bool read_rsa_public_key(struct connection_t *); extern void send_mtu_probe(struct node_t *); extern void handle_device_data(int, short, void *); diff --git a/src/net_setup.c b/src/net_setup.c index 7ceba360..1796c4bb 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -29,6 +29,7 @@ #include "control.h" #include "device.h" #include "digest.h" +#include "ecdsa.h" #include "graph.h" #include "logger.h" #include "net.h" @@ -44,6 +45,43 @@ char *myport; static struct event device_ev; +bool read_ecdsa_public_key(connection_t *c) { + 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); + free(p); + return result; + } + + /* Else, check for ECDSAPublicKeyFile statement and read it */ + + if(!get_config_string(lookup_config(c->config_tree, "ECDSAPublicKeyFile"), &fname)) + xasprintf(&fname, "%s/hosts/%s", confbase, c->name); + + fp = fopen(fname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading ECDSA public key file `%s': %s", + fname, strerror(errno)); + free(fname); + return false; + } + + result = ecdsa_read_pem_public_key(&c->ecdsa, fp); + fclose(fp); + + if(!result) + logger(LOG_ERR, "Reading ECDSA public key file `%s' failed: %s", fname, strerror(errno)); + free(fname); + return result; +} + bool read_rsa_public_key(connection_t *c) { FILE *fp; char *fname; @@ -81,6 +119,47 @@ bool read_rsa_public_key(connection_t *c) { return result; } +static bool read_ecdsa_private_key(void) { + FILE *fp; + char *fname; + bool result; + + /* Check for PrivateKeyFile statement and read it */ + + if(!get_config_string(lookup_config(config_tree, "ECDSAPrivateKeyFile"), &fname)) + xasprintf(&fname, "%s/ecdsa_key.priv", confbase); + + fp = fopen(fname, "r"); + + if(!fp) { + logger(LOG_ERR, "Error reading ECDSA private key file `%s': %s", + fname, strerror(errno)); + free(fname); + return false; + } + +#if !defined(HAVE_MINGW) && !defined(HAVE_CYGWIN) + struct stat s; + + if(fstat(fileno(fp), &s)) { + logger(LOG_ERR, "Could not stat ECDSA private key file `%s': %s'", fname, strerror(errno)); + free(fname); + return false; + } + + if(s.st_mode & ~0100700) + logger(LOG_WARNING, "Warning: insecure file permissions for ECDSA private key file `%s'!", fname); +#endif + + result = ecdsa_read_pem_private_key(&myself->connection->ecdsa, fp); + fclose(fp); + + if(!result) + logger(LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno)); + free(fname); + return result; +} + static bool read_rsa_private_key(void) { FILE *fp; char *fname; @@ -260,6 +339,9 @@ static bool setup_myself(void) { read_config_file(config_tree, fname); free(fname); + if(!read_ecdsa_private_key()) + return false; + if(!read_rsa_private_key()) return false;