Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / System / Security / Cryptography / Xml / ManifestSignedXml.cs / 1305376 / ManifestSignedXml.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography.Pkcs; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Text; using System.Xml; using Microsoft.Win32.SafeHandles; namespace System.Security.Cryptography.Xml { ////// Class which verifies the signature of a single manifest and can return detailed information /// about the signature. /// internal sealed class ManifestSignedXml : SignedXml { private ManifestKinds m_manifest; private XmlDocument m_manifestXml; private XmlNamespaceManager m_namespaceManager; public ManifestSignedXml(XmlDocument manifestXml, ManifestKinds manifest) : base(manifestXml) { Debug.Assert(manifestXml != null, "manifestXml != null"); Debug.Assert(manifest == ManifestKinds.Application || manifest == ManifestKinds.Deployment, "Unknown manifest kind"); m_manifest = manifest; m_manifestXml = manifestXml; m_namespaceManager = new XmlNamespaceManager(manifestXml.NameTable); m_namespaceManager.AddNamespace("as", "http://schemas.microsoft.com/windows/pki/2005/Authenticode"); m_namespaceManager.AddNamespace("asm", "urn:schemas-microsoft-com:asm.v1"); m_namespaceManager.AddNamespace("asmv2", "urn:schemas-microsoft-com:asm.v2"); m_namespaceManager.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); m_namespaceManager.AddNamespace("msrel", "http://schemas.microsoft.com/windows/rel/2005/reldata"); m_namespaceManager.AddNamespace("r", "urn:mpeg:mpeg21:2003:01-REL-R-NS"); } ////// Convert a hex string to bytes in reverse order /// private static byte[] BackwardHexToBytes(string hex) { if (String.IsNullOrEmpty(hex) || hex.Length % 2 != 0) { return null; } byte[] bytes = new byte[hex.Length / 2]; for (int stringIndex = hex.Length - 2, decodedIndex = 0; decodedIndex < bytes.Length;stringIndex -= 2, decodedIndex++) { byte? upper = HexToByte(hex[stringIndex]); byte? lower = HexToByte(hex[stringIndex + 1]); if (!upper.HasValue || !lower.HasValue) { return null; } bytes[decodedIndex] = (byte)((upper.Value << 4) | lower.Value); } return bytes; } ////// Get the chain from the Authenticode signing certificate /// ////// We want partially trusted callers to be able to verify the signature, so we'll /// assert permission to access the store here; however any API which hands out the chain /// or information derived from it such as the signing certificate needs to demand these /// permissions before doing so. /// //// [System.Security.SecurityCritical] [StorePermission(SecurityAction.Assert, EnumerateCertificates = true, OpenStore = true)] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] private X509Chain BuildSignatureChain(X509Native.AXL_AUTHENTICODE_SIGNER_INFO signer, XmlElement licenseNode, X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { Debug.Assert(licenseNode != null, "licenseNode != null"); X509Chain signatureChain = null; // CertVerifyAuthenticodeLicense will not return the certificate chain for self signed certificates // so we'll need to extract the certificate from the signature ourselves. if (signer.dwError == (int)SignatureVerificationResult.UntrustedRootCertificate) { Debug.Assert(signer.pChainContext == IntPtr.Zero, "signer.pChainContext == IntPtr.Zero"); XmlElement x509Data = licenseNode.SelectSingleNode("r:issuer/ds:Signature/ds:KeyInfo/ds:X509Data", m_namespaceManager) as XmlElement; if (x509Data != null) { byte[] rawCertificate = Convert.FromBase64String(x509Data.InnerText.Trim()); X509Certificate2 signingCertificate = new X509Certificate2(rawCertificate); signatureChain = new X509Chain(); signatureChain.ChainPolicy.RevocationFlag = revocationFlag; signatureChain.ChainPolicy.RevocationMode = revocationMode; signatureChain.Build(signingCertificate); } } else if (signer.pChainContext != IntPtr.Zero) { signatureChain = new X509Chain(signer.pChainContext); } return signatureChain; } ///// // // /// Get the public key token specified in the manifest id /// private byte[] CalculateManifestPublicKeyToken() { XmlElement identityElement = m_manifestXml.SelectSingleNode("//asm:assembly/asm:assemblyIdentity", m_namespaceManager) as XmlElement; if (identityElement == null) { return null; } return HexStringToBytes(identityElement.GetAttribute("publicKeyToken")); } ////// Get the public key token of the strong name key used in the strong name signature /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle", Justification = "DangerousGetHandle is protected by a CER")] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] private static byte[] CalculateSignerPublicKeyToken(AsymmetricAlgorithm key) { Debug.Assert(key != null, "key != null"); ICspAsymmetricAlgorithm cspAlgorithm = key as ICspAsymmetricAlgorithm; if (cspAlgorithm == null) { return null; } byte[] publicKey = cspAlgorithm.ExportCspBlob(false); SafeAxlBufferHandle tokenBuffer; unsafe { fixed (byte* pPublicKey = publicKey) { CapiNative.CRYPTOAPI_BLOB keyBlob = new CapiNative.CRYPTOAPI_BLOB(); keyBlob.cbData = publicKey.Length; keyBlob.pbData = new IntPtr(pPublicKey); int hrToken = CapiNative.UnsafeNativeMethods._AxlPublicKeyBlobToPublicKeyToken(ref keyBlob, out tokenBuffer); if (((uint)hrToken & 0x80000000) != 0) { return null; } } } bool acquired = false; RuntimeHelpers.PrepareConstrainedRegions(); try { tokenBuffer.DangerousAddRef(ref acquired); return HexStringToBytes(Marshal.PtrToStringUni(tokenBuffer.DangerousGetHandle())); } finally { if (acquired) { tokenBuffer.DangerousRelease(); } } } ///// // // // // // // // /// Compare two byte arrays for equality /// ///true if both arrays are the non-null, the same length, and have the same contents private static bool CompareBytes(byte[] lhs, byte[] rhs) { if (lhs == null || rhs == null) { return false; } for (int i = 0; i < lhs.Length; i++) { if (lhs[i] != rhs[i]) return false; } return true; } ////// Find the XML element being referenced by the signature /// public override XmlElement GetIdElement(XmlDocument document, string idValue) { // Redirect id elements back into the KeyInfo element if (KeyInfo != null && String.Compare(KeyInfo.Id, idValue, StringComparison.OrdinalIgnoreCase) == 0) { return KeyInfo.GetXml(); } return null; } ////// Gether information about the timestamp of the authenticode signature, if there is one /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] 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; } ///// // /// Convert a string of hex digits into an equivilent byte array, returning null on any error /// private static byte[] HexStringToBytes(string hex) { if (String.IsNullOrEmpty(hex) || hex.Length % 2 != 0) { return null; } byte[] bytes = new byte[hex.Length / 2]; for (int i = 0; i < bytes.Length; i++) { byte? upper = HexToByte(hex[i]); byte? lower = HexToByte(hex[i + 1]); if (!upper.HasValue || !lower.HasValue) { return null; } bytes[i] = (byte)((upper.Value << 4) | lower.Value); } return bytes; } ////// Convert a single hex character to a byte /// private static byte? HexToByte(char hex) { if (hex >= '0' && hex <= '9') { return (byte)(hex - '0'); } else if (hex >= 'a' && hex <= 'f') { return (byte)(hex - 'a' + 10); } else if (hex >= 'A' && hex <= 'F') { return (byte)(hex - 'A' + 10); } else { return null; } } ////// Map X509 revocation flags to flags for the AXL verification APIs /// private static X509Native.AxlVerificationFlags MapRevocationFlags(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { X509Native.AxlVerificationFlags axlFlags = X509Native.AxlVerificationFlags.None; switch (revocationFlag) { case X509RevocationFlag.EndCertificateOnly: axlFlags |= X509Native.AxlVerificationFlags.RevocationCheckEndCertOnly; break; case X509RevocationFlag.EntireChain: axlFlags |= X509Native.AxlVerificationFlags.RevocationCheckEntireChain; break; case X509RevocationFlag.ExcludeRoot: default: axlFlags |= X509Native.AxlVerificationFlags.None; break; } switch (revocationMode) { case X509RevocationMode.NoCheck: axlFlags |= X509Native.AxlVerificationFlags.NoRevocationCheck; break; case X509RevocationMode.Offline: axlFlags |= X509Native.AxlVerificationFlags.UrlOnlyCacheRetrieval; break; case X509RevocationMode.Online: default: axlFlags |= X509Native.AxlVerificationFlags.None; break; } return axlFlags; } ////// Verify the hash of the manifest without any signature attached is what the Authenticode /// signature expects it to be /// private SignatureVerificationResult VerifyAuthenticodeExpectedHash(XmlElement licenseNode) { Debug.Assert(licenseNode != null, "licenseNode != null"); // Get the expected hash value from the signature XmlElement manifestInformation = licenseNode.SelectSingleNode("r:grant/as:ManifestInformation", m_namespaceManager) as XmlElement; if (manifestInformation == null) return SignatureVerificationResult.BadSignatureFormat; string expectedHashString = manifestInformation.GetAttribute("Hash"); if (String.IsNullOrEmpty(expectedHashString)) { return SignatureVerificationResult.BadSignatureFormat; } // The expected hash value is stored in backward order, so we cannot use a standard hex to bytes // routine to decode it. byte[] expectedHash = BackwardHexToBytes(expectedHashString); // Make a normalized copy of the manifest without the strong name signature attached XmlDocument normalizedManifest = new XmlDocument(); normalizedManifest.PreserveWhitespace = true; XmlReaderSettings normalizationSettings = new XmlReaderSettings(); normalizationSettings.DtdProcessing = DtdProcessing.Parse; using (TextReader manifestReader = new StringReader(m_manifestXml.OuterXml)) using (XmlReader xmlReader = XmlReader.Create(manifestReader, normalizationSettings, m_manifestXml.BaseURI)) { normalizedManifest.Load(xmlReader); } XmlElement signatureNode = normalizedManifest.SelectSingleNode("//asm:assembly/ds:Signature", m_namespaceManager) as XmlElement; Debug.Assert(signatureNode != null, "signatureNode != null"); signatureNode.ParentNode.RemoveChild(signatureNode); // calculate the hash value of the manifest XmlDsigExcC14NTransform canonicalizedXml = new XmlDsigExcC14NTransform(); canonicalizedXml.LoadInput(normalizedManifest); byte[] actualHash = null; using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider()) { actualHash = sha1.ComputeHash(canonicalizedXml.GetOutput() as MemoryStream); } if (!CompareBytes(expectedHash, actualHash)) { return SignatureVerificationResult.BadDigest; } return SignatureVerificationResult.Valid; } ////// Verify that the certificate which signed the manifest is the certificate the manifest expected /// to be signed with /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle", Justification = "DangerousGetHandle is protected by a CER")] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] private SignatureVerificationResult VerifyAuthenticodePublisher(X509Certificate2 publisherCertificate) { Debug.Assert(publisherCertificate != null, "publisherCertificate != null"); // Get the expected name and key hash XmlElement publisherIdentity = m_manifestXml.SelectSingleNode("//asm:assembly/asmv2:publisherIdentity", m_namespaceManager) as XmlElement; if (publisherIdentity == null) return SignatureVerificationResult.BadSignatureFormat; string publisherName = publisherIdentity.GetAttribute("name"); string publisherIssuerKeyHash = publisherIdentity.GetAttribute("issuerKeyHash"); if (String.IsNullOrEmpty(publisherName) || String.IsNullOrEmpty(publisherIssuerKeyHash)) { return SignatureVerificationResult.BadSignatureFormat; } // Get the actual key hash SafeAxlBufferHandle issuerKeyBuffer = null; int hrHash = X509Native.UnsafeNativeMethods._AxlGetIssuerPublicKeyHash(publisherCertificate.Handle, out issuerKeyBuffer); if (hrHash != (int)SignatureVerificationResult.Valid) { return (SignatureVerificationResult)hrHash; } string actualKeyHash = null; bool acquired = false; RuntimeHelpers.PrepareConstrainedRegions(); try { issuerKeyBuffer.DangerousAddRef(ref acquired); actualKeyHash = Marshal.PtrToStringUni(issuerKeyBuffer.DangerousGetHandle()); } finally { if (acquired) { issuerKeyBuffer.DangerousRelease(); } } if (String.Compare(publisherName, publisherCertificate.SubjectName.Name, StringComparison.Ordinal) != 0 || String.Compare(publisherIssuerKeyHash, actualKeyHash, StringComparison.Ordinal) != 0) { return SignatureVerificationResult.PublisherMismatch; } return SignatureVerificationResult.Valid; } ///// // // // // // // // /// Verify the Authenticode signature has a valid format, applies to this manifest, and is valid /// //// [System.Security.SecurityCritical] [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "Reviewed")] 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) { 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; } ///// // // // // // // // // /// Verify that the Authenticode signature expects to be attached to this manifest /// private SignatureVerificationResult VerifyAuthenticodeSignatureIdentity(XmlElement licenseNode) { Debug.Assert(licenseNode != null, "licenseNode != null"); XmlElement signatureIdentity = licenseNode.SelectSingleNode("r:grant/as:ManifestInformation/as:assemblyIdentity", m_namespaceManager) as XmlElement; XmlElement assemblyIdentity = m_manifestXml.SelectSingleNode("//asm:assembly/asm:assemblyIdentity", m_namespaceManager) as XmlElement; bool validAssemblyIdentity = assemblyIdentity != null && assemblyIdentity.HasAttributes; bool validSignatureIdentity = signatureIdentity != null && signatureIdentity.HasAttributes; if (!validAssemblyIdentity || !validSignatureIdentity || assemblyIdentity.Attributes.Count != signatureIdentity.Attributes.Count) { return SignatureVerificationResult.BadSignatureFormat; } foreach (XmlAttribute identityAttribute in assemblyIdentity.Attributes) { string signatureValue = signatureIdentity.GetAttribute(identityAttribute.LocalName); if (signatureValue == null || String.Compare(identityAttribute.Value, signatureValue, StringComparison.Ordinal) != 0) { return SignatureVerificationResult.AssemblyIdentityMismatch; } } return SignatureVerificationResult.Valid; } ////// Verify that the strong name signature has a valid id /// private static SignatureVerificationResult VerifyStrongNameSignatureId(XmlElement signatureNode) { Debug.Assert(signatureNode != null, "signatureNode != null"); string signatureId = null; for (int i = 0; i < signatureNode.Attributes.Count && signatureId == null; i++) { if (String.Compare(signatureNode.Attributes[i].LocalName, "id", StringComparison.OrdinalIgnoreCase) == 0) { signatureId = signatureNode.Attributes[i].Value; } } if (String.IsNullOrEmpty(signatureId)) { return SignatureVerificationResult.BadSignatureFormat; } if (String.Compare(signatureId, "StrongNameSignature", StringComparison.Ordinal) != 0) { return SignatureVerificationResult.BadSignatureFormat; } return SignatureVerificationResult.Valid; } ////// Verify the transforms on a strong name signature are valid for a ClickOnce manifest. /// ////// For a reference to the entire document, we expect both exclusive cannonicalization and /// enveloped transform. For a reference to the strong name key section, we expect only exclusive /// cannonicalization. Other references are not given special meaning for a strong name signature /// and are ignored. Failure to have exactly the correct set of transforms is an error with the /// strong name signature. /// private static SignatureVerificationResult VerifyStrongNameSignatureTransforms(SignedInfo signedInfo) { Debug.Assert(signedInfo != null, "signedInfo != null"); int totalReferences = 0; foreach (Reference reference in signedInfo.References) { TransformChain transforms = reference.TransformChain; bool validTransformChain = false; if (String.IsNullOrEmpty(reference.Uri)) { totalReferences++; validTransformChain = transforms != null && transforms.Count == 2 && String.Compare(transforms[0].Algorithm, SignedXml.XmlDsigEnvelopedSignatureTransformUrl, StringComparison.Ordinal) == 0 && String.Compare(transforms[1].Algorithm, SignedXml.XmlDsigExcC14NTransformUrl, StringComparison.Ordinal) == 0; } else if (String.Compare(reference.Uri, "#StrongNameKeyInfo", StringComparison.Ordinal) == 0) { totalReferences++; validTransformChain = transforms != null && transforms.Count == 1 && String.Compare(transforms[0].Algorithm, SignedXml.XmlDsigExcC14NTransformUrl, StringComparison.Ordinal) == 0; } else { validTransformChain = true; } if (!validTransformChain) { return SignatureVerificationResult.BadSignatureFormat; } } if (totalReferences == 0) { return SignatureVerificationResult.BadSignatureFormat; } return SignatureVerificationResult.Valid; } ////// Verify the strong name signature has a valid format and applies to this manifest /// //// [System.Security.SecurityCritical] private StrongNameSignatureInformation VerifyStrongNameSignature(XmlElement signatureNode) { Debug.Assert(signatureNode != null, "signatureNode != null"); // Verify that the signature is valid AsymmetricAlgorithm key; if (!CheckSignatureReturningKey(out key)) { return new StrongNameSignatureInformation(SignatureVerificationResult.BadDigest); } // ensure there is an ID element, and it is the strong name id SignatureVerificationResult strongNameId = VerifyStrongNameSignatureId(signatureNode); if (strongNameId != SignatureVerificationResult.Valid) { return new StrongNameSignatureInformation(strongNameId); } // Verify that the transforms are the ones we expect. Debug.Assert(Signature != null && Signature.SignedInfo != null, "XML signature must be verified before getting SN details"); SignatureVerificationResult transformsValid = VerifyStrongNameSignatureTransforms(Signature.SignedInfo); if (transformsValid != SignatureVerificationResult.Valid) { return new StrongNameSignatureInformation(transformsValid); } // ensure the public key token in the manifest identity matches the public key token of the signing // strong name key if (!CompareBytes(CalculateManifestPublicKeyToken(), CalculateSignerPublicKeyToken(key))) { return new StrongNameSignatureInformation(SignatureVerificationResult.PublicKeyTokenMismatch); } return new StrongNameSignatureInformation(key); } ///// /// Verify the signature of the manifest /// //// [System.Security.SecurityCritical] public ManifestSignatureInformation VerifySignature(X509RevocationFlag revocationFlag, X509RevocationMode revocationMode) { XmlElement signatureNode = m_manifestXml.SelectSingleNode("//ds:Signature", m_namespaceManager) as XmlElement; if (signatureNode == null) { return new ManifestSignatureInformation(m_manifest, null, null); } LoadXml(signatureNode); StrongNameSignatureInformation strongName = VerifyStrongNameSignature(signatureNode); // Since the Authenticode signature is wrapped in the strong name signature, we do not want to // give a valid AuthenticodeSignatureInformation object for an Authenticode signature which is // contained within a strong name signature with an invalid hash value. AuthenticodeSignatureInformation authenticode = null; if (strongName.VerificationResult != SignatureVerificationResult.BadDigest) { authenticode = VerifyAuthenticodeSignature(signatureNode, revocationFlag, revocationMode); } else { authenticode = new AuthenticodeSignatureInformation(SignatureVerificationResult.ContainingSignatureInvalid); } return new ManifestSignatureInformation(m_manifest, strongName, authenticode); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.// //
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- sortedlist.cs
- HttpHandlerAction.cs
- SubpageParagraph.cs
- TraceListeners.cs
- StrokeCollection2.cs
- wgx_sdk_version.cs
- StatusBar.cs
- NativeRightsManagementAPIsStructures.cs
- PersistenceTypeAttribute.cs
- DependencyPropertyValueSerializer.cs
- SerializationEventsCache.cs
- SinglePageViewer.cs
- DataFormats.cs
- ByteStreamGeometryContext.cs
- QuadraticBezierSegment.cs
- CodeCommentStatementCollection.cs
- StylusCollection.cs
- ClientCredentialsSecurityTokenManager.cs
- SqlConnectionStringBuilder.cs
- FixUp.cs
- XMLDiffLoader.cs
- TileModeValidation.cs
- Grid.cs
- DefaultProxySection.cs
- RequestQueryParser.cs
- AnnotationHighlightLayer.cs
- ChangeBlockUndoRecord.cs
- AppDomain.cs
- SmtpDigestAuthenticationModule.cs
- GridViewUpdateEventArgs.cs
- ListBase.cs
- MediaEntryAttribute.cs
- DataPointer.cs
- ConnectionConsumerAttribute.cs
- SemanticResolver.cs
- CRYPTPROTECT_PROMPTSTRUCT.cs
- AuthenticationService.cs
- IPEndPoint.cs
- HttpHandlersSection.cs
- BaseParaClient.cs
- ResourceWriter.cs
- DeclarativeCatalogPart.cs
- ProgressBarAutomationPeer.cs
- CircleEase.cs
- ContextQuery.cs
- RubberbandSelector.cs
- Rect3D.cs
- EntityParameter.cs
- TextViewBase.cs
- CompoundFileIOPermission.cs
- HandlerWithFactory.cs
- StrongNameUtility.cs
- MediaContext.cs
- ComplexLine.cs
- MouseDevice.cs
- prompt.cs
- COM2Properties.cs
- SqlUdtInfo.cs
- XmlAutoDetectWriter.cs
- DataGrid.cs
- ConfigurationLocationCollection.cs
- Native.cs
- HttpCookie.cs
- OleDbError.cs
- ReferenceConverter.cs
- GlyphsSerializer.cs
- DesignSurfaceEvent.cs
- ToolStripSeparatorRenderEventArgs.cs
- Line.cs
- TraceEventCache.cs
- FieldToken.cs
- RelationshipNavigation.cs
- PreviewPageInfo.cs
- ParagraphVisual.cs
- ObservableCollectionDefaultValueFactory.cs
- EntityProviderServices.cs
- Base64Encoder.cs
- CommonBehaviorsSection.cs
- XDRSchema.cs
- SystemUdpStatistics.cs
- ContactManager.cs
- DataGridViewAutoSizeColumnsModeEventArgs.cs
- ILGenerator.cs
- TextureBrush.cs
- SourceFileInfo.cs
- httpapplicationstate.cs
- DBConnection.cs
- Drawing.cs
- SchemaNotation.cs
- ExpressionReplacer.cs
- DetailsViewDeleteEventArgs.cs
- XmlAnyElementAttributes.cs
- LoadMessageLogger.cs
- TogglePatternIdentifiers.cs
- ControlOperationInvoker.cs
- UiaCoreApi.cs
- TextEditorTables.cs
- StateChangeEvent.cs
- SettingsPropertyIsReadOnlyException.cs
- MappingException.cs