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