Coverage Report

Created: 2020-06-30 13:58

/src/botan/src/lib/x509/datastor.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Data Store
3
* (C) 1999-2007 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/datastor.h>
9
#include <botan/exceptn.h>
10
#include <botan/parsing.h>
11
#include <botan/hex.h>
12
#include <botan/internal/stl_util.h>
13
14
namespace Botan {
15
16
/*
17
* Data_Store Equality Comparison
18
*/
19
bool Data_Store::operator==(const Data_Store& other) const
20
0
   {
21
0
   return (m_contents == other.m_contents);
22
0
   }
23
24
/*
25
* Check if this key has at least one value
26
*/
27
bool Data_Store::has_value(const std::string& key) const
28
0
   {
29
0
   return (m_contents.lower_bound(key) != m_contents.end());
30
0
   }
31
32
/*
33
* Search based on an arbitrary predicate
34
*/
35
std::multimap<std::string, std::string> Data_Store::search_for(
36
   std::function<bool (std::string, std::string)> predicate) const
37
0
   {
38
0
   std::multimap<std::string, std::string> out;
39
0
40
0
   for(auto i = m_contents.begin(); i != m_contents.end(); ++i)
41
0
      if(predicate(i->first, i->second))
42
0
         out.insert(std::make_pair(i->first, i->second));
43
0
44
0
   return out;
45
0
   }
46
47
/*
48
* Search based on key equality
49
*/
50
std::vector<std::string> Data_Store::get(const std::string& looking_for) const
51
0
   {
52
0
   std::vector<std::string> out;
53
0
   auto range = m_contents.equal_range(looking_for);
54
0
   for(auto i = range.first; i != range.second; ++i)
55
0
      out.push_back(i->second);
56
0
   return out;
57
0
   }
58
59
/*
60
* Get a single atom
61
*/
62
std::string Data_Store::get1(const std::string& key) const
63
0
   {
64
0
   std::vector<std::string> vals = get(key);
65
0
66
0
   if(vals.empty())
67
0
      throw Invalid_State("Data_Store::get1: No values set for " + key);
68
0
   if(vals.size() > 1)
69
0
      throw Invalid_State("Data_Store::get1: More than one value for " + key);
70
0
71
0
   return vals[0];
72
0
   }
73
74
std::string Data_Store::get1(const std::string& key,
75
                             const std::string& default_value) const
76
0
   {
77
0
   std::vector<std::string> vals = get(key);
78
0
79
0
   if(vals.size() > 1)
80
0
      throw Invalid_State("Data_Store::get1: More than one value for " + key);
81
0
82
0
   if(vals.empty())
83
0
      return default_value;
84
0
85
0
   return vals[0];
86
0
   }
87
88
/*
89
* Get a single std::vector atom
90
*/
91
std::vector<uint8_t>
92
Data_Store::get1_memvec(const std::string& key) const
93
0
   {
94
0
   std::vector<std::string> vals = get(key);
95
0
96
0
   if(vals.empty())
97
0
      return std::vector<uint8_t>();
98
0
99
0
   if(vals.size() > 1)
100
0
      throw Invalid_State("Data_Store::get1_memvec: Multiple values for " +
101
0
                          key);
102
0
103
0
   return hex_decode(vals[0]);
104
0
   }
105
106
/*
107
* Get a single uint32_t atom
108
*/
109
uint32_t Data_Store::get1_uint32(const std::string& key,
110
                                 uint32_t default_val) const
111
0
   {
112
0
   std::vector<std::string> vals = get(key);
113
0
114
0
   if(vals.empty())
115
0
      return default_val;
116
0
   else if(vals.size() > 1)
117
0
      throw Invalid_State("Data_Store::get1_uint32: Multiple values for " + key);
118
0
119
0
   return to_u32bit(vals[0]);
120
0
   }
121
122
/*
123
* Insert a single key and value
124
*/
125
void Data_Store::add(const std::string& key, const std::string& val)
126
15.2k
   {
127
15.2k
   multimap_insert(m_contents, key, val);
128
15.2k
   }
129
130
/*
131
* Insert a single key and value
132
*/
133
void Data_Store::add(const std::string& key, uint32_t val)
134
13.4k
   {
135
13.4k
   add(key, std::to_string(val));
136
13.4k
   }
137
138
/*
139
* Insert a single key and value
140
*/
141
void Data_Store::add(const std::string& key, const secure_vector<uint8_t>& val)
142
0
   {
143
0
   add(key, hex_encode(val.data(), val.size()));
144
0
   }
145
146
void Data_Store::add(const std::string& key, const std::vector<uint8_t>& val)
147
966
   {
148
966
   add(key, hex_encode(val.data(), val.size()));
149
966
   }
150
151
/*
152
* Insert a mapping of key/value pairs
153
*/
154
void Data_Store::add(const std::multimap<std::string, std::string>& in)
155
24.1k
   {
156
24.1k
   std::multimap<std::string, std::string>::const_iterator i = in.begin();
157
102k
   while(i != in.end())
158
78.3k
      {
159
78.3k
      m_contents.insert(*i);
160
78.3k
      ++i;
161
78.3k
      }
162
24.1k
   }
163
164
/*
165
* Create and populate a X509_DN
166
*/
167
X509_DN create_dn(const Data_Store& info)
168
0
   {
169
0
   auto names = info.search_for(
170
0
      [](const std::string& key, const std::string&)
171
0
      {
172
0
         return (key.find("X520.") != std::string::npos);
173
0
      });
174
0
175
0
   X509_DN dn;
176
0
177
0
   for(auto i = names.begin(); i != names.end(); ++i)
178
0
      dn.add_attribute(i->first, i->second);
179
0
180
0
   return dn;
181
0
   }
182
183
/*
184
* Create and populate an AlternativeName
185
*/
186
AlternativeName create_alt_name(const Data_Store& info)
187
0
   {
188
0
   auto names = info.search_for(
189
0
      [](const std::string& key, const std::string&)
190
0
      {
191
0
         return (key == "RFC822" ||
192
0
                 key == "DNS" ||
193
0
                 key == "URI" ||
194
0
                 key == "IP");
195
0
      });
196
0
197
0
   AlternativeName alt_name;
198
0
199
0
   for(auto i = names.begin(); i != names.end(); ++i)
200
0
      alt_name.add_attribute(i->first, i->second);
201
0
202
0
   return alt_name;
203
0
   }
204
205
}