Example #1
0
PBYTE VerifyThis(
PBYTE   pBuffer, 
LPDWORD pcbMessage,
struct _SecHandle *hCtxt,
ULONG   cbMaxSignature)
{

	SECURITY_STATUS   ss;
	SecBufferDesc     BuffDesc;
	SecBuffer         SecBuff[2];
	ULONG             ulQop = 0;
	PBYTE             pSigBuffer;
	PBYTE             pDataBuffer;
	
	//-------------------------------------------------------------------
	//  The global cbMaxSignature is the size of the signature
	//  in the message received.

	printf ("data before verifying (including signature):\n");
	PrintHexDump (*pcbMessage, pBuffer);

	//--------------------------------------------------------------------
	//  By agreement with the server, 
	//  the signature is at the beginning of the message received,
	//  and the data that was signed comes after the signature.

	pSigBuffer = pBuffer;
	pDataBuffer = pBuffer + cbMaxSignature;

	//-------------------------------------------------------------------
	//  The size of the message is reset to the size of the data only.

	*pcbMessage = *pcbMessage - (cbMaxSignature);

	//--------------------------------------------------------------------
	//  Prepare the buffers to be passed to the signature verification 
	//  function.

	BuffDesc.ulVersion    = 0;
	BuffDesc.cBuffers     = 2;
	BuffDesc.pBuffers     = SecBuff;

	SecBuff[0].cbBuffer   = cbMaxSignature;
	SecBuff[0].BufferType = SECBUFFER_TOKEN;
	SecBuff[0].pvBuffer   = pSigBuffer;

	SecBuff[1].cbBuffer   = *pcbMessage;
	SecBuff[1].BufferType = SECBUFFER_DATA;
	SecBuff[1].pvBuffer   = pDataBuffer;

	ss = VerifySignature(
	hCtxt,
	&BuffDesc,
	0,
	&ulQop
	);

	if (!SEC_SUCCESS(ss)) 
	{
		fprintf(stderr, "VerifyMessage failed");
	}
	else
	{
		printf("Message was properly signed.\n");
	}

	return pDataBuffer;

}  // end VerifyThis
Example #2
0
PBYTE DecryptThis(
PBYTE              pBuffer, 
LPDWORD            pcbMessage,
struct _SecHandle *hCtxt,
ULONG              cbSecurityTrailer)
{
	SECURITY_STATUS   ss;
	SecBufferDesc     BuffDesc;
	SecBuffer         SecBuff[2];
	ULONG             ulQop = 0;
	PBYTE             pSigBuffer;
	PBYTE             pDataBuffer;
	DWORD             SigBufferSize;

	//-------------------------------------------------------------------
	//  By agreement, the server encrypted the message and set the size
	//  of the trailer block to be just what it needed. DecryptMessage 
	//  needs the size of the trailer block. 
	//  The size of the trailer is in the first DWORD of the
	//  message received. 

	SigBufferSize = *((DWORD *) pBuffer);
	printf ("data before decryption including trailer (%lu bytes):\n",
	*pcbMessage);
	PrintHexDump (*pcbMessage, (PBYTE) pBuffer);

	//--------------------------------------------------------------------
	//  By agreement, the server placed the trailer at the beginning 
	//  of the message that was sent immediately following the trailer 
	//  size DWORD.

	pSigBuffer = pBuffer + sizeof(DWORD);

	//--------------------------------------------------------------------
	//  The data comes after the trailer.

	pDataBuffer = pSigBuffer + SigBufferSize;

	//--------------------------------------------------------------------
	//  *pcbMessage is reset to the size of just the encrypted bytes.

	*pcbMessage = *pcbMessage - SigBufferSize - sizeof(DWORD);

	//--------------------------------------------------------------------
	//  Prepare the buffers to be passed to the DecryptMessage function.

	BuffDesc.ulVersion    = 0;
	BuffDesc.cBuffers     = 2;
	BuffDesc.pBuffers     = SecBuff;

	SecBuff[0].cbBuffer   = SigBufferSize;
	SecBuff[0].BufferType = SECBUFFER_TOKEN;
	SecBuff[0].pvBuffer   = pSigBuffer;

	SecBuff[1].cbBuffer   = *pcbMessage;
	SecBuff[1].BufferType = SECBUFFER_DATA;
	SecBuff[1].pvBuffer   = pDataBuffer;

	ss = DecryptMessage(
	hCtxt,
	&BuffDesc,
	0,
	&ulQop);

	if (!SEC_SUCCESS(ss)) 
	{
		fprintf(stderr, "DecryptMessage failed");
	}

	//-------------------------------------------------------------------
	//  Return a pointer to the decrypted data. The trailer data
	//  is discarded.

	return pDataBuffer;

}
Example #3
0
BOOL GenClientContext (
BYTE       *pIn,
DWORD       cbIn,
BYTE       *pOut,
DWORD      *pcbOut,
BOOL       *pfDone,
CHAR       *pszTarget,
CredHandle *hCred,
struct _SecHandle *hcText)
{
	SECURITY_STATUS   ss;
	TimeStamp         Lifetime;
	SecBufferDesc     OutBuffDesc;
	SecBuffer         OutSecBuff;
	SecBufferDesc     InBuffDesc;
	SecBuffer         InSecBuff;
	ULONG             ContextAttributes;
	static TCHAR      lpPackageName[1024];

