81fe569645b21d61112e6f6c0b61a188bae7d97a
[mono.git] / mcs / class / System / Mono.Btls / X509ChainImplBtls.cs
1 //
2 // X509ChainImplBtls.cs
3 //
4 // Author:
5 //       Martin Baulig <martin.baulig@xamarin.com>
6 //
7 // Copyright (c) 2016 Xamarin Inc. (http://www.xamarin.com)
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 #if SECURITY_DEP
27 using System;
28 using System.Text;
29 using System.Security;
30 using System.Security.Cryptography;
31 using System.Security.Cryptography.X509Certificates;
32 using MX = Mono.Security.X509;
33
34 namespace Mono.Btls
35 {
36         class X509ChainImplBtls : X509ChainImpl
37         {
38                 MonoBtlsX509StoreCtx storeCtx;
39                 MonoBtlsX509Chain chain;
40                 MonoBtlsX509Chain untrustedChain;
41                 X509ChainElementCollection elements;
42                 X509Certificate2Collection untrusted;
43                 X509Certificate2[] certificates;
44                 X509ChainPolicy policy;
45
46                 internal X509ChainImplBtls (MonoBtlsX509Chain chain)
47                 {
48                         this.chain = chain.Copy ();
49                         policy = new X509ChainPolicy ();
50                 }
51
52                 internal X509ChainImplBtls (MonoBtlsX509StoreCtx storeCtx)
53                 {
54                         this.storeCtx = storeCtx.Copy ();
55                         this.chain = storeCtx.GetChain ();
56
57                         policy = new X509ChainPolicy ();
58                         using (var test = (IDisposable)null) {
59                                 ;
60                         }
61
62                         untrustedChain = storeCtx.GetUntrusted ();
63
64                         if (untrustedChain != null) {
65                                 untrusted = new X509Certificate2Collection ();
66                                 policy.ExtraStore = untrusted;
67                                 for (int i = 0; i < untrustedChain.Count; i++) {
68                                         using (var cert = untrustedChain.GetCertificate (i))
69                                         using (var impl = new X509CertificateImplBtls (cert))
70                                                 untrusted.Add (new X509Certificate2 (impl));
71                                 }
72                         }
73                         storeCtx.Test ();
74                 }
75
76                 internal X509ChainImplBtls ()
77                 {
78                         chain = new MonoBtlsX509Chain ();
79                         elements = new X509ChainElementCollection ();
80                         policy = new X509ChainPolicy ();
81                 }
82
83                 public override bool IsValid {
84                         get { return chain != null && chain.IsValid; }
85                 }
86
87                 public override IntPtr Handle {
88                         get { return chain.Handle.DangerousGetHandle (); }
89                 }
90
91                 internal MonoBtlsX509Chain Chain {
92                         get {
93                                 ThrowIfContextInvalid ();
94                                 return chain;
95                         }
96                 }
97
98                 internal MonoBtlsX509StoreCtx StoreCtx {
99                         get {
100                                 ThrowIfContextInvalid ();
101                                 return storeCtx;
102                         }
103                 }
104
105                 public override X509ChainElementCollection ChainElements {
106                         get {
107                                 ThrowIfContextInvalid ();
108                                 if (elements != null)
109                                         return elements;
110
111                                 elements = new X509ChainElementCollection ();
112                                 certificates = new X509Certificate2 [chain.Count];
113
114                                 for (int i = 0; i < certificates.Length; i++) {
115                                         var cert = chain.GetCertificate (i);
116                                         var impl = new X509CertificateImplBtls (cert);
117                                         certificates [i] = new X509Certificate2 (impl);
118                                         elements.Add (certificates [i]);
119                                 }
120
121                                 return elements;
122                         }
123                 }
124
125                 public override X509ChainPolicy ChainPolicy {
126                         get { return policy; }
127                         set { policy = value; }
128                 }
129
130                 public override X509ChainStatus[] ChainStatus {
131                         get { throw new NotImplementedException (); }
132                 }
133
134                 public override bool Build (X509Certificate2 certificate)
135                 {
136                         return false;
137                 }
138
139                 public override void Reset ()
140                 {
141                         if (certificates != null) {
142                                 foreach (var certificate in certificates)
143                                         certificate.Dispose ();
144                                 certificates = null;
145                         }
146                         if (elements != null) {
147                                 elements.Clear ();
148                                 elements = null;
149                         }
150                 }
151
152                 protected override void Dispose (bool disposing)
153                 {
154                         if (disposing) {
155                                 if (chain != null) {
156                                         chain.Dispose ();
157                                         chain = null;
158                                 }
159                                 if (storeCtx != null) {
160                                         storeCtx.Dispose ();
161                                         storeCtx = null;
162                                 }
163                                 if (untrustedChain != null) {
164                                         untrustedChain.Dispose ();
165                                         untrustedChain = null;
166                                 }
167                                 if (untrusted != null) {
168                                         foreach (var cert in untrusted)
169                                                 cert.Dispose ();
170                                 }
171                         }
172                         base.Dispose (disposing);
173                 }
174         }
175 }
176 #endif