Exemple #1
1
BOOL WINAPI CryptHashMessage(PCRYPT_HASH_MESSAGE_PARA pHashPara,
 BOOL fDetachedHash, DWORD cToBeHashed, const BYTE *rgpbToBeHashed[],
 DWORD rgcbToBeHashed[], BYTE *pbHashedBlob, DWORD *pcbHashedBlob,
 BYTE *pbComputedHash, DWORD *pcbComputedHash)
{
    DWORD i, flags;
    BOOL ret = FALSE;
    HCRYPTMSG msg;
    CMSG_HASHED_ENCODE_INFO info;

    TRACE("(%p, %d, %d, %p, %p, %p, %p, %p, %p)\n", pHashPara, fDetachedHash,
     cToBeHashed, rgpbToBeHashed, rgcbToBeHashed, pbHashedBlob, pcbHashedBlob,
     pbComputedHash, pcbComputedHash);

    if (pHashPara->cbSize != sizeof(CRYPT_HASH_MESSAGE_PARA))
    {
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    /* Native seems to ignore any encoding type other than the expected
     * PKCS_7_ASN_ENCODING
     */
    if (GET_CMSG_ENCODING_TYPE(pHashPara->dwMsgEncodingType) !=
     PKCS_7_ASN_ENCODING)
        return TRUE;
    /* Native also seems to do nothing if the output parameter isn't given */
    if (!pcbHashedBlob)
        return TRUE;

    flags = fDetachedHash ? CMSG_DETACHED_FLAG : 0;
    memset(&info, 0, sizeof(info));
    info.cbSize = sizeof(info);
    info.hCryptProv = pHashPara->hCryptProv;
    memcpy(&info.HashAlgorithm, &pHashPara->HashAlgorithm,
     sizeof(info.HashAlgorithm));
    info.pvHashAuxInfo = pHashPara->pvHashAuxInfo;
    msg = CryptMsgOpenToEncode(pHashPara->dwMsgEncodingType, flags, CMSG_HASHED,
     &info, NULL, NULL);
    if (msg)
    {
        for (i = 0, ret = TRUE; ret && i < cToBeHashed; i++)
            ret = CryptMsgUpdate(msg, rgpbToBeHashed[i], rgcbToBeHashed[i],
             i == cToBeHashed - 1 ? TRUE : FALSE);
        if (ret)
        {
            ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbHashedBlob,
             pcbHashedBlob);
            if (ret && pcbComputedHash)
                ret = CryptMsgGetParam(msg, CMSG_COMPUTED_HASH_PARAM, 0,
                 pbComputedHash, pcbComputedHash);
        }
        CryptMsgClose(msg);
    }
    return ret;
}
DWORD do_low_sign (const char *infile, const char *outfile)
{
	char OID[64] = szOID_CP_GOST_R3411;
    int include = 1;
    HCRYPTPROV hCryptProv = 0;               // CSP handle
    PCCERT_CONTEXT pUserCert = NULL;		// User certificate to be used
	
    DWORD keytype = 0;
    CSP_BOOL should_release_ctx = FALSE;
    DWORD ret = 1;
    FILE *tbs = NULL;
    BYTE *mem_tbs = NULL;
    DWORD mem_len = 0;
    
    HCRYPTMSG hMsg = 0;
    
    DWORD			HashAlgSize;
	DWORD			dwSize;
    CRYPT_ALGORITHM_IDENTIFIER	HashAlgorithm;
    CMSG_SIGNER_ENCODE_INFO	SignerEncodeInfo;
    CERT_BLOB			SignerCertBlob;
    CERT_BLOB			SignerCertBlobArray[1];
    DWORD			cbEncodedBlob;
    BYTE			*pbEncodedBlob = NULL;
    CMSG_SIGNER_ENCODE_INFO	SignerEncodeInfoArray[1];
    CMSG_SIGNED_ENCODE_INFO	SignedMsgEncodeInfo;
	CSP_BOOL bResult = FALSE;
	CRYPT_KEY_PROV_INFO *pProvInfo = NULL;
	
	HCERTSTORE hCertStore = 0;
	
	hCertStore = CertOpenSystemStore(0, "My");
	if(!hCertStore){
		ret = CSP_GetLastError();
		fprintf (stderr, "CertOpenSystemStore failed.");
		goto err;
	}
	
	while( !bResult){
		pUserCert= CertEnumCertificatesInStore(hCertStore, pUserCert);
		if(!pUserCert){
			break;
		}
		bResult = CertGetCertificateContextProperty(
													pUserCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSize);
		if (bResult) {
			
			free(pProvInfo);
			pProvInfo = (CRYPT_KEY_PROV_INFO *)malloc(dwSize);
			if (pProvInfo) {
				bResult = CertGetCertificateContextProperty(
															pUserCert, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwSize);
			}
			
		}
	}
	if(!bResult){
		fprintf (stderr, "No certificates with private key link.");
		goto err;
	}
	
    if (! infile) {
		fprintf (stderr, "No input file was specified\n");
		goto err;
    }
	
    if (CryptAcquireCertificatePrivateKey(
										  pUserCert,        
										  0,		//DWORD dwFlags,               
										  NULL,            
										  &hCryptProv,     
										  &keytype,           // returned key type AT_SIGNATURE ! AT_KEYEXCAHGE
										  &should_release_ctx  // if FALSE DO NOT Release CTX
										  )) {
		printf("A CSP has been acquired. \n");
    }
    else {
		ret = CSP_GetLastError();
		fprintf (stderr, "Cryptographic context could not be acquired.");
		goto err;
    }
	
	
    tbs = fopen (infile, "rb");
    if (!tbs) {
		fprintf (stderr, "Cannot open input file\n");
		goto err;
    }
	
    
    mem_len = 0;
    while (!feof(tbs)) {
		int r = 0;
		BYTE tmp[1024];
		r = fread (tmp, 1, 1024, tbs);
		mem_tbs = (BYTE *)realloc(mem_tbs, mem_len+r);
		memcpy (&mem_tbs[mem_len], tmp, r);
		mem_len += r;
    }
    fclose (tbs);
    tbs = NULL;
	
	
	//--------------------------------------------------------------------
	// Initialize the algorithm identifier structure.
    
    HashAlgSize = sizeof(HashAlgorithm);
    memset(&HashAlgorithm, 0, HashAlgSize); // Init. to zero.
    HashAlgorithm.pszObjId = OID;	    // Initialize the necessary member.
    
    //--------------------------------------------------------------------
    // Initialize the CMSG_SIGNER_ENCODE_INFO structure.
    
    memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO));
    SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO);
    SignerEncodeInfo.pCertInfo = pUserCert->pCertInfo;
    SignerEncodeInfo.hCryptProv = hCryptProv;
    SignerEncodeInfo.dwKeySpec = keytype;
    SignerEncodeInfo.HashAlgorithm = HashAlgorithm;
    SignerEncodeInfo.pvHashAuxInfo = NULL;
    
    //--------------------------------------------------------------------
    // Create an array of one. Note: Currently, there can be only one
    // signer.
    
    SignerEncodeInfoArray[0] = SignerEncodeInfo;
    
    //--------------------------------------------------------------------
    // Initialize the CMSG_SIGNED_ENCODE_INFO structure.
    
    SignerCertBlob.cbData = pUserCert->cbCertEncoded;
    SignerCertBlob.pbData = pUserCert->pbCertEncoded;
    
    //--------------------------------------------------------------------
    // Initialize the array of one CertBlob.
    
    SignerCertBlobArray[0] = SignerCertBlob;
    memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO));
    SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO);
    SignedMsgEncodeInfo.cSigners = 1;
    SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray;
    SignedMsgEncodeInfo.cCertEncoded = include;
    if (include)
		SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray;
    else
		SignedMsgEncodeInfo.rgCertEncoded = NULL;
    SignedMsgEncodeInfo.rgCrlEncoded = NULL;
    
    //--------------------------------------------------------------------
    // Get the size of the encoded message blob.
    
    if(cbEncodedBlob = CryptMsgCalculateEncodedLength(
													  TYPE_DER,       // Message encoding type
													  0,                      // Flags
													  CMSG_SIGNED,            // Message type
													  &SignedMsgEncodeInfo,   // Pointer to structure
													  NULL,                   // Inner content object ID
													  mem_len))		// Size of content */
	{
		printf("The length of the data has been calculated. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "Getting cbEncodedBlob length failed");
		goto err;		
    }
    //--------------------------------------------------------------------
    // Allocate memory for the encoded blob.
    
    pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob);
    if (!pbEncodedBlob){
		ret = CSP_GetLastError();
		fprintf (stderr, "Memory allocation failed");
		goto err;
	}
    //--------------------------------------------------------------------
    // Open a message to encode.
    
    if(hMsg = CryptMsgOpenToEncode(
								   TYPE_DER,        // Encoding type
								   0,                       // Flags
								   CMSG_SIGNED,             // Message type
								   &SignedMsgEncodeInfo,    // Pointer to structure
								   NULL,                    // Inner content object ID
								   NULL))                   // Stream information (not used)
    {
		printf("The message to be encoded has been opened. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "OpenToEncode failed");
		goto err;
    }
    //--------------------------------------------------------------------
    // Update the message with the data.
    
    if(CryptMsgUpdate(
					  hMsg,		// Handle to the message
					  mem_tbs,		// Pointer to the content
					  mem_len,	// Size of the content
					  TRUE))		// Last call
    {
		printf("Content has been added to the encoded message. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "MsgUpdate failed");
		goto err;
    }
    //--------------------------------------------------------------------
    // Get the resulting message.
    
    if(CryptMsgGetParam(
						hMsg,                      // Handle to the message
						CMSG_CONTENT_PARAM,        // Parameter type
						0,                         // Index
						pbEncodedBlob,             // Pointer to the blob
						&cbEncodedBlob))           // Size of the blob
    {
		printf("Message encoded successfully. \n");
    }
    else
    {
		ret = CSP_GetLastError();
		fprintf (stderr, "MsgGetParam failed");
		goto err;
    }
    //--------------------------------------------------------------------
    // pbEncodedBlob now points to the encoded, signed content.
    //--------------------------------------------------------------------
    if (outfile) {
		FILE *out = NULL;
		out = fopen (outfile, "wb");
		if (out) {
			fwrite (pbEncodedBlob, cbEncodedBlob, 1, out);
			fclose (out);
			printf ("Output file (%s) has been saved\n", outfile);
			
		}
		else
			perror ("Cannot open out file\n");
	}
    
	ret = 0;
    //--------------------------------------------------------------------
    // Clean up.
err:
    if(pbEncodedBlob)
		free(pbEncodedBlob);
    if(hMsg)
		CryptMsgClose(hMsg);
    if(hCryptProv) 
		CryptReleaseContext(hCryptProv,0);
	if(hCertStore)
		CertCloseStore(hCertStore, 0);
	
    return ret;
} 
Exemple #3
0
BOOL WINAPI CryptEncryptMessage(PCRYPT_ENCRYPT_MESSAGE_PARA pEncryptPara,
 DWORD cRecipientCert, PCCERT_CONTEXT rgpRecipientCert[],
 const BYTE *pbToBeEncrypted, DWORD cbToBeEncrypted, BYTE *pbEncryptedBlob,
 DWORD *pcbEncryptedBlob)
{
    BOOL ret = TRUE;
    DWORD i;
    PCERT_INFO *certInfo = NULL;
    CMSG_ENVELOPED_ENCODE_INFO envelopedInfo;
    HCRYPTMSG msg = 0;

    TRACE("(%p, %d, %p, %p, %d, %p, %p)\n", pEncryptPara, cRecipientCert,
     rgpRecipientCert, pbToBeEncrypted, cbToBeEncrypted, pbEncryptedBlob,
     pcbEncryptedBlob);

    if (pEncryptPara->cbSize != sizeof(CRYPT_ENCRYPT_MESSAGE_PARA) ||
     GET_CMSG_ENCODING_TYPE(pEncryptPara->dwMsgEncodingType) !=
     PKCS_7_ASN_ENCODING)
    {
        *pcbEncryptedBlob = 0;
        SetLastError(E_INVALIDARG);
        return FALSE;
    }

    memset(&envelopedInfo, 0, sizeof(envelopedInfo));
    envelopedInfo.cbSize = sizeof(envelopedInfo);
    envelopedInfo.hCryptProv = pEncryptPara->hCryptProv;
    envelopedInfo.ContentEncryptionAlgorithm =
     pEncryptPara->ContentEncryptionAlgorithm;
    envelopedInfo.pvEncryptionAuxInfo = pEncryptPara->pvEncryptionAuxInfo;

    if (cRecipientCert)
    {
        certInfo = CryptMemAlloc(sizeof(PCERT_INFO) * cRecipientCert);
        if (certInfo)
        {
            for (i = 0; i < cRecipientCert; ++i)
                certInfo[i] = rgpRecipientCert[i]->pCertInfo;
            envelopedInfo.cRecipients = cRecipientCert;
            envelopedInfo.rgpRecipientCert = certInfo;
        }
        else
            ret = FALSE;
    }

    if (ret)
        msg = CryptMsgOpenToEncode(pEncryptPara->dwMsgEncodingType, 0,
         CMSG_ENVELOPED, &envelopedInfo, NULL, NULL);
    if (msg)
    {
        ret = CryptMsgUpdate(msg, pbToBeEncrypted, cbToBeEncrypted, TRUE);
        if (ret)
            ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbEncryptedBlob,
             pcbEncryptedBlob);
        CryptMsgClose(msg);
    }
    else
        ret = FALSE;

    CryptMemFree(certInfo);
    if (!ret) *pcbEncryptedBlob = 0;
    return ret;
}
Exemple #4
0
BOOL WINAPI CryptSignMessage(PCRYPT_SIGN_MESSAGE_PARA pSignPara,
 BOOL fDetachedSignature, DWORD cToBeSigned, const BYTE *rgpbToBeSigned[],
 DWORD rgcbToBeSigned[], BYTE *pbSignedBlob, DWORD *pcbSignedBlob)
{
    HCRYPTPROV hCryptProv;
    BOOL ret, freeProv = FALSE;
    DWORD i, keySpec;
    PCERT_BLOB certBlob = NULL;
    PCRL_BLOB crlBlob = NULL;
    CMSG_SIGNED_ENCODE_INFO signInfo;
    CMSG_SIGNER_ENCODE_INFO signer;
    HCRYPTMSG msg = 0;

    TRACE("(%p, %d, %d, %p, %p, %p, %p)\n", pSignPara, fDetachedSignature,
     cToBeSigned, rgpbToBeSigned, rgcbToBeSigned, pbSignedBlob, pcbSignedBlob);

    if (pSignPara->cbSize != sizeof(CRYPT_SIGN_MESSAGE_PARA) ||
     GET_CMSG_ENCODING_TYPE(pSignPara->dwMsgEncodingType) !=
     PKCS_7_ASN_ENCODING)
    {
        *pcbSignedBlob = 0;
        SetLastError(E_INVALIDARG);
        return FALSE;
    }
    if (!pSignPara->pSigningCert)
        return TRUE;

    ret = CryptAcquireCertificatePrivateKey(pSignPara->pSigningCert,
     CRYPT_ACQUIRE_CACHE_FLAG, NULL, &hCryptProv, &keySpec, &freeProv);
    if (!ret)
        return FALSE;

    memset(&signer, 0, sizeof(signer));
    signer.cbSize = sizeof(signer);
    signer.pCertInfo = pSignPara->pSigningCert->pCertInfo;
    signer.hCryptProv = hCryptProv;
    signer.dwKeySpec = keySpec;
    signer.HashAlgorithm = pSignPara->HashAlgorithm;
    signer.pvHashAuxInfo = pSignPara->pvHashAuxInfo;
    signer.cAuthAttr = pSignPara->cAuthAttr;
    signer.rgAuthAttr = pSignPara->rgAuthAttr;
    signer.cUnauthAttr = pSignPara->cUnauthAttr;
    signer.rgUnauthAttr = pSignPara->rgUnauthAttr;

    memset(&signInfo, 0, sizeof(signInfo));
    signInfo.cbSize = sizeof(signInfo);
    signInfo.cSigners = 1;
    signInfo.rgSigners = &signer;

    if (pSignPara->cMsgCert)
    {
        certBlob = CryptMemAlloc(sizeof(CERT_BLOB) * pSignPara->cMsgCert);
        if (certBlob)
        {
            for (i = 0; i < pSignPara->cMsgCert; ++i)
            {
                certBlob[i].cbData = pSignPara->rgpMsgCert[i]->cbCertEncoded;
                certBlob[i].pbData = pSignPara->rgpMsgCert[i]->pbCertEncoded;
            }
            signInfo.cCertEncoded = pSignPara->cMsgCert;
            signInfo.rgCertEncoded = certBlob;
        }
        else
            ret = FALSE;
    }
    if (pSignPara->cMsgCrl)
    {
        crlBlob = CryptMemAlloc(sizeof(CRL_BLOB) * pSignPara->cMsgCrl);
        if (crlBlob)
        {
            for (i = 0; i < pSignPara->cMsgCrl; ++i)
            {
                crlBlob[i].cbData = pSignPara->rgpMsgCrl[i]->cbCrlEncoded;
                crlBlob[i].pbData = pSignPara->rgpMsgCrl[i]->pbCrlEncoded;
            }
            signInfo.cCrlEncoded = pSignPara->cMsgCrl;
            signInfo.rgCrlEncoded = crlBlob;
        }
        else
            ret = FALSE;
    }
    if (pSignPara->dwFlags || pSignPara->dwInnerContentType)
        FIXME("unimplemented feature\n");

    if (ret)
        msg = CryptMsgOpenToEncode(pSignPara->dwMsgEncodingType,
         fDetachedSignature ? CMSG_DETACHED_FLAG : 0, CMSG_SIGNED, &signInfo,
         NULL, NULL);
    if (msg)
    {
        if (cToBeSigned)
        {
            for (i = 0; ret && i < cToBeSigned; ++i)
            {
                ret = CryptMsgUpdate(msg, rgpbToBeSigned[i], rgcbToBeSigned[i],
                 i == cToBeSigned - 1);
            }
        }
        else
            ret = CryptMsgUpdate(msg, NULL, 0, TRUE);
        if (ret)
            ret = CryptMsgGetParam(msg, CMSG_CONTENT_PARAM, 0, pbSignedBlob,
             pcbSignedBlob);
        CryptMsgClose(msg);
    }
    else
        ret = FALSE;

    CryptMemFree(crlBlob);
    CryptMemFree(certBlob);
    if (freeProv)
        CryptReleaseContext(hCryptProv, 0);
    return ret;
}