[pgsqlclient-checkins] pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls Alert.c
Status: Inactive
Brought to you by:
carlosga_fb
Update of /cvsroot/pgsqlclient/pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19625 Modified Files: CipherSuite.cs ClientContext.cs ClientRecordProtocol.cs Context.cs RecordProtocol.cs ServerRecordProtocol.cs SslClientStream.cs SslServerStream.cs TlsCipherSuite.cs TlsException.cs TlsServerSettings.cs Added Files: Alert.cs CipherSuiteCollection.cs CipherSuiteFactory.cs ContentType.cs SslCipherSuite.cs SslHandshakeHash.cs Removed Files: TlsCipherSuiteCollection.cs TlsCipherSuiteFactory.cs TlsContentType.cs TlsSslCipherSuite.cs TlsSslHandshakeHash.cs Log Message: 2004-03-03 Carlos Guzman Alvarez <car...@te...> * Mono.Security.Protocol.Tls/SslServerStream.cs: - Implemented flow for the server handshake. * Mono.Security.Protocol.Tls/Ciphersuite.cs: * Mono.Security.Protocol.Tls/TlsCiphersuite.cs: * Mono.Security.Protocol.Tls/ClientRecordProtocol.cs: * Mono.Security.Protocol.Tls/ServerRecordProtocol.cs: * Mono.Security.Protocol.Tls/SslClientStream.cs: * Mono.Security.Protocol.Tls/TlsServerSettings.cs: * Mono.Security.Protocol.Tls/TlsClientSettings.cs: * Mono.Security.Protocol.Tls/ClientContext.cs: * Mono.Security.Protocol.Tls.Handshake.Client/*.cs: * Mono.Security.Protocol.Tls.Handshake.Server/*.cs: - Changes for make use of the renamed classes and enums. * Mono.Security.Protocol.Tls.Handshake/TlsHandshakeType.cs: - Renamed to HandshakeType.cs (Enum and file) * Mono.Security.Protocol.Tls.Handshake/TlsHandshakeMessage.cs: - Renamed to HandshakeMessage.cs (Class and file) * Mono.Security.Protocol.Tls.Handshake/TlsClientCertificateType.cs: - Renamed to ClientCertificateType.cs (Enum and file) * Mono.Security.Protocol.Tls.Alerts/TlsAlert.cs: - Renamed to Alert (Class, enums and file) * Mono.Security.Protocol.Tls/TlsContentType.cs: - Renamed to ContentType.cs ( Enum and file ) * Mono.Security.Protocol.Tls/TlsCiphersuiteCollection.cs: - Renamed to CiphersuiteCollection.cs ( Class and file ) * Mono.Security.Protocol.Tls/TlsCiphersuiteFactory.cs: - Renamed to CiphersuiteCollection.cs ( Class and file ) * Mono.Security.Protocol.Tls/TlsSslHandshakeHash.cs: - Renamed to SslHandshakeHash.cs ( Class and file ) * Mono.Security.Protocol.Tls/TlsSslCipherSuite.cs: - Renamed to SslCipherSuite.cs ( Class and file ) --- NEW FILE: Alert.cs --- /* Transport Security Layer (TLS) * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; using Mono.Security.Protocol.Tls; namespace Mono.Security.Protocol.Tls { #region Enumerations [Serializable] internal enum AlertLevel : byte { Warning = 1, Fatal = 2 } [Serializable] internal enum AlertDescription : byte { CloseNotify = 0, UnexpectedMessage = 10, BadRecordMAC = 20, DecryptionFailed = 21, RecordOverflow = 22, DecompressionFailiure = 30, HandshakeFailiure = 40, BadCertificate = 42, UnsupportedCertificate = 43, CertificateRevoked = 44, CertificateExpired = 45, CertificateUnknown = 46, IlegalParameter = 47, UnknownCA = 48, AccessDenied = 49, DecodeError = 50, DecryptError = 51, ExportRestriction = 60, ProtocolVersion = 70, InsuficientSecurity = 71, InternalError = 80, UserCancelled = 90, NoRenegotiation = 100 } #endregion internal class Alert : TlsStream { #region Fields private Context context; private AlertLevel level; private AlertDescription description; #endregion #region Constructors public Alert( Context context, AlertDescription description) : base() { this.context = context; this.description = description; this.inferAlertLevel(); this.fill(); } public Alert( Context context, AlertLevel level, AlertDescription description) : base() { this.context = context; this.level = level; this.description = description; this.fill(); } #endregion #region Properties public string Message { get { return Alert.GetAlertMessage(this.description); } } public bool IsWarning { get { return this.level == AlertLevel.Warning ? true : false; } } public bool IsFatal { get { return this.level == AlertLevel.Fatal ? true : false; } } public bool IsCloseNotify { get { if (this.IsWarning && this.description == AlertDescription.CloseNotify) { return true; } return false; } } #endregion #region Methods public void Update() { if ( this.description == AlertDescription.CloseNotify ) { this.context.ConnectionEnd = true; } if (this.IsFatal) { this.context.ConnectionEnd = true; if (this.context is ServerContext) { ((ServerContext)this.context).SslStream.Close(); } } } #endregion #region Private Methods private void fill() { this.Write((byte)level); this.Write((byte)description); } private void inferAlertLevel() { switch (description) { case AlertDescription.CloseNotify: case AlertDescription.NoRenegotiation: case AlertDescription.UserCancelled: this.level = AlertLevel.Warning; break; case AlertDescription.AccessDenied: case AlertDescription.BadCertificate: case AlertDescription.BadRecordMAC: case AlertDescription.CertificateExpired: case AlertDescription.CertificateRevoked: case AlertDescription.CertificateUnknown: case AlertDescription.DecodeError: case AlertDescription.DecompressionFailiure: case AlertDescription.DecryptError: case AlertDescription.DecryptionFailed: case AlertDescription.ExportRestriction: case AlertDescription.HandshakeFailiure: case AlertDescription.IlegalParameter: case AlertDescription.InsuficientSecurity: case AlertDescription.InternalError: case AlertDescription.ProtocolVersion: case AlertDescription.RecordOverflow: case AlertDescription.UnexpectedMessage: case AlertDescription.UnknownCA: case AlertDescription.UnsupportedCertificate: default: this.level = AlertLevel.Fatal; break; } } #endregion #region Static Methods public static string GetAlertMessage(AlertDescription description) { #if (DEBUG) switch (description) { case AlertDescription.AccessDenied: return "An inappropriate message was received."; case AlertDescription.BadCertificate: return "TLSCiphertext decrypted in an invalid way."; case AlertDescription.BadRecordMAC: return "Record with an incorrect MAC."; case AlertDescription.CertificateExpired: return "Certificate has expired or is not currently valid"; case AlertDescription.CertificateRevoked: return "Certificate was revoked by its signer."; case AlertDescription.CertificateUnknown: return "Certificate Unknown."; case AlertDescription.CloseNotify: return "Connection closed"; case AlertDescription.DecodeError: return "A message could not be decoded because some field was out of the specified range or the length of the message was incorrect."; case AlertDescription.DecompressionFailiure: return "The decompression function received improper input (e.g. data that would expand to excessive length)."; case AlertDescription.DecryptError: 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."; case AlertDescription.DecryptionFailed: return "Handshake cryptographic operation failed, including being unable to correctly verify a signature, decrypt a key exchange, or validate finished message."; case AlertDescription.ExportRestriction: return "Negotiation not in compliance with export restrictions was detected."; case AlertDescription.HandshakeFailiure: return "Unable to negotiate an acceptable set of security parameters given the options available."; case AlertDescription.IlegalParameter: return "A field in the handshake was out of range or inconsistent with other fields."; case AlertDescription.InsuficientSecurity: return "Negotiation has failed specifically because the server requires ciphers more secure than those supported by the client."; case AlertDescription.InternalError: return "Internal error unrelated to the peer or the correctness of the protocol makes it impossible to continue."; case AlertDescription.NoRenegotiation: return "Invalid renegotiation."; case AlertDescription.ProtocolVersion: return "Unsupported protocol version."; case AlertDescription.RecordOverflow: return "Invalid length on TLSCiphertext record or TLSCompressed record."; case AlertDescription.UnexpectedMessage: return "Invalid message received."; case AlertDescription.UnknownCA: return "CA can't be identified as a trusted CA."; case AlertDescription.UnsupportedCertificate: return "Certificate was of an unsupported type."; case AlertDescription.UserCancelled: return "Handshake cancelled by user."; default: return ""; } #else return "The authentication or decryption has failed."; #endif } #endregion } } --- NEW FILE: CipherSuiteCollection.cs --- /* Transport Security Layer (TLS) * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; using System.Collections; using System.Globalization; using System.Security.Cryptography; namespace Mono.Security.Protocol.Tls { internal sealed class CipherSuiteCollection : ArrayList { #region Fields private SecurityProtocolType protocol; #endregion #region Properties public CipherSuite this[string name] { get { return (CipherSuite)this[IndexOf(name)]; } set { this[IndexOf(name)] = (CipherSuite)value; } } public CipherSuite this[short code] { get { return (CipherSuite)base[IndexOf(code)]; } set { base[IndexOf(code)] = (CipherSuite)value; } } public new CipherSuite this[int code] { get { return (CipherSuite)base[code]; } set { base[code] = (CipherSuite)value; } } #endregion #region Constructors public CipherSuiteCollection(SecurityProtocolType protocol) : base() { this.protocol = protocol; } #endregion #region Methods public bool Contains(string name) { return(-1 != IndexOf(name)); } public int IndexOf(string name) { int index = 0; foreach (CipherSuite suite in this) { if (cultureAwareCompare(suite.Name, name)) { return index; } index++; } return -1; } public int IndexOf(short code) { int index = 0; foreach (CipherSuite suite in this) { if (suite.Code == code) { return index; } index++; } return -1; } public void RemoveAt(string errorMessage) { RemoveAt(IndexOf(errorMessage)); } public CipherSuite 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) { switch (this.protocol) { case SecurityProtocolType.Default: case SecurityProtocolType.Tls: return this.add( new TlsCipherSuite( code, name, cipherType, hashType, exchangeType, exportable, blockMode, keyMaterialSize, expandedKeyMaterialSize, effectiveKeyBytes, ivSize, blockSize)); case SecurityProtocolType.Ssl3: return this.add( new SslCipherSuite( code, name, cipherType, hashType, exchangeType, exportable, blockMode, keyMaterialSize, expandedKeyMaterialSize, effectiveKeyBytes, ivSize, blockSize)); case SecurityProtocolType.Ssl2: default: throw new NotSupportedException("Unsupported security protocol type."); } } private TlsCipherSuite add(TlsCipherSuite cipherSuite) { base.Add(cipherSuite); return cipherSuite; } private SslCipherSuite add(SslCipherSuite cipherSuite) { base.Add(cipherSuite); return cipherSuite; } private bool cultureAwareCompare(string strA, string strB) { try { return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase) == 0 ? true : false; } catch (NotSupportedException) { return strA.ToUpper() == strB.ToUpper() ? true : false; } } #endregion } } --- NEW FILE: CipherSuiteFactory.cs --- /* Transport Security Layer (TLS) * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; namespace Mono.Security.Protocol.Tls { internal class CipherSuiteFactory { public static CipherSuiteCollection GetSupportedCiphers(SecurityProtocolType protocol) { switch (protocol) { case SecurityProtocolType.Default: case SecurityProtocolType.Tls: return CipherSuiteFactory.GetTls1SupportedCiphers(); case SecurityProtocolType.Ssl3: return CipherSuiteFactory.GetSsl3SupportedCiphers(); case SecurityProtocolType.Ssl2: default: throw new NotSupportedException("Unsupported security protocol type"); } } #region Private Static Methods private static CipherSuiteCollection GetTls1SupportedCiphers() { CipherSuiteCollection scs = new CipherSuiteCollection(SecurityProtocolType.Tls); // Supported ciphers scs.Add((0x00 << 0x08) | 0x35, "TLS_RSA_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 32, 32, 256, 16, 16); scs.Add((0x00 << 0x08) | 0x2F, "TLS_RSA_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 16, 16, 128, 16, 16); scs.Add((0x00 << 0x08) | 0x0A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 24, 24, 168, 8, 8); scs.Add((0x00 << 0x08) | 0x05, "TLS_RSA_WITH_RC4_128_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); scs.Add((0x00 << 0x08) | 0x04, "TLS_RSA_WITH_RC4_128_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); scs.Add((0x00 << 0x08) | 0x09, "TLS_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 8, 8, 56, 8, 8); // Default CipherSuite // scs.Add(0, "TLS_NULL_WITH_NULL_NULL", CipherAlgorithmType.None, HashAlgorithmType.None, ExchangeAlgorithmType.None, true, false, 0, 0, 0, 0, 0); // RSA Cipher Suites // scs.Add((0x00 << 0x08) | 0x01, "TLS_RSA_WITH_NULL_MD5", CipherAlgorithmType.None, HashAlgorithmType.Md5, ExchangeAlgorithmType.None, true, false, 0, 0, 0, 0, 0); // scs.Add((0x00 << 0x08) | 0x02, "TLS_RSA_WITH_NULL_SHA", CipherAlgorithmType.None, HashAlgorithmType.Sha1, ExchangeAlgorithmType.None, true, false, 0, 0, 0, 0, 0); // scs.Add((0x00 << 0x08) | 0x03, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, false, 5, 16, 40, 0, 0); // scs.Add((0x00 << 0x08) | 0x05, "TLS_RSA_WITH_RC4_128_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); // scs.Add((0x00 << 0x08) | 0x04, "TLS_RSA_WITH_RC4_128_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); // scs.Add((0x00 << 0x08) | 0x06, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", CipherAlgorithmType.Rc2, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, true, 5, 16, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x07, "TLS_RSA_WITH_IDEA_CBC_SHA", "IDEA", HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x08, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x09, "TLS_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x0A, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 24, 24, 168, 8, 8); // Diffie-Hellman Cipher Suites // scs.Add((0x00 << 0x08) | 0x0B, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x0C, "TLS_DH_DSS_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, false, ExchangeAlgorithmType.DiffieHellman, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x0D, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // scs.Add((0x00 << 0x08) | 0x0E, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x0F, "TLS_DH_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, false, ExchangeAlgorithmType.DiffieHellman, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x10, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // scs.Add((0x00 << 0x08) | 0x11, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x12, "TLS_DHE_DSS_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x13, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // scs.Add((0x00 << 0x08) | 0x14, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x15, "TLS_DHE_RSA_WITH_DES_CBC_SHA", HashAlgorithmType.Sha1, CipherAlgorithmType.Des, false, ExchangeAlgorithmType.DiffieHellman, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x16, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // Anonymous Diffie-Hellman Cipher Suites // scs.Add((0x00 << 0x08) | 0x17, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.DiffieHellman, true, false, 5, 16, 40, 0, 0); // scs.Add((0x00 << 0x08) | 0x18, "TLS_DH_anon_WITH_RC4_128_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, false, ExchangeAlgorithmType.DiffieHellman, false, 16, 16, 128, 0, 0); // scs.Add((0x00 << 0x08) | 0x19, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x1A, "TLS_DH_anon_WITH_DES_CBC_SHA", "DES4", HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x1B, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // AES CipherSuites // // Ref: RFC3268 - (http://www.ietf.org/rfc/rfc3268.txt) // scs.Add((0x00 << 0x08) | 0x2F, "TLS_RSA_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 16, 16, 128, 16, 16); // scs.Add((0x00 << 0x08) | 0x30, "TLS_DH_DSS_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x31, "TLS_DH_RSA_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x32, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x33, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x34, "TLS_DH_anon_WITH_AES_128_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x35, "TLS_RSA_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 32, 32, 256, 16, 16); // scs.Add((0x00 << 0x08) | 0x36, "TLS_DH_DSS_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 32, 32, 256, 16, 16); // scs.Add((0x00 << 0x08) | 0x37, "TLS_DH_RSA_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 32, 32, 256, 16, 16); // scs.Add((0x00 << 0x08) | 0x38, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 32, 32, 256, 16, 16); // scs.Add((0x00 << 0x08) | 0x39, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 32, 32, 256, 16, 16); // scs.Add((0x00 << 0x08) | 0x3A, "TLS_DH_anon_WITH_AES_256_CBC_SHA", CipherAlgorithmType.Rijndael, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 32, 32, 256, 16, 16); return scs; } private static CipherSuiteCollection GetSsl3SupportedCiphers() { CipherSuiteCollection scs = new CipherSuiteCollection(SecurityProtocolType.Ssl3); // Supported ciphers scs.Add((0x00 << 0x08) | 0x0A, "SSL_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 24, 24, 168, 8, 8); scs.Add((0x00 << 0x08) | 0x05, "SSL_RSA_WITH_RC4_128_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); scs.Add((0x00 << 0x08) | 0x04, "SSL_RSA_WITH_RC4_128_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); scs.Add((0x00 << 0x08) | 0x09, "SSL_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 8, 8, 56, 8, 8); // Default CipherSuite // scs.Add(0, "SSL_NULL_WITH_NULL_NULL", CipherAlgorithmType.None, HashAlgorithmType.None, true, false, 0, 0, 0, 0, 0); // RSA Cipher Suites // scs.Add((0x00 << 0x08) | 0x01, "SSL_RSA_WITH_NULL_MD5", CipherAlgorithmType.None, HashAlgorithmType.Md5, ExchangeAlgorithmType.None, true, false, 0, 0, 0, 0, 0); // scs.Add((0x00 << 0x08) | 0x02, "SSL_RSA_WITH_NULL_SHA", CipherAlgorithmType.None, HashAlgorithmType.Sha1, true, ExchangeAlgorithmType.None, false, 0, 0, 0, 0, 0); // scs.Add((0x00 << 0x08) | 0x03, "SSL_RSA_EXPORT_WITH_RC4_40_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, false, 5, 16, 40, 0, 0); // scs.Add((0x00 << 0x08) | 0x05, "SSL_RSA_WITH_RC4_128_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); // scs.Add((0x00 << 0x08) | 0x04, "SSL_RSA_WITH_RC4_128_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaSign, false, false, 16, 16, 128, 0, 0); // scs.Add((0x00 << 0x08) | 0x06, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", CipherAlgorithmType.Rc2, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, true, 5, 16, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x07, "SSL_RSA_WITH_IDEA_CBC_SHA", "IDEA", HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 16, 16, 128, 8, 8); // scs.Add((0x00 << 0x08) | 0x08, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyEx, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x09, "SSL_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x0A, "SSL_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaSign, false, true, 24, 24, 168, 8, 8); // Diffie-Hellman Cipher Suites // scs.Add((0x00 << 0x08) | 0x0B, "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x0C, "SSL_DH_DSS_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x0D, "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // scs.Add((0x00 << 0x08) | 0x0E, "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x0F, "SSL_DH_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x10, "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // scs.Add((0x00 << 0x08) | 0x11, "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x12, "SSL_DHE_DSS_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x13, "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // scs.Add((0x00 << 0x08) | 0x14, "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, true, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x15, "SSL_DHE_RSA_WITH_DES_CBC_SHA", HashAlgorithmType.Sha1, CipherAlgorithmType.Des, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x16, "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); // Anonymous Diffie-Hellman Cipher Suites // scs.Add((0x00 << 0x08) | 0x17, "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.DiffieHellman, true, false, 5, 16, 40, 0, 0); // scs.Add((0x00 << 0x08) | 0x18, "SSL_DH_anon_WITH_RC4_128_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, false, ExchangeAlgorithmType.DiffieHellman, false, 16, 16, 128, 0, 0); // scs.Add((0x00 << 0x08) | 0x19, "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 5, 8, 40, 8, 8); // scs.Add((0x00 << 0x08) | 0x1A, "SSL_DH_anon_WITH_DES_CBC_SHA", "DES4", HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 8, 8, 56, 8, 8); // scs.Add((0x00 << 0x08) | 0x1B, "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", CipherAlgorithmType.TripleDes, HashAlgorithmType.Sha1, ExchangeAlgorithmType.DiffieHellman, false, true, 24, 24, 168, 8, 8); return scs; } #endregion } } --- NEW FILE: ContentType.cs --- /* Transport Security Layer (TLS) * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; namespace Mono.Security.Protocol.Tls { [Serializable] internal enum ContentType : byte { ChangeCipherSpec = 20, Alert = 21, Handshake = 22, ApplicationData = 23, } } --- NEW FILE: SslCipherSuite.cs --- /* Transport Security Layer (TLS) * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; using System.IO; using System.Text; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using Mono.Security; using Mono.Security.Cryptography; namespace Mono.Security.Protocol.Tls { internal class SslCipherSuite : CipherSuite { #region Fields private byte[] pad1; private byte[] pad2; #endregion #region Constructors public SslCipherSuite( short code, string name, CipherAlgorithmType cipherAlgorithmType, HashAlgorithmType hashAlgorithmType, ExchangeAlgorithmType exchangeAlgorithmType, bool exportable, bool blockMode, byte keyMaterialSize, byte expandedKeyMaterialSize, short effectiveKeyBytes, byte ivSize, byte blockSize) : base(code, name, cipherAlgorithmType, hashAlgorithmType, exchangeAlgorithmType, exportable, blockMode, keyMaterialSize, expandedKeyMaterialSize, effectiveKeyBytes, ivSize, blockSize) { int padLength = (hashAlgorithmType == HashAlgorithmType.Md5) ? 48 : 40; // Fill pad arrays this.pad1 = new byte[padLength]; this.pad2 = new byte[padLength]; /* Pad the key for inner and outer digest */ for (int i = 0; i < padLength; ++i) { pad1[i] = 0x36; pad2[i] = 0x5C; } } #endregion #region MAC Generation Methods public override byte[] ComputeServerRecordMAC(ContentType contentType, byte[] fragment) { HashAlgorithm hash = HashAlgorithm.Create(this.HashAlgorithmName); TlsStream block = new TlsStream(); block.Write(this.Context.ServerWriteMAC); block.Write(this.pad1); block.Write(this.Context.ReadSequenceNumber); block.Write((byte)contentType); block.Write((short)fragment.Length); block.Write(fragment); hash.ComputeHash(block.ToArray(), 0, (int)block.Length); byte[] blockHash = hash.Hash; block.Reset(); block.Write(this.Context.ServerWriteMAC); block.Write(this.pad2); block.Write(blockHash); hash.ComputeHash(block.ToArray(), 0, (int)block.Length); block.Reset(); return hash.Hash; } public override byte[] ComputeClientRecordMAC(ContentType contentType, byte[] fragment) { HashAlgorithm hash = HashAlgorithm.Create(this.HashAlgorithmName); TlsStream block = new TlsStream(); block.Write(this.Context.ClientWriteMAC); block.Write(this.pad1); block.Write(this.Context.WriteSequenceNumber); block.Write((byte)contentType); block.Write((short)fragment.Length); block.Write(fragment); hash.ComputeHash(block.ToArray(), 0, (int)block.Length); byte[] blockHash = hash.Hash; block.Reset(); block.Write(this.Context.ClientWriteMAC); block.Write(this.pad2); block.Write(blockHash); hash.ComputeHash(block.ToArray(), 0, (int)block.Length); block.Reset(); return hash.Hash; } #endregion #region Key Generation Methods public override void ComputeMasterSecret(byte[] preMasterSecret) { TlsStream masterSecret = new TlsStream(); masterSecret.Write(this.prf(preMasterSecret, "A", this.Context.RandomCS)); masterSecret.Write(this.prf(preMasterSecret, "BB", this.Context.RandomCS)); masterSecret.Write(this.prf(preMasterSecret, "CCC", this.Context.RandomCS)); this.Context.MasterSecret = masterSecret.ToArray(); } public override void ComputeKeys() { // Compute KeyBlock TlsStream tmp = new TlsStream(); char labelChar = 'A'; int count = 1; while (tmp.Length < this.KeyBlockSize) { string label = String.Empty; for (int i = 0; i < count; i++) { label += labelChar.ToString(); } byte[] block = this.prf(this.Context.MasterSecret, label.ToString(), this.Context.RandomSC); int size = (tmp.Length + block.Length) > this.KeyBlockSize ? (this.KeyBlockSize - (int)tmp.Length) : block.Length; tmp.Write(block, 0, size); labelChar++; count++; } // Create keyblock TlsStream keyBlock = new TlsStream(tmp.ToArray()); this.Context.ClientWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.ServerWriteMAC = keyBlock.ReadBytes(this.HashSize); this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize); if (!this.IsExportable) { if (this.IvSize != 0) { this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize); this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize); } else { this.Context.ClientWriteIV = CipherSuite.EmptyArray; this.Context.ServerWriteIV = CipherSuite.EmptyArray; } } else { HashAlgorithm md5 = MD5.Create(); // Generate final write keys byte[] finalClientWriteKey = new byte[md5.HashSize]; md5.TransformBlock(this.Context.ClientWriteKey, 0, this.Context.ClientWriteKey.Length, finalClientWriteKey, 0); finalClientWriteKey = md5.TransformFinalBlock(this.Context.RandomCS, 0, this.Context.RandomCS.Length); byte[] finalServerWriteKey = new byte[md5.HashSize]; md5.TransformBlock(this.Context.ServerWriteKey, 0, this.Context.ServerWriteKey.Length, finalServerWriteKey, 0); finalClientWriteKey = md5.TransformFinalBlock(this.Context.RandomSC, 0, this.Context.RandomSC.Length); this.Context.ClientWriteKey = finalClientWriteKey; this.Context.ServerWriteKey = finalServerWriteKey; // Generate IV keys this.Context.ClientWriteIV = md5.TransformFinalBlock(this.Context.RandomCS, 0, this.Context.RandomCS.Length); this.Context.ServerWriteIV = md5.TransformFinalBlock(this.Context.RandomSC, 0, this.Context.RandomSC.Length); } // Clear no more needed data keyBlock.Reset(); tmp.Reset(); } #endregion #region Private Methods private byte[] prf(byte[] secret, string label, byte[] random) { HashAlgorithm md5 = MD5.Create(); HashAlgorithm sha = SHA1.Create(); // Compute SHA hash TlsStream block = new TlsStream(); block.Write(Encoding.ASCII.GetBytes(label)); block.Write(secret); block.Write(random); byte[] shaHash = sha.ComputeHash(block.ToArray(), 0, (int)block.Length); block.Reset(); // Compute MD5 hash block.Write(secret); block.Write(shaHash); byte[] result = md5.ComputeHash(block.ToArray(), 0, (int)block.Length); // Free resources block.Reset(); return result; } #endregion } } --- NEW FILE: SslHandshakeHash.cs --- /* Transport Security Layer (TLS) * Copyright (c) 2003-2004 Carlos Guzman Alvarez * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ using System; using System.Security.Cryptography; namespace Mono.Security.Protocol.Tls { internal class SslHandshakeHash : System.Security.Cryptography.HashAlgorithm { #region Fields private HashAlgorithm md5; private HashAlgorithm sha; private bool hashing; private byte[] secret; private byte[] innerPadMD5; private byte[] outerPadMD5; private byte[] innerPadSHA; private byte[] outerPadSHA; #endregion #region Constructors public SslHandshakeHash(byte[] secret) { // Create md5 and sha1 hashes this.md5 = HashAlgorithm.Create("MD5"); this.sha = HashAlgorithm.Create("SHA1"); // Set HashSizeValue this.HashSizeValue = md5.HashSize + sha.HashSize; // Update secret this.secret = secret; this.Initialize(); } #endregion #region Methods public override void Initialize() { md5.Initialize(); sha.Initialize(); initializePad(); hashing = false; } protected override byte[] HashFinal() { if (!hashing) { hashing = true; } // Finalize the md5 hash md5.TransformBlock(this.secret, 0, this.secret.Length, this.secret, 0); md5.TransformFinalBlock(this.innerPadMD5, 0, this.innerPadMD5.Length); byte[] firstResultMD5 = md5.Hash; md5.Initialize(); md5.TransformBlock(this.secret, 0, this.secret.Length, this.secret, 0); md5.TransformBlock(this.outerPadMD5, 0, this.outerPadMD5.Length, this.outerPadMD5, 0); md5.TransformFinalBlock(firstResultMD5, 0, firstResultMD5.Length); // Finalize the sha1 hash sha.TransformBlock(this.secret, 0, this.secret.Length, this.secret, 0); sha.TransformFinalBlock(this.innerPadSHA, 0, this.innerPadSHA.Length); byte[] firstResultSHA = sha.Hash; sha.Initialize(); sha.TransformBlock(this.secret, 0, this.secret.Length, this.secret, 0); sha.TransformBlock(this.outerPadSHA, 0, this.outerPadSHA.Length, this.outerPadSHA, 0); sha.TransformFinalBlock(firstResultSHA, 0, firstResultSHA.Length); this.Initialize(); byte[] result = new byte[36]; System.Array.Copy(md5.Hash, 0, result, 0, 16); System.Array.Copy(sha.Hash, 0, result, 16, 20); return result; } protected override void HashCore( byte[] array, int ibStart, int cbSize) { if (!hashing) { hashing = true; } md5.TransformBlock(array, ibStart, cbSize, array, ibStart); sha.TransformBlock(array, ibStart, cbSize, array, ibStart); } #endregion #region Private Methods private void initializePad() { // Fill md5 arrays this.innerPadMD5 = new byte[48]; this.outerPadMD5 = new byte[48]; /* Pad the key for inner and outer digest */ for (int i = 0; i < 48; ++i) { this.innerPadMD5[i] = 0x36; this.outerPadMD5[i] = 0x5C; } // Fill sha arrays this.innerPadSHA = new byte[40]; this.outerPadSHA = new byte[40]; /* Pad the key for inner and outer digest */ for (int i = 0; i < 40; ++i) { this.innerPadSHA[i] = 0x36; this.outerPadSHA[i] = 0x5C; } } #endregion } } Index: CipherSuite.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls/CipherSuite.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** CipherSuite.cs 23 Feb 2004 12:15:58 -0000 1.5 --- CipherSuite.cs 3 Mar 2004 16:22:36 -0000 1.6 *************** *** 339,345 **** #region Abstract Methods ! public abstract byte[] ComputeClientRecordMAC(TlsContentType contentType, byte[] fragment); ! public abstract byte[] ComputeServerRecordMAC(TlsContentType contentType, byte[] fragment); public abstract void ComputeMasterSecret(byte[] preMasterSecret); --- 339,345 ---- #region Abstract Methods ! public abstract byte[] ComputeClientRecordMAC(ContentType contentType, byte[] fragment); ! public abstract byte[] ComputeServerRecordMAC(ContentType contentType, byte[] fragment); public abstract void ComputeMasterSecret(byte[] preMasterSecret); Index: ClientContext.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls/ClientContext.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ClientContext.cs 25 Feb 2004 15:39:33 -0000 1.2 --- ClientContext.cs 3 Mar 2004 16:22:36 -0000 1.3 *************** *** 36,40 **** private SslClientStream sslStream; private short clientHelloProtocol; - private bool helloDone; #endregion --- 36,39 ---- *************** *** 47,56 **** } - public bool HelloDone - { - get { return helloDone; } - set { helloDone = value; } - } - public short ClientHelloProtocol { --- 46,49 ---- *************** *** 81,85 **** public override void Clear() { - this.helloDone = false; this.clientHelloProtocol = 0; --- 74,77 ---- Index: ClientRecordProtocol.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** ClientRecordProtocol.cs 25 Feb 2004 15:39:33 -0000 1.3 --- ClientRecordProtocol.cs 3 Mar 2004 16:22:36 -0000 1.4 *************** *** 26,30 **** using System.IO; - using Mono.Security.Protocol.Tls.Alerts; using Mono.Security.Protocol.Tls.Handshake; using Mono.Security.Protocol.Tls.Handshake.Client; --- 26,29 ---- *************** *** 46,53 **** #region Send Messages ! public override void SendRecord(TlsHandshakeType type) { // Create the record message ! TlsHandshakeMessage msg = this.createClientHandshakeMessage(type); // Write record --- 45,52 ---- #region Send Messages ! public override void SendRecord(HandshakeType type) { // Create the record message ! HandshakeMessage msg = this.createClientHandshakeMessage(type); // Write record *************** *** 67,72 **** protected override void ProcessHandshakeMessage(TlsStream handMsg) { ! TlsHandshakeType handshakeType = (TlsHandshakeType)handMsg.ReadByte(); ! TlsHandshakeMessage message = null; // Read message length --- 66,71 ---- protected override void ProcessHandshakeMessage(TlsStream handMsg) { ! HandshakeType handshakeType = (HandshakeType)handMsg.ReadByte(); ! HandshakeMessage message = null; // Read message length *************** *** 91,112 **** #region Client Handshake Message Factories ! private TlsHandshakeMessage createClientHandshakeMessage( ! TlsHandshakeType type) { switch (type) { ! case TlsHandshakeType.ClientHello: return new TlsClientHello(this.context); ! case TlsHandshakeType.Certificate: return new TlsClientCertificate(this.context); ! case TlsHandshakeType.ClientKeyExchange: return new TlsClientKeyExchange(this.context); ! case TlsHandshakeType.CertificateVerify: return new TlsClientCertificateVerify(this.context); ! case TlsHandshakeType.Finished: return new TlsClientFinished(this.context); --- 90,111 ---- #region Client Handshake Message Factories ! private HandshakeMessage createClientHandshakeMessage( ! HandshakeType type) { switch (type) { ! case HandshakeType.ClientHello: return new TlsClientHello(this.context); ! case HandshakeType.Certificate: return new TlsClientCertificate(this.context); ! case HandshakeType.ClientKeyExchange: return new TlsClientKeyExchange(this.context); ! case HandshakeType.CertificateVerify: return new TlsClientCertificateVerify(this.context); ! case HandshakeType.Finished: return new TlsClientFinished(this.context); *************** *** 116,121 **** } ! private TlsHandshakeMessage createServerHandshakeMessage( ! TlsHandshakeType type, byte[] buffer) { ClientContext context = (ClientContext)this.context; --- 115,120 ---- } ! private HandshakeMessage createServerHandshakeMessage( ! HandshakeType type, byte[] buffer) { ClientContext context = (ClientContext)this.context; *************** *** 123,127 **** switch (type) { ! case TlsHandshakeType.HelloRequest: if (context.HandshakeState != HandshakeState.Started) { --- 122,126 ---- switch (type) { ! case HandshakeType.HelloRequest: if (context.HandshakeState != HandshakeState.Started) { *************** *** 131,155 **** { this.SendAlert( ! TlsAlertLevel.Warning, ! TlsAlertDescription.NoRenegotiation); } return null; ! case TlsHandshakeType.ServerHello: return new TlsServerHello(this.context, buffer); ! case TlsHandshakeType.Certificate: return new TlsServerCertificate(this.context, buffer); ! case TlsHandshakeType.ServerKeyExchange: return new TlsServerKeyExchange(this.context, buffer); ! case TlsHandshakeType.CertificateRequest: return new TlsServerCertificateRequest(this.context, buffer); ! case TlsHandshakeType.ServerHelloDone: return new TlsServerHelloDone(this.context, buffer); ! case TlsHandshakeType.Finished: return new TlsServerFinished(this.context, buffer); --- 130,154 ---- { this.SendAlert( ! AlertLevel.Warning, ! AlertDescription.NoRenegotiation); } return null; ! case HandshakeType.ServerHello: return new TlsServerHello(this.context, buffer); ! case HandshakeType.Certificate: return new TlsServerCertificate(this.context, buffer); ! case HandshakeType.ServerKeyExchange: return new TlsServerKeyExchange(this.context, buffer); ! case HandshakeType.CertificateRequest: return new TlsServerCertificateRequest(this.context, buffer); ! case HandshakeType.ServerHelloDone: return new TlsServerHelloDone(this.context, buffer); ! case HandshakeType.Finished: return new TlsServerFinished(this.context, buffer); Index: Context.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls/Context.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** Context.cs 25 Feb 2004 15:39:33 -0000 1.2 --- Context.cs 3 Mar 2004 16:22:36 -0000 1.3 *************** *** 30,34 **** using Mono.Security.Cryptography; - using Mono.Security.Protocol.Tls.Alerts; using Mono.Security.Protocol.Tls.Handshake; --- 30,33 ---- *************** *** 64,69 **** // Cipher suite information ! private CipherSuite cipher; ! private TlsCipherSuiteCollection supportedCiphers; // Handshake negotiation state --- 63,71 ---- // Cipher suite information ! private CipherSuite cipher; ! private CipherSuiteCollection supportedCiphers; ! ! // Last handshake message received ! private HandshakeType lastHandshakeMsg; // Handshake negotiation state *************** *** 188,194 **** } public HandshakeState HandshakeState { ! get { return this.HandshakeState; } set { this.handshakeState = value; } } --- 190,202 ---- } + public HandshakeType LastHandshakeMsg + { + get { return this.lastHandshakeMsg; } + set { this.lastHandshakeMsg = value; } + } + public HandshakeState HandshakeState { ! get { return this.handshakeState; } set { this.handshakeState = value; } } *************** *** 206,210 **** } ! public TlsCipherSuiteCollection SupportedCiphers { get { return supportedCiphers; } --- 214,218 ---- } ! public CipherSuiteCollection SupportedCiphers { get { return supportedCiphers; } *************** *** 392,398 **** #region Exception Methods ! public TlsException CreateException(TlsAlertLevel alertLevel, TlsAlertDescription alertDesc) { ! return CreateException(TlsAlert.GetAlertMessage(alertDesc)); } --- 400,408 ---- #region Exception Methods ! public TlsException CreateException( ! AlertLevel alertLevel, ! AlertDescription alertDesc) { ! return CreateException(Alert.GetAlertMessage(alertDesc)); } Index: RecordProtocol.cs =================================================================== RCS file: /cvsroot/pgsqlclient/pgsqlclient_10/Mono.Security/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** RecordProtocol.cs 24 Feb 2004 16:03:51 -0000 1.5 --- RecordProtocol.cs 3 Mar 2004 16:22:36 -0000 1.6 *************** *** 28,32 **** using System.Security.Cryptography.X509Certificates; - using Mono.Security.Protocol.Tls.Alerts; using Mono.Security.Protocol.Tls.Handshake; --- 28,31 ---- *************** *** 70,74 **** #region Abstract Methods ! public abstract void SendRecord(TlsHandshakeType type); protected abstract void ProcessHandshakeMessage(TlsStream handMsg); --- 69,73 ---- #region Abstract Methods ! public abstract void SendRecord(HandshakeType type); protected abstract void ProcessHandshakeMessage(TlsStream handMsg); *************** *** 93,99 **** } ! TlsContentType contentType = (TlsContentType)type; ! short protocol = this.readShort(); ! short length = this.readShort(); // Read Record data --- 92,98 ---- } ! ContentType contentType = (ContentType)type; ! short protocol = this.readShort(); ! short length = this.readShort(); // Read Record data *************** *** 115,119 **** // Decrypt message contents if needed ! if (contentType == TlsContentType.Alert && length == 2) { } --- 114,118 ---- // Decrypt message contents if needed ! if (contentType == ContentType.Alert && length == 2) { } *************** *** 121,125 **** { if (this.context.IsActual && ! contentType != TlsContentType.ChangeCipherSpec) { message = this.decryptRecordFragment( --- 120,124 ---- { if (this.context.IsActual && ! contentType != ContentType.ChangeCipherSpec) { message = this.decryptRecordFragment( *************** *** 134,152 **** switch (contentType) { ! case TlsContentType.Alert: this.processAlert( ! (TlsAlertLevel)message.ReadByte(), ! (TlsAlertDescription)message.ReadByte()); break; ! case TlsContentType.ChangeCipherSpec: // Reset sequence numbers this.context.ReadSequenceNumber = 0; break; ! case TlsContentType.ApplicationData: break; ! case TlsContentType.Handshake: while (!message.EOF) { --- 133,151 ---- switch (contentType) { ! case ContentType.Alert: this.processAlert( ! (AlertLevel)message.ReadByte(), ! (AlertDescription)message.ReadByte()); break; ! case ContentType.ChangeCipherSpec: // Reset sequence numbers this.context.ReadSequenceNumber = 0; break; ! case ContentType.ApplicationData: break; ! case ContentType.Handshake: while (!message.EOF) { *************** *** 176,192 **** private void processAlert( ! TlsAlertLevel alertLevel, ! TlsAlertDescription alertDesc) { switch (alertLevel) { ! case TlsAlertLevel.Fatal: throw this.context.CreateException(alertLevel, alertDesc); ! case TlsAlertLevel.Warning: default: switch (alertDesc) { ! case TlsAlertDescription.CloseNotify: this.context.ConnectionEnd = true; break; --- 175,191 ---- private void processAlert( ! AlertLevel alertLevel, ! AlertDescription alertDesc) { switch (alertLevel) { ! case AlertLevel.Fatal: throw this.context.CreateException(alertLevel, alertDesc); ! case AlertLevel.Warning: default: switch (alertDesc) { ! case AlertDescription.CloseNotify: this.context.ConnectionEnd = true; break; *************** *** 200,219 **** #region Send Alert Methods ! public void SendAlert(TlsAlertDescription description) { ! this.SendAlert(new TlsAlert(this.Context, description)); } public void SendAlert( ! TlsAlertLevel level, ! TlsAlertDescription description) { ! this.SendAlert(new TlsAlert(this.Context, level, description)); } ! public void SendAlert(TlsAlert alert) { // Write record ! this.SendRecord(TlsContentType.Alert, alert.ToArray()); // Update session --- 199,218 ---- #region Send Alert Methods ! public void SendAlert(AlertDescription description) { ! this.SendAlert(new Alert(this.Context, description)); } public void SendAlert( ! AlertLevel level, ! AlertDescription description) { ! this.SendAlert(new Alert(this.Context, level, description)); } ! public void SendAlert(Alert alert) { // Write record ! this.SendRecord(ContentType.Alert, alert.ToArray()); // Update session *************** *** 231,235 **** { // Send Change Cipher Spec message ! this.SendRecord(TlsContentType.ChangeCipherSpec, new byte[] {1}); // Reset sequence numbers --- 230,234 ---- { // Send Change Cipher Spec message ! this.SendRecord(ContentType.ChangeCipherSpec, new byte[] {1}); // Reset sequence numbers *************** *** 240,247 **** // Send Finished message ! this.SendRecord(TlsHandshakeType.Finished); } ! public void SendRecord(TlsContentType contentType, byte[] recordData) { if (this.context.ConnectionEnd) --- 239,246 ---- // Send Finished message ! this.SendRecord(HandshakeType.Finished); } ! public void SendRecord(ContentType contentType, byte[] recordData) { if (this.context.ConnectionEnd) *************** *** 255,259 **** } ! public byte[] EncodeRecord(TlsContentType contentType, byte[] recordData) { return this.EncodeRecord( --- 254,258 ---- } ! public byte[] EncodeRecord(ContentType contentType, byte[] recordData) { return this.EncodeRecord( *************** *** 265,272 **** public byte[] EncodeRecord( ! Tls... [truncated message content] |