Added implementation of keying material export (RFC 5705) (API for PRF implementation...
[BearSSL] / src / ssl / ssl_hs_common.t0
index aa67ee8..962daa7 100644 (file)
@@ -275,7 +275,9 @@ cc: flush-record ( -- ) {
        addr-action get8 dup if
                case
                        1 of 0 do-close endof
        addr-action get8 dup if
                case
                        1 of 0 do-close endof
-                       2 of addr-application_data get8 if 0x10 or then endof
+                       2 of addr-application_data get8 1 = if
+                               0x10 or
+                       then endof
                endcase
        else
                drop
                endcase
        else
                drop
@@ -330,13 +332,18 @@ cc: flush-record ( -- ) {
 \ -- If 'cnr' is zero, then incoming data is discarded until a close_notify
 \    is received.
 \ -- At the end, the context is terminated.
 \ -- If 'cnr' is zero, then incoming data is discarded until a close_notify
 \    is received.
 \ -- At the end, the context is terminated.
+\
+\ cnr shall be either 0 or -1.
 : do-close ( cnr -- ! )
        \ 'cnr' is set to non-zero when a close_notify is received from
        \ the peer.
        { cnr }
 
 : do-close ( cnr -- ! )
        \ 'cnr' is set to non-zero when a close_notify is received from
        \ the peer.
        { cnr }
 
-       \ Get out of application data state.
-       0 addr-application_data set8
+       \ Get out of application data state. If we were accepting
+       \ application data (flag is 1), and we still expect a close_notify
+       \ from the peer (cnr is 0), then we should set the flag to 2.
+       \ In all other cases, flag should be set to 0.
+       addr-application_data get8 cnr not and 1 << addr-application_data set8
 
        \ Flush existing payload if any.
        flush-record
 
        \ Flush existing payload if any.
        flush-record
@@ -369,6 +376,10 @@ cc: flush-record ( -- ) {
                has-input? if
                        addr-record_type_in get8 21 = if
                                drop process-alerts
                has-input? if
                        addr-record_type_in get8 21 = if
                                drop process-alerts
+                               \ If we received a close_notify then we
+                               \ no longer accept incoming application
+                               \ data records.
+                               0 addr-application_data set8
                        else
                                discard-input
                        then
                        else
                                discard-input
                        then
@@ -743,6 +754,10 @@ cc: mkrand ( addr len -- ) {
 \ -- PRF for TLS-1.2:
 \       4  with SHA-256
 \       5  with SHA-384
 \ -- PRF for TLS-1.2:
 \       4  with SHA-256
 \       5  with SHA-384
+\
+\ WARNING: if adding a new cipher suite that does not use SHA-256 for the
+\ PRF (with TLS 1.2), be sure to check the suites_sha384[] array defined
+\ in ssl/ssl_keyexport.c
 
 data: cipher-suite-def
 
 
 data: cipher-suite-def
 
@@ -1008,21 +1023,22 @@ cc: switch-chapol-in ( is_client prf_id -- ) {
 cc: compute-Finished-inner ( from_client prf_id -- ) {
        int prf_id = T0_POP();
        int from_client = T0_POPi();
 cc: compute-Finished-inner ( from_client prf_id -- ) {
        int prf_id = T0_POP();
        int from_client = T0_POPi();
-       unsigned char seed[48];
-       size_t seed_len;
+       unsigned char tmp[48];
+       br_tls_prf_seed_chunk seed;
 
        br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id);
 
        br_tls_prf_impl prf = br_ssl_engine_get_PRF(ENG, prf_id);
+       seed.data = tmp;
        if (ENG->session.version >= BR_TLS12) {
        if (ENG->session.version >= BR_TLS12) {
-               seed_len = br_multihash_out(&ENG->mhash, prf_id, seed);
+               seed.len = br_multihash_out(&ENG->mhash, prf_id, tmp);
        } else {
        } else {
-               br_multihash_out(&ENG->mhash, br_md5_ID, seed);
-               br_multihash_out(&ENG->mhash, br_sha1_ID, seed + 16);
-               seed_len = 36;
+               br_multihash_out(&ENG->mhash, br_md5_ID, tmp);
+               br_multihash_out(&ENG->mhash, br_sha1_ID, tmp + 16);
+               seed.len = 36;
        }
        prf(ENG->pad, 12, ENG->session.master_secret,
                sizeof ENG->session.master_secret,
                from_client ? "client finished" : "server finished",
        }
        prf(ENG->pad, 12, ENG->session.master_secret,
                sizeof ENG->session.master_secret,
                from_client ? "client finished" : "server finished",
-               seed, seed_len);
+               1, &seed);
 }
 
 \ Receive ChangeCipherSpec and Finished from the peer.
 }
 
 \ Receive ChangeCipherSpec and Finished from the peer.