New run-jenkins tags to allow a checked build job and fix partial checked build suppo...
[mono.git] / mcs / class / Mono.Security.Providers.NewTls / Mono.Security.Providers.NewTls / TlsContextWrapper.cs
1 //
2 // TlsContextWrapper.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2015 Xamarin, Inc.
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining a copy
10 // of this software and associated documentation files (the "Software"), to deal
11 // in the Software without restriction, including without limitation the rights
12 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 // copies of the Software, and to permit persons to whom the Software is
14 // furnished to do so, subject to the following conditions:
15 //
16 // The above copyright notice and this permission notice shall be included in
17 // all copies or substantial portions of the Software.
18 //
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 // THE SOFTWARE.
26
27 extern alias NewSystemSource;
28
29 using System;
30 using System.Security.Cryptography;
31
32 using SSCX = System.Security.Cryptography.X509Certificates;
33 using PSSCX = System.Security.Cryptography.X509Certificates;
34
35 using MSI = Mono.Security.Interface;
36 using MX = Mono.Security.X509;
37
38 namespace Mono.Security.Providers.NewTls
39 {
40         class TlsContextWrapper : IDisposable, MSI.IMonoTlsContext
41         {
42                 ITlsConfiguration config;
43                 ITlsContext context;
44                 bool serverMode;
45
46                 public TlsContextWrapper (ITlsConfiguration config, bool serverMode)
47                 {
48                         this.config = config;
49                         this.serverMode = serverMode;
50                 }
51
52                 public bool IsServer {
53                         get { return serverMode; }
54                 }
55
56                 public bool IsValid {
57                         get { return context != null && context.IsValid; }
58                 }
59
60                 public void Initialize (MSI.IMonoTlsEventSink eventSink)
61                 {
62                         if (context != null)
63                                 throw new InvalidOperationException ();
64                         context = TlsProviderFactory.CreateTlsContext (config, serverMode, eventSink);
65                 }
66
67                 void Clear ()
68                 {
69                         if (context != null) {
70                                 context.Dispose ();
71                                 context = null;
72                         }
73                 }
74
75                 public ITlsConfiguration Configuration {
76                         get {
77                                 if (config == null)
78                                         throw new ObjectDisposedException ("TlsConfiguration");
79                                 return config;
80                         }
81                 }
82
83                 public ITlsContext Context {
84                         get {
85                                 if (!IsValid)
86                                         throw new ObjectDisposedException ("TlsContext");
87                                 return context;
88                         }
89                 }
90
91                 public bool HasCredentials {
92                         get { return Configuration.HasCredentials; }
93                 }
94
95                 public void SetCertificate (SSCX.X509Certificate certificate, AsymmetricAlgorithm privateKey)
96                 {
97                         var monoCert = new MX.X509Certificate (certificate.GetRawCertData ());
98                         Configuration.SetCertificate (monoCert, privateKey);
99                 }
100
101                 public int GenerateNextToken (MSI.IBufferOffsetSize incoming, out MSI.IBufferOffsetSize outgoing)
102                 {
103                         var input = incoming != null ? new MSI.TlsBuffer (BOSWrapper.Wrap (incoming)) : null;
104                         var output = new MSI.TlsMultiBuffer ();
105                         var retval = Context.GenerateNextToken (input, output);
106                         if (output.IsEmpty)
107                                 outgoing = null;
108                         outgoing = BOSWrapper.Wrap (output.StealBuffer ());
109                         return (int)retval;
110                 }
111
112                 public int EncryptMessage (ref MSI.IBufferOffsetSize incoming)
113                 {
114                         var buffer = new MSI.TlsBuffer (BOSWrapper.Wrap (incoming));
115                         var retval = Context.EncryptMessage (ref buffer);
116                         incoming = BOSWrapper.Wrap (buffer.GetRemaining ());
117                         return (int)retval;
118                 }
119
120                 public int DecryptMessage (ref MSI.IBufferOffsetSize incoming)
121                 {
122                         var buffer = new MSI.TlsBuffer (BOSWrapper.Wrap (incoming));
123                         var retval = Context.DecryptMessage (ref buffer);
124                         incoming = buffer != null ? BOSWrapper.Wrap (buffer.GetRemaining ()) : null;
125                         return (int)retval;
126                 }
127
128                 class BOSWrapper : MSI.IBufferOffsetSize
129                 {
130                         public byte[] Buffer {
131                                 get;
132                                 private set;
133                         }
134
135                         public int Offset {
136                                 get;
137                                 private set;
138                         }
139
140                         public int Size {
141                                 get;
142                                 private set;
143                         }
144
145                         BOSWrapper (byte[] buffer, int offset, int size)
146                         {
147                                 Buffer = buffer;
148                                 Offset = offset;
149                                 Size = size;
150                         }
151
152                         public static BOSWrapper Wrap (MSI.IBufferOffsetSize bos)
153                         {
154                                 return bos != null ? new BOSWrapper (bos.Buffer, bos.Offset, bos.Size) : null;
155                         }
156                 }
157
158                 public byte[] CreateCloseNotify ()
159                 {
160                         return Context.CreateAlert (new MSI.Alert (MSI.AlertLevel.Warning, MSI.AlertDescription.CloseNotify));
161                 }
162
163                 public byte[] CreateHelloRequest ()
164                 {
165                         return Context.CreateHelloRequest ();
166                 }
167
168                 public SSCX.X509Certificate GetRemoteCertificate (out PSSCX.X509CertificateCollection remoteCertificateStore)
169                 {
170                         MX.X509CertificateCollection monoCollection;
171                         var remoteCert = Context.GetRemoteCertificate (out monoCollection);
172                         if (remoteCert == null) {
173                                 remoteCertificateStore = null;
174                                 return null;
175                         }
176
177                         remoteCertificateStore = new PSSCX.X509CertificateCollection ();
178                         foreach (var cert in monoCollection) {
179                                 remoteCertificateStore.Add (new PSSCX.X509Certificate2 (cert.RawData));
180                         }
181                         return new PSSCX.X509Certificate2 (remoteCert.RawData);
182
183                 }
184
185                 public bool VerifyRemoteCertificate ()
186                 {
187                         return Context.VerifyRemoteCertificate ();
188                 }
189
190                 public Exception LastError {
191                         get {
192                                 if (context != null)
193                                         return context.LastError;
194                                 return null;
195                         }
196                 }
197
198                 public bool ReceivedCloseNotify {
199                         get {
200                                 return Context.ReceivedCloseNotify;
201                         }
202                 }
203
204                 public MSI.MonoTlsConnectionInfo GetConnectionInfo ()
205                 {
206                         return Context.ConnectionInfo;
207                 }
208
209                 public void Dispose ()
210                 {
211                         Dispose (true);
212                         GC.SuppressFinalize (this);
213                 }
214
215                 void Dispose (bool disposing)
216                 {
217                         Clear ();
218                 }
219         }
220 }
221