Coverage Report

Created: 2019-09-11 14:12

/src/botan/src/lib/pk_pad/emsa.cpp
Line
Count
Source (jump to first uncovered line)
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
38
AlgorithmIdentifier EMSA::config_for_x509(const Private_Key&,
39
                                          const std::string&) const
40
0
   {
41
0
   throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects");
42
0
   }
43
44
EMSA* get_emsa(const std::string& algo_spec)
45
7.82k
   {
46
7.82k
   SCAN_Name req(algo_spec);
47
7.82k
48
7.82k
#if defined(BOTAN_HAS_EMSA1)
49
7.82k
   if(req.algo_name() == "EMSA1" && req.arg_count() == 1)
50
1.78k
      {
51
1.78k
      if(auto hash = HashFunction::create(req.arg(0)))
52
1.78k
         return new EMSA1(hash.release());
53
6.03k
      }
54
6.03k
#endif
55
6.03k
56
6.03k
#if defined(BOTAN_HAS_EMSA_PKCS1)
57
6.03k
   if(req.algo_name() == "EMSA_PKCS1" ||
58
6.03k
      req.algo_name() == "PKCS1v15" ||
59
6.03k
      req.algo_name() == "EMSA-PKCS1-v1_5" ||
60
6.03k
      req.algo_name() == "EMSA3")
61
6.01k
      {
62
6.01k
      if(req.arg_count() == 2 && req.arg(0) == "Raw")
63
0
         {
64
0
         return new EMSA_PKCS1v15_Raw(req.arg(1));
65
0
         }
66
6.01k
      else if(req.arg_count() == 1)
67
6.01k
         {
68
6.01k
         if(req.arg(0) == "Raw")
69
0
            {
70
0
            return new EMSA_PKCS1v15_Raw;
71
0
            }
72
6.01k
         else
73
6.01k
            {
74
6.01k
            if(auto hash = HashFunction::create(req.arg(0)))
75
6.01k
               {
76
6.01k
               return new EMSA_PKCS1v15(hash.release());
77
6.01k
               }
78
25
            }
79
6.01k
         }
80
6.01k
      }
81
25
#endif
82
25
83
25
#if defined(BOTAN_HAS_EMSA_PSSR)
84
25
   if(req.algo_name() == "PSS_Raw" ||
85
25
      req.algo_name() == "PSSR_Raw")
86
0
      {
87
0
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
88
0
         {
89
0
         if(auto h = HashFunction::create(req.arg(0)))
90
0
            {
91
0
            if(req.arg_count() == 3)
92
0
               {
93
0
               const size_t salt_size = req.arg_as_integer(2, 0);
94
0
               return new PSSR_Raw(h.release(), salt_size);
95
0
               }
96
0
            else
97
0
               {
98
0
               return new PSSR_Raw(h.release());
99
0
               }
100
25
            }
101
0
         }
102
0
      }
103
25
104
25
   if(req.algo_name() == "PSS" ||
105
25
      req.algo_name() == "PSSR" ||
106
25
      req.algo_name() == "EMSA-PSS" ||
107
25
      req.algo_name() == "PSS-MGF1" ||
108
25
      req.algo_name() == "EMSA4")
109
23
      {
110
23
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
111
23
         {
112
23
         if(auto h = HashFunction::create(req.arg(0)))
113
23
            {
114
23
            if(req.arg_count() == 3)
115
23
               {
116
23
               const size_t salt_size = req.arg_as_integer(2, 0);
117
23
               return new PSSR(h.release(), salt_size);
118
23
               }
119
0
            else
120
0
               {
121
0
               return new PSSR(h.release());
122
0
               }
123
2
            }
124
23
         }
125
23
      }
126
2
#endif
127
2
128
2
#if defined(BOTAN_HAS_ISO_9796)
129
2
   if(req.algo_name() == "ISO_9796_DS2")
130
0
      {
131
0
      if(req.arg_count_between(1, 3))
132
0
         {
133
0
         if(auto h = HashFunction::create(req.arg(0)))
134
0
            {
135
0
            const size_t salt_size = req.arg_as_integer(2, h->output_length());
136
0
            const bool implicit = req.arg(1, "exp") == "imp";
137
0
            return new ISO_9796_DS2(h.release(), implicit, salt_size);
138
0
            }
139
2
         }
140
0
      }
141
2
   //ISO-9796-2 DS 3 is deterministic and DS2 without a salt
142
2
   if(req.algo_name() == "ISO_9796_DS3")
143
0
      {
144
0
      if(req.arg_count_between(1, 2))
145
0
         {
146
0
         if(auto h = HashFunction::create(req.arg(0)))
147
0
            {
148
0
            const bool implicit = req.arg(1, "exp") == "imp";
149
0
            return new ISO_9796_DS3(h.release(), implicit);
150
0
            }
151
2
         }
152
0
      }
153
2
#endif
154
2
155
2
#if defined(BOTAN_HAS_EMSA_X931)
156
2
   if(req.algo_name() == "EMSA_X931" ||
157
2
         req.algo_name() == "EMSA2" ||
158
2
         req.algo_name() == "X9.31")
159
0
      {
160
0
      if(req.arg_count() == 1)
161
0
         {
162
0
         if(auto hash = HashFunction::create(req.arg(0)))
163
0
            {
164
0
            return new EMSA_X931(hash.release());
165
0
            }
166
2
         }
167
0
      }
168
2
#endif
169
2
170
2
#if defined(BOTAN_HAS_EMSA_RAW)
171
2
   if(req.algo_name() == "Raw")
172
0
      {
173
0
      if(req.arg_count() == 0)
174
0
         {
175
0
         return new EMSA_Raw;
176
0
         }
177
0
      else
178
0
         {
179
0
         auto hash = HashFunction::create(req.arg(0));
180
0
         if(hash)
181
0
            return new EMSA_Raw(hash->output_length());
182
2
         }
183
0
      }
184
2
#endif
185
2
186
2
   throw Algorithm_Not_Found(algo_spec);
187
2
   }
188
189
std::string hash_for_emsa(const std::string& algo_spec)
190
7.81k
   {
191
7.81k
   SCAN_Name emsa_name(algo_spec);
192
7.81k
193
7.81k
   if(emsa_name.arg_count() > 0)
194
7.81k
      {
195
7.81k
      const std::string pos_hash = emsa_name.arg(0);
196
7.81k
      return pos_hash;
197
7.81k
      }
198
0
199
0
   // If we don't understand what this is return a safe default
200
0
#if defined(BOTAN_HAS_SHA2_64)
201
0
   return "SHA-512";
202
#else
203
   return "SHA-256";
204
#endif
205
   }
206
207
}