Beispiel #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;
                }
            }
Beispiel #2
0
            private static void SetSslOptionsForUnsupportedBackend(EasyRequest easy, ClientCertificateProvider certProvider)
            {
                if (certProvider != null)
                {
                    throw new PlatformNotSupportedException(SR.Format(SR.net_http_libcurl_clientcerts_notsupported_sslbackend, CurlVersionDescription, CurlSslVersionDescription, Interop.Http.RequiredOpenSslDescription));
                }

                if (easy._handler.CheckCertificateRevocationList)
                {
                    throw new PlatformNotSupportedException(SR.Format(SR.net_http_libcurl_revocation_notsupported_sslbackend, CurlVersionDescription, CurlSslVersionDescription, Interop.Http.RequiredOpenSslDescription));
                }

                if (easy._handler.ServerCertificateCustomValidationCallback != null)
                {
                    if (easy.ServerCertificateValidationCallbackAcceptsAll)
                    {
                        EventSourceTrace("Warning: Disabling peer and host verification per {0}", nameof(HttpClientHandler.DangerousAcceptAnyServerCertificateValidator), easy: easy);
                        easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYPEER, 0);
                        easy.SetCurlOption(Interop.Http.CURLoption.CURLOPT_SSL_VERIFYHOST, 0);
                    }
                    else
                    {
                        throw new PlatformNotSupportedException(SR.Format(SR.net_http_libcurl_callback_notsupported_sslbackend, CurlVersionDescription, CurlSslVersionDescription, Interop.Http.RequiredOpenSslDescription));
                    }
                }
                else
                {
                    SetSslOptionsForCertificateStore(easy);
                }

                // In case of defaults configure the allowed SSL protocols.
                SetSslVersion(easy);
            }
        public ActionResult WSDoreczyciel()
        {
            var certificate = new ClientCertificateProvider().GetClientCertificate();

            WSDoreczyciel_Dorecz_Demo(certificate);

            return(Redirect("/Home/Index"));
        }
        public ActionResult WSZarzadzanieDokumentami()
        {
            var certificate = new ClientCertificateProvider().GetClientCertificate();

            WSZarzadzanieDokumentami_DodajDokument_Demo(certificate);

            return(Redirect("/Home/Index"));
        }
        public ActionResult WSSkrytka()
        {
            var certificate = new ClientCertificateProvider().GetClientCertificate();

            WSSkrytka_Demo(certificate);

            return(Redirect("/Home/Index"));
        }
        public static void Run(AddClientCertArgs args, Func <ILogger> getLogger)
        {
            args.Validate();
            var settings = RunnerHelper.GetSettings(args.Configfile);
            var clientCertificateProvider = new ClientCertificateProvider(settings);

            var item = clientCertificateProvider.GetClientCertificate(args.PackageSource);

            if (item != null)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Error_ClientCertificateAlreadyExist,
                                                          args.PackageSource));
            }

            if (args.IsFileCertSettingsProvided())
            {
                item = new FileClientCertItem(args.PackageSource,
                                              args.Path,
                                              args.Password,
                                              args.StorePasswordInClearText,
                                              args.Configfile);
            }
            else if (args.IsStoreCertSettingsProvided())
            {
                item = new StoreClientCertItem(args.PackageSource,
                                               args.FindValue,
                                               args.GetStoreLocation(),
                                               args.GetStoreName(),
                                               args.GetFindBy());
            }
            else
            {
                throw new CommandLineArgumentCombinationException(string.Format(CultureInfo.CurrentCulture,
                                                                                Strings.Error_UnknownClientCertificateStoreType));
            }

            try
            {
                var certificates = item.Search();
                if (!certificates.Any())
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_ClientCertificatesNotFound));
                }
            }
            catch
            {
                if (!args.Force)
                {
                    throw;
                }
            }


            clientCertificateProvider.AddOrUpdate(item);

            getLogger().LogInformation(string.Format(CultureInfo.CurrentCulture, Strings.ClientCertificateSuccessfullyAdded, args.PackageSource));
        }
