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 232int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key) 233 { 234 if (cert == NULL) 235 return 1; 236 if (SSL_CTX_use_certificate(ctx,cert) <= 0) 237 { 238 BIO_printf(bio_err,"error setting certificate\n"); 239 ERR_print_errors(bio_err); 240 return 0; 241 } 242 if (SSL_CTX_use_PrivateKey(ctx,key) <= 0) 243 { 244 BIO_printf(bio_err,"error setting private key\n"); 245 ERR_print_errors(bio_err); 246 return 0; 247 } 248 249 250 /* Now we know that a key and cert have been set against 251 * the SSL context */ 252 if (!SSL_CTX_check_private_key(ctx)) 253 { 254 BIO_printf(bio_err,"Private key does not match the certificate public key\n"); 255 return 0; 256 } 257 return 1; 258 } 259 260long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, 261 int argi, long argl, long ret) 262 { 263 BIO *out; 264 265 out=(BIO *)BIO_get_callback_arg(bio); 266 if (out == NULL) return(ret); 267 268 if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) 269 { 270 BIO_printf(out,"read from %p [%p] (%d bytes => %ld (0x%lX))\n", 271 (void *)bio,argp,argi,ret,ret); 272 BIO_dump(out,argp,(int)ret); 273 return(ret); 274 } 275 else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) 276 { 277 BIO_printf(out,"write to %p [%p] (%d bytes => %ld (0x%lX))\n", 278 (void *)bio,argp,argi,ret,ret); 279 BIO_dump(out,argp,(int)ret); 280 } 281 return(ret); 282 } 283 284void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret) 285 { 286 const char *str; 287 int w; 288 289 w=where& ~SSL_ST_MASK; 290 291 if (w & SSL_ST_CONNECT) str="SSL_connect"; 292 else if (w & SSL_ST_ACCEPT) str="SSL_accept"; 293 else str="undefined"; 294 295 if (where & SSL_CB_LOOP) 296 { 297 BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s)); 298 } 299 else if (where & SSL_CB_ALERT) 300 { 301 str=(where & SSL_CB_READ)?"read":"write"; 302 BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n", 303 str, 304 SSL_alert_type_string_long(ret), 305 SSL_alert_desc_string_long(ret)); 306 } 307 else if (where & SSL_CB_EXIT) 308 { 309 if (ret == 0) 310 BIO_printf(bio_err,"%s:failed in %s\n", 311 str,SSL_state_string_long(s)); 312 else if (ret < 0) 313 { 314 BIO_printf(bio_err,"%s:error in %s\n", 315 str,SSL_state_string_long(s)); 316 } 317 } 318 } 319 320 321void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) 322 { 323 BIO *bio = arg; 324 const char *str_write_p, *str_version, *str_content_type = "", *str_details1 = "", *str_details2= ""; 325 326 str_write_p = write_p ? ">>>" : "<<<"; 327 328 switch (version) 329 { 330 case SSL2_VERSION: 331 str_version = "SSL 2.0"; 332 break; 333 case SSL3_VERSION: 334 str_version = "SSL 3.0 "; 335 break; 336 case TLS1_VERSION: 337 str_version = "TLS 1.0 "; 338 break; 339 default: 340 str_version = "???"; 341 } 342 343 if (version == SSL2_VERSION) 344 { 345 str_details1 = "???"; 346 347 if (len > 0) 348 { 349 switch (((const unsigned char*)buf)[0]) 350 { 351 case 0: 352 str_details1 = ", ERROR:"; 353 str_details2 = " ???"; 354 if (len >= 3) 355 { 356 unsigned err = (((const unsigned char*)buf)[1]<<8) + ((const unsigned char*)buf)[2]; 357 358 switch (err) 359 { 360 case 0x0001: 361 str_details2 = " NO-CIPHER-ERROR"; 362 break; 363 case 0x0002: 364 str_details2 = " NO-CERTIFICATE-ERROR"; 365 break; 366 case 0x0004: 367 str_details2 = " BAD-CERTIFICATE-ERROR"; 368 break; 369 case 0x0006: 370 str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR"; 371 break; 372 } 373 } 374 375 break; 376 case 1: 377 str_details1 = ", CLIENT-HELLO"; 378 break; 379 case 2: 380 str_details1 = ", CLIENT-MASTER-KEY"; 381 break; 382 case 3: 383 str_details1 = ", CLIENT-FINISHED"; 384 break; 385 case 4: 386 str_details1 = ", SERVER-HELLO"; 387 break; 388 case 5: 389 str_details1 = ", SERVER-VERIFY"; 390 break; 391 case 6: 392 str_details1 = ", SERVER-FINISHED"; 393 break; 394 case 7: 395 str_details1 = ", REQUEST-CERTIFICATE"; 396 break; 397 case 8: 398 str_details1 = ", CLIENT-CERTIFICATE"; 399 break; 400 } 401 } 402 } 403 404 if (version == SSL3_VERSION || version == TLS1_VERSION) 405 { 406 switch (content_type) 407 { 408 case 20: 409 str_content_type = "ChangeCipherSpec"; 410 break; 411 case 21: 412 str_content_type = "Alert"; 413 break; 414 case 22: 415 str_content_type = "Handshake"; 416 break; 417 } 418 419 if (content_type == 21) /* Alert */ 420 { 421 str_details1 = ", ???"; 422 423 if (len == 2) 424 { 425 switch (((const unsigned char*)buf)[0]) 426 { 427 case 1: 428 str_details1 = ", warning"; 429 break; 430 case 2: 431 str_details1 = ", fatal"; 432 break; 433 } 434 435 str_details2 = " ???"; 436 switch (((const unsigned char*)buf)[1]) 437 { 438 case 0: 439 str_details2 = " close_notify"; 440 break; 441 case 10: 442 str_details2 = " unexpected_message"; 443 break; 444 case 20: 445 str_details2 = " bad_record_mac"; 446 break; 447 case 21: 448 str_details2 = " decryption_failed"; 449 break; 450 case 22: 451 str_details2 = " record_overflow"; 452 break; 453 case 30: 454 str_details2 = " decompression_failure"; 455 break; 456 case 40: 457 str_details2 = " handshake_failure"; 458 break; 459 case 42: 460 str_details2 = " bad_certificate"; 461 break; 462 case 43: 463 str_details2 = " unsupported_certificate"; 464 break; 465 case 44: 466 str_details2 = " certificate_revoked"; 467 break; 468 case 45: 469 str_details2 = " certificate_expired"; 470 break; 471 case 46: 472 str_details2 = " certificate_unknown"; 473 break; 474 case 47: 475 str_details2 = " illegal_parameter"; 476 break; 477 case 48: 478 str_details2 = " unknown_ca"; 479 break; 480 case 49: 481 str_details2 = " access_denied"; 482 break; 483 case 50: 484 str_details2 = " decode_error"; 485 break; 486 case 51: 487 str_details2 = " decrypt_error"; 488 break; 489 case 60: 490 str_details2 = " export_restriction"; 491 break; 492 case 70: 493 str_details2 = " protocol_version"; 494 break; 495 case 71: 496 str_details2 = " insufficient_security"; 497 break; 498 case 80: 499 str_details2 = " internal_error"; 500 break; 501 case 90: 502 str_details2 = " user_canceled"; 503 break; 504 case 100: 505 str_details2 = " no_renegotiation"; 506 break; 507 } 508 } 509 } 510 511 if (content_type == 22) /* Handshake */ 512 { 513 str_details1 = "???"; 514 515 if (len > 0) 516 { 517 switch (((const unsigned char*)buf)[0]) 518 { 519 case 0: 520 str_details1 = ", HelloRequest"; 521 break; 522 case 1: 523 str_details1 = ", ClientHello"; 524 break; 525 case 2: 526 str_details1 = ", ServerHello"; 527 break; 528 case 11: 529 str_details1 = ", Certificate"; 530 break; 531 case 12: 532 str_details1 = ", ServerKeyExchange"; 533 break; 534 case 13: 535 str_details1 = ", CertificateRequest"; 536 break; 537 case 14: 538 str_details1 = ", ServerHelloDone"; 539 break; 540 case 15: 541 str_details1 = ", CertificateVerify"; 542 break; 543 case 16: 544 str_details1 = ", ClientKeyExchange"; 545 break; 546 case 20: 547 str_details1 = ", Finished"; 548 break; 549 } 550 } 551 } 552 } 553 554 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); 555 556 if (len > 0) 557 { 558 size_t num, i; 559 560 BIO_printf(bio, " "); 561 num = len; 562#if 0 563 if (num > 16) 564 num = 16; 565#endif 566 for (i = 0; i < num; i++) 567 { 568 if (i % 16 == 0 && i > 0) 569 BIO_printf(bio, "\n "); 570 BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i]); 571 } 572 if (i < len) 573 BIO_printf(bio, " ..."); 574 BIO_printf(bio, "\n"); 575 } 576 BIO_flush(bio); 577 } 578