std::optional<Salt> readOrMakeSalt(const String& path) { auto cpath = WebCore::fileSystemRepresentation(path); auto fd = open(cpath.data(), O_RDONLY, 0); Salt salt; auto bytesRead = read(fd, salt.data(), salt.size()); close(fd); if (bytesRead != salt.size()) { salt = makeSalt(); unlink(cpath.data()); fd = open(cpath.data(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); bool success = write(fd, salt.data(), salt.size()) == salt.size(); close(fd); if (!success) return { }; } return salt; }
SHA1::Digest computeSHA1(const Data& data, const Salt& salt) { SHA1 sha1; sha1.addBytes(salt.data(), salt.size()); data.apply([&sha1](const uint8_t* data, size_t size) { sha1.addBytes(data, size); return true; }); SHA1::Digest digest; sha1.computeHash(digest); return digest; }
PBE::PBE (const std::string &password, const Salt &salt, int iterationCount, int keyLength) { Botan::Algorithm_Factory& af = Botan::global_state().algorithm_factory(); Botan::MessageAuthenticationCode *prf = af.make_mac("HMAC(SHA-256)"); Botan::PKCS5_PBKDF2 kdf(prf); Botan::OctetString key = kdf.derive_key(keyLength/8, password, salt.data(), salt.size(), iterationCount); secretKey.assign(key.begin(), key.end()); cryptor = new CryptorAES(secretKey); LogDebug(mailiverse::core::crypt::PBE, "derived: " << toString(toBlockBase64(secretKey)) << " using " << toString(toBlockBase64(salt)) << " password " << password); }