summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp')
-rw-r--r--comm/third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp129
1 files changed, 129 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp b/comm/third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp
new file mode 100644
index 0000000000..f6db6d5026
--- /dev/null
+++ b/comm/third_party/botan/src/lib/pubkey/xmss/xmss_publickey.cpp
@@ -0,0 +1,129 @@
+/*
+ * XMSS Public Key
+ * An XMSS: Extended Hash-Based Siganture public key.
+ * The XMSS public key does not support the X509 standard. Instead the
+ * raw format described in [1] is used.
+ *
+ * [1] XMSS: Extended Hash-Based Signatures,
+ * Request for Comments: 8391
+ * Release: May 2018.
+ * https://datatracker.ietf.org/doc/rfc8391/
+ *
+ * (C) 2016,2017 Matthias Gierlings
+ *
+ * Botan is released under the Simplified BSD License (see license.txt)
+ **/
+
+#include <botan/xmss.h>
+#include <botan/internal/xmss_verification_operation.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
+#include <iterator>
+
+namespace Botan {
+
+namespace {
+
+// fall back to raw decoding for previous versions, which did not encode an OCTET STRING
+std::vector<uint8_t> extract_raw_key(const std::vector<uint8_t>& key_bits)
+ {
+ std::vector<uint8_t> raw_key;
+ try
+ {
+ BER_Decoder(key_bits).decode(raw_key, OCTET_STRING);
+ }
+ catch(Decoding_Error&)
+ {
+ raw_key = key_bits;
+ }
+ return raw_key;
+ }
+
+}
+
+XMSS_PublicKey::XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,
+ RandomNumberGenerator& rng)
+ : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),
+ m_root(m_xmss_params.element_size()),
+ m_public_seed(rng.random_vec(m_xmss_params.element_size()))
+ {}
+
+XMSS_PublicKey::XMSS_PublicKey(const std::vector<uint8_t>& key_bits)
+ : m_raw_key(extract_raw_key(key_bits)),
+ m_xmss_params(XMSS_PublicKey::deserialize_xmss_oid(m_raw_key)),
+ m_wots_params(m_xmss_params.ots_oid())
+ {
+ if(m_raw_key.size() < XMSS_PublicKey::size())
+ {
+ throw Decoding_Error("Invalid XMSS public key size detected");
+ }
+
+ // extract & copy root from raw key
+ m_root.clear();
+ m_root.reserve(m_xmss_params.element_size());
+ auto begin = m_raw_key.begin() + sizeof(uint32_t);
+ auto end = begin + m_xmss_params.element_size();
+ std::copy(begin, end, std::back_inserter(m_root));
+
+ // extract & copy public seed from raw key
+ begin = end;
+ end = begin + m_xmss_params.element_size();
+ m_public_seed.clear();
+ m_public_seed.reserve(m_xmss_params.element_size());
+ std::copy(begin, end, std::back_inserter(m_public_seed));
+ }
+
+XMSS_Parameters::xmss_algorithm_t
+XMSS_PublicKey::deserialize_xmss_oid(const std::vector<uint8_t>& raw_key)
+ {
+ if(raw_key.size() < 4)
+ {
+ throw Decoding_Error("XMSS signature OID missing.");
+ }
+
+ // extract and convert algorithm id to enum type
+ uint32_t raw_id = 0;
+ for(size_t i = 0; i < 4; i++)
+ { raw_id = ((raw_id << 8) | raw_key[i]); }
+
+ return static_cast<XMSS_Parameters::xmss_algorithm_t>(raw_id);
+ }
+
+std::unique_ptr<PK_Ops::Verification>
+XMSS_PublicKey::create_verification_op(const std::string&,
+ const std::string& provider) const
+ {
+ if(provider == "base" || provider.empty())
+ {
+ return std::unique_ptr<PK_Ops::Verification>(
+ new XMSS_Verification_Operation(*this));
+ }
+ throw Provider_Not_Found(algo_name(), provider);
+ }
+
+std::vector<uint8_t> XMSS_PublicKey::raw_public_key() const
+ {
+ std::vector<uint8_t> result
+ {
+ static_cast<uint8_t>(m_xmss_params.oid() >> 24),
+ static_cast<uint8_t>(m_xmss_params.oid() >> 16),
+ static_cast<uint8_t>(m_xmss_params.oid() >> 8),
+ static_cast<uint8_t>(m_xmss_params.oid())
+ };
+
+ std::copy(m_root.begin(), m_root.end(), std::back_inserter(result));
+ std::copy(m_public_seed.begin(),
+ m_public_seed.end(),
+ std::back_inserter(result));
+
+ return result;
+ }
+
+std::vector<uint8_t> XMSS_PublicKey::public_key_bits() const
+ {
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(raw_public_key(), OCTET_STRING);
+ return output;
+ }
+
+}