Beispiel #7
0
            private static CURLcode SslCtxCallback(IntPtr curl, IntPtr sslCtx, IntPtr userPointer)
            {
                EasyRequest easy;

                if (!TryGetEasyRequest(curl, out easy))
                {
                    return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                }
                EventSourceTrace(null, easy: easy);

                // Configure the SSL protocols allowed.
                SslProtocols protocols = easy._handler.SslProtocols;

                if (protocols == SslProtocols.None)
                {
                    // If None is selected, let OpenSSL use its defaults, but with SSL2/3 explicitly disabled.
                    // Since the shim/OpenSSL work on a disabling system, where any protocols for which bits aren't
                    // set are disabled, we set all of the bits other than those we want disabled.
#pragma warning disable 0618 // the enum values are obsolete
                    protocols = ~(SslProtocols.Ssl2 | SslProtocols.Ssl3);
#pragma warning restore 0618
                }
                Interop.Ssl.SetProtocolOptions(sslCtx, protocols);

                // Configure the SSL server certificate verification callback.
                Interop.Ssl.SslCtxSetCertVerifyCallback(sslCtx, s_sslVerifyCallback, curl);

                // If a client certificate provider was provided, also configure the client certificate callback.
                if (userPointer != IntPtr.Zero)
                {
                    try
                    {
                        // Provider is passed in via a GCHandle.  Get the provider, which contains
                        // the client certificate callback delegate.
                        GCHandle handle = GCHandle.FromIntPtr(userPointer);
                        ClientCertificateProvider provider = (ClientCertificateProvider)handle.Target;
                        if (provider == null)
                        {
                            Debug.Fail($"Expected non-null provider in {nameof(SslCtxCallback)}");
                            return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                        }

                        // Register the callback.
                        Interop.Ssl.SslCtxSetClientCertCallback(sslCtx, provider._callback);
                        EventSourceTrace("Registered client certificate callback.", easy: easy);
                    }
                    catch (Exception e)
                    {
                        Debug.Fail($"Exception in {nameof(SslCtxCallback)}", e.ToString());
                        return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                    }
                }

                return(CURLcode.CURLE_OK);
            }
