public PeerOrChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy) { _chain = X509CertificateValidator.CreateChainTrustValidator(useMachineContext, chainPolicy); _peer = (PeerTrustValidator)X509CertificateValidator.PeerTrust; }
internal X509ChainImplBtls(MonoBtlsX509Chain chain) { this.chain = chain.Copy(); policy = new X509ChainPolicy(); }
public ChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy, uint chainPolicyOID) { _useMachineContext = useMachineContext; _chainPolicy = chainPolicy; _chainPolicyOID = chainPolicyOID; }
/// <summary> /// Throws an exception if validation fails. /// </summary> /// <param name="certificate">The certificate to be checked.</param> /// <exception cref="ServiceResultException">If certificate cannot be accepted</exception> protected virtual void InternalValidate(X509Certificate2 certificate) { lock (m_lock) { // check for previously validated certificate. X509Certificate2 certificate2 = null; if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2)) { if (Utils.IsEqual(certificate2.RawData, certificate.RawData)) { return; } } CertificateIdentifier trustedCertificate = GetTrustedCertificate(certificate); // get the issuers (checks the revocation lists if using directory stores). List <CertificateIdentifier> issuers = new List <CertificateIdentifier>(); bool isIssuerTrusted = GetIssuers(certificate, issuers); // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.NoCheck; policy.VerificationFlags = X509VerificationFlags.NoFlag; foreach (CertificateIdentifier issuer in issuers) { if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0) { policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; } // we did the revocation check in the GetIssuers call. No need here. policy.RevocationMode = X509RevocationMode.NoCheck; policy.ExtraStore.Add(issuer.Certificate); } // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); // check the chain results. CertificateIdentifier target = trustedCertificate; if (target == null) { target = new CertificateIdentifier(certificate); } for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; CertificateIdentifier issuer = null; if (ii < issuers.Count) { issuer = issuers[ii]; } // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0)); if (ServiceResult.IsBad(result)) { throw new ServiceResultException(result); } } if (issuer != null) { target = issuer; } } // check if certificate is trusted. if (trustedCertificate == null && !isIssuerTrusted) { if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData)) { throw ServiceResultException.Create( StatusCodes.BadCertificateUntrusted, "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } } } }
public X509Chain(bool useMachineContext) { location = useMachineContext ? StoreLocation.LocalMachine : StoreLocation.CurrentUser; elements = new X509ChainElementCollection(); policy = new X509ChainPolicy(); }
public static void DefaultCtorState() { X509ChainPolicy policy = new X509ChainPolicy(); AssertDefaultState(policy); }
public static X509CertificateValidator CreateChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy) { if (chainPolicy == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("chainPolicy"); } return(new ChainTrustValidator(useMachineContext, chainPolicy, X509CertificateChain.DefaultChainPolicyOID)); }
public X509CertificateValidatorImpl(bool peer, bool chain, bool useMachineContext, X509ChainPolicy chainPolicy) { this.check_peer = peer; this.check_chain = chain; use_machine_ctx = useMachineContext; policy = chainPolicy; }
/// <summary> /// This is the verify certificate callback method used when initially binding to the /// LDAP server. This manages all certificate validation. /// </summary> /// <param name="conn">The LDAP connection.</param> /// <param name="cert">The server's certificate</param> /// <returns>true if verification succeeds, false otherwise.</returns> private bool VerifyCert(LdapConnection conn, X509Certificate cert) { m_logger.Debug("VerifyCert(...)"); m_logger.DebugFormat("Verifying certificate from host: {0}", conn.SessionOptions.HostName); // Convert to X509Certificate2 X509Certificate2 serverCert = new X509Certificate2(cert); // If we don't need to verify the cert, the verification succeeds if (!m_verifyCert) { m_logger.Debug("Server certificate accepted without verification."); return(true); } // If the certificate is null, then we verify against the machine's/user's certificate store if (m_cert == null) { m_logger.Debug("Verifying server cert with Windows store."); // We set the RevocationMode to NoCheck because most custom (self-generated) CAs // do not work properly with revocation lists. This is slightly less secure, but // the most common use case for this plugin probably doesn't rely on revocation // lists. X509ChainPolicy policy = new X509ChainPolicy() { RevocationMode = X509RevocationMode.NoCheck }; // Create a validator using the policy X509CertificateValidator validator = X509CertificateValidator.CreatePeerOrChainTrustValidator(false, policy); try { validator.Validate(serverCert); // If we get here, validation succeeded. m_logger.Debug("Server certificate verification succeeded."); return(true); } catch (SecurityTokenValidationException e) { m_logger.ErrorFormat("Server certificate validation failed: {0}", e.Message); return(false); } } else { m_logger.Debug("Validating server certificate with provided certificate."); // Verify against the provided cert by comparing the thumbprint bool result = m_cert.Thumbprint == serverCert.Thumbprint; if (result) { m_logger.Debug("Server certificate validated."); } else { m_logger.Debug("Server certificate validation failed."); } return(result); } }
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") { 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) { 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($"#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:U} To {cert.NotAfter:U}"); 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(); 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(); } catch (CryptographicException ex) { if (ex.HResult != 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 dialog = new SaveFileDialog { Filter = "Text Files|*.txt|All Files|*.*" }; if (dialog.ShowDialog() == DialogResult.Cancel) { return; } File.WriteAllText(dialog.FileName, txtResult.Text); })); container.Add( Observable.FromEventPattern <EventArgs>(btnVerify, "Click") .ObserveOn(System.Threading.SynchronizationContext.Current) .Subscribe(evt => { txtResult.Clear(); })); }
public static X509CertificateValidator CreatePeerOrChainTrustValidator( bool useMachineContext, X509ChainPolicy chainPolicy) { return(new X509CertificateValidatorImpl( true, true, useMachineContext, chainPolicy)); }
public ChainTrustValidator() { this.chainPolicy = null; }
public static X509CertificateValidator CreatePeerOrChainTrustValidator(bool useMachineContext, X509ChainPolicy chainPolicy) { if (chainPolicy == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(chainPolicy)); } return(new PeerOrChainTrustValidator(useMachineContext, chainPolicy)); }
internal X509ChainImplBtls() { chain = new MonoBtlsX509Chain(); elements = new X509ChainElementCollection(); policy = new X509ChainPolicy(); }
/// <summary> /// Creates an instance, specifying chain policy and problem flags /// </summary> /// <param name="policy">The <see cref="X509ChainPolicy"/> to use for validating trust chains</param> /// <param name="problemFlags">The status flags that will be treated as invalid in trust verification</param> public TrustChainValidator(X509ChainPolicy policy, X509ChainStatusFlags problemFlags) { m_policy = policy; m_problemFlags = problemFlags; }
public void RevocationFlag_Invalid() { X509ChainPolicy cp = GetPolicy(); cp.RevocationFlag = (X509RevocationFlag)Int32.MinValue; }
public bool AsExpected(JwtSecurityTokenRequirement requirement) { bool asExpected = true; JwtSecurityTokenRequirement controlRequirement = new JwtSecurityTokenRequirement(); if (requirement == null) { return(false); } Assert.IsFalse( MaxTokenSizeInBytes != null && MaxTokenSizeInBytes.Value != requirement.MaximumTokenSizeInBytes, string.Format(CultureInfo.InvariantCulture, "MaximumTokenSizeInBytes (expected, config): '{0}'. '{1}'.", MaxTokenSizeInBytes.ToString(), requirement.MaximumTokenSizeInBytes.ToString())); Assert.IsFalse( MaxTokenSizeInBytes == null && requirement.MaximumTokenSizeInBytes != controlRequirement.MaximumTokenSizeInBytes, string.Format(CultureInfo.InvariantCulture, "MaximumTokenSizeInBytes should be default (default, config): '{0}'. '{1}'.", controlRequirement.MaximumTokenSizeInBytes.ToString(), requirement.MaximumTokenSizeInBytes.ToString())); Assert.IsFalse( ClockSkewInSeconds != null && ClockSkewInSeconds.Value != requirement.ClockSkewInSeconds, string.Format(CultureInfo.InvariantCulture, "ClockSkew (expected, config): '{0}'. '{1}'.", ClockSkewInSeconds.ToString(), requirement.ClockSkewInSeconds.ToString())); Assert.IsFalse( ClockSkewInSeconds == null && requirement.ClockSkewInSeconds != controlRequirement.ClockSkewInSeconds, string.Format(CultureInfo.InvariantCulture, "ClockSkew should be default (default, config): '{0}'. '{1}'.", controlRequirement.ClockSkewInSeconds.ToString(), requirement.ClockSkewInSeconds.ToString())); Assert.IsFalse( DefaultTokenLifetimeInMinutes != null && DefaultTokenLifetimeInMinutes.Value != requirement.DefaultTokenLifetimeInMinutes, string.Format(CultureInfo.InvariantCulture, "DefaultTokenLifetimeInMinutes (expected, config): '{0}'. '{1}'.", DefaultTokenLifetimeInMinutes.ToString(), requirement.DefaultTokenLifetimeInMinutes.ToString())); Assert.IsFalse( DefaultTokenLifetimeInMinutes == null && requirement.DefaultTokenLifetimeInMinutes != controlRequirement.DefaultTokenLifetimeInMinutes, string.Format(CultureInfo.InvariantCulture, "DefaultTokenLifetimeInMinutes should be default (default, config): '{0}'. '{1}'.", controlRequirement.DefaultTokenLifetimeInMinutes.ToString(), requirement.DefaultTokenLifetimeInMinutes.ToString())); // make sure nameclaim and roleclaim are same, or null together. Assert.IsFalse(NameClaimType == null && requirement.NameClaimType != null, "NameClaimType == null && requirement.NameClaimType != null"); Assert.IsFalse(NameClaimType != null && requirement.NameClaimType == null, "NameClaimType != null && requirement.NameClaimType == null"); if ((NameClaimType != null && requirement.NameClaimType != null) && (NameClaimType != requirement.NameClaimType)) { Assert.Fail(string.Format(CultureInfo.InvariantCulture, "NameClaimType (expected, config): '{0}'. '{1}'.", NameClaimType, requirement.NameClaimType)); asExpected = false; } Assert.IsFalse(RoleClaimType == null && requirement.RoleClaimType != null, "RoleClaimType == null && requirement.RoleClaimType != null"); Assert.IsFalse(RoleClaimType != null && requirement.RoleClaimType == null, "RoleClaimType != null && requirement.RoleClaimType == null"); if ((RoleClaimType != null && requirement.RoleClaimType != null) && (RoleClaimType != requirement.RoleClaimType)) { Assert.Fail(string.Format(CultureInfo.InvariantCulture, "RoleClaimType (expected, config): '{0}'. '{1}'.", RoleClaimType, requirement.RoleClaimType)); asExpected = false; } // != null => this variation sets a custom validator. if (CertValidator != null) { if (requirement.CertificateValidator == null) { return(false); } Assert.IsFalse(CertValidator.GetType() != requirement.CertificateValidator.GetType(), string.Format("CertificateValidator.GetType() != requirement.CertificateValidator.GetType(). (expected, config): '{0}'. '{1}'.", CertValidator.GetType(), requirement.CertificateValidator.GetType())); } else { if (CertValidationMode.HasValue || CertRevocationMode.HasValue || CertStoreLocation.HasValue) { Assert.IsFalse(requirement.CertificateValidator == null, string.Format("X509CertificateValidationMode.HasValue || X09RevocationMode.HasValue || StoreLocation.HasValue is true, there should be a validator")); // get and check _certificateValidationMode Type type = requirement.CertificateValidator.GetType(); FieldInfo fi = type.GetField("validator", BindingFlags.NonPublic | BindingFlags.Instance); X509CertificateValidator validator = (X509CertificateValidator)fi.GetValue(requirement.CertificateValidator); // make sure we created the right validator if (CertValidationMode == CertMode.ChainTrust && (validator.GetType() != X509CertificateValidator.ChainTrust.GetType()) || CertValidationMode == CertMode.PeerTrust && (validator.GetType() != X509CertificateValidator.PeerTrust.GetType()) || CertValidationMode == CertMode.PeerOrChainTrust && (validator.GetType() != X509CertificateValidator.PeerOrChainTrust.GetType()) || CertValidationMode == CertMode.None && (validator.GetType() != X509CertificateValidator.None.GetType())) { Assert.Fail(string.Format(CultureInfo.InvariantCulture, "X509CertificateValidator type. expected: '{0}', actual: '{1}'", CertValidationMode.HasValue ? CertValidationMode.Value.ToString() : "null", validator.GetType().ToString())); asExpected = false; } // if these 'Modes' HasValue, then it should be matched, otherwise expect default. fi = type.GetField("certificateValidationMode", BindingFlags.NonPublic | BindingFlags.Instance); CertMode certMode = (CertMode)fi.GetValue(requirement.CertificateValidator); if (CertValidationMode.HasValue) { Assert.IsFalse(CertValidationMode.Value != certMode, string.Format(CultureInfo.InvariantCulture, "X509CertificateValidationMode. expected: '{0}', actual: '{1}'", CertValidationMode.Value.ToString(), certMode.ToString())); // if mode includes chain building, revocation mode Policy s/b null. if (CertValidationMode.Value == X509CertificateValidationMode.ChainTrust || CertValidationMode.Value == X509CertificateValidationMode.PeerOrChainTrust) { // check inner policy if (CertRevocationMode.HasValue) { fi = type.GetField("chainPolicy", BindingFlags.NonPublic | BindingFlags.Instance); X509ChainPolicy chainPolicy = (X509ChainPolicy)fi.GetValue(requirement.CertificateValidator); Assert.IsFalse( chainPolicy.RevocationMode != CertRevocationMode.Value, string.Format( CultureInfo.InvariantCulture, "chainPolicy.RevocationMode. . expected: '{0}', actual: '{1}'", CertRevocationMode.Value.ToString(), chainPolicy.RevocationMode.ToString())); } } } } } return(asExpected); }
public void RevocationMode_Invalid() { X509ChainPolicy cp = GetPolicy(); cp.RevocationMode = (X509RevocationMode)Int32.MinValue; }
private void OkBTN_Click(object sender, EventArgs e) { try { IPAddress address = IPAddress.Parse(IPAddressTB.Text); ushort port = (ushort)PortUD.Value; if (m_certificate == null) { throw new ArgumentException("You must specify a certificate."); } X509Certificate2 certificate = m_certificate.Find(true); if (certificate == null) { throw new ArgumentException("Certificate does not exist or has no private key."); } // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.Offline; policy.VerificationFlags = X509VerificationFlags.NoFlag; policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { if (status.Status == X509ChainStatusFlags.UntrustedRoot) { if (!Ask("Cannot verify certificate up to a trusted root.\r\nAdd anyways?")) { return; } continue; } if (status.Status == X509ChainStatusFlags.RevocationStatusUnknown) { if (!Ask("The revocation status of this certificate cannot be verified.\r\nAdd anyways?")) { return; } continue; } // ignore informational messages. if (status.Status == X509ChainStatusFlags.OfflineRevocation) { continue; } if (status.Status != X509ChainStatusFlags.NoError) { throw new ArgumentException("[" + status.Status + "] " + status.StatusInformation); } } } // get the target store. if (m_store == null) { m_store = new CertificateStoreIdentifier(); m_store.StoreType = CertificateStoreType.Windows; m_store.StorePath = CertificateStoreTB.Text; } if (m_store.StoreType != CertificateStoreType.Windows) { throw new ArgumentException("You must choose a Windows store for SSL certificates."); } if (!m_store.StorePath.StartsWith("LocalMachine\\", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException("You must choose a machine store for SSL certificates."); } bool deleteExisting = false; using (ICertificateStore store = m_store.OpenStore()) { if (store.FindByThumbprint(certificate.Thumbprint) == null) { store.Add(certificate); deleteExisting = true; } } if (deleteExisting) { if (Ask("Would you like to delete the certificate from its current location?")) { using (ICertificateStore store = m_certificate.OpenStore()) { store.Delete(certificate.Thumbprint); } } } SslCertificateBinding binding = new SslCertificateBinding(); binding.IPAddress = address; binding.Port = port; binding.Thumbprint = certificate.Thumbprint; binding.ApplicationId = s_DefaultApplicationId; binding.StoreName = null; if (!m_store.StorePath.EndsWith("\\My")) { int index = m_store.StorePath.LastIndexOf("\\"); binding.StoreName = m_store.StorePath.Substring(index + 1); } HttpAccessRule.SetSslCertificateBinding(binding); m_binding = binding; DialogResult = DialogResult.OK; } catch (Exception exception) { GuiUtils.HandleException(this.Text, MethodBase.GetCurrentMethod(), exception); } }
public void VerificationFlags_Invalid() { X509ChainPolicy cp = GetPolicy(); cp.VerificationFlags = (X509VerificationFlags)Int32.MinValue; }
public ChainTrustValidator() { _chainPolicy = null; }
public void Load(object sender, RoutedEventArgs routedEventArgs) { Hide(); var t = new Thread(async() => { // Get add-in pipeline folder (the folder in which this application was launched from) var appPath = Path.Combine(Environment.CurrentDirectory, "core"); using (var client = new WebClient()) { //This handles the IcyWind.Core verification process. if (!Directory.Exists(Path.Combine(Environment.CurrentDirectory, "Certificates"))) { Directory.CreateDirectory(Path.Combine(Environment.CurrentDirectory, "Certificates")); } else if (File.Exists( Path.Combine(Environment.CurrentDirectory, "Certificates", "IcyWindRootCA.cer"))) { File.Delete(Path.Combine(Environment.CurrentDirectory, "Certificates", "IcyWindRootCA.cer")); } //Download the RootCert from the CDN client.DownloadFile("https://cdn.icywindclient.com/IcyWindRootCA.cer", Path.Combine(Environment.CurrentDirectory, "Certificates", "IcyWindRootCA.cer")); //This handles updates and installs. Right now only installs var latest = client.DownloadString("https://cdn.icywindclient.com/latest.txt"); var json = JsonConvert.DeserializeObject <IcyWindVersionJson>(latest); if (!Directory.Exists(appPath)) { //Load the installer InstallWindow install = null; await Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)(() => { install = new InstallWindow(this); install.Show(); })); if (install != null) { var tr = await install.Load(json, true); } } } //This verifies the certificate that was downloaded. It should not be installed into the //user's certificate store for security reasons (It is a root CA) var root = new X509Certificate2(Path.Combine(Environment.CurrentDirectory, "Certificates", "IcyWindRootCA.cer")); var chain = new X509Chain(); var chainPolicy = new X509ChainPolicy { RevocationMode = X509RevocationMode.Offline, RevocationFlag = X509RevocationFlag.EntireChain, }; chain.ChainPolicy = chainPolicy; var cert = GetAppCertificate(Path.Combine(appPath, "AddIns", "IcyWind.Core", "IcyWind.Core.dll")); if (cert != null) { chain.ChainPolicy.ExtraStore.Add(cert); } else { ShowUnsignedCore(); } if (!chain.Build(root)) { //TODO: FIGURE OUT HOW THE F**K TO DO THIS BECAUSE I'M ALMOST ABOUT TO PUT MY OWN CERT IN var data = JsonConvert.SerializeObject(chain.ChainStatus); ShowUnsignedCore(); } await Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)Show); // Rebuild visual add-in pipeline var warnings = AddInStore.Rebuild(appPath); if (warnings.Length > 0) { var msg = warnings.Aggregate(LanguageHelper.ShortNameToString("PipelineRebuildFail"), (current, warning) => current + "\n" + warning); Log.Error("Pipeline rebuild failed. Stopping program"); MessageBox.Show(msg); Environment.Exit(5); } //Load the IcyWind.Core add-in var addInTokens = AddInStore.FindAddIn(typeof(IMainHostView), appPath, Path.Combine(appPath, "AddIns", "IcyWind.Core", "IcyWind.Core.dll"), "IcyWind.Core.IcyWind"); //Prevent other add-ins from being loaded and block start if add-ins are in wrong place if (addInTokens.Count > 1) { MessageBox.Show(LanguageHelper.ShortNameToString("MoreOneCore"), "IcyWind Error", MessageBoxButton.OK, MessageBoxImage.Error); Log.Fatal("More than one IcyWind Core installed."); Environment.Exit(1); } else { var dirs = Directory.GetFiles(Path.Combine(appPath, "AddIns")); if (dirs.Length > 1) { MessageBox.Show(LanguageHelper.ShortNameToString("PluginWrongLocation")); Log.Warn("Plugin installed in wrong location."); Environment.Exit(1); } } //Get the add-in var mainPage = addInTokens.First(); //Give the add-in full trust to the system mainHostView = mainPage.Activate <IMainHostView>(AddInSecurityLevel.FullTrust); await Dispatcher.BeginInvoke(DispatcherPriority.Render, (Action)(() => { var hwd = new System.Windows.Interop.WindowInteropHelper(this).Handle; var addInUi = mainHostView.Run("English", Assembly.GetEntryAssembly().Location, hwd); //AddInController controller = AddInController.GetAddInController(addInUi); MainContent.Content = addInUi; })); }); t.Start(); }
/// <summary> /// Throws an exception if validation fails. /// </summary> /// <param name="certificates">The certificates to be checked.</param> /// <exception cref="ServiceResultException">If certificate[0] cannot be accepted</exception> protected virtual async Task InternalValidate(X509Certificate2Collection certificates) { X509Certificate2 certificate = certificates[0]; // check for previously validated certificate. X509Certificate2 certificate2 = null; if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2)) { if (Utils.IsEqual(certificate2.RawData, certificate.RawData)) { return; } } CertificateIdentifier trustedCertificate = await GetTrustedCertificate(certificate); // get the issuers (checks the revocation lists if using directory stores). List <CertificateIdentifier> issuers = new List <CertificateIdentifier>(); bool isIssuerTrusted = await GetIssuers(certificates, issuers); // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.NoCheck; policy.VerificationFlags = X509VerificationFlags.NoFlag; foreach (CertificateIdentifier issuer in issuers) { if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0) { policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; } // we did the revocation check in the GetIssuers call. No need here. policy.RevocationMode = X509RevocationMode.NoCheck; policy.ExtraStore.Add(issuer.Certificate); } // build chain. bool chainStatusChecked = false; X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); // check the chain results. CertificateIdentifier target = trustedCertificate; if (target == null) { target = new CertificateIdentifier(certificate); } for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; CertificateIdentifier issuer = null; if (ii < issuers.Count) { issuer = issuers[ii]; } // check for chain status errors. if (element.ChainElementStatus.Length > 0) { foreach (X509ChainStatus status in element.ChainElementStatus) { ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0)); if (ServiceResult.IsBad(result)) { // check untrusted certificates. if (trustedCertificate == null) { ServiceResult errorResult = new ServiceResult( result.StatusCode, result.SymbolicId, result.NamespaceUri, result.LocalizedText, result.AdditionalInfo, StatusCodes.BadCertificateUntrusted); throw new ServiceResultException(errorResult); } throw new ServiceResultException(result); } chainStatusChecked = true; } } else { chainStatusChecked = true; } if (issuer != null) { target = issuer; } } // check whether the chain is complete (if there is a chain) bool issuedByCA = !X509Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer); bool chainIncomplete = false; if (issuers.Count > 0) { var rootCertificate = issuers[issuers.Count - 1].Certificate; if (!X509Utils.CompareDistinguishedName(rootCertificate.Subject, rootCertificate.Issuer)) { chainIncomplete = true; } } else { if (issuedByCA) { // no issuer found at all chainIncomplete = true; } } if (issuedByCA && (!chainStatusChecked || chainIncomplete)) { throw ServiceResultException.Create( StatusCodes.BadCertificateChainIncomplete, "Certificate chain validation incomplete.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } // check if certificate issuer is trusted. if (issuedByCA && !isIssuerTrusted && trustedCertificate == null) { if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData)) { throw ServiceResultException.Create( StatusCodes.BadCertificateUntrusted, "Certificate issuer is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } } // check if certificate is trusted. if (trustedCertificate == null && !isIssuerTrusted) { if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData)) { throw ServiceResultException.Create( StatusCodes.BadCertificateUntrusted, "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } } // check if certificate is valid for use as app/sw or user cert X509KeyUsageFlags certificateKeyUsage = X509Utils.GetKeyUsage(certificate); if ((certificateKeyUsage & X509KeyUsageFlags.DataEncipherment) == 0) { throw new ServiceResultException(StatusCodes.BadCertificateUseNotAllowed, "Usage of certificate is not allowed."); } // check if minimum requirements are met if (m_rejectSHA1SignedCertificates && IsSHA1SignatureAlgorithm(certificate.SignatureAlgorithm)) { throw new ServiceResultException(StatusCodes.BadCertificatePolicyCheckFailed, "SHA1 signed certificates are not trusted"); } int keySize = X509Utils.GetRSAPublicKeySize(certificate); if (keySize < m_minimumCertificateKeySize) { throw new ServiceResultException(StatusCodes.BadCertificatePolicyCheckFailed, "Certificate doesn't meet minimum key length requirement"); } }
/// <summary> /// Throws an exception if validation fails. /// </summary> /// <param name="certificates">The certificates to be checked.</param> /// <exception cref="ServiceResultException">If certificate[0] cannot be accepted</exception> protected virtual async Task InternalValidate(X509Certificate2Collection certificates) { X509Certificate2 certificate = certificates[0]; // check for previously validated certificate. X509Certificate2 certificate2 = null; if (m_validatedCertificates.TryGetValue(certificate.Thumbprint, out certificate2)) { if (Utils.IsEqual(certificate2.RawData, certificate.RawData)) { return; } } // check if minimum requirements are met if (m_rejectSHA1SignedCertificates && IsSHA1SignatureAlgorithm(certificate.SignatureAlgorithm)) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "SHA1 signed certificates are not trusted"); } if (certificate.GetRSAPublicKey().KeySize < m_minimumCertificateKeySize) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed, "Certificate doesn't meet minimum key length requirement"); } CertificateIdentifier trustedCertificate = await GetTrustedCertificate(certificate); // get the issuers (checks the revocation lists if using directory stores). List <CertificateIdentifier> issuers = new List <CertificateIdentifier>(); bool isIssuerTrusted = await GetIssuers(certificates, issuers); // setup policy chain X509ChainPolicy policy = new X509ChainPolicy(); policy.RevocationFlag = X509RevocationFlag.EntireChain; policy.RevocationMode = X509RevocationMode.NoCheck; policy.VerificationFlags = X509VerificationFlags.NoFlag; foreach (CertificateIdentifier issuer in issuers) { if ((issuer.ValidationOptions & CertificateValidationOptions.SuppressRevocationStatusUnknown) != 0) { policy.VerificationFlags |= X509VerificationFlags.IgnoreCertificateAuthorityRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreCtlSignerRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreEndRevocationUnknown; policy.VerificationFlags |= X509VerificationFlags.IgnoreRootRevocationUnknown; } // we did the revocation check in the GetIssuers call. No need here. policy.RevocationMode = X509RevocationMode.NoCheck; policy.ExtraStore.Add(issuer.Certificate); } // build chain. X509Chain chain = new X509Chain(); chain.ChainPolicy = policy; chain.Build(certificate); // check the chain results. CertificateIdentifier target = trustedCertificate; if (target == null) { target = new CertificateIdentifier(certificate); } for (int ii = 0; ii < chain.ChainElements.Count; ii++) { X509ChainElement element = chain.ChainElements[ii]; CertificateIdentifier issuer = null; if (ii < issuers.Count) { issuer = issuers[ii]; } // check for chain status errors. foreach (X509ChainStatus status in element.ChainElementStatus) { ServiceResult result = CheckChainStatus(status, target, issuer, (ii != 0)); if (ServiceResult.IsBad(result)) { // check untrusted certificates. if (trustedCertificate == null) { throw new ServiceResultException(StatusCodes.BadSecurityChecksFailed); } throw new ServiceResultException(result); } } if (issuer != null) { target = issuer; } } bool issuedByCA = !Utils.CompareDistinguishedName(certificate.Subject, certificate.Issuer); // check if certificate issuer is trusted. if (issuedByCA && !isIssuerTrusted) { if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData)) { throw ServiceResultException.Create( StatusCodes.BadCertificateUntrusted, "Certificate issuer is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } } // check if certificate is trusted. if (trustedCertificate == null && !isIssuerTrusted) { if (m_applicationCertificate == null || !Utils.IsEqual(m_applicationCertificate.RawData, certificate.RawData)) { throw ServiceResultException.Create( StatusCodes.BadCertificateUntrusted, "Certificate is not trusted.\r\nSubjectName: {0}\r\nIssuerName: {1}", certificate.SubjectName.Name, certificate.IssuerName.Name); } } }
public X509Chain (bool useMachineContext) { _machineContext = useMachineContext; _elements = new X509ChainElementCollection (); _policy = new X509ChainPolicy (); }
/////////////////////////////////////////////////////////////////////// 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); }