diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-17 18:17:27 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-01-17 18:17:27 +0100 |
commit | 5d1662ea1c29f53b6ece93806c4cf218f9b9a5ae (patch) | |
tree | 536ac5931ddd14b61c8040333db2d8424e6b25b4 | |
parent | e69d78c0385525a8e77002bebf47c4dcceaee1f4 (diff) | |
download | busybox-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.c | 144 |
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 */ |
267 | static void sha256_peek(sha256_ctx_t *ctx, void *buffer) | 266 | static 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 | ||
273 | static void sha256_hash_dbg(const char *fmt, sha256_ctx_t *ctx, const void *buffer, size_t len) | 273 | static 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. |
387 | static void tls_prf_hmac_sha256( | 387 | static 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 | ||
797 | static 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 | ||
797 | static void send_client_hello(tls_state_t *tls) | 826 | static 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 | ||
841 | static void get_server_hello(tls_state_t *tls) | 862 | static 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 |