New "i62" code for big integers with 64x64->128 opcodes; also improved "i31" modular...
[BearSSL] / src / ssl / ssl_hs_client.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 client.
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 client context, under that
31 * specific name. It must be noted that since the engine context is the
32 * first field of the br_ssl_client_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_client_context *)ENG)
38
39 /*
40 * Generate the pre-master secret for RSA key exchange, and encrypt it
41 * with the server's public key. Returned value is either the encrypted
42 * data length (in bytes), or -x on error, with 'x' being an error code.
43 *
44 * This code assumes that the public key has been already verified (it
45 * was properly obtained by the X.509 engine, and it has the right type,
46 * i.e. it is of type RSA and suitable for encryption).
47 */
48 static int
49 make_pms_rsa(br_ssl_client_context *ctx, int prf_id)
50 {
51 const br_x509_class **xc;
52 const br_x509_pkey *pk;
53 const unsigned char *n;
54 unsigned char *pms;
55 size_t nlen, u;
56
57 xc = ctx->eng.x509ctx;
58 pk = (*xc)->get_pkey(xc, NULL);
59
60 /*
61 * Compute actual RSA key length, in case there are leading zeros.
62 */
63 n = pk->key.rsa.n;
64 nlen = pk->key.rsa.nlen;
65 while (nlen > 0 && *n == 0) {
66 n ++;
67 nlen --;
68 }
69
70 /*
71 * We need at least 59 bytes (48 bytes for pre-master secret, and
72 * 11 bytes for the PKCS#1 type 2 padding). Note that the X.509
73 * minimal engine normally blocks RSA keys shorter than 128 bytes,
74 * so this is mostly for public keys provided explicitly by the
75 * caller.
76 */
77 if (nlen < 59) {
78 return -BR_ERR_X509_WEAK_PUBLIC_KEY;
79 }
80 if (nlen > sizeof ctx->eng.pad) {
81 return -BR_ERR_LIMIT_EXCEEDED;
82 }
83
84 /*
85 * Make PMS.
86 */
87 pms = ctx->eng.pad + nlen - 48;
88 br_enc16be(pms, ctx->eng.version_max);
89 br_hmac_drbg_generate(&ctx->eng.rng, pms + 2, 46);
90 br_ssl_engine_compute_master(&ctx->eng, prf_id, pms, 48);
91
92 /*
93 * Apply PKCS#1 type 2 padding.
94 */
95 ctx->eng.pad[0] = 0x00;
96 ctx->eng.pad[1] = 0x02;
97 ctx->eng.pad[nlen - 49] = 0x00;
98 br_hmac_drbg_generate(&ctx->eng.rng, ctx->eng.pad + 2, nlen - 51);
99 for (u = 2; u < nlen - 49; u ++) {
100 while (ctx->eng.pad[u] == 0) {
101 br_hmac_drbg_generate(&ctx->eng.rng,
102 &ctx->eng.pad[u], 1);
103 }
104 }
105
106 /*
107 * Compute RSA encryption.
108 */
109 if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) {
110 return -BR_ERR_LIMIT_EXCEEDED;
111 }
112 return (int)nlen;
113 }
114
115 /*
116 * OID for hash functions in RSA signatures.
117 */
118 static const unsigned char HASH_OID_SHA1[] = {
119 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
120 };
121
122 static const unsigned char HASH_OID_SHA224[] = {
123 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04
124 };
125
126 static const unsigned char HASH_OID_SHA256[] = {
127 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
128 };
129
130 static const unsigned char HASH_OID_SHA384[] = {
131 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
132 };
133
134 static const unsigned char HASH_OID_SHA512[] = {
135 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
136 };
137
138 static const unsigned char *HASH_OID[] = {
139 HASH_OID_SHA1,
140 HASH_OID_SHA224,
141 HASH_OID_SHA256,
142 HASH_OID_SHA384,
143 HASH_OID_SHA512
144 };
145
146 /*
147 * Check the RSA signature on the ServerKeyExchange message.
148 *
149 * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only)
150 * use_rsa non-zero for RSA signature, zero for ECDSA
151 * sig_len signature length (in bytes); signature value is in the pad
152 *
153 * Returned value is 0 on success, or an error code.
154 */
155 static int
156 verify_SKE_sig(br_ssl_client_context *ctx,
157 int hash, int use_rsa, size_t sig_len)
158 {
159 const br_x509_class **xc;
160 const br_x509_pkey *pk;
161 br_multihash_context mhc;
162 unsigned char hv[64], head[4];
163 size_t hv_len;
164
165 xc = ctx->eng.x509ctx;
166 pk = (*xc)->get_pkey(xc, NULL);
167 br_multihash_zero(&mhc);
168 br_multihash_copyimpl(&mhc, &ctx->eng.mhash);
169 br_multihash_init(&mhc);
170 br_multihash_update(&mhc,
171 ctx->eng.client_random, sizeof ctx->eng.client_random);
172 br_multihash_update(&mhc,
173 ctx->eng.server_random, sizeof ctx->eng.server_random);
174 head[0] = 3;
175 head[1] = 0;
176 head[2] = ctx->eng.ecdhe_curve;
177 head[3] = ctx->eng.ecdhe_point_len;
178 br_multihash_update(&mhc, head, sizeof head);
179 br_multihash_update(&mhc,
180 ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len);
181 if (hash) {
182 hv_len = br_multihash_out(&mhc, hash, hv);
183 if (hv_len == 0) {
184 return BR_ERR_INVALID_ALGORITHM;
185 }
186 } else {
187 if (!br_multihash_out(&mhc, br_md5_ID, hv)
188 || !br_multihash_out(&mhc, br_sha1_ID, hv + 16))
189 {
190 return BR_ERR_INVALID_ALGORITHM;
191 }
192 hv_len = 36;
193 }
194 if (use_rsa) {
195 unsigned char tmp[64];
196 const unsigned char *hash_oid;
197
198 if (hash) {
199 hash_oid = HASH_OID[hash - 2];
200 } else {
201 hash_oid = NULL;
202 }
203 if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len,
204 hash_oid, hv_len, &pk->key.rsa, tmp)
205 || memcmp(tmp, hv, hv_len) != 0)
206 {
207 return BR_ERR_BAD_SIGNATURE;
208 }
209 } else {
210 if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec,
211 ctx->eng.pad, sig_len))
212 {
213 return BR_ERR_BAD_SIGNATURE;
214 }
215 }
216 return 0;
217 }
218
219 /*
220 * Perform client-side ECDH (or ECDHE). The point that should be sent to
221 * the server is written in the pad; returned value is either the point
222 * length (in bytes), or -x on error, with 'x' being an error code.
223 *
224 * The point _from_ the server is taken from ecdhe_point[] if 'ecdhe'
225 * is non-zero, or from the X.509 engine context if 'ecdhe' is zero
226 * (for static ECDH).
227 */
228 static int
229 make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id)
230 {
231 int curve;
232 unsigned char key[66], point[133];
233 const unsigned char *order, *point_src;
234 size_t glen, olen, point_len, xoff, xlen;
235 unsigned char mask;
236
237 if (ecdhe) {
238 curve = ctx->eng.ecdhe_curve;
239 point_src = ctx->eng.ecdhe_point;
240 point_len = ctx->eng.ecdhe_point_len;
241 } else {
242 const br_x509_class **xc;
243 const br_x509_pkey *pk;
244
245 xc = ctx->eng.x509ctx;
246 pk = (*xc)->get_pkey(xc, NULL);
247 curve = pk->key.ec.curve;
248 point_src = pk->key.ec.q;
249 point_len = pk->key.ec.qlen;
250 }
251 if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) {
252 return -BR_ERR_INVALID_ALGORITHM;
253 }
254
255 /*
256 * We need to generate our key, as a non-zero random value which
257 * is lower than the curve order, in a "large enough" range. We
258 * force top bit to 0 and bottom bit to 1, which guarantees that
259 * the value is in the proper range.
260 */
261 order = ctx->eng.iec->order(curve, &olen);
262 mask = 0xFF;
263 while (mask >= order[0]) {
264 mask >>= 1;
265 }
266 br_hmac_drbg_generate(&ctx->eng.rng, key, olen);
267 key[0] &= mask;
268 key[olen - 1] |= 0x01;
269
270 /*
271 * Compute the common ECDH point, whose X coordinate is the
272 * pre-master secret.
273 */
274 ctx->eng.iec->generator(curve, &glen);
275 if (glen != point_len) {
276 return -BR_ERR_INVALID_ALGORITHM;
277 }
278
279 memcpy(point, point_src, glen);
280 if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) {
281 return -BR_ERR_INVALID_ALGORITHM;
282 }
283
284 /*
285 * The pre-master secret is the X coordinate.
286 */
287 xoff = ctx->eng.iec->xoff(curve, &xlen);
288 br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen);
289
290 ctx->eng.iec->mulgen(point, key, olen, curve);
291 memcpy(ctx->eng.pad, point, glen);
292 return (int)glen;
293 }
294
295 /*
296 * Perform full static ECDH. This occurs only in the context of client
297 * authentication with certificates: the server uses an EC public key,
298 * the cipher suite is of type ECDH (not ECDHE), the server requested a
299 * client certificate and accepts static ECDH, the client has a
300 * certificate with an EC public key in the same curve, and accepts
301 * static ECDH as well.
302 *
303 * Returned value is 0 on success, -1 on error.
304 */
305 static int
306 make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id)
307 {
308 unsigned char point[133];
309 size_t point_len;
310 const br_x509_class **xc;
311 const br_x509_pkey *pk;
312
313 xc = ctx->eng.x509ctx;
314 pk = (*xc)->get_pkey(xc, NULL);
315 point_len = pk->key.ec.qlen;
316 if (point_len > sizeof point) {
317 return -1;
318 }
319 memcpy(point, pk->key.ec.q, point_len);
320 if (!(*ctx->client_auth_vtable)->do_keyx(
321 ctx->client_auth_vtable, point, &point_len))
322 {
323 return -1;
324 }
325 br_ssl_engine_compute_master(&ctx->eng,
326 prf_id, point, point_len);
327 return 0;
328 }
329
330 /*
331 * Compute the client-side signature. This is invoked only when a
332 * signature-based client authentication was selected. The computed
333 * signature is in the pad; its length (in bytes) is returned. On
334 * error, 0 is returned.
335 */
336 static size_t
337 make_client_sign(br_ssl_client_context *ctx)
338 {
339 size_t hv_len;
340
341 /*
342 * Compute hash of handshake messages so far. This "cannot" fail
343 * because the list of supported hash functions provided to the
344 * client certificate handler was trimmed to include only the
345 * hash functions that the multi-hasher supports.
346 */
347 if (ctx->hash_id) {
348 hv_len = br_multihash_out(&ctx->eng.mhash,
349 ctx->hash_id, ctx->eng.pad);
350 } else {
351 br_multihash_out(&ctx->eng.mhash,
352 br_md5_ID, ctx->eng.pad);
353 br_multihash_out(&ctx->eng.mhash,
354 br_sha1_ID, ctx->eng.pad + 16);
355 hv_len = 36;
356 }
357 return (*ctx->client_auth_vtable)->do_sign(
358 ctx->client_auth_vtable, ctx->hash_id, hv_len,
359 ctx->eng.pad, sizeof ctx->eng.pad);
360 }
361
362 }
363
364 \ =======================================================================
365
366 : addr-ctx:
367 next-word { field }
368 "addr-" field + 0 1 define-word
369 0 8191 "offsetof(br_ssl_client_context, " field + ")" + make-CX
370 postpone literal postpone ; ;
371
372 addr-ctx: min_clienthello_len
373 addr-ctx: hashes
374 addr-ctx: auth_type
375 addr-ctx: hash_id
376
377 \ Length of the Secure Renegotiation extension. This is 5 for the
378 \ first handshake, 17 for a renegotiation (if the server supports the
379 \ extension), or 0 if we know that the server does not support the
380 \ extension.
381 : ext-reneg-length ( -- n )
382 addr-reneg get8 dup if 1 - 17 * else drop 5 then ;
383
384 \ Length of SNI extension.
385 : ext-sni-length ( -- len )
386 addr-server_name strlen dup if 9 + then ;
387
388 \ Length of Maximum Fragment Length extension.
389 : ext-frag-length ( -- len )
390 addr-log_max_frag_len get8 14 = if 0 else 5 then ;
391
392 \ Length of Signatures extension.
393 : ext-signatures-length ( -- len )
394 supported-hash-functions { num } drop 0
395 supports-rsa-sign? if num + then
396 supports-ecdsa? if num + then
397 dup if 1 << 6 + then ;
398
399 \ Write supported hash functions ( sign -- )
400 : write-hashes
401 { sign }
402 supported-hash-functions drop
403 \ We advertise hash functions in the following preference order:
404 \ SHA-256 SHA-224 SHA-384 SHA-512 SHA-1
405 \ Rationale:
406 \ -- SHA-256 and SHA-224 are more efficient on 32-bit architectures
407 \ -- SHA-1 is less than ideally collision-resistant
408 dup 0x10 and if 4 write8 sign write8 then
409 dup 0x08 and if 3 write8 sign write8 then
410 dup 0x20 and if 5 write8 sign write8 then
411 dup 0x40 and if 6 write8 sign write8 then
412 0x04 and if 2 write8 sign write8 then ;
413
414 \ Length of Supported Curves extension.
415 : ext-supported-curves-length ( -- len )
416 supported-curves dup if
417 0 { x }
418 begin dup while
419 dup 1 and x + >x
420 1 >>
421 repeat
422 drop x 1 << 6 +
423 then ;
424
425 \ Length of Supported Point Formats extension.
426 : ext-point-format-length ( -- len )
427 supported-curves if 6 else 0 then ;
428
429 \ Length of ALPN extension.
430 cc: ext-ALPN-length ( -- len ) {
431 size_t u, len;
432
433 if (ENG->protocol_names_num == 0) {
434 T0_PUSH(0);
435 T0_RET();
436 }
437 len = 6;
438 for (u = 0; u < ENG->protocol_names_num; u ++) {
439 len += 1 + strlen(ENG->protocol_names[u]);
440 }
441 T0_PUSH(len);
442 }
443
444 \ Write handshake message: ClientHello
445 : write-ClientHello ( -- )
446 { ; total-ext-length }
447
448 \ Compute length for extensions (without the general two-byte header).
449 \ This does not take padding extension into account.
450 ext-reneg-length ext-sni-length + ext-frag-length +
451 ext-signatures-length +
452 ext-supported-curves-length + ext-point-format-length +
453 ext-ALPN-length +
454 >total-ext-length
455
456 \ ClientHello type
457 1 write8
458
459 \ Compute and write length
460 39 addr-session_id_len get8 + addr-suites_num get8 1 << +
461 total-ext-length if 2+ total-ext-length + then
462 \ Compute padding (if requested).
463 addr-min_clienthello_len get16 over - dup 0> if
464 \ We well add a Pad ClientHello extension, which has its
465 \ own header (4 bytes) and might be the only extension
466 \ (2 extra bytes for the extension list header).
467 total-ext-length ifnot swap 2+ swap 2- then
468 \ Account for the extension header.
469 4 - dup 0< if drop 0 then
470 \ Adjust total extension length.
471 dup 4 + total-ext-length + >total-ext-length
472 \ Adjust ClientHello length.
473 swap 4 + over + swap
474 else
475 drop
476 -1
477 then
478 { ext-padding-amount }
479 write24
480
481 \ Protocol version
482 addr-version_max get16 write16
483
484 \ Client random
485 addr-client_random 4 bzero
486 addr-client_random 4 + 28 mkrand
487 addr-client_random 32 write-blob
488
489 \ Session ID
490 addr-session_id addr-session_id_len get8 write-blob-head8
491
492 \ Supported cipher suites. We also check here that we indeed
493 \ support all these suites.
494 addr-suites_num get8 dup 1 << write16
495 addr-suites_buf swap
496 begin
497 dup while 1-
498 over get16
499 dup suite-supported? ifnot ERR_BAD_CIPHER_SUITE fail then
500 write16
501 swap 2+ swap
502 repeat
503 2drop
504
505 \ Compression methods (only "null" compression)
506 1 write8 0 write8
507
508 \ Extensions
509 total-ext-length if
510 total-ext-length write16
511 ext-reneg-length if
512 0xFF01 write16 \ extension type (0xFF01)
513 addr-saved_finished
514 ext-reneg-length 4 - dup write16 \ extension length
515 1- write-blob-head8 \ verify data
516 then
517 ext-sni-length if
518 0x0000 write16 \ extension type (0)
519 addr-server_name
520 ext-sni-length 4 - dup write16 \ extension length
521 2 - dup write16 \ ServerNameList length
522 0 write8 \ name type: host_name
523 3 - write-blob-head16 \ the name itself
524 then
525 ext-frag-length if
526 0x0001 write16 \ extension type (1)
527 0x0001 write16 \ extension length
528 addr-log_max_frag_len get8 8 - write8
529 then
530 ext-signatures-length if
531 0x000D write16 \ extension type (13)
532 ext-signatures-length 4 - dup write16 \ extension length
533 2 - write16 \ list length
534 supports-ecdsa? if 3 write-hashes then
535 supports-rsa-sign? if 1 write-hashes then
536 then
537 \ TODO: add an API to specify preference order for curves.
538 \ Right now we send Curve25519 first, then other curves in
539 \ increasing ID values (hence P-256 in second).
540 ext-supported-curves-length dup if
541 0x000A write16 \ extension type (10)
542 4 - dup write16 \ extension length
543 2- write16 \ list length
544 supported-curves 0
545 dup 0x20000000 and if
546 0xDFFFFFFF and 29 write16
547 then
548 begin dup 32 < while
549 dup2 >> 1 and if dup write16 then
550 1+
551 repeat
552 2drop
553 else
554 drop
555 then
556 ext-point-format-length if
557 0x000B write16 \ extension type (11)
558 0x0002 write16 \ extension length
559 0x0100 write16 \ value: 1 format: uncompressed
560 then
561 ext-ALPN-length dup if
562 0x0010 write16 \ extension type (16)
563 4 - dup write16 \ extension length
564 2- write16 \ list length
565 addr-protocol_names_num get16 0
566 begin
567 dup2 > while
568 dup copy-protocol-name
569 dup write8 addr-pad swap write-blob
570 1+
571 repeat
572 2drop
573 else
574 drop
575 then
576 ext-padding-amount 0< ifnot
577 0x0015 write16 \ extension value (21)
578 ext-padding-amount
579 dup write16 \ extension length
580 begin dup while
581 1- 0 write8 repeat \ value (only zeros)
582 drop
583 then
584 then
585 ;
586
587 \ =======================================================================
588
589 \ Parse server SNI extension. If present, then it should be empty.
590 : read-server-sni ( lim -- lim )
591 read16 if ERR_BAD_SNI fail then ;
592
593 \ Parse server Max Fragment Length extension. If present, then it should
594 \ advertise the same length as the client. Note that whether the server
595 \ sends it or not changes nothing for us: we won't send any record larger
596 \ than the advertised value anyway, and we will accept incoming records
597 \ up to our input buffer length.
598 : read-server-frag ( lim -- lim )
599 read16 1 = ifnot ERR_BAD_FRAGLEN fail then
600 read8 8 + addr-log_max_frag_len get8 = ifnot ERR_BAD_FRAGLEN fail then ;
601
602 \ Parse server Secure Renegotiation extension. This is called only if
603 \ the client sent that extension, so we only have two cases to
604 \ distinguish: first handshake, and renegotiation; in the latter case,
605 \ we know that the server supports the extension, otherwise the client
606 \ would not have sent it.
607 : read-server-reneg ( lim -- lim )
608 read16
609 addr-reneg get8 ifnot
610 \ "reneg" is 0, so this is a first handshake. The server's
611 \ extension MUST be empty. We also learn that the server
612 \ supports the extension.
613 1 = ifnot ERR_BAD_SECRENEG fail then
614 read8 0 = ifnot ERR_BAD_SECRENEG fail then
615 2 addr-reneg set8
616 else
617 \ "reneg" is non-zero, and we sent an extension, so it must
618 \ be 2 and this is a renegotiation. We must verify that
619 \ the extension contents have length exactly 24 bytes and
620 \ match the saved client and server "Finished".
621 25 = ifnot ERR_BAD_SECRENEG fail then
622 read8 24 = ifnot ERR_BAD_SECRENEG fail then
623 addr-pad 24 read-blob
624 addr-saved_finished addr-pad 24 memcmp ifnot
625 ERR_BAD_SECRENEG fail
626 then
627 then ;
628
629 \ Read the ALPN extension from the server. It must contain a single name,
630 \ and that name must match one of our names.
631 : read-ALPN-from-server ( lim -- lim )
632 \ Extension contents length.
633 read16 open-elt
634 \ Length of list of names.
635 read16 open-elt
636 \ There should be a single name.
637 read8 addr-pad swap dup { len } read-blob
638 close-elt
639 close-elt
640 len test-protocol-name dup 0< if
641 3 flag? if ERR_UNEXPECTED fail then
642 drop
643 else
644 1+ addr-selected_protocol set16
645 then ;
646
647 \ Save a value in a 16-bit field, or check it in case of session resumption.
648 : check-resume ( val addr resume -- )
649 if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ;
650
651 cc: DEBUG-BLOB ( addr len -- ) {
652 extern int printf(const char *fmt, ...);
653
654 size_t len = T0_POP();
655 unsigned char *buf = (unsigned char *)CTX + T0_POP();
656 size_t u;
657
658 printf("BLOB:");
659 for (u = 0; u < len; u ++) {
660 if (u % 16 == 0) {
661 printf("\n ");
662 }
663 printf(" %02x", buf[u]);
664 }
665 printf("\n");
666 }
667
668 \ Parse incoming ServerHello. Returned value is true (-1) on session
669 \ resumption.
670 : read-ServerHello ( -- bool )
671 \ Get header, and check message type.
672 read-handshake-header 2 = ifnot ERR_UNEXPECTED fail then
673
674 \ Get protocol version.
675 read16 { version }
676 version addr-version_min get16 < version addr-version_max get16 > or if
677 ERR_UNSUPPORTED_VERSION fail
678 then
679
680 \ Enforce chosen version for subsequent records in both directions.
681 version addr-version_in get16 <> if ERR_BAD_VERSION fail then
682 version addr-version_out set16
683
684 \ Server random.
685 addr-server_random 32 read-blob
686
687 \ The "session resumption" flag.
688 0 { resume }
689
690 \ Session ID.
691 read8 { idlen }
692 idlen 32 > if ERR_OVERSIZED_ID fail then
693 addr-pad idlen read-blob
694 idlen addr-session_id_len get8 = idlen 0 > and if
695 addr-session_id addr-pad idlen memcmp if
696 \ Server session ID is non-empty and matches what
697 \ we sent, so this is a session resumption.
698 -1 >resume
699 then
700 then
701 addr-session_id addr-pad idlen memcpy
702 idlen addr-session_id_len set8
703
704 \ Record version.
705 version addr-version resume check-resume
706
707 \ Cipher suite. We check that it is part of the list of cipher
708 \ suites that we advertised.
709 \ read16 { suite ; found }
710 \ 0 >found
711 \ addr-suites_buf dup addr-suites_num get8 1 << +
712 \ begin dup2 < while
713 \ 2 - dup get16
714 \ suite = found or >found
715 \ repeat
716 \ 2drop found ifnot ERR_BAD_CIPHER_SUITE fail then
717 read16
718 dup scan-suite 0< if ERR_BAD_CIPHER_SUITE fail then
719 addr-cipher_suite resume check-resume
720
721 \ Compression method. Should be 0 (no compression).
722 read8 if ERR_BAD_COMPRESSION fail then
723
724 \ Parse extensions (if any). If there is no extension, then the
725 \ read limit (on the TOS) should be 0 at that point.
726 dup if
727 \ Length of extension list.
728 \ message size.
729 read16 open-elt
730
731 \ Enumerate extensions. For each of them, check that we
732 \ sent an extension of that type, and did not see it
733 \ yet; and then process it.
734 ext-sni-length { ok-sni }
735 ext-reneg-length { ok-reneg }
736 ext-frag-length { ok-frag }
737 ext-signatures-length { ok-signatures }
738 ext-supported-curves-length { ok-curves }
739 ext-point-format-length { ok-points }
740 ext-ALPN-length { ok-ALPN }
741 begin dup while
742 read16
743 case
744 \ Server Name Indication. The server may
745 \ send such an extension if it uses the SNI
746 \ from the client, but that "response
747 \ extension" is supposed to be empty.
748 0x0000 of
749 ok-sni ifnot
750 ERR_EXTRA_EXTENSION fail
751 then
752 0 >ok-sni
753 read-server-sni
754 endof
755
756 \ Max Frag Length. The contents shall be
757 \ a single byte whose value matches the one
758 \ sent by the client.
759 0x0001 of
760 ok-frag ifnot
761 ERR_EXTRA_EXTENSION fail
762 then
763 0 >ok-frag
764 read-server-frag
765 endof
766
767 \ Secure Renegotiation.
768 0xFF01 of
769 ok-reneg ifnot
770 ERR_EXTRA_EXTENSION fail
771 then
772 0 >ok-reneg
773 read-server-reneg
774 endof
775
776 \ Signature Algorithms.
777 \ Normally, the server should never send this
778 \ extension (so says RFC 5246 #7.4.1.4.1),
779 \ but some existing servers do.
780 0x000D of
781 ok-signatures ifnot
782 ERR_EXTRA_EXTENSION fail
783 then
784 0 >ok-signatures
785 read-ignore-16
786 endof
787
788 \ Supported Curves.
789 0x000A of
790 ok-curves ifnot
791 ERR_EXTRA_EXTENSION fail
792 then
793 0 >ok-curves
794 read-ignore-16
795 endof
796
797 \ Supported Point Formats.
798 0x000B of
799 ok-points ifnot
800 ERR_EXTRA_EXTENSION fail
801 then
802 0 >ok-points
803 read-ignore-16
804 endof
805
806 \ ALPN.
807 0x0010 of
808 ok-ALPN ifnot
809 ERR_EXTRA_EXTENSION fail
810 then
811 0 >ok-ALPN
812 read-ALPN-from-server
813 endof
814
815 ERR_EXTRA_EXTENSION fail
816 endcase
817 repeat
818
819 \ If we sent a secure renegotiation extension but did not
820 \ receive a response, then the server does not support
821 \ secure renegotiation. This is a hard failure if this
822 \ is a renegotiation.
823 ok-reneg if
824 ok-reneg 5 > if ERR_BAD_SECRENEG fail then
825 1 addr-reneg set8
826 then
827 close-elt
828 then
829 close-elt
830 resume
831 ;
832
833 cc: set-server-curve ( -- ) {
834 const br_x509_class *xc;
835 const br_x509_pkey *pk;
836
837 xc = *(ENG->x509ctx);
838 pk = xc->get_pkey(ENG->x509ctx, NULL);
839 CTX->server_curve =
840 (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0;
841 }
842
843 \ Read Certificate message from server.
844 : read-Certificate-from-server ( -- )
845 addr-cipher_suite get16 expected-key-type
846 -1 read-Certificate
847 dup 0< if neg fail then
848 dup ifnot ERR_UNEXPECTED fail then
849 over and <> if ERR_WRONG_KEY_USAGE fail then
850
851 \ Set server curve (used for static ECDH).
852 set-server-curve ;
853
854 \ Verify signature on ECDHE point sent by the server.
855 \ 'hash' is the hash function to use (1 to 6, or 0 for RSA with MD5+SHA-1)
856 \ 'use-rsa' is 0 for ECDSA, -1 for for RSA
857 \ 'sig-len' is the signature length (in bytes)
858 \ The signature itself is in the pad.
859 cc: verify-SKE-sig ( hash use-rsa sig-len -- err ) {
860 size_t sig_len = T0_POP();
861 int use_rsa = T0_POPi();
862 int hash = T0_POPi();
863
864 T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len));
865 }
866
867 \ Parse ServerKeyExchange
868 : read-ServerKeyExchange ( -- )
869 \ Get header, and check message type.
870 read-handshake-header 12 = ifnot ERR_UNEXPECTED fail then
871
872 \ We expect a named curve, and we must support it.
873 read8 3 = ifnot ERR_INVALID_ALGORITHM fail then
874 read16 dup addr-ecdhe_curve set8
875 dup 32 >= if ERR_INVALID_ALGORITHM fail then
876 supported-curves swap >> 1 and ifnot ERR_INVALID_ALGORITHM fail then
877
878 \ Read the server point.
879 read8
880 dup 133 > if ERR_INVALID_ALGORITHM fail then
881 dup addr-ecdhe_point_len set8
882 addr-ecdhe_point swap read-blob
883
884 \ If using TLS-1.2+, then the hash function and signature algorithm
885 \ are explicitly provided; the signature algorithm must match what
886 \ the cipher suite specifies. With TLS-1.0 and 1.1, the signature
887 \ algorithm is inferred from the cipher suite, and the hash is
888 \ either MD5+SHA-1 (for RSA signatures) or SHA-1 (for ECDSA).
889 addr-version get16 0x0303 >= { tls1.2+ }
890 addr-cipher_suite get16 use-rsa-ecdhe? { use-rsa }
891 2 { hash }
892 tls1.2+ if
893 \ Read hash function; accept only the SHA-* identifiers
894 \ (from SHA-1 to SHA-512, no MD5 here).
895 read8
896 dup dup 2 < swap 6 > or if ERR_INVALID_ALGORITHM fail then
897 >hash
898 read8
899 \ Get expected signature algorithm and compare with what
900 \ the server just sent. Expected value is 1 for RSA, 3
901 \ for ECDSA. Note that 'use-rsa' evaluates to -1 for RSA,
902 \ 0 for ECDSA.
903 use-rsa 1 << 3 + = ifnot ERR_INVALID_ALGORITHM fail then
904 else
905 \ For MD5+SHA-1, we set 'hash' to 0.
906 use-rsa if 0 >hash then
907 then
908
909 \ Read signature into the pad.
910 read16 dup { sig-len }
911
912 dup 512 > if ERR_LIMIT_EXCEEDED fail then
913 addr-pad swap read-blob
914
915 \ Verify signature.
916 hash use-rsa sig-len verify-SKE-sig
917 dup if fail then drop
918
919 close-elt ;
920
921 \ Client certificate: start processing of anchor names.
922 cc: anchor-dn-start-name-list ( -- ) {
923 if (CTX->client_auth_vtable != NULL) {
924 (*CTX->client_auth_vtable)->start_name_list(
925 CTX->client_auth_vtable);
926 }
927 }
928
929 \ Client certificate: start a new anchor DN (length is 16-bit).
930 cc: anchor-dn-start-name ( length -- ) {
931 size_t len;
932
933 len = T0_POP();
934 if (CTX->client_auth_vtable != NULL) {
935 (*CTX->client_auth_vtable)->start_name(
936 CTX->client_auth_vtable, len);
937 }
938 }
939
940 \ Client certificate: push some data for current anchor DN.
941 cc: anchor-dn-append-name ( length -- ) {
942 size_t len;
943
944 len = T0_POP();
945 if (CTX->client_auth_vtable != NULL) {
946 (*CTX->client_auth_vtable)->append_name(
947 CTX->client_auth_vtable, ENG->pad, len);
948 }
949 }
950
951 \ Client certificate: end current anchor DN.
952 cc: anchor-dn-end-name ( -- ) {
953 if (CTX->client_auth_vtable != NULL) {
954 (*CTX->client_auth_vtable)->end_name(
955 CTX->client_auth_vtable);
956 }
957 }
958
959 \ Client certificate: end list of anchor DN.
960 cc: anchor-dn-end-name-list ( -- ) {
961 if (CTX->client_auth_vtable != NULL) {
962 (*CTX->client_auth_vtable)->end_name_list(
963 CTX->client_auth_vtable);
964 }
965 }
966
967 \ Client certificate: obtain the client certificate chain.
968 cc: get-client-chain ( auth_types -- ) {
969 uint32_t auth_types;
970
971 auth_types = T0_POP();
972 if (CTX->client_auth_vtable != NULL) {
973 br_ssl_client_certificate ux;
974
975 (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable,
976 CTX, auth_types, &ux);
977 CTX->auth_type = (unsigned char)ux.auth_type;
978 CTX->hash_id = (unsigned char)ux.hash_id;
979 ENG->chain = ux.chain;
980 ENG->chain_len = ux.chain_len;
981 } else {
982 CTX->hash_id = 0;
983 ENG->chain_len = 0;
984 }
985 }
986
987 \ Parse CertificateRequest. Header has already been read.
988 : read-contents-CertificateRequest ( lim -- )
989 \ Read supported client authentification types. We keep only
990 \ RSA, ECDSA, and ECDH.
991 0 { auth_types }
992 read8 open-elt
993 begin dup while
994 read8 case
995 1 of 0x0000FF endof
996 64 of 0x00FF00 endof
997 65 of 0x010000 endof
998 66 of 0x020000 endof
999 0 swap
1000 endcase
1001 auth_types or >auth_types
1002 repeat
1003 close-elt
1004
1005 \ Full static ECDH is allowed only if the cipher suite is ECDH
1006 \ (not ECDHE). It would be theoretically feasible to use static
1007 \ ECDH on the client side with an ephemeral key pair from the
1008 \ server, but RFC 4492 (section 3) forbids it because ECDHE suites
1009 \ are supposed to provide forward secrecy, and static ECDH would
1010 \ negate that property.
1011 addr-cipher_suite get16 use-ecdh? ifnot
1012 auth_types 0xFFFF and >auth_types
1013 then
1014
1015 \ Note: if the cipher suite is ECDH, then the X.509 validation
1016 \ engine was invoked with the BR_KEYTYPE_EC | BR_KEYTYPE_KEYX
1017 \ combination, so the server's public key has already been
1018 \ checked to be fit for a key exchange.
1019
1020 \ With TLS 1.2:
1021 \ - rsa_fixed_ecdh and ecdsa_fixed_ecdh are synoymous.
1022 \ - There is an explicit list of supported sign+hash.
1023 \ With TLS 1.0,
1024 addr-version get16 0x0303 >= if
1025 \ With TLS 1.2:
1026 \ - There is an explicit list of supported sign+hash.
1027 \ - The ECDH flags must be adjusted for RSA/ECDSA
1028 \ support.
1029 read-list-sign-algos dup addr-hashes set32
1030
1031 \ Trim down the list depending on what hash functions
1032 \ we support (since the hashing itself is done by the SSL
1033 \ engine, not by the certificate handler).
1034 supported-hash-functions drop dup 8 << or 0x030000 or and
1035
1036 auth_types and
1037 auth_types 0x030000 and if
1038 dup 0x0000FF and if 0x010000 or then
1039 dup 0x00FF00 and if 0x020000 or then
1040 then
1041 >auth_types
1042 else
1043 \ TLS 1.0 or 1.1. The hash function is fixed for signatures
1044 \ (MD5+SHA-1 for RSA, SHA-1 for ECDSA).
1045 auth_types 0x030401 and >auth_types
1046 then
1047
1048 \ Parse list of anchor DN.
1049 anchor-dn-start-name-list
1050 read16 open-elt
1051 begin dup while
1052 read16 open-elt
1053 dup anchor-dn-start-name
1054
1055 \ We read the DN by chunks through the pad, so
1056 \ as to use the existing reading function (read-blob)
1057 \ that also ensures proper hashing.
1058 begin
1059 dup while
1060 dup 256 > if 256 else dup then { len }
1061 addr-pad len read-blob
1062 len anchor-dn-append-name
1063 repeat
1064 close-elt
1065 anchor-dn-end-name
1066 repeat
1067 close-elt
1068 anchor-dn-end-name-list
1069
1070 \ We should have reached the message end.
1071 close-elt
1072
1073 \ Obtain the client chain.
1074 auth_types get-client-chain
1075 ;
1076
1077 \ (obsolete)
1078 \ Write an empty Certificate message.
1079 \ : write-empty-Certificate ( -- )
1080 \ 11 write8 3 write24 0 write24 ;
1081
1082 cc: do-rsa-encrypt ( prf_id -- nlen ) {
1083 int x;
1084
1085 x = make_pms_rsa(CTX, T0_POP());
1086 if (x < 0) {
1087 br_ssl_engine_fail(ENG, -x);
1088 T0_CO();
1089 } else {
1090 T0_PUSH(x);
1091 }
1092 }
1093
1094 cc: do-ecdh ( echde prf_id -- ulen ) {
1095 unsigned prf_id = T0_POP();
1096 unsigned ecdhe = T0_POP();
1097 int x;
1098
1099 x = make_pms_ecdh(CTX, ecdhe, prf_id);
1100 if (x < 0) {
1101 br_ssl_engine_fail(ENG, -x);
1102 T0_CO();
1103 } else {
1104 T0_PUSH(x);
1105 }
1106 }
1107
1108 cc: do-static-ecdh ( prf-id -- ) {
1109 unsigned prf_id = T0_POP();
1110
1111 if (make_pms_static_ecdh(CTX, prf_id) < 0) {
1112 br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM);
1113 T0_CO();
1114 }
1115 }
1116
1117 cc: do-client-sign ( -- sig_len ) {
1118 size_t sig_len;
1119
1120 sig_len = make_client_sign(CTX);
1121 if (sig_len == 0) {
1122 br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM);
1123 T0_CO();
1124 }
1125 T0_PUSH(sig_len);
1126 }
1127
1128 \ Write ClientKeyExchange.
1129 : write-ClientKeyExchange ( -- )
1130 16 write8
1131 addr-cipher_suite get16
1132 dup use-rsa-keyx? if
1133 prf-id do-rsa-encrypt
1134 dup 2+ write24
1135 dup write16
1136 addr-pad swap write-blob
1137 else
1138 dup use-ecdhe? swap prf-id do-ecdh
1139 dup 1+ write24
1140 dup write8
1141 addr-pad swap write-blob
1142 then ;
1143
1144 \ Write CertificateVerify. This is invoked only if a client certificate
1145 \ was requested and sent, and the authentication is not full static ECDH.
1146 : write-CertificateVerify ( -- )
1147 do-client-sign
1148 15 write8 dup
1149 addr-version get16 0x0303 >= if
1150 4 + write24
1151 addr-hash_id get8 write8
1152 addr-auth_type get8 write8
1153 else
1154 2+ write24
1155 then
1156 dup write16 addr-pad swap write-blob ;
1157
1158 \ =======================================================================
1159
1160 \ Perform a handshake.
1161 : do-handshake ( -- )
1162 0 addr-application_data set8
1163 22 addr-record_type_out set8
1164 0 addr-selected_protocol set16
1165 multihash-init
1166
1167 write-ClientHello
1168 flush-record
1169 read-ServerHello
1170
1171 if
1172 \ Session resumption.
1173 -1 read-CCS-Finished
1174 -1 write-CCS-Finished
1175
1176 else
1177
1178 \ Not a session resumption.
1179
1180 \ Read certificate; then check key type and usages against
1181 \ cipher suite.
1182 read-Certificate-from-server
1183
1184 \ Depending on cipher suite, we may now expect a
1185 \ ServerKeyExchange.
1186 addr-cipher_suite get16 expected-key-type
1187 CX 0 63 { BR_KEYTYPE_SIGN } and if
1188 read-ServerKeyExchange
1189 then
1190
1191 \ Get next header.
1192 read-handshake-header
1193
1194 \ If this is a CertificateRequest, parse it, then read
1195 \ next header.
1196 dup 13 = if
1197 drop read-contents-CertificateRequest
1198 read-handshake-header
1199 -1
1200 else
1201 0
1202 then
1203 { seen-CR }
1204
1205 \ At that point, we should have a ServerHelloDone,
1206 \ whose length must be 0.
1207 14 = ifnot ERR_UNEXPECTED fail then
1208 if ERR_BAD_HELLO_DONE fail then
1209
1210 \ There should not be more bytes in the record at that point.
1211 more-incoming-bytes? if ERR_UNEXPECTED fail then
1212
1213 seen-CR if
1214 \ If the server requested a client certificate, then
1215 \ we must write a Certificate message (it may be
1216 \ empty).
1217 write-Certificate
1218
1219 \ If using static ECDH, then the ClientKeyExchange
1220 \ is empty, and there is no CertificateVerify.
1221 \ Otherwise, there is a ClientKeyExchange; there
1222 \ will then be a CertificateVerify if a client chain
1223 \ was indeed sent.
1224 addr-hash_id get8 0xFF = if
1225 drop
1226 16 write8 0 write24
1227 addr-cipher_suite get16 prf-id do-static-ecdh
1228 else
1229 write-ClientKeyExchange
1230 if write-CertificateVerify then
1231 then
1232 else
1233 write-ClientKeyExchange
1234 then
1235
1236 -1 write-CCS-Finished
1237 -1 read-CCS-Finished
1238 then
1239
1240 \ Now we should be invoked only in case of renegotiation.
1241 1 addr-application_data set8
1242 23 addr-record_type_out set8 ;
1243
1244 \ Read a HelloRequest message.
1245 : read-HelloRequest ( -- )
1246 \ A HelloRequest has length 0 and type 0.
1247 read-handshake-header-core
1248 if ERR_UNEXPECTED fail then
1249 if ERR_BAD_HANDSHAKE fail then ;
1250
1251 \ Entry point.
1252 : main ( -- ! )
1253 \ Perform initial handshake.
1254 do-handshake
1255
1256 begin
1257 \ Wait for further invocation. At that point, we should
1258 \ get either an explicit call for renegotiation, or
1259 \ an incoming HelloRequest handshake message.
1260 wait-co
1261 dup 0x07 and case
1262 0x00 of
1263 0x10 and if
1264 do-handshake
1265 then
1266 endof
1267 0x01 of
1268 drop
1269 0 addr-application_data set8
1270 read-HelloRequest
1271 \ Reject renegotiations if the peer does not
1272 \ support secure renegotiation, or if the
1273 \ "no renegotiation" flag is set.
1274 addr-reneg get8 1 = 1 flag? or if
1275 flush-record
1276 begin can-output? not while
1277 wait-co drop
1278 repeat
1279 100 send-warning
1280 else
1281 do-handshake
1282 then
1283 endof
1284 ERR_UNEXPECTED fail
1285 endcase
1286 again
1287 ;