1 \ Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
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:
11 \ The above copyright notice and this permission notice shall be
12 \ included in all copies or substantial portions of the Software.
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
23 \ ----------------------------------------------------------------------
24 \ Handshake processing code, for the client.
25 \ The common T0 code (ssl_hs_common.t0) shall be read first.
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.
37 #define CTX ((br_ssl_client_context *)ENG)
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.
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).
49 make_pms_rsa(br_ssl_client_context *ctx, int prf_id)
51 const br_x509_class **xc;
52 const br_x509_pkey *pk;
53 const unsigned char *n;
57 xc = ctx->eng.x509ctx;
58 pk = (*xc)->get_pkey(xc, NULL);
61 * Compute actual RSA key length, in case there are leading zeros.
64 nlen = pk->key.rsa.nlen;
65 while (nlen > 0 && *n == 0) {
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
78 return -BR_ERR_X509_WEAK_PUBLIC_KEY;
80 if (nlen > sizeof ctx->eng.pad) {
81 return -BR_ERR_LIMIT_EXCEEDED;
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);
93 * Apply PKCS#1 type 2 padding.
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);
107 * Compute RSA encryption.
109 if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) {
110 return -BR_ERR_LIMIT_EXCEEDED;
116 * OID for hash functions in RSA signatures.
118 static const unsigned char HASH_OID_SHA1[] = {
119 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A
122 static const unsigned char HASH_OID_SHA224[] = {
123 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04
126 static const unsigned char HASH_OID_SHA256[] = {
127 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01
130 static const unsigned char HASH_OID_SHA384[] = {
131 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02
134 static const unsigned char HASH_OID_SHA512[] = {
135 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03
138 static const unsigned char *HASH_OID[] = {
147 * Check the RSA signature on the ServerKeyExchange message.
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
153 * Returned value is 0 on success, or an error code.
156 verify_SKE_sig(br_ssl_client_context *ctx,
157 int hash, int use_rsa, size_t sig_len)
159 const br_x509_class **xc;
160 const br_x509_pkey *pk;
161 br_multihash_context mhc;
162 unsigned char hv[64], head[4];
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);
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);
182 hv_len = br_multihash_out(&mhc, hash, hv);
184 return BR_ERR_INVALID_ALGORITHM;
187 if (!br_multihash_out(&mhc, br_md5_ID, hv)
188 || !br_multihash_out(&mhc, br_sha1_ID, hv + 16))
190 return BR_ERR_INVALID_ALGORITHM;
195 unsigned char tmp[64];
196 const unsigned char *hash_oid;
199 hash_oid = HASH_OID[hash - 2];
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)
207 return BR_ERR_BAD_SIGNATURE;
210 if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec,
211 ctx->eng.pad, sig_len))
213 return BR_ERR_BAD_SIGNATURE;
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.
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
229 make_pms_ecdh(br_ssl_client_context *ctx, unsigned ecdhe, int prf_id)
232 unsigned char key[66], point[133];
233 const unsigned char *generator, *order, *point_src;
234 size_t glen, olen, point_len;
238 curve = ctx->eng.ecdhe_curve;
239 point_src = ctx->eng.ecdhe_point;
240 point_len = ctx->eng.ecdhe_point_len;
242 const br_x509_class **xc;
243 const br_x509_pkey *pk;
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;
251 if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) {
252 return -BR_ERR_INVALID_ALGORITHM;
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.
261 order = ctx->eng.iec->order(curve, &olen);
263 while (mask >= order[0]) {
266 br_hmac_drbg_generate(&ctx->eng.rng, key, olen);
268 key[olen - 1] |= 0x01;
271 * Compute the common ECDH point, whose X coordinate is the
274 generator = ctx->eng.iec->generator(curve, &glen);
275 if (glen != point_len) {
276 return -BR_ERR_INVALID_ALGORITHM;
279 memcpy(point, point_src, glen);
280 if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) {
281 return -BR_ERR_INVALID_ALGORITHM;
285 * The pre-master secret is the X coordinate.
287 br_ssl_engine_compute_master(&ctx->eng, prf_id, point + 1, glen >> 1);
289 memcpy(point, generator, glen);
290 if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) {
291 return -BR_ERR_INVALID_ALGORITHM;
293 memcpy(ctx->eng.pad, point, glen);
298 * Perform full static ECDH. This occurs only in the context of client
299 * authentication with certificates: the server uses an EC public key,
300 * the cipher suite is of type ECDH (not ECDHE), the server requested a
301 * client certificate and accepts static ECDH, the client has a
302 * certificate with an EC public key in the same curve, and accepts
303 * static ECDH as well.
305 * Returned value is 0 on success, -1 on error.
308 make_pms_static_ecdh(br_ssl_client_context *ctx, int prf_id)
310 unsigned char point[133];
312 const br_x509_class **xc;
313 const br_x509_pkey *pk;
315 xc = ctx->eng.x509ctx;
316 pk = (*xc)->get_pkey(xc, NULL);
317 point_len = pk->key.ec.qlen;
318 if (point_len > sizeof point) {
321 memcpy(point, pk->key.ec.q, point_len);
322 if (!(*ctx->client_auth_vtable)->do_keyx(
323 ctx->client_auth_vtable, point, point_len))
327 br_ssl_engine_compute_master(&ctx->eng,
328 prf_id, point + 1, point_len >> 1);
333 * Compute the client-side signature. This is invoked only when a
334 * signature-based client authentication was selected. The computed
335 * signature is in the pad; its length (in bytes) is returned. On
336 * error, 0 is returned.
339 make_client_sign(br_ssl_client_context *ctx)
344 * Compute hash of handshake messages so far. This "cannot" fail
345 * because the list of supported hash functions provided to the
346 * client certificate handler was trimmed to include only the
347 * hash functions that the multi-hasher supports.
350 hv_len = br_multihash_out(&ctx->eng.mhash,
351 ctx->hash_id, ctx->eng.pad);
353 br_multihash_out(&ctx->eng.mhash,
354 br_md5_ID, ctx->eng.pad);
355 br_multihash_out(&ctx->eng.mhash,
356 br_sha1_ID, ctx->eng.pad + 16);
359 return (*ctx->client_auth_vtable)->do_sign(
360 ctx->client_auth_vtable, ctx->hash_id, hv_len,
361 ctx->eng.pad, sizeof ctx->eng.pad);
366 \ =======================================================================
370 "addr-" field + 0 1 define-word
371 0 8191 "offsetof(br_ssl_client_context, " field + ")" + make-CX
372 postpone literal postpone ; ;
374 addr-ctx: min_clienthello_len
379 \ Length of the Secure Renegotiation extension. This is 5 for the
380 \ first handshake, 17 for a renegotiation (if the server supports the
381 \ extension), or 0 if we know that the server does not support the
383 : ext-reneg-length ( -- n )
384 addr-reneg get8 dup if 1 - 17 * else drop 5 then ;
386 \ Length of SNI extension.
387 : ext-sni-length ( -- len )
388 addr-server_name strlen dup if 9 + then ;
390 \ Length of Maximum Fragment Length extension.
391 : ext-frag-length ( -- len )
392 addr-log_max_frag_len get8 14 = if 0 else 5 then ;
394 \ Length of Signatures extension.
395 : ext-signatures-length ( -- len )
396 supported-hash-functions { x } drop
398 supports-rsa-sign? if x + then
399 supports-ecdsa? if x + then
400 dup if 1 << 6 + then ;
402 \ Write supported hash functions ( sign -- )
405 supported-hash-functions drop
406 \ We advertise hash functions in the following preference order:
407 \ SHA-256 SHA-224 SHA-384 SHA-512 SHA-1
409 \ -- SHA-256 and SHA-224 are more efficient on 32-bit architectures
410 \ -- SHA-1 is less than ideally collision-resistant
411 dup 0x10 and if 4 write8 sign write8 then
412 dup 0x08 and if 3 write8 sign write8 then
413 dup 0x20 and if 5 write8 sign write8 then
414 dup 0x40 and if 6 write8 sign write8 then
415 0x04 and if 2 write8 sign write8 then ;
417 \ Length of Supported Curves extension.
418 : ext-supported-curves-length ( -- len )
419 supported-curves dup if
428 \ Length of Supported Point Formats extension.
429 : ext-point-format-length ( -- len )
430 supported-curves if 6 else 0 then ;
432 \ Write handshake message: ClientHello
433 : write-ClientHello ( -- )
434 { ; total-ext-length }
436 \ Compute length for extensions (without the general two-byte header).
437 \ This does not take padding extension into account.
438 ext-reneg-length ext-sni-length + ext-frag-length +
439 ext-signatures-length +
440 ext-supported-curves-length + ext-point-format-length +
446 \ Compute and write length
447 39 addr-session_id_len get8 + addr-suites_num get8 1 << +
448 total-ext-length if 2+ total-ext-length + then
449 \ Compute padding (if requested).
450 addr-min_clienthello_len get16 over - dup 0> if
451 \ We well add a Pad ClientHello extension, which has its
452 \ own header (4 bytes) and might be the only extension
453 \ (2 extra bytes for the extension list header).
454 total-ext-length ifnot swap 2+ swap 2- then
455 \ Account for the extension header.
456 4 - dup 0< if drop 0 then
457 \ Adjust total extension length.
458 dup 4 + total-ext-length + >total-ext-length
459 \ Adjust ClientHello length.
465 { ext-padding-amount }
469 addr-version_max get16 write16
472 addr-client_random 4 bzero
473 addr-client_random 4 + 28 mkrand
474 addr-client_random 32 write-blob
477 addr-session_id addr-session_id_len get8 write-blob-head8
479 \ Supported cipher suites. We also check here that we indeed
480 \ support all these suites.
481 addr-suites_num get8 dup 1 << write16
486 dup suite-supported? ifnot ERR_BAD_CIPHER_SUITE fail then
492 \ Compression methods (only "null" compression)
497 total-ext-length write16
499 0xFF01 write16 \ extension type (0xFF01)
501 ext-reneg-length 4 - dup write16 \ extension length
502 1- write-blob-head8 \ verify data
505 0x0000 write16 \ extension type (0)
507 ext-sni-length 4 - dup write16 \ extension length
508 2 - dup write16 \ ServerNameList length
509 0 write8 \ name type: host_name
510 3 - write-blob-head16 \ the name itself
513 0x0001 write16 \ extension type (1)
514 0x0001 write16 \ extension length
515 addr-log_max_frag_len get8 8 - write8
517 ext-signatures-length if
518 0x000D write16 \ extension type (13)
519 ext-signatures-length 4 - dup write16 \ extension length
520 2 - write16 \ list length
521 supports-ecdsa? if 3 write-hashes then
522 supports-rsa-sign? if 1 write-hashes then
524 \ TODO: add an API to specify preference order for curves.
525 \ Right now we use increasing id order, which makes P-256
526 \ the preferred curve.
527 ext-supported-curves-length dup if
528 0x000A write16 \ extension type (10)
529 4 - dup write16 \ extension length
530 2- write16 \ list length
533 dup2 >> 1 and if dup write16 then
540 ext-point-format-length if
541 0x000B write16 \ extension type (11)
542 0x0002 write16 \ extension length
543 0x0100 write16 \ value: 1 format: uncompressed
545 ext-padding-amount 0< ifnot
546 0x0015 write16 \ extension value (21)
548 dup write16 \ extension length
550 1- 0 write8 repeat \ value (only zeros)
556 \ =======================================================================
558 \ Parse server SNI extension. If present, then it should be empty.
559 : read-server-sni ( lim -- lim )
560 read16 if ERR_BAD_SNI fail then ;
562 \ Parse server Max Fragment Length extension. If present, then it should
563 \ advertise the same length as the client. Note that whether the server
564 \ sends it or not changes nothing for us: we won't send any record larger
565 \ than the advertised value anyway, and we will accept incoming records
566 \ up to our input buffer length.
567 : read-server-frag ( lim -- lim )
568 read16 1 = ifnot ERR_BAD_FRAGLEN fail then
569 read8 8 + addr-log_max_frag_len get8 = ifnot ERR_BAD_FRAGLEN fail then ;
571 \ Parse server Secure Renegotiation extension. This is called only if
572 \ the client sent that extension, so we only have two cases to
573 \ distinguish: first handshake, and renegotiation; in the latter case,
574 \ we know that the server supports the extension, otherwise the client
575 \ would not have sent it.
576 : read-server-reneg ( lim -- lim )
578 addr-reneg get8 ifnot
579 \ "reneg" is 0, so this is a first handshake. The server's
580 \ extension MUST be empty. We also learn that the server
581 \ supports the extension.
582 1 = ifnot ERR_BAD_SECRENEG fail then
583 read8 0 = ifnot ERR_BAD_SECRENEG fail then
586 \ "reneg" is non-zero, and we sent an extension, so it must
587 \ be 2 and this is a renegotiation. We must verify that
588 \ the extension contents have length exactly 24 bytes and
589 \ match the saved client and server "Finished".
590 25 = ifnot ERR_BAD_SECRENEG fail then
591 read8 24 = ifnot ERR_BAD_SECRENEG fail then
592 addr-pad 24 read-blob
593 addr-saved_finished addr-pad 24 memcmp ifnot
594 ERR_BAD_SECRENEG fail
598 \ Save a value in a 16-bit field, or check it in case of session resumption.
599 : check-resume ( val addr resume -- )
600 if get16 = ifnot ERR_RESUME_MISMATCH fail then else set16 then ;
602 cc: DEBUG-BLOB ( addr len -- ) {
603 extern int printf(const char *fmt, ...);
605 size_t len = T0_POP();
606 unsigned char *buf = (unsigned char *)CTX + T0_POP();
610 for (u = 0; u < len; u ++) {
614 printf(" %02x", buf[u]);
619 \ Parse incoming ServerHello. Returned value is true (-1) on session
621 : read-ServerHello ( -- bool )
622 \ Get header, and check message type.
623 read-handshake-header 2 = ifnot ERR_UNEXPECTED fail then
625 \ Get protocol version.
627 version addr-version_min get16 < version addr-version_max get16 > or if
628 ERR_UNSUPPORTED_VERSION fail
631 \ Enforce chosen version for subsequent records in both directions.
632 version addr-version_in get16 <> if ERR_BAD_VERSION fail then
633 version addr-version_out set16
636 addr-server_random 32 read-blob
638 \ The "session resumption" flag.
643 idlen 32 > if ERR_OVERSIZED_ID fail then
644 addr-pad idlen read-blob
645 idlen addr-session_id_len get8 = idlen 0 > and if
646 addr-session_id addr-pad idlen memcmp if
647 \ Server session ID is non-empty and matches what
648 \ we sent, so this is a session resumption.
652 addr-session_id addr-pad idlen memcpy
653 idlen addr-session_id_len set8
656 version addr-version resume check-resume
658 \ Cipher suite. We check that it is part of the list of cipher
659 \ suites that we advertised.
660 \ read16 { suite ; found }
662 \ addr-suites_buf dup addr-suites_num get8 1 << +
665 \ suite = found or >found
667 \ 2drop found ifnot ERR_BAD_CIPHER_SUITE fail then
669 dup scan-suite 0< if ERR_BAD_CIPHER_SUITE fail then
670 addr-cipher_suite resume check-resume
672 \ Compression method. Should be 0 (no compression).
673 read8 if ERR_BAD_COMPRESSION fail then
675 \ Parse extensions (if any). If there is no extension, then the
676 \ read limit (on the TOS) should be 0 at that point.
678 \ Length of extension list.
682 \ Enumerate extensions. For each of them, check that we
683 \ sent an extension of that type, and did not see it
684 \ yet; and then process it.
685 ext-sni-length { ok-sni }
686 ext-reneg-length { ok-reneg }
687 ext-frag-length { ok-frag }
688 ext-signatures-length { ok-signatures }
689 ext-supported-curves-length { ok-curves }
690 ext-point-format-length { ok-points }
694 \ Server Name Indication. The server may
695 \ send such an extension if it uses the SNI
696 \ from the client, but that "response
697 \ extension" is supposed to be empty.
700 ERR_EXTRA_EXTENSION fail
706 \ Max Frag Length. The contents shall be
707 \ a single byte whose value matches the one
708 \ sent by the client.
711 ERR_EXTRA_EXTENSION fail
717 \ Secure Renegotiation.
720 ERR_EXTRA_EXTENSION fail
726 \ Signature Algorithms.
727 \ Normally, the server should never send this
728 \ extension (so says RFC 5246 #7.4.1.4.1),
729 \ but some existing servers do.
732 ERR_EXTRA_EXTENSION fail
741 ERR_EXTRA_EXTENSION fail
747 \ Supported Point Formats.
750 ERR_EXTRA_EXTENSION fail
756 ERR_EXTRA_EXTENSION fail
760 \ If we sent a secure renegotiation extension but did not
761 \ receive a response, then the server does not support
762 \ secure renegotiation. This is a hard failure if this
763 \ is a renegotiation.
765 ok-reneg 5 > if ERR_BAD_SECRENEG fail then
774 cc: set-server-curve ( -- ) {
775 const br_x509_class *xc;
776 const br_x509_pkey *pk;
778 xc = *(ENG->x509ctx);
779 pk = xc->get_pkey(ENG->x509ctx, NULL);
781 (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0;
784 \ Read Certificate message from server.
785 : read-Certificate-from-server ( -- )
786 addr-cipher_suite get16 expected-key-type
788 dup 0< if neg fail then
789 dup ifnot ERR_UNEXPECTED fail then
790 over and <> if ERR_WRONG_KEY_USAGE fail then
792 \ Set server curve (used for static ECDH).
795 \ Verify signature on ECDHE point sent by the server.
796 \ 'hash' is the hash function to use (1 to 6, or 0 for RSA with MD5+SHA-1)
797 \ 'use-rsa' is 0 for ECDSA, -1 for for RSA
798 \ 'sig-len' is the signature length (in bytes)
799 \ The signature itself is in the pad.
800 cc: verify-SKE-sig ( hash use-rsa sig-len -- err ) {
801 size_t sig_len = T0_POP();
802 int use_rsa = T0_POPi();
803 int hash = T0_POPi();
805 T0_PUSH(verify_SKE_sig(CTX, hash, use_rsa, sig_len));
808 \ Parse ServerKeyExchange
809 : read-ServerKeyExchange ( -- )
810 \ Get header, and check message type.
811 read-handshake-header 12 = ifnot ERR_UNEXPECTED fail then
813 \ We expect a named curve, and we must support it.
814 read8 3 = ifnot ERR_INVALID_ALGORITHM fail then
815 read16 dup addr-ecdhe_curve set8
816 dup 32 >= if ERR_INVALID_ALGORITHM fail then
817 supported-curves swap >> 1 and ifnot ERR_INVALID_ALGORITHM fail then
819 \ Read the server point.
821 dup 133 > if ERR_INVALID_ALGORITHM fail then
822 dup addr-ecdhe_point_len set8
823 addr-ecdhe_point swap read-blob
825 \ If using TLS-1.2+, then the hash function and signature algorithm
826 \ are explicitly provided; the signature algorithm must match what
827 \ the cipher suite specifies. With TLS-1.0 and 1.1, the signature
828 \ algorithm is inferred from the cipher suite, and the hash is
829 \ either MD5+SHA-1 (for RSA signatures) or SHA-1 (for ECDSA).
830 addr-version get16 0x0303 >= { tls1.2+ }
831 addr-cipher_suite get16 use-rsa-ecdhe? { use-rsa }
834 \ Read hash function; accept only the SHA-* identifiers
835 \ (from SHA-1 to SHA-512, no MD5 here).
837 dup dup 2 < swap 6 > or if ERR_INVALID_ALGORITHM fail then
840 \ Get expected signature algorithm and compare with what
841 \ the server just sent. Expected value is 1 for RSA, 3
842 \ for ECDSA. Note that 'use-rsa' evaluates to -1 for RSA,
844 use-rsa 1 << 3 + = ifnot ERR_INVALID_ALGORITHM fail then
846 \ For MD5+SHA-1, we set 'hash' to 0.
847 use-rsa if 0 >hash then
850 \ Read signature into the pad.
851 read16 dup { sig-len }
853 dup 512 > if ERR_LIMIT_EXCEEDED fail then
854 addr-pad swap read-blob
857 hash use-rsa sig-len verify-SKE-sig
858 dup if fail then drop
862 \ Client certificate: start processing of anchor names.
863 cc: anchor-dn-start-name-list ( -- ) {
864 if (CTX->client_auth_vtable != NULL) {
865 (*CTX->client_auth_vtable)->start_name_list(
866 CTX->client_auth_vtable);
870 \ Client certificate: start a new anchor DN (length is 16-bit).
871 cc: anchor-dn-start-name ( length -- ) {
875 if (CTX->client_auth_vtable != NULL) {
876 (*CTX->client_auth_vtable)->start_name(
877 CTX->client_auth_vtable, len);
881 \ Client certificate: push some data for current anchor DN.
882 cc: anchor-dn-append-name ( length -- ) {
886 if (CTX->client_auth_vtable != NULL) {
887 (*CTX->client_auth_vtable)->append_name(
888 CTX->client_auth_vtable, ENG->pad, len);
892 \ Client certificate: end current anchor DN.
893 cc: anchor-dn-end-name ( -- ) {
894 if (CTX->client_auth_vtable != NULL) {
895 (*CTX->client_auth_vtable)->end_name(
896 CTX->client_auth_vtable);
900 \ Client certificate: end list of anchor DN.
901 cc: anchor-dn-end-name-list ( -- ) {
902 if (CTX->client_auth_vtable != NULL) {
903 (*CTX->client_auth_vtable)->end_name_list(
904 CTX->client_auth_vtable);
908 \ Client certificate: obtain the client certificate chain.
909 cc: get-client-chain ( auth_types -- ) {
912 auth_types = T0_POP();
913 if (CTX->client_auth_vtable != NULL) {
914 br_ssl_client_certificate ux;
916 (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable,
917 CTX, auth_types, &ux);
918 CTX->auth_type = (unsigned char)ux.auth_type;
919 CTX->hash_id = (unsigned char)ux.hash_id;
920 ENG->chain = ux.chain;
921 ENG->chain_len = ux.chain_len;
928 \ Parse CertificateRequest. Header has already been read.
929 : read-contents-CertificateRequest ( lim -- )
930 \ Read supported client authentification types. We keep only
931 \ RSA, ECDSA, and ECDH.
942 auth_types or >auth_types
946 \ Full static ECDH is allowed only if the cipher suite is ECDH
947 \ (not ECDHE). It would be theoretically feasible to use static
948 \ ECDH on the client side with an ephemeral key pair from the
949 \ server, but RFC 4492 (section 3) forbids it because ECDHE suites
950 \ are supposed to provide forward secrecy, and static ECDH would
951 \ negate that property.
952 addr-cipher_suite get16 use-ecdh? ifnot
953 auth_types 0xFFFF and >auth_types
956 \ Note: if the cipher suite is ECDH, then the X.509 validation
957 \ engine was invoked with the BR_KEYTYPE_EC | BR_KEYTYPE_KEYX
958 \ combination, so the server's public key has already been
959 \ checked to be fit for a key exchange.
962 \ - rsa_fixed_ecdh and ecdsa_fixed_ecdh are synoymous.
963 \ - There is an explicit list of supported sign+hash.
965 addr-version get16 0x0303 >= if
967 \ - There is an explicit list of supported sign+hash.
968 \ - The ECDH flags must be adjusted for RSA/ECDSA
970 read-list-sign-algos dup addr-hashes set16
972 \ Trim down the list depending on what hash functions
973 \ we support (since the hashing itself is done by the SSL
974 \ engine, not by the certificate handler).
975 supported-hash-functions drop dup 8 << or 0x030000 or and
978 auth_types 0x030000 and if
979 dup 0x0000FF and if 0x010000 or then
980 dup 0x00FF00 and if 0x020000 or then
984 \ TLS 1.0 or 1.1. The hash function is fixed for signatures
985 \ (MD5+SHA-1 for RSA, SHA-1 for ECDSA).
986 auth_types 0x030401 and >auth_types
989 \ Parse list of anchor DN.
990 anchor-dn-start-name-list
994 dup anchor-dn-start-name
996 \ We read the DN by chunks through the pad, so
997 \ as to use the existing reading function (read-blob)
998 \ that also ensures proper hashing.
1001 dup 256 > if 256 else dup then { len }
1002 addr-pad len read-blob
1003 len anchor-dn-append-name
1009 anchor-dn-end-name-list
1011 \ We should have reached the message end.
1014 \ Obtain the client chain.
1015 auth_types get-client-chain
1019 \ Write an empty Certificate message.
1020 \ : write-empty-Certificate ( -- )
1021 \ 11 write8 3 write24 0 write24 ;
1023 cc: do-rsa-encrypt ( prf_id -- nlen ) {
1026 x = make_pms_rsa(CTX, T0_POP());
1028 br_ssl_engine_fail(ENG, -x);
1035 cc: do-ecdh ( echde prf_id -- ulen ) {
1036 unsigned prf_id = T0_POP();
1037 unsigned ecdhe = T0_POP();
1040 x = make_pms_ecdh(CTX, ecdhe, prf_id);
1042 br_ssl_engine_fail(ENG, -x);
1049 cc: do-static-ecdh ( prf-id -- ) {
1050 unsigned prf_id = T0_POP();
1052 if (make_pms_static_ecdh(CTX, prf_id) < 0) {
1053 br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM);
1058 cc: do-client-sign ( -- sig_len ) {
1061 sig_len = make_client_sign(CTX);
1063 br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM);
1069 \ Write ClientKeyExchange.
1070 : write-ClientKeyExchange ( -- )
1072 addr-cipher_suite get16
1073 dup use-rsa-keyx? if
1074 prf-id do-rsa-encrypt
1077 addr-pad swap write-blob
1079 dup use-ecdhe? swap prf-id do-ecdh
1082 addr-pad swap write-blob
1085 \ Write CertificateVerify. This is invoked only if a client certificate
1086 \ was requested and sent, and the authentication is not full static ECDH.
1087 : write-CertificateVerify ( -- )
1090 addr-version get16 0x0303 >= if
1092 addr-hash_id get8 write8
1093 addr-auth_type get8 write8
1097 dup write16 addr-pad swap write-blob ;
1099 \ =======================================================================
1101 \ Perform a handshake.
1102 : do-handshake ( -- )
1103 0 addr-application_data set8
1104 22 addr-record_type_out set8
1112 \ Session resumption.
1113 -1 read-CCS-Finished
1114 -1 write-CCS-Finished
1118 \ Not a session resumption.
1120 \ Read certificate; then check key type and usages against
1122 read-Certificate-from-server
1124 \ Depending on cipher suite, we may now expect a
1125 \ ServerKeyExchange.
1126 addr-cipher_suite get16 expected-key-type
1127 CX 0 63 { BR_KEYTYPE_SIGN } and if
1128 read-ServerKeyExchange
1132 read-handshake-header
1134 \ If this is a CertificateRequest, parse it, then read
1137 drop read-contents-CertificateRequest
1138 read-handshake-header
1145 \ At that point, we should have a ServerHelloDone,
1146 \ whose length must be 0.
1147 14 = ifnot ERR_UNEXPECTED fail then
1148 if ERR_BAD_HELLO_DONE fail then
1150 \ There should not be more bytes in the record at that point.
1151 more-incoming-bytes? if ERR_UNEXPECTED fail then
1154 \ If the server requested a client certificate, then
1155 \ we must write a Certificate message (it may be
1159 \ If using static ECDH, then the ClientKeyExchange
1160 \ is empty, and there is no CertificateVerify.
1161 \ Otherwise, there is a ClientKeyExchange; there
1162 \ will then be a CertificateVerify if a client chain
1164 addr-hash_id get8 0xFF = if
1167 addr-cipher_suite get16 prf-id do-static-ecdh
1169 write-ClientKeyExchange
1170 if write-CertificateVerify then
1173 write-ClientKeyExchange
1176 -1 write-CCS-Finished
1177 -1 read-CCS-Finished
1180 \ Now we should be invoked only in case of renegotiation.
1181 1 addr-application_data set8
1182 23 addr-record_type_out set8 ;
1184 \ Read a HelloRequest message.
1185 : read-HelloRequest ( -- )
1186 \ A HelloRequest has length 0 and type 0.
1187 read-handshake-header-core
1188 if ERR_UNEXPECTED fail then
1189 if ERR_BAD_HANDSHAKE fail then ;
1193 \ Perform initial handshake.
1197 \ Wait for further invocation. At that point, we should
1198 \ get either an explicit call for renegotiation, or
1199 \ an incoming HelloRequest handshake message.
1209 0 addr-application_data set8
1211 \ Reject renegotiations if the peer does not
1212 \ support secure renegotiation, or if the
1213 \ "no renegotiation" flag is set.
1214 addr-reneg get8 1 = 1 flag? or if
1216 begin can-output? not while