Coverage Report

Created: 2020-08-01 06:18

/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.71k
   {
46
7.71k
   SCAN_Name req(algo_spec);
47
7.71k
48
7.71k
#if defined(BOTAN_HAS_EMSA1)
49
7.71k
   if(req.algo_name() == "EMSA1" && req.arg_count() == 1)
50
1.44k
      {
51
1.44k
      if(auto hash = HashFunction::create(req.arg(0)))
52
1.44k
         return new EMSA1(hash.release());
53
6.27k
      }
54
6.27k
#endif
55
6.27k
56
6.27k
#if defined(BOTAN_HAS_EMSA_PKCS1)
57
6.27k
   if(req.algo_name() == "EMSA_PKCS1" ||
58
6.27k
      req.algo_name() == "PKCS1v15" ||
59
6.27k
      req.algo_name() == "EMSA-PKCS1-v1_5" ||
60
6.27k
      req.algo_name() == "EMSA3")
61
6.19k
      {
62
6.19k
      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.19k
      else if(req.arg_count() == 1)
67
6.19k
         {
68
6.19k
         if(req.arg(0) == "Raw")
69
0
            {
70
0
            return new EMSA_PKCS1v15_Raw;
71
0
            }
72
6.19k
         else
73
6.19k
            {
74
6.19k
            if(auto hash = HashFunction::create(req.arg(0)))
75
6.19k
               {
76
6.19k
               return new EMSA_PKCS1v15(hash.release());
77
6.19k
               }
78
79
            }
79
6.19k
         }
80
6.19k
      }
81
79
#endif
82
79
83
79
#if defined(BOTAN_HAS_EMSA_PSSR)
84
79
   if(req.algo_name() == "PSS_Raw" ||
85
79
      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
79
            }
101
0
         }
102
0
      }
103
79
104
79
   if(req.algo_name() == "PSS" ||
105
79
      req.algo_name() == "PSSR" ||
106
79
      req.algo_name() == "EMSA-PSS" ||
107
79
      req.algo_name() == "PSS-MGF1" ||
108
79
      req.algo_name() == "EMSA4")
109
78
      {
110
78
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
111
78
         {
112
78
         if(auto h = HashFunction::create(req.arg(0)))
113
78
            {
114
78
            if(req.arg_count() == 3)
115
78
               {
116
78
               const size_t salt_size = req.arg_as_integer(2, 0);
117
78
               return new PSSR(h.release(), salt_size);
118
78
               }
119
0
            else
120
0
               {
121
0
               return new PSSR(h.release());
122
0
               }
123
1
            }
124
78
         }
125
78
      }
126
1
#endif
127
1
128
1
#if defined(BOTAN_HAS_ISO_9796)
129
1
   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
1
         }
140
0
      }
141
1
   //ISO-9796-2 DS 3 is deterministic and DS2 without a salt
142
1
   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
1
         }
152
0
      }
153
1
#endif
154
1
155
1
#if defined(BOTAN_HAS_EMSA_X931)
156
1
   if(req.algo_name() == "EMSA_X931" ||
157
1
         req.algo_name() == "EMSA2" ||
158
1
         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
1
         }
167
0
      }
168
1
#endif
169
1
170
1
#if defined(BOTAN_HAS_EMSA_RAW)
171
1
   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
1
         }
183
0
      }
184
1
#endif
185
1
186
1
   throw Algorithm_Not_Found(algo_spec);
187
1
   }
188
189
std::string hash_for_emsa(const std::string& algo_spec)
190
7.71k
   {
191
7.71k
   SCAN_Name emsa_name(algo_spec);
192
7.71k
193
7.71k
   if(emsa_name.arg_count() > 0)
194
7.71k
      {
195
7.71k
      const std::string pos_hash = emsa_name.arg(0);
196
7.71k
      return pos_hash;
197
7.71k
      }
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
0
   }
206
207
}