aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-01-17 18:17:27 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2017-01-17 18:17:27 +0100
commit5d1662ea1c29f53b6ece93806c4cf218f9b9a5ae (patch)
tree536ac5931ddd14b61c8040333db2d8424e6b25b4
parente69d78c0385525a8e77002bebf47c4dcceaee1f4 (diff)
downloadbusybox-w32-5d1662ea1c29f53b6ece93806c4cf218f9b9a5ae.tar.gz
busybox-w32-5d1662ea1c29f53b6ece93806c4cf218f9b9a5ae.tar.bz2
busybox-w32-5d1662ea1c29f53b6ece93806c4cf218f9b9a5ae.zip
tls: address one easy FIXME, tidy up comments
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/tls.c144
1 files changed, 74 insertions, 70 deletions
diff --git a/networking/tls.c b/networking/tls.c
index 3df2015a0..8bcaee9a6 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -262,7 +262,6 @@ static void hash_sha256(uint8_t out[SHA256_OUTSIZE], const void *data, unsigned
262 sha256_end(&ctx, out); 262 sha256_end(&ctx, out);
263} 263}
264 264
265#if TLS_DEBUG >= 2
266/* Nondestructively see the current hash value */ 265/* Nondestructively see the current hash value */
267static void sha256_peek(sha256_ctx_t *ctx, void *buffer) 266static void sha256_peek(sha256_ctx_t *ctx, void *buffer)
268{ 267{
@@ -270,6 +269,7 @@ static void sha256_peek(sha256_ctx_t *ctx, void *buffer)
270 sha256_end(&ctx_copy, buffer); 269 sha256_end(&ctx_copy, buffer);
271} 270}
272 271
272#if TLS_DEBUG >= 2
273static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buffer, size_t len) 273static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buffer, size_t len)
274{ 274{
275 uint8_t h[SHA256_OUTSIZE]; 275 uint8_t h[SHA256_OUTSIZE];
@@ -384,7 +384,7 @@ static void hmac_sha256(uint8_t out[SHA256_OUTSIZE], uint8_t *key, unsigned key_
384// PRF(secret, label, seed) = P_<hash>(secret, label + seed) 384// PRF(secret, label, seed) = P_<hash>(secret, label + seed)
385// 385//
386// The label is an ASCII string. 386// The label is an ASCII string.
387static void tls_prf_hmac_sha256( 387static void prf_hmac_sha256(
388 uint8_t *outbuf, unsigned outbuf_size, 388 uint8_t *outbuf, unsigned outbuf_size,
389 uint8_t *secret, unsigned secret_size, 389 uint8_t *secret, unsigned secret_size,
390 const char *label, 390 const char *label,
@@ -794,6 +794,35 @@ static int xread_tls_handshake_block(tls_state_t *tls, int min_len)
794 return len; 794 return len;
795} 795}
796 796
797static void fill_handshake_record_hdr(struct record_hdr *xhdr, unsigned len)
798{
799 struct handshake_hdr {
800 struct record_hdr xhdr;
801 uint8_t type;
802 uint8_t len24_hi, len24_mid, len24_lo;
803 } *h = (void*)xhdr;
804
805 h->xhdr.type = RECORD_TYPE_HANDSHAKE;
806 h->xhdr.proto_maj = TLS_MAJ;
807 h->xhdr.proto_min = TLS_MIN;
808 len -= 5;
809 h->xhdr.len16_hi = len >> 8;
810 // can be optimized to do one store instead of four:
811 // uint32_t v = htonl(0x100*(RECORD_TYPE_HANDSHAKE + 0x100*(TLS_MAJ + 0x100*(TLS_MIN))))
812 // | ((len >> 8) << 24); // little-endian specific, don't use in this form
813 // *(uint32_t *)xhdr = v;
814
815 h->xhdr.len16_lo = len & 0xff;
816
817 len -= 4;
818 h->len24_hi = len >> 16;
819 h->len24_mid = len >> 8;
820 h->len24_lo = len & 0xff;
821
822 memset(h + 1, 0, len);
823}
824
825//TODO: implement RFC 5746 (Renegotiation Indication Extension) - some servers will refuse to work with us otherwise
797static void send_client_hello(tls_state_t *tls) 826static void send_client_hello(tls_state_t *tls)
798{ 827{
799 struct client_hello { 828 struct client_hello {
@@ -809,33 +838,25 @@ static void send_client_hello(tls_state_t *tls)
809 uint8_t comprtypes_len; 838 uint8_t comprtypes_len;
810 uint8_t comprtypes[1]; /* actually variable */ 839 uint8_t comprtypes[1]; /* actually variable */
811 }; 840 };
812 struct client_hello hello; 841 struct client_hello record;
813 842
814 memset(&hello, 0, sizeof(hello)); 843 fill_handshake_record_hdr(&record.xhdr, sizeof(record));
815 hello.xhdr.type = RECORD_TYPE_HANDSHAKE; 844 record.type = HANDSHAKE_CLIENT_HELLO;
816 hello.xhdr.proto_maj = TLS_MAJ; 845 record.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */
817 hello.xhdr.proto_min = TLS_MIN; 846 record.proto_min = TLS_MIN; /* can be higher than one in record headers */
818 //zero: hello.xhdr.len16_hi = (sizeof(hello) - sizeof(hello.xhdr)) >> 8; 847 tls_get_random(record.rand32, sizeof(record.rand32));
819 hello.xhdr.len16_lo = (sizeof(hello) - sizeof(hello.xhdr)); 848 /* record.session_id_len = 0; - already is */
820 hello.type = HANDSHAKE_CLIENT_HELLO; 849 /* record.cipherid_len16_hi = 0; */
821 //hello.len24_hi = 0; 850 record.cipherid_len16_lo = 2 * 1;
822 //zero: hello.len24_mid = (sizeof(hello) - sizeof(hello.xhdr) - 4) >> 8; 851 record.cipherid[0] = CIPHER_ID >> 8;
823 hello.len24_lo = (sizeof(hello) - sizeof(hello.xhdr) - 4); 852 record.cipherid[1] = CIPHER_ID & 0xff;
824 hello.proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ 853 record.comprtypes_len = 1;
825 hello.proto_min = TLS_MIN; /* can be higher than one in record headers */ 854 /* record.comprtypes[0] = 0; */
826 tls_get_random(hello.rand32, sizeof(hello.rand32)); 855
827 //hello.session_id_len = 0; 856 //dbg (make it repeatable): memset(record.rand32, 0x11, sizeof(record.rand32));
828 //hello.cipherid_len16_hi = 0;
829 hello.cipherid_len16_lo = 2 * 1;
830 hello.cipherid[0] = CIPHER_ID >> 8;
831 hello.cipherid[1] = CIPHER_ID & 0xff;
832 hello.comprtypes_len = 1;
833 //hello.comprtypes[0] = 0;
834
835 //dbg (make it repeatable): memset(hello.rand32, 0x11, sizeof(hello.rand32));
836 dbg(">> HANDSHAKE_CLIENT_HELLO\n"); 857 dbg(">> HANDSHAKE_CLIENT_HELLO\n");
837 xwrite_and_hash(tls, &hello, sizeof(hello)); 858 xwrite_and_hash(tls, &record, sizeof(record));
838 memcpy(tls->client_and_server_rand32, hello.rand32, sizeof(hello.rand32)); 859 memcpy(tls->client_and_server_rand32, record.rand32, sizeof(record.rand32));
839} 860}
840 861
841static void get_server_hello(tls_state_t *tls) 862static void get_server_hello(tls_state_t *tls)
@@ -892,7 +913,7 @@ static void get_server_hello(tls_state_t *tls)
892 tls_error_die(tls); 913 tls_error_die(tls);
893 } 914 }
894 915
895 dbg("got SERVER_HELLO\n"); 916 dbg("<< SERVER_HELLO\n");
896 memcpy(tls->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); 917 memcpy(tls->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32));
897} 918}
898 919
@@ -908,7 +929,7 @@ static void get_server_cert(tls_state_t *tls)
908 certbuf = (void*)(xhdr + 1); 929 certbuf = (void*)(xhdr + 1);
909 if (certbuf[0] != HANDSHAKE_CERTIFICATE) 930 if (certbuf[0] != HANDSHAKE_CERTIFICATE)
910 tls_error_die(tls); 931 tls_error_die(tls);
911 dbg("got CERTIFICATE\n"); 932 dbg("<< CERTIFICATE\n");
912 // 4392 bytes: 933 // 4392 bytes:
913 // 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... 934 // 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...
914 //Cert len=4388 ChainLen CertLen^ DER encoded X509 starts here. openssl x509 -in FILE -inform DER -noout -text 935 //Cert len=4388 ChainLen CertLen^ DER encoded X509 starts here. openssl x509 -in FILE -inform DER -noout -text
@@ -932,29 +953,22 @@ static void send_client_key_exchange(tls_state_t *tls)
932 struct record_hdr xhdr; 953 struct record_hdr xhdr;
933 uint8_t type; 954 uint8_t type;
934 uint8_t len24_hi, len24_mid, len24_lo; 955 uint8_t len24_hi, len24_mid, len24_lo;
935 uint8_t keylen16_hi, keylen16_lo; /* exist for RSA, but not for some other key types */ 956 /* keylen16 exists for RSA (in TLS, not in SSL), but not for some other key types */
936//had a bug when had no keylen: we: 957 uint8_t keylen16_hi, keylen16_lo;
937//write(3, "\x16\x03\x03\x01\x84\x10\x00\x01\x80\xXX\xXX\xXX\xXX\xXX\xXX...", 393) = 393
938//openssl:
939//write to 0xe9a090 [0xf9ac20] (395 bytes => 395 (0x18B))
940//0000 - 16 03 03 01 86 10 00 01 -82 01 80 xx xx xx xx xx
941 uint8_t key[4 * 1024]; // size?? 958 uint8_t key[4 * 1024]; // size??
942 }; 959 };
943 struct client_key_exchange record; 960 struct client_key_exchange record;
944 uint8_t rsa_premaster[SSL_HS_RSA_PREMASTER_SIZE]; 961 uint8_t rsa_premaster[SSL_HS_RSA_PREMASTER_SIZE];
945 int len; 962 int len;
946 963
947 memset(&record, 0, sizeof(record)); 964 fill_handshake_record_hdr(&record.xhdr, sizeof(record) - sizeof(record.key));
948 record.xhdr.type = RECORD_TYPE_HANDSHAKE;
949 record.xhdr.proto_maj = TLS_MAJ;
950 record.xhdr.proto_min = TLS_MIN;
951 record.type = HANDSHAKE_CLIENT_KEY_EXCHANGE; 965 record.type = HANDSHAKE_CLIENT_KEY_EXCHANGE;
952 966
953 tls_get_random(rsa_premaster, sizeof(rsa_premaster)); 967 tls_get_random(rsa_premaster, sizeof(rsa_premaster));
954// RFC 5246 968 // RFC 5246
955// "Note: The version number in the PreMasterSecret is the version 969 // "Note: The version number in the PreMasterSecret is the version
956// offered by the client in the ClientHello.client_version, not the 970 // offered by the client in the ClientHello.client_version, not the
957// version negotiated for the connection." 971 // version negotiated for the connection."
958 rsa_premaster[0] = TLS_MAJ; 972 rsa_premaster[0] = TLS_MAJ;
959 rsa_premaster[1] = TLS_MIN; 973 rsa_premaster[1] = TLS_MIN;
960 len = psRsaEncryptPub(/*pool:*/ NULL, 974 len = psRsaEncryptPub(/*pool:*/ NULL,
@@ -963,10 +977,11 @@ static void send_client_key_exchange(tls_state_t *tls)
963 record.key, sizeof(record.key), 977 record.key, sizeof(record.key),
964 data_param_ignored 978 data_param_ignored
965 ); 979 );
980 /* length fields need fixing */
966 record.keylen16_hi = len >> 8; 981 record.keylen16_hi = len >> 8;
967 record.keylen16_lo = len & 0xff; 982 record.keylen16_lo = len & 0xff;
968 len += 2; 983 len += 2;
969 //record.len24_hi = 0; 984 /* record.len24_hi = 0; - already is */
970 record.len24_mid = len >> 8; 985 record.len24_mid = len >> 8;
971 record.len24_lo = len & 0xff; 986 record.len24_lo = len & 0xff;
972 len += 4; 987 len += 4;
@@ -986,7 +1001,7 @@ static void send_client_key_exchange(tls_state_t *tls)
986 // [0..47]; 1001 // [0..47];
987 // The master secret is always exactly 48 bytes in length. The length 1002 // The master secret is always exactly 48 bytes in length. The length
988 // of the premaster secret will vary depending on key exchange method. 1003 // of the premaster secret will vary depending on key exchange method.
989 tls_prf_hmac_sha256( 1004 prf_hmac_sha256(
990 tls->master_secret, sizeof(tls->master_secret), 1005 tls->master_secret, sizeof(tls->master_secret),
991 rsa_premaster, sizeof(rsa_premaster), 1006 rsa_premaster, sizeof(rsa_premaster),
992 "master secret", 1007 "master secret",
@@ -1033,7 +1048,7 @@ static void send_client_key_exchange(tls_state_t *tls)
1033 memcpy(&tmp64[0] , &tls->client_and_server_rand32[32], 32); 1048 memcpy(&tmp64[0] , &tls->client_and_server_rand32[32], 32);
1034 memcpy(&tmp64[32], &tls->client_and_server_rand32[0] , 32); 1049 memcpy(&tmp64[32], &tls->client_and_server_rand32[0] , 32);
1035 1050
1036 tls_prf_hmac_sha256( 1051 prf_hmac_sha256(
1037 tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key), 1052 tls->client_write_MAC_key, sizeof(tls->client_write_MAC_key),
1038 tls->master_secret, sizeof(tls->master_secret), 1053 tls->master_secret, sizeof(tls->master_secret),
1039 "key expansion", 1054 "key expansion",
@@ -1107,23 +1122,12 @@ static void send_client_finished(tls_state_t *tls)
1107 }; 1122 };
1108 struct client_finished record; 1123 struct client_finished record;
1109 uint8_t handshake_hash[SHA256_OUTSIZE]; 1124 uint8_t handshake_hash[SHA256_OUTSIZE];
1110 sha256_ctx_t ctx;
1111 1125
1112 memset(&record, 0, sizeof(record)); 1126 fill_handshake_record_hdr(&record.xhdr, sizeof(record));
1113 record.xhdr.type = RECORD_TYPE_HANDSHAKE;
1114 record.xhdr.proto_maj = TLS_MAJ;
1115 record.xhdr.proto_min = TLS_MIN;
1116 record.xhdr.len16_hi = (sizeof(record) - sizeof(record.xhdr)) >> 8;
1117 record.xhdr.len16_lo = (sizeof(record) - sizeof(record.xhdr)) & 0xff;
1118 record.type = HANDSHAKE_FINISHED; 1127 record.type = HANDSHAKE_FINISHED;
1119 //record.len24_hi = 0; 1128
1120 record.len24_mid = (sizeof(record) - sizeof(record.xhdr) - 4) >> 8; 1129 sha256_peek(&tls->handshake_sha256_ctx, handshake_hash);
1121 record.len24_lo = (sizeof(record) - sizeof(record.xhdr) - 4) & 0xff; 1130 prf_hmac_sha256(record.prf_result, sizeof(record.prf_result),
1122//FIXME ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this code is repeatable
1123
1124 ctx = tls->handshake_sha256_ctx; /* struct copy */
1125 sha256_end(&ctx, handshake_hash);
1126 tls_prf_hmac_sha256(record.prf_result, sizeof(record.prf_result),
1127 tls->master_secret, sizeof(tls->master_secret), 1131 tls->master_secret, sizeof(tls->master_secret),
1128 "client finished", 1132 "client finished",
1129 handshake_hash, sizeof(handshake_hash) 1133 handshake_hash, sizeof(handshake_hash)
@@ -1182,12 +1186,13 @@ static void tls_handshake(tls_state_t *tls)
1182 //SvKey len=455^ 1186 //SvKey len=455^
1183 // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes: 1187 // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes:
1184 // 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... 1188 // 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...
1185 dbg("got SERVER_KEY_EXCHANGE len:%u\n", len); 1189 dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len);
1186//need to save it 1190//probably need to save it
1187 xread_tls_handshake_block(tls, 4); 1191 xread_tls_handshake_block(tls, 4);
1188 } 1192 }
1193
1189// if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) { 1194// if (tls->inbuf[5] == HANDSHAKE_CERTIFICATE_REQUEST) {
1190// dbg("got CERTIFICATE_REQUEST\n"); 1195// dbg("<< CERTIFICATE_REQUEST\n");
1191//RFC 5246: (in response to this,) "If no suitable certificate is available, 1196//RFC 5246: (in response to this,) "If no suitable certificate is available,
1192// the client MUST send a certificate message containing no 1197// the client MUST send a certificate message containing no
1193// certificates. That is, the certificate_list structure has a 1198// certificates. That is, the certificate_list structure has a
@@ -1197,10 +1202,11 @@ static void tls_handshake(tls_state_t *tls)
1197// (i.e. the same format as server certs) 1202// (i.e. the same format as server certs)
1198// xread_tls_handshake_block(tls, 4); 1203// xread_tls_handshake_block(tls, 4);
1199// } 1204// }
1205
1200 if (tls->inbuf[5] != HANDSHAKE_SERVER_HELLO_DONE) 1206 if (tls->inbuf[5] != HANDSHAKE_SERVER_HELLO_DONE)
1201 tls_error_die(tls); 1207 tls_error_die(tls);
1202 // 0e 000000 (len:0) 1208 // 0e 000000 (len:0)
1203 dbg("got SERVER_HELLO_DONE\n"); 1209 dbg("<< SERVER_HELLO_DONE\n");
1204 1210
1205 send_client_key_exchange(tls); 1211 send_client_key_exchange(tls);
1206 1212
@@ -1213,7 +1219,7 @@ static void tls_handshake(tls_state_t *tls)
1213 len = xread_tls_block(tls); 1219 len = xread_tls_block(tls);
1214 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) 1220 if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0)
1215 tls_error_die(tls); 1221 tls_error_die(tls);
1216 dbg("got CHANGE_CIPHER_SPEC\n"); 1222 dbg("<< CHANGE_CIPHER_SPEC\n");
1217 tls->decrypt_on_read = 1; 1223 tls->decrypt_on_read = 1;
1218 /* we now should receive encrypted */ 1224 /* we now should receive encrypted */
1219 1225
@@ -1221,7 +1227,7 @@ static void tls_handshake(tls_state_t *tls)
1221 len = xread_tls_block(tls); 1227 len = xread_tls_block(tls);
1222 if (len < 4 || tls->inbuf[5] != HANDSHAKE_FINISHED) 1228 if (len < 4 || tls->inbuf[5] != HANDSHAKE_FINISHED)
1223 tls_error_die(tls); 1229 tls_error_die(tls);
1224 dbg("got FINISHED\n"); 1230 dbg("<< FINISHED\n");
1225 /* application data can be sent/received */ 1231 /* application data can be sent/received */
1226} 1232}
1227 1233
@@ -1252,8 +1258,6 @@ int tls_main(int argc UNUSED_PARAM, char **argv)
1252 return EXIT_SUCCESS; 1258 return EXIT_SUCCESS;
1253} 1259}
1254 1260
1255//TODO: implement RFC 5746 (Renegotiation Indication Extension) - some servers will refuse to work with us otherwise
1256
1257/* Unencryped SHA256 example: 1261/* Unencryped SHA256 example:
1258 * $ openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' 1262 * $ openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost'
1259 * $ openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL 1263 * $ openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL