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