summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2012-03-03 23:29:20 +0100
committerMichael Brown2012-03-03 23:29:20 +0100
commita42f6cab144f1f65295dc194e70b3f05ffa1c560 (patch)
treef6d22d0c73702d70324a284a6db20d43363d5a5e
parent[tls] Allow transmitted records to be scheduled independently (diff)
downloadipxe-a42f6cab144f1f65295dc194e70b3f05ffa1c560.tar.gz
ipxe-a42f6cab144f1f65295dc194e70b3f05ffa1c560.tar.xz
ipxe-a42f6cab144f1f65295dc194e70b3f05ffa1c560.zip
[tls] Verify the contents of the Finished record
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/net/tls.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/src/net/tls.c b/src/net/tls.c
index edf8d9fb..28a4ba4e 100644
--- a/src/net/tls.c
+++ b/src/net/tls.c
@@ -997,10 +997,31 @@ static int tls_new_server_hello_done ( struct tls_session *tls,
*/
static int tls_new_finished ( struct tls_session *tls,
void *data, size_t len ) {
+ struct {
+ uint8_t verify_data[12];
+ char next[0];
+ } __attribute__ (( packed )) *finished = data;
+ void *end = finished->next;
+ uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE];
+ uint8_t verify_data[ sizeof ( finished->verify_data ) ];
+
+ /* Sanity check */
+ if ( end != ( data + len ) ) {
+ DBGC ( tls, "TLS %p received overlength Finished\n", tls );
+ DBGC_HD ( tls, data, len );
+ return -EINVAL;
+ }
- /* FIXME: Handle this properly */
- ( void ) data;
- ( void ) len;
+ /* Verify data */
+ tls_verify_handshake ( tls, digest );
+ tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
+ verify_data, sizeof ( verify_data ), "server finished",
+ digest, sizeof ( digest ) );
+ if ( memcmp ( verify_data, finished->verify_data,
+ sizeof ( verify_data ) ) != 0 ) {
+ DBGC ( tls, "TLS %p verification failed\n", tls );
+ return -EPERM;
+ }
/* Mark session as ready to transmit plaintext data */
tls->tx_ready = 1;