Beispiel #8
0
            public void SetupInitialItems(params ClientCertItem[] initialItems)
            {
                var settings = LoadSettingsFromConfigFile();
                var clientCertificateProvider = new ClientCertificateProvider(settings);

                foreach (ClientCertItem item in initialItems)
                {
                    clientCertificateProvider.AddOrUpdate(item);
                }

                settings.SaveToDisk();
            }
        public ActionResult AddDocumentToSigning(AddDocumentToSigningModel model)
        {
            if (this.ModelState.IsValid)
            {
                var tpSigningUri = ConfigurationManager.AppSettings["tpSigning"];
                var certificate  = new ClientCertificateProvider().GetClientCertificate();

                var document   = Encoding.UTF8.GetBytes(model.Document);
                var urlSuccess =
                    Url.Action("AddDocumentToSigningSuccess", "Home",
                               routeValues: null,
                               protocol: Request.Url.Scheme);
                var urlFailed =
                    Url.Action("AddDocumentToSigningFailure", "Home",
                               routeValues: null,
                               protocol: Request.Url.Scheme);

                var additionalInfo = "Some additional info";

                // call ePUAP and get their redirect uri
                // they redirect back to one of your uris
                var        client = new TpSigningClient(tpSigningUri, certificate);
                FaultModel fault;
                var        response = client.AddDocumentToSigning(document, urlSuccess, urlFailed, additionalInfo, out fault);

                if (response != null &&
                    response.Return != null &&
                    !string.IsNullOrEmpty(response.Return.Url)
                    )
                {
                    // the returned url has to be stored
                    // it will be used to query the GetSignedDocument
                    this.Session.Add("url", response.Return.Url);
                    return(Redirect(response.Return.Url));
                }
                else
                {
                    if (fault != null)
                    {
                        this.TempData.Add("Message", string.Format("ePUAP fault: {0}, information: {1}", fault.FaultCode, fault.FaultString));
                    }
                    else
                    {
                        this.TempData.Add("Message", "Unknown error");
                    }

                    return(Redirect("/Home/Index"));
                }
            }

            return(View(model));
        }
        public ActionResult AddDocumentToSigning5Success()
        {
            string message = string.Empty;

            var url = this.Session["url"] as string;

            if (!string.IsNullOrEmpty(url))
            {
                var tpSigningUri = ConfigurationManager.AppSettings["tpSigning5"];
                var certificate  = new ClientCertificateProvider().GetClientCertificate();

                // call ePUAP and get their redirect uri
                // they redirect back to one of your uris
                var        client = new TpSigning5Client(tpSigningUri, certificate);
                FaultModel fault;
                var        response = client.GetSignedDocument(url, out fault);

                if (response != null &&
                    response.IsValid
                    )
                {
                    var model = new AddDocumentToSigning5SuccessModel();

                    // this is the document signed by the user
                    model.Document = Encoding.UTF8.GetString(Convert.FromBase64String(response.Content));
                    // it contains the full user information
                    model.Signature = response.Signature;

                    // add to session
                    this.Session.Add(SESSIONDOCUMENT, Convert.FromBase64String(response.Content));

                    return(View(model));
                }
                else
                {
                    if (fault != null)
                    {
                        this.TempData.Add("Message", string.Format("ePUAP fault: {0}, information: {1}", fault.FaultCode, fault.FaultString));
                    }
                    else
                    {
                        this.TempData.Add("Message", "Unknown error");
                    }

                    return(Redirect("/Home/Index"));
                }
            }

            // fallback to the main page with message to the user
            this.TempData.Add("Message", message);
            return(Redirect("/Home/Index"));
        }
Beispiel #11
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, 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;
                }
            }
Beispiel #13
0
            internal static void SetSslOptions(EasyRequest easy, ClientCertificateOption clientCertOption)
            {
                EventSourceTrace("ClientCertificateOption: {0}", clientCertOption, easy: easy);
                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)
                {
                    EventSourceTrace("Created certificate provider", easy: easy);

                    // 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);
                }

                // Configure the options.  Our best support is when targeting OpenSSL/1.0.  For other backends,
                // we fall back to a minimal amount of support, and may throw a PNSE based on the options requested.
                if (Interop.Http.HasMatchingOpenSslVersion)
                {
                    // 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.
                    SetSslOptionsForSupportedBackend(easy, certProvider, userPointer);
                }
                else
                {
                    // Newer versions of OpenSSL, and other non-OpenSSL backends, do not currently support callbacks.
                    // That means we'll throw a PNSE if a callback is required.
                    SetSslOptionsForUnsupportedBackend(easy, certProvider);
                }
            }
            private static CURLcode SslCtxCallback(IntPtr curl, IntPtr sslCtx, IntPtr userPointer)
            {
                // Configure the SSL protocols allowed.
                EasyRequest easy;

                if (!TryGetEasyRequest(curl, out easy))
                {
                    return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                }
                Interop.Ssl.SetProtocolOptions(sslCtx, easy._handler.SslProtocols);

                // Configure the SSL server certificate verification callback.
                Interop.Ssl.SslCtxSetCertVerifyCallback(sslCtx, s_sslVerifyCallback, curl);

                // If a client certificate provider was provided, also configure the client certificate callback.
                if (userPointer != IntPtr.Zero)
                {
                    try
                    {
                        // Provider is passed in via a GCHandle.  Get the provider, which contains
                        // the client certificate callback delegate.
                        GCHandle handle = GCHandle.FromIntPtr(userPointer);
                        ClientCertificateProvider provider = (ClientCertificateProvider)handle.Target;
                        if (provider == null)
                        {
                            Debug.Fail($"Expected non-null provider in {nameof(SslCtxCallback)}");
                            return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                        }

                        // Register the callback.
                        Interop.Ssl.SslCtxSetClientCertCallback(sslCtx, provider._callback);
                        EventSourceTrace("Registered client certificate callback.");
                    }
                    catch (Exception e)
                    {
                        Debug.Fail($"Exception in {nameof(SslCtxCallback)}", e.ToString());
                        return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                    }
                }

                return(CURLcode.CURLE_OK);
            }
        public ActionResult VerifySignedDocument5(VerifySignedDocument5Model model)
        {
            if (model.Document == null)
            {
                this.ViewBag.Message = "Należy wskazać niepusty dokument do walidacji";
            }
            else
            {
                try
                {
                    var tpSigningUri = ConfigurationManager.AppSettings["tpSigning5"];
                    var certificate  = new ClientCertificateProvider().GetClientCertificate();

                    var client = new TpSigning5Client(tpSigningUri, certificate);

                    byte[] documentData = null;
                    using (var binaryReader = new BinaryReader(model.Document.InputStream))
                    {
                        documentData = binaryReader.ReadBytes(Request.Files[0].ContentLength);
                    }

                    FaultModel fault;
                    var        result = client.VerifySignedDocument(documentData, out fault);

                    if (fault != null)
                    {
                        this.ViewBag.Message = fault.FaultString;
                    }
                    else
                    {
                        model.Signature      = result.Signature;
                        this.ViewBag.Message = result.Content;
                    }
                }
                catch (Exception ex)
                {
                    this.ViewBag.Message = ex.Message;
                }
            }

            return(View(model));
        }
