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 385e54366dbd1bb4bad446446df0687503baf576..87ba30a3e919e5fb1660994bb6b39f0368614bd0 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 0ba5ad34f71b3f04cf9e510fa640806b7f62fdbe..b55e83078a045d975724de39d2d52cc0b57e61bf 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);