aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-14 13:57:16 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-14 13:57:16 +0100
commitb1003f7019827d4d2581cc447e293294a1d8e5ae (patch)
tree270b3856a1037635c452927b6e5a7339364907f4
parentceff6b0ea9d8084b439e7d80f42c073d3bdda58d (diff)
downloadbusybox-w32-b1003f7019827d4d2581cc447e293294a1d8e5ae.tar.gz
busybox-w32-b1003f7019827d4d2581cc447e293294a1d8e5ae.tar.bz2
busybox-w32-b1003f7019827d4d2581cc447e293294a1d8e5ae.zip
tls: a bit more work
$ ./busybox tls kernel.org insize:0 tail:0 got block len:74 got HANDSHAKE got SERVER_HELLO insize:79 tail:4406 got block len:4392 got HANDSHAKE got CERTIFICATE entered der @0x8f7e723:0x30 len:1452 inner_byte @0x8f7e727:0x30 entered der @0x8f7e727:0x30 len:1172 inner_byte @0x8f7e72b: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 @0x8f7e830:0x30 len:418 inner_byte @0x8f7e834:0x30 skipped der 0x30, next byte 0x03 entered der @0x8f7e843:0x03 len:399 inner_byte @0x8f7e847:0x00 copying key bytes:399, first:0x00 insize:4397 tail:9 got block len:4 got SERVER_HELLO_DONE Now need to teach it to send ClientKeyExchange... Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/tls.c72
1 files changed, 39 insertions, 33 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 983ed507d..3b6347ecc 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -128,7 +128,7 @@
128// (tested b/c this one doesn't req server certs... no luck) 128// (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 129//test TLS_RSA_WITH_AES_128_CBC_SHA, in tls 1.2 it's mandated to be always supported
130 130
131struct transport_hdr { 131struct record_hdr {
132 uint8_t type; 132 uint8_t type;
133 uint8_t proto_maj, proto_min; 133 uint8_t proto_maj, proto_min;
134 uint8_t len16_hi, len16_lo; 134 uint8_t len16_hi, len16_lo;
@@ -140,8 +140,6 @@ typedef struct tls_state {
140 uint8_t *pubkey; 140 uint8_t *pubkey;
141 int pubkey_len; 141 int pubkey_len;
142 142
143 int insize;
144 int tail;
145 // RFC 5246 143 // RFC 5246
146 // |6.2.1. Fragmentation 144 // |6.2.1. Fragmentation
147 // | The record layer fragments information blocks into TLSPlaintext 145 // | The record layer fragments information blocks into TLSPlaintext
@@ -167,6 +165,8 @@ typedef struct tls_state {
167 // | The length MUST NOT exceed 2^14 + 1024. 165 // | The length MUST NOT exceed 2^14 + 1024.
168 // 166 //
169 // Since our buffer also contains 5-byte headers, make it a bit bigger: 167 // Since our buffer also contains 5-byte headers, make it a bit bigger:
168 int insize;
169 int tail;
170 uint8_t inbuf[18*1024]; 170 uint8_t inbuf[18*1024];
171} tls_state_t; 171} tls_state_t;
172 172
@@ -220,6 +220,7 @@ static void tls_error_die(tls_state_t *tls)
220 220
221static int xread_tls_block(tls_state_t *tls) 221static int xread_tls_block(tls_state_t *tls)
222{ 222{
223 struct record_hdr *xhdr;
223 int len; 224 int len;
224 int total; 225 int total;
225 int target; 226 int target;
@@ -230,21 +231,28 @@ static int xread_tls_block(tls_state_t *tls)
230 total = tls->tail; 231 total = tls->tail;
231 target = sizeof(tls->inbuf); 232 target = sizeof(tls->inbuf);
232 for (;;) { 233 for (;;) {
233 if (total >= sizeof(struct transport_hdr) && target == sizeof(tls->inbuf)) { 234 if (total >= sizeof(*xhdr) && target == sizeof(tls->inbuf)) {
234 struct transport_hdr *xhdr = (void*)tls->inbuf; 235 xhdr = (void*)tls->inbuf;
235 target = sizeof(*xhdr) + (0x100 * xhdr->len16_hi + xhdr->len16_lo); 236 target = sizeof(*xhdr) + (0x100 * xhdr->len16_hi + xhdr->len16_lo);
237 if (target >= sizeof(tls->inbuf)) {
238 /* malformed input (too long): yell and die */
239 tls->tail = 0;
240 tls->insize = total;
241 tls_error_die(tls);
242 }
243 // can also check type/proto_maj/proto_min here
236 } 244 }
237 /* if total >= target, we have a full packet (and possibly more)... */ 245 /* if total >= target, we have a full packet (and possibly more)... */
238 if (target - total <= 0) 246 if (total - target >= 0)
239 break; 247 break;
240 len = safe_read(tls->fd, tls->inbuf + total, sizeof(tls->inbuf) - total); 248 len = safe_read(tls->fd, tls->inbuf + total, sizeof(tls->inbuf) - total);
241 if (len <= 0) 249 if (len <= 0)
242 bb_perror_msg_and_die("short read"); 250 bb_perror_msg_and_die("short read");
243 total += len; 251 total += len;
244 } 252 }
245 tls->tail = -(target - total); 253 tls->tail = total - target;
246 tls->insize = target; 254 tls->insize = target;
247 target -= sizeof(struct transport_hdr); 255 target -= sizeof(*xhdr);
248 dbg("got block len:%u\n", target); 256 dbg("got block len:%u\n", target);
249 return target; 257 return target;
250} 258}
@@ -252,7 +260,7 @@ static int xread_tls_block(tls_state_t *tls)
252static void send_client_hello(tls_state_t *tls) 260static void send_client_hello(tls_state_t *tls)
253{ 261{
254 struct client_hello { 262 struct client_hello {
255 struct transport_hdr xhdr; 263 struct record_hdr xhdr;
256 uint8_t type; 264 uint8_t type;
257 uint8_t len24_hi, len24_mid, len24_lo; 265 uint8_t len24_hi, len24_mid, len24_lo;
258 uint8_t proto_maj, proto_min; 266 uint8_t proto_maj, proto_min;
@@ -270,18 +278,18 @@ static void send_client_hello(tls_state_t *tls)
270 hello.xhdr.type = RECORD_TYPE_HANDSHAKE; 278 hello.xhdr.type = RECORD_TYPE_HANDSHAKE;
271 hello.xhdr.proto_maj = TLS_MAJ; 279 hello.xhdr.proto_maj = TLS_MAJ;
272 hello.xhdr.proto_min = TLS_MIN; 280 hello.xhdr.proto_min = TLS_MIN;
273 hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8; 281 //zero: hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8;
274 hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr)); 282 hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr));
275 hello.type = HANDSHAKE_CLIENT_HELLO; 283 hello.type = HANDSHAKE_CLIENT_HELLO;
276 hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8; 284 //hello.len24_hi = 0;
285 //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8;
277 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4); 286 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4);
278 hello.proto_maj = TLS_MAJ; 287 hello.proto_maj = TLS_MAJ;
279 hello.proto_min = TLS_MIN; 288 hello.proto_min = TLS_MIN;
280 //fillrand(hello.rand32, sizeof(hello.rand32));
281 open_read_close("/dev/urandom", hello.rand32, sizeof(hello.rand32)); 289 open_read_close("/dev/urandom", hello.rand32, sizeof(hello.rand32));
282 //hello.session_id_len = 0; 290 //hello.session_id_len = 0;
283 //hello.cipherid_len16_hi = 0; 291 //hello.cipherid_len16_hi = 0;
284 hello.cipherid_len16_lo = 2; 292 hello.cipherid_len16_lo = 2 * 1;
285 hello.cipherid[0] = CIPHER_ID >> 8; 293 hello.cipherid[0] = CIPHER_ID >> 8;
286 hello.cipherid[1] = CIPHER_ID & 0xff; 294 hello.cipherid[1] = CIPHER_ID & 0xff;
287 hello.comprtypes_len = 1; 295 hello.comprtypes_len = 1;
@@ -293,7 +301,7 @@ static void send_client_hello(tls_state_t *tls)
293static void get_server_hello_or_die(tls_state_t *tls) 301static void get_server_hello_or_die(tls_state_t *tls)
294{ 302{
295 struct server_hello { 303 struct server_hello {
296 struct transport_hdr xhdr; 304 struct record_hdr xhdr;
297 uint8_t type; 305 uint8_t type;
298 uint8_t len24_hi, len24_mid, len24_lo; 306 uint8_t len24_hi, len24_mid, len24_lo;
299 uint8_t proto_maj, proto_min; 307 uint8_t proto_maj, proto_min;
@@ -319,8 +327,9 @@ static void get_server_hello_or_die(tls_state_t *tls)
319 tls_error_die(tls); 327 tls_error_die(tls);
320 } 328 }
321 dbg("got HANDSHAKE\n"); 329 dbg("got HANDSHAKE\n");
322 // 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00| 330 // 74 bytes:
323 // SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel 331 // 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00|
332 //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel
324 if (hp->type != HANDSHAKE_SERVER_HELLO 333 if (hp->type != HANDSHAKE_SERVER_HELLO
325 || hp->len24_hi != 0 334 || hp->len24_hi != 0
326 || hp->len24_mid != 0 335 || hp->len24_mid != 0
@@ -359,8 +368,8 @@ static unsigned get_der_len(uint8_t **bodyp, uint8_t *der, uint8_t *end)
359 xfunc_die(); 368 xfunc_die();
360 /* it's "ii 82 xx yy" */ 369 /* it's "ii 82 xx yy" */
361 len = 0x100*der[2] + der[3]; 370 len = 0x100*der[2] + der[3];
362 if (len < 0x80) 371// if (len < 0x80)
363 xfunc_die(); /* invalid DER: must use short len if can */ 372// xfunc_die(); /* invalid DER: must use short len if can */
364 373
365 der += 2; /* skip [code]+[82]+[2byte_len] */ 374 der += 2; /* skip [code]+[82]+[2byte_len] */
366 } 375 }
@@ -395,7 +404,9 @@ static uint8_t *skip_der_item(uint8_t *der, uint8_t *end)
395 404
396static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len) 405static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len)
397{ 406{
398/* Example: partial decode of kernel.org certificate in DER format. 407/* Certificate is a DER-encoded data structure. Each DER element has a length,
408 * which makes it easy to skip over large compound elements of any complexity
409 * without parsing them. Example: partial decode of kernel.org certificate:
399 * SEQ 0x05ac/1452 bytes (Certificate): 308205ac 410 * SEQ 0x05ac/1452 bytes (Certificate): 308205ac
400 * SEQ 0x0494/1172 bytes (tbsCertificate): 30820494 411 * SEQ 0x0494/1172 bytes (tbsCertificate): 30820494
401 * [ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0] 3 bytes: a003 412 * [ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0] 3 bytes: a003
@@ -425,8 +436,7 @@ static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len)
425 * SET 32 bytes: 3120 436 * SET 32 bytes: 3120
426 * SEQ 30 bytes: 301e 437 * SEQ 30 bytes: 301e
427 * OID 3 bytes: 0603 550403 438 * OID 3 bytes: 0603 550403
428 * Printable string "Gandi Standard SSL CA 2": 1317 439 * Printable string "Gandi Standard SSL CA 2": 1317 47616e6469205374616e646172642053534c2043412032
429 * 47616e6469205374616e646172642053534c2043412032
430 * SEQ 30 bytes (validity): 301e 440 * SEQ 30 bytes (validity): 301e
431 * TIME "161011000000Z": 170d 3136313031313030303030305a 441 * TIME "161011000000Z": 170d 3136313031313030303030305a
432 * TIME "191011235959Z": 170d 3139313031313233353935395a 442 * TIME "191011235959Z": 170d 3139313031313233353935395a
@@ -452,10 +462,6 @@ static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len)
452 * [ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0x3] 0x01e5 bytes (X509v3 extensions): a38201e5 462 * [ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0x3] 0x01e5 bytes (X509v3 extensions): a38201e5
453 * SEQ 0x01e1 bytes: 308201e1 463 * SEQ 0x01e1 bytes: 308201e1
454 * ... 464 * ...
455 * Certificate is a DER-encoded data structure. Each DER element has a length,
456 * which makes it easy to skip over large compound elements of any complexity
457 * without parsing them.
458 *
459 * Certificate is a sequence of three elements: 465 * Certificate is a sequence of three elements:
460 * tbsCertificate (SEQ) 466 * tbsCertificate (SEQ)
461 * signatureAlgorithm (AlgorithmIdentifier) 467 * signatureAlgorithm (AlgorithmIdentifier)
@@ -475,7 +481,7 @@ static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len)
475 * algorithm (AlgorithmIdentifier) 481 * algorithm (AlgorithmIdentifier)
476 * publicKey (BIT STRING) 482 * publicKey (BIT STRING)
477 * 483 *
478 * Essentially, we want subjectPublicKeyInfo.publicKey 484 * We need Certificate.tbsCertificate.subjectPublicKeyInfo.publicKey
479 */ 485 */
480 uint8_t *end = der + len; 486 uint8_t *end = der + len;
481 487
@@ -510,7 +516,7 @@ static void *find_key_in_der_cert(int *key_len, uint8_t *der, int len)
510 516
511static void get_server_cert_or_die(tls_state_t *tls) 517static void get_server_cert_or_die(tls_state_t *tls)
512{ 518{
513 struct transport_hdr *xhdr; 519 struct record_hdr *xhdr;
514 uint8_t *certbuf; 520 uint8_t *certbuf;
515 int len, len1; 521 int len, len1;
516 522
@@ -528,16 +534,15 @@ static void get_server_cert_or_die(tls_state_t *tls)
528 if (certbuf[0] != HANDSHAKE_CERTIFICATE) 534 if (certbuf[0] != HANDSHAKE_CERTIFICATE)
529 tls_error_die(tls); 535 tls_error_die(tls);
530 dbg("got CERTIFICATE\n"); 536 dbg("got CERTIFICATE\n");
531 // 0b 00|11|24 00|11|21 00|05|b0 30|82|05|ac|30|82|04|94|a0|03|02|01|02|02|11|00|9f|85|bf|66|4b|0c|dd|af|ca|50|86|79|50|1b|2b|e4|30|0d... (4392 bytes) 537 // 4392 bytes:
532 // Cert len=4388 ChainLen CertLen^ DER encoded X509 starts here. openssl x509 -in FILE -inform DER -noout -text 538 // 0b 00|11|24 00|11|21 00|05|b0 30|82|05|ac|30|82|04|94|a0|03|02|01|02|02|11|00|9f|85|bf|66|4b|0c|dd|af|ca|50|86|79|50|1b|2b|e4|30|0d...
539 //Cert len=4388 ChainLen CertLen^ DER encoded X509 starts here. openssl x509 -in FILE -inform DER -noout -text
533 len1 = get24be(certbuf + 1); 540 len1 = get24be(certbuf + 1);
534 if (len1 > len - 4) tls_error_die(tls); 541 if (len1 > len - 4) tls_error_die(tls);
535 len = len1; 542 len = len1;
536
537 len1 = get24be(certbuf + 4); 543 len1 = get24be(certbuf + 4);
538 if (len1 > len - 3) tls_error_die(tls); 544 if (len1 > len - 3) tls_error_die(tls);
539 len = len1; 545 len = len1;
540
541 len1 = get24be(certbuf + 7); 546 len1 = get24be(certbuf + 7);
542 if (len1 > len - 3) tls_error_die(tls); 547 if (len1 > len - 3) tls_error_die(tls);
543 len = len1; 548 len = len1;
@@ -601,8 +606,9 @@ static void tls_handshake(tls_state_t *tls)
601 /* Next handshake type is not predetermined */ 606 /* Next handshake type is not predetermined */
602 switch (tls->inbuf[5]) { 607 switch (tls->inbuf[5]) {
603 case HANDSHAKE_SERVER_KEY_EXCHANGE: 608 case HANDSHAKE_SERVER_KEY_EXCHANGE:
604 //0c 0001c7 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... 459 bytes 609 // 459 bytes:
605 //SvKey len^^^ 610 // 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...
611 //SvKey len=455^
606 dbg("got SERVER_KEY_EXCHANGE\n"); 612 dbg("got SERVER_KEY_EXCHANGE\n");
607 len = xread_tls_block(tls); 613 len = xread_tls_block(tls);
608 break; 614 break;