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 |