os/ossrv/ssl/tsrc/topenssl/src/s_cb.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
sl@0
     2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
     3
 * All rights reserved.
sl@0
     4
 *
sl@0
     5
 * This package is an SSL implementation written
sl@0
     6
 * by Eric Young (eay@cryptsoft.com).
sl@0
     7
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
     8
 * 
sl@0
     9
 * This library is free for commercial and non-commercial use as long as
sl@0
    10
 * the following conditions are aheared to.  The following conditions
sl@0
    11
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    13
 * included with this distribution is covered by the same copyright terms
sl@0
    14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    15
 * 
sl@0
    16
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    17
 * the code are not to be removed.
sl@0
    18
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    19
 * as the author of the parts of the library used.
sl@0
    20
 * This can be in the form of a textual message at program startup or
sl@0
    21
 * in documentation (online or textual) provided with the package.
sl@0
    22
 * 
sl@0
    23
 * Redistribution and use in source and binary forms, with or without
sl@0
    24
 * modification, are permitted provided that the following conditions
sl@0
    25
 * are met:
sl@0
    26
 * 1. Redistributions of source code must retain the copyright
sl@0
    27
 *    notice, this list of conditions and the following disclaimer.
sl@0
    28
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    29
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    30
 *    documentation and/or other materials provided with the distribution.
sl@0
    31
 * 3. All advertising materials mentioning features or use of this software
sl@0
    32
 *    must display the following acknowledgement:
sl@0
    33
 *    "This product includes cryptographic software written by
sl@0
    34
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    35
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    36
 *    being used are not cryptographic related :-).
sl@0
    37
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    38
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    40
 * 
sl@0
    41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
    44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
    45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
    46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
    47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
    49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
    50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
    51
 * SUCH DAMAGE.
sl@0
    52
 * 
sl@0
    53
 * The licence and distribution terms for any publically available version or
sl@0
    54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
    55
 * copied and put under another distribution licence
sl@0
    56
 * [including the GNU Public Licence.]
sl@0
    57
 */
sl@0
    58
/* ====================================================================
sl@0
    59
 * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
sl@0
    60
 *
sl@0
    61
 * Redistribution and use in source and binary forms, with or without
sl@0
    62
 * modification, are permitted provided that the following conditions
sl@0
    63
 * are met:
sl@0
    64
 *
sl@0
    65
 * 1. Redistributions of source code must retain the above copyright
sl@0
    66
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    67
 *
sl@0
    68
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    69
 *    notice, this list of conditions and the following disclaimer in
sl@0
    70
 *    the documentation and/or other materials provided with the
sl@0
    71
 *    distribution.
sl@0
    72
 *
sl@0
    73
 * 3. All advertising materials mentioning features or use of this
sl@0
    74
 *    software must display the following acknowledgment:
sl@0
    75
 *    "This product includes software developed by the OpenSSL Project
sl@0
    76
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
sl@0
    77
 *
sl@0
    78
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    79
 *    endorse or promote products derived from this software without
sl@0
    80
 *    prior written permission. For written permission, please contact
sl@0
    81
 *    openssl-core@openssl.org.
sl@0
    82
 *
sl@0
    83
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    84
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    85
 *    permission of the OpenSSL Project.
sl@0
    86
 *
sl@0
    87
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    88
 *    acknowledgment:
sl@0
    89
 *    "This product includes software developed by the OpenSSL Project
sl@0
    90
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
sl@0
    91
 *
sl@0
    92
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    93
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    94
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    95
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    96
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    97
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    98
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    99
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
   100
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
   101
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
   102
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
   103
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
   104
 * ====================================================================
sl@0
   105
 *
sl@0
   106
 * This product includes cryptographic software written by Eric Young
sl@0
   107
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
   108
 * Hudson (tjh@cryptsoft.com).
sl@0
   109
 *
sl@0
   110
 */
sl@0
   111
sl@0
   112
#include <stdio.h>
sl@0
   113
#include <stdlib.h>
sl@0
   114
#define USE_SOCKETS
sl@0
   115
#define NON_MAIN
sl@0
   116
#include "apps.h"
sl@0
   117
#undef NON_MAIN
sl@0
   118
#undef USE_SOCKETS
sl@0
   119
#include <openssl/err.h>
sl@0
   120
#include <openssl/x509.h>
sl@0
   121
