示例#1
0
int main(int argc, char * argv[]) 
{
	HCRYPTPROV hCryptProv; 
	HCRYPTKEY hKey;

	if (CryptAcquireContext(&hCryptProv, CONTAINER_NAME, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
		printf("Created a new key container and acquired context \n");
	} else if (CryptAcquireContext(&hCryptProv, CONTAINER_NAME, MS_DEF_PROV, PROV_RSA_FULL, 0)) {
		printf("Acquired context \n");
	} else {
		return error("acquiring context");
	}

	if (CryptGenKey(hCryptProv, AT_KEYEXCHANGE, 0, &hKey)) {
		printf("Generated key for exchange \n");
	} else {
		return error("generating exchange key");
	}

	if (CryptGenKey(hCryptProv, AT_SIGNATURE, 0, &hKey)) {
		printf("Generated key for signing \n");
	} else {
		return error("generating signing key");
	}

	if (CryptReleaseContext(hCryptProv, 0)) {
		printf("Done.");
	} else {
		return error("releasing context");
	}
}
String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url)
{
    String keyString;

    HCRYPTPROV hContext = 0;
    HCRYPTKEY hKey = 0;
    PCERT_PUBLIC_KEY_INFO pPubInfo = 0;

    // Try to delete it if it exists already
    CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);

    do {
        if (!CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            break;

        DWORD dwPubInfoLength = 0;
        if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength))
            break;

        // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types.
        pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength));

        if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength))
            break;

        CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 };
        requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1;
        requestInfo.pwszChallengeString = L"";
        requestInfo.SubjectPublicKeyInfo = *pPubInfo;

        String localChallenge = challenge;

        // Windows API won't write to our buffer, although it's not declared with const.
        requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallenge.charactersWithNullTermination());

        CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 };
        signAlgo.pszObjId = szOID_RSA_SHA1RSA;

        DWORD dwEncodedLength;
        if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength))
            break;

        Vector<char> binary(dwEncodedLength);
        if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength))
            break;

        keyString = base64Encode(binary);
    } while(0);

    if (pPubInfo)
        fastFree(pPubInfo);

    if (hKey)
        CryptDestroyKey(hKey);

    if (hContext)
        CryptReleaseContext(hContext, 0);

    return keyString;
}
示例#3
0
文件: widget.cpp 项目: Naxik/Lab2
void Widget::on_keyErr_clicked()
{
    DWORD keyBlobLen, blockLen = 0;
    BYTE *keyBlob, *srcData, *newData, *blockData1, *blockData2;
    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey, dhKey;
    QVector<int> values;
    QFile myFile(fName);

    plot->clear();
    if (myFile.exists())
        myFile.open(QIODevice::ReadOnly);
    else
    {
        QMessageBox::critical(0, "Ошибка", "Файл не выбран", QMessageBox::Ok);
        return;
    }
    CryptAcquireContext(&hCryptProv, NULL, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
    CryptGenKey(hCryptProv, CALG_AES_256, 0, &hKey);
    CryptEncrypt(hKey, 0, true, 0, NULL, &blockLen, myFile.size());
    srcData = new BYTE[block * blockLen];
    newData = new BYTE[block * blockLen];
    blockData1  = new BYTE[blockLen];
    blockData2  = new BYTE[blockLen];
    myFile.read((char*)srcData, block * blockLen);
    myFile.close();
    memcpy((char*)newData, (char*)srcData, block * blockLen);
    newData[0] = -newData[0];
    CryptDuplicateKey(hKey, NULL, 0, &dhKey);
    CryptExportKey(dhKey, 0, SIMPLEBLOB, 0, NULL, &keyBlobLen);
    keyBlob = new BYTE[keyBlobLen];
    CryptExportKey(dhKey, 0, SIMPLEBLOB, 0, keyBlob, &keyBlobLen);
    keyBlob[0] = -keyBlob[0];
    CryptImportKey(hCryptProv, keyBlob, keyBlobLen, 0, 0, &dhKey);
    for (uint i = 0; i < (block * blockLen); i++)
    {
        CryptEncrypt(hKey, 0, i < 2, 0, srcData + i, &blockLen, block * blockLen);
        CryptEncrypt(dhKey, 0, i < 2, 0, newData + i, &blockLen, block * blockLen);
    }
    for(uint i = 0; i < (block * blockLen); i += blockLen)
    {
        int k = 0;
        memcpy(blockData1, srcData + i, blockLen);
        memcpy(blockData2, newData + i, blockLen);
        for (uint j = i; j < (i + blockLen); j++)
            k += trueBitsCount(srcData[j] ^ newData[j]);
        values.push_back(k);
    }
    delete[] newData;
    delete[] srcData;
    delete[] blockData1;
    delete[] blockData2;
    delete[] keyBlob;
    CryptReleaseContext(hCryptProv, 0);
    CryptDestroyKey(hKey);
    CryptDestroyKey(dhKey);
    DrawPlot(plot, values);
    plot->show();
}
示例#4
0
SessionKey::SessionKey()
{
	// acquire cryptographic provider
	if (!CryptAcquireContextA(&m_provider.get_ref(), 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
		throw SystemError(GetLastError());
	// generate session key
	if (!CryptGenKey(m_provider.get(), CALG_RC2, 0, &m_key.get_ref()))
		throw SystemError(GetLastError());
}
示例#5
0
int main(int argc, char* argv[]) {
  HCRYPTPROV hProv;
  HCRYPTKEY hKey;

  if (argc != 2) {
    fprintf(stderr, "Usage: CryptTest <data>\n");
    exit(1);
  }

  char* plaintext = argv[1];

  if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_FULL,
                            CRYPT_VERIFYCONTEXT)) {
    PrintError("CryptAcquireContext");
  }

  while (1) {
    puts("Generating key...");

    if (!CryptGenKey(hProv, CALG_RC2, 0x800000, &hKey)) {
      PrintError("CryptGenKey");
    }

    puts("New key generated...");

    DWORD plaintextSize = strlen(plaintext);
    DWORD cipherSize = plaintextSize;
    if (!CryptEncrypt(hKey, 0, 1, 0, 0, &cipherSize, 0)) {
      PrintError("CryptEncrypt[0]");
    }

    BYTE* data = (BYTE*)malloc(cipherSize);
    strncpy_s(data, cipherSize, plaintext, plaintextSize);
    if (!CryptEncrypt(hKey, 0, 1, 0, data, &plaintextSize, cipherSize)) {
      PrintError("CryptEncrypt[0]");
    }

    puts("Encrypted data:");
    PrintHex(data, cipherSize);
    puts("\n\n");

    if (!CryptDestroyKey(hKey)) {
      PrintError("CryptDestroyKey");
    }

    Sleep(5000);
  }

  if (!CryptReleaseContext(hProv, 0)) {
    PrintError("CryptReleaseContext");
  }
  getchar();
  return 0;
}
示例#6
0
BOOL CreateKeyset(HCRYPTPROV *hProv) {
	HCRYPTKEY hXchgKey;
	LONG error;
	if(!CryptAcquireContext(hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
		return FALSE;

    if(!CryptGenKey(*hProv,AT_SIGNATURE,0,&hXchgKey))  {
		error=GetLastError();
		CryptReleaseContext(*hProv, 0);
		SetLastError(error);
		return FALSE;
	}
    CryptDestroyKey(hXchgKey);
    
	if(!CryptGenKey(*hProv,AT_KEYEXCHANGE,CRYPT_EXPORTABLE,&hXchgKey)) {
		error=GetLastError();
		CryptReleaseContext(*hProv, 0);
		SetLastError(error);
		return FALSE;
	}
	CryptDestroyKey(hXchgKey);
	return TRUE;
}
示例#7
0
文件: widget.cpp 项目: Naxik/Lab2
void Widget::on_srcTextErr_clicked()
{
    DWORD blockLen = 32; // Хотя должно быть 16ж
    DWORD dataSize;
    HCRYPTPROV hCryptProv;
    HCRYPTKEY hKey;
    uchar srcData[blockLen];
    uchar newData[blockLen];
    QVector<int> values;
    QFile myFile(fName);

    plot->clear();
    if (myFile.exists())
        myFile.open(QIODevice::ReadOnly);
    else
    {
        QMessageBox::critical(0, "Ошибка", "Файл не выбран", QMessageBox::Ok);
        return;
    }
    CryptAcquireContext(&hCryptProv, NULL, MS_DEF_RSA_SCHANNEL_PROV, PROV_RSA_SCHANNEL, CRYPT_VERIFYCONTEXT);
    CryptGenKey(hCryptProv, CALG_AES_256, 0, &hKey);
    //CryptEncrypt(hKey, 0, true, 0, NULL, &blockLen, myFile.size());
    //srcData = new uchar[blockLen];
    //newData = new uchar[blockLen];
    dataSize = myFile.read((char *)(&srcData[0]), blockLen);
    memcpy(&newData[0], &srcData[0], blockLen);
    newData[0] = -newData[0];
    for (uint i = 0; i < block; i++)
    {
        int k = 0;
        CryptEncrypt(hKey, 0, i < 2, 0, &srcData[0], &dataSize, block*blockLen);
        CryptEncrypt(hKey, 0, i < 2, 0, &newData[0], &dataSize, block*blockLen);
        for (uint j = 0; j < blockLen; j++)
            k += trueBitsCount((uint)(srcData[j] ^ newData[j]));
        values.push_back(k);
        memset(&srcData[0], 0, blockLen);
        dataSize = myFile.read((char *)(&srcData[0]), blockLen);
        memcpy(&newData[0], &srcData[0], blockLen);
    }
    myFile.close();
    CryptReleaseContext(hCryptProv, 0);
    CryptDestroyKey(hKey);
    //delete[] srcData;
    //srcData = 0;
    //delete[] newData;
    //newData = 0;
    DrawPlot(plot, values);
    plot->show();
}
示例#8
0
bool Crypt::GeneratePrivateKey()
{
	// Acquire a provider handle for party 1.
	BOOL fReturn = CryptAcquireContext( &m_ProvParty, NULL, MS_ENH_DSS_DH_PROV, PROV_DSS_DH, CRYPT_VERIFYCONTEXT );
	if ( !fReturn )
	{
		ReleaseResources();
		return false;
	}

	// Create an ephemeral private key for party 1.
	// 임시 비밀 키 생성 
	fReturn = CryptGenKey( m_ProvParty, CALG_DH_EPHEM, DHKEYSIZE << 16 | CRYPT_EXPORTABLE | CRYPT_PREGEN, &m_PrivateKey );
	if ( !fReturn )
	{
		ReleaseResources();
		return false;
	}

	// Set the prime for party 1's private key.
	// P값 설정 
	fReturn = CryptSetKeyParam( m_PrivateKey, KP_P, (PBYTE)&m_P, 0 );
	if ( !fReturn )
	{
		ReleaseResources();
		return false;
	}

	// Set the generator for party 1's private key.
	// 비밀 키 생성기 장착
	fReturn = CryptSetKeyParam( m_PrivateKey, KP_G, (PBYTE)&m_G, 0 );
	if ( !fReturn )
	{
		ReleaseResources();
		return false;
	}

	// Generate the secret values for party 1's private key.
	// 비밀 키 생성 
	fReturn = CryptSetKeyParam( m_PrivateKey, KP_X, NULL, 0 );
	if ( !fReturn )
	{
		ReleaseResources();
		return false;
	}

	return true;
}
示例#9
0
文件: widget.cpp 项目: Naxik/Lab2
HCRYPTKEY GenKey(HCRYPTPROV hCrProv, QString keyText, QByteArray* key, DWORD& keyBlobLen, bool flag)
{
    HCRYPTKEY hKey = 0;
    HCRYPTHASH hHash = 0;
    if (flag)
    {
        CryptGenKey(hCrProv, CALG_AES_256, CRYPT_EXPORTABLE, &hKey);
    }
    else
    {
        CryptCreateHash(hCrProv, CALG_MD5, 0, 0, &hHash);
        CryptHashData(hHash, (BYTE *)keyText.toUtf8().constData(), keyText.length(), 0);
        CryptDeriveKey(hCrProv, CALG_AES_256, hHash, 0, &hKey);
    }
    CryptExportKey(hKey, 0, PLAINTEXTKEYBLOB, 0, NULL, &keyBlobLen);
    key->resize(keyBlobLen);
    CryptExportKey(hKey, 0, PLAINTEXTKEYBLOB, 0, (BYTE*)key->data(), &keyBlobLen);
    return hKey;
}
示例#10
0
/**
 * Generates an RSA private key with the given exponent and number of bits
 * and writes it into the specified key container
 */
RSA_key_t gen_RSA_key(int bits, int exponent, const char *container)
{
    int idx, found, flags;
    const char *_container;

    // First find available private key slot
    for (idx = 0, found = 0; (idx < MAXLIST) && (!found); idx++) {
        if (private_key_list[idx].provider == 0) {
            found = 1;
        }
    }
    if (!found) {
        log0(0, 0, 0, "Couldn't find empty key slot for private key");
        return 0;
    }
    idx--;

    if (!container || !strcmp(container, "")) {
        _container = NULL;
        flags = machine_keyset | CRYPT_VERIFYCONTEXT;
    } else {
        _container = container;
        flags = machine_keyset;
    }
    if (!CryptAcquireContext(&private_key_list[idx].provider, _container,
                             NULL, prov_type, flags)) {
        if (!CryptAcquireContext(&private_key_list[idx].provider, _container,
                    NULL, prov_type, CRYPT_NEWKEYSET | flags)) {
            mserror("CryptAcquireContext failed");
            return 0;
        }
    }

    if (!CryptGenKey(private_key_list[idx].provider, AT_KEYEXCHANGE,
                     ((bits ? bits : DEF_RSA_LEN) << 16) | CRYPT_EXPORTABLE,
                     &private_key_list[idx].key)) {
        mserror("CryptGenKey failed");
        return 0;
    }

    return private_key_list[idx].key;
}
// generate public/private key pair for digital signatures
void genkeys(void)
{
    if (open_crypt()) {
        if (CryptGenKey(hProv, AT_SIGNATURE,
                        keylen << 16 | CRYPT_EXPORTABLE, &hKey)) {
            // export as C array and binary
            export_key(PUBLICKEYBLOB,  DSA_PUBLIC_H,    DSA_C_ARRAY);
            export_key(PUBLICKEYBLOB,  DSA_PUBLIC_BIN,  DSA_BINARY);
            export_key(PRIVATEKEYBLOB, DSA_PRIVATE_H,   DSA_C_ARRAY);
            export_key(PRIVATEKEYBLOB, DSA_PRIVATE_BIN, DSA_BINARY);
            close_key();
        } else {
            xstrerror("CryptGenKey(%i)", keylen);
        }

        close_crypt();
    } else {
        xstrerror("CryptAcquireContext()");
    }
}
	inline cryptkey_ptr_t generate_cryptkey_ptr(HCRYPTPROV hProv, ALG_ID Algid, DWORD dwFlags)
	{
		HCRYPTKEY tmp;

		if( !CryptGenKey(hProv, Algid, dwFlags, &tmp ) )
		{
			DWORD const errc = GetLastError();
			STCRYPT_THROW_EXCEPTION( exception::cryptoapi_error() << exception::cryptoapi_einfo(errc) );
		}

		std::auto_ptr<HCRYPTKEY> HCRYPTKEY_mem;
		try {
			HCRYPTKEY_mem.reset(new HCRYPTKEY(tmp));
		}catch(...){
			BOOL const r = CryptDestroyKey(tmp); assert(r);
			throw;
		}

		return cryptkey_ptr_t  ( HCRYPTKEY_mem.release(), delete_HCRYPTKEY );
	}
示例#13
0
// http://code.google.com/p/drmemory/issues/detail?id=412
TEST(CryptoTests, CryptoBasic) {
    BOOL success;
    HCRYPTPROV provider;
    success = CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_AES, 0);
    // Ask for a new keyset if this one doesn't exist.
    if (!success && GetLastError() == NTE_BAD_KEYSET) {
        success = CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_AES,
                                      CRYPT_NEWKEYSET);
    }
    ASSERT_TRUE(success) << "CryptAcquireContext failed: " << GetLastError();

    HCRYPTKEY key;
    success = CryptGenKey(provider, CALG_AES_256, CRYPT_EXPORTABLE, &key);
    ASSERT_TRUE(success) << "CryptGenKey failed: " << GetLastError();

    // Get the key size.
    DWORD buffer_size = 0;
    success = CryptExportKey(key, 0, PLAINTEXTKEYBLOB, 0, NULL, &buffer_size);
    ASSERT_TRUE(success) << "CryptExportKey 1 failed: " << GetLastError();

    // Export the key.
    BYTE *buffer = new BYTE[buffer_size];
    success = CryptExportKey(key, 0, PLAINTEXTKEYBLOB, 0, buffer, &buffer_size);
    ASSERT_TRUE(success) << "CryptExportKey 2 failed: " << GetLastError();

    plaintext_blob_t *blob = (plaintext_blob_t*)buffer;
    ASSERT_EQ(buffer_size - offsetof(plaintext_blob_t, rgbKeyData), blob->cbKeySize);

    // Check that the rest of it is initialized.  Copy the buffer and compare it
    // against itself to trigger the uninit checks.
    BYTE *key_copy = new BYTE[blob->cbKeySize];
    memcpy(key_copy, blob->rgbKeyData, blob->cbKeySize);
    ASSERT_EQ(0, memcmp(blob->rgbKeyData, key_copy, blob->cbKeySize));
    delete [] key_copy;

    delete [] buffer;
    CryptDestroyKey(key);
    CryptReleaseContext(provider, 0);
}
示例#14
0
 BOOL CreateExchangeKeyPair(HCRYPTPROV hProv, HCRYPTKEY* phKey)
 {
     HCRYPTKEY hKey = NULL;
     BOOL bResult = FALSE;
     ;
     bResult = CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey);
     if(!bResult)
         goto onCleanup;
     ;
     if(phKey)
     {
         *phKey = hKey;
         hKey = NULL;
     };
     ;
 onCleanup:
     DWORD dwError = bResult ? 0 : GetLastError();
     if(hKey)
         CryptDestroyKey(hKey);
     SetLastError(dwError);
     return bResult;
 };
