private FileName TrackFile(string fileFullPath) { var signInfo = ExtractSignInfo(fileFullPath); var fileName = new FileName(fileFullPath, signInfo); if (signInfo.IsAlreadySigned) { _log.LogMessage($"Ignoring already signed file: {fileFullPath}"); } else if (signInfo.ShouldIgnore) { _log.LogMessage($"Ignoring signing for this file: {fileFullPath}"); } else { if (FileName.IsZipContainer(fileFullPath)) { if (BuildZipData(fileName, out var zipData)) { _zipDataMap[fileName] = zipData; } } _filesToSign.Add(fileName); _log.LogMessage($"New file to sign: {fileName}"); } return(fileName); }
/// <summary> /// Build up the <see cref="ZipData"/> instance for a given zip container. This will also report any consistency /// errors found when examining the zip archive. /// </summary> private bool BuildZipData(FileName zipFileName, out ZipData zipData) { Debug.Assert(zipFileName.IsZipContainer()); Package package = null; try { package = Package.Open(zipFileName.FullPath, FileMode.Open, FileAccess.Read); var packageTempDir = Path.Combine(_pathToContainerUnpackingDirectory, Guid.NewGuid().ToString()); var nestedParts = new List <ZipPart>(); foreach (var part in package.GetParts()) { var relativePath = GetPartRelativeFileName(part); var packagePartTempName = Path.Combine(packageTempDir, relativePath); var packagePartTempDirectory = Path.GetDirectoryName(packagePartTempName); if (!FileName.IsZipContainer(packagePartTempName) && !FileName.IsPEFile(packagePartTempName)) { continue; } Directory.CreateDirectory(packagePartTempDirectory); using (var tempFileStream = File.OpenWrite(packagePartTempName)) { part.GetStream().CopyTo(tempFileStream); tempFileStream.Close(); } var partFileName = TrackFile(packagePartTempName); nestedParts.Add(new ZipPart(relativePath, partFileName, null, partFileName.SignInfo)); } zipData = new ZipData(zipFileName, nestedParts.ToImmutableList()); return(true); } catch (Exception e) { _log.LogErrorFromException(e); zipData = null; return(false); } finally { package?.Close(); } }
private SignInfo ExtractSignInfo(string fileFullPath) { if (FileName.IsPEFile(fileFullPath)) { using (var stream = File.OpenRead(fileFullPath)) { if (ContentUtil.IsAssemblyStrongNameSigned(stream)) { return(SignInfo.AlreadySigned); } } if (!IsManaged(fileFullPath)) { return(new SignInfo(SignToolConstants.Certificate_MicrosoftSHA2, null)); } else { var fileAsm = System.Reflection.AssemblyName.GetAssemblyName(fileFullPath); var pktBytes = fileAsm.GetPublicKeyToken(); var publicKeyToken = (pktBytes == null || pktBytes.Length == 0) ? string.Empty : string.Join("", pktBytes.Select(b => b.ToString("x2"))); var targetFramework = GetTargetFrameworkName(fileFullPath).FullName; var fileName = Path.GetFileName(fileFullPath); var keyForAllTargets = new ExplicitCertificateKey(fileName, publicKeyToken, SignToolConstants.AllTargetFrameworksSentinel); var keyForSpecificTarget = new ExplicitCertificateKey(fileName, publicKeyToken, targetFramework); // Do we need to override the default certificate this file ? if (_explicitCertificates.TryGetValue(keyForSpecificTarget, out var overridingCertificate) || _explicitCertificates.TryGetValue(keyForAllTargets, out overridingCertificate)) { // If has overriding info, is it for ignoring the file? if (overridingCertificate != null && overridingCertificate.Equals(SignToolConstants.IgnoreFileCertificateSentinel)) { return(SignInfo.Ignore); // should ignore this file } // Otherwise, just use the overriding info if present } if (publicKeyToken == string.Empty) { if (string.IsNullOrEmpty(overridingCertificate)) { _log.LogError($"SignInfo for file ({fileFullPath}) and empty PKT not found. Expected it to be informed in overriding infos."); return(SignInfo.Empty); } return(new SignInfo(overridingCertificate, string.Empty)); } if (_defaultSignInfoForPublicKeyToken.ContainsKey(publicKeyToken)) { var signInfo = _defaultSignInfoForPublicKeyToken[publicKeyToken]; var certificate = overridingCertificate ?? signInfo.Certificate; return(new SignInfo(certificate, signInfo.StrongName, signInfo.ShouldIgnore, signInfo.IsEmpty, signInfo.IsAlreadySigned)); } _log.LogError($"SignInfo for file ({fileFullPath}) with Public Key Token {publicKeyToken} not found."); return(SignInfo.Empty); } } else if (FileName.IsZipContainer(fileFullPath)) { return(new SignInfo(FileName.IsNupkg(fileFullPath) ? SignToolConstants.Certificate_NuGet : SignToolConstants.Certificate_VsixSHA2, null)); } else { _log.LogWarning($"Unidentified artifact type: {fileFullPath}"); return(SignInfo.Ignore); } }