[Mono.Security]: Add 'MonoTlsProvider.SupportsCleanShutdown' and 'MonoTlsSettings...
[mono.git] / mcs / class / System / Mono.Btls / MonoBtlsContext.cs
index 343ecc47e45759d2347c4e8d98b6e019eb3e8a6e..559db4aca5d4f8288686b51369d6324a1114f5fd 100644 (file)
@@ -156,9 +156,20 @@ namespace Mono.Btls
 
                static Exception GetException (MonoBtlsSslError status)
                {
-                       var error = MonoBtlsError.GetError ();
+                       string file;
+                       int line;
+                       var error = MonoBtlsError.GetError (out file, out line);
+                       if (error == 0)
+                               return new MonoBtlsException (status);
+
                        var text = MonoBtlsError.GetErrorString (error);
-                       return new MonoBtlsException ("{0} {1}", status, text);
+
+                       string message;
+                       if (file != null)
+                               message = string.Format ("{0} {1}\n  at {2}:{3}", status, text, file, line);
+                       else
+                               message = string.Format ("{0} {1}", status, text);
+                       return new MonoBtlsException (message);
                }
 
                public override bool ProcessHandshake ()
@@ -207,16 +218,6 @@ namespace Mono.Btls
                        isAuthenticated = true;
                }
 
-               void SetupCertificateStore ()
-               {
-                       MonoBtlsProvider.SetupCertificateStore (ctx.CertificateStore);
-
-                       if (Settings != null && Settings.TrustAnchors != null) {
-                               var trust = IsServer ? MonoBtlsX509TrustKind.TRUST_CLIENT : MonoBtlsX509TrustKind.TRUST_SERVER;
-                               ctx.CertificateStore.AddCollection (Settings.TrustAnchors, trust);
-                       }
-               }
-
                void InitializeConnection ()
                {
                        ctx = new MonoBtlsSslCtx ();
@@ -226,14 +227,14 @@ namespace Mono.Btls
                        ctx.SetDebugBio (errbio);
 #endif
 
-                       SetupCertificateStore ();
+                       MonoBtlsProvider.SetupCertificateStore (ctx.CertificateStore, Settings, IsServer);
 
                        if (!IsServer || AskForClientCertificate)
                                ctx.SetVerifyCallback (VerifyCallback, false);
                        if (!IsServer)
                                ctx.SetSelectCallback (SelectCallback);
 
-                       ctx.SetVerifyParam (MonoBtlsProvider.GetVerifyParam (ServerName, IsServer));
+                       ctx.SetVerifyParam (MonoBtlsProvider.GetVerifyParam (Settings, ServerName, IsServer));
 
                        TlsProtocolCode minProtocol, maxProtocol;
                        GetProtocolVersions (out minProtocol, out maxProtocol);
@@ -299,7 +300,7 @@ namespace Mono.Btls
                        throw new NotImplementedException ();
                }
 
-               public override int Read (byte[] buffer, int offset, int size, out bool wantMore)
+               public override (int ret, bool wantMore) Read (byte[] buffer, int offset, int size)
                {
                        Debug ("Read: {0} {1} {2}", buffer.Length, offset, size);
 
@@ -312,24 +313,23 @@ namespace Mono.Btls
                                var status = ssl.Read (data, ref size);
                                Debug ("Read done: {0} {1}", status, size);
 
-                               if (status == MonoBtlsSslError.WantRead) {
-                                       wantMore = true;
-                                       return 0;
-                               } else if (status != MonoBtlsSslError.None) {
+                               if (status == MonoBtlsSslError.WantRead)
+                                       return (0, true);
+                               if (status == MonoBtlsSslError.ZeroReturn)
+                                       return (size, false);
+                               if (status != MonoBtlsSslError.None)
                                        throw GetException (status);
-                               }
 
                                if (size > 0)
                                        Marshal.Copy (data, buffer, offset, size);
 
-                               wantMore = false;
-                               return size;
+                               return (size, false);
                        } finally {
                                Marshal.FreeHGlobal (data);
                        }
                }
 
-               public override int Write (byte[] buffer, int offset, int size, out bool wantMore)
+               public override (int ret, bool wantMore) Write (byte[] buffer, int offset, int size)
                {
                        Debug ("Write: {0} {1} {2}", buffer.Length, offset, size);
 
@@ -343,24 +343,23 @@ namespace Mono.Btls
                                var status = ssl.Write (data, ref size);
                                Debug ("Write done: {0} {1}", status, size);
 
-                               if (status == MonoBtlsSslError.WantWrite) {
-                                       wantMore = true;
-                                       return 0;
-                               } else if (status != MonoBtlsSslError.None) {
+                               if (status == MonoBtlsSslError.WantWrite)
+                                       return (0, true);
+                               if (status != MonoBtlsSslError.None)
                                        throw GetException (status);
-                               }
 
-                               wantMore = false;
-                               return size;
+                               return (size, false);
                        } finally {
                                Marshal.FreeHGlobal (data);
                        }
                }
 
-               public override void Close ()
+               public override void Shutdown ()
                {
-                       Debug ("Close!");
-                       ssl.Dispose ();
+                       Debug ("Shutdown!");
+                       if (Settings == null || !Settings.SendCloseNotify)
+                               ssl.SetQuietShutdown ();
+                       ssl.Shutdown ();
                }
 
                void Dispose<T> (ref T disposable)
@@ -380,12 +379,12 @@ namespace Mono.Btls
                {
                        try {
                                if (disposing) {
+                                       Dispose (ref ssl);
+                                       Dispose (ref ctx);
                                        Dispose (ref remoteCertificate);
                                        Dispose (ref nativeServerCertificate);
                                        Dispose (ref nativeClientCertificate);
                                        Dispose (ref clientCertificate);
-                                       Dispose (ref ctx);
-                                       Dispose (ref ssl);
                                        Dispose (ref bio);
                                        Dispose (ref errbio);
                                }