13 #include "tlsschannel.h"
23 :
TLSBase( th, server ), m_cleanedup( true )
41 std::string data_copy = data;
44 SecBufferDesc buffer_desc;
45 DWORD cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;
47 PBYTE e_iobuffer =
static_cast<PBYTE
>( LocalAlloc( LMEM_FIXED, cbIoBufferLength ) );
49 if( e_iobuffer == NULL )
57 PBYTE e_message = e_iobuffer + m_sizes.cbHeader;
60 const int size = data_copy.size() > m_sizes.cbMaximumMessage
61 ? m_sizes.cbMaximumMessage
63 memcpy( e_message, data_copy.data(), size );
64 if( data_copy.size() > m_sizes.cbMaximumMessage )
65 data_copy.erase( 0, m_sizes.cbMaximumMessage );
69 buffer[0].pvBuffer = e_iobuffer;
70 buffer[0].cbBuffer = m_sizes.cbHeader;
71 buffer[0].BufferType = SECBUFFER_STREAM_HEADER;
73 buffer[1].pvBuffer = e_message;
74 buffer[1].cbBuffer = size;
75 buffer[1].BufferType = SECBUFFER_DATA;
77 buffer[2].pvBuffer =
static_cast<char*
>(buffer[1].pvBuffer) + buffer[1].cbBuffer;
78 buffer[2].cbBuffer = m_sizes.cbTrailer;
79 buffer[2].BufferType = SECBUFFER_STREAM_TRAILER;
81 buffer[3].BufferType = SECBUFFER_EMPTY;
83 buffer_desc.ulVersion = SECBUFFER_VERSION;
84 buffer_desc.cBuffers = 4;
85 buffer_desc.pBuffers = buffer;
87 SECURITY_STATUS e_status = EncryptMessage( &m_context, 0, &buffer_desc, 0 );
88 if( SUCCEEDED( e_status ) )
90 std::string encrypted( reinterpret_cast<const char*>(e_iobuffer),
91 buffer[0].cbBuffer + buffer[1].cbBuffer + buffer[2].cbBuffer );
97 LocalFree( e_iobuffer );
104 while( data_copy.size() > 0 );
105 LocalFree( e_iobuffer );
121 SecBufferDesc buffer_desc;
122 DWORD cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;
123 bool wantNewBufferSize =
false;
125 PBYTE e_iobuffer =
static_cast<PBYTE
>( LocalAlloc( LMEM_FIXED, cbIoBufferLength ) );
126 if( e_iobuffer == NULL )
134 SECURITY_STATUS e_status;
138 if( wantNewBufferSize )
140 e_iobuffer =
static_cast<PBYTE
>( LocalReAlloc( e_iobuffer, cbIoBufferLength, 0 ) );
141 wantNewBufferSize =
false;
145 memcpy( e_iobuffer, m_buffer.data(), m_buffer.size() >
146 cbIoBufferLength ? cbIoBufferLength : m_buffer.size() );
148 buffer[0].pvBuffer = e_iobuffer;
149 buffer[0].cbBuffer = m_buffer.size() > cbIoBufferLength ? cbIoBufferLength : m_buffer.size();
150 buffer[0].BufferType = SECBUFFER_DATA;
151 buffer[1].cbBuffer = buffer[2].cbBuffer = buffer[3].cbBuffer = 0;
152 buffer[1].BufferType = buffer[2].BufferType = buffer[3].BufferType = SECBUFFER_EMPTY;
154 buffer_desc.ulVersion = SECBUFFER_VERSION;
155 buffer_desc.cBuffers = 4;
156 buffer_desc.pBuffers = buffer;
158 unsigned long processed_data = buffer[0].cbBuffer;
159 e_status = DecryptMessage( &m_context, &buffer_desc, 0, 0 );
166 SecBuffer* pDataBuffer = NULL;
167 SecBuffer* pExtraBuffer = NULL;
168 for(
int i = 1; i < 4; i++ )
170 if( pDataBuffer == NULL && buffer[i].BufferType == SECBUFFER_DATA )
172 pDataBuffer = &buffer[i];
175 if( pExtraBuffer == NULL && buffer[i].BufferType == SECBUFFER_EXTRA )
177 pExtraBuffer = &buffer[i];
180 if( e_status == SEC_E_OK )
182 std::string decrypted( reinterpret_cast<const char*>( pDataBuffer->pvBuffer ),
183 pDataBuffer->cbBuffer );
185 if( pExtraBuffer == NULL )
187 m_buffer.erase( 0, processed_data );
192 m_buffer.erase( 0, processed_data - pExtraBuffer->cbBuffer );
195 cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;
196 wantNewBufferSize =
true;
199 else if( e_status == SEC_E_INCOMPLETE_MESSAGE )
201 if( cbIoBufferLength < 200000 && m_buffer.size() > cbIoBufferLength )
203 cbIoBufferLength += 1000;
204 wantNewBufferSize =
true;
208 cbIoBufferLength = m_sizes.cbHeader + m_sizes.cbMaximumMessage + m_sizes.cbTrailer;
209 wantNewBufferSize =
true;
222 while( m_buffer.size() != 0 );
223 LocalFree( e_iobuffer );
227 handshakeStage( data );
241 DeleteSecurityContext( &m_context );
242 FreeCredentialsHandle( &m_credHandle );
252 SECURITY_STATUS error;
257 SCHANNEL_CRED tlscred;
258 ULONG request = ISC_REQ_ALLOCATE_MEMORY
259 | ISC_REQ_CONFIDENTIALITY
260 | ISC_REQ_EXTENDED_ERROR
262 | ISC_REQ_REPLAY_DETECT
263 | ISC_REQ_SEQUENCE_DETECT
265 | ISC_REQ_MANUAL_CRED_VALIDATION;
268 memset( &tlscred, 0,
sizeof( SCHANNEL_CRED ) );
269 tlscred.dwVersion = SCHANNEL_CRED_VERSION;
270 tlscred.grbitEnabledProtocols = SP_PROT_TLS1;
272 error = AcquireCredentialsHandle( 0,
274 SECPKG_CRED_OUTBOUND,
282 if( error != SEC_E_OK )
291 obuf[0].cbBuffer = 0;
292 obuf[0].pvBuffer = 0;
293 obuf[0].BufferType = SECBUFFER_TOKEN;
295 obufs.ulVersion = SECBUFFER_VERSION;
297 obufs.pBuffers = obuf;
299 SEC_CHAR* hname =
const_cast<char*
>( m_server.c_str() );
301 error = InitializeSecurityContext( &m_credHandle,
306 SECURITY_NETWORK_DREP,
315 if( error == SEC_I_CONTINUE_NEEDED )
319 std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );
320 FreeContextBuffer( obuf[0].pvBuffer );
334 void SChannel::handshakeStage(
const std::string& data )
339 SECURITY_STATUS error;
342 SecBuffer ibuf[2], obuf[1];
343 SecBufferDesc ibufs, obufs;
344 ULONG request = ISC_REQ_ALLOCATE_MEMORY
345 | ISC_REQ_CONFIDENTIALITY
346 | ISC_REQ_EXTENDED_ERROR
348 | ISC_REQ_REPLAY_DETECT
349 | ISC_REQ_SEQUENCE_DETECT
351 | ISC_REQ_MANUAL_CRED_VALIDATION;
353 SEC_CHAR* hname =
const_cast<char*
>( m_server.c_str() );
358 ibuf[0].cbBuffer = m_buffer.size();
359 ibuf[0].pvBuffer =
static_cast<void*
>(
const_cast<char*
>( m_buffer.c_str() ) );
361 ibuf[1].cbBuffer = 0;
362 ibuf[1].pvBuffer = 0;
363 obuf[0].cbBuffer = 0;
364 obuf[0].pvBuffer = 0;
366 ibuf[0].BufferType = SECBUFFER_TOKEN;
367 ibuf[1].BufferType = SECBUFFER_EMPTY;
368 obuf[0].BufferType = SECBUFFER_EMPTY;
370 ibufs.ulVersion = obufs.ulVersion = SECBUFFER_VERSION;
373 ibufs.pBuffers = ibuf;
374 obufs.pBuffers = obuf;
383 error = InitializeSecurityContext( &m_credHandle,
396 if( error == SEC_E_OK )
399 if( ibuf[1].BufferType == SECBUFFER_EXTRA )
401 m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );
414 else if( error == SEC_I_CONTINUE_NEEDED )
423 if( obuf[0].cbBuffer != 0 && obuf[0].pvBuffer != NULL )
425 std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer );
426 FreeContextBuffer( obuf[0].pvBuffer );
430 if( ibuf[1].BufferType == SECBUFFER_EXTRA )
432 m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer );
436 if( obuf[0].cbBuffer == 0 )
437 handshakeStage(
"" );
445 else if( error == SEC_I_INCOMPLETE_CREDENTIALS )
447 handshakeStage(
"" );
449 else if( error == SEC_E_INCOMPLETE_MESSAGE )
467 void SChannel::setSizes()
469 if( QueryContextAttributes( &m_context, SECPKG_ATTR_STREAM_SIZES, &m_sizes ) == SEC_E_OK )
481 int SChannel::filetime2int( FILETIME t )
484 FileTimeToSystemTime(&t, &stUTC);
486 ts.tm_year = stUTC.wYear - 1900;
487 ts.tm_mon = stUTC.wMonth - 1;
488 ts.tm_mday = stUTC.wDay;
489 ts.tm_hour = stUTC.wHour;
490 ts.tm_min = stUTC.wMinute;
491 ts.tm_sec = stUTC.wSecond;
494 if ( (unixtime = mktime(&ts)) == -1 )
499 void SChannel::validateCert()
502 HTTPSPolicyCallbackData policyHTTPS;
503 CERT_CHAIN_POLICY_PARA policyParameter;
504 CERT_CHAIN_POLICY_STATUS policyStatus;
506 PCCERT_CONTEXT remoteCertContext = NULL;
507 PCCERT_CHAIN_CONTEXT chainContext = NULL;
508 CERT_CHAIN_PARA chainParameter;
509 PSTR serverName =
const_cast<char*
>( m_server.c_str() );
511 PWSTR uServerName = NULL;
512 DWORD csizeServerName;
515 szOID_PKIX_KP_SERVER_AUTH,
516 szOID_SERVER_GATED_CRYPTO,
519 DWORD cUsages =
sizeof( Usages ) /
sizeof( LPSTR );
524 if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
525 (PVOID)&remoteCertContext ) != SEC_E_OK )
534 csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, NULL, 0 );
535 uServerName =
reinterpret_cast<WCHAR *
>( LocalAlloc( LMEM_FIXED,
536 csizeServerName *
sizeof( WCHAR ) ) );
537 if( uServerName == NULL )
544 csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, uServerName, csizeServerName );
545 if( csizeServerName == 0 )
552 ZeroMemory( &chainParameter,
sizeof( chainParameter ) );
553 chainParameter.cbSize =
sizeof( chainParameter );
554 chainParameter.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR;
555 chainParameter.RequestedUsage.Usage.cUsageIdentifier = cUsages;
556 chainParameter.RequestedUsage.Usage.rgpszUsageIdentifier = Usages;
558 if( !CertGetCertificateChain( NULL, remoteCertContext, NULL, remoteCertContext->hCertStore,
559 &chainParameter, 0, NULL, &chainContext ) )
561 DWORD status = GetLastError();
567 ZeroMemory( &policyHTTPS,
sizeof( HTTPSPolicyCallbackData ) );
568 policyHTTPS.cbStruct =
sizeof( HTTPSPolicyCallbackData );
569 policyHTTPS.dwAuthType = AUTHTYPE_SERVER;
570 policyHTTPS.fdwChecks = 0;
571 policyHTTPS.pwszServerName = uServerName;
573 memset( &policyParameter, 0,
sizeof( policyParameter ) );
574 policyParameter.cbSize =
sizeof( policyParameter );
575 policyParameter.pvExtraPolicyPara = &policyHTTPS;
577 memset( &policyStatus, 0,
sizeof( policyStatus ) );
578 policyStatus.cbSize =
sizeof( policyStatus );
580 if( !CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_SSL, chainContext, &policyParameter,
583 DWORD status = GetLastError();
588 if( policyStatus.dwError )
597 if( chainContext ) CertFreeCertificateChain( chainContext );
598 m_certInfo.
chain = valid;
601 void SChannel::connectionInfos()
603 SecPkgContext_ConnectionInfo conn_info;
605 memset( &conn_info, 0,
sizeof( conn_info ) );
607 if( QueryContextAttributes( &m_context, SECPKG_ATTR_CONNECTION_INFO, &conn_info ) == SEC_E_OK )
609 switch( conn_info.dwProtocol )
611 case SP_PROT_TLS1_CLIENT:
614 case SP_PROT_SSL3_CLIENT:
621 switch( conn_info.aiCipher )
624 m_certInfo.
cipher =
"3DES";
627 m_certInfo.
cipher =
"AES_128";
630 m_certInfo.
cipher =
"AES_256";
633 m_certInfo.
cipher =
"DES";
636 m_certInfo.
cipher =
"RC2";
639 m_certInfo.
cipher =
"RC4";
645 switch( conn_info.aiHash )
648 m_certInfo.
mac =
"MD5";
651 m_certInfo.
mac =
"SHA";
659 void SChannel::certData()
661 PCCERT_CONTEXT remoteCertContext = NULL;
662 CHAR certString[1000];
665 if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT,
666 (PVOID)&remoteCertContext ) != SEC_E_OK )
672 m_certInfo.
date_from = filetime2int( remoteCertContext->pCertInfo->NotBefore );
673 m_certInfo.
date_to = filetime2int( remoteCertContext->pCertInfo->NotAfter );
675 if( !CertNameToStr( remoteCertContext->dwCertEncodingType,
676 &remoteCertContext->pCertInfo->Subject,
677 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
678 certString,
sizeof( certString ) ) )
682 m_certInfo.
server = certString;
684 if( !CertNameToStr( remoteCertContext->dwCertEncodingType,
685 &remoteCertContext->pCertInfo->Issuer,
686 CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG,
687 certString,
sizeof( certString ) ) )
691 m_certInfo.
issuer = certString;
694 void SChannel::setCertinfos()
702 void SChannel::print_error(
int errorcode,
const char* place )
704 printf(
"Win error at %s.\n", place );
708 printf(
"\tValue:\tSEC_E_OK\n" );
709 printf(
"\tDesc:\tNot really an error. Everything is fine.\n" );
711 case SEC_E_INSUFFICIENT_MEMORY:
712 printf(
"\tValue:\tSEC_E_INSUFFICIENT_MEMORY\n" );
713 printf(
"\tDesc:\tThere is not enough memory available to complete the requested action.\n" );
715 case SEC_E_INTERNAL_ERROR:
716 printf(
"\tValue:\tSEC_E_INTERNAL_ERROR\n" );
717 printf(
"\tDesc:\tAn error occurred that did not map to an SSPI error code.\n" );
719 case SEC_E_NO_CREDENTIALS:
720 printf(
"\tValue:\tSEC_E_NO_CREDENTIALS\n" );
721 printf(
"\tDesc:\tNo credentials are available in the security package.\n" );
723 case SEC_E_NOT_OWNER:
724 printf(
"\tValue:\tSEC_E_NOT_OWNER\n" );
725 printf(
"\tDesc:\tThe caller of the function does not have the necessary credentials.\n" );
727 case SEC_E_SECPKG_NOT_FOUND:
728 printf(
"\tValue:\tSEC_E_SECPKG_NOT_FOUND\n" );
729 printf(
"\tDesc:\tThe requested security package does not exist. \n" );
731 case SEC_E_UNKNOWN_CREDENTIALS:
732 printf(
"\tValue:\tSEC_E_UNKNOWN_CREDENTIALS\n" );
733 printf(
"\tDesc:\tThe credentials supplied to the package were not recognized.\n" );
735 case SEC_E_INCOMPLETE_MESSAGE:
736 printf(
"\tValue:\tSEC_E_INCOMPLETE_MESSAGE\n" );
737 printf(
"\tDesc:\tData for the whole message was not read from the wire.\n" );
739 case SEC_E_INVALID_HANDLE:
740 printf(
"\tValue:\tSEC_E_INVALID_HANDLE\n" );
741 printf(
"\tDesc:\tThe handle passed to the function is invalid.\n" );
743 case SEC_E_INVALID_TOKEN:
744 printf(
"\tValue:\tSEC_E_INVALID_TOKEN\n" );
745 printf(
"\tDesc:\tThe error is due to a malformed input token, such as a token "
746 "corrupted in transit...\n" );
748 case SEC_E_LOGON_DENIED:
749 printf(
"\tValue:\tSEC_E_LOGON_DENIED\n" );
750 printf(
"\tDesc:\tThe logon failed.\n" );
752 case SEC_E_NO_AUTHENTICATING_AUTHORITY:
753 printf(
"\tValue:\tSEC_E_NO_AUTHENTICATING_AUTHORITY\n" );
754 printf(
"\tDesc:\tNo authority could be contacted for authentication...\n" );
756 case SEC_E_TARGET_UNKNOWN:
757 printf(
"\tValue:\tSEC_E_TARGET_UNKNOWN\n" );
758 printf(
"\tDesc:\tThe target was not recognized.\n" );
760 case SEC_E_UNSUPPORTED_FUNCTION:
761 printf(
"\tValue:\tSEC_E_UNSUPPORTED_FUNCTION\n" );
762 printf(
"\tDesc:\tAn invalid context attribute flag (ISC_REQ_DELEGATE or "
763 "ISC_REQ_PROMPT_FOR_CREDS)...\n" );
765 case SEC_E_WRONG_PRINCIPAL:
766 printf(
"\tValue:\tSEC_E_WRONG_PRINCIPAL\n" );
767 printf(
"\tDesc:\tThe principal that received the authentication request "
768 "is not the same as the...\n" );
770 case SEC_I_COMPLETE_AND_CONTINUE:
771 printf(
"\tValue:\tSEC_I_COMPLETE_AND_CONTINUE\n" );
772 printf(
"\tDesc:\tThe client must call CompleteAuthToken and then pass the output...\n" );
774 case SEC_I_COMPLETE_NEEDED:
775 printf(
"\tValue:\tSEC_I_COMPLETE_NEEDED\n" );
776 printf(
"\tDesc:\tThe client must finish building the message and then "
777 "call the CompleteAuthToken function.\n" );
779 case SEC_I_CONTINUE_NEEDED:
780 printf(
"\tValue:\tSEC_I_CONTINUE_NEEDED\n" );
781 printf(
"\tDesc:\tThe client must send the output token to the server "
782 "and wait for a return token...\n" );
784 case SEC_I_INCOMPLETE_CREDENTIALS:
785 printf(
"\tValue:\tSEC_I_INCOMPLETE_CREDENTIALS\n" );
786 printf(
"\tDesc:\tThe server has requested client authentication, "
787 "and the supplied credentials either...\n" );
790 printf(
"\tValue:\t%d\n", errorcode );
791 printf(
"\tDesc:\tUnknown error code.\n" );
798 #endif // HAVE_WINTLS