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