Switch to compiler-tester
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / Alert.cs
1 // Transport Security Layer (TLS)
2 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
3
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining
6 // a copy of this software and associated documentation files (the
7 // "Software"), to deal in the Software without restriction, including
8 // without limitation the rights to use, copy, modify, merge, publish,
9 // distribute, sublicense, and/or sell copies of the Software, and to
10 // permit persons to whom the Software is furnished to do so, subject to
11 // the following conditions:
12 // 
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
15 // 
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 //
24
25 using System;
26
27 namespace Mono.Security.Protocol.Tls
28 {
29         #region Enumerations
30
31         [Serializable]
32         internal enum AlertLevel : byte
33         {
34                 Warning = 1,
35                 Fatal   = 2
36         }
37
38         [Serializable]
39         internal enum AlertDescription : byte
40         {
41                 CloseNotify                             = 0,
42                 UnexpectedMessage               = 10,
43                 BadRecordMAC                    = 20,
44                 DecryptionFailed                = 21,
45                 RecordOverflow                  = 22,
46                 DecompressionFailiure   = 30,
47                 HandshakeFailiure               = 40,
48                 NoCertificate                   = 41,   // should be used in SSL3
49                 BadCertificate                  = 42,
50                 UnsupportedCertificate  = 43,
51                 CertificateRevoked              = 44,
52                 CertificateExpired              = 45,
53                 CertificateUnknown              = 46,
54                 IlegalParameter                 = 47,
55                 UnknownCA                               = 48,
56                 AccessDenied                    = 49,
57                 DecodeError                             = 50,
58                 DecryptError                    = 51,
59                 ExportRestriction               = 60,
60                 ProtocolVersion                 = 70,
61                 InsuficientSecurity             = 71,
62                 InternalError                   = 80,
63                 UserCancelled                   = 90,
64                 NoRenegotiation                 = 100
65         }
66
67         #endregion
68         
69         internal class Alert
70         {
71                 #region Fields
72
73                 private AlertLevel                      level;
74                 private AlertDescription        description;
75
76                 #endregion
77
78                 #region Properties
79
80                 public AlertLevel Level
81                 {
82                         get { return this.level; }
83                 }
84
85                 public AlertDescription Description
86                 {
87                         get { return this.description; }
88                 }
89
90                 public string Message
91                 {
92                         get { return Alert.GetAlertMessage(this.description); }
93                 }
94
95                 public bool IsWarning
96                 {
97                         get { return this.level == AlertLevel.Warning ? true : false; }
98                 }
99
100                 /*
101                 public bool IsFatal
102                 {
103                         get { return this.level == AlertLevel.Fatal ? true : false; }
104                 }
105                 */
106
107                 public bool IsCloseNotify
108                 {
109                         get
110                         {
111                                 if (this.IsWarning &&
112                                         this.description == AlertDescription.CloseNotify)
113                                 {
114                                         return true;
115                                 }
116
117                                 return false;
118                         }
119                 }
120
121                 #endregion
122
123                 #region Constructors
124
125                 public Alert(AlertDescription description)
126                 {
127                         this.inferAlertLevel();
128                         this.description = description;
129                 }
130
131                 public Alert(
132                         AlertLevel                      level,
133                         AlertDescription        description)
134                 {
135                         this.level                      = level;
136                         this.description        = description;
137                 }
138
139                 #endregion
140
141                 #region Private Methods
142
143                 private void inferAlertLevel()
144                 {
145                         switch (description)
146                         {
147                                 case AlertDescription.CloseNotify:
148                                 case AlertDescription.NoRenegotiation:
149                                 case AlertDescription.UserCancelled:
150                                         this.level = AlertLevel.Warning;
151                                         break;
152
153                                 case AlertDescription.AccessDenied:
154                                 case AlertDescription.BadCertificate:
155                                 case AlertDescription.BadRecordMAC:
156                                 case AlertDescription.CertificateExpired:
157                                 case AlertDescription.CertificateRevoked:
158                                 case AlertDescription.CertificateUnknown:
159                                 case AlertDescription.DecodeError:
160                                 case AlertDescription.DecompressionFailiure:
161                                 case AlertDescription.DecryptError:
162                                 case AlertDescription.DecryptionFailed:
163                                 case AlertDescription.ExportRestriction:
164                                 case AlertDescription.HandshakeFailiure:
165                                 case AlertDescription.IlegalParameter:
166                                 case AlertDescription.InsuficientSecurity:
167                                 case AlertDescription.InternalError:
168                                 case AlertDescription.ProtocolVersion:
169                                 case AlertDescription.RecordOverflow:
170                                 case AlertDescription.UnexpectedMessage:
171                                 case AlertDescription.UnknownCA:
172                                 case AlertDescription.UnsupportedCertificate:
173                                 default:
174                                         this.level = AlertLevel.Fatal;
175                                         break;
176                         }
177                 }
178                 
179                 #endregion
180
181                 #region Static Methods
182
183                 public static string GetAlertMessage(AlertDescription description)
184                 {
185                         #if (DEBUG)
186                         switch (description)
187                         {
188                                 case AlertDescription.AccessDenied:
189                                         return "An inappropriate message was received.";
190
191                                 case AlertDescription.BadCertificate:
192                                         return "TLSCiphertext decrypted in an invalid way.";
193
194                                 case AlertDescription.BadRecordMAC:
195                                         return "Record with an incorrect MAC.";
196
197                                 case AlertDescription.CertificateExpired:
198                                         return "Certificate has expired or is not currently valid";
199
200                                 case AlertDescription.CertificateRevoked:
201                                         return "Certificate was revoked by its signer.";
202                                         
203                                 case AlertDescription.CertificateUnknown:
204                                         return "Certificate Unknown.";
205
206                                 case AlertDescription.CloseNotify:
207                                         return "Connection closed";
208
209                                 case AlertDescription.DecodeError:
210                                         return "A message could not be decoded because some field was out of the specified range or the length of the message was incorrect.";
211
212                                 case AlertDescription.DecompressionFailiure:
213                                         return "The decompression function received improper input (e.g. data that would expand to excessive length).";
214
215                                 case AlertDescription.DecryptError:
216                                         return "TLSCiphertext decrypted in an invalid way: either it wasn`t an even multiple of the block length or its padding values, when checked, weren`t correct.";
217
218                                 case AlertDescription.DecryptionFailed:
219                                         return "Handshake cryptographic operation failed, including being unable to correctly verify a signature, decrypt a key exchange, or validate finished message.";
220
221                                 case AlertDescription.ExportRestriction:
222                                         return "Negotiation not in compliance with export restrictions was detected.";
223
224                                 case AlertDescription.HandshakeFailiure:
225                                         return "Unable to negotiate an acceptable set of security parameters given the options available.";
226
227                                 case AlertDescription.IlegalParameter:
228                                         return "A field in the handshake was out of range or inconsistent with other fields.";
229                                         
230                                 case AlertDescription.InsuficientSecurity:
231                                         return "Negotiation has failed specifically because the server requires ciphers more secure than those supported by the client.";
232                                         
233                                 case AlertDescription.InternalError:
234                                         return "Internal error unrelated to the peer or the correctness of the protocol makes it impossible to continue.";
235
236                                 case AlertDescription.NoRenegotiation:
237                                         return "Invalid renegotiation.";
238
239                                 case AlertDescription.ProtocolVersion:
240                                         return "Unsupported protocol version.";
241
242                                 case AlertDescription.RecordOverflow:
243                                         return "Invalid length on TLSCiphertext record or TLSCompressed record.";
244
245                                 case AlertDescription.UnexpectedMessage:
246                                         return "Invalid message received.";
247
248                                 case AlertDescription.UnknownCA:
249                                         return "CA can't be identified as a trusted CA.";
250
251                                 case AlertDescription.UnsupportedCertificate:
252                                         return "Certificate was of an unsupported type.";
253
254                                 case AlertDescription.UserCancelled:
255                                         return "Handshake cancelled by user.";
256
257                                 default:
258                                         return "";
259                         }
260                         #else
261                         return "The authentication or decryption has failed.";
262                         #endif
263                 }
264
265                 #endregion
266         }
267 }