1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 #include <IceSSL/SChannelTransceiverI.h> 6 7 #include <IceUtil/StringUtil.h> 8 9 #include <IceSSL/ConnectionInfo.h> 10 #include <IceSSL/Instance.h> 11 #include <IceSSL/SChannelEngine.h> 12 #include <IceSSL/Util.h> 13 #include <Ice/Communicator.h> 14 #include <Ice/LoggerUtil.h> 15 #include <Ice/Buffer.h> 16 #include <Ice/LocalException.h> 17 18 using namespace std; 19 using namespace Ice; 20 using namespace IceSSL; 21 22 namespace 23 { 24 25 string 26 protocolName(DWORD protocol) 27 { 28 switch(protocol) 29 { 30 case SP_PROT_SSL2_CLIENT: PluginI(const Ice::CommunicatorPtr & com)31 case SP_PROT_SSL2_SERVER: 32 return "SSL 2.0"; 33 case SP_PROT_SSL3_CLIENT: 34 case SP_PROT_SSL3_SERVER: 35 return "SSL 3.0"; 36 case SP_PROT_TLS1_CLIENT: create(CERT_SIGNED_CONTENT_INFO * cert) const37 case SP_PROT_TLS1_SERVER: 38 return "TLS 1.0"; 39 case SP_PROT_TLS1_1_CLIENT: 40 case SP_PROT_TLS1_1_SERVER: 41 return "TLS 1.1"; 42 case SP_PROT_TLS1_2_CLIENT: load(const std::string & file) const43 case SP_PROT_TLS1_2_SERVER: 44 return "TLS 1.2"; 45 default: 46 return "Unknown"; 47 } 48 } decode(const std::string & encoding) const49 50 string 51 trustStatusToString(DWORD status) 52 { 53 if(status & CERT_TRUST_NO_ERROR) 54 { 55 return "CERT_TRUST_NO_ERROR"; 56 } 57 58 if(status & CERT_TRUST_IS_NOT_TIME_VALID) 59 { 60 return "CERT_TRUST_IS_NOT_TIME_VALID"; 61 } 62 63 if(status & CERT_TRUST_IS_REVOKED) 64 { 65 return "CERT_TRUST_IS_REVOKED"; 66 } 67 68 if(status & CERT_TRUST_IS_NOT_SIGNATURE_VALID) 69 { 70 return "CERT_TRUST_IS_NOT_SIGNATURE_VALID"; 71 } 72 73 if(status & CERT_TRUST_IS_NOT_VALID_FOR_USAGE) 74 { 75 return "CERT_TRUST_IS_NOT_VALID_FOR_USAGE"; 76 } 77 78 if(status & CERT_TRUST_IS_UNTRUSTED_ROOT) 79 { 80 return "CERT_TRUST_IS_UNTRUSTED_ROOT"; 81 } 82 83 if(status & CERT_TRUST_REVOCATION_STATUS_UNKNOWN) 84 { 85 return "CERT_TRUST_REVOCATION_STATUS_UNKNOWN"; 86 } 87 88 if(status & CERT_TRUST_IS_CYCLIC) 89 { 90 return "CERT_TRUST_IS_CYCLIC"; 91 } 92 93 if(status & CERT_TRUST_INVALID_EXTENSION) 94 { 95 return "CERT_TRUST_INVALID_EXTENSION"; 96 } 97 98 if(status & CERT_TRUST_INVALID_POLICY_CONSTRAINTS) 99 { 100 return "CERT_TRUST_INVALID_POLICY_CONSTRAINTS"; 101 } 102 103 if(status & CERT_TRUST_INVALID_BASIC_CONSTRAINTS) 104 { 105 return "CERT_TRUST_INVALID_BASIC_CONSTRAINTS"; 106 } 107 108 if(status & CERT_TRUST_INVALID_NAME_CONSTRAINTS) 109 { 110 return "CERT_TRUST_INVALID_NAME_CONSTRAINTS"; 111 } 112 113 if(status & CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT) 114 { 115 return "CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT"; 116 } 117 118 if(status & CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT) 119 { 120 return "CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT"; 121 } 122 123 if(status & CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT) 124 { 125 return "CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT"; 126 } 127 128 if(status & CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT) 129 { 130 return "CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT"; 131 } 132 133 if(status & CERT_TRUST_IS_OFFLINE_REVOCATION) 134 { 135 return "CERT_TRUST_IS_OFFLINE_REVOCATION"; 136 } 137 138 if(status & CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY) 139 { 140 return "CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY"; 141 } 142 143 if(status & CERT_TRUST_IS_EXPLICIT_DISTRUST) 144 { 145 return "CERT_TRUST_IS_EXPLICIT_DISTRUST"; 146 } 147 148 if(status & CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT) 149 { 150 return "CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT"; 151 } 152 153 // 154 // New in Windows 8 155 // 156 //if(status & CERT_TRUST_HAS_WEAK_SIGNATURE) 157 //{ 158 // return "CERT_TRUST_HAS_WEAK_SIGNATURE"; 159 //} 160 161 if(status & CERT_TRUST_IS_PARTIAL_CHAIN) 162 { 163 return "CERT_TRUST_IS_PARTIAL_CHAIN"; 164 } 165 166 if(status & CERT_TRUST_CTL_IS_NOT_TIME_VALID) 167 { 168 return "CERT_TRUST_CTL_IS_NOT_TIME_VALID"; 169 } 170 171 if(status & CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID) 172 { 173 return "CERT_TRUST_CTL_IS_NOT_SIGNATURE_VALID"; 174 } 175 176 if(status & CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE) 177 { 178 return "CERT_TRUST_CTL_IS_NOT_VALID_FOR_USAGE"; 179 } 180 181 ostringstream os; 182 os << "UNKNOWN TRUST FAILURE: " << status; 183 return os.str(); 184 } 185 186 SecBuffer* 187 getSecBufferWithType(const SecBufferDesc& desc, ULONG bufferType) 188 { 189 for(ULONG i = 0; i < desc.cBuffers; ++i) 190 { 191 if(desc.pBuffers[i].BufferType == bufferType) 192 { 193 return &desc.pBuffers[i]; 194 } 195 } 196 return 0; 197 } 198 199 string 200 secStatusToString(SECURITY_STATUS status) 201 { 202 return IceUtilInternal::errorToString(status); 203 } 204 205 } 206 207 IceInternal::NativeInfoPtr 208 SChannel::TransceiverI::getNativeInfo() 209 { 210 return _delegate->getNativeInfo(); 211 } 212 213 IceInternal::SocketOperation 214 SChannel::TransceiverI::sslHandshake() 215 { 216 DWORD flags = ASC_REQ_SEQUENCE_DETECT | ASC_REQ_REPLAY_DETECT | ASC_REQ_CONFIDENTIALITY | ASC_REQ_ALLOCATE_MEMORY | 217 ASC_REQ_STREAM; 218 if(_incoming) 219 { 220 flags |= ASC_REQ_EXTENDED_ERROR; 221 if(_engine->getVerifyPeer() > 0) 222 { 223 flags |= ASC_REQ_MUTUAL_AUTH; 224 } 225 } 226 else 227 { 228 flags |= ISC_REQ_USE_SUPPLIED_CREDS | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_RET_EXTENDED_ERROR; 229 } 230 231 SECURITY_STATUS err = SEC_E_OK; 232 if(_state == StateHandshakeNotStarted) 233 { 234 _ctxFlags = 0; 235 _readBuffer.b.resize(2048); 236 _readBuffer.i = _readBuffer.b.begin(); 237 _credentials = _engine->newCredentialsHandle(_incoming); 238 _credentialsInitialized = true; 239 240 if(!_incoming) 241 { 242 SecBuffer outBuffer = { 0, SECBUFFER_TOKEN, 0 }; 243 SecBufferDesc outBufferDesc = { SECBUFFER_VERSION, 1, &outBuffer }; 244 245 err = InitializeSecurityContext(&_credentials, 0, const_cast<char *>(_host.c_str()), flags, 0, 0, 0, 0, 246 &_ssl, &outBufferDesc, &_ctxFlags, 0); 247 if(err != SEC_E_OK && err != SEC_I_CONTINUE_NEEDED) 248 { 249 throw SecurityException(__FILE__, __LINE__, "IceSSL: handshake failure:\n" + secStatusToString(err)); 250 } 251 _sslInitialized = true; 252 253 // 254 // Copy the data to the write buffer 255 // 256 _writeBuffer.b.resize(outBuffer.cbBuffer); 257 _writeBuffer.i = _writeBuffer.b.begin(); 258 memcpy(_writeBuffer.i, outBuffer.pvBuffer, outBuffer.cbBuffer); 259 FreeContextBuffer(outBuffer.pvBuffer); 260 261 _state = StateHandshakeWriteContinue; 262 } 263 else 264 { 265 _state = StateHandshakeReadContinue; 266 } 267 } 268 269 while(true) 270 { 271 if(_state == StateHandshakeReadContinue) 272 { 273 // If read buffer is empty, try to read some data. 274 if(_readBuffer.i == _readBuffer.b.begin() && !readRaw(_readBuffer)) 275 { 276 return IceInternal::SocketOperationRead; 277 } 278 279 SecBuffer inBuffers[2] = { 280 { static_cast<DWORD>(_readBuffer.i - _readBuffer.b.begin()), SECBUFFER_TOKEN, _readBuffer.b.begin() }, 281 { 0, SECBUFFER_EMPTY, 0 } 282 }; 283 SecBufferDesc inBufferDesc = { SECBUFFER_VERSION, 2, inBuffers }; 284 285 SecBuffer outBuffers[2] = { 286 { 0, SECBUFFER_TOKEN, 0 }, 287 { 0, SECBUFFER_ALERT, 0 } 288 }; 289 SecBufferDesc outBufferDesc = { SECBUFFER_VERSION, 2, outBuffers }; 290 291 if(_incoming) 292 { 293 err = AcceptSecurityContext(&_credentials, (_sslInitialized ? &_ssl : 0), &inBufferDesc, flags, 0, 294 &_ssl, &outBufferDesc, &_ctxFlags, 0); 295 if(err == SEC_I_CONTINUE_NEEDED || err == SEC_E_OK) 296 { 297 _sslInitialized = true; 298 } 299 } 300 else 301 { 302 err = InitializeSecurityContext(&_credentials, &_ssl, const_cast<char*>(_host.c_str()), flags, 0, 0, 303 &inBufferDesc, 0, 0, &outBufferDesc, &_ctxFlags, 0); 304 } 305 306 // 307 // If the message is incomplete we need to read more data. 308 // 309 if(err == SEC_E_INCOMPLETE_MESSAGE) 310 { 311 SecBuffer* missing = getSecBufferWithType(inBufferDesc, SECBUFFER_MISSING); 312 size_t pos = _readBuffer.i - _readBuffer.b.begin(); 313 _readBuffer.b.resize((missing && missing->cbBuffer > 0) ? (pos + missing->cbBuffer) : (pos * 2)); 314 _readBuffer.i = _readBuffer.b.begin() + pos; 315 return IceInternal::SocketOperationRead; 316 } 317 else if(err != SEC_I_CONTINUE_NEEDED && err != SEC_E_OK) 318 { 319 throw SecurityException(__FILE__, __LINE__, "SSL handshake failure:\n" + secStatusToString(err)); 320 } 321 322 // 323 // Copy out security tokens to the write buffer if any. 324 // 325 SecBuffer* token = getSecBufferWithType(outBufferDesc, SECBUFFER_TOKEN); 326 assert(token); 327 if(token->cbBuffer) 328 { 329 _writeBuffer.b.resize(static_cast<size_t>(token->cbBuffer)); 330 _writeBuffer.i = _writeBuffer.b.begin(); 331 memcpy(_writeBuffer.i, token->pvBuffer, token->cbBuffer); 332 FreeContextBuffer(token->pvBuffer); 333 } 334 335 // 336 // Check for remaining data in the input buffer. 337 // 338 SecBuffer* extra = getSecBufferWithType(inBufferDesc, SECBUFFER_EXTRA); 339 if(extra) 340 { 341 // Shift the extra data to the start of the input buffer 342 memmove(_readBuffer.b.begin(), _readBuffer.i - extra->cbBuffer, extra->cbBuffer); 343 _readBuffer.i = _readBuffer.b.begin() + extra->cbBuffer; 344 } 345 else 346 { 347 _readBuffer.i = _readBuffer.b.begin(); 348 } 349 350 if(token->cbBuffer) 351 { 352 if(err == SEC_E_OK) 353 { 354 _state = StateHandshakeWriteNoContinue; // Write and don't continue. 355 } 356 else 357 { 358 _state = StateHandshakeWriteContinue; // Continue writing if we have a token. 359 } 360 } 361 else if(err == SEC_E_OK) 362 { 363 break; // We're done. 364 } 365 366 // Otherwise continue either reading credentials 367 } 368 369 if(_state == StateHandshakeWriteContinue || _state == StateHandshakeWriteNoContinue) 370 { 371 // 372 // Write any pending data. 373 // 374 if(!writeRaw(_writeBuffer)) 375 { 376 return IceInternal::SocketOperationWrite; 377 } 378 if(_state == StateHandshakeWriteNoContinue) 379 { 380 break; // Token is written and we weren't told to continue, so we're done! 381 } 382 _state = StateHandshakeReadContinue; 383 } 384 } 385 386 // 387 // Check if the requested capabilities are met. 388 // 389 // NOTE: it's important for _ctxFlags to be a data member. The context flags might not be checked immediately 390 // if the last write can't complete without blocking above. In such a case, the context flags are checked here 391 // only once the sslHandshake is called again after the write completes. 392 // 393 if(flags != _ctxFlags) 394 { 395 if(_incoming) 396 { 397 if(!(_ctxFlags & ASC_REQ_SEQUENCE_DETECT)) 398 { 399 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup sequence detect"); 400 } 401 402 if(!(_ctxFlags & ASC_REQ_REPLAY_DETECT)) 403 { 404 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup replay detect"); 405 } 406 407 if(!(_ctxFlags & ASC_REQ_CONFIDENTIALITY)) 408 { 409 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup confidentiality"); 410 } 411 412 if(!(_ctxFlags & ASC_REQ_EXTENDED_ERROR)) 413 { 414 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup extended error"); 415 } 416 417 if(!(_ctxFlags & ASC_REQ_ALLOCATE_MEMORY)) 418 { 419 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup memory allocation"); 420 } 421 422 if(!(_ctxFlags & ASC_REQ_STREAM)) 423 { 424 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup stream"); 425 } 426 } 427 else 428 { 429 if(!(_ctxFlags & ISC_REQ_SEQUENCE_DETECT)) 430 { 431 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup sequence detect"); 432 } 433 434 if(!(_ctxFlags & ISC_REQ_REPLAY_DETECT)) 435 { 436 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup replay detect"); 437 } 438 439 if(!(_ctxFlags & ISC_REQ_CONFIDENTIALITY)) 440 { 441 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup confidentiality"); 442 } 443 444 if(!(_ctxFlags & ISC_REQ_EXTENDED_ERROR)) 445 { 446 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup extended error"); 447 } 448 449 if(!(_ctxFlags & ISC_REQ_ALLOCATE_MEMORY)) 450 { 451 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup memory allocation"); 452 } 453 454 if(!(_ctxFlags & ISC_REQ_STREAM)) 455 { 456 throw SecurityException(__FILE__, __LINE__, "IceSSL: SChannel failed to setup stream"); 457 } 458 } 459 } 460 461 err = QueryContextAttributes(&_ssl, SECPKG_ATTR_STREAM_SIZES, &_sizes); 462 if(err != SEC_E_OK) 463 { 464 throw SecurityException(__FILE__, __LINE__, "IceSSL: failure to query stream sizes attributes:\n" + 465 secStatusToString(err)); 466 } 467 468 size_t pos = _readBuffer.i - _readBuffer.b.begin(); 469 if(pos <= (_sizes.cbHeader + _sizes.cbMaximumMessage + _sizes.cbTrailer)) 470 { 471 _readBuffer.b.resize(_sizes.cbHeader + _sizes.cbMaximumMessage + _sizes.cbTrailer); 472 _readBuffer.i = _readBuffer.b.begin() + pos; 473 } 474 475 _writeBuffer.b.reset(); 476 _writeBuffer.i = _writeBuffer.b.begin(); 477 478 return IceInternal::SocketOperationNone; 479 } 480 481 // 482 // Try to decrypt a message and return the number of bytes decrypted, if the number of bytes 483 // decrypted is less than the size requested it means that the application needs to read more 484 // data before it can decrypt the complete message. 485 // 486 size_t 487 SChannel::TransceiverI::decryptMessage(IceInternal::Buffer& buffer) 488 { 489 assert(_readBuffer.i != _readBuffer.b.begin() || !_readUnprocessed.b.empty()); 490 491 // 492 // First check if there is data in the unprocessed buffer. 493 // 494 size_t length = std::min(static_cast<size_t>(buffer.b.end() - buffer.i), _readUnprocessed.b.size()); 495 if(length > 0) 496 { 497 memcpy(buffer.i, _readUnprocessed.b.begin(), length); 498 memmove(_readUnprocessed.b.begin(), _readUnprocessed.b.begin() + length, _readUnprocessed.b.size() - length); 499 _readUnprocessed.b.resize(_readUnprocessed.b.size() - length); 500 } 501 502 while(true) 503 { 504 // 505 // If we have filled the buffer or if nothing left to read from 506 // the read buffer, we're done. 507 // 508 Byte* i = buffer.i + length; 509 if(i == buffer.b.end() || _readBuffer.i == _readBuffer.b.begin()) 510 { 511 break; 512 } 513 514 // 515 // Try to decrypt the buffered data. 516 // 517 SecBuffer inBuffers[4] = { 518 { static_cast<DWORD>(_readBuffer.i - _readBuffer.b.begin()), SECBUFFER_DATA, _readBuffer.b.begin() }, 519 { 0, SECBUFFER_EMPTY, 0 }, 520 { 0, SECBUFFER_EMPTY, 0 }, 521 { 0, SECBUFFER_EMPTY, 0 } 522 }; 523 SecBufferDesc inBufferDesc = { SECBUFFER_VERSION, 4, inBuffers }; 524 525 SECURITY_STATUS err = DecryptMessage(&_ssl, &inBufferDesc, 0, 0); 526 if(err == SEC_E_INCOMPLETE_MESSAGE) 527 { 528 // 529 // There isn't enough data to decrypt the message. The input 530 // buffer is resized to the SSL max message size after the SSL 531 // handshake completes so an incomplete message can only occur 532 // if the read buffer is not full. 533 // 534 assert(_readBuffer.i != _readBuffer.b.end()); 535 return length; 536 } 537 else if(err == SEC_I_CONTEXT_EXPIRED || err == SEC_I_RENEGOTIATE) 538 { 539 // 540 // The message sender has finished using the connection and 541 // has initiated a shutdown. 542 // 543 throw ConnectionLostException(__FILE__, __LINE__, 0); 544 } 545 else if(err != SEC_E_OK) 546 { 547 throw ProtocolException(__FILE__, __LINE__, "IceSSL: protocol error during read:\n" + 548 secStatusToString(err)); 549 } 550 551 SecBuffer* dataBuffer = getSecBufferWithType(inBufferDesc, SECBUFFER_DATA); 552 assert(dataBuffer); 553 DWORD remaining = min(static_cast<DWORD>(buffer.b.end() - i), dataBuffer->cbBuffer); 554 length += remaining; 555 if(remaining) 556 { 557 memcpy(i, dataBuffer->pvBuffer, remaining); 558 559 // 560 // Copy remaining decrypted data to unprocessed buffer 561 // 562 if(dataBuffer->cbBuffer > remaining) 563 { 564 _readUnprocessed.b.resize(dataBuffer->cbBuffer - remaining); 565 memcpy(_readUnprocessed.b.begin(), reinterpret_cast<Byte*>(dataBuffer->pvBuffer) + remaining, 566 dataBuffer->cbBuffer - remaining); 567 } 568 } 569 570 // 571 // Move any remaining encrypted data to the begining of the input buffer 572 // 573 SecBuffer* extraBuffer = getSecBufferWithType(inBufferDesc, SECBUFFER_EXTRA); 574 if(extraBuffer && extraBuffer->cbBuffer > 0) 575 { 576 memmove(_readBuffer.b.begin(), _readBuffer.i - extraBuffer->cbBuffer, extraBuffer->cbBuffer); 577 _readBuffer.i = _readBuffer.b.begin() + extraBuffer->cbBuffer; 578 } 579 else 580 { 581 _readBuffer.i = _readBuffer.b.begin(); 582 } 583 } 584 return length; 585 } 586 587 // 588 // Encrypt a message and return the number of bytes that has been encrypted, if the 589 // number of bytes is less than the message size, the function must be called again. 590 // 591 size_t 592 SChannel::TransceiverI::encryptMessage(IceInternal::Buffer& buffer) 593 { 594 // 595 // Limit the message size to cbMaximumMessage which is the maximun size data that can be 596 // embeded in a SSL record. 597 // 598 DWORD length = std::min(static_cast<DWORD>(buffer.b.end() - buffer.i), _sizes.cbMaximumMessage); 599 600 // 601 // Resize the buffer to hold the encrypted data 602 // 603 _writeBuffer.b.resize(_sizes.cbHeader + length + _sizes.cbTrailer); 604 _writeBuffer.i = _writeBuffer.b.begin(); 605 606 SecBuffer buffers[4] = { 607 { _sizes.cbHeader, SECBUFFER_STREAM_HEADER, _writeBuffer.i }, 608 { length, SECBUFFER_DATA, _writeBuffer.i + _sizes.cbHeader }, 609 { _sizes.cbTrailer, SECBUFFER_STREAM_TRAILER, _writeBuffer.i + _sizes.cbHeader + length }, 610 { 0, SECBUFFER_EMPTY, 0 } 611 }; 612 SecBufferDesc buffersDesc = { SECBUFFER_VERSION, 4, buffers }; 613 614 // Data is encrypted in place, copy the data to be encrypted to the data buffer. 615 memcpy(buffers[1].pvBuffer, buffer.i, length); 616 617 SECURITY_STATUS err = EncryptMessage(&_ssl, 0, &buffersDesc, 0); 618 if(err != SEC_E_OK) 619 { 620 throw ProtocolException(__FILE__, __LINE__, "IceSSL: protocol error encrypting message:\n" + 621 secStatusToString(err)); 622 } 623 624 // EncryptMessage resizes the buffers, so resize the write buffer as well to reflect this. 625 _writeBuffer.b.resize(buffers[0].cbBuffer + buffers[1].cbBuffer + buffers[2].cbBuffer); 626 _writeBuffer.i = _writeBuffer.b.begin(); 627 628 return length; 629 } 630 631 IceInternal::SocketOperation 632 SChannel::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::Buffer& writeBuffer) 633 { 634 if(_state == StateNotInitialized) 635 { 636 IceInternal::SocketOperation op = _delegate->initialize(readBuffer, writeBuffer); 637 if(op != IceInternal::SocketOperationNone) 638 { 639 return op; 640 } 641 _state = StateHandshakeNotStarted; 642 } 643 644 IceInternal::SocketOperation op = sslHandshake(); 645 if(op != IceInternal::SocketOperationNone) 646 { 647 return op; 648 } 649 650 // 651 // Build the peer certificate chain and verify it. 652 // 653 PCCERT_CONTEXT cert = 0; 654 SECURITY_STATUS err = QueryContextAttributes(&_ssl, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &cert); 655 if(err && err != SEC_E_NO_CREDENTIALS) 656 { 657 throw SecurityException(__FILE__, __LINE__, "IceSSL: certificate verification failure:\n" + 658 secStatusToString(err)); 659 } 660 661 if(!cert && ((!_incoming && _engine->getVerifyPeer() > 0) || (_incoming && _engine->getVerifyPeer() == 2))) 662 { 663 // 664 // Clients require server certificate if VerifyPeer > 0 and servers require client 665 // certificate if VerifyPeer == 2 666 // 667 throw SecurityException(__FILE__, __LINE__, "IceSSL: certificate required"); 668 } 669 else if(cert) // Verify the remote certificate 670 { 671 CERT_CHAIN_PARA chainP; 672 memset(&chainP, 0, sizeof(chainP)); 673 chainP.cbSize = sizeof(chainP); 674 675 string trustError; 676 PCCERT_CHAIN_CONTEXT certChain; 677 if(!CertGetCertificateChain(_engine->chainEngine(), cert, 0, 0, &chainP, 678 CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, 0, &certChain)) 679 { 680 CertFreeCertificateContext(cert); 681 trustError = IceUtilInternal::lastErrorToString(); 682 } 683 else 684 { 685 if(certChain->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR) 686 { 687 trustError = trustStatusToString(certChain->TrustStatus.dwErrorStatus); 688 } 689 else 690 { 691 _verified = true; 692 } 693 694 CERT_SIMPLE_CHAIN* simpleChain = certChain->rgpChain[0]; 695 for(DWORD i = 0; i < simpleChain->cElement; ++i) 696 { 697 PCCERT_CONTEXT c = simpleChain->rgpElement[i]->pCertContext; 698 PCERT_SIGNED_CONTENT_INFO cc; 699 700 DWORD length = 0; 701 if(!CryptDecodeObjectEx(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CERT, c->pbCertEncoded, 702 c->cbCertEncoded, CRYPT_DECODE_ALLOC_FLAG, 0, &cc, &length)) 703 { 704 CertFreeCertificateChain(certChain); 705 CertFreeCertificateContext(cert); 706 throw SecurityException(__FILE__, __LINE__, "IceSSL: error decoding peer certificate chain:\n" + 707 IceUtilInternal::lastErrorToString()); 708 } 709 _certs.push_back(SChannel::Certificate::create(cc)); 710 } 711 712 CertFreeCertificateChain(certChain); 713 CertFreeCertificateContext(cert); 714 } 715 716 if(!trustError.empty()) 717 { 718 if(_engine->getVerifyPeer() == 0) 719 { 720 if(_instance->traceLevel() >= 1) 721 { 722 _instance->logger()->trace(_instance->traceCategory(), 723 "IceSSL: ignoring certificate verification failure:\n" + trustError); 724 } 725 } 726 else 727 { 728 string msg = "IceSSL: certificate verification failure:\n" + trustError; 729 if(_instance->traceLevel() >= 1) 730 { 731 _instance->logger()->trace(_instance->traceCategory(), msg); 732 } 733 throw SecurityException(__FILE__, __LINE__, msg); 734 } 735 } 736 } 737 738 SecPkgContext_ConnectionInfo connInfo; 739 err = QueryContextAttributes(&_ssl, SECPKG_ATTR_CONNECTION_INFO, &connInfo); 740 if(err == SEC_E_OK) 741 { 742 _cipher = _engine->getCipherName(connInfo.aiCipher); 743 } 744 else 745 { 746 throw SecurityException(__FILE__, __LINE__, "IceSSL: error reading cipher info:\n" + secStatusToString(err)); 747 } 748 749 _engine->verifyPeer(_host, ICE_DYNAMIC_CAST(ConnectionInfo, getInfo()), toString()); 750 _state = StateHandshakeComplete; 751 752 if(_instance->engine()->securityTraceLevel() >= 1) 753 { 754 string sslCipherName; 755 string sslKeyExchangeAlgorithm; 756 string sslProtocolName; 757 SecPkgContext_ConnectionInfo info; 758 if(QueryContextAttributes(&_ssl, SECPKG_ATTR_CONNECTION_INFO, &info) == SEC_E_OK) 759 { 760 sslCipherName = _engine->getCipherName(info.aiCipher); 761 sslKeyExchangeAlgorithm = _engine->getCipherName(info.aiExch); 762 sslProtocolName = protocolName(info.dwProtocol); 763 } 764 765 Trace out(_instance->logger(), _instance->traceCategory()); 766 out << "SSL summary for " << (_incoming ? "incoming" : "outgoing") << " connection\n"; 767 768 if(sslCipherName.empty()) 769 { 770 out << "unknown cipher\n"; 771 } 772 else 773 { 774 out << "cipher = " << sslCipherName 775 << "\nkey exchange = " << sslKeyExchangeAlgorithm 776 << "\nprotocol = " << sslProtocolName << "\n"; 777 } 778 out << toString(); 779 } 780 _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, 781 !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); 782 return IceInternal::SocketOperationNone; 783 } 784 785 IceInternal::SocketOperation 786 SChannel::TransceiverI::closing(bool initiator, const Ice::LocalException&) 787 { 788 // If we are initiating the connection closure, wait for the peer 789 // to close the TCP/IP connection. Otherwise, close immediately. 790 return initiator ? IceInternal::SocketOperationRead : IceInternal::SocketOperationNone; 791 } 792 793 void 794 SChannel::TransceiverI::close() 795 { 796 if(_sslInitialized) 797 { 798 DeleteSecurityContext(&_ssl); 799 _sslInitialized = false; 800 } 801 802 if(_credentialsInitialized) 803 { 804 FreeCredentialsHandle(&_credentials); 805 _credentialsInitialized = false; 806 } 807 808 _delegate->close(); 809 810 // 811 // Clear the buffers now instead of waiting for destruction. 812 // 813 _writeBuffer.b.clear(); 814 _readBuffer.b.clear(); 815 _readUnprocessed.b.clear(); 816 } 817 818 IceInternal::SocketOperation 819 SChannel::TransceiverI::write(IceInternal::Buffer& buf) 820 { 821 if(_state == StateNotInitialized) 822 { 823 return _delegate->write(buf); 824 } 825 826 if(buf.i == buf.b.end()) 827 { 828 return IceInternal::SocketOperationNone; 829 } 830 assert(_state == StateHandshakeComplete); 831 832 while(buf.i != buf.b.end()) 833 { 834 if(_bufferedW == 0) 835 { 836 assert(_writeBuffer.i == _writeBuffer.b.end()); 837 _bufferedW = encryptMessage(buf); 838 } 839 840 if(!writeRaw(_writeBuffer)) 841 { 842 return IceInternal::SocketOperationWrite; 843 } 844 845 assert(_writeBuffer.i == _writeBuffer.b.end()); // Finished writing the encrypted data 846 847 buf.i += _bufferedW; 848 _bufferedW = 0; 849 } 850 return IceInternal::SocketOperationNone; 851 } 852 853 IceInternal::SocketOperation 854 SChannel::TransceiverI::read(IceInternal::Buffer& buf) 855 { 856 if(_state == StateNotInitialized) 857 { 858 return _delegate->read(buf); 859 } 860 861 if(buf.i == buf.b.end()) 862 { 863 return IceInternal::SocketOperationNone; 864 } 865 assert(_state == StateHandshakeComplete); 866 867 _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); 868 while(buf.i != buf.b.end()) 869 { 870 if(_readUnprocessed.b.empty() && _readBuffer.i == _readBuffer.b.begin() && !readRaw(_readBuffer)) 871 { 872 return IceInternal::SocketOperationRead; 873 } 874 875 size_t decrypted = decryptMessage(buf); 876 if(decrypted == 0) 877 { 878 if(!readRaw(_readBuffer)) 879 { 880 return IceInternal::SocketOperationRead; 881 } 882 continue; 883 } 884 885 buf.i += decrypted; 886 } 887 _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, 888 !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); 889 return IceInternal::SocketOperationNone; 890 } 891 892 #ifdef ICE_USE_IOCP 893 894 bool 895 SChannel::TransceiverI::startWrite(IceInternal::Buffer& buffer) 896 { 897 if(_state == StateNotInitialized) 898 { 899 return _delegate->startWrite(buffer); 900 } 901 902 if(_state == StateHandshakeComplete && _bufferedW == 0) 903 { 904 assert(_writeBuffer.i == _writeBuffer.b.end()); 905 _bufferedW = encryptMessage(buffer); 906 } 907 908 return _delegate->startWrite(_writeBuffer) && _bufferedW == static_cast<size_t>((buffer.b.end() - buffer.i)); 909 } 910 911 void 912 SChannel::TransceiverI::finishWrite(IceInternal::Buffer& buf) 913 { 914 if(_state == StateNotInitialized) 915 { 916 _delegate->finishWrite(buf); 917 return; 918 } 919 920 _delegate->finishWrite(_writeBuffer); 921 if(_writeBuffer.i != _writeBuffer.b.end()) 922 { 923 return; // We're not finished yet with writing the write buffer. 924 } 925 926 if(_state == StateHandshakeComplete) 927 { 928 buf.i += _bufferedW; 929 _bufferedW = 0; 930 } 931 } 932 933 void 934 SChannel::TransceiverI::startRead(IceInternal::Buffer& buffer) 935 { 936 if(_state == StateNotInitialized) 937 { 938 _delegate->startRead(buffer); 939 return; 940 } 941 _delegate->startRead(_readBuffer); 942 } 943 944 void 945 SChannel::TransceiverI::finishRead(IceInternal::Buffer& buf) 946 { 947 if(_state == StateNotInitialized) 948 { 949 _delegate->finishRead(buf); 950 return; 951 } 952 953 _delegate->finishRead(_readBuffer); 954 if(_state == StateHandshakeComplete) 955 { 956 size_t decrypted = decryptMessage(buf); 957 if(decrypted > 0) 958 { 959 buf.i += decrypted; 960 _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, 961 !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()); 962 } 963 else 964 { 965 _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false); 966 } 967 } 968 } 969 #endif 970 971 string 972 SChannel::TransceiverI::protocol() const 973 { 974 return _instance->protocol(); 975 } 976 977 string 978 SChannel::TransceiverI::toString() const 979 { 980 return _delegate->toString(); 981 } 982 983 string 984 SChannel::TransceiverI::toDetailedString() const 985 { 986 return toString(); 987 } 988 989 Ice::ConnectionInfoPtr 990 SChannel::TransceiverI::getInfo() const 991 { 992 ConnectionInfoPtr info = ICE_MAKE_SHARED(ConnectionInfo); 993 info->underlying = _delegate->getInfo(); 994 info->incoming = _incoming; 995 info->adapterName = _adapterName; 996 info->cipher = _cipher; 997 info->certs = _certs; 998 info->verified = _verified; 999 return info; 1000 } 1001 1002 void 1003 SChannel::TransceiverI::checkSendSize(const IceInternal::Buffer&) 1004 { 1005 } 1006 1007 void 1008 SChannel::TransceiverI::setBufferSize(int rcvSize, int sndSize) 1009 { 1010 _delegate->setBufferSize(rcvSize, sndSize); 1011 } 1012 1013 SChannel::TransceiverI::TransceiverI(const InstancePtr& instance, 1014 const IceInternal::TransceiverPtr& delegate, 1015 const string& hostOrAdapterName, 1016 bool incoming) : 1017 _instance(instance), 1018 _engine(SChannel::SSLEnginePtr::dynamicCast(instance->engine())), 1019 _host(incoming ? "" : hostOrAdapterName), 1020 _adapterName(incoming ? hostOrAdapterName : ""), 1021 _incoming(incoming), 1022 _delegate(delegate), 1023 _state(StateNotInitialized), 1024 _bufferedW(0), 1025 _sslInitialized(false), 1026 _credentialsInitialized(false), 1027 _verified(false) 1028 { 1029 } 1030 1031 SChannel::TransceiverI::~TransceiverI() 1032 { 1033 } 1034 1035 bool 1036 SChannel::TransceiverI::writeRaw(IceInternal::Buffer& buf) 1037 { 1038 _delegate->write(buf); 1039 return buf.i == buf.b.end(); 1040 } 1041 1042 bool 1043 SChannel::TransceiverI::readRaw(IceInternal::Buffer& buf) 1044 { 1045 IceInternal::Buffer::Container::iterator p = buf.i; 1046 _delegate->read(buf); 1047 return buf.i != p; 1048 } 1049