1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
#include "libfilezilla/signature.hpp"
#include "libfilezilla/encode.hpp"
#include "libfilezilla/util.hpp"
#include <nettle/eddsa.h>
namespace fz {
std::string public_verification_key::to_base64() const
{
auto raw = std::string(key_.cbegin(), key_.cend());
return fz::base64_encode(raw);
}
public_verification_key public_verification_key::from_base64(std::string_view const& base64)
{
public_verification_key ret;
auto raw = fz::base64_decode(base64);
if (raw.size() == key_size) {
auto p = reinterpret_cast<uint8_t const*>(raw.data());
ret.key_.assign(p, p + key_size);
}
return ret;
}
private_signing_key private_signing_key::generate()
{
private_signing_key ret;
ret.key_ = fz::random_bytes(key_size);
return ret;
}
std::string private_signing_key::to_base64() const
{
auto raw = std::string(key_.cbegin(), key_.cend());
return fz::base64_encode(raw);
}
private_signing_key private_signing_key::from_base64(std::string_view const& base64)
{
private_signing_key ret;
auto raw = fz::base64_decode(base64);
if (raw.size() == key_size) {
auto p = reinterpret_cast<uint8_t const*>(raw.data());
ret.key_.assign(p, p + key_size);
}
return ret;
}
public_verification_key private_signing_key::pubkey() const
{
public_verification_key ret;
if (*this) {
ret.key_.resize(public_verification_key::key_size);
nettle_ed25519_sha512_public_key(ret.key_.data(), key_.data());
}
return ret;
}
std::vector<uint8_t> sign(uint8_t const* message, size_t const size, private_signing_key const& priv, bool include_message)
{
std::vector<uint8_t> ret;
auto const pub = priv.pubkey();
if (priv && pub && size) {
size_t retsize = signature_size;
size_t offset{};
if (include_message) {
offset = size;
retsize += size;
ret.reserve(retsize);
ret.assign(message, message + size);
}
ret.resize(retsize);
nettle_ed25519_sha512_sign(pub.key_.data(), priv.data().data(), size, message, ret.data() + offset);
}
return ret;
}
std::vector<uint8_t> sign(std::vector<uint8_t> const& message, private_signing_key const& priv, bool include_message)
{
return sign(message.data(), message.size(), priv, include_message);
}
std::vector<uint8_t> sign(std::string_view const& message, private_signing_key const& priv, bool include_message)
{
return sign(reinterpret_cast<uint8_t const*>(message.data()), message.size(), priv, include_message);
}
bool verify(uint8_t const* message, size_t const message_size, uint8_t const* signature, size_t const sig_size, public_verification_key const& pub)
{
if (!message || !signature || sig_size != signature_size) {
return false;
}
return nettle_ed25519_sha512_verify(pub.key_.data(), message_size, message, signature) == 1;
}
bool verify(std::vector<uint8_t> const& message, std::vector<uint8_t> const& signature, public_verification_key const& pub)
{
return verify(message.data(), message.size(), signature.data(), signature.size(), pub);
}
bool verify(std::string_view const& message, std::string_view const& signature, public_verification_key const& pub)
{
return verify(reinterpret_cast<uint8_t const*>(message.data()), message.size(), reinterpret_cast<uint8_t const*>(signature.data()), signature.size(), pub);
}
bool verify(uint8_t const* message, size_t const size, public_verification_key const& pub)
{
if (!message || size < signature_size) {
return false;
}
return verify(message, size - signature_size, message + (size - signature_size), signature_size, pub);
}
bool verify(std::vector<uint8_t> const& message, public_verification_key const& pub)
{
return verify(message.data(), message.size(), pub);
}
bool verify(std::string_view const& message, public_verification_key const& pub)
{
return verify(reinterpret_cast<uint8_t const*>(message.data()), message.size(), pub);
}
}
|