|
@@ -997,10 +997,31 @@ static int tls_new_server_hello_done ( struct tls_session *tls,
|
997
|
997
|
*/
|
998
|
998
|
static int tls_new_finished ( struct tls_session *tls,
|
999
|
999
|
void *data, size_t len ) {
|
|
1000
|
+ struct {
|
|
1001
|
+ uint8_t verify_data[12];
|
|
1002
|
+ char next[0];
|
|
1003
|
+ } __attribute__ (( packed )) *finished = data;
|
|
1004
|
+ void *end = finished->next;
|
|
1005
|
+ uint8_t digest[MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE];
|
|
1006
|
+ uint8_t verify_data[ sizeof ( finished->verify_data ) ];
|
|
1007
|
+
|
|
1008
|
+ /* Sanity check */
|
|
1009
|
+ if ( end != ( data + len ) ) {
|
|
1010
|
+ DBGC ( tls, "TLS %p received overlength Finished\n", tls );
|
|
1011
|
+ DBGC_HD ( tls, data, len );
|
|
1012
|
+ return -EINVAL;
|
|
1013
|
+ }
|
1000
|
1014
|
|
1001
|
|
- /* FIXME: Handle this properly */
|
1002
|
|
- ( void ) data;
|
1003
|
|
- ( void ) len;
|
|
1015
|
+ /* Verify data */
|
|
1016
|
+ tls_verify_handshake ( tls, digest );
|
|
1017
|
+ tls_prf_label ( tls, &tls->master_secret, sizeof ( tls->master_secret ),
|
|
1018
|
+ verify_data, sizeof ( verify_data ), "server finished",
|
|
1019
|
+ digest, sizeof ( digest ) );
|
|
1020
|
+ if ( memcmp ( verify_data, finished->verify_data,
|
|
1021
|
+ sizeof ( verify_data ) ) != 0 ) {
|
|
1022
|
+ DBGC ( tls, "TLS %p verification failed\n", tls );
|
|
1023
|
+ return -EPERM;
|
|
1024
|
+ }
|
1004
|
1025
|
|
1005
|
1026
|
/* Mark session as ready to transmit plaintext data */
|
1006
|
1027
|
tls->tx_ready = 1;
|