in wangle/ssl/SSLUtil.cpp [158:206]
folly::Optional<std::string> SSLUtil::decryptOpenSSLEncFilePassString(
const std::string& filename,
const std::string& password,
const EVP_CIPHER* cipher,
const EVP_MD* digest) {
// Most of this code adapted from openssl/apps/enc.c
const std::string magic = "Salted__";
std::array<unsigned char, EVP_MAX_KEY_LENGTH> key;
std::array<unsigned char, EVP_MAX_IV_LENGTH> iv;
// Read encrypted file into string
std::string fileData;
if (!folly::readFile(filename.c_str(), fileData)) {
LOG(ERROR) << "Error reading file: " << filename;
return folly::none;
}
if (fileData.size() < magic.size() + PKCS5_SALT_LEN) {
LOG(ERROR) << "Not a valid encrypted file.";
return folly::none;
}
// Parse file contents into magic number, salt, and encrypted content
auto fileMagic = fileData.substr(0, magic.size());
if (fileMagic.compare(magic) != 0) {
LOG(ERROR) << "Incorrect magic number in file.";
return folly::none;
}
auto salt = fileData.substr(magic.size(), PKCS5_SALT_LEN);
auto ciphertext = fileData.substr(magic.size() + PKCS5_SALT_LEN);
// Construct key and iv from password
DCHECK_LE(password.size(), std::numeric_limits<int>::max());
EVP_BytesToKey(
cipher,
digest,
reinterpret_cast<const unsigned char*>(salt.data()),
reinterpret_cast<const unsigned char*>(password.data()),
folly::to_narrow(folly::to_signed(password.size())),
1 /* one round */,
key.data(),
iv.data());
// Decrypt content using key and iv
return decrypt(
folly::range(folly::StringPiece(ciphertext)),
folly::range(key),
folly::range(iv),
cipher);
}