void secure_info (void) { SecPkgContext_ConnectionInfo ci; ss = sspi->QueryContextAttributes (&hContext, SECPKG_ATTR_CONNECTION_INFO, (PVOID)&ci); if(ss != SEC_E_OK) { printf("Error 0x%x querying connection info\n", ss); return; } printf (" [ Protocol : %s\n", alg2s(ci.dwProtocol)); printf (" [ Cipher : %s-%i\n", alg2s(ci.aiCipher), ci.dwCipherStrength); printf (" [ Hash : %s-%i\n", alg2s(ci.aiHash), ci.dwHashStrength ); printf (" [ Exchange : %s-%i\n\n", alg2s(ci.aiExch), ci.dwExchStrength ); }
int NetlibSslWrite(SslHandle *ssl, const char *buf, int num) { if (ssl == NULL) return SOCKET_ERROR; SecPkgContext_StreamSizes Sizes; SECURITY_STATUS scRet = g_pSSPI->QueryContextAttributes(&ssl->hContext, SECPKG_ATTR_STREAM_SIZES, &Sizes); if (scRet != SEC_E_OK) return scRet; PUCHAR pbDataBuffer = (PUCHAR)mir_calloc(Sizes.cbMaximumMessage + Sizes.cbHeader + Sizes.cbTrailer); PUCHAR pbMessage = pbDataBuffer + Sizes.cbHeader; DWORD sendOff = 0; while (sendOff < (DWORD)num) { DWORD cbMessage = min(Sizes.cbMaximumMessage, (DWORD)num - sendOff); memcpy(pbMessage, buf + sendOff, cbMessage); SecBuffer Buffers[4] = { 0 }; Buffers[0].pvBuffer = pbDataBuffer; Buffers[0].cbBuffer = Sizes.cbHeader; Buffers[0].BufferType = SECBUFFER_STREAM_HEADER; Buffers[1].pvBuffer = pbMessage; Buffers[1].cbBuffer = cbMessage; Buffers[1].BufferType = SECBUFFER_DATA; Buffers[2].pvBuffer = pbMessage + cbMessage; Buffers[2].cbBuffer = Sizes.cbTrailer; Buffers[2].BufferType = SECBUFFER_STREAM_TRAILER; Buffers[3].BufferType = SECBUFFER_EMPTY; SecBufferDesc Message; Message.ulVersion = SECBUFFER_VERSION; Message.cBuffers = _countof(Buffers); Message.pBuffers = Buffers; if (g_pSSPI->EncryptMessage != NULL) scRet = g_pSSPI->EncryptMessage(&ssl->hContext, 0, &Message, 0); else scRet = ((ENCRYPT_MESSAGE_FN)g_pSSPI->Reserved3)(&ssl->hContext, 0, &Message, 0); if (FAILED(scRet)) break; // Calculate encrypted packet size DWORD cbData = Buffers[0].cbBuffer + Buffers[1].cbBuffer + Buffers[2].cbBuffer; // Send the encrypted data to the server. cbData = send(ssl->s, (char*)pbDataBuffer, cbData, 0); if (cbData == SOCKET_ERROR || cbData == 0) { Netlib_Logf(NULL, "SSL failure sending data (%d)", WSAGetLastError()); scRet = SEC_E_INTERNAL_ERROR; break; } sendOff += cbMessage; } mir_free(pbDataBuffer); return scRet == SEC_E_OK ? num : SOCKET_ERROR; }
static bool VerifyCertificate(SslHandle *ssl, PCSTR pszServerName, DWORD dwCertFlags) { static LPSTR rgszUsages[] = { szOID_PKIX_KP_SERVER_AUTH, szOID_SERVER_GATED_CRYPTO, szOID_SGC_NETSCAPE }; CERT_CHAIN_PARA ChainPara = { 0 }; HTTPSPolicyCallbackData polHttps = { 0 }; CERT_CHAIN_POLICY_PARA PolicyPara = { 0 }; CERT_CHAIN_POLICY_STATUS PolicyStatus = { 0 }; PCCERT_CHAIN_CONTEXT pChainContext = NULL; PCCERT_CONTEXT pServerCert = NULL; DWORD scRet; PWSTR pwszServerName = mir_a2u(pszServerName); scRet = g_pSSPI->QueryContextAttributes(&ssl->hContext, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &pServerCert); if (scRet != SEC_E_OK) goto cleanup; if (pServerCert == NULL) { scRet = SEC_E_WRONG_PRINCIPAL; goto cleanup; } ChainPara.cbSize = sizeof(ChainPara); ChainPara.RequestedUsage.dwType = USAGE_MATCH_TYPE_OR; ChainPara.RequestedUsage.Usage.cUsageIdentifier = _countof(rgszUsages); ChainPara.RequestedUsage.Usage.rgpszUsageIdentifier = rgszUsages; if (!CertGetCertificateChain(NULL, pServerCert, NULL, pServerCert->hCertStore, &ChainPara, 0, NULL, &pChainContext)) { scRet = GetLastError(); goto cleanup; } polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData); polHttps.dwAuthType = AUTHTYPE_SERVER; polHttps.fdwChecks = dwCertFlags; polHttps.pwszServerName = pwszServerName; PolicyPara.cbSize = sizeof(PolicyPara); PolicyPara.pvExtraPolicyPara = &polHttps; PolicyStatus.cbSize = sizeof(PolicyStatus); if (!CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL, pChainContext, &PolicyPara, &PolicyStatus)) { scRet = GetLastError(); goto cleanup; } if (PolicyStatus.dwError) { scRet = PolicyStatus.dwError; goto cleanup; } scRet = SEC_E_OK; cleanup: if (pChainContext) CertFreeCertificateChain(pChainContext); if (pServerCert) CertFreeCertificateContext(pServerCert); mir_free(pwszServerName); ReportSslError(scRet, __LINE__, true); return scRet == SEC_E_OK; }
char* CompleteGssapi(HANDLE hSecurity, unsigned char *szChallenge, unsigned chlsz) { if (!szChallenge || !szChallenge[0]) return NULL; NtlmHandleType* hNtlm = (NtlmHandleType*)hSecurity; unsigned char inDataBuffer[1024]; SecBuffer inBuffers[2] = { { sizeof(inDataBuffer), SECBUFFER_DATA, inDataBuffer }, { chlsz, SECBUFFER_STREAM, szChallenge }, }; SecBufferDesc inBuffersDesc = { SECBUFFER_VERSION, 2, inBuffers }; unsigned long qop = 0; SECURITY_STATUS sc = g_pSSPI->DecryptMessage(&hNtlm->hClientContext, &inBuffersDesc, 0, &qop); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } unsigned char LayerMask = inDataBuffer[0]; unsigned int MaxMessageSize = htonl(*(unsigned*)&inDataBuffer[1]); SecPkgContext_Sizes sizes; sc = g_pSSPI->QueryContextAttributes(&hNtlm->hClientContext, SECPKG_ATTR_SIZES, &sizes); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } unsigned char *tokenBuffer = (unsigned char*)alloca(sizes.cbSecurityTrailer); unsigned char *paddingBuffer = (unsigned char*)alloca(sizes.cbBlockSize); unsigned char outDataBuffer[4] = { 1, 0, 16, 0 }; SecBuffer outBuffers[3] = { { sizes.cbSecurityTrailer, SECBUFFER_TOKEN, tokenBuffer }, { sizeof(outDataBuffer), SECBUFFER_DATA, outDataBuffer }, { sizes.cbBlockSize, SECBUFFER_PADDING, paddingBuffer } }; SecBufferDesc outBuffersDesc = { SECBUFFER_VERSION, 3, outBuffers }; sc = g_pSSPI->EncryptMessage(&hNtlm->hClientContext, SECQOP_WRAP_NO_ENCRYPT, &outBuffersDesc, 0); if (sc != SEC_E_OK) { ReportSecError(sc, __LINE__); return NULL; } unsigned i, ressz = 0; for (i = 0; i < outBuffersDesc.cBuffers; i++) ressz += outBuffersDesc.pBuffers[i].cbBuffer; unsigned char *response = (unsigned char*)alloca(ressz), *p = response; for (i = 0; i < outBuffersDesc.cBuffers; i++) { memcpy(p, outBuffersDesc.pBuffers[i].pvBuffer, outBuffersDesc.pBuffers[i].cbBuffer); p += outBuffersDesc.pBuffers[i].cbBuffer; } NETLIBBASE64 nlb64; nlb64.cbDecoded = ressz; nlb64.pbDecoded = response; nlb64.cchEncoded = Netlib_GetBase64EncodedBufferSize(nlb64.cbDecoded); nlb64.pszEncoded = (char*)alloca(nlb64.cchEncoded); if (!NetlibBase64Encode(0,(LPARAM)&nlb64)) return NULL; return mir_strdup(nlb64.pszEncoded); }
int main (int argc, char *argv[]) { INIT_SECURITY_INTERFACE pInitSecurityInterface; // set buffer width of console setw (300); puts ("\n [ cms v0.1 - Copyleft 2015 (x) @Odzhan\n"); // set up default values args.address = NULL; args.ai_family = AF_INET; args.port = DEFAULT_PORT; args.port_nbr = atoi(args.port); pInitSecurityInterface = (INIT_SECURITY_INTERFACE)GetProcAddress(LoadLibrary("Secur32"), "InitSecurityInterfaceA" ); if (pInitSecurityInterface==NULL) printf ("didn't resolve"); sspi = pInitSecurityInterface(); // process command line parse_args(argc, argv); // resolve address and open socket if (open_tcp ()) { start_handler (); // create credentials if (create_creds()==SEC_E_OK) { // connect to server if (connect (s, ai_addr, ai_addrlen) != SOCKET_ERROR) { // perform the handshake if (chs () == SEC_E_OK) { printf (" [ connected\n\n"); secure_info(); ss=sspi->QueryContextAttributes (&hContext, SECPKG_ATTR_STREAM_SIZES, &Sizes ); cbBufferLen = Sizes.cbHeader + Sizes.cbMaximumMessage + Sizes.cbTrailer; pbBufferIn = LocalAlloc(LMEM_FIXED, cbBufferLen); pbBufferOut = LocalAlloc(LMEM_FIXED, cbBufferLen); pbDataIn=pbBufferIn + Sizes.cbHeader; pbDataOut=pbBufferOut + Sizes.cbHeader; cbBufferLen = Sizes.cbMaximumMessage; printf (" [ running cmd\n"); cmd(); } else { printf (" [ handshake failed\n"); } } else { printf (" [ unable to connect\n"); } } else { printf (" [ error creating credentials\n"); } stop_handler (); close_tcp(); } return 0; }