Esempio n. 1
0
            private static void SetSslOptionsForSupportedBackend(EasyRequest easy, ClientCertificateProvider certProvider, IntPtr userPointer)
            {
                CURLcode answer = easy.SetSslCtxCallback(s_sslCtxCallback, userPointer);

                EventSourceTrace("Callback registration result: {0}", answer, easy: easy);
                switch (answer)
                {
                case CURLcode.CURLE_OK:
                    // We successfully registered.  If we'll be invoking a user-provided callback to verify the server
                    // certificate as part of that, disable libcurl's verification of the host name; we need to get
                    // the callback from libcurl even if the host name doesn't match, so we take on the responsibility
                    // of doing the host name match in the callback prior to invoking the user's delegate.
                    if (easy._handler.ServerCertificateCustomValidationCallback != null)
                    {
                        easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYHOST, 0);
                        // But don't change the CURLOPT_SSL_VERIFYPEER setting, as setting it to 0 will
                        // cause SSL and libcurl to ignore the result of the server callback.
                    }

                    SetSslOptionsForCertificateStore(easy);

                    // The allowed SSL protocols will be set in the configuration callback.
                    break;

                case CURLcode.CURLE_UNKNOWN_OPTION:     // Curl 7.38 and prior
                case CURLcode.CURLE_NOT_BUILT_IN:       // Curl 7.39 and later
                    SetSslOptionsForUnsupportedBackend(easy, certProvider);
                    break;

                default:
                    ThrowIfCURLEError(answer);
                    break;
                }
            }
Esempio n. 2
0
            internal static void SetSslOptions(EasyRequest easy, ClientCertificateOption clientCertOption)
            {
                // Disable SSLv2/SSLv3, allow TLSv1.*
                easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSLVERSION, (long)Interop.Http.CurlSslVersion.CURL_SSLVERSION_TLSv1);

                IntPtr userPointer = IntPtr.Zero;

                if (clientCertOption == ClientCertificateOption.Automatic)
                {
                    ClientCertificateProvider certProvider = new ClientCertificateProvider();
                    userPointer = GCHandle.ToIntPtr(certProvider._gcHandle);
                    easy.Task.ContinueWith((_, state) => ((IDisposable)state).Dispose(),
                                           certProvider,
                                           CancellationToken.None,
                                           TaskContinuationOptions.ExecuteSynchronously,
                                           TaskScheduler.Default);
                }
                else
                {
                    Debug.Assert(clientCertOption == ClientCertificateOption.Manual, "ClientCertificateOption is manual or automatic");
                }

                CURLcode answer = easy.SetSslCtxCallback(s_sslCtxCallback, userPointer);

                switch (answer)
                {
                case CURLcode.CURLE_OK:
                    break;

                // Curl 7.38 and prior
                case CURLcode.CURLE_UNKNOWN_OPTION:
                // Curl 7.39 and later
                case CURLcode.CURLE_NOT_BUILT_IN:
                    EventSourceTrace("CURLOPT_SSL_CTX_FUNCTION not supported. Platform default HTTPS chain building in use");
                    if (clientCertOption == ClientCertificateOption.Automatic)
                    {
                        throw new PlatformNotSupportedException(SR.net_http_unix_invalid_client_cert_option);
                    }

                    break;

                default:
                    ThrowIfCURLEError(answer);
                    break;
                }
            }
