aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/tls_alert.cpp
blob: 15bb2a2dc72a17000c5bf7e11818654ae1acd76c (plain)
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
/*
* Alert Message
* (C) 2004-2006,2011 Jack Lloyd
*
* Released under the terms of the Botan license
*/

#include <botan/tls_alert.h>
#include <botan/exceptn.h>

namespace Botan {

namespace TLS {

Alert::Alert(const secure_vector<byte>& buf)
   {
   if(buf.size() != 2)
      throw Decoding_Error("Alert: Bad size " + std::to_string(buf.size()) +
                           " for alert message");

   if(buf[0] == 1)      m_fatal = false;
   else if(buf[0] == 2) m_fatal = true;
   else
      throw Decoding_Error("Alert: Bad code for alert level");

   const byte dc = buf[1];

   m_type_code = static_cast<Type>(dc);
   }

std::vector<byte> Alert::serialize() const
   {
   return std::vector<byte>({
      static_cast<byte>(is_fatal() ? 2 : 1),
      static_cast<byte>(type())
      });
   }

std::string Alert::type_string() const
   {
   switch(type())
      {
      case CLOSE_NOTIFY:
         return "close_notify";
      case UNEXPECTED_MESSAGE:
         return "unexpected_message";
      case BAD_RECORD_MAC:
         return "bad_record_mac";
      case DECRYPTION_FAILED:
         return "decryption_failed";
      case RECORD_OVERFLOW:
         return "record_overflow";
      case DECOMPRESSION_FAILURE:
         return "decompression_failure";
      case HANDSHAKE_FAILURE:
         return "handshake_failure";
      case NO_CERTIFICATE:
         return "no_certificate";
      case BAD_CERTIFICATE:
         return "bad_certificate";
      case UNSUPPORTED_CERTIFICATE:
         return "unsupported_certificate";
      case CERTIFICATE_REVOKED:
         return "certificate_revoked";
      case CERTIFICATE_EXPIRED:
         return "certificate_expired";
      case CERTIFICATE_UNKNOWN:
         return "certificate_unknown";
      case ILLEGAL_PARAMETER:
         return "illegal_parameter";
      case UNKNOWN_CA:
         return "unknown_ca";
      case ACCESS_DENIED:
         return "access_denied";
      case DECODE_ERROR:
         return "decode_error";
      case DECRYPT_ERROR:
         return "decrypt_error";
      case EXPORT_RESTRICTION:
         return "export_restriction";
      case PROTOCOL_VERSION:
         return "protocol_version";
      case INSUFFICIENT_SECURITY:
         return "insufficient_security";
      case INTERNAL_ERROR:
         return "internal_error";
      case USER_CANCELED:
         return "user_canceled";
      case NO_RENEGOTIATION:
         return "no_renegotiation";

      case UNSUPPORTED_EXTENSION:
         return "unsupported_extension";
      case CERTIFICATE_UNOBTAINABLE:
         return "certificate_unobtainable";
      case UNRECOGNIZED_NAME:
         return "unrecognized_name";
      case BAD_CERTIFICATE_STATUS_RESPONSE:
         return "bad_certificate_status_response";
      case BAD_CERTIFICATE_HASH_VALUE:
         return "bad_certificate_hash_value";
      case UNKNOWN_PSK_IDENTITY:
         return "unknown_psk_identity";

      case NULL_ALERT:
         return "none";

      case HEARTBEAT_PAYLOAD:
         return "heartbeat_payload";
      }

   /*
   * This is effectively the default case for the switch above, but we
   * leave it out so that when an alert type is added to the enum the
   * compiler can warn us that it is not included in the switch
   * statement.
   */
   return "unrecognized_alert_" + std::to_string(type());
   }

}

}