Moved chain building and validation from Mono.Security to System
[mono.git] / mcs / class / Mono.Security / Mono.Security.Protocol.Tls / SslStreamBase.cs
index 0e4802669d5a5e793cf62b7c1f860b91fb65c5a8..f347ccb2bdf72f6e32c170de56b59e468f05f6a5 100644 (file)
@@ -1,6 +1,6 @@
 // Transport Security Layer (TLS)
 // Copyright (c) 2003-2004 Carlos Guzman Alvarez
-// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+// 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
@@ -39,6 +39,8 @@ namespace Mono.Security.Protocol.Tls
                
                #region Fields
 
+               static ManualResetEvent record_processing = new ManualResetEvent (true);
+
                private const int WaitTimeOut = 5 * 60 * 1000;
 
                internal Stream innerStream;
@@ -183,6 +185,8 @@ namespace Mono.Security.Protocol.Tls
                                                                                                                        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);
 
@@ -203,6 +207,11 @@ namespace Mono.Security.Protocol.Tls
                        return OnRemoteCertificateValidation(certificate, errors);
                }
 
+               internal ValidationResult RaiseRemoteCertificateValidation2 (Mono.Security.X509.X509CertificateCollection collection)
+               {
+                       return OnRemoteCertificateValidation2 (collection);
+               }
+
                internal AsymmetricAlgorithm RaiseLocalPrivateKeySelection(
                        X509Certificate certificate,
                        string targetHost)
@@ -899,7 +908,7 @@ namespace Mono.Security.Protocol.Tls
 
                public override void Close()
                {
-                       ((IDisposable)this).Dispose();
+                       base.Close ();
                }
 
                public override void Flush()
@@ -946,6 +955,7 @@ namespace Mono.Security.Protocol.Tls
 
                        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 ?
@@ -953,8 +963,10 @@ namespace Mono.Security.Protocol.Tls
                                                        this.inputBuffer.SetLength (0);
                                                } else {
                                                        int n = this.inputBuffer.Read (buffer, offset, count);
-                                                       if (n > 0)
+                                                       if (n > 0) {
+                                                               record_processing.Set ();
                                                                return n;
+                                                       }
                                                }
                                        }
 
@@ -965,7 +977,16 @@ namespace Mono.Security.Protocol.Tls
                                                        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))
@@ -973,6 +994,7 @@ namespace Mono.Security.Protocol.Tls
                                                                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;
                                                        }
                                                }
@@ -1021,7 +1043,9 @@ namespace Mono.Security.Protocol.Tls
                                                        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;
                                                        }
                                                }
                                        }
@@ -1143,13 +1167,7 @@ namespace Mono.Security.Protocol.Tls
                        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)
                        {
@@ -1175,6 +1193,7 @@ namespace Mono.Security.Protocol.Tls
                                }
 
                                this.disposed = true;
+                               base.Dispose (disposing);
                        }
                }