Esempio n. 3
0
            internal static void SetSslOptions(EasyRequest easy, ClientCertificateOption clientCertOption)
            {
                // Disable SSLv2/SSLv3, allow TLSv1.*
                easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSLVERSION, (long)Interop.Http.CurlSslVersion.CURL_SSLVERSION_TLSv1);

                IntPtr userPointer = IntPtr.Zero;
                if (clientCertOption == ClientCertificateOption.Automatic)
                {
                    ClientCertificateProvider certProvider = new ClientCertificateProvider();
                    userPointer = GCHandle.ToIntPtr(certProvider._gcHandle);
                    easy.Task.ContinueWith((_, state) => ((IDisposable)state).Dispose(),
                                           certProvider,
                                           CancellationToken.None,
                                           TaskContinuationOptions.ExecuteSynchronously,
                                           TaskScheduler.Default);
                }
                else
                {
                    Debug.Assert(clientCertOption == ClientCertificateOption.Manual, "ClientCertificateOption is manual or automatic");
                }

                CURLcode answer = easy.SetSslCtxCallback(s_sslCtxCallback, userPointer);

                switch (answer)
                {
                    case CURLcode.CURLE_OK:
                        break;
                    // Curl 7.38 and prior
                    case CURLcode.CURLE_UNKNOWN_OPTION:
                    // Curl 7.39 and later
                    case CURLcode.CURLE_NOT_BUILT_IN:
                        EventSourceTrace("CURLOPT_SSL_CTX_FUNCTION not supported. Platform default HTTPS chain building in use");
                        if (clientCertOption == ClientCertificateOption.Automatic)
                        {
                            throw new PlatformNotSupportedException(SR.net_http_unix_invalid_client_cert_option);
                        }

                        break;
                    default:
                        ThrowIfCURLEError(answer);
                        break;
                }
            }
            internal static void SetSslOptions(EasyRequest easy)
            {
                CURLcode answer = easy.SetSslCtxCallback(s_sslCtxCallback);

                switch (answer)
                {
                    case CURLcode.CURLE_OK:
                        break;
                    // Curl 7.38 and prior
                    case CURLcode.CURLE_UNKNOWN_OPTION:
                    // Curl 7.39 and later
                    case CURLcode.CURLE_NOT_BUILT_IN:
                        VerboseTrace("CURLOPT_SSL_CTX_FUNCTION is not supported, platform default https chain building in use");
                        break;
                    default:
                        ThrowIfCURLEError(answer);
                        break;
                }
            }
