internal AuthenticodeSignatureInformation(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer,
                                                  X509Chain signatureChain,
                                                  TimestampInformation timestamp) {
            m_verificationResult = (SignatureVerificationResult)signer.dwError;
            m_hashAlgorithmId = signer.algHash;

            if (signer.pwszDescription != IntPtr.Zero) {
                m_description = Marshal.PtrToStringUni(signer.pwszDescription);
            }
            if (signer.pwszDescriptionUrl != IntPtr.Zero) {
                string descriptionUrl = Marshal.PtrToStringUni(signer.pwszDescriptionUrl);
                Uri.TryCreate(descriptionUrl, UriKind.RelativeOrAbsolute, out m_descriptionUrl);
            }

            m_signatureChain = signatureChain;

            // If there was a timestamp, and it was not valid we need to invalidate the entire Authenticode
            // signature as well, since we cannot assume that the signature would have verified without
            // the timestamp.
            if (timestamp != null && timestamp.VerificationResult != SignatureVerificationResult.MissingSignature) {
                if (timestamp.IsValid) {
                    m_timestamp = timestamp;
                }
                else {
                    m_verificationResult = SignatureVerificationResult.InvalidTimestamp;
                }
            }
            else {
                m_timestamp = null;
            }
        }
 internal AuthenticodeSignatureInformation(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, X509Chain signatureChain, TimestampInformation timestamp)
 {
     this.m_verificationResult = (SignatureVerificationResult)signer.dwError;
     this.m_hashAlgorithmId    = signer.algHash;
     if (signer.pwszDescription != IntPtr.Zero)
     {
         this.m_description = Marshal.PtrToStringUni(signer.pwszDescription);
     }
     if (signer.pwszDescriptionUrl != IntPtr.Zero)
     {
         Uri.TryCreate(Marshal.PtrToStringUni(signer.pwszDescriptionUrl), UriKind.RelativeOrAbsolute, out this.m_descriptionUrl);
     }
     this.m_signatureChain = signatureChain;
     if ((timestamp != null) && (timestamp.VerificationResult != SignatureVerificationResult.MissingSignature))
     {
         if (timestamp.IsValid)
         {
             this.m_timestamp = timestamp;
         }
         else
         {
             this.m_verificationResult = SignatureVerificationResult.InvalidTimestamp;
         }
     }
     else
     {
         this.m_timestamp = null;
     }
 }
        internal AuthenticodeSignatureInformation(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer,
                                                  X509Chain signatureChain,
                                                  TimestampInformation timestamp)
        {
            m_verificationResult = (SignatureVerificationResult)signer.dwError;
            m_hashAlgorithmId    = signer.algHash;

            if (signer.pwszDescription != IntPtr.Zero)
            {
                m_description = Marshal.PtrToStringUni(signer.pwszDescription);
            }
            if (signer.pwszDescriptionUrl != IntPtr.Zero)
            {
                string descriptionUrl = Marshal.PtrToStringUni(signer.pwszDescriptionUrl);
                Uri.TryCreate(descriptionUrl, UriKind.RelativeOrAbsolute, out m_descriptionUrl);
            }

            m_signatureChain = signatureChain;

            // If there was a timestamp, and it was not valid we need to invalidate the entire Authenticode
            // signature as well, since we cannot assume that the signature would have verified without
            // the timestamp.
            if (timestamp != null && timestamp.VerificationResult != SignatureVerificationResult.MissingSignature)
            {
                if (timestamp.IsValid)
                {
                    m_timestamp = timestamp;
                }
                else
                {
                    m_verificationResult = SignatureVerificationResult.InvalidTimestamp;
                }
            }
            else
            {
                m_timestamp = null;
            }
        }
        private TimestampInformation GetTimestampInformation(X509Native.AXL_AUTHENTICODE_TIMESTAMPER_INFO timestamper,
                                                             XmlElement licenseNode) {
            Debug.Assert(licenseNode != null, "licenseNode != null");

            TimestampInformation timestamp = null;

            // If the timestamper is a trusted publisher, then CAPI has done the work for us;
            // If the leaf certificate is not explicitly a trusted publisher, CAPI will not process
            // the timestamp information so we will verify it ourselves. In any other case, we will
            // return no timestamp information.
            if (timestamper.dwError == (int)SignatureVerificationResult.Valid) {
                timestamp = new TimestampInformation(timestamper);
            }
            else if (timestamper.dwError == (int)SignatureVerificationResult.CertificateNotExplicitlyTrusted ||
                     timestamper.dwError == (int)SignatureVerificationResult.MissingSignature) {

                XmlElement timestampElement = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:Object/as:Timestamp",
                                                                           m_namespaceManager) as XmlElement;
                if (timestampElement != null) {
                    // The timestamp is held as a parameter of a base64 encoded PKCS7 message in the signature
                    byte[] timestampBlob = Convert.FromBase64String(timestampElement.InnerText);

                    try {
                        SignedCms timestampCms = new SignedCms();
                        timestampCms.Decode(timestampBlob);
                        timestampCms.CheckSignature(true);

                        // The SignedCms class does not expose a way to read arbitrary properties from the
                        // message, nor does it expose the HCRYPTMSG to P/Invoke with. We cannot access the
                        // actual timestamp because of this, so for signatures which are not created by a
                        // trusted publisher, we will return a null timestamp. This should be corrected in
                        // v3 of the CLR, as we can extend SignedCms to have the properties we need to
                        // pull all of this information.
                        timestamp = null;
                    }
                    catch (CryptographicException e) {
                        timestamp = new TimestampInformation((SignatureVerificationResult)Marshal.GetHRForException(e));
                    }
                }
            }
            else {
                timestamp = null;
            }

            return timestamp;
        }