| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // This helper binary is only used for testing Chrome's SSL stack. | 5 // This helper binary is only used for testing Chrome's SSL stack. |
| 6 | 6 |
| 7 #include <sys/types.h> | 7 #include <sys/types.h> |
| 8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
| 9 | 9 |
| 10 #include <openssl/bio.h> | 10 #include <openssl/bio.h> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 } | 23 } |
| 24 | 24 |
| 25 // Client certificate verification callback from OpenSSL | 25 // Client certificate verification callback from OpenSSL |
| 26 static int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { | 26 static int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { |
| 27 return 1; | 27 return 1; |
| 28 } | 28 } |
| 29 | 29 |
| 30 // Next Protocol Negotiation callback from OpenSSL | 30 // Next Protocol Negotiation callback from OpenSSL |
| 31 static int next_proto_cb(SSL *ssl, const unsigned char **out, | 31 static int next_proto_cb(SSL *ssl, const unsigned char **out, |
| 32 unsigned int *outlen, void *arg) { | 32 unsigned int *outlen, void *arg) { |
| 33 bool* npn_mispredict = reinterpret_cast<bool*>(arg); |
| 33 static char kProtos[] = "\003foo\003bar"; | 34 static char kProtos[] = "\003foo\003bar"; |
| 34 *out = (const unsigned char*) kProtos; | 35 static char kProtos2[] = "\003baz\003boo"; |
| 35 *outlen = sizeof(kProtos) - 1; | 36 static unsigned count = 0; |
| 37 |
| 38 if (!*npn_mispredict || count == 0) { |
| 39 *out = (const unsigned char*) kProtos; |
| 40 *outlen = sizeof(kProtos) - 1; |
| 41 } else { |
| 42 *out = (const unsigned char*) kProtos2; |
| 43 *outlen = sizeof(kProtos2) - 1; |
| 44 } |
| 45 count++; |
| 36 return SSL_TLSEXT_ERR_OK; | 46 return SSL_TLSEXT_ERR_OK; |
| 37 } | 47 } |
| 38 | 48 |
| 39 int | 49 int |
| 40 main(int argc, char **argv) { | 50 main(int argc, char **argv) { |
| 41 SSL_library_init(); | 51 SSL_library_init(); |
| 42 ERR_load_crypto_strings(); | 52 ERR_load_crypto_strings(); |
| 43 OpenSSL_add_all_algorithms(); | 53 OpenSSL_add_all_algorithms(); |
| 44 SSL_load_error_strings(); | 54 SSL_load_error_strings(); |
| 45 | 55 |
| 46 bool sni = false, sni_good = false, snap_start = false; | 56 bool sni = false, sni_good = false, snap_start = false; |
| 47 bool snap_start_recovery = false, sslv3 = false, session_tickets = false; | 57 bool snap_start_recovery = false, sslv3 = false, session_tickets = false; |
| 48 bool fail_resume = false, client_cert = false, npn = false; | 58 bool fail_resume = false, client_cert = false, npn = false; |
| 59 bool npn_mispredict = false; |
| 49 | 60 |
| 50 const char* key_file = kDefaultPEMFile; | 61 const char* key_file = kDefaultPEMFile; |
| 51 const char* cert_file = kDefaultPEMFile; | 62 const char* cert_file = kDefaultPEMFile; |
| 52 | 63 |
| 53 for (int i = 1; i < argc; i++) { | 64 for (int i = 1; i < argc; i++) { |
| 54 if (strcmp(argv[i], "sni") == 0) { | 65 if (strcmp(argv[i], "sni") == 0) { |
| 55 // Require SNI | 66 // Require SNI |
| 56 sni = true; | 67 sni = true; |
| 57 } else if (strcmp(argv[i], "snap-start") == 0) { | 68 } else if (strcmp(argv[i], "snap-start") == 0) { |
| 58 // Support Snap Start | 69 // Support Snap Start |
| (...skipping 10 matching lines...) Expand all Loading... |
| 69 session_tickets = true; | 80 session_tickets = true; |
| 70 } else if (strcmp(argv[i], "fail-resume") == 0) { | 81 } else if (strcmp(argv[i], "fail-resume") == 0) { |
| 71 // Always fail to resume sessions | 82 // Always fail to resume sessions |
| 72 fail_resume = true; | 83 fail_resume = true; |
| 73 } else if (strcmp(argv[i], "client-cert") == 0) { | 84 } else if (strcmp(argv[i], "client-cert") == 0) { |
| 74 // Request a client certificate | 85 // Request a client certificate |
| 75 client_cert = true; | 86 client_cert = true; |
| 76 } else if (strcmp(argv[i], "npn") == 0) { | 87 } else if (strcmp(argv[i], "npn") == 0) { |
| 77 // Advertise NPN | 88 // Advertise NPN |
| 78 npn = true; | 89 npn = true; |
| 90 } else if (strcmp(argv[i], "npn-mispredict") == 0) { |
| 91 // Advertise NPN |
| 92 npn = true; |
| 93 npn_mispredict = true; |
| 79 } else if (strcmp(argv[i], "--key-file") == 0) { | 94 } else if (strcmp(argv[i], "--key-file") == 0) { |
| 80 // Use alternative key file | 95 // Use alternative key file |
| 81 i++; | 96 i++; |
| 82 if (i == argc) { | 97 if (i == argc) { |
| 83 fprintf(stderr, "Missing argument to --key-file\n"); | 98 fprintf(stderr, "Missing argument to --key-file\n"); |
| 84 return 1; | 99 return 1; |
| 85 } | 100 } |
| 86 key_file = argv[i]; | 101 key_file = argv[i]; |
| 87 } else if (strcmp(argv[i], "--cert-file") == 0) { | 102 } else if (strcmp(argv[i], "--cert-file") == 0) { |
| 88 // Use alternative certificate file | 103 // Use alternative certificate file |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 173 |
| 159 if (session_tickets) | 174 if (session_tickets) |
| 160 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); | 175 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); |
| 161 | 176 |
| 162 if (snap_start) { | 177 if (snap_start) { |
| 163 static const unsigned char orbit[8] = {1, 2, 3, 4, 5, 6, 7, 8}; | 178 static const unsigned char orbit[8] = {1, 2, 3, 4, 5, 6, 7, 8}; |
| 164 SSL_CTX_set_snap_start_orbit(ctx, orbit); | 179 SSL_CTX_set_snap_start_orbit(ctx, orbit); |
| 165 } | 180 } |
| 166 | 181 |
| 167 if (npn) | 182 if (npn) |
| 168 SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, NULL); | 183 SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &npn_mispredict); |
| 169 | 184 |
| 170 unsigned connection_limit = 1; | 185 unsigned connection_limit = 1; |
| 171 if (snap_start || session_tickets) | 186 if (snap_start || session_tickets) |
| 172 connection_limit = 2; | 187 connection_limit = 2; |
| 188 if (npn_mispredict) |
| 189 connection_limit = 3; |
| 173 | 190 |
| 174 for (unsigned connections = 0; connections < connection_limit; | 191 for (unsigned connections = 0; connections < connection_limit; |
| 175 connections++) { | 192 connections++) { |
| 176 const int fd = accept(3, NULL, NULL); | 193 const int fd = accept(3, NULL, NULL); |
| 177 | 194 |
| 178 SSL* server = SSL_new(ctx); | 195 SSL* server = SSL_new(ctx); |
| 179 BIO* bio = BIO_new_socket(fd, 1 /* take ownership of fd */); | 196 BIO* bio = BIO_new_socket(fd, 1 /* take ownership of fd */); |
| 180 SSL_set_bio(server, bio, bio); | 197 SSL_set_bio(server, bio, bio); |
| 181 | 198 |
| 182 if (fail_resume) { | 199 if (fail_resume) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 202 fprintf(stderr, "SSL_accept failed: %d\n", err); | 219 fprintf(stderr, "SSL_accept failed: %d\n", err); |
| 203 return 1; | 220 return 1; |
| 204 } | 221 } |
| 205 | 222 |
| 206 if (sni && !sni_good) { | 223 if (sni && !sni_good) { |
| 207 fprintf(stderr, "SNI failed\n"); | 224 fprintf(stderr, "SNI failed\n"); |
| 208 return 1; | 225 return 1; |
| 209 } | 226 } |
| 210 | 227 |
| 211 if (npn) { | 228 if (npn) { |
| 212 const unsigned char *data; | 229 const unsigned char *data, *expected_data; |
| 213 unsigned len; | 230 unsigned len, expected_len; |
| 214 SSL_get0_next_proto_negotiated(server, &data, &len); | 231 SSL_get0_next_proto_negotiated(server, &data, &len); |
| 215 if (len != 3 || memcmp(data, "bar", 3) != 0) { | 232 if (!npn_mispredict || connections == 0) { |
| 233 expected_data = (unsigned char*) "foo"; |
| 234 expected_len = 3; |
| 235 } else { |
| 236 expected_data = (unsigned char*) "baz"; |
| 237 expected_len = 3; |
| 238 } |
| 239 if (len != expected_len || memcmp(data, expected_data, len) != 0) { |
| 216 fprintf(stderr, "Bad NPN: %d\n", len); | 240 fprintf(stderr, "Bad NPN: %d\n", len); |
| 217 return 1; | 241 return 1; |
| 218 } | 242 } |
| 219 } | 243 } |
| 220 | 244 |
| 221 unsigned char buffer[6]; | 245 unsigned char buffer[6]; |
| 222 | 246 |
| 223 int ret = SSL_read(server, buffer, sizeof(buffer)); | 247 int ret = SSL_read(server, buffer, sizeof(buffer)); |
| 224 if (ret == -1) { | 248 if (ret == -1) { |
| 225 err = SSL_get_error(server, ret); | 249 err = SSL_get_error(server, ret); |
| 226 ERR_print_errors_fp(stderr); | 250 ERR_print_errors_fp(stderr); |
| 227 fprintf(stderr, "SSL_read failed: %d\n", err); | 251 fprintf(stderr, "SSL_read failed: %d\n", err); |
| 228 } | 252 } |
| 229 if (memcmp(buffer, "hello!", sizeof(buffer)) == 0) { | 253 if (memcmp(buffer, "hello!", sizeof(buffer)) == 0) { |
| 230 SSL_write(server, "goodbye!", 8); | 254 SSL_write(server, "goodbye!", 8); |
| 231 } | 255 } |
| 232 | 256 |
| 233 SSL_shutdown(server); | 257 SSL_shutdown(server); |
| 234 SSL_shutdown(server); | 258 SSL_shutdown(server); |
| 235 } | 259 } |
| 236 | 260 |
| 237 SSL_CTX_free(ctx); | 261 SSL_CTX_free(ctx); |
| 238 | 262 |
| 239 return 0; | 263 return 0; |
| 240 } | 264 } |
| OLD | NEW |