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());
|
||||
|
@ -12,6 +12,7 @@
|
||||
// Copyright 2003 Ximian, Inc. (http://www.ximian.com)
|
||||
// Copyright 2006, 2010 Novell, Inc. (http://www.novell.com)
|
||||
// Copyright 2012 Xamarin Inc. (http://www.xamarin.com)
|
||||
// Copyright 2014 Microsoft Inc
|
||||
//
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining
|
||||
@ -553,6 +554,21 @@ namespace System.Net
|
||||
}
|
||||
}
|
||||
|
||||
// From the Microsoft reference source
|
||||
string MapToDefaultMethod(Uri address) {
|
||||
Uri uri;
|
||||
if (!address.IsAbsoluteUri && baseAddress != null) {
|
||||
uri = new Uri(baseAddress, address);
|
||||
} else {
|
||||
uri = address;
|
||||
}
|
||||
if (uri.Scheme.ToLower(System.Globalization.CultureInfo.InvariantCulture) == "ftp") {
|
||||
return WebRequestMethods.Ftp.UploadFile;
|
||||
} else {
|
||||
return "POST";
|
||||
}
|
||||
}
|
||||
|
||||
byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
|
||||
{
|
||||
string fileCType = Headers ["Content-Type"];
|
||||
@ -565,7 +581,10 @@ namespace System.Net
|
||||
fileCType = "application/octet-stream";
|
||||
}
|
||||
|
||||
bool needs_boundary = (method != "PUT"); // only verified case so far
|
||||
if (method == null)
|
||||
method = MapToDefaultMethod (address);
|
||||
|
||||
bool needs_boundary = (method != "PUT" && method != WebRequestMethods.Ftp.UploadFile); // only verified case so far
|
||||
string boundary = null;
|
||||
if (needs_boundary) {
|
||||
boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
|
||||
|
@ -10,6 +10,7 @@
|
||||
#if NET_2_0
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
@ -23,6 +24,31 @@ namespace MonoTests.System.Net
|
||||
{
|
||||
FtpWebRequest defaultRequest;
|
||||
|
||||
private string _tempDirectory;
|
||||
private string _tempFile;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp ()
|
||||
{
|
||||
_tempDirectory = Path.Combine (Path.GetTempPath (), "MonoTests.System.Net.FileWebRequestTest");
|
||||
_tempFile = Path.Combine (_tempDirectory, "FtpWebRequestTest.tmp");
|
||||
if (!Directory.Exists (_tempDirectory)) {
|
||||
Directory.CreateDirectory (_tempDirectory);
|
||||
} else {
|
||||
// ensure no files are left over from previous runs
|
||||
string [] files = Directory.GetFiles (_tempDirectory, "*");
|
||||
foreach (string file in files)
|
||||
File.Delete (file);
|
||||
}
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown ()
|
||||
{
|
||||
if (Directory.Exists (_tempDirectory))
|
||||
Directory.Delete (_tempDirectory, true);
|
||||
}
|
||||
|
||||
[TestFixtureSetUp]
|
||||
public void Init ()
|
||||
{
|
||||
@ -183,13 +209,15 @@ namespace MonoTests.System.Net
|
||||
ftp.KeepAlive = false;
|
||||
ftp.Timeout = 5000;
|
||||
ftp.Method = WebRequestMethods.Ftp.UploadFile;
|
||||
ftp.ContentLength = 1;
|
||||
ftp.ContentLength = 10;
|
||||
ftp.UseBinary = true;
|
||||
Stream stream = ftp.GetRequestStream ();
|
||||
stream.WriteByte (0);
|
||||
for (int i = 0; i < 10; i++)
|
||||
stream.WriteByte ((byte)i);
|
||||
stream.Close ();
|
||||
FtpWebResponse response = (FtpWebResponse) ftp.GetResponse ();
|
||||
Assert.IsTrue ((int) response.StatusCode >= 200 && (int) response.StatusCode < 300, "UP#01");
|
||||
Assert.AreEqual (10, sp.result.Count, "UP#02");
|
||||
response.Close ();
|
||||
} catch (Exception) {
|
||||
if (!String.IsNullOrEmpty (sp.Where))
|
||||
@ -200,6 +228,24 @@ namespace MonoTests.System.Net
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UploadFile_WebClient ()
|
||||
{
|
||||
ServerPut sp = new ServerPut ();
|
||||
File.WriteAllText (_tempFile, "0123456789");
|
||||
sp.Start ();
|
||||
|
||||
using (WebClient m_WebClient = new WebClient())
|
||||
{
|
||||
string uri = String.Format ("ftp://{0}:{1}/uploads/file.txt", sp.IPAddress, sp.Port);
|
||||
|
||||
m_WebClient.UploadFile(uri, _tempFile);
|
||||
}
|
||||
Assert.AreEqual (10, sp.result.Count, "WebClient/Ftp#01");
|
||||
|
||||
sp.Stop ();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DownloadFile1 ()
|
||||
{
|
||||
@ -464,6 +510,8 @@ namespace MonoTests.System.Net
|
||||
}
|
||||
|
||||
class ServerPut : FtpServer {
|
||||
public List<byte> result = new List<byte> ();
|
||||
|
||||
protected override void Run ()
|
||||
{
|
||||
Socket client = control.Accept ();
|
||||
@ -511,8 +559,12 @@ namespace MonoTests.System.Net
|
||||
writer.Flush ();
|
||||
|
||||
Socket data_cnc = data.Accept ();
|
||||
byte [] dontcare = new byte [1];
|
||||
data_cnc.Receive (dontcare, 1, SocketFlags.None);
|
||||
var datastr = new NetworkStream (data_cnc, false);
|
||||
int ch;
|
||||
while ((ch = datastr.ReadByte ()) != -1){
|
||||
result.Add ((byte)ch);
|
||||
|
||||
}
|
||||
data_cnc.Close ();
|
||||
writer.WriteLine ("226 File received Ok");
|
||||
writer.Flush ();
|
||||
|
@ -1 +1 @@
|
||||
9ba190dcc3688e2a5c13d7497222758bd633e940
|
||||
bb677a1b285adc8f63d91bb2490e7a11bd6d78ec
|
@ -1 +1 @@
|
||||
e4a2800a0dcd404b2c1b5b83674c10e1fbbfc422
|
||||
46fe7a67471e0c277afe9e9843b2cd6fa7223d9e
|
@ -1 +1 @@
|
||||
8d3febc3bcc1a68179e2254527f999c81709567e
|
||||
aab470c977a75d50f8af904c5b6301c59dcaa9d9
|
@ -1 +1 @@
|
||||
de746eb848148a6d8d547c4fe4957549830f4100
|
||||
f80a3e921d07f9ca6ddfd6a6c76778b94052f139
|
@ -1 +1 @@
|
||||
388c79223d2c9dfd31370959baa8e0732bf2c782
|
||||
02cad6d9661f4105e52673659d24ddc3bf57c868
|
@ -1 +1 @@
|
||||
954b224e92c0ca40db3ed841324c99ac14419a15
|
||||
6859fa37972a78123015546fb7abd102201ab436
|
@ -1 +1 @@
|
||||
7eb420e04eb9641a8be30dbe4ad33d7591466e00
|
||||
d32723643e0a5a8ae25fa35ac6c829036082b6be
|
@ -1 +1 @@
|
||||
289dd62af9a9073a05a3d659b08b4bdb0fe1db4a
|
||||
f51ac490d60278d0e9f1a5258727bfd7492007ec
|
Reference in New Issue
Block a user