You've already forked linux-packaging-mono
Imported Upstream version 3.12.1
Former-commit-id: ce565ca85f5d5abe367a12026a5712944dbf6319
This commit is contained in:
@ -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);
|
||||
|
@ -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,37 @@ 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);
|
||||
|
||||
case HandshakeType.ServerKeyExchange:
|
||||
return new TlsServerKeyExchange(this.context, buffer);
|
||||
|
||||
// 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 +187,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
|
||||
|
@ -122,6 +122,8 @@ namespace Mono.Security.Protocol.Tls
|
||||
set { this.protocolNegotiated = value; }
|
||||
}
|
||||
|
||||
public bool ChangeCipherSpecDone { get; set; }
|
||||
|
||||
public SecurityProtocolType SecurityProtocol
|
||||
{
|
||||
get
|
||||
|
@ -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)
|
||||
@ -523,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");
|
||||
@ -1031,96 +951,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
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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());
|
||||
|
@ -588,14 +588,20 @@ namespace Mono.Security.Protocol.Tls
|
||||
}
|
||||
catch (TlsException ex)
|
||||
{
|
||||
// FIXME: should the send alert also be done asynchronously here and below?
|
||||
this.protocol.SendAlert(ex.Alert);
|
||||
negotiate.SetComplete (new IOException("The authentication or decryption has failed.", ex));
|
||||
try {
|
||||
Exception e = ex;
|
||||
this.protocol.SendAlert(ex.Alert != null ? ex.Alert : new Alert (AlertDescription.InternalError));
|
||||
} catch {
|
||||
}
|
||||
negotiate.SetComplete(new IOException("The authentication or decryption has failed.", ex));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.protocol.SendAlert(AlertDescription.InternalError);
|
||||
negotiate.SetComplete (new IOException("The authentication or decryption has failed.", ex));
|
||||
try {
|
||||
this.protocol.SendAlert(AlertDescription.InternalError);
|
||||
} catch {
|
||||
}
|
||||
negotiate.SetComplete(new IOException("The authentication or decryption has failed.", ex));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
Reference in New Issue
Block a user