aboutsummaryrefslogtreecommitdiff
path: root/networking/tls.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-15 00:12:42 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-15 00:12:42 +0100
commit11d0096516c0d5395729caba5dfd940a10a6e20c (patch)
tree035f3f0461a42b42421df48c9479bdc1549c1c09 /networking/tls.c
parent2a17d1fc9bdcbc97d48dd08a9fa4941da25187fd (diff)
downloadbusybox-w32-11d0096516c0d5395729caba5dfd940a10a6e20c.tar.gz
busybox-w32-11d0096516c0d5395729caba5dfd940a10a6e20c.tar.bz2
busybox-w32-11d0096516c0d5395729caba5dfd940a10a6e20c.zip
tls: format and send CLIENT_KEY_EXCHANGE
$ ./busybox tls kernel.org insize:0 tail:0 got block len:74 got HANDSHAKE got SERVER_HELLO insize:79 tail:4265 got block len:4392 got HANDSHAKE got CERTIFICATE entered der @0x8b217a7:0x30 len:1452 inner_byte @0x8b217ab:0x30 entered der @0x8b217ab:0x30 len:1172 inner_byte @0x8b217af:0xa0 skipped der 0xa0, next byte 0x02 skipped der 0x02, next byte 0x30 skipped der 0x30, next byte 0x30 skipped der 0x30, next byte 0x30 skipped der 0x30, next byte 0x30 skipped der 0x30, next byte 0x30 entered der @0x8b218b4:0x30 len:418 inner_byte @0x8b218b8:0x30 skipped der 0x30, next byte 0x03 entered der @0x8b218c7:0x03 len:399 inner_byte @0x8b218cb:0x00 key bytes:399, first:0x00 entered der @0x8b218cc:0x30 len:394 inner_byte @0x8b218d0:0x02 binary bytes:385, first:0x00 skipped der 0x02, next byte 0x02 binary bytes:3, first:0x01 server_rsa_pub_key.size:384 insize:4397 tail:9 got block len:4 got SERVER_HELLO_DONE insize:9 tail:0 ^C Next step: send CHANGE_CIPHER_SPEC... and actually implement it. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r--networking/tls.c225
1 files changed, 188 insertions, 37 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 69c81b558..b0a4f7e75 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Licensed under GPLv2, see file LICENSE in this source tree.
3 *
4 * Copyright (C) 2017 Denys Vlasenko 2 * Copyright (C) 2017 Denys Vlasenko
3 *
4 * Licensed under GPLv2, see file LICENSE in this source tree.
5 */ 5 */
6//config:config TLS 6//config:config TLS
7//config: bool "tls (debugging)" 7//config: bool "tls (debugging)"
@@ -10,6 +10,11 @@
10//applet:IF_TLS(APPLET(tls, BB_DIR_USR_BIN, BB_SUID_DROP)) 10//applet:IF_TLS(APPLET(tls, BB_DIR_USR_BIN, BB_SUID_DROP))
11 11
12//kbuild:lib-$(CONFIG_TLS) += tls.o 12//kbuild:lib-$(CONFIG_TLS) += tls.o
13//kbuild:lib-$(CONFIG_TLS) += tls_pstm.o
14//kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o
15//kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o
16//kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o
17//kbuild:lib-$(CONFIG_TLS) += tls_rsa.o
13////kbuild:lib-$(CONFIG_TLS) += tls_ciphers.o 18////kbuild:lib-$(CONFIG_TLS) += tls_ciphers.o
14////kbuild:lib-$(CONFIG_TLS) += tls_aes.o 19////kbuild:lib-$(CONFIG_TLS) += tls_aes.o
15////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o 20////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o
@@ -18,9 +23,7 @@
18//usage: "HOST[:PORT]" 23//usage: "HOST[:PORT]"
19//usage:#define tls_full_usage "\n\n" 24//usage:#define tls_full_usage "\n\n"
20 25
21#include "libbb.h" 26#include "tls.h"
22//#include "tls_cryptoapi.h"
23//#include "tls_ciphers.h"
24 27
25#if 1 28#if 1
26# define dbg(...) fprintf(stderr, __VA_ARGS__) 29# define dbg(...) fprintf(stderr, __VA_ARGS__)
@@ -28,23 +31,26 @@
28# define dbg(...) ((void)0) 31# define dbg(...) ((void)0)
29#endif 32#endif
30 33
31#define RECORD_TYPE_CHANGE_CIPHER_SPEC 20 34#define RECORD_TYPE_CHANGE_CIPHER_SPEC 20
32#define RECORD_TYPE_ALERT 21 35#define RECORD_TYPE_ALERT 21
33#define RECORD_TYPE_HANDSHAKE 22 36#define RECORD_TYPE_HANDSHAKE 22
34#define RECORD_TYPE_APPLICATION_DATA 23 37#define RECORD_TYPE_APPLICATION_DATA 23
35 38
36#define HANDSHAKE_HELLO_REQUEST 0 39#define HANDSHAKE_HELLO_REQUEST 0
37#define HANDSHAKE_CLIENT_HELLO 1 40#define HANDSHAKE_CLIENT_HELLO 1
38#define HANDSHAKE_SERVER_HELLO 2 41#define HANDSHAKE_SERVER_HELLO 2
39#define HANDSHAKE_HELLO_VERIFY_REQUEST 3 42#define HANDSHAKE_HELLO_VERIFY_REQUEST 3
40#define HANDSHAKE_NEW_SESSION_TICKET 4 43#define HANDSHAKE_NEW_SESSION_TICKET 4
41#define HANDSHAKE_CERTIFICATE 11 44#define HANDSHAKE_CERTIFICATE 11
42#define HANDSHAKE_SERVER_KEY_EXCHANGE 12 45#define HANDSHAKE_SERVER_KEY_EXCHANGE 12
43#define HANDSHAKE_CERTIFICATE_REQUEST 13 46#define HANDSHAKE_CERTIFICATE_REQUEST 13
44#define HANDSHAKE_SERVER_HELLO_DONE 14 47#define HANDSHAKE_SERVER_HELLO_DONE 14
45#define HANDSHAKE_CERTIFICATE_VERIFY 15 48#define HANDSHAKE_CERTIFICATE_VERIFY 15
46#define HANDSHAKE_CLIENT_KEY_EXCHANGE 16 49#define HANDSHAKE_CLIENT_KEY_EXCHANGE 16
47#define HANDSHAKE_FINISHED 20 50#define HANDSHAKE_FINISHED 20
51
52#define SSL_HS_RANDOM_SIZE 32
53#define SSL_HS_RSA_PREMASTER_SIZE 48
48 54
49#define SSL_NULL_WITH_NULL_NULL 0x0000 55#define SSL_NULL_WITH_NULL_NULL 0x0000
50#define SSL_RSA_WITH_NULL_MD5 0x0001 56#define SSL_RSA_WITH_NULL_MD5 0x0001
@@ -112,6 +118,7 @@
112//TLS 1.2 118//TLS 1.2
113#define TLS_MAJ 3 119#define TLS_MAJ 3
114#define TLS_MIN 3 120#define TLS_MIN 3
121//#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box
115//#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE 122//#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE
116// All GCMs: 123// All GCMs:
117//#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 // SSL_ALERT_HANDSHAKE_FAILURE 124//#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 // SSL_ALERT_HANDSHAKE_FAILURE
@@ -123,9 +130,9 @@
123//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 130//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
124//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE 131//#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE
125//#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE 132//#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE
126#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE 133#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE *** select this?
127//#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE 134//#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE
128// (tested b/c this one doesn't req server certs... no luck) 135//^^^^^^^^^^^^^^^^^^^^^^^ (tested b/c this one doesn't req server certs... no luck)
129//test TLS_RSA_WITH_AES_128_CBC_SHA, in tls 1.2 it's mandated to be always supported 136//test TLS_RSA_WITH_AES_128_CBC_SHA, in tls 1.2 it's mandated to be always supported
130 137
131struct record_hdr { 138struct record_hdr {
@@ -137,8 +144,7 @@ struct record_hdr {
137typedef struct tls_state { 144typedef struct tls_state {
138 int fd; 145 int fd;
139 146
140 uint8_t *pubkey; 147 psRsaKey_t server_rsa_pub_key;
141 int pubkey_len;
142 148
143 // RFC 5246 149 // RFC 5246
144 // |6.2.1. Fragmentation 150 // |6.2.1. Fragmentation
@@ -170,6 +176,12 @@ typedef struct tls_state {
170 uint8_t inbuf[18*1024]; 176 uint8_t inbuf[18*1024];
171} tls_state_t; 177} tls_state_t;
172 178
179void tls_get_random(void *buf, unsigned len)
180{
181 if (len != open_read_close("/dev/urandom", buf, len))
182 xfunc_die();
183}
184
173static 185static
174tls_state_t *new_tls_state(void) 186tls_state_t *new_tls_state(void)
175{ 187{
@@ -286,7 +298,7 @@ static void send_client_hello(tls_state_t *tls)
286 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4); 298 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
287 hello.proto_maj = TLS_MAJ; 299 hello.proto_maj = TLS_MAJ;
288 hello.proto_min = TLS_MIN; 300 hello.proto_min = TLS_MIN;
289 open_read_close("/dev/urandom", hello.rand32, sizeof(hello.rand32)); 301 tls_get_random(hello.rand32, sizeof(hello.rand32));
290 //hello.session_id_len = 0; 302 //hello.session_id_len = 0;
291 //hello.cipherid_len16_hi = 0; 303 //hello.cipherid_len16_hi = 0;
292 hello.cipherid_len16_lo = 2 * 1; 304 hello.cipherid_len16_lo = 2 * 1;
@@ -407,7 +419,18 @@ static uint8_t *skip_der_item(uint8_t *der, uint8_t *end)
407 return new_der; 419 return new_der;
408} 420}
409 421
410static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len) 422static void der_binary_to_pstm(pstm_int *pstm_n, uint8_t *der, uint8_t *end)
423{
424 uint8_t *bin_ptr;
425 unsigned len = get_der_len(&bin_ptr, der, end);
426
427 dbg("binary bytes:%u, first:0x%02x\n", len, bin_ptr[0]);
428 pstm_init_for_read_unsigned_bin(/*pool:*/ NULL, pstm_n, len);
429 pstm_read_unsigned_bin(pstm_n, bin_ptr, len);
430 //return bin + len;
431}
432
433static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
411{ 434{
412/* Certificate is a DER-encoded data structure. Each DER element has a length, 435/* Certificate is a DER-encoded data structure. Each DER element has a length,
413 * which makes it easy to skip over large compound elements of any complexity 436 * which makes it easy to skip over large compound elements of any complexity
@@ -504,19 +527,43 @@ static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len)
504 der = skip_der_item(der, end); /* validity */ 527 der = skip_der_item(der, end); /* validity */
505 der = skip_der_item(der, end); /* subject */ 528 der = skip_der_item(der, end); /* subject */
506 529
507 /* enter "subjectPublicKeyInfo" */ 530 /* enter subjectPublicKeyInfo */
508 der = enter_der_item(der, &end); 531 der = enter_der_item(der, &end);
509 532 { /* check subjectPublicKeyInfo.algorithm */
510 /* skip "subjectPublicKeyInfo.algorithm" */ 533 static const uint8_t expected[] = {
534 0x30,0x0d, // SEQ 13 bytes
535 0x06,0x09, 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, // OID RSA_KEY_ALG 42.134.72.134.247.13.1.1.1
536 //0x05,0x00, // NULL
537 };
538 if (memcmp(der, expected, sizeof(expected)) != 0)
539 bb_error_msg_and_die("not RSA key");
540 }
541 /* skip subjectPublicKeyInfo.algorithm */
511 der = skip_der_item(der, end); 542 der = skip_der_item(der, end);
512 /* enter "subjectPublicKeyInfo.publicKey" */ 543 /* enter subjectPublicKeyInfo.publicKey */
513// die_if_not_this_der_type(der, end, 0x03); /* must be BITSTRING */ 544// die_if_not_this_der_type(der, end, 0x03); /* must be BITSTRING */
514 der = enter_der_item(der, &end); 545 der = enter_der_item(der, &end);
515 546
516 /* return a copy */ 547 /* parse RSA key: */
517 *key_len = end - der; 548//based on getAsnRsaPubKey(), pkcs1ParsePrivBin() is also of note
518 dbg("copying key bytes:%u, first:0x%02x\n", *key_len, der[0]); 549 dbg("key bytes:%u, first:0x%02x\n", (int)(end - der), der[0]);
519 return xmemdup(der, *key_len); 550 if (end - der < 14) xfunc_die();
551 /* example format:
552 * ignore bits: 00
553 * SEQ 0x018a/394 bytes: 3082018a
554 * INTEGER 0x0181/385 bytes (modulus): 02820181 XX...XXX
555 * INTEGER 3 bytes (exponent): 0203 010001
556 */
557 if (*der != 0) /* "ignore bits", should be 0 */
558 xfunc_die();
559 der++;
560 der = enter_der_item(der, &end); /* enter SEQ */
561 //memset(tls->server_rsa_pub_key, 0, sizeof(tls->server_rsa_pub_key));
562 der_binary_to_pstm(&tls->server_rsa_pub_key.N, der, end); /* modulus */
563 der = skip_der_item(der, end);
564 der_binary_to_pstm(&tls->server_rsa_pub_key.e, der, end); /* exponent */
565 tls->server_rsa_pub_key.size = pstm_unsigned_bin_size(&tls->server_rsa_pub_key.N);
566 dbg("server_rsa_pub_key.size:%d\n", tls->server_rsa_pub_key.size);
520} 567}
521 568
522static void get_server_cert_or_die(tls_state_t *tls) 569static void get_server_cert_or_die(tls_state_t *tls)
@@ -553,7 +600,107 @@ static void get_server_cert_or_die(tls_state_t *tls)
553 len = len1; 600 len = len1;
554 601
555 if (len) 602 if (len)
556 tls->pubkey = find_key_in_der_cert(&tls->pubkey_len, certbuf + 10, len); 603 find_key_in_der_cert(tls, certbuf + 10, len);
604}
605
606static void send_client_key_exchange(tls_state_t *tls)
607{
608#if 0 //matrixssl code snippets:
609 int32 csRsaEncryptPub(psPool_t *pool, psPubKey_t *key,
610 unsigned char *in, uint32 inlen, unsigned char *out, uint32 outlen,
611 void *data)
612 {
613 psAssert(key->type == PS_RSA);
614 return psRsaEncryptPub(pool, (psRsaKey_t*)key->key, in, inlen, out, outlen,
615 data);
616 }
617...
618 /* pkaAfter.user is buffer len */
619 if ((rc = csRsaEncryptPub(pka->pool, &ssl->sec.cert->publicKey,
620 ssl->sec.premaster, ssl->sec.premasterSize, pka->outbuf,
621 pka->user, pka->data)) < 0) {
622 if (rc == PS_PENDING) {
623 /* For these ClientKeyExchange paths, we do want to come
624 back through nowDoCkePka for a double pass so each
625 case can manage its own pkaAfter and to make sure
626 psX509FreeCert and sslCreateKeys() are hit below. */
627 return rc;
628 }
629 psTraceIntInfo("csRsaEncryptPub in CKE failed %d\n", rc);
630 return MATRIXSSL_ERROR;
631 }
632 /* RSA closed the pool on second pass */
633 pka->pool = NULL;
634 clearPkaAfter(ssl);
635...
636#ifdef USE_RSA_CIPHER_SUITE
637/*
638 Standard RSA suite
639*/
640 ssl->sec.premasterSize = SSL_HS_RSA_PREMASTER_SIZE;
641 ssl->sec.premaster = psMalloc(ssl->hsPool,
642 SSL_HS_RSA_PREMASTER_SIZE);
643 if (ssl->sec.premaster == NULL) {
644 return SSL_MEM_ERROR;
645 }
646
647 ssl->sec.premaster[0] = ssl->reqMajVer;
648 ssl->sec.premaster[1] = ssl->reqMinVer;
649 if (matrixCryptoGetPrngData(ssl->sec.premaster + 2,
650 SSL_HS_RSA_PREMASTER_SIZE - 2, ssl->userPtr) < 0) {
651 return MATRIXSSL_ERROR;
652 }
653
654 /* Shedule RSA encryption. Put tmp pool under control of After */
655 pkaAfter->type = PKA_AFTER_RSA_ENCRYPT;
656 pkaAfter->outbuf = c;
657 pkaAfter->data = pkiData;
658 pkaAfter->pool = pkiPool;
659 pkaAfter->user = (uint32)(end - c); /* Available space */
660
661 c += keyLen;
662#endif
663#endif // 0
664
665 struct client_key_exchange {
666 struct record_hdr xhdr;
667 uint8_t type;
668 uint8_t len24_hi, len24_mid, len24_lo;
669 uint8_t keylen16_hi, keylen16_lo; /* exist for RSA, but not for some other key types */
670//had a bug when had no keylen: we:
671//write(3, "\x16\x03\x03\x01\x84\x10\x00\x01\x80\xXX\xXX\xXX\xXX\xXX\xXX...", 393) = 393
672//openssl:
673//write to 0xe9a090 [0xf9ac20] (395 bytes => 395 (0x18B))
674//0000 - 16 03 03 01 86 10 00 01 -82 01 80 xx xx xx xx xx
675 uint8_t key[384]; // size??
676 };
677 struct client_key_exchange record;
678 uint8_t premaster[SSL_HS_RSA_PREMASTER_SIZE];
679
680 memset(&record, 0, sizeof(record));
681 record.xhdr.type = RECORD_TYPE_HANDSHAKE;
682 record.xhdr.proto_maj = TLS_MAJ;
683 record.xhdr.proto_min = TLS_MIN;
684 record.xhdr.len16_hi = (sizeof(record) - sizeof(record.xhdr)) >> 8;
685 record.xhdr.len16_lo = (sizeof(record) - sizeof(record.xhdr)) & 0xff;
686 record.type = HANDSHAKE_CLIENT_KEY_EXCHANGE;
687 //record.len24_hi = 0;
688 record.len24_mid = (sizeof(record) - sizeof(record.xhdr) - 4) >> 8;
689 record.len24_lo = (sizeof(record) - sizeof(record.xhdr) - 4) & 0xff;
690 record.keylen16_hi = (sizeof(record) - sizeof(record.xhdr) - 6) >> 8;
691 record.keylen16_lo = (sizeof(record) - sizeof(record.xhdr) - 6) & 0xff;
692
693 tls_get_random(premaster, sizeof(premaster));
694 premaster[0] = TLS_MAJ;
695 premaster[1] = TLS_MIN;
696 psRsaEncryptPub(/*pool:*/ NULL,
697 /* psRsaKey_t* */ &tls->server_rsa_pub_key,
698 premaster, /*inlen:*/ sizeof(premaster),
699 record.key, sizeof(record.key),
700 data_param_ignored
701 );
702
703 xwrite(tls->fd, &record, sizeof(record));
557} 704}
558 705
559static void tls_handshake(tls_state_t *tls) 706static void tls_handshake(tls_state_t *tls)
@@ -614,6 +761,8 @@ static void tls_handshake(tls_state_t *tls)
614 // 459 bytes: 761 // 459 bytes:
615 // 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a... 762 // 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a...
616 //SvKey len=455^ 763 //SvKey len=455^
764 // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes:
765 // 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75...
617 dbg("got SERVER_KEY_EXCHANGE\n"); 766 dbg("got SERVER_KEY_EXCHANGE\n");
618 len = xread_tls_block(tls); 767 len = xread_tls_block(tls);
619 break; 768 break;
@@ -624,6 +773,8 @@ static void tls_handshake(tls_state_t *tls)
624 case HANDSHAKE_SERVER_HELLO_DONE: 773 case HANDSHAKE_SERVER_HELLO_DONE:
625 // 0e 000000 (len:0) 774 // 0e 000000 (len:0)
626 dbg("got SERVER_HELLO_DONE\n"); 775 dbg("got SERVER_HELLO_DONE\n");
776 send_client_key_exchange(tls);
777 len = xread_tls_block(tls);
627 break; 778 break;
628 default: 779 default:
629 tls_error_die(tls); 780 tls_error_die(tls);