1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
|
/*
* Exceptions
* (C) 1999-2009,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_EXCEPTION_H_
#define BOTAN_EXCEPTION_H_
#include <botan/types.h>
#include <exception>
#include <string>
namespace Botan {
/**
* Different types of errors that might occur
*/
enum class ErrorType {
/** Some unknown error */
Unknown = 1,
/** An error while calling a system interface */
SystemError,
/** An operation seems valid, but not supported by the current version */
NotImplemented,
/** Memory allocation failure */
OutOfMemory,
/** An internal error occurred */
InternalError,
/** An I/O error occurred */
IoError,
/** Invalid object state */
InvalidObjectState = 100,
/** A key was not set on an object when this is required */
KeyNotSet,
/** The application provided an argument which is invalid */
InvalidArgument,
/** A key with invalid length was provided */
InvalidKeyLength,
/** A nonce with invalid length was provided */
InvalidNonceLength,
/** An object type was requested but cannot be found */
LookupError,
/** Encoding a message or datum failed */
EncodingFailure,
/** Decoding a message or datum failed */
DecodingFailure,
/** A TLS error (error_code will be the alert type) */
TLSError,
/** An error during an HTTP operation */
HttpError,
/** A message with an invalid authentication tag was detected */
InvalidTag,
/** An error during Roughtime validation */
RoughtimeError,
/** An error when calling OpenSSL */
OpenSSLError = 200,
/** An error when interacting with CommonCrypto API */
CommonCryptoError,
/** An error when interacting with a PKCS11 device */
Pkcs11Error,
/** An error when interacting with a TPM device */
TPMError,
/** An error when interacting with a database */
DatabaseError,
/** An error when interacting with zlib */
ZlibError = 300,
/** An error when interacting with bzip2 */
Bzip2Error,
/** An error when interacting with lzma */
LzmaError,
};
//! \brief Convert an ErrorType to string
std::string BOTAN_PUBLIC_API(2,11) to_string(ErrorType type);
/**
* Base class for all exceptions thrown by the library
*/
class BOTAN_PUBLIC_API(2,0) Exception : public std::exception
{
public:
/**
* Return a descriptive string which is hopefully comprehensible to
* a developer. It will likely not be useful for an end user.
*
* The string has no particular format, and the content of exception
* messages may change from release to release. Thus the main use of this
* function is for logging or debugging.
*/
const char* what() const noexcept override { return m_msg.c_str(); }
/**
* Return the "type" of error which occurred.
*/
virtual ErrorType error_type() const noexcept { return Botan::ErrorType::Unknown; }
/**
* Return an error code associated with this exception, or otherwise 0.
*
* The domain of this error varies depending on the source, for example on
* POSIX systems it might be errno, while on a Windows system it might be
* the result of GetLastError or WSAGetLastError. For error_type() is
* OpenSSLError, it will (if nonzero) be an OpenSSL error code from
* ERR_get_error.
*/
virtual int error_code() const noexcept { return 0; }
/**
* Avoid throwing base Exception, use a subclass
*/
explicit Exception(const std::string& msg);
/**
* Avoid throwing base Exception, use a subclass
*/
Exception(const char* prefix, const std::string& msg);
/**
* Avoid throwing base Exception, use a subclass
*/
Exception(const std::string& msg, const std::exception& e);
private:
std::string m_msg;
};
/**
* An invalid argument was provided to an API call.
*/
class BOTAN_PUBLIC_API(2,0) Invalid_Argument : public Exception
{
public:
explicit Invalid_Argument(const std::string& msg);
explicit Invalid_Argument(const std::string& msg, const std::string& where);
Invalid_Argument(const std::string& msg, const std::exception& e);
ErrorType error_type() const noexcept override { return ErrorType::InvalidArgument; }
};
/**
* An invalid key length was used
*/
class BOTAN_PUBLIC_API(2,0) Invalid_Key_Length final : public Invalid_Argument
{
public:
Invalid_Key_Length(const std::string& name, size_t length);
ErrorType error_type() const noexcept override { return ErrorType::InvalidKeyLength; }
};
/**
* An invalid nonce length was used
*/
class BOTAN_PUBLIC_API(2,0) Invalid_IV_Length final : public Invalid_Argument
{
public:
Invalid_IV_Length(const std::string& mode, size_t bad_len);
ErrorType error_type() const noexcept override { return ErrorType::InvalidNonceLength; }
};
/**
* Invalid_Algorithm_Name Exception
*/
class BOTAN_PUBLIC_API(2,0) Invalid_Algorithm_Name final : public Invalid_Argument
{
public:
explicit Invalid_Algorithm_Name(const std::string& name);
};
/**
* Encoding_Error Exception
*/
class BOTAN_PUBLIC_API(2,0) Encoding_Error final : public Exception
{
public:
explicit Encoding_Error(const std::string& name);
ErrorType error_type() const noexcept override { return ErrorType::EncodingFailure; }
};
/**
* A decoding error occurred.
*/
class BOTAN_PUBLIC_API(2,0) Decoding_Error : public Exception
{
public:
explicit Decoding_Error(const std::string& name);
Decoding_Error(const std::string& name, const char* exception_message);
Decoding_Error(const std::string& msg, const std::exception& e);
ErrorType error_type() const noexcept override { return ErrorType::DecodingFailure; }
};
/**
* Invalid state was encountered. A request was made on an object while the
* object was in a state where the operation cannot be performed.
*/
class BOTAN_PUBLIC_API(2,0) Invalid_State : public Exception
{
public:
explicit Invalid_State(const std::string& err) : Exception(err) {}
ErrorType error_type() const noexcept override { return ErrorType::InvalidObjectState; }
};
/**
* A PRNG was called on to produce output while still unseeded
*/
class BOTAN_PUBLIC_API(2,0) PRNG_Unseeded final : public Invalid_State
{
public:
explicit PRNG_Unseeded(const std::string& algo);
};
/**
* The key was not set on an object. This occurs with symmetric objects where
* an operation which requires the key is called prior to set_key being called.
*/
class BOTAN_PUBLIC_API(2,4) Key_Not_Set : public Invalid_State
{
public:
explicit Key_Not_Set(const std::string& algo);
ErrorType error_type() const noexcept override { return ErrorType::KeyNotSet; }
};
/**
* A request was made for some kind of object which could not be located
*/
class BOTAN_PUBLIC_API(2,0) Lookup_Error : public Exception
{
public:
explicit Lookup_Error(const std::string& err) : Exception(err) {}
Lookup_Error(const std::string& type,
const std::string& algo,
const std::string& provider);
ErrorType error_type() const noexcept override { return ErrorType::LookupError; }
};
/**
* Algorithm_Not_Found Exception
*
* @warning This exception type will be removed in the future. Instead
* just catch Lookup_Error.
*/
class BOTAN_PUBLIC_API(2,0) Algorithm_Not_Found final : public Lookup_Error
{
public:
explicit Algorithm_Not_Found(const std::string& name);
};
/**
* Provider_Not_Found is thrown when a specific provider was requested
* but that provider is not available.
*
* @warning This exception type will be removed in the future. Instead
* just catch Lookup_Error.
*/
class BOTAN_PUBLIC_API(2,0) Provider_Not_Found final : public Lookup_Error
{
public:
Provider_Not_Found(const std::string& algo, const std::string& provider);
};
/**
* An AEAD or MAC check detected a message modification
*
* In versions before 2.10, Invalid_Authentication_Tag was named
* Integrity_Failure, it was renamed to make its usage more clear.
*/
class BOTAN_PUBLIC_API(2,0) Invalid_Authentication_Tag final : public Exception
{
public:
explicit Invalid_Authentication_Tag(const std::string& msg);
ErrorType error_type() const noexcept override { return ErrorType::InvalidTag; }
};
/**
* For compatability with older versions
*/
typedef Invalid_Authentication_Tag Integrity_Failure;
/**
* An error occurred while operating on an IO stream
*/
class BOTAN_PUBLIC_API(2,0) Stream_IO_Error final : public Exception
{
public:
explicit Stream_IO_Error(const std::string& err);
ErrorType error_type() const noexcept override { return ErrorType::IoError; }
};
/**
* System_Error
*
* This exception is thrown in the event of an error related to interacting
* with the operating system.
*
* This exception type also (optionally) captures an integer error code eg
* POSIX errno or Windows GetLastError.
*/
class BOTAN_PUBLIC_API(2,9) System_Error : public Exception
{
public:
System_Error(const std::string& msg) : Exception(msg), m_error_code(0) {}
System_Error(const std::string& msg, int err_code);
ErrorType error_type() const noexcept override { return ErrorType::SystemError; }
int error_code() const noexcept override { return m_error_code; }
private:
int m_error_code;
};
/**
* An internal error occurred. If observed, please file a bug.
*/
class BOTAN_PUBLIC_API(2,0) Internal_Error : public Exception
{
public:
explicit Internal_Error(const std::string& err);
ErrorType error_type() const noexcept override { return ErrorType::InternalError; }
};
/**
* Not Implemented Exception
*
* This is thrown in the situation where a requested operation is
* logically valid but is not implemented by this version of the library.
*/
class BOTAN_PUBLIC_API(2,0) Not_Implemented final : public Exception
{
public:
explicit Not_Implemented(const std::string& err);
ErrorType error_type() const noexcept override { return ErrorType::NotImplemented; }
};
template<typename E, typename... Args>
inline void do_throw_error(const char* file, int line, const char* func, Args... args)
{
throw E(file, line, func, args...);
}
}
#endif
|