40 auto next_line = [&](std::size_t& pos) -> std::string_view {
41 const std::size_t nl = blob.find(
'\n', pos);
42 const std::size_t
end = nl == std::string_view::npos ? blob.size() : nl;
43 std::string_view line = blob.substr(pos,
end - pos);
44 pos = nl == std::string_view::npos ? blob.size() : nl + 1;
46 if (!line.empty() && line.back() ==
'\r') line.remove_suffix(1);
51 const std::string_view pub_b64 = next_line(pos);
52 const std::string_view priv_b64 = next_line(pos);
55 if (!pub || !priv || pub->empty() || priv->empty())
return std::nullopt;
56 return KeyMaterial{std::move(*pub), std::move(*priv)};
67 if (std::filesystem::exists(path, ec)) {
68 std::ifstream in(path, std::ios::binary);
69 std::string blob((std::istreambuf_iterator<char>(in)),
70 std::istreambuf_iterator<char>());
74 if (!kp)
return std::nullopt;
76 std::filesystem::create_directories(path.parent_path(), ec);
78 std::ofstream out(path, std::ios::binary | std::ios::trunc);
79 if (!out)
return std::nullopt;
82 std::filesystem::permissions(path, std::filesystem::perms::owner_read |
83 std::filesystem::perms::owner_write,
84 std::filesystem::perm_options::replace, ec);
std::optional< Ed25519KeyPair > ed25519_keypair_generate()
Generate a fresh Ed25519 keypair using mbedTLS CTR-DRBG for entropy.
std::optional< std::vector< uint8_t > > base64_decode(std::string_view input)
Decode base64 string to binary data. Returns nullopt on invalid input.
std::string base64_encode(const uint8_t *data, size_t length)
Encode binary data to base64 string.