Botan  2.8.0
Crypto and TLS for C++11
emsa.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2015 Jack Lloyd
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/emsa.h>
8 #include <botan/hash.h>
9 #include <botan/scan_name.h>
10 #include <botan/exceptn.h>
11 
12 #if defined(BOTAN_HAS_EMSA1)
13  #include <botan/emsa1.h>
14 #endif
15 
16 #if defined(BOTAN_HAS_EMSA_X931)
17  #include <botan/emsa_x931.h>
18 #endif
19 
20 #if defined(BOTAN_HAS_EMSA_PKCS1)
21  #include <botan/emsa_pkcs1.h>
22 #endif
23 
24 #if defined(BOTAN_HAS_EMSA_PSSR)
25  #include <botan/pssr.h>
26 #endif
27 
28 #if defined(BOTAN_HAS_EMSA_RAW)
29  #include <botan/emsa_raw.h>
30 #endif
31 
32 #if defined(BOTAN_HAS_ISO_9796)
33  #include <botan/iso9796.h>
34 #endif
35 
36 namespace Botan {
37 
39  const std::string&) const
40  {
41  throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects");
42  }
43 
44 EMSA* get_emsa(const std::string& algo_spec)
45  {
46  SCAN_Name req(algo_spec);
47 
48 #if defined(BOTAN_HAS_EMSA1)
49  if(req.algo_name() == "EMSA1" && req.arg_count() == 1)
50  {
51  if(auto hash = HashFunction::create(req.arg(0)))
52  return new EMSA1(hash.release());
53  }
54 #endif
55 
56 #if defined(BOTAN_HAS_EMSA_PKCS1)
57  if(req.algo_name() == "EMSA_PKCS1" ||
58  req.algo_name() == "PKCS1v15" ||
59  req.algo_name() == "EMSA-PKCS1-v1_5" ||
60  req.algo_name() == "EMSA3")
61  {
62  if(req.arg_count() == 2 && req.arg(0) == "Raw")
63  {
64  return new EMSA_PKCS1v15_Raw(req.arg(1));
65  }
66  else if(req.arg_count() == 1)
67  {
68  if(req.arg(0) == "Raw")
69  {
70  return new EMSA_PKCS1v15_Raw;
71  }
72  else
73  {
74  if(auto hash = HashFunction::create(req.arg(0)))
75  {
76  return new EMSA_PKCS1v15(hash.release());
77  }
78  }
79  }
80  }
81 #endif
82 
83 #if defined(BOTAN_HAS_EMSA_PSSR)
84  if(req.algo_name() == "PSS_Raw" ||
85  req.algo_name() == "PSSR_Raw")
86  {
87  if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
88  {
89  if(auto h = HashFunction::create(req.arg(0)))
90  {
91  if(req.arg_count() == 3)
92  {
93  const size_t salt_size = req.arg_as_integer(2, 0);
94  return new PSSR_Raw(h.release(), salt_size);
95  }
96  else
97  {
98  return new PSSR_Raw(h.release());
99  }
100  }
101  }
102  }
103 
104  if(req.algo_name() == "PSS" ||
105  req.algo_name() == "PSSR" ||
106  req.algo_name() == "EMSA-PSS" ||
107  req.algo_name() == "PSS-MGF1" ||
108  req.algo_name() == "EMSA4")
109  {
110  if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
111  {
112  if(auto h = HashFunction::create(req.arg(0)))
113  {
114  if(req.arg_count() == 3)
115  {
116  const size_t salt_size = req.arg_as_integer(2, 0);
117  return new PSSR(h.release(), salt_size);
118  }
119  else
120  {
121  return new PSSR(h.release());
122  }
123  }
124  }
125  }
126 #endif
127 
128 #if defined(BOTAN_HAS_ISO_9796)
129  if(req.algo_name() == "ISO_9796_DS2")
130  {
131  if(req.arg_count_between(1, 3))
132  {
133  if(auto h = HashFunction::create(req.arg(0)))
134  {
135  const size_t salt_size = req.arg_as_integer(2, h->output_length());
136  const bool implicit = req.arg(1, "exp") == "imp";
137  return new ISO_9796_DS2(h.release(), implicit, salt_size);
138  }
139  }
140  }
141  //ISO-9796-2 DS 3 is deterministic and DS2 without a salt
142  if(req.algo_name() == "ISO_9796_DS3")
143  {
144  if(req.arg_count_between(1, 2))
145  {
146  if(auto h = HashFunction::create(req.arg(0)))
147  {
148  const bool implicit = req.arg(1, "exp") == "imp";
149  return new ISO_9796_DS3(h.release(), implicit);
150  }
151  }
152  }
153 #endif
154 
155 #if defined(BOTAN_HAS_EMSA_X931)
156  if(req.algo_name() == "EMSA_X931" ||
157  req.algo_name() == "EMSA2" ||
158  req.algo_name() == "X9.31")
159  {
160  if(req.arg_count() == 1)
161  {
162  if(auto hash = HashFunction::create(req.arg(0)))
163  {
164  return new EMSA_X931(hash.release());
165  }
166  }
167  }
168 #endif
169 
170 #if defined(BOTAN_HAS_EMSA_RAW)
171  if(req.algo_name() == "Raw")
172  {
173  if(req.arg_count() == 0)
174  {
175  return new EMSA_Raw;
176  }
177  else
178  {
179  auto hash = HashFunction::create(req.arg(0));
180  if(hash)
181  return new EMSA_Raw(hash->output_length());
182  }
183  }
184 #endif
185 
186  throw Algorithm_Not_Found(algo_spec);
187  }
188 
189 std::string hash_for_emsa(const std::string& algo_spec)
190  {
191  SCAN_Name emsa_name(algo_spec);
192 
193  if(emsa_name.arg_count() > 0)
194  {
195  const std::string pos_hash = emsa_name.arg(0);
196  return pos_hash;
197  }
198 
199  return "SHA-512"; // safe default if nothing we understand
200  }
201 
202 }
203 
204 
virtual AlgorithmIdentifier config_for_x509(const Private_Key &key, const std::string &cert_hash_name) const
Definition: emsa.cpp:38
size_t arg_count() const
Definition: scan_name.h:49
virtual std::string name() const =0
size_t arg_as_integer(size_t i, size_t def_value) const
Definition: scan_name.cpp:137
size_t salt_size
std::string arg(size_t i) const
Definition: scan_name.cpp:122
std::string hash_for_emsa(const std::string &algo_spec)
Definition: emsa.cpp:189
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:110
Definition: alg_id.cpp:13
const std::string & algo_name() const
Definition: scan_name.h:44
bool arg_count_between(size_t lower, size_t upper) const
Definition: scan_name.h:56
EMSA * get_emsa(const std::string &algo_spec)
Definition: emsa.cpp:44
MechanismType hash