aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorxiphon <xiphon@protonmail.com>2020-06-10 12:41:41 +0000
committerxiphon <xiphon@protonmail.com>2020-06-10 12:48:55 +0000
commitef5d855950910849c66edc94200c3b604ca06918 (patch)
treead6ffb5c42ff87fa896b1a3a6281867e42c77495 /src
parentc8f4355e15e6574c7139bfb5f6ea195ad4199644 (diff)
downloadmonzero-gui-ef5d855950910849c66edc94200c3b604ca06918.tar.gz
monzero-gui-ef5d855950910849c66edc94200c3b604ca06918.tar.xz
monzero-gui-ef5d855950910849c66edc94200c3b604ca06918.zip
openpgp: implement public subkeys support
Diffstat (limited to 'src')
-rw-r--r--src/openpgp/openpgp.cpp82
-rw-r--r--src/openpgp/openpgp.h19
-rw-r--r--src/openpgp/packet_stream.h12
-rw-r--r--src/openpgp/serialization.h1
-rw-r--r--src/qt/updater.cpp7
-rw-r--r--src/qt/updater.h2
6 files changed, 73 insertions, 50 deletions
diff --git a/src/openpgp/openpgp.cpp b/src/openpgp/openpgp.cpp
index 108990fb..437e0d99 100644
--- a/src/openpgp/openpgp.cpp
+++ b/src/openpgp/openpgp.cpp
@@ -93,15 +93,9 @@ std::string get_armored_block_contents(const std::string &text, const std::strin
} // namespace
-public_key_rsa::public_key_rsa(const std::string &armored)
- : public_key_rsa(decode(armored))
-{
-}
-
-public_key_rsa::public_key_rsa(std::tuple<std::string, s_expression, size_t> params)
- : m_expression(std::move(std::get<1>(params)))
- , m_bits(std::get<2>(params))
- , m_user_id(std::move(std::get<0>(params)))
+public_key_rsa::public_key_rsa(s_expression expression, size_t bits)
+ : m_expression(std::move(expression))
+ , m_bits(bits)
{
}
@@ -115,19 +109,14 @@ size_t public_key_rsa::bits() const
return m_bits;
}
-std::string public_key_rsa::user_id() const
-{
- return m_user_id;
-}
-
-std::tuple<std::string, s_expression, size_t> public_key_rsa::decode(const std::string &armored)
+public_key_block::public_key_block(const std::string &armored)
+ : public_key_block(epee::to_byte_span(epee::to_span(epee::string_encoding::base64_decode(
+ strip_line_breaks(get_armored_block_contents(armored, "BEGIN PGP PUBLIC KEY BLOCK"))))))
{
- const std::string buffer = epee::string_encoding::base64_decode(
- strip_line_breaks(get_armored_block_contents(armored, "BEGIN PGP PUBLIC KEY BLOCK")));
- return decode(epee::to_byte_span(epee::to_span(buffer)));
}
-std::tuple<std::string, s_expression, size_t> public_key_rsa::decode(const epee::span<const uint8_t> buffer)
+// TODO: Public-Key expiration, User ID and Public-Key certification, Subkey binding checks
+public_key_block::public_key_block(const epee::span<const uint8_t> buffer)
{
packet_stream packets(buffer);
@@ -136,38 +125,51 @@ std::tuple<std::string, s_expression, size_t> public_key_rsa::decode(const epee:
{
throw std::runtime_error("user id is missing");
}
- std::string user_id(data->begin(), data->end());
+ m_user_id.assign(data->begin(), data->end());
- data = packets.find_first(packet_tag::type::public_key);
- if (data == nullptr)
- {
- throw std::runtime_error("public key is missing");
- }
+ const auto append_public_key = [this](const std::vector<uint8_t> &data) {
+ deserializer<std::vector<uint8_t>> serialized(data);
- deserializer<std::vector<uint8_t>> serialized(*data);
+ const auto version = serialized.read_big_endian<uint8_t>();
+ if (version != 4)
+ {
+ throw std::runtime_error("unsupported public key version");
+ }
- const auto version = serialized.read_big_endian<uint8_t>();
- if (version != 4)
- {
- throw std::runtime_error("unsupported public key version");
- }
+ /* const auto timestamp = */ serialized.read_big_endian<uint32_t>();
- /* const auto timestamp = */ serialized.read_big_endian<uint32_t>();
+ const auto algorithm = serialized.read_big_endian<uint8_t>();
+ if (algorithm != algorithm::rsa)
+ {
+ throw std::runtime_error("unsupported public key algorithm");
+ }
- const auto algorithm = serialized.read_big_endian<uint8_t>();
- if (algorithm != algorithm::rsa)
+ {
+ const mpi public_key_n = serialized.read_mpi();
+ const mpi public_key_e = serialized.read_mpi();
+
+ emplace_back(
+ s_expression("(public-key (rsa (n %m) (e %m)))", public_key_n.get(), public_key_e.get()),
+ gcry_mpi_get_nbits(public_key_n.get()));
+ }
+ };
+
+ data = packets.find_first(packet_tag::type::public_key);
+ if (data == nullptr)
{
- throw std::runtime_error("unsupported public key algorithm");
+ throw std::runtime_error("public key is missing");
}
+ append_public_key(*data);
- const mpi public_key_n = serialized.read_mpi();
- const mpi public_key_e = serialized.read_mpi();
-
- s_expression expression("(public-key (rsa (n %m) (e %m)))", public_key_n.get(), public_key_e.get());
+ packets.for_each(packet_tag::type::public_subkey, append_public_key);
+}
- return {std::move(user_id), std::move(expression), gcry_mpi_get_nbits(public_key_n.get())};
+std::string public_key_block::user_id() const
+{
+ return m_user_id;
}
+// TODO: Signature expiration check
signature_rsa::signature_rsa(
uint8_t algorithm,
std::pair<uint8_t, uint8_t> hash_leftmost_bytes,
diff --git a/src/openpgp/openpgp.h b/src/openpgp/openpgp.h
index cef003ed..e876ecca 100644
--- a/src/openpgp/openpgp.h
+++ b/src/openpgp/openpgp.h
@@ -47,20 +47,25 @@ enum algorithm : uint8_t
class public_key_rsa
{
public:
- public_key_rsa(const std::string &armored);
- public_key_rsa(std::tuple<std::string, s_expression, size_t> params);
+ public_key_rsa(s_expression expression, size_t bits);
size_t bits() const;
const gcry_sexp_t &get() const;
- std::string user_id() const;
-
-private:
- static std::tuple<std::string, s_expression, size_t> decode(const std::string &armored);
- static std::tuple<std::string, s_expression, size_t> decode(const epee::span<const uint8_t> buffer);
private:
s_expression m_expression;
size_t m_bits;
+};
+
+class public_key_block : public std::vector<public_key_rsa>
+{
+public:
+ public_key_block(const std::string &armored);
+ public_key_block(const epee::span<const uint8_t> buffer);
+
+ std::string user_id() const;
+
+private:
std::string m_user_id;
};
diff --git a/src/openpgp/packet_stream.h b/src/openpgp/packet_stream.h
index b93b8747..6a993e92 100644
--- a/src/openpgp/packet_stream.h
+++ b/src/openpgp/packet_stream.h
@@ -69,6 +69,18 @@ public:
return nullptr;
}
+ template <typename Callback>
+ void for_each(packet_tag::type type, Callback &callback) const
+ {
+ for (const auto &packet : packets)
+ {
+ if (packet.first.packet_type == type)
+ {
+ callback(packet.second);
+ }
+ }
+ }
+
private:
std::vector<std::pair<packet_tag, std::vector<uint8_t>>> packets;
};
diff --git a/src/openpgp/serialization.h b/src/openpgp/serialization.h
index 33de9216..fb42c1b6 100644
--- a/src/openpgp/serialization.h
+++ b/src/openpgp/serialization.h
@@ -60,6 +60,7 @@ struct packet_tag
signature = 2,
public_key = 6,
user_id = 13,
+ public_subkey = 14,
};
const type packet_type;
diff --git a/src/qt/updater.cpp b/src/qt/updater.cpp
index 17d6eddb..0eb79dfe 100644
--- a/src/qt/updater.cpp
+++ b/src/qt/updater.cpp
@@ -157,9 +157,12 @@ QString Updater::verifySignature(const epee::span<const uint8_t> data, const ope
{
for (const auto &maintainer : m_maintainers)
{
- if (signature.verify(data, maintainer))
+ for (const auto &public_key : maintainer)
{
- return QString::fromStdString(maintainer.user_id());
+ if (signature.verify(data, public_key))
+ {
+ return QString::fromStdString(maintainer.user_id());
+ }
}
}
diff --git a/src/qt/updater.h b/src/qt/updater.h
index 48a59a71..e787e42d 100644
--- a/src/qt/updater.h
+++ b/src/qt/updater.h
@@ -60,5 +60,5 @@ private:
QByteArray parseShasumOutput(const QString &message, const QString &filename) const;
private:
- std::vector<openpgp::public_key_rsa> m_maintainers;
+ std::vector<openpgp::public_key_block> m_maintainers;
};