private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer,
                                              XmlElement licenseNode,
                                              X509RevocationFlag revocationFlag,
                                              X509RevocationMode revocationMode)
        {
            Debug.Assert(licenseNode != null, "licenseNode != null");

            X509Chain signatureChain = null;

            if (signer.pChainContext != IntPtr.Zero)
            {
                signatureChain = new X509Chain(signer.pChainContext);
            }
            else if (signer.dwError == (int)SignatureVerificationResult.UntrustedRootCertificate)
            {
                // CertVerifyAuthenticodeLicense will not return the certificate chain for self signed certificates
                // so we'll need to extract the certificate from the signature ourselves.

                XmlElement x509Data = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data",
                                                                   m_namespaceManager) as XmlElement;
                if (x509Data != null)
                {
                    XmlNodeList certificateNodes = x509Data.SelectNodes("ds:X509Certificate", m_namespaceManager);

                    // A manifest could have many X509Certificate nodes in its X509Data, which may include the
                    // signing certificate, links on the chain to a root, or certificates not used at all in
                    // the chain.  Since we don't know which certificate actually did the signing, we only
                    // process the chain if we have a single certificate.
                    if (certificateNodes.Count == 1 && certificateNodes[0] is XmlElement)
                    {
                        byte[]           rawCertificate     = Convert.FromBase64String(certificateNodes[0].InnerText.Trim());
                        X509Certificate2 signingCertificate = new X509Certificate2(rawCertificate);

                        signatureChain = new X509Chain();
                        signatureChain.ChainPolicy.RevocationFlag = revocationFlag;
                        signatureChain.ChainPolicy.RevocationMode = revocationMode;

                        signatureChain.Build(signingCertificate);
                    }
                }
            }

            return(signatureChain);
        }
Пример #2
0
        private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, XmlElement licenseNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode)
        {
            X509Chain chain = null;

            if (signer.dwError == -2146762487)
            {
                XmlElement element = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data", this.m_namespaceManager) as XmlElement;
                if (element != null)
                {
                    X509Certificate2 certificate = new X509Certificate2(Convert.FromBase64String(element.InnerText.Trim()));
                    chain = new X509Chain {
                        ChainPolicy = { RevocationFlag = revocationFlag, RevocationMode = revocationMode }
                    };
                    chain.Build(certificate);
                }
                return(chain);
            }
            if (signer.pChainContext != IntPtr.Zero)
            {
                chain = new X509Chain(signer.pChainContext);
            }
            return(chain);
        }
        private AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode,
                                                                             X509RevocationFlag revocationFlag,
                                                                             X509RevocationMode revocationMode)
        {
            Debug.Assert(signatureNode != null, "signatureNode != null");

            // See if there is an Authenticode signature on the manifest
            XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license",
                                                                    m_namespaceManager) as XmlElement;

            if (licenseNode == null)
            {
                return(null);
            }

            // Make sure that the signature is for this manifest
            SignatureVerificationResult identityVerification = VerifyAuthenticodeSignatureIdentity(licenseNode);

            if (identityVerification != SignatureVerificationResult.Valid)
            {
                return(new AuthenticodeSignatureInformation(identityVerification));
            }

            SignatureVerificationResult hashVerification = VerifyAuthenticodeExpectedHash(licenseNode);

            if (hashVerification != SignatureVerificationResult.Valid)
            {
                return(new AuthenticodeSignatureInformation(hashVerification));
            }

            // Verify the signature, extracting information about it
            AuthenticodeSignatureInformation authenticodeSignature = null;

            X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO();
            signer.cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO));

            X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO();
            timestamper.cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO));

            RuntimeHelpers.PrepareConstrainedRegions();
            try {
                byte[] licenseXml = Encoding.UTF8.GetBytes(licenseNode.OuterXml);
                X509Native.AxlVerificationFlags verificationFlags = MapRevocationFlags(revocationFlag,
                                                                                       revocationMode);

                unsafe
                {
                    fixed(byte *pLicenseXml = licenseXml)
                    {
                        // Safe since we're verifying the size of this buffer is correct
                        CapiNative.CRYPTOAPI_BLOB xmlBlob = new CapiNative.CRYPTOAPI_BLOB();
                        xmlBlob.cbData = licenseXml.Length;
                        xmlBlob.pbData = new IntPtr(pLicenseXml);

                        int hrVerify = X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref xmlBlob,
                                                                                                    verificationFlags,
                                                                                                    ref signer,
                                                                                                    ref timestamper);

                        if (hrVerify == (int)SignatureVerificationResult.MissingSignature)
                        {
                            return(new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature));
                        }
                    }
                }

                X509Chain signatureChain = BuildSignatureChain(signer,
                                                               licenseNode,
                                                               revocationFlag,
                                                               revocationMode);

                TimestampInformation timestamp = GetTimestampInformation(timestamper,
                                                                         licenseNode);

                authenticodeSignature = new AuthenticodeSignatureInformation(signer,
                                                                             signatureChain,
                                                                             timestamp);
            }
            finally {
                X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref signer);
                X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref timestamper);
            }

            // Verify the signing certificate matches the expected publisher
            Debug.Assert(authenticodeSignature != null, "authenticodeSignature != null");
            if (authenticodeSignature.SigningCertificate == null)
            {
                return(new AuthenticodeSignatureInformation(authenticodeSignature.VerificationResult));
            }

            SignatureVerificationResult publisherMatch = VerifyAuthenticodePublisher(authenticodeSignature.SigningCertificate);

            if (publisherMatch != SignatureVerificationResult.Valid)
            {
                return(new AuthenticodeSignatureInformation(publisherMatch));
            }

            return(authenticodeSignature);
        }
