Fixed scheduling error (jumping back to failed engine, could lead to segfault).
[BearSSL] / src / ssl / ssl_hs_server.t0
1 \ Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
2 \
3 \ Permission is hereby granted, free of charge, to any person obtaining
4 \ a copy of this software and associated documentation files (the
5 \ "Software"), to deal in the Software without restriction, including
6 \ without limitation the rights to use, copy, modify, merge, publish,
7 \ distribute, sublicense, and/or sell copies of the Software, and to
8 \ permit persons to whom the Software is furnished to do so, subject to
9 \ the following conditions:
10 \
11 \ The above copyright notice and this permission notice shall be
12 \ included in all copies or substantial portions of the Software.
13 \
14 \ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 \ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 \ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 \ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18 \ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 \ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 \ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 \ SOFTWARE.
22
23 \ ----------------------------------------------------------------------
24 \ Handshake processing code, for the server.
25 \ The common T0 code (ssl_hs_common.t0) shall be read first.
26
27 preamble {
28
29 /*
30 * This macro evaluates to a pointer to the server context, under that
31 * specific name. It must be noted that since the engine context is the
32 * first field of the br_ssl_server_context structure ('eng'), then
33 * pointers values of both types are interchangeable, modulo an
34 * appropriate cast. This also means that "adresses" computed as offsets
35 * within the structure work for both kinds of context.
36 */
37 #define CTX ((br_ssl_server_context *)ENG)
38
39 /*
40 * Decrypt the pre-master secret (RSA key exchange).
41 */
42 static void
43 do_rsa_decrypt(br_ssl_server_context *ctx, int prf_id,
44 unsigned char *epms, size_t len)
45 {
46 uint32_t x;
47 unsigned char rpms[48];
48
49 /*
50 * Decrypt the PMS.
51 */
52 x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable, epms, len);
53
54 /*
55 * Set the first two bytes to the maximum supported client
56 * protocol version. These bytes are used for version rollback
57 * detection; forceing the two bytes will make the master secret
58 * wrong if the bytes are not correct. This process is
59 * recommended by RFC 5246 (section 7.4.7.1).
60 */
61 br_enc16be(epms, ctx->client_max_version);
62
63 /*
64 * Make a random PMS and copy it above the decrypted value if the
65 * decryption failed. Note that we use a constant-time conditional
66 * copy.
67 */
68 br_hmac_drbg_generate(&ctx->eng.rng, rpms, sizeof rpms);
69 br_ccopy(x ^ 1, epms, rpms, sizeof rpms);
70
71 /*
72 * Compute master secret.
73 */
74 br_ssl_engine_compute_master(&ctx->eng, prf_id, epms, 48);
75
76 /*
77 * Clear the pre-master secret from RAM: it is normally a buffer
78 * in the context, hence potentially long-lived.
79 */
80 memset(epms, 0, len);
81 }
82
83 /*
84 * Common part for ECDH and ECDHE.
85 */
86 static void
87 ecdh_common(br_ssl_server_context *ctx, int prf_id,
88 unsigned char *cpoint, size_t cpoint_len, uint32_t ctl)
89 {
90 unsigned char rpms[80];
91 size_t pms_len;
92
93 /*
94 * The point length is supposed to be 1+2*Xlen, where Xlen is
95 * the length (in bytes) of the X coordinate, i.e. the pre-master
96 * secret. If the provided point is too large, then it is
97 * obviously incorrect (i.e. everybody can see that it is
98 * incorrect), so leaking that fact is not a problem.
99 */
100 pms_len = cpoint_len >> 1;
101 if (pms_len > sizeof rpms) {
102 pms_len = sizeof rpms;
103 ctl = 0;
104 }
105
106 /*
107 * Make a random PMS and copy it above the decrypted value if the
108 * decryption failed. Note that we use a constant-time conditional
109 * copy.
110 */
111 br_hmac_drbg_generate(&ctx->eng.rng, rpms, pms_len);
112 br_ccopy(ctl ^ 1, cpoint + 1, rpms, pms_len);
113
114 /*
115 * Compute master secret.
116 */
117 br_ssl_engine_compute_master(&ctx->eng, prf_id, cpoint + 1, pms_len);
118
119 /*
120 * Clear the pre-master secret from RAM: it is normally a buffer
121 * in the context, hence potentially long-lived.
122 */
123 memset(cpoint, 0, cpoint_len);
124 }
125
126 /*
127 * Do the ECDH key exchange (not ECDHE).
128 */
129 static void
130 do_ecdh(br_ssl_server_context *ctx, int prf_id,
131 unsigned char *cpoint, size_t cpoint_len)
132 {
133 uint32_t x;
134
135 /*
136 * Finalise the key exchange.
137 */
138 x = (*ctx->policy_vtable)->do_keyx(ctx->policy_vtable,
139 cpoint, cpoint_len);
140 ecdh_common(ctx, prf_id, cpoint, cpoint_len, x);
141 }
142
143 /*
144 * Do the full static ECDH key exchange. When this function is called,
145 * it has already been verified that the cipher suite uses ECDH (not ECDHE),
146 * and the client's public key (from its certificate) has type EC and is
147 * apt for key exchange.
148 */
149 static void
150 do_static_ecdh(br_ssl_server_context *ctx, int prf_id)
151 {
152 unsigned char cpoint[133];
153 size_t cpoint_len;
154 const br_x509_class **xc;
155 const br_x509_pkey *pk;
156
157 xc = ctx->eng.x509ctx;
158 pk = (*xc)->get_pkey(xc, NULL);
159 cpoint_len = pk->key.ec.qlen;
160 if (cpoint_len > sizeof cpoint) {
161 /*
162 * If the point is larger than our buffer then we need to
163 * restrict it. Length 2 is not a valid point length, so
164 * the ECDH will fail.
165 */
166 cpoint_len = 2;
167 }
168 memcpy(cpoint, pk->key.ec.q, cpoint_len);
169 do_ecdh(ctx, prf_id, cpoint, cpoint_len);
170 }
171
172 /*
173 * Do the ECDHE key exchange (part 1: generation of transient key, and
174 * computing of the point to send to the client). Returned value is the
175 * signature length (in bytes), or -x on error (with x being an error
176 * code). The encoded point is written in the ecdhe_point[] context buffer
177 * (length in ecdhe_point_len).
178 */
179 static int
180 do_ecdhe_part1(br_ssl_server_context *ctx, int curve)
181 {
182 int hash;
183 unsigned mask;
184 const unsigned char *order, *generator;
185 size_t olen, glen;
186 br_multihash_context mhc;
187 unsigned char head[4];
188 size_t hv_len, sig_len;
189
190 if (!((ctx->eng.iec->supported_curves >> curve) & 1)) {
191 return -BR_ERR_INVALID_ALGORITHM;
192 }
193 ctx->eng.ecdhe_curve = curve;
194
195 /*
196 * Generate our private key. We need a non-zero random value
197 * which is lower than the curve order, in a "large enough"
198 * range. We force the top bit to 0 and bottom bit to 1, which
199 * does the trick. Note that contrary to what happens in ECDSA,
200 * this is not a problem if we do not cover the full range of
201 * possible values.
202 */
203 order = ctx->eng.iec->order(curve, &olen);
204 mask = 0xFF;
205 while (mask >= order[0]) {
206 mask >>= 1;
207 }
208 br_hmac_drbg_generate(&ctx->eng.rng, ctx->ecdhe_key, olen);
209 ctx->ecdhe_key[0] &= mask;
210 ctx->ecdhe_key[olen - 1] |= 0x01;
211 ctx->ecdhe_key_len = olen;
212
213 /*
214 * Compute our ECDH point.
215 */
216 generator = ctx->eng.iec->generator(curve, &glen);
217 memcpy(ctx->eng.ecdhe_point, generator, glen);
218 ctx->eng.ecdhe_point_len = glen;
219 if (!ctx->eng.iec->mul(ctx->eng.ecdhe_point, glen,
220 ctx->ecdhe_key, olen, curve))
221 {
222 return -BR_ERR_INVALID_ALGORITHM;
223 }
224
225 /*
226 * Compute the signature.
227 */
228 br_multihash_zero(&mhc);
229 br_multihash_copyimpl(&mhc, &ctx->eng.mhash);
230 br_multihash_init(&mhc);
231 br_multihash_update(&mhc,
232 ctx->eng.client_random, sizeof ctx->eng.client_random);
233 br_multihash_update(&mhc,
234 ctx->eng.server_random, sizeof ctx->eng.server_random);
235 head[0] = 3;
236 head[1] = 0;
237 head[2] = curve;
238 head[3] = ctx->eng.ecdhe_point_len;
239 br_multihash_update(&mhc, head, sizeof head);
240 br_multihash_update(&mhc,
241 ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len);
242 hash = ctx->sign_hash_id;
243 if (hash) {
244 hv_len = br_multihash_out(&mhc, hash, ctx->eng.pad);
245 if (hv_len == 0) {
246 return -BR_ERR_INVALID_ALGORITHM;
247 }
248 } else {
249 if (!br_multihash_out(&mhc, br_md5_ID, ctx->eng.pad)
250 || !br_multihash_out(&mhc,
251 br_sha1_ID, ctx->eng.pad + 16))
252 {
253 return -BR_ERR_INVALID_ALGORITHM;
254 }
255 hv_len = 36;
256 }
257 sig_len = (*ctx->policy_vtable)->do_sign(ctx->policy_vtable,
258 hash, hv_len, ctx->eng.pad, sizeof ctx->eng.pad);
259 return sig_len ? (int)sig_len : -BR_ERR_INVALID_ALGORITHM;
260 }
261
262 /*
263 * Do the ECDHE key exchange (part 2: computation of the shared secret
264 * from the point sent by the client).
265 */
266 static void
267 do_ecdhe_part2(br_ssl_server_context *ctx, int prf_id,
268 unsigned char *cpoint, size_t cpoint_len)
269 {
270 int curve;
271 uint32_t x;
272
273 curve = ctx->eng.ecdhe_curve;
274
275 /*
276 * Finalise the key exchange.
277 */
278 x = ctx->eng.iec->mul(cpoint, cpoint_len,
279 ctx->ecdhe_key, ctx->ecdhe_key_len, curve);
280 ecdh_common(ctx, prf_id, cpoint, cpoint_len, x);
281
282 /*
283 * Clear the ECDHE private key. Forward Secrecy is achieved insofar
284 * as that key does not get stolen, so we'd better destroy it
285 * as soon as it ceases to be useful.
286 */
287 memset(ctx->ecdhe_key, 0, ctx->ecdhe_key_len);
288 }
289
290 /*
291 * Offset for hash value within the pad (when obtaining all hash values,
292 * in preparation for verification of the CertificateVerify message).
293 * Order is MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512; last value
294 * is used to get the total length.
295 */
296 static const unsigned char HASH_PAD_OFF[] = { 0, 16, 36, 64, 96, 144, 208 };
297
298 /*
299 * OID for hash functions in RSA signatures.
300 */
301 static const unsigned char HASH_OID_SHA1[] = {
302 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
303 };
304
305 static const unsigned char HASH_OID_SHA224[] = {
306 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04
307 };
308
309 static const unsigned char HASH_OID_SHA256[] = {
310 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
311 };
312
313 static const unsigned char HASH_OID_SHA384[] = {
314 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
315 };
316
317 static const unsigned char HASH_OID_SHA512[] = {
318 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
319 };
320
321 static const unsigned char *HASH_OID[] = {
322 HASH_OID_SHA1,
323 HASH_OID_SHA224,
324 HASH_OID_SHA256,
325 HASH_OID_SHA384,
326 HASH_OID_SHA512
327 };
328
329 /*
330 * Verify the signature in CertificateVerify. Returned value is 0 on
331 * success, or a non-zero error code. Lack of implementation of the
332 * designated signature algorithm is reported as a "bad signature"
333 * error (because it means that the peer did not honour our advertised
334 * set of supported signature algorithms).
335 */
336 static int
337 verify_CV_sig(br_ssl_server_context *ctx, size_t sig_len)
338 {
339 const br_x509_class **xc;
340 const br_x509_pkey *pk;
341 int id;
342
343 id = ctx->hash_CV_id;
344 xc = ctx->eng.x509ctx;
345 pk = (*xc)->get_pkey(xc, NULL);
346 if (pk->key_type == BR_KEYTYPE_RSA) {
347 unsigned char tmp[64];
348 const unsigned char *hash_oid;
349
350 if (id == 0) {
351 hash_oid = NULL;
352 } else {
353 hash_oid = HASH_OID[id - 2];
354 }
355 if (ctx->eng.irsavrfy == 0) {
356 return BR_ERR_BAD_SIGNATURE;
357 }
358 if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len,
359 hash_oid, ctx->hash_CV_len, &pk->key.rsa, tmp)
360 || memcmp(tmp, ctx->hash_CV, ctx->hash_CV_len) != 0)
361 {
362 return BR_ERR_BAD_SIGNATURE;
363 }
364 } else {
365 if (ctx->eng.iecdsa == 0) {
366 return BR_ERR_BAD_SIGNATURE;
367 }
368 if (!ctx->eng.iecdsa(ctx->eng.iec,
369 ctx->hash_CV, ctx->hash_CV_len,
370 &pk->key.ec, ctx->eng.pad, sig_len))
371 {
372 return BR_ERR_BAD_SIGNATURE;
373 }
374 }
375 return 0;
376 }
377
378 }
379
380 \ =======================================================================
381
382 : addr-ctx:
383 next-word { field }
384 "addr-" field + 0 1 define-word
385 0 8191 "offsetof(br_ssl_server_context, " field + ")" + make-CX
386 postpone literal postpone ; ;
387
388 addr-ctx: client_max_version
389 addr-ctx: client_suites
390 addr-ctx: client_suites_num
391 addr-ctx: hashes
392 addr-ctx: curves
393 addr-ctx: sign_hash_id
394
395 \ Get address and length of the client_suites[] buffer. Length is expressed
396 \ in bytes.
397 : addr-len-client_suites ( -- addr len )
398 addr-client_suites
399 CX 0 1023 { BR_MAX_CIPHER_SUITES * sizeof(br_suite_translated) } ;
400
401 \ Read the client SNI extension.
402 : read-client-sni ( lim -- lim )
403 \ Open extension value.
404 read16 open-elt
405
406 \ Open ServerNameList.
407 read16 open-elt
408
409 \ Find if there is a name of type 0 (host_name) with a length
410 \ that fits in our dedicated buffer.
411 begin dup while
412 read8 if
413 read-ignore-16
414 else
415 read16
416 dup 255 <= if
417 dup addr-server_name + 0 swap set8
418 addr-server_name swap read-blob
419 else
420 skip-blob
421 then
422 then
423 repeat
424
425 \ Close ServerNameList.
426 close-elt
427
428 \ Close extension value.
429 close-elt ;
430
431 \ Set the new maximum fragment length. BEWARE: this shall be called only
432 \ after reading the ClientHello and before writing the ServerHello.
433 cc: set-max-frag-len ( len -- ) {
434 size_t max_frag_len = T0_POP();
435
436 br_ssl_engine_new_max_frag_len(ENG, max_frag_len);
437
438 /*
439 * We must adjust our own output limit. Since we call this only
440 * after receiving a ClientHello and before beginning to send
441 * the ServerHello, the next output record should be empty at
442 * that point, so we can use max_frag_len as a limit.
443 */
444 if (ENG->hlen_out > max_frag_len) {
445 ENG->hlen_out = max_frag_len;
446 }
447 }
448
449 \ Read the client Max Frag Length extension.
450 : read-client-frag ( lim -- lim )
451 \ Extension value must have length exactly 1 byte.
452 read16 1 <> if ERR_BAD_FRAGLEN fail then
453 read8
454
455 \ The byte value must be 1, 2, 3 or 4.
456 dup dup 0= swap 5 >= or if ERR_BAD_FRAGLEN fail then
457
458 \ If our own maximum fragment length is greater, then we reduce
459 \ our length.
460 8 + dup addr-log_max_frag_len get8 < if
461 dup 1 swap << set-max-frag-len
462 dup addr-log_max_frag_len set8
463 addr-peer_log_max_frag_len set8
464 else
465 drop
466 then ;
467
468 \ Read the Secure Renegotiation extension from the client.
469 : read-client-reneg ( lim -- lim )
470 \ Get value length.
471 read16
472
473 \ The "reneg" value is one of:
474 \ 0 on first handshake, client support is unknown
475 \ 1 client does not support secure renegotiation
476 \ 2 client supports secure renegotiation
477 addr-reneg get8 case
478 0 of
479 \ First handshake, value length shall be 1.
480 1 = ifnot ERR_BAD_SECRENEG fail then
481 read8 if ERR_BAD_SECRENEG fail then
482 2 addr-reneg set8
483 endof
484 2 of
485 \ Renegotiation, value shall consist of 13 bytes
486 \ (header + copy of the saved client "Finished").
487 13 = ifnot ERR_BAD_SECRENEG fail then
488 read8 12 = ifnot ERR_BAD_SECRENEG fail then
489 addr-pad 12 read-blob
490 addr-saved_finished addr-pad 12 memcmp ifnot
491 ERR_BAD_SECRENEG fail
492 then
493 endof
494
495 \ If "reneg" is 1 then the client is not supposed to support
496 \ the extension, and it sends it nonetheless, which means
497 \ foul play.
498 ERR_BAD_SECRENEG fail
499 endcase ;
500
501 \ Read the Signature Algorithms extension.
502 : read-signatures ( lim -- lim )
503 \ Open extension value.
504 read16 open-elt
505
506 read-list-sign-algos addr-hashes set16
507
508 \ Close extension value.
509 close-elt ;
510
511 \ Read the Supported Curves extension.
512 : read-supported-curves ( lim -- lim )
513 \ Open extension value.
514 read16 open-elt
515
516 \ Open list of curve identifiers.
517 read16 open-elt
518
519 \ Get all supported curves.
520 0 addr-curves set32
521 begin dup while
522 read16 dup 32 < if
523 1 swap << addr-curves get32 or addr-curves set32
524 else
525 drop
526 then
527 repeat
528 close-elt
529 close-elt ;
530
531 \ Call policy handler to get cipher suite, hash function identifier and
532 \ certificate chain. Returned value is 0 (false) on failure.
533 cc: call-policy-handler ( -- bool ) {
534 int x;
535 br_ssl_server_choices choices;
536
537 x = (*CTX->policy_vtable)->choose(
538 CTX->policy_vtable, CTX, &choices);
539 ENG->session.cipher_suite = choices.cipher_suite;
540 CTX->sign_hash_id = choices.hash_id;
541 ENG->chain = choices.chain;
542 ENG->chain_len = choices.chain_len;
543 T0_PUSHi(-(x != 0));
544 }
545
546 \ Check for a remembered session.
547 cc: check-resume ( -- bool ) {
548 if (ENG->session.session_id_len == 32
549 && CTX->cache_vtable != NULL && (*CTX->cache_vtable)->load(
550 CTX->cache_vtable, CTX, &ENG->session))
551 {
552 T0_PUSHi(-1);
553 } else {
554 T0_PUSH(0);
555 }
556 }
557
558 \ Save the current session.
559 cc: save-session ( -- ) {
560 if (CTX->cache_vtable != NULL) {
561 (*CTX->cache_vtable)->save(
562 CTX->cache_vtable, CTX, &ENG->session);
563 }
564 }
565
566 \ Read ClientHello. If the session is resumed, then -1 is returned.
567 : read-ClientHello ( -- resume )
568 \ Get header, and check message type.
569 read-handshake-header 1 = ifnot ERR_UNEXPECTED fail then
570
571 \ Get maximum protocol version from client.
572 read16 dup { client-version-max } addr-client_max_version set16
573
574 \ Client random.
575 addr-client_random 32 read-blob
576
577 \ Client session ID.
578 read8 dup 32 > if ERR_OVERSIZED_ID fail then
579 dup addr-session_id_len set8
580 addr-session_id swap read-blob
581
582 \ Lookup session for resumption. We should do that here because
583 \ we need to verify that the remembered cipher suite is still
584 \ matched by this ClientHello.
585 check-resume { resume }
586
587 \ Cipher suites. We read all cipher suites from client, each time
588 \ matching against our own list. We accumulate suites in the
589 \ client_suites[] context buffer: we keep suites that are
590 \ supported by both the client and the server (so the list size
591 \ cannot exceed that of the server list), and we keep them in
592 \ either client or server preference order (depending on the
593 \ relevant flag).
594 \
595 \ We also need to identify the pseudo cipher suite for secure
596 \ renegotiation here.
597 read16 open-elt
598 0 { reneg-scsv }
599 0 { resume-suite }
600 addr-len-client_suites dup2 bzero
601 over + { css-off css-max }
602 begin
603 dup while
604 read16 dup { suite }
605
606 \ Check that when resuming a session, the requested
607 \ suite is still valid.
608 resume if
609 dup addr-cipher_suite get16 = if
610 -1 >resume-suite
611 then
612 then
613
614 \ Special handling for TLS_EMPTY_RENEGOTIATION_INFO_SCSV.
615 \ This fake cipher suite may occur only in the first
616 \ handshake.
617 dup 0x00FF = if
618 addr-reneg get8 if ERR_BAD_SECRENEG fail then
619 -1 >reneg-scsv
620 then
621
622 \ Special handling for TLS_FALLBACK_SCSV. If the client
623 \ maximum version is less than our own maximum version,
624 \ then this is an undue downgrade. We mark it by setting
625 \ the client max version to 0x10000.
626 dup 0x5600 = if
627 client-version-max addr-version_min get16 >=
628 client-version-max addr-version_max get16 < and if
629 -1 >client-version-max
630 then
631 then
632
633 \ Test whether the suite is supported by the server.
634 scan-suite dup 0< if
635 \ We do not support this cipher suite. Note
636 \ that this also covers the case of pseudo
637 \ cipher suites.
638 drop
639 else
640 \ If we use server order, then we place the
641 \ suite at the computed offset; otherwise, we
642 \ append it to the list at the current place.
643 0 flag? if
644 2 << addr-client_suites + suite swap set16
645 else
646 drop
647 \ We need to test for list length because
648 \ the client list may have duplicates,
649 \ that we do not filter. Duplicates are
650 \ invalid so this is not a problem if we
651 \ reject such clients.
652 css-off css-max >= if
653 ERR_BAD_HANDSHAKE fail
654 then
655 suite css-off set16
656 css-off 4 + >css-off
657 then
658 then
659 repeat
660 drop
661
662 \ Compression methods. We need method 0 (no compression).
663 0 { ok-compression }
664 read8 open-elt
665 begin dup while
666 read8 ifnot -1 >ok-compression then
667 repeat
668 close-elt
669
670 \ Set default values for parameters that may be affected by
671 \ extensions:
672 \ -- server name is empty
673 \ -- client is reputed to know RSA and ECDSA, both with SHA-1
674 \ -- the default elliptic curve is P-256 (secp256r1, id = 23)
675 0 addr-server_name set8
676 0x404 addr-hashes set16
677 0x800000 addr-curves set32
678
679 \ Process extensions, if any.
680 dup if
681 read16 open-elt
682 begin dup while
683 read16 case
684 \ Server Name Indication.
685 0x0000 of
686 read-client-sni
687 endof
688 \ Max Frag Length.
689 0x0001 of
690 read-client-frag
691 endof
692 \ Secure Renegotiation.
693 0xFF01 of
694 read-client-reneg
695 endof
696 \ Signature Algorithms.
697 0x000D of
698 read-signatures
699 endof
700 \ Supported Curves.
701 0x000A of
702 read-supported-curves
703 endof
704 \ Supported Point Formats.
705 \ We only support "uncompressed", that all
706 \ implementations are supposed to support,
707 \ so we can simply ignore that extension.
708 \ 0x000B of
709 \ read-ignore-16
710 \ endof
711
712 \ Other extensions are ignored.
713 drop read-ignore-16 0
714 endcase
715 repeat
716 close-elt
717 then
718
719 \ Close message.
720 close-elt
721
722 \ Cancel session resumption if the cipher suite was not found.
723 resume resume-suite and >resume
724
725 \ Now check the received data. Since the client is expecting an
726 \ answer, we can send an appropriate fatal alert on any error.
727
728 \ Compute protocol version as the minimum of our maximum version,
729 \ and the maximum version sent by the client. If that is less than
730 \ 0x0300 (SSL-3.0), then fail. Otherwise, we may at least send an
731 \ alert with that version. We still reject versions lower than our
732 \ configured minimum.
733 \ As a special case, in case of undue downgrade, we send a specific
734 \ alert (see RFC 7507). Note that this case may happen only if
735 \ we would otherwise accept the client's version.
736 client-version-max 0< if
737 addr-client_max_version get16 addr-version_out set16
738 86 fail-alert
739 then
740 addr-version_max get16
741 dup client-version-max > if drop client-version-max then
742 dup 0x0300 < if ERR_BAD_VERSION fail then
743 client-version-max addr-version_min get16 < if
744 70 fail-alert
745 then
746 \ If resuming the session, then enforce the previously negotiated
747 \ version (if still possible).
748 resume if
749 addr-version get16 client-version-max <= if
750 drop addr-version get16
751 else
752 0 >resume
753 then
754 then
755 dup addr-version set16
756 dup addr-version_in set16
757 dup addr-version_out set16
758 0x0303 >= { can-tls12 }
759
760 \ If the client sent TLS_EMPTY_RENEGOTIATION_INFO_SCSV, then
761 \ we should mark the client as "supporting secure renegotiation".
762 reneg-scsv if 2 addr-reneg set8 then
763
764 \ Check compression.
765 ok-compression ifnot 40 fail-alert then
766
767 \ Filter hash function support by what the server also supports.
768 \ If no common hash function remains with RSA and/or ECDSA, then
769 \ the corresponding ECDHE suites are not possible.
770 supported-hash-functions drop 257 *
771 addr-hashes get16 and dup addr-hashes set16
772 \ In 'can-ecdhe', bit 12 is set if ECDHE_RSA is possible, bit 13 is
773 \ set if ECDHE_ECDSA is possible.
774 dup 0xFF and 0<> neg
775 swap 8 >> 0<> 2 and or 12 << { can-ecdhe }
776
777 \ Filter supported curves. If there is no common curve between
778 \ client and us, then ECDHE suites cannot be used. Note that we
779 \ may still allow ECDH, depending on the EC key handler.
780 addr-curves get32 supported-curves and dup addr-curves set32
781 ifnot 0 >can-ecdhe then
782
783 \ If resuming a session, then the next steps are not necessary;
784 \ we won't invoke the policy handler.
785 resume if -1 ret then
786
787 \ We are not resuming, so a new session ID should be generated.
788 \ We don't check that the new ID is distinct from the one sent
789 \ by the client because probability of such an event is 2^(-256),
790 \ i.e. much (much) lower than that of an undetected transmission
791 \ error or hardware miscomputation, and with similar consequences
792 \ (handshake simply fails).
793 addr-session_id 32 mkrand
794 32 addr-session_id_len set8
795
796 \ Translate common cipher suites, then squeeze out holes: there
797 \ may be holes because of the way we fill the list when the
798 \ server preference order is enforced, and also in case some
799 \ suites are filtered out. In particular:
800 \ -- ECDHE suites are removed if there is no common hash function
801 \ (for the relevant signature algorithm) or no common curve.
802 \ -- TLS-1.2-only suites are removed if the negociated version is
803 \ TLS-1.1 or lower.
804 addr-client_suites dup >css-off
805 begin dup css-max < while
806 dup get16 dup cipher-suite-to-elements
807 dup 12 >> dup 1 = swap 2 = or if
808 dup can-ecdhe and ifnot
809 2drop 0 dup
810 then
811 then
812 can-tls12 ifnot
813 \ Suites compatible with TLS-1.0 and TLS-1.1 are
814 \ exactly the ones that use HMAC/SHA-1.
815 dup 0xF0 and 0x20 <> if
816 2drop 0 dup
817 then
818 then
819 dup if
820 css-off 2+ set16 css-off set16
821 css-off 4 + >css-off
822 else
823 2drop
824 then
825 4 +
826 repeat
827 drop
828 css-off addr-client_suites - 2 >>
829 dup ifnot
830 \ No common cipher suite: handshake failure.
831 40 fail-alert
832 then
833 addr-client_suites_num set8
834
835 \ Call policy handler to obtain the cipher suite and other
836 \ parameters.
837 call-policy-handler ifnot 40 fail-alert then
838
839 \ We are not resuming a session.
840 0 ;
841
842 \ Write ServerHello.
843 : write-ServerHello ( initial -- )
844 { initial }
845 \ Compute ServerHello length. Right now we only send the
846 \ "secure renegotiation" extension.
847 2 write8 70
848
849 addr-reneg get8 2 = if
850 initial if 5 else 29 then
851 else
852 0
853 then
854 { ext-reneg-len }
855 addr-peer_log_max_frag_len get8 if 5 else 0 then
856 { ext-max-frag-len }
857
858 ext-reneg-len ext-max-frag-len + dup if 2 + then +
859 write24
860
861 \ Protocol version
862 addr-version get16 write16
863
864 \ Server random
865 addr-server_random 4 bzero
866 addr-server_random 4 + 28 mkrand
867 addr-server_random 32 write-blob
868
869 \ Session ID
870 \ TODO: if we have no session cache at all, we might send here
871 \ an empty session ID. This would save a bit of network
872 \ bandwidth.
873 32 write8
874 addr-session_id 32 write-blob
875
876 \ Cipher suite
877 addr-cipher_suite get16 write16
878
879 \ Compression method
880 0 write8
881
882 \ Extensions
883 ext-reneg-len ext-max-frag-len + dup if
884 write16
885 ext-reneg-len dup if
886 0xFF01 write16
887 4 - dup write16
888 1- addr-saved_finished swap write-blob-head8
889 else
890 drop
891 then
892 ext-max-frag-len if
893 0x0001 write16
894 1 write16 addr-peer_log_max_frag_len get8 8 - write8
895 then
896 else
897 drop
898 then ;
899
900 \ Do the first part of ECDHE. Returned value is the computed signature
901 \ length, or a negative error code on error.
902 cc: do-ecdhe-part1 ( curve -- len ) {
903 int curve = T0_POPi();
904 T0_PUSHi(do_ecdhe_part1(CTX, curve));
905 }
906
907 \ Write the Server Key Exchange message (if applicable).
908 : write-ServerKeyExchange ( -- )
909 addr-cipher_suite get16 use-ecdhe? ifnot ret then
910
911 \ We must select an appropriate curve among the curves that
912 \ are supported both by us and the peer. Right now we use
913 \ the one with the smallest ID, which in practice means P-256.
914 \ (TODO: add some option to make that behaviour configurable.)
915 \
916 \ This loop always terminates because previous processing made
917 \ sure that ECDHE suites are not selectable if there is no common
918 \ curve.
919 addr-curves get32 0
920 begin dup2 >> 1 and 0= while 1+ repeat
921 { curve-id } drop
922
923 \ Compute the signed curve point to send.
924 curve-id do-ecdhe-part1 dup 0< if neg fail then { sig-len }
925
926 \ If using TLS-1.2+, then the hash function and signature
927 \ algorithm are explicitly encoded in the message.
928 addr-version get16 0x0303 >= { tls1.2+ }
929
930 12 write8
931 sig-len addr-ecdhe_point_len get8 + tls1.2+ 2 and + 6 + write24
932
933 \ Curve parameters: named curve with 16-bit ID.
934 3 write8 curve-id write16
935
936 \ Public point.
937 addr-ecdhe_point addr-ecdhe_point_len get8 write-blob-head8
938
939 \ If TLS-1.2+, write hash and signature identifiers.
940 tls1.2+ if
941 \ Hash identifier is in the sign_hash_id field.
942 addr-sign_hash_id get8 write8
943 \ 'use-rsa-ecdhe?' returns -1 for RSA, 0 for ECDSA.
944 \ The byte on the wire shall be 1 for RSA, 3 for ECDSA.
945 addr-cipher_suite get16 use-rsa-ecdhe? 1 << 3 + write8
946 then
947
948 \ Signature.
949 sig-len write16
950 addr-pad sig-len write-blob ;
951
952 \ Get length of the list of anchor names to send to the client. The length
953 \ includes the per-name 2-byte header, but _not_ the 2-byte header for
954 \ the list itself. If no client certificate is requested, then this
955 \ returns 0.
956 cc: ta-names-total-length ( -- len ) {
957 size_t u, len;
958
959 len = 0;
960 if (CTX->ta_names != NULL) {
961 for (u = 0; u < CTX->num_tas; u ++) {
962 len += CTX->ta_names[u].len + 2;
963 }
964 } else if (CTX->tas != NULL) {
965 for (u = 0; u < CTX->num_tas; u ++) {
966 len += CTX->tas[u].dn.len + 2;
967 }
968 }
969 T0_PUSH(len);
970 }
971
972 \ Compute length and optionally write the contents of the list of
973 \ supported client authentication methods.
974 : write-list-auth ( do_write -- len )
975 0
976 addr-cipher_suite get16 use-ecdh? if
977 2+ over if 65 write8 66 write8 then
978 then
979 supports-rsa-sign? if 1+ over if 1 write8 then then
980 supports-ecdsa? if 1+ over if 64 write8 then then
981 swap drop ;
982
983 : write-signhash-inner2 ( dow algo hashes len id -- dow algo hashes len )
984 { id }
985 over 1 id << and ifnot ret then
986 2+
987 3 pick if id write8 2 pick write8 then ;
988
989 : write-signhash-inner1 ( dow algo hashes -- dow len )
990 0
991 4 write-signhash-inner2
992 5 write-signhash-inner2
993 6 write-signhash-inner2
994 3 write-signhash-inner2
995 2 write-signhash-inner2
996 -rot 2drop ;
997
998 \ Compute length and optionally write the contents of the list of
999 \ supported sign+hash algorithms.
1000 : write-list-signhash ( do_write -- len )
1001 0 { len }
1002 \ If supporting neither RSA nor ECDSA in the engine, then we
1003 \ will do only static ECDH, and thus we claim support for
1004 \ everything (for the X.509 validator).
1005 supports-rsa-sign? supports-ecdsa? or ifnot
1006 1 0x7C write-signhash-inner1 >len
1007 3 0x7C write-signhash-inner1 len +
1008 swap drop ret
1009 then
1010 supports-rsa-sign? if
1011 1 supported-hash-functions drop
1012 write-signhash-inner1 >len
1013 then
1014 supports-ecdsa? if
1015 3 supported-hash-functions drop
1016 write-signhash-inner1 len + >len
1017 then
1018 drop len ;
1019
1020 \ Initialise index for sending the list of anchor DN.
1021 cc: begin-ta-name-list ( -- ) {
1022 CTX->cur_dn_index = 0;
1023 }
1024
1025 \ Switch to next DN in the list. Returned value is the DN length, or -1
1026 \ if the end of the list was reached.
1027 cc: begin-ta-name ( -- len ) {
1028 const br_x500_name *dn;
1029 if (CTX->cur_dn_index >= CTX->num_tas) {
1030 T0_PUSHi(-1);
1031 } else {
1032 if (CTX->ta_names == NULL) {
1033 dn = &CTX->tas[CTX->cur_dn_index].dn;
1034 } else {
1035 dn = &CTX->ta_names[CTX->cur_dn_index];
1036 }
1037 CTX->cur_dn_index ++;
1038 CTX->cur_dn = dn->data;
1039 CTX->cur_dn_len = dn->len;
1040 T0_PUSH(CTX->cur_dn_len);
1041 }
1042 }
1043
1044 \ Copy a chunk of the current DN into the pad. Returned value is the
1045 \ chunk length; this is 0 when the end of the current DN is reached.
1046 cc: copy-dn-chunk ( -- len ) {
1047 size_t clen;
1048
1049 clen = CTX->cur_dn_len;
1050 if (clen > sizeof ENG->pad) {
1051 clen = sizeof ENG->pad;
1052 }
1053 memcpy(ENG->pad, CTX->cur_dn, clen);
1054 CTX->cur_dn += clen;
1055 CTX->cur_dn_len -= clen;
1056 T0_PUSH(clen);
1057 }
1058
1059 \ Write a CertificateRequest message.
1060 : write-CertificateRequest ( -- )
1061 \ The list of client authentication types includes:
1062 \ rsa_sign (1)
1063 \ ecdsa_sign (64)
1064 \ rsa_fixed_ecdh (65)
1065 \ ecdsa_fixed_ecdh (66)
1066 \ rsa_sign and ecdsa_sign require, respectively, RSA and ECDSA
1067 \ support. Static ECDH requires that the cipher suite is ECDH.
1068 \ When we ask for static ECDH, we always send both rsa_fixed_ecdh
1069 \ and ecdsa_fixed_ecdh because what matters there is what the
1070 \ X.509 engine may support, and we do not control that.
1071 \
1072 \ With TLS 1.2, we must also send a list of supported signature
1073 \ and hash algorithms. That list is supposed to qualify both
1074 \ the engine itself, and the X.509 validator, which are separate
1075 \ in BearSSL. There again, we use the engine capabilities in that
1076 \ list, and resort to a generic all-support list if only
1077 \ static ECDH is accepted.
1078 \
1079 \ (In practice, client implementations tend to have at most one
1080 \ or two certificates, and send the chain regardless of what
1081 \ algorithms are used in it.)
1082
1083 0 write-list-auth
1084 addr-version get16 0x0303 >= if
1085 2+ 0 write-list-signhash +
1086 then
1087 ta-names-total-length + 3 +
1088
1089 \ Message header
1090 13 write8 write24
1091
1092 \ List of authentication methods
1093 0 write-list-auth write8 1 write-list-auth drop
1094
1095 \ For TLS 1.2+, list of sign+hash
1096 addr-version get16 0x0303 >= if
1097 0 write-list-signhash write16 1 write-list-signhash drop
1098 then
1099
1100 \ Trust anchor names
1101 ta-names-total-length write16
1102 begin-ta-name-list
1103 begin
1104 begin-ta-name
1105 dup 0< if drop ret then write16
1106 begin copy-dn-chunk dup while
1107 addr-pad swap write-blob
1108 repeat
1109 drop
1110 again ;
1111
1112 \ Write the Server Hello Done message.
1113 : write-ServerHelloDone ( -- )
1114 14 write8 0 write24 ;
1115
1116 \ Perform RSA decryption of the client-sent pre-master secret. The value
1117 \ is in the pad, and its length is provided as parameter.
1118 cc: do-rsa-decrypt ( len prf_id -- ) {
1119 int prf_id = T0_POPi();
1120 size_t len = T0_POP();
1121 do_rsa_decrypt(CTX, prf_id, ENG->pad, len);
1122 }
1123
1124 \ Perform ECDH (not ECDHE). The point from the client is in the pad, and
1125 \ its length is provided as parameter.
1126 cc: do-ecdh ( len prf_id -- ) {
1127 int prf_id = T0_POPi();
1128 size_t len = T0_POP();
1129 do_ecdh(CTX, prf_id, ENG->pad, len);
1130 }
1131
1132 \ Do the second part of ECDHE.
1133 cc: do-ecdhe-part2 ( len prf_id -- ) {
1134 int prf_id = T0_POPi();
1135 size_t len = T0_POP();
1136 do_ecdhe_part2(CTX, prf_id, ENG->pad, len);
1137 }
1138
1139 \ Perform static ECDH. The point from the client is the public key
1140 \ extracted from its certificate.
1141 cc: do-static-ecdh ( prf_id -- ) {
1142 do_static_ecdh(CTX, T0_POP());
1143 }
1144
1145 \ Read a ClientKeyExchange header.
1146 : read-ClientKeyExchange-header ( -- len )
1147 read-handshake-header 16 = ifnot ERR_UNEXPECTED fail then ;
1148
1149 \ Read the Client Key Exchange contents (non-empty case).
1150 : read-ClientKeyExchange-contents ( lim -- )
1151 \ What we should get depends on the cipher suite.
1152 addr-cipher_suite get16 use-rsa-keyx? if
1153 \ RSA key exchange: we expect a RSA-encrypted value.
1154 read16
1155 dup 512 > if ERR_LIMIT_EXCEEDED fail then
1156 dup { enc-rsa-len }
1157 addr-pad swap read-blob
1158 enc-rsa-len addr-cipher_suite get16 prf-id do-rsa-decrypt
1159 then
1160 addr-cipher_suite get16 dup use-ecdhe? swap use-ecdh? { ecdhe ecdh }
1161 ecdh ecdhe or if
1162 \ ECDH or ECDHE key exchange: we expect an EC point.
1163 read8 dup { ec-point-len }
1164 addr-pad swap read-blob
1165 ec-point-len addr-cipher_suite get16 prf-id
1166 ecdhe if do-ecdhe-part2 else do-ecdh then
1167 then
1168 close-elt ;
1169
1170 \ Read the Client Key Exchange (normal case).
1171 : read-ClientKeyExchange ( -- )
1172 read-ClientKeyExchange-header
1173 read-ClientKeyExchange-contents ;
1174
1175 \ Obtain all possible hash values for handshake messages so far. This
1176 \ is done because we need the hash value for the CertificateVerify
1177 \ _before_ knowing which hash function will actually be used, as this
1178 \ information is obtained from decoding the message header itself.
1179 \ All hash values are stored in the pad (208 bytes in total).
1180 cc: compute-hash-CV ( -- ) {
1181 int i;
1182
1183 for (i = 1; i <= 6; i ++) {
1184 br_multihash_out(&ENG->mhash, i,
1185 ENG->pad + HASH_PAD_OFF[i - 1]);
1186 }
1187 }
1188
1189 \ Copy the proper hash value from the pad into the dedicated buffer.
1190 \ Returned value is true (-1) on success, false (0) on error (error
1191 \ being an unimplemented hash function). The id has already been verified
1192 \ to be either 0 (for MD5+SHA-1) or one of the SHA-* functions.
1193 cc: copy-hash-CV ( hash_id -- bool ) {
1194 int id = T0_POP();
1195 size_t off, len;
1196
1197 if (id == 0) {
1198 off = 0;
1199 len = 36;
1200 } else {
1201 if (br_multihash_getimpl(&ENG->mhash, id) == 0) {
1202 T0_PUSH(0);
1203 T0_RET();
1204 }
1205 off = HASH_PAD_OFF[id - 1];
1206 len = HASH_PAD_OFF[id] - off;
1207 }
1208 memcpy(CTX->hash_CV, ENG->pad + off, len);
1209 CTX->hash_CV_len = len;
1210 CTX->hash_CV_id = id;
1211 T0_PUSHi(-1);
1212 }
1213
1214 \ Verify signature in CertificateVerify. Output is 0 on success, or a
1215 \ non-zero error code.
1216 cc: verify-CV-sig ( sig-len -- err ) {
1217 int err;
1218
1219 err = verify_CV_sig(CTX, T0_POP());
1220 T0_PUSHi(err);
1221 }
1222
1223 \ Process static ECDH.
1224 : process-static-ECDH ( ktu -- )
1225 \ Static ECDH is allowed only if the cipher suite uses ECDH, and
1226 \ the client's public key has type EC and allows key exchange.
1227 \ BR_KEYTYPE_KEYX is 0x10, and BR_KEYTYPE_EC is 2.
1228 0x1F and 0x12 = ifnot ERR_WRONG_KEY_USAGE fail then
1229 addr-cipher_suite get16
1230 dup use-ecdh? ifnot ERR_UNEXPECTED fail then
1231 prf-id
1232 do-static-ecdh ;
1233
1234 \ Read CertificateVerify header.
1235 : read-CertificateVerify-header ( -- lim )
1236 compute-hash-CV
1237 read-handshake-header 15 = ifnot ERR_UNEXPECTED fail then ;
1238
1239 \ Read CertificateVerify. The client key type + usage is expected on the
1240 \ stack.
1241 : read-CertificateVerify ( ktu -- )
1242 \ Check that the key allows for signatures.
1243 dup 0x20 and ifnot ERR_WRONG_KEY_USAGE fail then
1244 0x0F and { key-type }
1245
1246 \ Get header.
1247 read-CertificateVerify-header
1248
1249 \ With TLS 1.2+, there is an explicit hash + signature indication,
1250 \ which must be compatible with the key type.
1251 addr-version get16 0x0303 >= if
1252 \ Get hash function, then signature algorithm. The
1253 \ signature algorithm is 1 (RSA) or 3 (ECDSA) while our
1254 \ symbolic constants for key types are 1 (RSA) or 2 (EC).
1255 read16
1256 dup 0xFF and 1+ 1 >> key-type = ifnot
1257 ERR_BAD_SIGNATURE fail
1258 then
1259 8 >>
1260
1261 \ We support only SHA-1, SHA-224, SHA-256, SHA-384
1262 \ and SHA-512. We explicitly reject MD5.
1263 dup 2 < over 6 > or if ERR_INVALID_ALGORITHM fail then
1264 else
1265 \ With TLS 1.0 and 1.1, hash is MD5+SHA-1 (0) for RSA,
1266 \ SHA-1 (2) for ECDSA.
1267 key-type 0x01 = if 0 else 2 then
1268 then
1269 copy-hash-CV ifnot ERR_INVALID_ALGORITHM fail then
1270
1271 \ Read signature.
1272 read16 dup { sig-len }
1273 dup 512 > if ERR_LIMIT_EXCEEDED fail then
1274 addr-pad swap read-blob
1275 sig-len verify-CV-sig
1276 dup if fail then drop
1277
1278 close-elt ;
1279
1280 \ Send a HelloRequest.
1281 : send-HelloRequest ( -- )
1282 flush-record
1283 begin can-output? not while wait-co drop repeat
1284 22 addr-record_type_out set8
1285 0 write8 0 write24 flush-record
1286 23 addr-record_type_out set8 ;
1287
1288 \ Make a handshake.
1289 : do-handshake ( initial -- )
1290 0 addr-application_data set8
1291 22 addr-record_type_out set8
1292 multihash-init
1293 read-ClientHello
1294 more-incoming-bytes? if ERR_UNEXPECTED fail then
1295 if
1296 \ Session resumption
1297 write-ServerHello
1298 0 write-CCS-Finished
1299 0 read-CCS-Finished
1300 else
1301 \ Not a session resumption
1302 write-ServerHello
1303 write-Certificate drop
1304 write-ServerKeyExchange
1305 ta-names-total-length if
1306 write-CertificateRequest
1307 then
1308 write-ServerHelloDone
1309 flush-record
1310
1311 \ If we sent a CertificateRequest then we expect a
1312 \ Certificate message.
1313 ta-names-total-length if
1314 \ Read client certificate.
1315 0 read-Certificate
1316
1317 choice
1318 dup 0< uf
1319 \ Client certificate validation failed.
1320 2 flag? ifnot neg fail then
1321 drop
1322 read-ClientKeyExchange
1323 read-CertificateVerify-header
1324 dup skip-blob drop
1325 enduf
1326 dup 0= uf
1327 \ Client sent no certificate at all.
1328 drop
1329 2 flag? ifnot
1330 ERR_NO_CLIENT_AUTH fail
1331 then
1332 read-ClientKeyExchange
1333 enduf
1334
1335 \ Client certificate was validated.
1336 read-ClientKeyExchange-header
1337 dup ifnot
1338 \ Empty ClientKeyExchange.
1339 drop
1340 process-static-ECDH
1341 else
1342 read-ClientKeyExchange-contents
1343 read-CertificateVerify
1344 then
1345 endchoice
1346 else
1347 \ No client certificate request, we just expect
1348 \ a non-empty ClientKeyExchange.
1349 read-ClientKeyExchange
1350 then
1351 0 read-CCS-Finished
1352 0 write-CCS-Finished
1353 save-session
1354 then
1355 1 addr-application_data set8
1356 23 addr-record_type_out set8 ;
1357
1358 \ Entry point.
1359 : main ( -- ! )
1360 \ Perform initial handshake.
1361 -1 do-handshake
1362
1363 begin
1364 \ Wait for further invocation. At that point, we should
1365 \ get either an explicit call for renegotiation, or
1366 \ an incoming ClientHello handshake message.
1367 wait-co
1368 dup 0x07 and case
1369 0x00 of
1370 0x10 and if
1371 \ The best we can do is ask for a
1372 \ renegotiation, then wait for it
1373 \ to happen.
1374 send-HelloRequest
1375 then
1376 endof
1377 0x01 of
1378 \ Reject renegotiations if the peer does not
1379 \ support secure renegotiation, or if the
1380 \ "no renegotiation" flag is set.
1381 drop
1382 addr-reneg get8 1 = 1 flag? or if
1383 flush-record
1384 begin can-output? not while
1385 wait-co drop
1386 repeat
1387 100 send-warning
1388 else
1389 0 do-handshake
1390 then
1391 endof
1392 ERR_UNEXPECTED fail
1393 endcase
1394 again
1395 ;