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 /* static */ void 183 BSecureSocket::Private::_CreateContext() 184 { 185 sContext = SSL_CTX_new(SSLv23_method()); 186 187 // Disable legacy protocols. They have known vulnerabilities. 188 SSL_CTX_set_options(sContext, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); 189 190 // Disable SSL/TLS compression to prevent the CRIME attack. 191 SSL_CTX_set_options(sContext, SSL_OP_NO_COMPRESSION); 192 193 // Don't bother us with ERROR_WANT_READ. 194 SSL_CTX_set_mode(sContext, SSL_MODE_AUTO_RETRY); 195 196 // Setup cipher suites. 197 // These suites are mostly the same ones used by Firefox 47 and Chrome 50. 198 SSL_CTX_set_cipher_list(sContext, 199 "ECDHE-ECDSA-AES128-GCM-SHA256:" 200 "ECDHE-RSA-AES128-GCM-SHA256:" 201 "ECDHE-ECDSA-AES256-GCM-SHA384:" 202 "ECDHE-RSA-AES256-GCM-SHA384:" 203 "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:" 204 "ECDHE-RSA-CHACHA20-POLY1305-SHA256:" 205 "ECDHE-ECDSA-AES256-SHA:" 206 "ECDHE-ECDSA-AES128-SHA:" 207 "ECDHE-RSA-AES128-SHA:" 208 "ECDHE-RSA-AES256-SHA:" 209 "DHE-RSA-AES128-SHA:" 210 "DHE-RSA-AES256-SHA:" 211 "AES128-SHA:" 212 "AES256-SHA"); 213 214 // Let OpenSSL choose the most appropriate D-H curve for us 215 SSL_CTX_set_ecdh_auto(sContext, 1); 216 217 // Setup certificate verification 218 BPath certificateStore; 219 find_directory(B_SYSTEM_DATA_DIRECTORY, &certificateStore); 220 certificateStore.Append("ssl/CARootCertificates.pem"); 221 // TODO we may want to add a non-packaged certificate directory? 222 // (would make it possible to store user-added certificate exceptions 223 // there) 224 SSL_CTX_load_verify_locations(sContext, certificateStore.Path(), NULL); 225 SSL_CTX_set_verify(sContext, SSL_VERIFY_PEER, VerifyCallback); 226 227 // OpenSSL 1.0.2 and later: use the alternate "trusted first" algorithm to validate certificate 228 // chains. This makes the validation stop as soon as a recognized certificate is found in the 229 // chain, instead of validating the whole chain, then seeing if the root certificate is known. 230 #ifdef X509_V_FLAG_TRUSTED_FIRST 231 X509_VERIFY_PARAM* verifyParam = X509_VERIFY_PARAM_new(); 232 X509_VERIFY_PARAM_set_flags(verifyParam, X509_V_FLAG_TRUSTED_FIRST); 233 SSL_CTX_set1_param(sContext, verifyParam); 234 235 // TODO we need to free this after freeing the SSL context (which we currently never do) 236 // X509_VERIFY_PARAM_free(verifyParam); 237 #endif 238 239 // Get an unique index number for storing application data in SSL 240 // structs. We will store a pointer to the BSecureSocket class there. 241 sDataIndex = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); 242 } 243 244 245 // # pragma mark - BSecureSocket 246 247 248 BSecureSocket::BSecureSocket() 249 : 250 fPrivate(new(std::nothrow) BSecureSocket::Private()) 251 { 252 fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY; 253 } 254 255 256 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout) 257 : 258 fPrivate(new(std::nothrow) BSecureSocket::Private()) 259 { 260 fInitStatus = fPrivate != NULL ? fPrivate->InitCheck() : B_NO_MEMORY; 261 Connect(peer, timeout); 262 } 263 264 265 BSecureSocket::BSecureSocket(const BSecureSocket& other) 266 : 267 BSocket(other) 268 { 269 fPrivate = new(std::nothrow) BSecureSocket::Private(*other.fPrivate); 270 // TODO: this won't work this way! - write working copy constructor for 271 // Private. 272 273 if (fPrivate != NULL) 274 SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this); 275 else 276 fInitStatus = B_NO_MEMORY; 277 278 } 279 280 281 BSecureSocket::~BSecureSocket() 282 { 283 delete fPrivate; 284 } 285 286 287 status_t 288 BSecureSocket::Accept(BAbstractSocket*& _socket) 289 { 290 int fd = -1; 291 BNetworkAddress peer; 292 status_t error = AcceptNext(fd, peer); 293 if (error != B_OK) 294 return error; 295 BSecureSocket* socket = new(std::nothrow) BSecureSocket(); 296 ObjectDeleter<BSecureSocket> socketDeleter(socket); 297 if (socket == NULL || socket->InitCheck() != B_OK) { 298 close(fd); 299 return B_NO_MEMORY; 300 } 301 302 socket->_SetTo(fd, fLocal, peer); 303 error = socket->_SetupAccept(); 304 if (error != B_OK) 305 return error; 306 307 _socket = socket; 308 socketDeleter.Detach(); 309 310 return B_OK; 311 } 312 313 314 status_t 315 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout) 316 { 317 status_t status = InitCheck(); 318 if (status != B_OK) 319 return status; 320 321 status = BSocket::Connect(peer, timeout); 322 if (status != B_OK) 323 return status; 324 325 return _SetupConnect(peer.HostName().String()); 326 } 327 328 329 void 330 BSecureSocket::Disconnect() 331 { 332 if (IsConnected()) { 333 if (fPrivate->fSSL != NULL) 334 SSL_shutdown(fPrivate->fSSL); 335 336 BSocket::Disconnect(); 337 } 338 } 339 340 341 status_t 342 BSecureSocket::WaitForReadable(bigtime_t timeout) const 343 { 344 if (fInitStatus != B_OK) 345 return fInitStatus; 346 if (!IsConnected()) 347 return B_ERROR; 348 349 if (SSL_pending(fPrivate->fSSL) > 0) 350 return B_OK; 351 352 return BSocket::WaitForReadable(timeout); 353 } 354 355 356 status_t 357 BSecureSocket::InitCheck() 358 { 359 if (fPrivate == NULL) 360 return B_NO_MEMORY; 361 362 status_t state = fPrivate->InitCheck(); 363 return state; 364 } 365 366 367 bool 368 BSecureSocket::CertificateVerificationFailed(BCertificate&, const char*) 369 { 370 // Until apps actually make use of the certificate API, let's keep the old 371 // behavior and accept all connections, even if the certificate validation 372 // didn't work. 373 return true; 374 } 375 376 377 // #pragma mark - BDataIO implementation 378 379 380 ssize_t 381 BSecureSocket::Read(void* buffer, size_t size) 382 { 383 if (!IsConnected()) 384 return B_ERROR; 385 386 int bytesRead = SSL_read(fPrivate->fSSL, buffer, size); 387 if (bytesRead >= 0) 388 return bytesRead; 389 390 return fPrivate->ErrorCode(bytesRead); 391 } 392 393 394 ssize_t 395 BSecureSocket::Write(const void* buffer, size_t size) 396 { 397 if (!IsConnected()) 398 return B_ERROR; 399 400 int bytesWritten = SSL_write(fPrivate->fSSL, buffer, size); 401 if (bytesWritten >= 0) 402 return bytesWritten; 403 404 return fPrivate->ErrorCode(bytesWritten); 405 } 406 407 408 status_t 409 BSecureSocket::_SetupCommon(const char* host) 410 { 411 // Do this only after BSocket::Connect has checked wether we're already 412 // connected. We don't want to kill an existing SSL session, as that would 413 // likely crash the protocol loop for it. 414 if (fPrivate->fSSL != NULL) { 415 SSL_free(fPrivate->fSSL); 416 } 417 418 fPrivate->fSSL = SSL_new(BSecureSocket::Private::Context()); 419 if (fPrivate->fSSL == NULL) { 420 BSocket::Disconnect(); 421 return B_NO_MEMORY; 422 } 423 424 BIO_set_fd(fPrivate->fBIO, fSocket, BIO_NOCLOSE); 425 SSL_set_bio(fPrivate->fSSL, fPrivate->fBIO, fPrivate->fBIO); 426 SSL_set_ex_data(fPrivate->fSSL, Private::sDataIndex, this); 427 if (host != NULL) { 428 BString hostString = host; 429 if (hostString != "") 430 SSL_set_tlsext_host_name(fPrivate->fSSL, host); 431 } 432 433 return B_OK; 434 } 435 436 437 status_t 438 BSecureSocket::_SetupConnect(const char* host) 439 { 440 status_t error = _SetupCommon(host); 441 if (error != B_OK) 442 return error; 443 444 int returnValue = SSL_connect(fPrivate->fSSL); 445 if (returnValue <= 0) { 446 TRACE("SSLConnection can't connect\n"); 447 BSocket::Disconnect(); 448 return fPrivate->ErrorCode(returnValue); 449 } 450 451 return B_OK; 452 } 453 454 455 status_t 456 BSecureSocket::_SetupAccept() 457 { 458 status_t error = _SetupCommon(); 459 if (error != B_OK) 460 return error; 461 462 int returnValue = SSL_accept(fPrivate->fSSL); 463 if (returnValue <= 0) { 464 TRACE("SSLConnection can't accept\n"); 465 BSocket::Disconnect(); 466 return fPrivate->ErrorCode(returnValue); 467 } 468 469 return B_OK; 470 } 471 472 473 #else // OPENSSL_ENABLED 474 475 476 // #pragma mark - No-SSL stubs 477 478 479 BSecureSocket::BSecureSocket() 480 { 481 } 482 483 484 BSecureSocket::BSecureSocket(const BNetworkAddress& peer, bigtime_t timeout) 485 { 486 fInitStatus = B_UNSUPPORTED; 487 } 488 489 490 BSecureSocket::BSecureSocket(const BSecureSocket& other) 491 : 492 BSocket(other) 493 { 494 } 495 496 497 BSecureSocket::~BSecureSocket() 498 { 499 } 500 501 502 bool 503 BSecureSocket::CertificateVerificationFailed(BCertificate& certificate, const char*) 504 { 505 (void)certificate; 506 return false; 507 } 508 509 510 status_t 511 BSecureSocket::Accept(BAbstractSocket*& _socket) 512 { 513 return B_UNSUPPORTED; 514 } 515 516 517 status_t 518 BSecureSocket::Connect(const BNetworkAddress& peer, bigtime_t timeout) 519 { 520 return fInitStatus = B_UNSUPPORTED; 521 } 522 523 524 void 525 BSecureSocket::Disconnect() 526 { 527 } 528 529 530 status_t 531 BSecureSocket::WaitForReadable(bigtime_t timeout) const 532 { 533 return B_UNSUPPORTED; 534 } 535 536 537 // #pragma mark - BDataIO implementation 538 539 540 ssize_t 541 BSecureSocket::Read(void* buffer, size_t size) 542 { 543 return B_UNSUPPORTED; 544 } 545 546 547 ssize_t 548 BSecureSocket::Write(const void* buffer, size_t size) 549 { 550 return B_UNSUPPORTED; 551 } 552 553 554 status_t 555 BSecureSocket::InitCheck() 556 { 557 return B_UNSUPPORTED; 558 } 559 560 561 status_t 562 BSecureSocket::_SetupCommon(const char* host) 563 { 564 return B_UNSUPPORTED; 565 } 566 567 568 status_t 569 BSecureSocket::_SetupConnect(const char* host) 570 { 571 return B_UNSUPPORTED; 572 } 573 574 575 status_t 576 BSecureSocket::_SetupAccept() 577 { 578 return B_UNSUPPORTED; 579 } 580 581 582 #endif // !OPENSSL_ENABLED 583