Beispiel #16
0
        public static void Run(RemoveClientCertArgs args, Func <ILogger> getLogger)
        {
            args.Validate();

            var settings = RunnerHelper.GetSettings(args.Configfile);
            var clientCertificateProvider = new ClientCertificateProvider(settings);

            var item = clientCertificateProvider.GetClientCertificate(args.PackageSource);

            if (item == null)
            {
                getLogger().LogInformation(string.Format(CultureInfo.CurrentCulture,
                                                         Strings.NoClientCertificatesMatching,
                                                         args.PackageSource));
                return;
            }

            clientCertificateProvider.Remove(new[] { item });

            getLogger().LogInformation(string.Format(CultureInfo.CurrentCulture, Strings.ClientCertificateSuccessfullyRemoved, args.PackageSource));
        }
        public ActionResult TrustedProfileInfoForPESEL()
        {
            var certificate = new ClientCertificateProvider().GetClientCertificate();

            FaultModel fault;

            var _pesel = "15280119601";

            var client   = new TpUserObjectsInfoClient(TpUserObjectsInfoClient.INTEGRATION_URI, certificate);
            var response = client.TrustedProfileInfoForPESEL(
                _pesel,
                Client.Model.TrustedProfileInfoForPESEL.ProfileInfoEnum.MOST_RECENT,
                out fault);

            if (response != null && response.Profile != null)
            {
                var userId = response.Profile.UserId;
            }

            return(Redirect("/Home/Index"));
        }
