Added API to save and restore session parameters (for controllable session resumption...
[BearSSL] / src / ssl / ssl_hs_server.t0
index c6bb939..8176429 100644 (file)
@@ -268,7 +268,6 @@ do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id,
        0 8191 "offsetof(br_ssl_server_context, " field + ")" + make-CX
        postpone literal postpone ; ;
 
-addr-ctx: flags
 addr-ctx: client_max_version
 addr-ctx: client_suites
 addr-ctx: client_suites_num
@@ -282,10 +281,6 @@ addr-ctx: sign_hash_id
        addr-client_suites
        CX 0 1023 { BR_MAX_CIPHER_SUITES * sizeof(br_suite_translated) } ;
 
-\ Check a server flag by index.
-: flag? ( index -- bool )
-       addr-flags get32 swap >> 1 and neg ;
-
 \ Read the client SNI extension.
 : read-client-sni ( lim -- lim )
        \ Open extension value.
@@ -526,6 +521,17 @@ cc: save-session ( -- ) {
                        -1 >reneg-scsv
                then
 
+               \ Special handling for TLS_FALLBACK_SCSV. If the client
+               \ maximum version is less than our own maximum version,
+               \ then this is an undue downgrade. We mark it by setting
+               \ the client max version to 0x10000.
+               dup 0x5600 = if
+                       client-version-max addr-version_min get16 >=
+                       client-version-max addr-version_max get16 < and if
+                               -1 >client-version-max
+                       then
+               then
+
                \ Test whether the suite is supported by the server.
                scan-suite dup 0< if
                        \ We do not support this cipher suite. Note
@@ -626,6 +632,13 @@ cc: save-session ( -- ) {
        \ 0x0300 (SSL-3.0), then fail. Otherwise, we may at least send an
        \ alert with that version. We still reject versions lower than our
        \ configured minimum.
+       \ As a special case, in case of undue downgrade, we send a specific
+       \ alert (see RFC 7507). Note that this case may happen only if
+       \ we would otherwise accept the client's version.
+       client-version-max 0< if
+               addr-client_max_version get16 addr-version_out set16
+               86 fail-alert
+       then
        addr-version_max get16
        dup client-version-max > if drop client-version-max then
        dup 0x0300 < if ERR_BAD_VERSION fail then
@@ -672,6 +685,7 @@ cc: save-session ( -- ) {
 
        \ We are not resuming, so a new session ID should be generated.
        addr-session_id 32 mkrand
+       32 addr-session_id_len set8
 
        \ Translate common cipher suites, then squeeze out holes: there
        \ may be holes because of the way we fill the list when the
@@ -993,18 +1007,17 @@ cc: do-ecdhe-part2 ( len prf_id -- ) {
                        endof
                        0x01 of
                                \ Reject renegotiations if the peer does not
-                               \ support secure renegotiation. As allowed
-                               \ by RFC 5246, we do not send a
-                               \ no_renegotiation alert and just ignore the
-                               \ HelloRequest.
+                               \ support secure renegotiation, or if the
+                               \ "no renegotiation" flag is set.
                                drop
-                               addr-reneg get8 1 <> if
-                                       0 do-handshake
-                               else
+                               addr-reneg get8 1 = 1 flag? or if
                                        flush-record
                                        begin can-output? not while
                                                wait-co drop
                                        repeat
+                                       100 send-warning
+                               else
+                                       0 do-handshake
                                then
                        endof
                        ERR_UNEXPECTED fail