1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at http://curl.haxx.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 ***************************************************************************/ 22 23/* 24 * Source file for all OpenSSL-specific code for the TLS/SSL layer. No code 25 * but sslgen.c should ever call or use these functions. 26 */ 27 28/* 29 * The original SSLeay-using code for curl was written by Linas Vepstas and 30 * Sampo Kellomaki 1998. 31 */ 32 33#include "setup.h" 34 35#include <string.h> 36#include <stdlib.h> 37#include <ctype.h> 38#ifdef HAVE_LIMITS_H 39#include <limits.h> 40#endif 41#ifdef HAVE_SYS_SOCKET_H 42#include <sys/socket.h> 43#endif 44 45#include "urldata.h" 46#include "sendf.h" 47#include "formdata.h" /* for the boundary function */ 48#include "url.h" /* for the ssl config check function */ 49#include "inet_pton.h" 50#include "ssluse.h" 51#include "connect.h" 52#include "strequal.h" 53#include "select.h" 54#include "sslgen.h" 55#include "rawstr.h" 56 57#define _MPRINTF_REPLACE /* use the internal *printf() functions */ 58#include <curl/mprintf.h> 59 60#ifdef USE_SSLEAY 61 62#ifdef USE_OPENSSL 63#include <openssl/rand.h> 64#include <openssl/x509v3.h> 65#include <openssl/dsa.h> 66#include <openssl/dh.h> 67#include <openssl/err.h> 68#else 69#include <rand.h> 70#include <x509v3.h> 71#endif 72 73#include "curl_memory.h" 74#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */ 75 76/* The last #include file should be: */ 77#include "memdebug.h" 78 79#ifndef OPENSSL_VERSION_NUMBER 80#error "OPENSSL_VERSION_NUMBER not defined" 81#endif 82 83#if OPENSSL_VERSION_NUMBER >= 0x0090581fL 84#define HAVE_SSL_GET1_SESSION 1 85#else 86#undef HAVE_SSL_GET1_SESSION 87#endif 88 89#if OPENSSL_VERSION_NUMBER >= 0x00904100L 90#define HAVE_USERDATA_IN_PWD_CALLBACK 1 91#else 92#undef HAVE_USERDATA_IN_PWD_CALLBACK 93#endif 94 95#if OPENSSL_VERSION_NUMBER >= 0x00907001L 96/* ENGINE_load_private_key() takes four arguments */ 97#define HAVE_ENGINE_LOAD_FOUR_ARGS 98#include <openssl/ui.h> 99#else 100/* ENGINE_load_private_key() takes three arguments */ 101#undef HAVE_ENGINE_LOAD_FOUR_ARGS 102#endif 103 104#if (OPENSSL_VERSION_NUMBER >= 0x00903001L) && defined(HAVE_OPENSSL_PKCS12_H) 105/* OpenSSL has PKCS 12 support */ 106#define HAVE_PKCS12_SUPPORT 107#else 108/* OpenSSL/SSLEay does not have PKCS12 support */ 109#undef HAVE_PKCS12_SUPPORT 110#endif 111 112#if OPENSSL_VERSION_NUMBER >= 0x00906001L 113#define HAVE_ERR_ERROR_STRING_N 1 114#endif 115 116#if OPENSSL_VERSION_NUMBER >= 0x00909000L 117#define SSL_METHOD_QUAL const 118#else 119#define SSL_METHOD_QUAL 120#endif 121 122#if OPENSSL_VERSION_NUMBER >= 0x00907000L 123/* 0.9.6 didn't have X509_STORE_set_flags() */ 124#define HAVE_X509_STORE_SET_FLAGS 1 125#else 126#define X509_STORE_set_flags(x,y) 127#endif 128 129/* 130 * Number of bytes to read from the random number seed file. This must be 131 * a finite value (because some entropy "files" like /dev/urandom have 132 * an infinite length), but must be large enough to provide enough 133 * entopy to properly seed OpenSSL's PRNG. 134 */ 135#define RAND_LOAD_LENGTH 1024 136 137#ifndef HAVE_USERDATA_IN_PWD_CALLBACK 138static char global_passwd[64]; 139#endif 140 141static int passwd_callback(char *buf, int num, int verify 142#ifdef HAVE_USERDATA_IN_PWD_CALLBACK 143 /* This was introduced in 0.9.4, we can set this 144 using SSL_CTX_set_default_passwd_cb_userdata() 145 */ 146 , void *global_passwd 147#endif 148 ) 149{ 150 if(verify) 151 fprintf(stderr, "%s\n", buf); 152 else { 153 if(num > (int)strlen((char *)global_passwd)) { 154 strcpy(buf, global_passwd); 155 return (int)strlen(buf); 156 } 157 } 158 return 0; 159} 160 161/* 162 * rand_enough() is a function that returns TRUE if we have seeded the random 163 * engine properly. We use some preprocessor magic to provide a seed_enough() 164 * macro to use, just to prevent a compiler warning on this function if we 165 * pass in an argument that is never used. 166 */ 167 168#ifdef HAVE_RAND_STATUS 169#define seed_enough(x) rand_enough() 170static bool rand_enough(void) 171{ 172 return (bool)(0 != RAND_status()); 173} 174#else 175#define seed_enough(x) rand_enough(x) 176static bool rand_enough(int nread) 177{ 178 /* this is a very silly decision to make */ 179 return (bool)(nread > 500); 180} 181#endif 182 183static int ossl_seed(struct SessionHandle *data) 184{ 185 char *buf = data->state.buffer; /* point to the big buffer */ 186 int nread=0; 187 188 /* Q: should we add support for a random file name as a libcurl option? 189 A: Yes, it is here */ 190 191#ifndef RANDOM_FILE 192 /* if RANDOM_FILE isn't defined, we only perform this if an option tells 193 us to! */ 194 if(data->set.ssl.random_file) 195#define RANDOM_FILE "" /* doesn't matter won't be used */ 196#endif 197 { 198 /* let the option override the define */ 199 nread += RAND_load_file((data->set.str[STRING_SSL_RANDOM_FILE]? 200 data->set.str[STRING_SSL_RANDOM_FILE]: 201 RANDOM_FILE), 202 RAND_LOAD_LENGTH); 203 if(seed_enough(nread)) 204 return nread; 205 } 206 207#if defined(HAVE_RAND_EGD) 208 /* only available in OpenSSL 0.9.5 and later */ 209 /* EGD_SOCKET is set at configure time or not at all */ 210#ifndef EGD_SOCKET 211 /* If we don't have the define set, we only do this if the egd-option 212 is set */ 213 if(data->set.str[STRING_SSL_EGDSOCKET]) 214#define EGD_SOCKET "" /* doesn't matter won't be used */ 215#endif 216 { 217 /* If there's an option and a define, the option overrides the 218 define */ 219 int ret = RAND_egd(data->set.str[STRING_SSL_EGDSOCKET]? 220 data->set.str[STRING_SSL_EGDSOCKET]:EGD_SOCKET); 221 if(-1 != ret) { 222 nread += ret; 223 if(seed_enough(nread)) 224 return nread; 225 } 226 } 227#endif 228 229 /* If we get here, it means we need to seed the PRNG using a "silly" 230 approach! */ 231#ifdef HAVE_RAND_SCREEN 232 /* if RAND_screen() is present, this is windows and thus we assume that the 233 randomness is already taken care of */ 234 nread = 100; /* just a value */ 235#else 236 { 237 int len; 238 char *area; 239 240 /* Changed call to RAND_seed to use the underlying RAND_add implementation 241 * directly. Do this in a loop, with the amount of additional entropy 242 * being dependent upon the algorithm used by Curl_FormBoundary(): N bytes 243 * of a 7-bit ascii set. -- Richard Gorton, March 11 2003. 244 */ 245 246 do { 247 area = Curl_FormBoundary(); 248 if(!area) 249 return 3; /* out of memory */ 250 251 len = (int)strlen(area); 252 RAND_add(area, len, (len >> 1)); 253 254 free(area); /* now remove the random junk */ 255 } while(!RAND_status()); 256 } 257#endif 258 259 /* generates a default path for the random seed file */ 260 buf[0]=0; /* blank it first */ 261 RAND_file_name(buf, BUFSIZE); 262 if(buf[0]) { 263 /* we got a file name to try */ 264 nread += RAND_load_file(buf, RAND_LOAD_LENGTH); 265 if(seed_enough(nread)) 266 return nread; 267 } 268 269 infof(data, "libcurl is now using a weak random seed!\n"); 270 return nread; 271} 272 273int Curl_ossl_seed(struct SessionHandle *data) 274{ 275 /* we have the "SSL is seeded" boolean static to prevent multiple 276 time-consuming seedings in vain */ 277 static bool ssl_seeded = FALSE; 278 279 if(!ssl_seeded || data->set.str[STRING_SSL_RANDOM_FILE] || 280 data->set.str[STRING_SSL_EGDSOCKET]) { 281 ossl_seed(data); 282 ssl_seeded = TRUE; 283 } 284 return 0; 285} 286 287 288#ifndef SSL_FILETYPE_ENGINE 289#define SSL_FILETYPE_ENGINE 42 290#endif 291#ifndef SSL_FILETYPE_PKCS12 292#define SSL_FILETYPE_PKCS12 43 293#endif 294static int do_file_type(const char *type) 295{ 296 if(!type || !type[0]) 297 return SSL_FILETYPE_PEM; 298 if(Curl_raw_equal(type, "PEM")) 299 return SSL_FILETYPE_PEM; 300 if(Curl_raw_equal(type, "DER")) 301 return SSL_FILETYPE_ASN1; 302 if(Curl_raw_equal(type, "ENG")) 303 return SSL_FILETYPE_ENGINE; 304 if(Curl_raw_equal(type, "P12")) 305 return SSL_FILETYPE_PKCS12; 306 return -1; 307} 308 309static 310int cert_stuff(struct connectdata *conn, 311 SSL_CTX* ctx, 312 char *cert_file, 313 const char *cert_type, 314 char *key_file, 315 const char *key_type) 316{ 317 struct SessionHandle *data = conn->data; 318 319 int file_type = do_file_type(cert_type); 320 321 if(cert_file != NULL || file_type == SSL_FILETYPE_ENGINE) { 322 SSL *ssl; 323 X509 *x509; 324 int cert_done = 0; 325 326 if(data->set.str[STRING_KEY_PASSWD]) { 327#ifndef HAVE_USERDATA_IN_PWD_CALLBACK 328 /* 329 * If password has been given, we store that in the global 330 * area (*shudder*) for a while: 331 */ 332 size_t len = strlen(data->set.str[STRING_KEY_PASSWD]); 333 if(len < sizeof(global_passwd)) 334 memcpy(global_passwd, data->set.str[STRING_KEY_PASSWD], len+1); 335#else 336 /* 337 * We set the password in the callback userdata 338 */ 339 SSL_CTX_set_default_passwd_cb_userdata(ctx, 340 data->set.str[STRING_KEY_PASSWD]); 341#endif 342 /* Set passwd callback: */ 343 SSL_CTX_set_default_passwd_cb(ctx, passwd_callback); 344 } 345 346 347#define SSL_CLIENT_CERT_ERR \ 348 "unable to use client certificate (no key found or wrong pass phrase?)" 349 350 switch(file_type) { 351 case SSL_FILETYPE_PEM: 352 /* SSL_CTX_use_certificate_chain_file() only works on PEM files */ 353 if(SSL_CTX_use_certificate_chain_file(ctx, 354 cert_file) != 1) { 355 failf(data, SSL_CLIENT_CERT_ERR); 356 return 0; 357 } 358 break; 359 360 case SSL_FILETYPE_ASN1: 361 /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but 362 we use the case above for PEM so this can only be performed with 363 ASN1 files. */ 364 if(SSL_CTX_use_certificate_file(ctx, 365 cert_file, 366 file_type) != 1) { 367 failf(data, SSL_CLIENT_CERT_ERR); 368 return 0; 369 } 370 break; 371 case SSL_FILETYPE_ENGINE: 372#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME) 373 { 374 if(data->state.engine) { 375 const char *cmd_name = "LOAD_CERT_CTRL"; 376 struct { 377 const char *cert_id; 378 X509 *cert; 379 } params; 380 381 params.cert_id = cert_file; 382 params.cert = NULL; 383 384 /* Does the engine supports LOAD_CERT_CTRL ? */ 385 if(!ENGINE_ctrl(data->state.engine, ENGINE_CTRL_GET_CMD_FROM_NAME, 386 0, (void *)cmd_name, NULL)) { 387 failf(data, "ssl engine does not support loading certificates"); 388 return 0; 389 } 390 391 /* Load the certificate from the engine */ 392 if(!ENGINE_ctrl_cmd(data->state.engine, cmd_name, 393 0, ¶ms, NULL, 1)) { 394 failf(data, "ssl engine cannot load client cert with id" 395 " '%s' [%s]", cert_file, 396 ERR_error_string(ERR_get_error(), NULL)); 397 return 0; 398 } 399 400 if(!params.cert) { 401 failf(data, "ssl engine didn't initialized the certificate " 402 "properly."); 403 return 0; 404 } 405 406 if(SSL_CTX_use_certificate(ctx, params.cert) != 1) { 407 failf(data, "unable to set client certificate"); 408 X509_free(params.cert); 409 return 0; 410 } 411 X509_free(params.cert); /* we don't need the handle any more... */ 412 } 413 else { 414 failf(data, "crypto engine not set, can't load certificate"); 415 return 0; 416 } 417 } 418 break; 419#else 420 failf(data, "file type ENG for certificate not implemented"); 421 return 0; 422#endif 423 424 case SSL_FILETYPE_PKCS12: 425 { 426#ifdef HAVE_PKCS12_SUPPORT 427 FILE *f; 428 PKCS12 *p12; 429 EVP_PKEY *pri; 430 STACK_OF(X509) *ca = NULL; 431 int i; 432 433 f = fopen(cert_file,"rb"); 434 if(!f) { 435 failf(data, "could not open PKCS12 file '%s'", cert_file); 436 return 0; 437 } 438 p12 = d2i_PKCS12_fp(f, NULL); 439 fclose(f); 440 441 if(!p12) { 442 failf(data, "error reading PKCS12 file '%s'", cert_file ); 443 return 0; 444 } 445 446 PKCS12_PBE_add(); 447 448 if(!PKCS12_parse(p12, data->set.str[STRING_KEY_PASSWD], &pri, &x509, 449 &ca)) { 450 failf(data, 451 "could not parse PKCS12 file, check password, OpenSSL error %s", 452 ERR_error_string(ERR_get_error(), NULL) ); 453 PKCS12_free(p12); 454 return 0; 455 } 456 457 PKCS12_free(p12); 458 459 if(SSL_CTX_use_certificate(ctx, x509) != 1) { 460 failf(data, SSL_CLIENT_CERT_ERR); 461 EVP_PKEY_free(pri); 462 X509_free(x509); 463 return 0; 464 } 465 466 if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) { 467 failf(data, "unable to use private key from PKCS12 file '%s'", 468 cert_file); 469 EVP_PKEY_free(pri); 470 X509_free(x509); 471 return 0; 472 } 473 474 if(!SSL_CTX_check_private_key (ctx)) { 475 failf(data, "private key from PKCS12 file '%s' " 476 "does not match certificate in same file", cert_file); 477 EVP_PKEY_free(pri); 478 X509_free(x509); 479 return 0; 480 } 481 /* Set Certificate Verification chain */ 482 if(ca && sk_X509_num(ca)) { 483 for(i = 0; i < sk_X509_num(ca); i++) { 484 if(!SSL_CTX_add_extra_chain_cert(ctx,sk_X509_value(ca, i))) { 485 failf(data, "cannot add certificate to certificate chain"); 486 EVP_PKEY_free(pri); 487 X509_free(x509); 488 return 0; 489 } 490 if(!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) { 491 failf(data, "cannot add certificate to client CA list"); 492 EVP_PKEY_free(pri); 493 X509_free(x509); 494 return 0; 495 } 496 } 497 } 498 499 EVP_PKEY_free(pri); 500 X509_free(x509); 501 cert_done = 1; 502 break; 503#else 504 failf(data, "file type P12 for certificate not supported"); 505 return 0; 506#endif 507 } 508 default: 509 failf(data, "not supported file type '%s' for certificate", cert_type); 510 return 0; 511 } 512 513 file_type = do_file_type(key_type); 514 515 switch(file_type) { 516 case SSL_FILETYPE_PEM: 517 if(cert_done) 518 break; 519 if(key_file == NULL) 520 /* cert & key can only be in PEM case in the same file */ 521 key_file=cert_file; 522 case SSL_FILETYPE_ASN1: 523 if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) { 524 failf(data, "unable to set private key file: '%s' type %s", 525 key_file, key_type?key_type:"PEM"); 526 return 0; 527 } 528 break; 529 case SSL_FILETYPE_ENGINE: 530#ifdef HAVE_OPENSSL_ENGINE_H 531 { /* XXXX still needs some work */ 532 EVP_PKEY *priv_key = NULL; 533 if(data->state.engine) { 534#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS 535 UI_METHOD *ui_method = UI_OpenSSL(); 536#endif 537 /* the typecast below was added to please mingw32 */ 538 priv_key = (EVP_PKEY *) 539 ENGINE_load_private_key(data->state.engine,key_file, 540#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS 541 ui_method, 542#endif 543 data->set.str[STRING_KEY_PASSWD]); 544 if(!priv_key) { 545 failf(data, "failed to load private key from crypto engine"); 546 return 0; 547 } 548 if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) { 549 failf(data, "unable to set private key"); 550 EVP_PKEY_free(priv_key); 551 return 0; 552 } 553 EVP_PKEY_free(priv_key); /* we don't need the handle any more... */ 554 } 555 else { 556 failf(data, "crypto engine not set, can't load private key"); 557 return 0; 558 } 559 } 560 break; 561#else 562 failf(data, "file type ENG for private key not supported"); 563 return 0; 564#endif 565 case SSL_FILETYPE_PKCS12: 566 if(!cert_done) { 567 failf(data, "file type P12 for private key not supported"); 568 return 0; 569 } 570 break; 571 default: 572 failf(data, "not supported file type for private key"); 573 return 0; 574 } 575 576 ssl=SSL_new(ctx); 577 if(NULL == ssl) { 578 failf(data,"unable to create an SSL structure"); 579 return 0; 580 } 581 582 x509=SSL_get_certificate(ssl); 583 584 /* This version was provided by Evan Jordan and is supposed to not 585 leak memory as the previous version: */ 586 if(x509 != NULL) { 587 EVP_PKEY *pktmp = X509_get_pubkey(x509); 588 EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl)); 589 EVP_PKEY_free(pktmp); 590 } 591 592 SSL_free(ssl); 593 594 /* If we are using DSA, we can copy the parameters from 595 * the private key */ 596 597 598 /* Now we know that a key and cert have been set against 599 * the SSL context */ 600 if(!SSL_CTX_check_private_key(ctx)) { 601 failf(data, "Private key does not match the certificate public key"); 602 return 0; 603 } 604#ifndef HAVE_USERDATA_IN_PWD_CALLBACK 605 /* erase it now */ 606 memset(global_passwd, 0, sizeof(global_passwd)); 607#endif 608 } 609 return 1; 610} 611 612/* returns non-zero on failure */ 613static int x509_name_oneline(X509_NAME *a, char *buf, size_t size) 614{ 615#if 0 616 return X509_NAME_oneline(a, buf, size); 617#else 618 BIO *bio_out = BIO_new(BIO_s_mem()); 619 BUF_MEM *biomem; 620 int rc; 621 622 if(!bio_out) 623 return 1; /* alloc failed! */ 624 625 rc = X509_NAME_print_ex(bio_out, a, 0, XN_FLAG_SEP_SPLUS_SPC); 626 BIO_get_mem_ptr(bio_out, &biomem); 627 628 if((size_t)biomem->length < size) 629 size = biomem->length; 630 else 631 size--; /* don't overwrite the buffer end */ 632 633 memcpy(buf, biomem->data, size); 634 buf[size]=0; 635 636 BIO_free(bio_out); 637 638 return !rc; 639#endif 640} 641 642static 643int cert_verify_callback(int ok, X509_STORE_CTX *ctx) 644{ 645 X509 *err_cert; 646 char buf[256]; 647 648 err_cert=X509_STORE_CTX_get_current_cert(ctx); 649 (void)x509_name_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf)); 650 return ok; 651} 652 653/* Return error string for last OpenSSL error 654 */ 655static char *SSL_strerror(unsigned long error, char *buf, size_t size) 656{ 657#ifdef HAVE_ERR_ERROR_STRING_N 658 /* OpenSSL 0.9.6 and later has a function named 659 ERRO_error_string_n() that takes the size of the buffer as a 660 third argument */ 661 ERR_error_string_n(error, buf, size); 662#else 663 (void) size; 664 ERR_error_string(error, buf); 665#endif 666 return buf; 667} 668 669#endif /* USE_SSLEAY */ 670 671#ifdef USE_SSLEAY 672/** 673 * Global SSL init 674 * 675 * @retval 0 error initializing SSL 676 * @retval 1 SSL initialized successfully 677 */ 678int Curl_ossl_init(void) 679{ 680#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES 681 ENGINE_load_builtin_engines(); 682#endif 683 684 /* Lets get nice error messages */ 685 SSL_load_error_strings(); 686 687 /* Init the global ciphers and digests */ 688 if(!SSLeay_add_ssl_algorithms()) 689 return 0; 690 691 OpenSSL_add_all_algorithms(); 692 693 return 1; 694} 695 696#endif /* USE_SSLEAY */ 697 698#ifdef USE_SSLEAY 699 700/* Global cleanup */ 701void Curl_ossl_cleanup(void) 702{ 703 /* Free the SSL error strings */ 704 ERR_free_strings(); 705 706 /* EVP_cleanup() removes all ciphers and digests from the table. */ 707 EVP_cleanup(); 708 709#ifdef HAVE_ENGINE_CLEANUP 710 ENGINE_cleanup(); 711#endif 712 713#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 714 /* this function was not present in 0.9.6b, but was added sometimes 715 later */ 716 CRYPTO_cleanup_all_ex_data(); 717#endif 718} 719 720/* 721 * This function uses SSL_peek to determine connection status. 722 * 723 * Return codes: 724 * 1 means the connection is still in place 725 * 0 means the connection has been closed 726 * -1 means the connection status is unknown 727 */ 728int Curl_ossl_check_cxn(struct connectdata *conn) 729{ 730 int rc; 731 char buf; 732 733 rc = SSL_peek(conn->ssl[FIRSTSOCKET].handle, (void*)&buf, 1); 734 if(rc > 0) 735 return 1; /* connection still in place */ 736 737 if(rc == 0) 738 return 0; /* connection has been closed */ 739 740 return -1; /* connection status unknown */ 741} 742 743/* Selects an OpenSSL crypto engine 744 */ 745CURLcode Curl_ossl_set_engine(struct SessionHandle *data, const char *engine) 746{ 747#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) 748 ENGINE *e; 749 750#if OPENSSL_VERSION_NUMBER >= 0x00909000L 751 e = ENGINE_by_id(engine); 752#else 753 /* avoid memory leak */ 754 for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { 755 const char *e_id = ENGINE_get_id(e); 756 if(!strcmp(engine, e_id)) 757 break; 758 } 759#endif 760 761 if(!e) { 762 failf(data, "SSL Engine '%s' not found", engine); 763 return CURLE_SSL_ENGINE_NOTFOUND; 764 } 765 766 if(data->state.engine) { 767 ENGINE_finish(data->state.engine); 768 ENGINE_free(data->state.engine); 769 data->state.engine = NULL; 770 } 771 if(!ENGINE_init(e)) { 772 char buf[256]; 773 774 ENGINE_free(e); 775 failf(data, "Failed to initialise SSL Engine '%s':\n%s", 776 engine, SSL_strerror(ERR_get_error(), buf, sizeof(buf))); 777 return CURLE_SSL_ENGINE_INITFAILED; 778 } 779 data->state.engine = e; 780 return CURLE_OK; 781#else 782 (void)engine; 783 failf(data, "SSL Engine not supported"); 784 return CURLE_SSL_ENGINE_NOTFOUND; 785#endif 786} 787 788/* Sets engine as default for all SSL operations 789 */ 790CURLcode Curl_ossl_set_engine_default(struct SessionHandle *data) 791{ 792#ifdef HAVE_OPENSSL_ENGINE_H 793 if(data->state.engine) { 794 if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) { 795 infof(data,"set default crypto engine '%s'\n", 796 ENGINE_get_id(data->state.engine)); 797 } 798 else { 799 failf(data, "set default crypto engine '%s' failed", 800 ENGINE_get_id(data->state.engine)); 801 return CURLE_SSL_ENGINE_SETFAILED; 802 } 803 } 804#else 805 (void) data; 806#endif 807 return CURLE_OK; 808} 809 810/* Return list of OpenSSL crypto engine names. 811 */ 812struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data) 813{ 814 struct curl_slist *list = NULL; 815#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H) 816 struct curl_slist *beg = NULL; 817 ENGINE *e; 818 819 for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) { 820 list = curl_slist_append(list, ENGINE_get_id(e)); 821 if(list == NULL) { 822 curl_slist_free_all(beg); 823 return NULL; 824 } 825 else if(beg == NULL) { 826 beg = list; 827 } 828 } 829#endif 830 (void) data; 831 return list; 832} 833 834 835/* 836 * This function is called when an SSL connection is closed. 837 */ 838void Curl_ossl_close(struct connectdata *conn, int sockindex) 839{ 840 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 841 842 if(connssl->handle) { 843 (void)SSL_shutdown(connssl->handle); 844 SSL_set_connect_state(connssl->handle); 845 846 SSL_free (connssl->handle); 847 connssl->handle = NULL; 848 } 849 if(connssl->ctx) { 850 SSL_CTX_free (connssl->ctx); 851 connssl->ctx = NULL; 852 } 853} 854 855/* 856 * This function is called to shut down the SSL layer but keep the 857 * socket open (CCC - Clear Command Channel) 858 */ 859int Curl_ossl_shutdown(struct connectdata *conn, int sockindex) 860{ 861 int retval = 0; 862 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 863 struct SessionHandle *data = conn->data; 864 char buf[120]; /* We will use this for the OpenSSL error buffer, so it has 865 to be at least 120 bytes long. */ 866 unsigned long sslerror; 867 ssize_t nread; 868 int buffsize; 869 int err; 870 int done = 0; 871 872 /* This has only been tested on the proftpd server, and the mod_tls code 873 sends a close notify alert without waiting for a close notify alert in 874 response. Thus we wait for a close notify alert from the server, but 875 we do not send one. Let's hope other servers do the same... */ 876 877 if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) 878 (void)SSL_shutdown(connssl->handle); 879 880 if(connssl->handle) { 881 buffsize = (int)sizeof(buf); 882 while(!done) { 883 int what = Curl_socket_ready(conn->sock[sockindex], 884 CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); 885 if(what > 0) { 886 ERR_clear_error(); 887 888 /* Something to read, let's do it and hope that it is the close 889 notify alert from the server */ 890 nread = (ssize_t)SSL_read(conn->ssl[sockindex].handle, buf, 891 buffsize); 892 err = SSL_get_error(conn->ssl[sockindex].handle, (int)nread); 893 894 switch(err) { 895 case SSL_ERROR_NONE: /* this is not an error */ 896 case SSL_ERROR_ZERO_RETURN: /* no more data */ 897 /* This is the expected response. There was no data but only 898 the close notify alert */ 899 done = 1; 900 break; 901 case SSL_ERROR_WANT_READ: 902 /* there's data pending, re-invoke SSL_read() */ 903 infof(data, "SSL_ERROR_WANT_READ\n"); 904 break; 905 case SSL_ERROR_WANT_WRITE: 906 /* SSL wants a write. Really odd. Let's bail out. */ 907 infof(data, "SSL_ERROR_WANT_WRITE\n"); 908 done = 1; 909 break; 910 default: 911 /* openssl/ssl.h says "look at error stack/return value/errno" */ 912 sslerror = ERR_get_error(); 913 failf(conn->data, "SSL read: %s, errno %d", 914 ERR_error_string(sslerror, buf), 915 SOCKERRNO); 916 done = 1; 917 break; 918 } 919 } 920 else if(0 == what) { 921 /* timeout */ 922 failf(data, "SSL shutdown timeout"); 923 done = 1; 924 } 925 else { 926 /* anything that gets here is fatally bad */ 927 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); 928 retval = -1; 929 done = 1; 930 } 931 } /* while()-loop for the select() */ 932 933 if(data->set.verbose) { 934#ifdef HAVE_SSL_GET_SHUTDOWN 935 switch(SSL_get_shutdown(connssl->handle)) { 936 case SSL_SENT_SHUTDOWN: 937 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN\n"); 938 break; 939 case SSL_RECEIVED_SHUTDOWN: 940 infof(data, "SSL_get_shutdown() returned SSL_RECEIVED_SHUTDOWN\n"); 941 break; 942 case SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN: 943 infof(data, "SSL_get_shutdown() returned SSL_SENT_SHUTDOWN|" 944 "SSL_RECEIVED__SHUTDOWN\n"); 945 break; 946 } 947#endif 948 } 949 950 SSL_free (connssl->handle); 951 connssl->handle = NULL; 952 } 953 return retval; 954} 955 956void Curl_ossl_session_free(void *ptr) 957{ 958 /* free the ID */ 959 SSL_SESSION_free(ptr); 960} 961 962/* 963 * This function is called when the 'data' struct is going away. Close 964 * down everything and free all resources! 965 */ 966int Curl_ossl_close_all(struct SessionHandle *data) 967{ 968 /* 969 ERR_remove_state() frees the error queue associated with 970 thread pid. If pid == 0, the current thread will have its 971 error queue removed. 972 973 Since error queue data structures are allocated 974 automatically for new threads, they must be freed when 975 threads are terminated in oder to avoid memory leaks. 976 */ 977 ERR_remove_state(0); 978 979#ifdef HAVE_OPENSSL_ENGINE_H 980 if(data->state.engine) { 981 ENGINE_finish(data->state.engine); 982 ENGINE_free(data->state.engine); 983 data->state.engine = NULL; 984 } 985#else 986 (void)data; 987#endif 988 return 0; 989} 990 991static int asn1_output(const ASN1_UTCTIME *tm, 992 char *buf, 993 size_t sizeofbuf) 994{ 995 const char *asn1_string; 996 int gmt=FALSE; 997 int i; 998 int year=0,month=0,day=0,hour=0,minute=0,second=0; 999 1000 i=tm->length; 1001 asn1_string=(const char *)tm->data; 1002 1003 if(i < 10) 1004 return 1; 1005 if(asn1_string[i-1] == 'Z') 1006 gmt=TRUE; 1007 for(i=0; i<10; i++) 1008 if((asn1_string[i] > '9') || (asn1_string[i] < '0')) 1009 return 2; 1010 1011 year= (asn1_string[0]-'0')*10+(asn1_string[1]-'0'); 1012 if(year < 50) 1013 year+=100; 1014 1015 month= (asn1_string[2]-'0')*10+(asn1_string[3]-'0'); 1016 if((month > 12) || (month < 1)) 1017 return 3; 1018 1019 day= (asn1_string[4]-'0')*10+(asn1_string[5]-'0'); 1020 hour= (asn1_string[6]-'0')*10+(asn1_string[7]-'0'); 1021 minute= (asn1_string[8]-'0')*10+(asn1_string[9]-'0'); 1022 1023 if((asn1_string[10] >= '0') && (asn1_string[10] <= '9') && 1024 (asn1_string[11] >= '0') && (asn1_string[11] <= '9')) 1025 second= (asn1_string[10]-'0')*10+(asn1_string[11]-'0'); 1026 1027 snprintf(buf, sizeofbuf, 1028 "%04d-%02d-%02d %02d:%02d:%02d %s", 1029 year+1900, month, day, hour, minute, second, (gmt?"GMT":"")); 1030 1031 return 0; 1032} 1033 1034/* ====================================================== */ 1035 1036/* 1037 * Match a hostname against a wildcard pattern. 1038 * E.g. 1039 * "foo.host.com" matches "*.host.com". 1040 * 1041 * We are a bit more liberal than RFC2818 describes in that we 1042 * accept multiple "*" in pattern (similar to what some other browsers do). 1043 * E.g. 1044 * "abc.def.domain.com" should strickly not match "*.domain.com", but we 1045 * don't consider "." to be important in CERT checking. 1046 */ 1047#define HOST_NOMATCH 0 1048#define HOST_MATCH 1 1049 1050static int hostmatch(const char *hostname, const char *pattern) 1051{ 1052 for(;;) { 1053 char c = *pattern++; 1054 1055 if(c == '\0') 1056 return (*hostname ? HOST_NOMATCH : HOST_MATCH); 1057 1058 if(c == '*') { 1059 c = *pattern; 1060 if(c == '\0') /* "*\0" matches anything remaining */ 1061 return HOST_MATCH; 1062 1063 while(*hostname) { 1064 /* The only recursive function in libcurl! */ 1065 if(hostmatch(hostname++,pattern) == HOST_MATCH) 1066 return HOST_MATCH; 1067 } 1068 break; 1069 } 1070 1071 if(Curl_raw_toupper(c) != Curl_raw_toupper(*hostname++)) 1072 break; 1073 } 1074 return HOST_NOMATCH; 1075} 1076 1077static int 1078cert_hostcheck(const char *match_pattern, const char *hostname) 1079{ 1080 if(!match_pattern || !*match_pattern || 1081 !hostname || !*hostname) /* sanity check */ 1082 return 0; 1083 1084 if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */ 1085 return 1; 1086 1087 if(hostmatch(hostname,match_pattern) == HOST_MATCH) 1088 return 1; 1089 return 0; 1090} 1091 1092/* Quote from RFC2818 section 3.1 "Server Identity" 1093 1094 If a subjectAltName extension of type dNSName is present, that MUST 1095 be used as the identity. Otherwise, the (most specific) Common Name 1096 field in the Subject field of the certificate MUST be used. Although 1097 the use of the Common Name is existing practice, it is deprecated and 1098 Certification Authorities are encouraged to use the dNSName instead. 1099 1100 Matching is performed using the matching rules specified by 1101 [RFC2459]. If more than one identity of a given type is present in 1102 the certificate (e.g., more than one dNSName name, a match in any one 1103 of the set is considered acceptable.) Names may contain the wildcard 1104 character * which is considered to match any single domain name 1105 component or component fragment. E.g., *.a.com matches foo.a.com but 1106 not bar.foo.a.com. f*.com matches foo.com but not bar.com. 1107 1108 In some cases, the URI is specified as an IP address rather than a 1109 hostname. In this case, the iPAddress subjectAltName must be present 1110 in the certificate and must exactly match the IP in the URI. 1111 1112*/ 1113static CURLcode verifyhost(struct connectdata *conn, 1114 X509 *server_cert) 1115{ 1116 int matched = -1; /* -1 is no alternative match yet, 1 means match and 0 1117 means mismatch */ 1118 int target = GEN_DNS; /* target type, GEN_DNS or GEN_IPADD */ 1119 size_t addrlen = 0; 1120 struct SessionHandle *data = conn->data; 1121 STACK_OF(GENERAL_NAME) *altnames; 1122#ifdef ENABLE_IPV6 1123 struct in6_addr addr; 1124#else 1125 struct in_addr addr; 1126#endif 1127 CURLcode res = CURLE_OK; 1128 1129#ifdef ENABLE_IPV6 1130 if(conn->bits.ipv6_ip && 1131 Curl_inet_pton(AF_INET6, conn->host.name, &addr)) { 1132 target = GEN_IPADD; 1133 addrlen = sizeof(struct in6_addr); 1134 } 1135 else 1136#endif 1137 if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) { 1138 target = GEN_IPADD; 1139 addrlen = sizeof(struct in_addr); 1140 } 1141 1142 /* get a "list" of alternative names */ 1143 altnames = X509_get_ext_d2i(server_cert, NID_subject_alt_name, NULL, NULL); 1144 1145 if(altnames) { 1146 int numalts; 1147 int i; 1148 1149 /* get amount of alternatives, RFC2459 claims there MUST be at least 1150 one, but we don't depend on it... */ 1151 numalts = sk_GENERAL_NAME_num(altnames); 1152 1153 /* loop through all alternatives while none has matched */ 1154 for(i=0; (i<numalts) && (matched != 1); i++) { 1155 /* get a handle to alternative name number i */ 1156 const GENERAL_NAME *check = sk_GENERAL_NAME_value(altnames, i); 1157 1158 /* only check alternatives of the same type the target is */ 1159 if(check->type == target) { 1160 /* get data and length */ 1161 const char *altptr = (char *)ASN1_STRING_data(check->d.ia5); 1162 size_t altlen = (size_t) ASN1_STRING_length(check->d.ia5); 1163 1164 switch(target) { 1165 case GEN_DNS: /* name/pattern comparison */ 1166 /* The OpenSSL man page explicitly says: "In general it cannot be 1167 assumed that the data returned by ASN1_STRING_data() is null 1168 terminated or does not contain embedded nulls." But also that 1169 "The actual format of the data will depend on the actual string 1170 type itself: for example for and IA5String the data will be ASCII" 1171 1172 Gisle researched the OpenSSL sources: 1173 "I checked the 0.9.6 and 0.9.8 sources before my patch and 1174 it always 0-terminates an IA5String." 1175 */ 1176 if((altlen == strlen(altptr)) && 1177 /* if this isn't true, there was an embedded zero in the name 1178 string and we cannot match it. */ 1179 cert_hostcheck(altptr, conn->host.name)) 1180 matched = 1; 1181 else 1182 matched = 0; 1183 break; 1184 1185 case GEN_IPADD: /* IP address comparison */ 1186 /* compare alternative IP address if the data chunk is the same size 1187 our server IP address is */ 1188 if((altlen == addrlen) && !memcmp(altptr, &addr, altlen)) 1189 matched = 1; 1190 else 1191 matched = 0; 1192 break; 1193 } 1194 } 1195 } 1196 GENERAL_NAMES_free(altnames); 1197 } 1198 1199 if(matched == 1) 1200 /* an alternative name matched the server hostname */ 1201 infof(data, "\t subjectAltName: %s matched\n", conn->host.dispname); 1202 else if(matched == 0) { 1203 /* an alternative name field existed, but didn't match and then 1204 we MUST fail */ 1205 infof(data, "\t subjectAltName does not match %s\n", conn->host.dispname); 1206 res = CURLE_PEER_FAILED_VERIFICATION; 1207 } 1208 else { 1209 /* we have to look to the last occurrence of a commonName in the 1210 distinguished one to get the most significant one. */ 1211 int j,i=-1 ; 1212 1213/* The following is done because of a bug in 0.9.6b */ 1214 1215 unsigned char *nulstr = (unsigned char *)""; 1216 unsigned char *peer_CN = nulstr; 1217 1218 X509_NAME *name = X509_get_subject_name(server_cert) ; 1219 if(name) 1220 while((j = X509_NAME_get_index_by_NID(name, NID_commonName, i))>=0) 1221 i=j; 1222 1223 /* we have the name entry and we will now convert this to a string 1224 that we can use for comparison. Doing this we support BMPstring, 1225 UTF8 etc. */ 1226 1227 if(i>=0) { 1228 ASN1_STRING *tmp = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name,i)); 1229 1230 /* In OpenSSL 0.9.7d and earlier, ASN1_STRING_to_UTF8 fails if the input 1231 is already UTF-8 encoded. We check for this case and copy the raw 1232 string manually to avoid the problem. This code can be made 1233 conditional in the future when OpenSSL has been fixed. Work-around 1234 brought by Alexis S. L. Carvalho. */ 1235 if(tmp) { 1236 if(ASN1_STRING_type(tmp) == V_ASN1_UTF8STRING) { 1237 j = ASN1_STRING_length(tmp); 1238 if(j >= 0) { 1239 peer_CN = OPENSSL_malloc(j+1); 1240 if(peer_CN) { 1241 memcpy(peer_CN, ASN1_STRING_data(tmp), j); 1242 peer_CN[j] = '\0'; 1243 } 1244 } 1245 } 1246 else /* not a UTF8 name */ 1247 j = ASN1_STRING_to_UTF8(&peer_CN, tmp); 1248 1249 if(peer_CN && ((int)strlen((char *)peer_CN) != j)) { 1250 /* there was a terminating zero before the end of string, this 1251 cannot match and we return failure! */ 1252 failf(data, "SSL: illegal cert name field"); 1253 res = CURLE_PEER_FAILED_VERIFICATION; 1254 } 1255 } 1256 } 1257 1258 if(peer_CN == nulstr) 1259 peer_CN = NULL; 1260 else { 1261 /* convert peer_CN from UTF8 */ 1262 CURLcode rc = Curl_convert_from_utf8(data, peer_CN, strlen(peer_CN)); 1263 /* Curl_convert_from_utf8 calls failf if unsuccessful */ 1264 if(rc) { 1265 OPENSSL_free(peer_CN); 1266 return rc; 1267 } 1268 } 1269 1270 if(res) 1271 /* error already detected, pass through */ 1272 ; 1273 else if(!peer_CN) { 1274 failf(data, 1275 "SSL: unable to obtain common name from peer certificate"); 1276 res = CURLE_PEER_FAILED_VERIFICATION; 1277 } 1278 else if(!cert_hostcheck((const char *)peer_CN, conn->host.name)) { 1279 if(data->set.ssl.verifyhost > 1) { 1280 failf(data, "SSL: certificate subject name '%s' does not match " 1281 "target host name '%s'", peer_CN, conn->host.dispname); 1282 res = CURLE_PEER_FAILED_VERIFICATION; 1283 } 1284 else 1285 infof(data, "\t common name: %s (does not match '%s')\n", 1286 peer_CN, conn->host.dispname); 1287 } 1288 else { 1289 infof(data, "\t common name: %s (matched)\n", peer_CN); 1290 } 1291 if(peer_CN) 1292 OPENSSL_free(peer_CN); 1293 } 1294 return res; 1295} 1296#endif /* USE_SSLEAY */ 1297 1298/* The SSL_CTRL_SET_MSG_CALLBACK doesn't exist in ancient OpenSSL versions 1299 and thus this cannot be done there. */ 1300#ifdef SSL_CTRL_SET_MSG_CALLBACK 1301 1302static const char *ssl_msg_type(int ssl_ver, int msg) 1303{ 1304 if(ssl_ver == SSL2_VERSION_MAJOR) { 1305 switch (msg) { 1306 case SSL2_MT_ERROR: 1307 return "Error"; 1308 case SSL2_MT_CLIENT_HELLO: 1309 return "Client hello"; 1310 case SSL2_MT_CLIENT_MASTER_KEY: 1311 return "Client key"; 1312 case SSL2_MT_CLIENT_FINISHED: 1313 return "Client finished"; 1314 case SSL2_MT_SERVER_HELLO: 1315 return "Server hello"; 1316 case SSL2_MT_SERVER_VERIFY: 1317 return "Server verify"; 1318 case SSL2_MT_SERVER_FINISHED: 1319 return "Server finished"; 1320 case SSL2_MT_REQUEST_CERTIFICATE: 1321 return "Request CERT"; 1322 case SSL2_MT_CLIENT_CERTIFICATE: 1323 return "Client CERT"; 1324 } 1325 } 1326 else if(ssl_ver == SSL3_VERSION_MAJOR) { 1327 switch (msg) { 1328 case SSL3_MT_HELLO_REQUEST: 1329 return "Hello request"; 1330 case SSL3_MT_CLIENT_HELLO: 1331 return "Client hello"; 1332 case SSL3_MT_SERVER_HELLO: 1333 return "Server hello"; 1334 case SSL3_MT_CERTIFICATE: 1335 return "CERT"; 1336 case SSL3_MT_SERVER_KEY_EXCHANGE: 1337 return "Server key exchange"; 1338 case SSL3_MT_CLIENT_KEY_EXCHANGE: 1339 return "Client key exchange"; 1340 case SSL3_MT_CERTIFICATE_REQUEST: 1341 return "Request CERT"; 1342 case SSL3_MT_SERVER_DONE: 1343 return "Server finished"; 1344 case SSL3_MT_CERTIFICATE_VERIFY: 1345 return "CERT verify"; 1346 case SSL3_MT_FINISHED: 1347 return "Finished"; 1348 } 1349 } 1350 return "Unknown"; 1351} 1352 1353static const char *tls_rt_type(int type) 1354{ 1355 return ( 1356 type == SSL3_RT_CHANGE_CIPHER_SPEC ? "TLS change cipher, " : 1357 type == SSL3_RT_ALERT ? "TLS alert, " : 1358 type == SSL3_RT_HANDSHAKE ? "TLS handshake, " : 1359 type == SSL3_RT_APPLICATION_DATA ? "TLS app data, " : 1360 "TLS Unknown, "); 1361} 1362 1363 1364/* 1365 * Our callback from the SSL/TLS layers. 1366 */ 1367static void ssl_tls_trace(int direction, int ssl_ver, int content_type, 1368 const void *buf, size_t len, const SSL *ssl, 1369 struct connectdata *conn) 1370{ 1371 struct SessionHandle *data; 1372 const char *msg_name, *tls_rt_name; 1373 char ssl_buf[1024]; 1374 int ver, msg_type, txt_len; 1375 1376 if(!conn || !conn->data || !conn->data->set.fdebug || 1377 (direction != 0 && direction != 1)) 1378 return; 1379 1380 data = conn->data; 1381 ssl_ver >>= 8; 1382 ver = (ssl_ver == SSL2_VERSION_MAJOR ? '2' : 1383 ssl_ver == SSL3_VERSION_MAJOR ? '3' : '?'); 1384 1385 /* SSLv2 doesn't seem to have TLS record-type headers, so OpenSSL 1386 * always pass-up content-type as 0. But the interesting message-type 1387 * is at 'buf[0]'. 1388 */ 1389 if(ssl_ver == SSL3_VERSION_MAJOR && content_type != 0) 1390 tls_rt_name = tls_rt_type(content_type); 1391 else 1392 tls_rt_name = ""; 1393 1394 msg_type = *(char*)buf; 1395 msg_name = ssl_msg_type(ssl_ver, msg_type); 1396 1397 txt_len = snprintf(ssl_buf, sizeof(ssl_buf), "SSLv%c, %s%s (%d):\n", 1398 ver, tls_rt_name, msg_name, msg_type); 1399 Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL); 1400 1401 Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT : 1402 CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL); 1403 (void) ssl; 1404} 1405#endif 1406 1407#ifdef USE_SSLEAY 1408/* ====================================================== */ 1409 1410#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME 1411# define use_sni(x) sni = (x) 1412#else 1413# define use_sni(x) do { } while (0) 1414#endif 1415 1416static CURLcode 1417ossl_connect_step1(struct connectdata *conn, 1418 int sockindex) 1419{ 1420 CURLcode retcode = CURLE_OK; 1421 1422 struct SessionHandle *data = conn->data; 1423 SSL_METHOD_QUAL SSL_METHOD *req_method=NULL; 1424 void *ssl_sessionid=NULL; 1425 X509_LOOKUP *lookup=NULL; 1426 curl_socket_t sockfd = conn->sock[sockindex]; 1427 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 1428#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME 1429 bool sni; 1430#ifdef ENABLE_IPV6 1431 struct in6_addr addr; 1432#else 1433 struct in_addr addr; 1434#endif 1435#endif 1436 1437 DEBUGASSERT(ssl_connect_1 == connssl->connecting_state); 1438 1439 /* Make funny stuff to get random input */ 1440 Curl_ossl_seed(data); 1441 1442 /* check to see if we've been told to use an explicit SSL/TLS version */ 1443 1444 switch(data->set.ssl.version) { 1445 default: 1446 case CURL_SSLVERSION_DEFAULT: 1447#ifdef USE_TLS_SRP 1448 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { 1449 infof(data, "Set version TLSv1 for SRP authorisation\n"); 1450 req_method = TLSv1_client_method() ; 1451 } 1452 else 1453#endif 1454 /* we try to figure out version */ 1455 req_method = SSLv23_client_method(); 1456 use_sni(TRUE); 1457 break; 1458 case CURL_SSLVERSION_TLSv1: 1459 req_method = TLSv1_client_method(); 1460 use_sni(TRUE); 1461 break; 1462 case CURL_SSLVERSION_SSLv2: 1463#ifdef OPENSSL_NO_SSL2 1464 failf(data, "OpenSSL was built without SSLv2 support"); 1465 return CURLE_NOT_BUILT_IN; 1466#else 1467#ifdef USE_TLS_SRP 1468 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) 1469 return CURLE_SSL_CONNECT_ERROR; 1470#endif 1471 req_method = SSLv2_client_method(); 1472 use_sni(FALSE); 1473 break; 1474#endif 1475 case CURL_SSLVERSION_SSLv3: 1476#ifdef USE_TLS_SRP 1477 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) 1478 return CURLE_SSL_CONNECT_ERROR; 1479#endif 1480 req_method = SSLv3_client_method(); 1481 use_sni(FALSE); 1482 break; 1483 } 1484 1485 if(connssl->ctx) 1486 SSL_CTX_free(connssl->ctx); 1487 connssl->ctx = SSL_CTX_new(req_method); 1488 1489 if(!connssl->ctx) { 1490 failf(data, "SSL: couldn't create a context: %s", 1491 ERR_error_string(ERR_peek_error(), NULL)); 1492 return CURLE_OUT_OF_MEMORY; 1493 } 1494 1495#ifdef SSL_CTRL_SET_MSG_CALLBACK 1496 if(data->set.fdebug && data->set.verbose) { 1497 /* the SSL trace callback is only used for verbose logging so we only 1498 inform about failures of setting it */ 1499 if(!SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK, 1500 (void (*)(void))ssl_tls_trace)) { 1501 infof(data, "SSL: couldn't set callback!\n"); 1502 } 1503 else if(!SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, 1504 conn)) { 1505 infof(data, "SSL: couldn't set callback argument!\n"); 1506 } 1507 } 1508#endif 1509 1510 /* OpenSSL contains code to work-around lots of bugs and flaws in various 1511 SSL-implementations. SSL_CTX_set_options() is used to enabled those 1512 work-arounds. The man page for this option states that SSL_OP_ALL enables 1513 all the work-arounds and that "It is usually safe to use SSL_OP_ALL to 1514 enable the bug workaround options if compatibility with somewhat broken 1515 implementations is desired." 1516 1517 The "-no_ticket" option was introduced in Openssl0.9.8j. It's a flag to 1518 disable "rfc4507bis session ticket support". rfc4507bis was later turned 1519 into the proper RFC5077 it seems: http://tools.ietf.org/html/rfc5077 1520 1521 The enabled extension concerns the session management. I wonder how often 1522 libcurl stops a connection and then resumes a TLS session. also, sending 1523 the session data is some overhead. .I suggest that you just use your 1524 proposed patch (which explicitly disables TICKET). 1525 1526 If someone writes an application with libcurl and openssl who wants to 1527 enable the feature, one can do this in the SSL callback. 1528 1529 */ 1530#ifdef SSL_OP_NO_TICKET 1531 /* expect older openssl releases to not have this define so only use it if 1532 present */ 1533#define CURL_CTX_OPTIONS SSL_OP_ALL|SSL_OP_NO_TICKET 1534#else 1535#define CURL_CTX_OPTIONS SSL_OP_ALL 1536#endif 1537 1538 SSL_CTX_set_options(connssl->ctx, CURL_CTX_OPTIONS); 1539 1540 /* disable SSLv2 in the default case (i.e. allow SSLv3 and TLSv1) */ 1541 if(data->set.ssl.version == CURL_SSLVERSION_DEFAULT) 1542 SSL_CTX_set_options(connssl->ctx, SSL_OP_NO_SSLv2); 1543 1544#if 0 1545 /* 1546 * Not sure it's needed to tell SSL_connect() that socket is 1547 * non-blocking. It doesn't seem to care, but just return with 1548 * SSL_ERROR_WANT_x. 1549 */ 1550 if(data->state.used_interface == Curl_if_multi) 1551 SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL); 1552#endif 1553 1554 if(data->set.str[STRING_CERT] || data->set.str[STRING_CERT_TYPE]) { 1555 if(!cert_stuff(conn, 1556 connssl->ctx, 1557 data->set.str[STRING_CERT], 1558 data->set.str[STRING_CERT_TYPE], 1559 data->set.str[STRING_KEY], 1560 data->set.str[STRING_KEY_TYPE])) { 1561 /* failf() is already done in cert_stuff() */ 1562 return CURLE_SSL_CERTPROBLEM; 1563 } 1564 } 1565 1566 if(data->set.str[STRING_SSL_CIPHER_LIST]) { 1567 if(!SSL_CTX_set_cipher_list(connssl->ctx, 1568 data->set.str[STRING_SSL_CIPHER_LIST])) { 1569 failf(data, "failed setting cipher list"); 1570 return CURLE_SSL_CIPHER; 1571 } 1572 } 1573 1574#ifdef USE_TLS_SRP 1575 if(data->set.ssl.authtype == CURL_TLSAUTH_SRP) { 1576 infof(data, "Using TLS-SRP username: %s\n", data->set.ssl.username); 1577 1578 if(!SSL_CTX_set_srp_username(connssl->ctx, data->set.ssl.username)) { 1579 failf(data, "Unable to set SRP user name"); 1580 return CURLE_BAD_FUNCTION_ARGUMENT; 1581 } 1582 if(!SSL_CTX_set_srp_password(connssl->ctx,data->set.ssl.password)) { 1583 failf(data, "failed setting SRP password"); 1584 return CURLE_BAD_FUNCTION_ARGUMENT; 1585 } 1586 if(!data->set.str[STRING_SSL_CIPHER_LIST]) { 1587 infof(data, "Setting cipher list SRP\n"); 1588 1589 if(!SSL_CTX_set_cipher_list(connssl->ctx, "SRP")) { 1590 failf(data, "failed setting SRP cipher list"); 1591 return CURLE_SSL_CIPHER; 1592 } 1593 } 1594 } 1595#endif 1596 if(data->set.str[STRING_SSL_CAFILE] || data->set.str[STRING_SSL_CAPATH]) { 1597 /* tell SSL where to find CA certificates that are used to verify 1598 the servers certificate. */ 1599 if(!SSL_CTX_load_verify_locations(connssl->ctx, 1600 data->set.str[STRING_SSL_CAFILE], 1601 data->set.str[STRING_SSL_CAPATH])) { 1602 if(data->set.ssl.verifypeer) { 1603 /* Fail if we insist on successfully verifying the server. */ 1604 failf(data,"error setting certificate verify locations:\n" 1605 " CAfile: %s\n CApath: %s\n", 1606 data->set.str[STRING_SSL_CAFILE]? 1607 data->set.str[STRING_SSL_CAFILE]: "none", 1608 data->set.str[STRING_SSL_CAPATH]? 1609 data->set.str[STRING_SSL_CAPATH] : "none"); 1610 return CURLE_SSL_CACERT_BADFILE; 1611 } 1612 else { 1613 /* Just continue with a warning if no strict certificate verification 1614 is required. */ 1615 infof(data, "error setting certificate verify locations," 1616 " continuing anyway:\n"); 1617 } 1618 } 1619 else { 1620 /* Everything is fine. */ 1621 infof(data, "successfully set certificate verify locations:\n"); 1622 } 1623 infof(data, 1624 " CAfile: %s\n" 1625 " CApath: %s\n", 1626 data->set.str[STRING_SSL_CAFILE] ? data->set.str[STRING_SSL_CAFILE]: 1627 "none", 1628 data->set.str[STRING_SSL_CAPATH] ? data->set.str[STRING_SSL_CAPATH]: 1629 "none"); 1630 } 1631 1632 if(data->set.str[STRING_SSL_CRLFILE]) { 1633 /* tell SSL where to find CRL file that is used to check certificate 1634 * revocation */ 1635 lookup=X509_STORE_add_lookup(connssl->ctx->cert_store,X509_LOOKUP_file()); 1636 if(!lookup || 1637 (!X509_load_crl_file(lookup,data->set.str[STRING_SSL_CRLFILE], 1638 X509_FILETYPE_PEM)) ) { 1639 failf(data,"error loading CRL file: %s\n", 1640 data->set.str[STRING_SSL_CRLFILE]); 1641 return CURLE_SSL_CRL_BADFILE; 1642 } 1643 else { 1644 /* Everything is fine. */ 1645 infof(data, "successfully load CRL file:\n"); 1646 X509_STORE_set_flags(connssl->ctx->cert_store, 1647 X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL); 1648 } 1649 infof(data, 1650 " CRLfile: %s\n", data->set.str[STRING_SSL_CRLFILE] ? 1651 data->set.str[STRING_SSL_CRLFILE]: "none"); 1652 } 1653 1654 /* SSL always tries to verify the peer, this only says whether it should 1655 * fail to connect if the verification fails, or if it should continue 1656 * anyway. In the latter case the result of the verification is checked with 1657 * SSL_get_verify_result() below. */ 1658 SSL_CTX_set_verify(connssl->ctx, 1659 data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE, 1660 cert_verify_callback); 1661 1662 /* give application a chance to interfere with SSL set up. */ 1663 if(data->set.ssl.fsslctx) { 1664 retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx, 1665 data->set.ssl.fsslctxp); 1666 if(retcode) { 1667 failf(data,"error signaled by ssl ctx callback"); 1668 return retcode; 1669 } 1670 } 1671 1672 /* Lets make an SSL structure */ 1673 if(connssl->handle) 1674 SSL_free(connssl->handle); 1675 connssl->handle = SSL_new(connssl->ctx); 1676 if(!connssl->handle) { 1677 failf(data, "SSL: couldn't create a context (handle)!"); 1678 return CURLE_OUT_OF_MEMORY; 1679 } 1680 SSL_set_connect_state(connssl->handle); 1681 1682 connssl->server_cert = 0x0; 1683 1684#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME 1685 if((0 == Curl_inet_pton(AF_INET, conn->host.name, &addr)) && 1686#ifdef ENABLE_IPV6 1687 (0 == Curl_inet_pton(AF_INET6, conn->host.name, &addr)) && 1688#endif 1689 sni && 1690 !SSL_set_tlsext_host_name(connssl->handle, conn->host.name)) 1691 infof(data, "WARNING: failed to configure server name indication (SNI) " 1692 "TLS extension\n"); 1693#endif 1694 1695 /* Check if there's a cached ID we can/should use here! */ 1696 if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, NULL)) { 1697 /* we got a session id, use it! */ 1698 if(!SSL_set_session(connssl->handle, ssl_sessionid)) { 1699 failf(data, "SSL: SSL_set_session failed: %s", 1700 ERR_error_string(ERR_get_error(),NULL)); 1701 return CURLE_SSL_CONNECT_ERROR; 1702 } 1703 /* Informational message */ 1704 infof (data, "SSL re-using session ID\n"); 1705 } 1706 1707 /* pass the raw socket into the SSL layers */ 1708 if(!SSL_set_fd(connssl->handle, (int)sockfd)) { 1709 failf(data, "SSL: SSL_set_fd failed: %s", 1710 ERR_error_string(ERR_get_error(),NULL)); 1711 return CURLE_SSL_CONNECT_ERROR; 1712 } 1713 1714 connssl->connecting_state = ssl_connect_2; 1715 return CURLE_OK; 1716} 1717 1718static CURLcode 1719ossl_connect_step2(struct connectdata *conn, int sockindex) 1720{ 1721 struct SessionHandle *data = conn->data; 1722 int err; 1723 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 1724 1725 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state 1726 || ssl_connect_2_reading == connssl->connecting_state 1727 || ssl_connect_2_writing == connssl->connecting_state); 1728 1729 ERR_clear_error(); 1730 1731 err = SSL_connect(connssl->handle); 1732 1733 /* 1 is fine 1734 0 is "not successful but was shut down controlled" 1735 <0 is "handshake was not successful, because a fatal error occurred" */ 1736 if(1 != err) { 1737 int detail = SSL_get_error(connssl->handle, err); 1738 1739 if(SSL_ERROR_WANT_READ == detail) { 1740 connssl->connecting_state = ssl_connect_2_reading; 1741 return CURLE_OK; 1742 } 1743 else if(SSL_ERROR_WANT_WRITE == detail) { 1744 connssl->connecting_state = ssl_connect_2_writing; 1745 return CURLE_OK; 1746 } 1747 else { 1748 /* untreated error */ 1749 unsigned long errdetail; 1750 char error_buffer[256]; /* OpenSSL documents that this must be at least 1751 256 bytes long. */ 1752 CURLcode rc; 1753 const char *cert_problem = NULL; 1754 1755 connssl->connecting_state = ssl_connect_2; /* the connection failed, 1756 we're not waiting for 1757 anything else. */ 1758 1759 errdetail = ERR_get_error(); /* Gets the earliest error code from the 1760 thread's error queue and removes the 1761 entry. */ 1762 1763 switch(errdetail) { 1764 case 0x1407E086: 1765 /* 1407E086: 1766 SSL routines: 1767 SSL2_SET_CERTIFICATE: 1768 certificate verify failed */ 1769 /* fall-through */ 1770 case 0x14090086: 1771 /* 14090086: 1772 SSL routines: 1773 SSL3_GET_SERVER_CERTIFICATE: 1774 certificate verify failed */ 1775 cert_problem = "SSL certificate problem, verify that the CA cert is" 1776 " OK. Details:\n"; 1777 rc = CURLE_SSL_CACERT; 1778 break; 1779 default: 1780 rc = CURLE_SSL_CONNECT_ERROR; 1781 break; 1782 } 1783 1784 /* detail is already set to the SSL error above */ 1785 1786 /* If we e.g. use SSLv2 request-method and the server doesn't like us 1787 * (RST connection etc.), OpenSSL gives no explanation whatsoever and 1788 * the SO_ERROR is also lost. 1789 */ 1790 if(CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) { 1791 failf(data, "Unknown SSL protocol error in connection to %s:%ld ", 1792 conn->host.name, conn->port); 1793 return rc; 1794 } 1795 /* Could be a CERT problem */ 1796 1797 SSL_strerror(errdetail, error_buffer, sizeof(error_buffer)); 1798 failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer); 1799 return rc; 1800 } 1801 } 1802 else { 1803 /* we have been connected fine, we're not waiting for anything else. */ 1804 connssl->connecting_state = ssl_connect_3; 1805 1806 /* Informational message */ 1807 infof (data, "SSL connection using %s\n", 1808 SSL_get_cipher(connssl->handle)); 1809 1810 return CURLE_OK; 1811 } 1812} 1813 1814static int asn1_object_dump(ASN1_OBJECT *a, char *buf, size_t len) 1815{ 1816 int i, ilen; 1817 1818 if((ilen = (int)len) < 0) 1819 return 1; /* buffer too big */ 1820 1821 i = i2t_ASN1_OBJECT(buf, ilen, a); 1822 1823 if(i >= ilen) 1824 return 1; /* buffer too small */ 1825 1826 return 0; 1827} 1828 1829static CURLcode push_certinfo_len(struct SessionHandle *data, 1830 int certnum, 1831 const char *label, 1832 const char *value, 1833 size_t valuelen) 1834{ 1835 struct curl_certinfo *ci = &data->info.certs; 1836 char *output; 1837 struct curl_slist *nl; 1838 CURLcode res = CURLE_OK; 1839 size_t labellen = strlen(label); 1840 size_t outlen = labellen + 1 + valuelen + 1; /* label:value\0 */ 1841 1842 output = malloc(outlen); 1843 if(!output) 1844 return CURLE_OUT_OF_MEMORY; 1845 1846 /* sprintf the label and colon */ 1847 snprintf(output, outlen, "%s:", label); 1848 1849 /* memcpy the value (it might not be zero terminated) */ 1850 memcpy(&output[labellen+1], value, valuelen); 1851 1852 /* zero terminate the output */ 1853 output[labellen + 1 + valuelen] = 0; 1854 1855 /* TODO: we should rather introduce an internal API that can do the 1856 equivalent of curl_slist_append but doesn't strdup() the given data as 1857 like in this place the extra malloc/free is totally pointless */ 1858 nl = curl_slist_append(ci->certinfo[certnum], output); 1859 if(!nl) { 1860 curl_slist_free_all(ci->certinfo[certnum]); 1861 res = CURLE_OUT_OF_MEMORY; 1862 } 1863 else 1864 ci->certinfo[certnum] = nl; 1865 1866 free(output); 1867 1868 return res; 1869} 1870 1871/* this is a convenience function for push_certinfo_len that takes a zero 1872 terminated value */ 1873static CURLcode push_certinfo(struct SessionHandle *data, 1874 int certnum, 1875 const char *label, 1876 const char *value) 1877{ 1878 size_t valuelen = strlen(value); 1879 1880 return push_certinfo_len(data, certnum, label, value, valuelen); 1881} 1882 1883static void pubkey_show(struct SessionHandle *data, 1884 int num, 1885 const char *type, 1886 const char *name, 1887 unsigned char *raw, 1888 int len) 1889{ 1890 size_t left; 1891 int i; 1892 char namebuf[32]; 1893 char *buffer; 1894 1895 left = len*3 + 1; 1896 buffer = malloc(left); 1897 if(buffer) { 1898 char *ptr=buffer; 1899 snprintf(namebuf, sizeof(namebuf), "%s(%s)", type, name); 1900 for(i=0; i< len; i++) { 1901 snprintf(ptr, left, "%02x:", raw[i]); 1902 ptr += 3; 1903 left -= 3; 1904 } 1905 infof(data, " %s: %s\n", namebuf, buffer); 1906 push_certinfo(data, num, namebuf, buffer); 1907 free(buffer); 1908 } 1909} 1910 1911#define print_pubkey_BN(_type, _name, _num) \ 1912do { \ 1913 if(pubkey->pkey._type->_name != NULL) { \ 1914 int len = BN_num_bytes(pubkey->pkey._type->_name); \ 1915 if(len < CERTBUFFERSIZE) { \ 1916 BN_bn2bin(pubkey->pkey._type->_name, (unsigned char*)bufp); \ 1917 bufp[len] = 0; \ 1918 pubkey_show(data, _num, #_type, #_name, (unsigned char*)bufp, len); \ 1919 } \ 1920 } \ 1921} while(0) 1922 1923static int X509V3_ext(struct SessionHandle *data, 1924 int certnum, 1925 STACK_OF(X509_EXTENSION) *exts) 1926{ 1927 int i; 1928 size_t j; 1929 1930 if(sk_X509_EXTENSION_num(exts) <= 0) 1931 /* no extensions, bail out */ 1932 return 1; 1933 1934 for(i=0; i<sk_X509_EXTENSION_num(exts); i++) { 1935 ASN1_OBJECT *obj; 1936 X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); 1937 BUF_MEM *biomem; 1938 char buf[512]; 1939 char *ptr=buf; 1940 char namebuf[128]; 1941 BIO *bio_out = BIO_new(BIO_s_mem()); 1942 1943 if(!bio_out) 1944 return 1; 1945 1946 obj = X509_EXTENSION_get_object(ext); 1947 1948 asn1_object_dump(obj, namebuf, sizeof(namebuf)); 1949 1950 infof(data, "%s: %s\n", namebuf, 1951 X509_EXTENSION_get_critical(ext)?"(critical)":""); 1952 1953 if(!X509V3_EXT_print(bio_out, ext, 0, 0)) 1954 M_ASN1_OCTET_STRING_print(bio_out, ext->value); 1955 1956 BIO_get_mem_ptr(bio_out, &biomem); 1957 1958 /* biomem->length bytes at biomem->data, this little loop here is only 1959 done for the infof() call, we send the "raw" data to the certinfo 1960 function */ 1961 for(j=0; j<(size_t)biomem->length; j++) { 1962 const char *sep=""; 1963 if(biomem->data[j] == '\n') { 1964 sep=", "; 1965 j++; /* skip the newline */ 1966 }; 1967 while((biomem->data[j] == ' ') && (j<(size_t)biomem->length)) 1968 j++; 1969 if(j<(size_t)biomem->length) 1970 ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%s%c", sep, 1971 biomem->data[j]); 1972 } 1973 infof(data, " %s\n", buf); 1974 1975 push_certinfo(data, certnum, namebuf, buf); 1976 1977 BIO_free(bio_out); 1978 1979 } 1980 return 0; /* all is fine */ 1981} 1982 1983 1984static void X509_signature(struct SessionHandle *data, 1985 int numcert, 1986 ASN1_STRING *sig) 1987{ 1988 char buf[1024]; 1989 char *ptr = buf; 1990 int i; 1991 for(i=0; i<sig->length; i++) 1992 ptr+=snprintf(ptr, sizeof(buf)-(ptr-buf), "%02x:", sig->data[i]); 1993 1994 infof(data, " Signature: %s\n", buf); 1995 push_certinfo(data, numcert, "Signature", buf); 1996} 1997 1998static void dumpcert(struct SessionHandle *data, X509 *x, int numcert) 1999{ 2000 BIO *bio_out = BIO_new(BIO_s_mem()); 2001 BUF_MEM *biomem; 2002 2003 /* this outputs the cert in this 64 column wide style with newlines and 2004 -----BEGIN CERTIFICATE----- texts and more */ 2005 PEM_write_bio_X509(bio_out, x); 2006 2007 BIO_get_mem_ptr(bio_out, &biomem); 2008 2009 infof(data, "%s\n", biomem->data); 2010 2011 push_certinfo_len(data, numcert, "Cert", biomem->data, biomem->length); 2012 2013 BIO_free(bio_out); 2014 2015} 2016 2017 2018static int init_certinfo(struct SessionHandle *data, 2019 int num) 2020{ 2021 struct curl_certinfo *ci = &data->info.certs; 2022 struct curl_slist **table; 2023 2024 Curl_ssl_free_certinfo(data); 2025 2026 ci->num_of_certs = num; 2027 table = calloc((size_t)num, sizeof(struct curl_slist *)); 2028 if(!table) 2029 return 1; 2030 2031 ci->certinfo = table; 2032 return 0; 2033} 2034 2035/* 2036 * This size was previously 512 which has been reported "too small" without 2037 * any specifics, so it was enlarged to allow more data to get shown uncut. 2038 * The "perfect" size is yet to figure out. 2039 */ 2040#define CERTBUFFERSIZE 8192 2041 2042static CURLcode get_cert_chain(struct connectdata *conn, 2043 struct ssl_connect_data *connssl) 2044 2045{ 2046 STACK_OF(X509) *sk; 2047 int i; 2048 char *bufp; 2049 struct SessionHandle *data = conn->data; 2050 int numcerts; 2051 2052 bufp = malloc(CERTBUFFERSIZE); 2053 if(!bufp) 2054 return CURLE_OUT_OF_MEMORY; 2055 2056 sk = SSL_get_peer_cert_chain(connssl->handle); 2057 if(!sk) { 2058 free(bufp); 2059 return CURLE_OUT_OF_MEMORY; 2060 } 2061 2062 numcerts = sk_X509_num(sk); 2063 if(init_certinfo(data, numcerts)) { 2064 free(bufp); 2065 return CURLE_OUT_OF_MEMORY; 2066 } 2067 2068 infof(data, "--- Certificate chain\n"); 2069 for(i=0; i<numcerts; i++) { 2070 long value; 2071 ASN1_INTEGER *num; 2072 ASN1_TIME *certdate; 2073 2074 /* get the certs in "importance order" */ 2075#if 0 2076 X509 *x = sk_X509_value(sk, numcerts - i - 1); 2077#else 2078 X509 *x = sk_X509_value(sk, i); 2079#endif 2080 2081 X509_CINF *cinf; 2082 EVP_PKEY *pubkey=NULL; 2083 int j; 2084 char *ptr; 2085 2086 (void)x509_name_oneline(X509_get_subject_name(x), bufp, CERTBUFFERSIZE); 2087 infof(data, "%2d Subject: %s\n", i, bufp); 2088 push_certinfo(data, i, "Subject", bufp); 2089 2090 (void)x509_name_oneline(X509_get_issuer_name(x), bufp, CERTBUFFERSIZE); 2091 infof(data, " Issuer: %s\n", bufp); 2092 push_certinfo(data, i, "Issuer", bufp); 2093 2094 value = X509_get_version(x); 2095 infof(data, " Version: %lu (0x%lx)\n", value+1, value); 2096 snprintf(bufp, CERTBUFFERSIZE, "%lx", value); 2097 push_certinfo(data, i, "Version", bufp); /* hex */ 2098 2099 num=X509_get_serialNumber(x); 2100 if(num->length <= 4) { 2101 value = ASN1_INTEGER_get(num); 2102 infof(data," Serial Number: %ld (0x%lx)\n", value, value); 2103 snprintf(bufp, CERTBUFFERSIZE, "%lx", value); 2104 } 2105 else { 2106 int left = CERTBUFFERSIZE; 2107 2108 ptr = bufp; 2109 *ptr++ = 0; 2110 if(num->type == V_ASN1_NEG_INTEGER) 2111 *ptr++='-'; 2112 2113 for(j=0; (j<num->length) && (left>=4); j++) { 2114 /* TODO: length restrictions */ 2115 snprintf(ptr, 3, "%02x%c",num->data[j], 2116 ((j+1 == num->length)?'\n':':')); 2117 ptr += 3; 2118 left-=4; 2119 } 2120 if(num->length) 2121 infof(data," Serial Number: %s\n", bufp); 2122 else 2123 bufp[0]=0; 2124 } 2125 if(bufp[0]) 2126 push_certinfo(data, i, "Serial Number", bufp); /* hex */ 2127 2128 cinf = x->cert_info; 2129 2130 j = asn1_object_dump(cinf->signature->algorithm, bufp, CERTBUFFERSIZE); 2131 if(!j) { 2132 infof(data, " Signature Algorithm: %s\n", bufp); 2133 push_certinfo(data, i, "Signature Algorithm", bufp); 2134 } 2135 2136 certdate = X509_get_notBefore(x); 2137 asn1_output(certdate, bufp, CERTBUFFERSIZE); 2138 infof(data, " Start date: %s\n", bufp); 2139 push_certinfo(data, i, "Start date", bufp); 2140 2141 certdate = X509_get_notAfter(x); 2142 asn1_output(certdate, bufp, CERTBUFFERSIZE); 2143 infof(data, " Expire date: %s\n", bufp); 2144 push_certinfo(data, i, "Expire date", bufp); 2145 2146 j = asn1_object_dump(cinf->key->algor->algorithm, bufp, CERTBUFFERSIZE); 2147 if(!j) { 2148 infof(data, " Public Key Algorithm: %s\n", bufp); 2149 push_certinfo(data, i, "Public Key Algorithm", bufp); 2150 } 2151 2152 pubkey = X509_get_pubkey(x); 2153 if(!pubkey) 2154 infof(data, " Unable to load public key\n"); 2155 else { 2156 switch(pubkey->type) { 2157 case EVP_PKEY_RSA: 2158 infof(data, " RSA Public Key (%d bits)\n", 2159 BN_num_bits(pubkey->pkey.rsa->n)); 2160 snprintf(bufp, CERTBUFFERSIZE, "%d", BN_num_bits(pubkey->pkey.rsa->n)); 2161 push_certinfo(data, i, "RSA Public Key", bufp); 2162 2163 print_pubkey_BN(rsa, n, i); 2164 print_pubkey_BN(rsa, e, i); 2165 print_pubkey_BN(rsa, d, i); 2166 print_pubkey_BN(rsa, p, i); 2167 print_pubkey_BN(rsa, q, i); 2168 print_pubkey_BN(rsa, dmp1, i); 2169 print_pubkey_BN(rsa, dmq1, i); 2170 print_pubkey_BN(rsa, iqmp, i); 2171 break; 2172 case EVP_PKEY_DSA: 2173 print_pubkey_BN(dsa, p, i); 2174 print_pubkey_BN(dsa, q, i); 2175 print_pubkey_BN(dsa, g, i); 2176 print_pubkey_BN(dsa, priv_key, i); 2177 print_pubkey_BN(dsa, pub_key, i); 2178 break; 2179 case EVP_PKEY_DH: 2180 print_pubkey_BN(dh, p, i); 2181 print_pubkey_BN(dh, g, i); 2182 print_pubkey_BN(dh, priv_key, i); 2183 print_pubkey_BN(dh, pub_key, i); 2184 break; 2185#if 0 2186 case EVP_PKEY_EC: /* symbol not present in OpenSSL 0.9.6 */ 2187 /* left TODO */ 2188 break; 2189#endif 2190 } 2191 EVP_PKEY_free(pubkey); 2192 } 2193 2194 X509V3_ext(data, i, cinf->extensions); 2195 2196 X509_signature(data, i, x->signature); 2197 2198 dumpcert(data, x, i); 2199 } 2200 2201 free(bufp); 2202 2203 return CURLE_OK; 2204} 2205 2206/* 2207 * Get the server cert, verify it and show it etc, only call failf() if the 2208 * 'strict' argument is TRUE as otherwise all this is for informational 2209 * purposes only! 2210 * 2211 * We check certificates to authenticate the server; otherwise we risk 2212 * man-in-the-middle attack. 2213 */ 2214static CURLcode servercert(struct connectdata *conn, 2215 struct ssl_connect_data *connssl, 2216 bool strict) 2217{ 2218 CURLcode retcode = CURLE_OK; 2219 int rc; 2220 long lerr; 2221 ASN1_TIME *certdate; 2222 struct SessionHandle *data = conn->data; 2223 X509 *issuer; 2224 FILE *fp; 2225 char buffer[256]; 2226 2227 if(data->set.ssl.certinfo) 2228 /* we've been asked to gather certificate info! */ 2229 (void)get_cert_chain(conn, connssl); 2230 2231 data->set.ssl.certverifyresult = !X509_V_OK; 2232 2233 connssl->server_cert = SSL_get_peer_certificate(connssl->handle); 2234 if(!connssl->server_cert) { 2235 if(strict) 2236 failf(data, "SSL: couldn't get peer certificate!"); 2237 return CURLE_PEER_FAILED_VERIFICATION; 2238 } 2239 infof (data, "Server certificate:\n"); 2240 2241 rc = x509_name_oneline(X509_get_subject_name(connssl->server_cert), 2242 buffer, sizeof(buffer)); 2243 if(rc) { 2244 if(strict) 2245 failf(data, "SSL: couldn't get X509-subject!"); 2246 X509_free(connssl->server_cert); 2247 connssl->server_cert = NULL; 2248 return CURLE_SSL_CONNECT_ERROR; 2249 } 2250 infof(data, "\t subject: %s\n", buffer); 2251 2252 certdate = X509_get_notBefore(connssl->server_cert); 2253 asn1_output(certdate, buffer, sizeof(buffer)); 2254 infof(data, "\t start date: %s\n", buffer); 2255 2256 certdate = X509_get_notAfter(connssl->server_cert); 2257 asn1_output(certdate, buffer, sizeof(buffer)); 2258 infof(data, "\t expire date: %s\n", buffer); 2259 2260 if(data->set.ssl.verifyhost) { 2261 retcode = verifyhost(conn, connssl->server_cert); 2262 if(retcode) { 2263 X509_free(connssl->server_cert); 2264 connssl->server_cert = NULL; 2265 return retcode; 2266 } 2267 } 2268 2269 rc = x509_name_oneline(X509_get_issuer_name(connssl->server_cert), 2270 buffer, sizeof(buffer)); 2271 if(rc) { 2272 if(strict) 2273 failf(data, "SSL: couldn't get X509-issuer name!"); 2274 retcode = CURLE_SSL_CONNECT_ERROR; 2275 } 2276 else { 2277 infof(data, "\t issuer: %s\n", buffer); 2278 2279 /* We could do all sorts of certificate verification stuff here before 2280 deallocating the certificate. */ 2281 2282 /* e.g. match issuer name with provided issuer certificate */ 2283 if(data->set.str[STRING_SSL_ISSUERCERT]) { 2284 fp=fopen(data->set.str[STRING_SSL_ISSUERCERT],"r"); 2285 if(!fp) { 2286 if(strict) 2287 failf(data, "SSL: Unable to open issuer cert (%s)\n", 2288 data->set.str[STRING_SSL_ISSUERCERT]); 2289 X509_free(connssl->server_cert); 2290 connssl->server_cert = NULL; 2291 return CURLE_SSL_ISSUER_ERROR; 2292 } 2293 issuer = PEM_read_X509(fp,NULL,ZERO_NULL,NULL); 2294 if(!issuer) { 2295 if(strict) 2296 failf(data, "SSL: Unable to read issuer cert (%s)\n", 2297 data->set.str[STRING_SSL_ISSUERCERT]); 2298 X509_free(connssl->server_cert); 2299 X509_free(issuer); 2300 fclose(fp); 2301 return CURLE_SSL_ISSUER_ERROR; 2302 } 2303 fclose(fp); 2304 if(X509_check_issued(issuer,connssl->server_cert) != X509_V_OK) { 2305 if(strict) 2306 failf(data, "SSL: Certificate issuer check failed (%s)\n", 2307 data->set.str[STRING_SSL_ISSUERCERT]); 2308 X509_free(connssl->server_cert); 2309 X509_free(issuer); 2310 connssl->server_cert = NULL; 2311 return CURLE_SSL_ISSUER_ERROR; 2312 } 2313 infof(data, "\t SSL certificate issuer check ok (%s)\n", 2314 data->set.str[STRING_SSL_ISSUERCERT]); 2315 X509_free(issuer); 2316 } 2317 2318 lerr = data->set.ssl.certverifyresult= 2319 SSL_get_verify_result(connssl->handle); 2320 if(data->set.ssl.certverifyresult != X509_V_OK) { 2321 if(data->set.ssl.verifypeer) { 2322 /* We probably never reach this, because SSL_connect() will fail 2323 and we return earlier if verifypeer is set? */ 2324 if(strict) 2325 failf(data, "SSL certificate verify result: %s (%ld)", 2326 X509_verify_cert_error_string(lerr), lerr); 2327 retcode = CURLE_PEER_FAILED_VERIFICATION; 2328 } 2329 else 2330 infof(data, "\t SSL certificate verify result: %s (%ld)," 2331 " continuing anyway.\n", 2332 X509_verify_cert_error_string(lerr), lerr); 2333 } 2334 else 2335 infof(data, "\t SSL certificate verify ok.\n"); 2336 } 2337 2338 X509_free(connssl->server_cert); 2339 connssl->server_cert = NULL; 2340 connssl->connecting_state = ssl_connect_done; 2341 2342 return retcode; 2343} 2344 2345 2346static CURLcode 2347ossl_connect_step3(struct connectdata *conn, 2348 int sockindex) 2349{ 2350 CURLcode retcode = CURLE_OK; 2351 void *old_ssl_sessionid=NULL; 2352 struct SessionHandle *data = conn->data; 2353 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 2354 int incache; 2355 SSL_SESSION *our_ssl_sessionid; 2356 2357 DEBUGASSERT(ssl_connect_3 == connssl->connecting_state); 2358 2359#ifdef HAVE_SSL_GET1_SESSION 2360 our_ssl_sessionid = SSL_get1_session(connssl->handle); 2361 2362 /* SSL_get1_session() will increment the reference 2363 count and the session will stay in memory until explicitly freed with 2364 SSL_SESSION_free(3), regardless of its state. 2365 This function was introduced in openssl 0.9.5a. */ 2366#else 2367 our_ssl_sessionid = SSL_get_session(connssl->handle); 2368 2369 /* if SSL_get1_session() is unavailable, use SSL_get_session(). 2370 This is an inferior option because the session can be flushed 2371 at any time by openssl. It is included only so curl compiles 2372 under versions of openssl < 0.9.5a. 2373 2374 WARNING: How curl behaves if it's session is flushed is 2375 untested. 2376 */ 2377#endif 2378 2379 incache = !(Curl_ssl_getsessionid(conn, &old_ssl_sessionid, NULL)); 2380 if(incache) { 2381 if(old_ssl_sessionid != our_ssl_sessionid) { 2382 infof(data, "old SSL session ID is stale, removing\n"); 2383 Curl_ssl_delsessionid(conn, old_ssl_sessionid); 2384 incache = FALSE; 2385 } 2386 } 2387 if(!incache) { 2388 retcode = Curl_ssl_addsessionid(conn, our_ssl_sessionid, 2389 0 /* unknown size */); 2390 if(retcode) { 2391 failf(data, "failed to store ssl session"); 2392 return retcode; 2393 } 2394 } 2395#ifdef HAVE_SSL_GET1_SESSION 2396 else { 2397 /* Session was incache, so refcount already incremented earlier. 2398 * Avoid further increments with each SSL_get1_session() call. 2399 * This does not free the session as refcount remains > 0 2400 */ 2401 SSL_SESSION_free(our_ssl_sessionid); 2402 } 2403#endif 2404 2405 /* 2406 * We check certificates to authenticate the server; otherwise we risk 2407 * man-in-the-middle attack; NEVERTHELESS, if we're told explicitly not to 2408 * verify the peer ignore faults and failures from the server cert 2409 * operations. 2410 */ 2411 2412 if(!data->set.ssl.verifypeer) 2413 (void)servercert(conn, connssl, FALSE); 2414 else 2415 retcode = servercert(conn, connssl, TRUE); 2416 2417 if(CURLE_OK == retcode) 2418 connssl->connecting_state = ssl_connect_done; 2419 return retcode; 2420} 2421 2422static Curl_recv ossl_recv; 2423static Curl_send ossl_send; 2424 2425static CURLcode 2426ossl_connect_common(struct connectdata *conn, 2427 int sockindex, 2428 bool nonblocking, 2429 bool *done) 2430{ 2431 CURLcode retcode; 2432 struct SessionHandle *data = conn->data; 2433 struct ssl_connect_data *connssl = &conn->ssl[sockindex]; 2434 curl_socket_t sockfd = conn->sock[sockindex]; 2435 long timeout_ms; 2436 int what; 2437 2438 /* check if the connection has already been established */ 2439 if(ssl_connection_complete == connssl->state) { 2440 *done = TRUE; 2441 return CURLE_OK; 2442 } 2443 2444 if(ssl_connect_1==connssl->connecting_state) { 2445 /* Find out how much more time we're allowed */ 2446 timeout_ms = Curl_timeleft(data, NULL, TRUE); 2447 2448 if(timeout_ms < 0) { 2449 /* no need to continue if time already is up */ 2450 failf(data, "SSL connection timeout"); 2451 return CURLE_OPERATION_TIMEDOUT; 2452 } 2453 retcode = ossl_connect_step1(conn, sockindex); 2454 if(retcode) 2455 return retcode; 2456 } 2457 2458 while(ssl_connect_2 == connssl->connecting_state || 2459 ssl_connect_2_reading == connssl->connecting_state || 2460 ssl_connect_2_writing == connssl->connecting_state) { 2461 2462 /* check allowed time left */ 2463 timeout_ms = Curl_timeleft(data, NULL, TRUE); 2464 2465 if(timeout_ms < 0) { 2466 /* no need to continue if time already is up */ 2467 failf(data, "SSL connection timeout"); 2468 return CURLE_OPERATION_TIMEDOUT; 2469 } 2470 2471 /* if ssl is expecting something, check if it's available. */ 2472 if(connssl->connecting_state == ssl_connect_2_reading 2473 || connssl->connecting_state == ssl_connect_2_writing) { 2474 2475 curl_socket_t writefd = ssl_connect_2_writing== 2476 connssl->connecting_state?sockfd:CURL_SOCKET_BAD; 2477 curl_socket_t readfd = ssl_connect_2_reading== 2478 connssl->connecting_state?sockfd:CURL_SOCKET_BAD; 2479 2480 what = Curl_socket_ready(readfd, writefd, nonblocking?0:timeout_ms); 2481 if(what < 0) { 2482 /* fatal error */ 2483 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); 2484 return CURLE_SSL_CONNECT_ERROR; 2485 } 2486 else if(0 == what) { 2487 if(nonblocking) { 2488 *done = FALSE; 2489 return CURLE_OK; 2490 } 2491 else { 2492 /* timeout */ 2493 failf(data, "SSL connection timeout"); 2494 return CURLE_OPERATION_TIMEDOUT; 2495 } 2496 } 2497 /* socket is readable or writable */ 2498 } 2499 2500 /* Run transaction, and return to the caller if it failed or if this 2501 * connection is done nonblocking and this loop would execute again. This 2502 * permits the owner of a multi handle to abort a connection attempt 2503 * before step2 has completed while ensuring that a client using select() 2504 * or epoll() will always have a valid fdset to wait on. 2505 */ 2506 retcode = ossl_connect_step2(conn, sockindex); 2507 if(retcode || (nonblocking && 2508 (ssl_connect_2 == connssl->connecting_state || 2509 ssl_connect_2_reading == connssl->connecting_state || 2510 ssl_connect_2_writing == connssl->connecting_state))) 2511 return retcode; 2512 2513 } /* repeat step2 until all transactions are done. */ 2514 2515 2516 if(ssl_connect_3==connssl->connecting_state) { 2517 retcode = ossl_connect_step3(conn, sockindex); 2518 if(retcode) 2519 return retcode; 2520 } 2521 2522 if(ssl_connect_done==connssl->connecting_state) { 2523 connssl->state = ssl_connection_complete; 2524 conn->recv[sockindex] = ossl_recv; 2525 conn->send[sockindex] = ossl_send; 2526 *done = TRUE; 2527 } 2528 else 2529 *done = FALSE; 2530 2531 /* Reset our connect state machine */ 2532 connssl->connecting_state = ssl_connect_1; 2533 2534 return CURLE_OK; 2535} 2536 2537CURLcode 2538Curl_ossl_connect_nonblocking(struct connectdata *conn, 2539 int sockindex, 2540 bool *done) 2541{ 2542 return ossl_connect_common(conn, sockindex, TRUE, done); 2543} 2544 2545CURLcode 2546Curl_ossl_connect(struct connectdata *conn, 2547 int sockindex) 2548{ 2549 CURLcode retcode; 2550 bool done = FALSE; 2551 2552 retcode = ossl_connect_common(conn, sockindex, FALSE, &done); 2553 if(retcode) 2554 return retcode; 2555 2556 DEBUGASSERT(done); 2557 2558 return CURLE_OK; 2559} 2560 2561bool Curl_ossl_data_pending(const struct connectdata *conn, 2562 int connindex) 2563{ 2564 if(conn->ssl[connindex].handle) 2565 /* SSL is in use */ 2566 return (bool)(0 != SSL_pending(conn->ssl[connindex].handle)); 2567 else 2568 return FALSE; 2569} 2570 2571static ssize_t ossl_send(struct connectdata *conn, 2572 int sockindex, 2573 const void *mem, 2574 size_t len, 2575 CURLcode *curlcode) 2576{ 2577 /* SSL_write() is said to return 'int' while write() and send() returns 2578 'size_t' */ 2579 int err; 2580 char error_buffer[120]; /* OpenSSL documents that this must be at least 120 2581 bytes long. */ 2582 unsigned long sslerror; 2583 int memlen; 2584 int rc; 2585 2586 ERR_clear_error(); 2587 2588 memlen = (len > (size_t)INT_MAX) ? INT_MAX : (int)len; 2589 rc = SSL_write(conn->ssl[sockindex].handle, mem, memlen); 2590 2591 if(rc < 0) { 2592 err = SSL_get_error(conn->ssl[sockindex].handle, rc); 2593 2594 switch(err) { 2595 case SSL_ERROR_WANT_READ: 2596 case SSL_ERROR_WANT_WRITE: 2597 /* The operation did not complete; the same TLS/SSL I/O function 2598 should be called again later. This is basically an EWOULDBLOCK 2599 equivalent. */ 2600 *curlcode = CURLE_AGAIN; 2601 return -1; 2602 case SSL_ERROR_SYSCALL: 2603 failf(conn->data, "SSL_write() returned SYSCALL, errno = %d", 2604 SOCKERRNO); 2605 *curlcode = CURLE_SEND_ERROR; 2606 return -1; 2607 case SSL_ERROR_SSL: 2608 /* A failure in the SSL library occurred, usually a protocol error. 2609 The OpenSSL error queue contains more information on the error. */ 2610 sslerror = ERR_get_error(); 2611 failf(conn->data, "SSL_write() error: %s", 2612 ERR_error_string(sslerror, error_buffer)); 2613 *curlcode = CURLE_SEND_ERROR; 2614 return -1; 2615 } 2616 /* a true error */ 2617 failf(conn->data, "SSL_write() return error %d", err); 2618 *curlcode = CURLE_SEND_ERROR; 2619 return -1; 2620 } 2621 return (ssize_t)rc; /* number of bytes */ 2622} 2623 2624static ssize_t ossl_recv(struct connectdata *conn, /* connection data */ 2625 int num, /* socketindex */ 2626 char *buf, /* store read data here */ 2627 size_t buffersize, /* max amount to read */ 2628 CURLcode *curlcode) 2629{ 2630 char error_buffer[120]; /* OpenSSL documents that this must be at 2631 least 120 bytes long. */ 2632 unsigned long sslerror; 2633 ssize_t nread; 2634 int buffsize; 2635 2636 ERR_clear_error(); 2637 2638 buffsize = (buffersize > (size_t)INT_MAX) ? INT_MAX : (int)buffersize; 2639 nread = (ssize_t)SSL_read(conn->ssl[num].handle, buf, buffsize); 2640 if(nread < 0) { 2641 /* failed SSL_read */ 2642 int err = SSL_get_error(conn->ssl[num].handle, (int)nread); 2643 2644 switch(err) { 2645 case SSL_ERROR_NONE: /* this is not an error */ 2646 case SSL_ERROR_ZERO_RETURN: /* no more data */ 2647 break; 2648 case SSL_ERROR_WANT_READ: 2649 case SSL_ERROR_WANT_WRITE: 2650 /* there's data pending, re-invoke SSL_read() */ 2651 *curlcode = CURLE_AGAIN; 2652 return -1; 2653 default: 2654 /* openssl/ssl.h says "look at error stack/return value/errno" */ 2655 sslerror = ERR_get_error(); 2656 failf(conn->data, "SSL read: %s, errno %d", 2657 ERR_error_string(sslerror, error_buffer), 2658 SOCKERRNO); 2659 *curlcode = CURLE_RECV_ERROR; 2660 return -1; 2661 } 2662 } 2663 return nread; 2664} 2665 2666size_t Curl_ossl_version(char *buffer, size_t size) 2667{ 2668#ifdef YASSL_VERSION 2669 /* yassl provides an OpenSSL API compatibility layer so it looks identical 2670 to OpenSSL in all other aspects */ 2671 return snprintf(buffer, size, "yassl/%s", YASSL_VERSION); 2672#else /* YASSL_VERSION */ 2673 2674#if(SSLEAY_VERSION_NUMBER >= 0x905000) 2675 { 2676 char sub[2]; 2677 unsigned long ssleay_value; 2678 sub[1]='\0'; 2679 ssleay_value=SSLeay(); 2680 if(ssleay_value < 0x906000) { 2681 ssleay_value=SSLEAY_VERSION_NUMBER; 2682 sub[0]='\0'; 2683 } 2684 else { 2685 if(ssleay_value&0xff0) { 2686 sub[0]=(char)(((ssleay_value>>4)&0xff) + 'a' -1); 2687 } 2688 else 2689 sub[0]='\0'; 2690 } 2691 2692 return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx%s", 2693 (ssleay_value>>28)&0xf, 2694 (ssleay_value>>20)&0xff, 2695 (ssleay_value>>12)&0xff, 2696 sub); 2697 } 2698 2699#else /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */ 2700 2701#if(SSLEAY_VERSION_NUMBER >= 0x900000) 2702 return snprintf(buffer, size, "OpenSSL/%lx.%lx.%lx", 2703 (SSLEAY_VERSION_NUMBER>>28)&0xff, 2704 (SSLEAY_VERSION_NUMBER>>20)&0xff, 2705 (SSLEAY_VERSION_NUMBER>>12)&0xf); 2706 2707#else /* (SSLEAY_VERSION_NUMBER >= 0x900000) */ 2708 { 2709 char sub[2]; 2710 sub[1]='\0'; 2711 if(SSLEAY_VERSION_NUMBER&0x0f) { 2712 sub[0]=(SSLEAY_VERSION_NUMBER&0x0f) + 'a' -1; 2713 } 2714 else 2715 sub[0]='\0'; 2716 2717 return snprintf(buffer, size, "SSL/%x.%x.%x%s", 2718 (SSLEAY_VERSION_NUMBER>>12)&0xff, 2719 (SSLEAY_VERSION_NUMBER>>8)&0xf, 2720 (SSLEAY_VERSION_NUMBER>>4)&0xf, sub); 2721 } 2722#endif /* (SSLEAY_VERSION_NUMBER >= 0x900000) */ 2723#endif /* SSLEAY_VERSION_NUMBER is less than 0.9.5 */ 2724 2725#endif /* YASSL_VERSION */ 2726} 2727#endif /* USE_SSLEAY */ 2728