Esempio n. 1
0
 public LegacySslStream(Stream innerStream, bool leaveInnerStreamOpen, SslStream owner, MonoTlsProvider provider, MonoTlsSettings settings)
     : base(innerStream, leaveInnerStreamOpen)
 {
     SslStream            = owner;
     Provider             = provider;
     certificateValidator = ChainValidationHelper.GetInternalValidator(provider, settings);
 }
Esempio n. 2
0
 internal static object GetDefaultValidator(object settings)
 {
                 #if SECURITY_DEP
     return(ChainValidationHelper.GetDefaultValidator((MSI.MonoTlsSettings)settings));
                 #else
     throw new NotSupportedException();
                 #endif
 }
Esempio n. 3
0
        /*
         * Mono-specific version of 'userCertValidationCallbackWrapper'; we're called from ChainValidationHelper.ValidateChain() here.
         *
         * Since we're built without the PrebuiltSystem alias, we can't use 'SslPolicyErrors' here.  This prevents us from creating a subclass of 'ChainValidationHelper'
         * as well as providing a custom 'ServerCertValidationCallback'.
         */
        bool myUserCertValidationCallbackWrapper(ServerCertValidationCallback callback, X509Certificate certificate, X509Chain chain, MonoSslPolicyErrors sslPolicyErrors)
        {
            m_RemoteCertificateOrBytes = certificate == null ? null : certificate.GetRawCertData();
            if (callback == null)
            {
                if (!_SslState.RemoteCertRequired)
                {
                    sslPolicyErrors &= ~MonoSslPolicyErrors.RemoteCertificateNotAvailable;
                }

                return(sslPolicyErrors == MonoSslPolicyErrors.None);
            }

            return(ChainValidationHelper.InvokeCallback(callback, this, certificate, chain, sslPolicyErrors));
        }
Esempio n. 4
0
        internal SslStream(Stream innerStream, bool leaveInnerStreamOpen, EncryptionPolicy encryptionPolicy, MonoTlsSettings settings)
            : base(innerStream, leaveInnerStreamOpen)
        {
            if (encryptionPolicy != EncryptionPolicy.RequireEncryption && encryptionPolicy != EncryptionPolicy.AllowNoEncryption && encryptionPolicy != EncryptionPolicy.NoEncryption)
            {
                throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "EncryptionPolicy"), "encryptionPolicy");
            }

            var validationHelper = ChainValidationHelper.CloneWithCallbackWrapper(ref settings, myUserCertValidationCallbackWrapper);

            LocalCertSelectionCallback selectionCallback = null;

            if (validationHelper.HasCertificateSelectionCallback)
            {
                selectionCallback = validationHelper.SelectClientCertificate;
            }

            _Configuration = new MyConfiguration(settings, this);
            _SslState      = new SslState(innerStream, null, selectionCallback, encryptionPolicy, _Configuration);
        }
Esempio n. 5
0
 public LegacySslStream(Stream innerStream, bool leaveInnerStreamOpen, MonoTlsProvider provider, MonoTlsSettings settings)
     : base(innerStream, leaveInnerStreamOpen)
 {
     this.provider        = provider;
     certificateValidator = ChainValidationHelper.GetDefaultValidator(provider, settings);
 }
