/** * Loads an RSA private key from the specified key container */ RSA_key_t read_RSA_key(const char *container) { int idx, found; // 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 (!CryptAcquireContext(&private_key_list[idx].provider, container, NULL, prov_type, machine_keyset)) { mserror("CryptAcquireContext failed"); return 0; } if (!CryptGetUserKey(private_key_list[idx].provider, AT_KEYEXCHANGE, &private_key_list[idx].key)) { mserror("CryptGetUserKey failed"); return 0; } return private_key_list[idx].key; }
static CAPI_KEY *capi_get_key(CAPI_CTX *ctx, const char *contname, char *provname, DWORD ptype, DWORD keyspec) { CAPI_KEY *key; key = OPENSSL_malloc(sizeof(CAPI_KEY)); CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", contname, provname, ptype); if (!CryptAcquireContextA(&key->hprov, contname, provname, ptype, 0)) { CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); capi_addlasterror(); goto err; } if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) { CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR); capi_addlasterror(); CryptReleaseContext(key->hprov, 0); goto err; } key->keyspec = keyspec; key->pcert = NULL; return key; err: OPENSSL_free(key); return NULL; }
BOOL GetRSAKeyFromContainer(LPTSTR szContainerName, DWORD dwAcquireFlags, DWORD dwKeySpec, HCRYPTPROV *hProv, HCRYPTKEY *hPubKey) { BOOL fResult; BOOL fReturn = FALSE; __try { if (hProv == NULL || hPubKey == NULL) { __leave; } // acquire crypto context using container name fResult = CryptAcquireContext(hProv, szContainerName, MS_DEF_PROV, PROV_RSA_FULL, dwAcquireFlags); if (!fResult) { MyPrintf(_T("CryptAcquireContext failed with %x\n"), GetLastError()); __leave; } // Get the key handle for verification fResult = CryptGetUserKey(*hProv, dwKeySpec, hPubKey); if (!fResult) { MyPrintf(_T("CryptGetUserKey failed with %x\n"), GetLastError()); __leave; } fReturn = TRUE; } __finally { if (!fReturn) { if (*hPubKey != NULL) { CryptDestroyKey(*hPubKey); *hPubKey = NULL; } if (*hProv != NULL) { CryptReleaseContext(*hProv, 0); *hProv = NULL; } } } return fReturn; }
bool testVerifyHash(bool bVerbose){ BYTE bSignature[64]; strtobyte( "41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC049301456C64BA4642A1653C235A98A60249BCD6D3F746B631DF928014F6C5BF9C40" , bSignature ); DWORD dwSigLen = 64; HCRYPTHASH hHash; HCRYPTKEY hPub; BYTE bHashVal[32+1] = "\x2D\xFB\xC1\xB3\x72\xD8\x9A\x11\x88\xC0\x9C\x52\xE0\xEE\xC6\x1F\xCE\x52\x03\x2A\xB1\x02\x2E\x8E\x67\xEC\xE6\x67\x2B\x04\x3E\xE5"; if ( bVerbose ) std::cout << "Supplied hash value is: \n" << bHashVal << std::endl; if (!(CryptCreateHash(hProv, CALG_GOST_HASH, 0, 0, &hHash))) { if ( bVerbose ) printf("CryptCreateHash Failed\n"); return false; } if ( !CryptSetHashParam( hHash, HP_HASHVAL, bHashVal, 0)) { if ( bVerbose ) printf("CryptSetHashParam Failed\n"); return false; } if ( !CryptGetUserKey( hProv, AT_SIGNATURE, &hPub )) { if ( bVerbose ) printf("CryptGetUserKey Failed\n"); return false; } if (!CryptVerifySignature(hHash, bSignature, dwSigLen, hPub, NULL, 0)) { if ( bVerbose ) printf("Test Failed\n"); return false; } return true; }
int main(int argc, char *argv[]) { HANDLE signf = 0; HANDLE signmmf = 0; PBYTE signdata = NULL; LARGE_INTEGER signsz = {.QuadPart = 0}; void *keyblob = NULL; unsigned char err = 1; HCRYPTPROV prov; HCRYPTKEY key; HCRYPTHASH hash = 0; if (argc != 3) { fputs("Usage: lab2sign <input file> <output file>", stderr); return -1; } crash_if(!CryptAcquireContext(&prov, "lab2", MS_ENHANCED_PROV, PROV_RSA_FULL, 0), "Can't acquire crypt context."); hash = GetFileHash(prov, argv[1]); signf = CreateFileA(argv[2], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); signmmf = CreateFileMappingA(signf, NULL, PAGE_READONLY, 0, 0, NULL); crash_if(!signmmf, "Can't open memory mapped file."); GetFileSizeEx(signf, &signsz); signdata = MapViewOfFile(signmmf, FILE_MAP_READ, 0, 0, 0); crash_if(!signdata, "Can't map view of file."); crash_if(!CryptGetUserKey(prov, AT_SIGNATURE, &key), "Can't acquire signature key."); if (CryptVerifySignature(hash, signdata, signsz.LowPart, key, NULL, 0)) { printf("Signature matches.\n"); err = 0; } else { printf("Signature mismatch.\n"); } err: apply_not_null(signdata, UnmapViewOfFile); apply_not_null(signmmf, CloseHandle); apply_not_null(signf, CloseHandle); apply_not_null(keyblob, free); apply_not_null(hash, CryptDestroyHash) if (err) return -1; return 0; }
QByteArray QCSP::decrypt( const QByteArray &data ) { HCRYPTKEY key = 0; if( !CryptGetUserKey( d->h, AT_KEYEXCHANGE, &key ) ) return QByteArray(); QByteArray rev = reverse( data ); DWORD size = rev.size(); bool result = CryptDecrypt( key, 0, true, 0, LPBYTE(rev.data()), &size ); CryptDestroyKey( key ); return result ? rev : QByteArray(); }
QByteArray QCSP::decrypt( const QByteArray &data ) { HCRYPTKEY key = 0; if( !CryptGetUserKey( d->h, AT_KEYEXCHANGE, &key ) ) return QByteArray(); QByteArray reverse; for( QByteArray::const_iterator i = data.constEnd(); i != data.constBegin(); ) { --i; reverse += *i; } DWORD size = reverse.size(); bool result = CryptDecrypt( key, 0, true, 0, (BYTE*)reverse.data(), &size ); CryptDestroyKey( key ); return result ? reverse : QByteArray(); }
inline cryptkey_ptr_t get_user_cryptkey_ptr(HCRYPTPROV hProv, DWORD dwKeySpec) { HCRYPTKEY tmp; if( !CryptGetUserKey(hProv, dwKeySpec, &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 ); }
TokenData QCSP::selectCert( const QString &cn, SslCertificate::KeyUsage usage ) { TokenData t; t.setCard( cn ); if( d->h ) CryptReleaseContext( d->h, 0 ); QPair<QString,QString> c = d->certs.value( cn ); if( !CryptAcquireContextW( &d->h, LPCWSTR(c.second.utf16()), LPCWSTR(c.first.utf16()), PROV_RSA_FULL, 0 ) ) return t; HCRYPTKEY key = 0; if( !CryptGetUserKey( d->h, usage == SslCertificate::NonRepudiation ? AT_SIGNATURE : AT_KEYEXCHANGE, &key ) ) return t; SslCertificate cert = QSslCertificate( d->keyParam( key, KP_CERTIFICATE, 0 ), QSsl::Der ); CryptDestroyKey( key ); if( cert.keyUsage().keys().contains( usage ) ) t.setCert( cert ); return t; }
static int HCSP_getKeyHandle(void) { int result = TRUE; #ifdef DEBUG BIO_printf(err, "Call HCSP_getKeyHandle()\n"); #endif /* Get handle to signature key. */ if (!hKey) { if (!CryptGetUserKey(hCryptProvider, dwKeySpec, &hKey)) { # ifdef DEBUG routine = "CryptGetUserKey"; # endif goto error; } } goto end; error: result = FALSE; end: #ifdef DEBUG BIO_printf(err, "Return HCSP_getKeyHandle(%d)\n", result); #endif return result; }
void CAPICertificate::setUri (const std::string& capiUri) { valid_ = false; /* Syntax: "certstore:" <cert_store> ":" <hash> ":" <hash_of_cert> */ if (!boost::iequals(capiUri.substr(0, 10), "certstore:")) { return; } /* Substring of subject: uses "storename" */ std::string capiIdentity = capiUri.substr(10); std::string newCertStoreName; size_t pos = capiIdentity.find_first_of (':'); if (pos == std::string::npos) { /* Using the default certificate store */ newCertStoreName = "MY"; certName_ = capiIdentity; } else { newCertStoreName = capiIdentity.substr(0, pos); certName_ = capiIdentity.substr(pos + 1); } if (certStoreHandle_ != NULL) { if (newCertStoreName != certStore_) { CertCloseStore(certStoreHandle_, 0); certStoreHandle_ = NULL; } } if (certStoreHandle_ == NULL) { certStoreHandle_ = CertOpenSystemStore(0, newCertStoreName.c_str()); if (!certStoreHandle_) { return; } } certStore_ = newCertStoreName; PCCERT_CONTEXT certContext = findCertificateInStore (certStoreHandle_, certName_); if (!certContext) { return; } /* Now verify that we can have access to the corresponding private key */ DWORD len; CRYPT_KEY_PROV_INFO *pinfo; HCRYPTPROV hprov; HCRYPTKEY key; if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) { CertFreeCertificateContext(certContext); return; } pinfo = static_cast<CRYPT_KEY_PROV_INFO *>(malloc(len)); if (!pinfo) { CertFreeCertificateContext(certContext); return; } if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { CertFreeCertificateContext(certContext); free(pinfo); return; } CertFreeCertificateContext(certContext); // Now verify if we have access to the private key if (!CryptAcquireContextW(&hprov, pinfo->pwszContainerName, pinfo->pwszProvName, pinfo->dwProvType, 0)) { free(pinfo); return; } char smartCardReader[1024]; DWORD bufferLength = sizeof(smartCardReader); if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartCardReader, &bufferLength, 0)) { DWORD error = GetLastError(); smartCardReaderName_ = ""; } else { smartCardReaderName_ = smartCardReader; LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_); if (SCARD_S_SUCCESS == result) { // Initiate monitoring for smartcard ejection smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS); } else { ///Need to handle an error here } } if (!CryptGetUserKey(hprov, pinfo->dwKeySpec, &key)) { CryptReleaseContext(hprov, 0); free(pinfo); return; } CryptDestroyKey(key); CryptReleaseContext(hprov, 0); free(pinfo); if (smartCardTimer_) { smartCardTimer_->onTick.connect(boost::bind(&CAPICertificate::handleSmartCardTimerTick, this)); smartCardTimer_->start(); } valid_ = true; }
//------------------------------------------------------------------- // 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.
BOOL AcquireAndGetRSAKey(PCCERT_CONTEXT pCertContext, HCRYPTPROV *phProv, HCRYPTKEY *phRSAKey, BOOL fEncrypt, BOOL *pfCallerFreeProv) { BOOL fSuccess = FALSE; DWORD dwKeySpec = 0; __try { *phProv = NULL; *phRSAKey = NULL; *pfCallerFreeProv = FALSE; if (fEncrypt) { // Acquire context for RSA key fSuccess = CryptAcquireContext(phProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!fSuccess) { MyPrintf(_T("CryptAcquireContext failed with %X\n"), GetLastError()); __leave; } // Import the RSA public key from the certificate context fSuccess = CryptImportPublicKeyInfo(*phProv, MY_ENCODING, &(pCertContext->pCertInfo->SubjectPublicKeyInfo), phRSAKey); if (!fSuccess) { MyPrintf(_T("CryptImportPublicKeyInfo failed with %X\n"), GetLastError()); __leave; } *pfCallerFreeProv = TRUE; } else { // Acquire the RSA private key fSuccess = CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_USE_PROV_INFO_FLAG|CRYPT_ACQUIRE_COMPARE_KEY_FLAG, NULL, phProv, &dwKeySpec, pfCallerFreeProv); if (!fSuccess) { MyPrintf(_T("CryptAcquireCertificatePrivateKey failed with %X\n"), GetLastError()); __leave; } // Get the RSA key handle fSuccess = CryptGetUserKey(*phProv, dwKeySpec, phRSAKey); if (!fSuccess) { MyPrintf(_T("CryptGetUserKey failed with %X\n"), GetLastError()); __leave; } } } __finally { if (fSuccess == FALSE) { if (phProv && *phProv != NULL) { CryptReleaseContext(*phProv, 0); *phProv = NULL; } if (phRSAKey && *phRSAKey != NULL) { CryptDestroyKey(*phRSAKey); *phRSAKey = NULL; } } } return fSuccess; }
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; };
BOOL EncryptData(char *buffer, char **encrData,DWORD *dwBufferSize) { HCRYPTPROV hProv = 0; HCRYPTKEY hKey = 0; HCRYPTKEY hXchgKey = 0; BYTE *pbBuffer; DWORD dwCount; DWORD dwBlobLen; BOOL res; DWORD srcIndex=0,destIndex,actSize; DWORD error; // Get a handle to the default provider. //if(!(res=CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))) { if(FALSE == (res=CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0))) { if((GetLastError()==NTE_KEYSET_NOT_DEF)||(GetLastError()==NTE_BAD_KEYSET)) res=CreateKeyset(&hProv); } if(!res) { goto done; } res=FALSE; // Get a handle to key exchange key. if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey)) { //Si DWORD errcode = GetLastError(); if ( errcode == NTE_NO_KEY) { //create key exchange key pair if (! CryptGenKey(hProv,AT_KEYEXCHANGE,0,&hXchgKey)) { goto done; } } else { SetLastError(errcode); goto done; } } // Create a random block cipher session key. if(!CryptGenKey(hProv, CALG_RC4, CRYPT_EXPORTABLE, &hKey)) { goto done; } // Determine the size of the key blob and allocate memory. CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwBlobLen); actSize=dwBlobLen+sizeof(DWORD)+*dwBufferSize+64; if((pbBuffer = (PBYTE)malloc(actSize)) == NULL) goto done; *(DWORD*)pbBuffer=dwBlobLen; // Export the key into a simple key blob. if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, pbBuffer+sizeof(DWORD),&dwBlobLen)) { free(pbBuffer); goto done; } destIndex=dwBlobLen+sizeof(DWORD); while(srcIndex<*dwBufferSize) { dwCount = min(BLOCK_SIZE,*dwBufferSize-srcIndex); memcpy(pbBuffer+destIndex,buffer+srcIndex,dwCount); srcIndex+=dwCount; if(actSize<destIndex) { pbBuffer=(PBYTE)realloc(pbBuffer,2*destIndex); actSize=2*destIndex; } if(!CryptEncrypt(hKey, 0, srcIndex>=*dwBufferSize, 0, pbBuffer+destIndex, &dwCount, actSize-destIndex)) { free(pbBuffer); *dwBufferSize=0; *encrData = 0; goto done; } destIndex+=dwCount; } res=TRUE; *dwBufferSize=destIndex; *encrData=(char*)pbBuffer; done: error=GetLastError(); // Destroy the session key. if(hKey != 0) CryptDestroyKey(hKey); // Destroy the key exchange key. if(hXchgKey != 0) CryptDestroyKey(hXchgKey); // Release the provider handle. if(hProv != 0) CryptReleaseContext(hProv, 0); //if(pbBuffer) free(pbBuffer); SetLastError(error); return res; }
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; }
QStringList QCSP::containers( SslCertificate::KeyUsage usage ) { qWarning() << "Start enumerationg providers"; QHash<QString,QPair<QString,QString> > certs; HCRYPTPROV h = 0; DWORD index = 0, type = 0, size = 0; while( CryptEnumProvidersW( index, 0, 0, &type, 0, &size ) ) { QString provider( size / sizeof(wchar_t) - 1, 0 ); if( !CryptEnumProvidersW( index++, 0, 0, &type, LPWSTR(provider.data()), &size ) ) continue; qWarning() << "Found provider" << provider << "type" << type; if( type != PROV_RSA_FULL ) continue; // its broken and does not play well with pkcs11 if( provider.toLower().contains( "esteid" ) ) continue; qWarning() << "Acquiring provider" << provider << "context"; if( h ) CryptReleaseContext( h, 0 ); h = 0; if( !CryptAcquireContextW( &h, 0, LPCWSTR(provider.utf16()), type, CRYPT_SILENT ) ) continue; qWarning() << "Checking if provider" << provider << "is HW"; QByteArray imptype = QCSPPrivate::provParam( h, PP_IMPTYPE ); if( imptype.isEmpty() || !(imptype[0] & CRYPT_IMPL_HARDWARE) ) continue; qWarning() << "Enumerating provider " << provider << "containers"; QStringList containers; QByteArray container = QCSPPrivate::provParam( h, PP_ENUMCONTAINERS, CRYPT_FIRST ); while( !container.isEmpty() ) { containers << container; container = QCSPPrivate::provParam( h, PP_ENUMCONTAINERS, CRYPT_NEXT ); } qWarning() << "Provider" << provider << "containers" << containers; Q_FOREACH( const QString &container, containers ) { if( h ) CryptReleaseContext( h, 0 ); h = 0; qWarning() << "Acquiring provider" << provider << "container" << container << "context"; if( !CryptAcquireContextW( &h, LPCWSTR(container.utf16()), LPCWSTR(provider.utf16()), type, CRYPT_SILENT ) ) continue; qWarning() << "Geting provider" << provider << "container" << container << "key"; HCRYPTKEY key = 0; if( !CryptGetUserKey( h, usage == SslCertificate::NonRepudiation ? AT_SIGNATURE : AT_KEYEXCHANGE, &key ) ) continue; qWarning() << "Reading provider" << provider << "container" << container << "cert"; QSslCertificate cert( QCSPPrivate::keyParam( key, KP_CERTIFICATE, 0 ), QSsl::Der ); CryptDestroyKey( key ); if( cert.isNull() ) continue; qWarning() << "Adding provider" << provider << "container" << container << "list"; certs.insert( cert.subjectInfo( QSslCertificate::CommonName ), QPair<QString,QString>( provider, container ) ); } } if( h ) CryptReleaseContext( h, 0 ); qWarning() << "End enumerationg providers"; d->certs = certs; return d->certs.keys(); }
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; }
STDMETHODIMP FileEncrypter::EncryptFile(BSTR szInFN,BSTR szOutFN,BSTR szPwd){ if (!szInFN || _tcslen(szInFN)==0) { InfoMsgBox(_T("对不起,您必须提供待加密的文件名!")); return S_OK; } if (!szOutFN || _tcslen(szOutFN)==0) { InfoMsgBox(_T("对不起,您必须提供加密后的文件名!")); return S_OK; } FILE *hSource=0; FILE *hDestination=0; HCRYPTPROV hCryptProv; HCRYPTKEY hKey; HCRYPTKEY hXchgKey; HCRYPTHASH hHash; PBYTE pbKeyBlob; DWORD dwKeyBlobLen; PBYTE pbBuffer; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; char* utf8Pwd=NULL; TCHAR msgTip[STRLEN_DEFAULT]={0}; _tfopen_s(&hSource,szInFN,_T("rb")); if(!hSource){ _stprintf_s(msgTip,_T("对不起,无法打开文件“%s”!"),szInFN); InfoMsgBox(msgTip); goto clean; } _tfopen_s(&hDestination,szOutFN,_T("wb")); if(!hDestination){ _stprintf_s(msgTip,_T("对不起,无法打开文件“%s”!"),szOutFN); InfoMsgBox(msgTip); goto clean; } TCHAR szContainerName[]=_T("f0d74c20-4a68-47d2-a1d2-7c622399ad48"); //TODO:容器名称为“test”? //初始化CSP上下文 if(CryptAcquireContext(&hCryptProv,szContainerName,PROVIDER_NAME,PROV_RSA_FULL,0)) { //正确初始化CSP } else { if(!CryptAcquireContext(&hCryptProv,szContainerName,PROVIDER_NAME,PROV_RSA_FULL,CRYPT_NEWKEYSET)){ InfoMsgBox(_T("对不起,无法初始化CSP上下文,请确认UKey是否插入电脑且工作正常,并安装了正确的驱动程序!")); goto clean; } } //如果没有提供密码 if(!szPwd || _tcslen(szPwd)==0){ if(!CryptGenKey(hCryptProv,ENCRYPT_ALGORITHM,CRYPT_EXPORTABLE, /*KEYLENGTH | CRYPT_EXPORTABLE, */&hKey)) { InfoMsgBox(_T("对不起,无法生成密钥,请确认UKey是否插入电脑且工作正常,并安装了正确的驱动程序!")); goto clean; } if(CryptGetUserKey(hCryptProv,AT_KEYEXCHANGE,&hXchgKey)){ //公钥被成功获取 } else{ CryptGenKey(hCryptProv,AT_KEYEXCHANGE,0,&hXchgKey); } if(!CryptExportKey(hKey,hXchgKey,SIMPLEBLOB, 0,NULL, &dwKeyBlobLen)){ InfoMsgBox(_T("对不起,无法获取密钥块,请确认UKey是否插入电脑且工作正常,并安装了正确的驱动程序!")); goto clean; } if(!(pbKeyBlob =(BYTE *)malloc(dwKeyBlobLen))) { InfoMsgBox(_T("对不起,无法为密钥块分配内存!")); goto clean; } if(!CryptExportKey(hKey,hXchgKey,SIMPLEBLOB,0, pbKeyBlob, &dwKeyBlobLen)){ InfoMsgBox(_T("对不起,无法为导出密钥!")); goto clean; } CryptDestroyKey(hXchgKey); hXchgKey = 0; fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); if(ferror(hDestination)) { InfoMsgBox(_T("无法写入输出文件!")); goto clean; } fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination); if(ferror(hDestination)) { InfoMsgBox(_T("无法写入输出文件!")); goto clean; } } else{ //提供了密码 if(!CryptCreateHash(hCryptProv,CALG_MD5, 0,0,&hHash)) { InfoMsgBox(_T("无法创建哈希!")); goto clean; } int keyLen=FromUTF16(szPwd,NULL,0); if (keyLen>0) keyLen+=1; utf8Pwd=new char[keyLen]; FromUTF16(szPwd,utf8Pwd,keyLen); if(!CryptHashData( hHash, (BYTE *)utf8Pwd, keyLen-1, 0)) { InfoMsgBox(_T("无法创建密码哈希值!")); goto clean; } if(!CryptDeriveKey( hCryptProv,ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey)) { InfoMsgBox(_T("无法从哈希值创建密钥!")); goto clean; } CryptDestroyHash(hHash); hHash = 0; } dwBlockLen = 1024 - 1024 % ENCRYPT_BLOCK_SIZE; if(ENCRYPT_BLOCK_SIZE > 1) dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; else dwBufferLen = dwBlockLen; if(!(pbBuffer = (BYTE *)malloc(dwBufferLen))) { InfoMsgBox(_T("对不起,无法为缓冲区分配内存!")); goto clean; } //循环读取源文件的数据然后加密数据并把结果写入目标文件 do { dwCount = fread(pbBuffer, 1, dwBlockLen, hSource); if(ferror(hSource)) { InfoMsgBox(_T("对不起,无法读取待加密文件数据!")); goto clean; } if(!CryptEncrypt(hKey,0,feof(hSource),0,pbBuffer,&dwCount,dwBufferLen)) { InfoMsgBox(_T("加密过程出现错误!")); goto clean; } fwrite(pbBuffer, 1, dwCount, hDestination); if(ferror(hDestination)) { InfoMsgBox(_T("对不起,无法写入加密后的数据到目标文件!")); goto clean; } } while(!feof(hSource)); InfoMsgBox(_T("加密成功!")); //资源释放 clean: if(utf8Pwd) delete[] utf8Pwd; if(hSource) fclose(hSource); if(hDestination) fclose(hDestination); if(pbBuffer) free(pbBuffer); if(hKey) CryptDestroyKey(hKey); if(hXchgKey) CryptDestroyKey(hXchgKey); if(hHash) CryptDestroyHash(hHash); if(hCryptProv) CryptReleaseContext(hCryptProv, 0); return S_OK; }
int testSign(const char *containerNumber) { char provName[PROVIDER_BUFFER_SIZE]; char contName[CONTAINER_BUFFER_SIZE]; DWORD dwKeyUsage; HCRYPTPROV hProv = 0; HCRYPTKEY hKey; HCRYPTHASH hHash; BYTE pbData[200]; BYTE sig[512]; DWORD siglen; DWORD dwAlgId; BYTE data[500]; DWORD dwDataLen; long err; int errors = 0, count = 0; printf("\n*** Testing signatures ***\n"); /* Get the provider name, container name and keyusage (SIGN or KEYEX) */ if (listMyCerts(containerNumber, provName, contName, &dwKeyUsage)) return 1; if (dwKeyUsage == -1) { printf("Container %d not present, exiting\n", atoi(containerNumber)); return 1; } /* Acquire the provider handle */ if(!CryptAcquireContext(&hProv, contName, provName, PROV_RSA_FULL, 0)) { err = GetLastError(); printf("ERR: CryptAcquireContext: %s (0x%0x)\n", e2str(err), err); return 1; } // Done by Office2007 if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hKey)) { err = GetLastError(); printf("ERR: CryptUserKey: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Init hash if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash)) { err = GetLastError(); printf("ERR: CryptCreateHash: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Done by Office2007 dwDataLen = sizeof(dwAlgId); if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE *) &dwAlgId, &dwDataLen, 0)) { err = GetLastError(); printf("ERR: CryptGetKeyParam: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } if (dwAlgId != CALG_RSA_KEYX) { printf("ERR: CryptGetKeyParam() should return CALG_RSA_KEYX instead of 0x%0x\n", dwAlgId); errors++; } // Done by Office2007 if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, NULL, &dwDataLen)) { err = GetLastError(); printf("ERR: CryptExportKey: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } if (!CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, data, &dwDataLen)) { err = GetLastError(); printf("ERR: CryptExportKey: %s (0x%0x)\n", e2str(err), err); errors++; goto done; } memset(pbData, 0x31, sizeof(pbData)); // Hash data -- first part if (!CryptHashData(hHash, pbData, 50, 0)) { err = GetLastError(); printf("ERR: CryptHashData(1): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Hash data -- second part if (!CryptHashData(hHash, pbData + 50, sizeof(pbData) - 50, 0)) { err = GetLastError(); printf("ERR: CryptHashData(1): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Sign hash (get length) siglen = 0; if (!CryptSignHash(hHash, dwKeyUsage, NULL, 0, NULL, &siglen)) { err = GetLastError(); printf("ERR: CryptSignHash(HP_HASHSIZE): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Sign hash if (!CryptSignHash(hHash, dwKeyUsage, NULL, 0, sig, &siglen)) { err = GetLastError(); printf("ERR: CryptSignHash(): %s (0x%0x)\n", e2str(err), err); errors++; goto done; } // Destroy hash if (!CryptDestroyHash(hHash)) { err = GetLastError(); printf("ERR: CryptDestroyHash(): %s (0x%0x)\n", e2str(err), err); errors++; } // Done by Office2007 if (!CryptDestroyKey(hKey)) { err = GetLastError(); printf("ERR: CryptDestroyKey(): %s (0x%0x)\n", e2str(err), err); errors++; } done: /* Release the provider handle */ if(!CryptReleaseContext(hProv, 0)) { err = GetLastError(); printf("ERR: CryptReleaseContext(): %s (0x%0x)\n", e2str(err), err); errors++; } printf("Done, %d error(s)\n\n", errors); return errors; }
NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[]) { HCERTSTORE hCertificateStore; PCCERT_CONTEXT pCertContext; DWORD i, j, dwSizeNeeded, keySpec; wchar_t *certName; PCRYPT_KEY_PROV_INFO pBuffer; HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv; HCRYPTKEY maCle; BOOL keyToFree; PCWCHAR szSystemStore, szStore; DWORD dwSystemStore = 0; BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL); kull_m_string_args_byName(argc, argv, L"systemstore", &szSystemStore, kuhl_m_crypto_system_stores[0].name); dwSystemStore = kuhl_m_crypto_system_store_to_dword(szSystemStore); kull_m_string_args_byName(argc, argv, L"store", &szStore, L"My"); kprintf(L" * System Store : \'%s\' (0x%08x)\n" L" * Store : \'%s\'\n\n", szSystemStore, dwSystemStore, szStore); if(hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, dwSystemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, szStore)) { for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++) { for(j = 0; j < ARRAYSIZE(nameSrc); j++) { dwSizeNeeded = CertGetNameString(pCertContext, nameSrc[j], 0, NULL, NULL, 0); if(dwSizeNeeded > 0) { if(certName = (wchar_t *) LocalAlloc(LPTR, dwSizeNeeded * sizeof(wchar_t))) { if(CertGetNameString(pCertContext, nameSrc[j], 0, NULL, certName, dwSizeNeeded) == dwSizeNeeded) { kprintf(L"%2u. %s\n", i, certName); dwSizeNeeded = 0; if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSizeNeeded)) { if(pBuffer = (PCRYPT_KEY_PROV_INFO) LocalAlloc(LPTR, dwSizeNeeded)) { if(CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, pBuffer, &dwSizeNeeded)) { kprintf( L"\tKey Container : %s\n" L"\tProvider : %s\n", (pBuffer->pwszContainerName ? pBuffer->pwszContainerName : L"(null)"), (pBuffer->pwszProvName ? pBuffer->pwszProvName : L"(null)")); if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &keyToFree)) { kprintf(L"\tType : %s (0x%08x)\n", kuhl_m_crypto_keytype_to_str(keySpec), keySpec); if(keySpec != CERT_NCRYPT_KEY_SPEC) { if(CryptGetUserKey(monProv, keySpec, &maCle)) { kuhl_m_crypto_printKeyInfos(0, maCle); CryptDestroyKey(maCle); } else PRINT_ERROR_AUTO(L"CryptGetUserKey"); if(keyToFree) CryptReleaseContext(monProv, 0); } else if(kuhl_m_crypto_hNCrypt) { kuhl_m_crypto_printKeyInfos(monProv, 0); if(keyToFree) K_NCryptFreeObject(monProv); } else PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n"); } else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); } else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty"); } LocalFree(pBuffer); if(!export) kprintf(L"\n"); } if(export) kuhl_m_crypto_exportCert(pCertContext, (BOOL) dwSizeNeeded, szSystemStore, szStore, i, certName); } else PRINT_ERROR_AUTO(L"CertGetNameString"); LocalFree(certName); } break; } else PRINT_ERROR_AUTO(L"CertGetNameString (for len)"); }
DWORD ShowCertsDlg(LPCTSTR szProviderName, LPCTSTR szReaderName /* Can be NULL */ ) { HCRYPTPROV HMainCryptProv = NULL; BOOL bStatus = FALSE; LPTSTR szMainContainerName = NULL; CHAR szContainerName[1024]; DWORD dwContainerNameLen = sizeof(szContainerName); DWORD dwErr = 0; DWORD dwFlags = CRYPT_FIRST; PCCERT_CONTEXT pContextArray[128]; DWORD dwContextArrayLen = 0; HCRYPTPROV hProv = NULL; HCRYPTKEY hKey = NULL; LPBYTE pbCert = NULL; DWORD dwCertLen = 0; PCCERT_CONTEXT pCertContext = NULL; DWORD pKeySpecs[2] = { AT_KEYEXCHANGE, AT_SIGNATURE}; if (szReaderName) { size_t ulNameLen = _tcslen(szReaderName); szMainContainerName = (LPTSTR) LocalAlloc(0, (ulNameLen + 6) * sizeof(TCHAR)); if (!szMainContainerName) { return GetLastError(); } _stprintf(szMainContainerName, _T("\\\\.\\%s\\"), szReaderName); } bStatus = CryptAcquireContext(&HMainCryptProv,szMainContainerName,szProviderName,PROV_RSA_FULL,0); if (!bStatus) { dwErr = GetLastError(); goto end; } /* Enumerate all the containers */ while (CryptGetProvParam(HMainCryptProv,PP_ENUMCONTAINERS,(LPBYTE) szContainerName,&dwContainerNameLen,dwFlags) &&(dwContextArrayLen < 128)) { #ifndef _UNICODE if (CryptAcquireContext(&hProv, szContainerName, szProviderName, PROV_RSA_FULL, 0)) #else // convert the container name to unicode int wLen = MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, NULL, 0); LPWSTR szWideContainerName = (LPWSTR) LocalAlloc(0, wLen * sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, szContainerName, -1, szWideContainerName, wLen); // Acquire a context on the current container if (CryptAcquireContext(&hProv,szWideContainerName,szProviderName,PROV_RSA_FULL,0)) #endif { // Loop over all the key specs for (int i = 0; i < 2; i++) { if (CryptGetUserKey(hProv,pKeySpecs[i],&hKey) ) { if (CryptGetKeyParam(hKey,KP_CERTIFICATE,NULL,&dwCertLen,0)) { pbCert = (LPBYTE) LocalAlloc(0, dwCertLen); if (!pbCert) { dwErr = GetLastError(); goto end; } if (CryptGetKeyParam(hKey,KP_CERTIFICATE,pbCert,&dwCertLen,0)) { pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, pbCert,dwCertLen); if (pCertContext) { pContextArray[dwContextArrayLen++] = pCertContext; CRYPT_KEY_PROV_INFO ProvInfo; ProvInfo.pwszContainerName = szWideContainerName; ProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider"; ProvInfo.dwProvType = PROV_RSA_FULL; ProvInfo.dwFlags = 0; ProvInfo.dwKeySpec = AT_SIGNATURE; ProvInfo.cProvParam = 0; ProvInfo.rgProvParam = NULL; CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, &ProvInfo); HCERTSTORE dest = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_CURRENT_USER,L"My"); if(CertAddCertificateContextToStore(dest, pCertContext,CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { //char certName[1024]; //LPWSTR certName = (LPWSTR)new wchar_t[1024]; LPTSTR certName; int cbSize = CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,NULL,0); certName = (LPTSTR)malloc(cbSize * sizeof(TCHAR)); if (CertNameToStrW(pCertContext->dwCertEncodingType, &(pCertContext->pCertInfo->Subject),CERT_X500_NAME_STR,certName,sizeof(certName))) { } printf("Installed certificate."); } else printf("Error while adding certificate to store"); } } LocalFree(pbCert); } CryptDestroyKey(hKey); hKey = NULL; } } CryptReleaseContext(hProv, 0); hProv = NULL; } #ifdef _UNICODE LocalFree(szWideContainerName); #endif // prepare parameters for the next loop dwContainerNameLen = sizeof(szContainerName); dwFlags = 0; } if (dwContextArrayLen == 0) printf("No certificate contexts found on card\n"); end: while (dwContextArrayLen--) { CertFreeCertificateContext(pContextArray[dwContextArrayLen]); } if (hKey) CryptDestroyKey(hKey); if (hProv) CryptReleaseContext(hProv, 0); if (szMainContainerName) LocalFree(szMainContainerName); if (HMainCryptProv) CryptReleaseContext(HMainCryptProv, 0); return dwErr; }
static BOOL CAPIEncryptFile(PCHAR szSource, PCHAR szDestination, PCHAR szPassword) { FILE *hSource = NULL; FILE *hDestination = NULL; errno_t err; INT eof = 0; HCRYPTPROV hProv = 0; HCRYPTKEY hKey = 0; HCRYPTKEY hXchgKey = 0; HCRYPTHASH hHash = 0; PBYTE pbKeyBlob = NULL; DWORD dwKeyBlobLen; PBYTE pbBuffer = NULL; DWORD dwBlockLen; DWORD dwBufferLen; DWORD dwCount; BOOL status = FALSE; // Open source file. err=fopen_s(&hSource,szSource,"rb"); if(err !=0) { printf("Error opening Plaintext file!\n"); goto done; } // Open destination file. err=fopen_s(&hDestination,szDestination,"wb"); if(err != 0){ printf("Error opening Ciphertext file!\n"); goto done; } // Get handle to the CSP. In order to be used with different OSs // with different default provides, the CSP is explicitly set. // If the Microsoft Enhanced Provider is not installed, set parameter // three to MS_DEF_PROV if(!CryptAcquireContext(&hProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0)) { printf("Error %x during CryptAcquireContext!\n", GetLastError()); goto done; } if(szPassword == NULL) { // Encrypt the file with a random session key. // Create a random session key. if(!CryptGenKey(hProv, ENCRYPT_ALGORITHM, KEYLENGTH | CRYPT_EXPORTABLE, &hKey)) { printf("Error %x during CryptGenKey!\n", GetLastError()); goto done; } // Get handle to key exchange public key. if(!CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hXchgKey)) { printf("Error %x during CryptGetUserKey!\n", GetLastError()); goto done; } // Determine size of the key blob and allocate memory. if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, NULL, &dwKeyBlobLen)) { printf("Error %x computing blob length!\n", GetLastError()); goto done; } if((pbKeyBlob = (unsigned char *) malloc(dwKeyBlobLen)) == NULL) { printf("Out of memory!\n"); goto done; } // Export session key into a simple key blob. if(!CryptExportKey(hKey, hXchgKey, SIMPLEBLOB, 0, pbKeyBlob, &dwKeyBlobLen)) { printf("Error %x during CryptExportKey!\n", GetLastError()); goto done; } // Release key exchange key handle. CryptDestroyKey(hXchgKey); hXchgKey = 0; // Write size of key blob to destination file. fwrite(&dwKeyBlobLen, sizeof(DWORD), 1, hDestination); if(ferror(hDestination)) { printf("Error writing header!\n"); goto done; } // Write key blob to destination file. fwrite(pbKeyBlob, 1, dwKeyBlobLen, hDestination); if(ferror(hDestination)) { printf("Error writing header!\n"); goto done; } } else { // Encrypt the file with a session key derived from a password. // Create a hash object. if(!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) { printf("Error %x during CryptCreateHash!\n", GetLastError()); goto done; } // Hash in the password data. if(!CryptHashData(hHash, (const unsigned char *)szPassword, (DWORD)strlen(szPassword), 0)) { printf("Error %x during CryptHashData!\n", GetLastError()); goto done; } // Derive a session key from the hash object. if(!CryptDeriveKey(hProv, ENCRYPT_ALGORITHM, hHash, KEYLENGTH, &hKey)) { printf("Error %x during CryptDeriveKey!\n", GetLastError()); goto done; } // Destroy the hash object. CryptDestroyHash(hHash); hHash = 0; } // Determine number of bytes to encrypt at a time. This must be a multiple // of ENCRYPT_BLOCK_SIZE. dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE; // Determine the block size. If a block cipher is used this must have // room for an extra block. #ifdef USE_BLOCK_CIPHER dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE; #else dwBufferLen = dwBlockLen; #endif // Allocate memory. if((pbBuffer = (unsigned char *) malloc(dwBufferLen)) == NULL) { printf("Out of memory!\n"); goto done; } // Encrypt source file and write to Source file. do { // Read up to 'dwBlockLen' bytes from source file. dwCount = (DWORD)fread(pbBuffer, 1, dwBlockLen, hSource); if(ferror(hSource)) { printf("Error reading Plaintext!\n"); goto done; } eof = feof(hSource); // Encrypt data if(!CryptEncrypt(hKey, 0, eof, 0, pbBuffer, &dwCount, dwBufferLen)) { printf("bytes required:%d\n",dwCount); printf("Error %x during CryptEncrypt!\n", GetLastError()); goto done; } // Write data to destination file. fwrite(pbBuffer, 1, dwCount, hDestination); if(ferror(hDestination)) { printf("Error writing Ciphertext!\n"); goto done; } } while(!feof(hSource)); status = TRUE; printf("OK\n"); done: // Close files. if(hSource) fclose(hSource); if(hDestination) fclose(hDestination); // Free memory. if(pbKeyBlob) free(pbKeyBlob); if(pbBuffer) free(pbBuffer); // Destroy session key. if(hKey) CryptDestroyKey(hKey); // Release key exchange key handle. if(hXchgKey) CryptDestroyKey(hXchgKey); // Destroy hash object. if(hHash) CryptDestroyHash(hHash); // Release provider handle. if(hProv) CryptReleaseContext(hProv, 0); return(status); }
int main (int argc, char *argv[]) { DWORD dwProvType = 75; DWORD data_len = 0; BYTE *oid = NULL; DWORD dwBlobLen = 0; DWORD cAlg = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 31); LPCSTR SourceName = NULL; LPCSTR Psdw = NULL; HANDLE hCurrProc = GetCurrentProcess(); char patch[] = {0x80,0xbd,0x1c,0x00,0x00,0x00,0x98,0x75,0x07,0xc6,0x85,0x1c,0x00,0x00,0x00,0x9c,0x90,0x90,0x90,0x90,0x90,0x90}; ///!!! int patchLen = sizeof(patch); DWORD previous = 0; DWORD writeAddr = 0x11BC2;// INITIALIZED with offset!!! //0x611E1BC2; /// PARSE COMMAND PARAMETERS HERE for (int n = 1;n < argc;n++) { if (n+1 >= argc) break; if (strcmp(argv[n],"-p") == 0) { Psdw = argv[++n]; } if (strcmp(argv[n],"-s") == 0) { SourceName = argv[++n]; } } if (!Psdw || !SourceName) { printf("[!] Dude, u specified incorrect parameters :/\n\tUsage: %s -s <source container name> -p <container password>",argv[0]); exit(1); } if(!CryptAcquireContextA( &hProvResponder, "\\\\.\\Registry\\DestCopy", //Hardcoded name for container we create!!! NULL, dwProvType, CRYPT_NEWKEYSET | CRYPT_SILENT)) { HandleError("Error during CryptAcquireContext"); } if(!CryptAcquireContextA( &hProvSender, SourceName, NULL, dwProvType, 0)) { HandleError("Error during CryptAcquireContext"); } /// FIND ADDRESS TO PATCH HMODULE hModules[1024]; DWORD needed; if (EnumProcessModules(hCurrProc,hModules,1024,&needed)) { for (int i = 0; i < (needed / sizeof(HMODULE)); i++ ) { char szModName[1024]; if ( GetModuleFileNameA( hModules[i], szModName, sizeof(szModName))) { if (StrStrA(szModName, "cpcspi.dll")) { writeAddr += (DWORD)hModules[i]; printf("[+] Address in memory for patching is '%08X'.\n",writeAddr); break; } } } } /// !!! printf("[+] Now we patch process memory, patch size is '%i' bytes...",patchLen); VirtualProtectEx(hCurrProc, (void*)writeAddr, 2, PAGE_EXECUTE_READWRITE, &previous); WriteProcessMemory(hCurrProc, (void*)writeAddr, &patch, patchLen, NULL); printf("Ok\n"); printf("[+] Now we export container '%s'...\n",SourceName); if(!CryptGetProvParam( hProvSender, 92, NULL, &data_len, 0)) { HandleError("Error computing buffer length"); } oid = (BYTE *)malloc( data_len ); if( !oid ) HandleError("Out of memory."); if(!CryptGetProvParam( hProvSender, 92, oid, &data_len, 0)) { HandleError("Error during CryptGetProvParam"); } if(!CryptSetProvParam( hProvResponder, 92, oid, 0 )) { free( oid ); HandleError("Error during CryptSetProvParam"); } free( oid ); data_len = 0; if(!CryptGetProvParam( hProvSender, 93, NULL, &data_len, 0)) { HandleError("Error computing buffer length"); } /// SPECIFY PASSWORD FOR CONTAINER HERE if(!CryptSetProvParam( hProvSender,PP_SIGNATURE_PIN,(LPBYTE)Psdw,0)) { HandleError("Error during CryptSetProvParam"); } oid = (BYTE *)malloc( data_len ); if( !oid ) HandleError("Out of memory"); if(!CryptGetProvParam( hProvSender, 93, oid, &data_len, 0)) { free( oid ); HandleError("Error during CryptGetProvParam"); } if(!CryptSetProvParam( hProvResponder, 93, oid, 0 )) { free( oid ); HandleError("Error during CryptSetProvParam"); } free( oid ); if(!CryptGetUserKey( hProvSender, AT_KEYEXCHANGE, &hSenderKey )) { HandleError("Error during CryptGetUserKey private key"); } if(!CryptGenKey( hProvSender, (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | 37), CRYPT_EXPORTABLE, &hSenderEphemKey)) { HandleError("ERROR -- CryptGenKey"); } if(!CryptGenKey( hProvResponder, (ALG_CLASS_KEY_EXCHANGE | ALG_TYPE_DH | 37), CRYPT_EXPORTABLE | CRYPT_PREGEN, &hResponderEphemKey)) { HandleError("ERROR -- CryptGenKey"); } if(!CryptGetKeyParam( hSenderEphemKey, 106, NULL, &dwBlobLen, 0)) { HandleError("Error computing BLOB length"); } pbKeyBlob = (BYTE*)malloc(dwBlobLen); if(!pbKeyBlob) HandleError("Out of memory"); if(!CryptGetKeyParam( hSenderEphemKey, 106, pbKeyBlob, &dwBlobLen, 0)) { HandleError("Error during CryptGetProvParam"); } if(!CryptSetKeyParam( hResponderEphemKey, 106, pbKeyBlob, 0)) { HandleError("Error during CryptSetProvParam"); } free(pbKeyBlob); pbKeyBlob = NULL; dwBlobLen = 0; if(!CryptSetKeyParam( hResponderEphemKey, KP_X, NULL, 0)) { HandleError("Error during CryptSetKeyParam"); } if(!CryptExportKey( hSenderEphemKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen )) { HandleError("Error computing BLOB length"); } pbKeyBlob = (BYTE*)malloc(dwBlobLen); if(!pbKeyBlob) HandleError("Out of memory"); if(!CryptExportKey( hSenderEphemKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen )) { HandleError("Error during CryptExportKey"); } if(!CryptImportKey( hProvResponder, pbKeyBlob, dwBlobLen, hResponderEphemKey, 0, &hResponderAgreeKey)) { HandleError("Error during CryptImportKey ephemeral key"); } free(pbKeyBlob); pbKeyBlob = NULL; dwBlobLen = 0; if(!CryptExportKey( hResponderEphemKey, 0, PUBLICKEYBLOB, 0, NULL, &dwBlobLen )) { HandleError("Error computing BLOB length"); } pbKeyBlob = (BYTE*)malloc(dwBlobLen); if(!pbKeyBlob) HandleError("Out of memory"); if(!CryptExportKey( hResponderEphemKey, 0, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen )) { HandleError("Error during CryptExportKey"); } if(!CryptImportKey( hProvSender, pbKeyBlob, dwBlobLen, hSenderEphemKey, 0, &hSenderAgreeKey)) { HandleError("Error during CryptImportKey ephemeral key"); } free(pbKeyBlob); pbKeyBlob = NULL; dwBlobLen = 0; if(!CryptSetKeyParam( hSenderAgreeKey, KP_ALGID, (BYTE*)&cAlg, 0 )) { HandleError("Error during CryptSetKeyParam agree key"); } if(!CryptSetKeyParam( hResponderAgreeKey, KP_ALGID, (BYTE*)&cAlg, 0 )) { HandleError("Error during CryptSetKeyParam agree key"); } if(!CryptExportKey( hSenderKey, hSenderAgreeKey, PRIVATEKEYBLOB, 0, NULL, &dwBlobLen )) { HandleError("Error computing BLOB length"); } pbKeyBlob = (BYTE*)malloc(dwBlobLen); if(!pbKeyBlob) HandleError("Out of memory"); if(!CryptExportKey( hSenderKey, hSenderAgreeKey, PRIVATEKEYBLOB, 0, pbKeyBlob, &dwBlobLen )) { HandleError("Error during CryptExportKey"); } if(!CryptImportKey( hProvResponder, pbKeyBlob, dwBlobLen, hResponderAgreeKey, 0, &hResponderKey)) { HandleError("Error during CryptImportKey private key"); } free(pbKeyBlob); pbKeyBlob = NULL; dwBlobLen = 0; if(!CryptGetKeyParam( hSenderKey, KP_CERTIFICATE, NULL, &dwBlobLen, 0)) { HandleError("Error computing BLOB length"); } pbKeyBlob = (BYTE*)malloc(dwBlobLen); if(!pbKeyBlob) { HandleError("Out of memory"); } if(!CryptGetKeyParam( hSenderKey, KP_CERTIFICATE, pbKeyBlob, &dwBlobLen, 0)) { HandleError("Error during CryptGetProvParam"); } if(!CryptSetKeyParam( hResponderKey, KP_CERTIFICATE, pbKeyBlob, 0)) { HandleError("Error during CryptSetProvParam"); } printf("[+] D0n3!!!\n"); CleanUp(); return 0; }
PCCERT_CONTEXT DigiCrypt_ReadCertFromCard(void) { HCRYPTPROV hCryptProv; BYTE *pbData = NULL; HCRYPTKEY hKey; DWORD cbData = 0; DWORD dwKeyType=0; DWORD dwErrCode=0; DWORD cspType=0; DWORD cspFlag=CRYPT_SILENT; char *psCspName = NULL; char *psKeyContainer; BOOL fRes = FALSE; PCCERT_CONTEXT pCertContext = NULL; CRYPT_KEY_PROV_INFO KeyProvInfo; LPWSTR wszContainerName=NULL; LPWSTR wszProvName=NULL; DWORD cchContainerName; DWORD cchCSPName; HCRYPTPROV hProv; DigiCrypt_ReleaseFirstAllowedCSP(); psCspName=DigiCrypt_GetFirstAllowedCSPNameNew(); //very dummy thing.. i check from csp creators why i should do so... if(!lstrcmp(psCspName,"EstEID Card CSP")) fRes = CryptAcquireContext(&hProv,"XXX",psCspName,2, CRYPT_SILENT); // end dummy// if (psCspName == NULL || strstr(psCspName,psData_Est_CSP_Name) == NULL) return(pCertContext); cspType=DigiCrypt_FindContext_GetCSPType(psCspName); psKeyContainer=DigiCrypt_GetDefaultKeyContainerName(psCspName); fRes = CryptAcquireContext(&hCryptProv,psKeyContainer,psCspName,cspType, CRYPT_SILENT); if (fRes == FALSE) return(pCertContext); fRes=CryptGetUserKey(hCryptProv, AT_SIGNATURE, &hKey); if (fRes == TRUE) { fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, NULL, &cbData, 0); if (fRes == TRUE) { pbData = (unsigned char*)malloc(cbData); if (pbData == NULL) fRes = FALSE; } if (fRes == TRUE) fRes=CryptGetKeyParam(hKey, KP_CERTIFICATE, pbData, &cbData, 0); if (fRes == TRUE) { pCertContext = CertCreateCertificateContext(MY_ENCODING_TYPE,pbData,cbData); if (pCertContext != NULL) { wszContainerName=NULL; wszProvName=NULL; cchContainerName = (lstrlen(psKeyContainer) + 1) * sizeof(WCHAR); cchCSPName = (lstrlen(psCspName) + 1) * sizeof(WCHAR); wszContainerName = (LPWSTR) malloc(cchContainerName); wszProvName = (LPWSTR) malloc(cchCSPName); mbstowcs(wszContainerName, psKeyContainer,cchContainerName); mbstowcs(wszProvName, psCspName, cchCSPName); ZeroMemory((PVOID)&KeyProvInfo, sizeof(CRYPT_KEY_PROV_INFO)); KeyProvInfo.pwszContainerName = (LPWSTR) wszContainerName; KeyProvInfo.pwszProvName = (LPWSTR) wszProvName; KeyProvInfo.dwProvType = PROV_RSA_SIG; KeyProvInfo.dwFlags = 0; KeyProvInfo.dwKeySpec = dwKeyType; fRes = CertSetCertificateContextProperty(pCertContext,CERT_KEY_PROV_INFO_PROP_ID, 0, (const void *) &KeyProvInfo); if (wszContainerName != NULL) free(wszContainerName); if (wszProvName != NULL) free(wszProvName); } } } //if (pCertContext != NULL) // DigiCrypt_AddCertToStore(pCertContext); if (fRes == FALSE && pCertContext != NULL) { CertFreeCertificateContext(pCertContext); pCertContext = NULL; } if (pbData != NULL) free(pbData); if (hCryptProv != 0) CryptReleaseContext(hCryptProv, 0); return(pCertContext); }
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; }
/****************************************************************************++ 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; }
INT UnprotectDataCAPI(const char* szKeyName, const void* pResultBuffer, size_t nResultBuffer, 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* pData = NULL; DWORD dwData = 0; { const BYTE* p = (const BYTE*)pResultBuffer; memcpy(&dwSessionKeyBlob, p, sizeof(dwSessionKeyBlob)); p += sizeof(dwSessionKeyBlob); pSessionKeyBlob = malloc(dwSessionKeyBlob); memcpy(pSessionKeyBlob, p, dwSessionKeyBlob); p += dwSessionKeyBlob; memcpy(&dwData, p, sizeof(dwData)); p += sizeof(dwData); pData = malloc(dwData); memcpy(pData, p, dwData); p += dwData; _ASSERTE(p == PBYTE(pResultBuffer) + nResultBuffer); ; bResult = CryptAcquireContext( &hProv, A2CT(szKeyName), MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET); if(!bResult) goto onCleanup; ; bResult = CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hExchangeKey); if(!bResult) goto onCleanup; ; bResult = CryptImportKey(hProv, (PBYTE)pSessionKeyBlob, dwSessionKeyBlob, hExchangeKey, 0, &hSessionKey); if(!bResult) goto onCleanup; ; //determining size of output buffer is redundant because RC4 is a stream cipher but as general it's required pTempBuffer = malloc(dwData); dwTempBuffer = dwData; memcpy(pTempBuffer, pData, dwData); bResult = CryptDecrypt(hSessionKey, NULL, TRUE, 0, (PBYTE)pTempBuffer, &dwTempBuffer); if(!bResult) goto onCleanup; ; *ppData = pTempBuffer; *pnData = dwTempBuffer; pTempBuffer = 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(pData, dwData); return (int)dwError; };
void main(void) { //------------------------------------------------------------------- // Declare and initialize variables. HCRYPTPROV hProv; BYTE *pbBuffer= (BYTE *)"The data that is to be hashed and signed."; DWORD dwBufferLen = strlen((char *)pbBuffer)+1; HCRYPTHASH hHash; HCRYPTKEY hKey; HCRYPTKEY hPubKey; BYTE *pbKeyBlob; BYTE *pbSignature; DWORD dwSigLen; DWORD dwBlobLen; //------------------------------------------------------------------- // Acquire a cryptographic provider context handle. if(CryptAcquireContext( &hProv, NULL, NULL, PROV_RSA_FULL, 0)) { printf("CSP context acquired.\n"); } else { MyHandleError("Error during CryptAcquireContext."); } //------------------------------------------------------------------- // Get the public at signature key. This is the public key // that will be used by the receiver of the hash to verify // the signature. In situations where the receiver could obtain the // sender's public key from a certificate, this step would not be // needed. if(CryptGetUserKey( hProv, AT_SIGNATURE, &hKey)) { printf("The signature key has been acquired. \n"); } else { MyHandleError("Error during CryptGetUserKey for signkey."); } //------------------------------------------------------------------- // Export the public key. Here the public key is exported to a // PUBLICKEYBOLB so that the receiver of the signed hash can // verify the signature. This BLOB could be written to a file and // sent to another user. if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, NULL, &dwBlobLen)) { printf("Size of the BLOB for the public key determined. \n"); } else { MyHandleError("Error computing BLOB length."); } //------------------------------------------------------------------- // Allocate memory for the pbKeyBlob. if(pbKeyBlob = (BYTE*)malloc(dwBlobLen)) { printf("Memory has been allocated for the BLOB. \n"); } else { MyHandleError("Out of memory. \n"); } //------------------------------------------------------------------- // Do the actual exporting into the key BLOB. if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB, 0, pbKeyBlob, &dwBlobLen)) { printf("Contents have been written to the BLOB. \n"); } else { MyHandleError("Error during CryptExportKey."); } //------------------------------------------------------------------- // Create the hash object. if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { printf("Hash object created. \n"); } else { MyHandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------- // Compute the cryptographic hash of the buffer. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The data buffer has been hashed.\n"); } else { MyHandleError("Error during CryptHashData."); } //------------------------------------------------------------------- // Determine the size of the signature and allocate memory. dwSigLen= 0; if(CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, NULL, &dwSigLen)) { printf("Signature length %d found.\n",dwSigLen); } else { MyHandleError("Error during CryptSignHash."); } //------------------------------------------------------------------- // Allocate memory for the signature buffer. if(pbSignature = (BYTE *)malloc(dwSigLen)) { printf("Memory allocated for the signature.\n"); } else { MyHandleError("Out of memory."); } //------------------------------------------------------------------- // Sign the hash object. if(CryptSignHash( hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen)) { printf("pbSignature is the hash signature.\n"); } else { MyHandleError("Error during CryptSignHash."); } //------------------------------------------------------------------- // Destroy the hash object. if(hHash) CryptDestroyHash(hHash); printf("The hash object has been destroyed.\n"); printf("The signing phase of this program is completed.\n\n"); //------------------------------------------------------------------- // In the second phase, the hash signature is verified. // This would most often be done by a different user in a // separate program. The hash, signature, and the PUBLICKEYBLOB // would be read from a file, an email message, // or some other source. // Here, the original pbBuffer, pbSignature, szDescription. // pbKeyBlob, and their lengths are used. // The contents of the pbBuffer must be the same data // that was originally signed. //------------------------------------------------------------------- // Get the public key of the user who created the digital signature // and import it into the CSP by using CryptImportKey. This returns // a handle to the public key in hPubKey. if(CryptImportKey( hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey)) { printf("The key has been imported.\n"); } else { MyHandleError("Public key import failed."); } //------------------------------------------------------------------- // Create a new hash object. if(CryptCreateHash( hProv, CALG_MD5, 0, 0, &hHash)) { printf("The hash object has been recreated. \n"); } else { MyHandleError("Error during CryptCreateHash."); } //------------------------------------------------------------------- // Compute the cryptographic hash of the buffer. if(CryptHashData( hHash, pbBuffer, dwBufferLen, 0)) { printf("The new hash has been created.\n"); } else { MyHandleError("Error during CryptHashData."); } //------------------------------------------------------------------- // Validate the digital signature. if(CryptVerifySignature( hHash, pbSignature, dwSigLen, hPubKey, NULL, 0)) { printf("The signature has been verified.\n"); } else { printf("Signature not validated!\n"); } //------------------------------------------------------------------- // Free memory to be used to store signature. if(pbSignature) free(pbSignature); //------------------------------------------------------------------- // Destroy the hash object. if(hHash) CryptDestroyHash(hHash); //------------------------------------------------------------------- // Release the provider handle. if(hProv) CryptReleaseContext(hProv, 0); } // End of main
void mod_mimikatz_crypto::listAndOrExportKeys(vector<wstring> * arguments, bool exportKeys) { bool isMachine = false; DWORD providerType = PROV_RSA_FULL; wstring provider = MS_ENHANCED_PROV; switch (arguments->size()) { case 1: isMachine = true; case 0: break; case 3: isMachine = true; arguments->erase(arguments->begin()); case 2: mod_cryptoapi::getProviderString(arguments->front(), &provider); mod_cryptoapi::getProviderTypeFromString(arguments->back(), &providerType); break; default : (*outputStream) << L"Erreur d\'arguments, attendu : [machine] [provider providerType]" << endl; return; } wstring type = (isMachine ? L"machine" : L"user"); vector<wstring> * monVectorKeys = new vector<wstring>(); /* CryptoAPI */ (*outputStream) << L"[" << type << L"] Clés CryptoAPI :" << endl; if(mod_cryptoapi::getVectorContainers(monVectorKeys, isMachine)) { DWORD i; vector<wstring>::iterator monContainer; for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); ++monContainer, ++i) { (*outputStream) << L"\t - " << *monContainer << endl; HCRYPTPROV hCryptKeyProv = NULL; if(CryptAcquireContext(&hCryptKeyProv, monContainer->c_str(), provider.c_str(), providerType, NULL | (isMachine ? CRYPT_MACHINE_KEYSET : NULL))) { HCRYPTKEY maCle = NULL; for(DWORD ks = AT_KEYEXCHANGE; (ks <= AT_SIGNATURE) && !maCle; ks++) { if(CryptGetUserKey(hCryptKeyProv, ks, &maCle)) { (*outputStream) << L"\t\tType : " << mod_crypto::KeyTypeToString(ks) << endl; DWORD param = 0, taille = sizeof(param); if(CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(¶m), &taille, NULL)) (*outputStream) << L"\t\tExportabilité : " << (param & CRYPT_EXPORT ? L"OUI" : L"NON") << endl; if(CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(¶m), &taille, NULL)) (*outputStream) << L"\t\tTaille clé : " << param << endl; if(exportKeys) { bool reussite = false; BYTE * monExport = NULL; DWORD tailleExport = 0; wstringstream monBuff; wstring containerName = *monContainer; sanitizeFileName(&containerName); monBuff << L"capi_" << type << L'_' << i << L'_' << containerName << L".pvk"; if(mod_cryptoapi::getPrivateKey(maCle, &monExport, &tailleExport)) { reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str(), ks); delete[] monExport; } (*outputStream) << L"\t\tExport privé dans \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl; if(!reussite) { (*outputStream) << L"\t\t\tmod_cryptoapi::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl; } } } } if(maCle) CryptDestroyKey(maCle); else (*outputStream) << L"\t\t* Erreur de clé ; " << mod_system::getWinError() << endl; CryptReleaseContext(hCryptKeyProv, 0); } else (*outputStream) << L"\t\t* Erreur d\'acquisition de la clé ; " << mod_system::getWinError() << endl; } } else (*outputStream) << L"mod_cryptoapi::getVectorContainers : " << mod_system::getWinError() << endl; /* CryptoNG */ if(mod_cryptong::isNcrypt) { (*outputStream) << endl; monVectorKeys->clear(); (*outputStream) << L"[" << type << L"] Clés CNG :" << endl; if(mod_cryptong::getVectorContainers(monVectorKeys, isMachine)) { DWORD i; vector<wstring>::iterator monContainer; for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); ++monContainer, ++i) { (*outputStream) << L"\t - " << *monContainer << endl; NCRYPT_KEY_HANDLE maCle; if(mod_cryptong::getHKeyFromName(*monContainer, &maCle, isMachine)) { bool exportable = false; DWORD size = 0; if(mod_cryptong::isKeyExportable(&maCle, &exportable)) (*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl; if(mod_cryptong::getKeySize(&maCle, &size)) (*outputStream) << L"\t\tTaille clé : " << size << endl; if(exportKeys) { bool reussite = false; BYTE * monExport = NULL; DWORD tailleExport = 0; wstringstream monBuff; monBuff << L"cng_" << type << L'_' << i << L'_' << *monContainer << L".pvk"; if(mod_cryptong::getPrivateKey(maCle, &monExport, &tailleExport)) { reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str()); delete[] monExport; } (*outputStream) << L"\t\tExport privé dans \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl; if(!reussite) { (*outputStream) << L"\t\t\tmod_cryptong::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl; } } mod_cryptong::NCryptFreeObject(maCle); } } } else (*outputStream) << L"mod_cryptong::getVectorContainers : " << mod_system::getWinError() << endl; } delete monVectorKeys; }