| OLD | NEW |
| (Empty) |
| 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-2006 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/rand.h> | |
| 121 #include <openssl/x509.h> | |
| 122 #include <openssl/ssl.h> | |
| 123 #include "s_apps.h" | |
| 124 | |
| 125 #define COOKIE_SECRET_LENGTH 16 | |
| 126 | |
| 127 int verify_depth=0; | |
| 128 int verify_error=X509_V_OK; | |
| 129 int verify_return_error=0; | |
| 130 unsigned char cookie_secret[COOKIE_SECRET_LENGTH]; | |
| 131 int cookie_initialized=0; | |
| 132 | |
| 133 int MS_CALLBACK verify_callback(int ok, X509_STORE_CTX *ctx) | |
| 134 { | |
| 135 X509 *err_cert; | |
| 136 int err,depth; | |
| 137 | |
| 138 err_cert=X509_STORE_CTX_get_current_cert(ctx); | |
| 139 err= X509_STORE_CTX_get_error(ctx); | |
| 140 depth= X509_STORE_CTX_get_error_depth(ctx); | |
| 141 | |
| 142 BIO_printf(bio_err,"depth=%d ",depth); | |
| 143 if (err_cert) | |
| 144 { | |
| 145 X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert), | |
| 146 0, XN_FLAG_ONELINE); | |
| 147 BIO_puts(bio_err, "\n"); | |
| 148 } | |
| 149 else | |
| 150 BIO_puts(bio_err, "<no cert>\n"); | |
| 151 if (!ok) | |
| 152 { | |
| 153 BIO_printf(bio_err,"verify error:num=%d:%s\n",err, | |
| 154 X509_verify_cert_error_string(err)); | |
| 155 if (verify_depth >= depth) | |
| 156 { | |
| 157 if (!verify_return_error) | |
| 158 ok=1; | |
| 159 verify_error=X509_V_OK; | |
| 160 } | |
| 161 else | |
| 162 { | |
| 163 ok=0; | |
| 164 verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG; | |
| 165 } | |
| 166 } | |
| 167 switch (err) | |
| 168 { | |
| 169 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: | |
| 170 BIO_puts(bio_err,"issuer= "); | |
| 171 X509_NAME_print_ex(bio_err, X509_get_issuer_name(err_cert), | |
| 172 0, XN_FLAG_ONELINE); | |
| 173 BIO_puts(bio_err, "\n"); | |
| 174 break; | |
| 175 case X509_V_ERR_CERT_NOT_YET_VALID: | |
| 176 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: | |
| 177 BIO_printf(bio_err,"notBefore="); | |
| 178 ASN1_TIME_print(bio_err,X509_get_notBefore(err_cert)); | |
| 179 BIO_printf(bio_err,"\n"); | |
| 180 break; | |
| 181 case X509_V_ERR_CERT_HAS_EXPIRED: | |
| 182 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: | |
| 183 BIO_printf(bio_err,"notAfter="); | |
| 184 ASN1_TIME_print(bio_err,X509_get_notAfter(err_cert)); | |
| 185 BIO_printf(bio_err,"\n"); | |
| 186 break; | |
| 187 case X509_V_ERR_NO_EXPLICIT_POLICY: | |
| 188 policies_print(bio_err, ctx); | |
| 189 break; | |
| 190 } | |
| 191 if (err == X509_V_OK && ok == 2) | |
| 192 policies_print(bio_err, ctx); | |
| 193 | |
| 194 BIO_printf(bio_err,"verify return:%d\n",ok); | |
| 195 return(ok); | |
| 196 } | |
| 197 | |
| 198 int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file) | |
| 199 { | |
| 200 if (cert_file != NULL) | |
| 201 { | |
| 202 /* | |
| 203 SSL *ssl; | |
| 204 X509 *x509; | |
| 205 */ | |
| 206 | |
| 207 if (SSL_CTX_use_certificate_file(ctx,cert_file, | |
| 208 SSL_FILETYPE_PEM) <= 0) | |
| 209 { | |
| 210 BIO_printf(bio_err,"unable to get certificate from '%s'\
n",cert_file); | |
| 211 ERR_print_errors(bio_err); | |
| 212 return(0); | |
| 213 } | |
| 214 if (key_file == NULL) key_file=cert_file; | |
| 215 if (SSL_CTX_use_PrivateKey_file(ctx,key_file, | |
| 216 SSL_FILETYPE_PEM) <= 0) | |
| 217 { | |
| 218 BIO_printf(bio_err,"unable to get private key from '%s'\
n",key_file); | |
| 219 ERR_print_errors(bio_err); | |
| 220 return(0); | |
| 221 } | |
| 222 | |
| 223 /* | |
| 224 In theory this is no longer needed | |
| 225 ssl=SSL_new(ctx); | |
| 226 x509=SSL_get_certificate(ssl); | |
| 227 | |
| 228 if (x509 != NULL) { | |
| 229 EVP_PKEY *pktmp; | |
| 230 pktmp = X509_get_pubkey(x509); | |
| 231 EVP_PKEY_copy_parameters(pktmp, | |
| 232 SSL_get_privatekey(ssl)); | |
| 233 EVP_PKEY_free(pktmp); | |
| 234 } | |
| 235 SSL_free(ssl); | |
| 236 */ | |
| 237 | |
| 238 /* If we are using DSA, we can copy the parameters from | |
| 239 * the private key */ | |
| 240 | |
| 241 | |
| 242 /* Now we know that a key and cert have been set against | |
| 243 * the SSL context */ | |
| 244 if (!SSL_CTX_check_private_key(ctx)) | |
| 245 { | |
| 246 BIO_printf(bio_err,"Private key does not match the certi
ficate public key\n"); | |
| 247 return(0); | |
| 248 } | |
| 249 } | |
| 250 return(1); | |
| 251 } | |
| 252 | |
| 253 int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key) | |
| 254 { | |
| 255 if (cert == NULL) | |
| 256 return 1; | |
| 257 if (SSL_CTX_use_certificate(ctx,cert) <= 0) | |
| 258 { | |
| 259 BIO_printf(bio_err,"error setting certificate\n"); | |
| 260 ERR_print_errors(bio_err); | |
| 261 return 0; | |
| 262 } | |
| 263 if (SSL_CTX_use_PrivateKey(ctx,key) <= 0) | |
| 264 { | |
| 265 BIO_printf(bio_err,"error setting private key\n"); | |
| 266 ERR_print_errors(bio_err); | |
| 267 return 0; | |
| 268 } | |
| 269 | |
| 270 | |
| 271 /* Now we know that a key and cert have been set against | |
| 272 * the SSL context */ | |
| 273 if (!SSL_CTX_check_private_key(ctx)) | |
| 274 { | |
| 275 BIO_printf(bio_err,"Private key does not match the certificate p
ublic key\n"); | |
| 276 return 0; | |
| 277 } | |
| 278 return 1; | |
| 279 } | |
| 280 | |
| 281 long MS_CALLBACK bio_dump_callback(BIO *bio, int cmd, const char *argp, | |
| 282 int argi, long argl, long ret) | |
| 283 { | |
| 284 BIO *out; | |
| 285 | |
| 286 out=(BIO *)BIO_get_callback_arg(bio); | |
| 287 if (out == NULL) return(ret); | |
| 288 | |
| 289 if (cmd == (BIO_CB_READ|BIO_CB_RETURN)) | |
| 290 { | |
| 291 BIO_printf(out,"read from %p [%p] (%lu bytes => %ld (0x%lX))\n", | |
| 292 (void *)bio,argp,(unsigned long)argi,ret,ret); | |
| 293 BIO_dump(out,argp,(int)ret); | |
| 294 return(ret); | |
| 295 } | |
| 296 else if (cmd == (BIO_CB_WRITE|BIO_CB_RETURN)) | |
| 297 { | |
| 298 BIO_printf(out,"write to %p [%p] (%lu bytes => %ld (0x%lX))\n", | |
| 299 (void *)bio,argp,(unsigned long)argi,ret,ret); | |
| 300 BIO_dump(out,argp,(int)ret); | |
| 301 } | |
| 302 return(ret); | |
| 303 } | |
| 304 | |
| 305 void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret) | |
| 306 { | |
| 307 const char *str; | |
| 308 int w; | |
| 309 | |
| 310 w=where& ~SSL_ST_MASK; | |
| 311 | |
| 312 if (w & SSL_ST_CONNECT) str="SSL_connect"; | |
| 313 else if (w & SSL_ST_ACCEPT) str="SSL_accept"; | |
| 314 else str="undefined"; | |
| 315 | |
| 316 if (where & SSL_CB_LOOP) | |
| 317 { | |
| 318 BIO_printf(bio_err,"%s:%s\n",str,SSL_state_string_long(s)); | |
| 319 } | |
| 320 else if (where & SSL_CB_ALERT) | |
| 321 { | |
| 322 str=(where & SSL_CB_READ)?"read":"write"; | |
| 323 BIO_printf(bio_err,"SSL3 alert %s:%s:%s\n", | |
| 324 str, | |
| 325 SSL_alert_type_string_long(ret), | |
| 326 SSL_alert_desc_string_long(ret)); | |
| 327 } | |
| 328 else if (where & SSL_CB_EXIT) | |
| 329 { | |
| 330 if (ret == 0) | |
| 331 BIO_printf(bio_err,"%s:failed in %s\n", | |
| 332 str,SSL_state_string_long(s)); | |
| 333 else if (ret < 0) | |
| 334 { | |
| 335 BIO_printf(bio_err,"%s:error in %s\n", | |
| 336 str,SSL_state_string_long(s)); | |
| 337 } | |
| 338 } | |
| 339 } | |
| 340 | |
| 341 | |
| 342 void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *
buf, size_t len, SSL *ssl, void *arg) | |
| 343 { | |
| 344 BIO *bio = arg; | |
| 345 const char *str_write_p, *str_version, *str_content_type = "", *str_deta
ils1 = "", *str_details2= ""; | |
| 346 | |
| 347 str_write_p = write_p ? ">>>" : "<<<"; | |
| 348 | |
| 349 switch (version) | |
| 350 { | |
| 351 case SSL2_VERSION: | |
| 352 str_version = "SSL 2.0"; | |
| 353 break; | |
| 354 case SSL3_VERSION: | |
| 355 str_version = "SSL 3.0 "; | |
| 356 break; | |
| 357 case TLS1_VERSION: | |
| 358 str_version = "TLS 1.0 "; | |
| 359 break; | |
| 360 case TLS1_1_VERSION: | |
| 361 str_version = "TLS 1.1 "; | |
| 362 break; | |
| 363 case TLS1_2_VERSION: | |
| 364 str_version = "TLS 1.2 "; | |
| 365 break; | |
| 366 case DTLS1_VERSION: | |
| 367 str_version = "DTLS 1.0 "; | |
| 368 break; | |
| 369 case DTLS1_BAD_VER: | |
| 370 str_version = "DTLS 1.0 (bad) "; | |
| 371 break; | |
| 372 default: | |
| 373 str_version = "???"; | |
| 374 } | |
| 375 | |
| 376 if (version == SSL2_VERSION) | |
| 377 { | |
| 378 str_details1 = "???"; | |
| 379 | |
| 380 if (len > 0) | |
| 381 { | |
| 382 switch (((const unsigned char*)buf)[0]) | |
| 383 { | |
| 384 case 0: | |
| 385 str_details1 = ", ERROR:"; | |
| 386 str_details2 = " ???"; | |
| 387 if (len >= 3) | |
| 388 { | |
| 389 unsigned err = (((const unsigned
char*)buf)[1]<<8) + ((const unsigned char*)buf)[2]; | |
| 390 | |
| 391 switch (err) | |
| 392 { | |
| 393 case 0x0001: | |
| 394 str_details2 = " NO-CIPH
ER-ERROR"; | |
| 395 break; | |
| 396 case 0x0002: | |
| 397 str_details2 = " NO-CERT
IFICATE-ERROR"; | |
| 398 break; | |
| 399 case 0x0004: | |
| 400 str_details2 = " BAD-CER
TIFICATE-ERROR"; | |
| 401 break; | |
| 402 case 0x0006: | |
| 403 str_details2 = " UNSUPPO
RTED-CERTIFICATE-TYPE-ERROR"; | |
| 404 break; | |
| 405 } | |
| 406 } | |
| 407 | |
| 408 break; | |
| 409 case 1: | |
| 410 str_details1 = ", CLIENT-HELLO"; | |
| 411 break; | |
| 412 case 2: | |
| 413 str_details1 = ", CLIENT-MASTER-KEY"; | |
| 414 break; | |
| 415 case 3: | |
| 416 str_details1 = ", CLIENT-FINISHED"; | |
| 417 break; | |
| 418 case 4: | |
| 419 str_details1 = ", SERVER-HELLO"; | |
| 420 break; | |
| 421 case 5: | |
| 422 str_details1 = ", SERVER-VERIFY"; | |
| 423 break; | |
| 424 case 6: | |
| 425 str_details1 = ", SERVER-FINISHED"; | |
| 426 break; | |
| 427 case 7: | |
| 428 str_details1 = ", REQUEST-CERTIFICATE"; | |
| 429 break; | |
| 430 case 8: | |
| 431 str_details1 = ", CLIENT-CERTIFICATE"; | |
| 432 break; | |
| 433 } | |
| 434 } | |
| 435 } | |
| 436 | |
| 437 if (version == SSL3_VERSION || | |
| 438 version == TLS1_VERSION || | |
| 439 version == TLS1_1_VERSION || | |
| 440 version == TLS1_2_VERSION || | |
| 441 version == DTLS1_VERSION || | |
| 442 version == DTLS1_BAD_VER) | |
| 443 { | |
| 444 switch (content_type) | |
| 445 { | |
| 446 case 20: | |
| 447 str_content_type = "ChangeCipherSpec"; | |
| 448 break; | |
| 449 case 21: | |
| 450 str_content_type = "Alert"; | |
| 451 break; | |
| 452 case 22: | |
| 453 str_content_type = "Handshake"; | |
| 454 break; | |
| 455 } | |
| 456 | |
| 457 if (content_type == 21) /* Alert */ | |
| 458 { | |
| 459 str_details1 = ", ???"; | |
| 460 | |
| 461 if (len == 2) | |
| 462 { | |
| 463 switch (((const unsigned char*)buf)[0]) | |
| 464 { | |
| 465 case 1: | |
| 466 str_details1 = ", warning"; | |
| 467 break; | |
| 468 case 2: | |
| 469 str_details1 = ", fatal"; | |
| 470 break; | |
| 471 } | |
| 472 | |
| 473 str_details2 = " ???"; | |
| 474 switch (((const unsigned char*)buf)[1]) | |
| 475 { | |
| 476 case 0: | |
| 477 str_details2 = " close_notify"; | |
| 478 break; | |
| 479 case 10: | |
| 480 str_details2 = " unexpected_message"; | |
| 481 break; | |
| 482 case 20: | |
| 483 str_details2 = " bad_record_mac"; | |
| 484 break; | |
| 485 case 21: | |
| 486 str_details2 = " decryption_failed"; | |
| 487 break; | |
| 488 case 22: | |
| 489 str_details2 = " record_overflow"; | |
| 490 break; | |
| 491 case 30: | |
| 492 str_details2 = " decompression_failure"; | |
| 493 break; | |
| 494 case 40: | |
| 495 str_details2 = " handshake_failure"; | |
| 496 break; | |
| 497 case 42: | |
| 498 str_details2 = " bad_certificate"; | |
| 499 break; | |
| 500 case 43: | |
| 501 str_details2 = " unsupported_certificate
"; | |
| 502 break; | |
| 503 case 44: | |
| 504 str_details2 = " certificate_revoked"; | |
| 505 break; | |
| 506 case 45: | |
| 507 str_details2 = " certificate_expired"; | |
| 508 break; | |
| 509 case 46: | |
| 510 str_details2 = " certificate_unknown"; | |
| 511 break; | |
| 512 case 47: | |
| 513 str_details2 = " illegal_parameter"; | |
| 514 break; | |
| 515 case 48: | |
| 516 str_details2 = " unknown_ca"; | |
| 517 break; | |
| 518 case 49: | |
| 519 str_details2 = " access_denied"; | |
| 520 break; | |
| 521 case 50: | |
| 522 str_details2 = " decode_error"; | |
| 523 break; | |
| 524 case 51: | |
| 525 str_details2 = " decrypt_error"; | |
| 526 break; | |
| 527 case 60: | |
| 528 str_details2 = " export_restriction"; | |
| 529 break; | |
| 530 case 70: | |
| 531 str_details2 = " protocol_version"; | |
| 532 break; | |
| 533 case 71: | |
| 534 str_details2 = " insufficient_security"; | |
| 535 break; | |
| 536 case 80: | |
| 537 str_details2 = " internal_error"; | |
| 538 break; | |
| 539 case 90: | |
| 540 str_details2 = " user_canceled"; | |
| 541 break; | |
| 542 case 100: | |
| 543 str_details2 = " no_renegotiation"; | |
| 544 break; | |
| 545 case 110: | |
| 546 str_details2 = " unsupported_extension"; | |
| 547 break; | |
| 548 case 111: | |
| 549 str_details2 = " certificate_unobtainabl
e"; | |
| 550 break; | |
| 551 case 112: | |
| 552 str_details2 = " unrecognized_name"; | |
| 553 break; | |
| 554 case 113: | |
| 555 str_details2 = " bad_certificate_status_
response"; | |
| 556 break; | |
| 557 case 114: | |
| 558 str_details2 = " bad_certificate_hash_va
lue"; | |
| 559 break; | |
| 560 case 115: | |
| 561 str_details2 = " unknown_psk_identity"; | |
| 562 break; | |
| 563 } | |
| 564 } | |
| 565 } | |
| 566 | |
| 567 if (content_type == 22) /* Handshake */ | |
| 568 { | |
| 569 str_details1 = "???"; | |
| 570 | |
| 571 if (len > 0) | |
| 572 { | |
| 573 switch (((const unsigned char*)buf)[0]) | |
| 574 { | |
| 575 case 0: | |
| 576 str_details1 = ", HelloRequest"; | |
| 577 break; | |
| 578 case 1: | |
| 579 str_details1 = ", ClientHello"; | |
| 580 break; | |
| 581 case 2: | |
| 582 str_details1 = ", ServerHello"; | |
| 583 break; | |
| 584 case 3: | |
| 585 str_details1 = ", HelloVerifyRequest"; | |
| 586 break; | |
| 587 case 11: | |
| 588 str_details1 = ", Certificate"; | |
| 589 break; | |
| 590 case 12: | |
| 591 str_details1 = ", ServerKeyExchange"; | |
| 592 break; | |
| 593 case 13: | |
| 594 str_details1 = ", CertificateRequest"; | |
| 595 break; | |
| 596 case 14: | |
| 597 str_details1 = ", ServerHelloDone"; | |
| 598 break; | |
| 599 case 15: | |
| 600 str_details1 = ", CertificateVerify"; | |
| 601 break; | |
| 602 case 16: | |
| 603 str_details1 = ", ClientKeyExchange"; | |
| 604 break; | |
| 605 case 20: | |
| 606 str_details1 = ", Finished"; | |
| 607 break; | |
| 608 } | |
| 609 } | |
| 610 } | |
| 611 | |
| 612 #ifndef OPENSSL_NO_HEARTBEATS | |
| 613 if (content_type == 24) /* Heartbeat */ | |
| 614 { | |
| 615 str_details1 = ", Heartbeat"; | |
| 616 | |
| 617 if (len > 0) | |
| 618 { | |
| 619 switch (((const unsigned char*)buf)[0]) | |
| 620 { | |
| 621 case 1: | |
| 622 str_details1 = ", HeartbeatRequest"; | |
| 623 break; | |
| 624 case 2: | |
| 625 str_details1 = ", HeartbeatResponse"; | |
| 626 break; | |
| 627 } | |
| 628 } | |
| 629 } | |
| 630 #endif | |
| 631 } | |
| 632 | |
| 633 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); | |
| 634 | |
| 635 if (len > 0) | |
| 636 { | |
| 637 size_t num, i; | |
| 638 | |
| 639 BIO_printf(bio, " "); | |
| 640 num = len; | |
| 641 #if 0 | |
| 642 if (num > 16) | |
| 643 num = 16; | |
| 644 #endif | |
| 645 for (i = 0; i < num; i++) | |
| 646 { | |
| 647 if (i % 16 == 0 && i > 0) | |
| 648 BIO_printf(bio, "\n "); | |
| 649 BIO_printf(bio, " %02x", ((const unsigned char*)buf)[i])
; | |
| 650 } | |
| 651 if (i < len) | |
| 652 BIO_printf(bio, " ..."); | |
| 653 BIO_printf(bio, "\n"); | |
| 654 } | |
| 655 (void)BIO_flush(bio); | |
| 656 } | |
| 657 | |
| 658 void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type, | |
| 659 unsigned char *data, int len, | |
| 660 void *arg) | |
| 661 { | |
| 662 BIO *bio = arg; | |
| 663 char *extname; | |
| 664 | |
| 665 switch(type) | |
| 666 { | |
| 667 case TLSEXT_TYPE_server_name: | |
| 668 extname = "server name"; | |
| 669 break; | |
| 670 | |
| 671 case TLSEXT_TYPE_max_fragment_length: | |
| 672 extname = "max fragment length"; | |
| 673 break; | |
| 674 | |
| 675 case TLSEXT_TYPE_client_certificate_url: | |
| 676 extname = "client certificate URL"; | |
| 677 break; | |
| 678 | |
| 679 case TLSEXT_TYPE_trusted_ca_keys: | |
| 680 extname = "trusted CA keys"; | |
| 681 break; | |
| 682 | |
| 683 case TLSEXT_TYPE_truncated_hmac: | |
| 684 extname = "truncated HMAC"; | |
| 685 break; | |
| 686 | |
| 687 case TLSEXT_TYPE_status_request: | |
| 688 extname = "status request"; | |
| 689 break; | |
| 690 | |
| 691 case TLSEXT_TYPE_user_mapping: | |
| 692 extname = "user mapping"; | |
| 693 break; | |
| 694 | |
| 695 case TLSEXT_TYPE_client_authz: | |
| 696 extname = "client authz"; | |
| 697 break; | |
| 698 | |
| 699 case TLSEXT_TYPE_server_authz: | |
| 700 extname = "server authz"; | |
| 701 break; | |
| 702 | |
| 703 case TLSEXT_TYPE_cert_type: | |
| 704 extname = "cert type"; | |
| 705 break; | |
| 706 | |
| 707 case TLSEXT_TYPE_elliptic_curves: | |
| 708 extname = "elliptic curves"; | |
| 709 break; | |
| 710 | |
| 711 case TLSEXT_TYPE_ec_point_formats: | |
| 712 extname = "EC point formats"; | |
| 713 break; | |
| 714 | |
| 715 case TLSEXT_TYPE_srp: | |
| 716 extname = "SRP"; | |
| 717 break; | |
| 718 | |
| 719 case TLSEXT_TYPE_signature_algorithms: | |
| 720 extname = "signature algorithms"; | |
| 721 break; | |
| 722 | |
| 723 case TLSEXT_TYPE_use_srtp: | |
| 724 extname = "use SRTP"; | |
| 725 break; | |
| 726 | |
| 727 case TLSEXT_TYPE_heartbeat: | |
| 728 extname = "heartbeat"; | |
| 729 break; | |
| 730 | |
| 731 case TLSEXT_TYPE_session_ticket: | |
| 732 extname = "session ticket"; | |
| 733 break; | |
| 734 | |
| 735 case TLSEXT_TYPE_renegotiate: | |
| 736 extname = "renegotiation info"; | |
| 737 break; | |
| 738 | |
| 739 #ifdef TLSEXT_TYPE_opaque_prf_input | |
| 740 case TLSEXT_TYPE_opaque_prf_input: | |
| 741 extname = "opaque PRF input"; | |
| 742 break; | |
| 743 #endif | |
| 744 #ifdef TLSEXT_TYPE_next_proto_neg | |
| 745 case TLSEXT_TYPE_next_proto_neg: | |
| 746 extname = "next protocol"; | |
| 747 break; | |
| 748 #endif | |
| 749 | |
| 750 default: | |
| 751 extname = "unknown"; | |
| 752 break; | |
| 753 | |
| 754 } | |
| 755 | |
| 756 BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n", | |
| 757 client_server ? "server": "client", | |
| 758 extname, type, len); | |
| 759 BIO_dump(bio, (char *)data, len); | |
| 760 (void)BIO_flush(bio); | |
| 761 } | |
| 762 | |
| 763 int MS_CALLBACK generate_cookie_callback(SSL *ssl, unsigned char *cookie, unsign
ed int *cookie_len) | |
| 764 { | |
| 765 unsigned char *buffer, result[EVP_MAX_MD_SIZE]; | |
| 766 unsigned int length, resultlength; | |
| 767 union { | |
| 768 struct sockaddr sa; | |
| 769 struct sockaddr_in s4; | |
| 770 #if OPENSSL_USE_IPV6 | |
| 771 struct sockaddr_in6 s6; | |
| 772 #endif | |
| 773 } peer; | |
| 774 | |
| 775 /* Initialize a random secret */ | |
| 776 if (!cookie_initialized) | |
| 777 { | |
| 778 if (!RAND_bytes(cookie_secret, COOKIE_SECRET_LENGTH)) | |
| 779 { | |
| 780 BIO_printf(bio_err,"error setting random cookie secret\n
"); | |
| 781 return 0; | |
| 782 } | |
| 783 cookie_initialized = 1; | |
| 784 } | |
| 785 | |
| 786 /* Read peer information */ | |
| 787 (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); | |
| 788 | |
| 789 /* Create buffer with peer's address and port */ | |
| 790 length = 0; | |
| 791 switch (peer.sa.sa_family) | |
| 792 { | |
| 793 case AF_INET: | |
| 794 length += sizeof(struct in_addr); | |
| 795 length += sizeof(peer.s4.sin_port); | |
| 796 break; | |
| 797 #if OPENSSL_USE_IPV6 | |
| 798 case AF_INET6: | |
| 799 length += sizeof(struct in6_addr); | |
| 800 length += sizeof(peer.s6.sin6_port); | |
| 801 break; | |
| 802 #endif | |
| 803 default: | |
| 804 OPENSSL_assert(0); | |
| 805 break; | |
| 806 } | |
| 807 buffer = OPENSSL_malloc(length); | |
| 808 | |
| 809 if (buffer == NULL) | |
| 810 { | |
| 811 BIO_printf(bio_err,"out of memory\n"); | |
| 812 return 0; | |
| 813 } | |
| 814 | |
| 815 switch (peer.sa.sa_family) | |
| 816 { | |
| 817 case AF_INET: | |
| 818 memcpy(buffer, | |
| 819 &peer.s4.sin_port, | |
| 820 sizeof(peer.s4.sin_port)); | |
| 821 memcpy(buffer + sizeof(peer.s4.sin_port), | |
| 822 &peer.s4.sin_addr, | |
| 823 sizeof(struct in_addr)); | |
| 824 break; | |
| 825 #if OPENSSL_USE_IPV6 | |
| 826 case AF_INET6: | |
| 827 memcpy(buffer, | |
| 828 &peer.s6.sin6_port, | |
| 829 sizeof(peer.s6.sin6_port)); | |
| 830 memcpy(buffer + sizeof(peer.s6.sin6_port), | |
| 831 &peer.s6.sin6_addr, | |
| 832 sizeof(struct in6_addr)); | |
| 833 break; | |
| 834 #endif | |
| 835 default: | |
| 836 OPENSSL_assert(0); | |
| 837 break; | |
| 838 } | |
| 839 | |
| 840 /* Calculate HMAC of buffer using the secret */ | |
| 841 HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, | |
| 842 buffer, length, result, &resultlength); | |
| 843 OPENSSL_free(buffer); | |
| 844 | |
| 845 memcpy(cookie, result, resultlength); | |
| 846 *cookie_len = resultlength; | |
| 847 | |
| 848 return 1; | |
| 849 } | |
| 850 | |
| 851 int MS_CALLBACK verify_cookie_callback(SSL *ssl, unsigned char *cookie, unsigned
int cookie_len) | |
| 852 { | |
| 853 unsigned char *buffer, result[EVP_MAX_MD_SIZE]; | |
| 854 unsigned int length, resultlength; | |
| 855 union { | |
| 856 struct sockaddr sa; | |
| 857 struct sockaddr_in s4; | |
| 858 #if OPENSSL_USE_IPV6 | |
| 859 struct sockaddr_in6 s6; | |
| 860 #endif | |
| 861 } peer; | |
| 862 | |
| 863 /* If secret isn't initialized yet, the cookie can't be valid */ | |
| 864 if (!cookie_initialized) | |
| 865 return 0; | |
| 866 | |
| 867 /* Read peer information */ | |
| 868 (void)BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer); | |
| 869 | |
| 870 /* Create buffer with peer's address and port */ | |
| 871 length = 0; | |
| 872 switch (peer.sa.sa_family) | |
| 873 { | |
| 874 case AF_INET: | |
| 875 length += sizeof(struct in_addr); | |
| 876 length += sizeof(peer.s4.sin_port); | |
| 877 break; | |
| 878 #if OPENSSL_USE_IPV6 | |
| 879 case AF_INET6: | |
| 880 length += sizeof(struct in6_addr); | |
| 881 length += sizeof(peer.s6.sin6_port); | |
| 882 break; | |
| 883 #endif | |
| 884 default: | |
| 885 OPENSSL_assert(0); | |
| 886 break; | |
| 887 } | |
| 888 buffer = OPENSSL_malloc(length); | |
| 889 | |
| 890 if (buffer == NULL) | |
| 891 { | |
| 892 BIO_printf(bio_err,"out of memory\n"); | |
| 893 return 0; | |
| 894 } | |
| 895 | |
| 896 switch (peer.sa.sa_family) | |
| 897 { | |
| 898 case AF_INET: | |
| 899 memcpy(buffer, | |
| 900 &peer.s4.sin_port, | |
| 901 sizeof(peer.s4.sin_port)); | |
| 902 memcpy(buffer + sizeof(peer.s4.sin_port), | |
| 903 &peer.s4.sin_addr, | |
| 904 sizeof(struct in_addr)); | |
| 905 break; | |
| 906 #if OPENSSL_USE_IPV6 | |
| 907 case AF_INET6: | |
| 908 memcpy(buffer, | |
| 909 &peer.s6.sin6_port, | |
| 910 sizeof(peer.s6.sin6_port)); | |
| 911 memcpy(buffer + sizeof(peer.s6.sin6_port), | |
| 912 &peer.s6.sin6_addr, | |
| 913 sizeof(struct in6_addr)); | |
| 914 break; | |
| 915 #endif | |
| 916 default: | |
| 917 OPENSSL_assert(0); | |
| 918 break; | |
| 919 } | |
| 920 | |
| 921 /* Calculate HMAC of buffer using the secret */ | |
| 922 HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH, | |
| 923 buffer, length, result, &resultlength); | |
| 924 OPENSSL_free(buffer); | |
| 925 | |
| 926 if (cookie_len == resultlength && memcmp(result, cookie, resultlength) =
= 0) | |
| 927 return 1; | |
| 928 | |
| 929 return 0; | |
| 930 } | |
| OLD | NEW |