Пример #1
0
        private static uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA cpp)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("SecureChannel::VerifyChainPolicy", "chainContext=" + chainContext + ", options=" + String.Format("0x{0:x}", cpp.dwFlags));
            }

            var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();

            status.cbSize = (uint)Marshal.SizeOf <Interop.Crypt32.CERT_CHAIN_POLICY_STATUS>();

            bool errorCode =
                Interop.Crypt32.CertVerifyCertificateChainPolicy(
                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                    chainContext,
                    ref cpp,
                    ref status);

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print("SecureChannel::VerifyChainPolicy() CertVerifyCertificateChainPolicy returned: " + errorCode);
#if TRACE_VERBOSE
                GlobalLog.Print("SecureChannel::VerifyChainPolicy() error code: " + status.dwError + String.Format(" [0x{0:x8}", status.dwError) + " " + Interop.MapSecurityStatus(status.dwError) + "]");
#endif
                GlobalLog.Leave("SecureChannel::VerifyChainPolicy", status.dwError.ToString());
            }

            return(status.dwError);
        }
Пример #2
0
        private static unsafe uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA cpp)
        {
            Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default;
            status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);

            bool errorCode =
                Interop.Crypt32.CertVerifyCertificateChainPolicy(
                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                    chainContext,
                    ref cpp,
                    ref status);

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Info(chainContext, $"CertVerifyCertificateChainPolicy returned: {errorCode}. Status: {status.dwError}");
            }
            return(status.dwError);
        }
Пример #3
0
        /// <summary>
        /// Does not throw on api error. Returns default(bool?) and sets "exception" instead.
        /// </summary>
        public bool?Verify(X509VerificationFlags flags, out Exception?exception)
        {
            exception = null;

            unsafe
            {
                Interop.Crypt32.CERT_CHAIN_POLICY_PARA para = default;
                para.cbSize  = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_PARA);
                para.dwFlags = (uint)flags;

                Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default;
                status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);

                if (!Interop.crypt32.CertVerifyCertificateChainPolicy(ChainPolicy.CERT_CHAIN_POLICY_BASE, _chain, ref para, ref status))
                {
                    int errorCode = Marshal.GetLastPInvokeError();
                    exception = errorCode.ToCryptographicException();
                    return(default(bool?));
                }
                return(status.dwError == 0);
            }
        }
Пример #4
0
        private static uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA cpp)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(chainContext, cpp.dwFlags);
            }

            var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();

            status.cbSize = (uint)Marshal.SizeOf <Interop.Crypt32.CERT_CHAIN_POLICY_STATUS>();

            bool errorCode =
                Interop.Crypt32.CertVerifyCertificateChainPolicy(
                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                    chainContext,
                    ref cpp,
                    ref status);

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(chainContext, $"CertVerifyCertificateChainPolicy returned: {errorCode}. Status: {status.dwError}");
            }
            return(status.dwError);
        }
        public static void BuildChain(
            X509Certificate2 certificate,
            X509Certificate2Collection remoteCertificateStore,
            string hostName,
            bool checkCertificateRevocationList,
            out X509Chain chain,
            out SslPolicyErrors sslPolicyErrors)
        {
            chain           = null;
            sslPolicyErrors = SslPolicyErrors.None;

            // Build the chain.
            chain = new X509Chain();
            chain.ChainPolicy.RevocationMode =
                checkCertificateRevocationList ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
            // Authenticate the remote party: (e.g. when operating in client mode, authenticate the server).
            chain.ChainPolicy.ApplicationPolicy.Add(s_serverAuthOid);

            if (remoteCertificateStore.Count > 0)
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    foreach (X509Certificate cert in remoteCertificateStore)
                    {
                        NetEventSource.Info(remoteCertificateStore, $"Adding cert to ExtraStore: {cert.Subject}");
                    }
                }

                chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
            }

            if (!chain.Build(certificate))
            {
                sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
            }

            // Verify the hostName matches the certificate.
            unsafe
            {
                Interop.Crypt32.CERT_CHAIN_POLICY_PARA cppStruct = default;
                cppStruct.cbSize  = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_PARA);
                cppStruct.dwFlags = 0;

                Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA eppStruct = default;
                eppStruct.cbSize     = (uint)sizeof(Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA);
                eppStruct.dwAuthType = Interop.Crypt32.AuthType.AUTHTYPE_SERVER;

                cppStruct.pvExtraPolicyPara = &eppStruct;

                fixed(char *namePtr = hostName)
                {
                    eppStruct.pwszServerName = namePtr;
                    cppStruct.dwFlags        =
                        Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
                        ~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG;

                    Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default;
                    status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);
                    if (Interop.Crypt32.CertVerifyCertificateChainPolicy(
                            (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                            chain.SafeHandle,
                            ref cppStruct,
                            ref status))
                    {
                        if (status.dwError == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH)
                        {
                            if (NetEventSource.Log.IsEnabled())
                            {
                                NetEventSource.Error(certificate, nameof(Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH));
                            }
                            sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                        }
                    }
                    else
                    {
                        // Failure checking the policy. This is a rare error. We will assume the name check failed.
                        if (NetEventSource.Log.IsEnabled())
                        {
                            NetEventSource.Error(certificate, $"Failure calling {nameof(Interop.Crypt32.CertVerifyCertificateChainPolicy)}");
                        }
                        sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    }
                }
            }
        }
        private static uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA cpp)
        {
            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Enter("SecureChannel::VerifyChainPolicy", "chainContext=" + chainContext + ", options=" + String.Format("0x{0:x}", cpp.dwFlags));
            }

            var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();
            status.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_STATUS>();

            bool errorCode =
                Interop.Crypt32.CertVerifyCertificateChainPolicy(
                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                    chainContext,
                    ref cpp,
                    ref status);

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print("SecureChannel::VerifyChainPolicy() CertVerifyCertificateChainPolicy returned: " + errorCode);
#if TRACE_VERBOSE
                GlobalLog.Print("SecureChannel::VerifyChainPolicy() error code: " + status.dwError + String.Format(" [0x{0:x8}", status.dwError) + " " + Interop.MapSecurityStatus(status.dwError) + "]");
