Make use of the improved hex and base64 functions.

Also, use base64 for all EC related data, it is shorter and easy to
distinguish from the legacy protocol.
This commit is contained in:
Guus Sliepen 2011-07-12 23:43:12 +02:00
parent 06b8271ed5
commit fec279a9c5
3 changed files with 29 additions and 50 deletions

View file

@ -134,7 +134,6 @@ bool control_h(connection_t *c, char *request) {
bool init_control(void) { bool init_control(void) {
randomize(controlcookie, sizeof controlcookie / 2); randomize(controlcookie, sizeof controlcookie / 2);
bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2); bin2hex(controlcookie, controlcookie, sizeof controlcookie / 2);
controlcookie[sizeof controlcookie - 1] = 0;
FILE *f = fopen(pidfilename, "w"); FILE *f = fopen(pidfilename, "w");
if(!f) { if(!f) {

View file

@ -143,24 +143,19 @@ bool send_metakey_ec(connection_t *c) {
size_t siglen = ecdsa_size(&myself->connection->ecdsa); size_t siglen = ecdsa_size(&myself->connection->ecdsa);
char key[ECDH_SIZE]; char key[(ECDH_SIZE + siglen) * 2 + 1];
char sig[siglen];
// TODO: include nonce? Use relevant parts of SSH or TLS protocol // TODO: include nonce? Use relevant parts of SSH or TLS protocol
if(!ecdh_generate_public(&c->ecdh, key)) if(!ecdh_generate_public(&c->ecdh, key))
return false; return false;
if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, sig)) if(!ecdsa_sign(&myself->connection->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE))
return false; return false;
char out[MAX_STRING_SIZE]; b64encode(key, key, ECDH_SIZE + siglen);
bin2hex(key, out, ECDH_SIZE);
bin2hex(sig, out + ECDH_SIZE * 2, siglen);
out[(ECDH_SIZE + siglen) * 2] = 0;
bool result = send_request(c, "%d %s", METAKEY, out); bool result = send_request(c, "%d %s", METAKEY, key);
} }
bool send_metakey(connection_t *c) { bool send_metakey(connection_t *c) {
@ -198,7 +193,6 @@ bool send_metakey(connection_t *c) {
ifdebug(SCARY_THINGS) { ifdebug(SCARY_THINGS) {
bin2hex(key, hexkey, len); bin2hex(key, hexkey, len);
hexkey[len * 2] = '\0';
logger(LOG_DEBUG, "Generated random meta key (unencrypted): %s", hexkey); logger(LOG_DEBUG, "Generated random meta key (unencrypted): %s", hexkey);
} }
@ -217,7 +211,6 @@ bool send_metakey(connection_t *c) {
/* Convert the encrypted random data to a hexadecimal formatted string */ /* Convert the encrypted random data to a hexadecimal formatted string */
bin2hex(enckey, hexkey, len); bin2hex(enckey, hexkey, len);
hexkey[len * 2] = '\0';
/* Send the meta key */ /* Send the meta key */
@ -232,31 +225,29 @@ bool send_metakey(connection_t *c) {
static bool metakey_ec_h(connection_t *c, const char *request) { static bool metakey_ec_h(connection_t *c, const char *request) {
size_t siglen = ecdsa_size(&c->ecdsa); size_t siglen = ecdsa_size(&c->ecdsa);
char in[MAX_STRING_SIZE];
char key[MAX_STRING_SIZE]; char key[MAX_STRING_SIZE];
char sig[siglen]; char sig[siglen];
logger(LOG_DEBUG, "Got ECDH metakey from %s", c->name); logger(LOG_DEBUG, "Got ECDH metakey from %s", c->name);
if(sscanf(request, "%*d " MAX_STRING, in) != 1) { if(sscanf(request, "%*d " MAX_STRING, key) != 1) {
logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname); logger(LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname);
return false; return false;
} }
if(strlen(in) != (ECDH_SIZE + siglen) * 2) { int inlen = b64decode(key, key, sizeof key);
logger(LOG_ERR, "Possible intruder %s (%s): %s %d != %d", c->name, c->hostname, "wrong keylength", strlen(in) / 2, (ECDH_SIZE + siglen));
if(inlen != (ECDH_SIZE + siglen)) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength");
return false; return false;
} }
hex2bin(in, key, ECDH_SIZE); if(!ecdsa_verify(&c->ecdsa, key, ECDH_SIZE, key + ECDH_SIZE)) {
hex2bin(in + ECDH_SIZE * 2, sig, siglen);
if(!ecdsa_verify(&c->ecdsa, key, ECDH_SIZE, sig)) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "invalid ECDSA signature"); logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "invalid ECDSA signature");
return false; return false;
} }
char shared[ECDH_SHARED_SIZE * 2 + 1]; char shared[ECDH_SHARED_SIZE];
if(!ecdh_compute_shared(&c->ecdh, key, shared)) if(!ecdh_compute_shared(&c->ecdh, key, shared))
return false; return false;
@ -294,10 +285,6 @@ static bool metakey_ec_h(connection_t *c, const char *request) {
free(seed); free(seed);
bin2hex(shared, shared, ECDH_SHARED_SIZE);
shared[ECDH_SHARED_SIZE * 2] = 0;
logger(LOG_DEBUG, "Shared secret is %s", shared);
cipher_set_key(&c->incipher, mykey, true); cipher_set_key(&c->incipher, mykey, true);
digest_set_key(&c->indigest, mykey + mykeylen, mykeylen); digest_set_key(&c->indigest, mykey + mykeylen, mykeylen);
@ -326,17 +313,17 @@ bool metakey_h(connection_t *c, char *request) {
return false; return false;
} }
/* Convert the challenge from hexadecimal back to binary */
int inlen = hex2bin(hexkey, enckey, sizeof enckey);
/* Check if the length of the meta key is all right */ /* Check if the length of the meta key is all right */
if(strlen(hexkey) != len * 2) { if(inlen != len) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength"); logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength");
return false; return false;
} }
/* Convert the challenge from hexadecimal back to binary */
hex2bin(hexkey, enckey, len);
/* Decrypt the meta key */ /* Decrypt the meta key */
if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) { if(!rsa_private_decrypt(&myself->connection->rsa, enckey, len, key)) {
@ -346,7 +333,6 @@ bool metakey_h(connection_t *c, char *request) {
ifdebug(SCARY_THINGS) { ifdebug(SCARY_THINGS) {
bin2hex(key, hexkey, len); bin2hex(key, hexkey, len);
hexkey[len * 2] = '\0';
logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey); logger(LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey);
} }
@ -383,7 +369,6 @@ bool send_challenge(connection_t *c) {
/* Convert to hex */ /* Convert to hex */
bin2hex(c->hischallenge, buffer, len); bin2hex(c->hischallenge, buffer, len);
buffer[len * 2] = '\0';
/* Send the challenge */ /* Send the challenge */
@ -401,17 +386,17 @@ bool challenge_h(connection_t *c, char *request) {
return false; return false;
} }
/* Convert the challenge from hexadecimal back to binary */
int inlen = hex2bin(buffer, buffer, sizeof buffer);
/* Check if the length of the challenge is all right */ /* Check if the length of the challenge is all right */
if(strlen(buffer) != len * 2) { if(inlen != len) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length"); logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge length");
return false; return false;
} }
/* Convert the challenge from hexadecimal back to binary */
hex2bin(buffer, buffer, len);
c->allow_request = CHAL_REPLY; c->allow_request = CHAL_REPLY;
/* Calculate the hash from the challenge we received */ /* Calculate the hash from the challenge we received */
@ -421,7 +406,6 @@ bool challenge_h(connection_t *c, char *request) {
/* Convert the hash to a hexadecimal formatted string */ /* Convert the hash to a hexadecimal formatted string */
bin2hex(digest, buffer, digestlen); bin2hex(digest, buffer, digestlen);
buffer[digestlen * 2] = '\0';
/* Send the reply */ /* Send the reply */
@ -437,16 +421,17 @@ bool chal_reply_h(connection_t *c, char *request) {
return false; return false;
} }
/* Convert the hash to binary format */
int inlen = hex2bin(hishash, hishash, sizeof hishash);
/* Check if the length of the hash is all right */ /* Check if the length of the hash is all right */
if(strlen(hishash) != digest_length(&c->outdigest) * 2) { if(inlen != digest_length(&c->outdigest)) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length"); logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong challenge reply length");
return false; return false;
} }
/* Convert the hash to binary format */
hex2bin(hishash, hishash, digest_length(&c->outdigest));
/* Verify the hash */ /* Verify the hash */

