Coverage Report

Created: 2022-11-24 06:56

/src/botan/src/lib/tls/tls_signature_scheme.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* (C) 2022 Jack Lloyd
3
* (C) 2022 René Meusel, Hannes Rantzsch - neXenio GmbH
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/tls_signature_scheme.h>
9
10
#include <botan/ec_group.h>
11
#include <botan/tls_exceptn.h>
12
#include <botan/tls_version.h>
13
#include <botan/internal/stl_util.h>
14
15
namespace Botan::TLS {
16
17
const std::vector<Signature_Scheme>& Signature_Scheme::all_available_schemes()
18
11.0k
   {
19
   /*
20
   * This is ordered in some approximate order of preference
21
   */
22
11.0k
   static const std::vector<Signature_Scheme> all_schemes = {
23
24
// EdDSA 25519 is currently not supported as a signature scheme for certificates
25
// certificate authentication.
26
// See: https://github.com/randombit/botan/pull/2958#discussion_r851294715
27
//
28
// #if defined(BOTAN_HAS_ED25519)
29
//       EDDSA_25519,
30
// #endif
31
32
11.0k
      RSA_PSS_SHA384,
33
11.0k
      RSA_PSS_SHA256,
34
11.0k
      RSA_PSS_SHA512,
35
36
11.0k
      RSA_PKCS1_SHA384,
37
11.0k
      RSA_PKCS1_SHA512,
38
11.0k
      RSA_PKCS1_SHA256,
39
40
11.0k
      ECDSA_SHA384,
41
11.0k
      ECDSA_SHA512,
42
11.0k
      ECDSA_SHA256,
43
11.0k
   };
44
45
11.0k
   return all_schemes;
46
11.0k
   }
47
48
49
Signature_Scheme::Signature_Scheme()
50
   : m_code(NONE)
51
23.9k
   {}
52
53
Signature_Scheme::Signature_Scheme(uint16_t wire_code)
54
   : Signature_Scheme(Signature_Scheme::Code(wire_code))
55
23.3k
   {}
56
57
Signature_Scheme::Signature_Scheme(Signature_Scheme::Code wire_code)
58
   : m_code(wire_code)
59
23.3k
   {}
60
61
bool Signature_Scheme::is_available() const noexcept
62
8.40k
   {
63
8.40k
   return value_exists(Signature_Scheme::all_available_schemes(), *this);
64
8.40k
   }
65
66
bool Signature_Scheme::is_set() const noexcept
67
1.54k
   {
68
1.54k
   return m_code != NONE;
69
1.54k
   }
70
71
std::string Signature_Scheme::to_string() const noexcept
72
0
   {
73
0
   switch(m_code)
74
0
      {
75
0
      case RSA_PKCS1_SHA1:
76
0
         return "RSA_PKCS1_SHA1";
77
0
      case RSA_PKCS1_SHA256:
78
0
         return "RSA_PKCS1_SHA256";
79
0
      case RSA_PKCS1_SHA384:
80
0
         return "RSA_PKCS1_SHA384";
81
0
      case RSA_PKCS1_SHA512:
82
0
         return "RSA_PKCS1_SHA512";
83
84
0
      case ECDSA_SHA1:
85
0
         return "ECDSA_SHA1";
86
0
      case ECDSA_SHA256:
87
0
         return "ECDSA_SHA256";
88
0
      case ECDSA_SHA384:
89
0
         return "ECDSA_SHA384";
90
0
      case ECDSA_SHA512:
91
0
         return "ECDSA_SHA512";
92
93
0
      case RSA_PSS_SHA256:
94
0
         return "RSA_PSS_SHA256";
95
0
      case RSA_PSS_SHA384:
96
0
         return "RSA_PSS_SHA384";
97
0
      case RSA_PSS_SHA512:
98
0
         return "RSA_PSS_SHA512";
99
100
0
      case EDDSA_25519:
101
0
         return "EDDSA_25519";
102
0
      case EDDSA_448:
103
0
         return "EDDSA_448";
104
105
0
      case DSA_SHA1:
106
0
         return "DSA_SHA1";
107
0
      case DSA_SHA256:
108
0
         return "DSA_SHA256";
109
0
      case DSA_SHA384:
110
0
         return "DSA_SHA384";
111
0
      case DSA_SHA512:
112
0
         return "DSA_SHA512";
113
114
0
      default:
115
0
         return "Unknown signature scheme: " + std::to_string(m_code);
116
0
      }
117
0
   }
118
119
std::string Signature_Scheme::hash_function_name() const noexcept
120
27.0k
   {
121
27.0k
   switch(m_code)
122
27.0k
      {
123
0
      case RSA_PKCS1_SHA1:
124
0
      case ECDSA_SHA1:
125
0
      case DSA_SHA1:
126
0
         return "SHA-1";
127
128
2.94k
      case ECDSA_SHA256:
129
6.17k
      case RSA_PKCS1_SHA256:
130
9.77k
      case RSA_PSS_SHA256:
131
9.77k
      case DSA_SHA256:
132
9.77k
         return "SHA-256";
133
134
2.89k
      case ECDSA_SHA384:
135
5.64k
      case RSA_PKCS1_SHA384:
136
8.64k
      case RSA_PSS_SHA384:
137
8.64k
      case DSA_SHA384:
138
8.64k
         return "SHA-384";
139
140
2.95k
      case ECDSA_SHA512:
141
5.68k
      case RSA_PKCS1_SHA512:
142
8.65k
      case RSA_PSS_SHA512:
143
8.65k
      case DSA_SHA512:
144
8.65k
         return "SHA-512";
145
146
0
      case EDDSA_25519:
147
0
      case EDDSA_448:
148
0
         return "Pure";
149
150
0
      default:
151
0
         return "Unknown hash function";
152
27.0k
      }
153
27.0k
   }
154
155
std::string Signature_Scheme::padding_string() const noexcept
156
0
   {
157
0
   switch(m_code)
158
0
      {
159
0
      case RSA_PKCS1_SHA1:
160
0
         return "EMSA_PKCS1(SHA-1)";
161
0
      case RSA_PKCS1_SHA256:
162
0
         return "EMSA_PKCS1(SHA-256)";
163
0
      case RSA_PKCS1_SHA384:
164
0
         return "EMSA_PKCS1(SHA-384)";
165
0
      case RSA_PKCS1_SHA512:
166
0
         return "EMSA_PKCS1(SHA-512)";
167
168
0
      case ECDSA_SHA1:
169
0
         return "EMSA1(SHA-1)";
170
0
      case ECDSA_SHA256:
171
0
         return "EMSA1(SHA-256)";
172
0
      case ECDSA_SHA384:
173
0
         return "EMSA1(SHA-384)";
174
0
      case ECDSA_SHA512:
175
0
         return "EMSA1(SHA-512)";
176
177
0
      case RSA_PSS_SHA256:
178
0
         return "PSSR(SHA-256,MGF1,32)";
179
0
      case RSA_PSS_SHA384:
180
0
         return "PSSR(SHA-384,MGF1,48)";
181
0
      case RSA_PSS_SHA512:
182
0
         return "PSSR(SHA-512,MGF1,64)";
183
184
0
      case EDDSA_25519:
185
0
         return "Pure";
186
0
      case EDDSA_448:
187
0
         return "Pure";
188
189
0
      default:
190
0
         return "Unknown padding";
191
0
      }
192
0
   }
193
194
std::string Signature_Scheme::algorithm_name() const noexcept
195
25.7k
   {
196
25.7k
   switch(m_code)
197
25.7k
      {
198
0
      case RSA_PKCS1_SHA1:
199
3.22k
      case RSA_PKCS1_SHA256:
200
5.97k
      case RSA_PKCS1_SHA384:
201
8.70k
      case RSA_PKCS1_SHA512:
202
11.9k
      case RSA_PSS_SHA256:
203
14.7k
      case RSA_PSS_SHA384:
204
17.4k
      case RSA_PSS_SHA512:
205
17.4k
         return "RSA";
206
207
0
      case ECDSA_SHA1:
208
2.78k
      case ECDSA_SHA256:
209
5.51k
      case ECDSA_SHA384:
210
8.27k
      case ECDSA_SHA512:
211
8.27k
         return "ECDSA";
212
213
0
      case EDDSA_25519:
214
0
         return "Ed25519";
215
216
0
      case EDDSA_448:
217
0
         return "Ed448";
218
219
0
      case DSA_SHA1:
220
0
      case DSA_SHA256:
221
0
      case DSA_SHA384:
222
0
      case DSA_SHA512:
223
0
         return "DSA";
224
225
0
      default:
226
0
         return "Unknown algorithm";
227
25.7k
      }
228
25.7k
   }
229
230
AlgorithmIdentifier Signature_Scheme::algorithm_identifier() const noexcept
231
0
   {
232
0
   switch(m_code)
233
0
      {
234
      // case ECDSA_SHA1:  not defined
235
0
      case ECDSA_SHA256:
236
0
         return { "ECDSA", Botan::EC_Group("secp256r1").DER_encode(Botan::EC_Group_Encoding::NamedCurve) };
237
0
      case ECDSA_SHA384:
238
0
         return { "ECDSA", Botan::EC_Group("secp384r1").DER_encode(Botan::EC_Group_Encoding::NamedCurve) };
239
0
      case ECDSA_SHA512:
240
0
         return { "ECDSA", Botan::EC_Group("secp521r1").DER_encode(Botan::EC_Group_Encoding::NamedCurve) };
241
242
0
      case EDDSA_25519:
243
0
         return { "Ed25519", AlgorithmIdentifier::USE_EMPTY_PARAM };
244
245
0
      case RSA_PKCS1_SHA1:
246
0
      case RSA_PKCS1_SHA256:
247
0
      case RSA_PKCS1_SHA384:
248
0
      case RSA_PKCS1_SHA512:
249
0
      case RSA_PSS_SHA256:
250
0
      case RSA_PSS_SHA384:
251
0
      case RSA_PSS_SHA512:
252
0
         return { "RSA", AlgorithmIdentifier::USE_NULL_PARAM };
253
254
0
      default:
255
0
         return AlgorithmIdentifier();
256
0
      }
257
0
   }
258
259
std::optional<Signature_Format> Signature_Scheme::format() const noexcept
260
0
   {
261
0
   switch(m_code)
262
0
      {
263
0
      case RSA_PKCS1_SHA1:
264
0
      case RSA_PKCS1_SHA256:
265
0
      case RSA_PKCS1_SHA384:
266
0
      case RSA_PKCS1_SHA512:
267
0
      case RSA_PSS_SHA256:
268
0
      case RSA_PSS_SHA384:
269
0
      case RSA_PSS_SHA512:
270
0
         return IEEE_1363;
271
272
0
      case ECDSA_SHA1:
273
0
      case ECDSA_SHA256:
274
0
      case ECDSA_SHA384:
275
0
      case ECDSA_SHA512:
276
0
      case EDDSA_25519:
277
0
      case EDDSA_448:
278
0
      case DSA_SHA1:
279
0
      case DSA_SHA256:
280
0
      case DSA_SHA384:
281
0
      case DSA_SHA512:
282
0
         return DER_SEQUENCE;
283
284
0
      default:
285
0
         return std::nullopt;
286
0
      }
287
0
   }
288
289
bool Signature_Scheme::is_compatible_with(const Protocol_Version& protocol_version) const noexcept
290
1.51k
   {
291
   // RFC 8446 4.4.3:
292
   //   The SHA-1 algorithm MUST NOT be used in any signatures of
293
   //   CertificateVerify messages.
294
   //
295
   // Note that Botan enforces that for TLS 1.2 as well.
296
1.51k
   if(hash_function_name() == "SHA-1")
297
0
      return false;
298
299
   // RFC 8446 4.4.3:
300
   //   RSA signatures MUST use an RSASSA-PSS algorithm, regardless of whether
301
   //   RSASSA-PKCS1-v1_5 algorithms appear in "signature_algorithms".
302
   //
303
   // Note that this is enforced for TLS 1.3 and above only.
304
1.51k
   if(!protocol_version.is_pre_tls_13() &&
305
1.51k
       (m_code == RSA_PKCS1_SHA1   ||
306
1.51k
        m_code == RSA_PKCS1_SHA256 ||
307
1.51k
        m_code == RSA_PKCS1_SHA384 ||
308
1.51k
        m_code == RSA_PKCS1_SHA512))
309
3
      return false;
310
311
1.51k
   return true;
312
1.51k
   }
313
314
bool Signature_Scheme::is_suitable_for(const Private_Key &private_key) const noexcept
315
0
   {
316
0
   if(algorithm_name() != private_key.algo_name())
317
0
      return false;
318
319
   // The ECDSA private key length must match the utilized hash output length.
320
0
   const auto keylen = private_key.key_length();
321
0
   if(keylen <= 250)
322
0
      return false;
323
324
0
   if(m_code == ECDSA_SHA256 && !(keylen >= 250 && keylen <= 350)) // lgtm [cpp/constant-comparison]
325
0
      return false;                                                // `keylen >= 250` will always be true, because keylen <= 250
326
                                                                   // was checked before. Leaving it in for readability.
327
0
   if(m_code == ECDSA_SHA384 && !(keylen >= 350 && keylen <= 450))
328
0
      return false;
329
330
0
   if(m_code == ECDSA_SHA512 && !(keylen >= 450 && keylen <= 550))
331
0
      return false;
332
333
0
   return true;
334
0
   }
335
336
}  // Botan::TLS