#endif
                GlobalLog.Leave("SecureChannel::VerifyChainPolicy", status.dwError.ToString());
            }

            return status.dwError;
        }
Пример #7
0
        // TODO: Issue #2165. Merge with similar code used in System.Net.Security move to Common/src//System/Net.
        public static void BuildChain(
            X509Certificate2 certificate,
            string hostName,
            bool checkCertificateRevocationList,
            out X509Chain chain,
            out SslPolicyErrors sslPolicyErrors)
        {
            chain = null;
            sslPolicyErrors = SslPolicyErrors.None;

            // Build the chain.
            chain = new X509Chain();
            chain.ChainPolicy.RevocationMode =
                checkCertificateRevocationList ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
            if (!chain.Build(certificate))
            {
                sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
            }

            // Verify the hostName matches the certificate.
            unsafe
            {
                var cppStruct = new Interop.Crypt32.CERT_CHAIN_POLICY_PARA();
                cppStruct.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_PARA>();
                cppStruct.dwFlags = 0;

                var eppStruct = new Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA();
                eppStruct.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA>();
                eppStruct.dwAuthType = Interop.Crypt32.AuthType.AUTHTYPE_CLIENT;
                
                cppStruct.pvExtraPolicyPara = &eppStruct;

                fixed (char* namePtr = hostName)
                {
                    eppStruct.pwszServerName = namePtr;
                    cppStruct.dwFlags = 
                        Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
                        ~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG;
                        
                    var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();
                    status.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_STATUS>();
                    if (Interop.Crypt32.CertVerifyCertificateChainPolicy(
                            (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                            chain.SafeHandle,
                            ref cppStruct,
                            ref status))
                    {
                        if (status.dwError == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH)
                        {
                            sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                        }
                    }
                    else
                    {
                        // Failure checking the policy. This is a rare error. We will assume the name check failed.
                        // TODO: Issue #2165. Log this error or perhaps throw an exception instead.
                        sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    }
                }
            }
        }
Пример #8
0
        // TODO: Issue #2165. Merge with similar code used in System.Net.Security move to Common/src//System/Net.
        public static void BuildChain(
            X509Certificate2 certificate,
            string hostName,
            bool checkCertificateRevocationList,
            out X509Chain chain,
            out SslPolicyErrors sslPolicyErrors)
        {
            chain           = null;
            sslPolicyErrors = SslPolicyErrors.None;

            // Build the chain.
            chain = new X509Chain();
            chain.ChainPolicy.RevocationMode =
                checkCertificateRevocationList ? X509RevocationMode.Online : X509RevocationMode.NoCheck;
            chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
            // Authenticate the remote party: (e.g. when operating in client mode, authenticate the server).
            chain.ChainPolicy.ApplicationPolicy.Add(s_serverAuthOid);

            if (!chain.Build(certificate))
            {
                sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
            }

            // Verify the hostName matches the certificate.
            unsafe
            {
                var cppStruct = new Interop.Crypt32.CERT_CHAIN_POLICY_PARA();
                cppStruct.cbSize  = (uint)Marshal.SizeOf <Interop.Crypt32.CERT_CHAIN_POLICY_PARA>();
                cppStruct.dwFlags = 0;

                var eppStruct = new Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA();
                eppStruct.cbSize     = (uint)Marshal.SizeOf <Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA>();
                eppStruct.dwAuthType = Interop.Crypt32.AuthType.AUTHTYPE_SERVER;

                cppStruct.pvExtraPolicyPara = &eppStruct;

                fixed(char *namePtr = hostName)
                {
                    eppStruct.pwszServerName = namePtr;
                    cppStruct.dwFlags        =
                        Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
                        ~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG;

                    var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();

                    status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);
                    if (Interop.Crypt32.CertVerifyCertificateChainPolicy(
                            (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                            chain.SafeHandle,
                            ref cppStruct,
                            ref status))
                    {
                        if (status.dwError == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH)
                        {
                            sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                        }
                    }
                    else
                    {
                        // Failure checking the policy. This is a rare error. We will assume the name check failed.
                        // TODO: Issue #2165. Log this error or perhaps throw an exception instead.
                        sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
                    }
                }
            }
        }
        private static uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA cpp)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Enter(chainContext, cpp.dwFlags);

            var status = new Interop.Crypt32.CERT_CHAIN_POLICY_STATUS();
            status.cbSize = (uint)Marshal.SizeOf<Interop.Crypt32.CERT_CHAIN_POLICY_STATUS>();

            bool errorCode =
                Interop.Crypt32.CertVerifyCertificateChainPolicy(
                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                    chainContext,
                    ref cpp,
                    ref status);

            if (NetEventSource.IsEnabled) NetEventSource.Info(chainContext, $"CertVerifyCertificateChainPolicy returned: {errorCode}. Status: {status.dwError}");
            return status.dwError;
        }
Пример #10
0
 public static bool CertVerifyCertificateChainPolicy(ChainPolicy pszPolicyOID, SafeX509ChainHandle pChainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA pPolicyPara, ref Interop.Crypt32.CERT_CHAIN_POLICY_STATUS pPolicyStatus)
 {
     return(Interop.Crypt32.CertVerifyCertificateChainPolicy((IntPtr)pszPolicyOID, pChainContext, ref pPolicyPara, ref pPolicyStatus));
 }