#include <openssl/ssl.h>
sl@0
   122
#include "s_apps.h"
sl@0
   123
sl@0
   124
int verify_depth=0;
sl@0
   125
int verify_error=X509_V_OK;
sl@0
   126
sl@0
   127
sl@0
   128
int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
sl@0
   129
	{
sl@0
   130
	char buf[256];
sl@0
   131
	X509 *err_cert;
sl@0
   132
	int err,depth;
sl@0
   133
sl@0
   134
	err_cert=X509_STORE_CTX_get_current_cert(ctx);
sl@0
   135
	err=	X509_STORE_CTX_get_error(ctx);
sl@0
   136
	depth=	X509_STORE_CTX_get_error_depth(ctx);
sl@0
   137
sl@0
   138
	X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
sl@0
   139
	BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
sl@0
   140
	if (!ok)
sl@0
   141
		{
sl@0
   142
		BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
sl@0
   143
			X509_verify_cert_error_string(err));
sl@0
   144
		if (verify_depth >= depth)
sl@0
   145
			{
sl@0
   146
			ok=1;
sl@0
   147
			verify_error=X509_V_OK;
sl@0
   148
			}
sl@0
   149
		else
sl@0
   150
			{
sl@0
   151
			ok=0;
sl@0
   152
			verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
sl@0
   153
			}
sl@0
   154
		}
sl@0
   155
	switch (ctx->error)
sl@0
   156
		{
sl@0
   157
	case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
sl@0
   158
		X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf);
sl@0
   159
		BIO_printf(bio_err,"issuer= %s\n",buf);
sl@0
   160
		break;
sl@0
   161
	case X509_V_ERR_CERT_NOT_YET_VALID:
sl@0
   162
	case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
sl@0
   163
		BIO_printf(bio_err,"notBefore=");
sl@0
   164
		ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
sl@0
   165
		BIO_printf(bio_err,"\n");
sl@0
   166
		break;
sl@0
   167
	case X509_V_ERR_CERT_HAS_EXPIRED:
sl@0
   168
	case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
sl@0
   169
		BIO_printf(bio_err,"notAfter=");
sl@0
   170
		ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
sl@0
   171
		BIO_printf(bio_err,"\n");
sl@0
   172
		break;
sl@0
   173
		}
sl@0
   174
	BIO_printf(bio_err,"verify return:%d\n",ok);
sl@0
   175
	return(ok);
sl@0
   176
	}
sl@0
   177
sl@0
   178
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
sl@0
   179
	{
sl@0
   180
	if (cert_file != NULL)
sl@0
   181
		{
sl@0
   182
		/*
sl@0
   183
		SSL *ssl;
sl@0
   184
		X509 *x509;
sl@0
   185
		*/
sl@0
   186
sl@0
   187
		if (SSL_CTX_use_certificate_file(ctx,cert_file,
sl@0
   188
			SSL_FILETYPE_PEM) <= 0)
sl@0
   189
			{
sl@0
   190
			BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
sl@0
   191
			ERR_print_errors(bio_err);
sl@0
   192
			return(0);
sl@0
   193
			}
sl@0
   194
		if (key_file == NULL) key_file=cert_file;
sl@0
   195
		if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
sl@0
   196
			SSL_FILETYPE_PEM) <= 0)
sl@0
   197
			{
sl@0
   198
			BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
sl@0
   199
			ERR_print_errors(bio_err);
sl@0
   200
			return(0);
sl@0
   201
			}
sl@0
   202
sl@0
   203
		/*
sl@0
   204
		In theory this is no longer needed 
sl@0
   205
		ssl=SSL_new(ctx);
sl@0
   206
		x509=SSL_get_certificate(ssl);
sl@0
   207
sl@0
   208
		if (x509 != NULL) {
sl@0
   209
			EVP_PKEY *pktmp;
sl@0
   210
			pktmp = X509_get_pubkey(x509);
sl@0
   211
			EVP_PKEY_copy_parameters(pktmp,
sl@0
   212
						SSL_get_privatekey(ssl));
sl@0
   213
			EVP_PKEY_free(pktmp);
sl@0
   214
		}
sl@0
   215
		SSL_free(ssl);
sl@0
   216
		*/
sl@0
   217
sl@0
   218
		/* If we are using DSA, we can copy the parameters from
sl@0
   219
		 * the private key */
sl@0
   220
		
