aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey
diff options
context:
space:
mode:
authorRené Korthaus <[email protected]>2019-10-19 07:20:50 +0200
committerRené Korthaus <[email protected]>2019-10-21 16:56:24 +0200
commit84b8d3eeee5aaf29046091c0e675cfeb8c6434b8 (patch)
treeab56ae27ad340b1dc61eeaaffa25995fce8d30af /src/lib/pubkey
parentcb34802ed24b0963ed5a0180236cabd593268987 (diff)
Add support for XMSS X.509 certificates
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r--src/lib/pubkey/xmss/xmss_parameters.cpp2
-rw-r--r--src/lib/pubkey/xmss/xmss_privatekey.cpp29
-rw-r--r--src/lib/pubkey/xmss/xmss_privatekey.h1
-rw-r--r--src/lib/pubkey/xmss/xmss_publickey.cpp35
-rw-r--r--src/lib/pubkey/xmss/xmss_publickey.h32
5 files changed, 74 insertions, 25 deletions
diff --git a/src/lib/pubkey/xmss/xmss_parameters.cpp b/src/lib/pubkey/xmss/xmss_parameters.cpp
index 933072da6..0654821fd 100644
--- a/src/lib/pubkey/xmss/xmss_parameters.cpp
+++ b/src/lib/pubkey/xmss/xmss_parameters.cpp
@@ -176,7 +176,7 @@ XMSS_Parameters::XMSS_Parameters(xmss_algorithm_t oid)
m_wots_oid = XMSS_WOTS_Parameters::ots_algorithm_t::WOTSP_SHAKE_512;
break;
default:
- throw Not_Implemented("Algorithm id does not match any known XMSS algorithm id.");
+ throw Not_Implemented("Algorithm id does not match any known XMSS algorithm id:" + std::to_string(oid));
break;
}
}
diff --git a/src/lib/pubkey/xmss/xmss_privatekey.cpp b/src/lib/pubkey/xmss/xmss_privatekey.cpp
index d4a353d3c..7f6cc5f6f 100644
--- a/src/lib/pubkey/xmss/xmss_privatekey.cpp
+++ b/src/lib/pubkey/xmss/xmss_privatekey.cpp
@@ -17,6 +17,7 @@
#include <botan/xmss_privatekey.h>
#include <botan/internal/xmss_signature_operation.h>
+#include <botan/ber_dec.h>
#if defined(BOTAN_HAS_THREAD_UTILS)
#include <botan/internal/thread_pool.h>
@@ -24,8 +25,26 @@
namespace Botan {
-XMSS_PrivateKey::XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key)
- : XMSS_PublicKey(unlock(raw_key)),
+namespace {
+
+secure_vector<uint8_t> extract_raw_key(const secure_vector<uint8_t>& key_bits)
+{
+ secure_vector<uint8_t> raw_key;
+ try
+ {
+ BER_Decoder(key_bits).decode(raw_key, OCTET_STRING);
+ }
+ catch(Decoding_Error& e)
+ {
+ raw_key = key_bits;
+ }
+ return raw_key;
+}
+
+}
+
+XMSS_PrivateKey::XMSS_PrivateKey(const secure_vector<uint8_t>& key_bits)
+ : XMSS_PublicKey(unlock(key_bits)),
XMSS_Common_Ops(XMSS_PublicKey::m_xmss_params.oid()),
m_wots_priv_key(m_wots_params.oid(), m_public_seed),
m_index_reg(XMSS_Index_Registry::get_instance())
@@ -40,12 +59,14 @@ XMSS_PrivateKey::XMSS_PrivateKey(const secure_vector<uint8_t>& raw_key)
*/
static_assert(sizeof(size_t) >= 4, "size_t is big enough to support leaf index");
+ secure_vector<uint8_t> raw_key = extract_raw_key(key_bits);
+
if(raw_key.size() != XMSS_PrivateKey::size())
{
- throw Decoding_Error("Invalid XMSS private key size detected.");
+ throw Decoding_Error("Invalid XMSS private key size");
}
- // extract & copy unused leaf index from raw_key.
+ // extract & copy unused leaf index from raw_key
uint64_t unused_leaf = 0;
auto begin = (raw_key.begin() + XMSS_PublicKey::size());
auto end = raw_key.begin() + XMSS_PublicKey::size() + sizeof(uint32_t);
diff --git a/src/lib/pubkey/xmss/xmss_privatekey.h b/src/lib/pubkey/xmss/xmss_privatekey.h
index 2bfcbc82e..301fef04b 100644
--- a/src/lib/pubkey/xmss/xmss_privatekey.h
+++ b/src/lib/pubkey/xmss/xmss_privatekey.h
@@ -202,6 +202,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PrivateKey final : public virtual XMSS_PublicKe
secure_vector<uint8_t> private_key_bits() const override
{
+ return DER_Encoder().encode(raw_private_key(), OCTET_STRING).get_contents();
return raw_private_key();
}
diff --git a/src/lib/pubkey/xmss/xmss_publickey.cpp b/src/lib/pubkey/xmss/xmss_publickey.cpp
index 7c7c19fc1..4db7a2232 100644
--- a/src/lib/pubkey/xmss/xmss_publickey.cpp
+++ b/src/lib/pubkey/xmss/xmss_publickey.cpp
@@ -16,26 +16,47 @@
#include <botan/internal/xmss_verification_operation.h>
#include <botan/xmss_publickey.h>
+#include <botan/der_enc.h>
+#include <botan/ber_dec.h>
namespace Botan {
-XMSS_PublicKey::XMSS_PublicKey(const std::vector<uint8_t>& raw_key)
- : m_xmss_params(XMSS_PublicKey::deserialize_xmss_oid(raw_key)),
+namespace {
+
+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& e)
+ {
+ raw_key = key_bits;
+ }
+ return raw_key;
+}
+
+}
+
+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(raw_key.size() < XMSS_PublicKey::size())
+ if(m_raw_key.size() < XMSS_PublicKey::size())
{
- throw Decoding_Error("Invalid XMSS public key size detected.");
+ throw Decoding_Error("Invalid XMSS public key size detected");
}
- // extract & copy root from raw key.
+ // extract & copy root from raw key
m_root.clear();
m_root.reserve(m_xmss_params.element_size());
- auto begin = raw_key.begin() + sizeof(uint32_t);
+ 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.
+ // extract & copy public seed from raw key
begin = end;
end = begin + m_xmss_params.element_size();
m_public_seed.clear();
diff --git a/src/lib/pubkey/xmss/xmss_publickey.h b/src/lib/pubkey/xmss/xmss_publickey.h
index ff56c1378..e055d3a3a 100644
--- a/src/lib/pubkey/xmss/xmss_publickey.h
+++ b/src/lib/pubkey/xmss/xmss_publickey.h
@@ -1,6 +1,7 @@
/*
* XMSS Public Key
* (C) 2016,2017 Matthias Gierlings
+ * (C) 2019 René Korthaus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
**/
@@ -29,8 +30,6 @@ class XMSS_Verification_Operation;
/**
* An XMSS: Extended Hash-Based Signature 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
@@ -56,10 +55,14 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
m_public_seed(rng.random_vec(m_xmss_params.element_size())) {}
/**
- * Creates an XMSS public key from a byte sequence produced by
- * raw_private_key().
- **/
- XMSS_PublicKey(const std::vector<uint8_t>& raw_key);
+ * Loads a public key.
+ *
+ * Public key must be encoded as in RFC
+ * draft-vangeest-x509-hash-sigs-03.
+ *
+ * @param key_bits DER encoded public key bits
+ */
+ XMSS_PublicKey(const std::vector<uint8_t>& key_bits);
/**
* Creates a new XMSS public key for a chosen XMSS signature method as
@@ -121,7 +124,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
/**
* Retrieves the Winternitz One Time Signature (WOTS) method,
- * corrseponding to the chosen XMSS signature method.
+ * corresponding to the chosen XMSS signature method.
*
* @return XMSS WOTS signature method identifier.
**/
@@ -188,7 +191,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
AlgorithmIdentifier algorithm_identifier() const override
{
- return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_NULL_PARAM);
+ return AlgorithmIdentifier(get_oid(), AlgorithmIdentifier::USE_EMPTY_PARAM);
}
bool check_key(RandomNumberGenerator&, bool) const override
@@ -211,14 +214,16 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
}
/**
- * Returns a raw byte sequence as defined in [1].
- * This method acts as an alias for raw_public_key().
+ * Returns the encoded public key as defined in RFC
+ * draft-vangeest-x509-hash-sigs-03.
*
- * @return raw public key bits.
+ * @return encoded public key bits
**/
std::vector<uint8_t> public_key_bits() const override
{
- return raw_public_key();
+ std::vector<uint8_t> output;
+ DER_Encoder(output).encode(raw_public_key(), OCTET_STRING);
+ return output;
}
/**
@@ -233,7 +238,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
}
/**
- * Generates a non standardized byte sequence representing the XMSS
+ * Generates a byte sequence representing the XMSS
* public key, as defined in [1] (p. 23, "XMSS Public Key")
*
* @return 4-byte OID, followed by n-byte root node, followed by
@@ -242,6 +247,7 @@ class BOTAN_PUBLIC_API(2,0) XMSS_PublicKey : public virtual Public_Key
virtual std::vector<uint8_t> raw_public_key() const;
protected:
+ std::vector<uint8_t> m_raw_key;
XMSS_Parameters m_xmss_params;
XMSS_WOTS_Parameters m_wots_params;
secure_vector<uint8_t> m_root;