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. 855714Skris * 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). 1555714Skris * 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. 2255714Skris * 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 :-). 3755714Skris * 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)" 4055714Skris * 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. 5255714Skris * 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 66109998Smarkm * 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> 11455714Skris#define USE_SOCKETS 11555714Skris#define NON_MAIN 11655714Skris#include "apps.h" 11755714Skris#undef NON_MAIN 11855714Skris#undef USE_SOCKETS 11955714Skris#include <openssl/err.h> 120205128Ssimon#include <openssl/rand.h> 12155714Skris#include <openssl/x509.h> 12255714Skris#include <openssl/ssl.h> 12355714Skris#include "s_apps.h" 12455714Skris 125205128Ssimon#define COOKIE_SECRET_LENGTH 16 126205128Ssimon 12755714Skrisint verify_depth=0; 12855714Skrisint verify_error=X509_V_OK; 129238405Sjkimint verify_return_error=0; 130205128Ssimonunsigned char cookie_secret[COOKIE_SECRET_LENGTH]; 131205128Ssimonint cookie_initialized=0; 13255714Skris 13355714Skrisint MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) 13455714Skris { 13555714Skris X509 *err_cert; 13655714Skris int err,depth; 13755714Skris 13855714Skris err_cert=X509_STORE_CTX_get_current_cert(ctx); 13955714Skris err= X509_STORE_CTX_get_error(ctx); 14055714Skris depth= X509_STORE_CTX_get_error_depth(ctx); 14155714Skris 142238405Sjkim BIO_printf(bio_err,"depth=%d ",depth); 143238405Sjkim if (err_cert) 144238405Sjkim { 145238405Sjkim X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), 146238405Sjkim 0, XN_FLAG_ONELINE); 147238405Sjkim BIO_puts(bio_err, "\n"); 148238405Sjkim } 149238405Sjkim else 150238405Sjkim BIO_puts(bio_err, "<no cert>\n"); 15155714Skris if (!ok) 15255714Skris { 15355714Skris BIO_printf(bio_err,"verify error:num=%d:%s\n",err, 15455714Skris X509_verify_cert_error_string(err)); 15555714Skris if (verify_depth >= depth) 15655714Skris { 157238405Sjkim if (!verify_return_error) 158238405Sjkim ok=1; 15955714Skris verify_error=X509_V_OK; 16055714Skris } 16155714Skris else 16255714Skris { 16355714Skris ok=0; 16455714Skris verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; 16555714Skris } 16655714Skris } 167238405Sjkim switch (err) 16855714Skris { 16955714Skris case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 170238405Sjkim BIO_puts(bio_err,"issuer= "); 171238405Sjkim X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), 172238405Sjkim 0, XN_FLAG_ONELINE); 173238405Sjkim BIO_puts(bio_err, "\n"); 17455714Skris break; 17555714Skris case X509_V_ERR_CERT_NOT_YET_VALID: 17655714Skris case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 17755714Skris BIO_printf(bio_err,"notBefore="); 178238405Sjkim ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); 17955714Skris BIO_printf(bio_err,"\n"); 18055714Skris break; 18155714Skris case X509_V_ERR_CERT_HAS_EXPIRED: 18255714Skris case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 18355714Skris BIO_printf(bio_err,"notAfter="); 184238405Sjkim ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); 18555714Skris BIO_printf(bio_err,"\n"); 18655714Skris break; 187238405Sjkim case X509_V_ERR_NO_EXPLICIT_POLICY: 188238405Sjkim policies_print(bio_err, ctx); 189238405Sjkim break; 19055714Skris } 191238405Sjkim if (err == X509_V_OK && ok == 2) 192238405Sjkim policies_print(bio_err, ctx); 193238405Sjkim 19455714Skris BIO_printf(bio_err,"verify return:%d\n",ok); 19555714Skris return(ok); 19655714Skris } 19755714Skris 19855714Skrisint set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) 19955714Skris { 20055714Skris if (cert_file != NULL) 20155714Skris { 20255714Skris /* 20355714Skris SSL *ssl; 20455714Skris X509 *x509; 20555714Skris */ 20655714Skris 20755714Skris if (SSL_CTX_use_certificate_file(ctx,cert_file, 20855714Skris SSL_FILETYPE_PEM) <= 0) 20955714Skris { 21055714Skris BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file); 21155714Skris ERR_print_errors(bio_err); 21255714Skris return(0); 21355714Skris } 21455714Skris if (key_file == NULL) key_file=cert_file; 21555714Skris if (SSL_CTX_use_PrivateKey_file(ctx,key_file, 21655714Skris SSL_FILETYPE_PEM) <= 0) 21755714Skris { 21855714Skris BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file); 21955714Skris ERR_print_errors(bio_err); 22055714Skris return(0); 22155714Skris } 22255714Skris 22355714Skris /* 22455714Skris In theory this is no longer needed 22555714Skris ssl=SSL_new(ctx); 22655714Skris x509=SSL_get_certificate(ssl); 22755714Skris 22855714Skris if (x509 != NULL) { 22955714Skris EVP_PKEY *pktmp; 23055714Skris pktmp = X509_get_pubkey(x509); 23155714Skris EVP_PKEY_copy_parameters(pktmp, 23255714Skris SSL_get_privatekey(ssl)); 23355714Skris EVP_PKEY_free(pktmp); 23455714Skris } 23555714Skris SSL_free(ssl); 23655714Skris */ 23755714Skris 23855714Skris /* If we are using DSA, we can copy the parameters from 23955714Skris * the private key */ 240246772Sjkim 241246772Sjkim 24255714Skris /* Now we know that a key and cert have been set against 24355714Skris * the SSL context */ 24455714Skris if (!SSL_CTX_check_private_key(ctx)) 24555714Skris { 24655714Skris BIO_printf(bio_err,"Private key does not match the certificate public key\n"); 24755714Skris return(0); 24855714Skris } 24955714Skris } 25055714Skris return(1); 25155714Skris } 25255714Skris 253160814Ssimonint set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key) 25455714Skris { 255160814Ssimon if (cert == NULL) 256160814Ssimon return 1; 257160814Ssimon if (SSL_CTX_use_certificate(ctx,cert) <= 0) 258160814Ssimon { 259160814Ssimon BIO_printf(bio_err,"error setting certificate\n"); 260160814Ssimon ERR_print_errors(bio_err); 261160814Ssimon return 0; 262160814Ssimon } 263160814Ssimon if (SSL_CTX_use_PrivateKey(ctx,key) <= 0) 264160814Ssimon { 265160814Ssimon BIO_printf(bio_err,"error setting private key\n"); 266160814Ssimon ERR_print_errors(bio_err); 267160814Ssimon return 0; 268160814Ssimon } 269160814Ssimon 270160814Ssimon 271160814Ssimon /* Now we know that a key and cert have been set against 272160814Ssimon * the SSL context */ 273160814Ssimon if (!SSL_CTX_check_private_key(ctx)) 274160814Ssimon { 275160814Ssimon BIO_printf(bio_err,"Private key does not match the certificate public key\n"); 276160814Ssimon return 0; 277160814Ssimon } 278160814Ssimon return 1; 279160814Ssimon } 280160814Ssimon 281160814Ssimonlong MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, 282238405Sjkim int argi, long argl, long ret) 283160814Ssimon { 28455714Skris BIO *out; 28555714Skris 28655714Skris out=(BIO *)BIO_get_callback_arg(bio); 28755714Skris if (out == NULL) return(ret); 28855714Skris 28955714Skris if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) 29055714Skris { 291238405Sjkim BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n", 292238405Sjkim (void *)bio,argp,(unsigned long)argi,ret,ret); 29355714Skris BIO_dump(out,argp,(int)ret); 29455714Skris return(ret); 29555714Skris } 29655714Skris else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) 29755714Skris { 298238405Sjkim BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n", 299238405Sjkim (void *)bio,argp,(unsigned long)argi,ret,ret); 30055714Skris BIO_dump(out,argp,(int)ret); 30155714Skris } 30255714Skris return(ret); 30355714Skris } 30455714Skris 305109998Smarkmvoid MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret) 30655714Skris { 307160814Ssimon const char *str; 30855714Skris int w; 30955714Skris 31055714Skris w=where& ~SSL_ST_MASK; 31155714Skris 31255714Skris if (w & SSL_ST_CONNECT) str="SSL_connect"; 31355714Skris else if (w & SSL_ST_ACCEPT) str="SSL_accept"; 31455714Skris else str="undefined"; 31555714Skris 31655714Skris if (where & SSL_CB_LOOP) 31755714Skris { 31855714Skris BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s)); 31955714Skris } 32055714Skris else if (where & SSL_CB_ALERT) 32155714Skris { 32255714Skris str=(where & SSL_CB_READ)?"read":"write"; 32355714Skris BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n", 32455714Skris str, 32555714Skris SSL_alert_type_string_long(ret), 32655714Skris SSL_alert_desc_string_long(ret)); 32755714Skris } 32855714Skris else if (where & SSL_CB_EXIT) 32955714Skris { 33055714Skris if (ret == 0) 33155714Skris BIO_printf(bio_err,"%s:failed in %s\n", 33255714Skris str,SSL_state_string_long(s)); 33355714Skris else if (ret < 0) 33455714Skris { 33555714Skris BIO_printf(bio_err,"%s:error in %s\n", 33655714Skris str,SSL_state_string_long(s)); 33755714Skris } 33855714Skris } 33955714Skris } 34055714Skris 341109998Smarkm 342109998Smarkmvoid MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) 343109998Smarkm { 344109998Smarkm BIO *bio = arg; 345109998Smarkm const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= ""; 346109998Smarkm 347109998Smarkm str_write_p = write_p ? ">>>" : "<<<"; 348109998Smarkm 349109998Smarkm switch (version) 350109998Smarkm { 351109998Smarkm case SSL2_VERSION: 352109998Smarkm str_version = "SSL 2.0"; 353109998Smarkm break; 354109998Smarkm case SSL3_VERSION: 355109998Smarkm str_version = "SSL 3.0 "; 356109998Smarkm break; 357109998Smarkm case TLS1_VERSION: 358109998Smarkm str_version = "TLS 1.0 "; 359109998Smarkm break; 360238405Sjkim case TLS1_1_VERSION: 361238405Sjkim str_version = "TLS 1.1 "; 362238405Sjkim break; 363238405Sjkim case TLS1_2_VERSION: 364238405Sjkim str_version = "TLS 1.2 "; 365238405Sjkim break; 366205128Ssimon case DTLS1_VERSION: 367205128Ssimon str_version = "DTLS 1.0 "; 368205128Ssimon break; 369205128Ssimon case DTLS1_BAD_VER: 370205128Ssimon str_version = "DTLS 1.0 (bad) "; 371205128Ssimon break; 372238405Sjkim default: 373238405Sjkim str_version = "???"; 374109998Smarkm } 375109998Smarkm 376109998Smarkm if (version == SSL2_VERSION) 377109998Smarkm { 378109998Smarkm str_details1 = "???"; 379109998Smarkm 380109998Smarkm if (len > 0) 381109998Smarkm { 382160814Ssimon switch (((const unsigned char*)buf)[0]) 383109998Smarkm { 384109998Smarkm case 0: 385109998Smarkm str_details1 = ", ERROR:"; 386109998Smarkm str_details2 = " ???"; 387109998Smarkm if (len >= 3) 388109998Smarkm { 389160814Ssimon unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2]; 390109998Smarkm 391109998Smarkm switch (err) 392109998Smarkm { 393109998Smarkm case 0x0001: 394109998Smarkm str_details2 = " NO-CIPHER-ERROR"; 395109998Smarkm break; 396109998Smarkm case 0x0002: 397109998Smarkm str_details2 = " NO-CERTIFICATE-ERROR"; 398109998Smarkm break; 399109998Smarkm case 0x0004: 400109998Smarkm str_details2 = " BAD-CERTIFICATE-ERROR"; 401109998Smarkm break; 402109998Smarkm case 0x0006: 403109998Smarkm str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; 404109998Smarkm break; 405109998Smarkm } 406109998Smarkm } 407109998Smarkm 408109998Smarkm break; 409109998Smarkm case 1: 410109998Smarkm str_details1 = ", CLIENT-HELLO"; 411109998Smarkm break; 412109998Smarkm case 2: 413109998Smarkm str_details1 = ", CLIENT-MASTER-KEY"; 414109998Smarkm break; 415109998Smarkm case 3: 416109998Smarkm str_details1 = ", CLIENT-FINISHED"; 417109998Smarkm break; 418109998Smarkm case 4: 419109998Smarkm str_details1 = ", SERVER-HELLO"; 420109998Smarkm break; 421109998Smarkm case 5: 422109998Smarkm str_details1 = ", SERVER-VERIFY"; 423109998Smarkm break; 424109998Smarkm case 6: 425109998Smarkm str_details1 = ", SERVER-FINISHED"; 426109998Smarkm break; 427109998Smarkm case 7: 428109998Smarkm str_details1 = ", REQUEST-CERTIFICATE"; 429109998Smarkm break; 430109998Smarkm case 8: 431109998Smarkm str_details1 = ", CLIENT-CERTIFICATE"; 432109998Smarkm break; 433109998Smarkm } 434109998Smarkm } 435109998Smarkm } 436109998Smarkm 437205128Ssimon if (version == SSL3_VERSION || 438205128Ssimon version == TLS1_VERSION || 439246772Sjkim version == TLS1_1_VERSION || 440246772Sjkim version == TLS1_2_VERSION || 441205128Ssimon version == DTLS1_VERSION || 442205128Ssimon version == DTLS1_BAD_VER) 443109998Smarkm { 444109998Smarkm switch (content_type) 445109998Smarkm { 446109998Smarkm case 20: 447109998Smarkm str_content_type = "ChangeCipherSpec"; 448109998Smarkm break; 449109998Smarkm case 21: 450109998Smarkm str_content_type = "Alert"; 451109998Smarkm break; 452109998Smarkm case 22: 453109998Smarkm str_content_type = "Handshake"; 454109998Smarkm break; 455109998Smarkm } 456109998Smarkm 457109998Smarkm if (content_type == 21) /* Alert */ 458109998Smarkm { 459109998Smarkm str_details1 = ", ???"; 460109998Smarkm 461109998Smarkm if (len == 2) 462109998Smarkm { 463160814Ssimon switch (((const unsigned char*)buf)[0]) 464109998Smarkm { 465109998Smarkm case 1: 466109998Smarkm str_details1 = ", warning"; 467109998Smarkm break; 468109998Smarkm case 2: 469109998Smarkm str_details1 = ", fatal"; 470109998Smarkm break; 471109998Smarkm } 472109998Smarkm 473109998Smarkm str_details2 = " ???"; 474160814Ssimon switch (((const unsigned char*)buf)[1]) 475109998Smarkm { 476109998Smarkm case 0: 477109998Smarkm str_details2 = " close_notify"; 478109998Smarkm break; 479109998Smarkm case 10: 480109998Smarkm str_details2 = " unexpected_message"; 481109998Smarkm break; 482109998Smarkm case 20: 483109998Smarkm str_details2 = " bad_record_mac"; 484109998Smarkm break; 485109998Smarkm case 21: 486109998Smarkm str_details2 = " decryption_failed"; 487109998Smarkm break; 488109998Smarkm case 22: 489109998Smarkm str_details2 = " record_overflow"; 490109998Smarkm break; 491109998Smarkm case 30: 492109998Smarkm str_details2 = " decompression_failure"; 493109998Smarkm break; 494109998Smarkm case 40: 495109998Smarkm str_details2 = " handshake_failure"; 496109998Smarkm break; 497109998Smarkm case 42: 498109998Smarkm str_details2 = " bad_certificate"; 499109998Smarkm break; 500109998Smarkm case 43: 501109998Smarkm str_details2 = " unsupported_certificate"; 502109998Smarkm break; 503109998Smarkm case 44: 504109998Smarkm str_details2 = " certificate_revoked"; 505109998Smarkm break; 506109998Smarkm case 45: 507109998Smarkm str_details2 = " certificate_expired"; 508109998Smarkm break; 509109998Smarkm case 46: 510109998Smarkm str_details2 = " certificate_unknown"; 511109998Smarkm break; 512109998Smarkm case 47: 513109998Smarkm str_details2 = " illegal_parameter"; 514109998Smarkm break; 515109998Smarkm case 48: 516109998Smarkm str_details2 = " unknown_ca"; 517109998Smarkm break; 518109998Smarkm case 49: 519109998Smarkm str_details2 = " access_denied"; 520109998Smarkm break; 521109998Smarkm case 50: 522109998Smarkm str_details2 = " decode_error"; 523109998Smarkm break; 524109998Smarkm case 51: 525109998Smarkm str_details2 = " decrypt_error"; 526109998Smarkm break; 527109998Smarkm case 60: 528109998Smarkm str_details2 = " export_restriction"; 529109998Smarkm break; 530109998Smarkm case 70: 531109998Smarkm str_details2 = " protocol_version"; 532109998Smarkm break; 533109998Smarkm case 71: 534109998Smarkm str_details2 = " insufficient_security"; 535109998Smarkm break; 536109998Smarkm case 80: 537109998Smarkm str_details2 = " internal_error"; 538109998Smarkm break; 539109998Smarkm case 90: 540109998Smarkm str_details2 = " user_canceled"; 541109998Smarkm break; 542109998Smarkm case 100: 543109998Smarkm str_details2 = " no_renegotiation"; 544109998Smarkm break; 545238405Sjkim case 110: 546238405Sjkim str_details2 = " unsupported_extension"; 547238405Sjkim break; 548238405Sjkim case 111: 549238405Sjkim str_details2 = " certificate_unobtainable"; 550238405Sjkim break; 551238405Sjkim case 112: 552238405Sjkim str_details2 = " unrecognized_name"; 553238405Sjkim break; 554238405Sjkim case 113: 555238405Sjkim str_details2 = " bad_certificate_status_response"; 556238405Sjkim break; 557238405Sjkim case 114: 558238405Sjkim str_details2 = " bad_certificate_hash_value"; 559238405Sjkim break; 560238405Sjkim case 115: 561238405Sjkim str_details2 = " unknown_psk_identity"; 562238405Sjkim break; 563109998Smarkm } 564109998Smarkm } 565109998Smarkm } 566109998Smarkm 567109998Smarkm if (content_type == 22) /* Handshake */ 568109998Smarkm { 569109998Smarkm str_details1 = "???"; 570109998Smarkm 571109998Smarkm if (len > 0) 572109998Smarkm { 573160814Ssimon switch (((const unsigned char*)buf)[0]) 574109998Smarkm { 575109998Smarkm case 0: 576109998Smarkm str_details1 = ", HelloRequest"; 577109998Smarkm break; 578109998Smarkm case 1: 579109998Smarkm str_details1 = ", ClientHello"; 580109998Smarkm break; 581109998Smarkm case 2: 582109998Smarkm str_details1 = ", ServerHello"; 583109998Smarkm break; 584238405Sjkim case 3: 585238405Sjkim str_details1 = ", HelloVerifyRequest"; 586238405Sjkim break; 587109998Smarkm case 11: 588109998Smarkm str_details1 = ", Certificate"; 589109998Smarkm break; 590109998Smarkm case 12: 591109998Smarkm str_details1 = ", ServerKeyExchange"; 592109998Smarkm break; 593109998Smarkm case 13: 594109998Smarkm str_details1 = ", CertificateRequest"; 595109998Smarkm break; 596109998Smarkm case 14: 597109998Smarkm str_details1 = ", ServerHelloDone"; 598109998Smarkm break; 599109998Smarkm case 15: 600109998Smarkm str_details1 = ", CertificateVerify"; 601109998Smarkm break; 602109998Smarkm case 16: 603109998Smarkm str_details1 = ", ClientKeyExchange"; 604109998Smarkm break; 605109998Smarkm case 20: 606109998Smarkm str_details1 = ", Finished"; 607109998Smarkm break; 608109998Smarkm } 609109998Smarkm } 610109998Smarkm } 611238405Sjkim 612238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 613238405Sjkim if (content_type == 24) /* Heartbeat */ 614238405Sjkim { 615238405Sjkim str_details1 = ", Heartbeat"; 616238405Sjkim 617238405Sjkim if (len > 0) 618238405Sjkim { 619238405Sjkim switch (((const unsigned char*)buf)[0]) 620238405Sjkim { 621238405Sjkim case 1: 622238405Sjkim str_details1 = ", HeartbeatRequest"; 623238405Sjkim break; 624238405Sjkim case 2: 625238405Sjkim str_details1 = ", HeartbeatResponse"; 626238405Sjkim break; 627238405Sjkim } 628238405Sjkim } 629238405Sjkim } 630238405Sjkim#endif 631109998Smarkm } 632109998Smarkm 633109998Smarkm 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); 634109998Smarkm 635109998Smarkm if (len > 0) 636109998Smarkm { 637109998Smarkm size_t num, i; 638109998Smarkm 639109998Smarkm BIO_printf(bio, " "); 640109998Smarkm num = len; 641109998Smarkm#if 0 642109998Smarkm if (num > 16) 643109998Smarkm num = 16; 644109998Smarkm#endif 645109998Smarkm for (i = 0; i < num; i++) 646109998Smarkm { 647109998Smarkm if (i % 16 == 0 && i > 0) 648109998Smarkm BIO_printf(bio, "\n "); 649160814Ssimon BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]); 650109998Smarkm } 651109998Smarkm if (i < len) 652109998Smarkm BIO_printf(bio, " ..."); 653109998Smarkm BIO_printf(bio, "\n"); 654109998Smarkm } 655194206Ssimon (void)BIO_flush(bio); 656109998Smarkm } 657194206Ssimon 658194206Ssimonvoid MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, 659194206Ssimon unsigned char *data, int len, 660194206Ssimon void *arg) 661194206Ssimon { 662194206Ssimon BIO *bio = arg; 663194206Ssimon char *extname; 664194206Ssimon 665194206Ssimon switch(type) 666194206Ssimon { 667194206Ssimon case TLSEXT_TYPE_server_name: 668194206Ssimon extname = "server name"; 669194206Ssimon break; 670194206Ssimon 671194206Ssimon case TLSEXT_TYPE_max_fragment_length: 672194206Ssimon extname = "max fragment length"; 673194206Ssimon break; 674194206Ssimon 675194206Ssimon case TLSEXT_TYPE_client_certificate_url: 676194206Ssimon extname = "client certificate URL"; 677194206Ssimon break; 678194206Ssimon 679194206Ssimon case TLSEXT_TYPE_trusted_ca_keys: 680194206Ssimon extname = "trusted CA keys"; 681194206Ssimon break; 682194206Ssimon 683194206Ssimon case TLSEXT_TYPE_truncated_hmac: 684194206Ssimon extname = "truncated HMAC"; 685194206Ssimon break; 686194206Ssimon 687194206Ssimon case TLSEXT_TYPE_status_request: 688194206Ssimon extname = "status request"; 689194206Ssimon break; 690194206Ssimon 691238405Sjkim case TLSEXT_TYPE_user_mapping: 692238405Sjkim extname = "user mapping"; 693238405Sjkim break; 694238405Sjkim 695238405Sjkim case TLSEXT_TYPE_client_authz: 696238405Sjkim extname = "client authz"; 697238405Sjkim break; 698238405Sjkim 699238405Sjkim case TLSEXT_TYPE_server_authz: 700238405Sjkim extname = "server authz"; 701238405Sjkim break; 702238405Sjkim 703238405Sjkim case TLSEXT_TYPE_cert_type: 704238405Sjkim extname = "cert type"; 705238405Sjkim break; 706238405Sjkim 707194206Ssimon case TLSEXT_TYPE_elliptic_curves: 708194206Ssimon extname = "elliptic curves"; 709194206Ssimon break; 710194206Ssimon 711194206Ssimon case TLSEXT_TYPE_ec_point_formats: 712194206Ssimon extname = "EC point formats"; 713194206Ssimon break; 714194206Ssimon 715238405Sjkim case TLSEXT_TYPE_srp: 716238405Sjkim extname = "SRP"; 717238405Sjkim break; 718238405Sjkim 719238405Sjkim case TLSEXT_TYPE_signature_algorithms: 720238405Sjkim extname = "signature algorithms"; 721238405Sjkim break; 722238405Sjkim 723238405Sjkim case TLSEXT_TYPE_use_srtp: 724238405Sjkim extname = "use SRTP"; 725238405Sjkim break; 726238405Sjkim 727238405Sjkim case TLSEXT_TYPE_heartbeat: 728238405Sjkim extname = "heartbeat"; 729238405Sjkim break; 730238405Sjkim 731194206Ssimon case TLSEXT_TYPE_session_ticket: 732238405Sjkim extname = "session ticket"; 733194206Ssimon break; 734194206Ssimon 735238405Sjkim case TLSEXT_TYPE_renegotiate: 736238405Sjkim extname = "renegotiation info"; 737205128Ssimon break; 738194206Ssimon 739238405Sjkim#ifdef TLSEXT_TYPE_opaque_prf_input 740238405Sjkim case TLSEXT_TYPE_opaque_prf_input: 741238405Sjkim extname = "opaque PRF input"; 742238405Sjkim break; 743238405Sjkim#endif 744238405Sjkim#ifdef TLSEXT_TYPE_next_proto_neg 745238405Sjkim case TLSEXT_TYPE_next_proto_neg: 746238405Sjkim extname = "next protocol"; 747238405Sjkim break; 748238405Sjkim#endif 749238405Sjkim 750279264Sdelphij case TLSEXT_TYPE_padding: 751279264Sdelphij extname = "TLS padding"; 752279264Sdelphij break; 753279264Sdelphij 754194206Ssimon default: 755194206Ssimon extname = "unknown"; 756194206Ssimon break; 757194206Ssimon 758194206Ssimon } 759194206Ssimon 760194206Ssimon BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", 761194206Ssimon client_server ? "server": "client", 762194206Ssimon extname, type, len); 763194206Ssimon BIO_dump(bio, (char *)data, len); 764194206Ssimon (void)BIO_flush(bio); 765194206Ssimon } 766205128Ssimon 767205128Ssimonint MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) 768205128Ssimon { 769205128Ssimon unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 770205128Ssimon unsigned int length, resultlength; 771238405Sjkim union { 772238405Sjkim struct sockaddr sa; 773238405Sjkim struct sockaddr_in s4; 774238405Sjkim#if OPENSSL_USE_IPV6 775238405Sjkim struct sockaddr_in6 s6; 776238405Sjkim#endif 777238405Sjkim } peer; 778238405Sjkim 779205128Ssimon /* Initialize a random secret */ 780205128Ssimon if (!cookie_initialized) 781205128Ssimon { 782205128Ssimon if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH)) 783205128Ssimon { 784205128Ssimon BIO_printf(bio_err,"error setting random cookie secret\n"); 785205128Ssimon return 0; 786205128Ssimon } 787205128Ssimon cookie_initialized = 1; 788205128Ssimon } 789205128Ssimon 790205128Ssimon /* Read peer information */ 791205128Ssimon (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 792205128Ssimon 793205128Ssimon /* Create buffer with peer's address and port */ 794238405Sjkim length = 0; 795238405Sjkim switch (peer.sa.sa_family) 796238405Sjkim { 797238405Sjkim case AF_INET: 798238405Sjkim length += sizeof(struct in_addr); 799238405Sjkim length += sizeof(peer.s4.sin_port); 800238405Sjkim break; 801238405Sjkim#if OPENSSL_USE_IPV6 802238405Sjkim case AF_INET6: 803238405Sjkim length += sizeof(struct in6_addr); 804238405Sjkim length += sizeof(peer.s6.sin6_port); 805238405Sjkim break; 806238405Sjkim#endif 807238405Sjkim default: 808238405Sjkim OPENSSL_assert(0); 809238405Sjkim break; 810238405Sjkim } 811205128Ssimon buffer = OPENSSL_malloc(length); 812205128Ssimon 813205128Ssimon if (buffer == NULL) 814205128Ssimon { 815205128Ssimon BIO_printf(bio_err,"out of memory\n"); 816205128Ssimon return 0; 817205128Ssimon } 818205128Ssimon 819238405Sjkim switch (peer.sa.sa_family) 820238405Sjkim { 821238405Sjkim case AF_INET: 822238405Sjkim memcpy(buffer, 823238405Sjkim &peer.s4.sin_port, 824238405Sjkim sizeof(peer.s4.sin_port)); 825238405Sjkim memcpy(buffer + sizeof(peer.s4.sin_port), 826238405Sjkim &peer.s4.sin_addr, 827238405Sjkim sizeof(struct in_addr)); 828238405Sjkim break; 829238405Sjkim#if OPENSSL_USE_IPV6 830238405Sjkim case AF_INET6: 831238405Sjkim memcpy(buffer, 832238405Sjkim &peer.s6.sin6_port, 833238405Sjkim sizeof(peer.s6.sin6_port)); 834238405Sjkim memcpy(buffer + sizeof(peer.s6.sin6_port), 835238405Sjkim &peer.s6.sin6_addr, 836238405Sjkim sizeof(struct in6_addr)); 837238405Sjkim break; 838238405Sjkim#endif 839238405Sjkim default: 840238405Sjkim OPENSSL_assert(0); 841238405Sjkim break; 842238405Sjkim } 843238405Sjkim 844205128Ssimon /* Calculate HMAC of buffer using the secret */ 845205128Ssimon HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 846205128Ssimon buffer, length, result, &resultlength); 847205128Ssimon OPENSSL_free(buffer); 848205128Ssimon 849205128Ssimon memcpy(cookie, result, resultlength); 850205128Ssimon *cookie_len = resultlength; 851205128Ssimon 852205128Ssimon return 1; 853205128Ssimon } 854205128Ssimon 855205128Ssimonint MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned int cookie_len) 856205128Ssimon { 857205128Ssimon unsigned char *buffer, result[EVP_MAX_MD_SIZE]; 858205128Ssimon unsigned int length, resultlength; 859238405Sjkim union { 860238405Sjkim struct sockaddr sa; 861238405Sjkim struct sockaddr_in s4; 862238405Sjkim#if OPENSSL_USE_IPV6 863238405Sjkim struct sockaddr_in6 s6; 864238405Sjkim#endif 865238405Sjkim } peer; 866238405Sjkim 867205128Ssimon /* If secret isn't initialized yet, the cookie can't be valid */ 868205128Ssimon if (!cookie_initialized) 869205128Ssimon return 0; 870205128Ssimon 871205128Ssimon /* Read peer information */ 872205128Ssimon (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); 873205128Ssimon 874205128Ssimon /* Create buffer with peer's address and port */ 875238405Sjkim length = 0; 876238405Sjkim switch (peer.sa.sa_family) 877238405Sjkim { 878238405Sjkim case AF_INET: 879238405Sjkim length += sizeof(struct in_addr); 880238405Sjkim length += sizeof(peer.s4.sin_port); 881238405Sjkim break; 882238405Sjkim#if OPENSSL_USE_IPV6 883238405Sjkim case AF_INET6: 884238405Sjkim length += sizeof(struct in6_addr); 885238405Sjkim length += sizeof(peer.s6.sin6_port); 886238405Sjkim break; 887238405Sjkim#endif 888238405Sjkim default: 889238405Sjkim OPENSSL_assert(0); 890238405Sjkim break; 891238405Sjkim } 892238405Sjkim buffer = OPENSSL_malloc(length); 893205128Ssimon 894205128Ssimon if (buffer == NULL) 895205128Ssimon { 896205128Ssimon BIO_printf(bio_err,"out of memory\n"); 897205128Ssimon return 0; 898205128Ssimon } 899205128Ssimon 900238405Sjkim switch (peer.sa.sa_family) 901238405Sjkim { 902238405Sjkim case AF_INET: 903238405Sjkim memcpy(buffer, 904238405Sjkim &peer.s4.sin_port, 905238405Sjkim sizeof(peer.s4.sin_port)); 906238405Sjkim memcpy(buffer + sizeof(peer.s4.sin_port), 907238405Sjkim &peer.s4.sin_addr, 908238405Sjkim sizeof(struct in_addr)); 909238405Sjkim break; 910238405Sjkim#if OPENSSL_USE_IPV6 911238405Sjkim case AF_INET6: 912238405Sjkim memcpy(buffer, 913238405Sjkim &peer.s6.sin6_port, 914238405Sjkim sizeof(peer.s6.sin6_port)); 915238405Sjkim memcpy(buffer + sizeof(peer.s6.sin6_port), 916238405Sjkim &peer.s6.sin6_addr, 917238405Sjkim sizeof(struct in6_addr)); 918238405Sjkim break; 919238405Sjkim#endif 920238405Sjkim default: 921238405Sjkim OPENSSL_assert(0); 922238405Sjkim break; 923238405Sjkim } 924238405Sjkim 925205128Ssimon /* Calculate HMAC of buffer using the secret */ 926205128Ssimon HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, 927205128Ssimon buffer, length, result, &resultlength); 928205128Ssimon OPENSSL_free(buffer); 929238405Sjkim 930205128Ssimon if (cookie_len == resultlength && memcmp(result, cookie, resultlength) == 0) 931205128Ssimon return 1; 932205128Ssimon 933205128Ssimon return 0; 934205128Ssimon } 935