|
@@ -596,7 +596,7 @@ static void tls_verify_handshake ( struct tls_session *tls, void *out ) {
|
596
|
596
|
|
597
|
597
|
/******************************************************************************
|
598
|
598
|
*
|
599
|
|
- * TX state machine transitions
|
|
599
|
+ * Record handling
|
600
|
600
|
*
|
601
|
601
|
******************************************************************************
|
602
|
602
|
*/
|
|
@@ -610,53 +610,6 @@ static void tls_tx_resume ( struct tls_session *tls ) {
|
610
|
610
|
process_add ( &tls->process );
|
611
|
611
|
}
|
612
|
612
|
|
613
|
|
-/**
|
614
|
|
- * Enter TX state machine active state
|
615
|
|
- *
|
616
|
|
- * @v tls TLS session
|
617
|
|
- * @v state TX state
|
618
|
|
- */
|
619
|
|
-static void tls_tx_start ( struct tls_session *tls, enum tls_tx_state state ) {
|
620
|
|
-
|
621
|
|
- /* Enter specified state */
|
622
|
|
- tls->tx_state = state;
|
623
|
|
-
|
624
|
|
- /* Resume state machine */
|
625
|
|
- tls_tx_resume ( tls );
|
626
|
|
-}
|
627
|
|
-
|
628
|
|
-/**
|
629
|
|
- * Enter TX state machine idle state
|
630
|
|
- *
|
631
|
|
- * @v tls TLS session
|
632
|
|
- */
|
633
|
|
-static void tls_tx_none ( struct tls_session *tls ) {
|
634
|
|
-
|
635
|
|
- /* Enter idle state */
|
636
|
|
- tls->tx_state = TLS_TX_NONE;
|
637
|
|
-}
|
638
|
|
-
|
639
|
|
-/**
|
640
|
|
- * Enter TX state machine data state
|
641
|
|
- *
|
642
|
|
- * @v tls TLS session
|
643
|
|
- */
|
644
|
|
-static void tls_tx_data ( struct tls_session *tls ) {
|
645
|
|
-
|
646
|
|
- /* Enter data state */
|
647
|
|
- tls->tx_state = TLS_TX_DATA;
|
648
|
|
-
|
649
|
|
- /* Send notification of a window change */
|
650
|
|
- xfer_window_changed ( &tls->plainstream );
|
651
|
|
-}
|
652
|
|
-
|
653
|
|
-/******************************************************************************
|
654
|
|
- *
|
655
|
|
- * Record handling
|
656
|
|
- *
|
657
|
|
- ******************************************************************************
|
658
|
|
- */
|
659
|
|
-
|
660
|
613
|
/**
|
661
|
614
|
* Transmit Handshake record
|
662
|
615
|
*
|
|
@@ -1025,15 +978,11 @@ static int tls_new_server_hello_done ( struct tls_session *tls,
|
1025
|
978
|
return -EINVAL;
|
1026
|
979
|
}
|
1027
|
980
|
|
1028
|
|
- /* Check that we are ready to send the Client Key Exchange */
|
1029
|
|
- if ( tls->tx_state != TLS_TX_NONE ) {
|
1030
|
|
- DBGC ( tls, "TLS %p received Server Hello Done while in "
|
1031
|
|
- "TX state %d\n", tls, tls->tx_state );
|
1032
|
|
- return -EIO;
|
1033
|
|
- }
|
1034
|
|
-
|
1035
|
|
- /* Start sending the Client Key Exchange */
|
1036
|
|
- tls_tx_start ( tls, TLS_TX_CLIENT_KEY_EXCHANGE );
|
|
981
|
+ /* Schedule Client Key Exchange, Change Cipher, and Finished */
|
|
982
|
+ tls->tx_pending |= ( TLS_TX_CLIENT_KEY_EXCHANGE |
|
|
983
|
+ TLS_TX_CHANGE_CIPHER |
|
|
984
|
+ TLS_TX_FINISHED );
|
|
985
|
+ tls_tx_resume ( tls );
|
1037
|
986
|
|
1038
|
987
|
return 0;
|
1039
|
988
|
}
|
|
@@ -1050,10 +999,15 @@ static int tls_new_finished ( struct tls_session *tls,
|
1050
|
999
|
void *data, size_t len ) {
|
1051
|
1000
|
|
1052
|
1001
|
/* FIXME: Handle this properly */
|
1053
|
|
- tls_tx_data ( tls );
|
1054
|
1002
|
( void ) data;
|
1055
|
1003
|
( void ) len;
|
1056
|
1004
|
|
|
1005
|
+ /* Mark session as ready to transmit plaintext data */
|
|
1006
|
+ tls->tx_ready = 1;
|
|
1007
|
+
|
|
1008
|
+ /* Send notification of a window change */
|
|
1009
|
+ xfer_window_changed ( &tls->plainstream );
|
|
1010
|
+
|
1057
|
1011
|
return 0;
|
1058
|
1012
|
}
|
1059
|
1013
|
|
|
@@ -1561,7 +1515,7 @@ static int tls_new_ciphertext ( struct tls_session *tls,
|
1561
|
1515
|
static size_t tls_plainstream_window ( struct tls_session *tls ) {
|
1562
|
1516
|
|
1563
|
1517
|
/* Block window unless we are ready to accept data */
|
1564
|
|
- if ( tls->tx_state != TLS_TX_DATA )
|
|
1518
|
+ if ( ! tls->tx_ready )
|
1565
|
1519
|
return 0;
|
1566
|
1520
|
|
1567
|
1521
|
return xfer_window ( &tls->cipherstream );
|
|
@@ -1581,7 +1535,7 @@ static int tls_plainstream_deliver ( struct tls_session *tls,
|
1581
|
1535
|
int rc;
|
1582
|
1536
|
|
1583
|
1537
|
/* Refuse unless we are ready to accept data */
|
1584
|
|
- if ( tls->tx_state != TLS_TX_DATA ) {
|
|
1538
|
+ if ( ! tls->tx_ready ) {
|
1585
|
1539
|
rc = -ENOTCONN;
|
1586
|
1540
|
goto done;
|
1587
|
1541
|
}
|
|
@@ -1757,29 +1711,24 @@ static void tls_tx_step ( struct tls_session *tls ) {
|
1757
|
1711
|
if ( ! xfer_window ( &tls->cipherstream ) )
|
1758
|
1712
|
return;
|
1759
|
1713
|
|
1760
|
|
- switch ( tls->tx_state ) {
|
1761
|
|
- case TLS_TX_NONE:
|
1762
|
|
- /* Nothing to do */
|
1763
|
|
- break;
|
1764
|
|
- case TLS_TX_CLIENT_HELLO:
|
|
1714
|
+ /* Send first pending transmission */
|
|
1715
|
+ if ( tls->tx_pending & TLS_TX_CLIENT_HELLO ) {
|
1765
|
1716
|
/* Send Client Hello */
|
1766
|
1717
|
if ( ( rc = tls_send_client_hello ( tls ) ) != 0 ) {
|
1767
|
1718
|
DBGC ( tls, "TLS %p could not send Client Hello: %s\n",
|
1768
|
1719
|
tls, strerror ( rc ) );
|
1769
|
1720
|
goto err;
|
1770
|
1721
|
}
|
1771
|
|
- tls_tx_none ( tls );
|
1772
|
|
- break;
|
1773
|
|
- case TLS_TX_CLIENT_KEY_EXCHANGE:
|
|
1722
|
+ tls->tx_pending &= ~TLS_TX_CLIENT_HELLO;
|
|
1723
|
+ } else if ( tls->tx_pending & TLS_TX_CLIENT_KEY_EXCHANGE ) {
|
1774
|
1724
|
/* Send Client Key Exchange */
|
1775
|
1725
|
if ( ( rc = tls_send_client_key_exchange ( tls ) ) != 0 ) {
|
1776
|
1726
|
DBGC ( tls, "TLS %p could send Client Key Exchange: "
|
1777
|
1727
|
"%s\n", tls, strerror ( rc ) );
|
1778
|
1728
|
goto err;
|
1779
|
1729
|
}
|
1780
|
|
- tls_tx_start ( tls, TLS_TX_CHANGE_CIPHER );
|
1781
|
|
- break;
|
1782
|
|
- case TLS_TX_CHANGE_CIPHER:
|
|
1730
|
+ tls->tx_pending &= ~TLS_TX_CLIENT_KEY_EXCHANGE;
|
|
1731
|
+ } else if ( tls->tx_pending & TLS_TX_CHANGE_CIPHER ) {
|
1783
|
1732
|
/* Send Change Cipher, and then change the cipher in use */
|
1784
|
1733
|
if ( ( rc = tls_send_change_cipher ( tls ) ) != 0 ) {
|
1785
|
1734
|
DBGC ( tls, "TLS %p could not send Change Cipher: "
|
|
@@ -1794,24 +1743,21 @@ static void tls_tx_step ( struct tls_session *tls ) {
|
1794
|
1743
|
goto err;
|
1795
|
1744
|
}
|
1796
|
1745
|
tls->tx_seq = 0;
|
1797
|
|
- tls_tx_start ( tls, TLS_TX_FINISHED );
|
1798
|
|
- break;
|
1799
|
|
- case TLS_TX_FINISHED:
|
|
1746
|
+ tls->tx_pending &= ~TLS_TX_CHANGE_CIPHER;
|
|
1747
|
+ } else if ( tls->tx_pending & TLS_TX_FINISHED ) {
|
1800
|
1748
|
/* Send Finished */
|
1801
|
1749
|
if ( ( rc = tls_send_finished ( tls ) ) != 0 ) {
|
1802
|
1750
|
DBGC ( tls, "TLS %p could not send Finished: %s\n",
|
1803
|
1751
|
tls, strerror ( rc ) );
|
1804
|
1752
|
goto err;
|
1805
|
1753
|
}
|
1806
|
|
- tls_tx_none ( tls );
|
1807
|
|
- break;
|
1808
|
|
- case TLS_TX_DATA:
|
1809
|
|
- /* Nothing to do */
|
1810
|
|
- break;
|
1811
|
|
- default:
|
1812
|
|
- assert ( 0 );
|
|
1754
|
+ tls->tx_pending &= ~TLS_TX_FINISHED;
|
1813
|
1755
|
}
|
1814
|
1756
|
|
|
1757
|
+ /* Reschedule process if pending transmissions remain */
|
|
1758
|
+ if ( tls->tx_pending )
|
|
1759
|
+ tls_tx_resume ( tls );
|
|
1760
|
+
|
1815
|
1761
|
return;
|
1816
|
1762
|
|
1817
|
1763
|
err:
|
|
@@ -1862,8 +1808,8 @@ int add_tls ( struct interface *xfer, const char *name,
|
1862
|
1808
|
}
|
1863
|
1809
|
digest_init ( &md5_algorithm, tls->handshake_md5_ctx );
|
1864
|
1810
|
digest_init ( &sha1_algorithm, tls->handshake_sha1_ctx );
|
1865
|
|
- process_init_stopped ( &tls->process, &tls_process_desc, &tls->refcnt );
|
1866
|
|
- tls_tx_start ( tls, TLS_TX_CLIENT_HELLO );
|
|
1811
|
+ tls->tx_pending = TLS_TX_CLIENT_HELLO;
|
|
1812
|
+ process_init ( &tls->process, &tls_process_desc, &tls->refcnt );
|
1867
|
1813
|
|
1868
|
1814
|
/* Attach to parent interface, mortalise self, and return */
|
1869
|
1815
|
intf_plug_plug ( &tls->plainstream, xfer );
|