X-Git-Url: https://tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=src%2Fprotocol_auth.c;h=65e96342f7f3504ab840f2b85080f9f8acb1aa97;hp=a542ca9ea922813b75cc741f24dbe8d1f2550c9c;hb=65d6f023c46ac3a087f59b60762f87c869783f21;hpb=efd21e232dced3225f119aeb7a585ebf55b7cf77 diff --git a/src/protocol_auth.c b/src/protocol_auth.c index a542ca9e..65e96342 100644 --- a/src/protocol_auth.c +++ b/src/protocol_auth.c @@ -31,12 +31,14 @@ #include "edge.h" #include "graph.h" #include "logger.h" +#include "meta.h" #include "net.h" #include "netutl.h" #include "node.h" #include "prf.h" #include "protocol.h" #include "rsa.h" +#include "sptps.h" #include "utils.h" #include "xalloc.h" @@ -122,9 +124,10 @@ bool id_h(connection_t *c, char *request) { return false; } - if(experimental && c->protocol_minor >= 2) + if(experimental && c->protocol_minor >= 2) { if(!read_ecdsa_public_key(c)) return false; + } } else { if(c->protocol_minor && !ecdsa_active(&c->ecdsa)) c->protocol_minor = 1; @@ -132,30 +135,19 @@ bool id_h(connection_t *c, char *request) { c->allow_request = METAKEY; - if(c->protocol_minor >= 2) - return send_metakey_ec(c); - else - return send_metakey(c); -} - -bool send_metakey_ec(connection_t *c) { - logger(LOG_DEBUG, "Sending ECDH metakey to %s", c->name); - - size_t siglen = ecdsa_size(&myself->connection->ecdsa); - - char key[(ECDH_SIZE + siglen) * 2 + 1]; - - // TODO: include nonce? Use relevant parts of SSH or TLS protocol - - if(!ecdh_generate_public(&c->ecdh, key)) - return false; + if(c->protocol_minor >= 2) { + c->allow_request = ACK; + char label[25 + strlen(myself->name) + strlen(c->name)]; - if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) - return false; + if(c->outgoing) + snprintf(label, sizeof label, "tinc TCP key expansion %s %s", myself->name, c->name); + else + snprintf(label, sizeof label, "tinc TCP key expansion %s %s", c->name, myself->name); - b64encode(key, key, ECDH_SIZE + siglen); - - return send_request(c, "%d %s", METAKEY, key); + return start_sptps(&c->sptps, c, c->outgoing, myself->connection->ecdsa, c->ecdsa, label, sizeof label, send_meta_sptps, receive_meta_sptps); + } else { + return send_metakey(c); + } } bool send_metakey(connection_t *c) { @@ -223,84 +215,7 @@ bool send_metakey(connection_t *c) { return result; } -static bool metakey_ec_h(connection_t *c, const char *request) { - size_t siglen = ecdsa_size(&c->ecdsa); - char key[MAX_STRING_SIZE]; - - logger(LOG_DEBUG, "Got ECDH metakey from %s", c->name); - - if(sscanf(request, "%*d " MAX_STRING, key) != 1) { - logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); - return false; - } - - int inlen = b64decode(key, key, sizeof key); - - if(inlen != (ECDH_SIZE + siglen)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); - return false; - } - - if(!ecdsa_verify(&c->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) { - logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "invalid ECDSA signature"); - return false; - } - - char shared[ECDH_SHARED_SIZE]; - - if(!ecdh_compute_shared(&c->ecdh, key, shared)) - return false; - - /* Update our crypto end */ - - if(!cipher_open_by_name(&c->incipher, "aes-256-ofb")) - return false; - if(!digest_open_by_name(&c->indigest, "sha512", -1)) - return false; - if(!cipher_open_by_name(&c->outcipher, "aes-256-ofb")) - return false; - if(!digest_open_by_name(&c->outdigest, "sha512", -1)) - return false; - - size_t mykeylen = cipher_keylength(&c->incipher); - size_t hiskeylen = cipher_keylength(&c->outcipher); - - char *mykey; - char *hiskey; - char *seed; - - if(strcmp(myself->name, c->name) < 0) { - mykey = key; - hiskey = key + mykeylen * 2; - xasprintf(&seed, "tinc TCP key expansion %s %s", myself->name, c->name); - } else { - mykey = key + hiskeylen * 2; - hiskey = key; - xasprintf(&seed, "tinc TCP key expansion %s %s", c->name, myself->name); - } - - if(!prf(shared, ECDH_SHARED_SIZE, seed, strlen(seed), key, hiskeylen * 2 + mykeylen * 2)) - return false; - - free(seed); - - cipher_set_key(&c->incipher, mykey, false); - digest_set_key(&c->indigest, mykey + mykeylen, mykeylen); - - cipher_set_key(&c->outcipher, hiskey, true); - digest_set_key(&c->outdigest, hiskey + hiskeylen, hiskeylen); - - c->status.decryptin = true; - c->status.encryptout = true; - c->allow_request = CHALLENGE; - - return send_challenge(c); -} - bool metakey_h(connection_t *c, char *request) { - if(c->protocol_minor >= 2) - return metakey_ec_h(c, request); - char hexkey[MAX_STRING_SIZE]; int cipher, digest, maclength, compression; size_t len = rsa_size(&myself->connection->rsa); @@ -355,7 +270,7 @@ bool metakey_h(connection_t *c, char *request) { } bool send_challenge(connection_t *c) { - size_t len = c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&c->rsa); + size_t len = rsa_size(&c->rsa); char buffer[len * 2 + 1]; if(!c->hischallenge) @@ -376,7 +291,7 @@ bool send_challenge(connection_t *c) { bool challenge_h(connection_t *c, char *request) { char buffer[MAX_STRING_SIZE]; - size_t len = c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&myself->connection->rsa); + size_t len = rsa_size(&myself->connection->rsa); size_t digestlen = digest_length(&c->indigest); char digest[digestlen]; @@ -434,7 +349,7 @@ bool chal_reply_h(connection_t *c, char *request) { /* Verify the hash */ - if(!digest_verify(&c->outdigest, c->hischallenge, c->protocol_minor >= 2 ? ECDH_SIZE : rsa_size(&c->rsa), hishash)) { + if(!digest_verify(&c->outdigest, c->hischallenge, rsa_size(&c->rsa), hishash)) { logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply"); return false; }