Add a return value to tls_crypto_t.derive_secrets()
authorMartin Willi <martin@revosec.ch>
Fri, 6 Jul 2012 07:28:25 +0000 (09:28 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 16 Jul 2012 12:53:33 +0000 (14:53 +0200)
src/libtls/tls_crypto.c
src/libtls/tls_crypto.h
src/libtls/tls_peer.c
src/libtls/tls_server.c

index 4d84876..61632e7 100644 (file)
@@ -1495,7 +1495,7 @@ static void derive_master(private_tls_crypto_t *this, chunk_t premaster,
 /**
  * Expand key material from master secret
  */
-static void expand_keys(private_tls_crypto_t *this,
+static bool expand_keys(private_tls_crypto_t *this,
                                                chunk_t client_random, chunk_t server_random)
 {
        chunk_t seed, block, client_write, server_write;
@@ -1577,14 +1577,15 @@ static void expand_keys(private_tls_crypto_t *this,
                this->prf->get_bytes(this->prf, this->msk_label, seed,
                                                         this->msk.len, this->msk.ptr);
        }
+       return TRUE;
 }
 
-METHOD(tls_crypto_t, derive_secrets, void,
+METHOD(tls_crypto_t, derive_secrets, bool,
        private_tls_crypto_t *this, chunk_t premaster, chunk_t session,
        identification_t *id, chunk_t client_random, chunk_t server_random)
 {
        derive_master(this, premaster, session, id, client_random, server_random);
-       expand_keys(this, client_random, server_random);
+       return expand_keys(this, client_random, server_random);
 }
 
 METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
@@ -1602,7 +1603,10 @@ METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t,
                        if (this->suite)
                        {
                                this->prf->set_key(this->prf, master);
-                               expand_keys(this, client_random, server_random);
+                               if (!expand_keys(this, client_random, server_random))
+                               {
+                                       this->suite = 0;
+                               }
                        }
                        chunk_clear(&master);
                }
index 7430aea..5512b1f 100644 (file)
@@ -515,8 +515,9 @@ struct tls_crypto_t {
         * @param id                    identity the session is bound to
         * @param client_random random data from client hello
         * @param server_random random data from server hello
+        * @return                              TRUE if secrets derived successfully
         */
-       void (*derive_secrets)(tls_crypto_t *this, chunk_t premaster,
+       bool (*derive_secrets)(tls_crypto_t *this, chunk_t premaster,
                                                   chunk_t session, identification_t *id,
                                                   chunk_t client_random, chunk_t server_random);
 
index 6091702..068dd3a 100644 (file)
@@ -913,10 +913,14 @@ static status_t send_key_exchange_encrypt(private_tls_peer_t *this,
        rng->destroy(rng);
        htoun16(premaster, TLS_1_2);
 
-       this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
-                                                                this->session, this->server,
-                                                                chunk_from_thing(this->client_random),
-                                                                chunk_from_thing(this->server_random));
+       if (!this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
+                                                                         this->session, this->server,
+                                                                         chunk_from_thing(this->client_random),
+                                                                         chunk_from_thing(this->server_random)))
+       {
+               this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               return NEED_MORE;
+       }
 
        public = find_public_key(this);
        if (!public)
@@ -958,10 +962,15 @@ static status_t send_key_exchange_dhe(private_tls_peer_t *this,
                this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
                return NEED_MORE;
        }
-       this->crypto->derive_secrets(this->crypto, premaster,
-                                                                this->session, this->server,
-                                                                chunk_from_thing(this->client_random),
-                                                                chunk_from_thing(this->server_random));
+       if (!this->crypto->derive_secrets(this->crypto, premaster,
+                                                                         this->session, this->server,
+                                                                         chunk_from_thing(this->client_random),
+                                                                         chunk_from_thing(this->server_random)))
+       {
+               this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               chunk_clear(&premaster);
+               return NEED_MORE;
+       }
        chunk_clear(&premaster);
 
        this->dh->get_my_public_value(this->dh, &pub);
index e3617dc..8d6a933 100644 (file)
@@ -436,10 +436,14 @@ static status_t process_key_exchange_encrypted(private_tls_server_t *this,
                DBG1(DBG_TLS, "decrypting Client Key Exchange failed");
        }
 
-       this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
-                                                                this->session, this->peer,
-                                                                chunk_from_thing(this->client_random),
-                                                                chunk_from_thing(this->server_random));
+       if (!this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
+                                                                         this->session, this->peer,
+                                                                         chunk_from_thing(this->client_random),
+                                                                         chunk_from_thing(this->server_random)))
+       {
+               this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               return NEED_MORE;
+       }
 
        this->state = STATE_KEY_EXCHANGE_RECEIVED;
        return NEED_MORE;
@@ -485,10 +489,15 @@ static status_t process_key_exchange_dhe(private_tls_server_t *this,
                return NEED_MORE;
        }
 
-       this->crypto->derive_secrets(this->crypto, premaster,
-                                                                this->session, this->peer,
-                                                                chunk_from_thing(this->client_random),
-                                                                chunk_from_thing(this->server_random));
+       if (!this->crypto->derive_secrets(this->crypto, premaster,
+                                                                         this->session, this->peer,
+                                                                         chunk_from_thing(this->client_random),
+                                                                         chunk_from_thing(this->server_random)))
+       {
+               this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
+               chunk_clear(&premaster);
+               return NEED_MORE;
+       }
        chunk_clear(&premaster);
 
        this->state = STATE_KEY_EXCHANGE_RECEIVED;