diff options
author | René Korthaus <[email protected]> | 2019-10-19 07:20:50 +0200 |
---|---|---|
committer | René Korthaus <[email protected]> | 2019-10-21 16:56:24 +0200 |
commit | 84b8d3eeee5aaf29046091c0e675cfeb8c6434b8 (patch) | |
tree | ab56ae27ad340b1dc61eeaaffa25995fce8d30af /src/lib/pubkey | |
parent | cb34802ed24b0963ed5a0180236cabd593268987 (diff) |
Add support for XMSS X.509 certificates
Diffstat (limited to 'src/lib/pubkey')
-rw-r--r-- | src/lib/pubkey/xmss/xmss_parameters.cpp | 2 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_privatekey.cpp | 29 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_privatekey.h | 1 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_publickey.cpp | 35 | ||||
-rw-r--r-- | src/lib/pubkey/xmss/xmss_publickey.h | 32 |
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; |