X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=src%2Fssl%2Fssl_hs_server.t0;h=a31ab6aaeba94934dfa525ec48aac7441b5729ca;hp=7f5fe85155bbbdcaa6f4032cf2aafc37650ba167;hb=44c79c1add4cd4a217b1dd77c8421c1d3a08dcef;hpb=b42bd5972f935ffc32019acac6f8a07ae08ae9c2 diff --git a/src/ssl/ssl_hs_server.t0 b/src/ssl/ssl_hs_server.t0 index 7f5fe85..a31ab6a 100644 --- a/src/ssl/ssl_hs_server.t0 +++ b/src/ssl/ssl_hs_server.t0 @@ -181,7 +181,7 @@ do_ecdhe_part1(br_ssl_server_context *ctx, int curve) { int hash; unsigned mask; - const unsigned char *order, *generator; + const unsigned char *order; size_t olen, glen; br_multihash_context mhc; unsigned char head[4]; @@ -213,6 +213,8 @@ do_ecdhe_part1(br_ssl_server_context *ctx, int curve) /* * Compute our ECDH point. */ +#if 0 +/* obsolete */ generator = ctx->eng.iec->generator(curve, &glen); memcpy(ctx->eng.ecdhe_point, generator, glen); ctx->eng.ecdhe_point_len = glen; @@ -221,6 +223,10 @@ do_ecdhe_part1(br_ssl_server_context *ctx, int curve) { return -BR_ERR_INVALID_ALGORITHM; } +#endif + glen = ctx->eng.iec->mulgen(ctx->eng.ecdhe_point, + ctx->ecdhe_key, olen, curve); + ctx->eng.ecdhe_point_len = glen; /* * Compute the signature. @@ -528,6 +534,41 @@ cc: set-max-frag-len ( len -- ) { close-elt close-elt ; +\ Read the ALPN extension from client. +: read-ALPN-from-client ( lim -- lim ) + \ If we do not have configured names, then we just ignore the + \ extension. + addr-protocol_names_num get16 ifnot read-ignore-16 ret then + + \ Open extension value. + read16 open-elt + + \ Open list of protocol names. + read16 open-elt + + \ Get all names and test for their support. We keep the one with + \ the lowest index (because we apply server's preferences, as + \ recommended by RFC 7301, section 3.2. We set the 'found' variable + \ to -2 and use an unsigned comparison, making -2 a huge value. + -2 { found } + begin dup while + read8 dup { len } addr-pad swap read-blob + len test-protocol-name dup found u< if + >found + else + drop + then + repeat + + \ End of extension. + close-elt + close-elt + + \ Write back found name index (or not). If no match was found, + \ then we write -1 (0xFFFF) in the index value, not 0, so that + \ the caller knows that we tried to match, and failed. + found 1+ addr-selected_protocol set16 ; + \ Call policy handler to get cipher suite, hash function identifier and \ certificate chain. Returned value is 0 (false) on failure. cc: call-policy-handler ( -- bool ) { @@ -709,6 +750,11 @@ cc: save-session ( -- ) { \ read-ignore-16 \ endof + \ ALPN + 0x0010 of + read-ALPN-from-client + endof + \ Other extensions are ignored. drop read-ignore-16 0 endcase @@ -832,6 +878,12 @@ cc: save-session ( -- ) { then addr-client_suites_num set8 + \ Check ALPN. + addr-selected_protocol get16 0xFFFF = if + 3 flag? if 120 fail-alert then + 0 addr-selected_protocol set16 + then + \ Call policy handler to obtain the cipher suite and other \ parameters. call-policy-handler ifnot 40 fail-alert then @@ -842,20 +894,28 @@ cc: save-session ( -- ) { \ Write ServerHello. : write-ServerHello ( initial -- ) { initial } - \ Compute ServerHello length. Right now we only send the - \ "secure renegotiation" extension. + \ Compute ServerHello length. 2 write8 70 + \ Compute length of Secure Renegotiation extension. addr-reneg get8 2 = if initial if 5 else 29 then else 0 then { ext-reneg-len } + + \ Compute length of Max Fragment Length extension. addr-peer_log_max_frag_len get8 if 5 else 0 then { ext-max-frag-len } - ext-reneg-len ext-max-frag-len + dup if 2 + then + + \ Compute length of ALPN extension. This also copy the + \ selected protocol name into the pad. + addr-selected_protocol get16 dup if 1- copy-protocol-name 7 + then + { ext-ALPN-len } + + \ Adjust ServerHello length to account for the extensions. + ext-reneg-len ext-max-frag-len + ext-ALPN-len + dup if 2 + then + write24 \ Protocol version @@ -880,7 +940,7 @@ cc: save-session ( -- ) { 0 write8 \ Extensions - ext-reneg-len ext-max-frag-len + dup if + ext-reneg-len ext-max-frag-len + ext-ALPN-len + dup if write16 ext-reneg-len dup if 0xFF01 write16 @@ -893,6 +953,16 @@ cc: save-session ( -- ) { 0x0001 write16 1 write16 addr-peer_log_max_frag_len get8 8 - write8 then + ext-ALPN-len dup if + \ Note: the selected protocol name was previously + \ copied into the pad. + 0x0010 write16 + 4 - dup write16 + 2- dup write16 + 1- addr-pad swap write-blob-head8 + else + drop + then else drop then ; @@ -1289,6 +1359,7 @@ cc: verify-CV-sig ( sig-len -- err ) { : do-handshake ( initial -- ) 0 addr-application_data set8 22 addr-record_type_out set8 + 0 addr-selected_protocol set16 multihash-init read-ClientHello more-incoming-bytes? if ERR_UNEXPECTED fail then