1 /* $OpenBSD: s_cb.c,v 1.5 2015/09/10 06:36:45 bcook Exp $ */ 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-2006 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 #include <sys/socket.h> 113 114 #include <netinet/in.h> 115 116 #include <netdb.h> 117 #include <stdio.h> 118 #include <stdlib.h> 119 #include <string.h> 120 121 #include "apps.h" 122 123 #include <openssl/err.h> 124 #include <openssl/ssl.h> 125 #include <openssl/x509.h> 126 127 #include "s_apps.h" 128 129 #define COOKIE_SECRET_LENGTH 16 130 131 int verify_depth = 0; 132 int verify_return_error = 0; 133 unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; 134 int cookie_initialized = 0; 135 136 int 137 verify_callback(int ok, X509_STORE_CTX * ctx) 138 { 139 X509 *err_cert; 140 int err, depth; 141 142 err_cert = X509_STORE_CTX_get_current_cert(ctx); 143 err = X509_STORE_CTX_get_error(ctx); 144 depth = X509_STORE_CTX_get_error_depth(ctx); 145 146 BIO_printf(bio_err, "depth=%d ", depth); 147 if (err_cert) { 148 X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), 149 0, XN_FLAG_ONELINE); 150 BIO_puts(bio_err, "\n"); 151 } else 152 BIO_puts(bio_err, "<no cert>\n"); 153 if (!ok) { 154 BIO_printf(bio_err, "verify error:num=%d:%s\n", err, 155 X509_verify_cert_error_string(err)); 156 if (verify_depth >= depth) { 157 if (!verify_return_error) 158 ok = 1; 159 } else { 160 ok = 0; 161 } 162 } 163 switch (err) { 164 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 165 BIO_puts(bio_err, "issuer= "); 166 if (err_cert == NULL) 167 BIO_puts(bio_err, "<error getting cert>"); 168 else 169 X509_NAME_print_ex(bio_err, 170 X509_get_issuer_name(err_cert), 0, XN_FLAG_ONELINE); 171 BIO_puts(bio_err, "\n"); 172 break; 173 case X509_V_ERR_CERT_NOT_YET_VALID: 174 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 175 BIO_printf(bio_err, "notBefore="); 176 if (err_cert == NULL) 177 BIO_printf(bio_err, " <error getting cert>"); 178 else 179 ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert)); 180 BIO_printf(bio_err, "\n"); 181 break; 182 case X509_V_ERR_CERT_HAS_EXPIRED: 183 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 184 BIO_printf(bio_err, "notAfter="); 185 if (err_cert == NULL) 186 BIO_printf(bio_err, " <error getting cert>"); 187 else 188 ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert)); 189 BIO_printf(bio_err, "\n"); 190 break; 191 case X509_V_ERR_NO_EXPLICIT_POLICY: 192 policies_print(bio_err, ctx); 193 break; 194 } 195 if (err == X509_V_OK && ok == 2) 196 policies_print(bio_err, ctx); 197 198 BIO_printf(bio_err, "verify return:%d\n", ok); 199 return (ok); 200 } 201 202 int 203 set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file) 204 { 205 if (cert_file != NULL) { 206 /* 207 SSL *ssl; 208 X509 *x509; 209 */ 210 211 if (SSL_CTX_use_certificate_file(ctx, cert_file, 212 SSL_FILETYPE_PEM) <= 0) { 213 BIO_printf(bio_err, 214 "unable to get certificate from '%s'\n", cert_file); 215 ERR_print_errors(bio_err); 216 return (0); 217 } 218 if (key_file == NULL) 219 key_file = cert_file; 220 if (SSL_CTX_use_PrivateKey_file(ctx, key_file, 221 SSL_FILETYPE_PEM) <= 0) { 222 BIO_printf(bio_err, 223 "unable to get private key from '%s'\n", key_file); 224 ERR_print_errors(bio_err); 225 return (0); 226 } 227 /* 228 In theory this is no longer needed 229 ssl=SSL_new(ctx); 230 x509=SSL_get_certificate(ssl); 231 232 if (x509 != NULL) { 233 EVP_PKEY *pktmp; 234 pktmp = X509_get_pubkey(x509); 235 EVP_PKEY_copy_parameters(pktmp, 236 SSL_get_privatekey(ssl)); 237 EVP_PKEY_free(pktmp); 238 } 239 SSL_free(ssl); 240 */ 241 242 /* 243 * If we are using DSA, we can copy the parameters from the 244 * private key 245 */ 246 247 248 /* 249 * Now we know that a key and cert have been set against the 250 * SSL context 251 */ 252 if (!SSL_CTX_check_private_key(ctx)) { 253 BIO_printf(bio_err, 254 "Private key does not match the certificate public key\n"); 255 return (0); 256 } 257 } 258 return (1); 259 } 260 261 int 262 set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key) 263 { 264 if (cert == NULL) 265 return 1; 266 if (SSL_CTX_use_certificate(ctx, cert) <= 0) { 267 BIO_printf(bio_err, "error setting certificate\n"); 268 ERR_print_errors(bio_err); 269 return 0; 270 } 271 if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) { 272 BIO_printf(bio_err, "error setting private key\n"); 273 ERR_print_errors(bio_err); 274 return 0; 275 } 276 /* 277 * Now we know that a key and cert have been set against the SSL 278 * context 279 */ 280 if (!SSL_CTX_check_private_key(ctx)) { 281 BIO_printf(bio_err, 282 "Private key does not match the certificate public key\n"); 283 return 0; 284 } 285 return 1; 286 } 287 288 long 289 bio_dump_callback(BIO * bio, int cmd, const char *argp, 290 int argi, long argl, long ret) 291 { 292 BIO *out; 293 294 out = (BIO *) BIO_get_callback_arg(bio); 295 if (out == NULL) 296 return (ret); 297 298 if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { 299 BIO_printf(out, 300 "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", 301 (void *) bio, argp, (unsigned long) argi, ret, ret); 302 BIO_dump(out, argp, (int) ret); 303 return (ret); 304 } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { 305 BIO_printf(out, 306 "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", 307 (void *) bio, argp, (unsigned long) argi, ret, ret); 308 BIO_dump(out, argp, (int) ret); 309 } 310 return (ret); 311 } 312 313 void 314 apps_ssl_info_callback(const SSL * s, int where, int ret) 315 { 316 const char *str; 317 int w; 318 319 w = where & ~SSL_ST_MASK; 320 321 if (w & SSL_ST_CONNECT) 322 str = "SSL_connect"; 323 else if (w & SSL_ST_ACCEPT) 324 str = "SSL_accept"; 325 else 326 str = "undefined"; 327 328 if (where & SSL_CB_LOOP) { 329 BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s)); 330 } else if (where & SSL_CB_ALERT) { 331 str = (where & SSL_CB_READ) ? "read" : "write"; 332 BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str, 333 SSL_alert_type_string_long(ret), 334 SSL_alert_desc_string_long(ret)); 335 } else if (where & SSL_CB_EXIT) { 336 if (ret == 0) 337 BIO_printf(bio_err, "%s:failed in %s\n", 338 str, SSL_state_string_long(s)); 339 else if (ret < 0) { 340 BIO_printf(bio_err, "%s:error in %s\n", 341 str, SSL_state_string_long(s)); 342 } 343 } 344 } 345 346 347 void 348 msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg) 349 { 350 BIO *bio = arg; 351 const char *str_write_p, *str_version, *str_content_type = "", 352 *str_details1 = "", *str_details2 = ""; 353 354 str_write_p = write_p ? ">>>" : "<<<"; 355 356 switch (version) { 357 case SSL2_VERSION: 358 str_version = "SSL 2.0"; 359 break; 360 case SSL3_VERSION: 361 str_version = "SSL 3.0 "; 362 break; 363 case TLS1_VERSION: 364 str_version = "TLS 1.0 "; 365 break; 366 case TLS1_1_VERSION: 367 str_version = "TLS 1.1 "; 368 break; 369 case TLS1_2_VERSION: 370 str_version = "TLS 1.2 "; 371 break; 372 case DTLS1_VERSION: 373 str_version = "DTLS 1.0 "; 374 break; 375 default: 376 str_version = "???"; 377 } 378 379 if (version == SSL2_VERSION) { 380 str_details1 = "???"; 381 382 if (len > 0) { 383 switch (((const unsigned char *) buf)[0]) { 384 case 0: 385 str_details1 = ", ERROR:"; 386 str_details2 = " ???"; 387 if (len >= 3) { 388 unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2]; 389 390 switch (err) { 391 case 0x0001: 392 str_details2 = " NO-CIPHER-ERROR"; 393 break; 394 case 0x0002: 395 str_details2 = " NO-CERTIFICATE-ERROR"; 396 break; 397 case 0x0004: 398 str_details2 = " BAD-CERTIFICATE-ERROR"; 399 break; 400 case 0x0006: 401 str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; 402 break; 403 } 404 } 405 break; 406 case 1: 407 str_details1 = ", CLIENT-HELLO"; 408 break; 409 case 2: 410 str_details1 = ", CLIENT-MASTER-KEY"; 411 break; 412 case 3: 413 str_details1 = ", CLIENT-FINISHED"; 414 break; 415 case 4: 416 str_details1 = ", SERVER-HELLO"; 417 break; 418 case 5: 419 str_details1 = ", SERVER-VERIFY"; 420 break; 421 case 6: 422 str_details1 = ", SERVER-FINISHED"; 423 break; 424 case 7: 425 str_details1 = ", REQUEST-CERTIFICATE"; 426 break; 427 case 8: 428 str_details1 = ", CLIENT-CERTIFICATE"; 429 break; 430 } 431 } 432 } 433 if (version == SSL3_VERSION || version == TLS1_VERSION || 434 version == TLS1_1_VERSION || version == TLS1_2_VERSION || 435 version == DTLS1_VERSION) { 436 switch (content_type) { 437 case 20: 438 str_content_type = "ChangeCipherSpec"; 439 break; 440 case 21: 441 str_content_type = "Alert"; 442 break; 443 case 22: 444 str_content_type = "Handshake"; 445 break; 446 } 447 448 if (content_type == 21) { /* Alert */ 449 str_details1 = ", ???"; 450 451 if (len == 2) { 452 switch (((const unsigned char *) buf)[0]) { 453 case 1: 454 str_details1 = ", warning"; 455 break; 456 case 2: 457 str_details1 = ", fatal"; 458 break; 459 } 460 461 str_details2 = " ???"; 462 switch (((const unsigned char *) buf)[1]) { 463 case 0: 464 str_details2 = " close_notify"; 465 break; 466 case 10: 467 str_details2 = " unexpected_message"; 468 break; 469 case 20: 470 str_details2 = " bad_record_mac"; 471 break; 472 case 21: 473 str_details2 = " decryption_failed"; 474 break; 475 case 22: 476 str_details2 = " record_overflow"; 477 break; 478 case 30: 479 str_details2 = " decompression_failure"; 480 break; 481 case 40: 482 str_details2 = " handshake_failure"; 483 break; 484 case 42: 485 str_details2 = " bad_certificate"; 486 break; 487 case 43: 488 str_details2 = " unsupported_certificate"; 489 break; 490 case 44: 491 str_details2 = " certificate_revoked"; 492 break; 493 case 45: 494 str_details2 = " certificate_expired"; 495 break; 496 case 46: 497 str_details2 = " certificate_unknown"; 498 break; 499 case 47: 500 str_details2 = " illegal_parameter"; 501 break; 502 case 48: 503 str_details2 = " unknown_ca"; 504 break; 505 case 49: 506 str_details2 = " access_denied"; 507 break; 508 case 50: 509 str_details2 = " decode_error"; 510 break; 511 case 51: 512 str_details2 = " decrypt_error"; 513 break; 514 case 60: 515 str_details2 = " export_restriction"; 516 break; 517 case 70: 518 str_details2 = " protocol_version"; 519 break; 520 case 71: 521 str_details2 = " insufficient_security"; 522 break; 523 case 80: 524 str_details2 = " internal_error"; 525 break; 526 case 90: 527 str_details2 = " user_canceled"; 528 break; 529 case 100: 530 str_details2 = " no_renegotiation"; 531 break; 532 case 110: 533 str_details2 = " unsupported_extension"; 534 break; 535 case 111: 536 str_details2 = " certificate_unobtainable"; 537 break; 538 case 112: 539 str_details2 = " unrecognized_name"; 540 break; 541 case 113: 542 str_details2 = " bad_certificate_status_response"; 543 break; 544 case 114: 545 str_details2 = " bad_certificate_hash_value"; 546 break; 547 case 115: 548 str_details2 = " unknown_psk_identity"; 549 break; 550 } 551 } 552 } 553 if (content_type == 22) { /* Handshake */ 554 str_details1 = "???"; 555 556 if (len > 0) { 557 switch (((const unsigned char *) buf)[0]) { 558 case 0: 559 str_details1 = ", HelloRequest"; 560 break; 561 case 1: 562 str_details1 = ", ClientHello"; 563 break; 564 case 2: 565 str_details1 = ", ServerHello"; 566 break; 567 case 3: 568 str_details1 = ", HelloVerifyRequest"; 569 break; 570 case 11: 571 str_details1 = ", Certificate"; 572 break; 573 case 12: 574 str_details1 = ", ServerKeyExchange"; 575 break; 576 case 13: 577 str_details1 = ", CertificateRequest"; 578 break; 579 case 14: 580 str_details1 = ", ServerHelloDone"; 581 break; 582 case 15: 583 str_details1 = ", CertificateVerify"; 584 break; 585 case 16: 586 str_details1 = ", ClientKeyExchange"; 587 break; 588 case 20: 589 str_details1 = ", Finished"; 590 break; 591 } 592 } 593 } 594 } 595 BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, 596 str_version, str_content_type, (unsigned long) len, 597 str_details1, str_details2); 598 599 if (len > 0) { 600 size_t num, i; 601 602 BIO_printf(bio, " "); 603 num = len; 604 605 for (i = 0; i < num; i++) { 606 if (i % 16 == 0 && i > 0) 607 BIO_printf(bio, "\n "); 608 BIO_printf(bio, " %02x", 609 ((const unsigned char *) buf)[i]); 610 } 611 if (i < len) 612 BIO_printf(bio, " ..."); 613 BIO_printf(bio, "\n"); 614 } 615 (void) BIO_flush(bio); 616 } 617 618 void 619 tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len, 620 void *arg) 621 { 622 BIO *bio = arg; 623 char *extname; 624 625 switch (type) { 626 case TLSEXT_TYPE_server_name: 627 extname = "server name"; 628 break; 629 630 case TLSEXT_TYPE_max_fragment_length: 631 extname = "max fragment length"; 632 break; 633 634 case TLSEXT_TYPE_client_certificate_url: 635 extname = "client certificate URL"; 636 break; 637 638 case TLSEXT_TYPE_trusted_ca_keys: 639 extname = "trusted CA keys"; 640 break; 641 642 case TLSEXT_TYPE_truncated_hmac: 643 extname = "truncated HMAC"; 644 break; 645 646 case TLSEXT_TYPE_status_request: 647 extname = "status request"; 648 break; 649 650 case TLSEXT_TYPE_user_mapping: 651 extname = "user mapping"; 652 break; 653 654 case TLSEXT_TYPE_client_authz: 655 extname = "client authz"; 656 break; 657 658 case TLSEXT_TYPE_server_authz: 659 extname = "server authz"; 660 break; 661 662 case TLSEXT_TYPE_cert_type: 663 extname = "cert type"; 664 break; 665 666 case TLSEXT_TYPE_elliptic_curves: 667 extname = "elliptic curves"; 668 break; 669 670 case TLSEXT_TYPE_ec_point_formats: 671 extname = "EC point formats"; 672 break; 673 674 case TLSEXT_TYPE_srp: 675 extname = "SRP"; 676 break; 677 678 case TLSEXT_TYPE_signature_algorithms: 679 extname = "signature algorithms"; 680 break; 681 682 case TLSEXT_TYPE_use_srtp: 683 extname = "use SRTP"; 684 break; 685 686 case TLSEXT_TYPE_heartbeat: 687 extname = "heartbeat"; 688 break; 689 690 case TLSEXT_TYPE_session_ticket: 691 extname = "session ticket"; 692 break; 693 694 case TLSEXT_TYPE_renegotiate: 695 extname = "renegotiation info"; 696 break; 697 698 #ifdef TLSEXT_TYPE_next_proto_neg 699 case TLSEXT_TYPE_next_proto_neg: 700 extname = "next protocol"; 701 break; 702 #endif 703 704 default: 705 extname = "unknown"; 706 break; 707 708 } 709 710 BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", 711 client_server ? "server" : "client", extname, type, len); 712 BIO_dump(bio, (char *) data, len); 713 (void) BIO_flush(bio); 714 } 715 716 int 717 generate_cookie_callback(SSL * ssl, unsigned char *cookie, 718 unsigned int *cookie_len) 719 { 720 unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 721 unsigned int length, resultlength; 722 union { 723 struct sockaddr sa; 724 struct sockaddr_in s4; 725 struct sockaddr_in6 s6; 726 } peer; 727 728 /* Initialize a random secret */ 729 if (!cookie_initialized) { 730 arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH); 731 cookie_initialized = 1; 732 } 733 /* Read peer information */ 734 (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 735 736 /* Create buffer with peer's address and port */ 737 length = 0; 738 switch (peer.sa.sa_family) { 739 case AF_INET: 740 length += sizeof(struct in_addr); 741 length += sizeof(peer.s4.sin_port); 742 break; 743 case AF_INET6: 744 length += sizeof(struct in6_addr); 745 length += sizeof(peer.s6.sin6_port); 746 break; 747 default: 748 OPENSSL_assert(0); 749 break; 750 } 751 buffer = malloc(length); 752 753 if (buffer == NULL) { 754 BIO_printf(bio_err, "out of memory\n"); 755 return 0; 756 } 757 switch (peer.sa.sa_family) { 758 case AF_INET: 759 memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); 760 memcpy(buffer + sizeof(peer.s4.sin_port), 761 &peer.s4.sin_addr, sizeof(struct in_addr)); 762 break; 763 case AF_INET6: 764 memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); 765 memcpy(buffer + sizeof(peer.s6.sin6_port), 766 &peer.s6.sin6_addr, sizeof(struct in6_addr)); 767 break; 768 default: 769 OPENSSL_assert(0); 770 break; 771 } 772 773 /* Calculate HMAC of buffer using the secret */ 774 HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 775 buffer, length, result, &resultlength); 776 free(buffer); 777 778 memcpy(cookie, result, resultlength); 779 *cookie_len = resultlength; 780 781 return 1; 782 } 783 784 int 785 verify_cookie_callback(SSL * ssl, unsigned char *cookie, unsigned int cookie_len) 786 { 787 unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 788 unsigned int length, resultlength; 789 union { 790 struct sockaddr sa; 791 struct sockaddr_in s4; 792 struct sockaddr_in6 s6; 793 } peer; 794 795 /* If secret isn't initialized yet, the cookie can't be valid */ 796 if (!cookie_initialized) 797 return 0; 798 799 /* Read peer information */ 800 (void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 801 802 /* Create buffer with peer's address and port */ 803 length = 0; 804 switch (peer.sa.sa_family) { 805 case AF_INET: 806 length += sizeof(struct in_addr); 807 length += sizeof(peer.s4.sin_port); 808 break; 809 case AF_INET6: 810 length += sizeof(struct in6_addr); 811 length += sizeof(peer.s6.sin6_port); 812 break; 813 default: 814 OPENSSL_assert(0); 815 break; 816 } 817 buffer = malloc(length); 818 819 if (buffer == NULL) { 820 BIO_printf(bio_err, "out of memory\n"); 821 return 0; 822 } 823 switch (peer.sa.sa_family) { 824 case AF_INET: 825 memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); 826 memcpy(buffer + sizeof(peer.s4.sin_port), 827 &peer.s4.sin_addr, sizeof(struct in_addr)); 828 break; 829 case AF_INET6: 830 memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); 831 memcpy(buffer + sizeof(peer.s6.sin6_port), 832 &peer.s6.sin6_addr, sizeof(struct in6_addr)); 833 break; 834 default: 835 OPENSSL_assert(0); 836 break; 837 } 838 839 /* Calculate HMAC of buffer using the secret */ 840 HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 841 buffer, length, result, &resultlength); 842 free(buffer); 843 844 if (cookie_len == resultlength && 845 memcmp(result, cookie, resultlength) == 0) 846 return 1; 847 848 return 0; 849 } 850