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 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 CipherSuiteCollection(SecurityProtocolType protocol)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 CopyTo(Array array, int index)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 IEnumerable.GetEnumerator()123 IEnumerator IEnumerable.GetEnumerator() 124 { 125 return this.cipherSuites.GetEnumerator(); 126 } 127 128 #endregion 129 130 #region IList Methods 131 Clear()132 public void Clear() 133 { 134 this.cipherSuites.Clear(); 135 } 136 IList.Contains(object value)137 bool IList.Contains(object value) 138 { 139 return this.cipherSuites.Contains(value as CipherSuite); 140 } 141 IndexOf(string name)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 IndexOf(short code)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 IList.IndexOf(object value)174 int IList.IndexOf(object value) 175 { 176 return this.cipherSuites.IndexOf(value as CipherSuite); 177 } 178 IList.Insert(int index, object value)179 void IList.Insert(int index, object value) 180 { 181 this.cipherSuites.Insert(index, value as CipherSuite); 182 } 183 IList.Remove(object value)184 void IList.Remove(object value) 185 { 186 this.cipherSuites.Remove(value as CipherSuite); 187 } 188 IList.RemoveAt(int index)189 void IList.RemoveAt(int index) 190 { 191 this.cipherSuites.RemoveAt(index); 192 } 193 Add( short code, string name, CipherAlgorithmType cipherType, HashAlgorithmType hashType, ExchangeAlgorithmType exchangeType, bool exportable, bool blockMode, byte keyMaterialSize, byte expandedKeyMaterialSize, short effectiveKeyBytes, byte ivSize, byte blockSize)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 add(TlsCipherSuite cipherSuite)224 private TlsCipherSuite add(TlsCipherSuite cipherSuite) 225 { 226 this.cipherSuites.Add(cipherSuite); 227 228 return cipherSuite; 229 } 230 add(SslCipherSuite cipherSuite)231 private SslCipherSuite add(SslCipherSuite cipherSuite) 232 { 233 this.cipherSuites.Add(cipherSuite); 234 235 return cipherSuite; 236 } 237 IList.Add(object value)238 int IList.Add(object value) 239 { 240 return this.cipherSuites.Add(value as CipherSuite); 241 } 242 cultureAwareCompare(string strA, string strB)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 } 255