sl@0
   221
		
sl@0
   222
		/* Now we know that a key and cert have been set against
sl@0
   223
		 * the SSL context */
sl@0
   224
		if (!SSL_CTX_check_private_key(ctx))
sl@0
   225
			{
sl@0
   226
			BIO_printf(bio_err,"Private key does not match the certificate public key\n");
sl@0
   227
			return(0);
sl@0
   228
			}
sl@0
   229
		}
sl@0
   230
	return(1);
sl@0
   231
	}
sl@0
   232
sl@0
   233
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
sl@0
   234
	{
sl@0
   235
	if (cert ==  NULL)
sl@0
   236
		return 1;
sl@0
   237
	if (SSL_CTX_use_certificate(ctx,cert) <= 0)
sl@0
   238
		{
sl@0
   239
		BIO_printf(bio_err,"error setting certificate\n");
sl@0
   240
		ERR_print_errors(bio_err);
sl@0
   241
		return 0;
sl@0
   242
		}
sl@0
   243
	if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
sl@0
   244
		{
sl@0
   245
		BIO_printf(bio_err,"error setting private key\n");
sl@0
   246
		ERR_print_errors(bio_err);
sl@0
   247
		return 0;
sl@0
   248
		}
sl@0
   249
sl@0
   250
		
sl@0
   251
		/* Now we know that a key and cert have been set against
sl@0
   252
		 * the SSL context */
sl@0
   253
	if (!SSL_CTX_check_private_key(ctx))
sl@0
   254
		{
sl@0
   255
		BIO_printf(bio_err,"Private key does not match the certificate public key\n");
sl@0
   256
		return 0;
sl@0
   257
		}
sl@0
   258
	return 1;
sl@0
   259
	}
sl@0
   260
sl@0
   261
long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
sl@0
   262
	int argi, long argl, long ret)
sl@0
   263
	{
sl@0
   264
	BIO *out;
sl@0
   265
sl@0
   266
	out=(BIO *)BIO_get_callback_arg(bio);
sl@0
   267
	if (out == NULL) return(ret);
sl@0
   268
sl@0
   269
	if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
sl@0
   270
		{
sl@0
   271
		BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n",
sl@0
   272
 			(void *)bio,argp,argi,ret,ret);
sl@0
   273
		BIO_dump(out,argp,(int)ret);
sl@0
   274
		return(ret);
sl@0
   275
		}
sl@0
   276
	else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
sl@0
   277
		{
sl@0
   278
		BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n",
sl@0
   279
			(void *)bio,argp,argi,ret,ret);
sl@0
   280
		BIO_dump(out,argp,(int)ret);
sl@0
   281
		}
sl@0
   282
	return(ret);
sl@0
   283
	}
sl@0
   284
sl@0
   285
void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
sl@0
   286
	{
sl@0
   287
	const char *str;
sl@0
   288
	int w;
sl@0
   289
sl@0
   290
	w=where& ~SSL_ST_MASK;
sl@0
   291
sl@0
   292
	if (w & SSL_ST_CONNECT) str="SSL_connect";
sl@0
   293
	else if (w & SSL_ST_ACCEPT) str="SSL_accept";
sl@0
   294
	else str="undefined";
sl@0
   295
sl@0
   296
	if (where & SSL_CB_LOOP)
sl@0
   297
		{
sl@0
   298
		BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
sl@0
   299
		}
sl@0
   300
	else if (where & SSL_CB_ALERT)
sl@0
   301
		{
sl@0
   302
		str=(where & SSL_CB_READ)?"read":"write";
sl@0
   303
		BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
sl@0
   304
			str,
sl@0
   305
			SSL_alert_type_string_long(ret),
sl@0
   306
			SSL_alert_desc_string_long(ret));
sl@0
   307
		}
sl@0
   308
	else if (where & SSL_CB_EXIT)
sl@0
   309
		{
sl@0
   310
		if (ret == 0)
sl@0
   311
			BIO_printf(bio_err,"%s:failed in %s\n",
sl@0
   312
				str,SSL_state_string_long(s));
sl@0
   313
		else if (ret < 0)
sl@0
   314
			{
sl@0
   315
			BIO_printf(bio_err,"%s:error in %s\n",
sl@0
   316
				str,SSL_state_string_long(s));
sl@0
   317
			}
sl@0
   318
		}
sl@0
   319
	}
