159191Skris/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280304Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280304Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280304Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280304Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280304Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280304Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 58109998Smarkm/* ==================================================================== 59238405Sjkim * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. 60109998Smarkm * 61109998Smarkm * Redistribution and use in source and binary forms, with or without 62109998Smarkm * modification, are permitted provided that the following conditions 63109998Smarkm * are met: 64109998Smarkm * 65109998Smarkm * 1. Redistributions of source code must retain the above copyright 66280304Sjkim * notice, this list of conditions and the following disclaimer. 67109998Smarkm * 68109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 69109998Smarkm * notice, this list of conditions and the following disclaimer in 70109998Smarkm * the documentation and/or other materials provided with the 71109998Smarkm * distribution. 72109998Smarkm * 73109998Smarkm * 3. All advertising materials mentioning features or use of this 74109998Smarkm * software must display the following acknowledgment: 75109998Smarkm * "This product includes software developed by the OpenSSL Project 76109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77109998Smarkm * 78109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79109998Smarkm * endorse or promote products derived from this software without 80109998Smarkm * prior written permission. For written permission, please contact 81109998Smarkm * openssl-core@openssl.org. 82109998Smarkm * 83109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 84109998Smarkm * nor may "OpenSSL" appear in their names without prior written 85109998Smarkm * permission of the OpenSSL Project. 86109998Smarkm * 87109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 88109998Smarkm * acknowledgment: 89109998Smarkm * "This product includes software developed by the OpenSSL Project 90109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91109998Smarkm * 92109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 104109998Smarkm * ==================================================================== 105109998Smarkm * 106109998Smarkm * This product includes cryptographic software written by Eric Young 107109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 108109998Smarkm * Hudson (tjh@cryptsoft.com). 109109998Smarkm * 110109998Smarkm */ 11155714Skris 11255714Skris#include <stdio.h> 11355714Skris#include <stdlib.h> 114284285Sjkim#include <string.h> /* for memcpy() */ 11555714Skris#define USE_SOCKETS 11655714Skris#define NON_MAIN 11755714Skris#include "apps.h" 11855714Skris#undef NON_MAIN 11955714Skris#undef USE_SOCKETS 12055714Skris#include <openssl/err.h> 121205128Ssimon#include <openssl/rand.h> 12255714Skris#include <openssl/x509.h> 12355714Skris#include <openssl/ssl.h> 12455714Skris#include "s_apps.h" 12555714Skris 126280304Sjkim#define COOKIE_SECRET_LENGTH 16 127205128Ssimon 128280304Sjkimint verify_depth = 0; 129280304Sjkimint verify_error = X509_V_OK; 130280304Sjkimint verify_return_error = 0; 131205128Ssimonunsigned char cookie_secret[COOKIE_SECRET_LENGTH]; 132280304Sjkimint cookie_initialized = 0; 13355714Skris 13455714Skrisint MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 135280304Sjkim{ 136280304Sjkim X509 *err_cert; 137280304Sjkim int err, depth; 13855714Skris 139280304Sjkim err_cert = X509_STORE_CTX_get_current_cert(ctx); 140280304Sjkim err = X509_STORE_CTX_get_error(ctx); 141280304Sjkim depth = X509_STORE_CTX_get_error_depth(ctx); 14255714Skris 143280304Sjkim BIO_printf(bio_err, "depth=%d ", depth); 144280304Sjkim if (err_cert) { 145280304Sjkim X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), 146280304Sjkim 0, XN_FLAG_ONELINE); 147280304Sjkim BIO_puts(bio_err, "\n"); 148280304Sjkim } else 149280304Sjkim BIO_puts(bio_err, "<no cert>\n"); 150280304Sjkim if (!ok) { 151280304Sjkim BIO_printf(bio_err, "verify error:num=%d:%s\n", err, 152280304Sjkim X509_verify_cert_error_string(err)); 153280304Sjkim if (verify_depth >= depth) { 154280304Sjkim if (!verify_return_error) 155280304Sjkim ok = 1; 156280304Sjkim verify_error = X509_V_OK; 157280304Sjkim } else { 158280304Sjkim ok = 0; 159280304Sjkim verify_error = X509_V_ERR_CERT_CHAIN_TOO_LONG; 160280304Sjkim } 161280304Sjkim } 162280304Sjkim switch (err) { 163280304Sjkim case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 164280304Sjkim BIO_puts(bio_err, "issuer= "); 165280304Sjkim X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), 166280304Sjkim 0, XN_FLAG_ONELINE); 167280304Sjkim BIO_puts(bio_err, "\n"); 168280304Sjkim break; 169280304Sjkim case X509_V_ERR_CERT_NOT_YET_VALID: 170280304Sjkim case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 171280304Sjkim BIO_printf(bio_err, "notBefore="); 172280304Sjkim ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert)); 173280304Sjkim BIO_printf(bio_err, "\n"); 174280304Sjkim break; 175280304Sjkim case X509_V_ERR_CERT_HAS_EXPIRED: 176280304Sjkim case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 177280304Sjkim BIO_printf(bio_err, "notAfter="); 178280304Sjkim ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert)); 179280304Sjkim BIO_printf(bio_err, "\n"); 180280304Sjkim break; 181280304Sjkim case X509_V_ERR_NO_EXPLICIT_POLICY: 182280304Sjkim policies_print(bio_err, ctx); 183280304Sjkim break; 184280304Sjkim } 185280304Sjkim if (err == X509_V_OK && ok == 2) 186280304Sjkim policies_print(bio_err, ctx); 187238405Sjkim 188280304Sjkim BIO_printf(bio_err, "verify return:%d\n", ok); 189280304Sjkim return (ok); 190280304Sjkim} 19155714Skris 19255714Skrisint set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) 193280304Sjkim{ 194280304Sjkim if (cert_file != NULL) { 195280304Sjkim /*- 196280304Sjkim SSL *ssl; 197280304Sjkim X509 *x509; 198280304Sjkim */ 19955714Skris 200280304Sjkim if (SSL_CTX_use_certificate_file(ctx, cert_file, 201280304Sjkim SSL_FILETYPE_PEM) <= 0) { 202280304Sjkim BIO_printf(bio_err, "unable to get certificate from '%s'\n", 203280304Sjkim cert_file); 204280304Sjkim ERR_print_errors(bio_err); 205280304Sjkim return (0); 206280304Sjkim } 207280304Sjkim if (key_file == NULL) 208280304Sjkim key_file = cert_file; 209280304Sjkim if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) { 210280304Sjkim BIO_printf(bio_err, "unable to get private key from '%s'\n", 211280304Sjkim key_file); 212280304Sjkim ERR_print_errors(bio_err); 213280304Sjkim return (0); 214280304Sjkim } 21555714Skris 216280304Sjkim /*- 217280304Sjkim In theory this is no longer needed 218280304Sjkim ssl=SSL_new(ctx); 219280304Sjkim x509=SSL_get_certificate(ssl); 22055714Skris 221280304Sjkim if (x509 != NULL) { 222280304Sjkim EVP_PKEY *pktmp; 223280304Sjkim pktmp = X509_get_pubkey(x509); 224280304Sjkim EVP_PKEY_copy_parameters(pktmp, 225280304Sjkim SSL_get_privatekey(ssl)); 226280304Sjkim EVP_PKEY_free(pktmp); 227280304Sjkim } 228280304Sjkim SSL_free(ssl); 229280304Sjkim */ 23055714Skris 231280304Sjkim /* 232280304Sjkim * If we are using DSA, we can copy the parameters from the private 233280304Sjkim * key 234280304Sjkim */ 235246772Sjkim 236280304Sjkim /* 237280304Sjkim * Now we know that a key and cert have been set against the SSL 238280304Sjkim * context 239280304Sjkim */ 240280304Sjkim if (!SSL_CTX_check_private_key(ctx)) { 241280304Sjkim BIO_printf(bio_err, 242280304Sjkim "Private key does not match the certificate public key\n"); 243280304Sjkim return (0); 244280304Sjkim } 245280304Sjkim } 246280304Sjkim return (1); 247280304Sjkim} 248246772Sjkim 249160814Ssimonint set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key) 250280304Sjkim{ 251280304Sjkim if (cert == NULL) 252280304Sjkim return 1; 253280304Sjkim if (SSL_CTX_use_certificate(ctx, cert) <= 0) { 254280304Sjkim BIO_printf(bio_err, "error setting certificate\n"); 255280304Sjkim ERR_print_errors(bio_err); 256280304Sjkim return 0; 257280304Sjkim } 258280304Sjkim if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) { 259280304Sjkim BIO_printf(bio_err, "error setting private key\n"); 260280304Sjkim ERR_print_errors(bio_err); 261280304Sjkim return 0; 262280304Sjkim } 263160814Ssimon 264280304Sjkim /* 265280304Sjkim * Now we know that a key and cert have been set against the SSL context 266280304Sjkim */ 267280304Sjkim if (!SSL_CTX_check_private_key(ctx)) { 268280304Sjkim BIO_printf(bio_err, 269280304Sjkim "Private key does not match the certificate public key\n"); 270280304Sjkim return 0; 271280304Sjkim } 272280304Sjkim return 1; 273280304Sjkim} 274160814Ssimon 275160814Ssimonlong MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, 276280304Sjkim int argi, long argl, long ret) 277280304Sjkim{ 278280304Sjkim BIO *out; 27955714Skris 280280304Sjkim out = (BIO *)BIO_get_callback_arg(bio); 281280304Sjkim if (out == NULL) 282280304Sjkim return (ret); 28355714Skris 284280304Sjkim if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) { 285280304Sjkim BIO_printf(out, "read from %p [%p] (%lu bytes => %ld (0x%lX))\n", 286280304Sjkim (void *)bio, argp, (unsigned long)argi, ret, ret); 287280304Sjkim BIO_dump(out, argp, (int)ret); 288280304Sjkim return (ret); 289280304Sjkim } else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) { 290280304Sjkim BIO_printf(out, "write to %p [%p] (%lu bytes => %ld (0x%lX))\n", 291280304Sjkim (void *)bio, argp, (unsigned long)argi, ret, ret); 292280304Sjkim BIO_dump(out, argp, (int)ret); 293280304Sjkim } 294280304Sjkim return (ret); 295280304Sjkim} 29655714Skris 297109998Smarkmvoid MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret) 298280304Sjkim{ 299280304Sjkim const char *str; 300280304Sjkim int w; 30155714Skris 302280304Sjkim w = where & ~SSL_ST_MASK; 30355714Skris 304280304Sjkim if (w & SSL_ST_CONNECT) 305280304Sjkim str = "SSL_connect"; 306280304Sjkim else if (w & SSL_ST_ACCEPT) 307280304Sjkim str = "SSL_accept"; 308280304Sjkim else 309280304Sjkim str = "undefined"; 31055714Skris 311280304Sjkim if (where & SSL_CB_LOOP) { 312280304Sjkim BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s)); 313280304Sjkim } else if (where & SSL_CB_ALERT) { 314280304Sjkim str = (where & SSL_CB_READ) ? "read" : "write"; 315280304Sjkim BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", 316280304Sjkim str, 317280304Sjkim SSL_alert_type_string_long(ret), 318280304Sjkim SSL_alert_desc_string_long(ret)); 319280304Sjkim } else if (where & SSL_CB_EXIT) { 320280304Sjkim if (ret == 0) 321280304Sjkim BIO_printf(bio_err, "%s:failed in %s\n", 322280304Sjkim str, SSL_state_string_long(s)); 323280304Sjkim else if (ret < 0) { 324280304Sjkim BIO_printf(bio_err, "%s:error in %s\n", 325280304Sjkim str, SSL_state_string_long(s)); 326280304Sjkim } 327280304Sjkim } 328280304Sjkim} 32955714Skris 330280304Sjkimvoid MS_CALLBACK msg_cb(int write_p, int version, int content_type, 331280304Sjkim const void *buf, size_t len, SSL *ssl, void *arg) 332280304Sjkim{ 333280304Sjkim BIO *bio = arg; 334280304Sjkim const char *str_write_p, *str_version, *str_content_type = 335280304Sjkim "", *str_details1 = "", *str_details2 = ""; 336109998Smarkm 337280304Sjkim str_write_p = write_p ? ">>>" : "<<<"; 338109998Smarkm 339280304Sjkim switch (version) { 340280304Sjkim case SSL2_VERSION: 341280304Sjkim str_version = "SSL 2.0"; 342280304Sjkim break; 343280304Sjkim case SSL3_VERSION: 344280304Sjkim str_version = "SSL 3.0 "; 345280304Sjkim break; 346280304Sjkim case TLS1_VERSION: 347280304Sjkim str_version = "TLS 1.0 "; 348280304Sjkim break; 349280304Sjkim case TLS1_1_VERSION: 350280304Sjkim str_version = "TLS 1.1 "; 351280304Sjkim break; 352280304Sjkim case TLS1_2_VERSION: 353280304Sjkim str_version = "TLS 1.2 "; 354280304Sjkim break; 355280304Sjkim case DTLS1_VERSION: 356280304Sjkim str_version = "DTLS 1.0 "; 357280304Sjkim break; 358280304Sjkim case DTLS1_BAD_VER: 359280304Sjkim str_version = "DTLS 1.0 (bad) "; 360280304Sjkim break; 361280304Sjkim default: 362280304Sjkim str_version = "???"; 363280304Sjkim } 364109998Smarkm 365280304Sjkim if (version == SSL2_VERSION) { 366280304Sjkim str_details1 = "???"; 367109998Smarkm 368280304Sjkim if (len > 0) { 369280304Sjkim switch (((const unsigned char *)buf)[0]) { 370280304Sjkim case 0: 371280304Sjkim str_details1 = ", ERROR:"; 372280304Sjkim str_details2 = " ???"; 373280304Sjkim if (len >= 3) { 374280304Sjkim unsigned err = 375280304Sjkim (((const unsigned char *)buf)[1] << 8) + 376280304Sjkim ((const unsigned char *)buf)[2]; 377109998Smarkm 378280304Sjkim switch (err) { 379280304Sjkim case 0x0001: 380280304Sjkim str_details2 = " NO-CIPHER-ERROR"; 381280304Sjkim break; 382280304Sjkim case 0x0002: 383280304Sjkim str_details2 = " NO-CERTIFICATE-ERROR"; 384280304Sjkim break; 385280304Sjkim case 0x0004: 386280304Sjkim str_details2 = " BAD-CERTIFICATE-ERROR"; 387280304Sjkim break; 388280304Sjkim case 0x0006: 389280304Sjkim str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; 390280304Sjkim break; 391280304Sjkim } 392280304Sjkim } 393109998Smarkm 394280304Sjkim break; 395280304Sjkim case 1: 396280304Sjkim str_details1 = ", CLIENT-HELLO"; 397280304Sjkim break; 398280304Sjkim case 2: 399280304Sjkim str_details1 = ", CLIENT-MASTER-KEY"; 400280304Sjkim break; 401280304Sjkim case 3: 402280304Sjkim str_details1 = ", CLIENT-FINISHED"; 403280304Sjkim break; 404280304Sjkim case 4: 405280304Sjkim str_details1 = ", SERVER-HELLO"; 406280304Sjkim break; 407280304Sjkim case 5: 408280304Sjkim str_details1 = ", SERVER-VERIFY"; 409280304Sjkim break; 410280304Sjkim case 6: 411280304Sjkim str_details1 = ", SERVER-FINISHED"; 412280304Sjkim break; 413280304Sjkim case 7: 414280304Sjkim str_details1 = ", REQUEST-CERTIFICATE"; 415280304Sjkim break; 416280304Sjkim case 8: 417280304Sjkim str_details1 = ", CLIENT-CERTIFICATE"; 418280304Sjkim break; 419280304Sjkim } 420280304Sjkim } 421280304Sjkim } 422109998Smarkm 423280304Sjkim if (version == SSL3_VERSION || 424280304Sjkim version == TLS1_VERSION || 425280304Sjkim version == TLS1_1_VERSION || 426280304Sjkim version == TLS1_2_VERSION || 427280304Sjkim version == DTLS1_VERSION || version == DTLS1_BAD_VER) { 428280304Sjkim switch (content_type) { 429280304Sjkim case 20: 430280304Sjkim str_content_type = "ChangeCipherSpec"; 431280304Sjkim break; 432280304Sjkim case 21: 433280304Sjkim str_content_type = "Alert"; 434280304Sjkim break; 435280304Sjkim case 22: 436280304Sjkim str_content_type = "Handshake"; 437280304Sjkim break; 438280304Sjkim } 439109998Smarkm 440280304Sjkim if (content_type == 21) { /* Alert */ 441280304Sjkim str_details1 = ", ???"; 442109998Smarkm 443280304Sjkim if (len == 2) { 444280304Sjkim switch (((const unsigned char *)buf)[0]) { 445280304Sjkim case 1: 446280304Sjkim str_details1 = ", warning"; 447280304Sjkim break; 448280304Sjkim case 2: 449280304Sjkim str_details1 = ", fatal"; 450280304Sjkim break; 451280304Sjkim } 452238405Sjkim 453280304Sjkim str_details2 = " ???"; 454280304Sjkim switch (((const unsigned char *)buf)[1]) { 455280304Sjkim case 0: 456280304Sjkim str_details2 = " close_notify"; 457280304Sjkim break; 458280304Sjkim case 10: 459280304Sjkim str_details2 = " unexpected_message"; 460280304Sjkim break; 461280304Sjkim case 20: 462280304Sjkim str_details2 = " bad_record_mac"; 463280304Sjkim break; 464280304Sjkim case 21: 465280304Sjkim str_details2 = " decryption_failed"; 466280304Sjkim break; 467280304Sjkim case 22: 468280304Sjkim str_details2 = " record_overflow"; 469280304Sjkim break; 470280304Sjkim case 30: 471280304Sjkim str_details2 = " decompression_failure"; 472280304Sjkim break; 473280304Sjkim case 40: 474280304Sjkim str_details2 = " handshake_failure"; 475280304Sjkim break; 476280304Sjkim case 42: 477280304Sjkim str_details2 = " bad_certificate"; 478280304Sjkim break; 479280304Sjkim case 43: 480280304Sjkim str_details2 = " unsupported_certificate"; 481280304Sjkim break; 482280304Sjkim case 44: 483280304Sjkim str_details2 = " certificate_revoked"; 484280304Sjkim break; 485280304Sjkim case 45: 486280304Sjkim str_details2 = " certificate_expired"; 487280304Sjkim break; 488280304Sjkim case 46: 489280304Sjkim str_details2 = " certificate_unknown"; 490280304Sjkim break; 491280304Sjkim case 47: 492280304Sjkim str_details2 = " illegal_parameter"; 493280304Sjkim break; 494280304Sjkim case 48: 495280304Sjkim str_details2 = " unknown_ca"; 496280304Sjkim break; 497280304Sjkim case 49: 498280304Sjkim str_details2 = " access_denied"; 499280304Sjkim break; 500280304Sjkim case 50: 501280304Sjkim str_details2 = " decode_error"; 502280304Sjkim break; 503280304Sjkim case 51: 504280304Sjkim str_details2 = " decrypt_error"; 505280304Sjkim break; 506280304Sjkim case 60: 507280304Sjkim str_details2 = " export_restriction"; 508280304Sjkim break; 509280304Sjkim case 70: 510280304Sjkim str_details2 = " protocol_version"; 511280304Sjkim break; 512280304Sjkim case 71: 513280304Sjkim str_details2 = " insufficient_security"; 514280304Sjkim break; 515280304Sjkim case 80: 516280304Sjkim str_details2 = " internal_error"; 517280304Sjkim break; 518280304Sjkim case 90: 519280304Sjkim str_details2 = " user_canceled"; 520280304Sjkim break; 521280304Sjkim case 100: 522280304Sjkim str_details2 = " no_renegotiation"; 523280304Sjkim break; 524280304Sjkim case 110: 525280304Sjkim str_details2 = " unsupported_extension"; 526280304Sjkim break; 527280304Sjkim case 111: 528280304Sjkim str_details2 = " certificate_unobtainable"; 529280304Sjkim break; 530280304Sjkim case 112: 531280304Sjkim str_details2 = " unrecognized_name"; 532280304Sjkim break; 533280304Sjkim case 113: 534280304Sjkim str_details2 = " bad_certificate_status_response"; 535280304Sjkim break; 536280304Sjkim case 114: 537280304Sjkim str_details2 = " bad_certificate_hash_value"; 538280304Sjkim break; 539280304Sjkim case 115: 540280304Sjkim str_details2 = " unknown_psk_identity"; 541280304Sjkim break; 542280304Sjkim } 543280304Sjkim } 544280304Sjkim } 545280304Sjkim 546280304Sjkim if (content_type == 22) { /* Handshake */ 547280304Sjkim str_details1 = "???"; 548280304Sjkim 549280304Sjkim if (len > 0) { 550280304Sjkim switch (((const unsigned char *)buf)[0]) { 551280304Sjkim case 0: 552280304Sjkim str_details1 = ", HelloRequest"; 553280304Sjkim break; 554280304Sjkim case 1: 555280304Sjkim str_details1 = ", ClientHello"; 556280304Sjkim break; 557280304Sjkim case 2: 558280304Sjkim str_details1 = ", ServerHello"; 559280304Sjkim break; 560280304Sjkim case 3: 561280304Sjkim str_details1 = ", HelloVerifyRequest"; 562280304Sjkim break; 563280304Sjkim case 11: 564280304Sjkim str_details1 = ", Certificate"; 565280304Sjkim break; 566280304Sjkim case 12: 567280304Sjkim str_details1 = ", ServerKeyExchange"; 568280304Sjkim break; 569280304Sjkim case 13: 570280304Sjkim str_details1 = ", CertificateRequest"; 571280304Sjkim break; 572280304Sjkim case 14: 573280304Sjkim str_details1 = ", ServerHelloDone"; 574280304Sjkim break; 575280304Sjkim case 15: 576280304Sjkim str_details1 = ", CertificateVerify"; 577280304Sjkim break; 578280304Sjkim case 16: 579280304Sjkim str_details1 = ", ClientKeyExchange"; 580280304Sjkim break; 581280304Sjkim case 20: 582280304Sjkim str_details1 = ", Finished"; 583280304Sjkim break; 584280304Sjkim } 585280304Sjkim } 586280304Sjkim } 587238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 588280304Sjkim if (content_type == 24) { /* Heartbeat */ 589280304Sjkim str_details1 = ", Heartbeat"; 590280304Sjkim 591280304Sjkim if (len > 0) { 592280304Sjkim switch (((const unsigned char *)buf)[0]) { 593280304Sjkim case 1: 594280304Sjkim str_details1 = ", HeartbeatRequest"; 595280304Sjkim break; 596280304Sjkim case 2: 597280304Sjkim str_details1 = ", HeartbeatResponse"; 598280304Sjkim break; 599280304Sjkim } 600280304Sjkim } 601280304Sjkim } 602238405Sjkim#endif 603280304Sjkim } 604109998Smarkm 605280304Sjkim BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p, str_version, 606280304Sjkim str_content_type, (unsigned long)len, str_details1, 607280304Sjkim str_details2); 608109998Smarkm 609280304Sjkim if (len > 0) { 610280304Sjkim size_t num, i; 611280304Sjkim 612280304Sjkim BIO_printf(bio, " "); 613280304Sjkim num = len; 614109998Smarkm#if 0 615280304Sjkim if (num > 16) 616280304Sjkim num = 16; 617109998Smarkm#endif 618280304Sjkim for (i = 0; i < num; i++) { 619280304Sjkim if (i % 16 == 0 && i > 0) 620280304Sjkim BIO_printf(bio, "\n "); 621280304Sjkim BIO_printf(bio, " %02x", ((const unsigned char *)buf)[i]); 622280304Sjkim } 623280304Sjkim if (i < len) 624280304Sjkim BIO_printf(bio, " ..."); 625280304Sjkim BIO_printf(bio, "\n"); 626280304Sjkim } 627280304Sjkim (void)BIO_flush(bio); 628280304Sjkim} 629194206Ssimon 630194206Ssimonvoid MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, 631280304Sjkim unsigned char *data, int len, void *arg) 632280304Sjkim{ 633280304Sjkim BIO *bio = arg; 634280304Sjkim char *extname; 635194206Ssimon 636280304Sjkim switch (type) { 637280304Sjkim case TLSEXT_TYPE_server_name: 638280304Sjkim extname = "server name"; 639280304Sjkim break; 640194206Ssimon 641280304Sjkim case TLSEXT_TYPE_max_fragment_length: 642280304Sjkim extname = "max fragment length"; 643280304Sjkim break; 644194206Ssimon 645280304Sjkim case TLSEXT_TYPE_client_certificate_url: 646280304Sjkim extname = "client certificate URL"; 647280304Sjkim break; 648194206Ssimon 649280304Sjkim case TLSEXT_TYPE_trusted_ca_keys: 650280304Sjkim extname = "trusted CA keys"; 651280304Sjkim break; 652194206Ssimon 653280304Sjkim case TLSEXT_TYPE_truncated_hmac: 654280304Sjkim extname = "truncated HMAC"; 655280304Sjkim break; 656194206Ssimon 657280304Sjkim case TLSEXT_TYPE_status_request: 658280304Sjkim extname = "status request"; 659280304Sjkim break; 660194206Ssimon 661280304Sjkim case TLSEXT_TYPE_user_mapping: 662280304Sjkim extname = "user mapping"; 663280304Sjkim break; 664238405Sjkim 665280304Sjkim case TLSEXT_TYPE_client_authz: 666280304Sjkim extname = "client authz"; 667280304Sjkim break; 668238405Sjkim 669280304Sjkim case TLSEXT_TYPE_server_authz: 670280304Sjkim extname = "server authz"; 671280304Sjkim break; 672238405Sjkim 673280304Sjkim case TLSEXT_TYPE_cert_type: 674280304Sjkim extname = "cert type"; 675280304Sjkim break; 676238405Sjkim 677280304Sjkim case TLSEXT_TYPE_elliptic_curves: 678280304Sjkim extname = "elliptic curves"; 679280304Sjkim break; 680194206Ssimon 681280304Sjkim case TLSEXT_TYPE_ec_point_formats: 682280304Sjkim extname = "EC point formats"; 683280304Sjkim break; 684194206Ssimon 685280304Sjkim case TLSEXT_TYPE_srp: 686280304Sjkim extname = "SRP"; 687280304Sjkim break; 688238405Sjkim 689280304Sjkim case TLSEXT_TYPE_signature_algorithms: 690280304Sjkim extname = "signature algorithms"; 691280304Sjkim break; 692238405Sjkim 693280304Sjkim case TLSEXT_TYPE_use_srtp: 694280304Sjkim extname = "use SRTP"; 695280304Sjkim break; 696238405Sjkim 697280304Sjkim case TLSEXT_TYPE_heartbeat: 698280304Sjkim extname = "heartbeat"; 699280304Sjkim break; 700238405Sjkim 701280304Sjkim case TLSEXT_TYPE_session_ticket: 702280304Sjkim extname = "session ticket"; 703280304Sjkim break; 704194206Ssimon 705280304Sjkim case TLSEXT_TYPE_renegotiate: 706280304Sjkim extname = "renegotiation info"; 707280304Sjkim break; 708194206Ssimon 709238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 710280304Sjkim case TLSEXT_TYPE_opaque_prf_input: 711280304Sjkim extname = "opaque PRF input"; 712280304Sjkim break; 713238405Sjkim#endif 714238405Sjkim#ifdef TLSEXT_TYPE_next_proto_neg 715280304Sjkim case TLSEXT_TYPE_next_proto_neg: 716280304Sjkim extname = "next protocol"; 717280304Sjkim break; 718238405Sjkim#endif 719238405Sjkim 720280304Sjkim case TLSEXT_TYPE_padding: 721280304Sjkim extname = "TLS padding"; 722280304Sjkim break; 723267258Sjkim 724280304Sjkim default: 725280304Sjkim extname = "unknown"; 726280304Sjkim break; 727194206Ssimon 728280304Sjkim } 729205128Ssimon 730280304Sjkim BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", 731280304Sjkim client_server ? "server" : "client", extname, type, len); 732280304Sjkim BIO_dump(bio, (char *)data, len); 733280304Sjkim (void)BIO_flush(bio); 734280304Sjkim} 735280304Sjkim 736280304Sjkimint MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, 737280304Sjkim unsigned int *cookie_len) 738280304Sjkim{ 739280304Sjkim unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 740280304Sjkim unsigned int length, resultlength; 741280304Sjkim union { 742280304Sjkim struct sockaddr sa; 743280304Sjkim struct sockaddr_in s4; 744238405Sjkim#if OPENSSL_USE_IPV6 745280304Sjkim struct sockaddr_in6 s6; 746238405Sjkim#endif 747280304Sjkim } peer; 748238405Sjkim 749280304Sjkim /* Initialize a random secret */ 750280304Sjkim if (!cookie_initialized) { 751284285Sjkim if (RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH) <= 0) { 752280304Sjkim BIO_printf(bio_err, "error setting random cookie secret\n"); 753280304Sjkim return 0; 754280304Sjkim } 755280304Sjkim cookie_initialized = 1; 756280304Sjkim } 757205128Ssimon 758280304Sjkim /* Read peer information */ 759280304Sjkim (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 760205128Ssimon 761280304Sjkim /* Create buffer with peer's address and port */ 762280304Sjkim length = 0; 763280304Sjkim switch (peer.sa.sa_family) { 764280304Sjkim case AF_INET: 765280304Sjkim length += sizeof(struct in_addr); 766280304Sjkim length += sizeof(peer.s4.sin_port); 767280304Sjkim break; 768238405Sjkim#if OPENSSL_USE_IPV6 769280304Sjkim case AF_INET6: 770280304Sjkim length += sizeof(struct in6_addr); 771280304Sjkim length += sizeof(peer.s6.sin6_port); 772280304Sjkim break; 773238405Sjkim#endif 774280304Sjkim default: 775280304Sjkim OPENSSL_assert(0); 776280304Sjkim break; 777280304Sjkim } 778280304Sjkim buffer = OPENSSL_malloc(length); 779205128Ssimon 780280304Sjkim if (buffer == NULL) { 781280304Sjkim BIO_printf(bio_err, "out of memory\n"); 782280304Sjkim return 0; 783280304Sjkim } 784205128Ssimon 785280304Sjkim switch (peer.sa.sa_family) { 786280304Sjkim case AF_INET: 787280304Sjkim memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); 788280304Sjkim memcpy(buffer + sizeof(peer.s4.sin_port), 789280304Sjkim &peer.s4.sin_addr, sizeof(struct in_addr)); 790280304Sjkim break; 791238405Sjkim#if OPENSSL_USE_IPV6 792280304Sjkim case AF_INET6: 793280304Sjkim memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); 794280304Sjkim memcpy(buffer + sizeof(peer.s6.sin6_port), 795280304Sjkim &peer.s6.sin6_addr, sizeof(struct in6_addr)); 796280304Sjkim break; 797238405Sjkim#endif 798280304Sjkim default: 799280304Sjkim OPENSSL_assert(0); 800280304Sjkim break; 801280304Sjkim } 802238405Sjkim 803280304Sjkim /* Calculate HMAC of buffer using the secret */ 804280304Sjkim HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 805280304Sjkim buffer, length, result, &resultlength); 806280304Sjkim OPENSSL_free(buffer); 807205128Ssimon 808280304Sjkim memcpy(cookie, result, resultlength); 809280304Sjkim *cookie_len = resultlength; 810205128Ssimon 811280304Sjkim return 1; 812280304Sjkim} 813205128Ssimon 814280304Sjkimint MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, 815280304Sjkim unsigned int cookie_len) 816280304Sjkim{ 817280304Sjkim unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 818280304Sjkim unsigned int length, resultlength; 819280304Sjkim union { 820280304Sjkim struct sockaddr sa; 821280304Sjkim struct sockaddr_in s4; 822238405Sjkim#if OPENSSL_USE_IPV6 823280304Sjkim struct sockaddr_in6 s6; 824238405Sjkim#endif 825280304Sjkim } peer; 826238405Sjkim 827280304Sjkim /* If secret isn't initialized yet, the cookie can't be valid */ 828280304Sjkim if (!cookie_initialized) 829280304Sjkim return 0; 830205128Ssimon 831280304Sjkim /* Read peer information */ 832280304Sjkim (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 833205128Ssimon 834280304Sjkim /* Create buffer with peer's address and port */ 835280304Sjkim length = 0; 836280304Sjkim switch (peer.sa.sa_family) { 837280304Sjkim case AF_INET: 838280304Sjkim length += sizeof(struct in_addr); 839280304Sjkim length += sizeof(peer.s4.sin_port); 840280304Sjkim break; 841238405Sjkim#if OPENSSL_USE_IPV6 842280304Sjkim case AF_INET6: 843280304Sjkim length += sizeof(struct in6_addr); 844280304Sjkim length += sizeof(peer.s6.sin6_port); 845280304Sjkim break; 846238405Sjkim#endif 847280304Sjkim default: 848280304Sjkim OPENSSL_assert(0); 849280304Sjkim break; 850280304Sjkim } 851280304Sjkim buffer = OPENSSL_malloc(length); 852205128Ssimon 853280304Sjkim if (buffer == NULL) { 854280304Sjkim BIO_printf(bio_err, "out of memory\n"); 855280304Sjkim return 0; 856280304Sjkim } 857280304Sjkim 858280304Sjkim switch (peer.sa.sa_family) { 859280304Sjkim case AF_INET: 860280304Sjkim memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port)); 861280304Sjkim memcpy(buffer + sizeof(peer.s4.sin_port), 862280304Sjkim &peer.s4.sin_addr, sizeof(struct in_addr)); 863280304Sjkim break; 864238405Sjkim#if OPENSSL_USE_IPV6 865280304Sjkim case AF_INET6: 866280304Sjkim memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port)); 867280304Sjkim memcpy(buffer + sizeof(peer.s6.sin6_port), 868280304Sjkim &peer.s6.sin6_addr, sizeof(struct in6_addr)); 869280304Sjkim break; 870238405Sjkim#endif 871280304Sjkim default: 872280304Sjkim OPENSSL_assert(0); 873280304Sjkim break; 874280304Sjkim } 875238405Sjkim 876280304Sjkim /* Calculate HMAC of buffer using the secret */ 877280304Sjkim HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 878280304Sjkim buffer, length, result, &resultlength); 879280304Sjkim OPENSSL_free(buffer); 880238405Sjkim 881280304Sjkim if (cookie_len == resultlength 882280304Sjkim && memcmp(result, cookie, resultlength) == 0) 883280304Sjkim return 1; 884205128Ssimon 885280304Sjkim return 0; 886280304Sjkim} 887