diff options
-rw-r--r-- | networking/tls.c | 362 | ||||
-rw-r--r-- | networking/tls_pstm.c | 14 | ||||
-rw-r--r-- | networking/tls_pstm.h | 9 | ||||
-rw-r--r-- | networking/tls_pstm_montgomery_reduce.c | 6 | ||||
-rw-r--r-- | networking/tls_pstm_mul_comba.c | 8 | ||||
-rw-r--r-- | networking/tls_pstm_sqr_comba.c | 8 | ||||
-rw-r--r-- | networking/tls_rsa.c | 122 | ||||
-rw-r--r-- | networking/tls_rsa.h | 2 |
8 files changed, 304 insertions, 227 deletions
diff --git a/networking/tls.c b/networking/tls.c index 71e5ac3a5..44c9da195 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -286,85 +286,6 @@ static int xread_tls_handshake_block(tls_state_t *tls, int min_len) | |||
286 | return len; | 286 | return len; |
287 | } | 287 | } |
288 | 288 | ||
289 | static void send_client_hello(tls_state_t *tls) | ||
290 | { | ||
291 | struct client_hello { | ||
292 | struct record_hdr xhdr; | ||
293 | uint8_t type; | ||
294 | uint8_t len24_hi, len24_mid, len24_lo; | ||
295 | uint8_t proto_maj, proto_min; | ||
296 | uint8_t rand32[32]; | ||
297 | uint8_t session_id_len; | ||
298 | /* uint8_t session_id[]; */ | ||
299 | uint8_t cipherid_len16_hi, cipherid_len16_lo; | ||
300 | uint8_t cipherid[2 * 1]; /* actually variable */ | ||
301 | uint8_t comprtypes_len; | ||
302 | uint8_t comprtypes[1]; /* actually variable */ | ||
303 | }; | ||
304 | struct client_hello hello; | ||
305 | |||
306 | memset(&hello, 0, sizeof(hello)); | ||
307 | hello.xhdr.type = RECORD_TYPE_HANDSHAKE; | ||
308 | hello.xhdr.proto_maj = TLS_MAJ; | ||
309 | hello.xhdr.proto_min = TLS_MIN; | ||
310 | //zero: hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8; | ||
311 | hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr)); | ||
312 | hello.type = HANDSHAKE_CLIENT_HELLO; | ||
313 | //hello.len24_hi = 0; | ||
314 | //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8; | ||
315 | hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4); | ||
316 | hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ | ||
317 | hello.proto_min = TLS_MIN; /* can be higher than one in record headers */ | ||
318 | tls_get_random(hello.rand32, sizeof(hello.rand32)); | ||
319 | //hello.session_id_len = 0; | ||
320 | //hello.cipherid_len16_hi = 0; | ||
321 | hello.cipherid_len16_lo = 2 * 1; | ||
322 | hello.cipherid[0] = CIPHER_ID >> 8; | ||
323 | hello.cipherid[1] = CIPHER_ID & 0xff; | ||
324 | hello.comprtypes_len = 1; | ||
325 | //hello.comprtypes[0] = 0; | ||
326 | |||
327 | xwrite(tls->fd, &hello, sizeof(hello)); | ||
328 | } | ||
329 | |||
330 | static void get_server_hello_or_die(tls_state_t *tls) | ||
331 | { | ||
332 | struct server_hello { | ||
333 | struct record_hdr xhdr; | ||
334 | uint8_t type; | ||
335 | uint8_t len24_hi, len24_mid, len24_lo; | ||
336 | uint8_t proto_maj, proto_min; | ||
337 | uint8_t rand32[32]; /* first 4 bytes are unix time in BE format */ | ||
338 | uint8_t session_id_len; | ||
339 | uint8_t session_id[32]; | ||
340 | uint8_t cipherid_hi, cipherid_lo; | ||
341 | uint8_t comprtype; | ||
342 | /* extensions may follow, but only those which client offered in its Hello */ | ||
343 | }; | ||
344 | struct server_hello *hp; | ||
345 | |||
346 | xread_tls_handshake_block(tls, 74); | ||
347 | |||
348 | hp = (void*)tls->inbuf; | ||
349 | // 74 bytes: | ||
350 | // 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| | ||
351 | //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel | ||
352 | if (hp->type != HANDSHAKE_SERVER_HELLO | ||
353 | || hp->len24_hi != 0 | ||
354 | || hp->len24_mid != 0 | ||
355 | || hp->len24_lo != 70 | ||
356 | || hp->proto_maj != TLS_MAJ | ||
357 | || hp->proto_min != TLS_MIN | ||
358 | || hp->session_id_len != 32 | ||
359 | || hp->cipherid_hi != (CIPHER_ID >> 8) | ||
360 | || hp->cipherid_lo != (CIPHER_ID & 0xff) | ||
361 | || hp->comprtype != 0 | ||
362 | ) { | ||
363 | tls_error_die(tls); | ||
364 | } | ||
365 | dbg("got SERVER_HELLO\n"); | ||
366 | } | ||
367 | |||
368 | static unsigned get_der_len(uint8_t **bodyp, uint8_t *der, uint8_t *end) | 289 | static unsigned get_der_len(uint8_t **bodyp, uint8_t *der, uint8_t *end) |
369 | { | 290 | { |
370 | unsigned len, len1; | 291 | unsigned len, len1; |
@@ -573,7 +494,104 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) | |||
573 | dbg("server_rsa_pub_key.size:%d\n", tls->server_rsa_pub_key.size); | 494 | dbg("server_rsa_pub_key.size:%d\n", tls->server_rsa_pub_key.size); |
574 | } | 495 | } |
575 | 496 | ||
576 | static void get_server_cert_or_die(tls_state_t *tls) | 497 | /* |
498 | * TLS Handshake routines | ||
499 | */ | ||
500 | static void send_client_hello(tls_state_t *tls) | ||
501 | { | ||
502 | struct client_hello { | ||
503 | struct record_hdr xhdr; | ||
504 | uint8_t type; | ||
505 | uint8_t len24_hi, len24_mid, len24_lo; | ||
506 | uint8_t proto_maj, proto_min; | ||
507 | uint8_t rand32[32]; | ||
508 | uint8_t session_id_len; | ||
509 | /* uint8_t session_id[]; */ | ||
510 | uint8_t cipherid_len16_hi, cipherid_len16_lo; | ||
511 | uint8_t cipherid[2 * 1]; /* actually variable */ | ||
512 | uint8_t comprtypes_len; | ||
513 | uint8_t comprtypes[1]; /* actually variable */ | ||
514 | }; | ||
515 | struct client_hello hello; | ||
516 | |||
517 | memset(&hello, 0, sizeof(hello)); | ||
518 | hello.xhdr.type = RECORD_TYPE_HANDSHAKE; | ||
519 | hello.xhdr.proto_maj = TLS_MAJ; | ||
520 | hello.xhdr.proto_min = TLS_MIN; | ||
521 | //zero: hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8; | ||
522 | hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr)); | ||
523 | hello.type = HANDSHAKE_CLIENT_HELLO; | ||
524 | //hello.len24_hi = 0; | ||
525 | //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8; | ||
526 | hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4); | ||
527 | hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ | ||
528 | hello.proto_min = TLS_MIN; /* can be higher than one in record headers */ | ||
529 | tls_get_random(hello.rand32, sizeof(hello.rand32)); | ||
530 | //hello.session_id_len = 0; | ||
531 | //hello.cipherid_len16_hi = 0; | ||
532 | hello.cipherid_len16_lo = 2 * 1; | ||
533 | hello.cipherid[0] = CIPHER_ID >> 8; | ||
534 | hello.cipherid[1] = CIPHER_ID & 0xff; | ||
535 | hello.comprtypes_len = 1; | ||
536 | //hello.comprtypes[0] = 0; | ||
537 | |||
538 | xwrite(tls->fd, &hello, sizeof(hello)); | ||
539 | #if 0 /* dump */ | ||
540 | for (;;) { | ||
541 | uint8_t buf[16*1024]; | ||
542 | sleep(2); | ||
543 | len = recv(tls->fd, buf, sizeof(buf), 0); //MSG_DONTWAIT); | ||
544 | if (len < 0) { | ||
545 | if (errno == EAGAIN) | ||
546 | continue; | ||
547 | bb_perror_msg_and_die("recv"); | ||
548 | } | ||
549 | if (len == 0) | ||
550 | break; | ||
551 | dump(buf, len); | ||
552 | } | ||
553 | #endif | ||
554 | } | ||
555 | |||
556 | static void get_server_hello(tls_state_t *tls) | ||
557 | { | ||
558 | struct server_hello { | ||
559 | struct record_hdr xhdr; | ||
560 | uint8_t type; | ||
561 | uint8_t len24_hi, len24_mid, len24_lo; | ||
562 | uint8_t proto_maj, proto_min; | ||
563 | uint8_t rand32[32]; /* first 4 bytes are unix time in BE format */ | ||
564 | uint8_t session_id_len; | ||
565 | uint8_t session_id[32]; | ||
566 | uint8_t cipherid_hi, cipherid_lo; | ||
567 | uint8_t comprtype; | ||
568 | /* extensions may follow, but only those which client offered in its Hello */ | ||
569 | }; | ||
570 | struct server_hello *hp; | ||
571 | |||
572 | xread_tls_handshake_block(tls, 74); | ||
573 | |||
574 | hp = (void*)tls->inbuf; | ||
575 | // 74 bytes: | ||
576 | // 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| | ||
577 | //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel | ||
578 | if (hp->type != HANDSHAKE_SERVER_HELLO | ||
579 | || hp->len24_hi != 0 | ||
580 | || hp->len24_mid != 0 | ||
581 | || hp->len24_lo != 70 | ||
582 | || hp->proto_maj != TLS_MAJ | ||
583 | || hp->proto_min != TLS_MIN | ||
584 | || hp->session_id_len != 32 | ||
585 | || hp->cipherid_hi != (CIPHER_ID >> 8) | ||
586 | || hp->cipherid_lo != (CIPHER_ID & 0xff) | ||
587 | || hp->comprtype != 0 | ||
588 | ) { | ||
589 | tls_error_die(tls); | ||
590 | } | ||
591 | dbg("got SERVER_HELLO\n"); | ||
592 | } | ||
593 | |||
594 | static void get_server_cert(tls_state_t *tls) | ||
577 | { | 595 | { |
578 | struct record_hdr *xhdr; | 596 | struct record_hdr *xhdr; |
579 | uint8_t *certbuf; | 597 | uint8_t *certbuf; |
@@ -605,63 +623,6 @@ static void get_server_cert_or_die(tls_state_t *tls) | |||
605 | 623 | ||
606 | static void send_client_key_exchange(tls_state_t *tls) | 624 | static void send_client_key_exchange(tls_state_t *tls) |
607 | { | 625 | { |
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 { | 626 | struct client_key_exchange { |
666 | struct record_hdr xhdr; | 627 | struct record_hdr xhdr; |
667 | uint8_t type; | 628 | uint8_t type; |
@@ -675,7 +636,7 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
675 | uint8_t key[384]; // size?? | 636 | uint8_t key[384]; // size?? |
676 | }; | 637 | }; |
677 | struct client_key_exchange record; | 638 | struct client_key_exchange record; |
678 | uint8_t premaster[SSL_HS_RSA_PREMASTER_SIZE]; | 639 | uint8_t rsa_premaster[SSL_HS_RSA_PREMASTER_SIZE]; |
679 | 640 | ||
680 | memset(&record, 0, sizeof(record)); | 641 | memset(&record, 0, sizeof(record)); |
681 | record.xhdr.type = RECORD_TYPE_HANDSHAKE; | 642 | record.xhdr.type = RECORD_TYPE_HANDSHAKE; |
@@ -690,12 +651,16 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
690 | record.keylen16_hi = (sizeof(record) - sizeof(record.xhdr) - 6) >> 8; | 651 | record.keylen16_hi = (sizeof(record) - sizeof(record.xhdr) - 6) >> 8; |
691 | record.keylen16_lo = (sizeof(record) - sizeof(record.xhdr) - 6) & 0xff; | 652 | record.keylen16_lo = (sizeof(record) - sizeof(record.xhdr) - 6) & 0xff; |
692 | 653 | ||
693 | tls_get_random(premaster, sizeof(premaster)); | 654 | tls_get_random(rsa_premaster, sizeof(rsa_premaster)); |
694 | premaster[0] = TLS_MAJ; | 655 | // RFC 5246 |
695 | premaster[1] = TLS_MIN; | 656 | // "Note: The version number in the PreMasterSecret is the version |
657 | // offered by the client in the ClientHello.client_version, not the | ||
658 | // version negotiated for the connection." | ||
659 | rsa_premaster[0] = TLS_MAJ; | ||
660 | rsa_premaster[1] = TLS_MIN; | ||
696 | psRsaEncryptPub(/*pool:*/ NULL, | 661 | psRsaEncryptPub(/*pool:*/ NULL, |
697 | /* psRsaKey_t* */ &tls->server_rsa_pub_key, | 662 | /* psRsaKey_t* */ &tls->server_rsa_pub_key, |
698 | premaster, /*inlen:*/ sizeof(premaster), | 663 | rsa_premaster, /*inlen:*/ sizeof(rsa_premaster), |
699 | record.key, sizeof(record.key), | 664 | record.key, sizeof(record.key), |
700 | data_param_ignored | 665 | data_param_ignored |
701 | ); | 666 | ); |
@@ -712,6 +677,88 @@ static void send_change_cipher_spec(tls_state_t *tls) | |||
712 | xwrite(tls->fd, rec, sizeof(rec)); | 677 | xwrite(tls->fd, rec, sizeof(rec)); |
713 | } | 678 | } |
714 | 679 | ||
680 | static void send_client_finished(tls_state_t *tls) | ||
681 | { | ||
682 | // RFC 5246 on pseudorandom function (PRF): | ||
683 | // | ||
684 | // 5. HMAC and the Pseudorandom Function | ||
685 | //... | ||
686 | // In this section, we define one PRF, based on HMAC. This PRF with the | ||
687 | // SHA-256 hash function is used for all cipher suites defined in this | ||
688 | // document and in TLS documents published prior to this document when | ||
689 | // TLS 1.2 is negotiated. | ||
690 | //... | ||
691 | // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + | ||
692 | // HMAC_hash(secret, A(2) + seed) + | ||
693 | // HMAC_hash(secret, A(3) + seed) + ... | ||
694 | // where + indicates concatenation. | ||
695 | // A() is defined as: | ||
696 | // A(0) = seed | ||
697 | // A(i) = HMAC_hash(secret, A(i-1)) | ||
698 | // P_hash can be iterated as many times as necessary to produce the | ||
699 | // required quantity of data. For example, if P_SHA256 is being used to | ||
700 | // create 80 bytes of data, it will have to be iterated three times | ||
701 | // (through A(3)), creating 96 bytes of output data; the last 16 bytes | ||
702 | // of the final iteration will then be discarded, leaving 80 bytes of | ||
703 | // output data. | ||
704 | // | ||
705 | // TLS's PRF is created by applying P_hash to the secret as: | ||
706 | // | ||
707 | // PRF(secret, label, seed) = P_<hash>(secret, label + seed) | ||
708 | // | ||
709 | // The label is an ASCII string. | ||
710 | |||
711 | tls->fd = 0; | ||
712 | |||
713 | // 7.4.9. Finished | ||
714 | // A Finished message is always sent immediately after a change | ||
715 | // cipher spec message to verify that the key exchange and | ||
716 | // authentication processes were successful. It is essential that a | ||
717 | // change cipher spec message be received between the other handshake | ||
718 | // messages and the Finished message. | ||
719 | //... | ||
720 | // The Finished message is the first one protected with the just | ||
721 | // negotiated algorithms, keys, and secrets. Recipients of Finished | ||
722 | // messages MUST verify that the contents are correct. Once a side | ||
723 | // has sent its Finished message and received and validated the | ||
724 | // Finished message from its peer, it may begin to send and receive | ||
725 | // application data over the connection. | ||
726 | //... | ||
727 | // struct { | ||
728 | // opaque verify_data[verify_data_length]; | ||
729 | // } Finished; | ||
730 | // | ||
731 | // verify_data | ||
732 | // PRF(master_secret, finished_label, Hash(handshake_messages)) | ||
733 | // [0..verify_data_length-1]; | ||
734 | // | ||
735 | // finished_label | ||
736 | // For Finished messages sent by the client, the string | ||
737 | // "client finished". For Finished messages sent by the server, | ||
738 | // the string "server finished". | ||
739 | // | ||
740 | // Hash denotes a Hash of the handshake messages. For the PRF | ||
741 | // defined in Section 5, the Hash MUST be the Hash used as the basis | ||
742 | // for the PRF. Any cipher suite which defines a different PRF MUST | ||
743 | // also define the Hash to use in the Finished computation. | ||
744 | // | ||
745 | // In previous versions of TLS, the verify_data was always 12 octets | ||
746 | // long. In the current version of TLS, it depends on the cipher | ||
747 | // suite. Any cipher suite which does not explicitly specify | ||
748 | // verify_data_length has a verify_data_length equal to 12. This | ||
749 | // includes all existing cipher suites. | ||
750 | } | ||
751 | |||
752 | static void get_change_cipher_spec(tls_state_t *tls) | ||
753 | { | ||
754 | tls->fd = 0; | ||
755 | } | ||
756 | |||
757 | static void get_server_finished(tls_state_t *tls) | ||
758 | { | ||
759 | tls->fd = 0; | ||
760 | } | ||
761 | |||
715 | static void tls_handshake(tls_state_t *tls) | 762 | static void tls_handshake(tls_state_t *tls) |
716 | { | 763 | { |
717 | // Client RFC 5246 Server | 764 | // Client RFC 5246 Server |
@@ -734,23 +781,7 @@ static void tls_handshake(tls_state_t *tls) | |||
734 | int len; | 781 | int len; |
735 | 782 | ||
736 | send_client_hello(tls); | 783 | send_client_hello(tls); |
737 | #if 0 /* dump */ | 784 | get_server_hello(tls); |
738 | for (;;) { | ||
739 | uint8_t buf[16*1024]; | ||
740 | sleep(2); | ||
741 | len = recv(tls->fd, buf, sizeof(buf), 0); //MSG_DONTWAIT); | ||
742 | if (len < 0) { | ||
743 | if (errno == EAGAIN) | ||
744 | continue; | ||
745 | bb_perror_msg_and_die("recv"); | ||
746 | } | ||
747 | if (len == 0) | ||
748 | break; | ||
749 | dump(buf, len); | ||
750 | } | ||
751 | #endif | ||
752 | |||
753 | get_server_hello_or_die(tls); | ||
754 | 785 | ||
755 | //RFC 5246 | 786 | //RFC 5246 |
756 | // The server MUST send a Certificate message whenever the agreed- | 787 | // The server MUST send a Certificate message whenever the agreed- |
@@ -761,7 +792,7 @@ static void tls_handshake(tls_state_t *tls) | |||
761 | // | 792 | // |
762 | // IOW: in practice, Certificate *always* follows. | 793 | // IOW: in practice, Certificate *always* follows. |
763 | // (for example, kernel.org does not even accept DH_anon cipher id) | 794 | // (for example, kernel.org does not even accept DH_anon cipher id) |
764 | get_server_cert_or_die(tls); | 795 | get_server_cert(tls); |
765 | 796 | ||
766 | len = xread_tls_handshake_block(tls, 4); | 797 | len = xread_tls_handshake_block(tls, 4); |
767 | if (tls->inbuf[5] == HANDSHAKE_SERVER_KEY_EXCHANGE) { | 798 | if (tls->inbuf[5] == HANDSHAKE_SERVER_KEY_EXCHANGE) { |
@@ -776,6 +807,13 @@ static void tls_handshake(tls_state_t *tls) | |||
776 | } | 807 | } |
777 | // if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) { | 808 | // if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) { |
778 | // dbg("got CERTIFICATE_REQUEST\n"); | 809 | // dbg("got CERTIFICATE_REQUEST\n"); |
810 | //RFC 5246: (in response to this,) "If no suitable certificate is available, | ||
811 | // the client MUST send a certificate message containing no | ||
812 | // certificates. That is, the certificate_list structure has a | ||
813 | // length of zero. ... | ||
814 | // Client certificates are sent using the Certificate structure | ||
815 | // defined in Section 7.4.2." | ||
816 | // (i.e. the same format as server certs) | ||
779 | // xread_tls_handshake_block(tls, 4); | 817 | // xread_tls_handshake_block(tls, 4); |
780 | // } | 818 | // } |
781 | if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) { | 819 | if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) { |
@@ -784,6 +822,10 @@ static void tls_handshake(tls_state_t *tls) | |||
784 | send_client_key_exchange(tls); | 822 | send_client_key_exchange(tls); |
785 | send_change_cipher_spec(tls); | 823 | send_change_cipher_spec(tls); |
786 | //we now should be able to send encrypted... as soon as we grok AES. | 824 | //we now should be able to send encrypted... as soon as we grok AES. |
825 | send_client_finished(tls); | ||
826 | get_change_cipher_spec(tls); | ||
827 | get_server_finished(tls); | ||
828 | //we now should receive encrypted, and application data can be sent/received | ||
787 | } else { | 829 | } else { |
788 | tls_error_die(tls); | 830 | tls_error_die(tls); |
789 | } | 831 | } |
diff --git a/networking/tls_pstm.c b/networking/tls_pstm.c index 0d797f87f..f802baa15 100644 --- a/networking/tls_pstm.c +++ b/networking/tls_pstm.c | |||
@@ -5,6 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | #include "tls.h" | 6 | #include "tls.h" |
7 | 7 | ||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with ///bbox | ||
10 | */ | ||
11 | |||
8 | /** | 12 | /** |
9 | * @file pstm.c | 13 | * @file pstm.c |
10 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | 14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) |
@@ -51,12 +55,13 @@ static int32 pstm_mul_2d(pstm_int *a, int16 b, pstm_int *c); | |||
51 | */ | 55 | */ |
52 | int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size) | 56 | int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size) |
53 | { | 57 | { |
58 | ///bbox | ||
54 | // uint16 x; | 59 | // uint16 x; |
55 | 60 | ||
56 | /* | 61 | /* |
57 | alloc mem | 62 | alloc mem |
58 | */ | 63 | */ |
59 | a->dp = xzalloc(sizeof (pstm_digit) * size); | 64 | a->dp = xzalloc(sizeof (pstm_digit) * size);///bbox |
60 | a->pool = pool; | 65 | a->pool = pool; |
61 | a->used = 0; | 66 | a->used = 0; |
62 | a->alloc = (int16)size; | 67 | a->alloc = (int16)size; |
@@ -77,11 +82,12 @@ int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size) | |||
77 | */ | 82 | */ |
78 | int32 pstm_init(psPool_t *pool, pstm_int * a) | 83 | int32 pstm_init(psPool_t *pool, pstm_int * a) |
79 | { | 84 | { |
85 | ///bbox | ||
80 | // int32 i; | 86 | // int32 i; |
81 | /* | 87 | /* |
82 | allocate memory required and clear it | 88 | allocate memory required and clear it |
83 | */ | 89 | */ |
84 | a->dp = xzalloc(sizeof (pstm_digit) * PSTM_DEFAULT_INIT); | 90 | a->dp = xzalloc(sizeof (pstm_digit) * PSTM_DEFAULT_INIT);///bbox |
85 | /* | 91 | /* |
86 | set the digits to zero | 92 | set the digits to zero |
87 | */ | 93 | */ |
@@ -120,7 +126,7 @@ int32 pstm_grow(pstm_int * a, int16 size) | |||
120 | We store the return in a temporary variable in case the operation | 126 | We store the return in a temporary variable in case the operation |
121 | failed we don't want to overwrite the dp member of a. | 127 | failed we don't want to overwrite the dp member of a. |
122 | */ | 128 | */ |
123 | tmp = xrealloc(a->dp, sizeof (pstm_digit) * size); | 129 | tmp = xrealloc(a->dp, sizeof (pstm_digit) * size);///bbox |
124 | /* | 130 | /* |
125 | reallocation succeeded so set a->dp | 131 | reallocation succeeded so set a->dp |
126 | */ | 132 | */ |
@@ -1616,7 +1622,7 @@ int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, | |||
1616 | Pre-allocated digit. Used for mul, sqr, AND reduce | 1622 | Pre-allocated digit. Used for mul, sqr, AND reduce |
1617 | */ | 1623 | */ |
1618 | paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit); | 1624 | paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit); |
1619 | paD = xzalloc(paDlen); | 1625 | paD = xzalloc(paDlen);///bbox |
1620 | /* | 1626 | /* |
1621 | compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times | 1627 | compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times |
1622 | */ | 1628 | */ |
diff --git a/networking/tls_pstm.h b/networking/tls_pstm.h index 1affc1b69..de03e3f92 100644 --- a/networking/tls_pstm.h +++ b/networking/tls_pstm.h | |||
@@ -1,3 +1,12 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
7 | * Changes are flagged with ///bbox | ||
8 | */ | ||
9 | |||
1 | /** | 10 | /** |
2 | * @file pstm.h | 11 | * @file pstm.h |
3 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | 12 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) |
diff --git a/networking/tls_pstm_montgomery_reduce.c b/networking/tls_pstm_montgomery_reduce.c index c231c4ddf..e9ae81c53 100644 --- a/networking/tls_pstm_montgomery_reduce.c +++ b/networking/tls_pstm_montgomery_reduce.c | |||
@@ -5,6 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | #include "tls.h" | 6 | #include "tls.h" |
7 | 7 | ||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with ///bbox | ||
10 | */ | ||
11 | |||
8 | /** | 12 | /** |
9 | * @file pstm_montgomery_reduce.c | 13 | * @file pstm_montgomery_reduce.c |
10 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | 14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) |
@@ -353,7 +357,7 @@ int32 pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, pstm_int *m, | |||
353 | c = paD; | 357 | c = paD; |
354 | memset(c, 0x0, paDlen); | 358 | memset(c, 0x0, paDlen); |
355 | } else { | 359 | } else { |
356 | c = xzalloc(2*pa+1); | 360 | c = xzalloc(2*pa+1);///bbox |
357 | } | 361 | } |
358 | /* copy the input */ | 362 | /* copy the input */ |
359 | oldused = a->used; | 363 | oldused = a->used; |
diff --git a/networking/tls_pstm_mul_comba.c b/networking/tls_pstm_mul_comba.c index 6e051baeb..7967231df 100644 --- a/networking/tls_pstm_mul_comba.c +++ b/networking/tls_pstm_mul_comba.c | |||
@@ -5,6 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | #include "tls.h" | 6 | #include "tls.h" |
7 | 7 | ||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with ///bbox | ||
10 | */ | ||
11 | |||
8 | /** | 12 | /** |
9 | * @file pstm_mul_comba.c | 13 | * @file pstm_mul_comba.c |
10 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | 14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) |
@@ -246,13 +250,13 @@ static int32 pstm_mul_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, | |||
246 | if (paD != NULL) { | 250 | if (paD != NULL) { |
247 | if (paDlen < (sizeof(pstm_digit) * pa)) { | 251 | if (paDlen < (sizeof(pstm_digit) * pa)) { |
248 | paDfail = 1; /* have a paD but it's not large enough */ | 252 | paDfail = 1; /* have a paD but it's not large enough */ |
249 | dst = xzalloc(sizeof(pstm_digit) * pa); | 253 | dst = xzalloc(sizeof(pstm_digit) * pa);///bbox |
250 | } else { | 254 | } else { |
251 | dst = paD; | 255 | dst = paD; |
252 | memset(dst, 0x0, paDlen); | 256 | memset(dst, 0x0, paDlen); |
253 | } | 257 | } |
254 | } else { | 258 | } else { |
255 | dst = xzalloc(sizeof(pstm_digit) * pa); | 259 | dst = xzalloc(sizeof(pstm_digit) * pa);///bbox |
256 | } | 260 | } |
257 | 261 | ||
258 | for (ix = 0; ix < pa; ix++) { | 262 | for (ix = 0; ix < pa; ix++) { |
diff --git a/networking/tls_pstm_sqr_comba.c b/networking/tls_pstm_sqr_comba.c index 98186d31f..378e0647b 100644 --- a/networking/tls_pstm_sqr_comba.c +++ b/networking/tls_pstm_sqr_comba.c | |||
@@ -5,6 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | #include "tls.h" | 6 | #include "tls.h" |
7 | 7 | ||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with ///bbox | ||
10 | */ | ||
11 | |||
8 | /** | 12 | /** |
9 | * @file pstm_sqr_comba.c | 13 | * @file pstm_sqr_comba.c |
10 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | 14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) |
@@ -466,13 +470,13 @@ static int32 pstm_sqr_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, | |||
466 | if (paD != NULL) { | 470 | if (paD != NULL) { |
467 | if (paDlen < (sizeof(pstm_digit) * pa)) { | 471 | if (paDlen < (sizeof(pstm_digit) * pa)) { |
468 | paDfail = 1; /* have a paD, but it's not big enough */ | 472 | paDfail = 1; /* have a paD, but it's not big enough */ |
469 | dst = xzalloc(sizeof(pstm_digit) * pa); | 473 | dst = xzalloc(sizeof(pstm_digit) * pa);///bbox |
470 | } else { | 474 | } else { |
471 | dst = paD; | 475 | dst = paD; |
472 | memset(dst, 0x0, paDlen); | 476 | memset(dst, 0x0, paDlen); |
473 | } | 477 | } |
474 | } else { | 478 | } else { |
475 | dst = xzalloc(sizeof(pstm_digit) * pa); | 479 | dst = xzalloc(sizeof(pstm_digit) * pa);///bbox |
476 | } | 480 | } |
477 | 481 | ||
478 | for (ix = 0; ix < pa; ix++) { | 482 | for (ix = 0; ix < pa; ix++) { |
diff --git a/networking/tls_rsa.c b/networking/tls_rsa.c index 058b09cee..3114435dd 100644 --- a/networking/tls_rsa.c +++ b/networking/tls_rsa.c | |||
@@ -5,49 +5,55 @@ | |||
5 | */ | 5 | */ |
6 | #include "tls.h" | 6 | #include "tls.h" |
7 | 7 | ||
8 | /* The code below is taken from parts of | ||
9 | * matrixssl-3-7-2b-open/crypto/pubkey/pkcs.c | ||
10 | * matrixssl-3-7-2b-open/crypto/pubkey/rsa.c | ||
11 | * and (so far) almost not modified. Changes are flagged with ///bbox | ||
12 | */ | ||
13 | |||
8 | #define pkcs1Pad(in, inlen, out, outlen, cryptType, userPtr) \ | 14 | #define pkcs1Pad(in, inlen, out, outlen, cryptType, userPtr) \ |
9 | pkcs1Pad(in, inlen, out, outlen, cryptType) | 15 | pkcs1Pad(in, inlen, out, outlen, cryptType) |
10 | static ///bbox | 16 | static ///bbox |
11 | int32 pkcs1Pad(unsigned char *in, uint32 inlen, unsigned char *out, | 17 | int32 pkcs1Pad(unsigned char *in, uint32 inlen, unsigned char *out, |
12 | uint32 outlen, int32 cryptType, void *userPtr) | 18 | uint32 outlen, int32 cryptType, void *userPtr) |
13 | { | 19 | { |
14 | unsigned char *c; | 20 | unsigned char *c; |
15 | int32 randomLen; | 21 | int32 randomLen; |
16 | 22 | ||
17 | randomLen = outlen - 3 - inlen; | 23 | randomLen = outlen - 3 - inlen; |
18 | if (randomLen < 8) { | 24 | if (randomLen < 8) { |
19 | psTraceCrypto("pkcs1Pad failure\n"); | 25 | psTraceCrypto("pkcs1Pad failure\n"); |
20 | return PS_LIMIT_FAIL; | 26 | return PS_LIMIT_FAIL; |
21 | } | 27 | } |
22 | c = out; | 28 | c = out; |
23 | *c = 0x00; | 29 | *c = 0x00; |
24 | c++; | 30 | c++; |
25 | *c = (unsigned char)cryptType; | 31 | *c = (unsigned char)cryptType; |
26 | c++; | 32 | c++; |
27 | if (cryptType == PUBKEY_TYPE) { | 33 | if (cryptType == PUBKEY_TYPE) { |
28 | while (randomLen-- > 0) { | 34 | while (randomLen-- > 0) { |
29 | *c++ = 0xFF; | 35 | *c++ = 0xFF; |
30 | } | 36 | } |
31 | } else { | 37 | } else { |
32 | if (matrixCryptoGetPrngData(c, (uint32)randomLen, userPtr) < 0) { | 38 | if (matrixCryptoGetPrngData(c, (uint32)randomLen, userPtr) < 0) { |
33 | return PS_PLATFORM_FAIL; | 39 | return PS_PLATFORM_FAIL; |
34 | } | 40 | } |
35 | /* | 41 | /* |
36 | SECURITY: Read through the random data and change all 0x0 to 0x01. | 42 | SECURITY: Read through the random data and change all 0x0 to 0x01. |
37 | This is per spec that no random bytes should be 0 | 43 | This is per spec that no random bytes should be 0 |
38 | */ | 44 | */ |
39 | while (randomLen-- > 0) { | 45 | while (randomLen-- > 0) { |
40 | if (*c == 0x0) { | 46 | if (*c == 0x0) { |
41 | *c = 0x01; | 47 | *c = 0x01; |
42 | } | 48 | } |
43 | c++; | 49 | c++; |
44 | } | 50 | } |
45 | } | 51 | } |
46 | *c = 0x00; | 52 | *c = 0x00; |
47 | c++; | 53 | c++; |
48 | memcpy(c, in, inlen); | 54 | memcpy(c, in, inlen); |
49 | 55 | ||
50 | return outlen; | 56 | return outlen; |
51 | } | 57 | } |
52 | 58 | ||
53 | #define psRsaCrypt(pool, in, inlen, out, outlen, key, type, data) \ | 59 | #define psRsaCrypt(pool, in, inlen, out, outlen, key, type, data) \ |
@@ -173,31 +179,31 @@ done: | |||
173 | } | 179 | } |
174 | 180 | ||
175 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | 181 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, |
176 | unsigned char *in, uint32 inlen, | 182 | unsigned char *in, uint32 inlen, |
177 | unsigned char *out, uint32 outlen, void *data) | 183 | unsigned char *out, uint32 outlen, void *data) |
178 | { | 184 | { |
179 | int32 err; | 185 | int32 err; |
180 | uint32 size; | 186 | uint32 size; |
181 | 187 | ||
182 | size = key->size; | 188 | size = key->size; |
183 | if (outlen < size) { | 189 | if (outlen < size) { |
184 | psTraceCrypto("Error on bad outlen parameter to psRsaEncryptPub\n"); | 190 | psTraceCrypto("Error on bad outlen parameter to psRsaEncryptPub\n"); |
185 | return PS_ARG_FAIL; | 191 | return PS_ARG_FAIL; |
186 | } | 192 | } |
187 | 193 | ||
188 | if ((err = pkcs1Pad(in, inlen, out, size, PRIVKEY_TYPE, data)) | 194 | if ((err = pkcs1Pad(in, inlen, out, size, PRIVKEY_TYPE, data)) |
189 | < PS_SUCCESS) { | 195 | < PS_SUCCESS) { |
190 | psTraceCrypto("Error padding psRsaEncryptPub. Likely data too long\n"); | 196 | psTraceCrypto("Error padding psRsaEncryptPub. Likely data too long\n"); |
191 | return err; | 197 | return err; |
192 | } | 198 | } |
193 | if ((err = psRsaCrypt(pool, out, size, out, (uint32*)&outlen, key, | 199 | if ((err = psRsaCrypt(pool, out, size, out, (uint32*)&outlen, key, |
194 | PUBKEY_TYPE, data)) < PS_SUCCESS) { | 200 | PUBKEY_TYPE, data)) < PS_SUCCESS) { |
195 | psTraceCrypto("Error performing psRsaEncryptPub\n"); | 201 | psTraceCrypto("Error performing psRsaEncryptPub\n"); |
196 | return err; | 202 | return err; |
197 | } | 203 | } |
198 | if (outlen != size) { | 204 | if (outlen != size) { |
199 | psTraceCrypto("Encrypted size error in psRsaEncryptPub\n"); | 205 | psTraceCrypto("Encrypted size error in psRsaEncryptPub\n"); |
200 | return PS_FAILURE; | 206 | return PS_FAILURE; |
201 | } | 207 | } |
202 | return size; | 208 | return size; |
203 | } | 209 | } |
diff --git a/networking/tls_rsa.h b/networking/tls_rsa.h index 3281087c7..93f469e83 100644 --- a/networking/tls_rsa.h +++ b/networking/tls_rsa.h | |||
@@ -2,6 +2,8 @@ | |||
2 | * Copyright (C) 2017 Denys Vlasenko | 2 | * Copyright (C) 2017 Denys Vlasenko |
3 | * | 3 | * |
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | 4 | * Licensed under GPLv2, see file LICENSE in this source tree. |
5 | * | ||
6 | * Selected few declarations for RSA. | ||
5 | */ | 7 | */ |
6 | 8 | ||
7 | typedef struct { | 9 | typedef struct { |