sl@0
   320
sl@0
   321
sl@0
   322
void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
sl@0
   323
	{
sl@0
   324
	BIO *bio = arg;
sl@0
   325
	const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= "";
sl@0
   326
	
sl@0
   327
	str_write_p = write_p ? ">>>" : "<<<";
sl@0
   328
sl@0
   329
	switch (version)
sl@0
   330
		{
sl@0
   331
	case SSL2_VERSION:
sl@0
   332
		str_version = "SSL 2.0";
sl@0
   333
		break;
sl@0
   334
	case SSL3_VERSION:
sl@0
   335
		str_version = "SSL 3.0 ";
sl@0
   336
		break;
sl@0
   337
	case TLS1_VERSION:
sl@0
   338
		str_version = "TLS 1.0 ";
sl@0
   339
		break;
sl@0
   340
	default:
sl@0
   341
		str_version = "???";
sl@0
   342
		}
sl@0
   343
sl@0
   344
	if (version == SSL2_VERSION)
sl@0
   345
		{
sl@0
   346
		str_details1 = "???";
sl@0
   347
sl@0
   348
		if (len > 0)
sl@0
   349
			{
sl@0
   350
			switch (((const unsigned char*)buf)[0])
sl@0
   351
				{
sl@0
   352
				case 0:
sl@0
   353
					str_details1 = ", ERROR:";
sl@0
   354
					str_details2 = " ???";
sl@0
   355
					if (len >= 3)
sl@0
   356
						{
sl@0
   357
						unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2];
sl@0
   358
						
sl@0
   359
						switch (err)
sl@0
   360
							{
sl@0
   361
						case 0x0001:
sl@0
   362
							str_details2 = " NO-CIPHER-ERROR";
sl@0
   363
							break;
sl@0
   364
						case 0x0002:
sl@0
   365
							str_details2 = " NO-CERTIFICATE-ERROR";
sl@0
   366
							break;
sl@0
   367
						case 0x0004:
sl@0
   368
							str_details2 = " BAD-CERTIFICATE-ERROR";
sl@0
   369
							break;
sl@0
   370
						case 0x0006:
sl@0
   371
							str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
sl@0
   372
							break;
sl@0
   373
							}
sl@0
   374
						}
sl@0
   375
sl@0
   376
					break;
sl@0
   377
				case 1:
sl@0
   378
					str_details1 = ", CLIENT-HELLO";
sl@0
   379
					break;
sl@0
   380
				case 2:
sl@0
   381
					str_details1 = ", CLIENT-MASTER-KEY";
sl@0
   382
					break;
sl@0
   383
				case 3:
sl@0
   384
					str_details1 = ", CLIENT-FINISHED";
sl@0
   385
					break;
sl@0
   386
				case 4:
sl@0
   387
					str_details1 = ", SERVER-HELLO";
sl@0
   388
					break;
sl@0
   389
				case 5:
sl@0
   390
					str_details1 = ", SERVER-VERIFY";
sl@0
   391
					break;
sl@0
   392
				case 6:
sl@0
   393
					str_details1 = ", SERVER-FINISHED";
sl@0
   394
					break;
sl@0
   395
				case 7:
sl@0
   396
					str_details1 = ", REQUEST-CERTIFICATE";
sl@0
   397
					break;
sl@0
   398
				case 8:
sl@0
   399
					str_details1 = ", CLIENT-CERTIFICATE";
sl@0
   400
					break;
sl@0
   401
				}
sl@0
   402
			}
sl@0
   403
		}
sl@0
   404
sl@0
   405
	if (version == SSL3_VERSION || version == TLS1_VERSION)
