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; } }
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; }