Coverage Report

Created: 2021-10-13 08:49

/src/botan/src/lib/pubkey/xmss/xmss_publickey.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * XMSS Public Key
3
 * An XMSS: Extended Hash-Based Siganture public key.
4
 * The XMSS public key does not support the X509 standard. Instead the
5
 * raw format described in [1] is used.
6
 *
7
 * [1] XMSS: Extended Hash-Based Signatures,
8
 *     Request for Comments: 8391
9
 *     Release: May 2018.
10
 *     https://datatracker.ietf.org/doc/rfc8391/
11
 *
12
 * (C) 2016,2017 Matthias Gierlings
13
 *
14
 * Botan is released under the Simplified BSD License (see license.txt)
15
 **/
16
17
#include <botan/xmss.h>
18
#include <botan/internal/xmss_verification_operation.h>
19
#include <botan/der_enc.h>
20
#include <botan/ber_dec.h>
21
#include <iterator>
22
23
namespace Botan {
24
25
namespace {
26
27
// fall back to raw decoding for previous versions, which did not encode an OCTET STRING
28
std::vector<uint8_t> extract_raw_key(const std::vector<uint8_t>& key_bits)
29
0
   {
30
0
   std::vector<uint8_t> raw_key;
31
0
   try
32
0
      {
33
0
      BER_Decoder(key_bits).decode(raw_key, ASN1_Type::OctetString);
34
0
      }
35
0
   catch(Decoding_Error&)
36
0
      {
37
0
      raw_key = key_bits;
38
0
      }
39
0
   return raw_key;
40
0
   }
41
42
}
43
44
XMSS_PublicKey::XMSS_PublicKey(XMSS_Parameters::xmss_algorithm_t xmss_oid,
45
                               RandomNumberGenerator& rng)
46
   : m_xmss_params(xmss_oid), m_wots_params(m_xmss_params.ots_oid()),
47
     m_root(m_xmss_params.element_size()),
48
     m_public_seed(rng.random_vec(m_xmss_params.element_size()))
49
0
   {}
Unexecuted instantiation: Botan::XMSS_PublicKey::XMSS_PublicKey(Botan::XMSS_Parameters::xmss_algorithm_t, Botan::RandomNumberGenerator&)
Unexecuted instantiation: Botan::XMSS_PublicKey::XMSS_PublicKey(Botan::XMSS_Parameters::xmss_algorithm_t, Botan::RandomNumberGenerator&)
50
51
XMSS_PublicKey::XMSS_PublicKey(const std::vector<uint8_t>& key_bits)
52
   : m_raw_key(extract_raw_key(key_bits)),
53
     m_xmss_params(XMSS_PublicKey::deserialize_xmss_oid(m_raw_key)),
54
     m_wots_params(m_xmss_params.ots_oid())
55
0
   {
56
0
   if(m_raw_key.size() < XMSS_PublicKey::size())
57
0
      {
58
0
      throw Decoding_Error("Invalid XMSS public key size detected");
59
0
      }
60
61
   // extract & copy root from raw key
62
0
   m_root.clear();
63
0
   m_root.reserve(m_xmss_params.element_size());
64
0
   auto begin = m_raw_key.begin() + sizeof(uint32_t);
65
0
   auto end = begin + m_xmss_params.element_size();
66
0
   std::copy(begin, end, std::back_inserter(m_root));
67
68
   // extract & copy public seed from raw key
69
0
   begin = end;
70
0
   end = begin + m_xmss_params.element_size();
71
0
   m_public_seed.clear();
72
0
   m_public_seed.reserve(m_xmss_params.element_size());
73
0
   std::copy(begin, end, std::back_inserter(m_public_seed));
74
0
   }
Unexecuted instantiation: Botan::XMSS_PublicKey::XMSS_PublicKey(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
Unexecuted instantiation: Botan::XMSS_PublicKey::XMSS_PublicKey(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&)
75
76
XMSS_Parameters::xmss_algorithm_t
77
XMSS_PublicKey::deserialize_xmss_oid(const std::vector<uint8_t>& raw_key)
78
0
   {
79
0
   if(raw_key.size() < 4)
80
0
      {
81
0
      throw Decoding_Error("XMSS signature OID missing.");
82
0
      }
83
84
   // extract and convert algorithm id to enum type
85
0
   uint32_t raw_id = 0;
86
0
   for(size_t i = 0; i < 4; i++)
87
0
      { raw_id = ((raw_id << 8) | raw_key[i]); }
88
89
0
   return static_cast<XMSS_Parameters::xmss_algorithm_t>(raw_id);
90
0
   }
91
92
std::unique_ptr<PK_Ops::Verification>
93
XMSS_PublicKey::create_verification_op(const std::string&,
94
                                       const std::string& provider) const
95
0
   {
96
0
   if(provider == "base" || provider.empty())
97
0
      {
98
0
      return std::unique_ptr<PK_Ops::Verification>(
99
0
                new XMSS_Verification_Operation(*this));
100
0
      }
101
0
   throw Provider_Not_Found(algo_name(), provider);
102
0
   }
103
104
std::vector<uint8_t> XMSS_PublicKey::raw_public_key() const
105
0
   {
106
0
   std::vector<uint8_t> result
107
0
      {
108
0
      static_cast<uint8_t>(m_xmss_params.oid() >> 24),
109
0
      static_cast<uint8_t>(m_xmss_params.oid() >> 16),
110
0
      static_cast<uint8_t>(m_xmss_params.oid() >>  8),
111
0
      static_cast<uint8_t>(m_xmss_params.oid())
112
0
      };
113
114
0
   std::copy(m_root.begin(), m_root.end(), std::back_inserter(result));
115
0
   std::copy(m_public_seed.begin(),
116
0
             m_public_seed.end(),
117
0
             std::back_inserter(result));
118
119
0
   return result;
120
0
   }
121
122
std::vector<uint8_t> XMSS_PublicKey::public_key_bits() const
123
0
   {
124
0
   std::vector<uint8_t> output;
125
0
   DER_Encoder(output).encode(raw_public_key(), ASN1_Type::OctetString);
126
0
   return output;
127
0
   }
128
129
}