sl@0
   406
		{
sl@0
   407
		switch (content_type)
sl@0
   408
			{
sl@0
   409
		case 20:
sl@0
   410
			str_content_type = "ChangeCipherSpec";
sl@0
   411
			break;
sl@0
   412
		case 21:
sl@0
   413
			str_content_type = "Alert";
sl@0
   414
			break;
sl@0
   415
		case 22:
sl@0
   416
			str_content_type = "Handshake";
sl@0
   417
			break;
sl@0
   418
			}
sl@0
   419
sl@0
   420
		if (content_type == 21) /* Alert */
sl@0
   421
			{
sl@0
   422
			str_details1 = ", ???";
sl@0
   423
			
sl@0
   424
			if (len == 2)
sl@0
   425
				{
sl@0
   426
				switch (((const unsigned char*)buf)[0])
sl@0
   427
					{
sl@0
   428
				case 1:
sl@0
   429
					str_details1 = ", warning";
sl@0
   430
					break;
sl@0
   431
				case 2:
sl@0
   432
					str_details1 = ", fatal";
sl@0
   433
					break;
sl@0
   434
					}
sl@0
   435
sl@0
   436
				str_details2 = " ???";
sl@0
   437
				switch (((const unsigned char*)buf)[1])
sl@0
   438
					{
sl@0
   439
				case 0:
sl@0
   440
					str_details2 = " close_notify";
sl@0
   441
					break;
sl@0
   442
				case 10:
sl@0
   443
					str_details2 = " unexpected_message";
sl@0
   444
					break;
sl@0
   445
				case 20:
sl@0
   446
					str_details2 = " bad_record_mac";
sl@0
   447
					break;
sl@0
   448
				case 21:
sl@0
   449
					str_details2 = " decryption_failed";
sl@0
   450
					break;
sl@0
   451
				case 22:
sl@0
   452
					str_details2 = " record_overflow";
sl@0
   453
					break;
sl@0
   454
				case 30:
sl@0
   455
					str_details2 = " decompression_failure";
sl@0
   456
					break;
sl@0
   457
				case 40:
sl@0
   458
					str_details2 = " handshake_failure";
sl@0
   459
					break;
sl@0
   460
				case 42:
sl@0
   461
					str_details2 = " bad_certificate";
sl@0
   462
					break;
sl@0
   463
				case 43:
sl@0
   464
					str_details2 = " unsupported_certificate";
sl@0
   465
					break;
sl@0
   466
				case 44:
sl@0
   467
					str_details2 = " certificate_revoked";
sl@0
   468
					break;
sl@0
   469
				case 45:
sl@0
   470
					str_details2 = " certificate_expired";
sl@0
   471
					break;
sl@0
   472
				case 46:
sl@0
   473
					str_details2 = " certificate_unknown";
sl@0
   474
					break;
sl@0
   475
				case 47:
sl@0
   476
					str_details2 = " illegal_parameter";
sl@0
   477
					break;
sl@0
   478
				case 48:
sl@0
   479
					str_details2 = " unknown_ca";
sl@0
   480
					break;
sl@0
   481
				case 49:
sl@0
   482
					str_details2 = " access_denied";
sl@0
   483
					break;
sl@0
   484
				case 50:
sl@0
   485
					str_details2 = " decode_error";
sl@0
   486
					break;
sl@0
   487
				case 51:
sl@0
   488
					str_details2 = " decrypt_error";
sl@0
   489
					break;
sl@0
   490
				case 60:
sl@0
   491
					str_details2 = " export_restriction";
sl@0
   492
					break;
sl@0
   493
				case 70:
sl@0
   494
					str_details2 = " protocol_version";
sl@0
   495
					break;
sl@0
   496
				case 71:
sl@0
   497
					str_details2 = " insufficient_security";
sl@0
   498
					break;
sl@0
   499
				case 80:
sl@0
   500
					str_details2 = " internal_error";
sl@0
   501
					break;
sl@0
   502
				case 90:
sl@0
   503
					str_details2 = " user_canceled";
sl@0
   504
					break;
sl@0
   505
				case 100:
sl@0
   506
					str_details2 = " no_renegotiation";
sl@0
   507
					break;
sl@0
   508
					}
sl@0
   509
				}
sl@0
   510
			}
sl@0
   511
		
sl@0
   512
		if (content_type == 22) /* Handshake */
sl@0
   513
			{
sl@0
   514
			str_details1 = "???";
sl@0
   515
sl@0
   516
			if (len > 0)
sl@0
   517
				{
sl@0
   518
				switch (((const unsigned char*)buf)[0])
sl@0
   519
					{
sl@0
   520
				case 0:
sl@0
   521
					str_details1 = ", HelloRequest";
sl@0
   522
					break;
sl@0
   523
				case 1:
sl@0
   524
					str_details1 = ", ClientHello";
sl@0
   525
					break;
sl@0
   526
				case 2:
sl@0
   527
					str_details1 = ", ServerHello";
sl@0
   528
					break;
sl@0
   529
				case 11:
sl@0
   530
					str_details1 = ", Certificate";
sl@0
   531
					break;
sl@0
   532
				case 12:
sl@0
   533
					str_details1 = ", ServerKeyExchange";
sl@0
   534
					break;
sl@0
   535
				case 13:
sl@0
   536
					str_details1 = ", CertificateRequest";
sl@0
   537
					break;
sl@0
   538
				case 14:
sl@0
   539
					str_details1 = ", ServerHelloDone";
sl@0
   540
					break;
sl@0
   541
				case 15:
sl@0
   542
					str_details1 = ", CertificateVerify";
sl@0
   543
					break;
sl@0
   544
				case 16:
sl@0
   545
					str_details1 = ", ClientKeyExchange";
sl@0
   546
					break;
sl@0
   547
				case 20:
sl@0
   548
					str_details1 = ", Finished";
sl@0
   549
					break;
sl@0
   550
					}
sl@0
   551
				}
sl@0
   552
			}
sl@0
   553
		}
