Ejemplo n.º 1
0
        private uint[] GetChainErrors(string hostName, X509Chain chain, ref bool fatalError)
        {
            fatalError = false;
            SafeFreeCertChain chainContext= new SafeFreeCertChain(chain.ChainContext);
            ArrayList certificateProblems = new ArrayList();
            unsafe {
                uint status = 0;
                ChainPolicyParameter cppStruct = new ChainPolicyParameter();
                cppStruct.cbSize  = ChainPolicyParameter.StructSize;
                cppStruct.dwFlags = 0;

                SSL_EXTRA_CERT_CHAIN_POLICY_PARA eppStruct = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(false);
                cppStruct.pvExtraPolicyPara = &eppStruct;

                fixed (char* namePtr = hostName) {
                    if (ServicePointManager.CheckCertificateName){
                        eppStruct.pwszServerName = namePtr;
                    }

                    while (true) {
                        status = VerifyChainPolicy(chainContext, ref cppStruct);
                        uint ignoreErrorMask = (uint)MapErrorCode(status);

                        certificateProblems.Add(status);

                        if (status == 0) {  // No more problems with the certificate
                            break;          // Then break out of the callback loop
                        }

                        if (ignoreErrorMask == 0) {  // Unrecognized error encountered
                            fatalError = true;
                            break;
                        }
                        else {
                            cppStruct.dwFlags |= ignoreErrorMask;
                            if ((CertificateProblem)status == CertificateProblem.CertCN_NO_MATCH && ServicePointManager.CheckCertificateName) {
                                eppStruct.fdwChecks = IgnoreUnmatchedCN;
                            }
                        }
                    }
                }
            }

            return (uint[]) certificateProblems.ToArray(typeof(uint));
        }
Ejemplo n.º 2
0
        internal unsafe bool VerifyRemoteCertificate(RemoteCertValidationCallback remoteCertValidationCallback)
        {
            SslPolicyErrors  none              = SslPolicyErrors.None;
            bool             flag              = false;
            X509Chain        chain             = null;
            X509Certificate2 remoteCertificate = null;

            try
            {
                X509Certificate2Collection certificates;
                remoteCertificate = this.GetRemoteCertificate(out certificates);
                this.m_IsRemoteCertificateAvailable = remoteCertificate != null;
                if (remoteCertificate == null)
                {
                    none |= SslPolicyErrors.RemoteCertificateNotAvailable;
                }
                else
                {
                    chain = new X509Chain {
                        ChainPolicy = { RevocationMode = this.m_CheckCertRevocation ? X509RevocationMode.Online : X509RevocationMode.NoCheck, RevocationFlag = X509RevocationFlag.ExcludeRoot }
                    };
                    if (certificates != null)
                    {
                        chain.ChainPolicy.ExtraStore.AddRange(certificates);
                    }
                    if (!chain.Build(remoteCertificate) && (chain.ChainContext == IntPtr.Zero))
                    {
                        throw new CryptographicException(Marshal.GetLastWin32Error());
                    }
                    if (this.m_CheckCertName)
                    {
                        ChainPolicyParameter cpp = new ChainPolicyParameter {
                            cbSize  = ChainPolicyParameter.StructSize,
                            dwFlags = 0
                        };
                        SSL_EXTRA_CERT_CHAIN_POLICY_PARA ssl_extra_cert_chain_policy_para = new SSL_EXTRA_CERT_CHAIN_POLICY_PARA(this.IsServer);
                        cpp.pvExtraPolicyPara = &ssl_extra_cert_chain_policy_para;
                        fixed(char *str = ((char *)this.m_HostName))
                        {
                            char *chPtr = str;

                            ssl_extra_cert_chain_policy_para.pwszServerName = chPtr;
                            cpp.dwFlags |= 0xfbf;
                            SafeFreeCertChain chainContext = new SafeFreeCertChain(chain.ChainContext);

                            if (PolicyWrapper.VerifyChainPolicy(chainContext, ref cpp) == 0x800b010f)
                            {
                                none |= SslPolicyErrors.RemoteCertificateNameMismatch;
                            }
                        }
                    }
                    X509ChainStatus[] chainStatus = chain.ChainStatus;
                    if ((chainStatus != null) && (chainStatus.Length != 0))
                    {
                        none |= SslPolicyErrors.RemoteCertificateChainErrors;
                    }
                }
                if (remoteCertValidationCallback != null)
                {
                    flag = remoteCertValidationCallback(this.m_HostName, remoteCertificate, chain, none);
                }
                else if ((none == SslPolicyErrors.RemoteCertificateNotAvailable) && !this.m_RemoteCertRequired)
                {
                    flag = true;
                }
                else
                {
                    flag = none == SslPolicyErrors.None;
                }
                if (!Logging.On)
                {
                    return(flag);
                }
                if (none != SslPolicyErrors.None)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_errors"));
                    if ((none & SslPolicyErrors.RemoteCertificateNotAvailable) != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_not_available"));
                    }
                    if ((none & SslPolicyErrors.RemoteCertificateNameMismatch) != SslPolicyErrors.None)
                    {
                        Logging.PrintInfo(Logging.Web, this, "\t" + SR.GetString("net_log_remote_cert_name_mismatch"));
                    }
                    if ((none & SslPolicyErrors.RemoteCertificateChainErrors) != SslPolicyErrors.None)
                    {
                        foreach (X509ChainStatus status in chain.ChainStatus)
                        {
                            Logging.PrintInfo(Logging.Web, this, "\t" + status.StatusInformation);
                        }
                    }
                }
                if (flag)
                {
                    if (remoteCertValidationCallback != null)
                    {
                        Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_valid"));
                        return(flag);
                    }
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_has_no_errors"));
                    return(flag);
                }
                if (remoteCertValidationCallback != null)
                {
                    Logging.PrintInfo(Logging.Web, this, SR.GetString("net_log_remote_cert_user_declared_invalid"));
                }
            }
            finally
            {
                if (chain != null)
                {
                    chain.Reset();
                }
                if (remoteCertificate != null)
                {
                    remoteCertificate.Reset();
                }
            }
            return(flag);
        }
Ejemplo n.º 3
0
        internal static uint VerifyChainPolicy(SafeFreeCertChain chainContext, ref ChainPolicyParameter cpp)
        {
            GlobalLog.Enter("PolicyWrapper::VerifyChainPolicy", "chainContext="+ chainContext + ", options="+String.Format("0x{0:x}", cpp.dwFlags));
            ChainPolicyStatus status = new ChainPolicyStatus();
            status.cbSize = ChainPolicyStatus.StructSize;
            int errorCode =
                UnsafeNclNativeMethods.NativePKI.CertVerifyCertificateChainPolicy(
                    (IntPtr) ChainPolicyType.SSL,
                    chainContext,
                    ref cpp,
                    ref status);

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