Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs
diff options
context:
space:
mode:
authorSebastien Pouliot <sebastien@ximian.com>2005-02-02 21:25:16 +0300
committerSebastien Pouliot <sebastien@ximian.com>2005-02-02 21:25:16 +0300
commit3d9acd1dd40910d19e8d3f7e69196579a80709a8 (patch)
tree2091e771e6335024d7bd4b08af4e1b4f15f2166c /mcs
parent8b9597e2dcb8aba0ff41517f54a9a2719b241bc1 (diff)
2005-02-02 Sebastien Pouliot <sebastien@ximian.com>
* SslClientStream.cs: Throw exception when we receive a null record. * RecordProtocol.cs: Added code to avoid blocking and endless loops if the data is incomplete or missing - even in the case the server side doesn't close the connection (see new cutcli tool). svn path=/trunk/mcs/; revision=39997
Diffstat (limited to 'mcs')
-rw-r--r--mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog7
-rw-r--r--mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs107
-rw-r--r--mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs17
3 files changed, 105 insertions, 26 deletions
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
index bc8ffe4dbce..2a41f6d0937 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/ChangeLog
@@ -1,3 +1,10 @@
+2005-02-02 Sebastien Pouliot <sebastien@ximian.com>
+
+ * SslClientStream.cs: Throw exception when we receive a null record.
+ * RecordProtocol.cs: Added code to avoid blocking and endless loops
+ if the data is incomplete or missing - even in the case the server
+ side doesn't close the connection (see new cutcli tool).
+
2004-12-15 Sebastien Pouliot <sebastien@ximian.com>
* CipherSuite.cs: Removed unused MD5 and SHA1 instances created in
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 155e02be93f..412ca23a60e 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/RecordProtocol.cs
@@ -24,9 +24,11 @@
using System;
using System.Collections;
-using System.IO;
+using System.IO;
+using System.Net.Sockets;
using System.Security.Cryptography;
-using System.Security.Cryptography.X509Certificates;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
using Mono.Security.Protocol.Tls.Handshake;
@@ -70,7 +72,31 @@ namespace Mono.Security.Protocol.Tls
#endregion
- #region Reveive Record Methods
+ #region Reveive Record Methods
+
+ internal const int Timeout = 1000;
+
+ internal bool WaitForData ()
+ {
+ // problem: NetworkStream.ReadByte blocks until a byte is received
+ // and (maybe) no byte will ever be received
+ if (this.innerStream is NetworkStream)
+ {
+ NetworkStream ns = (this.innerStream as NetworkStream);
+ int delay = 10;
+ while (delay < Timeout)
+ {
+ if (ns.DataAvailable)
+ return true;
+ Thread.Sleep (delay);
+ delay *= 2;
+ }
+ // nothing to see, move along
+ return false;
+ }
+ // we assume other type of stream have their own timeout capabilities
+ return true;
+ }
public byte[] ReceiveRecord()
{
@@ -79,20 +105,25 @@ namespace Mono.Security.Protocol.Tls
throw new TlsException(
AlertDescription.InternalError,
"The session is finished and it's no longer valid.");
- }
-
- // Try to read the Record Content Type
- int type = this.innerStream.ReadByte();
+ }
+
+ if (!WaitForData ())
+ {
+ return null;
+ }
+
+ // Try to read the Record Content Type
+ int type = this.innerStream.ReadByte ();
if (type == -1)
- {
+ {
return null;
- }
+ }
// Set last handshake message received to None
this.context.LastHandshakeMsg = HandshakeType.ClientHello;
- ContentType contentType = (ContentType)type;
- byte[] buffer = this.ReadRecordBuffer(type);
+ ContentType contentType = (ContentType)type;
+ byte[] buffer = this.ReadRecordBuffer (type);
TlsStream message = new TlsStream(buffer);
@@ -173,13 +204,19 @@ namespace Mono.Security.Protocol.Tls
}
private byte[] ReadClientHelloV2()
- {
- int msgLength = this.innerStream.ReadByte();
- byte[] message = new byte [msgLength];
- this.innerStream.Read (message, 0, msgLength);
-
- int msgType = message [0];
- if (msgType != 1)
+ {
+ int msgType = -1;
+ byte[] message = null;
+
+ int msgLength = this.innerStream.ReadByte();
+ if (msgLength > 0)
+ {
+ message = new byte [msgLength];
+ if (this.innerStream.Read (message, 0, msgLength) == msgLength)
+ msgType = message [0];
+ }
+
+ if ((msgType != 1) || (message.Length < 9))
{
throw new TlsException(AlertDescription.DecodeError);
}
@@ -229,6 +266,19 @@ namespace Mono.Security.Protocol.Tls
this.context.ProtocolNegotiated = true;
return message;
+ }
+
+ private bool Wait (ref int delay)
+ {
+ if (delay < 10)
+ delay = 10;
+
+ if (delay >= Timeout)
+ return false;
+
+ Thread.Sleep (delay);
+ delay *= 2;
+ return true;
}
private byte[] ReadStandardRecordBuffer()
@@ -239,9 +289,21 @@ namespace Mono.Security.Protocol.Tls
// Read Record data
int received = 0;
byte[] buffer = new byte[length];
+ int n = 0;
while (received != length)
{
- received += this.innerStream.Read(buffer, received, buffer.Length - received);
+ int incoming = this.innerStream.Read(buffer, received, buffer.Length - received);
+ // we risk an infinite loop is data isn't available
+ if (incoming == 0)
+ {
+ if (!Wait (ref n))
+ throw new TlsException (AlertLevel.Fatal, AlertDescription.CloseNotify);
+ }
+ else
+ {
+ n = 0; // reset
+ }
+ received += incoming;
}
// Check that the message has a valid protocol version
@@ -258,8 +320,11 @@ namespace Mono.Security.Protocol.Tls
private short ReadShort()
{
- byte[] b = new byte[2];
- this.innerStream.Read(b, 0, b.Length);
+ byte[] b = new byte[2];
+ if (this.innerStream.Read (b, 0, b.Length) != 2)
+ {
+ throw new TlsException (AlertLevel.Fatal, AlertDescription.DecodeError);
+ }
short val = BitConverter.ToInt16(b, 0);
diff --git a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
index ed99efe0257..926fb7af5b1 100644
--- a/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
+++ b/mcs/class/Mono.Security/Mono.Security.Protocol.Tls/SslClientStream.cs
@@ -688,7 +688,7 @@ namespace Mono.Security.Protocol.Tls
*/
internal void NegotiateHandshake()
- {
+ {
lock (this)
{
try
@@ -707,8 +707,11 @@ namespace Mono.Security.Protocol.Tls
// Read server response
while (this.context.LastHandshakeMsg != HandshakeType.ServerHelloDone)
{
- // Read next record
- this.protocol.ReceiveRecord();
+ // Read next record
+ if (this.protocol.ReceiveRecord () == null)
+ {
+ throw new TlsException (AlertLevel.Fatal, AlertDescription.CloseNotify);
+ }
}
// Send client certificate if requested
@@ -737,8 +740,12 @@ namespace Mono.Security.Protocol.Tls
{
// If all goes well this will process messages:
// Change Cipher Spec
- // Server finished
- this.protocol.ReceiveRecord();
+ // Server finished
+ // Read next record
+ if (this.protocol.ReceiveRecord () == null)
+ {
+ throw new TlsException (AlertLevel.Fatal, AlertDescription.CloseNotify);
+ }
}
// Clear Key Info