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