Пример #4
0
        private unsafe AuthenticodeSignatureInformation VerifyAuthenticodeSignature(XmlElement signatureNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode)
        {
            XmlElement licenseNode = signatureNode.SelectSingleNode("ds:KeyInfo/msrel:RelData/r:license", this.m_namespaceManager) as XmlElement;

            if (licenseNode == null)
            {
                return(null);
            }
            SignatureVerificationResult error = this.VerifyAuthenticodeSignatureIdentity(licenseNode);

            if (error != SignatureVerificationResult.Valid)
            {
                return(new AuthenticodeSignatureInformation(error));
            }
            SignatureVerificationResult result2 = this.VerifyAuthenticodeExpectedHash(licenseNode);

            if (result2 != SignatureVerificationResult.Valid)
            {
                return(new AuthenticodeSignatureInformation(result2));
            }
            AuthenticodeSignatureInformation information = null;

            X509Native.AXL_AUTHENTICODE_SIGNER_INFO pSignerInfo = new X509Native.AXL_AUTHENTICODE_SIGNER_INFO {
                cbSize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_SIGNER_INFO))
            };
            X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO pTimestamperInfo = new X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO {
                cbsize = Marshal.SizeOf(typeof(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO))
            };
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(licenseNode.OuterXml);
                X509Native.AxlVerificationFlags dwFlags = MapRevocationFlags(revocationFlag, revocationMode);
                try
                {
                    fixed(byte *numRef = bytes)
                    {
                        CapiNative.CRYPTOAPI_BLOB pLicenseBlob = new CapiNative.CRYPTOAPI_BLOB {
                            cbData = bytes.Length,
                            pbData = new IntPtr((void *)numRef)
                        };
                        if (X509Native.UnsafeNativeMethods.CertVerifyAuthenticodeLicense(ref pLicenseBlob, dwFlags, ref pSignerInfo, ref pTimestamperInfo) == -2146762496)
                        {
                            return(new AuthenticodeSignatureInformation(SignatureVerificationResult.MissingSignature));
                        }
                    }
                }
                finally
                {
                    numRef = null;
                }
                X509Chain            signatureChain       = this.BuildSignatureChain(pSignerInfo, licenseNode, revocationFlag, revocationMode);
                TimestampInformation timestampInformation = this.GetTimestampInformation(pTimestamperInfo, licenseNode);
                information = new AuthenticodeSignatureInformation(pSignerInfo, signatureChain, timestampInformation);
            }
            finally
            {
                X509Native.UnsafeNativeMethods.CertFreeAuthenticodeSignerInfo(ref pSignerInfo);
                X509Native.UnsafeNativeMethods.CertFreeAuthenticodeTimestamperInfo(ref pTimestamperInfo);
            }
            if (information.SigningCertificate == null)
            {
                return(new AuthenticodeSignatureInformation(information.VerificationResult));
            }
            SignatureVerificationResult result3 = this.VerifyAuthenticodePublisher(information.SigningCertificate);

            if (result3 != SignatureVerificationResult.Valid)
            {
                return(new AuthenticodeSignatureInformation(result3));
            }
            return(information);
        }