return toupper(c) - 'A' + 10;
}
-
-void hex2bin(char *src, char *dst, int length) {
- int i;
- for(i = 0; i < length; i++)
+bool hex2bin(char *src, char *dst, int length) {
+ for(int i = 0; i < length; i++) {
+ if(!isxdigit(src[i * 2]) || !isxdigit(src[i * 2 + 1]))
+ return false;
dst[i] = charhex2bin(src[i * 2]) * 16 + charhex2bin(src[i * 2 + 1]);
+ }
+ return true;
}
void bin2hex(char *src, char *dst, int length) {
#ifndef __TINC_UTILS_H__
#define __TINC_UTILS_H__
-extern void hex2bin(char *src, char *dst, int length);
+extern bool hex2bin(char *src, char *dst, int length);
extern void bin2hex(char *src, char *dst, int length);
#ifdef HAVE_MINGW
/* First, check for simple PublicKey statement */
if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) {
- BN_hex2bn(&c->rsa_key->n, key);
+ if(BN_hex2bn(&c->rsa_key->n, key) != strlen(key)) {
+ logger(LOG_ERR, "Invalid PublicKey for %s!", c->name);
+ return false;
+ }
BN_hex2bn(&c->rsa_key->e, "FFFF");
free(key);
return true;
}
myself->connection->rsa_key = RSA_new();
// RSA_blinding_on(myself->connection->rsa_key, NULL);
- BN_hex2bn(&myself->connection->rsa_key->d, key);
- BN_hex2bn(&myself->connection->rsa_key->n, pubkey);
+ if(BN_hex2bn(&myself->connection->rsa_key->d, key) != strlen(key)) {
+ logger(LOG_ERR, "Invalid PrivateKey for myself!");
+ return false;
+ }
+ if(BN_hex2bn(&myself->connection->rsa_key->n, pubkey) != strlen(pubkey)) {
+ logger(LOG_ERR, "Invalid PublicKey for myself!");
+ return false;
+ }
BN_hex2bn(&myself->connection->rsa_key->e, "FFFF");
free(key);
free(pubkey);
/* Convert the challenge from hexadecimal back to binary */
- hex2bin(buffer, buffer, len);
+ if(!hex2bin(buffer, buffer, len)) {
+ logger(LOG_ERR, "Got bad %s from %s(%s): %s", "METAKEY", c->name, c->hostname, "invalid key");
+ return false;
+ }
/* Decrypt the meta key */
/* Convert the challenge from hexadecimal back to binary */
- hex2bin(buffer, c->mychallenge, len);
+ if(!hex2bin(buffer, c->mychallenge, len)) {
+ logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHALLENGE", c->name, c->hostname, "invalid challenge");
+ return false;
+ }
c->allow_request = CHAL_REPLY;
/* Convert the hash to binary format */
- hex2bin(hishash, hishash, c->outdigest->md_size);
+ if(!hex2bin(hishash, hishash, c->outdigest->md_size)) {
+ logger(LOG_ERR, "Got bad %s from %s(%s): %s", "CHAL_REPLY", c->name, c->hostname, "invalid hash");
+ return false;
+ }
/* Calculate the hash from the challenge we sent */
return send_request(to->nexthop->connection, "%s", c->buffer);
}
+ /* Don't use key material until every check has passed. */
+ from->status.validkey = false;
+
/* Update our copy of the origin's packet key */
from->outkey = xrealloc(from->outkey, strlen(key) / 2);
from->outkeylength = strlen(key) / 2;
- hex2bin(key, from->outkey, from->outkeylength);
+ if(!hex2bin(key, from->outkey, from->outkeylength)) {
+ logger(LOG_ERR, "Got bad %s from %s(%s): %s", "ANS_KEY", from->name, from->hostname, "invalid key");
+ return true;
+ }
/* Check and lookup cipher and digest algorithms */