< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 58
Coverable lines: 58
Total lines: 100
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 16
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
BuildChainAndVerifyProperties(...)0%14140%
Verify(...)0%220%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/Common/src/System/Net/Security/CertificateValidation.Windows.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Diagnostics;
 5using System.Net.Security;
 6using System.Runtime.InteropServices;
 7using System.Security.Cryptography;
 8using System.Security.Cryptography.X509Certificates;
 9using System.Security.Principal;
 10using Microsoft.Win32.SafeHandles;
 11
 12namespace System.Net
 13{
 14    internal static partial class CertificateValidation
 15    {
 16#pragma warning disable IDE0060
 17        internal static SslPolicyErrors BuildChainAndVerifyProperties(X509Chain chain, X509Certificate2 remoteCertificat
 18            => BuildChainAndVerifyProperties(chain, remoteCertificate, checkCertName, isServer, hostName);
 19#pragma warning restore IDE0060
 20
 21        internal static SslPolicyErrors BuildChainAndVerifyProperties(X509Chain chain, X509Certificate2 remoteCertificat
 022        {
 023            SslPolicyErrors sslPolicyErrors = SslPolicyErrors.None;
 24
 025            bool chainBuildResult = chain.Build(remoteCertificate);
 026            if (!chainBuildResult       // Build failed on handle or on policy.
 027                && chain.SafeHandle!.DangerousGetHandle() == IntPtr.Zero)   // Build failed to generate a valid handle.
 028            {
 29#if NETFRAMEWORK
 30                throw new CryptographicException(Marshal.GetLastWin32Error());
 31#else
 032                throw new CryptographicException(Marshal.GetLastPInvokeError());
 33#endif
 34            }
 35
 036            if (checkCertName)
 037            {
 38                unsafe
 039                {
 040                    uint status = 0;
 41
 042                    var eppStruct = new Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA()
 043                    {
 044                        cbSize = (uint)sizeof(Interop.Crypt32.SSL_EXTRA_CERT_CHAIN_POLICY_PARA),
 045                        // Authenticate the remote party: (e.g. when operating in server mode, authenticate the client).
 046                        dwAuthType = isServer ? Interop.Crypt32.AuthType.AUTHTYPE_CLIENT : Interop.Crypt32.AuthType.AUTH
 047                        fdwChecks = 0,
 048                        pwszServerName = null
 049                    };
 50
 051                    var cppStruct = new Interop.Crypt32.CERT_CHAIN_POLICY_PARA()
 052                    {
 053                        cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_PARA),
 054                        dwFlags = 0,
 055                        pvExtraPolicyPara = &eppStruct
 056                    };
 57
 058                    fixed (char* namePtr = hostName)
 059                    {
 060                        eppStruct.pwszServerName = (ushort*)namePtr;
 061                        cppStruct.dwFlags |=
 062                            (Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_ALL &
 063                             ~Interop.Crypt32.CertChainPolicyIgnoreFlags.CERT_CHAIN_POLICY_IGNORE_INVALID_NAME_FLAG);
 64
 065                        SafeX509ChainHandle chainContext = chain.SafeHandle!;
 066                        status = Verify(chainContext, ref cppStruct);
 067                        if (status == Interop.Crypt32.CertChainPolicyErrors.CERT_E_CN_NO_MATCH)
 068                        {
 069                            sslPolicyErrors |= SslPolicyErrors.RemoteCertificateNameMismatch;
 070                        }
 071                    }
 072                }
 073            }
 74
 075            if (!chainBuildResult)
 076            {
 077                sslPolicyErrors |= SslPolicyErrors.RemoteCertificateChainErrors;
 078            }
 79
 080            return sslPolicyErrors;
 081        }
 82
 83        private static unsafe uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA c
 084        {
 085            Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default;
 086            status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);
 87
 088            bool errorCode =
 089                Interop.Crypt32.CertVerifyCertificateChainPolicy(
 090                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
 091                    chainContext,
 092                    ref cpp,
 093                    ref status);
 94
 095            if (NetEventSource.Log.IsEnabled()) NetEventSource.Info(chainContext, $"CertVerifyCertificateChainPolicy ret
 096            return status.dwError;
 097        }
 98    }
 99}
 100