1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Code to share.Sign and verify with a Certificate.

Discussion in 'Win32' started by wanjing, Apr 10, 2007.

  1. wanjing

    wanjing New Member

    Joined:
    Apr 10, 2007
    Messages:
    2
    Likes Received:
    0
    Trophy Points:
    0
    Location:
    Socialist Party China
    Home Page:
    Code:
    bool SignData(BYTE *sgin1Data,int sgin1Len,
    				  BYTE *sgoutData,int &sgoutLen,
    				   LPWSTR CertName,LPWSTR SignerName)
    {
    	BYTE *sgin11Data;
    	DWORD sgin11Len;
    	if(! make_hash( sgin1Data, sgin1Len,  sgin11Data, sgin11Len))
    	{
    		return false;
    	}
    
    	PBYTE tempBuffer =NULL; 
    	bool sdRet =true;
    
    	//-------------------------------------------------------------------
    	// Size of message. Note that the length set is one more than the 
    	// length returned by the strlen function in order to include
    	// the NULL string termination character.
    	DWORD cbMessage = sgin11Len+1; 
    	DWORD cbSignedMessageBlob;
    
    	//-------------------------------------------------------------------
    	// Pointer to a signer certificate
    	PCCERT_CONTEXT pSignerCert; 
    	CRYPT_SIGN_MESSAGE_PARA  SigParams;
    
    	//-------------------------------------------------------------------
    	// Create the MessageArray and the MessageSizeArray.
    
    	const BYTE* MessageArray[] = {sgin11Data};
    	DWORD MessageSizeArray[1];
    	MessageSizeArray[0] = cbMessage;
    
    	//-------------------------------------------------------------------
    	// System store handle
    	HCERTSTORE hStoreHandle;  
    
    	//-------------------------------------------------------------------
    	// Open a certificate store.
    
    	if ( !( hStoreHandle = CertOpenStore(
    		CERT_STORE_PROV_SYSTEM,
    		0,
    		NULL,
    		CERT_SYSTEM_STORE_CURRENT_USER,
    		CertName)))
    	{
    		return false;
    	}
    
    	//-------------------------------------------------------------------
    	// Get a pointer to the signer's certificate.
    	// This certificate must have access to the signer's private key.
    
    	if(pSignerCert = CertFindCertificateInStore(
    		hStoreHandle,
    		MY_ENCODING_TYPE,
    		0,
    		CERT_FIND_SUBJECT_STR,
    		SignerName,
    		NULL))
    	{
    	}
    	else
    	{
    		AfxTrace("%d ", GetLastError());
    		return false;
    	}
    
    	if(VerifyClientCertificate(pSignerCert,0) !=SEC_E_OK)
    	{
    		sdRet =false;
    		goto SPError;
    	}
    
    	//-------------------------------------------------------------------
    	// Initialize the signature structure.
    	SigParams.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
    	SigParams.dwMsgEncodingType = MY_ENCODING_TYPE;
    	SigParams.pSigningCert = pSignerCert;
    	SigParams.HashAlgorithm.pszObjId = szOID_RSA_MD5;
    	SigParams.HashAlgorithm.Parameters.cbData = NULL;
    	SigParams.cMsgCert = 1;
    	SigParams.rgpMsgCert = &pSignerCert;
    	SigParams.cAuthAttr = 0;
    	SigParams.dwInnerContentType = 0;
    	SigParams.cMsgCrl = 0;
    	SigParams.cUnauthAttr = 0;
    	SigParams.dwFlags = 0;
    	SigParams.pvHashAuxInfo = NULL;
    	SigParams.rgAuthAttr = NULL;
    
    	//-------------------------------------------------------------------
    	// With two calls to CryptSignMessage, sign the message.
    	// First, get the size of the output signed BLOB.
    
    	if(CryptSignMessage(
    		&SigParams,            // Signature parameters
    		FALSE,                 // Not detached
    		1,                     // Number of messages
    		MessageArray,          // Messages to be signed
    		MessageSizeArray,      // Size of messages
    		NULL,                  // Buffer for signed message
    		&cbSignedMessageBlob)) // Size of buffer
    	{
    	}
    	else
    	{
    		AfxTrace("%d ", GetLastError());
    		return false;
    	}
    
    	//-------------------------------------------------------------------
    	// Allocate memory for the signed BLOB.
    	if(!(tempBuffer = (BYTE*)malloc(cbSignedMessageBlob*10)))
    	{
    		return false;
    	}
    
    	//-------------------------------------------------------------------
    	// Get the SignedMessageBlob.
    
    	if(CryptSignMessage(
    		&SigParams,             // Signature parameters
    		FALSE,                  // Not detached
    		1,                      // Number of messages
    		MessageArray,          // Messages to be signed
    		MessageSizeArray,      // Size of messages
    		tempBuffer,			   // Buffer for signed message
    		&cbSignedMessageBlob)) // Size of buffer
    	{
    	}
    	else
    	{
    		AfxTrace("%d ", GetLastError());
    		return false;
    	}
    
    	memcpy(sgoutData,tempBuffer,cbSignedMessageBlob);
    	sgoutLen+=cbSignedMessageBlob;
    
    	//-------------------------------------------------------------------
    	// Clean up and free memory.
    SPError:if(tempBuffer)  free(tempBuffer); 
    
    	if(pSignerCert)
    		CertFreeCertificateContext(pSignerCert);
    
    	CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_CHECK_FLAG);
    
    	return sdRet;
    }
    
    bool VerifyData(BYTE *vfinData,int vfinLen,
    				BYTE *vfnewData,int vfnewLen)
    {
    	BYTE *vfin11Data;
    	DWORD vfin11Len;
    	if(! make_hash(vfnewData,vfnewLen,   vfin11Data ,vfin11Len))
    	{
    		return false;
    	}
    
    	HCRYPTMSG hMsg;
    
        DWORD cb3Decoded;
    	BYTE *p3Decoded;
    
    	//  Open a message for decoding.
    	if(!(hMsg = CryptMsgOpenToDecode(
    	MY_ENCODING_TYPE,      // Encoding type.
    	0,                     // Flags.
    	0,                     // Use the default message type.
    							// The message type is 
    							// listed in the message header.
    	NULL,                  // Cryptographic provider. Use NULL
    							// for the default provider.
    	NULL,                  // Recipient information.
    	NULL)))                 // Stream information.
    	{
    		return false;
    	}
    	
    	//-------------------------------------------------------------------
    	//  Update the message with an encoded BLOB.
    	//  Both pbEncodedBlob, the encoded data, 
    	//  and cbEnclodeBlob, the length of the encoded data,
    	//  must be available. 
    
    	if(!(CryptMsgUpdate(
    		hMsg,             // Handle to the message
    		vfinData,        // Pointer to the encoded BLOB
    		vfinLen,        // Size of the encoded BLOB
    		TRUE)))          // Last call
    	{
    		return false;
    	}
    
    	//-------------------------------------------------------------------
    	//  Get the number of bytes needed for a buffer
    	//  to hold the decoded message.
    
    	if(!(CryptMsgGetParam(
    		hMsg,                  // Handle to the message
    		CMSG_CONTENT_PARAM,    // Parameter type
    		0,                     // Index
    		NULL,                 
    		&cb3Decoded)))           // Size of the returned 
    							// information.
    	{
    		AfxTrace("%d ", GetLastError());
    		return false;
    	}
    	
    	//-------------------------------------------------------------------
    	// Allocate memory.
    
    	if(!(p3Decoded = (BYTE *) malloc(cb3Decoded)))
    	{
    		return false;
    	}
    
    	//-------------------------------------------------------------------
    	// Copy the content to the buffer.
    
    	if(!(CryptMsgGetParam(
    	hMsg,                 // Handle to the message
    	CMSG_CONTENT_PARAM,   // Parameter type
    	0,                    // Index
    	p3Decoded,            // Address for returned 
    							// information.
    	&cb3Decoded)))          // Size of the returned        
    							// information.
    	{
    		return false;
    	}
    
    	if(memcmp(p3Decoded,vfin11Data, min(vfin11Len,cb3Decoded)))
    	{
    		return false;
    	}
    	
    	//-------------------------------------------------------------------
    	// Clean up.
    	if(p3Decoded)
    		free(p3Decoded);
    
    	if(hMsg)
    		CryptMsgClose(hMsg);
    
    	return true;
    }
     
  2. NewsBot

    NewsBot New Member

    Joined:
    Dec 2, 2008
    Messages:
    1,267
    Likes Received:
    2
    Trophy Points:
    0
    I have edited to have the code formatted.
     

Share This Page