public void VerifyStrongName(SignatureVerificationResult svr, PortableExecutableHeader portableExecutableHeader) { if (portableExecutableHeader.IsManagedCode) { svr.IsNativeImage = !portableExecutableHeader.IsILImage; // NGEN/CrossGen don't preserve StrongName signatures. if (!svr.IsNativeImage) { bool wasVerified = false; int hresult = StrongName.ClrStrongName.StrongNameSignatureVerificationEx(svr.FullPath, fForceVerification: true, pfWasVerified: out wasVerified); svr.IsStrongNameSigned = hresult == StrongName.S_OK; svr.AddDetail(DetailKeys.StrongName, SignCheckResources.DetailSignedStrongName, svr.IsStrongNameSigned); if (hresult != StrongName.S_OK) { svr.AddDetail(DetailKeys.StrongName, SignCheckResources.DetailHResult, hresult); } else { string publicToken; hresult = StrongName.GetStrongNameTokenFromAssembly(svr.FullPath, out publicToken); if (hresult == StrongName.S_OK) { svr.AddDetail(DetailKeys.StrongName, SignCheckResources.DetailPublicKeyToken, publicToken); } } } else { svr.AddDetail(DetailKeys.StrongName, SignCheckResources.DetailNativeImage); } } }
/// <summary> /// Verify whether the portable executable contains an AuthentiCode signature and optionally check the /// StrongName signature if it is enabled and the file represents a managed code executable. /// </summary> /// <param name="path"></param> /// <param name="parent"></param> /// <returns></returns> public override SignatureVerificationResult VerifySignature(string path, string parent) { // Defer to the base implementation to check the AuthentiCode signature. SignatureVerificationResult svr = base.VerifySignature(path, parent); PEHeader = new PortableExecutableHeader(svr.FullPath); if (VerifyStrongNameSignature) { VerifyStrongName(svr, PEHeader); } svr.IsSigned = svr.IsAuthentiCodeSigned & ((svr.IsStrongNameSigned) || (!VerifyStrongNameSignature) || svr.IsNativeImage); svr.AddDetail(DetailKeys.File, SignCheckResources.DetailSigned, svr.IsSigned); return(svr); }
/// <summary> /// Retrieves a FileVerifier by looking at the header of the file to determine its type to assign an extension to it. /// </summary> /// <param name="path">The path of the file.</param> /// <returns>A FileVerifier that can verify the file or null if the verifier could not be found.</returns> public static FileVerifier GetFileVerifierByHeader(string path) { if (String.IsNullOrEmpty(path)) { throw new ArgumentException(String.Format(SignCheckResources.ArgumentNullOrEmpty, "path")); } FileVerifier fileVerifier = null; using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var reader = new BinaryReader(stream)) { // Test for 4-byte magic numbers if (stream.Length > 4) { uint magic4 = reader.ReadUInt32(); if (magic4 == FileHeaders.Zip) { using (ZipArchive zipArchive = ZipFile.OpenRead(path)) { if (zipArchive.Entries.Any(z => String.Equals(Path.GetExtension(z.FullName), "nuspec", StringComparison.OrdinalIgnoreCase))) { // NUPKGs use .zip format, but should have a .nuspec files inside fileVerifier = GetFileVerifierByExtension(".nupkg"); } else if (zipArchive.Entries.Any(z => String.Equals(Path.GetExtension(z.FullName), "vsixmanifest", StringComparison.OrdinalIgnoreCase))) { // If it's an SDK based VSIX there should be a vsixmanifest file fileVerifier = GetFileVerifierByExtension(".vsix"); } else if (zipArchive.Entries.Any(z => String.Equals(z.FullName, "META-INF/MANIFEST.MF", StringComparison.OrdinalIgnoreCase))) { // Zip file with META-INF/MANIFEST.MF file is likely a JAR fileVerifier = GetFileVerifierByExtension(".jar"); } else { fileVerifier = GetFileVerifierByExtension(".zip"); } } } else if (magic4 == FileHeaders.Cab) { fileVerifier = GetFileVerifierByExtension(".cab"); } } reader.BaseStream.Seek(0, SeekOrigin.Begin); if (stream.Length > 2) { UInt16 magic2 = reader.ReadUInt16(); if (magic2 == FileHeaders.Dos) { PortableExecutableHeader pe = new PortableExecutableHeader(path); if ((pe.FileHeader.Characteristics & ImageFileCharacteristics.IMAGE_FILE_DLL) != 0) { fileVerifier = GetFileVerifierByExtension(".dll"); } else if ((pe.FileHeader.Characteristics & ImageFileCharacteristics.IMAGE_FILE_EXECUTABLE_IMAGE) != 0) { fileVerifier = GetFileVerifierByExtension(".exe"); } } } } return(fileVerifier); }