1 //
2 // MonoTlsSettings.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 using System;
27 using System.Threading;
28 using System.Security.Cryptography.X509Certificates;
29 
30 namespace Mono.Security.Interface
31 {
32 	public sealed class MonoTlsSettings
33 	{
34 		public MonoRemoteCertificateValidationCallback RemoteCertificateValidationCallback {
35 			get; set;
36 		}
37 
38 		public MonoLocalCertificateSelectionCallback ClientCertificateSelectionCallback {
39 			get; set;
40 		}
41 
42 		public bool CheckCertificateName {
43 			get { return checkCertName; }
44 			set { checkCertName = value; }
45 		}
46 
47 		public bool CheckCertificateRevocationStatus {
48 			get { return checkCertRevocationStatus; }
49 			set { checkCertRevocationStatus = value; }
50 		}
51 
52 		public bool? UseServicePointManagerCallback {
53 			get { return useServicePointManagerCallback; }
54 			set { useServicePointManagerCallback = value; }
55 		}
56 
57 		public bool SkipSystemValidators {
58 			get { return skipSystemValidators; }
59 			set { skipSystemValidators = value; }
60 		}
61 
62 		public bool CallbackNeedsCertificateChain {
63 			get { return callbackNeedsChain; }
64 			set { callbackNeedsChain = value; }
65 		}
66 
67 		/*
68 		 * Use custom time for certificate expiration checks
69 		 */
70 		public DateTime? CertificateValidationTime {
71 			get; set;
72 		}
73 
74 		/*
75 		 * This is only supported if CertificateValidationHelper.SupportsTrustAnchors is true.
76 		 */
77 		public X509CertificateCollection TrustAnchors {
78 			get; set;
79 		}
80 
81 		public object UserSettings {
82 			get; set;
83 		}
84 
85 		internal string[] CertificateSearchPaths {
86 			get; set;
87 		}
88 
89 		/*
90 		 * This is only supported if MonoTlsProvider.SupportsCleanShutdown is true.
91 		 */
92 		internal bool SendCloseNotify {
93 			get; set;
94 		}
95 
96 		/*
97 		 * If you set this here, then it will override 'ServicePointManager.SecurityProtocol'.
98 		 */
99 		public TlsProtocols? EnabledProtocols {
100 			get; set;
101 		}
102 
103 		[CLSCompliant (false)]
104 		public CipherSuiteCode[] EnabledCiphers {
105 			get; set;
106 		}
107 
108 		bool cloned = false;
109 		bool checkCertName = true;
110 		bool checkCertRevocationStatus = false;
111 		bool? useServicePointManagerCallback = null;
112 		bool skipSystemValidators = false;
113 		bool callbackNeedsChain = true;
114 		ICertificateValidator certificateValidator;
115 
MonoTlsSettings()116 		public MonoTlsSettings ()
117 		{
118 		}
119 
120 		static MonoTlsSettings defaultSettings;
121 
122 		public static MonoTlsSettings DefaultSettings {
123 			get {
124 				if (defaultSettings == null)
125 					Interlocked.CompareExchange (ref defaultSettings, new MonoTlsSettings (), null);
126 				return defaultSettings;
127 			}
128 			set {
129 				defaultSettings = value ?? new MonoTlsSettings ();
130 			}
131 		}
132 
CopyDefaultSettings()133 		public static MonoTlsSettings CopyDefaultSettings ()
134 		{
135 			return DefaultSettings.Clone ();
136 		}
137 
138 		#region Private APIs
139 
140 		/*
141 		 * Private APIs - do not use!
142 		 *
143 		 * This is only public to avoid making our internals visible to System.dll.
144 		 *
145 		 */
146 
147 		[Obsolete ("Do not use outside System.dll!")]
148 		public ICertificateValidator CertificateValidator {
149 			get { return certificateValidator; }
150 		}
151 
152 		[Obsolete ("Do not use outside System.dll!")]
CloneWithValidator(ICertificateValidator validator)153 		public MonoTlsSettings CloneWithValidator (ICertificateValidator validator)
154 		{
155 			if (cloned) {
156 				this.certificateValidator = validator;
157 				return this;
158 			}
159 
160 			var copy = new MonoTlsSettings (this);
161 			copy.certificateValidator = validator;
162 			return copy;
163 		}
164 
Clone()165 		public MonoTlsSettings Clone ()
166 		{
167 			return new MonoTlsSettings (this);
168 		}
169 
MonoTlsSettings(MonoTlsSettings other)170 		MonoTlsSettings (MonoTlsSettings other)
171 		{
172 			RemoteCertificateValidationCallback = other.RemoteCertificateValidationCallback;
173 			ClientCertificateSelectionCallback = other.ClientCertificateSelectionCallback;
174 			checkCertName = other.checkCertName;
175 			checkCertRevocationStatus = other.checkCertRevocationStatus;
176 			UseServicePointManagerCallback = other.useServicePointManagerCallback;
177 			skipSystemValidators = other.skipSystemValidators;
178 			callbackNeedsChain = other.callbackNeedsChain;
179 			UserSettings = other.UserSettings;
180 			EnabledProtocols = other.EnabledProtocols;
181 			EnabledCiphers = other.EnabledCiphers;
182 			CertificateValidationTime = other.CertificateValidationTime;
183 			SendCloseNotify = other.SendCloseNotify;
184 			if (other.TrustAnchors != null)
185 				TrustAnchors = new X509CertificateCollection (other.TrustAnchors);
186 			if (other.CertificateSearchPaths != null) {
187 				CertificateSearchPaths = new string [other.CertificateSearchPaths.Length];
188 				other.CertificateSearchPaths.CopyTo (CertificateSearchPaths, 0);
189 			}
190 
191 			cloned = true;
192 		}
193 
194 		#endregion
195 	}
196 }
197 
198