Check RAND_bytes() return value, fail when getting random fails.
authorSteffan Karger <steffan@karger.me>
Tue, 29 Apr 2014 20:03:43 +0000 (22:03 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 1 May 2014 12:56:07 +0000 (14:56 +0200)
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>
src/protocol_auth.c
src/protocol_key.c

index 385e543..87ba30a 100644 (file)
@@ -215,7 +215,12 @@ bool send_metakey(connection_t *c) {
 
        /* 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:
@@ -391,7 +396,11 @@ bool send_challenge(connection_t *c) {
 
        /* 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.
+       }
 
        /* Convert to hex */
 
index 0ba5ad3..b55e830 100644 (file)
@@ -127,7 +127,8 @@ bool req_key_h(connection_t *c) {
        /* Check if this key request is for us */
 
        if(to == myself) {                      /* Yes, send our own key back */
-               send_ans_key(from);
+               if (!send_ans_key(from))
+                       return false;
        } else {
                if(tunnelserver)
                        return true;
@@ -156,7 +157,12 @@ bool send_ans_key(node_t *to) {
        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);