10Sstevel@tonic-gate /* apps/s_cb.c - callback functions used by s_client, s_server, and s_time */
20Sstevel@tonic-gate /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
30Sstevel@tonic-gate * All rights reserved.
40Sstevel@tonic-gate *
50Sstevel@tonic-gate * This package is an SSL implementation written
60Sstevel@tonic-gate * by Eric Young (eay@cryptsoft.com).
70Sstevel@tonic-gate * The implementation was written so as to conform with Netscapes SSL.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * This library is free for commercial and non-commercial use as long as
100Sstevel@tonic-gate * the following conditions are aheared to. The following conditions
110Sstevel@tonic-gate * apply to all code found in this distribution, be it the RC4, RSA,
120Sstevel@tonic-gate * lhash, DES, etc., code; not just the SSL code. The SSL documentation
130Sstevel@tonic-gate * included with this distribution is covered by the same copyright terms
140Sstevel@tonic-gate * except that the holder is Tim Hudson (tjh@cryptsoft.com).
150Sstevel@tonic-gate *
160Sstevel@tonic-gate * Copyright remains Eric Young's, and as such any Copyright notices in
170Sstevel@tonic-gate * the code are not to be removed.
180Sstevel@tonic-gate * If this package is used in a product, Eric Young should be given attribution
190Sstevel@tonic-gate * as the author of the parts of the library used.
200Sstevel@tonic-gate * This can be in the form of a textual message at program startup or
210Sstevel@tonic-gate * in documentation (online or textual) provided with the package.
220Sstevel@tonic-gate *
230Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
240Sstevel@tonic-gate * modification, are permitted provided that the following conditions
250Sstevel@tonic-gate * are met:
260Sstevel@tonic-gate * 1. Redistributions of source code must retain the copyright
270Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
280Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
290Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in the
300Sstevel@tonic-gate * documentation and/or other materials provided with the distribution.
310Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this software
320Sstevel@tonic-gate * must display the following acknowledgement:
330Sstevel@tonic-gate * "This product includes cryptographic software written by
340Sstevel@tonic-gate * Eric Young (eay@cryptsoft.com)"
350Sstevel@tonic-gate * The word 'cryptographic' can be left out if the rouines from the library
360Sstevel@tonic-gate * being used are not cryptographic related :-).
370Sstevel@tonic-gate * 4. If you include any Windows specific code (or a derivative thereof) from
380Sstevel@tonic-gate * the apps directory (application code) you must include an acknowledgement:
390Sstevel@tonic-gate * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
400Sstevel@tonic-gate *
410Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
420Sstevel@tonic-gate * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
430Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
440Sstevel@tonic-gate * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
450Sstevel@tonic-gate * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
460Sstevel@tonic-gate * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
470Sstevel@tonic-gate * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
480Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490Sstevel@tonic-gate * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
500Sstevel@tonic-gate * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
510Sstevel@tonic-gate * SUCH DAMAGE.
520Sstevel@tonic-gate *
530Sstevel@tonic-gate * The licence and distribution terms for any publically available version or
540Sstevel@tonic-gate * derivative of this code cannot be changed. i.e. this code cannot simply be
550Sstevel@tonic-gate * copied and put under another distribution licence
560Sstevel@tonic-gate * [including the GNU Public Licence.]
570Sstevel@tonic-gate */
580Sstevel@tonic-gate /* ====================================================================
590Sstevel@tonic-gate * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
600Sstevel@tonic-gate *
610Sstevel@tonic-gate * Redistribution and use in source and binary forms, with or without
620Sstevel@tonic-gate * modification, are permitted provided that the following conditions
630Sstevel@tonic-gate * are met:
640Sstevel@tonic-gate *
650Sstevel@tonic-gate * 1. Redistributions of source code must retain the above copyright
660Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer.
670Sstevel@tonic-gate *
680Sstevel@tonic-gate * 2. Redistributions in binary form must reproduce the above copyright
690Sstevel@tonic-gate * notice, this list of conditions and the following disclaimer in
700Sstevel@tonic-gate * the documentation and/or other materials provided with the
710Sstevel@tonic-gate * distribution.
720Sstevel@tonic-gate *
730Sstevel@tonic-gate * 3. All advertising materials mentioning features or use of this
740Sstevel@tonic-gate * software must display the following acknowledgment:
750Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
760Sstevel@tonic-gate * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
770Sstevel@tonic-gate *
780Sstevel@tonic-gate * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
790Sstevel@tonic-gate * endorse or promote products derived from this software without
800Sstevel@tonic-gate * prior written permission. For written permission, please contact
810Sstevel@tonic-gate * openssl-core@openssl.org.
820Sstevel@tonic-gate *
830Sstevel@tonic-gate * 5. Products derived from this software may not be called "OpenSSL"
840Sstevel@tonic-gate * nor may "OpenSSL" appear in their names without prior written
850Sstevel@tonic-gate * permission of the OpenSSL Project.
860Sstevel@tonic-gate *
870Sstevel@tonic-gate * 6. Redistributions of any form whatsoever must retain the following
880Sstevel@tonic-gate * acknowledgment:
890Sstevel@tonic-gate * "This product includes software developed by the OpenSSL Project
900Sstevel@tonic-gate * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
910Sstevel@tonic-gate *
920Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
930Sstevel@tonic-gate * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
940Sstevel@tonic-gate * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
950Sstevel@tonic-gate * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
960Sstevel@tonic-gate * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
970Sstevel@tonic-gate * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
980Sstevel@tonic-gate * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
990Sstevel@tonic-gate * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1000Sstevel@tonic-gate * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
1010Sstevel@tonic-gate * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1020Sstevel@tonic-gate * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
1030Sstevel@tonic-gate * OF THE POSSIBILITY OF SUCH DAMAGE.
1040Sstevel@tonic-gate * ====================================================================
1050Sstevel@tonic-gate *
1060Sstevel@tonic-gate * This product includes cryptographic software written by Eric Young
1070Sstevel@tonic-gate * (eay@cryptsoft.com). This product includes software written by Tim
1080Sstevel@tonic-gate * Hudson (tjh@cryptsoft.com).
1090Sstevel@tonic-gate *
1100Sstevel@tonic-gate */
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate #include <stdio.h>
1130Sstevel@tonic-gate #include <stdlib.h>
1140Sstevel@tonic-gate #define USE_SOCKETS
1150Sstevel@tonic-gate #define NON_MAIN
1160Sstevel@tonic-gate #include "apps.h"
1170Sstevel@tonic-gate #undef NON_MAIN
1180Sstevel@tonic-gate #undef USE_SOCKETS
1190Sstevel@tonic-gate #include <openssl/err.h>
1200Sstevel@tonic-gate #include <openssl/x509.h>
1210Sstevel@tonic-gate #include <openssl/ssl.h>
1220Sstevel@tonic-gate #include "s_apps.h"
1230Sstevel@tonic-gate
1240Sstevel@tonic-gate int verify_depth=0;
1250Sstevel@tonic-gate int verify_error=X509_V_OK;
1260Sstevel@tonic-gate
verify_callback(int ok,X509_STORE_CTX * ctx)1270Sstevel@tonic-gate int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx)
1280Sstevel@tonic-gate {
1290Sstevel@tonic-gate char buf[256];
1300Sstevel@tonic-gate X509 *err_cert;
1310Sstevel@tonic-gate int err,depth;
1320Sstevel@tonic-gate
1330Sstevel@tonic-gate err_cert=X509_STORE_CTX_get_current_cert(ctx);
1340Sstevel@tonic-gate err= X509_STORE_CTX_get_error(ctx);
1350Sstevel@tonic-gate depth= X509_STORE_CTX_get_error_depth(ctx);
1360Sstevel@tonic-gate
1370Sstevel@tonic-gate X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof buf);
1380Sstevel@tonic-gate BIO_printf(bio_err,"depth=%d %s\n",depth,buf);
1390Sstevel@tonic-gate if (!ok)
1400Sstevel@tonic-gate {
1410Sstevel@tonic-gate BIO_printf(bio_err,"verify error:num=%d:%s\n",err,
1420Sstevel@tonic-gate X509_verify_cert_error_string(err));
1430Sstevel@tonic-gate if (verify_depth >= depth)
1440Sstevel@tonic-gate {
1450Sstevel@tonic-gate ok=1;
1460Sstevel@tonic-gate verify_error=X509_V_OK;
1470Sstevel@tonic-gate }
1480Sstevel@tonic-gate else
1490Sstevel@tonic-gate {
1500Sstevel@tonic-gate ok=0;
1510Sstevel@tonic-gate verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
1520Sstevel@tonic-gate }
1530Sstevel@tonic-gate }
1540Sstevel@tonic-gate switch (ctx->error)
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
1570Sstevel@tonic-gate X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof buf);
1580Sstevel@tonic-gate BIO_printf(bio_err,"issuer= %s\n",buf);
1590Sstevel@tonic-gate break;
1600Sstevel@tonic-gate case X509_V_ERR_CERT_NOT_YET_VALID:
1610Sstevel@tonic-gate case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
1620Sstevel@tonic-gate BIO_printf(bio_err,"notBefore=");
1630Sstevel@tonic-gate ASN1_TIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
1640Sstevel@tonic-gate BIO_printf(bio_err,"\n");
1650Sstevel@tonic-gate break;
1660Sstevel@tonic-gate case X509_V_ERR_CERT_HAS_EXPIRED:
1670Sstevel@tonic-gate case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
1680Sstevel@tonic-gate BIO_printf(bio_err,"notAfter=");
1690Sstevel@tonic-gate ASN1_TIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
1700Sstevel@tonic-gate BIO_printf(bio_err,"\n");
1710Sstevel@tonic-gate break;
1720Sstevel@tonic-gate }
1730Sstevel@tonic-gate BIO_printf(bio_err,"verify return:%d\n",ok);
1740Sstevel@tonic-gate return(ok);
1750Sstevel@tonic-gate }
1760Sstevel@tonic-gate
set_cert_stuff(SSL_CTX * ctx,char * cert_file,char * key_file)1770Sstevel@tonic-gate int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file)
1780Sstevel@tonic-gate {
1790Sstevel@tonic-gate if (cert_file != NULL)
1800Sstevel@tonic-gate {
1810Sstevel@tonic-gate /*
1820Sstevel@tonic-gate SSL *ssl;
1830Sstevel@tonic-gate X509 *x509;
1840Sstevel@tonic-gate */
1850Sstevel@tonic-gate
1860Sstevel@tonic-gate if (SSL_CTX_use_certificate_file(ctx,cert_file,
1870Sstevel@tonic-gate SSL_FILETYPE_PEM) <= 0)
1880Sstevel@tonic-gate {
1890Sstevel@tonic-gate BIO_printf(bio_err,"unable to get certificate from '%s'\n",cert_file);
1900Sstevel@tonic-gate ERR_print_errors(bio_err);
1910Sstevel@tonic-gate return(0);
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate if (key_file == NULL) key_file=cert_file;
1940Sstevel@tonic-gate if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
1950Sstevel@tonic-gate SSL_FILETYPE_PEM) <= 0)
1960Sstevel@tonic-gate {
1970Sstevel@tonic-gate BIO_printf(bio_err,"unable to get private key from '%s'\n",key_file);
1980Sstevel@tonic-gate ERR_print_errors(bio_err);
1990Sstevel@tonic-gate return(0);
2000Sstevel@tonic-gate }
2010Sstevel@tonic-gate
2020Sstevel@tonic-gate /*
2030Sstevel@tonic-gate In theory this is no longer needed
2040Sstevel@tonic-gate ssl=SSL_new(ctx);
2050Sstevel@tonic-gate x509=SSL_get_certificate(ssl);
2060Sstevel@tonic-gate
2070Sstevel@tonic-gate if (x509 != NULL) {
2080Sstevel@tonic-gate EVP_PKEY *pktmp;
2090Sstevel@tonic-gate pktmp = X509_get_pubkey(x509);
2100Sstevel@tonic-gate EVP_PKEY_copy_parameters(pktmp,
2110Sstevel@tonic-gate SSL_get_privatekey(ssl));
2120Sstevel@tonic-gate EVP_PKEY_free(pktmp);
2130Sstevel@tonic-gate }
2140Sstevel@tonic-gate SSL_free(ssl);
2150Sstevel@tonic-gate */
2160Sstevel@tonic-gate
2170Sstevel@tonic-gate /* If we are using DSA, we can copy the parameters from
2180Sstevel@tonic-gate * the private key */
2190Sstevel@tonic-gate
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate /* Now we know that a key and cert have been set against
2220Sstevel@tonic-gate * the SSL context */
2230Sstevel@tonic-gate if (!SSL_CTX_check_private_key(ctx))
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate BIO_printf(bio_err,"Private key does not match the certificate public key\n");
2260Sstevel@tonic-gate return(0);
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate return(1);
2300Sstevel@tonic-gate }
2310Sstevel@tonic-gate
set_cert_key_stuff(SSL_CTX * ctx,X509 * cert,EVP_PKEY * key)232*2139Sjp161948 int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key)
233*2139Sjp161948 {
234*2139Sjp161948 if (cert == NULL)
235*2139Sjp161948 return 1;
236*2139Sjp161948 if (SSL_CTX_use_certificate(ctx,cert) <= 0)
237*2139Sjp161948 {
238*2139Sjp161948 BIO_printf(bio_err,"error setting certificate\n");
239*2139Sjp161948 ERR_print_errors(bio_err);
240*2139Sjp161948 return 0;
241*2139Sjp161948 }
242*2139Sjp161948 if (SSL_CTX_use_PrivateKey(ctx,key) <= 0)
243*2139Sjp161948 {
244*2139Sjp161948 BIO_printf(bio_err,"error setting private key\n");
245*2139Sjp161948 ERR_print_errors(bio_err);
246*2139Sjp161948 return 0;
247*2139Sjp161948 }
248*2139Sjp161948
249*2139Sjp161948
250*2139Sjp161948 /* Now we know that a key and cert have been set against
251*2139Sjp161948 * the SSL context */
252*2139Sjp161948 if (!SSL_CTX_check_private_key(ctx))
253*2139Sjp161948 {
254*2139Sjp161948 BIO_printf(bio_err,"Private key does not match the certificate public key\n");
255*2139Sjp161948 return 0;
256*2139Sjp161948 }
257*2139Sjp161948 return 1;
258*2139Sjp161948 }
259*2139Sjp161948
bio_dump_callback(BIO * bio,int cmd,const char * argp,int argi,long argl,long ret)260*2139Sjp161948 long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp,
261*2139Sjp161948 int argi, long argl, long ret)
2620Sstevel@tonic-gate {
2630Sstevel@tonic-gate BIO *out;
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate out=(BIO *)BIO_get_callback_arg(bio);
2660Sstevel@tonic-gate if (out == NULL) return(ret);
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate if (cmd == (BIO_CB_READ|BIO_CB_RETURN))
2690Sstevel@tonic-gate {
270*2139Sjp161948 BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n",
271*2139Sjp161948 (void *)bio,argp,argi,ret,ret);
2720Sstevel@tonic-gate BIO_dump(out,argp,(int)ret);
2730Sstevel@tonic-gate return(ret);
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN))
2760Sstevel@tonic-gate {
277*2139Sjp161948 BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n",
278*2139Sjp161948 (void *)bio,argp,argi,ret,ret);
2790Sstevel@tonic-gate BIO_dump(out,argp,(int)ret);
2800Sstevel@tonic-gate }
2810Sstevel@tonic-gate return(ret);
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate
apps_ssl_info_callback(const SSL * s,int where,int ret)2840Sstevel@tonic-gate void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
2850Sstevel@tonic-gate {
286*2139Sjp161948 const char *str;
2870Sstevel@tonic-gate int w;
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate w=where& ~SSL_ST_MASK;
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate if (w & SSL_ST_CONNECT) str="SSL_connect";
2920Sstevel@tonic-gate else if (w & SSL_ST_ACCEPT) str="SSL_accept";
2930Sstevel@tonic-gate else str="undefined";
2940Sstevel@tonic-gate
2950Sstevel@tonic-gate if (where & SSL_CB_LOOP)
2960Sstevel@tonic-gate {
2970Sstevel@tonic-gate BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s));
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate else if (where & SSL_CB_ALERT)
3000Sstevel@tonic-gate {
3010Sstevel@tonic-gate str=(where & SSL_CB_READ)?"read":"write";
3020Sstevel@tonic-gate BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n",
3030Sstevel@tonic-gate str,
3040Sstevel@tonic-gate SSL_alert_type_string_long(ret),
3050Sstevel@tonic-gate SSL_alert_desc_string_long(ret));
3060Sstevel@tonic-gate }
3070Sstevel@tonic-gate else if (where & SSL_CB_EXIT)
3080Sstevel@tonic-gate {
3090Sstevel@tonic-gate if (ret == 0)
3100Sstevel@tonic-gate BIO_printf(bio_err,"%s:failed in %s\n",
3110Sstevel@tonic-gate str,SSL_state_string_long(s));
3120Sstevel@tonic-gate else if (ret < 0)
3130Sstevel@tonic-gate {
3140Sstevel@tonic-gate BIO_printf(bio_err,"%s:error in %s\n",
3150Sstevel@tonic-gate str,SSL_state_string_long(s));
3160Sstevel@tonic-gate }
3170Sstevel@tonic-gate }
3180Sstevel@tonic-gate }
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate
msg_cb(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg)3210Sstevel@tonic-gate void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
3220Sstevel@tonic-gate {
3230Sstevel@tonic-gate BIO *bio = arg;
3240Sstevel@tonic-gate const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= "";
3250Sstevel@tonic-gate
3260Sstevel@tonic-gate str_write_p = write_p ? ">>>" : "<<<";
3270Sstevel@tonic-gate
3280Sstevel@tonic-gate switch (version)
3290Sstevel@tonic-gate {
3300Sstevel@tonic-gate case SSL2_VERSION:
3310Sstevel@tonic-gate str_version = "SSL 2.0";
3320Sstevel@tonic-gate break;
3330Sstevel@tonic-gate case SSL3_VERSION:
3340Sstevel@tonic-gate str_version = "SSL 3.0 ";
3350Sstevel@tonic-gate break;
3360Sstevel@tonic-gate case TLS1_VERSION:
3370Sstevel@tonic-gate str_version = "TLS 1.0 ";
3380Sstevel@tonic-gate break;
3390Sstevel@tonic-gate default:
3400Sstevel@tonic-gate str_version = "???";
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate if (version == SSL2_VERSION)
3440Sstevel@tonic-gate {
3450Sstevel@tonic-gate str_details1 = "???";
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate if (len > 0)
3480Sstevel@tonic-gate {
349*2139Sjp161948 switch (((const unsigned char*)buf)[0])
3500Sstevel@tonic-gate {
3510Sstevel@tonic-gate case 0:
3520Sstevel@tonic-gate str_details1 = ", ERROR:";
3530Sstevel@tonic-gate str_details2 = " ???";
3540Sstevel@tonic-gate if (len >= 3)
3550Sstevel@tonic-gate {
356*2139Sjp161948 unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2];
3570Sstevel@tonic-gate
3580Sstevel@tonic-gate switch (err)
3590Sstevel@tonic-gate {
3600Sstevel@tonic-gate case 0x0001:
3610Sstevel@tonic-gate str_details2 = " NO-CIPHER-ERROR";
3620Sstevel@tonic-gate break;
3630Sstevel@tonic-gate case 0x0002:
3640Sstevel@tonic-gate str_details2 = " NO-CERTIFICATE-ERROR";
3650Sstevel@tonic-gate break;
3660Sstevel@tonic-gate case 0x0004:
3670Sstevel@tonic-gate str_details2 = " BAD-CERTIFICATE-ERROR";
3680Sstevel@tonic-gate break;
3690Sstevel@tonic-gate case 0x0006:
3700Sstevel@tonic-gate str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
3710Sstevel@tonic-gate break;
3720Sstevel@tonic-gate }
3730Sstevel@tonic-gate }
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate break;
3760Sstevel@tonic-gate case 1:
3770Sstevel@tonic-gate str_details1 = ", CLIENT-HELLO";
3780Sstevel@tonic-gate break;
3790Sstevel@tonic-gate case 2:
3800Sstevel@tonic-gate str_details1 = ", CLIENT-MASTER-KEY";
3810Sstevel@tonic-gate break;
3820Sstevel@tonic-gate case 3:
3830Sstevel@tonic-gate str_details1 = ", CLIENT-FINISHED";
3840Sstevel@tonic-gate break;
3850Sstevel@tonic-gate case 4:
3860Sstevel@tonic-gate str_details1 = ", SERVER-HELLO";
3870Sstevel@tonic-gate break;
3880Sstevel@tonic-gate case 5:
3890Sstevel@tonic-gate str_details1 = ", SERVER-VERIFY";
3900Sstevel@tonic-gate break;
3910Sstevel@tonic-gate case 6:
3920Sstevel@tonic-gate str_details1 = ", SERVER-FINISHED";
3930Sstevel@tonic-gate break;
3940Sstevel@tonic-gate case 7:
3950Sstevel@tonic-gate str_details1 = ", REQUEST-CERTIFICATE";
3960Sstevel@tonic-gate break;
3970Sstevel@tonic-gate case 8:
3980Sstevel@tonic-gate str_details1 = ", CLIENT-CERTIFICATE";
3990Sstevel@tonic-gate break;
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate }
4020Sstevel@tonic-gate }
4030Sstevel@tonic-gate
4040Sstevel@tonic-gate if (version == SSL3_VERSION || version == TLS1_VERSION)
4050Sstevel@tonic-gate {
4060Sstevel@tonic-gate switch (content_type)
4070Sstevel@tonic-gate {
4080Sstevel@tonic-gate case 20:
4090Sstevel@tonic-gate str_content_type = "ChangeCipherSpec";
4100Sstevel@tonic-gate break;
4110Sstevel@tonic-gate case 21:
4120Sstevel@tonic-gate str_content_type = "Alert";
4130Sstevel@tonic-gate break;
4140Sstevel@tonic-gate case 22:
4150Sstevel@tonic-gate str_content_type = "Handshake";
4160Sstevel@tonic-gate break;
4170Sstevel@tonic-gate }
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate if (content_type == 21) /* Alert */
4200Sstevel@tonic-gate {
4210Sstevel@tonic-gate str_details1 = ", ???";
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate if (len == 2)
4240Sstevel@tonic-gate {
425*2139Sjp161948 switch (((const unsigned char*)buf)[0])
4260Sstevel@tonic-gate {
4270Sstevel@tonic-gate case 1:
4280Sstevel@tonic-gate str_details1 = ", warning";
4290Sstevel@tonic-gate break;
4300Sstevel@tonic-gate case 2:
4310Sstevel@tonic-gate str_details1 = ", fatal";
4320Sstevel@tonic-gate break;
4330Sstevel@tonic-gate }
4340Sstevel@tonic-gate
4350Sstevel@tonic-gate str_details2 = " ???";
436*2139Sjp161948 switch (((const unsigned char*)buf)[1])
4370Sstevel@tonic-gate {
4380Sstevel@tonic-gate case 0:
4390Sstevel@tonic-gate str_details2 = " close_notify";
4400Sstevel@tonic-gate break;
4410Sstevel@tonic-gate case 10:
4420Sstevel@tonic-gate str_details2 = " unexpected_message";
4430Sstevel@tonic-gate break;
4440Sstevel@tonic-gate case 20:
4450Sstevel@tonic-gate str_details2 = " bad_record_mac";
4460Sstevel@tonic-gate break;
4470Sstevel@tonic-gate case 21:
4480Sstevel@tonic-gate str_details2 = " decryption_failed";
4490Sstevel@tonic-gate break;
4500Sstevel@tonic-gate case 22:
4510Sstevel@tonic-gate str_details2 = " record_overflow";
4520Sstevel@tonic-gate break;
4530Sstevel@tonic-gate case 30:
4540Sstevel@tonic-gate str_details2 = " decompression_failure";
4550Sstevel@tonic-gate break;
4560Sstevel@tonic-gate case 40:
4570Sstevel@tonic-gate str_details2 = " handshake_failure";
4580Sstevel@tonic-gate break;
4590Sstevel@tonic-gate case 42:
4600Sstevel@tonic-gate str_details2 = " bad_certificate";
4610Sstevel@tonic-gate break;
4620Sstevel@tonic-gate case 43:
4630Sstevel@tonic-gate str_details2 = " unsupported_certificate";
4640Sstevel@tonic-gate break;
4650Sstevel@tonic-gate case 44:
4660Sstevel@tonic-gate str_details2 = " certificate_revoked";
4670Sstevel@tonic-gate break;
4680Sstevel@tonic-gate case 45:
4690Sstevel@tonic-gate str_details2 = " certificate_expired";
4700Sstevel@tonic-gate break;
4710Sstevel@tonic-gate case 46:
4720Sstevel@tonic-gate str_details2 = " certificate_unknown";
4730Sstevel@tonic-gate break;
4740Sstevel@tonic-gate case 47:
4750Sstevel@tonic-gate str_details2 = " illegal_parameter";
4760Sstevel@tonic-gate break;
4770Sstevel@tonic-gate case 48:
4780Sstevel@tonic-gate str_details2 = " unknown_ca";
4790Sstevel@tonic-gate break;
4800Sstevel@tonic-gate case 49:
4810Sstevel@tonic-gate str_details2 = " access_denied";
4820Sstevel@tonic-gate break;
4830Sstevel@tonic-gate case 50:
4840Sstevel@tonic-gate str_details2 = " decode_error";
4850Sstevel@tonic-gate break;
4860Sstevel@tonic-gate case 51:
4870Sstevel@tonic-gate str_details2 = " decrypt_error";
4880Sstevel@tonic-gate break;
4890Sstevel@tonic-gate case 60:
4900Sstevel@tonic-gate str_details2 = " export_restriction";
4910Sstevel@tonic-gate break;
4920Sstevel@tonic-gate case 70:
4930Sstevel@tonic-gate str_details2 = " protocol_version";
4940Sstevel@tonic-gate break;
4950Sstevel@tonic-gate case 71:
4960Sstevel@tonic-gate str_details2 = " insufficient_security";
4970Sstevel@tonic-gate break;
4980Sstevel@tonic-gate case 80:
4990Sstevel@tonic-gate str_details2 = " internal_error";
5000Sstevel@tonic-gate break;
5010Sstevel@tonic-gate case 90:
5020Sstevel@tonic-gate str_details2 = " user_canceled";
5030Sstevel@tonic-gate break;
5040Sstevel@tonic-gate case 100:
5050Sstevel@tonic-gate str_details2 = " no_renegotiation";
5060Sstevel@tonic-gate break;
5070Sstevel@tonic-gate }
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate if (content_type == 22) /* Handshake */
5120Sstevel@tonic-gate {
5130Sstevel@tonic-gate str_details1 = "???";
5140Sstevel@tonic-gate
5150Sstevel@tonic-gate if (len > 0)
5160Sstevel@tonic-gate {
517*2139Sjp161948 switch (((const unsigned char*)buf)[0])
5180Sstevel@tonic-gate {
5190Sstevel@tonic-gate case 0:
5200Sstevel@tonic-gate str_details1 = ", HelloRequest";
5210Sstevel@tonic-gate break;
5220Sstevel@tonic-gate case 1:
5230Sstevel@tonic-gate str_details1 = ", ClientHello";
5240Sstevel@tonic-gate break;
5250Sstevel@tonic-gate case 2:
5260Sstevel@tonic-gate str_details1 = ", ServerHello";
5270Sstevel@tonic-gate break;
5280Sstevel@tonic-gate case 11:
5290Sstevel@tonic-gate str_details1 = ", Certificate";
5300Sstevel@tonic-gate break;
5310Sstevel@tonic-gate case 12:
5320Sstevel@tonic-gate str_details1 = ", ServerKeyExchange";
5330Sstevel@tonic-gate break;
5340Sstevel@tonic-gate case 13:
5350Sstevel@tonic-gate str_details1 = ", CertificateRequest";
5360Sstevel@tonic-gate break;
5370Sstevel@tonic-gate case 14:
5380Sstevel@tonic-gate str_details1 = ", ServerHelloDone";
5390Sstevel@tonic-gate break;
5400Sstevel@tonic-gate case 15:
5410Sstevel@tonic-gate str_details1 = ", CertificateVerify";
5420Sstevel@tonic-gate break;
5430Sstevel@tonic-gate case 16:
5440Sstevel@tonic-gate str_details1 = ", ClientKeyExchange";
5450Sstevel@tonic-gate break;
5460Sstevel@tonic-gate case 20:
5470Sstevel@tonic-gate str_details1 = ", Finished";
5480Sstevel@tonic-gate break;
5490Sstevel@tonic-gate }
5500Sstevel@tonic-gate }
5510Sstevel@tonic-gate }
5520Sstevel@tonic-gate }
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate 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);
5550Sstevel@tonic-gate
5560Sstevel@tonic-gate if (len > 0)
5570Sstevel@tonic-gate {
5580Sstevel@tonic-gate size_t num, i;
5590Sstevel@tonic-gate
5600Sstevel@tonic-gate BIO_printf(bio, " ");
5610Sstevel@tonic-gate num = len;
5620Sstevel@tonic-gate #if 0
5630Sstevel@tonic-gate if (num > 16)
5640Sstevel@tonic-gate num = 16;
5650Sstevel@tonic-gate #endif
5660Sstevel@tonic-gate for (i = 0; i < num; i++)
5670Sstevel@tonic-gate {
5680Sstevel@tonic-gate if (i % 16 == 0 && i > 0)
5690Sstevel@tonic-gate BIO_printf(bio, "\n ");
570*2139Sjp161948 BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]);
5710Sstevel@tonic-gate }
5720Sstevel@tonic-gate if (i < len)
5730Sstevel@tonic-gate BIO_printf(bio, " ...");
5740Sstevel@tonic-gate BIO_printf(bio, "\n");
5750Sstevel@tonic-gate }
5760Sstevel@tonic-gate BIO_flush(bio);
5770Sstevel@tonic-gate }
578