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; } }
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)); }
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); }
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")); }
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) { 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)); }
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")); }
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); }
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)); }