|
Lines 305-314
static int s_nbio=0;
Link Here
|
| 305 |
#endif |
305 |
#endif |
| 306 |
#endif |
306 |
#endif |
| 307 |
|
307 |
|
| 308 |
static const char rnd_seed[] = "string to make the random number generator think it has entropy"; |
308 |
static const char rnd_seed[] = "string to make the random number generator think it has entropy"; |
| 309 |
|
309 |
|
|
|
310 |
static const char *alpn_client; |
| 311 |
static const char *alpn_server; |
| 312 |
static const char *alpn_expected; |
| 313 |
static unsigned char *alpn_selected; |
| 314 |
|
| 315 |
/* next_protos_parse parses a comma separated list of strings into a string |
| 316 |
* in a format suitable for passing to SSL_CTX_set_next_protos_advertised. |
| 317 |
* outlen: (output) set to the length of the resulting buffer on success. |
| 318 |
* err: (maybe NULL) on failure, an error message line is written to this BIO. |
| 319 |
* in: a NUL termianted string like "abc,def,ghi" |
| 320 |
* |
| 321 |
* returns: a malloced buffer or NULL on failure. |
| 322 |
*/ |
| 323 |
static unsigned char *next_protos_parse(unsigned short *outlen, const char *in) |
| 324 |
{ |
| 325 |
size_t len; |
| 326 |
unsigned char *out; |
| 327 |
size_t i, start = 0; |
| 328 |
|
| 329 |
len = strlen(in); |
| 330 |
if (len >= 65535) |
| 331 |
return NULL; |
| 332 |
|
| 333 |
out = OPENSSL_malloc(strlen(in) + 1); |
| 334 |
if (!out) |
| 335 |
return NULL; |
| 336 |
|
| 337 |
for (i = 0; i <= len; ++i) |
| 338 |
{ |
| 339 |
if (i == len || in[i] == ',') |
| 340 |
{ |
| 341 |
if (i - start > 255) |
| 342 |
{ |
| 343 |
OPENSSL_free(out); |
| 344 |
return NULL; |
| 345 |
} |
| 346 |
out[start] = i - start; |
| 347 |
start = i + 1; |
| 348 |
} |
| 349 |
else |
| 350 |
out[i+1] = in[i]; |
| 351 |
} |
| 352 |
|
| 353 |
*outlen = len + 1; |
| 354 |
return out; |
| 355 |
} |
| 356 |
|
| 357 |
static int cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) |
| 358 |
{ |
| 359 |
unsigned char *protos; |
| 360 |
unsigned short protos_len; |
| 361 |
|
| 362 |
protos = next_protos_parse(&protos_len, alpn_server); |
| 363 |
if (protos == NULL) |
| 364 |
{ |
| 365 |
fprintf(stderr, "failed to parser ALPN server protocol string: %s\n", alpn_server); |
| 366 |
abort(); |
| 367 |
} |
| 368 |
|
| 369 |
if (SSL_select_next_proto((unsigned char**) out, outlen, protos, protos_len, in, inlen) != |
| 370 |
OPENSSL_NPN_NEGOTIATED) |
| 371 |
{ |
| 372 |
OPENSSL_free(protos); |
| 373 |
return SSL_TLSEXT_ERR_NOACK; |
| 374 |
} |
| 375 |
|
| 376 |
/* Make a copy of the selected protocol which will be freed in verify_alpn. */ |
| 377 |
alpn_selected = OPENSSL_malloc(*outlen); |
| 378 |
memcpy(alpn_selected, *out, *outlen); |
| 379 |
*out = alpn_selected; |
| 380 |
|
| 381 |
OPENSSL_free(protos); |
| 382 |
return SSL_TLSEXT_ERR_OK; |
| 383 |
} |
| 384 |
|
| 385 |
static int verify_alpn(SSL *client, SSL *server) |
| 386 |
{ |
| 387 |
const unsigned char *client_proto, *server_proto; |
| 388 |
unsigned int client_proto_len = 0, server_proto_len = 0; |
| 389 |
SSL_get0_alpn_selected(client, &client_proto, &client_proto_len); |
| 390 |
SSL_get0_alpn_selected(server, &server_proto, &server_proto_len); |
| 391 |
|
| 392 |
if (alpn_selected != NULL) |
| 393 |
{ |
| 394 |
OPENSSL_free(alpn_selected); |
| 395 |
alpn_selected = NULL; |
| 396 |
} |
| 397 |
|
| 398 |
if (client_proto_len != server_proto_len || |
| 399 |
memcmp(client_proto, server_proto, client_proto_len) != 0) |
| 400 |
{ |
| 401 |
BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); |
| 402 |
goto err; |
| 403 |
} |
| 404 |
|
| 405 |
if (client_proto_len > 0 && alpn_expected == NULL) |
| 406 |
{ |
| 407 |
BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n"); |
| 408 |
goto err; |
| 409 |
} |
| 410 |
|
| 411 |
if (alpn_expected != NULL && |
| 412 |
(client_proto_len != strlen(alpn_expected) || |
| 413 |
memcmp(client_proto, alpn_expected, client_proto_len) != 0)) |
| 414 |
{ |
| 415 |
BIO_printf(bio_stdout, "ALPN selected protocols not equal to expected protocol: %s\n", alpn_expected); |
| 416 |
goto err; |
| 417 |
} |
| 418 |
|
| 419 |
return 0; |
| 420 |
|
| 421 |
err: |
| 422 |
BIO_printf(bio_stdout, "ALPN results: client: '"); |
| 423 |
BIO_write(bio_stdout, client_proto, client_proto_len); |
| 424 |
BIO_printf(bio_stdout, "', server: '"); |
| 425 |
BIO_write(bio_stdout, server_proto, server_proto_len); |
| 426 |
BIO_printf(bio_stdout, "'\n"); |
| 427 |
BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", alpn_client, alpn_server); |
| 428 |
return -1; |
| 429 |
} |
| 430 |
|
| 310 |
int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time); |
431 |
int doit_biopair(SSL *s_ssl,SSL *c_ssl,long bytes,clock_t *s_time,clock_t *c_time); |
| 311 |
int doit(SSL *s_ssl,SSL *c_ssl,long bytes); |
432 |
int doit(SSL *s_ssl,SSL *c_ssl,long bytes); |
| 312 |
static int do_test_cipherlist(void); |
433 |
static int do_test_cipherlist(void); |
| 313 |
static void sv_usage(void) |
434 |
static void sv_usage(void) |
| 314 |
{ |
435 |
{ |
|
Lines 366-376
static void sv_usage(void)
Link Here
|
| 366 |
#ifndef OPENSSL_NO_ECDH |
487 |
#ifndef OPENSSL_NO_ECDH |
| 367 |
fprintf(stderr," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ |
488 |
fprintf(stderr," -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ |
| 368 |
" Use \"openssl ecparam -list_curves\" for all names\n" \ |
489 |
" Use \"openssl ecparam -list_curves\" for all names\n" \ |
| 369 |
" (default is sect163r2).\n"); |
490 |
" (default is sect163r2).\n"); |
| 370 |
#endif |
491 |
#endif |
| 371 |
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n"); |
492 |
fprintf(stderr," -custom_ext - try various custom extension callbacks\n"); |
|
|
493 |
fprintf(stderr," -alpn_client <string> - have client side offer ALPN\n"); |
| 494 |
fprintf(stderr," -alpn_server <string> - have server side offer ALPN\n"); |
| 495 |
fprintf(stderr," -alpn_expected <string> - the ALPN protocol that should be negotiated\n"); |
| 372 |
} |
496 |
} |
| 373 |
|
497 |
|
| 374 |
static void print_details(SSL *c_ssl, const char *prefix) |
498 |
static void print_details(SSL *c_ssl, const char *prefix) |
| 375 |
{ |
499 |
{ |
| 376 |
const SSL_CIPHER *ciph; |
500 |
const SSL_CIPHER *ciph; |
|
Lines 763-772
int main(int argc, char *argv[])
Link Here
|
| 763 |
} |
887 |
} |
| 764 |
else if (strcmp(*argv,"-test_cipherlist") == 0) |
888 |
else if (strcmp(*argv,"-test_cipherlist") == 0) |
| 765 |
{ |
889 |
{ |
| 766 |
test_cipherlist = 1; |
890 |
test_cipherlist = 1; |
| 767 |
} |
891 |
} |
|
|
892 |
else if (strcmp(*argv,"-alpn_client") == 0) |
| 893 |
{ |
| 894 |
if (--argc < 1) goto bad; |
| 895 |
alpn_client = *(++argv); |
| 896 |
} |
| 897 |
else if (strcmp(*argv,"-alpn_server") == 0) |
| 898 |
{ |
| 899 |
if (--argc < 1) goto bad; |
| 900 |
alpn_server = *(++argv); |
| 901 |
} |
| 902 |
else if (strcmp(*argv,"-alpn_expected") == 0) |
| 903 |
{ |
| 904 |
if (--argc < 1) goto bad; |
| 905 |
alpn_expected = *(++argv); |
| 906 |
} |
| 768 |
else |
907 |
else |
| 769 |
{ |
908 |
{ |
| 770 |
fprintf(stderr,"unknown option %s\n",*argv); |
909 |
fprintf(stderr,"unknown option %s\n",*argv); |
| 771 |
badop=1; |
910 |
badop=1; |
| 772 |
break; |
911 |
break; |
|
Lines 1068-1077
bad:
Link Here
|
| 1068 |
SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); |
1207 |
SSL_CTX_set_srp_cb_arg(s_ctx, &srp_server_arg); |
| 1069 |
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); |
1208 |
SSL_CTX_set_srp_username_callback(s_ctx, ssl_srp_server_param_cb); |
| 1070 |
} |
1209 |
} |
| 1071 |
#endif |
1210 |
#endif |
| 1072 |
|
1211 |
|
|
|
1212 |
if (alpn_server) |
| 1213 |
SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); |
| 1214 |
|
| 1215 |
if (alpn_client) |
| 1216 |
{ |
| 1217 |
unsigned short alpn_len; |
| 1218 |
unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); |
| 1219 |
|
| 1220 |
if (alpn == NULL) |
| 1221 |
{ |
| 1222 |
BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); |
| 1223 |
goto end; |
| 1224 |
} |
| 1225 |
SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len); |
| 1226 |
OPENSSL_free(alpn); |
| 1227 |
} |
| 1228 |
|
| 1073 |
c_ssl=SSL_new(c_ctx); |
1229 |
c_ssl=SSL_new(c_ctx); |
| 1074 |
s_ssl=SSL_new(s_ctx); |
1230 |
s_ssl=SSL_new(s_ctx); |
| 1075 |
|
1231 |
|
| 1076 |
#ifndef OPENSSL_NO_KRB5 |
1232 |
#ifndef OPENSSL_NO_KRB5 |
| 1077 |
if (c_ssl && c_ssl->kssl_ctx) |
1233 |
if (c_ssl && c_ssl->kssl_ctx) |
|
Lines 1518-1527
int doit_biopair(SSL *s_ssl, SSL *c_ssl, long count,
Link Here
|
| 1518 |
} |
1674 |
} |
| 1519 |
while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); |
1675 |
while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); |
| 1520 |
|
1676 |
|
| 1521 |
if (verbose) |
1677 |
if (verbose) |
| 1522 |
print_details(c_ssl, "DONE via BIO pair: "); |
1678 |
print_details(c_ssl, "DONE via BIO pair: "); |
|
|
1679 |
|
| 1680 |
if (verify_alpn(c_ssl, s_ssl) < 0) |
| 1681 |
{ |
| 1682 |
ret = 1; |
| 1683 |
goto err; |
| 1684 |
} |
| 1523 |
end: |
1685 |
end: |
| 1524 |
ret = 0; |
1686 |
ret = 0; |
| 1525 |
|
1687 |
|
| 1526 |
err: |
1688 |
err: |
| 1527 |
ERR_print_errors(bio_err); |
1689 |
ERR_print_errors(bio_err); |