[runtime] Fix monitor exception throwing
[mono.git] / mcs / class / System / Mono.Net.Security / MobileTlsContext.cs
1 //
2 // MobileTlsContext.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2015 Xamarin, Inc.
8 //
9
10 #if SECURITY_DEP
11 #if MONO_SECURITY_ALIAS
12 extern alias MonoSecurity;
13 #endif
14
15 #if MONO_SECURITY_ALIAS
16 using MonoSecurity::Mono.Security.Interface;
17 #else
18 using Mono.Security.Interface;
19 #endif
20
21 using System;
22 using System.IO;
23 using SD = System.Diagnostics;
24 using System.Collections;
25 using System.Collections.Generic;
26 using System.Threading;
27 using System.Threading.Tasks;
28 using System.Security.Authentication;
29 using System.Security.Cryptography.X509Certificates;
30
31 namespace Mono.Net.Security
32 {
33         abstract class MobileTlsContext : IDisposable
34         {
35                 MobileAuthenticatedStream parent;
36                 bool serverMode;
37                 string targetHost;
38                 SslProtocols enabledProtocols;
39                 X509Certificate serverCertificate;
40                 X509CertificateCollection clientCertificates;
41                 bool askForClientCert;
42                 ICertificateValidator2 certificateValidator;
43
44                 public MobileTlsContext (
45                         MobileAuthenticatedStream parent, bool serverMode, string targetHost,
46                         SslProtocols enabledProtocols, X509Certificate serverCertificate,
47                         X509CertificateCollection clientCertificates, bool askForClientCert)
48                 {
49                         this.parent = parent;
50                         this.serverMode = serverMode;
51                         this.targetHost = targetHost;
52                         this.enabledProtocols = enabledProtocols;
53                         this.serverCertificate = serverCertificate;
54                         this.clientCertificates = clientCertificates;
55                         this.askForClientCert = askForClientCert;
56
57                         certificateValidator = CertificateValidationHelper.GetInternalValidator (
58                                 parent.Settings, parent.Provider);
59                 }
60
61                 internal MobileAuthenticatedStream Parent {
62                         get { return parent; }
63                 }
64
65                 public MonoTlsSettings Settings {
66                         get { return parent.Settings; }
67                 }
68
69                 public MonoTlsProvider Provider {
70                         get { return parent.Provider; }
71                 }
72
73                 [SD.Conditional ("MARTIN_DEBUG")]
74                 protected void Debug (string message, params object[] args)
75                 {
76                         Console.Error.WriteLine ("{0}: {1}", GetType ().Name, string.Format (message, args));
77                 }
78
79                 public abstract bool HasContext {
80                         get;
81                 }
82
83                 public abstract bool IsAuthenticated {
84                         get;
85                 }
86
87                 public bool IsServer {
88                         get { return serverMode; }
89                 }
90
91                 protected string TargetHost {
92                         get { return targetHost; }
93                 }
94
95                 protected bool AskForClientCertificate {
96                         get { return askForClientCert; }
97                 }
98
99                 protected SslProtocols EnabledProtocols {
100                         get { return enabledProtocols; }
101                 }
102
103                 protected X509CertificateCollection ClientCertificates {
104                         get { return clientCertificates; }
105                 }
106
107                 protected void GetProtocolVersions (out TlsProtocolCode min, out TlsProtocolCode max)
108                 {
109                         if ((enabledProtocols & SslProtocols.Tls) != 0)
110                                 min = TlsProtocolCode.Tls10;
111                         else if ((enabledProtocols & SslProtocols.Tls11) != 0)
112                                 min = TlsProtocolCode.Tls11;
113                         else
114                                 min = TlsProtocolCode.Tls12;
115
116                         if ((enabledProtocols & SslProtocols.Tls12) != 0)
117                                 max = TlsProtocolCode.Tls12;
118                         else if ((enabledProtocols & SslProtocols.Tls11) != 0)
119                                 max = TlsProtocolCode.Tls11;
120                         else
121                                 max = TlsProtocolCode.Tls10;
122                 }
123
124                 public abstract void StartHandshake ();
125
126                 public abstract bool ProcessHandshake ();
127
128                 public abstract void FinishHandshake ();
129
130                 public abstract MonoTlsConnectionInfo ConnectionInfo {
131                         get;
132                 }
133
134                 internal X509Certificate LocalServerCertificate {
135                         get { return serverCertificate; }
136                 }
137
138                 internal abstract bool IsRemoteCertificateAvailable {
139                         get;
140                 }
141
142                 internal abstract X509Certificate LocalClientCertificate {
143                         get;
144                 }
145
146                 public abstract X509Certificate RemoteCertificate {
147                         get;
148                 }
149
150                 public abstract TlsProtocols NegotiatedProtocol {
151                         get;
152                 }
153
154                 public abstract void Flush ();
155
156                 public abstract int Read (byte[] buffer, int offset, int count, out bool wantMore);
157
158                 public abstract int Write (byte[] buffer, int offset, int count, out bool wantMore);
159
160                 public abstract void Close ();
161
162                 protected bool ValidateCertificate (X509Certificate leaf, X509Chain chain)
163                 {
164                         var result = certificateValidator.ValidateCertificate (TargetHost, IsServer, leaf, chain);
165                         return result != null && result.Trusted && !result.UserDenied;
166                 }
167
168                 protected bool ValidateCertificate (X509CertificateCollection certificates)
169                 {
170                         var result = certificateValidator.ValidateCertificate (TargetHost, IsServer, certificates);
171                         return result != null && result.Trusted && !result.UserDenied;
172                 }
173
174                 protected X509Certificate SelectClientCertificate (X509Certificate serverCertificate, string[] acceptableIssuers)
175                 {
176                         X509Certificate certificate;
177                         var selected = certificateValidator.SelectClientCertificate (
178                                 TargetHost, ClientCertificates, serverCertificate, acceptableIssuers, out certificate);
179                         if (selected)
180                                 return certificate;
181
182                         if (clientCertificates == null || clientCertificates.Count == 0)
183                                 return null;
184
185                         if (clientCertificates.Count == 1)
186                                 return clientCertificates [0];
187
188                         // FIXME: select onne.
189                         throw new NotImplementedException ();
190                 }
191
192                 public void Dispose ()
193                 {
194                         Dispose (true);
195                         GC.SuppressFinalize (this);
196                 }
197
198                 protected virtual void Dispose (bool disposing)
199                 {
200                 }
201
202                 ~MobileTlsContext ()
203                 {
204                         Dispose (false);
205                 }
206         }
207 }
208
209 #endif