online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#define SECURITY_WIN32 #define IO_BUFFER_SIZE 0x10000 #define CLIENT_CERTIFICATE_SUBJECT_NAME L"C=US,ST=Ks,L=Olathe,O=XYZ LTD,OU=ABC,CN=Client8,[email protected]" #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <winsock.h> #include <wincrypt.h> #include <wintrust.h> #include <schannel.h> #include <security.h> #include <sspi.h> #pragma comment(lib, "WSock32.Lib") #pragma comment(lib, "Ws2_32.lib") #pragma comment(lib, "Advapi32.lib") #pragma comment(lib,"Secur32.lib") #pragma comment(lib,"Crypt32.lib") int context_expire = 0; INT iPortNumber = 27015; LPSTR pszServerName = "localhost"; PBYTE ExtraEncBuff = NULL; #define ExtraMemorySize 1024 unsigned int ExtraEncBufferSize = 0; unsigned int ExtraEncBufferLen = 0; char * ExtraDecBuff = NULL; unsigned int ExtraDecBufferSize = 0; unsigned int ExtraDecBufferLen = 0; SCHANNEL_CRED SchannelCred; static DWORD EncryptSend( SOCKET Socket, CtxtHandle * phContext, PBYTE pbIoBuffer, SecPkgContext_StreamSizes Sizes ); static int ssl_default_callback_read(SOCKET fd, void *buf, int num) { int rc; do { { while (((rc = recv(fd, buf, num, 0)) == -1) && ((NT_WSA2errno ()) == EINTR || (NT_WSA2errno ()) == EINPROGRESS)); }; } while (rc < 0 && ((NT_WSA2errno ()) == EAGAIN || (NT_WSA2errno()) == EWOULDBLOCK) && ssl_wait_for_socket(fd, 1) > 0); if (rc < 0) printf("cannot recv data from socket %d", (int)fd); return rc; } static int ssl_default_callback_write(SOCKET fd, void *buf, int num) { int rc; do { { while (((rc = send(fd, buf, num, 0)) == -1) && ((NT_WSA2errno ()) == EINTR || (NT_WSA2errno ()) == EINPROGRESS)); }; } while (rc < 0 && ((NT_WSA2errno ()) == EAGAIN || (NT_WSA2errno ()) == EWOULDBLOCK) && ssl_wait_for_socket(fd, 0) > 0); if (rc < 0) printf("cannot send data to socket %d", (int)fd); return rc; } #define ESHUTDOWN 58 static int NT_WSA2errno() { int ret; switch (WSAGetLastError()) { case WSAEACCES: ret = EACCES; break; case WSAEADDRINUSE: ret = EADDRINUSE; break; case WSAEADDRNOTAVAIL: ret = EADDRNOTAVAIL; break; case WSAEAFNOSUPPORT: ret = EAFNOSUPPORT; break; case WSAEALREADY: ret = EALREADY; break; case WSAEBADF: ret = EBADF; break; case WSAECONNABORTED: ret = ECONNABORTED; break; case WSAECONNREFUSED: ret = ECONNREFUSED; break; case WSAECONNRESET: ret = ECONNRESET; break; case WSAEDESTADDRREQ: ret = EDESTADDRREQ; break; case WSAEFAULT: ret = EFAULT; break; case WSAEHOSTUNREACH: ret = EHOSTUNREACH; break; case WSAEINPROGRESS: ret = EINPROGRESS; break; case WSAEINTR: ret = EINTR; break; case WSAEINVAL: ret = EINVAL; break; case WSAEISCONN: ret = EISCONN; break; case WSAELOOP: ret = ELOOP; break; case WSAEMFILE: ret = EMFILE; break; case WSAEMSGSIZE: ret = EMSGSIZE; break; case WSAENAMETOOLONG: ret = ENAMETOOLONG; break; case WSAENETDOWN: ret = ENETDOWN; break; case WSAENETRESET: ret = EBADF; break; case WSAENETUNREACH: ret = ENETUNREACH; break; case WSAENOBUFS: ret = ENOBUFS; break; case WSAENOPROTOOPT: ret = ENOPROTOOPT; break; case WSAENOTCONN: ret = ENOTCONN; break; case WSAENOTEMPTY: ret = ENOTEMPTY; break; case WSAENOTSOCK: ret = EBADF; break; case WSAEOPNOTSUPP: ret = EBADF; break; case WSAEPROTONOSUPPORT: ret = EPROTONOSUPPORT; break; case WSAEPROTOTYPE: ret = EPROTOTYPE; break; case WSAESHUTDOWN: ret = ESHUTDOWN; break; case WSAETIMEDOUT: ret = ETIMEDOUT; break; case WSAEWOULDBLOCK: ret = EWOULDBLOCK; break; case WSANOTINITIALISED: ret = ENETDOWN; break; default: ret = WSAGetLastError(); break; } return ret; } #define SELECT_TIMEOUT_MS 200 static int ssl_wait_for_socket(SOCKET fd, int mode_read) { int rc; fd_set fds, *read_fds, *write_fds; struct timeval timeout = { 0, SELECT_TIMEOUT_MS * 1000 }; read_fds = mode_read ? &fds : NULL; write_fds = mode_read ? NULL : &fds; do { FD_ZERO(&fds); FD_SET(fd, &fds); {while (((rc = select(fd + 1, read_fds, write_fds, NULL, &timeout)) == -1) && ((NT_WSA2errno ()) == EINTR || (NT_WSA2errno ()) == EINPROGRESS));}; } while (rc == 0); if (rc < 0) printf("failed checking socket %d for being %s", (int)fd, mode_read ? "readable" : "writable"); return rc; } /*****************************************************************************/ static void DisplayWinVerifyTrustError(DWORD Status) { LPSTR pszName = NULL; switch(Status) { case CERT_E_EXPIRED: pszName = "CERT_E_EXPIRED"; break; case CERT_E_VALIDITYPERIODNESTING: pszName = "CERT_E_VALIDITYPERIODNESTING"; break; case CERT_E_ROLE: pszName = "CERT_E_ROLE"; break; case CERT_E_PATHLENCONST: pszName = "CERT_E_PATHLENCONST"; break; case CERT_E_CRITICAL: pszName = "CERT_E_CRITICAL"; break; case CERT_E_PURPOSE: pszName = "CERT_E_PURPOSE"; break; case CERT_E_ISSUERCHAINING: pszName = "CERT_E_ISSUERCHAINING"; break; case CERT_E_MALFORMED: pszName = "CERT_E_MALFORMED"; break; case CERT_E_UNTRUSTEDROOT: pszName = "CERT_E_UNTRUSTEDROOT"; break; case CERT_E_CHAINING: pszName = "CERT_E_CHAINING"; break; case TRUST_E_FAIL: pszName = "TRUST_E_FAIL"; break; case CERT_E_REVOKED: pszName = "CERT_E_REVOKED"; break; case CERT_E_UNTRUSTEDTESTROOT: pszName = "CERT_E_UNTRUSTEDTESTROOT"; break; case CERT_E_REVOCATION_FAILURE: pszName = "CERT_E_REVOCATION_FAILURE"; break; case CERT_E_CN_NO_MATCH: pszName = "CERT_E_CN_NO_MATCH"; break; case CERT_E_WRONG_USAGE: pszName = "CERT_E_WRONG_USAGE"; break; default: pszName = "(unknown)"; break; } printf("Error 0x%x (%s) returned by CertVerifyCertificateChainPolicy!\n", Status, pszName); } /*****************************************************************************/ static void DisplaySchannelError(DWORD ErrCode) { LPSTR pszName = NULL; // WinError.h switch(ErrCode) { case SEC_E_BUFFER_TOO_SMALL: pszName = "SEC_E_BUFFER_TOO_SMALL - The message buffer is too small. Used with the Digest SSP."; break; case SEC_E_CRYPTO_SYSTEM_INVALID: pszName = "SEC_E_CRYPTO_SYSTEM_INVALID - The cipher chosen for the security context is not supported. Used with the Digest SSP."; break; case SEC_E_INCOMPLETE_MESSAGE: pszName = "SEC_E_INCOMPLETE_MESSAGE - The data in the input buffer is incomplete. The application needs to read more data from the server and call DecryptMessage (General) again."; break; case SEC_E_INVALID_HANDLE: pszName = "SEC_E_INVALID_HANDLE - A context handle that is not valid was specified in the phContext parameter. Used with the Digest and Schannel SSPs."; break; case SEC_E_INVALID_TOKEN: pszName = "SEC_E_INVALID_TOKEN - The buffers are of the wrong type or no buffer of type SECBUFFER_DATA was found. Used with the Schannel SSP."; break; case SEC_E_MESSAGE_ALTERED: pszName = "SEC_E_MESSAGE_ALTERED - The message has been altered. Used with the Digest and Schannel SSPs."; break; case SEC_E_OUT_OF_SEQUENCE: pszName = "SEC_E_OUT_OF_SEQUENCE - The message was not received in the correct sequence."; break; case SEC_E_QOP_NOT_SUPPORTED: pszName = "SEC_E_QOP_NOT_SUPPORTED - Neither confidentiality nor integrity are supported by the security context. Used with the Digest SSP."; break; case SEC_I_CONTEXT_EXPIRED: pszName = "SEC_I_CONTEXT_EXPIRED - The message sender has finished using the connection and has initiated a shutdown."; break; case SEC_I_RENEGOTIATE: pszName = "SEC_I_RENEGOTIATE - The remote party requires a new handshake sequence or the application has just initiated a shutdown."; break; case SEC_E_ENCRYPT_FAILURE: pszName = "SEC_E_ENCRYPT_FAILURE - The specified data could not be encrypted."; break; case SEC_E_DECRYPT_FAILURE: pszName = "SEC_E_DECRYPT_FAILURE - The specified data could not be decrypted."; break; } printf("Error 0x%x %s \n", ErrCode, pszName); } DWORD client_send(char * client_message, SOCKET Socket,CtxtHandle * phContext, SecPkgContext_StreamSizes Sizes ){ DWORD cbIoBufferLength, cbData; PBYTE pbIoBuffer; cbIoBufferLength = Sizes.cbHeader + Sizes.cbMaximumMessage + Sizes.cbTrailer; pbIoBuffer = LocalAlloc(LMEM_FIXED, cbIoBufferLength); if(pbIoBuffer == NULL) { printf("**** Out of memory (2)\n"); return -1; } // Build the request - must be < maximum message size2 sprintf( pbIoBuffer+Sizes.cbHeader, "%s", client_message ); // message begins after the header cbData = EncryptSend(Socket, phContext, pbIoBuffer, Sizes ); if(cbData == SOCKET_ERROR || cbData == 0) { printf("**** Error %d sending data to server (3)\n", WSAGetLastError()); } LocalFree(pbIoBuffer); return cbData; } /*****************************************************************************/ static void DisplayCertChain(PCCERT_CONTEXT pServerCert) { CHAR szName[1000]; PCCERT_CONTEXT pCurrentCert, pIssuerCert; DWORD dwVerificationFlags; printf("\n"); // display leaf name if(!CertNameToStr( pServerCert->dwCertEncodingType, &pServerCert->pCertInfo->Subject, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, szName, sizeof(szName) ) ) { printf("**** Error 0x%x building subject name\n", GetLastError()); } printf("Server subject: %s\n", szName); if(!CertNameToStr( pServerCert->dwCertEncodingType, &pServerCert->pCertInfo->Issuer, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, szName, sizeof(szName) ) ) { printf("**** Error 0x%x building issuer name\n", GetLastError()); } printf("Server issuer: %s\n\n", szName); // display certificate chain pCurrentCert = pServerCert; while(pCurrentCert != NULL) { dwVerificationFlags = 0; pIssuerCert = CertGetIssuerCertificateFromStore( pServerCert->hCertStore, pCurrentCert, NULL, &dwVerificationFlags ); if(pIssuerCert == NULL) { if(pCurrentCert != pServerCert) CertFreeCertificateContext(pCurrentCert); break; } if( !CertNameToStr( pIssuerCert->dwCertEncodingType, &pIssuerCert->pCertInfo->Subject, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, szName, sizeof(szName) ) ) { printf("**** Error 0x%x building subject name\n", GetLastError()); } printf("CA subject: %s\n", szName); if(!CertNameToStr( pIssuerCert->dwCertEncodingType, &pIssuerCert->pCertInfo->Issuer, CERT_X500_NAME_STR | CERT_NAME_STR_NO_PLUS_FLAG, szName, sizeof(szName) ) ) { printf("**** Error 0x%x building issuer name\n", GetLastError()); } printf("CA issuer: %s\n\n", szName); if(pCurrentCert != pServerCert) CertFreeCertificateContext(pCurrentCert); pCurrentCert = pIssuerCert; pIssuerCert = NULL; } } /*****************************************************************************/ static void DisplayConnectionInfo( CtxtHandle *phContext ) { SECURITY_STATUS Status; SecPkgContext_ConnectionInfo ConnectionInfo; SecPkgContext_CipherInfo CipherInfo = { SECPKGCONTEXT_CIPHERINFO_V1 }; Status = QueryContextAttributes( phContext, SECPKG_ATTR_CIPHER_INFO, &CipherInfo); if(Status != SEC_E_OK) { printf("Error 0x%x querying cipher info\n", Status); return; } printf("%S\n", CipherInfo.szCipherSuite); Status = QueryContextAttributes( phContext, SECPKG_ATTR_CONNECTION_INFO, (PVOID)&ConnectionInfo ); if(Status != SEC_E_OK) { printf("Error 0x%x querying connection info\n", Status); return; } printf("\n"); switch(ConnectionInfo.dwProtocol) { case SP_PROT_TLS1_CLIENT: printf("Protocol: TLS1\n"); break; case SP_PROT_SSL3_CLIENT: printf("Protocol: SSL3\n"); break; case SP_PROT_PCT1_CLIENT: printf("Protocol: PCT\n"); break; case SP_PROT_SSL2_CLIENT: printf("Protocol: SSL2\n"); break; default: printf("Protocol: 0x%x\n", ConnectionInfo.dwProtocol); } switch(ConnectionInfo.aiCipher) { case CALG_RC4: printf("Cipher: RC4\n"); break; case CALG_3DES: printf("Cipher: Triple DES\n"); break; case CALG_RC2: printf("Cipher: RC2\n"); break; case CALG_DES: case CALG_CYLINK_MEK: printf("Cipher: DES\n"); break; case CALG_SKIPJACK: printf("Cipher: Skipjack\n"); break; default: printf("Cipher: 0x%x\n", ConnectionInfo.aiCipher); } printf("Cipher strength: %d\n", ConnectionInfo.dwCipherStrength); switch(ConnectionInfo.aiHash) { case CALG_MD5: printf("Hash: MD5\n"); break; case CALG_SHA: printf("Hash: SHA\n"); break; default: printf("Hash: 0x%x\n", ConnectionInfo.aiHash); } printf("Hash strength: %d\n", ConnectionInfo.dwHashStrength); switch(ConnectionInfo.aiExch) { case CALG_RSA_KEYX: case CALG_RSA_SIGN: printf("Key exchange: RSA\n"); break; case CALG_KEA_KEYX: printf("Key exchange: KEA\n"); break; case CALG_DH_EPHEM: printf("Key exchange: DH Ephemeral\n"); break; default: printf("Key exchange: 0x%x\n", ConnectionInfo.aiExch); } printf("Key exchange strength: %d\n", ConnectionInfo.dwExchStrength); } /*****************************************************************************/ static DWORD VerifyServerCertificate( PCCERT_CONTEXT pServerCert, PSTR pszServerName, DWORD dwCertFlags ) { HTTPSPolicyCallbackData polHttps; CERT_CHAIN_POLICY_PARA PolicyPara; CERT_CHAIN_POLICY_STATUS PolicyStatus; CERT_CHAIN_PARA ChainPara; PCCERT_CHAIN_CONTEXT pChainContext = NULL; DWORD cchServerName, Status; LPSTR rgszUsages[] = { szOID_PKIX_KP_SERVER_AUTH, szOID_SERVER_GATED_CRYPTO, szOID_SGC_NETSCAPE }; DWORD cUsages = sizeof(rgszUsages) / sizeof(LPSTR); PWSTR pwszServerName = NULL; if(pServerCert == NULL) { Status = SEC_E_WRONG_PRINCIPAL; goto cleanup; } // Convert server name to unicode. if(pszServerName == NULL || strlen(pszServerName) == 0) { Status = SEC_E_WRONG_PRINCIPAL; goto cleanup; } cchServerName = MultiByteToWideChar(CP_ACP, 0, pszServerName, -1, NULL, 0); pwszServerName = LocalAlloc(LMEM_FIXED, cchServerName * sizeof(WCHAR)); if(pwszServerName == NULL) { Status = SEC_E_INSUFFICIENT_MEMORY; goto cleanup; } cchServerName = MultiByteToWideChar(CP_ACP, 0, pszServerName, -1, pwszServerName, cchServerName); if(cchServerName == 0) { Status = SEC_E_WRONG_PRINCIPAL; goto cleanup; } // Build certificate chain. ZeroMemory(&ChainPara, sizeof(ChainPara)); ChainPara.cbSize = sizeof(ChainPara); ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; ChainPara.RequestedUsage.Usage.cUsageIdentifier = cUsages; ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgszUsages; if(!CertGetCertificateChain(NULL, pServerCert, NULL, pServerCert->hCertStore, &ChainPara, 0, NULL, &pChainContext)) { Status = GetLastError(); printf("Error 0x%x returned by CertGetCertificateChain!\n", Status); goto cleanup; } // Validate certificate chain. ZeroMemory(&polHttps, sizeof(HTTPSPolicyCallbackData)); polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData); polHttps.dwAuthType = AUTHTYPE_SERVER; polHttps.fdwChecks = dwCertFlags; memset(&PolicyPara, 0, sizeof(PolicyPara)); PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.pvExtraPolicyPara = &polHttps; memset(&PolicyStatus, 0, sizeof(PolicyStatus)); PolicyStatus.cbSize = sizeof(PolicyStatus); if( !CertVerifyCertificateChainPolicy( CERT_CHAIN_POLICY_SSL, pChainContext, &PolicyPara, &PolicyStatus ) ) { Status = GetLastError(); printf("Error 0x%x returned by CertVerifyCertificateChainPolicy!\n", Status); goto cleanup; } if(PolicyStatus.dwError) { Status = PolicyStatus.dwError; DisplayWinVerifyTrustError(Status); goto cleanup; } Status = SEC_E_OK; cleanup: if(pChainContext) CertFreeCertificateChain(pChainContext); if(pwszServerName) LocalFree(pwszServerName); return Status; } /*****************************************************************************/ static SECURITY_STATUS CreateCredentials(PCredHandle phCreds) { TimeStamp tsExpiry; SECURITY_STATUS Status; PCCERT_CONTEXT client_cert = NULL; const char *cert_prop="118563ef50222440b4f638cc9f8b9bbbf3044ca0"; unsigned char hash[255]; char *p; int i, x = 0; CRYPT_HASH_BLOB blob; for (p = (char *) cert_prop, i = 0; *p && i < sizeof(hash); i++) { if (*p >= '0' && *p <= '9') x = (*p - '0') << 4; else if (*p >= 'A' && *p <= 'F') x = (*p - 'A' + 10) << 4; else if (*p >= 'a' && *p <= 'f') x = (*p - 'a' + 10) << 4; if (!*++p) /* unexpected end of string */ break; if (*p >= '0' && *p <= '9') x += *p - '0'; else if (*p >= 'A' && *p <= 'F') x += *p - 'A' + 10; else if (*p >= 'a' && *p <= 'f') x += *p - 'a' + 10; hash[i] = x; /* skip any space(s) between hex numbers */ for (p++; *p && *p == ' '; p++); } blob.cbData = i; blob.pbData = (unsigned char *) &hash; HCERTSTORE cert_store = NULL; PCCERT_CONTEXT server_cert = NULL; cert_store = CertOpenStore(CERT_STORE_PROV_SYSTEM, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY"); if(!cert_store) { printf("\nschannel: Failed to open cert store last error is 0x%x", GetLastError()); } client_cert = CertFindCertificateInStore(cert_store, X509_ASN_ENCODING, 0, CERT_FIND_HASH, &blob, NULL); if(client_cert == NULL) { printf("\n\ncertificate not found"); //return -1; } else printf("\n\ncertificate found"); // Build Schannel credential structure. Currently, this sample only // specifies the protocol to be used (and optionally the certificate, // of course). Real applications may wish to specify other parameters as well. ZeroMemory( &SchannelCred, sizeof(SchannelCred) ); SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; if(client_cert) { SchannelCred.cCreds = 1; SchannelCred.paCred = &client_cert; } SchannelCred.grbitEnabledProtocols = SP_PROT_TLS1_2_CLIENT; SchannelCred.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION | SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_IGNORE_NO_REVOCATION_CHECK | SCH_CRED_IGNORE_REVOCATION_OFFLINE ; // Create an SSPI credential. Status = AcquireCredentialsHandle(NULL, // Name of principal UNISP_NAME, // Name of package SECPKG_CRED_OUTBOUND, // Flags indicating use NULL, // Pointer to logon ID &SchannelCred, // Package specific data NULL, // Pointer to GetKey() func NULL, // Value to pass to GetKey() phCreds, // (out) Cred Handle &tsExpiry ); // (out) Lifetime (optional) if(Status != SEC_E_OK) printf("**** Error 0x%x returned by AcquireCredentialsHandle\n", Status); // cleanup: Free the certificate context. Schannel has already made its own copy. if(client_cert) CertFreeCertificateContext(client_cert); return Status; } /*****************************************************************************/ static INT ConnectToServer( LPSTR pszServerName, INT iPortNumber, SOCKET * pSocket ) { SOCKET Socket; struct sockaddr_in sin; struct hostent *hp; Socket = socket(PF_INET, SOCK_STREAM, 0); if(Socket == INVALID_SOCKET) { printf("**** Error %d creating socket\n", WSAGetLastError()); return WSAGetLastError(); } sin.sin_family = AF_INET; sin.sin_port = htons((u_short)iPortNumber); if((hp = gethostbyname(pszServerName)) == NULL) { printf("**** Error returned by gethostbyname\n"); return WSAGetLastError(); } else memcpy(&sin.sin_addr, hp->h_addr, 4); if(connect(Socket, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) { printf( "**** Error %d connecting to \"%s\" (%s)\n", WSAGetLastError(), pszServerName, inet_ntoa(sin.sin_addr) ); closesocket(Socket); return WSAGetLastError(); } *pSocket = Socket; return SEC_E_OK; } /*****************************************************************************/ static LONG DisconnectFromServer( SOCKET Socket, PCredHandle phCreds, CtxtHandle * phContext ) { PBYTE pbMessage; DWORD dwType, dwSSPIFlags, dwSSPIOutFlags, cbMessage, Status; SecBufferDesc OutBuffer; SecBuffer OutBuffers[1]; TimeStamp tsExpiry; int cbData; dwType = SCHANNEL_SHUTDOWN; // Notify schannel that we are about to close the connection. OutBuffers[0].pvBuffer = &dwType; OutBuffers[0].BufferType = SECBUFFER_TOKEN; OutBuffers[0].cbBuffer = sizeof(dwType); OutBuffer.cBuffers = 1; OutBuffer.pBuffers = OutBuffers; OutBuffer.ulVersion = SECBUFFER_VERSION; Status = ApplyControlToken(phContext, &OutBuffer); if(FAILED(Status)) { printf("**** Error 0x%x returned by ApplyControlToken\n", Status); goto cleanup; } // Build an SSL close notify message. dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_MUTUAL_AUTH; OutBuffers[0].pvBuffer = NULL; OutBuffers[0].BufferType = SECBUFFER_TOKEN; OutBuffers[0].cbBuffer = 0; OutBuffer.cBuffers = 1; OutBuffer.pBuffers = OutBuffers; OutBuffer.ulVersion = SECBUFFER_VERSION; Status = InitializeSecurityContextA( phCreds, phContext, NULL, dwSSPIFlags, 0, SECURITY_NATIVE_DREP, NULL, 0, phContext, &OutBuffer, &dwSSPIOutFlags, &tsExpiry ); if(FAILED(Status)) { printf("**** Error 0x%x returned by InitializeSecurityContext\n", Status); goto cleanup; } pbMessage = OutBuffers[0].pvBuffer; cbMessage = OutBuffers[0].cbBuffer; // Send the close notify message to the server. if(pbMessage != NULL && cbMessage != 0) { cbData = ssl_default_callback_write(Socket,pbMessage, cbMessage); if(cbData == SOCKET_ERROR || cbData == 0) { Status = WSAGetLastError(); printf("**** Error %d sending close notify\n", Status); goto cleanup; } printf("Sending Close Notify\n"); printf("%d bytes of handshake data sent\n", cbData); FreeContextBuffer(pbMessage); // Free output buffer. } cleanup: int iResult; DeleteSecurityContext(phContext); // Free the security context. iResult = shutdown(Socket, 0); if (iResult == SOCKET_ERROR) { printf("\nshutdown failed with error: %d\n", WSAGetLastError()); closesocket(Socket); WSACleanup(); } else { closesocket(Socket); WSACleanup(); printf(" shutdown done/n"); } return Status; } /*****************************************************************************/ static SECURITY_STATUS ClientHandshakeLoop( SOCKET Socket, // in PCredHandle phCreds, // in CtxtHandle * phContext, // in, out BOOL fDoInitialRead, // in SecBuffer * pExtraData ) // out { SecBufferDesc OutBuffer, InBuffer; SecBuffer InBuffers[2], OutBuffers[1]; DWORD dwSSPIFlags, dwSSPIOutFlags; TimeStamp tsExpiry; SECURITY_STATUS scRet; int cbData; dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_MUTUAL_AUTH ; printf("\ninside handshake loop\n"); // Loop until the handshake is finished or an error occurs. scRet = SEC_I_CONTINUE_NEEDED; while( scRet == SEC_I_CONTINUE_NEEDED || scRet == SEC_E_INCOMPLETE_MESSAGE || scRet == SEC_I_INCOMPLETE_CREDENTIALS ) { //printf("\nExtraEncbufflen : %d",ExtraEncBufferLen); //printf("\nExtraEncbuffsize : %d",ExtraEncBufferSize); //printf("\nscRet Value : 0x%x",scRet); if(0 == ExtraEncBufferLen || scRet == SEC_E_INCOMPLETE_MESSAGE) // Read data from server. { if(ExtraEncBufferSize - ExtraEncBufferLen < ExtraMemorySize) { printf("\n memalloc "); fflush(stdout); ExtraEncBuff = realloc(ExtraEncBuff, ExtraEncBufferSize + ExtraMemorySize); if(ExtraEncBuff == NULL) { printf("**** Out of memory (1)\n"); return SEC_E_INTERNAL_ERROR; } ExtraEncBufferSize = ExtraEncBufferSize + ExtraMemorySize; } cbData = ssl_default_callback_read(Socket,ExtraEncBuff+ ExtraEncBufferLen, ExtraEncBufferSize - ExtraEncBufferLen); if(cbData == SOCKET_ERROR) { printf("**** Error %d reading data from server\n", WSAGetLastError()); scRet = SEC_E_INTERNAL_ERROR; break; } else if(cbData == 0) { printf("**** Server unexpectedly disconnected\n"); scRet = SEC_E_INTERNAL_ERROR; break; } printf("\n%d bytes of handshake data received\n", cbData); ExtraEncBufferLen += cbData; } // Set up the input buffers. Buffer 0 is used to pass in data // received from the server. Schannel will consume some or all // of this. Leftover data (if any) will be placed in buffer 1 and // given a buffer type of SECBUFFER_EXTRA. InBuffers[0].pvBuffer = ExtraEncBuff; InBuffers[0].cbBuffer = ExtraEncBufferLen; InBuffers[0].BufferType = SECBUFFER_TOKEN; InBuffers[1].pvBuffer = NULL; InBuffers[1].cbBuffer = 0; InBuffers[1].BufferType = SECBUFFER_EMPTY; InBuffer.cBuffers = 2; InBuffer.pBuffers = InBuffers; InBuffer.ulVersion = SECBUFFER_VERSION; // Set up the output buffers. These are initialized to NULL // so as to make it less likely we'll attempt to free random // garbage later. OutBuffers[0].pvBuffer = NULL; OutBuffers[0].BufferType= SECBUFFER_TOKEN; OutBuffers[0].cbBuffer = 0; OutBuffer.cBuffers = 1; OutBuffer.pBuffers = OutBuffers; OutBuffer.ulVersion = SECBUFFER_VERSION; // Call InitializeSecurityContext. scRet = InitializeSecurityContextA( phCreds, phContext, NULL, dwSSPIFlags, 0, SECURITY_NATIVE_DREP, &InBuffer, 0, NULL, &OutBuffer, &dwSSPIOutFlags, &tsExpiry ); printf("\nscRet Value : 0x%x\n",scRet); if (scRet == SEC_I_INCOMPLETE_CREDENTIALS) { printf("\nRecieved SEC_I_INCOMPLETE_CREDENTIALS"); } if(scRet == SEC_E_OK || scRet == SEC_I_CONTINUE_NEEDED || FAILED(scRet) && (dwSSPIOutFlags & ISC_RET_EXTENDED_ERROR)) { if(OutBuffers[0].cbBuffer != 0 && OutBuffers[0].pvBuffer != NULL) { cbData = ssl_default_callback_write(Socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer); if(cbData == SOCKET_ERROR || cbData == 0) { printf( "**** Error %d sending data to server (2)\n", WSAGetLastError() ); FreeContextBuffer(OutBuffers[0].pvBuffer); DeleteSecurityContext(phContext); return SEC_E_INTERNAL_ERROR; } printf("%d bytes of handshake data sent\n", cbData); // Free output buffer. FreeContextBuffer(OutBuffers[0].pvBuffer); OutBuffers[0].pvBuffer = NULL; } } // If InitializeSecurityContext returned SEC_E_INCOMPLETE_MESSAGE, // then we need to read more data from the server and try again. if(scRet == SEC_E_INCOMPLETE_MESSAGE){ printf("\n Incomplete message"); continue; } if(ExtraEncBufferSize==0){ ExtraEncBuff=malloc(InBuffers[1].cbBuffer); ExtraEncBufferSize=InBuffers[1].cbBuffer; } if(InBuffers[1].BufferType == SECBUFFER_EXTRA && InBuffers[1].pvBuffer != NULL && InBuffers[1].cbBuffer > 0) { int free_mem = ExtraEncBufferSize - ExtraEncBufferLen; if(free_mem < InBuffers[1].cbBuffer) { ExtraEncBuff = realloc(ExtraEncBuff, ExtraEncBufferSize + InBuffers[1].cbBuffer - free_mem ); if(ExtraEncBuff == NULL){ printf("**** Out of memory (1)\n"); return SEC_E_INTERNAL_ERROR; } ExtraEncBufferSize = ExtraEncBufferSize + InBuffers[1].cbBuffer - free_mem; } memmove(ExtraEncBuff,InBuffers[1].pvBuffer, InBuffers[1].cbBuffer); ExtraEncBufferLen = InBuffers[1].cbBuffer; } else { ExtraEncBufferLen = 0; } if(scRet == SEC_E_OK) { printf("Handshake was successful\n"); break; // Bail out to quit } // Check for fatal error. if(FAILED(scRet)) { printf("**** Error 0x%x returned by InitializeSecurityContext (2)\n", scRet); break; } // If InitializeSecurityContext returned SEC_I_INCOMPLETE_CREDENTIALS, // then the server just requested client authentication. if(scRet == SEC_I_INCOMPLETE_CREDENTIALS) { scRet = SEC_E_INTERNAL_ERROR; break; } } // Delete the security context in the case of a fatal error. if(FAILED(scRet)) DeleteSecurityContext(phContext); return scRet; } /*****************************************************************************/ static SECURITY_STATUS PerformClientHandshake( SOCKET Socket, // in PCredHandle phCreds, // in LPSTR pszServerName, // in CtxtHandle * phContext, // out SecBuffer * pExtraData ) // out { SecBufferDesc OutBuffer; SecBuffer OutBuffers[1]; DWORD dwSSPIFlags, dwSSPIOutFlags; TimeStamp tsExpiry; SECURITY_STATUS scRet; int cbData; dwSSPIFlags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_RET_EXTENDED_ERROR | ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_STREAM | ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_MUTUAL_AUTH; // Initiate a ClientHello message and generate a token. OutBuffers[0].pvBuffer = NULL; OutBuffers[0].BufferType = SECBUFFER_TOKEN; OutBuffers[0].cbBuffer = 0; OutBuffer.cBuffers = 1; OutBuffer.pBuffers = OutBuffers; OutBuffer.ulVersion = SECBUFFER_VERSION; scRet = InitializeSecurityContextA( phCreds, NULL, NULL, dwSSPIFlags, 0, SECURITY_NATIVE_DREP, NULL, 0, phContext, &OutBuffer, &dwSSPIOutFlags, &tsExpiry ); if(scRet != SEC_I_CONTINUE_NEEDED) { printf("**** Error 0x%x returned by InitializeSecurityContext (1)\n", scRet); return scRet; } // Send response to server if there is one. if(OutBuffers[0].cbBuffer != 0 && OutBuffers[0].pvBuffer != NULL) { cbData = ssl_default_callback_write(Socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer); // cbData = send( Socket, OutBuffers[0].pvBuffer, OutBuffers[0].cbBuffer, 0 ); if( cbData == SOCKET_ERROR || cbData == 0 ) { printf("**** Error %d sending data to server (1)\n", WSAGetLastError()); FreeContextBuffer(OutBuffers[0].pvBuffer); DeleteSecurityContext(phContext); return SEC_E_INTERNAL_ERROR; } printf("%d bytes of handshake data sent\n", cbData); FreeContextBuffer(OutBuffers[0].pvBuffer); // Free output buffer. OutBuffers[0].pvBuffer = NULL; } return ClientHandshakeLoop(Socket, phCreds, phContext, TRUE, pExtraData); } /*****************************************************************************/ static DWORD EncryptSend( SOCKET Socket, CtxtHandle * phContext, PBYTE pbIoBuffer, SecPkgContext_StreamSizes Sizes ) { SECURITY_STATUS scRet; // unsigned long cbBuffer; // Size of the buffer, in bytes SecBufferDesc Message; // unsigned long BufferType; // Type of the buffer (below) SecBuffer Buffers[4]; // void SEC_FAR * pvBuffer; // Pointer to the buffer DWORD cbMessage, cbData; PBYTE pbMessage; pbMessage = pbIoBuffer + Sizes.cbHeader; // Offset by "header size" cbMessage = (DWORD)strlen(pbMessage); // Encrypt the HTTP request. Buffers[0].pvBuffer = pbIoBuffer; // Pointer to buffer 1 Buffers[0].cbBuffer = Sizes.cbHeader; // length of header Buffers[0].BufferType = SECBUFFER_STREAM_HEADER; // Type of the buffer Buffers[1].pvBuffer = pbMessage; // Pointer to buffer 2 Buffers[1].cbBuffer = cbMessage; // length of the message Buffers[1].BufferType = SECBUFFER_DATA; // Type of the buffer Buffers[2].pvBuffer = pbMessage + cbMessage; // Pointer to buffer 3 Buffers[2].cbBuffer = Sizes.cbTrailer; // length of the trailor Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; // Type of the buffer Buffers[3].pvBuffer = SECBUFFER_EMPTY; // Pointer to buffer 4 Buffers[3].cbBuffer = SECBUFFER_EMPTY; // length of buffer 4 Buffers[3].BufferType = SECBUFFER_EMPTY; // Type of the buffer 4 Message.ulVersion = SECBUFFER_VERSION; // Version number Message.cBuffers = 4; // Number of buffers - must contain four SecBuffer structures. Message.pBuffers = Buffers; // Pointer to array of buffers scRet = EncryptMessage(phContext, 0, &Message, 0); // must contain four SecBuffer structures. if(FAILED(scRet)) { printf("**** Error 0x%x returned by EncryptMessage\n", scRet); return scRet; } if(scRet == SEC_E_CONTEXT_EXPIRED){ printf("SEC_E_CONTEXT_EXPIRED\n"); return scRet; } // Send the encrypted data to the server. cbData = ssl_default_callback_write(Socket, pbIoBuffer, Buffers[0].cbBuffer + Buffers[1].cbBuffer + Buffers[2].cbBuffer); printf("%d bytes of encrypted data sent\n", cbData); return cbData; // send( Socket, pbIoBuffer, Sizes.cbHeader + strlen(pbMessage) + Sizes.cbTrailer, 0 ); } /*****************************************************************************/ int ReadDecrypt( SOCKET Socket, PCredHandle phCreds, CtxtHandle *phContext, PBYTE pbIoBuffer, DWORD cbIoBufferLength, char * message, int messagesize) { SecBuffer ExtraBuffer; SecBuffer *pDataBuffer, *pExtraBuffer; SECURITY_STATUS scRet; // unsigned long cbBuffer; // Size of the buffer, in bytes SecBufferDesc Message; // unsigned long BufferType; // Type of the buffer (below) SecBuffer Buffers[4]; // void SEC_FAR * pvBuffer; // Pointer to the buffer DWORD cbIoBuffer, length; PBYTE buff; int free_mem = 0; int cbData,i; cbIoBuffer = 0; printf("\nread decrypt-Started"); if(ExtraDecBufferLen>0 && messagesize<ExtraDecBufferLen){ printf("\nFound Decrypted Data"); memcpy(message, ExtraDecBuff,messagesize); memmove(ExtraDecBuff,ExtraDecBuff+messagesize,ExtraDecBufferLen - messagesize);//Check this ExtraDecBufferSize ExtraDecBufferLen=ExtraDecBufferLen-messagesize; return messagesize; } if(context_expire==1){ return -1; } // Read data from server until done. while(TRUE) // Read some data. { if( ExtraEncBufferLen == 0 || scRet == SEC_E_INCOMPLETE_MESSAGE ) // get the data { if((ExtraEncBufferSize - ExtraEncBufferLen) < cbIoBufferLength) { if(ExtraEncBufferSize == 0) { ExtraEncBuff = malloc(cbIoBufferLength); ExtraEncBufferSize = cbIoBufferLength; printf("\nAllocated merory ExtraEncBufferSize <%d>",ExtraEncBufferSize); } else { ExtraEncBuff = realloc(ExtraEncBuff,cbIoBufferLength+ExtraEncBufferSize); ExtraEncBufferSize = ExtraEncBufferSize + cbIoBufferLength; } } cbData = ssl_default_callback_read(Socket, ExtraEncBuff + ExtraEncBufferLen, ExtraEncBufferSize - ExtraEncBufferLen); printf("\nafter read cbData is <%d>",cbData); if(cbData == SOCKET_ERROR) { printf("\n**** Error %d reading data from server", WSAGetLastError()); scRet = SEC_E_INTERNAL_ERROR; break; } else if(cbData == 0) // Server disconnected. { if(cbIoBuffer) { printf("\n**** Server unexpectedly disconnected"); scRet = SEC_E_INTERNAL_ERROR; return -1; } else break; // All Done } else // success { cbIoBuffer += cbData; printf("\nBefore updating ExtraEncBufferLen %d\n",ExtraEncBufferLen); ExtraEncBufferLen += cbData; printf("\nAfter updating ExtraEncBufferLen %d\n",ExtraEncBufferLen); } } // Decrypt the received data. Buffers[0].pvBuffer = ExtraEncBuff; Buffers[0].cbBuffer = ExtraEncBufferLen; Buffers[0].BufferType = SECBUFFER_DATA; // Initial Type of the buffer 1 Buffers[1].BufferType = SECBUFFER_EMPTY; // Initial Type of the buffer 2 Buffers[2].BufferType = SECBUFFER_EMPTY; // Initial Type of the buffer 3 Buffers[3].BufferType = SECBUFFER_EMPTY; // Initial Type of the buffer 4 Message.ulVersion = SECBUFFER_VERSION; // Version number Message.cBuffers = 4; // Number of buffers - must contain four SecBuffer structures. Message.pBuffers = Buffers; // Pointer to array of buffers scRet = DecryptMessage(phContext, &Message, 0, NULL); if( scRet == SEC_I_CONTEXT_EXPIRED ){ context_expire=1; break; } if( scRet != SEC_E_OK && scRet != SEC_I_RENEGOTIATE && scRet != SEC_I_CONTEXT_EXPIRED ) { printf("\n**** DecryptMessage"); DisplaySchannelError((DWORD)scRet); return -1; } // Locate data and (optional) extra buffers. pDataBuffer = NULL; pExtraBuffer = NULL; for(i = 1; i < 4; i++) { if( pDataBuffer == NULL && Buffers[i].BufferType == SECBUFFER_DATA ) pDataBuffer = &Buffers[i]; if( pExtraBuffer == NULL && Buffers[i].BufferType == SECBUFFER_EXTRA ) pExtraBuffer = &Buffers[i]; } //printf("\npDataBuffer data is:%s\n",(char *)pDataBuffer->pvBuffer); if(pDataBuffer) { free_mem = ExtraDecBufferSize - ExtraDecBufferLen; if(free_mem < pDataBuffer->cbBuffer) { ExtraDecBuff = realloc(ExtraDecBuff,ExtraDecBufferSize + pDataBuffer->cbBuffer- free_mem); ExtraDecBufferSize=ExtraDecBufferSize + pDataBuffer->cbBuffer - free_mem; } memcpy(ExtraDecBuff+ExtraDecBufferLen,pDataBuffer->pvBuffer,pDataBuffer->cbBuffer); ExtraDecBufferLen=pDataBuffer->cbBuffer + ExtraDecBufferLen; printf("\nDecrypt mess %s\n",ExtraDecBuff); printf("\nExtraDecBufferLen <%d> pDataBuffer->cbBuffer <%d>",ExtraDecBufferLen,pDataBuffer->cbBuffer); if(messagesize <= ExtraDecBufferLen) { printf("\nextra message decripted 2"); memcpy(message,ExtraDecBuff,messagesize); memmove(ExtraDecBuff,ExtraDecBuff+messagesize,ExtraDecBufferLen - messagesize); ExtraDecBufferLen=ExtraDecBufferLen-messagesize; // break; } } // Move any "extra" data to the input buffer. printf("\nDecrypted message pvBuffer : %.*s",pDataBuffer->cbBuffer,(char *)pDataBuffer->pvBuffer); //ExtraEncBufferLen = 0; if(pExtraBuffer && pExtraBuffer->cbBuffer > 0 ) { free_mem = ExtraEncBufferSize - ExtraEncBufferLen; if(ExtraEncBufferLen > pExtraBuffer->cbBuffer) { if(ExtraEncBufferSize < pExtraBuffer->cbBuffer) { printf("\nExtra ExtraEncBufferSize Before <%d>",ExtraEncBufferSize); ExtraEncBuff = realloc(ExtraEncBuff, pExtraBuffer->cbBuffer); ExtraEncBufferSize = pExtraBuffer->cbBuffer; printf("\nExtra ExtraEncBufferSize after <%d>",ExtraEncBufferSize); } memmove(ExtraEncBuff, pExtraBuffer->pvBuffer, pExtraBuffer->cbBuffer ); ExtraEncBufferLen = pExtraBuffer->cbBuffer; printf("\nAfter moving data %d",ExtraEncBufferLen); } } else { ExtraEncBufferLen = 0; } if(scRet == SEC_I_RENEGOTIATE) { printf("\nServer requested renegotiate!"); scRet = ClientHandshakeLoop( Socket, phCreds, phContext, FALSE, &ExtraBuffer); if(scRet != SEC_E_OK) return -2; } if(scRet == SEC_E_INCOMPLETE_MESSAGE){ continue; } else{ break; } } printf("\n%.16s",message); return messagesize; } /*****************************************************************************/ void _cdecl main( int argc, char *argv[] ) { WSADATA WsaData; SOCKET Socket = INVALID_SOCKET; CredHandle hClientCreds; CtxtHandle hContext; BOOL fCredsInitialized = FALSE; BOOL fContextInitialized = FALSE; SecBuffer ExtraData; SECURITY_STATUS Status; char message[100]; PCCERT_CONTEXT pRemoteCertContext = NULL; // Initialize the WinSock subsystem. if(WSAStartup(0x0101, &WsaData) == SOCKET_ERROR) { printf("Error %d returned by WSAStartup\n", GetLastError()); goto cleanup; } // printf("----- WinSock Initialized\n"); // Create credentials. if(CreateCredentials(&hClientCreds)) { printf("Error creating credentials\n"); goto cleanup; } fCredsInitialized = TRUE; // printf("----- Credentials Initialized\n"); // Connect to server. if(ConnectToServer(pszServerName, iPortNumber, &Socket)) { printf("Error connecting to server\n"); goto cleanup; } // printf("----- Connectd To Server\n"); // Perform handshake if( PerformClientHandshake( Socket, &hClientCreds, pszServerName, &hContext, &ExtraData ) ) { printf("Error performing handshake\n"); goto cleanup; } fContextInitialized = TRUE; // printf("----- Client Handshake Performed\n"); // Authenticate server's credentials. Get server's certificate. Status = QueryContextAttributes(&hContext, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (PVOID)&pRemoteCertContext); if(Status != SEC_E_OK) { printf("Error 0x%x querying remote certificate\n", Status); goto cleanup; } // printf("----- Server Credentials Authenticated \n"); // Display server certificate chain. DisplayCertChain(pRemoteCertContext); // printf("----- Certificate Chain Displayed \n"); // Attempt to validate server certificate. Status = VerifyServerCertificate(pRemoteCertContext, "client_cert", 0); if(Status) { printf("**** Error 0x%x authenticating server credentials!\n", Status); goto cleanup; } // The server certificate did not validate correctly. At this point, we cannot tell // if we are connecting to the correct server, or if we are connecting to a // "man in the middle" attack server - Best to just abort the connection. printf("----- Server Certificate Verified\n"); // Free the server certificate context. CertFreeCertificateContext(pRemoteCertContext); pRemoteCertContext = NULL; // printf("----- Server certificate context released \n"); // Display connection info. DisplayConnectionInfo(&hContext); // printf("----- Secure Connection Info\n"); SECURITY_STATUS scRet; // unsigned long BufferType; // Type of the buffer (below) PBYTE pbIoBuffer; // void SEC_FAR * pvBuffer; // Pointer to the buffer DWORD cbIoBufferLength, cbData; SecPkgContext_StreamSizes Sizes; // Read stream encryption properties. scRet = QueryContextAttributes(&hContext, SECPKG_ATTR_STREAM_SIZES, &Sizes); if(scRet != SEC_E_OK) { printf("**** Error 0x%x reading SECPKG_ATTR_STREAM_SIZES\n", scRet); } // Create a buffer. cbIoBufferLength = Sizes.cbHeader + Sizes.cbMaximumMessage + Sizes.cbTrailer; pbIoBuffer = LocalAlloc(LMEM_FIXED, cbIoBufferLength); if(pbIoBuffer == NULL) { printf("**** Out of memory (2)\n"); } char message1[] =" client message 1" "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc." "These are reserved words in C language are int, float, " "if, else, for, while etc. An Identifier is a sequence of" "letters and digits, but must start with a letter. " "Underscore ( _ ) is treated as a letter. Identifiers are " "case sensitive. Identifiers are used to name variables," "functions etc."; char * client_message=message1; client_send(client_message,Socket, &hContext, Sizes); char message2[] ="client message 2"; client_message=message2; client_send(client_message,Socket, &hContext, Sizes); char message3[] ="client message 3"; client_message=message3; client_send(client_message,Socket, &hContext, Sizes); char message4[] ="client message 4"; client_message=message4; client_send(client_message,Socket, &hContext, Sizes); int mess_len=16; int recv_len=0; recv_len = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0) { printf("\nReceived mess length id:%d\n",recv_len); } else { printf("something went wrong in read decrypt\n"); } mess_len=16; scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0) { printf("\nReceived mess length id:%d\n",recv_len); } else { printf("something went wrong in read decrypt\n"); } mess_len=16; scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0) { printf("\nReceived mess length id:%d\n",recv_len); } else { printf("something went wrong in read decrypt\n"); } scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0) { printf("\nReceived mess length id:%d\n",recv_len); } else { printf("something went wrong in read decrypt\n"); } char message5[] ="client message 5"; client_message=message5; client_send(client_message,Socket, &hContext, Sizes); char message6[] ="client message 6"; client_message=message6; client_send(client_message,Socket, &hContext, Sizes); scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0){ printf("\nReceived mess length id:%d\n",recv_len); } else{ printf("something went wrong in read decrypt\n"); } scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0){ printf("\nReceived mess length id:%d\n",recv_len); } else{ printf("something went wrong in read decrypt\n"); } char message7[] ="client message 7"; client_message=message7; client_send(client_message,Socket, &hContext, Sizes); scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0){ printf("\nReceived mess length id:%d\n",recv_len); } else{ printf("something went wrong in read decrypt\n"); } char message8[] ="client message 8"; client_message=message8; client_send(client_message,Socket, &hContext, Sizes); scRet = ReadDecrypt( Socket, &hClientCreds, &hContext, pbIoBuffer, cbIoBufferLength ,message,mess_len); if(recv_len > 0){ printf("\nReceived mess length id:%d\n",recv_len); } else{ printf("something went wrong in read decrypt\n"); } // Send a close_notify alert to the server and close down the connection. if(DisconnectFromServer(Socket, &hClientCreds, &hContext)) { printf("Error disconnecting from server\n"); goto cleanup; } fContextInitialized = FALSE; Socket = INVALID_SOCKET; // printf("----- Disconnected From Server\n"); cleanup: // printf("----- Begin Cleanup\n"); // Free the server certificate context. if(pRemoteCertContext) { CertFreeCertificateContext(pRemoteCertContext); pRemoteCertContext = NULL; } // Free SSPI context handle. if(fContextInitialized) { DeleteSecurityContext(&hContext); fContextInitialized = FALSE; } // Free SSPI credentials handle. if(fCredsInitialized) { FreeCredentialsHandle(&hClientCreds); fCredsInitialized = FALSE; } // Close socket. if(Socket != INVALID_SOCKET) closesocket(Socket); // Shutdown WinSock subsystem. WSACleanup(); printf("----- All Done ----- \n"); free(ExtraEncBuff); free(ExtraDecBuff); }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue