/**
* 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;
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,
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);
}
* @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);
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)
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);
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;
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;