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