diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-17 17:24:11 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-17 17:24:11 +0100 |
commit | e69d78c0385525a8e77002bebf47c4dcceaee1f4 (patch) | |
tree | abe246799ad443a981cba9faa427f52feb69b085 /networking/tls.c | |
parent | fe0588df3b12a084cd01118e1c06767a815a9998 (diff) | |
download | busybox-w32-e69d78c0385525a8e77002bebf47c4dcceaee1f4.tar.gz busybox-w32-e69d78c0385525a8e77002bebf47c4dcceaee1f4.tar.bz2 busybox-w32-e69d78c0385525a8e77002bebf47c4dcceaee1f4.zip |
tls: process CHANGE_CIPHER_SPEC and FINISHED from server
Successfully finishes handshake with test servers using NULL-SHA256
cipher.
The "only" thing remaining before there is a chance
this can actually work with real servers is AES encrypt/decrypt.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/tls.c')
-rw-r--r-- | networking/tls.c | 60 |
1 files changed, 32 insertions, 28 deletions
diff --git a/networking/tls.c b/networking/tls.c index 81820e9a1..3df2015a0 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -163,6 +163,7 @@ typedef struct tls_state { | |||
163 | uint8_t master_secret[48]; | 163 | uint8_t master_secret[48]; |
164 | 164 | ||
165 | uint8_t encrypt_on_write; | 165 | uint8_t encrypt_on_write; |
166 | uint8_t decrypt_on_read; | ||
166 | uint8_t client_write_MAC_key[SHA256_OUTSIZE]; | 167 | uint8_t client_write_MAC_key[SHA256_OUTSIZE]; |
167 | // RFC 5246 | 168 | // RFC 5246 |
168 | // sequence number | 169 | // sequence number |
@@ -1044,15 +1045,16 @@ static void send_client_key_exchange(tls_state_t *tls) | |||
1044 | } | 1045 | } |
1045 | } | 1046 | } |
1046 | 1047 | ||
1048 | static const uint8_t rec_CHANGE_CIPHER_SPEC[] = { | ||
1049 | RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01, | ||
1050 | 01 | ||
1051 | }; | ||
1052 | |||
1047 | static void send_change_cipher_spec(tls_state_t *tls) | 1053 | static void send_change_cipher_spec(tls_state_t *tls) |
1048 | { | 1054 | { |
1049 | static const uint8_t rec[] = { | ||
1050 | RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01, | ||
1051 | 01 | ||
1052 | }; | ||
1053 | /* Not "xwrite_and_hash": this is not a handshake message */ | 1055 | /* Not "xwrite_and_hash": this is not a handshake message */ |
1054 | dbg(">> CHANGE_CIPHER_SPEC\n"); | 1056 | dbg(">> CHANGE_CIPHER_SPEC\n"); |
1055 | xwrite(tls->fd, rec, sizeof(rec)); | 1057 | xwrite(tls->fd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC)); |
1056 | 1058 | ||
1057 | /* tls->write_seq64_be = 0; - already is */ | 1059 | /* tls->write_seq64_be = 0; - already is */ |
1058 | tls->encrypt_on_write = 1; | 1060 | tls->encrypt_on_write = 1; |
@@ -1138,16 +1140,6 @@ static void send_client_finished(tls_state_t *tls) | |||
1138 | xwrite_and_hash(tls, &record, sizeof(record)); | 1140 | xwrite_and_hash(tls, &record, sizeof(record)); |
1139 | } | 1141 | } |
1140 | 1142 | ||
1141 | static void get_change_cipher_spec(tls_state_t *tls) | ||
1142 | { | ||
1143 | tls->fd = 0; | ||
1144 | } | ||
1145 | |||
1146 | static void get_server_finished(tls_state_t *tls) | ||
1147 | { | ||
1148 | tls->fd = 0; | ||
1149 | } | ||
1150 | |||
1151 | static void tls_handshake(tls_state_t *tls) | 1143 | static void tls_handshake(tls_state_t *tls) |
1152 | { | 1144 | { |
1153 | // Client RFC 5246 Server | 1145 | // Client RFC 5246 Server |
@@ -1205,20 +1197,32 @@ static void tls_handshake(tls_state_t *tls) | |||
1205 | // (i.e. the same format as server certs) | 1197 | // (i.e. the same format as server certs) |
1206 | // xread_tls_handshake_block(tls, 4); | 1198 | // xread_tls_handshake_block(tls, 4); |
1207 | // } | 1199 | // } |
1208 | if (tls->inbuf[5] == HANDSHAKE_SERVER_HELLO_DONE) { | 1200 | if (tls->inbuf[5] != HANDSHAKE_SERVER_HELLO_DONE) |
1209 | // 0e 000000 (len:0) | ||
1210 | dbg("got SERVER_HELLO_DONE\n"); | ||
1211 | send_client_key_exchange(tls); | ||
1212 | send_change_cipher_spec(tls); | ||
1213 | //we now should be able to send encrypted... as soon as we grok AES. | ||
1214 | send_client_finished(tls); | ||
1215 | |||
1216 | get_change_cipher_spec(tls); | ||
1217 | get_server_finished(tls); | ||
1218 | //we now should receive encrypted, and application data can be sent/received | ||
1219 | } else { | ||
1220 | tls_error_die(tls); | 1201 | tls_error_die(tls); |
1221 | } | 1202 | // 0e 000000 (len:0) |
1203 | dbg("got SERVER_HELLO_DONE\n"); | ||
1204 | |||
1205 | send_client_key_exchange(tls); | ||
1206 | |||
1207 | send_change_cipher_spec(tls); | ||
1208 | /* we now should send encrypted... as soon as we grok AES. */ | ||
1209 | |||
1210 | send_client_finished(tls); | ||
1211 | |||
1212 | /* Get CHANGE_CIPHER_SPEC */ | ||
1213 | len = xread_tls_block(tls); | ||
1214 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) | ||
1215 | tls_error_die(tls); | ||
1216 | dbg("got CHANGE_CIPHER_SPEC\n"); | ||
1217 | tls->decrypt_on_read = 1; | ||
1218 | /* we now should receive encrypted */ | ||
1219 | |||
1220 | /* Get (encrypted) FINISHED from the server */ | ||
1221 | len = xread_tls_block(tls); | ||
1222 | if (len < 4 || tls->inbuf[5] != HANDSHAKE_FINISHED) | ||
1223 | tls_error_die(tls); | ||
1224 | dbg("got FINISHED\n"); | ||
1225 | /* application data can be sent/received */ | ||
1222 | } | 1226 | } |
1223 | 1227 | ||
1224 | // To run a test server using openssl: | 1228 | // To run a test server using openssl: |