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