Coverage Report

Created: 2022-06-23 06:44

/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/internal/emsa.h>
8
#include <botan/hash.h>
9
#include <botan/internal/scan_name.h>
10
#include <botan/exceptn.h>
11
12
#if defined(BOTAN_HAS_EMSA1)
13
   #include <botan/internal/emsa1.h>
14
#endif
15
16
#if defined(BOTAN_HAS_EMSA_X931)
17
   #include <botan/internal/emsa_x931.h>
18
#endif
19
20
#if defined(BOTAN_HAS_EMSA_PKCS1)
21
   #include <botan/internal/emsa_pkcs1.h>
22
#endif
23
24
#if defined(BOTAN_HAS_EMSA_PSSR)
25
   #include <botan/internal/pssr.h>
26
#endif
27
28
#if defined(BOTAN_HAS_EMSA_RAW)
29
   #include <botan/internal/emsa_raw.h>
30
#endif
31
32
#if defined(BOTAN_HAS_ISO_9796)
33
   #include <botan/internal/iso9796.h>
34
#endif
35
36
namespace Botan {
37
38
AlgorithmIdentifier EMSA::config_for_x509(const Private_Key& /*unused*/,
39
                                          const std::string& /*unused*/) const
40
0
   {
41
0
   throw Not_Implemented("Encoding " + name() + " not supported for signing X509 objects");
42
0
   }
43
44
std::unique_ptr<EMSA> EMSA::create(const std::string& algo_spec)
45
6.79k
   {
46
6.79k
   SCAN_Name req(algo_spec);
47
48
6.79k
#if defined(BOTAN_HAS_EMSA1)
49
6.79k
   if(req.algo_name() == "EMSA1" && req.arg_count() == 1)
50
556
      {
51
556
      if(auto hash = HashFunction::create(req.arg(0)))
52
556
         return std::make_unique<EMSA1>(std::move(hash));
53
556
      }
54
6.23k
#endif
55
56
6.23k
#if defined(BOTAN_HAS_EMSA_PKCS1)
57
6.23k
   if(req.algo_name() == "EMSA_PKCS1" ||
58
6.23k
      req.algo_name() == "PKCS1v15" ||
59
6.23k
      req.algo_name() == "EMSA-PKCS1-v1_5" ||
60
6.23k
      req.algo_name() == "EMSA3")
61
6.18k
      {
62
6.18k
      if(req.arg_count() == 2 && req.arg(0) == "Raw")
63
0
         {
64
0
         return std::make_unique<EMSA_PKCS1v15_Raw>(req.arg(1));
65
0
         }
66
6.18k
      else if(req.arg_count() == 1)
67
6.18k
         {
68
6.18k
         if(req.arg(0) == "Raw")
69
0
            {
70
0
            return std::make_unique<EMSA_PKCS1v15_Raw>();
71
0
            }
72
6.18k
         else
73
6.18k
            {
74
6.18k
            if(auto hash = HashFunction::create(req.arg(0)))
75
6.18k
               {
76
6.18k
               return std::make_unique<EMSA_PKCS1v15>(std::move(hash));
77
6.18k
               }
78
6.18k
            }
79
6.18k
         }
80
6.18k
      }
81
57
#endif
82
83
57
#if defined(BOTAN_HAS_EMSA_PSSR)
84
57
   if(req.algo_name() == "PSS_Raw" ||
85
57
      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 hash = 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 std::make_unique<PSSR_Raw>(std::move(hash), salt_size);
95
0
               }
96
0
            else
97
0
               {
98
0
               return std::make_unique<PSSR_Raw>(std::move(hash));
99
0
               }
100
0
            }
101
0
         }
102
0
      }
103
104
57
   if(req.algo_name() == "PSS" ||
105
57
      req.algo_name() == "PSSR" ||
106
57
      req.algo_name() == "EMSA-PSS" ||
107
57
      req.algo_name() == "PSS-MGF1" ||
108
57
      req.algo_name() == "EMSA4")
109
56
      {
110
56
      if(req.arg_count_between(1, 3) && req.arg(1, "MGF1") == "MGF1")
111
56
         {
112
56
         if(auto hash = HashFunction::create(req.arg(0)))
113
56
            {
114
56
            if(req.arg_count() == 3)
115
56
               {
116
56
               const size_t salt_size = req.arg_as_integer(2, 0);
117
56
               return std::make_unique<PSSR>(std::move(hash), salt_size);
118
56
               }
119
0
            else
120
0
               {
121
0
               return std::make_unique<PSSR>(std::move(hash));
122
0
               }
123
56
            }
124
56
         }
125
56
      }
126
1
#endif
127
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 hash = HashFunction::create(req.arg(0)))
134
0
            {
135
0
            const size_t salt_size = req.arg_as_integer(2, hash->output_length());
136
0
            const bool implicit = req.arg(1, "exp") == "imp";
137
0
            return std::make_unique<ISO_9796_DS2>(std::move(hash), implicit, salt_size);
138
0
            }
139
0
         }
140
0
      }
141
   //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 hash = HashFunction::create(req.arg(0)))
147
0
            {
148
0
            const bool implicit = req.arg(1, "exp") == "imp";
149
0
            return std::make_unique<ISO_9796_DS3>(std::move(hash), implicit);
150
0
            }
151
0
         }
152
0
      }
153
1
#endif
154
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 std::make_unique<EMSA_X931>(std::move(hash));
165
0
            }
166
0
         }
167
0
      }
168
1
#endif
169
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 std::make_unique<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 std::make_unique<EMSA_Raw>(hash->output_length());
182
0
         }
183
0
      }
184
1
#endif
185
186
1
   return nullptr;
187
1
   }
188
189
std::unique_ptr<EMSA> EMSA::create_or_throw(const std::string& algo_spec)
190
6.79k
   {
191
6.79k
   auto emsa = EMSA::create(algo_spec);
192
6.79k
   if(emsa)
193
6.79k
      return emsa;
194
1
   throw Algorithm_Not_Found(algo_spec);
195
6.79k
   }
196
197
std::string hash_for_emsa(const std::string& algo_spec)
198
6.79k
   {
199
6.79k
   SCAN_Name emsa_name(algo_spec);
200
201
6.79k
   if(emsa_name.arg_count() > 0)
202
6.79k
      {
203
6.79k
      return emsa_name.arg(0);
204
6.79k
      }
205
206
   // If we don't understand what this is return a safe default
207
0
#if defined(BOTAN_HAS_SHA2_64)
208
0
   return "SHA-512";
209
#else
210
   return "SHA-256";
211
#endif
212
6.79k
   }
213
214
}