2005-04-12 Dick Porter <dick@ximian.com>
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / CipherSuiteCollection.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 \r
25 using System;
26 using System.Collections;
27 using System.Globalization;
28 using System.Security.Cryptography;
29
30 namespace Mono.Security.Protocol.Tls
31 {
32         internal sealed class CipherSuiteCollection : ICollection, IList, IEnumerable
33         {
34                 #region Fields
35
36                 private ArrayList                               cipherSuites;
37                 private SecurityProtocolType    protocol;
38
39                 #endregion
40
41                 #region Indexers
42
43                 public CipherSuite this[string name] 
44                 {
45                         get { return (CipherSuite)this.cipherSuites[this.IndexOf(name)]; }
46                         set { this.cipherSuites[this.IndexOf(name)] = (CipherSuite)value; }
47                 }
48
49                 public CipherSuite this[int index] 
50                 {
51                         get { return (CipherSuite)this.cipherSuites[index]; }
52                         set { this.cipherSuites[index] = (CipherSuite)value; }
53                 }
54
55                 public CipherSuite this[short code] 
56                 {
57                         get { return (CipherSuite)this.cipherSuites[this.IndexOf(code)]; }
58                         set { this.cipherSuites[this.IndexOf(code)] = (CipherSuite)value; }
59                 }
60
61                 object IList.this[int index]
62                 {
63                         get { return this[index]; }
64                         set { this[index] = (CipherSuite)value; }
65                 }
66
67                 #endregion
68
69                 #region ICollection Properties
70
71                 bool ICollection.IsSynchronized
72                 {
73                         get { return this.cipherSuites.IsSynchronized; }
74                 }
75
76                 object ICollection.SyncRoot 
77                 {
78                         get { return this.cipherSuites.SyncRoot; }
79                 }
80
81                 public int Count 
82                 {
83                         get { return this.cipherSuites.Count; }
84                 }
85                 
86                 #endregion
87
88                 #region IList Properties
89
90                 public bool IsFixedSize 
91                 {
92                         get { return this.cipherSuites.IsFixedSize; }
93                 }
94
95                 public bool IsReadOnly
96                 {
97                         get { return this.cipherSuites.IsReadOnly; }
98                 }
99
100                 #endregion
101
102                 #region Constructors
103
104                 public CipherSuiteCollection(SecurityProtocolType protocol) : base()
105                 {
106                         this.protocol           = protocol;
107                         this.cipherSuites       = new ArrayList();
108                 }
109
110                 #endregion
111
112                 #region ICollection Methods
113
114                 public void CopyTo(Array array, int index)
115                 {
116                         this.cipherSuites.CopyTo(array, index);
117                 }
118                 
119                 #endregion
120
121                 #region IEnumerable Methods
122
123                 IEnumerator IEnumerable.GetEnumerator()
124                 {
125                         return this.cipherSuites.GetEnumerator();
126                 }
127
128                 #endregion
129
130                 #region IList Methods
131
132                 public void Clear()
133                 {
134                         this.cipherSuites.Clear();
135                 }
136                         
137                 bool IList.Contains(object value)
138                 {
139                         return this.cipherSuites.Contains(value as CipherSuite);
140                 }
141
142                 public int IndexOf(string name)
143                 {
144                         int index = 0;
145
146                         foreach (CipherSuite cipherSuite in this.cipherSuites)
147                         {
148                                 if (this.cultureAwareCompare(cipherSuite.Name, name))
149                                 {
150                                         return index;
151                                 }
152                                 index++;
153                         }
154
155                         return -1;
156                 }
157
158                 public int IndexOf(short code)
159                 {
160                         int index = 0;
161
162                         foreach (CipherSuite cipherSuite in this.cipherSuites)
163                         {
164                                 if (cipherSuite.Code == code)
165                                 {
166                                         return index;
167                                 }
168                                 index++;
169                         }
170
171                         return -1;
172                 }
173
174                 int IList.IndexOf(object value)
175                 {
176                         return this.cipherSuites.IndexOf(value as CipherSuite);
177                 }
178
179                 void IList.Insert(int index, object value)
180                 {
181                         this.cipherSuites.Insert(index, value as CipherSuite);
182                 }
183
184                 void IList.Remove(object value)
185                 {
186                         this.cipherSuites.Remove(value as CipherSuite);
187                 }
188
189                 void IList.RemoveAt(int index)
190                 {
191                         this.cipherSuites.RemoveAt(index);
192                 }
193
194                 public CipherSuite Add(
195                         short code, string name, CipherAlgorithmType cipherType, 
196                         HashAlgorithmType hashType, ExchangeAlgorithmType exchangeType,
197                         bool exportable, bool blockMode, byte keyMaterialSize, 
198                         byte expandedKeyMaterialSize, short effectiveKeyBytes, 
199                         byte ivSize, byte blockSize)
200                 {
201                         switch (this.protocol)
202                         {
203                                 case SecurityProtocolType.Default:
204                                 case SecurityProtocolType.Tls:
205                                         return this.add(
206                                                 new TlsCipherSuite(
207                                                 code, name, cipherType, hashType, exchangeType, exportable, 
208                                                 blockMode, keyMaterialSize, expandedKeyMaterialSize, 
209                                                 effectiveKeyBytes, ivSize, blockSize));
210
211                                 case SecurityProtocolType.Ssl3:
212                                         return this.add(
213                                                 new SslCipherSuite(
214                                                 code, name, cipherType, hashType, exchangeType, exportable, 
215                                                 blockMode, keyMaterialSize, expandedKeyMaterialSize, 
216                                                 effectiveKeyBytes, ivSize, blockSize));
217
218                                 case SecurityProtocolType.Ssl2:
219                                 default:
220                                         throw new NotSupportedException("Unsupported security protocol type.");
221                         }
222                 }
223
224                 private TlsCipherSuite add(TlsCipherSuite cipherSuite)
225                 {
226                         this.cipherSuites.Add(cipherSuite);
227
228                         return cipherSuite;
229                 }
230
231                 private SslCipherSuite add(SslCipherSuite cipherSuite)
232                 {
233                         this.cipherSuites.Add(cipherSuite);
234
235                         return cipherSuite;
236                 }
237
238                 int IList.Add(object value)
239                 {
240                         return this.cipherSuites.Add(value as CipherSuite);
241                 }
242                 
243                 private bool cultureAwareCompare(string strA, string strB)
244                 {
245                         return CultureInfo.CurrentCulture.CompareInfo.Compare(
246                                 strA, 
247                                 strB, 
248                                 CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | 
249                                 CompareOptions.IgnoreCase) == 0 ? true : false;
250                 }
251
252                 #endregion
253         }
254 }