示例#15
0
/**
 *
 * generate new key pair of keyLen-bits
 *
 */
int rsa_genkey(RSA* rsa, int keyLen)
{
    BOOL ok = FALSE;

    if (rsa == NULL) return 0;

    // release public
    if (rsa->pubkey != 0) {
        CryptDestroyKey(rsa->pubkey);
        rsa->pubkey = 0;
    }

    // release private
    if (rsa->privkey != 0) {
        CryptDestroyKey(rsa->privkey);
        rsa->privkey = 0;
    }

    // generate key pair for signing
    ok = CryptGenKey(rsa->prov, AT_KEYEXCHANGE,
                     (keyLen << 16) | CRYPT_EXPORTABLE,
                     &rsa->privkey);
    return ok;
}
示例#16
0
文件: symkeys.c 项目: esproul/xmlsec
BOOL
xmlSecMSCryptoImportPlainSessionBlob(HCRYPTPROV hProv, HCRYPTKEY hPrivateKey,
                                     ALG_ID dwAlgId, LPBYTE pbKeyMaterial,
                                     DWORD dwKeyMaterial, BOOL bCheckKeyLength,
                                     HCRYPTKEY *hSessionKey) {
    ALG_ID dwPrivKeyAlg;
    LPBYTE keyBlob = NULL;
    DWORD keyBlobLen, rndBlobSize, dwSize, n;
    PUBLICKEYSTRUC* pubKeyStruc;
    ALG_ID* algId;
    DWORD dwPublicKeySize;
    DWORD dwProvSessionKeySize = 0;
    LPBYTE pbPtr;
    DWORD dwFlags;
    PROV_ENUMALGS_EX ProvEnum;
    HCRYPTKEY hTempKey = 0;
    BOOL fFound;
    BOOL res = FALSE;

    xmlSecAssert2(hProv != 0, FALSE);
    xmlSecAssert2(hPrivateKey != 0, FALSE);
    xmlSecAssert2(pbKeyMaterial != NULL, FALSE);
    xmlSecAssert2(dwKeyMaterial > 0, FALSE);
    xmlSecAssert2(hSessionKey != NULL, FALSE);

    /*  Double check to see if this provider supports this algorithm and key size */
    fFound = FALSE;
    dwFlags = CRYPT_FIRST;
    dwSize = sizeof(ProvEnum);
    while(CryptGetProvParam(hProv, PP_ENUMALGS_EX, (LPBYTE)&ProvEnum, &dwSize, dwFlags)) {
        if (ProvEnum.aiAlgid == dwAlgId) {
            fFound = TRUE;
            break;
        }
        dwSize = sizeof(ProvEnum);
        dwFlags = 0;
    }
    if(!fFound) {
        xmlSecMSCryptoError2("CryptGetProvParam", NULL,
                             "algId=%ld is not supported",
                             (long int)dwAlgId);
        goto done;
    }

    if(bCheckKeyLength) {
        /* We have to get the key size(including padding) from an HCRYPTKEY handle.
         * PP_ENUMALGS_EX contains the key size without the padding so we can't use it.
         */
        if(!CryptGenKey(hProv, dwAlgId, 0, &hTempKey)) {
            xmlSecMSCryptoError2("CryptGenKey", NULL,
                                 "algId=%ld",
                                 (long int)dwAlgId);
            goto done;
        }

        dwSize = sizeof(DWORD);
        if(!CryptGetKeyParam(hTempKey, KP_KEYLEN, (LPBYTE)&dwProvSessionKeySize, &dwSize, 0)) {
            xmlSecMSCryptoError2("CryptGetKeyParam(KP_KEYLEN)", NULL,
                                 "algId=%ld", (long int)dwAlgId);
            goto done;
        }
        CryptDestroyKey(hTempKey);
        hTempKey = 0;

        /* yell if key is too big */
        if ((dwKeyMaterial * 8) > dwProvSessionKeySize) {
            xmlSecInvalidSizeMoreThanError("Key value (bits)",
                                           (dwKeyMaterial * 8), dwProvSessionKeySize,
                                           NULL);
            goto done;
        }
    } else {
        dwProvSessionKeySize = dwKeyMaterial * 8;
    }

    /* Get private key's algorithm */
    dwSize = sizeof(ALG_ID);
    if(!CryptGetKeyParam(hPrivateKey, KP_ALGID, (LPBYTE)&dwPrivKeyAlg, &dwSize, 0)) {
        xmlSecMSCryptoError2("CryptGetKeyParam(KP_ALGID)", NULL,
                             "algId=%ld",
                             (long int)dwAlgId);
        goto done;
    }

    /* Get private key's length in bits */
    dwSize = sizeof(DWORD);
    if(!CryptGetKeyParam(hPrivateKey, KP_KEYLEN, (LPBYTE)&dwPublicKeySize, &dwSize, 0)) {
        xmlSecMSCryptoError2("CryptGetKeyParam(KP_KEYLEN)", NULL,
                             "algId=%ld",
                             (long int)dwAlgId);
        goto done;
    }

    /* 3 is for the first reserved byte after the key material and the 2 reserved bytes at the end. */
    if(dwPublicKeySize / 8 < dwKeyMaterial + 3) {
        xmlSecInvalidSizeLessThanError("Key value", dwPublicKeySize / 8, dwKeyMaterial + 3, NULL);
        goto done;
    }
    rndBlobSize = dwPublicKeySize / 8 - (dwKeyMaterial + 3);

    /* Simple key BLOBs, type SIMPLEBLOB, are used to store and transport session keys outside a CSP.
     * Base provider simple-key BLOBs are always encrypted with a key exchange public key. The pbData
     * member of the SIMPLEBLOB is a sequence of bytes in the following format:
     *
     * PUBLICKEYSTRUC  publickeystruc ;
     * ALG_ID algid;
     * BYTE encryptedkey[rsapubkey.bitlen/8];
     */

    /* calculate Simple blob's length */
    keyBlobLen = sizeof(PUBLICKEYSTRUC) + sizeof(ALG_ID) + (dwPublicKeySize / 8);

    /* allocate simple blob buffer */
    keyBlob = (LPBYTE)xmlMalloc(sizeof(BYTE) * keyBlobLen);
    if(keyBlob == NULL) {
        xmlSecMallocError(sizeof(BYTE) * keyBlobLen, NULL);
        goto done;
    }
    memset(keyBlob, 0, keyBlobLen);

    /* initialize PUBLICKEYSTRUC */
    pubKeyStruc             = (PUBLICKEYSTRUC*)(keyBlob);
    pubKeyStruc->bType      = SIMPLEBLOB;
    pubKeyStruc->bVersion   = 0x02;
    pubKeyStruc->reserved   = 0;
    pubKeyStruc->aiKeyAlg   = dwAlgId;

    /* Copy private key algorithm to buffer */
    algId                   = (ALG_ID*)(keyBlob + sizeof(PUBLICKEYSTRUC));
    (*algId)                = dwPrivKeyAlg;

    /* Place the key material in reverse order */
    pbPtr                   = (BYTE*)(keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(ALG_ID));
    for (n = 0; n < dwKeyMaterial; n++) {
        pbPtr[n] = pbKeyMaterial[dwKeyMaterial - n - 1];
    }
    pbPtr += dwKeyMaterial;

    /* skip reserved byte */
    pbPtr += 1;

    /* Generate random data for the rest of the buffer */
    if((rndBlobSize > 0) && !CryptGenRandom(hProv, rndBlobSize, pbPtr)) {
        xmlSecMSCryptoError2("CryptGenRandom", NULL,
                             "rndBlobSize=%ld",
                             (long int)rndBlobSize);
        goto done;
    }
    /* aleksey: why are we doing this? */
    for (n = 0; n < rndBlobSize; n++) {
        if (pbPtr[n] == 0) pbPtr[n] = 1;
    }

    /* set magic number at the end */
    keyBlob[keyBlobLen - 2] = 2;

    if(!CryptImportKey(hProv, keyBlob , keyBlobLen, hPrivateKey, CRYPT_EXPORTABLE, hSessionKey)) {
        xmlSecMSCryptoError2("CryptImportKey", NULL,
                             "algId=%ld",
                             (long int)dwAlgId);
        goto done;
    }

    /* success */
    res = TRUE;

done:
    if(hTempKey != 0) {
        CryptDestroyKey(hTempKey);
    }
    if(keyBlob != NULL) {
        xmlFree(keyBlob);
    }
    return(res);
}
示例#17
0
BOOL CCrypto::Initialize(CHAR* szKeyFile)
{			
	DWORD	dwResult;
	errno_t err;
	FILE* fp;

	m_cbBlob = file_length(szKeyFile);
	m_pbBlob = (BYTE*)malloc(m_cbBlob + 1);
	memset(m_pbBlob, 0, m_cbBlob + 1); 

	err = fopen_s(&fp, szKeyFile, "rb");
	if (err == 0) 
	{
		fread(m_pbBlob, 1, m_cbBlob, fp);
		fclose(fp);
	} 
	else 
	{
		free(m_pbBlob);
		m_pbBlob = NULL;
	}

	if (!CryptAcquireContext(&m_hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
	{
		dwResult = GetLastError();
		if (dwResult == NTE_BAD_KEYSET)
		{
			if (!CryptAcquireContext(&m_hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
			{
				dwResult = GetLastError();
				//MessageBox(_T("Error [0x%x]: CryptAcquireContext() failed."), _T("Information"), MB_OK);
				return FALSE;
			}
		} else {
			dwResult = GetLastError();
			return FALSE;
		}
	}

	if (m_pbBlob)
	{
		if (!CryptImportKey(m_hProv, m_pbBlob, m_cbBlob, 0, 0, &m_hSessionKey))
		{
			dwResult = GetLastError();
			//MessageBox(_T("Error [0x%x]: CryptImportKey() failed."), "Information", MB_OK);
			return FALSE;
		}
	} 
	else 
	{ 
		if (!CryptImportKey(m_hProv, PrivateKeyWithExponentOfOne, sizeof(PrivateKeyWithExponentOfOne), 0, 0, &m_hKey))
		{
			dwResult = GetLastError();
			//MessageBox(_T("Error CryptImportKey() failed."), _T("Information"), MB_OK);
			return FALSE;
		}

		if (!CryptGenKey(m_hProv, CALG_RC4, CRYPT_EXPORTABLE, &m_hSessionKey))
		{
			dwResult = GetLastError();
			//MessageBox(_T("Error CryptGenKey() failed."), _T("Information"), MB_OK);
			return FALSE;
		}	
	}

	return TRUE;
}
示例#18
0
void CKeyPair::GenerateKey() 
{
	// Generate a key pair
	HCRYPTPROV hCryptProv = m_pContext->GetProvider();
	CryptGenKey(hCryptProv, AT_SIGNATURE, (ms_dwRSAKeySize << 16) | CRYPT_EXPORTABLE, &m_hCryptKey);
}
示例#19
0
/*
 * '_sspiGetCredentials()' - Retrieve an SSL/TLS certificate from the system store
 *                              If one cannot be found, one is created.
 */
BOOL					/* O - 1 on success, 0 on failure */
_sspiGetCredentials(_sspi_struct_t *conn,
					/* I - Client connection */
                    const LPWSTR   container,
					/* I - Cert container name */
                    const TCHAR    *cn,	/* I - Common name of certificate */
                    BOOL           isServer)
					/* I - Is caller a server? */
{
  HCERTSTORE		store = NULL;	/* Certificate store */
  PCCERT_CONTEXT	storedContext = NULL;
					/* Context created from the store */
  PCCERT_CONTEXT	createdContext = NULL;
					/* Context created by us */
  DWORD			dwSize = 0;	/* 32 bit size */
  PBYTE			p = NULL;	/* Temporary storage */
  HCRYPTPROV		hProv = (HCRYPTPROV) NULL;
					/* Handle to a CSP */
  CERT_NAME_BLOB	sib;		/* Arbitrary array of bytes */
  SCHANNEL_CRED		SchannelCred;	/* Schannel credential data */
  TimeStamp		tsExpiry;	/* Time stamp */
  SECURITY_STATUS	Status;		/* Status */
  HCRYPTKEY		hKey = (HCRYPTKEY) NULL;
					/* Handle to crypto key */
  CRYPT_KEY_PROV_INFO	kpi;		/* Key container info */
  SYSTEMTIME		et;		/* System time */
  CERT_EXTENSIONS	exts;		/* Array of cert extensions */
  CRYPT_KEY_PROV_INFO	ckp;		/* Handle to crypto key */
  BOOL			ok = TRUE;	/* Return value */


  DEBUG_printf(("_sspiGetCredentials(conn=%p, container=%p, cn=\"%s\", isServer=%d)", conn, container, cn, isServer));

  if (!conn)
    return (FALSE);
  if (!cn)
    return (FALSE);

  if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W,
                           PROV_RSA_FULL,
                           CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
  {
    if (GetLastError() == NTE_EXISTS)
    {
      if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W,
                               PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
      {
        DEBUG_printf(("_sspiGetCredentials: CryptAcquireContext failed: %x\n",
                      GetLastError()));
        ok = FALSE;
        goto cleanup;
      }
    }
  }

  store = CertOpenStore(CERT_STORE_PROV_SYSTEM,
                        X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                        hProv,
                        CERT_SYSTEM_STORE_LOCAL_MACHINE |
                        CERT_STORE_NO_CRYPT_RELEASE_FLAG |
                        CERT_STORE_OPEN_EXISTING_FLAG,
                        L"MY");

  if (!store)
  {
    DEBUG_printf(("_sspiGetCredentials: CertOpenSystemStore failed: %x\n",
                  GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  dwSize = 0;

  if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR,
                     NULL, NULL, &dwSize, NULL))
  {
    DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x\n",
                   GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  p = (PBYTE) malloc(dwSize);

  if (!p)
  {
    DEBUG_printf(("_sspiGetCredentials: malloc failed for %d bytes", dwSize));
    ok = FALSE;
    goto cleanup;
  }

  if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL,
                     p, &dwSize, NULL))
  {
    DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x",
                 GetLastError()));
    ok = FALSE;
    goto cleanup;
  }

  sib.cbData = dwSize;
  sib.pbData = p;

  storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                                             0, CERT_FIND_SUBJECT_NAME, &sib, NULL);

  if (!storedContext)
  {
   /*
    * If we couldn't find the context, then we'll
    * create a new one
    */
    if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
    {
      DEBUG_printf(("_sspiGetCredentials: CryptGenKey failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    ZeroMemory(&kpi, sizeof(kpi));
    kpi.pwszContainerName = (LPWSTR) container;
    kpi.pwszProvName = MS_DEF_PROV_W;
    kpi.dwProvType = PROV_RSA_FULL;
    kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
    kpi.dwKeySpec = AT_KEYEXCHANGE;

    GetSystemTime(&et);
    et.wYear += 10;

    ZeroMemory(&exts, sizeof(exts));

    createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL,
                                                   &et, &exts);

    if (!createdContext)
    {
      DEBUG_printf(("_sspiGetCredentials: CertCreateSelfSignCertificate failed: %x",
                   GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    if (!CertAddCertificateContextToStore(store, createdContext,
                                          CERT_STORE_ADD_REPLACE_EXISTING,
                                          &storedContext))
    {
      DEBUG_printf(("_sspiGetCredentials: CertAddCertificateContextToStore failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }

    ZeroMemory(&ckp, sizeof(ckp));
    ckp.pwszContainerName = (LPWSTR) container;
    ckp.pwszProvName = MS_DEF_PROV_W;
    ckp.dwProvType = PROV_RSA_FULL;
    ckp.dwFlags = CRYPT_MACHINE_KEYSET;
    ckp.dwKeySpec = AT_KEYEXCHANGE;

    if (!CertSetCertificateContextProperty(storedContext,
                                           CERT_KEY_PROV_INFO_PROP_ID,
                                           0, &ckp))
    {
      DEBUG_printf(("_sspiGetCredentials: CertSetCertificateContextProperty failed: %x",
                    GetLastError()));
      ok = FALSE;
      goto cleanup;
    }
  }

  ZeroMemory(&SchannelCred, sizeof(SchannelCred));

  SchannelCred.dwVersion = SCHANNEL_CRED_VERSION;
  SchannelCred.cCreds = 1;
  SchannelCred.paCred = &storedContext;

 /*
  * SSPI doesn't seem to like it if grbitEnabledProtocols
  * is set for a client
  */
  if (isServer)
    SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1;

 /*
  * Create an SSPI credential.
  */
  Status = AcquireCredentialsHandle(NULL, UNISP_NAME,
                                    isServer ? SECPKG_CRED_INBOUND:SECPKG_CRED_OUTBOUND,
                                    NULL, &SchannelCred, NULL, NULL, &conn->creds,
                                    &tsExpiry);
  if (Status != SEC_E_OK)
  {
    DEBUG_printf(("_sspiGetCredentials: AcquireCredentialsHandle failed: %x", Status));
    ok = FALSE;
    goto cleanup;
  }

cleanup:

 /*
  * Cleanup
  */
  if (hKey)
    CryptDestroyKey(hKey);

  if (createdContext)
    CertFreeCertificateContext(createdContext);

  if (storedContext)
    CertFreeCertificateContext(storedContext);

  if (p)
    free(p);

  if (store)
    CertCloseStore(store, 0);

  if (hProv)
    CryptReleaseContext(hProv, 0);

  return (ok);
}
示例#20
0
 ::PCCERT_CONTEXT acquire ()
 {
     HRESULT hr = 0;
     HCRYPTPROV hProv = NULL;
     PCCERT_CONTEXT p = 0;
     HCRYPTKEY hKey = 0;
     CERT_NAME_BLOB sib = { 0 };
     BOOL AX = 0;
     
     try
     {
         char cb[1000] = {0};
         sib.pbData = (BYTE*)cb; 
         sib.cbData = 1000;
         wchar_t*    szSubject= L"CN=Certificate";
         if (!CertStrToNameW(CRYPT_ASN_ENCODING, szSubject,0,0,sib.pbData,&sib.cbData,NULL))
             throw;
         wchar_t* pszKeyContainerName = L"Container";
         if (!CryptAcquireContextW(&hProv,pszKeyContainerName,MS_DEF_PROV_W,PROV_RSA_FULL,CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
         {
             hr = GetLastError();
             if (GetLastError() == NTE_EXISTS)
             {
                 if (!CryptAcquireContextW(&hProv,pszKeyContainerName,MS_DEF_PROV_W,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET))
                 {
                     throw;
                 }
             }
             else
                 throw;
         }
         
         if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
             throw;
         
         CRYPT_KEY_PROV_INFO kpi = {0};
         kpi.pwszContainerName = pszKeyContainerName;
         kpi.pwszProvName = MS_DEF_PROV_W;
         kpi.dwProvType = PROV_RSA_FULL;
         kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
         kpi.dwKeySpec = AT_KEYEXCHANGE;
         
         SYSTEMTIME et;
         GetSystemTime(&et);
         et.wYear += 1;
         
         CERT_EXTENSIONS exts = {0};
         p = CertCreateSelfSignCertificate(hProv,&sib,0,&kpi,NULL,NULL,&et,&exts);
         AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL) ;
     }
     catch(...)
     {
     }
     
     // cleanup.
     if (hKey)
         CryptDestroyKey(hKey);
     hKey = 0;
     if (hProv)
         CryptReleaseContext(hProv,0);
     hProv = 0;
     // return certificate.
     return (p);
 }
void gen_aes256_key_iv()
{
    HCRYPTPROV provider = NULL;
    HCRYPTKEY hKey = NULL;
    HCRYPTKEY newHKey = NULL;
    DWORD ivLen, blockLen = 0;
    BYTE* iv = NULL;
    BYTE* buffer = NULL;
    char* cipherText = NULL;
    unsigned long cLen;
    char* cipherText2 = NULL;
    unsigned long cLen2;
    char* cipherText3 = NULL;
    unsigned long cLen3;
    char* cipherText4 = NULL;
    unsigned long cLen4;

    if (!OpenCryptContext(&provider)) {
        printf("CryptAcquireContext() failed:");
        goto Exit0;
    }

    // 生成随机密钥
    // 还可以从通过给定密码 HASH 后获取 AES 密钥
    if (!CryptGenKey(provider, CALG_AES_256, CRYPT_EXPORTABLE, &hKey)) {
        goto Exit0;
    }

    // Get the key size.
    DWORD buffer_size = 0;

    if (!CryptExportKey(hKey, 0, PLAINTEXTKEYBLOB, 0, NULL, &buffer_size)) {
        printf("CryptExportKey failed.\n");
        goto Exit0;
    }

    // Export the key.
    buffer = new BYTE[buffer_size];

    if (!CryptExportKey(hKey, 0, PLAINTEXTKEYBLOB, 0, buffer, &buffer_size)) {
        printf("CryptExportKey2 failed.\n");
        goto Exit0;
    }

    plaintext_blob_t* blob = (plaintext_blob_t*)buffer;
    printf("aes Key:\n");
    printf("\nchar aes256_key[]=\n{");
    print_bin2c(blob->rgbKeyData, blob->cbKeySize);
    printf("};");
    printf("\n\n");

    // base64 编码
    if (!Base64EncodeA(&cipherText, &cLen, blob->rgbKeyData, blob->cbKeySize))  {
        //xfree(encrypted);
        xstrerror("Base64EncodeA()");
        goto Exit0;
    }

    printf("aes base64 Key:\n");
    printf(cipherText);
    printf("\n\n");

    // Hex 编码
    if (!Bin2Hex(&cipherText3, &cLen3, blob->rgbKeyData, blob->cbKeySize)) {
        xstrerror("Bin2Hex()");
        goto Exit0;
    }

    printf("aes hex Key:\n");
    printf(cipherText3);
    printf("\n\n");

    // 从随机密钥获取 IV 长度
    if (!CryptGetKeyParam(hKey, KP_IV, NULL, &ivLen, 0)) {
        goto Exit0;
    }

    iv = new BYTE[ivLen];
    ZeroMemory(iv, ivLen);

    if (!CryptGenRandom(provider, ivLen, iv)) {
        goto Exit0;
    }

    printf("aes IV:\n");
    printf("\nchar aes256_iv[]=\n{");
    print_bin2c(iv, ivLen);
    printf("};");
    printf("\n\n");

    if (!Base64EncodeA(&cipherText2, &cLen2, iv, ivLen))    {
        xstrerror("Base64EncodeA()");
        goto Exit0;
    }

    printf("aes base64 iv:\n");
    printf(cipherText2);
    printf("\n\n");

    // Hex 编码
    if (!Bin2Hex(&cipherText4, &cLen4, iv, ivLen)) {
        xstrerror("Bin2Hex()");
        goto Exit0;
    }

    printf("aes hex iv:\n");
    printf(cipherText4);
    printf("\n\n");
    DWORD LenBlockAES = 0;
    DWORD dwCount = sizeof(DWORD);

    if (!CryptGetKeyParam(hKey, KP_BLOCKLEN, (BYTE*)&LenBlockAES, &dwCount, 0)) {
        goto Exit0;
    }

    printf("aes block data len: %d\n", LenBlockAES);
Exit0:

    if (cipherText4) {
        xfree(cipherText4);
        cipherText4 = NULL;
    }

    if (cipherText3) {
        xfree(cipherText3);
        cipherText3 = NULL;
    }

    if (cipherText2) {
        xfree(cipherText2);
        cipherText2 = NULL;
    }

    if (cipherText) {
        xfree(cipherText);
        cipherText = NULL;
    }

    if (buffer) {
        delete[] buffer;
        buffer = NULL;
    }

    if (iv) {
        delete[] iv;
        iv = NULL;
    }

    if (hKey) {
        CryptDestroyKey(hKey);
    }

    if (provider) {
        CryptReleaseContext(provider, 0);
    }

    return;
}
示例#22
0
PCCERT_CONTEXT SSL_SOCKET :: CreateOurCertificate()
	{
	// CertCreateSelfSignCertificate(0,&SubjectName,0,0,0,0,0,0);
	HRESULT hr = 0;
	HCRYPTPROV hProv = NULL;
	PCCERT_CONTEXT p = 0;
	HCRYPTKEY hKey = 0;
	CERT_NAME_BLOB sib = { 0 };
	BOOL AX = 0;

	// Step by step to create our own certificate
	try
		{
		// Create the subject
		char cb[1000] = {0};
		sib.pbData = (BYTE*)cb; 
		sib.cbData = 1000;
		wchar_t*	szSubject= L"CN=Certificate";
		if (!CertStrToName(CRYPT_ASN_ENCODING, szSubject,0,0,sib.pbData,&sib.cbData,NULL))
			throw;
	

		// Acquire Context
		wchar_t* pszKeyContainerName = L"Container";

		if (!CryptAcquireContext(&hProv,pszKeyContainerName,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET))
			{
			hr = GetLastError();
			if (GetLastError() == NTE_EXISTS)
				{
				if (!CryptAcquireContext(&hProv,pszKeyContainerName,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET))
					{
					throw;
					}
				}
			else
				throw;
			}

		// Generate KeyPair
		if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey))
			throw;

		// Generate the certificate
		CRYPT_KEY_PROV_INFO kpi = {0};
		kpi.pwszContainerName = pszKeyContainerName;
		kpi.pwszProvName = MS_DEF_PROV;
		kpi.dwProvType = PROV_RSA_FULL;
		kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID;
		kpi.dwKeySpec = AT_KEYEXCHANGE;

		SYSTEMTIME et;
		GetSystemTime(&et);
		et.wYear += 1;

		CERT_EXTENSIONS exts = {0};
		p = CertCreateSelfSignCertificate(hProv,&sib,0,&kpi,NULL,NULL,&et,&exts);

		AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL) ;
/*		hCS = CertOpenStore(CERT_STORE_PROV_MEMORY,0,0,CERT_STORE_CREATE_NEW_FLAG,0);
		AX = CertAddCertificateContextToStore(hCS,p,CERT_STORE_ADD_NEW,0);
		AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL);*/
		}
	
	catch(...)
		{
		}
	
	if (hKey)
		CryptDestroyKey(hKey);
	hKey = 0;
	
	if (hProv)
		CryptReleaseContext(hProv,0);
	hProv = 0;
	return p;
	}
BOOL EncryptDecryptFile(LPTSTR lpszCertificateName,
                        LPTSTR lpszCertificateStoreName,
                        DWORD  dwCertStoreOpenFlags,
                        LPTSTR lpszInputFileName,
                        LPTSTR lpszOutputFileName,
                        BOOL fEncrypt)
{
    BOOL fResult = FALSE;
    HCRYPTPROV hProv = NULL;
    HCRYPTKEY hRSAKey = NULL;
    HCRYPTKEY hSessionKey = NULL;
    HANDLE hInFile = INVALID_HANDLE_VALUE;
    HANDLE hOutFile = INVALID_HANDLE_VALUE;
    BOOL finished = FALSE;
    BYTE pbBuffer[OUT_BUFFER_SIZE];
    DWORD dwByteCount = 0;
    DWORD dwBytesRead = 0;
    DWORD dwBytesWritten = 0;
    LPBYTE pbSessionKeyBlob = NULL;
    DWORD dwSessionKeyBlob = 0;
    BOOL fCallerFreeProv = FALSE;
    PCCERT_CONTEXT pCertContext = NULL;
    BOOL fSuccess = FALSE;

    __try
    {
        pCertContext = GetCertificateContextFromName(lpszCertificateName,
                       lpszCertificateStoreName,
                       dwCertStoreOpenFlags);
        if (pCertContext == NULL)
        {
            __leave;
        }

        fResult = AcquireAndGetRSAKey(pCertContext,
                                      &hProv,
                                      &hRSAKey,
                                      fEncrypt,
                                      &fCallerFreeProv);
        if (fResult == FALSE)
        {
            __leave;
        }

        // Open the input file to be encrypted or decrypted
        hInFile = CreateFile(lpszInputFileName,
                             GENERIC_READ,
                             0,
                             NULL,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL);
        if (hInFile == INVALID_HANDLE_VALUE)
        {
            MyPrintf(_T("CreateFile failed with %d\n"), GetLastError());
            __leave;
        }

        // Open the output file to write the encrypted or decrypted data
        hOutFile = CreateFile(lpszOutputFileName,
                              GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL);
        if (hOutFile == INVALID_HANDLE_VALUE)
        {
            MyPrintf(_T("CreateFile failed with %d\n"), GetLastError());
            __leave;
        }

        if (fEncrypt)
        {
            fResult = CryptGenKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hSessionKey);
            if (!fResult)
            {
                MyPrintf(_T("CryptGenKey failed with %X\n"), GetLastError());
                __leave;
            }

            // The first call to ExportKey with NULL gets the key size.
            dwSessionKeyBlob = 0;
            fResult = CryptExportKey(hSessionKey, hRSAKey, SIMPLEBLOB, 0,
                                     NULL, &dwSessionKeyBlob);
            if (!fResult)
            {
                MyPrintf(_T("CryptExportKey failed with %X\n"), GetLastError());
                __leave;
            }

            // Allocate memory for Encrypted Session key blob
            pbSessionKeyBlob = (LPBYTE)LocalAlloc(LPTR, dwSessionKeyBlob);
            if (!pbSessionKeyBlob)
            {
                MyPrintf(_T("LocalAlloc failed with %d\n"), GetLastError());
                __leave;
            }

            fResult = CryptExportKey(hSessionKey, hRSAKey, SIMPLEBLOB, 0,
                                     pbSessionKeyBlob, &dwSessionKeyBlob);
            if (!fResult)
            {
                MyPrintf(_T("CryptExportKey failed with %X\n"), GetLastError());
                __leave;
            }

            // Write the size of key blob, then the key blob itself, to output file.
            fResult = WriteFile(hOutFile, &dwSessionKeyBlob,
                                sizeof(dwSessionKeyBlob),
                                &dwBytesWritten, NULL);
            if (!fResult)
            {
                MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
                __leave;
            }
            fResult = WriteFile(hOutFile, pbSessionKeyBlob,
                                dwSessionKeyBlob,
                                &dwBytesWritten, NULL);
            if (!fResult)
            {
                MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
                __leave;
            }
        }
        else
        {
            // Read in key block size, then key blob itself from input file.
            fResult = ReadFile(hInFile, &dwByteCount, sizeof(dwByteCount),
                               &dwBytesRead, NULL);
            if (!fResult)
            {
                MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
                __leave;
            }

            fResult = ReadFile(hInFile, pbBuffer, dwByteCount, &dwBytesRead, NULL);
            if (!fResult)
            {
                MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
                __leave;
            }

            // import key blob into "CSP"
            fResult = CryptImportKey(hProv, pbBuffer, dwByteCount, hRSAKey, 0, &hSessionKey);
            if (!fResult)
            {
                MyPrintf(_T("CryptImportKey failed with %X\n"), GetLastError());
                __leave;
            }
        }

        do
        {
            dwByteCount = 0;

            // Now read data from the input file 64K bytes at a time.
            fResult = ReadFile(hInFile, pbBuffer, IN_BUFFER_SIZE, &dwByteCount, NULL);

            // If the file size is exact multiple of 64K, dwByteCount will be zero after
            // all the data has been read from the input file. In this case, simply break
            // from the while loop. The check to do this is below
            if (dwByteCount == 0)
                break;

            if (!fResult)
            {
                MyPrintf(_T("ReadFile failed with %d\n"), GetLastError());
                __leave;
            }

            finished = (dwByteCount < IN_BUFFER_SIZE);

            // Encrypt/Decrypt depending on the required action.
            if (fEncrypt)
            {
                fResult = CryptEncrypt(hSessionKey, 0, finished, 0, pbBuffer, &dwByteCount,
                                       OUT_BUFFER_SIZE);
                if (!fResult)
                {
                    MyPrintf(_T("CryptEncrypt failed with %X\n"), GetLastError());
                    __leave;
                }
            }
            else
            {
                fResult = CryptDecrypt(hSessionKey, 0, finished, 0, pbBuffer, &dwByteCount);
                if (!fResult)
                {
                    MyPrintf(_T("CryptDecrypt failed with %X\n"), GetLastError());
                    __leave;
                }
            }

            // Write the encrypted/decrypted data to the output file.
            fResult = WriteFile(hOutFile, pbBuffer, dwByteCount,
                                &dwBytesWritten, NULL);
            if (!fResult)
            {
                MyPrintf(_T("WriteFile failed with %d\n"), GetLastError());
                __leave;
            }

        } while (!finished);

        if (fEncrypt)
            MyPrintf(_T("File %s is encrypted successfully!\n"), lpszInputFileName);
        else
            MyPrintf(_T("File %s is decrypted successfully!\n"), lpszInputFileName);

        fSuccess = TRUE;
    }
    __finally
    {
        /* Cleanup */
        CheckAndLocalFree(pbSessionKeyBlob);
        if (pCertContext != NULL) CertFreeCertificateContext(pCertContext);
        if (hRSAKey != NULL) CryptDestroyKey(hRSAKey);
        if (hSessionKey != NULL) CryptDestroyKey(hSessionKey);
        if (fCallerFreeProv && hProv != NULL) CryptReleaseContext(hProv, 0);
        if (hInFile != INVALID_HANDLE_VALUE) CloseHandle(hInFile);
        if (hOutFile != INVALID_HANDLE_VALUE) CloseHandle(hOutFile);
    }

    return fSuccess;
}
bool testCrypt(const unsigned uiVerboseLevel){
	HCRYPTKEY hKey = NULL;
	if ( !CryptGenKey( hProv,
		CALG_GOST_CRYPT,
		0,
		&hKey) )
	{
		if ( uiVerboseLevel > 0 )
			std::cout << "CryptGenKey failed" << std::endl;
		return false;
	}
	const DWORD cdwPlainTextLen = 70;
	const DWORD cdwBufLen = 170;
	DWORD dwDataLen = cdwPlainTextLen;
	BYTE *pbData = new BYTE[cdwBufLen];
	BYTE *pbDataCopy = new BYTE[dwDataLen];
	if ( !CryptGenRandom( hProv,
		dwDataLen, 
		pbData) )
	{

		if ( uiVerboseLevel > 0 )
			std::cout << "CryptGenRandom failed" << std::endl;
		return false;
	}
	memcpy( pbDataCopy, pbData, dwDataLen );

	if ( uiVerboseLevel > 1 ){
		print( std::cout, pbData, dwDataLen );
	}

	if ( !CryptEncrypt(
		hKey,
		0,
		TRUE,
		0,
		pbData,
		&dwDataLen,
		cdwBufLen))
	{
		if ( uiVerboseLevel > 0 )
			std::cout << "CryptEncrypt failed" << std::endl;
		return false;
	}

	if ( uiVerboseLevel > 1 ){
		print( std::cout, pbData, dwDataLen );
	}

	if ( !CryptDecrypt(
		hKey,
		0,
		TRUE,
		0,
		pbData,
		&dwDataLen))
	{
		if ( uiVerboseLevel > 0 )
			std::cout << "CryptDecrypt failed" << std::endl;
		return false;
	}

	if ( uiVerboseLevel > 1 ){
		print( std::cout, pbData, dwDataLen );
	}

	/*if ( dwDataLen != cdwPlainTextLen ){
		if ( uiVerboseLevel > 0 )
			std::cout << "Length of decrypted text is not equal length of plaintext" << std::endl;
		return false;
	}*/

	if ( memcmp( pbData, pbDataCopy, cdwPlainTextLen ) != 0 ){
		if ( uiVerboseLevel > 0 )
			std::cout << "Decrypted text and plaintext do not match" << std::endl;
		return false;
	}

	return true;
}	
示例#25
0
int _tmain(int argc, _TCHAR* argv[])
{
		// Handle for the cryptographic provider context.
		HCRYPTPROV hCryptProv;        

		// The name of the container.
		LPCTSTR pszContainerName = TEXT("My Sample Key Container");

		//---------------------------------------------------------------
		// Begin processing. Attempt to acquire a context by using the 
		// specified key container.
		if(CryptAcquireContext(
			&hCryptProv,
			pszContainerName,
			NULL,
			PROV_RSA_FULL,
			0))
		{
			_tprintf(
				TEXT("A crypto context with the %s key container ")
				TEXT("has been acquired.\n"), 
				pszContainerName);
		}
		else
		{ 
			//-----------------------------------------------------------
			// Some sort of error occurred in acquiring the context. 
			// This is most likely due to the specified container 
			// not existing. Create a new key container.
			if(GetLastError() == NTE_BAD_KEYSET)
			{
				if(CryptAcquireContext(
					&hCryptProv, 
					pszContainerName, 
					NULL, 
					PROV_RSA_FULL, 
					CRYPT_NEWKEYSET)) 
				{
					_tprintf(TEXT("A new key container has been ")
						TEXT("created.\n"));
				}
				else
				{
					MyHandleError(TEXT("Could not create a new key ")
						TEXT("container.\n"));
				}
			}
			else
			{
				MyHandleError(TEXT("CryptAcquireContext failed.\n"));
			}
		}

		//---------------------------------------------------------------
		// A context with a key container is available.
		// Attempt to get the handle to the signature key. 

		// Public/private key handle.
		HCRYPTKEY hKey;               

		if(CryptGetUserKey(
			hCryptProv,
			AT_SIGNATURE,
			&hKey))
		{
			_tprintf(TEXT("A signature key is available.\n"));
		}
		else
		{
			_tprintf(TEXT("No signature key is available.\n"));
			if(GetLastError() == NTE_NO_KEY) 
			{
				//-------------------------------------------------------
				// The error was that there is a container but no key.

				// Create a signature key pair. 
				_tprintf(TEXT("The signature key does not exist.\n"));
				_tprintf(TEXT("Create a signature key pair.\n")); 
				if(CryptGenKey(
					hCryptProv,
					AT_SIGNATURE,
					0,
					&hKey)) 
				{
					_tprintf(TEXT("Created a signature key pair.\n"));
				}
				else
				{
					MyHandleError(TEXT("Error occurred creating a ")
						TEXT("signature key.\n")); 
				}
			}
			else
			{
				MyHandleError(TEXT("An error other than NTE_NO_KEY ")
					TEXT("getting a signature key.\n"));
			}
		} // End if.

		_tprintf(TEXT("A signature key pair existed, or one was ")
			TEXT("created.\n\n"));

		// Destroy the signature key.
		if(hKey)
		{
			if(!(CryptDestroyKey(hKey)))
			{
				MyHandleError(TEXT("Error during CryptDestroyKey."));
			}

			hKey = NULL;
		} 

		// Next, check the exchange key. 
		if(CryptGetUserKey(
			hCryptProv,
			AT_KEYEXCHANGE,
			&hKey)) 
		{
			_tprintf(TEXT("An exchange key exists.\n"));
		}
		else
		{
			_tprintf(TEXT("No exchange key is available.\n"));

			// Check to determine whether an exchange key 
			// needs to be created.
			if(GetLastError() == NTE_NO_KEY) 
			{ 
				// Create a key exchange key pair.
				_tprintf(TEXT("The exchange key does not exist.\n"));
				_tprintf(TEXT("Attempting to create an exchange key ")
					TEXT("pair.\n"));
				if(CryptGenKey(
					hCryptProv,
					AT_KEYEXCHANGE,
					0,
					&hKey)) 
				{
					_tprintf(TEXT("Exchange key pair created.\n"));
				}
				else
				{
					MyHandleError(TEXT("Error occurred attempting to ")
						TEXT("create an exchange key.\n"));
				}
			}
			else
			{
				MyHandleError(TEXT("An error other than NTE_NO_KEY ")
					TEXT("occurred.\n"));
			}
		}

		// Destroy the exchange key.
		if(hKey)
		{
			if(!(CryptDestroyKey(hKey)))
			{
				MyHandleError(TEXT("Error during CryptDestroyKey."));
			}

			hKey = NULL;
		}

		// Release the CSP.
		if(hCryptProv)
		{
			if(!(CryptReleaseContext(hCryptProv, 0)))
			{
				MyHandleError(TEXT("Error during CryptReleaseContext."));
			}
		} 

		_tprintf(TEXT("Everything is okay. A signature key "));
		_tprintf(TEXT("pair and an exchange key exist in "));
		_tprintf(TEXT("the %s key container.\n"), pszContainerName);  
	
		getchar();
	return 0;
}
示例#26
0
 INT ProtectDataCAPI(const char* szKeyName, const void* pData, size_t nData, void** ppData, size_t* pnData)
 {
     USES_CONVERSION;
     ;
     HCRYPTPROV hProv=NULL;
     BOOL bResult = FALSE;
     ;
     HCRYPTKEY hExchangeKey = NULL;
     HCRYPTKEY hSessionKey = NULL;
     void*   pTempBuffer = NULL;
     DWORD   dwTempBuffer = 0;
     void*   pSessionKeyBlob = NULL;
     DWORD   dwSessionKeyBlob = 0;
     void*   pResultBuffer = NULL;
     size_t  nResultBuffer = 0;
     {
         if(!(bResult = CryptAcquireContext(
                                 &hProv,
                                 A2CT(szKeyName),
                                 MS_DEF_PROV,
                                 PROV_RSA_FULL,
                                 CRYPT_MACHINE_KEYSET)))
         {
             DWORD dwError = GetLastError();
             if(dwError == NTE_BAD_KEYSET || dwError == NTE_KEYSET_NOT_DEF)
             {
                 bResult = CreateContainer(A2CT(szKeyName), &hProv);
                 if(!bResult)
                     goto onCleanup;
             }
             else
                 goto onCleanup;
         };
         ;
         if(!(bResult = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hExchangeKey)))
         {
             DWORD dwError = GetLastError();
             if(dwError == NTE_NO_KEY)
             {
                 bResult = CreateExchangeKeyPair(hProv, &hExchangeKey);
                 if(!bResult)
                     goto onCleanup;
             }
             else
                 goto onCleanup;
         };
         ;   
         bResult = CryptGenKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hSessionKey);
         if(!bResult)
             goto onCleanup;
         ;
         //determining size of output buffer is redundant because RC4 is a stream cipher but as general it's required
         DWORD dwTempBufferSize = nData;
         bResult = CryptEncrypt(hSessionKey, NULL, TRUE, 0, NULL, &dwTempBufferSize, dwTempBufferSize);
         if(!bResult)
             goto onCleanup;
         pTempBuffer = malloc(dwTempBufferSize);
         dwTempBuffer = nData;
         memcpy(pTempBuffer, pData, nData);
         bResult = CryptEncrypt(hSessionKey, NULL, TRUE, 0, (PBYTE)pTempBuffer, &dwTempBuffer, dwTempBufferSize);
         if(!bResult)
             goto onCleanup;
         ;
         bResult = CryptExportKey(hSessionKey, hExchangeKey, SIMPLEBLOB, 0, NULL, &dwSessionKeyBlob);
         if(!bResult)
             goto onCleanup;
         pSessionKeyBlob = malloc(dwSessionKeyBlob);
         bResult = CryptExportKey(hSessionKey, hExchangeKey, SIMPLEBLOB, 0, (PBYTE)pSessionKeyBlob, &dwSessionKeyBlob);
         if(!bResult)
             goto onCleanup;
         ;
         nResultBuffer = dwTempBuffer + dwSessionKeyBlob + sizeof(dwSessionKeyBlob) + sizeof(dwTempBuffer);
         pResultBuffer = malloc(nResultBuffer);
         PBYTE p = (PBYTE)pResultBuffer;
         memcpy(p, &dwSessionKeyBlob, sizeof(dwSessionKeyBlob));
         p += sizeof(dwSessionKeyBlob);
         memcpy(p, pSessionKeyBlob, dwSessionKeyBlob);
         p += dwSessionKeyBlob;
         memcpy(p, &dwTempBuffer, sizeof(dwTempBuffer));
         p += sizeof(dwTempBuffer);
         memcpy(p, pTempBuffer, dwTempBuffer);
         p += dwTempBuffer;
         _ASSERTE(p  == nResultBuffer + PBYTE(pResultBuffer));
         *ppData = pResultBuffer;
         *pnData = nResultBuffer;
         pResultBuffer = NULL;
     };
 onCleanup:
     DWORD dwError = bResult ? 0 : GetLastError();
     if(hSessionKey)
         CryptDestroyKey(hSessionKey);
     if(hExchangeKey)
         CryptDestroyKey(hExchangeKey);
     if(hProv)
         CryptReleaseContext(hProv, 0);
     Free(pTempBuffer, dwTempBuffer);
     Free(pSessionKeyBlob, dwSessionKeyBlob);
     Free(pResultBuffer, nResultBuffer);
     return (int)dwError;
 };
示例#27
0
//-------------------------------------------------------------------
// Code for the function MyEncryptFile called by main.
//-------------------------------------------------------------------
// Parameters passed are:
//  pszSource, the name of the input, a plaintext file.
//  pszDestination, the name of the output, an encrypted file to be 
//   created.
//  pszPassword, either NULL if a password is not to be used or the 
//   string that is the password.
bool MyEncryptFile(
    LPTSTR pszSourceFile, 
    LPTSTR pszDestinationFile, 
    LPTSTR pszPassword)
{ 
    //---------------------------------------------------------------
    // Declare and initialize local variables.
    bool fReturn = false;
    HANDLE hSourceFile = INVALID_HANDLE_VALUE;
    HANDLE hDestinationFile = INVALID_HANDLE_VALUE; 

    HCRYPTPROV hCryptProv = NULL; 
    HCRYPTKEY hKey = NULL; 
    HCRYPTKEY hXchgKey = NULL; 
    HCRYPTHASH hHash = NULL; 

    PBYTE pbKeyBlob = NULL; 
    DWORD dwKeyBlobLen; 

    PBYTE pbBuffer = NULL; 
    DWORD dwBlockLen; 
    DWORD dwBufferLen; 
    DWORD dwCount; 
     
    //---------------------------------------------------------------
    // Open the source file. 
    hSourceFile = CreateFile(
        pszSourceFile, 
        FILE_READ_DATA,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(INVALID_HANDLE_VALUE != hSourceFile)
    {
        _tprintf(
            TEXT("The source plaintext file, %s, is open. \n"), 
            pszSourceFile);
    }
    else
    { 
        MyHandleError(
            TEXT("Error opening source plaintext file!\n"), 
            GetLastError());
        goto Exit_MyEncryptFile;
    } 

    //---------------------------------------------------------------
    // Open the destination file. 
    hDestinationFile = CreateFile(
        pszDestinationFile, 
        FILE_WRITE_DATA,
        FILE_SHARE_READ,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if(INVALID_HANDLE_VALUE != hDestinationFile)
    {
         _tprintf(
             TEXT("The destination file, %s, is open. \n"), 
             pszDestinationFile);
    }
    else
    {
        MyHandleError(
            TEXT("Error opening destination file!\n"), 
            GetLastError()); 
        goto Exit_MyEncryptFile;
    }

    //---------------------------------------------------------------
    // Get the handle to the default provider. 
    if(CryptAcquireContext(
        &hCryptProv, 
        NULL, 
        MS_ENH_RSA_AES_PROV, 
        PROV_RSA_AES, 
        0))
    {
        _tprintf(
            TEXT("A cryptographic provider has been acquired. \n"));
    }
    else
    {
        MyHandleError(
            TEXT("Error during CryptAcquireContext!\n"), 
            GetLastError());
        goto Exit_MyEncryptFile;
    }

    //---------------------------------------------------------------
    // Create the session key.
    if(!pszPassword || !pszPassword[0]) 
    { 
        //-----------------------------------------------------------
        // No password was passed.
        // Encrypt the file with a random session key, and write the 
        // key to a file. 

        //-----------------------------------------------------------
        // Create a random session key. 
        if(CryptGenKey(
            hCryptProv, 
            ENCRYPT_ALGORITHM, 
            KEYLENGTH | CRYPT_EXPORTABLE, 
            &hKey))
        {
            _tprintf(TEXT("A session key has been created. \n"));
        } 
        else
        {
            MyHandleError(
                TEXT("Error during CryptGenKey. \n"), 
                GetLastError()); 
            goto Exit_MyEncryptFile;
        }

        //-----------------------------------------------------------
        // Get the handle to the exchange public key. 
        if(CryptGetUserKey(
            hCryptProv, 
            AT_KEYEXCHANGE, 
            &hXchgKey))
        {
            _tprintf(
                TEXT("The user public key has been retrieved. \n"));
        }
        else
        { 
            if(NTE_NO_KEY == GetLastError())
            {
                // No exchange key exists. Try to create one.
                if(!CryptGenKey(
                    hCryptProv, 
                    AT_KEYEXCHANGE, 
                    CRYPT_EXPORTABLE, 
                    &hXchgKey))
                {
                    MyHandleError(
                        TEXT("Could not create a user public key.\n"), 
                        GetLastError()); 
                    goto Exit_MyEncryptFile;
                }
            }
            else
            {
                MyHandleError(
                    TEXT("User public key is not available and may ")
                        TEXT("not exist.\n"), 
                    GetLastError()); 
                goto Exit_MyEncryptFile;
            }
        }

        //-----------------------------------------------------------
        // Determine size of the key BLOB, and allocate memory. 
        if(CryptExportKey(
            hKey, 
            hXchgKey, 
            SIMPLEBLOB, 
            0, 
            NULL, 
            &dwKeyBlobLen))
        {
            _tprintf(
                TEXT("The key BLOB is %d bytes long. \n"), 
                dwKeyBlobLen);
        }
        else
        {  
            MyHandleError(
                TEXT("Error computing BLOB length! \n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        }

        if(pbKeyBlob = (BYTE *)malloc(dwKeyBlobLen))
        { 
            _tprintf(
                TEXT("Memory is allocated for the key BLOB. \n"));
        }
        else
        { 
            MyHandleError(TEXT("Out of memory. \n"), E_OUTOFMEMORY); 
            goto Exit_MyEncryptFile;
        }

        //-----------------------------------------------------------
        // Encrypt and export the session key into a simple key 
        // BLOB. 
        if(CryptExportKey(
            hKey, 
            hXchgKey, 
            SIMPLEBLOB, 
            0, 
            pbKeyBlob, 
            &dwKeyBlobLen))
        {
            _tprintf(TEXT("The key has been exported. \n"));
        } 
        else
        {
            MyHandleError(
                TEXT("Error during CryptExportKey!\n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        } 
         
        //-----------------------------------------------------------
        // Release the key exchange key handle. 
        if(hXchgKey)
        {
            if(!(CryptDestroyKey(hXchgKey)))
            {
                MyHandleError(
                    TEXT("Error during CryptDestroyKey.\n"), 
                    GetLastError()); 
                goto Exit_MyEncryptFile;
            }
      
            hXchgKey = 0;
        }
     
        //-----------------------------------------------------------
        // Write the size of the key BLOB to the destination file. 
        if(!WriteFile(
            hDestinationFile, 
            &dwKeyBlobLen, 
            sizeof(DWORD),
            &dwCount,
            NULL))
        { 
            MyHandleError(
                TEXT("Error writing header.\n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        }
        else
        {
            _tprintf(TEXT("A file header has been written. \n"));
        }

        //-----------------------------------------------------------
        // Write the key BLOB to the destination file. 
        if(!WriteFile(
            hDestinationFile, 
            pbKeyBlob, 
            dwKeyBlobLen,
            &dwCount,
            NULL))
        { 
            MyHandleError(
                TEXT("Error writing header.\n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        }
        else
        {
            _tprintf(
                TEXT("The key BLOB has been written to the ")
                    TEXT("file. \n"));
        }

        // Free memory.
        free(pbKeyBlob);
    } 
    else 
    { 

        //-----------------------------------------------------------
        // The file will be encrypted with a session key derived 
        // from a password.
        // The session key will be recreated when the file is 
        // decrypted only if the password used to create the key is 
        // available. 

        //-----------------------------------------------------------
        // Create a hash object. 
        if(CryptCreateHash(
            hCryptProv, 
            CALG_MD5, 
            0, 
            0, 
            &hHash))
        {
            _tprintf(TEXT("A hash object has been created. \n"));
        }
        else
        { 
            MyHandleError(
                TEXT("Error during CryptCreateHash!\n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        }  

        //-----------------------------------------------------------
        // Hash the password. 
        if(CryptHashData(
            hHash, 
            (BYTE *)pszPassword, 
            lstrlen(pszPassword), 
            0))
        {
            _tprintf(
                TEXT("The password has been added to the hash. \n"));
        }
        else
        {
            MyHandleError(
                TEXT("Error during CryptHashData. \n"), 
                GetLastError()); 
            goto Exit_MyEncryptFile;
        }

        //-----------------------------------------------------------
        // Derive a session key from the hash object. 
        if(CryptDeriveKey(
            hCryptProv, 
            ENCRYPT_ALGORITHM, 
            hHash, 
            KEYLENGTH, 
            &hKey))
        {
            _tprintf(
                TEXT("An encryption key is derived from the ")
                    TEXT("password hash. \n")); 
        }
        else
        {
            MyHandleError(
                TEXT("Error during CryptDeriveKey!\n"), 
                GetLastError()); 
            goto Exit_MyEncryptFile;
        }
    } 

    //---------------------------------------------------------------
    // The session key is now ready. If it is not a key derived from 
    // a  password, the session key encrypted with the private key 
    // has been written to the destination file.
     
    //---------------------------------------------------------------
    // Determine the number of bytes to encrypt at a time. 
    // This must be a multiple of ENCRYPT_BLOCK_SIZE.
    // ENCRYPT_BLOCK_SIZE is set by a #define statement.
    dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; 

    //---------------------------------------------------------------
    // Determine the block size. If a block cipher is used, 
    // it must have room for an extra block. 
    if(ENCRYPT_BLOCK_SIZE > 1) 
    {
        dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; 
    }
    else 
    {
        dwBufferLen = dwBlockLen; 
    }
        
    //---------------------------------------------------------------
    // Allocate memory. 
    if(pbBuffer = (BYTE *)malloc(dwBufferLen))
    {
        _tprintf(
            TEXT("Memory has been allocated for the buffer. \n"));
    }
    else
    { 
        MyHandleError(TEXT("Out of memory. \n"), E_OUTOFMEMORY); 
        goto Exit_MyEncryptFile;
    }

    //---------------------------------------------------------------
    // In a do loop, encrypt the source file, 
    // and write to the source file. 
    bool fEOF = FALSE;
    do 
    { 
        //-----------------------------------------------------------
        // Read up to dwBlockLen bytes from the source file. 
        if(!ReadFile(
            hSourceFile, 
            pbBuffer, 
            dwBlockLen, 
            &dwCount, 
            NULL))
        {
            MyHandleError(
                TEXT("Error reading plaintext!\n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        }

        if(dwCount < dwBlockLen)
        {
            fEOF = TRUE;
        }

        //-----------------------------------------------------------
        // Encrypt data. 
        if(!CryptEncrypt(
            hKey, 
            NULL, 
            fEOF,
            0, 
            pbBuffer, 
            &dwCount, 
            dwBufferLen))
        { 
            MyHandleError(
                TEXT("Error during CryptEncrypt. \n"), 
                GetLastError()); 
            goto Exit_MyEncryptFile;
        } 

        //-----------------------------------------------------------
        // Write the encrypted data to the destination file. 
        if(!WriteFile(
            hDestinationFile, 
            pbBuffer, 
            dwCount,
            &dwCount,
            NULL))
        { 
            MyHandleError(
                TEXT("Error writing ciphertext.\n"), 
                GetLastError());
            goto Exit_MyEncryptFile;
        }

        //-----------------------------------------------------------
        // End the do loop when the last block of the source file 
        // has been read, encrypted, and written to the destination 
        // file.
    } while(!fEOF);

    fReturn = true;

Exit_MyEncryptFile:
    //---------------------------------------------------------------
    // Close files.
    if(hSourceFile)
    {
        CloseHandle(hSourceFile);
    }

    if(hDestinationFile)
    {
        CloseHandle(hDestinationFile);
    }

    //---------------------------------------------------------------
    // Free memory. 
    if(pbBuffer) 
    {
        free(pbBuffer); 
    }
     

    //-----------------------------------------------------------
    // Release the hash object. 
    if(hHash) 
    {
        if(!(CryptDestroyHash(hHash)))
        {
            MyHandleError(
                TEXT("Error during CryptDestroyHash.\n"), 
                GetLastError()); 
        }

        hHash = NULL;
    }

    //---------------------------------------------------------------
    // Release the session key. 
    if(hKey)
    {
        if(!(CryptDestroyKey(hKey)))
        {
            MyHandleError(
                TEXT("Error during CryptDestroyKey!\n"), 
                GetLastError());
        }
    }

    //---------------------------------------------------------------
    // Release the provider handle. 
    if(hCryptProv)
    {
        if(!(CryptReleaseContext(hCryptProv, 0)))
        {
            MyHandleError(
                TEXT("Error during CryptReleaseContext!\n"), 
                GetLastError());
        }
    }
    
    return fReturn; 
} // End Encryptfile.
/****************************************************************************++

Routine Description:

    Creates a handle to the CSP

Arguments:

    pwzContainerName - name of the container to be created. if NULL, GUID is generated
                      for the name of the container

    fCreateNewKeys   - forces new keys to be created

    phCryptProv      - pointer to the location, where handle should be returned

Notes:

    -

Return Value:

    - S_OK

      - or -

    - CAPI error returned by CryptAcquireContextW

--*****************************************************************************/
HRESULT
CreateCryptProv(
    IN      PCWSTR          pwzContainerName,
    IN      BOOL            fCreateNewKeys,
    OUT     HCRYPTPROV*     phCryptProv)
{

    HRESULT         hr = S_OK;
    HCRYPTKEY       hKey = NULL;
    RPC_STATUS      status =  RPC_S_OK;
    BOOL            fCreatedContainer = FALSE;
    WCHAR*          pwzNewContainerName = NULL;

    *phCryptProv = NULL;

    if (NULL == pwzContainerName)
    {
         UUID    uuid;
         BOOL   fServiceAccount = FALSE;

        //
        // generate container name from the UUID
        //
        status = UuidCreate(&uuid);
        hr = HRESULT_FROM_RPCSTATUS(status);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        status = UuidToStringW(&uuid, (unsigned short**)&pwzNewContainerName);
        hr = HRESULT_FROM_RPCSTATUS(status);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        pwzContainerName = pwzNewContainerName;

        hr = IsServiceAccount(&fServiceAccount);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        //
        // open the clean key container
        //
        // note: CRYPT_NEW_KEYSET is not creating new keys, it just
        // creates new key container. duh.
        //
        if (!CryptAcquireContextW(phCryptProv,
                                pwzNewContainerName,
                                NULL,               // default provider name
                                DEFAULT_PROV_TYPE,
                                fServiceAccount ?
                                    (CRYPT_SILENT | CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET) :
                                    (CRYPT_SILENT | CRYPT_NEWKEYSET)))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());

            //
            // we are seeing that CryptAcquireContextW returns NTE_FAIL under low
            // memory condition, so we just mask the error
            //
            if (NTE_FAIL == hr)
            {
                hr = E_OUTOFMEMORY;
            }

            goto Cleanup;
        }

        fCreatedContainer = TRUE;

    }
    else
    {
        BOOL    fServiceAccount = FALSE;

        hr = IsServiceAccount(&fServiceAccount);
        if (FAILED(hr))
        {
            goto Cleanup;
        }

        //
        // open the provider first, create the keys too
        //
        if (!CryptAcquireContextW(phCryptProv,
                            pwzContainerName,
                            NULL,               // default provider name
                            DEFAULT_PROV_TYPE,
                            fServiceAccount ?
                                (CRYPT_SILENT | CRYPT_MACHINE_KEYSET) :
                                (CRYPT_SILENT)))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());

            //
            // we are seeing that CryptAcquireContextW returns NTE_FAIL under low
            // memory condition, so we just mask the error
            //
            if (NTE_FAIL == hr)
            {
                hr = E_OUTOFMEMORY;
            }

            goto Cleanup;
        }
    }

    if (fCreateNewKeys)
    {
        //
        // make sure keys exist
        //
        if (!CryptGetUserKey(*phCryptProv,
                            DEFAULT_KEY_SPEC,
                            &hKey))
        {
            hr = HRESULT_FROM_WIN32(GetLastError());

            // if key does not exist, create it
            if (HRESULT_FROM_WIN32((unsigned long)NTE_NO_KEY) == hr)
            {
                hr = S_OK;

                if (!CryptGenKey(*phCryptProv,
                                  DEFAULT_KEY_SPEC,
                                  CRYPT_EXPORTABLE,
                                  &hKey))
                {
                    hr = HRESULT_FROM_WIN32(GetLastError());

                    //
                    // we are seeing that CryptGenKey returns ERROR_CANTOPEN under low
                    // memory condition, so we just mask the error
                    //
                    if (HRESULT_FROM_WIN32(ERROR_CANTOPEN) == hr)
                    {
                        hr = E_OUTOFMEMORY;
                    }

                    goto Cleanup;
                }

            }
            else
            {
                // failed to get user key by some misterious reason, so bail out
                goto Cleanup;
            }
        }
    }

Cleanup:

    DestroyKey(hKey);

    if (FAILED(hr))
    {

        //
        // release the context
        //
        ReleaseCryptProv(*phCryptProv);
        *phCryptProv = NULL;

        //
        // delete the keys, if we created them
        //
        if (fCreatedContainer)
        {
            DeleteKeys(pwzContainerName);
        }
    }

    if (NULL != pwzNewContainerName)
    {
        // this always returns RPC_S_OK
        status = RpcStringFreeW((unsigned short**)&pwzNewContainerName);
        USES(status);
    }

    return hr;
}
示例#29
0
void _cdecl main(void)
{
    INT iReturn = 0;
    HCRYPTPROV hProv = 0;
    LPSTR pszContainerName = NULL;
    DWORD cbContainerName = 0;
    HCRYPTKEY hKey;

    // Attempt to acquire a handle to the default key container.
    if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) {
        
        if(GetLastError() != NTE_BAD_KEYSET) {
            // Some sort of error occured.
            printf("Error opening default key container!\n");
            goto Error;
        }
        
        // Create default key container.
        if(!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) {
            
            printf("Error creating default key container!\n");
            goto Error;
        }

        // Get size of the name of the default key container name.
        if(CryptGetProvParam(hProv, PP_CONTAINER, NULL, &cbContainerName, 0)) {
            
            // Allocate buffer to receive default key container name.
            pszContainerName = malloc(cbContainerName);

            if(pszContainerName) {
                // Get name of default key container name.
                if(!CryptGetProvParam(hProv, PP_CONTAINER, (PBYTE)pszContainerName, &cbContainerName, 0)) {
                    // Error getting default key container name.
                    pszContainerName[0] = 0;
                }
            }
        }

        printf("Create key container '%s'\n", pszContainerName ? pszContainerName : "");

        // Free container name buffer (if created)
        if(pszContainerName) {
            free(pszContainerName);
        }
    }

    // Attempt to get handle to signature key.
    if(!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) {
        
        if(GetLastError() != NTE_NO_KEY) {
            printf("Error %x during CryptGetUserKey!\n", GetLastError());
            goto Error;
        }

        // Create signature key pair.
        printf("Create signature key pair\n");

        if(!CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey)) {
            printf("Error %x during CryptGenKey!\n", GetLastError());
            goto Error;
        }
    }
    
    // Close key handle
    CryptDestroyKey(hKey);

    // Attempt to get handle to exchange key.
    if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hKey)) {

        if(GetLastError() != NTE_NO_KEY) {
            printf("Error %x during CryptGetUserKey!\n", GetLastError());
            goto Error;
        }

        // Create key exchange key pair.
        printf("Create key exchange key pair\n");

        if(!CryptGenKey(hProv, AT_KEYEXCHANGE, 0, &hKey)) {
            printf("Error %x during CryptGenKey!\n", GetLastError());
            goto Error;
        }
    }

    // Close key handle
    CryptDestroyKey(hKey);

    printf("OK\n");

Exit:

    // Close the context (if open)
    if(hProv) {
        CryptReleaseContext(hProv, 0);
    }

    exit(iReturn);

Error:

    iReturn = 1;
    goto Exit;
}
示例#30
0
BOOL SetupCryptoClient()
{
	// Ensure that the default cryptographic client is set up.
	HCRYPTPROV hProv;
	HCRYPTKEY hKey;
	int nError;
	
	// Attempt to acquire a handle to the default key container.
	//if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, 0))
	if (!CryptAcquireContext(&hProv, "MPICH", MS_DEF_PROV, PROV_RSA_FULL, 0))
	{
		// Some sort of error occured, create default key container.
		//if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
		if (!CryptAcquireContext(&hProv, "MPICH", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
		{
			// Error creating key container!
			nError = GetLastError();
			printf("SetupCryptoClient:CryptAcquireContext(...) failed, error: %d\n", nError);
			return FALSE;
		}
	}

	// Attempt to get handle to signature key.
	if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey))
	{
		if ((nError = GetLastError()) == NTE_NO_KEY)
		{
			// Create signature key pair.
			if (!CryptGenKey(hProv, AT_SIGNATURE, 0, &hKey))
			{
				// Error during CryptGenKey!
				nError = GetLastError();
				CryptReleaseContext(hProv, 0);
				printf("SetupCryptoClient:CryptGenKey(...) failed, error: %d\n", nError);
				return FALSE;
			}
			else
			{
				CryptDestroyKey(hKey);
			}
		}
		else 
		{
			// Error during CryptGetUserKey!
			CryptReleaseContext(hProv, 0);
			printf("SetupCryptoClient:CryptGetUserKey(...) failed, error: %d\n", nError);
			return FALSE;
		}
	}

	// Attempt to get handle to exchange key.
	if (!CryptGetUserKey(hProv,AT_KEYEXCHANGE,&hKey))
	{
		if ((nError = GetLastError()) == NTE_NO_KEY)
		{
			// Create key exchange key pair.
			if (!CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hKey))
			{
				// Error during CryptGenKey!
				nError = GetLastError();
				CryptReleaseContext(hProv, 0);
				printf("SetupCryptoClient:CryptGenKey(...) failed, error: %d\n", nError);
				return FALSE;
			}
			else
			{
				CryptDestroyKey(hKey);
			}
		}
		else
		{
			// Error during CryptGetUserKey!
			CryptReleaseContext(hProv, 0);
			printf("SetupCryptoClient:CryptGetUserKey(...) failed, error: %d\n", nError);
			return FALSE;
		}
	}

	CryptReleaseContext(hProv, 0);
	return TRUE;
}