Skip to content
Permalink
Browse files

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.
(cherry picked from commit b371da6)
  • Loading branch information
spouliot authored and screenconnect committed Mar 6, 2015
1 parent 8447a9e commit 7134b8cef6db98cbf66b145dbf8c13065994b730
Showing with 1 addition and 168 deletions.
  1. +1 −168 mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
@@ -444,87 +444,11 @@ public byte[] ReceiveRecord(Stream record)

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)
if (!Enum.IsDefined(typeof(ContentType), (ContentType)contentType))
{
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)
{
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");
@@ -888,96 +812,5 @@ private bool Compare (byte[] array1, byte[] array2)
}

#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
}
}

0 comments on commit 7134b8c

Please sign in to comment.
You can’t perform that action at this time.