📄 tlsschannel.cpp
字号:
setCertinfos(); m_secure = true; m_handler->handleHandshakeResult( this, true, m_certInfo ); break; } else if( error == SEC_I_CONTINUE_NEEDED ) { /* * std::cout << "obuf[0].cbBuffer: " << obuf[0].cbBuffer << "\t" << obuf[0].BufferType << "\n"; * std::cout << "ibuf[0].cbBuffer: " << ibuf[0].cbBuffer << "\t" << ibuf[0].BufferType << "\n"; * std::cout << "ibuf[1].cbBuffer: " << ibuf[1].cbBuffer << "\t" << ibuf[1].BufferType << "\n"; */ // STUFF TO SEND?? if( obuf[0].cbBuffer != 0 && obuf[0].pvBuffer != NULL ) { std::string senddata( static_cast<char*>(obuf[0].pvBuffer), obuf[0].cbBuffer ); FreeContextBuffer( obuf[0].pvBuffer ); m_handler->handleEncryptedData( this, senddata ); } // EXTRA STUFF?? if( ibuf[1].BufferType == SECBUFFER_EXTRA ) { m_buffer.erase( 0, m_buffer.size() - ibuf[1].cbBuffer ); } else { m_buffer = ""; } return; } else if( error == SEC_I_INCOMPLETE_CREDENTIALS ) { handshakeStage( "" ); } else if( error == SEC_E_INCOMPLETE_MESSAGE ) { break; } else { cleanup(); m_handler->handleHandshakeResult( this, false, m_certInfo ); break; } } while( true ); } void SChannel::setCACerts( const StringList& cacerts ) {} void SChannel::setClientCert( const std::string& clientKey, const std::string& clientCerts ) {} void SChannel::setSizes() { if( QueryContextAttributes( &m_context, SECPKG_ATTR_STREAM_SIZES, &m_sizes ) == SEC_E_OK ) { //std::cout << "set_sizes success\n"; } else { //std::cout << "set_sizes no success\n"; cleanup(); m_handler->handleHandshakeResult( this, false, m_certInfo ); } } int SChannel::filetime2int( FILETIME t ) { SYSTEMTIME stUTC; FileTimeToSystemTime(&t, &stUTC); std::tm ts; ts.tm_year = stUTC.wYear - 1900; ts.tm_mon = stUTC.wMonth - 1; ts.tm_mday = stUTC.wDay; ts.tm_hour = stUTC.wHour; ts.tm_min = stUTC.wMinute; ts.tm_sec = stUTC.wSecond; int unixtime; if ( (unixtime = mktime(&ts)) == -1 ) unixtime = 0; return unixtime; } void SChannel::validateCert() { bool valid = false; HTTPSPolicyCallbackData policyHTTPS; CERT_CHAIN_POLICY_PARA policyParameter; CERT_CHAIN_POLICY_STATUS policyStatus; PCCERT_CONTEXT remoteCertContext = NULL; PCCERT_CHAIN_CONTEXT chainContext = NULL; CERT_CHAIN_PARA chainParameter; PSTR serverName = const_cast<char*>( m_server.c_str() ); PWSTR uServerName = NULL; DWORD csizeServerName; LPSTR Usages[] = { szOID_PKIX_KP_SERVER_AUTH, szOID_SERVER_GATED_CRYPTO, szOID_SGC_NETSCAPE }; DWORD cUsages = sizeof( Usages ) / sizeof( LPSTR ); do { // Get server's certificate. if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&remoteCertContext ) != SEC_E_OK ) { //printf("Error querying remote certificate\n"); // !!! THROW SOME ERROR break; } // unicode conversation // calculating unicode server name size csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, NULL, 0 ); uServerName = reinterpret_cast<WCHAR *>( LocalAlloc( LMEM_FIXED, csizeServerName * sizeof( WCHAR ) ) ); if( uServerName == NULL ) { //printf("SEC_E_INSUFFICIENT_MEMORY ~ Not enough memory!!!\n"); break; } // convert into unicode csizeServerName = MultiByteToWideChar( CP_ACP, 0, serverName, -1, uServerName, csizeServerName ); if( csizeServerName == 0 ) { //printf("SEC_E_WRONG_PRINCIPAL\n"); break; } // create the chain ZeroMemory( &chainParameter, sizeof( chainParameter ) ); chainParameter.cbSize = sizeof( chainParameter ); chainParameter.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; chainParameter.RequestedUsage.Usage.cUsageIdentifier = cUsages; chainParameter.RequestedUsage.Usage.rgpszUsageIdentifier = Usages; if( !CertGetCertificateChain( NULL, remoteCertContext, NULL, remoteCertContext->hCertStore, &chainParameter, 0, NULL, &chainContext ) ) { DWORD status = GetLastError(); //printf("Error 0x%x returned by CertGetCertificateChain!!!\n", status); break; } // validate the chain ZeroMemory( &policyHTTPS, sizeof( HTTPSPolicyCallbackData ) ); policyHTTPS.cbStruct = sizeof( HTTPSPolicyCallbackData ); policyHTTPS.dwAuthType = AUTHTYPE_SERVER; policyHTTPS.fdwChecks = 0; policyHTTPS.pwszServerName = uServerName; memset( &policyParameter, 0, sizeof( policyParameter ) ); policyParameter.cbSize = sizeof( policyParameter ); policyParameter.pvExtraPolicyPara = &policyHTTPS; memset( &policyStatus, 0, sizeof( policyStatus ) ); policyStatus.cbSize = sizeof( policyStatus ); if( !CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_SSL, chainContext, &policyParameter, &policyStatus ) ) { DWORD status = GetLastError(); //printf("Error 0x%x returned by CertVerifyCertificateChainPolicy!!!\n", status); break; } if( policyStatus.dwError ) { //printf("Trust Error!!!}n"); break; } valid = true; } while( false ); // cleanup if( chainContext ) CertFreeCertificateChain( chainContext ); m_certInfo.chain = valid; } void SChannel::connectionInfos() { SecPkgContext_ConnectionInfo conn_info; memset( &conn_info, 0, sizeof( conn_info ) ); if( QueryContextAttributes( &m_context, SECPKG_ATTR_CONNECTION_INFO, &conn_info ) == SEC_E_OK ) { switch( conn_info.dwProtocol ) { case SP_PROT_TLS1_CLIENT: m_certInfo.protocol = "TLSv1"; break; case SP_PROT_SSL3_CLIENT: m_certInfo.protocol = "SSLv3"; break; default: m_certInfo.protocol = "unknown"; } switch( conn_info.aiCipher ) { case CALG_3DES: m_certInfo.cipher = "3DES"; break; case CALG_AES_128: m_certInfo.cipher = "AES_128"; break; case CALG_AES_256: m_certInfo.cipher = "AES_256"; break; case CALG_DES: m_certInfo.cipher = "DES"; break; case CALG_RC2: m_certInfo.cipher = "RC2"; break; case CALG_RC4: m_certInfo.cipher = "RC4"; break; default: m_certInfo.cipher = ""; } switch( conn_info.aiHash ) { case CALG_MD5: m_certInfo.mac = "MD5"; break; case CALG_SHA: m_certInfo.mac = "SHA"; break; default: m_certInfo.mac = ""; } } } void SChannel::certData() { PCCERT_CONTEXT remoteCertContext = NULL; CHAR certString[1000]; // getting server's certificate if( QueryContextAttributes( &m_context, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&remoteCertContext ) != SEC_E_OK ) { return; } // setting certificat's lifespan m_certInfo.date_from = filetime2int( remoteCertContext->pCertInfo->NotBefore ); m_certInfo.date_to = filetime2int( remoteCertContext->pCertInfo->NotAfter ); if( !CertNameToStr( remoteCertContext->dwCertEncodingType, &remoteCertContext->pCertInfo->Subject, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, certString, sizeof( certString ) ) ) { return; } m_certInfo.server = certString; if( !CertNameToStr( remoteCertContext->dwCertEncodingType, &remoteCertContext->pCertInfo->Issuer, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, certString, sizeof( certString ) ) ) { return; } m_certInfo.issuer = certString; } void SChannel::setCertinfos() { validateCert(); connectionInfos(); certData(); }#if 0 void SChannel::print_error( int errorcode, const char* place ) { printf( "Win error at %s.\n", place ); switch( errorcode ) { case SEC_E_OK: printf( "\tValue:\tSEC_E_OK\n" ); printf( "\tDesc:\tNot really an error. Everything is fine.\n" ); break; case SEC_E_INSUFFICIENT_MEMORY: printf( "\tValue:\tSEC_E_INSUFFICIENT_MEMORY\n" ); printf( "\tDesc:\tThere is not enough memory available to complete the requested action.\n" ); break; case SEC_E_INTERNAL_ERROR: printf( "\tValue:\tSEC_E_INTERNAL_ERROR\n" ); printf( "\tDesc:\tAn error occurred that did not map to an SSPI error code.\n" ); break; case SEC_E_NO_CREDENTIALS: printf( "\tValue:\tSEC_E_NO_CREDENTIALS\n" ); printf( "\tDesc:\tNo credentials are available in the security package.\n" ); break; case SEC_E_NOT_OWNER: printf( "\tValue:\tSEC_E_NOT_OWNER\n" ); printf( "\tDesc:\tThe caller of the function does not have the necessary credentials.\n" ); break; case SEC_E_SECPKG_NOT_FOUND: printf( "\tValue:\tSEC_E_SECPKG_NOT_FOUND\n" ); printf( "\tDesc:\tThe requested security package does not exist. \n" ); break; case SEC_E_UNKNOWN_CREDENTIALS: printf( "\tValue:\tSEC_E_UNKNOWN_CREDENTIALS\n" ); printf( "\tDesc:\tThe credentials supplied to the package were not recognized.\n" ); break; case SEC_E_INCOMPLETE_MESSAGE: printf( "\tValue:\tSEC_E_INCOMPLETE_MESSAGE\n" ); printf( "\tDesc:\tData for the whole message was not read from the wire.\n" ); break; case SEC_E_INVALID_HANDLE: printf( "\tValue:\tSEC_E_INVALID_HANDLE\n" ); printf( "\tDesc:\tThe handle passed to the function is invalid.\n" ); break; case SEC_E_INVALID_TOKEN: printf( "\tValue:\tSEC_E_INVALID_TOKEN\n" ); printf( "\tDesc:\tThe error is due to a malformed input token, such as a token " "corrupted in transit...\n" ); break; case SEC_E_LOGON_DENIED: printf( "\tValue:\tSEC_E_LOGON_DENIED\n" ); printf( "\tDesc:\tThe logon failed.\n" ); break; case SEC_E_NO_AUTHENTICATING_AUTHORITY: printf( "\tValue:\tSEC_E_NO_AUTHENTICATING_AUTHORITY\n" ); printf( "\tDesc:\tNo authority could be contacted for authentication...\n" ); break; case SEC_E_TARGET_UNKNOWN: printf( "\tValue:\tSEC_E_TARGET_UNKNOWN\n" ); printf( "\tDesc:\tThe target was not recognized.\n" ); break; case SEC_E_UNSUPPORTED_FUNCTION: printf( "\tValue:\tSEC_E_UNSUPPORTED_FUNCTION\n" ); printf( "\tDesc:\tAn invalid context attribute flag (ISC_REQ_DELEGATE or " "ISC_REQ_PROMPT_FOR_CREDS)...\n" ); break; case SEC_E_WRONG_PRINCIPAL: printf( "\tValue:\tSEC_E_WRONG_PRINCIPAL\n" ); printf( "\tDesc:\tThe principal that received the authentication request " "is not the same as the...\n" ); break; case SEC_I_COMPLETE_AND_CONTINUE: printf( "\tValue:\tSEC_I_COMPLETE_AND_CONTINUE\n" ); printf( "\tDesc:\tThe client must call CompleteAuthToken and then pass the output...\n" ); break; case SEC_I_COMPLETE_NEEDED: printf( "\tValue:\tSEC_I_COMPLETE_NEEDED\n" ); printf( "\tDesc:\tThe client must finish building the message and then " "call the CompleteAuthToken function.\n" ); break; case SEC_I_CONTINUE_NEEDED: printf( "\tValue:\tSEC_I_CONTINUE_NEEDED\n" ); printf( "\tDesc:\tThe client must send the output token to the server " "and wait for a return token...\n" ); break; case SEC_I_INCOMPLETE_CREDENTIALS: printf( "\tValue:\tSEC_I_INCOMPLETE_CREDENTIALS\n" ); printf( "\tDesc:\tThe server has requested client authentication, " "and the supplied credentials either...\n" ); break; default: printf( "\tValue:\t%d\n", errorcode ); printf( "\tDesc:\tUnknown error code.\n" ); } }#endif}#endif // HAVE_WINTLS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -