Lines Matching +full:1 +full:- +full:eng
23 \ ----------------------------------------------------------------------
32 * first field of the br_ssl_client_context structure ('eng'), then
37 #define CTX ((br_ssl_client_context *)ENG)
40 * Generate the pre-master secret for RSA key exchange, and encrypt it
42 * data length (in bytes), or -x on error, with 'x' being an error code.
57 xc = ctx->eng.x509ctx;
58 pk = (*xc)->get_pkey(xc, NULL);
63 n = pk->key.rsa.n;
64 nlen = pk->key.rsa.nlen;
67 nlen --;
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
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);
109 if (!ctx->irsapub(ctx->eng.pad, nlen, &pk->key.rsa)) {
110 return -BR_ERR_LIMIT_EXCEEDED;
129 * hash hash function ID (2 to 6), or 0 for MD5+SHA-1 (with RSA only)
130 * use_rsa non-zero for RSA signature, zero for ECDSA
145 xc = ctx->eng.x509ctx;
146 pk = (*xc)->get_pkey(xc, NULL);
148 br_multihash_copyimpl(&mhc, &ctx->eng.mhash);
151 ctx->eng.client_random, sizeof ctx->eng.client_random);
153 ctx->eng.server_random, sizeof ctx->eng.server_random);
155 head[1] = 0;
156 head[2] = ctx->eng.ecdhe_curve;
157 head[3] = ctx->eng.ecdhe_point_len;
160 ctx->eng.ecdhe_point, ctx->eng.ecdhe_point_len);
179 hash_oid = HASH_OID[hash - 2];
183 if (!ctx->eng.irsavrfy(ctx->eng.pad, sig_len,
184 hash_oid, hv_len, &pk->key.rsa, tmp)
190 if (!ctx->eng.iecdsa(ctx->eng.iec, hv, hv_len, &pk->key.ec,
191 ctx->eng.pad, sig_len))
200 * Perform client-side ECDH (or ECDHE). The point that should be sent to
202 * length (in bytes), or -x on error, with 'x' being an error code.
205 * is non-zero, or from the X.509 engine context if 'ecdhe' is zero
218 curve = ctx->eng.ecdhe_curve;
219 point_src = ctx->eng.ecdhe_point;
220 point_len = ctx->eng.ecdhe_point_len;
225 xc = ctx->eng.x509ctx;
226 pk = (*xc)->get_pkey(xc, NULL);
227 curve = pk->key.ec.curve;
228 point_src = pk->key.ec.q;
229 point_len = pk->key.ec.qlen;
231 if ((ctx->eng.iec->supported_curves & ((uint32_t)1 << curve)) == 0) {
232 return -BR_ERR_INVALID_ALGORITHM;
236 * We need to generate our key, as a non-zero random value which
238 * force top bit to 0 and bottom bit to 1, which guarantees that
241 order = ctx->eng.iec->order(curve, &olen);
244 mask >>= 1;
246 br_hmac_drbg_generate(&ctx->eng.rng, key, olen);
248 key[olen - 1] |= 0x01;
252 * pre-master secret.
254 ctx->eng.iec->generator(curve, &glen);
256 return -BR_ERR_INVALID_ALGORITHM;
260 if (!ctx->eng.iec->mul(point, glen, key, olen, curve)) {
261 return -BR_ERR_INVALID_ALGORITHM;
265 * The pre-master secret is the X coordinate.
267 xoff = ctx->eng.iec->xoff(curve, &xlen);
268 br_ssl_engine_compute_master(&ctx->eng, prf_id, point + xoff, xlen);
270 ctx->eng.iec->mulgen(point, key, olen, curve);
271 memcpy(ctx->eng.pad, point, glen);
283 * Returned value is 0 on success, -1 on error.
293 xc = ctx->eng.x509ctx;
294 pk = (*xc)->get_pkey(xc, NULL);
295 point_len = pk->key.ec.qlen;
297 return -1;
299 memcpy(point, pk->key.ec.q, point_len);
300 if (!(*ctx->client_auth_vtable)->do_keyx(
301 ctx->client_auth_vtable, point, &point_len))
303 return -1;
305 br_ssl_engine_compute_master(&ctx->eng,
311 * Compute the client-side signature. This is invoked only when a
312 * signature-based client authentication was selected. The computed
325 * hash functions that the multi-hasher supports.
327 if (ctx->hash_id) {
328 hv_len = br_multihash_out(&ctx->eng.mhash,
329 ctx->hash_id, ctx->eng.pad);
331 br_multihash_out(&ctx->eng.mhash,
332 br_md5_ID, ctx->eng.pad);
333 br_multihash_out(&ctx->eng.mhash,
334 br_sha1_ID, ctx->eng.pad + 16);
337 return (*ctx->client_auth_vtable)->do_sign(
338 ctx->client_auth_vtable, ctx->hash_id, hv_len,
339 ctx->eng.pad, sizeof ctx->eng.pad);
346 : addr-ctx:
347 next-word { field }
348 "addr-" field + 0 1 define-word
349 0 8191 "offsetof(br_ssl_client_context, " field + ")" + make-CX
352 addr-ctx: min_clienthello_len
353 addr-ctx: hashes
354 addr-ctx: auth_type
355 addr-ctx: hash_id
361 : ext-reneg-length ( -- n )
362 addr-reneg get8 dup if 1 - 17 * else drop 5 then ;
365 : ext-sni-length ( -- len )
366 addr-server_name strlen dup if 9 + then ;
369 : ext-frag-length ( -- len )
370 addr-log_max_frag_len get8 14 = if 0 else 5 then ;
373 : ext-signatures-length ( -- len )
374 supported-hash-functions { num } drop 0
375 supports-rsa-sign? if num + then
376 supports-ecdsa? if num + then
377 dup if 1 << 6 + then ;
379 \ Write supported hash functions ( sign -- )
380 : write-hashes
382 supported-hash-functions drop
384 \ SHA-256 SHA-224 SHA-384 SHA-512 SHA-1
386 \ -- SHA-256 and SHA-224 are more efficient on 32-bit architectures
387 \ -- SHA-1 is less than ideally collision-resistant
395 : ext-supported-curves-length ( -- len )
396 supported-curves dup if
399 dup 1 and x + >x
400 1 >>
402 drop x 1 << 6 +
406 : ext-point-format-length ( -- len )
407 supported-curves if 6 else 0 then ;
410 cc: ext-ALPN-length ( -- len ) {
413 if (ENG->protocol_names_num == 0) {
418 for (u = 0; u < ENG->protocol_names_num; u ++) {
419 len += 1 + strlen(ENG->protocol_names[u]);
425 : write-ClientHello ( -- )
426 { ; total-ext-length }
428 \ Compute length for extensions (without the general two-byte header).
430 ext-reneg-length ext-sni-length + ext-frag-length +
431 ext-signatures-length +
432 ext-supported-curves-length + ext-point-format-length +
433 ext-ALPN-length +
434 >total-ext-length
437 1 write8
440 39 addr-session_id_len get8 + addr-suites_num get8 1 << +
441 total-ext-length if 2+ total-ext-length + then
443 addr-min_clienthello_len get16 over - dup 0> if
447 total-ext-length ifnot swap 2+ swap 2- then
449 4 - dup 0< if drop 0 then
451 dup 4 + total-ext-length + >total-ext-length
456 -1
458 { ext-padding-amount }
462 addr-version_max get16 write16
465 addr-client_random 4 bzero
466 addr-client_random 4 + 28 mkrand
467 addr-client_random 32 write-blob
470 addr-session_id addr-session_id_len get8 write-blob-head8
474 addr-suites_num get8 dup 1 << write16
475 addr-suites_buf swap
477 dup while 1-
479 dup suite-supported? ifnot ERR_BAD_CIPHER_SUITE fail then
486 1 write8 0 write8
489 total-ext-length if
490 total-ext-length write16
491 ext-reneg-length if
493 addr-saved_finished
494 ext-reneg-length 4 - dup write16 \ extension length
495 1- write-blob-head8 \ verify data
497 ext-sni-length if
499 addr-server_name
500 ext-sni-length 4 - dup write16 \ extension length
501 2 - dup write16 \ ServerNameList length
503 3 - write-blob-head16 \ the name itself
505 ext-frag-length if
506 0x0001 write16 \ extension type (1)
508 addr-log_max_frag_len get8 8 - write8
510 ext-signatures-length if
512 ext-signatures-length 4 - dup write16 \ extension length
513 2 - write16 \ list length
514 supports-ecdsa? if 3 write-hashes then
515 supports-rsa-sign? if 1 write-hashes then
519 \ increasing ID values (hence P-256 in second).
520 ext-supported-curves-length dup if
522 4 - dup write16 \ extension length
523 2- write16 \ list length
524 supported-curves 0
529 dup2 >> 1 and if dup write16 then
530 1+
536 ext-point-format-length if
539 0x0100 write16 \ value: 1 format: uncompressed
541 ext-ALPN-length dup if
543 4 - dup write16 \ extension length
544 2- write16 \ list length
545 addr-protocol_names_num get16 0
548 dup copy-protocol-name
549 dup write8 addr-pad swap write-blob
550 1+
556 ext-padding-amount 0< ifnot
558 ext-padding-amount
561 1- 0 write8 repeat \ value (only zeros)
570 : read-server-sni ( lim -- lim )
578 : read-server-frag ( lim -- lim )
579 read16 1 = ifnot ERR_BAD_FRAGLEN fail then
580 read8 8 + addr-log_max_frag_len get8 = ifnot ERR_BAD_FRAGLEN fail then ;
587 : read-server-reneg ( lim -- lim )
589 addr-reneg get8 ifnot
593 1 = ifnot ERR_BAD_SECRENEG fail then
595 2 addr-reneg set8
597 \ "reneg" is non-zero, and we sent an extension, so it must
603 addr-pad 24 read-blob
604 addr-saved_finished addr-pad 24 memcmp ifnot
611 : read-ALPN-from-server ( lim -- lim )
613 read16 open-elt
615 read16 open-elt
617 read8 addr-pad swap dup { len } read-blob
618 close-elt
619 close-elt
620 len test-protocol-name dup 0< if
624 1+ addr-selected_protocol set16
627 \ Save a value in a 16-bit field, or check it in case of session resumption.
628 : check-resume ( val addr resume -- )
631 cc: DEBUG-BLOB ( addr len -- ) {
648 \ Parse incoming ServerHello. Returned value is true (-1) on session
650 : read-ServerHello ( -- bool )
652 read-handshake-header 2 = ifnot ERR_UNEXPECTED fail then
656 version addr-version_min get16 < version addr-version_max get16 > or if
661 version addr-version_in get16 <> if ERR_BAD_VERSION fail then
662 version addr-version_out set16
665 addr-server_random 32 read-blob
673 addr-pad idlen read-blob
674 idlen addr-session_id_len get8 = idlen 0 > and if
675 addr-session_id addr-pad idlen memcmp if
676 \ Server session ID is non-empty and matches what
678 -1 >resume
681 addr-session_id addr-pad idlen memcpy
682 idlen addr-session_id_len set8
685 version addr-version resume check-resume
690 dup scan-suite 0< if ERR_BAD_CIPHER_SUITE fail then
692 \ announced version: suites that don't use HMAC/SHA-1 are
693 \ for TLS-1.2 only, not older versions.
694 dup use-tls12? version 0x0303 < and if ERR_BAD_CIPHER_SUITE fail then
695 addr-cipher_suite resume check-resume
705 read16 open-elt
710 ext-sni-length { ok-sni }
711 ext-reneg-length { ok-reneg }
712 ext-frag-length { ok-frag }
713 ext-signatures-length { ok-signatures }
714 ext-supported-curves-length { ok-curves }
715 ext-point-format-length { ok-points }
716 ext-ALPN-length { ok-ALPN }
725 ok-sni ifnot
728 0 >ok-sni
729 read-server-sni
736 ok-frag ifnot
739 0 >ok-frag
740 read-server-frag
745 ok-reneg ifnot
748 0 >ok-reneg
749 read-server-reneg
754 \ extension (so says RFC 5246 #7.4.1.4.1),
757 ok-signatures ifnot
760 0 >ok-signatures
761 read-ignore-16
766 ok-curves ifnot
769 0 >ok-curves
770 read-ignore-16
775 ok-points ifnot
778 0 >ok-points
779 read-ignore-16
784 ok-ALPN ifnot
787 0 >ok-ALPN
788 read-ALPN-from-server
799 ok-reneg if
800 ok-reneg 5 > if ERR_BAD_SECRENEG fail then
801 1 addr-reneg set8
803 close-elt
809 ext-reneg-length 5 > if ERR_BAD_SECRENEG fail then
810 1 addr-reneg set8
812 close-elt
816 cc: set-server-curve ( -- ) {
820 xc = *(ENG->x509ctx);
821 pk = xc->get_pkey(ENG->x509ctx, NULL);
822 CTX->server_curve =
823 (pk->key_type == BR_KEYTYPE_EC) ? pk->key.ec.curve : 0;
827 : read-Certificate-from-server ( -- )
828 addr-cipher_suite get16 expected-key-type
829 -1 read-Certificate
835 set-server-curve ;
838 \ 'hash' is the hash function to use (1 to 6, or 0 for RSA with MD5+SHA-1)
839 \ 'use-rsa' is 0 for ECDSA, -1 for for RSA
840 \ 'sig-len' is the signature length (in bytes)
842 cc: verify-SKE-sig ( hash use-rsa sig-len -- err ) {
851 : read-ServerKeyExchange ( -- )
853 read-handshake-header 12 = ifnot ERR_UNEXPECTED fail then
857 read16 dup addr-ecdhe_curve set8
859 supported-curves swap >> 1 and ifnot ERR_INVALID_ALGORITHM fail then
864 dup addr-ecdhe_point_len set8
865 addr-ecdhe_point swap read-blob
867 \ If using TLS-1.2+, then the hash function and signature algorithm
869 \ the cipher suite specifies. With TLS-1.0 and 1.1, the signature
871 \ either MD5+SHA-1 (for RSA signatures) or SHA-1 (for ECDSA).
872 addr-version get16 0x0303 >= { tls1.2+ }
873 addr-cipher_suite get16 use-rsa-ecdhe? { use-rsa }
876 \ Read hash function; accept only the SHA-* identifiers
877 \ (from SHA-1 to SHA-512, no MD5 here).
883 \ the server just sent. Expected value is 1 for RSA, 3
884 \ for ECDSA. Note that 'use-rsa' evaluates to -1 for RSA,
886 use-rsa 1 << 3 + = ifnot ERR_INVALID_ALGORITHM fail then
888 \ For MD5+SHA-1, we set 'hash' to 0.
889 use-rsa if 0 >hash then
893 read16 dup { sig-len }
896 addr-pad swap read-blob
899 hash use-rsa sig-len verify-SKE-sig
902 close-elt ;
905 cc: anchor-dn-start-name-list ( -- ) {
906 if (CTX->client_auth_vtable != NULL) {
907 (*CTX->client_auth_vtable)->start_name_list(
908 CTX->client_auth_vtable);
912 \ Client certificate: start a new anchor DN (length is 16-bit).
913 cc: anchor-dn-start-name ( length -- ) {
917 if (CTX->client_auth_vtable != NULL) {
918 (*CTX->client_auth_vtable)->start_name(
919 CTX->client_auth_vtable, len);
924 cc: anchor-dn-append-name ( length -- ) {
928 if (CTX->client_auth_vtable != NULL) {
929 (*CTX->client_auth_vtable)->append_name(
930 CTX->client_auth_vtable, ENG->pad, len);
935 cc: anchor-dn-end-name ( -- ) {
936 if (CTX->client_auth_vtable != NULL) {
937 (*CTX->client_auth_vtable)->end_name(
938 CTX->client_auth_vtable);
943 cc: anchor-dn-end-name-list ( -- ) {
944 if (CTX->client_auth_vtable != NULL) {
945 (*CTX->client_auth_vtable)->end_name_list(
946 CTX->client_auth_vtable);
951 cc: get-client-chain ( auth_types -- ) {
955 if (CTX->client_auth_vtable != NULL) {
958 (*CTX->client_auth_vtable)->choose(CTX->client_auth_vtable,
960 CTX->auth_type = (unsigned char)ux.auth_type;
961 CTX->hash_id = (unsigned char)ux.hash_id;
962 ENG->chain = ux.chain;
963 ENG->chain_len = ux.chain_len;
965 CTX->hash_id = 0;
966 ENG->chain_len = 0;
971 : read-contents-CertificateRequest ( lim -- )
975 read8 open-elt
978 1 of 0x0000FF endof
986 close-elt
994 addr-cipher_suite get16 use-ecdh? ifnot
1004 \ - rsa_fixed_ecdh and ecdsa_fixed_ecdh are synoymous.
1005 \ - There is an explicit list of supported sign+hash.
1007 addr-version get16 0x0303 >= if
1009 \ - There is an explicit list of supported sign+hash.
1010 \ - The ECDH flags must be adjusted for RSA/ECDSA
1012 read-list-sign-algos dup addr-hashes set32
1017 supported-hash-functions drop dup 8 << or 0x030000 or and
1027 \ (MD5+SHA-1 for RSA, SHA-1 for ECDSA).
1032 anchor-dn-start-name-list
1033 read16 open-elt
1035 read16 open-elt
1036 dup anchor-dn-start-name
1039 \ as to use the existing reading function (read-blob)
1044 addr-pad len read-blob
1045 len anchor-dn-append-name
1047 close-elt
1048 anchor-dn-end-name
1050 close-elt
1051 anchor-dn-end-name-list
1054 close-elt
1057 auth_types get-client-chain
1062 \ : write-empty-Certificate ( -- )
1065 cc: do-rsa-encrypt ( prf_id -- nlen ) {
1070 br_ssl_engine_fail(ENG, -x);
1077 cc: do-ecdh ( echde prf_id -- ulen ) {
1084 br_ssl_engine_fail(ENG, -x);
1091 cc: do-static-ecdh ( prf-id -- ) {
1095 br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM);
1100 cc: do-client-sign ( -- sig_len ) {
1105 br_ssl_engine_fail(ENG, BR_ERR_INVALID_ALGORITHM);
1112 : write-ClientKeyExchange ( -- )
1114 addr-cipher_suite get16
1115 dup use-rsa-keyx? if
1116 prf-id do-rsa-encrypt
1119 addr-pad swap write-blob
1121 dup use-ecdhe? swap prf-id do-ecdh
1122 dup 1+ write24
1124 addr-pad swap write-blob
1129 : write-CertificateVerify ( -- )
1130 do-client-sign
1132 addr-version get16 0x0303 >= if
1134 addr-hash_id get8 write8
1135 addr-auth_type get8 write8
1139 dup write16 addr-pad swap write-blob ;
1144 : do-handshake ( -- )
1145 0 addr-application_data set8
1146 22 addr-record_type_out set8
1147 0 addr-selected_protocol set16
1148 multihash-init
1150 write-ClientHello
1151 flush-record
1152 read-ServerHello
1156 -1 read-CCS-Finished
1157 -1 write-CCS-Finished
1165 read-Certificate-from-server
1169 addr-cipher_suite get16 expected-key-type
1171 read-ServerKeyExchange
1175 read-handshake-header
1180 drop read-contents-CertificateRequest
1181 read-handshake-header
1182 -1
1186 { seen-CR }
1194 more-incoming-bytes? if ERR_UNEXPECTED fail then
1196 seen-CR if
1200 write-Certificate
1207 addr-hash_id get8 0xFF = if
1210 addr-cipher_suite get16 prf-id do-static-ecdh
1212 write-ClientKeyExchange
1213 if write-CertificateVerify then
1216 write-ClientKeyExchange
1219 -1 write-CCS-Finished
1220 -1 read-CCS-Finished
1224 1 addr-application_data set8
1225 23 addr-record_type_out set8 ;
1228 : read-HelloRequest ( -- )
1230 read-handshake-header-core
1235 : main ( -- ! )
1237 do-handshake
1243 wait-co
1247 do-handshake
1252 0 addr-application_data set8
1253 read-HelloRequest
1257 addr-reneg get8 1 = 1 flag? or if
1258 flush-record
1259 begin can-output? not while
1260 wait-co drop
1262 100 send-warning
1267 1 addr-application_data set8
1268 23 addr-record_type_out set8
1270 do-handshake