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