	if( NULL == pIn )  
	{   
		strcpy_s(lpPackageName, 1024 * sizeof(TCHAR), "Negotiate");
		ss = AcquireCredentialsHandle (
		NULL, 
		lpPackageName,
		SECPKG_CRED_OUTBOUND,
		NULL, 
		NULL, 
		NULL, 
		NULL, 
		hCred,
		&Lifetime);

		if (!(SEC_SUCCESS (ss)))
		{
			MyHandleError("AcquireCreds failed ");
		}
	}

	//--------------------------------------------------------------------
	//  Prepare the buffers.

	OutBuffDesc.ulVersion = 0;
	OutBuffDesc.cBuffers  = 1;
	OutBuffDesc.pBuffers  = &OutSecBuff;

	OutSecBuff.cbBuffer   = *pcbOut;
	OutSecBuff.BufferType = SECBUFFER_TOKEN;
	OutSecBuff.pvBuffer   = pOut;

	//-------------------------------------------------------------------
	//  The input buffer is created only if a message has been received 
	//  from the server.

	if (pIn)   
	{
		InBuffDesc.ulVersion = 0;
		InBuffDesc.cBuffers  = 1;
		InBuffDesc.pBuffers  = &InSecBuff;

		InSecBuff.cbBuffer   = cbIn;
		InSecBuff.BufferType = SECBUFFER_TOKEN;
		InSecBuff.pvBuffer   = pIn;

		ss = InitializeSecurityContext (
		hCred,
		hcText,
		pszTarget,
		MessageAttribute, 
		0,
		SECURITY_NATIVE_DREP,
		&InBuffDesc,
		0, 
		hcText,
		&OutBuffDesc,
		&ContextAttributes,
		&Lifetime);
	}
	else
	{
		ss = InitializeSecurityContext (
		hCred,
		NULL,
		pszTarget,
		MessageAttribute, 
		0, 
		SECURITY_NATIVE_DREP,
		NULL,
		0, 
		hcText,
		&OutBuffDesc,
		&ContextAttributes,
		&Lifetime);
	}

	if (!SEC_SUCCESS (ss))  
	{
		MyHandleError ("InitializeSecurityContext failed " );
	}

	//-------------------------------------------------------------------
	//  If necessary, complete the token.

	if ((SEC_I_COMPLETE_NEEDED == ss) 
			|| (SEC_I_COMPLETE_AND_CONTINUE == ss))  
	{
		ss = CompleteAuthToken (hcText, &OutBuffDesc);
		if (!SEC_SUCCESS(ss))  
		{
			fprintf (stderr, "complete failed: 0x%08x\n", ss);
			return FALSE;
		}
	}

	*pcbOut = OutSecBuff.cbBuffer;

	*pfDone = !((SEC_I_CONTINUE_NEEDED == ss) ||
	(SEC_I_COMPLETE_AND_CONTINUE == ss));