Beispiel #18
0
            public void ValidateSettings(params ClientCertItem[] expectedItems)
            {
                var settings = LoadSettingsFromConfigFile();
                var clientCertificateProvider = new ClientCertificateProvider(settings);
                var existingItems             = clientCertificateProvider.GetClientCertificates();

                var comparison = Compare(expectedItems, existingItems);

                Assert.Empty(comparison.PresentInFirstOnly);
                Assert.Empty(comparison.PresentInSecondOnly);

                foreach (Tuple <ClientCertItem, ClientCertItem> tuple in comparison.PresentInBoth)
                {
                    var expectedItem = tuple.Item1;
                    var existItem    = tuple.Item2;
                    Assert.Equal(expectedItem.GetType(), existItem.GetType());
                    if (expectedItem is FileClientCertItem expectedFileClientCertItem && existItem is FileClientCertItem existFileClientCertItem)
                    {
                        Assert.Equal(expectedFileClientCertItem.FilePath, existFileClientCertItem.FilePath);
                        Assert.Equal(expectedFileClientCertItem.Password, existFileClientCertItem.Password);
                        Assert.Equal(expectedFileClientCertItem.IsPasswordIsClearText, existFileClientCertItem.IsPasswordIsClearText);
                    }
Beispiel #19
0
            private static CURLcode SetSslCtxVerifyCallback(
                IntPtr curl,
                IntPtr sslCtx,
                IntPtr userPointer)
            {
                using (SafeSslContextHandle ctx = new SafeSslContextHandle(sslCtx, ownsHandle: false))
                {
                    Interop.Ssl.SslCtxSetCertVerifyCallback(ctx, s_sslVerifyCallback, curl);

                    if (userPointer == IntPtr.Zero)
                    {
                        VerboseTrace("Not using client Certificate callback ");
                    }
                    else
                    {
                        ClientCertificateProvider provider = null;
                        try
                        {
                            GCHandle handle = GCHandle.FromIntPtr(userPointer);
                            provider = (ClientCertificateProvider)handle.Target;
                        }
                        catch (InvalidCastException)
                        {
                            Debug.Fail("ClientCertificateProvider wasn't the GCHandle's Target");
                            return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                        }
                        catch (InvalidOperationException)
                        {
                            Debug.Fail("Invalid GCHandle in CurlSslCallback");
                            return(CURLcode.CURLE_ABORTED_BY_CALLBACK);
                        }

                        Debug.Assert(provider != null, "Expected non-null sslCallback in curlCallBack");
                        Interop.Ssl.SslCtxSetClientCertCallback(ctx, provider._callback);
                    }
                }
                return(CURLcode.CURLE_OK);
            }
        public void CertificateFromStore_Success_ParsedAndAddedToAssociatedPackageSource()
        {
            using (var testInfo = new TestInfo())
            {
                // Arrange
                testInfo.SetupCertificateInStorage();

                // Act
                var settings = testInfo.LoadSettingsFromConfigFile();
                var clientCertificateProvider = new ClientCertificateProvider(settings);
                clientCertificateProvider.AddOrUpdate(new StoreClientCertItem(testInfo.PackageSourceName,
                                                                              testInfo.CertificateFindValue.ToString(),
                                                                              testInfo.CertificateStoreLocation,
                                                                              testInfo.CertificateStoreName,
                                                                              testInfo.CertificateFindBy));

                // Assert
                var packageSourceProvider = new PackageSourceProvider(settings);
                var packageSourceList     = packageSourceProvider.LoadPackageSources().ToList();
                Assert.Equal(1, packageSourceList.Count);
                Assert.Equal(1, packageSourceList[0].ClientCertificates.Count);
                Assert.Equal(testInfo.Certificate, packageSourceList[0].ClientCertificates[0]);
            }
        }
        public void CertificateFromFile_Success_ParsedAndAddedToAssociatedPackageSource()
        {
            using (var testInfo = new TestInfo())
            {
                // Arrange
                testInfo.SetupCertificateFile();

                // Act
                var settings = testInfo.LoadSettingsFromConfigFile();
                var clientCertificateProvider = new ClientCertificateProvider(settings);
                clientCertificateProvider.AddOrUpdate(new FileClientCertItem(testInfo.PackageSourceName,
                                                                             testInfo.CertificateAbsoluteFilePath,
                                                                             testInfo.CertificatePassword,
                                                                             false,
                                                                             testInfo.ConfigFile));

                // Assert
                var packageSourceProvider = new PackageSourceProvider(settings);
                var packageSourceList     = packageSourceProvider.LoadPackageSources().ToList();
                Assert.Equal(1, packageSourceList.Count);
                Assert.Equal(1, packageSourceList[0].ClientCertificates.Count);
                Assert.Equal(testInfo.Certificate, packageSourceList[0].ClientCertificates[0]);
            }
        }
        public static void Run(ListClientCertArgs args, Func <ILogger> getLogger)
        {
            var settings = RunnerHelper.GetSettings(args.Configfile);
            var clientCertificateProvider = new ClientCertificateProvider(settings);

            var items = clientCertificateProvider.GetClientCertificates();

            if (!items.Any())
            {
                getLogger().LogInformation(Strings.NoClientCertificates);
                return;
            }

            var clientCertificatesLogs = new List <LogMessage>();

            getLogger().LogInformation(Strings.RegsiteredClientCertificates);
            getLogger().LogInformation(string.Empty);

            var defaultIndentation = string.Empty.PadRight(PaddingWidth);

            for (var i = 0; i < items.Count; i++)
            {
                var item = items[i];

                var builder          = new StringBuilder();
                var indexIndentation = $" {i + 1}.".PadRight(PaddingWidth);

                builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesLogTitle, indexIndentation, item.PackageSource, item.ElementName);
                builder.AppendLine();

                switch (item)
                {
                case FileClientCertItem fileCertItem:
                {
                    builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesFileCertFilePath, defaultIndentation, fileCertItem.FilePath);
                    builder.AppendLine();

                    if (string.IsNullOrEmpty(fileCertItem.Password))
                    {
                        builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesFileCertNoPassword, defaultIndentation);
                    }
                    else
                    {
                        builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesFileCertWithPassword, defaultIndentation);
                    }

                    builder.AppendLine();

                    break;
                }

                case StoreClientCertItem storeCertItem:
                    builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesStoreCertStoreLocation, defaultIndentation, StoreClientCertItem.GetString(storeCertItem.StoreLocation));
                    builder.AppendLine();
                    builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesStoreCertStoreName, defaultIndentation, StoreClientCertItem.GetString(storeCertItem.StoreName));
                    builder.AppendLine();
                    builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesStoreCertFindBy, defaultIndentation, StoreClientCertItem.GetString(storeCertItem.FindType));
                    builder.AppendLine();
                    builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesStoreCertFindValue, defaultIndentation, storeCertItem.FindValue);
                    builder.AppendLine();
                    break;
                }

                try
                {
                    var certificates = item.Search();
                    foreach (var certificate in certificates)
                    {
                        builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesItemCertificateMessage, defaultIndentation, certificate.GetCertHashString());
                        builder.AppendLine();
                    }
                }
                catch (Exception e)
                {
                    builder.AppendFormat(CultureInfo.CurrentCulture, Strings.ClientCertificatesItemCertificateError, defaultIndentation, e.GetBaseException().Message);
                    builder.AppendLine();
                }

                clientCertificatesLogs.Add(new LogMessage(LogLevel.Information, builder.ToString()));
            }

            getLogger().LogMessages(clientCertificatesLogs);
        }
        public static void Run(UpdateClientCertArgs args, Func <ILogger> getLogger)
        {
            args.Validate();

            var settings = RunnerHelper.GetSettings(args.Configfile);
            var clientCertificateProvider = new ClientCertificateProvider(settings);

            var item = clientCertificateProvider.GetClientCertificate(args.PackageSource);

            if (item == null)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                          Strings.Error_ClientCertificateNotExist,
                                                          args.PackageSource));
            }

            switch (item)
            {
            case FileClientCertItem fileCertItem:
                if (args.IsStoreCertSettingsProvided())
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                              Strings.Error_ClientCertificateTypeMismatch,
                                                              args.PackageSource));
                }

                fileCertItem.Update(args.Path, args.Password, args.StorePasswordInClearText);
                break;

            case StoreClientCertItem storeCertItem:
                if (args.IsFileCertSettingsProvided())
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture,
                                                              Strings.Error_ClientCertificateTypeMismatch,
                                                              args.PackageSource));
                }

                storeCertItem.Update(args.FindValue,
                                     args.GetStoreLocation(),
                                     args.GetStoreName(),
                                     args.GetFindBy());
                break;
            }

            try
            {
                var certificates = item.Search();
                if (!certificates.Any())
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.Error_ClientCertificatesNotFound));
                }
            }
            catch
            {
                if (!args.Force)
                {
                    throw;
                }
            }

            clientCertificateProvider.AddOrUpdate(item);

            getLogger().LogInformation(string.Format(CultureInfo.CurrentCulture, Strings.ClientCertificateSuccessfullyUpdated, args.PackageSource));
        }
            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;
                }
            }
        /// <summary>
        /// SAML2 Logout.
        ///
        /// The SAML2 logout is complicated as there are two main scenarios.
        ///
        /// Scenario 1.
        ///
        /// It's this application that triggers the logout.
        /// The application sends the LogoutRequest to the server
        /// and the server is supposed to answer with the LogoutResponse,
        /// sent to this endpoint (assuming the /account/logout is
        /// registered as the logout endpoint in the IdP).
        ///
        /// In this app the LogoutRequest sending is handled in the HomeController
        /// (home/logout)
        ///
        /// Scenario 2.
        ///
        /// Another application triggers the logout. The server
        /// gets the LogoutRequest from this another app and
        /// sends LogoutRequest here. This app is supposed to
        /// answer with the LogoutResponse.
        ///
        /// Both scenarios means that to handle logouts correctly,
        /// the app has to be able to both send and receive
        /// both LogoutRequest and LogoutResponse
        /// </summary>
        public ActionResult Logout()
        {
            var sam2           = new Saml2AuthenticationModule();
            var idpCertificate = new ClientCertificateProvider().GetIdPCertificate();

            if (sam2.IsLogoutRequest(this.Request) ||
                sam2.IsLogoutResponse(this.Request)
                )
            {
                // first check if this is a LogoutResponse from the IdP
                var logoutResponse = new LogoutResponseFactory().From(this.Request);
                if (logoutResponse != null)
                {
                    var result = sam2.MessageSigner.Validate(logoutResponse, idpCertificate);
                    if (!result)
                    {
                        throw new ValidationException("The LogoutResponse is not correctly signed with the IdP certificate");
                    }
                }

                // then check if this is a LogoutRequest from the IdP
                var logoutRequest = new LogoutRequestFactory().From(this.Request);
                if (logoutRequest != null)
                {
                    var result = sam2.MessageSigner.Validate(logoutRequest, idpCertificate);
                    if (!result)
                    {
                        throw new ValidationException("The LogoutResponse is not correctly signed with the IdP certificate");
                    }
                }

                // both possibilities were validated
                // signout can be performed
                FormsAuthentication.SignOut();

                // create the response in case of the LogoutRequest
                if (logoutRequest != null)
                {
                    var assertionIssuer  = ConfigurationManager.AppSettings["AssertionIssuer"];
                    var identityProvider = ConfigurationManager.AppSettings["IdentityProvider"];

                    var x509Configuration = new X509Configuration()
                    {
                        SignatureCertificate = new ClientCertificateProvider().GetClientCertificate(),
                        IncludeKeyInfo       = true,
                        SignatureAlgorithm   = Signature.SignatureAlgorithm.SHA256
                    };

                    var requestBinding = Binding.POST;

                    var logoutResponseFactory = new LogoutResponseFactory();

                    logoutResponseFactory.Issuer      = assertionIssuer;
                    logoutResponseFactory.Destination = identityProvider;

                    logoutResponseFactory.RequestBinding    = requestBinding;
                    logoutResponseFactory.X509Configuration = x509Configuration;

                    // mark the response
                    logoutResponseFactory.InResponseTo = logoutRequest.SessionIndex;

                    switch (logoutResponseFactory.RequestBinding)
                    {
                    case Constants.Binding.POST:
                        return(Content(logoutResponseFactory.CreatePostBindingContent()));

                    default:
                        throw new ArgumentException(string.Format("The {0} logout response binding is not supported", logoutResponseFactory.RequestBinding));
                    }
                }
            }

            // go back to the main page (possibly with logout
            return(Redirect(FormsAuthentication.DefaultUrl));
        }