// Transport Security Layer (TLS)
// Copyright (c) 2003-2004 Carlos Guzman Alvarez
-
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
#region Fields
+ static ManualResetEvent record_processing = new ManualResetEvent (true);
+
private const int WaitTimeOut = 5 * 60 * 1000;
internal Stream innerStream;
X509CertificateCollection serverRequestedCertificates);
internal abstract bool OnRemoteCertificateValidation(X509Certificate certificate, int[] errors);
+ internal abstract ValidationResult OnRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection);
+ internal abstract bool HaveRemoteValidation2Callback { get; }
internal abstract AsymmetricAlgorithm OnLocalPrivateKeySelection(X509Certificate certificate, string targetHost);
return OnRemoteCertificateValidation(certificate, errors);
}
+ internal ValidationResult RaiseRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+ {
+ return OnRemoteCertificateValidation2 (collection);
+ }
+
internal AsymmetricAlgorithm RaiseLocalPrivateKeySelection(
X509Certificate certificate,
string targetHost)
{
if (this.context.HandshakeState == HandshakeState.Finished)
{
- return this.context.Cipher.CipherAlgorithmType;
+ return this.context.Current.Cipher.CipherAlgorithmType;
}
return CipherAlgorithmType.None;
{
if (this.context.HandshakeState == HandshakeState.Finished)
{
- return this.context.Cipher.EffectiveKeyBits;
+ return this.context.Current.Cipher.EffectiveKeyBits;
}
return 0;
{
if (this.context.HandshakeState == HandshakeState.Finished)
{
- return this.context.Cipher.HashAlgorithmType;
+ return this.context.Current.Cipher.HashAlgorithmType;
}
return HashAlgorithmType.None;
{
if (this.context.HandshakeState == HandshakeState.Finished)
{
- return this.context.Cipher.HashSize * 8;
+ return this.context.Current.Cipher.HashSize * 8;
}
return 0;
{
if (this.context.HandshakeState == HandshakeState.Finished)
{
- return this.context.Cipher.ExchangeAlgorithmType;
+ return this.context.Current.Cipher.ExchangeAlgorithmType;
}
return ExchangeAlgorithmType.None;
return asyncResult;
}
+ // bigger than max record length for SSL/TLS
+ private byte[] recbuf = new byte[16384];
+
private void InternalBeginRead(InternalAsyncResult asyncResult)
{
try
}
else if (!this.context.ConnectionEnd)
{
- // bigger than max record length for SSL/TLS
- byte[] recbuf = new byte[16384];
-
// this will read data from the network until we have (at least) one
// record to send back to the caller
this.innerStream.BeginRead(recbuf, 0, recbuf.Length,
public override void Close()
{
- ((IDisposable)this).Dispose();
+ base.Close ();
}
public override void Flush()
lock (this.read) {
try {
+ record_processing.Reset ();
// do we already have some decrypted data ?
if (this.inputBuffer.Position > 0) {
// or maybe we used all the buffer before ?
this.inputBuffer.SetLength (0);
} else {
int n = this.inputBuffer.Read (buffer, offset, count);
- if (n > 0)
+ if (n > 0) {
+ record_processing.Set ();
return n;
+ }
}
}
needMoreData = false;
// if we loop, then it either means we need more data
byte[] recbuf = new byte[16384];
- int n = innerStream.Read (recbuf, 0, recbuf.Length);
+ int n = 0;
+ if (count == 1) {
+ int value = innerStream.ReadByte ();
+ if (value >= 0) {
+ recbuf[0] = (byte) value;
+ n = 1;
+ }
+ } else {
+ n = innerStream.Read (recbuf, 0, recbuf.Length);
+ }
if (n > 0) {
// Add the new received data to the waiting data
if ((recordStream.Length > 0) && (recordStream.Position != recordStream.Length))
recordStream.Write (recbuf, 0, n);
} else {
// or that the read operation is done (lost connection in the case of a network stream).
+ record_processing.Set ();
return 0;
}
}
bool dataToReturn = false;
- long pos = recordStream.Position;
recordStream.Position = 0;
byte[] record = null;
if (dataToReturn) {
// we have record(s) to return -or- no more available to read from network
// reset position for further reading
- return this.inputBuffer.Read (buffer, offset, count);
+ int i = inputBuffer.Read (buffer, offset, count);
+ record_processing.Set ();
+ return i;
}
}
}
throw new IOException("IO exception during read.", ex);
}
}
- return 0;
}
public override long Seek(long offset, SeekOrigin origin)
this.Dispose(false);
}
- public void Dispose()
- {
- this.Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
+ protected override void Dispose (bool disposing)
{
if (!this.disposed)
{
}
this.disposed = true;
+ base.Dispose (disposing);
}
}