Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Side by Side Diff: net/test/openssl_helper.cc

Issue 6804032: Add TLS-SRP (RFC 5054) support Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: remove "httpsv" scheme, minor NSS/OpenSSL changes Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/test/test_server.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <arpa/inet.h>
8 #include <netinet/tcp.h>
7 #include <sys/types.h> 9 #include <sys/types.h>
8 #include <sys/socket.h> 10 #include <sys/socket.h>
11 #include <unistd.h>
9 12
10 #include <openssl/bio.h> 13 #include <openssl/bio.h>
11 #include <openssl/ssl.h> 14 #include <openssl/ssl.h>
12 #include <openssl/err.h> 15 #include <openssl/err.h>
16 #include <openssl/srp.h>
13 17
14 static const char kDefaultPEMFile[] = "net/data/ssl/certificates/ok_cert.pem"; 18 static const char kDefaultPEMFile[] = "net/data/ssl/certificates/ok_cert.pem";
19 static const char kDefaultSRPVFile[] = "net/data/ssl/certificates/ok.srpv";
15 20
16 // Server Name Indication callback from OpenSSL 21 // Server Name Indication callback from OpenSSL
17 static int sni_cb(SSL *s, int *ad, void *arg) { 22 static int sni_cb(SSL *s, int *ad, void *arg) {
18 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name); 23 const char* servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
19 if (servername && strcmp(servername, "test.example.com") == 0) 24 if (servername && strcmp(servername, "test.example.com") == 0)
20 *reinterpret_cast<bool*>(arg) = true; 25 *reinterpret_cast<bool*>(arg) = true;
21 26
22 return SSL_TLSEXT_ERR_OK; 27 return SSL_TLSEXT_ERR_OK;
23 } 28 }
24 29
(...skipping 14 matching lines...) Expand all
39 *out = (const unsigned char*) kProtos; 44 *out = (const unsigned char*) kProtos;
40 *outlen = sizeof(kProtos) - 1; 45 *outlen = sizeof(kProtos) - 1;
41 } else { 46 } else {
42 *out = (const unsigned char*) kProtos2; 47 *out = (const unsigned char*) kProtos2;
43 *outlen = sizeof(kProtos2) - 1; 48 *outlen = sizeof(kProtos2) - 1;
44 } 49 }
45 count++; 50 count++;
46 return SSL_TLSEXT_ERR_OK; 51 return SSL_TLSEXT_ERR_OK;
47 } 52 }
48 53
54 // This is a context that we pass to callbacks
55 // (from openssl/apps/s_server.c)
56 typedef struct srpsrvparm_st {
57 int verbose;
58 char *login;
59 SRP_VBASE *vb;
60 } srpsrvparm;
61
62 // (from openssl/apps/s_server.c)
63 static int ssl_srp_server_param_cb(SSL *s, int *ad, void *arg) {
64 srpsrvparm * p = (srpsrvparm *) arg;
65 SRP_user_pwd *user;
66 int rv;
67
68 p->login = BUF_strdup(SSL_get_srp_username(s));
69 fprintf(stderr,"SRP username = \"%s\"\n",p->login);
70
71 user = SRP_VBASE_get_by_user(p->vb, p->login);
72 if (user == NULL) {
73 fprintf(stderr, "User %s doesn't exist\n", p->login);
74 return SSL3_AL_FATAL;
75 }
76
77 /* TODO(sqs): see why it expects non-const BIGNUM* */
78 rv = SSL_set_srp_server_param(s, (BIGNUM*)user->N, (BIGNUM*)user->g,
79 user->s, user->v, user->info);
80 if (rv < 0) {
81 *ad = SSL_AD_INTERNAL_ERROR;
82 return SSL3_AL_FATAL;
83 }
84 return SSL_ERROR_NONE;
85 }
86
49 int 87 int
50 main(int argc, char **argv) { 88 main(int argc, char **argv) {
51 SSL_library_init(); 89 SSL_library_init();
52 ERR_load_crypto_strings(); 90 ERR_load_crypto_strings();
53 OpenSSL_add_all_algorithms(); 91 OpenSSL_add_all_algorithms();
54 SSL_load_error_strings(); 92 SSL_load_error_strings();
55 93
56 bool sni = false, sni_good = false, snap_start = false; 94 bool sni = false, sni_good = false, snap_start = false;
57 bool snap_start_recovery = false, sslv3 = false, session_tickets = false; 95 bool snap_start_recovery = false, sslv3 = false, session_tickets = false;
58 bool fail_resume = false, client_cert = false, npn = false; 96 bool fail_resume = false, client_cert = false, npn = false;
59 bool npn_mispredict = false; 97 bool npn_mispredict = false, tlssrp = false, open_socket = false;
98
99 unsigned short listen_port = 4443;
60 100
61 const char* key_file = kDefaultPEMFile; 101 const char* key_file = kDefaultPEMFile;
62 const char* cert_file = kDefaultPEMFile; 102 const char* cert_file = kDefaultPEMFile;
103 const char* srpv_file = kDefaultSRPVFile;
104
105 srpsrvparm srpp;
63 106
64 for (int i = 1; i < argc; i++) { 107 for (int i = 1; i < argc; i++) {
65 if (strcmp(argv[i], "sni") == 0) { 108 if (strcmp(argv[i], "sni") == 0) {
66 // Require SNI 109 // Require SNI
67 sni = true; 110 sni = true;
68 } else if (strcmp(argv[i], "snap-start") == 0) { 111 } else if (strcmp(argv[i], "snap-start") == 0) {
69 // Support Snap Start 112 // Support Snap Start
70 snap_start = true; 113 snap_start = true;
71 } else if (strcmp(argv[i], "snap-start-recovery") == 0) { 114 } else if (strcmp(argv[i], "snap-start-recovery") == 0) {
72 // Support Snap Start, but always trigger a recovery 115 // Support Snap Start, but always trigger a recovery
73 snap_start = true; 116 snap_start = true;
74 snap_start_recovery = true; 117 snap_start_recovery = true;
75 } else if (strcmp(argv[i], "sslv3") == 0) { 118 } else if (strcmp(argv[i], "sslv3") == 0) {
76 // Use SSLv3 119 // Use SSLv3
77 sslv3 = true; 120 sslv3 = true;
121 if (tlssrp) {
122 fprintf(stderr, "TLS-SRP requires TLSv1; do not use sslv3 option\n");
123 return 1;
124 }
78 } else if (strcmp(argv[i], "session-tickets") == 0) { 125 } else if (strcmp(argv[i], "session-tickets") == 0) {
79 // Enable Session Tickets 126 // Enable Session Tickets
80 session_tickets = true; 127 session_tickets = true;
81 } else if (strcmp(argv[i], "fail-resume") == 0) { 128 } else if (strcmp(argv[i], "fail-resume") == 0) {
82 // Always fail to resume sessions 129 // Always fail to resume sessions
83 fail_resume = true; 130 fail_resume = true;
84 } else if (strcmp(argv[i], "client-cert") == 0) { 131 } else if (strcmp(argv[i], "client-cert") == 0) {
85 // Request a client certificate 132 // Request a client certificate
86 client_cert = true; 133 client_cert = true;
87 } else if (strcmp(argv[i], "npn") == 0) { 134 } else if (strcmp(argv[i], "npn") == 0) {
88 // Advertise NPN 135 // Advertise NPN
89 npn = true; 136 npn = true;
90 } else if (strcmp(argv[i], "npn-mispredict") == 0) { 137 } else if (strcmp(argv[i], "npn-mispredict") == 0) {
91 // Advertise NPN 138 // Advertise NPN
92 npn = true; 139 npn = true;
93 npn_mispredict = true; 140 npn_mispredict = true;
141 } else if (strcmp(argv[i], "open-socket") == 0) {
142 open_socket = true;
143 } else if (strcmp(argv[i], "tls-srp") == 0) {
144 tlssrp = true;
145 if (sslv3) {
146 fprintf(stderr, "TLS-SRP requires TLSv1; do not use sslv3 option\n");
147 return 1;
148 }
94 } else if (strcmp(argv[i], "--key-file") == 0) { 149 } else if (strcmp(argv[i], "--key-file") == 0) {
95 // Use alternative key file 150 // Use alternative key file
96 i++; 151 i++;
97 if (i == argc) { 152 if (i == argc) {
98 fprintf(stderr, "Missing argument to --key-file\n"); 153 fprintf(stderr, "Missing argument to --key-file\n");
99 return 1; 154 return 1;
100 } 155 }
101 key_file = argv[i]; 156 key_file = argv[i];
102 } else if (strcmp(argv[i], "--cert-file") == 0) { 157 } else if (strcmp(argv[i], "--cert-file") == 0) {
103 // Use alternative certificate file 158 // Use alternative certificate file
104 i++; 159 i++;
105 if (i == argc) { 160 if (i == argc) {
106 fprintf(stderr, "Missing argument to --cert-file\n"); 161 fprintf(stderr, "Missing argument to --cert-file\n");
107 return 1; 162 return 1;
108 } 163 }
109 cert_file = argv[i]; 164 cert_file = argv[i];
165 } else if (strcmp(argv[i], "--srpv-file") == 0) {
166 i++;
167 if (i == argc) {
168 fprintf(stderr, "Missing argument to --srpv-file\n");
169 return 1;
170 }
171 srpv_file = argv[i];
172 } else if (strcmp(argv[i], "--port") == 0) {
173 i++;
174 if (i == argc) {
175 fprintf(stderr, "Missing argument to --port\n");
176 return 1;
177 }
178 listen_port = (unsigned short)atoi(argv[i]);
110 } else { 179 } else {
111 fprintf(stderr, "Unknown argument: %s\n", argv[i]); 180 fprintf(stderr, "Unknown argument: %s\n", argv[i]);
112 return 1; 181 return 1;
113 } 182 }
114 } 183 }
115 184
116 SSL_CTX* ctx; 185 SSL_CTX* ctx;
117 186
118 if (sslv3) { 187 if (sslv3) {
119 ctx = SSL_CTX_new(SSLv3_server_method()); 188 ctx = SSL_CTX_new(SSLv3_server_method());
120 } else { 189 } else {
121 ctx = SSL_CTX_new(TLSv1_server_method()); 190 ctx = SSL_CTX_new(TLSv1_server_method());
122 } 191 }
123 192
124 if (sni) { 193 if (sni) {
125 SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb); 194 SSL_CTX_set_tlsext_servername_callback(ctx, sni_cb);
126 SSL_CTX_set_tlsext_servername_arg(ctx, &sni_good); 195 SSL_CTX_set_tlsext_servername_arg(ctx, &sni_good);
127 } 196 }
128 197
129 BIO* key = BIO_new(BIO_s_file()); 198 if (!tlssrp) {
130 if (BIO_read_filename(key, key_file) <= 0) { 199 BIO* key = BIO_new(BIO_s_file());
131 fprintf(stderr, "Failed to read %s\n", key_file); 200 if (BIO_read_filename(key, key_file) <= 0) {
132 return 1; 201 fprintf(stderr, "Failed to read %s\n", key_file);
133 } 202 return 1;
203 }
134 204
135 EVP_PKEY *pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL); 205 EVP_PKEY *pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, NULL);
136 if (!pkey) { 206 if (!pkey) {
137 fprintf(stderr, "Failed to parse %s\n", key_file); 207 fprintf(stderr, "Failed to parse %s\n", key_file);
138 return 1; 208 return 1;
139 } 209 }
140 BIO_free(key); 210 BIO_free(key);
141 211
142 212
143 BIO* cert = BIO_new(BIO_s_file()); 213 BIO* cert = BIO_new(BIO_s_file());
144 if (BIO_read_filename(cert, cert_file) <= 0) { 214 if (BIO_read_filename(cert, cert_file) <= 0) {
145 fprintf(stderr, "Failed to read %s\n", cert_file); 215 fprintf(stderr, "Failed to read %s\n", cert_file);
146 return 1; 216 return 1;
217 }
218
219 X509 *pcert = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
220 if (!pcert) {
221 fprintf(stderr, "Failed to parse %s\n", cert_file);
222 return 1;
223 }
224 BIO_free(cert);
225
226 if (SSL_CTX_use_certificate(ctx, pcert) <= 0) {
227 fprintf(stderr, "Failed to load %s\n", cert_file);
228 return 1;
229 }
230
231 if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) {
232 fprintf(stderr, "Failed to load %s\n", key_file);
233 return 1;
234 }
235
236 if (!SSL_CTX_check_private_key(ctx)) {
237 fprintf(stderr, "Public and private keys don't match\n");
238 return 1;
239 }
240
241 if (client_cert)
242 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
147 } 243 }
148 244
149 X509 *pcert = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
150 if (!pcert) {
151 fprintf(stderr, "Failed to parse %s\n", cert_file);
152 return 1;
153 }
154 BIO_free(cert);
155
156 if (SSL_CTX_use_certificate(ctx, pcert) <= 0) {
157 fprintf(stderr, "Failed to load %s\n", cert_file);
158 return 1;
159 }
160
161 if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) {
162 fprintf(stderr, "Failed to load %s\n", key_file);
163 return 1;
164 }
165
166 if (!SSL_CTX_check_private_key(ctx)) {
167 fprintf(stderr, "Public and private keys don't match\n");
168 return 1;
169 }
170
171 if (client_cert)
172 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_cb);
173
174 if (session_tickets) 245 if (session_tickets)
175 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH); 246 SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
176 247
177 if (snap_start) { 248 if (snap_start) {
178 static const unsigned char orbit[8] = {1, 2, 3, 4, 5, 6, 7, 8}; 249 static const unsigned char orbit[8] = {1, 2, 3, 4, 5, 6, 7, 8};
179 SSL_CTX_set_snap_start_orbit(ctx, orbit); 250 SSL_CTX_set_snap_start_orbit(ctx, orbit);
180 } 251 }
181 252
182 if (npn) 253 if (npn)
183 SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &npn_mispredict); 254 SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb, &npn_mispredict);
184 255
256 if (tlssrp) {
257 srpp.vb = SRP_VBASE_new(NULL);
258 if (SRP_VBASE_init(srpp.vb, (char *)srpv_file) != SRP_NO_ERROR) {
259 fprintf(stderr, "Failed to load SRP verifier file %s\n", srpv_file);
260 return 1;
261 }
262 SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_cb);
263 SSL_CTX_set_srp_cb_arg(ctx, &srpp);
264 SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
265 fprintf(stderr, "Using SRP verifier file %s\n", srpv_file);
266 }
267
185 unsigned connection_limit = 1; 268 unsigned connection_limit = 1;
186 if (snap_start || session_tickets) 269 if (snap_start || session_tickets)
187 connection_limit = 2; 270 connection_limit = 2;
188 if (npn_mispredict) 271 if (npn_mispredict)
189 connection_limit = 3; 272 connection_limit = 3;
190 273
191 for (unsigned connections = 0; connections < connection_limit; 274 for (unsigned connections = 0; connections < connection_limit;
192 connections++) { 275 connections++) {
193 const int fd = accept(3, NULL, NULL); 276 int listener = 3; /* default to using parent process' fd 3 */
277
278 if (open_socket) {
279 listener = socket(AF_INET, SOCK_STREAM, 0);
280 if (listener < 0) {
281 fprintf(stderr, "Failed to open socket\n");
282 return 1;
283 }
284
285 struct sockaddr_in sin;
286 memset(&sin, 0, sizeof(sin));
287 sin.sin_family = AF_INET;
288 sin.sin_port = htons((unsigned short)listen_port);
289 if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
290 fprintf(stderr, "Failed to bind socket\n");
291 return 1;
292 }
293
294 if (listen(listener, 1) != 0) {
295 fprintf(stderr, "Failed to listen on socket\n");
296 return 1;
297 }
298
299 fprintf(stderr, "Listening on localhost:%d\n", listen_port);
300 }
301
302 const int fd = accept(listener, NULL, NULL);
194 303
195 SSL* server = SSL_new(ctx); 304 SSL* server = SSL_new(ctx);
196 BIO* bio = BIO_new_socket(fd, 1 /* take ownership of fd */); 305 BIO* bio = BIO_new_socket(fd, 1 /* take ownership of fd */);
197 SSL_set_bio(server, bio, bio); 306 SSL_set_bio(server, bio, bio);
198 307
199 if (fail_resume) { 308 if (fail_resume) {
200 SSL_set_session_id_context(server, (unsigned char*) &connections, 309 SSL_set_session_id_context(server, (unsigned char*) &connections,
201 sizeof(connections)); 310 sizeof(connections));
202 } 311 }
203 312
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 unsigned char buffer[6]; 354 unsigned char buffer[6];
246 355
247 int ret = SSL_read(server, buffer, sizeof(buffer)); 356 int ret = SSL_read(server, buffer, sizeof(buffer));
248 if (ret == -1) { 357 if (ret == -1) {
249 err = SSL_get_error(server, ret); 358 err = SSL_get_error(server, ret);
250 ERR_print_errors_fp(stderr); 359 ERR_print_errors_fp(stderr);
251 fprintf(stderr, "SSL_read failed: %d\n", err); 360 fprintf(stderr, "SSL_read failed: %d\n", err);
252 } 361 }
253 if (memcmp(buffer, "hello!", sizeof(buffer)) == 0) { 362 if (memcmp(buffer, "hello!", sizeof(buffer)) == 0) {
254 SSL_write(server, "goodbye!", 8); 363 SSL_write(server, "goodbye!", 8);
364 } else if (memcmp(buffer, "whoami", sizeof(buffer)) == 0) {
365 char *username = SSL_get_srp_username(server);
366 if (username) {
367 SSL_write(server, username, strlen(username));
368 } else {
369 SSL_write(server, "not-using-tls-srp", 17);
370 }
255 } 371 }
256 372
257 SSL_shutdown(server); 373 SSL_shutdown(server);
258 SSL_shutdown(server); 374 SSL_shutdown(server);
375 close(fd);
259 } 376 }
260 377
261 SSL_CTX_free(ctx); 378 SSL_CTX_free(ctx);
262 379
263 return 0; 380 return 0;
264 } 381 }
OLDNEW
« no previous file with comments | « net/spdy/spdy_stream.h ('k') | net/test/test_server.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698