View file

@ -149,8 +149,7 @@ bool send_ans_key_ecdh(node_t *to) {
ecdh_generate_public(&to->ecdh, key); ecdh_generate_public(&to->ecdh, key);
bin2hex(key, key, ECDH_SIZE); b64encode(key, key, ECDH_SIZE);
key[ECDH_SIZE * 2] = '\0';
return send_request(to->nexthop->connection, "%d %s %s ECDH:%s %d %d %zu %d", ANS_KEY, return send_request(to->nexthop->connection, "%d %s %s ECDH:%s %d %d %zu %d", ANS_KEY,
myself->name, to->name, key, myself->name, to->name, key,
@ -176,7 +175,6 @@ bool send_ans_key(node_t *to) {
digest_set_key(&to->indigest, key, keylen); digest_set_key(&to->indigest, key, keylen);
bin2hex(key, key, keylen); bin2hex(key, key, keylen);
key[keylen * 2] = '\0';
// Reset sequence number and late packet window // Reset sequence number and late packet window
mykeyused = true; mykeyused = true;
@ -281,7 +279,7 @@ bool ans_key_h(connection_t *c, char *request) {
/* ECDH or old-style key exchange? */ /* ECDH or old-style key exchange? */
if(experimental && !strncmp(key, "ECDH:", 5)) { if(experimental && !strncmp(key, "ECDH:", 5)) {
keylen = (strlen(key) - 5) / 2; int keylen = b64decode(key + 5, key + 5, sizeof key - 5);
if(keylen != ECDH_SIZE) { if(keylen != ECDH_SIZE) {
logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);
@ -300,8 +298,6 @@ bool ans_key_h(connection_t *c, char *request) {
} }
char shared[ECDH_SHARED_SIZE * 2 + 1]; char shared[ECDH_SHARED_SIZE * 2 + 1];
char hex[ECDH_SHARED_SIZE * 2 + 1];
hex2bin(key + 5, key + 5, keylen);
if(!ecdh_compute_shared(&from->ecdh, key + 5, shared)) if(!ecdh_compute_shared(&from->ecdh, key + 5, shared))
return false; return false;
@ -349,8 +345,7 @@ bool ans_key_h(connection_t *c, char *request) {
if(strcmp(myself->name, from->name) < 0) if(strcmp(myself->name, from->name) < 0)
memmove(key, key + mykeylen * 2, hiskeylen * 2); memmove(key, key + mykeylen * 2, hiskeylen * 2);
} else { } else {
keylen = strlen(key) / 2; keylen = hex2bin(key, key, sizeof key);
hex2bin(key, key, keylen);
if(keylen != cipher_keylength(&from->outcipher)) { if(keylen != cipher_keylength(&from->outcipher)) {
logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname); logger(LOG_ERR, "Node %s (%s) uses wrong keylength!", from->name, from->hostname);