Botan  2.4.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() == "EMSA-PKCS1-v1_5" ||
59  req.algo_name() == "EMSA3")
60  {
61  if(req.arg_count() == 2 && req.arg(0) == "Raw")
62  {
63  return new EMSA_PKCS1v15_Raw(req.arg(1));
64  }
65  else if(req.arg_count() == 1)
66  {
67  if(req.arg(0) == "Raw")
68  {
69  return new EMSA_PKCS1v15_Raw;
70  }
71  else
72  {
73  if(auto hash = HashFunction::create(req.arg(0)))
74  {
75  return new EMSA_PKCS1v15(hash.release());
76  }
77  }
78  }
79  }
80 #endif
81 
82 #if defined(BOTAN_HAS_EMSA_PSSR)
83  if(req.algo_name() == "PSSR" ||
84  req.algo_name() == "EMSA-PSS" ||
85  req.algo_name() == "PSS-MGF1" ||
86  req.algo_name() == "EMSA4" ||
87  req.algo_name() == "PSSR_Raw")
88  {
89  if(req.arg_count_between(1, 3))
90  {
91  if(req.arg(1, "MGF1") != "MGF1")
92  return nullptr; // not supported
93 
94  if(auto h = HashFunction::create(req.arg(0)))
95  {
96  const size_t salt_size = req.arg_as_integer(2, h->output_length());
97 
98  if(req.algo_name() == "PSSR_Raw")
99  return new PSSR_Raw(h.release(), salt_size);
100  else
101  return new PSSR(h.release(), salt_size);
102  }
103  }
104  }
105 #endif
106 
107 #if defined(BOTAN_HAS_ISO_9796)
108  if(req.algo_name() == "ISO_9796_DS2")
109  {
110  if(req.arg_count_between(1, 3))
111  {
112  if(auto h = HashFunction::create(req.arg(0)))
113  {
114  const size_t salt_size = req.arg_as_integer(2, h->output_length());
115  const bool implicit = req.arg(1, "exp") == "imp";
116  return new ISO_9796_DS2(h.release(), implicit, salt_size);
117  }
118  }
119  }
120  //ISO-9796-2 DS 3 is deterministic and DS2 without a salt
121  if(req.algo_name() == "ISO_9796_DS3")
122  {
123  if(req.arg_count_between(1, 2))
124  {
125  if(auto h = HashFunction::create(req.arg(0)))
126  {
127  const bool implicit = req.arg(1, "exp") == "imp";
128  return new ISO_9796_DS3(h.release(), implicit);
129  }
130  }
131  }
132 #endif
133 
134 #if defined(BOTAN_HAS_EMSA_X931)
135  if(req.algo_name() == "EMSA_X931" ||
136  req.algo_name() == "EMSA2" ||
137  req.algo_name() == "X9.31")
138  {
139  if(req.arg_count() == 1)
140  {
141  if(auto hash = HashFunction::create(req.arg(0)))
142  {
143  return new EMSA_X931(hash.release());
144  }
145  }
146  }
147 #endif
148 
149 #if defined(BOTAN_HAS_EMSA_RAW)
150  if(req.algo_name() == "Raw")
151  {
152  if(req.arg_count() == 0)
153  {
154  return new EMSA_Raw;
155  }
156  else
157  {
158  auto hash = HashFunction::create(req.arg(0));
159  if(hash)
160  return new EMSA_Raw(hash->output_length());
161  }
162  }
163 #endif
164 
165  throw Algorithm_Not_Found(algo_spec);
166  }
167 
168 std::string hash_for_emsa(const std::string& algo_spec)
169  {
170  SCAN_Name emsa_name(algo_spec);
171 
172  if(emsa_name.arg_count() > 0)
173  {
174  const std::string pos_hash = emsa_name.arg(0);
175  return pos_hash;
176  }
177 
178  return "SHA-512"; // safe default if nothing we understand
179  }
180 
181 }
182 
183 
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:168
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:106
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