diff options
author | jsing <> | 2014-10-13 13:42:39 +0000 |
---|---|---|
committer | jsing <> | 2014-10-13 13:42:39 +0000 |
commit | 8890ce1e761bbb200cb6447b579ed30d21164f9f (patch) | |
tree | 17e87849b332239cdd57ddb161ef0ed699ae122f /src | |
parent | 742c764ecc0f891a8d36d3c11815aab4f8ac8f80 (diff) | |
download | openbsd-8890ce1e761bbb200cb6447b579ed30d21164f9f.tar.gz openbsd-8890ce1e761bbb200cb6447b579ed30d21164f9f.tar.bz2 openbsd-8890ce1e761bbb200cb6447b579ed30d21164f9f.zip |
Add NPN regress tests from OpenSSL. However, unlike OpenSSL, actually exit
with a failure if the NPN verification fails.
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libssl/ssl/ssltest.c | 135 | ||||
-rw-r--r-- | src/regress/lib/libssl/ssl/testssl | 14 |
2 files changed, 146 insertions, 3 deletions
diff --git a/src/regress/lib/libssl/ssl/ssltest.c b/src/regress/lib/libssl/ssl/ssltest.c index 4346cf4465..5587c0e424 100644 --- a/src/regress/lib/libssl/ssl/ssltest.c +++ b/src/regress/lib/libssl/ssl/ssltest.c | |||
@@ -208,6 +208,89 @@ static DH *get_dh1024dsa(void); | |||
208 | static BIO *bio_err = NULL; | 208 | static BIO *bio_err = NULL; |
209 | static BIO *bio_stdout = NULL; | 209 | static BIO *bio_stdout = NULL; |
210 | 210 | ||
211 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
212 | /* Note that this code assumes that this is only a one element list: */ | ||
213 | static const char NEXT_PROTO_STRING[] = "\x09testproto"; | ||
214 | int npn_client = 0; | ||
215 | int npn_server = 0; | ||
216 | int npn_server_reject = 0; | ||
217 | |||
218 | static int | ||
219 | cb_client_npn(SSL *s, unsigned char **out, unsigned char *outlen, | ||
220 | const unsigned char *in, unsigned int inlen, void *arg) | ||
221 | { | ||
222 | /* | ||
223 | * This callback only returns the protocol string, rather than a length | ||
224 | * prefixed set. We assume that NEXT_PROTO_STRING is a one element list | ||
225 | * and remove the first byte to chop off the length prefix. | ||
226 | */ | ||
227 | *out = (unsigned char *)NEXT_PROTO_STRING + 1; | ||
228 | *outlen = sizeof(NEXT_PROTO_STRING) - 2; | ||
229 | return (SSL_TLSEXT_ERR_OK); | ||
230 | } | ||
231 | |||
232 | static int | ||
233 | cb_server_npn(SSL *s, const unsigned char **data, unsigned int *len, void *arg) | ||
234 | { | ||
235 | *data = (const unsigned char *)NEXT_PROTO_STRING; | ||
236 | *len = sizeof(NEXT_PROTO_STRING) - 1; | ||
237 | return (SSL_TLSEXT_ERR_OK); | ||
238 | } | ||
239 | |||
240 | static int | ||
241 | cb_server_rejects_npn(SSL *s, const unsigned char **data, unsigned int *len, | ||
242 | void *arg) | ||
243 | { | ||
244 | return (SSL_TLSEXT_ERR_NOACK); | ||
245 | } | ||
246 | |||
247 | static int | ||
248 | verify_npn(SSL *client, SSL *server) | ||
249 | { | ||
250 | const unsigned char *client_s; | ||
251 | unsigned int client_len; | ||
252 | const unsigned char *server_s; | ||
253 | unsigned int server_len; | ||
254 | |||
255 | SSL_get0_next_proto_negotiated(client, &client_s, &client_len); | ||
256 | SSL_get0_next_proto_negotiated(server, &server_s, &server_len); | ||
257 | |||
258 | if (client_len) { | ||
259 | BIO_printf(bio_stdout, "Client NPN: "); | ||
260 | BIO_write(bio_stdout, client_s, client_len); | ||
261 | BIO_printf(bio_stdout, "\n"); | ||
262 | } | ||
263 | |||
264 | if (server_len) { | ||
265 | BIO_printf(bio_stdout, "Server NPN: "); | ||
266 | BIO_write(bio_stdout, server_s, server_len); | ||
267 | BIO_printf(bio_stdout, "\n"); | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * If an NPN string was returned, it must be the protocol that we | ||
272 | * expected to negotiate. | ||
273 | */ | ||
274 | if (client_len && (client_len != sizeof(NEXT_PROTO_STRING) - 2 || | ||
275 | memcmp(client_s, NEXT_PROTO_STRING + 1, client_len))) | ||
276 | return (-1); | ||
277 | if (server_len && (server_len != sizeof(NEXT_PROTO_STRING) - 2 || | ||
278 | memcmp(server_s, NEXT_PROTO_STRING + 1, server_len))) | ||
279 | return (-1); | ||
280 | |||
281 | if (!npn_client && client_len) | ||
282 | return (-1); | ||
283 | if (!npn_server && server_len) | ||
284 | return (-1); | ||
285 | if (npn_server_reject && server_len) | ||
286 | return (-1); | ||
287 | if (npn_client && npn_server && (!client_len || !server_len)) | ||
288 | return (-1); | ||
289 | |||
290 | return (0); | ||
291 | } | ||
292 | #endif | ||
293 | |||
211 | static char *cipher = NULL; | 294 | static char *cipher = NULL; |
212 | static int verbose = 0; | 295 | static int verbose = 0; |
213 | static int debug = 0; | 296 | static int debug = 0; |
@@ -253,6 +336,11 @@ sv_usage(void) | |||
253 | " Use \"openssl ecparam -list_curves\" for all names\n" \ | 336 | " Use \"openssl ecparam -list_curves\" for all names\n" \ |
254 | " (default is sect163r2).\n"); | 337 | " (default is sect163r2).\n"); |
255 | fprintf(stderr, " -test_cipherlist - verifies the order of the ssl cipher lists\n"); | 338 | fprintf(stderr, " -test_cipherlist - verifies the order of the ssl cipher lists\n"); |
339 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
340 | fprintf(stderr, " -npn_client - have client side offer NPN\n"); | ||
341 | fprintf(stderr, " -npn_server - have server side offer NPN\n"); | ||
342 | fprintf(stderr, " -npn_server_reject - have server reject NPN\n"); | ||
343 | #endif | ||
256 | } | 344 | } |
257 | 345 | ||
258 | static void | 346 | static void |
@@ -495,7 +583,17 @@ main(int argc, char *argv[]) | |||
495 | app_verify_arg.allow_proxy_certs = 1; | 583 | app_verify_arg.allow_proxy_certs = 1; |
496 | } else if (strcmp(*argv, "-test_cipherlist") == 0) { | 584 | } else if (strcmp(*argv, "-test_cipherlist") == 0) { |
497 | test_cipherlist = 1; | 585 | test_cipherlist = 1; |
498 | } else { | 586 | } |
587 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
588 | else if (strcmp(*argv, "-npn_client") == 0) { | ||
589 | npn_client = 1; | ||
590 | } else if (strcmp(*argv, "-npn_server") == 0) { | ||
591 | npn_server = 1; | ||
592 | } else if (strcmp(*argv, "-npn_server_reject") == 0) { | ||
593 | npn_server_reject = 1; | ||
594 | } | ||
595 | #endif | ||
596 | else { | ||
499 | fprintf(stderr, "unknown option %s\n", *argv); | 597 | fprintf(stderr, "unknown option %s\n", *argv); |
500 | badop = 1; | 598 | badop = 1; |
501 | break; | 599 | break; |
@@ -541,7 +639,6 @@ bad: | |||
541 | SSL_library_init(); | 639 | SSL_library_init(); |
542 | SSL_load_error_strings(); | 640 | SSL_load_error_strings(); |
543 | 641 | ||
544 | |||
545 | if (dtls1) | 642 | if (dtls1) |
546 | meth = DTLSv1_method(); | 643 | meth = DTLSv1_method(); |
547 | else if (tls1) | 644 | else if (tls1) |
@@ -653,6 +750,24 @@ bad: | |||
653 | (void *)&session_id_context, sizeof(session_id_context)); | 750 | (void *)&session_id_context, sizeof(session_id_context)); |
654 | } | 751 | } |
655 | 752 | ||
753 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
754 | if (npn_client) | ||
755 | SSL_CTX_set_next_proto_select_cb(c_ctx, cb_client_npn, NULL); | ||
756 | if (npn_server) { | ||
757 | if (npn_server_reject) { | ||
758 | BIO_printf(bio_err, "Can't have both -npn_server and " | ||
759 | "-npn_server_reject\n"); | ||
760 | goto end; | ||
761 | } | ||
762 | SSL_CTX_set_next_protos_advertised_cb(s_ctx, | ||
763 | cb_server_npn, NULL); | ||
764 | } | ||
765 | if (npn_server_reject) { | ||
766 | SSL_CTX_set_next_protos_advertised_cb(s_ctx, | ||
767 | cb_server_rejects_npn, NULL); | ||
768 | } | ||
769 | #endif | ||
770 | |||
656 | c_ssl = SSL_new(c_ctx); | 771 | c_ssl = SSL_new(c_ctx); |
657 | s_ssl = SSL_new(s_ctx); | 772 | s_ssl = SSL_new(s_ctx); |
658 | 773 | ||
@@ -1054,6 +1169,14 @@ doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time, | |||
1054 | 1169 | ||
1055 | if (verbose) | 1170 | if (verbose) |
1056 | print_details(c_ssl, "DONE via BIO pair: "); | 1171 | print_details(c_ssl, "DONE via BIO pair: "); |
1172 | |||
1173 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
1174 | if (verify_npn(c_ssl, s_ssl) < 0) { | ||
1175 | ret = 1; | ||
1176 | goto err; | ||
1177 | } | ||
1178 | #endif | ||
1179 | |||
1057 | end: | 1180 | end: |
1058 | ret = 0; | 1181 | ret = 0; |
1059 | 1182 | ||
@@ -1305,6 +1428,14 @@ doit(SSL *s_ssl, SSL *c_ssl, long count) | |||
1305 | 1428 | ||
1306 | if (verbose) | 1429 | if (verbose) |
1307 | print_details(c_ssl, "DONE: "); | 1430 | print_details(c_ssl, "DONE: "); |
1431 | |||
1432 | #ifndef OPENSSL_NO_NEXTPROTONEG | ||
1433 | if (verify_npn(c_ssl, s_ssl) < 0) { | ||
1434 | ret = 1; | ||
1435 | goto err; | ||
1436 | } | ||
1437 | #endif | ||
1438 | |||
1308 | ret = 0; | 1439 | ret = 0; |
1309 | err: | 1440 | err: |
1310 | /* We have to set the BIO's to NULL otherwise they will be | 1441 | /* We have to set the BIO's to NULL otherwise they will be |
diff --git a/src/regress/lib/libssl/ssl/testssl b/src/regress/lib/libssl/ssl/testssl index a4fa4112df..ca974a68c9 100644 --- a/src/regress/lib/libssl/ssl/testssl +++ b/src/regress/lib/libssl/ssl/testssl | |||
@@ -143,7 +143,7 @@ fi | |||
143 | #fi | 143 | #fi |
144 | 144 | ||
145 | # | 145 | # |
146 | # DTLS | 146 | # DTLS tests |
147 | # | 147 | # |
148 | 148 | ||
149 | echo test dtlsv1 | 149 | echo test dtlsv1 |
@@ -171,3 +171,15 @@ for protocol in SSLv3; do | |||
171 | fi | 171 | fi |
172 | done | 172 | done |
173 | done | 173 | done |
174 | |||
175 | # | ||
176 | # Next Protocol Negotiation tests | ||
177 | # | ||
178 | echo "Testing NPN..." | ||
179 | $ssltest -bio_pair -tls1 -npn_client || exit 1 | ||
180 | $ssltest -bio_pair -tls1 -npn_server || exit 1 | ||
181 | $ssltest -bio_pair -tls1 -npn_server_reject || exit 1 | ||
182 | $ssltest -bio_pair -tls1 -npn_client -npn_server_reject || exit 1 | ||
183 | $ssltest -bio_pair -tls1 -npn_client -npn_server || exit 1 | ||
184 | $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 || exit 1 | ||
185 | $ssltest -bio_pair -tls1 -npn_client -npn_server -num 2 -reuse || exit 1 | ||