/// <summary> /// Returns true if the certificate <paramref name="me"/> is trusted by a SanteSuite certificate /// </summary> public static bool IsTrustedIntern(this X509Certificate2 me, X509Certificate2Collection extraCerts, out IEnumerable <X509ChainStatus> chainStatus) { var chain = X509Chain.Create(); chain.ChainPolicy = new X509ChainPolicy() { RevocationMode = X509RevocationMode.NoCheck }; if (extraCerts != null) { chain.ChainPolicy.ExtraStore.AddRange(extraCerts); } chain.ChainPolicy.ExtraStore.AddRange(GetInternalCertificates().ToArray()); var retVal = chain.Build(me); chainStatus = chain.ChainStatus; if (!retVal) { using (var trustedPublisherStore = new X509Store(StoreName.TrustedPublisher, StoreLocation.LocalMachine)) { trustedPublisherStore.Open(OpenFlags.ReadOnly); retVal = trustedPublisherStore.Certificates.Find(X509FindType.FindBySubjectName, me.Subject, false).Count > 0; } } return(retVal || HasTrustedRootCert(chain)); }
/// <summary> /// 校验证书链是否可信 /// </summary> /// <param name="certificate">需要验证的目标证书或者证书链</param> /// <param name="rootCertificate">可信根证书</param> public static bool IsTrusted(string certificate, string rootCertificate) { var rootCertificates = ReadPemCertChain(rootCertificate); var certificates = ReadPemCertChain(certificate); using (var chain = X509Chain.Create()) { chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; foreach (var rootCert in rootCertificates) { chain.ChainPolicy.ExtraStore.Add(rootCert); } foreach (var cert in certificates) { if (!chain.Build(cert)) { return(false); } } } return(true); }
private static void AddServerCertificateInfo(HttpResponseMessage response, SslPolicyErrors sslPolicyErrors) { response.RequestMessage.Properties[nameof(ServerCertificateInfo)] = new ServerCertificateInfo("X509CertificateName", X509Chain.Create(), sslPolicyErrors); }
/// <summary> /// Verify file is signed only with one self-signed certificate and verify this certificate chain. /// </summary> /// <param name="filename">An filename to verify.</param> /// <returns>true if the file signed with certificate; otherwise, false.</returns> /// <exception cref="ArgumentNullException">The filename is null.</exception> /// <exception cref="CryptographicException">The certificate is unreadable.</exception> public bool VerifyFileCertificate(string filename) { if (filename == null) { throw new ArgumentNullException(nameof(filename)); } _logger.Info("Verify file certificate"); using var fileCertificateCollection = DynamicDisposable <X509Certificate2Collection> .CreateNonNull(new X509Certificate2Collection ()); fileCertificateCollection.Object.Import(filename); if (fileCertificateCollection.Object.Count != 1) { _logger.Error($"Invalid certificates count: {fileCertificateCollection.Object.Count}"); return(false); } var fileCertificate = fileCertificateCollection.Object[0]; if (fileCertificate.RawData.SequenceEqual(_fileSignCertificate.RawData)) { using var chain = DynamicDisposable <X509Chain> .CreateNonNull(X509Chain.Create()); if (_rootCertificate != null) { chain.Object.ChainPolicy.ExtraStore.Add(_rootCertificate); // add CA cert for verification } chain.Object.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // no revocation checking chain.Object.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; chain.Object.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; return(chain.Object.Build(fileCertificate) && VerifyChain(chain.Object)); } _logger.Error("Invalid certificate data"); return(false); }
public async Task ValidateAsync_ReturnsFalse_WithInvalidCNCertificate() { var clientCertificateWithInvalidEuiPath = await BasicsStationNetworkServerTests.CreatePfxCertificateAsync(false, InvalidStationEui); try { using var cert = new X509Certificate2(clientCertificateWithInvalidEuiPath); using var chain = X509Chain.Create(); _ = this.stationConfigService.Setup(x => x.GetAllowedClientThumbprintsAsync(It.IsAny <StationEui>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new[] { cert.Thumbprint })); var result = await this.clientCertValidatorSvc.ValidateAsync(cert, chain, System.Net.Security.SslPolicyErrors.None, default); Assert.False(result); Assert.Contains(this.logger.Invocations, i => i.Arguments.Any(a => a.ToString() !.Contains(InvalidStationEui, StringComparison.OrdinalIgnoreCase))); } finally { if (!string.IsNullOrEmpty(clientCertificateWithInvalidEuiPath)) { File.Delete(clientCertificateWithInvalidEuiPath); } } }
/// <summary> /// Verify file is signed only with one self-signed certificate and verify this certificate chain. /// </summary> /// <param name="filename">An filename to verify.</param> /// <returns>true if the file signed with certificate; otherwise, false.</returns> /// <exception cref="ArgumentNullException">The filename is null.</exception> /// <exception cref="CryptographicException">The certificate is unreadable.</exception> public bool VerifyFileCertificate(string filename) { if (filename == null) { throw new ArgumentNullException("filename"); } X509Certificate2Collection fileCertificateCollection = new X509Certificate2Collection(); fileCertificateCollection.Import(filename); if (fileCertificateCollection.Count == 1) { X509Certificate2 fileCertificate = fileCertificateCollection[0]; if (fileCertificate.RawData.SequenceEqual(fileSignCertificate.RawData)) { X509Chain chain = X509Chain.Create(); if (rootCertificate != null) { chain.ChainPolicy.ExtraStore.Add(rootCertificate); // add CA cert for verification } chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // no revocation checking chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; return(chain.Build(fileCertificate) && VerifyChain(chain)); } } return(false); }
public static void BuildChainInvalidValues() { using (var chain = X509Chain.Create()) { AssertExtensions.Throws <ArgumentException>("certificate", () => chain.Build(null)); AssertExtensions.Throws <ArgumentException>("certificate", () => chain.Build(new X509Certificate2())); } }
private static X509Chain GetCertificateChain(X509Certificate2 cert) { var certificateChain = X509Chain.Create(); certificateChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; certificateChain.Build(cert); return(certificateChain); }
private SignRequest Create2StepSignRequest(Document document, SignatureRequestProperties properties) { var documentId = "doc-" + Guid.NewGuid().ToString(); byte[][] x509Chain; if (SignerChain.Length == 1 && SignerChain[0].Issuer != SignerChain[0].Subject) { var chain = X509Chain.Create(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.Build(SignerChain[0]); x509Chain = chain.ChainElements .Cast <X509ChainElement>() .AsQueryable() .Select(x => x.Certificate.RawData) .ToArray(); } else { x509Chain = SignerChain.AsQueryable() .Select(x => x.RawData) .ToArray(); } return(new SignRequest() { Profile = "http://docs.oasis-open.org/dss-x/ns/localsig", OptionalInputs = new OptionalInputs() { SignatureType = SignatureType, ServicePolicy = "http://docs.oasis-open.org/dss-x/ns/localsig/two-step-approach", SignaturePlacement = CreateEnvelopedSignature(documentId), RequestDocumentHash = new RequestDocumentHash() { MaintainRequestState = true, MaintainRequestStateSpecified = true }, KeySelector = new KeySelector() { KeyInfo = new KeyInfoType() { X509Data = x509Chain } }, VisibleSignatureConfiguration = properties?.Configuration }, InputDocuments = new InputDocuments() { Document = new DocumentType[] { CreateDocumentType(documentId, document) } } }); }
public void StaticCreation() { X509Chain c = X509Chain.Create(); #if MOBILE Assert.IsNull(c); #else CheckDefaultChain(c); #endif }
static int Main(string[] args) { if (args.Length == 0) { Console.WriteLine("Usage: mono x509build.exe filename"); return(2); } string filename = args [0]; X509Certificate2 cert = new X509Certificate2(filename); // using X509Chain.Create will use the X509Chain defined in machine.config X509Chain chain = X509Chain.Create(); bool result = chain.Build(cert); Console.WriteLine("Build: {0}", result); Console.WriteLine(); Console.WriteLine("ChainStatus:"); if (chain.ChainStatus.Length > 0) { foreach (X509ChainStatus st in chain.ChainStatus) { Console.WriteLine("\t{0}", st.Status); } } else { Console.WriteLine("\t{0}", X509ChainStatusFlags.NoError); } Console.WriteLine(); int n = 1; Console.WriteLine("ChainElements:"); foreach (X509ChainElement ce in chain.ChainElements) { Console.WriteLine("{0}. Certificate: {1}", n++, ce.Certificate); Console.WriteLine("\tChainStatus:"); if (ce.ChainElementStatus.Length > 0) { foreach (X509ChainStatus st in ce.ChainElementStatus) { Console.WriteLine("\t\t{0}", st.Status); } } else { Console.WriteLine("\t\t{0}", X509ChainStatusFlags.NoError); } Console.WriteLine(); } return(result ? 0 : 1); }
public void ValidateSelfSignedAllowedNoViolation() { var path = Path.Combine(Environment.CurrentDirectory, "security", "TestValidationCertificate.pfx"); var certificate = new X509Certificate2(path, "abc123"); var chain = X509Chain.Create(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly; chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; chain.Build(certificate); var isValid = CertificateValidation.CertificateValidationCallBackAllowsSelfSigned(this, certificate, chain, SslPolicyErrors.None); Assert.IsTrue(isValid, "The certificate is expected to pass validation"); }
public async Task ValidateAsync_ReturnsFalse_WithNonExpectedThumbprint() { if (string.IsNullOrEmpty(this.clientCertificateWithEuiPath)) { throw new InvalidOperationException("Client certificate was not properly initialized."); } using var cert = new X509Certificate2(this.clientCertificateWithEuiPath); using var chain = X509Chain.Create(); _ = this.stationConfigService.Setup(x => x.GetAllowedClientThumbprintsAsync(It.IsAny <StationEui>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new[] { "AnotherThumbprint" })); var result = await this.clientCertValidatorSvc.ValidateAsync(cert, chain, System.Net.Security.SslPolicyErrors.None, default); Assert.False(result); }
private static bool IsModuleSignedOneTry(Module module) { try { X509Certificate certificate = module.GetSignerCertificate(); if (certificate == null) { // File is not signed. return(false); } X509Certificate2 certificate2 = new X509Certificate2(certificate); using (X509Chain CertificateChain = X509Chain.Create()) { CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly; CertificateChain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(60); CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; bool IsEndCertificateValid = CertificateChain.Build(certificate2); if (!IsEndCertificateValid) { return(false); } CertificateChain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; CertificateChain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(60); CertificateChain.ChainPolicy.RevocationMode = X509RevocationMode.Online; CertificateChain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; bool IsCertificateChainValid = CertificateChain.Build(certificate2); if (!IsCertificateChainValid) { return(false); } return(true); } } catch { return(false); } }
/// <summary> /// /// </summary> /// <param name="name">The name of the certificate to retrieve</param> /// <returns>Returns the first instance of the certificate matching the name</returns> public static X509Certificate2 GetRootCertificate(string name) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("Certificate name must be provided!", nameof(name)); } try { X509Certificate2 CAroot = null; var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadOnly); var cers = store.Certificates.Find(X509FindType.FindBySubjectName, name, false); if (cers.Count > 0) { foreach (var certificate in cers) { var chain = X509Chain.Create(); chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags; if (chain.Build(certificate)) { CAroot = certificate; Log.Entry(LogName, name + " cert found"); } } } else { throw new ArgumentException(name + " NOT found in keystore"); } store.Close(); return(CAroot); } catch (Exception ex) { Log.Error(LogName, "Unable to retrieve " + name); Log.Error(LogName, ex); } return(null); }
private static X509Certificate2 AttemptToResolveCACertificateFromUserCertificate(X509Certificate2 userCertificate) { #if NET45 X509Chain certificateChain = X509Chain.Create(); #elif NETSTANDARD1_3 using (var certificateChain = new X509Chain()) #else using (var certificateChain = new X509Chain(true)) #endif { certificateChain.Build(userCertificate); return(certificateChain.ChainElements.Count > 1 ? certificateChain.ChainElements[certificateChain.ChainElements.Count - 1].Certificate : null); } }
public async Task ValidateAsync_ReturnsFalse_WithUntrustedRoot() { if (string.IsNullOrEmpty(this.clientCertificateWithEuiPath)) { throw new InvalidOperationException("Client certificate was not properly initialized."); } using var cert = new X509Certificate2(this.clientCertificateWithEuiPath); using var chain = X509Chain.Create(); _ = chain.Build(cert); _ = this.stationConfigService.Setup(x => x.GetAllowedClientThumbprintsAsync(It.IsAny <StationEui>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(new[] { cert.Thumbprint })); var result = await this.clientCertValidatorSvc.ValidateAsync(cert, chain, System.Net.Security.SslPolicyErrors.None, default); Assert.False(result); Assert.Contains(this.logger.Invocations, i => i.Arguments.Any(a => a.ToString() !.Contains(X509ChainStatusFlags.UntrustedRoot.ToString(), StringComparison.OrdinalIgnoreCase))); }
public override void Validate(X509Certificate2 cert) { if (check_peer) { X509Store store = new X509Store(); store.Open(OpenFlags.ReadOnly); foreach (X509Certificate2 c in store.Certificates) { if (c.Thumbprint == cert.Thumbprint) { return; } } } if (check_chain) { if (chain == null) { if (use_machine_ctx) { chain = X509Chain.Create(); } else { chain = new X509Chain(); } chain.ChainPolicy = policy; } else { chain.Reset(); } if (chain.Build(cert)) { return; } } throw new ArgumentException("The argument certificate is invalid."); }
private static bool IsModuleSignedOneTry(Module module, OidCollection oidCheckList, out int signedExitCode) { #if DEBUG bool Success = true; #else bool Success = false; #endif signedExitCode = 0; try { using X509Certificate Certificate = GetSignerCertificate(module); if (Certificate == null) { // File is not signed. signedExitCode = -7; return(Success); } using (X509Certificate2 Certificate2 = new X509Certificate2(Certificate)) { using (X509Chain CertificateChain = X509Chain.Create()) { Success = true; CheckCertificateChain(Certificate2, CertificateChain, oidCheckList, X509RevocationFlag.EndCertificateOnly, X509VerificationFlags.IgnoreEndRevocationUnknown, -8, ref Success, ref signedExitCode); CheckCertificateChain(Certificate2, CertificateChain, oidCheckList, X509RevocationFlag.EntireChain, X509VerificationFlags.IgnoreEndRevocationUnknown | X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown, -9, ref Success, ref signedExitCode); } } } catch { signedExitCode = -10; } return(Success); }
static X509Chain smethod_8() { return(X509Chain.Create()); }
/// <summary> /// Signs the PDF-document using the provided parameters. /// </summary> /// <param name="src"> /// The source document. /// </param> /// <param name="destFilename"> /// The destination filename. /// </param> internal static void SignDocumentStream(Stream src, string destFilename, string l_issuerName) { const string l_fieldname = "Signature1"; var l_reason = "Aprovant el document"; var l_location = "Barcelona"; var l_pin = "1234"; var l_signatureVisible = true; var l_x = 5; var l_y = 5; var l_w = 200; var l_h = 200; var l_cert = GetCertificate(l_issuerName); // This is risky business. The private key part of the certificate is protected by a pin-code. // This solution reads the pin-code from web.config and enters it automatically. This circumvention // of the built-in security-layer must be mitigated by thorough security in the infrastructure // where the solution runs. var l_key = GetKey(l_cert, l_pin); // Find the number of pages in the document var l_document = new PdfDocument(new PdfReader(src), new PdfWriter(destFilename + "_temp")); var l_pageCount = l_document.GetNumberOfPages(); l_document.Close(); // Create certificate chain (might add validation) var l_ch = X509Chain.Create(); l_ch.Build(l_cert); // Convert chain to BC classes var l_chain = new X509Certificate[l_ch.ChainElements.Count]; var l_chainElements = new X509ChainElement[l_ch.ChainElements.Count]; l_ch.ChainElements.CopyTo(l_chainElements, 0); for (var l_i = 0; l_i < l_ch.ChainElements.Count; l_i++) { l_chain[l_i] = DotNetUtilities.FromX509Certificate(l_chainElements[l_i].Certificate); } var l_reader = new PdfReader(destFilename + "_temp"); var l_signer = new PdfSigner(l_reader, new FileStream(destFilename, FileMode.OpenOrCreate), false); // Creating the appearance var l_appearance = l_signer.GetSignatureAppearance() .SetReason(l_reason) .SetLocation(l_location) .SetReuseAppearance(false); if (l_signatureVisible) { // Define rectangle for visible signature //var l_rect = new Rectangle(l_x, l_y, l_w, l_h); //l_appearance.SetPageRect(l_rect).SetPageNumber(l_pageCount); //l_appearance.SetLocationCaption("Signatura_Direccio"); } l_signer.SetFieldName("Signatura_Direccio"); // Creating the signature, providing our own implementation of IExternalSignature IExternalSignature l_pks = new TokenSigner(l_key, DigestAlgorithms.SHA256); l_signer.SignDetached(l_pks, l_chain, null, null, null, 0, PdfSigner.CryptoStandard.CADES); }
public static void Create() { using (var chain = X509Chain.Create()) Assert.NotNull(chain); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode VerifyChain( Assembly assembly, X509Certificate2 certificate2, X509VerificationFlags verificationFlags, X509RevocationMode revocationMode, X509RevocationFlag revocationFlag, ref Result error ) { if (certificate2 != null) { try { X509Chain chain = X509Chain.Create(); if (chain != null) { X509ChainPolicy chainPolicy = chain.ChainPolicy; if (chainPolicy != null) { // // NOTE: Setup the chain policy settings as specified // by the caller. // chainPolicy.VerificationFlags = verificationFlags; chainPolicy.RevocationMode = revocationMode; chainPolicy.RevocationFlag = revocationFlag; if (chain.Build(certificate2)) { return(ReturnCode.Ok); } else { StringList list = new StringList(); if (chain.ChainStatus != null) { foreach (X509ChainStatus status in chain.ChainStatus) { list.Add( status.Status.ToString(), status.StatusInformation); } if (assembly != null) { error = String.Format( "assembly {0}: {1}", FormatOps.WrapOrNull(assembly), list.ToString()); } else { error = list; } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid chain status", FormatOps.WrapOrNull(assembly)); } else { error = "invalid chain status"; } } } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid chain policy", FormatOps.WrapOrNull(assembly)); } else { error = "invalid chain policy"; } } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid chain", FormatOps.WrapOrNull(assembly)); } else { error = "invalid chain"; } } } catch (Exception e) { if (assembly != null) { error = String.Format( "assembly {0}: {1}", FormatOps.WrapOrNull(assembly), e); } else { error = e; } } } else { if (assembly != null) { error = String.Format( "assembly {0}: invalid certificate", FormatOps.WrapOrNull(assembly)); } else { error = "invalid certificate"; } } return(ReturnCode.Error); }
public void StaticCreation() { X509Chain c = X509Chain.Create(); CheckDefaultChain(c); }
public SslDiagDialog(IServiceProvider provider, ServerManager server) : base(provider) { InitializeComponent(); // from https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.ikya100/sigalg.htm var wellKnownSignatureAlgorithms = new Dictionary <string, bool> { { "1.2.840.113549.1.1.5", false }, // sha1RSA, not secure { "1.2.840.113549.1.1.14", true }, // sha224RSA, secure { "1.2.840.113549.1.1.11", true }, // sha256RSA, secure { "1.2.840.113549.1.1.12", true }, // sha384RSA, secure { "1.2.840.113549.1.1.13", true }, // sha512RSA, secure { "1.2.840.10040.4.3", false }, // sha1DSA, not secure { "1.2.840.10045.4.1", false }, // sha1ECDSA, not secure { "1.2.840.10045.4.3.1", true }, // sha224ECDSA, secure { "1.2.840.10045.4.3.2", true }, // sha256ECDSA, secure { "1.2.840.10045.4.3.3", true }, // sha384ECDSA, secure { "1.2.840.10045.4.3.4", true }, // sha512ECDSA, secure }; var container = new CompositeDisposable(); FormClosed += (sender, args) => container.Dispose(); container.Add( Observable.FromEventPattern <EventArgs>(btnGenerate, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); try { Warn("IMPORTANT: This report might contain confidential information. Mask such before sharing to others."); Warn("-----"); Debug($"System Time: {DateTime.Now}"); Debug($"Processor Architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}"); Debug($"OS: {Environment.OSVersion}"); Debug($"Server Type: {server.Mode.AsString(EnumFormat.Description)}"); Debug(string.Empty); Debug($"SERVER SSL PROTOCOLS{Environment.NewLine}"); bool ssl10Enabled = GetProtocol("PCT 1.0"); Debug($"PCT 1.0: {ssl10Enabled}"); if (ssl10Enabled) { Warn("PCT 1.0 is not secure. Please disable it."); } bool ssl20Enabled = GetProtocol("SSL 2.0"); Debug($"SSL 2.0: {ssl20Enabled}"); if (ssl20Enabled) { Warn("SSL 2.0 is not secure. Please disable it."); } bool ssl30Enabled = GetProtocol("SSL 3.0"); Debug($"SSL 3.0: {ssl30Enabled}"); if (ssl30Enabled) { Warn("SSL 3.0 is not secure. Please disable it."); } Debug($"TLS 1.0: {GetProtocol("TLS 1.0")}"); Debug($"TLS 1.1: {GetProtocol("TLS 1.1")}"); Debug($"TLS 1.2: {GetProtocol("TLS 1.2")}"); Debug($"SChannel EventLogging: {GetEventLogging()} (hex)"); Warn($"To tune TLS related settings, try out IIS Crypto from https://www.nartac.com/Products/IISCrypto/."); Debug("-----"); foreach (Site site in server.Sites) { Debug($"[W3SVC/{site.Id}]"); Debug($"ServerComment : {site.Name}"); Debug($"ServerAutoStart: {site.ServerAutoStart}"); Debug($"ServerState : {site.State}"); Debug(string.Empty); foreach (Binding binding in site.Bindings) { Info($"BINDING: {binding.Protocol} {binding}"); if (binding.Protocol == "https") { if (binding.CertificateHash == null) { // SNI mapping missing. Debug($"SSL Flags: {binding.SslFlags}"); if (binding.SslFlags == SslFlags.Sni) { Error( $"Cannot find {binding.Host}:{binding.EndPoint.Port} combination for this SNI binding."); } else { var querySslCertificateInfo = Microsoft.Web.Administration.NativeMethods.QuerySslCertificateInfo( binding.EndPoint); Error( querySslCertificateInfo == null ? $"Cannot find {binding.EndPoint} combination for this IP based binding." : $"Cannot find certificate with thumpprint {querySslCertificateInfo.Hash} in store {querySslCertificateInfo.StoreName}."); } Debug(string.Empty); continue; } var hashString = Hex.ToHexString(binding.CertificateHash); Debug($"SSLCertHash: {hashString}"); if (site.Server.SupportsSni) { Debug($"SSL Flags: {binding.SslFlags}"); } Debug("Testing EndPoint: 127.0.0.1"); var personal = new X509Store(binding.CertificateStoreName, StoreLocation.LocalMachine); try { personal.Open(OpenFlags.MaxAllowed); var selectedItem = personal.Certificates.Find(X509FindType.FindByThumbprint, hashString, false); if (selectedItem.Count == 0) { Error($"Cannot find certificate with thumbprint {hashString} in store {binding.CertificateStoreName}."); } else { var cert = selectedItem[0]; Debug($"#CertName: {cert.FriendlyName}"); Debug($"#Version: {cert.Version}"); if (cert.HasPrivateKey) { if (PublicNativeMethods.IsProcessElevated) { var newHandle = IntPtr.Zero; int newCount = 0; var shouldRelease = false; if (NativeMethods.CryptAcquireCertificatePrivateKey( cert.Handle, 0, IntPtr.Zero, ref newHandle, ref newCount, ref shouldRelease)) { Debug( "#You have a private key that corresponds to this certificate."); } else { Error("#You have a private key that corresponds to this certificate but CryptAcquireCertificatePrivateKey failed."); Rollbar.RollbarLocator.RollbarInstance.Error( "CryptAcquireCertificatePrivateKey failed"); } if (shouldRelease) { NativeMethods.CloseHandle(newHandle); } } else { Warn("It seems that you have a private key that corresponds to this certificate. Please run Jexus Manager as administrator and SSL Diag can report in more details."); } } else { Error( "#You don't have a private key that corresponds to this certificate."); } var key = cert.PublicKey.Key; var signatureAlgorithm = cert.SignatureAlgorithm; Debug($"#Signature Algorithm: {signatureAlgorithm.FriendlyName}"); if (wellKnownSignatureAlgorithms.ContainsKey(signatureAlgorithm.Value)) { if (!wellKnownSignatureAlgorithms[signatureAlgorithm.Value]) { Warn("Modern web browsers require signature algorithm to be secure. This signature algorithm is not secure, and might trigger warnings and/or errors."); } } else { Warn("This certificate uses a not-well-known signature algorithm, which might not be supported by all web browsers and servers."); } Debug($"#Key Exchange Algorithm: {key.KeyExchangeAlgorithm} Key Size: {key.KeySize}"); Debug($"#Subject: {cert.Subject}"); Debug($"#Issuer: {cert.Issuer}"); Debug($"#Validity: From {cert.NotBefore:G} To {cert.NotAfter:G}"); var now = DateTime.UtcNow; if (now < cert.NotBefore) { Warn("This certificate is not yet valid."); } if (cert.NotAfter < now) { Error("This certificate is already expired."); } Debug($"#Serial Number: {cert.SerialNumber}"); Debug($"DS Mapper Usage: {(binding.UseDsMapper ? "Enabled" : "Disabled")}"); Debug($"Archived: {cert.Archived}"); var hasSAN = false; foreach (var extension in cert.Extensions) { if (extension.Oid.Value == "2.5.29.15") { Debug($"#Key Usage: {((X509KeyUsageExtension)extension).KeyUsages}"); continue; } if (extension.Oid.Value == "2.5.29.37") { var usages = ((X509EnhancedKeyUsageExtension)extension).EnhancedKeyUsages; var enhancedKeyUsage = usages.Cast <Oid>().Select(usage => $"{usage.FriendlyName} ({usage.Value})") .Combine(","); Debug($"#Enhanced Key Usage: {enhancedKeyUsage}"); continue; } if (extension.Oid.Value == "2.5.29.17") { var name = extension.Format(true).TrimEnd(); Debug($"#Subject Alternative Name: {name}"); hasSAN = true; continue; } if (extension.Oid.FriendlyName == "Basic Constraints") { var ext = (X509BasicConstraintsExtension)extension; Debug( $"#Basic Constraints: Subject Type={(ext.CertificateAuthority ? "CA" : "End Entity")}, Path Length Constraint={(ext.HasPathLengthConstraint ? ext.PathLengthConstraint.ToString() : "None")}"); } } if (!hasSAN) { Warn("Modern web browsers require Subject Alternative Name extension to present. This certificate does not have SAN extension, so might trigger warnings and/or errors."); } X509Chain chain = X509Chain.Create(); chain.ChainPolicy = new X509ChainPolicy { RevocationMode = X509RevocationMode.Online }; bool valid = chain.Build(cert); if (valid) { Debug("Certificate verified."); } else { Error("Certificate validation failed."); } foreach (var item in chain.ChainStatus) { Warn(item.StatusInformation); } } personal.Close(); } catch (CryptographicException ex) { Error($"Problems detected on certificate store {binding.CertificateStoreName}."); if (ex.HResult != Microsoft.Web.Administration.NativeMethods.NonExistingStore) { throw; } Error($"Invalid certificate store {binding.CertificateStoreName}."); } } Debug(string.Empty); } } } catch (CryptographicException ex) { Debug(ex.ToString()); Rollbar.RollbarLocator.RollbarInstance.Error(ex, custom: new Dictionary <string, object> { { "hResult", ex.HResult } }); } catch (Exception ex) { Debug(ex.ToString()); Rollbar.RollbarLocator.RollbarInstance.Error(ex); } })); container.Add( Observable.FromEventPattern <EventArgs>(btnSave, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { var fileName = DialogHelper.ShowSaveFileDialog(null, "Text Files|*.txt|All Files|*.*", null); if (string.IsNullOrEmpty(fileName)) { return; } File.WriteAllText(fileName, txtResult.Text); })); container.Add( Observable.FromEventPattern <EventArgs>(btnVerify, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); })); }
private bool ValidateServerCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (certificate is X509Certificate2 c2) { PeerCertificateReceived?.Invoke(this, new TlsCertificateReceivedEventArgs(c2)); } if (_options.PinnedServerCertificate != null) { var retVal = certificate.Equals(_options.PinnedServerCertificate); if (!retVal) { WriteLog.To.Sync.W(Tag, "Server certificate did not match the pinned one!"); _validationException = new TlsCertificateException("The certificate does not match the pinned certificate", C4NetworkErrorCode.TLSCertUnknownRoot, X509ChainStatusFlags.ExplicitDistrust); } return(retVal); } // Mono doesn't pass chain information? if (chain?.ChainElements?.Count == 0 && certificate is X509Certificate2 cert2) { chain = X509Chain.Create(); chain.Build(cert2); } #if COUCHBASE_ENTERPRISE var onlySelfSigned = _options.AcceptOnlySelfSignedServerCertificate; #else var onlySelfSigned = false; #endif if (!onlySelfSigned && sslPolicyErrors != SslPolicyErrors.None) { WriteLog.To.Sync.W(Tag, $"Error validating TLS chain: {sslPolicyErrors}"); if (chain.ChainElements != null) { foreach (var element in chain.ChainElements) { if (element.ChainElementStatus != null) { foreach (var status in element.ChainElementStatus) { if (status.Status != X509ChainStatusFlags.NoError) { WriteLog.To.Sync.V(Tag, $"Error {status.Status} ({status.StatusInformation}) for certificate:{Environment.NewLine}{element.Certificate}"); if (status.Status == X509ChainStatusFlags.UntrustedRoot) { _validationException = new TlsCertificateException("The certificate does not terminate in a trusted root CA.", C4NetworkErrorCode.TLSCertUnknownRoot, X509ChainStatusFlags.UntrustedRoot); return(false); } } } } } } if (chain.ChainStatus != null) { foreach (var status in chain.ChainStatus) { if (status.Status == X509ChainStatusFlags.PartialChain) { _validationException = new TlsCertificateException("The certificate does not terminate in a trusted root CA.", C4NetworkErrorCode.TLSCertUnknownRoot, X509ChainStatusFlags.PartialChain); return(false); } } } } else if (onlySelfSigned) { if (chain.ChainElements.Count != 1) { _validationException = new TlsCertificateException("A non self-signed certificate was received in self-signed mode.", C4NetworkErrorCode.TLSCertUnknownRoot, X509ChainStatusFlags.ExplicitDistrust); return(false); } if (chain.ChainStatus[0].Status != X509ChainStatusFlags.UntrustedRoot && chain.ChainStatus[0].Status != X509ChainStatusFlags.PartialChain && chain.ChainStatus[0].Status != X509ChainStatusFlags.NoError) { _validationException = new TlsCertificateException("Certificate verification failed", C4NetworkErrorCode.TLSCertUnknownRoot, chain.ChainStatus[0].Status); return(false); } if (chain.ChainElements[0].Certificate.IssuerName.Name != chain.ChainElements[0].Certificate.SubjectName.Name) { _validationException = new TlsCertificateException("A non self-signed certificate was received in self-signed mode.", C4NetworkErrorCode.TLSCertUnknownRoot, X509ChainStatusFlags.ExplicitDistrust); return(false); } return(true); } if (sslPolicyErrors == SslPolicyErrors.None) { return(true); } _validationException = new TlsCertificateException("Certificate verification failed", C4NetworkErrorCode.TLSCertUntrusted, sslPolicyErrors); return(false); }
async Task RequestAsync(int id) { var handler = new HttpClientHandler(); handler.ClientCertificateOptions = ClientCertificateOption.Manual; //handler.SslProtocols = SslProtocols.Tls12; if (!string.IsNullOrEmpty(_configuration["SSLCertThmbprint"])) { //Perfome SSL Pinning. It is required to get SHA1 thumbprint of the SSL Server Certificate //and put it in the appSettings //Maybe the Key Identifier should be used. But the first version we should simply use SHA1 thumbprint. handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, error) => { var fixedSID = _configuration["SSLCertThmbprint"]; var ch = X509Chain.Create(); ch.ChainPolicy = new X509ChainPolicy { RevocationFlag = X509RevocationFlag.EndCertificateOnly, RevocationMode = X509RevocationMode.NoCheck }; //It is required to build the certificate chain upto the TRUSTED ROOT located in //TRUST ROOT Certficate Store if (ch.Build(cert as X509Certificate2)) { foreach (var s in ch.ChainStatus) { if (s.Status != X509ChainStatusFlags.NoError) { return(false); } } } else { return(false); } //And finally compare the thumbprints. var cert2 = cert as X509Certificate2; string sidValue = cert2.Thumbprint.ToLower(); if (string.IsNullOrEmpty(sidValue)) { sidValue = BitConverter.ToString( (new SHA1Managed()).ComputeHash(cert2.GetPublicKey())).Replace("-", string.Empty).ToLower(); } if (string.IsNullOrEmpty(sidValue)) { return(false); } if (sidValue == fixedSID) { return(true); } return(false); }; } //Loading the client certificate to setup SSL Client Authentication. var clientCertFile = _configuration["SSLClientCert"]; var clientCertFilePwd = _configuration["SSLClientCertPwd"]; var clientCert = new X509Certificate2(clientCertFile, clientCertFilePwd); handler.ClientCertificates.Add(clientCert); var client = new HttpClient(handler); var url = _apiUrl + id; var outgoing = new Uri(url); var httpRequest = new HttpRequestMessage(HttpMethod.Get, outgoing); var response = await client.SendAsync(httpRequest).ConfigureAwait(false); _statusCode = response.StatusCode; _rawMessage = await response.Content.ReadAsStringAsync().ConfigureAwait(false); }
public SslDiagDialog(IServiceProvider provider, ServerManager server) : base(provider) { InitializeComponent(); var container = new CompositeDisposable(); FormClosed += (sender, args) => container.Dispose(); container.Add( Observable.FromEventPattern <EventArgs>(btnGenerate, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); try { Debug($"System Time: {DateTime.Now}"); Debug($"Processor Architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}"); Debug($"OS: {Environment.OSVersion}"); Debug($"{server.Type}"); Debug(Environment.NewLine); Debug($"SERVER SSL PROTOCOLS{Environment.NewLine}"); Debug($"PCT 1.0: {GetProtocol("PCT 1.0")}"); Debug($"SSL 2.0: {GetProtocol("SSL 2.0")}"); Debug($"SSL 3.0: {GetProtocol("SSL 3.0")}"); Debug($"TLS 1.0: {GetProtocol("TLS 1.0")}"); Debug($"TLS 1.1: {GetProtocol("TLS 1.1")}"); Debug($"TLS 1.2: {GetProtocol("TLS 1.2")}"); Debug($"SChannel EventLogging: {GetEventLogging()} (hex)"); Debug("-----"); foreach (Site site in server.Sites) { Debug($"[W3SVC/{site.Id}]"); Debug($"ServerComment : {site.Name}"); Debug($"ServerAutoStart: {site.ServerAutoStart}"); Debug($"ServerState : {site.State}"); Debug(string.Empty); foreach (Binding binding in site.Bindings) { Info($"BINDING: {binding.Protocol} {binding}"); if (binding.Protocol == "https") { if (binding.CertificateHash == null) { // SNI mapping missing. Debug($"SSL Flags: {binding.SslFlags}"); if (binding.SslFlags == SslFlags.Sni) { Error( $"Cannot find {binding.Host}:{binding.EndPoint.Port} combination for this binding."); } else { var querySslCertificateInfo = Microsoft.Web.Administration.NativeMethods.QuerySslCertificateInfo( binding.EndPoint); Error( querySslCertificateInfo == null ? $"Cannot find {binding.EndPoint} combination for this binding." : $"Cannot find certificate with thumpprint {querySslCertificateInfo.Hash} in store {querySslCertificateInfo.StoreName}."); } Debug(string.Empty); continue; } var hashString = Hex.ToHexString(binding.CertificateHash); Debug($"SSLCertHash: {hashString}"); if (site.Server.SupportsSni) { Debug($"SSL Flags: {binding.SslFlags}"); } Debug("Testing EndPoint: 127.0.0.1"); var personal = new X509Store(binding.CertificateStoreName, StoreLocation.LocalMachine); try { personal.Open(OpenFlags.MaxAllowed); var selectedItem = personal.Certificates.Find(X509FindType.FindByThumbprint, hashString, false); if (selectedItem.Count == 0) { Error($"Cannot find certificate with thumbprint {hashString} in store {binding.CertificateStoreName}."); } else { var cert = selectedItem[0]; Debug($"#CertName: {cert.FriendlyName}"); Debug($"#Version: {cert.Version}"); if (cert.HasPrivateKey) { var newHandle = IntPtr.Zero; int newCount = 0; var shouldRelease = false; if (NativeMethods.CryptAcquireCertificatePrivateKey( cert.Handle, 0, IntPtr.Zero, ref newHandle, ref newCount, ref shouldRelease)) { Debug( "#You have a private key that corresponds to this certificate."); } else { Error("#You have a private key that corresponds to this certificate but CryptAcquireCertificatePrivateKey failed."); RollbarDotNet.Rollbar.Report( "CryptAcquireCertificatePrivateKey failed"); } if (shouldRelease) { NativeMethods.CloseHandle(newHandle); } } else { Error( "#You don't have a private key that corresponds to this certificate."); } var key = cert.PublicKey.Key; Debug($"#Signature Algorithm: {cert.SignatureAlgorithm.FriendlyName}"); Debug($"#Key Exchange Algorithm: {key.KeyExchangeAlgorithm} Key Size: {key.KeySize}"); Debug($"#Subject: {cert.Subject}"); Debug($"#Issuer: {cert.Issuer}"); Debug($"#Validity: From {cert.NotBefore:G} To {cert.NotAfter:G}"); Debug($"#Serial Number: {cert.SerialNumber}"); Debug($"DS Mapper Usage: {(binding.UseDsMapper ? "Enabled" : "Disabled")}"); Debug($"Archived: {cert.Archived}"); foreach (var extension in cert.Extensions) { if (extension.Oid.FriendlyName == "Key Usage") { Debug($"#Key Usage: {((X509KeyUsageExtension)extension).KeyUsages}"); continue; } if (extension.Oid.FriendlyName == "Enhanced Key Usage") { var usages = ((X509EnhancedKeyUsageExtension)extension).EnhancedKeyUsages; var enhancedKeyUsage = usages.Cast <Oid>().Select(usage => $"{usage.FriendlyName} ({usage.Value})") .Combine(","); Debug($"#Enhanced Key Usage: {enhancedKeyUsage}"); continue; } if (extension.Oid.FriendlyName == "Basic Constraints") { var ext = (X509BasicConstraintsExtension)extension; Debug( $"#Basic Constraints: Subject Type={(ext.CertificateAuthority ? "CA" : "End Entity")}, Path Length Constraint={(ext.HasPathLengthConstraint ? ext.PathLengthConstraint.ToString() : "None")}"); } } X509Chain chain = X509Chain.Create(); chain.ChainPolicy = new X509ChainPolicy { RevocationMode = X509RevocationMode.Online }; bool valid = chain.Build(cert); if (valid) { Debug("Certificate verified."); } else { Error("Certificate validation failed."); } foreach (var item in chain.ChainStatus) { Warn(item.StatusInformation); } } personal.Close(); } catch (CryptographicException ex) { if (ex.HResult != Microsoft.Web.Administration.NativeMethods.NonExistingStore) { throw; } Error($"Invalid certificate store {binding.CertificateStoreName}."); } } Debug(string.Empty); } } } catch (CryptographicException ex) { Debug(ex.ToString()); RollbarDotNet.Rollbar.Report(ex, custom: new Dictionary <string, object> { { "hResult", ex.HResult } }); } catch (Exception ex) { Debug(ex.ToString()); RollbarDotNet.Rollbar.Report(ex); } })); container.Add( Observable.FromEventPattern <EventArgs>(btnSave, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { var fileName = DialogHelper.ShowSaveFileDialog(null, "Text Files|*.txt|All Files|*.*"); if (string.IsNullOrEmpty(fileName)) { return; } File.WriteAllText(fileName, txtResult.Text); })); container.Add( Observable.FromEventPattern <EventArgs>(btnVerify, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); })); }
private void BtnGenerateClick(object sender, System.EventArgs e) { txtResult.Clear(); Debug(string.Format("System Time: {0}", DateTime.Now)); Debug(string.Format("Processor Architecture: {0}", Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE"))); Debug(string.Format("OS: {0}", Environment.OSVersion)); Debug(string.Format("{0}", _server.Type)); Debug(Environment.NewLine); Debug(string.Format("SERVER SSL PROTOCOLS{0}", Environment.NewLine)); Debug(string.Format("PCT 1.0: {0}", GetProtocol("PCT 1.0"))); Debug(string.Format("SSL 2.0: {0}", GetProtocol("SSL 2.0"))); Debug(string.Format("SSL 3.0: {0}", GetProtocol("SSL 3.0"))); Debug(string.Format("TLS 1.0: {0}", GetProtocol("TLS 1.0"))); Debug(string.Format("TLS 1.1: {0}", GetProtocol("TLS 1.1"))); Debug(string.Format("TLS 1.2: {0}", GetProtocol("TLS 1.2"))); Debug(string.Format("SChannel EventLogging: {0} (hex)", GetEventLogging())); Debug("-----"); foreach (Site site in _server.Sites) { Debug(string.Format("[W3SVC/{0}]", site.Id)); Debug(string.Format("ServerComment : {0}", site.Name)); Debug(string.Format("ServerAutoStart: {0}", site.ServerAutoStart)); Debug(string.Format("ServerState : {0}", site.State)); Debug(string.Empty); foreach (Binding binding in site.Bindings) { Info(string.Format("BINDING: {0} {1}", binding.Protocol, binding)); if (binding.Protocol == "https") { var hashString = Hex.ToHexString(binding.CertificateHash); Debug(string.Format("SSLCertHash: {0}", hashString)); Debug(string.Format("SSL Flags: {0}", binding.SslFlags)); Debug("Testing EndPoint: 127.0.0.1"); var personal = new X509Store(binding.CertificateStoreName, StoreLocation.LocalMachine); personal.Open(OpenFlags.MaxAllowed); var selectedItem = personal.Certificates.Find(X509FindType.FindByThumbprint, hashString, false); var cert = selectedItem[0]; Debug(string.Format("#CertName: {0}", cert.FriendlyName)); Debug(string.Format("#Version: {0}", cert.Version)); if (cert.HasPrivateKey) { Debug("#You have a private key that corresponds to this certificate."); } else { Error("#You don't have a private key that corresponds to this certificate."); } var key = cert.PublicKey.Key; Debug(string.Format("#Signature Algorithm: {0}", cert.SignatureAlgorithm.FriendlyName)); Debug(string.Format("#Key Exchange Algorithm: {0} Key Size: {1}", key.KeyExchangeAlgorithm, key.KeySize)); Debug(string.Format("#Subject: {0}", cert.Subject)); Debug(string.Format("#Issuer: {0}", cert.Issuer)); Debug(string.Format("#Validity: From {0} To {1}", cert.NotBefore.ToString("U"), cert.NotAfter.ToString("U"))); Debug(string.Format("#Serial Number: {0}", cert.SerialNumber)); Debug(string.Format("DS Mapper Usage: {0}", binding.UseDsMapper ? "Enabled" : "Disabled")); Debug(string.Format("Archived: {0}", cert.Archived)); foreach (var extension in cert.Extensions) { if (extension.Oid.FriendlyName == "Key Usage") { Debug(string.Format("#Key Usage: {0}", ((X509KeyUsageExtension)extension).KeyUsages)); continue; } if (extension.Oid.FriendlyName == "Enhanced Key Usage") { var enhancedKeyUsage = new StringBuilder(); var usages = ((X509EnhancedKeyUsageExtension)extension).EnhancedKeyUsages; foreach (var usage in usages) { enhancedKeyUsage.AppendFormat("{0} ({1}), ", usage.FriendlyName, usage.Value); } if (enhancedKeyUsage.Length > 0) { enhancedKeyUsage.Length -= 2; } Debug(string.Format("#Enhanced Key Usage: {0}", enhancedKeyUsage)); continue; } if (extension.Oid.FriendlyName == "Basic Constraints") { var ext = (X509BasicConstraintsExtension)extension; Debug( string.Format( "#Basic Constraints: Subject Type={0}, Path Length Constraint={1}", ext.CertificateAuthority ? "CA" : "End Entity", ext.HasPathLengthConstraint ? ext.PathLengthConstraint.ToString() : "None")); continue; } } X509Chain chain = X509Chain.Create(); X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationMode = X509RevocationMode.NoCheck; chain.ChainPolicy = policy; bool valid = chain.Build(cert); if (valid) { Debug("Certificate verified."); } else { Error("Certificate valication failed."); } foreach (var item in chain.ChainStatus) { Warn(item.StatusInformation); } personal.Close(); } Debug(string.Empty); } } }