Esempio n. 5
0
            internal static void SetSslOptions(EasyRequest easy, ClientCertificateOption clientCertOption)
            {
                Debug.Assert(clientCertOption == ClientCertificateOption.Automatic || clientCertOption == ClientCertificateOption.Manual);

                // Create a client certificate provider if client certs may be used.
                X509Certificate2Collection clientCertificates = easy._handler._clientCertificates;
                ClientCertificateProvider certProvider =
                    clientCertOption == ClientCertificateOption.Automatic ? new ClientCertificateProvider(null) : // automatic
                    clientCertificates?.Count > 0 ? new ClientCertificateProvider(clientCertificates) : // manual with certs
                    null; // manual without certs
                IntPtr userPointer = IntPtr.Zero;
                if (certProvider != null)
                {
                    // The client cert provider needs to be passed through to the callback, and thus
                    // we create a GCHandle to keep it rooted.  This handle needs to be cleaned up
                    // when the request has completed, and a simple and pay-for-play way to do that
                    // is by cleaning it up in a continuation off of the request.
                    userPointer = GCHandle.ToIntPtr(certProvider._gcHandle);
                    easy.Task.ContinueWith((_, state) => ((IDisposable)state).Dispose(), certProvider,
                        CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
                }

                // Register the callback with libcurl.  We need to register even if there's no user-provided
                // server callback and even if there are no client certificates, because we support verifying
                // server certificates against more than those known to OpenSSL.
                CURLcode answer = easy.SetSslCtxCallback(s_sslCtxCallback, userPointer);
                switch (answer)
                {
                    case CURLcode.CURLE_OK:
                        // We successfully registered.  If we'll be invoking a user-provided callback to verify the server
                        // certificate as part of that, disable libcurl's verification of the host name.  The user's callback
                        // needs to be given the opportunity to examine the cert, and our logic will determine whether
                        // the host name matches and will inform the callback of that.
                        if (easy._handler.ServerCertificateValidationCallback != null)
                        {
                            easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYHOST, 0); // don't verify the peer cert's hostname
                            // We don't change the SSL_VERIFYPEER setting, as setting it to 0 will cause
                            // SSL and libcurl to ignore the result of the server callback.
                        }

                        // The allowed SSL protocols will be set in the configuration callback.
                        break;

                    case CURLcode.CURLE_UNKNOWN_OPTION: // Curl 7.38 and prior
                    case CURLcode.CURLE_NOT_BUILT_IN:   // Curl 7.39 and later
                        // It's ok if we failed to register the callback if all of the defaults are in play
                        // with relation to handling of certificates.  But if that's not the case, failing to 
                        // register the callback will result in those options not being factored in, which is
                        // a significant enough error that we need to fail.
                        EventSourceTrace("CURLOPT_SSL_CTX_FUNCTION not supported: {0}", answer, easy: easy);
                        if (certProvider != null ||
                            easy._handler.ServerCertificateValidationCallback != null ||
                            easy._handler.CheckCertificateRevocationList)
                        {
                            throw new PlatformNotSupportedException(
                                SR.Format(SR.net_http_unix_invalid_certcallback_option, CurlVersionDescription, CurlSslVersionDescription));
                        }

                        // Since there won't be a callback to configure the allowed SSL protocols, configure them here.
                        SetSslVersion(easy);

                        break;

                    default:
                        ThrowIfCURLEError(answer);
                        break;
                }
            }
            internal static void SetSslOptions(EasyRequest easy, ClientCertificateOption clientCertOption)
            {
                Debug.Assert(clientCertOption == ClientCertificateOption.Automatic || clientCertOption == ClientCertificateOption.Manual);

                // Create a client certificate provider if client certs may be used.
                X509Certificate2Collection clientCertificates = easy._handler._clientCertificates;
                ClientCertificateProvider  certProvider       =
                    clientCertOption == ClientCertificateOption.Automatic ? new ClientCertificateProvider(null) : // automatic
                    clientCertificates?.Count > 0 ? new ClientCertificateProvider(clientCertificates) :           // manual with certs
                    null;                                                                                         // manual without certs
                IntPtr userPointer = IntPtr.Zero;

                if (certProvider != null)
                {
                    // The client cert provider needs to be passed through to the callback, and thus
                    // we create a GCHandle to keep it rooted.  This handle needs to be cleaned up
                    // when the request has completed, and a simple and pay-for-play way to do that
                    // is by cleaning it up in a continuation off of the request.
                    userPointer = GCHandle.ToIntPtr(certProvider._gcHandle);
                    easy.Task.ContinueWith((_, state) => ((IDisposable)state).Dispose(), certProvider,
                                           CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
                }

                // Register the callback with libcurl.  We need to register even if there's no user-provided
                // server callback and even if there are no client certificates, because we support verifying
                // server certificates against more than those known to OpenSSL.
                CURLcode answer = easy.SetSslCtxCallback(s_sslCtxCallback, userPointer);

                switch (answer)
                {
                case CURLcode.CURLE_OK:
                    // We successfully registered.  If we'll be invoking a user-provided callback to verify the server
                    // certificate as part of that, disable libcurl's verification of the host name.  The user's callback
                    // needs to be given the opportunity to examine the cert, and our logic will determine whether
                    // the host name matches and will inform the callback of that.
                    if (easy._handler.ServerCertificateValidationCallback != null)
                    {
                        easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYHOST, 0);     // don't verify the peer cert's hostname
                        // We don't change the SSL_VERIFYPEER setting, as setting it to 0 will cause
                        // SSL and libcurl to ignore the result of the server callback.
                    }

                    // The allowed SSL protocols will be set in the configuration callback.
                    break;

                case CURLcode.CURLE_UNKNOWN_OPTION:     // Curl 7.38 and prior
                case CURLcode.CURLE_NOT_BUILT_IN:       // Curl 7.39 and later
                    // It's ok if we failed to register the callback if all of the defaults are in play
                    // with relation to handling of certificates.  But if that's not the case, failing to
                    // register the callback will result in those options not being factored in, which is
                    // a significant enough error that we need to fail.
                    EventSourceTrace("CURLOPT_SSL_CTX_FUNCTION not supported: {0}", answer);
                    if (certProvider != null ||
                        easy._handler.ServerCertificateValidationCallback != null ||
                        easy._handler.CheckCertificateRevocationList)
                    {
                        throw new PlatformNotSupportedException(
                                  SR.Format(SR.net_http_unix_invalid_certcallback_option, CurlVersionDescription, CurlSslVersionDescription));
                    }

                    // Since there won't be a callback to configure the allowed SSL protocols, configure them here.
                    SetSslVersion(easy);

                    break;

                default:
                    ThrowIfCURLEError(answer);
                    break;
                }
            }