- switch (protocol)
- {
- case SecurityProtocolType.Default:
- case SecurityProtocolType.Tls:
- return CipherSuiteFactory.GetTls1SupportedCiphers();
-
- case SecurityProtocolType.Ssl3:
- return CipherSuiteFactory.GetSsl3SupportedCiphers();
-
- case SecurityProtocolType.Ssl2:
- default:
- throw new NotSupportedException("Unsupported security protocol type");
+ CipherSuiteCollection suites;
+ switch (protocol) {
+ case SecurityProtocolType.Default:
+ case SecurityProtocolType.Tls:
+ suites = CipherSuiteFactory.GetTls1SupportedCiphers ();
+ break;
+ case SecurityProtocolType.Ssl3:
+ suites = CipherSuiteFactory.GetSsl3SupportedCiphers ();
+ break;
+ case SecurityProtocolType.Ssl2:
+ default:
+ throw new NotSupportedException ("Unsupported security protocol type");
+ }
+
+ IEnumerable<string> list = null;
+#if INSIDE_SYSTEM
+ // if SSL/TLS support is built-in System.dll (e.g. monotouch) then we can access ServicePointManager
+ // extension directly
+ var cb = server ? ServicePointManager.ServerCipherSuitesCallback : ClientCipherSuitesCallback;
+ if (cb == null)
+ return suites; // e.g. no callback was set
+
+ list = cb ((System.Net.SecurityProtocolType) (int) protocol, suites.GetNames ());
+#elif !BOOTSTRAP_BASIC
+ // Mono.Security must work on MS.NET so it cannot depend on any Mono-specific extensions
+ PropertyInfo pi = null;
+ if (server) {
+ if (server_callback == null)
+ server_callback = spm.GetProperty ("ServerCipherSuitesCallback", BindingFlags.Static | BindingFlags.Public);
+ pi = server_callback;
+ } else {
+ if (client_callback == null)
+ client_callback = spm.GetProperty ("ClientCipherSuitesCallback", BindingFlags.Static | BindingFlags.Public);
+ pi = client_callback;
+ }
+ if (pi == null)
+ return suites; // e.g. MS runtime - return every supported suites
+
+ var cb = (Delegate) pi.GetGetMethod ().Invoke (null, null);
+ if (cb == null)
+ return suites; // e.g. no callback was set - return every supported suites
+
+ list = (IEnumerable<string>) cb.DynamicInvoke (new object[] {
+ (System.Net.SecurityProtocolType) (int) protocol, suites.GetNames ()
+ });
+#else
+ // TODO: right now the callback is only available when using System.Net.* types for SSL/TLS
+ return suites;
+#endif
+ CipherSuiteCollection allowed = new CipherSuiteCollection (protocol);
+ if (list != null) {
+ foreach (var name in list) {
+ // add any supported (ignore unknowns) ciphers requested by the callback
+ var cipher = suites [name];
+ if (cipher != null)
+ allowed.Add (cipher);
+ }