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
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.
-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
\ 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
\ 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
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