	printf ("Token buffer generated (%lu bytes):\n", OutSecBuff.cbBuffer);
	PrintHexDump (OutSecBuff.cbBuffer, (PBYTE)OutSecBuff.pvBuffer);
	return TRUE;

}
Example #4
0
// Trace handshake buffer
void CSSLHelper::TraceHandshake()
{
   if (MaxBufBytes < 5)
      DebugMsg("Buffer space too small");
   else
   {
      const byte * BufPtr = DataPtr;
      if (length + 5 == MaxBufBytes)
         DebugMsg("Exactly one buffer is present");
      else if (length + 5 <= MaxBufBytes)
         DebugMsg("Whole buffer is present");
      else
         DebugMsg("Only part of the buffer is present");
      if (major == 3)
      {
         if (minor == 0)
            DebugMsg("SSL version 3.0");
         else if (minor == 1)
            DebugMsg("TLS version 1.0");
         else if (minor == 2)
            DebugMsg("TLS version 1.1");
         else if (minor == 3)
            DebugMsg("TLS version 1.2");
         else
            DebugMsg("TLS version after 1.2");
      }
      else
      {
         DebugMsg("Content Type = %d, Major.Minor Version = %d.%d, length %d (0x%04X)", contentType, major, minor, length, length);
         DebugMsg("This version is not recognized so no more information is available");
         PrintHexDump(MaxBufBytes, OriginalBufPtr);
         return;
      }
      // This is a version we recognize
      if (contentType != 22)
      {
         DebugMsg("This content type (%d) is not recognized", contentType);
         PrintHexDump(MaxBufBytes, OriginalBufPtr);
         return;
      }
      // This is a handshake message (content type 22)
      if (handshakeType != 1)
      {
         DebugMsg("This handshake type (%d) is not recognized", handshakeType);
         PrintHexDump(MaxBufBytes, OriginalBufPtr);
         return;
      }
      // This is a client hello message (handshake type 1)
      DebugMsg("client_hello");
      BufPtr += 2; // Skip ClientVersion
      BufPtr += 32; // Skip Random
      UINT8 sessionidLength = *BufPtr;
      BufPtr += 1 + sessionidLength; // Skip SessionID
      UINT16 cipherSuitesLength = (*(BufPtr) << 8) + *(BufPtr + 1);
      BufPtr += 2 + cipherSuitesLength; // Skip CipherSuites
      UINT8 compressionMethodsLength = *BufPtr;
      BufPtr += 1 + compressionMethodsLength; // Skip Compression methods
      bool extensionsPresent = BufPtr < BufEnd;
      UINT16 extensionsLength = (*(BufPtr) << 8) + *(BufPtr + 1);
      BufPtr += 2;
      if (extensionsLength == BufEnd - BufPtr)
         DebugMsg("There are %d bytes of extension data", extensionsLength);
      while (BufPtr < BufEnd)
      {
         UINT16 extensionType = (*(BufPtr) << 8) + *(BufPtr + 1);
         BufPtr += 2;
         UINT16 extensionDataLength = (*(BufPtr) << 8) + *(BufPtr + 1);
         BufPtr += 2;
         if (extensionType == 0) // server name list, in practice there's only ever one name in it (see RFC 6066)
         {
            UINT16 serverNameListLength = (*(BufPtr) << 8) + *(BufPtr + 1);
            BufPtr += 2;
            DebugMsg("Server name list extension, length %d", serverNameListLength);
            const byte * serverNameListEnd = BufPtr + serverNameListLength;
            while (BufPtr < serverNameListEnd)
            {
               UINT8 serverNameType = *(BufPtr++);
               UINT16 serverNameLength = (*(BufPtr) << 8) + *(BufPtr + 1);
               BufPtr += 2;
               if (serverNameType == 0)
                  DebugMsg("   Requested name \"%*s\"", serverNameLength, BufPtr);
               else
                  DebugMsg("   Server name Type %d, length %d, data \"%*s\"", serverNameType, serverNameLength, serverNameLength, BufPtr);
               BufPtr += serverNameLength;
            }
         }
         else
         {
            DebugMsg("Extension Type %d, length %d", extensionType, extensionDataLength);
            BufPtr += extensionDataLength;
         }
      }
      if (BufPtr == BufEnd)
         DebugMsg("Extensions exactly filled the header, as expected");
      else
         DebugMsg("** Error ** Extensions did not fill the header");
   }
   PrintHexDump(MaxBufBytes, OriginalBufPtr);
   return;
}
Example #5
0
// Display a UI with the certificate info and also write it to the debug output
HRESULT ShowCertInfo(PCCERT_CONTEXT pCertContext, CString Title)
{
	TCHAR pszNameString[256];
	void*            pvData;
	DWORD            cbData;
	DWORD            dwPropId = 0;


	//  Display the certificate.
	if (!CryptUIDlgViewContext(
		CERT_STORE_CERTIFICATE_CONTEXT,
		pCertContext,
		NULL,
		CStringW(Title),
		0,
		NULL))
	{
		DebugMsg("UI failed.");
	}

	if (CertGetNameString(
		pCertContext,
		CERT_NAME_SIMPLE_DISPLAY_TYPE,
		0,
		NULL,
		pszNameString,
		128))
	{
		DebugMsg("Certificate for %S", ATL::CT2W(pszNameString));
	}
	else
		DebugMsg("CertGetName failed.");


	int Extensions = pCertContext->pCertInfo->cExtension;

	auto *p = pCertContext->pCertInfo->rgExtension;
	for (int i = 0; i < Extensions; i++)
	{
		DebugMsg("Extension %s", (p++)->pszObjId);
	}

	//-------------------------------------------------------------------
	// Loop to find all of the property identifiers for the specified  
	// certificate. The loop continues until 
	// CertEnumCertificateContextProperties returns zero.
	while (0 != (dwPropId = CertEnumCertificateContextProperties(
		pCertContext, // The context whose properties are to be listed.
		dwPropId)))    // Number of the last property found.  
		// This must be zero to find the first 
		// property identifier.
	{
		//-------------------------------------------------------------------
		// When the loop is executed, a property identifier has been found.
		// Print the property number.

		DebugMsg("Property # %d found->", dwPropId);

		//-------------------------------------------------------------------
		// Indicate the kind of property found.

		switch (dwPropId)
		{
		case CERT_FRIENDLY_NAME_PROP_ID:
		{
			DebugMsg("Friendly name: ");
			break;
		}
		case CERT_SIGNATURE_HASH_PROP_ID:
		{
			DebugMsg("Signature hash identifier ");
			break;
		}
		case CERT_KEY_PROV_HANDLE_PROP_ID:
		{
			DebugMsg("KEY PROVE HANDLE");
			break;
		}
		case CERT_KEY_PROV_INFO_PROP_ID:
		{
			DebugMsg("KEY PROV INFO PROP ID ");
			break;
		}
		case CERT_SHA1_HASH_PROP_ID:
		{
			DebugMsg("SHA1 HASH identifier");
			break;
		}
		case CERT_MD5_HASH_PROP_ID:
		{
			DebugMsg("md5 hash identifier ");
			break;
		}
		case CERT_KEY_CONTEXT_PROP_ID:
		{
			DebugMsg("KEY CONTEXT PROP identifier");
			break;
		}
		case CERT_KEY_SPEC_PROP_ID:
		{
			DebugMsg("KEY SPEC PROP identifier");
			break;
		}
		case CERT_ENHKEY_USAGE_PROP_ID:
		{
			DebugMsg("ENHKEY USAGE PROP identifier");
			break;
		}
		case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
		{
			DebugMsg("NEXT UPDATE LOCATION PROP identifier");
			break;
		}
		case CERT_PVK_FILE_PROP_ID:
		{
			DebugMsg("PVK FILE PROP identifier ");
			break;
		}
		case CERT_DESCRIPTION_PROP_ID:
		{
			DebugMsg("DESCRIPTION PROP identifier ");
			break;
		}
		case CERT_ACCESS_STATE_PROP_ID:
		{
			DebugMsg("ACCESS STATE PROP identifier ");
			break;
		}
		case CERT_SMART_CARD_DATA_PROP_ID:
		{
			DebugMsg("SMART_CARD DATA PROP identifier ");
			break;
		}
		case CERT_EFS_PROP_ID:
		{
			DebugMsg("EFS PROP identifier ");
			break;
		}
		case CERT_FORTEZZA_DATA_PROP_ID:
		{
			DebugMsg("FORTEZZA DATA PROP identifier ");
			break;
		}
		case CERT_ARCHIVED_PROP_ID:
		{
			DebugMsg("ARCHIVED PROP identifier ");
			break;
		}
		case CERT_KEY_IDENTIFIER_PROP_ID:
		{
			DebugMsg("KEY IDENTIFIER PROP identifier ");
			break;
		}
		case CERT_AUTO_ENROLL_PROP_ID:
		{
			DebugMsg("AUTO ENROLL identifier. ");
			break;
		}
		case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
		{
			DebugMsg("ISSUER PUBLIC KEY MD5 HASH identifier. ");
			break;
		}
		} // End switch.

		//-------------------------------------------------------------------
		// Retrieve information on the property by first getting the 
		// property size. 
		// For more information, see CertGetCertificateContextProperty.

		if (CertGetCertificateContextProperty(
			pCertContext,
			dwPropId,
			NULL,
			&cbData))
		{
			//  Continue.
		}
		else
		{
			// If the first call to the function failed,
			// exit to an error routine.
			DebugMsg("Call #1 to GetCertContextProperty failed.");
			return E_FAIL;
		}
		//-------------------------------------------------------------------
		// The call succeeded. Use the size to allocate memory 
		// for the property.

		if (NULL != (pvData = (void*)malloc(cbData)))
		{
			// Memory is allocated. Continue.
		}
		else
		{
			// If memory allocation failed, exit to an error routine.
			DebugMsg("Memory allocation failed.");
			return E_FAIL;
		}
		//----------------------------------------------------------------
		// Allocation succeeded. Retrieve the property data.

		if (CertGetCertificateContextProperty(
			pCertContext,
			dwPropId,
			pvData,
			&cbData))
		{
			// The data has been retrieved. Continue.
		}
		else
		{
			// If an error occurred in the second call, 
			// exit to an error routine.
			DebugMsg("Call #2 failed.");
			return E_FAIL;
		}
		//---------------------------------------------------------------
		// Show the results.

		DebugMsg("The Property Content is");
		PrintHexDump(cbData, pvData);

		//----------------------------------------------------------------
		// Free the certificate context property memory.

		free(pvData);
	}
	return S_OK;
}
Example #6
0
BOOL DoAuthentication (void)
{
	SECURITY_STATUS   	ss;
	DWORD 			  	cbIn;
	DWORD		      	cbOut;
	DWORD 			  	g_cbMaxMessage;
	BOOL              	done = FALSE;
	BOOL		      	fDone = FALSE;
	BOOL              	fNewConversation = TRUE;
	TimeStamp         	Lifetime;
	PSecPkgInfoA	  	pkgInfo;
	CredHandle        	hcred;
	CredHandle 	      	hCcred;
	struct _SecHandle 	hctxt;
	struct _SecHandle 	hCctxt;
	PBYTE 			  	g_pInBuf = NULL;
	PBYTE 			  	g_pOutBuf = NULL;
	SEC_CHAR          	g_lpPackageName[1024];
	PBYTE				nonce, clientnonce, lmhash, nthash;
	PCHAR pUserName = NULL;
	DWORD cbUserName = 0;



	lstrcpynA (g_lpPackageName, "NTLM",5);
	ss = QuerySecurityPackageInfoA ( g_lpPackageName, &pkgInfo);
	if (!SEC_SUCCESS(ss)) MyHandleError("Could not query package");

	g_cbMaxMessage = pkgInfo->cbMaxToken;
	FreeContextBuffer(pkgInfo);
	g_pInBuf = (PBYTE) malloc (g_cbMaxMessage);
	g_pOutBuf = (PBYTE) malloc (g_cbMaxMessage);
   
	if (NULL == g_pInBuf || NULL == g_pOutBuf) MyHandleError("Memory allocation");

	ss = AcquireCredentialsHandleA (NULL, g_lpPackageName, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &hcred, &Lifetime);

	if (!SEC_SUCCESS (ss)) MyHandleError("AcquireCreds failed");
	cbOut = g_cbMaxMessage;

	if (!GenClientContext ( NULL, 0, g_pOutBuf, &cbOut, &fDone, "NTLM", &hCcred, &hCctxt))
		MyHandleError("Cant't generate client context");

	printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut);//type1
	PrintHexDump (cbOut, (PBYTE)g_pOutBuf);

	memcpy(g_pInBuf,g_pOutBuf, cbOut);
	cbIn = cbOut;
	cbOut = g_cbMaxMessage;


	if (!GenServerContext (g_pInBuf, cbIn, g_pOutBuf, &cbOut, &done, fNewConversation, &hcred, &hctxt))
		MyHandleError("GenServerContext failed");

	fNewConversation = FALSE;

	printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut); //type2
	PrintHexDump (cbOut, (PBYTE)g_pOutBuf);
	
	memcpy(g_pInBuf,g_pOutBuf, cbOut);
	cbIn = cbOut;
	cbOut = g_cbMaxMessage;

	nonce = (PBYTE) malloc (16);
	memcpy (nonce, (void *)&g_pOutBuf[24], 8);
	
	if (!GenClientContext (g_pInBuf, cbIn, g_pOutBuf, &cbOut, &fDone, "NTLM", &hCcred, &hCctxt))
		MyHandleError("GenClientContext failed");

	printf ("Type%hhd message (%lu bytes):\n",g_pOutBuf[8], cbOut);//type3
	PrintHexDump (cbOut, (PBYTE)g_pOutBuf);

	GetUserNameExA(NameSamCompatible, pUserName, &cbUserName);
	pUserName = (PCHAR) malloc (cbUserName);
	GetUserNameExA(NameSamCompatible, pUserName, &cbUserName);
	cbUserName = (DWORD)((int)strchr(pUserName,'\\'));
	*(char *)cbUserName = 0;

	printf("g_pOutBuf[22]=%d\n",g_pOutBuf[22]);

	if (g_pOutBuf[22] > 24) 
	{
		printf("NTLMv2\n");
		nthash = (PBYTE) malloc (16);
		cbIn = g_pOutBuf[24] + (g_pOutBuf[25] << 8);
		memcpy (nthash, (void *)&g_pOutBuf[cbIn], 16);

		cbIn += 16;
		clientnonce = (PBYTE) malloc (cbOut - cbIn - 16);
		//memcpy (clientnonce, (void *)&g_pOutBuf[cbIn], 84);
		memcpy (clientnonce, (void *)&g_pOutBuf[cbIn], cbOut - cbIn - 16);

		printf("Nonce:  ");
		PrintHex (8, nonce);
		printf("\nClientNonce: ");
		PrintHex (cbOut - cbIn - 16, clientnonce);
		printf("\nNThash: ");
		PrintHex (16, nthash);
		printf("\n");
		
		printf("\nJTR: %s::%s", (unsigned char *)((int)cbUserName+1), (unsigned char *)pUserName);
		printf(":");
		PrintHex (8, nonce);
		printf(":");
		PrintHex (16, nthash);
		printf(":");
		PrintHex (cbOut - cbIn - 16, clientnonce);

		printf("\n");
	}
	else if (g_pOutBuf[22] == 24)
	{
		printf("NTLM\n");
		lmhash = (PBYTE) malloc (24);
		cbIn = g_pOutBuf[16] + (g_pOutBuf[17] << 8);
		memcpy (lmhash, (void *)&g_pOutBuf[cbIn], 24);

		nthash = (PBYTE) malloc (24);
		cbIn = g_pOutBuf[24] + (g_pOutBuf[25] << 8);
		memcpy (nthash, (void *)&g_pOutBuf[cbIn], 24);

		printf("\nNonce:  ");
		PrintHex (8, nonce);
		printf("\nLMhash: ");
		PrintHex (24, lmhash);
		printf("\nNThash: ");
		PrintHex (24, nthash);

		printf("\nJTR: %s::%s", (unsigned char *)((int)cbUserName+1), (unsigned char *)pUserName);
		printf(":");
		PrintHex (24, lmhash);
		printf(":");
		PrintHex (24, nthash);
		printf(":");
		PrintHex (8, nonce);
		printf("\n");
		
	}
	else
	{
		printf("Unknown hashtype");
	}


	return(TRUE);
}