This commit is contained in:
Jo Shields 2015-03-06 17:21:03 +00:00
parent ffce5d5289
commit 4808441afc
4 changed files with 644 additions and 1 deletions

View File

@ -0,0 +1,200 @@
From 1509226c41d74194c146deb173e752b8d3cdeec4 Mon Sep 17 00:00:00 2001
From: Sebastien Pouliot <sebastien@xamarin.com>
Date: Fri, 6 Mar 2015 10:34:14 -0500
Subject: [PATCH 1/3] TLS protocol: add handshake state validation
---
.../ClientRecordProtocol.cs | 33 ++++++++++++++++---
.../Mono.Security.Protocol.Tls/Context.cs | 2 ++
.../Mono.Security.Protocol.Tls/RecordProtocol.cs | 8 ++---
.../ServerRecordProtocol.cs | 37 ++++++++++++++++------
4 files changed, 59 insertions(+), 21 deletions(-)
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs
index 7cece50..acaa0c2 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs
@@ -129,6 +129,7 @@ namespace Mono.Security.Protocol.Tls
HandshakeType type, byte[] buffer)
{
ClientContext context = (ClientContext)this.context;
+ var last = context.LastHandshakeMsg;
switch (type)
{
@@ -148,23 +149,44 @@ namespace Mono.Security.Protocol.Tls
return null;
case HandshakeType.ServerHello:
+ if (last != HandshakeType.HelloRequest)
+ break;
return new TlsServerHello(this.context, buffer);
+ // Optional
case HandshakeType.Certificate:
+ if (last != HandshakeType.ServerHello)
+ break;
return new TlsServerCertificate(this.context, buffer);
+ // Optional
case HandshakeType.ServerKeyExchange:
- return new TlsServerKeyExchange(this.context, buffer);
+ // only for RSA_EXPORT
+ if (last == HandshakeType.Certificate && context.Current.Cipher.IsExportable)
+ return new TlsServerKeyExchange(this.context, buffer);
+ break;
+ // Optional
case HandshakeType.CertificateRequest:
- return new TlsServerCertificateRequest(this.context, buffer);
+ if (last == HandshakeType.ServerKeyExchange || last == HandshakeType.Certificate)
+ return new TlsServerCertificateRequest(this.context, buffer);
+ break;
case HandshakeType.ServerHelloDone:
- return new TlsServerHelloDone(this.context, buffer);
+ if (last == HandshakeType.CertificateRequest || last == HandshakeType.Certificate || last == HandshakeType.ServerHello)
+ return new TlsServerHelloDone(this.context, buffer);
+ break;
case HandshakeType.Finished:
- return new TlsServerFinished(this.context, buffer);
-
+ // depends if a full (ServerHelloDone) or an abbreviated handshake (ServerHello) is being done
+ bool check = context.AbbreviatedHandshake ? (last == HandshakeType.ServerHello) : (last == HandshakeType.ServerHelloDone);
+ // ChangeCipherSpecDone is not an handshake message (it's a content type) but still needs to be happens before finished
+ if (check && context.ChangeCipherSpecDone) {
+ context.ChangeCipherSpecDone = false;
+ return new TlsServerFinished (this.context, buffer);
+ }
+ break;
+
default:
throw new TlsException(
AlertDescription.UnexpectedMessage,
@@ -172,6 +194,7 @@ namespace Mono.Security.Protocol.Tls
"Unknown server handshake message received ({0})",
type.ToString()));
}
+ throw new TlsException (AlertDescription.HandshakeFailiure, String.Format ("Protocol error, unexpected protocol transition from {0} to {1}", last, type));
}
#endregion
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs
index b4caf28..3923daf 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/Context.cs
@@ -122,6 +122,8 @@ namespace Mono.Security.Protocol.Tls
set { this.protocolNegotiated = value; }
}
+ public bool ChangeCipherSpecDone { get; set; }
+
public SecurityProtocolType SecurityProtocol
{
get
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
index 5895106..e8ae131 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
@@ -88,6 +88,8 @@ namespace Mono.Security.Protocol.Tls
} else {
ctx.StartSwitchingSecurityParameters (false);
}
+
+ ctx.ChangeCipherSpecDone = true;
}
public virtual HandshakeMessage GetMessage(HandshakeType type)
@@ -348,9 +350,6 @@ namespace Mono.Security.Protocol.Tls
// Try to read the Record Content Type
int type = internalResult.InitialBuffer[0];
- // Set last handshake message received to None
- this.context.LastHandshakeMsg = HandshakeType.ClientHello;
-
ContentType contentType = (ContentType)type;
byte[] buffer = this.ReadRecordBuffer(type, record);
if (buffer == null)
@@ -458,9 +457,6 @@ namespace Mono.Security.Protocol.Tls
// Try to read the Record Content Type
int type = recordTypeBuffer[0];
- // Set last handshake message received to None
- this.context.LastHandshakeMsg = HandshakeType.ClientHello;
-
ContentType contentType = (ContentType)type;
byte[] buffer = this.ReadRecordBuffer(type, record);
if (buffer == null)
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs
index 6e316dc..31c2547 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ServerRecordProtocol.cs
@@ -33,6 +33,8 @@ namespace Mono.Security.Protocol.Tls
{
internal class ServerRecordProtocol : RecordProtocol
{
+ TlsClientCertificate cert;
+
#region Constructors
public ServerRecordProtocol(
@@ -93,30 +95,45 @@ namespace Mono.Security.Protocol.Tls
private HandshakeMessage createClientHandshakeMessage(
HandshakeType type, byte[] buffer)
{
+ var last = context.LastHandshakeMsg;
switch (type)
{
case HandshakeType.ClientHello:
return new TlsClientHello(this.context, buffer);
case HandshakeType.Certificate:
- return new TlsClientCertificate(this.context, buffer);
+ if (last != HandshakeType.ClientHello)
+ break;
+ cert = new TlsClientCertificate(this.context, buffer);
+ return cert;
case HandshakeType.ClientKeyExchange:
- return new TlsClientKeyExchange(this.context, buffer);
+ if (last == HandshakeType.ClientHello || last == HandshakeType.Certificate)
+ return new TlsClientKeyExchange(this.context, buffer);
+ break;
case HandshakeType.CertificateVerify:
- return new TlsClientCertificateVerify(this.context, buffer);
+ if (last == HandshakeType.ClientKeyExchange && cert != null)
+ return new TlsClientCertificateVerify(this.context, buffer);
+ break;
case HandshakeType.Finished:
- return new TlsClientFinished(this.context, buffer);
-
+ // Certificates are optional, but if provided, they should send a CertificateVerify
+ bool check = (cert == null) ? (last == HandshakeType.ClientKeyExchange) : (last == HandshakeType.CertificateVerify);
+ // ChangeCipherSpecDone is not an handshake message (it's a content type) but still needs to be happens before finished
+ if (check && context.ChangeCipherSpecDone) {
+ context.ChangeCipherSpecDone = false;
+ return new TlsClientFinished(this.context, buffer);
+ }
+ break;
+
default:
- throw new TlsException(
- AlertDescription.UnexpectedMessage,
- String.Format(CultureInfo.CurrentUICulture,
- "Unknown server handshake message received ({0})",
- type.ToString()));
+ throw new TlsException(AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture,
+ "Unknown server handshake message received ({0})",
+ type.ToString()));
+ break;
}
+ throw new TlsException (AlertDescription.HandshakeFailiure, String.Format ("Protocol error, unexpected protocol transition from {0} to {1}", last, type));
}
private HandshakeMessage createServerHandshakeMessage(
--
1.9.1

View File

@ -0,0 +1,204 @@
From b371da6b2d68b4cdd0f21d6342af6c42794f998b Mon Sep 17 00:00:00 2001
From: Sebastien Pouliot <sebastien@xamarin.com>
Date: Fri, 6 Mar 2015 10:34:59 -0500
Subject: [PATCH 2/3] Remove the client-side SSLv2 fallback.
There's almost no SSLv3 web site left so a v2 fallback is only extra
code we do not need to carry forward.
---
.../Mono.Security.Protocol.Tls/RecordProtocol.cs | 169 +--------------------
1 file changed, 1 insertion(+), 168 deletions(-)
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
index e8ae131..e194013 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
@@ -519,87 +519,11 @@ namespace Mono.Security.Protocol.Tls
private byte[] ReadRecordBuffer (int contentType, Stream record)
{
- switch (contentType)
- {
- case 0x80:
- return this.ReadClientHelloV2(record);
-
- default:
- if (!Enum.IsDefined(typeof(ContentType), (ContentType)contentType))
- {
- throw new TlsException(AlertDescription.DecodeError);
- }
- return this.ReadStandardRecordBuffer(record);
- }
- }
-
- private byte[] ReadClientHelloV2 (Stream record)
- {
- int msgLength = record.ReadByte ();
- // process further only if the whole record is available
- if (record.CanSeek && (msgLength + 1 > record.Length))
- {
- return null;
- }
-
- byte[] message = new byte[msgLength];
- record.Read (message, 0, msgLength);
-
- int msgType = message [0];
- if (msgType != 1)
- {
- throw new TlsException(AlertDescription.DecodeError);
- }
- int protocol = (message [1] << 8 | message [2]);
- int cipherSpecLength = (message [3] << 8 | message [4]);
- int sessionIdLength = (message [5] << 8 | message [6]);
- int challengeLength = (message [7] << 8 | message [8]);
- int length = (challengeLength > 32) ? 32 : challengeLength;
-
- // Read CipherSpecs
- byte[] cipherSpecV2 = new byte[cipherSpecLength];
- Buffer.BlockCopy (message, 9, cipherSpecV2, 0, cipherSpecLength);
-
- // Read session ID
- byte[] sessionId = new byte[sessionIdLength];
- Buffer.BlockCopy (message, 9 + cipherSpecLength, sessionId, 0, sessionIdLength);
-
- // Read challenge ID
- byte[] challenge = new byte[challengeLength];
- Buffer.BlockCopy (message, 9 + cipherSpecLength + sessionIdLength, challenge, 0, challengeLength);
-
- if (challengeLength < 16 || cipherSpecLength == 0 || (cipherSpecLength % 3) != 0)
+ if (!Enum.IsDefined(typeof(ContentType), (ContentType)contentType))
{
throw new TlsException(AlertDescription.DecodeError);
}
- // Updated the Session ID
- if (sessionId.Length > 0)
- {
- this.context.SessionId = sessionId;
- }
-
- // Update the protocol version
- this.Context.ChangeProtocol((short)protocol);
-
- // Select the Cipher suite
- this.ProcessCipherSpecV2Buffer(this.Context.SecurityProtocol, cipherSpecV2);
-
- // Updated the Client Random
- this.context.ClientRandom = new byte [32]; // Always 32
- // 1. if challenge is bigger than 32 bytes only use the last 32 bytes
- // 2. right justify (0) challenge in ClientRandom if less than 32
- Buffer.BlockCopy (challenge, challenge.Length - length, this.context.ClientRandom, 32 - length, length);
-
- // Set
- this.context.LastHandshakeMsg = HandshakeType.ClientHello;
- this.context.ProtocolNegotiated = true;
-
- return message;
- }
-
- private byte[] ReadStandardRecordBuffer (Stream record)
- {
byte[] header = new byte[4];
if (record.Read (header, 0, 4) != 4)
throw new TlsException ("buffer underrun");
@@ -1037,96 +961,5 @@ namespace Mono.Security.Protocol.Tls
}
#endregion
-
- #region CipherSpecV2 processing
-
- private void ProcessCipherSpecV2Buffer (SecurityProtocolType protocol, byte[] buffer)
- {
- TlsStream codes = new TlsStream(buffer);
-
- string prefix = (protocol == SecurityProtocolType.Ssl3) ? "SSL_" : "TLS_";
-
- while (codes.Position < codes.Length)
- {
- byte check = codes.ReadByte();
-
- if (check == 0)
- {
- // SSL/TLS cipher spec
- short code = codes.ReadInt16();
- int index = this.Context.SupportedCiphers.IndexOf(code);
- if (index != -1)
- {
- this.Context.Negotiating.Cipher = this.Context.SupportedCiphers[index];
- break;
- }
- }
- else
- {
- byte[] tmp = new byte[2];
- codes.Read(tmp, 0, tmp.Length);
-
- int tmpCode = ((check & 0xff) << 16) | ((tmp[0] & 0xff) << 8) | (tmp[1] & 0xff);
- CipherSuite cipher = this.MapV2CipherCode(prefix, tmpCode);
-
- if (cipher != null)
- {
- this.Context.Negotiating.Cipher = cipher;
- break;
- }
- }
- }
-
- if (this.Context.Negotiating == null)
- {
- throw new TlsException(AlertDescription.InsuficientSecurity, "Insuficient Security");
- }
- }
-
- private CipherSuite MapV2CipherCode(string prefix, int code)
- {
- try
- {
- switch (code)
- {
- case 65664:
- // TLS_RC4_128_WITH_MD5
- return this.Context.SupportedCiphers[prefix + "RSA_WITH_RC4_128_MD5"];
-
- case 131200:
- // TLS_RC4_128_EXPORT40_WITH_MD5
- return this.Context.SupportedCiphers[prefix + "RSA_EXPORT_WITH_RC4_40_MD5"];
-
- case 196736:
- // TLS_RC2_CBC_128_CBC_WITH_MD5
- return this.Context.SupportedCiphers[prefix + "RSA_EXPORT_WITH_RC2_CBC_40_MD5"];
-
- case 262272:
- // TLS_RC2_CBC_128_CBC_EXPORT40_WITH_MD5
- return this.Context.SupportedCiphers[prefix + "RSA_EXPORT_WITH_RC2_CBC_40_MD5"];
-
- case 327808:
- // TLS_IDEA_128_CBC_WITH_MD5
- return null;
-
- case 393280:
- // TLS_DES_64_CBC_WITH_MD5
- return null;
-
- case 458944:
- // TLS_DES_192_EDE3_CBC_WITH_MD5
- return null;
-
- default:
- return null;
- }
- }
- catch
- {
- return null;
- }
- }
-
- #endregion
}
}
--
1.9.1

View File

@ -0,0 +1,233 @@
From 9c38772f094168d8bfd5bc73bf8925cd04faad10 Mon Sep 17 00:00:00 2001
From: Sebastien Pouliot <sebastien@xamarin.com>
Date: Fri, 6 Mar 2015 10:35:27 -0500
Subject: [PATCH 3/3] Remove the EXPORT ciphers and related code path
That was still useful in 2003/2004 but the technical and legal landscape
changed a lot since then. Removing the old, limited key size, cipher
suites also allow removed additional parts of the code that deals with
them.
---
.../CipherSuiteFactory.cs | 28 +++++------
.../ClientRecordProtocol.cs | 7 ---
.../Mono.Security.Protocol.Tls/SslCipherSuite.cs | 54 ++--------------------
.../Mono.Security.Protocol.Tls/SslServerStream.cs | 12 +----
.../Mono.Security.Protocol.Tls/TlsCipherSuite.cs | 40 ++--------------
5 files changed, 26 insertions(+), 115 deletions(-)
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/CipherSuiteFactory.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/CipherSuiteFactory.cs
index b8eb7ec..13573cb 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/CipherSuiteFactory.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/CipherSuiteFactory.cs
@@ -116,14 +116,14 @@ namespace Mono.Security.Protocol.Tls
scs.Add((0x00 << 0x08) | 0x09, "TLS_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, false, true, 8, 8, 56, 8, 8);
// Supported exportable ciphers
- 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) | 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) | 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) | 0x60, "TLS_RSA_EXPORT_WITH_RC4_56_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
- scs.Add((0x00 << 0x08) | 0x61, "TLS_RSA_EXPORT_WITH_RC2_CBC_56_MD5", CipherAlgorithmType.Rc2, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, true, 7, 16, 56, 8, 8);
+ // 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) | 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) | 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) | 0x60, "TLS_RSA_EXPORT_WITH_RC4_56_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
+ // scs.Add((0x00 << 0x08) | 0x61, "TLS_RSA_EXPORT_WITH_RC2_CBC_56_MD5", CipherAlgorithmType.Rc2, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, true, 7, 16, 56, 8, 8);
// 56 bits but we use 64 bits because of parity (DES is really 56 bits)
- scs.Add((0x00 << 0x08) | 0x62, "TLS_RSA_EXPORT_WITH_DES_CBC_56_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 8, 8, 64, 8, 8);
- scs.Add((0x00 << 0x08) | 0x64, "TLS_RSA_EXPORT_WITH_RC4_56_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
+ // scs.Add((0x00 << 0x08) | 0x62, "TLS_RSA_EXPORT_WITH_DES_CBC_56_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 8, 8, 64, 8, 8);
+ // scs.Add((0x00 << 0x08) | 0x64, "TLS_RSA_EXPORT_WITH_RC4_56_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
// Default CipherSuite
// scs.Add(0, "TLS_NULL_WITH_NULL_NULL", CipherAlgorithmType.None, HashAlgorithmType.None, ExchangeAlgorithmType.None, true, false, 0, 0, 0, 0, 0);
@@ -195,14 +195,14 @@ namespace Mono.Security.Protocol.Tls
scs.Add((0x00 << 0x08) | 0x09, "SSL_RSA_WITH_DES_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, false, true, 8, 8, 56, 8, 8);
// Supported exportable ciphers
- 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) | 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) | 0x08, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 5, 8, 40, 8, 8);
- scs.Add((0x00 << 0x08) | 0x60, "SSL_RSA_EXPORT_WITH_RC4_56_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
- scs.Add((0x00 << 0x08) | 0x61, "SSL_RSA_EXPORT_WITH_RC2_CBC_56_MD5", CipherAlgorithmType.Rc2, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, true, 7, 16, 56, 8, 8);
+ // 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) | 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) | 0x08, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 5, 8, 40, 8, 8);
+ // scs.Add((0x00 << 0x08) | 0x60, "SSL_RSA_EXPORT_WITH_RC4_56_MD5", CipherAlgorithmType.Rc4, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
+ // scs.Add((0x00 << 0x08) | 0x61, "SSL_RSA_EXPORT_WITH_RC2_CBC_56_MD5", CipherAlgorithmType.Rc2, HashAlgorithmType.Md5, ExchangeAlgorithmType.RsaKeyX, true, true, 7, 16, 56, 8, 8);
// 56 bits but we use 64 bits because of parity (DES is really 56 bits)
- scs.Add((0x00 << 0x08) | 0x62, "SSL_RSA_EXPORT_WITH_DES_CBC_56_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 8, 8, 64, 8, 8);
- scs.Add((0x00 << 0x08) | 0x64, "SSL_RSA_EXPORT_WITH_RC4_56_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
+ // scs.Add((0x00 << 0x08) | 0x62, "SSL_RSA_EXPORT_WITH_DES_CBC_56_SHA", CipherAlgorithmType.Des, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, true, 8, 8, 64, 8, 8);
+ // scs.Add((0x00 << 0x08) | 0x64, "SSL_RSA_EXPORT_WITH_RC4_56_SHA", CipherAlgorithmType.Rc4, HashAlgorithmType.Sha1, ExchangeAlgorithmType.RsaKeyX, true, false, 7, 16, 56, 0, 0);
// Default CipherSuite
// scs.Add(0, "SSL_NULL_WITH_NULL_NULL", CipherAlgorithmType.None, HashAlgorithmType.None, true, false, 0, 0, 0, 0, 0);
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs
index acaa0c2..0602e70 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ClientRecordProtocol.cs
@@ -160,13 +160,6 @@ namespace Mono.Security.Protocol.Tls
return new TlsServerCertificate(this.context, buffer);
// Optional
- case HandshakeType.ServerKeyExchange:
- // only for RSA_EXPORT
- if (last == HandshakeType.Certificate && context.Current.Cipher.IsExportable)
- return new TlsServerKeyExchange(this.context, buffer);
- break;
-
- // Optional
case HandshakeType.CertificateRequest:
if (last == HandshakeType.ServerKeyExchange || last == HandshakeType.Certificate)
return new TlsServerCertificateRequest(this.context, buffer);
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslCipherSuite.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslCipherSuite.cs
index ae9b9d5..da95ed1 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslCipherSuite.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslCipherSuite.cs
@@ -190,59 +190,15 @@ namespace Mono.Security.Protocol.Tls
this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
- if (!this.IsExportable)
+ if (this.IvSize != 0)
{
- 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;
- }
+ this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
+ this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
}
else
{
- HashAlgorithm md5 = MD5.Create();
-
- int keySize = (md5.HashSize >> 3); //in bytes not bits
- byte[] temp = new byte [keySize];
-
- // Generate final write keys
- md5.TransformBlock(this.Context.ClientWriteKey, 0, this.Context.ClientWriteKey.Length, temp, 0);
- md5.TransformFinalBlock(this.Context.RandomCS, 0, this.Context.RandomCS.Length);
- byte[] finalClientWriteKey = new byte[this.ExpandedKeyMaterialSize];
- Buffer.BlockCopy(md5.Hash, 0, finalClientWriteKey, 0, this.ExpandedKeyMaterialSize);
-
- md5.Initialize();
- md5.TransformBlock(this.Context.ServerWriteKey, 0, this.Context.ServerWriteKey.Length, temp, 0);
- md5.TransformFinalBlock(this.Context.RandomSC, 0, this.Context.RandomSC.Length);
- byte[] finalServerWriteKey = new byte[this.ExpandedKeyMaterialSize];
- Buffer.BlockCopy(md5.Hash, 0, finalServerWriteKey, 0, this.ExpandedKeyMaterialSize);
-
- this.Context.ClientWriteKey = finalClientWriteKey;
- this.Context.ServerWriteKey = finalServerWriteKey;
-
- // Generate IV keys
- if (this.IvSize > 0)
- {
- md5.Initialize();
- temp = md5.ComputeHash(this.Context.RandomCS, 0, this.Context.RandomCS.Length);
- this.Context.ClientWriteIV = new byte[this.IvSize];
- Buffer.BlockCopy(temp, 0, this.Context.ClientWriteIV, 0, this.IvSize);
-
- md5.Initialize();
- temp = md5.ComputeHash(this.Context.RandomSC, 0, this.Context.RandomSC.Length);
- this.Context.ServerWriteIV = new byte[this.IvSize];
- Buffer.BlockCopy(temp, 0, this.Context.ServerWriteIV, 0, this.IvSize);
- }
- else
- {
- this.Context.ClientWriteIV = CipherSuite.EmptyArray;
- this.Context.ServerWriteIV = CipherSuite.EmptyArray;
- }
+ this.Context.ClientWriteIV = CipherSuite.EmptyArray;
+ this.Context.ServerWriteIV = CipherSuite.EmptyArray;
}
DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
index 6862c69..fb8ede4 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslServerStream.cs
@@ -233,16 +233,8 @@ namespace Mono.Security.Protocol.Tls
// Send ServerCertificate message
this.protocol.SendRecord(HandshakeType.Certificate);
- // If the negotiated cipher is a KeyEx cipher send ServerKeyExchange
- if (this.context.Negotiating.Cipher.IsExportable)
- {
- this.protocol.SendRecord(HandshakeType.ServerKeyExchange);
- }
-
- // If the negotiated cipher is a KeyEx cipher or
- // the client certificate is required send the CertificateRequest message
- if (this.context.Negotiating.Cipher.IsExportable ||
- ((ServerContext)this.context).ClientCertificateRequired ||
+ // If the client certificate is required send the CertificateRequest message
+ if (((ServerContext)this.context).ClientCertificateRequired ||
((ServerContext)this.context).RequestClientCertificate)
{
this.protocol.SendRecord(HandshakeType.CertificateRequest);
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/TlsCipherSuite.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/TlsCipherSuite.cs
index f4feb4e..2b261bf 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/TlsCipherSuite.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/TlsCipherSuite.cs
@@ -123,45 +123,15 @@ namespace Mono.Security.Protocol.Tls
this.Context.ClientWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
this.Context.ServerWriteKey = keyBlock.ReadBytes(this.KeyMaterialSize);
- if (!this.IsExportable)
+ if (this.IvSize != 0)
{
- 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;
- }
+ this.Context.ClientWriteIV = keyBlock.ReadBytes(this.IvSize);
+ this.Context.ServerWriteIV = keyBlock.ReadBytes(this.IvSize);
}
else
{
- // Generate final write keys
- byte[] finalClientWriteKey = PRF(this.Context.ClientWriteKey, "client write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize);
- byte[] finalServerWriteKey = PRF(this.Context.ServerWriteKey, "server write key", this.Context.RandomCS, this.ExpandedKeyMaterialSize);
-
- this.Context.ClientWriteKey = finalClientWriteKey;
- this.Context.ServerWriteKey = finalServerWriteKey;
-
- if (this.IvSize > 0)
- {
- // Generate IV block
- byte[] ivBlock = PRF(CipherSuite.EmptyArray, "IV block", this.Context.RandomCS, this.IvSize*2);
-
- // Generate IV keys
- this.Context.ClientWriteIV = new byte[this.IvSize];
- Buffer.BlockCopy(ivBlock, 0, this.Context.ClientWriteIV, 0, this.Context.ClientWriteIV.Length);
-
- this.Context.ServerWriteIV = new byte[this.IvSize];
- Buffer.BlockCopy(ivBlock, this.IvSize, this.Context.ServerWriteIV, 0, this.Context.ServerWriteIV.Length);
- }
- else
- {
- this.Context.ClientWriteIV = CipherSuite.EmptyArray;
- this.Context.ServerWriteIV = CipherSuite.EmptyArray;
- }
+ this.Context.ClientWriteIV = CipherSuite.EmptyArray;
+ this.Context.ServerWriteIV = CipherSuite.EmptyArray;
}
DebugHelper.WriteLine(">>>> KeyBlock", keyBlock.ToArray());
--
1.9.1

View File

@ -28,13 +28,16 @@
Name: mono-core
Version: 3.12.0
Release: 1
Release: 2
Summary: Cross-platform, Open Source, .NET development framework
License: LGPL-2.1 and MIT and MS-PL
Group: Development/Languages/Mono
Url: http://www.mono-project.com
Source0: http://download.mono-project.com/sources/mono/mono-%{version}.tar.bz2
Patch0: 0001-Workaround-for-X509Certificate.RSA-throwing-an-unhan.patch
Patch1: 0001-TLS-protocol-add-handshake-state-validation.patch
Patch2: 0002-Remove-the-client-side-SSLv2-fallback.patch
Patch3: 0003-Remove-the-EXPORT-ciphers-and-related-code-path.patch
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: bison
@ -112,6 +115,9 @@ technologies that have been submitted to the ECMA for standardization.
%prep
%setup -q -n mono-%{version}
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
%build
./autogen.sh