sl@0
   554
sl@0
   555
	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);
sl@0
   556
sl@0
   557
	if (len > 0)
sl@0
   558
		{
sl@0
   559
		size_t num, i;
sl@0
   560
		
sl@0
   561
		BIO_printf(bio, "   ");
sl@0
   562
		num = len;
sl@0
   563
#if 0
sl@0
   564
		if (num > 16)
sl@0
   565
			num = 16;
sl@0
   566
#endif
sl@0
   567
		for (i = 0; i < num; i++)
sl@0
   568
			{
sl@0
   569
			if (i % 16 == 0 && i > 0)
sl@0
   570
				BIO_printf(bio, "\n   ");
sl@0
   571
			BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]);
sl@0
   572
			}
sl@0
   573
		if (i < len)
sl@0
   574
			BIO_printf(bio, " ...");
sl@0
   575
		BIO_printf(bio, "\n");
sl@0
   576
		}
sl@0
   577
	(void)BIO_flush(bio);
sl@0
   578
	}
sl@0
   579
sl@0
   580
void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
sl@0
   581
					unsigned char *data, int len,
sl@0
   582
					void *arg)
sl@0
   583
	{
sl@0
   584
	BIO *bio = arg;
sl@0
   585
	char *extname;
sl@0
   586
sl@0
   587
	switch(type)
sl@0
   588
		{
sl@0
   589
		case TLSEXT_TYPE_server_name:
sl@0
   590
		extname = "server name";
sl@0
   591
		break;
sl@0
   592
sl@0
   593
		case TLSEXT_TYPE_max_fragment_length:
sl@0
   594
		extname = "max fragment length";
sl@0
   595
		break;
sl@0
   596
sl@0
   597
		case TLSEXT_TYPE_client_certificate_url:
sl@0
   598
		extname = "client certificate URL";
sl@0
   599
		break;
sl@0
   600
sl@0
   601
		case TLSEXT_TYPE_trusted_ca_keys:
sl@0
   602
		extname = "trusted CA keys";
sl@0
   603
		break;
sl@0
   604
sl@0
   605
		case TLSEXT_TYPE_truncated_hmac:
sl@0
   606
		extname = "truncated HMAC";
sl@0
   607
		break;
sl@0
   608
sl@0
   609
		case TLSEXT_TYPE_status_request:
sl@0
   610
		extname = "status request";
sl@0
   611
		break;
sl@0
   612
sl@0
   613
		case TLSEXT_TYPE_elliptic_curves:
sl@0
   614
		extname = "elliptic curves";
sl@0
   615
		break;
sl@0
   616
sl@0
   617
		case TLSEXT_TYPE_ec_point_formats:
sl@0
   618
		extname = "EC point formats";
sl@0
   619
		break;
sl@0
   620
sl@0
   621
		case TLSEXT_TYPE_session_ticket:
sl@0
   622
		extname = "server ticket";
sl@0
   623
		break;
sl@0
   624
sl@0
   625
sl@0
   626
		default:
sl@0
   627
		extname = "unknown";
sl@0
   628
		break;
sl@0
   629
sl@0
   630
		}
sl@0
   631
	
sl@0
   632
	BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
sl@0
   633
			client_server ? "server": "client",
sl@0
   634
			extname, type, len);
sl@0
   635
	BIO_dump(bio, (char *)data, len);
sl@0
   636
	(void)BIO_flush(bio);
sl@0
   637
	}