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