When RAND_bytes() does not return success, the buffer contents cannot be
used. This patch makes sure the return code is checked, and the connection
fails when keys or challenges cannot be trusted.
Signed-off-by: Steffan Karger <steffan@karger.me>
/* Copy random data to the buffer */
/* Copy random data to the buffer */
- RAND_bytes((unsigned char *)c->outkey, len);
+ if (1 != RAND_bytes((unsigned char *)c->outkey, len)) {
+ int err = ERR_get_error();
+ logger(LOG_ERR, "Failed to generate meta key (%s)", "SEND_METAKEY", ERR_error_string(err, NULL));
+ return false;
+ }
+
/* The message we send must be smaller than the modulus of the RSA key.
By definition, for a key of k bits, the following formula holds:
/* The message we send must be smaller than the modulus of the RSA key.
By definition, for a key of k bits, the following formula holds:
/* Copy random data to the buffer */
/* Copy random data to the buffer */
- RAND_bytes((unsigned char *)c->hischallenge, len);
+ if (1 != RAND_bytes((unsigned char *)c->hischallenge, len)) {
+ int err = ERR_get_error();
+ logger(LOG_ERR, "Failed to generate challenge (%s)", "SEND_CHALLENGE", ERR_error_string(err, NULL));
+ return false; // Do not send predictable challenges, let connection attempt fail.
+ }
/* Check if this key request is for us */
if(to == myself) { /* Yes, send our own key back */
/* Check if this key request is for us */
if(to == myself) { /* Yes, send our own key back */
+ if (!send_ans_key(from))
+ return false;
} else {
if(tunnelserver)
return true;
} else {
if(tunnelserver)
return true;
to->inkey = xrealloc(to->inkey, to->inkeylength);
// Create a new key
to->inkey = xrealloc(to->inkey, to->inkeylength);
// Create a new key
- RAND_bytes((unsigned char *)to->inkey, to->inkeylength);
+ if (1 != RAND_bytes((unsigned char *)to->inkey, to->inkeylength)) {
+ int err = ERR_get_error();
+ logger(LOG_ERR, "Failed to generate random for key (%s)", "SEND_ANS_KEY", ERR_error_string(err, NULL));
+ return false; // Do not send insecure keys, let connection attempt fail.
+ }
+
if(to->incipher)
EVP_DecryptInit_ex(&to->inctx, to->incipher, NULL, (unsigned char *)to->inkey, (unsigned char *)to->inkey + to->incipher->key_len);
if(to->incipher)
EVP_DecryptInit_ex(&to->inctx, to->incipher, NULL, (unsigned char *)to->inkey, (unsigned char *)to->inkey + to->incipher->key_len);