ssltest.c revision 1.29
1/* ssl/ssltest.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay@cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] 57 */ 58/* ==================================================================== 59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 60 * 61 * Redistribution and use in source and binary forms, with or without 62 * modification, are permitted provided that the following conditions 63 * are met: 64 * 65 * 1. Redistributions of source code must retain the above copyright 66 * notice, this list of conditions and the following disclaimer. 67 * 68 * 2. Redistributions in binary form must reproduce the above copyright 69 * notice, this list of conditions and the following disclaimer in 70 * the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3. All advertising materials mentioning features or use of this 74 * software must display the following acknowledgment: 75 * "This product includes software developed by the OpenSSL Project 76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77 * 78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79 * endorse or promote products derived from this software without 80 * prior written permission. For written permission, please contact 81 * openssl-core@openssl.org. 82 * 83 * 5. Products derived from this software may not be called "OpenSSL" 84 * nor may "OpenSSL" appear in their names without prior written 85 * permission of the OpenSSL Project. 86 * 87 * 6. Redistributions of any form whatsoever must retain the following 88 * acknowledgment: 89 * "This product includes software developed by the OpenSSL Project 90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91 * 92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103 * OF THE POSSIBILITY OF SUCH DAMAGE. 104 * ==================================================================== 105 * 106 * This product includes cryptographic software written by Eric Young 107 * (eay@cryptsoft.com). This product includes software written by Tim 108 * Hudson (tjh@cryptsoft.com). 109 * 110 */ 111/* ==================================================================== 112 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 113 * ECC cipher suite support in OpenSSL originally developed by 114 * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 115 */ 116/* ==================================================================== 117 * Copyright 2005 Nokia. All rights reserved. 118 * 119 * The portions of the attached software ("Contribution") is developed by 120 * Nokia Corporation and is licensed pursuant to the OpenSSL open source 121 * license. 122 * 123 * The Contribution, originally written by Mika Kousa and Pasi Eronen of 124 * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites 125 * support (see RFC 4279) to OpenSSL. 126 * 127 * No patent licenses or other rights except those expressly stated in 128 * the OpenSSL open source license shall be deemed granted or received 129 * expressly, by implication, estoppel, or otherwise. 130 * 131 * No assurances are provided by Nokia that the Contribution does not 132 * infringe the patent or other intellectual property rights of any third 133 * party or that the license provides you with all the necessary rights 134 * to make use of the Contribution. 135 * 136 * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN 137 * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA 138 * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY 139 * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR 140 * OTHERWISE. 141 */ 142 143#define _BSD_SOURCE 1 /* Or gethostname won't be declared properly 144 on Linux and GNU platforms. */ 145#include <sys/types.h> 146#include <sys/socket.h> 147 148#include <netinet/in.h> 149 150#include <assert.h> 151#include <errno.h> 152#include <limits.h> 153#include <netdb.h> 154#include <stdio.h> 155#include <stdlib.h> 156#include <string.h> 157#include <time.h> 158#include <unistd.h> 159 160#include <ctype.h> 161 162#include <openssl/opensslconf.h> 163#include <openssl/bio.h> 164#include <openssl/crypto.h> 165#include <openssl/evp.h> 166#include <openssl/x509.h> 167#include <openssl/x509v3.h> 168#include <openssl/ssl.h> 169#ifndef OPENSSL_NO_ENGINE 170#include <openssl/engine.h> 171#endif 172#include <openssl/err.h> 173#include <openssl/rand.h> 174#include <openssl/rsa.h> 175#include <openssl/dsa.h> 176#include <openssl/dh.h> 177#include <openssl/bn.h> 178 179#define TEST_SERVER_CERT "../apps/server.pem" 180#define TEST_CLIENT_CERT "../apps/client.pem" 181 182static int verify_callback(int ok, X509_STORE_CTX *ctx); 183static int app_verify_callback(X509_STORE_CTX *ctx, void *arg); 184#define APP_CALLBACK_STRING "Test Callback Argument" 185struct app_verify_arg { 186 char *string; 187 int app_verify; 188 int allow_proxy_certs; 189 char *proxy_auth; 190 char *proxy_cond; 191}; 192 193static DH *get_dh1024(void); 194static DH *get_dh1024dsa(void); 195 196static BIO *bio_err = NULL; 197static BIO *bio_stdout = NULL; 198 199static const char *alpn_client; 200static const char *alpn_server; 201static const char *alpn_expected; 202static unsigned char *alpn_selected; 203 204/* 205 * next_protos_parse parses a comma separated list of strings into a string 206 * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. 207 * outlen: (output) set to the length of the resulting buffer on success. 208 * err: (maybe NULL) on failure, an error message line is written to this BIO. 209 * in: a NUL terminated string like "abc,def,ghi" 210 * 211 * returns: a malloced buffer or NULL on failure. 212 */ 213static unsigned char * 214next_protos_parse(unsigned short *outlen, const char *in) 215{ 216 size_t i, len, start = 0; 217 unsigned char *out; 218 219 len = strlen(in); 220 if (len >= 65535) 221 return (NULL); 222 223 if ((out = malloc(strlen(in) + 1)) == NULL) 224 return (NULL); 225 226 for (i = 0; i <= len; ++i) { 227 if (i == len || in[i] == ',') { 228 if (i - start > 255) { 229 free(out); 230 return (NULL); 231 } 232 out[start] = i - start; 233 start = i + 1; 234 } else 235 out[i+1] = in[i]; 236 } 237 *outlen = len + 1; 238 return (out); 239} 240 241static int 242cb_server_alpn(SSL *s, const unsigned char **out, unsigned char *outlen, 243 const unsigned char *in, unsigned int inlen, void *arg) 244{ 245 unsigned char *protos; 246 unsigned short protos_len; 247 248 if ((protos = next_protos_parse(&protos_len, alpn_server)) == NULL) { 249 fprintf(stderr, 250 "failed to parser ALPN server protocol string: %s\n", 251 alpn_server); 252 abort(); 253 } 254 255 if (SSL_select_next_proto((unsigned char **)out, outlen, protos, 256 protos_len, in, inlen) != OPENSSL_NPN_NEGOTIATED) { 257 free(protos); 258 return (SSL_TLSEXT_ERR_NOACK); 259 } 260 261 /* 262 * Make a copy of the selected protocol which will be freed in 263 * verify_alpn. 264 */ 265 if ((alpn_selected = malloc(*outlen)) == NULL) { 266 fprintf(stderr, "malloc failed\n"); 267 abort(); 268 } 269 memcpy(alpn_selected, *out, *outlen); 270 *out = alpn_selected; 271 free(protos); 272 273 return (SSL_TLSEXT_ERR_OK); 274} 275 276static int 277verify_alpn(SSL *client, SSL *server) 278{ 279 const unsigned char *client_proto, *server_proto; 280 unsigned int client_proto_len = 0, server_proto_len = 0; 281 282 SSL_get0_alpn_selected(client, &client_proto, &client_proto_len); 283 SSL_get0_alpn_selected(server, &server_proto, &server_proto_len); 284 285 free(alpn_selected); 286 alpn_selected = NULL; 287 288 if (client_proto_len != server_proto_len || 289 memcmp(client_proto, server_proto, client_proto_len) != 0) { 290 BIO_printf(bio_stdout, "ALPN selected protocols differ!\n"); 291 goto err; 292 } 293 294 if (client_proto_len > 0 && alpn_expected == NULL) { 295 BIO_printf(bio_stdout, "ALPN unexpectedly negotiated\n"); 296 goto err; 297 } 298 299 if (alpn_expected != NULL && 300 (client_proto_len != strlen(alpn_expected) || 301 memcmp(client_proto, alpn_expected, client_proto_len) != 0)) { 302 BIO_printf(bio_stdout, "ALPN selected protocols not equal to " 303 "expected protocol: %s\n", alpn_expected); 304 goto err; 305 } 306 307 return (0); 308 309err: 310 BIO_printf(bio_stdout, "ALPN results: client: '"); 311 BIO_write(bio_stdout, client_proto, client_proto_len); 312 BIO_printf(bio_stdout, "', server: '"); 313 BIO_write(bio_stdout, server_proto, server_proto_len); 314 BIO_printf(bio_stdout, "'\n"); 315 BIO_printf(bio_stdout, "ALPN configured: client: '%s', server: '%s'\n", 316 alpn_client, alpn_server); 317 318 return (-1); 319} 320 321static char *cipher = NULL; 322static int verbose = 0; 323static int debug = 0; 324 325int doit_biopair(SSL *s_ssl, SSL *c_ssl, long bytes, clock_t *s_time, 326 clock_t *c_time); 327int doit(SSL *s_ssl, SSL *c_ssl, long bytes); 328 329static void 330sv_usage(void) 331{ 332 fprintf(stderr, "usage: ssltest [args ...]\n"); 333 fprintf(stderr, "\n"); 334 fprintf(stderr, " -server_auth - check server certificate\n"); 335 fprintf(stderr, " -client_auth - do client authentication\n"); 336 fprintf(stderr, " -proxy - allow proxy certificates\n"); 337 fprintf(stderr, " -proxy_auth <val> - set proxy policy rights\n"); 338 fprintf(stderr, " -proxy_cond <val> - experssion to test proxy policy rights\n"); 339 fprintf(stderr, " -v - more output\n"); 340 fprintf(stderr, " -d - debug output\n"); 341 fprintf(stderr, " -reuse - use session-id reuse\n"); 342 fprintf(stderr, " -num <val> - number of connections to perform\n"); 343 fprintf(stderr, " -bytes <val> - number of bytes to swap between client/server\n"); 344 fprintf(stderr, " -dhe1024dsa - use 1024 bit key (with 160-bit subprime) for DHE\n"); 345 fprintf(stderr, " -no_dhe - disable DHE\n"); 346 fprintf(stderr, " -no_ecdhe - disable ECDHE\n"); 347 fprintf(stderr, " -dtls1 - use DTLSv1\n"); 348 fprintf(stderr, " -tls1 - use TLSv1\n"); 349 fprintf(stderr, " -tls1_2 - use TLSv1.2\n"); 350 fprintf(stderr, " -CApath arg - PEM format directory of CA's\n"); 351 fprintf(stderr, " -CAfile arg - PEM format file of CA's\n"); 352 fprintf(stderr, " -cert arg - Server certificate file\n"); 353 fprintf(stderr, " -key arg - Server key file (default: same as -cert)\n"); 354 fprintf(stderr, " -c_cert arg - Client certificate file\n"); 355 fprintf(stderr, " -c_key arg - Client key file (default: same as -c_cert)\n"); 356 fprintf(stderr, " -cipher arg - The cipher list\n"); 357 fprintf(stderr, " -bio_pair - Use BIO pairs\n"); 358 fprintf(stderr, " -f - Test even cases that can't work\n"); 359 fprintf(stderr, " -time - measure processor time used by client and server\n"); 360 fprintf(stderr, " -named_curve arg - Elliptic curve name to use for ephemeral ECDH keys.\n" \ 361 " Use \"openssl ecparam -list_curves\" for all names\n" \ 362 " (default is sect163r2).\n"); 363 fprintf(stderr, " -alpn_client <string> - have client side offer ALPN\n"); 364 fprintf(stderr, " -alpn_server <string> - have server side offer ALPN\n"); 365 fprintf(stderr, " -alpn_expected <string> - the ALPN protocol that should be negotiated\n"); 366} 367 368static void 369print_details(SSL *c_ssl, const char *prefix) 370{ 371 const SSL_CIPHER *ciph; 372 X509 *cert; 373 374 ciph = SSL_get_current_cipher(c_ssl); 375 BIO_printf(bio_stdout, "%s%s, cipher %s %s", 376 prefix, SSL_get_version(c_ssl), SSL_CIPHER_get_version(ciph), 377 SSL_CIPHER_get_name(ciph)); 378 cert = SSL_get_peer_certificate(c_ssl); 379 if (cert != NULL) { 380 EVP_PKEY *pkey = X509_get_pubkey(cert); 381 if (pkey != NULL) { 382 if (pkey->type == EVP_PKEY_RSA && 383 pkey->pkey.rsa != NULL && 384 pkey->pkey.rsa->n != NULL) { 385 BIO_printf(bio_stdout, ", %d bit RSA", 386 BN_num_bits(pkey->pkey.rsa->n)); 387 } else if (pkey->type == EVP_PKEY_DSA && 388 pkey->pkey.dsa != NULL && 389 pkey->pkey.dsa->p != NULL) { 390 BIO_printf(bio_stdout, ", %d bit DSA", 391 BN_num_bits(pkey->pkey.dsa->p)); 392 } 393 EVP_PKEY_free(pkey); 394 } 395 X509_free(cert); 396 } 397 /* The SSL API does not allow us to look at temporary RSA/DH keys, 398 * otherwise we should print their lengths too */ 399 BIO_printf(bio_stdout, "\n"); 400} 401 402int 403main(int argc, char *argv[]) 404{ 405 char *CApath = NULL, *CAfile = NULL; 406 int badop = 0; 407 int bio_pair = 0; 408 int force = 0; 409 int tls1 = 0, tls1_2 = 0, dtls1 = 0, ret = 1; 410 int client_auth = 0; 411 int server_auth = 0, i; 412 struct app_verify_arg app_verify_arg = 413 { APP_CALLBACK_STRING, 0, 0, NULL, NULL }; 414 char *server_cert = TEST_SERVER_CERT; 415 char *server_key = NULL; 416 char *client_cert = TEST_CLIENT_CERT; 417 char *client_key = NULL; 418 char *named_curve = NULL; 419 SSL_CTX *s_ctx = NULL; 420 SSL_CTX *c_ctx = NULL; 421 const SSL_METHOD *meth = NULL; 422 SSL *c_ssl, *s_ssl; 423 int number = 1, reuse = 0; 424 long bytes = 256L; 425 DH *dh; 426 int dhe1024dsa = 0; 427 EC_KEY *ecdh = NULL; 428 int no_dhe = 0; 429 int no_ecdhe = 0; 430 int print_time = 0; 431 clock_t s_time = 0, c_time = 0; 432 433 verbose = 0; 434 debug = 0; 435 cipher = 0; 436 437 bio_err = BIO_new_fp(stderr, BIO_NOCLOSE|BIO_FP_TEXT); 438 439 bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE|BIO_FP_TEXT); 440 441 argc--; 442 argv++; 443 444 while (argc >= 1) { 445 if (!strcmp(*argv, "-F")) { 446 fprintf(stderr, "not compiled with FIPS support, so exiting without running.\n"); 447 exit(0); 448 } else if (strcmp(*argv, "-server_auth") == 0) 449 server_auth = 1; 450 else if (strcmp(*argv, "-client_auth") == 0) 451 client_auth = 1; 452 else if (strcmp(*argv, "-proxy_auth") == 0) { 453 if (--argc < 1) 454 goto bad; 455 app_verify_arg.proxy_auth= *(++argv); 456 } else if (strcmp(*argv, "-proxy_cond") == 0) { 457 if (--argc < 1) 458 goto bad; 459 app_verify_arg.proxy_cond= *(++argv); 460 } else if (strcmp(*argv, "-v") == 0) 461 verbose = 1; 462 else if (strcmp(*argv, "-d") == 0) 463 debug = 1; 464 else if (strcmp(*argv, "-reuse") == 0) 465 reuse = 1; 466 else if (strcmp(*argv, "-dhe1024dsa") == 0) { 467 dhe1024dsa = 1; 468 } else if (strcmp(*argv, "-no_dhe") == 0) 469 no_dhe = 1; 470 else if (strcmp(*argv, "-no_ecdhe") == 0) 471 no_ecdhe = 1; 472 else if (strcmp(*argv, "-dtls1") == 0) 473 dtls1 = 1; 474 else if (strcmp(*argv, "-tls1") == 0) 475 tls1 = 1; 476 else if (strcmp(*argv, "-tls1_2") == 0) 477 tls1_2 = 1; 478 else if (strncmp(*argv, "-num", 4) == 0) { 479 if (--argc < 1) 480 goto bad; 481 number = atoi(*(++argv)); 482 if (number == 0) 483 number = 1; 484 } else if (strcmp(*argv, "-bytes") == 0) { 485 if (--argc < 1) 486 goto bad; 487 bytes = atol(*(++argv)); 488 if (bytes == 0L) 489 bytes = 1L; 490 i = strlen(argv[0]); 491 if (argv[0][i - 1] == 'k') 492 bytes*=1024L; 493 if (argv[0][i - 1] == 'm') 494 bytes*=1024L*1024L; 495 } else if (strcmp(*argv, "-cert") == 0) { 496 if (--argc < 1) 497 goto bad; 498 server_cert= *(++argv); 499 } else if (strcmp(*argv, "-s_cert") == 0) { 500 if (--argc < 1) 501 goto bad; 502 server_cert= *(++argv); 503 } else if (strcmp(*argv, "-key") == 0) { 504 if (--argc < 1) 505 goto bad; 506 server_key= *(++argv); 507 } else if (strcmp(*argv, "-s_key") == 0) { 508 if (--argc < 1) 509 goto bad; 510 server_key= *(++argv); 511 } else if (strcmp(*argv, "-c_cert") == 0) { 512 if (--argc < 1) 513 goto bad; 514 client_cert= *(++argv); 515 } else if (strcmp(*argv, "-c_key") == 0) { 516 if (--argc < 1) 517 goto bad; 518 client_key= *(++argv); 519 } else if (strcmp(*argv, "-cipher") == 0) { 520 if (--argc < 1) 521 goto bad; 522 cipher= *(++argv); 523 } else if (strcmp(*argv, "-CApath") == 0) { 524 if (--argc < 1) 525 goto bad; 526 CApath= *(++argv); 527 } else if (strcmp(*argv, "-CAfile") == 0) { 528 if (--argc < 1) 529 goto bad; 530 CAfile= *(++argv); 531 } else if (strcmp(*argv, "-bio_pair") == 0) { 532 bio_pair = 1; 533 } else if (strcmp(*argv, "-f") == 0) { 534 force = 1; 535 } else if (strcmp(*argv, "-time") == 0) { 536 print_time = 1; 537 } else if (strcmp(*argv, "-named_curve") == 0) { 538 if (--argc < 1) 539 goto bad; 540 named_curve = *(++argv); 541 } else if (strcmp(*argv, "-app_verify") == 0) { 542 app_verify_arg.app_verify = 1; 543 } else if (strcmp(*argv, "-proxy") == 0) { 544 app_verify_arg.allow_proxy_certs = 1; 545 } else if (strcmp(*argv, "-alpn_client") == 0) { 546 if (--argc < 1) 547 goto bad; 548 alpn_client = *(++argv); 549 } else if (strcmp(*argv, "-alpn_server") == 0) { 550 if (--argc < 1) 551 goto bad; 552 alpn_server = *(++argv); 553 } else if (strcmp(*argv, "-alpn_expected") == 0) { 554 if (--argc < 1) 555 goto bad; 556 alpn_expected = *(++argv); 557 } else { 558 fprintf(stderr, "unknown option %s\n", *argv); 559 badop = 1; 560 break; 561 } 562 argc--; 563 argv++; 564 } 565 if (badop) { 566bad: 567 sv_usage(); 568 goto end; 569 } 570 571 if (!dtls1 && !tls1 && !tls1_2 && number > 1 && !reuse && !force) { 572 fprintf(stderr, 573 "This case cannot work. Use -f to perform " 574 "the test anyway (and\n-d to see what happens), " 575 "or add one of -dtls1, -tls1, -tls1_2, -reuse\n" 576 "to avoid protocol mismatch.\n"); 577 exit(1); 578 } 579 580 if (print_time) { 581 if (!bio_pair) { 582 fprintf(stderr, "Using BIO pair (-bio_pair)\n"); 583 bio_pair = 1; 584 } 585 if (number < 50 && !force) 586 fprintf(stderr, "Warning: For accurate timings, use more connections (e.g. -num 1000)\n"); 587 } 588 589/* if (cipher == NULL) cipher=getenv("SSL_CIPHER"); */ 590 591 SSL_library_init(); 592 SSL_load_error_strings(); 593 594 if (dtls1) 595 meth = DTLSv1_method(); 596 else if (tls1) 597 meth = TLSv1_method(); 598 else if (tls1_2) 599 meth = TLSv1_2_method(); 600 else 601 meth = TLS_method(); 602 603 c_ctx = SSL_CTX_new(meth); 604 s_ctx = SSL_CTX_new(meth); 605 if ((c_ctx == NULL) || (s_ctx == NULL)) { 606 ERR_print_errors(bio_err); 607 goto end; 608 } 609 610 if (cipher != NULL) { 611 SSL_CTX_set_cipher_list(c_ctx, cipher); 612 SSL_CTX_set_cipher_list(s_ctx, cipher); 613 } 614 615 if (!no_dhe) { 616 if (dhe1024dsa) { 617 /* use SSL_OP_SINGLE_DH_USE to avoid small subgroup attacks */ 618 SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); 619 dh = get_dh1024dsa(); 620 } else 621 dh = get_dh1024(); 622 SSL_CTX_set_tmp_dh(s_ctx, dh); 623 DH_free(dh); 624 } 625 626 if (!no_ecdhe) { 627 int nid; 628 629 if (named_curve != NULL) { 630 nid = OBJ_sn2nid(named_curve); 631 if (nid == 0) { 632 BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve); 633 goto end; 634 } 635 } else 636 nid = NID_X9_62_prime256v1; 637 638 ecdh = EC_KEY_new_by_curve_name(nid); 639 if (ecdh == NULL) { 640 BIO_printf(bio_err, "unable to create curve\n"); 641 goto end; 642 } 643 644 SSL_CTX_set_tmp_ecdh(s_ctx, ecdh); 645 SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_ECDH_USE); 646 EC_KEY_free(ecdh); 647 } 648 649 if (!SSL_CTX_use_certificate_file(s_ctx, server_cert, 650 SSL_FILETYPE_PEM)) { 651 ERR_print_errors(bio_err); 652 } else if (!SSL_CTX_use_PrivateKey_file(s_ctx, 653 (server_key ? server_key : server_cert), SSL_FILETYPE_PEM)) { 654 ERR_print_errors(bio_err); 655 goto end; 656 } 657 658 if (client_auth) { 659 SSL_CTX_use_certificate_file(c_ctx, client_cert, 660 SSL_FILETYPE_PEM); 661 SSL_CTX_use_PrivateKey_file(c_ctx, 662 (client_key ? client_key : client_cert), 663 SSL_FILETYPE_PEM); 664 } 665 666 if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || 667 (!SSL_CTX_set_default_verify_paths(s_ctx)) || 668 (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || 669 (!SSL_CTX_set_default_verify_paths(c_ctx))) { 670 /* fprintf(stderr,"SSL_load_verify_locations\n"); */ 671 ERR_print_errors(bio_err); 672 /* goto end; */ 673 } 674 675 if (client_auth) { 676 BIO_printf(bio_err, "client authentication\n"); 677 SSL_CTX_set_verify(s_ctx, 678 SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 679 verify_callback); 680 SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, 681 &app_verify_arg); 682 } 683 if (server_auth) { 684 BIO_printf(bio_err, "server authentication\n"); 685 SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, 686 verify_callback); 687 SSL_CTX_set_cert_verify_callback(c_ctx, app_verify_callback, 688 &app_verify_arg); 689 } 690 691 { 692 int session_id_context = 0; 693 SSL_CTX_set_session_id_context(s_ctx, 694 (void *)&session_id_context, sizeof(session_id_context)); 695 } 696 697 if (alpn_server != NULL) 698 SSL_CTX_set_alpn_select_cb(s_ctx, cb_server_alpn, NULL); 699 700 if (alpn_client != NULL) { 701 unsigned short alpn_len; 702 unsigned char *alpn = next_protos_parse(&alpn_len, alpn_client); 703 704 if (alpn == NULL) { 705 BIO_printf(bio_err, "Error parsing -alpn_client argument\n"); 706 goto end; 707 } 708 SSL_CTX_set_alpn_protos(c_ctx, alpn, alpn_len); 709 free(alpn); 710 } 711 712 c_ssl = SSL_new(c_ctx); 713 s_ssl = SSL_new(s_ctx); 714 715 for (i = 0; i < number; i++) { 716 if (!reuse) 717 SSL_set_session(c_ssl, NULL); 718 if (bio_pair) 719 ret = doit_biopair(s_ssl, c_ssl, bytes, &s_time, 720 &c_time); 721 else 722 ret = doit(s_ssl, c_ssl, bytes); 723 } 724 725 if (!verbose) { 726 print_details(c_ssl, ""); 727 } 728 if ((number > 1) || (bytes > 1L)) 729 BIO_printf(bio_stdout, "%d handshakes of %ld bytes done\n", 730 number, bytes); 731 if (print_time) { 732#ifdef CLOCKS_PER_SEC 733 /* "To determine the time in seconds, the value returned 734 * by the clock function should be divided by the value 735 * of the macro CLOCKS_PER_SEC." 736 * -- ISO/IEC 9899 */ 737 BIO_printf(bio_stdout, 738 "Approximate total server time: %6.2f s\n" 739 "Approximate total client time: %6.2f s\n", 740 (double)s_time/CLOCKS_PER_SEC, 741 (double)c_time/CLOCKS_PER_SEC); 742#else 743 /* "`CLOCKS_PER_SEC' undeclared (first use this function)" 744 * -- cc on NeXTstep/OpenStep */ 745 BIO_printf(bio_stdout, 746 "Approximate total server time: %6.2f units\n" 747 "Approximate total client time: %6.2f units\n", 748 (double)s_time, 749 (double)c_time); 750#endif 751 } 752 753 SSL_free(s_ssl); 754 SSL_free(c_ssl); 755 756end: 757 SSL_CTX_free(s_ctx); 758 SSL_CTX_free(c_ctx); 759 BIO_free(bio_stdout); 760 761#ifndef OPENSSL_NO_ENGINE 762 ENGINE_cleanup(); 763#endif 764 CRYPTO_cleanup_all_ex_data(); 765 ERR_free_strings(); 766 ERR_remove_thread_state(NULL); 767 EVP_cleanup(); 768 CRYPTO_mem_leaks(bio_err); 769 BIO_free(bio_err); 770 771 exit(ret); 772 return ret; 773} 774 775int 776doit_biopair(SSL *s_ssl, SSL *c_ssl, long count, clock_t *s_time, 777 clock_t *c_time) 778{ 779 long cw_num = count, cr_num = count, sw_num = count, sr_num = count; 780 BIO *s_ssl_bio = NULL, *c_ssl_bio = NULL; 781 BIO *server = NULL, *server_io = NULL; 782 BIO *client = NULL, *client_io = NULL; 783 int ret = 1; 784 785 size_t bufsiz = 256; /* small buffer for testing */ 786 787 if (!BIO_new_bio_pair(&server, bufsiz, &server_io, bufsiz)) 788 goto err; 789 if (!BIO_new_bio_pair(&client, bufsiz, &client_io, bufsiz)) 790 goto err; 791 792 s_ssl_bio = BIO_new(BIO_f_ssl()); 793 if (!s_ssl_bio) 794 goto err; 795 796 c_ssl_bio = BIO_new(BIO_f_ssl()); 797 if (!c_ssl_bio) 798 goto err; 799 800 SSL_set_connect_state(c_ssl); 801 SSL_set_bio(c_ssl, client, client); 802 (void)BIO_set_ssl(c_ssl_bio, c_ssl, BIO_NOCLOSE); 803 804 SSL_set_accept_state(s_ssl); 805 SSL_set_bio(s_ssl, server, server); 806 (void)BIO_set_ssl(s_ssl_bio, s_ssl, BIO_NOCLOSE); 807 808 do { 809 /* c_ssl_bio: SSL filter BIO 810 * 811 * client: pseudo-I/O for SSL library 812 * 813 * client_io: client's SSL communication; usually to be 814 * relayed over some I/O facility, but in this 815 * test program, we're the server, too: 816 * 817 * server_io: server's SSL communication 818 * 819 * server: pseudo-I/O for SSL library 820 * 821 * s_ssl_bio: SSL filter BIO 822 * 823 * The client and the server each employ a "BIO pair": 824 * client + client_io, server + server_io. 825 * BIO pairs are symmetric. A BIO pair behaves similar 826 * to a non-blocking socketpair (but both endpoints must 827 * be handled by the same thread). 828 * [Here we could connect client and server to the ends 829 * of a single BIO pair, but then this code would be less 830 * suitable as an example for BIO pairs in general.] 831 * 832 * Useful functions for querying the state of BIO pair endpoints: 833 * 834 * BIO_ctrl_pending(bio) number of bytes we can read now 835 * BIO_ctrl_get_read_request(bio) number of bytes needed to fulfil 836 * other side's read attempt 837 * BIO_ctrl_get_write_guarantee(bio) number of bytes we can write now 838 * 839 * ..._read_request is never more than ..._write_guarantee; 840 * it depends on the application which one you should use. 841 */ 842 843 /* We have non-blocking behaviour throughout this test program, but 844 * can be sure that there is *some* progress in each iteration; so 845 * we don't have to worry about ..._SHOULD_READ or ..._SHOULD_WRITE 846 * -- we just try everything in each iteration 847 */ 848 849 { 850 /* CLIENT */ 851 852 char cbuf[1024*8]; 853 int i, r; 854 clock_t c_clock = clock(); 855 856 memset(cbuf, 0, sizeof(cbuf)); 857 858 if (debug) 859 if (SSL_in_init(c_ssl)) 860 printf("client waiting in SSL_connect - %s\n", 861 SSL_state_string_long(c_ssl)); 862 863 if (cw_num > 0) { 864 /* Write to server. */ 865 866 if (cw_num > (long)sizeof cbuf) 867 i = sizeof cbuf; 868 else 869 i = (int)cw_num; 870 r = BIO_write(c_ssl_bio, cbuf, i); 871 if (r < 0) { 872 if (!BIO_should_retry(c_ssl_bio)) { 873 fprintf(stderr, "ERROR in CLIENT\n"); 874 goto err; 875 } 876 /* BIO_should_retry(...) can just be ignored here. 877 * The library expects us to call BIO_write with 878 * the same arguments again, and that's what we will 879 * do in the next iteration. */ 880 } else if (r == 0) { 881 fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 882 goto err; 883 } else { 884 if (debug) 885 printf("client wrote %d\n", r); 886 cw_num -= r; 887 888 } 889 } 890 891 if (cr_num > 0) { 892 /* Read from server. */ 893 894 r = BIO_read(c_ssl_bio, cbuf, sizeof(cbuf)); 895 if (r < 0) { 896 if (!BIO_should_retry(c_ssl_bio)) { 897 fprintf(stderr, "ERROR in CLIENT\n"); 898 goto err; 899 } 900 /* Again, "BIO_should_retry" can be ignored. */ 901 } else if (r == 0) { 902 fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 903 goto err; 904 } else { 905 if (debug) 906 printf("client read %d\n", r); 907 cr_num -= r; 908 } 909 } 910 911 /* c_time and s_time increments will typically be very small 912 * (depending on machine speed and clock tick intervals), 913 * but sampling over a large number of connections should 914 * result in fairly accurate figures. We cannot guarantee 915 * a lot, however -- if each connection lasts for exactly 916 * one clock tick, it will be counted only for the client 917 * or only for the server or even not at all. 918 */ 919 *c_time += (clock() - c_clock); 920 } 921 922 { 923 /* SERVER */ 924 925 char sbuf[1024*8]; 926 int i, r; 927 clock_t s_clock = clock(); 928 929 memset(sbuf, 0, sizeof(sbuf)); 930 931 if (debug) 932 if (SSL_in_init(s_ssl)) 933 printf("server waiting in SSL_accept - %s\n", 934 SSL_state_string_long(s_ssl)); 935 936 if (sw_num > 0) { 937 /* Write to client. */ 938 939 if (sw_num > (long)sizeof sbuf) 940 i = sizeof sbuf; 941 else 942 i = (int)sw_num; 943 r = BIO_write(s_ssl_bio, sbuf, i); 944 if (r < 0) { 945 if (!BIO_should_retry(s_ssl_bio)) { 946 fprintf(stderr, "ERROR in SERVER\n"); 947 goto err; 948 } 949 /* Ignore "BIO_should_retry". */ 950 } else if (r == 0) { 951 fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 952 goto err; 953 } else { 954 if (debug) 955 printf("server wrote %d\n", r); 956 sw_num -= r; 957 958 } 959 } 960 961 if (sr_num > 0) { 962 /* Read from client. */ 963 964 r = BIO_read(s_ssl_bio, sbuf, sizeof(sbuf)); 965 if (r < 0) { 966 if (!BIO_should_retry(s_ssl_bio)) { 967 fprintf(stderr, "ERROR in SERVER\n"); 968 goto err; 969 } 970 /* blah, blah */ 971 } else if (r == 0) { 972 fprintf(stderr, "SSL SERVER STARTUP FAILED\n"); 973 goto err; 974 } else { 975 if (debug) 976 printf("server read %d\n", r); 977 sr_num -= r; 978 } 979 } 980 981 *s_time += (clock() - s_clock); 982 } 983 984 { 985 /* "I/O" BETWEEN CLIENT AND SERVER. */ 986 987 size_t r1, r2; 988 BIO *io1 = server_io, *io2 = client_io; 989 /* we use the non-copying interface for io1 990 * and the standard BIO_write/BIO_read interface for io2 991 */ 992 993 static int prev_progress = 1; 994 int progress = 0; 995 996 /* io1 to io2 */ 997 do { 998 size_t num; 999 int r; 1000 1001 r1 = BIO_ctrl_pending(io1); 1002 r2 = BIO_ctrl_get_write_guarantee(io2); 1003 1004 num = r1; 1005 if (r2 < num) 1006 num = r2; 1007 if (num) { 1008 char *dataptr; 1009 1010 if (INT_MAX < num) /* yeah, right */ 1011 num = INT_MAX; 1012 1013 r = BIO_nread(io1, &dataptr, (int)num); 1014 assert(r > 0); 1015 assert(r <= (int)num); 1016 /* possibly r < num (non-contiguous data) */ 1017 num = r; 1018 r = BIO_write(io2, dataptr, (int)num); 1019 if (r != (int)num) /* can't happen */ 1020 { 1021 fprintf(stderr, "ERROR: BIO_write could not write " 1022 "BIO_ctrl_get_write_guarantee() bytes"); 1023 goto err; 1024 } 1025 progress = 1; 1026 1027 if (debug) 1028 printf((io1 == client_io) ? 1029 "C->S relaying: %d bytes\n" : 1030 "S->C relaying: %d bytes\n", 1031 (int)num); 1032 } 1033 } while (r1 && r2); 1034 1035 /* io2 to io1 */ 1036 { 1037 size_t num; 1038 int r; 1039 1040 r1 = BIO_ctrl_pending(io2); 1041 r2 = BIO_ctrl_get_read_request(io1); 1042 /* here we could use ..._get_write_guarantee instead of 1043 * ..._get_read_request, but by using the latter 1044 * we test restartability of the SSL implementation 1045 * more thoroughly */ 1046 num = r1; 1047 if (r2 < num) 1048 num = r2; 1049 if (num) { 1050 char *dataptr; 1051 1052 if (INT_MAX < num) 1053 num = INT_MAX; 1054 1055 if (num > 1) 1056 --num; /* test restartability even more thoroughly */ 1057 1058 r = BIO_nwrite0(io1, &dataptr); 1059 assert(r > 0); 1060 if (r < (int)num) 1061 num = r; 1062 r = BIO_read(io2, dataptr, (int)num); 1063 if (r != (int)num) /* can't happen */ 1064 { 1065 fprintf(stderr, "ERROR: BIO_read could not read " 1066 "BIO_ctrl_pending() bytes"); 1067 goto err; 1068 } 1069 progress = 1; 1070 r = BIO_nwrite(io1, &dataptr, (int)num); 1071 if (r != (int)num) /* can't happen */ 1072 { 1073 fprintf(stderr, "ERROR: BIO_nwrite() did not accept " 1074 "BIO_nwrite0() bytes"); 1075 goto err; 1076 } 1077 1078 if (debug) 1079 printf((io2 == client_io) ? 1080 "C->S relaying: %d bytes\n" : 1081 "S->C relaying: %d bytes\n", 1082 (int)num); 1083 } 1084 } /* no loop, BIO_ctrl_get_read_request now returns 0 anyway */ 1085 1086 if (!progress && !prev_progress) { 1087 if (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0) { 1088 fprintf(stderr, "ERROR: got stuck\n"); 1089 goto err; 1090 } 1091 } 1092 prev_progress = progress; 1093 } 1094 } while (cw_num > 0 || cr_num > 0 || sw_num > 0 || sr_num > 0); 1095 1096 if (verbose) 1097 print_details(c_ssl, "DONE via BIO pair: "); 1098 1099 if (verify_alpn(c_ssl, s_ssl) < 0) { 1100 ret = 1; 1101 goto err; 1102 } 1103 1104 ret = 0; 1105 1106err: 1107 ERR_print_errors(bio_err); 1108 1109 BIO_free(server); 1110 BIO_free(server_io); 1111 BIO_free(client); 1112 BIO_free(client_io); 1113 BIO_free(s_ssl_bio); 1114 BIO_free(c_ssl_bio); 1115 1116 return ret; 1117} 1118 1119 1120#define W_READ 1 1121#define W_WRITE 2 1122#define C_DONE 1 1123#define S_DONE 2 1124 1125int 1126doit(SSL *s_ssl, SSL *c_ssl, long count) 1127{ 1128 char cbuf[1024*8], sbuf[1024*8]; 1129 long cw_num = count, cr_num = count; 1130 long sw_num = count, sr_num = count; 1131 int ret = 1; 1132 BIO *c_to_s = NULL; 1133 BIO *s_to_c = NULL; 1134 BIO *c_bio = NULL; 1135 BIO *s_bio = NULL; 1136 int c_r, c_w, s_r, s_w; 1137 int i, j; 1138 int done = 0; 1139 int c_write, s_write; 1140 int do_server = 0, do_client = 0; 1141 1142 memset(cbuf, 0, sizeof(cbuf)); 1143 memset(sbuf, 0, sizeof(sbuf)); 1144 1145 c_to_s = BIO_new(BIO_s_mem()); 1146 s_to_c = BIO_new(BIO_s_mem()); 1147 if ((s_to_c == NULL) || (c_to_s == NULL)) { 1148 ERR_print_errors(bio_err); 1149 goto err; 1150 } 1151 1152 c_bio = BIO_new(BIO_f_ssl()); 1153 s_bio = BIO_new(BIO_f_ssl()); 1154 if ((c_bio == NULL) || (s_bio == NULL)) { 1155 ERR_print_errors(bio_err); 1156 goto err; 1157 } 1158 1159 SSL_set_connect_state(c_ssl); 1160 SSL_set_bio(c_ssl, s_to_c, c_to_s); 1161 BIO_set_ssl(c_bio, c_ssl, BIO_NOCLOSE); 1162 1163 SSL_set_accept_state(s_ssl); 1164 SSL_set_bio(s_ssl, c_to_s, s_to_c); 1165 BIO_set_ssl(s_bio, s_ssl, BIO_NOCLOSE); 1166 1167 c_r = 0; 1168 s_r = 1; 1169 c_w = 1; 1170 s_w = 0; 1171 c_write = 1, s_write = 0; 1172 1173 /* We can always do writes */ 1174 for (;;) { 1175 do_server = 0; 1176 do_client = 0; 1177 1178 i = (int)BIO_pending(s_bio); 1179 if ((i && s_r) || s_w) 1180 do_server = 1; 1181 1182 i = (int)BIO_pending(c_bio); 1183 if ((i && c_r) || c_w) 1184 do_client = 1; 1185 1186 if (do_server && debug) { 1187 if (SSL_in_init(s_ssl)) 1188 printf("server waiting in SSL_accept - %s\n", 1189 SSL_state_string_long(s_ssl)); 1190 } 1191 1192 if (do_client && debug) { 1193 if (SSL_in_init(c_ssl)) 1194 printf("client waiting in SSL_connect - %s\n", 1195 SSL_state_string_long(c_ssl)); 1196 } 1197 1198 if (!do_client && !do_server) { 1199 fprintf(stdout, "ERROR in STARTUP\n"); 1200 ERR_print_errors(bio_err); 1201 goto err; 1202 } 1203 1204 if (do_client && !(done & C_DONE)) { 1205 if (c_write) { 1206 j = (cw_num > (long)sizeof(cbuf)) ? 1207 (int)sizeof(cbuf) : (int)cw_num; 1208 i = BIO_write(c_bio, cbuf, j); 1209 if (i < 0) { 1210 c_r = 0; 1211 c_w = 0; 1212 if (BIO_should_retry(c_bio)) { 1213 if (BIO_should_read(c_bio)) 1214 c_r = 1; 1215 if (BIO_should_write(c_bio)) 1216 c_w = 1; 1217 } else { 1218 fprintf(stderr, "ERROR in CLIENT\n"); 1219 ERR_print_errors(bio_err); 1220 goto err; 1221 } 1222 } else if (i == 0) { 1223 fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1224 goto err; 1225 } else { 1226 if (debug) 1227 printf("client wrote %d\n", i); 1228 /* ok */ 1229 s_r = 1; 1230 c_write = 0; 1231 cw_num -= i; 1232 } 1233 } else { 1234 i = BIO_read(c_bio, cbuf, sizeof(cbuf)); 1235 if (i < 0) { 1236 c_r = 0; 1237 c_w = 0; 1238 if (BIO_should_retry(c_bio)) { 1239 if (BIO_should_read(c_bio)) 1240 c_r = 1; 1241 if (BIO_should_write(c_bio)) 1242 c_w = 1; 1243 } else { 1244 fprintf(stderr, "ERROR in CLIENT\n"); 1245 ERR_print_errors(bio_err); 1246 goto err; 1247 } 1248 } else if (i == 0) { 1249 fprintf(stderr, "SSL CLIENT STARTUP FAILED\n"); 1250 goto err; 1251 } else { 1252 if (debug) 1253 printf("client read %d\n", i); 1254 cr_num -= i; 1255 if (sw_num > 0) { 1256 s_write = 1; 1257 s_w = 1; 1258 } 1259 if (cr_num <= 0) { 1260 s_write = 1; 1261 s_w = 1; 1262 done = S_DONE|C_DONE; 1263 } 1264 } 1265 } 1266 } 1267 1268 if (do_server && !(done & S_DONE)) { 1269 if (!s_write) { 1270 i = BIO_read(s_bio, sbuf, sizeof(cbuf)); 1271 if (i < 0) { 1272 s_r = 0; 1273 s_w = 0; 1274 if (BIO_should_retry(s_bio)) { 1275 if (BIO_should_read(s_bio)) 1276 s_r = 1; 1277 if (BIO_should_write(s_bio)) 1278 s_w = 1; 1279 } else { 1280 fprintf(stderr, "ERROR in SERVER\n"); 1281 ERR_print_errors(bio_err); 1282 goto err; 1283 } 1284 } else if (i == 0) { 1285 ERR_print_errors(bio_err); 1286 fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_read\n"); 1287 goto err; 1288 } else { 1289 if (debug) 1290 printf("server read %d\n", i); 1291 sr_num -= i; 1292 if (cw_num > 0) { 1293 c_write = 1; 1294 c_w = 1; 1295 } 1296 if (sr_num <= 0) { 1297 s_write = 1; 1298 s_w = 1; 1299 c_write = 0; 1300 } 1301 } 1302 } else { 1303 j = (sw_num > (long)sizeof(sbuf)) ? 1304 (int)sizeof(sbuf) : (int)sw_num; 1305 i = BIO_write(s_bio, sbuf, j); 1306 if (i < 0) { 1307 s_r = 0; 1308 s_w = 0; 1309 if (BIO_should_retry(s_bio)) { 1310 if (BIO_should_read(s_bio)) 1311 s_r = 1; 1312 if (BIO_should_write(s_bio)) 1313 s_w = 1; 1314 } else { 1315 fprintf(stderr, "ERROR in SERVER\n"); 1316 ERR_print_errors(bio_err); 1317 goto err; 1318 } 1319 } else if (i == 0) { 1320 ERR_print_errors(bio_err); 1321 fprintf(stderr, "SSL SERVER STARTUP FAILED in SSL_write\n"); 1322 goto err; 1323 } else { 1324 if (debug) 1325 printf("server wrote %d\n", i); 1326 sw_num -= i; 1327 s_write = 0; 1328 c_r = 1; 1329 if (sw_num <= 0) 1330 done |= S_DONE; 1331 } 1332 } 1333 } 1334 1335 if ((done & S_DONE) && (done & C_DONE)) 1336 break; 1337 } 1338 1339 if (verbose) 1340 print_details(c_ssl, "DONE: "); 1341 1342 if (verify_alpn(c_ssl, s_ssl) < 0) { 1343 ret = 1; 1344 goto err; 1345 } 1346 1347 ret = 0; 1348err: 1349 /* We have to set the BIO's to NULL otherwise they will be 1350 * free()ed twice. Once when th s_ssl is SSL_free()ed and 1351 * again when c_ssl is SSL_free()ed. 1352 * This is a hack required because s_ssl and c_ssl are sharing the same 1353 * BIO structure and SSL_set_bio() and SSL_free() automatically 1354 * BIO_free non NULL entries. 1355 * You should not normally do this or be required to do this */ 1356 if (s_ssl != NULL) { 1357 s_ssl->rbio = NULL; 1358 s_ssl->wbio = NULL; 1359 } 1360 if (c_ssl != NULL) { 1361 c_ssl->rbio = NULL; 1362 c_ssl->wbio = NULL; 1363 } 1364 1365 BIO_free(c_to_s); 1366 BIO_free(s_to_c); 1367 BIO_free_all(c_bio); 1368 BIO_free_all(s_bio); 1369 1370 return (ret); 1371} 1372 1373static int 1374get_proxy_auth_ex_data_idx(void) 1375{ 1376 static volatile int idx = -1; 1377 if (idx < 0) { 1378 CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); 1379 if (idx < 0) { 1380 idx = X509_STORE_CTX_get_ex_new_index(0, 1381 "SSLtest for verify callback", NULL, NULL, NULL); 1382 } 1383 CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); 1384 } 1385 return idx; 1386} 1387 1388static int 1389verify_callback(int ok, X509_STORE_CTX *ctx) 1390{ 1391 char *s, buf[256]; 1392 1393 s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), buf, 1394 sizeof buf); 1395 if (s != NULL) { 1396 if (ok) 1397 fprintf(stderr, "depth=%d %s\n", 1398 ctx->error_depth, buf); 1399 else { 1400 fprintf(stderr, "depth=%d error=%d %s\n", 1401 ctx->error_depth, ctx->error, buf); 1402 } 1403 } 1404 1405 if (ok == 0) { 1406 fprintf(stderr, "Error string: %s\n", 1407 X509_verify_cert_error_string(ctx->error)); 1408 switch (ctx->error) { 1409 case X509_V_ERR_CERT_NOT_YET_VALID: 1410 case X509_V_ERR_CERT_HAS_EXPIRED: 1411 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: 1412 fprintf(stderr, " ... ignored.\n"); 1413 ok = 1; 1414 } 1415 } 1416 1417 if (ok == 1) { 1418 X509 *xs = ctx->current_cert; 1419#if 0 1420 X509 *xi = ctx->current_issuer; 1421#endif 1422 1423 if (xs->ex_flags & EXFLAG_PROXY) { 1424 unsigned int *letters = 1425 X509_STORE_CTX_get_ex_data(ctx, 1426 get_proxy_auth_ex_data_idx()); 1427 1428 if (letters) { 1429 int found_any = 0; 1430 int i; 1431 PROXY_CERT_INFO_EXTENSION *pci = 1432 X509_get_ext_d2i(xs, NID_proxyCertInfo, 1433 NULL, NULL); 1434 1435 switch (OBJ_obj2nid(pci->proxyPolicy->policyLanguage)) { 1436 case NID_Independent: 1437 /* Completely meaningless in this 1438 program, as there's no way to 1439 grant explicit rights to a 1440 specific PrC. Basically, using 1441 id-ppl-Independent is the perfect 1442 way to grant no rights at all. */ 1443 fprintf(stderr, " Independent proxy certificate"); 1444 for (i = 0; i < 26; i++) 1445 letters[i] = 0; 1446 break; 1447 case NID_id_ppl_inheritAll: 1448 /* This is basically a NOP, we 1449 simply let the current rights 1450 stand as they are. */ 1451 fprintf(stderr, " Proxy certificate inherits all"); 1452 break; 1453 default: 1454 s = (char *) 1455 pci->proxyPolicy->policy->data; 1456 i = pci->proxyPolicy->policy->length; 1457 1458 /* The algorithm works as follows: 1459 it is assumed that previous 1460 iterations or the initial granted 1461 rights has already set some elements 1462 of `letters'. What we need to do is 1463 to clear those that weren't granted 1464 by the current PrC as well. The 1465 easiest way to do this is to add 1 1466 to all the elements whose letters 1467 are given with the current policy. 1468 That way, all elements that are set 1469 by the current policy and were 1470 already set by earlier policies and 1471 through the original grant of rights 1472 will get the value 2 or higher. 1473 The last thing to do is to sweep 1474 through `letters' and keep the 1475 elements having the value 2 as set, 1476 and clear all the others. */ 1477 1478 fprintf(stderr, " Certificate proxy rights = %*.*s", i, i, s); 1479 while (i-- > 0) { 1480 int c = *s++; 1481 if (isascii(c) && isalpha(c)) { 1482 if (islower(c)) 1483 c = toupper(c); 1484 letters[c - 'A']++; 1485 } 1486 } 1487 for (i = 0; i < 26; i++) 1488 if (letters[i] < 2) 1489 letters[i] = 0; 1490 else 1491 letters[i] = 1; 1492 } 1493 1494 found_any = 0; 1495 fprintf(stderr, ", resulting proxy rights = "); 1496 for (i = 0; i < 26; i++) 1497 if (letters[i]) { 1498 fprintf(stderr, "%c", i + 'A'); 1499 found_any = 1; 1500 } 1501 if (!found_any) 1502 fprintf(stderr, "none"); 1503 fprintf(stderr, "\n"); 1504 1505 PROXY_CERT_INFO_EXTENSION_free(pci); 1506 } 1507 } 1508 } 1509 1510 return (ok); 1511} 1512 1513static void 1514process_proxy_debug(int indent, const char *format, ...) 1515{ 1516 static const char indentation[] = 1517 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 1518 ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; /* That's 80 > */ 1519 char my_format[256]; 1520 va_list args; 1521 1522 (void) snprintf(my_format, sizeof(my_format), "%*.*s %s", 1523 indent, indent, indentation, format); 1524 1525 va_start(args, format); 1526 vfprintf(stderr, my_format, args); 1527 va_end(args); 1528} 1529/* Priority levels: 1530 0 [!]var, () 1531 1 & ^ 1532 2 | 1533*/ 1534static int process_proxy_cond_adders(unsigned int letters[26], 1535 const char *cond, const char **cond_end, int *pos, int indent); 1536 1537static int 1538process_proxy_cond_val(unsigned int letters[26], const char *cond, 1539 const char **cond_end, int *pos, int indent) 1540{ 1541 int c; 1542 int ok = 1; 1543 int negate = 0; 1544 1545 while (isspace((int)*cond)) { 1546 cond++; 1547 (*pos)++; 1548 } 1549 c = *cond; 1550 1551 if (debug) 1552 process_proxy_debug(indent, 1553 "Start process_proxy_cond_val at position %d: %s\n", 1554 *pos, cond); 1555 1556 while (c == '!') { 1557 negate = !negate; 1558 cond++; 1559 (*pos)++; 1560 while (isspace((int)*cond)) { 1561 cond++; 1562 (*pos)++; 1563 } 1564 c = *cond; 1565 } 1566 1567 if (c == '(') { 1568 cond++; 1569 (*pos)++; 1570 ok = process_proxy_cond_adders(letters, cond, cond_end, pos, 1571 indent + 1); 1572 cond = *cond_end; 1573 if (ok < 0) 1574 goto end; 1575 while (isspace((int)*cond)) { 1576 cond++; 1577 (*pos)++; 1578 } 1579 c = *cond; 1580 if (c != ')') { 1581 fprintf(stderr, 1582 "Weird condition character in position %d: " 1583 "%c\n", *pos, c); 1584 ok = -1; 1585 goto end; 1586 } 1587 cond++; 1588 (*pos)++; 1589 } else if (isascii(c) && isalpha(c)) { 1590 if (islower(c)) 1591 c = toupper(c); 1592 ok = letters[c - 'A']; 1593 cond++; 1594 (*pos)++; 1595 } else { 1596 fprintf(stderr, 1597 "Weird condition character in position %d: " 1598 "%c\n", *pos, c); 1599 ok = -1; 1600 goto end; 1601 } 1602end: 1603 *cond_end = cond; 1604 if (ok >= 0 && negate) 1605 ok = !ok; 1606 1607 if (debug) 1608 process_proxy_debug(indent, 1609 "End process_proxy_cond_val at position %d: %s, returning %d\n", 1610 *pos, cond, ok); 1611 1612 return ok; 1613} 1614 1615static int 1616process_proxy_cond_multipliers(unsigned int letters[26], const char *cond, 1617 const char **cond_end, int *pos, int indent) 1618{ 1619 int ok; 1620 char c; 1621 1622 if (debug) 1623 process_proxy_debug(indent, 1624 "Start process_proxy_cond_multipliers at position %d: %s\n", 1625 *pos, cond); 1626 1627 ok = process_proxy_cond_val(letters, cond, cond_end, pos, indent + 1); 1628 cond = *cond_end; 1629 if (ok < 0) 1630 goto end; 1631 1632 while (ok >= 0) { 1633 while (isspace((int)*cond)) { 1634 cond++; 1635 (*pos)++; 1636 } 1637 c = *cond; 1638 1639 switch (c) { 1640 case '&': 1641 case '^': 1642 { 1643 int save_ok = ok; 1644 1645 cond++; 1646 (*pos)++; 1647 ok = process_proxy_cond_val(letters, 1648 cond, cond_end, pos, indent + 1); 1649 cond = *cond_end; 1650 if (ok < 0) 1651 break; 1652 1653 switch (c) { 1654 case '&': 1655 ok &= save_ok; 1656 break; 1657 case '^': 1658 ok ^= save_ok; 1659 break; 1660 default: 1661 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 1662 " STOPPING\n"); 1663 exit(1); 1664 } 1665 } 1666 break; 1667 default: 1668 goto end; 1669 } 1670 } 1671end: 1672 if (debug) 1673 process_proxy_debug(indent, 1674 "End process_proxy_cond_multipliers at position %d: %s, " 1675 "returning %d\n", 1676 *pos, cond, ok); 1677 1678 *cond_end = cond; 1679 return ok; 1680} 1681 1682static int 1683process_proxy_cond_adders(unsigned int letters[26], const char *cond, 1684 const char **cond_end, int *pos, int indent) 1685{ 1686 int ok; 1687 char c; 1688 1689 if (debug) 1690 process_proxy_debug(indent, 1691 "Start process_proxy_cond_adders at position %d: %s\n", 1692 *pos, cond); 1693 1694 ok = process_proxy_cond_multipliers(letters, cond, cond_end, pos, 1695 indent + 1); 1696 cond = *cond_end; 1697 if (ok < 0) 1698 goto end; 1699 1700 while (ok >= 0) { 1701 while (isspace((int)*cond)) { 1702 cond++; 1703 (*pos)++; 1704 } 1705 c = *cond; 1706 1707 switch (c) { 1708 case '|': 1709 { 1710 int save_ok = ok; 1711 1712 cond++; 1713 (*pos)++; 1714 ok = process_proxy_cond_multipliers(letters, 1715 cond, cond_end, pos, indent + 1); 1716 cond = *cond_end; 1717 if (ok < 0) 1718 break; 1719 1720 switch (c) { 1721 case '|': 1722 ok |= save_ok; 1723 break; 1724 default: 1725 fprintf(stderr, "SOMETHING IS SERIOUSLY WRONG!" 1726 " STOPPING\n"); 1727 exit(1); 1728 } 1729 } 1730 break; 1731 default: 1732 goto end; 1733 } 1734 } 1735end: 1736 if (debug) 1737 process_proxy_debug(indent, 1738 "End process_proxy_cond_adders at position %d: %s, returning %d\n", 1739 *pos, cond, ok); 1740 1741 *cond_end = cond; 1742 return ok; 1743} 1744 1745static int 1746process_proxy_cond(unsigned int letters[26], const char *cond, 1747 const char **cond_end) 1748{ 1749 int pos = 1; 1750 return process_proxy_cond_adders(letters, cond, cond_end, &pos, 1); 1751} 1752 1753static int 1754app_verify_callback(X509_STORE_CTX *ctx, void *arg) 1755{ 1756 int ok = 1; 1757 struct app_verify_arg *cb_arg = arg; 1758 unsigned int letters[26]; /* only used with proxy_auth */ 1759 1760 if (cb_arg->app_verify) { 1761 char *s = NULL, buf[256]; 1762 1763 fprintf(stderr, "In app_verify_callback, allowing cert. "); 1764 fprintf(stderr, "Arg is: %s\n", cb_arg->string); 1765 fprintf(stderr, "Finished printing do we have a context? 0x%p a cert? 0x%p\n", 1766 (void *)ctx, (void *)ctx->cert); 1767 if (ctx->cert) 1768 s = X509_NAME_oneline(X509_get_subject_name(ctx->cert), buf, 256); 1769 if (s != NULL) { 1770 fprintf(stderr, "cert depth=%d %s\n", ctx->error_depth, buf); 1771 } 1772 return (1); 1773 } 1774 if (cb_arg->proxy_auth) { 1775 int found_any = 0, i; 1776 char *sp; 1777 1778 for (i = 0; i < 26; i++) 1779 letters[i] = 0; 1780 for (sp = cb_arg->proxy_auth; *sp; sp++) { 1781 int c = *sp; 1782 if (isascii(c) && isalpha(c)) { 1783 if (islower(c)) 1784 c = toupper(c); 1785 letters[c - 'A'] = 1; 1786 } 1787 } 1788 1789 fprintf(stderr, " Initial proxy rights = "); 1790 for (i = 0; i < 26; i++) 1791 if (letters[i]) { 1792 fprintf(stderr, "%c", i + 'A'); 1793 found_any = 1; 1794 } 1795 if (!found_any) 1796 fprintf(stderr, "none"); 1797 fprintf(stderr, "\n"); 1798 1799 X509_STORE_CTX_set_ex_data(ctx, 1800 get_proxy_auth_ex_data_idx(), letters); 1801 } 1802 if (cb_arg->allow_proxy_certs) { 1803 X509_STORE_CTX_set_flags(ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); 1804 } 1805 1806 ok = X509_verify_cert(ctx); 1807 1808 if (cb_arg->proxy_auth) { 1809 if (ok > 0) { 1810 const char *cond_end = NULL; 1811 1812 ok = process_proxy_cond(letters, 1813 cb_arg->proxy_cond, &cond_end); 1814 1815 if (ok < 0) 1816 exit(3); 1817 if (*cond_end) { 1818 fprintf(stderr, "Stopped processing condition before it's end.\n"); 1819 ok = 0; 1820 } 1821 if (!ok) 1822 fprintf(stderr, "Proxy rights check with condition '%s' proved invalid\n", 1823 cb_arg->proxy_cond); 1824 else 1825 fprintf(stderr, "Proxy rights check with condition '%s' proved valid\n", 1826 cb_arg->proxy_cond); 1827 } 1828 } 1829 return (ok); 1830} 1831 1832/* These DH parameters have been generated as follows: 1833 * $ openssl dhparam -C -noout 1024 1834 * $ openssl dhparam -C -noout -dsaparam 1024 1835 * (The second function has been renamed to avoid name conflicts.) 1836 */ 1837static DH * 1838get_dh1024() 1839{ 1840 static unsigned char dh1024_p[] = { 1841 0xF8, 0x81, 0x89, 0x7D, 0x14, 0x24, 0xC5, 0xD1, 0xE6, 0xF7, 0xBF, 0x3A, 1842 0xE4, 0x90, 0xF4, 0xFC, 0x73, 0xFB, 0x34, 0xB5, 0xFA, 0x4C, 0x56, 0xA2, 1843 0xEA, 0xA7, 0xE9, 0xC0, 0xC0, 0xCE, 0x89, 0xE1, 0xFA, 0x63, 0x3F, 0xB0, 1844 0x6B, 0x32, 0x66, 0xF1, 0xD1, 0x7B, 0xB0, 0x00, 0x8F, 0xCA, 0x87, 0xC2, 1845 0xAE, 0x98, 0x89, 0x26, 0x17, 0xC2, 0x05, 0xD2, 0xEC, 0x08, 0xD0, 0x8C, 1846 0xFF, 0x17, 0x52, 0x8C, 0xC5, 0x07, 0x93, 0x03, 0xB1, 0xF6, 0x2F, 0xB8, 1847 0x1C, 0x52, 0x47, 0x27, 0x1B, 0xDB, 0xD1, 0x8D, 0x9D, 0x69, 0x1D, 0x52, 1848 0x4B, 0x32, 0x81, 0xAA, 0x7F, 0x00, 0xC8, 0xDC, 0xE6, 0xD9, 0xCC, 0xC1, 1849 0x11, 0x2D, 0x37, 0x34, 0x6C, 0xEA, 0x02, 0x97, 0x4B, 0x0E, 0xBB, 0xB1, 1850 0x71, 0x33, 0x09, 0x15, 0xFD, 0xDD, 0x23, 0x87, 0x07, 0x5E, 0x89, 0xAB, 1851 0x6B, 0x7C, 0x5F, 0xEC, 0xA6, 0x24, 0xDC, 0x53, 1852 }; 1853 static unsigned char dh1024_g[] = { 1854 0x02, 1855 }; 1856 DH *dh; 1857 1858 if ((dh = DH_new()) == NULL) 1859 return (NULL); 1860 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 1861 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 1862 if ((dh->p == NULL) || (dh->g == NULL)) { 1863 DH_free(dh); 1864 return (NULL); 1865 } 1866 return (dh); 1867} 1868 1869static DH * 1870get_dh1024dsa() 1871{ 1872 static unsigned char dh1024_p[] = { 1873 0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 0x00, 1874 0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 0x19, 1875 0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 0xD2, 1876 0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 0x55, 1877 0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 0xFC, 1878 0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 0x97, 1879 0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 0x8D, 1880 0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 0xBB, 1881 0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 0xF6, 1882 0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 0x9E, 1883 0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39, 1884 }; 1885 static unsigned char dh1024_g[] = { 1886 0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 0x05, 1887 0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 0xF3, 1888 0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 0xE9, 1889 0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 0x3C, 1890 0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 0x65, 1891 0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 0x60, 1892 0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 0xF6, 1893 0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 0xA7, 1894 0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 0xA1, 1895 0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 0x60, 1896 0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2, 1897 }; 1898 DH *dh; 1899 1900 if ((dh = DH_new()) == NULL) 1901 return (NULL); 1902 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); 1903 dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); 1904 if ((dh->p == NULL) || (dh->g == NULL)) { 1905 DH_free(dh); 1906 return (NULL); 1907 } 1908 dh->length = 160; 1909 return (dh); 1910} 1911