blob: 540fdd8385389dc80f8a6a019b15a918e5178cc9 (
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
124
125
126
127
128
129
130
|
/*
* 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 std::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];
/*
* This is allowed by the specification but is not allocated and we're
* using it internally as a special 'no alert' type.
*/
if(dc == 255)
throw Internal_Error("Alert: description code 255, rejecting");
m_type_code = static_cast<Type>(dc);
}
std::vector<byte> Alert::serialize() const
{
std::vector<byte> alert(2);
alert[0] = static_cast<byte>(is_fatal() ? 2 : 1);
alert[1] = static_cast<byte>(type());
return alert;
}
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());
}
}
}
|