1 /* 2 * Copyright 2013-2016 Haiku, Inc. 3 * Copyright 2011-2015, Axel Dörfler, axeld@pinc-software.de. 4 * Copyright 2016, Rene Gollent, rene@gollent.com. 5 * Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de> 6 * Distributed under the terms of the MIT License. 7 */ 8 9 10 #include <SecureSocket.h> 11 12 #ifdef OPENSSL_ENABLED 13 # include <openssl/ssl.h> 14 # include <openssl/err.h> 15 #endif 16 17 #include <pthread.h> 18 19 #include <Certificate.h> 20 #include <FindDirectory.h> 21 #include <Path.h> 22 23 #include <AutoDeleter.h> 24 25 #include "CertificatePrivate.h" 26 27 28 //#define TRACE_SOCKET 29 #ifdef TRACE_SOCKET 30 # define TRACE(x...) printf(x) 31 #else 32 # define TRACE(x...) ; 33 #endif 34 35 36 #ifdef OPENSSL_ENABLED 37 38 39 class BSecureSocket::Private { 40 public: 41 Private(); 42 ~Private(); 43 44 status_t InitCheck(); 45 status_t ErrorCode(int returnValue); 46 47 static SSL_CTX* Context(); 48 static int VerifyCallback(int ok, X509_STORE_CTX* ctx); 49 50 private: 51 static void _CreateContext(); 52 53 public: 54 SSL* fSSL; 55 BIO* fBIO; 56 static int sDataIndex; 57 58 private: 59 static SSL_CTX* sContext; 60 // FIXME When do we SSL_CTX_free it? 61 static pthread_once_t sInitOnce; 62 }; 63 64 65 /* static */ SSL_CTX* BSecureSocket::Private::sContext = NULL; 66 /* static */ int BSecureSocket::Private::sDataIndex; 67 /* static */ pthread_once_t BSecureSocket::Private::sInitOnce 68 = PTHREAD_ONCE_INIT; 69 70 71 BSecureSocket::Private::Private() 72 : 73 fSSL(NULL), 74 fBIO(BIO_new(BIO_s_socket())) 75 { 76 } 77 78 79 BSecureSocket::Private::~Private() 80 { 81 // SSL_free also frees the underlying BIO. 82 if (fSSL != NULL) 83 SSL_free(fSSL); 84 else { 85 // The SSL session was never created (Connect() was not called or 86 // failed). We must free the BIO we created in the constructor. 87 BIO_free(fBIO); 88 } 89 } 90 91 92 status_t 93 BSecureSocket::Private::InitCheck() 94 { 95 if (fBIO == NULL) 96 return B_NO_MEMORY; 97 return B_OK; 98 } 99 100 101 status_t 102 BSecureSocket::Private::ErrorCode(int returnValue) 103 { 104 int error = SSL_get_error(fSSL, returnValue); 105 switch (error) { 106 case SSL_ERROR_NONE: 107 // Shouldn't happen... 108 return B_NO_ERROR; 109 case SSL_ERROR_ZERO_RETURN: 110 // Socket is closed 111 return B_CANCELED; 112 case SSL_ERROR_SSL: 113 // Probably no certificate 114 return B_NOT_ALLOWED; 115 116 case SSL_ERROR_WANT_READ: 117 case SSL_ERROR_WANT_WRITE: 118 case SSL_ERROR_WANT_CONNECT: 119 case SSL_ERROR_WANT_ACCEPT: 120 case SSL_ERROR_WANT_X509_LOOKUP: 121 case SSL_ERROR_SYSCALL: 122 default: 123 // TODO: translate SSL error codes! 124 fprintf(stderr, "SSL %s\n", ERR_error_string(error, NULL)); 125 return B_ERROR; 126 } 127 } 128 129 130 /* static */ SSL_CTX* 131 BSecureSocket::Private::Context() 132 { 133 // We use lazy initialisation here, because reading certificates from disk 134 // and parsing them is a relatively long operation and uses some memory. 135 // We don't want programs that don't use SSL to waste resources with that. 136 pthread_once(&sInitOnce, _CreateContext); 137 138 return sContext; 139 } 140 141 142 /*! This is called each time a certificate verification occurs. It allows us to 143 catch failures and report them. 144 */ 145 /* static */ int 146 BSecureSocket::Private::VerifyCallback(int ok, X509_STORE_CTX* ctx) 147 { 148 // OpenSSL already checked the certificate again the certificate store for 149 // us, and tells the result of that in the ok parameter. 150 151 // If the verification succeeded, no need for any further checks. Let's 152 // proceed with the connection. 153 if (ok) 154 return ok; 155 156 // The certificate verification failed. Signal this to the BSecureSocket. 157 158 // First of all, get the affected BSecureSocket 159 SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(ctx, 160 SSL_get_ex_data_X509_STORE_CTX_idx()); 161 BSecureSocket* socket = (BSecureSocket*)SSL_get_ex_data(ssl, sDataIndex); 162 163 // Get the certificate that we could not validate (this may not be the one 164 // we got from the server, but something higher up in the certificate 165 // chain) 166 X509* x509 = X509_STORE_CTX_get_current_cert(ctx); 167 BCertificate::Private* certificate 168 = new(std::nothrow) BCertificate::Private(x509); 169 170 if (certificate == NULL) 171 return 0; 172 173 int error = X509_STORE_CTX_get_error(ctx); 174 const char* message = X509_verify_cert_error_string(error); 175 176 // Let the BSecureSocket (or subclass) decide if we should continue anyway. 177 BCertificate failedCertificate(certificate); 178 return socket->CertificateVerificationFailed(failedCertificate, message); 179 } 180 181 182 #if TRACE_SSL 183 static void apps_ssl_info_callback(const SSL *s, int where, int ret) 184 { 185 const char *str; 186 int w; 187 188 w=where& ~SSL_ST_MASK; 189 190 if (w & SSL_ST_CONNECT) str="SSL_connect"; 191 else if (w & SSL_ST_ACCEPT) str="SSL_accept"; 192 else str="undefined"; 193 194 if (where & SSL_CB_LOOP) 195 { 196 fprintf(stderr,"%s:%s\n",str,SSL_state_string_long(s)); 197 } 198 else if (where & SSL_CB_ALERT) 199 { 200 str=(where & SSL_CB_READ)?"read":"write"; 201 fprintf(stderr,"SSL3 alert %s:%s:%s\n", 202 str, 203 SSL_alert_type_string_long(ret), 204 SSL_alert_desc_string_long(ret)); 205 } 206 else if (where & SSL_CB_EXIT) 207 { 208 if (ret == 0) 209 fprintf(stderr,"%s:failed in %s\n", 210 str,SSL_state_string_long(s)); 211 else if (ret < 0) 212 { 213 fprintf(stderr,"%s:error in %s\n", 214 str,SSL_state_string_long(s)); 215 } 216 } 217 } 218 #endif 219 220 221 /* static */ void 222 BSecureSocket::Private::_CreateContext() 223 { 224 // We want SSL to report errors in human readable format. 225 SSL_load_error_strings(); 226 227 sContext = SSL_CTX_new(SSLv23_method()); 228 229 #if TRACE_SSL 230 // For debugging purposes: get all SSL messages to the standard error. 231 SSL_CTX_set_info_callback(sContext, apps_ssl_info_callback); 232 #endif 233 234 // Disable legacy protocols. They have known vulnerabilities. 235 SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); 236 237 // Disable SSL/TLS compression to prevent the CRIME attack. 238 SSL_CTX_set_options(sContext, SSL_OP_NO_COMPRESSION); 239 240 // Don't bother us with ERROR_WANT_READ. 241 SSL_CTX_set_mode(sContext, SSL_MODE_AUTO_RETRY); 242 243 // Setup cipher suites. 244 // These suites are mostly the same ones used by Firefox 47 and Chrome 50. 245 SSL_CTX_set_cipher_list(sContext, 246 "ECDHE-ECDSA-AES128-GCM-SHA256:" 247 "ECDHE-RSA-AES128-GCM-SHA256:" 248 "ECDHE-ECDSA-AES256-GCM-SHA384:" 249 "ECDHE-RSA-AES256-GCM-SHA384:" 250 "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:" 251 "ECDHE-RSA-CHACHA20-POLY1305-SHA256:" 252 "ECDHE-ECDSA-AES256-SHA:" 253 "ECDHE-ECDSA-AES128-SHA:" 254 "ECDHE-RSA-AES128-SHA:" 255 "ECDHE-RSA-AES256-SHA:" 256 "DHE-RSA-AES128-SHA:" 257 "DHE-RSA-AES256-SHA:" 258 "AES128-SHA:" 259 "AES256-SHA"); 260 261 // Let OpenSSL choose the most appropriate D-H curve for us 262 SSL_CTX_set_ecdh_auto(sContext, 1); 263 264 // Setup certificate verification 265 BPath certificateStore; 266 find_directory(B_SYSTEM_DATA_DIRECTORY, &certificateStore); 267 certificateStore.Append("ssl/CARootCertificates.pem"); 268 // TODO we may want to add a non-packaged certificate directory? 269 // (would make it possible to store user-added certificate exceptions 270 // there) 271 SSL_CTX_load_verify_locations(sContext, certificateStore.Path(), NULL); 272 SSL_CTX_set_verify(sContext, SSL_VERIFY_PEER, VerifyCallback); 273 274 // OpenSSL 1.0.2 and later: use the alternate "trusted first" algorithm to validate certificate 275 // chains. This makes the validation stop as soon as a recognized certificate is found in the 276 // chain, instead of validating the whole chain, then seeing if the root certificate is known. 277 #ifdef X509_V_FLAG_TRUSTED_FIRST 278 X509_VERIFY_PARAM* verifyParam = X509_VERIFY_PARAM_new(); 279 X509_VERIFY_PARAM_set_flags(verifyParam, X509_V_FLAG_TRUSTED_FIRST); 280 SSL_CTX_set1_param(sContext, verifyParam); 281 282 // TODO we need to free this after freeing the SSL context (which we currently never do) 283 // X509_VERIFY_PARAM_free(verifyParam); 284 #endif 285 286 // Get an unique index number for storing application data in SSL 287 // structs. We will store a pointer to the BSecureSocket class there. 288 sDataIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); 289 } 290 291 292 // # pragma mark - BSecureSocket 293 294 295 BSecureSocket::BSecureSocket() 296 : 297 fPrivate(new(std::nothrow) BSecureSocket::Private()) 298 { 299 fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY; 300 } 301 302 303 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout) 304 : 305 fPrivate(new(std::nothrow) BSecureSocket::Private()) 306 { 307 fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY; 308 Connect(peer, timeout); 309 } 310 311 312 BSecureSocket::BSecureSocket(const BSecureSocket& other) 313 : 314 BSocket(other) 315 { 316 fPrivate = new(std::nothrow) BSecureSocket::Private(*other.fPrivate); 317 // TODO: this won't work this way! - write working copy constructor for 318 // Private. 319 320 if (fPrivate != NULL) 321 SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this); 322 else 323 fInitStatus = B_NO_MEMORY; 324 325 } 326 327 328 BSecureSocket::~BSecureSocket() 329 { 330 delete fPrivate; 331 } 332 333 334 status_t 335 BSecureSocket::Accept(BAbstractSocket*& _socket) 336 { 337 int fd = -1; 338 BNetworkAddress peer; 339 status_t error = AcceptNext(fd, peer); 340 if (error != B_OK) 341 return error; 342 BSecureSocket* socket = new(std::nothrow) BSecureSocket(); 343 ObjectDeleter<BSecureSocket> socketDeleter(socket); 344 if (socket == NULL || socket->InitCheck() != B_OK) { 345 close(fd); 346 return B_NO_MEMORY; 347 } 348 349 socket->_SetTo(fd, fLocal, peer); 350 error = socket->_SetupAccept(); 351 if (error != B_OK) 352 return error; 353 354 _socket = socket; 355 socketDeleter.Detach(); 356 357 return B_OK; 358 } 359 360 361 status_t 362 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout) 363 { 364 status_t status = InitCheck(); 365 if (status != B_OK) 366 return status; 367 368 status = BSocket::Connect(peer, timeout); 369 if (status != B_OK) 370 return status; 371 372 return _SetupConnect(peer.HostName().String()); 373 } 374 375 376 void 377 BSecureSocket::Disconnect() 378 { 379 if (IsConnected()) { 380 if (fPrivate->fSSL != NULL) 381 SSL_shutdown(fPrivate->fSSL); 382 383 BSocket::Disconnect(); 384 } 385 } 386 387 388 status_t 389 BSecureSocket::WaitForReadable(bigtime_t timeout) const 390 { 391 if (fInitStatus != B_OK) 392 return fInitStatus; 393 if (!IsConnected()) 394 return B_ERROR; 395 396 if (SSL_pending(fPrivate->fSSL) > 0) 397 return B_OK; 398 399 return BSocket::WaitForReadable(timeout); 400 } 401 402 403 status_t 404 BSecureSocket::InitCheck() 405 { 406 if (fPrivate == NULL) 407 return B_NO_MEMORY; 408 409 status_t state = fPrivate->InitCheck(); 410 return state; 411 } 412 413 414 bool 415 BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*) 416 { 417 // Until apps actually make use of the certificate API, let's keep the old 418 // behavior and accept all connections, even if the certificate validation 419 // didn't work. 420 return true; 421 } 422 423 424 // #pragma mark - BDataIO implementation 425 426 427 ssize_t 428 BSecureSocket::Read(void* buffer, size_t size) 429 { 430 if (!IsConnected()) 431 return B_ERROR; 432 433 int bytesRead = SSL_read(fPrivate->fSSL, buffer, size); 434 if (bytesRead >= 0) 435 return bytesRead; 436 437 return fPrivate->ErrorCode(bytesRead); 438 } 439 440 441 ssize_t 442 BSecureSocket::Write(const void* buffer, size_t size) 443 { 444 if (!IsConnected()) 445 return B_ERROR; 446 447 int bytesWritten = SSL_write(fPrivate->fSSL, buffer, size); 448 if (bytesWritten >= 0) 449 return bytesWritten; 450 451 return fPrivate->ErrorCode(bytesWritten); 452 } 453 454 455 status_t 456 BSecureSocket::_SetupCommon(const char* host) 457 { 458 // Do this only after BSocket::Connect has checked wether we're already 459 // connected. We don't want to kill an existing SSL session, as that would 460 // likely crash the protocol loop for it. 461 if (fPrivate->fSSL != NULL) { 462 SSL_free(fPrivate->fSSL); 463 } 464 465 fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context()); 466 if (fPrivate->fSSL == NULL) { 467 BSocket::Disconnect(); 468 return B_NO_MEMORY; 469 } 470 471 BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE); 472 SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO); 473 SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this); 474 if (host != NULL) { 475 BString hostString = host; 476 if (hostString != "") 477 SSL_set_tlsext_host_name(fPrivate->fSSL, host); 478 } 479 480 return B_OK; 481 } 482 483 484 status_t 485 BSecureSocket::_SetupConnect(const char* host) 486 { 487 status_t error = _SetupCommon(host); 488 if (error != B_OK) 489 return error; 490 491 int returnValue = SSL_connect(fPrivate->fSSL); 492 if (returnValue <= 0) { 493 TRACE("SSLConnection can't connect\n"); 494 BSocket::Disconnect(); 495 return fPrivate->ErrorCode(returnValue); 496 } 497 498 return B_OK; 499 } 500 501 502 status_t 503 BSecureSocket::_SetupAccept() 504 { 505 status_t error = _SetupCommon(); 506 if (error != B_OK) 507 return error; 508 509 int returnValue = SSL_accept(fPrivate->fSSL); 510 if (returnValue <= 0) { 511 TRACE("SSLConnection can't accept\n"); 512 BSocket::Disconnect(); 513 return fPrivate->ErrorCode(returnValue); 514 } 515 516 return B_OK; 517 } 518 519 520 #else // OPENSSL_ENABLED 521 522 523 // #pragma mark - No-SSL stubs 524 525 526 BSecureSocket::BSecureSocket() 527 { 528 } 529 530 531 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout) 532 { 533 fInitStatus = B_UNSUPPORTED; 534 } 535 536 537 BSecureSocket::BSecureSocket(const BSecureSocket& other) 538 : 539 BSocket(other) 540 { 541 } 542 543 544 BSecureSocket::~BSecureSocket() 545 { 546 } 547 548 549 bool 550 BSecureSocket::CertificateVerificationFailed(BCertificate& certificate, const char*) 551 { 552 (void)certificate; 553 return false; 554 } 555 556 557 status_t 558 BSecureSocket::Accept(BAbstractSocket*& _socket) 559 { 560 return B_UNSUPPORTED; 561 } 562 563 564 status_t 565 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout) 566 { 567 return fInitStatus = B_UNSUPPORTED; 568 } 569 570 571 void 572 BSecureSocket::Disconnect() 573 { 574 } 575 576 577 status_t 578 BSecureSocket::WaitForReadable(bigtime_t timeout) const 579 { 580 return B_UNSUPPORTED; 581 } 582 583 584 // #pragma mark - BDataIO implementation 585 586 587 ssize_t 588 BSecureSocket::Read(void* buffer, size_t size) 589 { 590 return B_UNSUPPORTED; 591 } 592 593 594 ssize_t 595 BSecureSocket::Write(const void* buffer, size_t size) 596 { 597 return B_UNSUPPORTED; 598 } 599 600 601 status_t 602 BSecureSocket::InitCheck() 603 { 604 return B_UNSUPPORTED; 605 } 606 607 608 status_t 609 BSecureSocket::_SetupCommon(const char* host) 610 { 611 return B_UNSUPPORTED; 612 } 613 614 615 status_t 616 BSecureSocket::_SetupConnect(const char* host) 617 { 618 return B_UNSUPPORTED; 619 } 620 621 622 status_t 623 BSecureSocket::_SetupAccept() 624 { 625 return B_UNSUPPORTED; 626 } 627 628 629 #endif // !OPENSSL_ENABLED 630