Esempio n. 6
0
		bool CreateStream (HttpWebRequest request)
		{
			try {
				NetworkStream serverStream = new NetworkStream (socket, false);

				if (request.Address.Scheme == Uri.UriSchemeHttps) {
					ssl = true;
					EnsureSSLStreamAvailable ();
					if (!reused || nstream == null || nstream.GetType () != sslStream) {
						byte [] buffer = null;
						if (sPoint.UseConnect) {
							bool ok = CreateTunnel (request, sPoint.Address, serverStream, out buffer);
							if (!ok)
								return false;
						}
#if SECURITY_DEP
#if MONOTOUCH || MONODROID
						nstream = new HttpsClientStream (serverStream, request.ClientCertificates, request, buffer);
#else
						object[] args = new object [4] { serverStream,
							request.ClientCertificates,
							request, buffer};
						nstream = (Stream) Activator.CreateInstance (sslStream, args);
#endif
						SslClientStream scs = (SslClientStream) nstream;
						var helper = new ChainValidationHelper (request);
						scs.ServerCertValidation2 += (certs) => helper.ValidateChain (request.Address.Host, certs);
#endif
						certsAvailable = false;
					}
					// we also need to set ServicePoint.Certificate 
					// and ServicePoint.ClientCertificate but this can
					// only be done later (after handshake - which is
					// done only after a read operation).
				} else {
					ssl = false;
					nstream = serverStream;
				}
			} catch (Exception) {
				if (!request.Aborted)
					status = WebExceptionStatus.ConnectFailure;
				return false;
			}

			return true;
		}
        public override bool ValidateCertificate(ChainValidationHelper validator, string targetHost, bool serverMode,
                                                 X509CertificateCollection certificates, bool wantsChain, ref X509Chain chain, ref SslPolicyErrors errors,
                                                 ref int status11)
        {
            var errorState = UnityTls.NativeInterface.unitytls_errorstate_create();

            var unityTlsChainImpl = chain.Impl as X509ChainImplUnityTls;

            if (unityTlsChainImpl == null)
            {
                if (certificates == null || certificates.Count == 0)
                {
                    errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                    return(false);
                }

                if (wantsChain)
                {
                    chain = SystemCertificateValidator.CreateX509Chain(certificates);
                }
            }
            else
            {
                var cert = UnityTls.NativeInterface.unitytls_x509list_get_x509(unityTlsChainImpl.NativeCertificateChain,
                                                                               (size_t)0, &errorState);
                if (cert.handle == UnityTls.NativeInterface.UNITYTLS_INVALID_HANDLE)
                {
                    errors |= SslPolicyErrors.RemoteCertificateNotAvailable;
                    return(false);
                }
            }

            // fixup targetHost name by removing port
            if (!string.IsNullOrEmpty(targetHost))
            {
                var pos = targetHost.IndexOf(':');
                if (pos > 0)
                {
                    targetHost = targetHost.Substring(0, pos);
                }
            }

            // convert cert to native or extract from unityTlsChainImpl.
            var result = UnityTls.unitytls_x509verify_result.UNITYTLS_X509VERIFY_NOT_DONE;

            UnityTls.unitytls_x509list *certificatesNative = null;
            try
            {
                // Things the validator provides that we might want to make use of here:
                //validator.Settings.CheckCertificateName				// not used by mono?
                //validator.Settings.CheckCertificateRevocationStatus	// not used by mono?
                //validator.Settings.CertificateValidationTime
                //validator.Settings.CertificateSearchPaths				// currently only used by MonoBtlsProvider

                UnityTls.unitytls_x509list_ref certificatesNativeRef;
                if (unityTlsChainImpl == null)
                {
                    certificatesNative = UnityTls.NativeInterface.unitytls_x509list_create(&errorState);
                    CertHelper.AddCertificatesToNativeChain(certificatesNative, certificates, &errorState);
                    certificatesNativeRef =
                        UnityTls.NativeInterface.unitytls_x509list_get_ref(certificatesNative, &errorState);
                }
                else
                {
                    certificatesNativeRef = unityTlsChainImpl.NativeCertificateChain;
                }

                var targetHostUtf8 = Encoding.UTF8.GetBytes(targetHost);

                if (validator.Settings.TrustAnchors != null)
                {
                    UnityTls.unitytls_x509list *trustCAnative = null;
                    try
                    {
                        trustCAnative = UnityTls.NativeInterface.unitytls_x509list_create(&errorState);
                        CertHelper.AddCertificatesToNativeChain(trustCAnative, validator.Settings.TrustAnchors,
                                                                &errorState);
                        var trustCAnativeRef =
                            UnityTls.NativeInterface.unitytls_x509list_get_ref(trustCAnative, &errorState);

                        fixed(byte *targetHostUtf8Ptr = targetHostUtf8)
                        {
                            result = UnityTls.NativeInterface.unitytls_x509verify_explicit_ca(certificatesNativeRef,
                                                                                              trustCAnativeRef, targetHostUtf8Ptr, (size_t)targetHostUtf8.Length, null, null,
                                                                                              &errorState);
                        }
                    }
                    finally
                    {
                        UnityTls.NativeInterface.unitytls_x509list_free(trustCAnative);
                    }
                }
                else
                {
                    fixed(byte *targetHostUtf8Ptr = targetHostUtf8)
                    {
                        result = UnityTls.NativeInterface.unitytls_x509verify_default_ca(certificatesNativeRef,
                                                                                         targetHostUtf8Ptr, (size_t)targetHostUtf8.Length, null, null, &errorState);
                    }
                }
            }
            finally
            {
                UnityTls.NativeInterface.unitytls_x509list_free(certificatesNative);
            }

            errors = UnityTlsConversions.VerifyResultToPolicyErrror(result);
            // There should be a status per certificate, but once again we're following closely the BTLS implementation
            // https://github.com/mono/mono/blob/1553889bc54f87060158febca7e6b8b9910975f8/mcs/class/System/Mono.Btls/MonoBtlsProvider.cs#L180
            // which also provides only a single status for the entire chain.
            // It is notoriously tricky to implement in OpenSSL to get a status for all invididual certificates without finishing the handshake in the process.
            // This is partially the reason why unitytls_x509verify_X doesn't expose it (TODO!) and likely the reason Mono's BTLS impl ignores this.
            unityTlsChainImpl?.AddStatus(UnityTlsConversions.VerifyResultToChainStatus(result));
            return(result == UnityTls.unitytls_x509verify_result.UNITYTLS_X509VERIFY_SUCCESS &&
                   errorState.code == UnityTls.unitytls_error_code.UNITYTLS_SUCCESS);
        }