bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) { if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false; int i = 0; if (nDerivationMethod == 0) { i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); } if (nDerivationMethod == 1) { // Passphrase conversion uint256 scryptHash = scrypt_salted_multiround_hash((const void*)strKeyData.c_str(), strKeyData.size(), &chSalt[0], 8, nRounds); i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], (unsigned char *)&scryptHash, sizeof scryptHash, nRounds, chKey, chIV); OPENSSL_cleanse(&scryptHash, sizeof scryptHash); } if (i != (int)WALLET_CRYPTO_KEY_SIZE) { OPENSSL_cleanse(chKey, sizeof(chKey)); OPENSSL_cleanse(chIV, sizeof(chIV)); return false; } fKeySet = true; return true; }
bool DecryptAES256(const SecureString& sKey, const std::string& sCiphertext, const std::string& sIV, SecureString& sPlaintext) { // plaintext will always be equal to or lesser than length of ciphertext int nLen = sCiphertext.size(); int nPLen = nLen, nFLen = 0; // Verify key sizes if(sKey.size() != 32 || sIV.size() != AES_BLOCK_SIZE) { LogPrintf("crypter DecryptAES256 - Invalid key or block size\n"); return false; } sPlaintext.resize(nPLen); EVP_CIPHER_CTX ctx; bool fOk = true; EVP_CIPHER_CTX_init(&ctx); if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*) &sKey[0], (const unsigned char*) &sIV[0]); if (fOk) fOk = EVP_DecryptUpdate(&ctx, (unsigned char *) &sPlaintext[0], &nPLen, (const unsigned char *) &sCiphertext[0], nLen); if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (unsigned char *) (&sPlaintext[0])+nPLen, &nFLen); EVP_CIPHER_CTX_cleanup(&ctx); if (!fOk) return false; sPlaintext.resize(nPLen + nFLen); return true; }
// General secure AES 256 CBC encryption routine bool EncryptAES256(const SecureString& sKey, const SecureString& sPlaintext, const std::string& sIV, std::string& sCiphertext) { // max ciphertext len for a n bytes of plaintext is // n + AES_BLOCK_SIZE - 1 bytes int nLen = sPlaintext.size(); int nCLen = nLen + AES_BLOCK_SIZE; int nFLen = 0; // Verify key sizes if(sKey.size() != 32 || sIV.size() != AES_BLOCK_SIZE) { LogPrintf("crypter EncryptAES256 - Invalid key or block size: Key: %d sIV:%d\n", sKey.size(), sIV.size()); return false; } // Prepare output buffer sCiphertext.resize(nCLen); // Perform the encryption EVP_CIPHER_CTX ctx; bool fOk = true; EVP_CIPHER_CTX_init(&ctx); if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, (const unsigned char*) &sKey[0], (const unsigned char*) &sIV[0]); if (fOk) fOk = EVP_EncryptUpdate(&ctx, (unsigned char*) &sCiphertext[0], &nCLen, (const unsigned char*) &sPlaintext[0], nLen); if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (unsigned char*) (&sCiphertext[0])+nCLen, &nFLen); EVP_CIPHER_CTX_cleanup(&ctx); if (!fOk) return false; sCiphertext.resize(nCLen + nFLen); return true; }
// SecureString CMnemonic::FromData(const uint8_t *data, int len) SecureString CMnemonic::FromData(const SecureVector& data, int len) { if (len % 4 || len < 16 || len > 32) { return SecureString(); } SecureVector checksum(32); CSHA256().Write(&data[0], len).Finalize(&checksum[0]); // data SecureVector bits(len); memcpy(&bits[0], &data[0], len); // checksum bits.push_back(checksum[0]); int mlen = len * 3 / 4; SecureString mnemonic; int i, j, idx; for (i = 0; i < mlen; i++) { idx = 0; for (j = 0; j < 11; j++) { idx <<= 1; idx += (bits[(i * 11 + j) / 8] & (1 << (7 - ((i * 11 + j) % 8)))) > 0; } mnemonic.append(wordlist[idx]); if (i < mlen - 1) { mnemonic += ' '; } } return mnemonic; }
Value walletpassphrase(const Array& params, bool fHelp) { if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrase <passphrase> <timeout>\n" "Stores the wallet decryption key in memory for <timeout> seconds."); if (fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); // Note that the walletpassphrase is stored in params[0] which is not mlock()ed SecureString strWalletPass; strWalletPass.reserve(100); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) // Alternately, find a way to make params[0] mlock()'d to begin with. strWalletPass = params[0].get_str().c_str(); if (strWalletPass.length() > 0) { if (!pwalletMain->Unlock(strWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); } else throw runtime_error( "walletpassphrase <passphrase> <timeout>\n" "Stores the wallet decryption key in memory for <timeout> seconds."); int64 nSleepTime = params[1].get_int64(); LOCK(cs_nWalletUnlockTime); nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); return Value::null; }
Value encryptwallet(const Array& params, bool fHelp) { if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1)) throw runtime_error( "encryptwallet <passphrase>\n" "Encrypts the wallet with <passphrase>."); if (fHelp) return true; if (pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called."); // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string) // Alternately, find a way to make params[0] mlock()'d to begin with. SecureString strWalletPass; strWalletPass.reserve(100); strWalletPass = params[0].get_str().c_str(); if (strWalletPass.length() < 1) throw runtime_error( "encryptwallet <passphrase>\n" "Encrypts the wallet with <passphrase>."); if (!pwalletMain->EncryptWallet(strWalletPass)) throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet."); // BDB seems to have a bad habit of writing old data into // slack space in .dat files; that is bad if the old data is // unencrypted private keys. So: StartShutdown(); return "wallet encrypted; Twister server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; }
int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const { // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc // cipher and sha512 message digest. Because sha512's output size (64b) is // greater than the aes256 block size (16b) + aes256 key size (32b), // there's no need to process more than once (D_0). if(!count || !key || !iv) return 0; unsigned char buf[CSHA512::OUTPUT_SIZE]; CSHA512 di; di.Write((const unsigned char*)strKeyData.c_str(), strKeyData.size()); di.Write(chSalt.data(), chSalt.size()); di.Finalize(buf); for(int i = 0; i != count - 1; i++) di.Reset().Write(buf, sizeof(buf)).Finalize(buf); memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE); memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE); memory_cleanse(buf, sizeof(buf)); return WALLET_CRYPTO_KEY_SIZE; }
bool SecurityUser::IsPasswordUpdated(SecurityUserSPtr const & other) { bool needUpdate = false; if(this->AccountType == SecurityPrincipalAccountType::DomainUser) { if(other) { wstring originalPswd = password_; wstring currentPswd = other->Password; if(this->isPasswordEncrypted_) { SecureString pswd; CryptoUtility::DecryptText(password_, pswd); originalPswd = pswd.GetPlaintext(); } if(other->isPasswordEncrypted_) { SecureString pswd; CryptoUtility::DecryptText(other->password_, pswd); currentPswd = pswd.GetPlaintext(); } needUpdate = (originalPswd != currentPswd); originalPswd.clear(); currentPswd.clear(); } } return needUpdate; }
static void TestPassphrase(const std::vector<unsigned char>& vchSalt, const SecureString& passphrase, uint32_t rounds, const std::vector<unsigned char>& correctKey = std::vector<unsigned char>(), const std::vector<unsigned char>& correctIV=std::vector<unsigned char>()) { TestPassphraseSingle(vchSalt, passphrase, rounds, correctKey, correctIV); for(SecureString::const_iterator i(passphrase.begin()); i != passphrase.end(); ++i) TestPassphraseSingle(vchSalt, SecureString(i, passphrase.end()), rounds); }
bool myLabelcompare(SecureString a, SecureString b) { const char* aStr = a.getUnsecureString(); const char* bStr = b.getUnsecureString(); bool res = _strcmpi(aStr, bStr) < 0; a.UnsecuredStringFinished(); b.UnsecuredStringFinished(); return res; }
void CKeePassIntegrator::CKeePassRequest::init() { SecureString sIVSecure = generateRandomKey(KEEPASS_CRYPTO_BLOCK_SIZE); sIV = std::string(&sIVSecure[0], sIVSecure.size()); // Generate Nonce, Verifier and RequestType SecureString sNonceBase64Secure = EncodeBase64Secure(sIVSecure); addStrParameter("Nonce", std::string(&sNonceBase64Secure[0], sNonceBase64Secure.size())); // Plain addStrParameter("Verifier", sNonceBase64Secure); // Encoded addStrParameter("RequestType", sType); }
Value walletpassphrase(const Array& params, bool fHelp) { if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrase \"passphrase\" timeout\n" "\nStores the wallet decryption key in memory for 'timeout' seconds.\n" "This is needed prior to performing transactions related to private keys such as sending Dacrss\n" "\nArguments:\n" "1. \"passphrase\" (string, required) The wallet passphrase\n" "2. timeout (numeric, required) The time to keep the decryption key in seconds.\n" "\nNote:\n" "Issuing the walletpassphrase command while the wallet is already unlocked will set a new unlock\n" "time that overrides the old one.\n" "\nExamples:\n" "\nunlock the wallet for 60 seconds\n" + HelpExampleCli("walletpassphrase", "\"my pass phrase\" 60") + "\nLock the wallet again (before 60 seconds)\n" + HelpExampleCli("walletlock", "") + "\nAs json rpc call\n" + HelpExampleRpc("walletpassphrase", "\"my pass phrase\", 60") ); LOCK2(cs_main, pwalletMain->cs_wallet); if (fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called."); // Note that the walletpassphrase is stored in params[0] which is not mlock()ed SecureString strWalletPass; strWalletPass.reserve(100); // TODO: get rid of this .c_str() by implementing SecureString::operator=(string) // Alternately, find a way to make params[0] mlock()'d to begin with. strWalletPass = params[0].get_str().c_str(); //assert(0); if (strWalletPass.length() > 0) { if (!pwalletMain->Unlock(strWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); } else throw runtime_error( "walletpassphrase <passphrase> <timeout>\n" "Stores the wallet decryption key in memory for <timeout> seconds."); int64_t nSleepTime = params[1].get_int64(); LOCK(cs_nWalletUnlockTime); nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); Object retObj; retObj.push_back(Pair("passphrase", true)); return retObj; }
// passphrase must be at most 256 characters or code may crash void CMnemonic::ToSeed(SecureString mnemonic, SecureString passphrase, SecureVector& seedRet) { SecureString ssSalt = SecureString("mnemonic") + passphrase; SecureVector vchSalt(ssSalt.begin(), ssSalt.end()); seedRet.resize(64); // int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, // const unsigned char *salt, int saltlen, int iter, // const EVP_MD *digest, // int keylen, unsigned char *out); PKCS5_PBKDF2_HMAC(mnemonic.c_str(), mnemonic.size(), &vchSalt[0], vchSalt.size(), 2048, EVP_sha512(), 64, &seedRet[0]); }
SecureString CKeePassIntegrator::generateRandomKey(size_t nSize) { // Generates random key SecureString key; key.resize(nSize); RandAddSeedPerfmon(); RAND_bytes((unsigned char *) &key[0], nSize); return key; }
int __pass_cb(char *buf, int size, int rwflag, void *u) { Key::PassphraseFunctor* pf = (Key::PassphraseFunctor*)u; bool verify = (rwflag == 1); SecureString ss = (*pf)(verify); int len; len = ss.size(); if (len <= 0) return 0; // if too long, truncate if (len > size) len = size; memcpy(buf, ss.c_str(), len); return len; }
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) { if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false; // Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap) // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process. // mlock(&chKey[0], sizeof chKey); // mlock(&chIV[0], sizeof chIV); int i = 0; if (nDerivationMethod == 0) i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); if (i != (int)WALLET_CRYPTO_KEY_SIZE) { // memset(&chKey, 0, sizeof chKey); // memset(&chIV, 0, sizeof chIV); OPENSSL_cleanse(chKey, sizeof(chKey)); OPENSSL_cleanse(chIV, sizeof(chIV)); return false; } fKeySet = true; return true; }
void permutation(int k, SecureString &s) { for(unsigned int j = 1; j < s.size(); ++j) { swap(s, k % (j + 1), j); k = k / (j + 1); } }
PwdLabelVector PwdList::FilterLabels(SecureString pattern) { std::lock_guard<std::recursive_mutex> lock(mutex_lock); PwdLabelVector vector; const char* strPtrn = pattern.getUnsecureString(); for (auto it = existingLabels.begin(); it != existingLabels.end(); it++) { if (strstr(strPtrn, (*it).getUnsecureString()) != NULL) { vector.push_back((*it)); } (*it).UnsecuredStringFinished(); } pattern.UnsecuredStringFinished(); std::sort(vector.begin(), vector.end(), myLabelcompare); return vector; }
//key:128 //encrypt output:nonce(12)+tag(16)+cipher_text //no aad // int Encrypt_AesGcm128(const uint8_t * plain_text, uint32_t plain_text_len, const SecureString & key, string & cipher_text){ cipher_text.clear(); EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER * cipher=EVP_aes_128_gcm(); if(1 != EVP_EncryptInit_ex(&ctx, cipher, NULL, NULL, NULL)) return LIB_ERR; unsigned char nonce[GCM_NONCE_LENGTH]={}; RAND_bytes(nonce,4); struct timeval t={0,0}; if(0==gettimeofday(&t,NULL)){ memcpy(&nonce[4],&t.tv_sec,4); memcpy(&nonce[8],&t.tv_nsec,4); }else{ RAND_bytes(&nonce[4],GCM_NONCE_LENGTH-4); } if(1 != EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_NONCE_LENGTH, NULL)) return LIB_ERR; if(1 != EVP_EncryptInit_ex(&ctx, NULL, NULL, key.data(), &nonce[0])) return LIB_ERR; cipher_text.reserve(GCM_NONCE_LENGTH+GCM_TAG_LENGTH+plain_text_len); cipher_text.append(&nonce[0],GCM_NONCE_LENGTH); cipher_text.append(GCM_TAG_LENGTH,0);//fill tag later cipher_text.resize(GCM_NONCE_LENGTH+GCM_TAG_LENGTH+plain_text_len); //do the real encryption. int out_len=plain_text_len; const int ret = EVP_CipherUpdate(&ctx,&cipher_text[GCM_NONCE_LENGTH+GCM_TAG_LENGTH],&out_len, plain_text,plain_text_len); if(1!=ret){ cipher_text.clear(); return LIB_ERR; } out_len=0; if(1 != EVP_CipherFinal_ex(&ctx,cipher_text.end(),out_len) ){ cipher_text.clear(); return LIB_ERR; } /* Get the tag */ if(1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, &cipher_text[GCM_NONCE_LENGTH])){ cipher_text.clear(); return LIB_ERR; } return OK; }
Value walletpassphrasechange(const Array& params, bool fHelp) { if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( "walletpassphrasechange <oldpassphrase> <newpassphrase>\n" "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>."); if (fHelp) return true; if (!pwalletMain->IsCrypted()) throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called."); // TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string) // Alternately, find a way to make params[0] mlock()'d to begin with. SecureString strOldWalletPass; strOldWalletPass.reserve(100); strOldWalletPass = params[0].get_str().c_str(); SecureString strNewWalletPass; strNewWalletPass.reserve(100); strNewWalletPass = params[1].get_str().c_str(); if (strOldWalletPass.length() < 1 || strNewWalletPass.length() < 1) throw runtime_error( "walletpassphrasechange <oldpassphrase> <newpassphrase>\n" "Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>."); if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); return Value::null; }
void MinerAutoUnlockFeature(CWallet *pwallet) { /////////////////////// Auto Unlock Feature for Research Miner if (pwallet->IsLocked()) { //11-5-2014 R Halford - If wallet is locked - see if user has an encrypted password stored: std::string passphrase = ""; if (mapArgs.count("-autounlock")) { passphrase = GetArg("-autounlock", ""); } if (passphrase.length() > 1) { std::string decrypted = AdvancedDecryptWithHWID(passphrase); //Unlock the wallet for 10 days (Equivalent to: walletpassphrase mylongpass 999999) FOR STAKING ONLY! int64_t nSleepTime = 9999999; SecureString strWalletPass; strWalletPass.reserve(100); strWalletPass = decrypted.c_str(); if (strWalletPass.length() > 0) { if (!pwallet->Unlock(strWalletPass)) { LogPrintf("GridcoinResearchMiner:AutoUnlock:Error: The wallet passphrase entered was incorrect."); } else { NewThread(ThreadTopUpKeyPool,NULL); int64_t* pnSleepTime = new int64_t(nSleepTime); NewThread(ThreadCleanWalletPassphrase, pnSleepTime); fWalletUnlockStakingOnly = true; } } } } return; // End of AutoUnlock Feature }
vector<unsigned char> Convert (SecureString hexNumber) // assumes 2 character string with legal hex digits { vector<unsigned char> chars; int size = hexNumber.length(); for (int i = 0; i < size; i+=2) { char highOrderDig = hexNumber[i]; char lowOrderDig = hexNumber[i+1]; int lowOrderValue = GetDigitValue(lowOrderDig);//; convert lowOrderDig to number from 0 to 15 int highOrderValue = GetDigitValue(highOrderDig);//; convert highOrderDig to number from 0 to 15 chars.push_back(lowOrderValue + 16 * highOrderValue); } return chars; }
void CKeePassIntegrator::rpcSetLogin(const SecureString& strWalletPass, const SecureString& sEntryId) { // Convert key format SecureString sKey = DecodeBase64Secure(sKeyBase64); CKeePassRequest request(sKey, "set-login"); request.addStrParameter("Id", sKeePassId); request.addStrParameter("Url", sUrl); if(fDebug) LogPrintf("CKeePassIntegrator::rpcSetLogin - send Url: %s\n", sUrl.c_str()); //request.addStrParameter("SubmitUrl", sSubmitUrl); // Is used to construct the entry title request.addStrParameter("Login", SecureString("Nodes")); request.addStrParameter("Password", strWalletPass); if(sEntryId.size() != 0) { request.addStrParameter("Uuid", sEntryId); // Update existing } int nStatus; std::string sResponse; doHTTPPost(request.getJson(), nStatus, sResponse); if(fDebug) LogPrintf("CKeePassIntegrator::rpcSetLogin - send result: status: %d response: %s\n", nStatus, sResponse.c_str()); if(nStatus != 200) { std::string sErrorMessage = "Error returned: HTTP code "; sErrorMessage += boost::lexical_cast<std::string>(nStatus); sErrorMessage += " - Response: "; sErrorMessage += " response: ["; sErrorMessage += sResponse; sErrorMessage += "]"; throw std::runtime_error(sErrorMessage); } // Parse the response CKeePassResponse response(sKey, sResponse); if(!response.getSuccess()) { throw std::runtime_error("KeePassHttp returned failure status"); } }
bool myPwdCompare(Pwd* a, Pwd* b) { SecureString aSstr = a->GetDescription(); const char* aStr = aSstr.getUnsecureString(); SecureString bSstr = b->GetDescription(); const char* bStr = bSstr.getUnsecureString(); bool res = _strcmpi(aStr, bStr) < 0; aSstr.UnsecuredStringFinished(); bSstr.UnsecuredStringFinished(); return res; }
bool OldSetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod, unsigned char* chKey, unsigned char* chIV) { if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false; int i = 0; if (nDerivationMethod == 0) i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); if (i != (int)WALLET_CRYPTO_KEY_SIZE) { memory_cleanse(chKey, WALLET_CRYPTO_KEY_SIZE); memory_cleanse(chIV, WALLET_CRYPTO_IV_SIZE); return false; } return true; }
PwdList::PwdVector PwdList::Filter(const SecureString& pattern, const PwdLabelVector& labels) { std::lock_guard<std::recursive_mutex> lock(mutex_lock); PwdVector filtered; if (pattern.length() > 0) { SecureString patternCpy = pattern; char* strPtrn = (char*)patternCpy.getUnsecureString(); for (auto it = pwds.begin(); it != pwds.end(); it++) { SecureString description = (*it)->GetDescription(); if (strcasestr((char*)description.getUnsecureString(), strPtrn) != NULL) { filtered.push_back((*it)); } description.UnsecuredStringFinished(); } patternCpy.UnsecuredStringFinished(); } else { filtered = PwdVector(pwds.begin(), pwds.end()); } if (labels.size() > 0) { for (auto iLabel = labels.begin(); iLabel != labels.end(); iLabel++) { PwdVector passed; for (auto iPwd = filtered.begin(); iPwd != filtered.end(); iPwd++) { if ((*iPwd)->HasLabel(*iLabel)) { passed.push_back(*iPwd); } } filtered = passed; } } pwds.sort(myPwdCompare); return filtered; }
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) { if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) return false; int i = 0; if (nDerivationMethod == 0) i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); if (i != (int)WALLET_CRYPTO_KEY_SIZE) { OPENSSL_cleanse(chKey, sizeof(chKey)); OPENSSL_cleanse(chIV, sizeof(chIV)); return false; } fKeySet = true; return true; }
int Decrypt_AesGcm128(const uint8_t * cipher_text, uint32_t cipher_text_len, const SecureString & key, string & plain_text){ EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); EVP_CIPHER * cipher=EVP_aes_128_gcm(); if(1 != EVP_DecryptInit_ex(&ctx, cipher, NULL, NULL, NULL)) return false; if(1 != EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, GCM_NONCE_LENGTH, NULL)) return false; unsigned char nonce[GCM_NONCE_LENGTH]={}; if(1 != EVP_EncryptInit_ex(&ctx, NULL, NULL, key.data(), cipher_text)) return false; int outl=out.size(); const int ret = EVP_CipherUpdate(&ctx,&out[0],outl,&in[0],in.size()); if(1==ret){ out.resize(outl); return true; } out.resize(EVP_CIPHER_CTX_block_size(&ctx)); /* Set expected tag value. Works in OpenSSL 1.0.1d and later */ if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag)) return false; if(1 != EVP_CipherFinal_ex(&ctx,out.data(),outl) ){ return false; } out.resize(outl); return OK; }
bool Exporter::write(const SecureByteArray &data, const SecureString &pwd) { Q_D(Exporter); Q_ASSERT((data.size() % Crypter::AESBlockSize) == 0); QByteArray salt = Crypter::generateSalt(); SecureByteArray iv; SecureByteArray key; Crypter::makeKeyAndIVFromPassword(pwd.toUtf8(), salt, key, iv); CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption enc; enc.SetKeyWithIV(reinterpret_cast<const byte*>(key.constData()), key.size(), reinterpret_cast<const byte*>(iv.constData())); const int cipherSize = data.size(); QByteArray cipher(cipherSize, static_cast<char>(0)); CryptoPP::ArraySource s( reinterpret_cast<const byte*>(data.constData()), data.size(), true, new CryptoPP::StreamTransformationFilter( enc, new CryptoPP::ArraySink(reinterpret_cast<byte*>(cipher.data()), cipher.size()), CryptoPP::StreamTransformationFilter::NO_PADDING ) ); Q_UNUSED(s); // just to please the compiler QFile file(d->filename); bool opened = file.open(QIODevice::WriteOnly); if (!opened) return false; QByteArray block = salt + cipher; file.write(PemPreamble.toUtf8()); file.write("\n"); const SecureByteArray &b64 = block.toBase64(); for (int i = 0; i < b64.size(); i += 64) { file.write(b64.mid(i, qMin(64, b64.size() - i))); file.write("\n"); } file.write(PemEpilog.toUtf8()); file.write("\n"); file.close(); return true; }
void CKeePassIntegrator::rpcAssociate(std::string& sId, SecureString& sKeyBase64) { sKey = generateRandomKey(KEEPASS_CRYPTO_KEY_SIZE); CKeePassRequest request(sKey, "associate"); sKeyBase64 = EncodeBase64Secure(sKey); request.addStrParameter("Key", std::string(&sKeyBase64[0], sKeyBase64.size())); int nStatus; std::string sResponse; doHTTPPost(request.getJson(), nStatus, sResponse); if(fDebug) LogPrintf("CKeePassIntegrator::rpcAssociate - send result: status: %d response: %s\n", nStatus, sResponse.c_str()); if(nStatus != 200) { std::string sErrorMessage = "Error returned: HTTP code "; sErrorMessage += boost::lexical_cast<std::string>(nStatus); sErrorMessage += " - Response: "; sErrorMessage += " response: ["; sErrorMessage += sResponse; sErrorMessage += "]"; throw std::runtime_error(sErrorMessage); } // Parse the response CKeePassResponse response(sKey, sResponse); if(!response.getSuccess()) { throw std::runtime_error("KeePassHttp returned failure status"); } // If we got here, we were successful. Return the information sId = response.getStr("Id"); }