/// <summary> /// Sign all of the assembly files. No need to consider nesting here and it can be done in a single pass. /// </summary> private void SignAssemblies() { Console.WriteLine("Signing assemblies"); foreach (var name in _batchData.AssemblyNames) { Console.WriteLine($"\t{name.RelativePath}"); } _signTool.Sign(_batchData.AssemblyNames.Select(x => _batchData.BinarySignDataMap[x])); }
/// <summary> /// Sign all of the assembly files. No need to consider nesting here and it can be done in a single pass. /// </summary> private void SignFlatFiles() { Console.WriteLine("Signing files"); var otherFiles = _batchData.FileNames.Where(x => !x.IsVsix); foreach (var name in otherFiles) { Console.WriteLine($"\t{name.RelativePath}"); } _signTool.Sign(otherFiles.Select(x => _batchData.FileSignDataMap[x])); }
/// <summary> /// Actually sign all of the described files. /// </summary> private bool SignFiles(ContentMap contentMap, Dictionary <FileName, ZipData> zipDataMap, TextWriter textWriter) { // Generate the list of signed files in a deterministic order. Makes it easier to track down // bugs if repeated runs use the same ordering. var toSignList = _batchData.FileNames.ToList(); var round = 0; var signedSet = new HashSet <FileName>(); void signFiles(IEnumerable <FileName> files) { textWriter.WriteLine($"Signing Round {round}"); foreach (var name in files) { textWriter.WriteLine($"\t{name}"); } _signTool.Sign(round, files.Select(x => _batchData.FileSignInfoMap[x]).Where(x => !x.IsEmpty), textWriter); } void repackFiles(IEnumerable <FileName> files) { var any = false; foreach (var file in files) { if (file.IsZipContainer) { if (!any) { textWriter.WriteLine("Repacking"); any = true; } textWriter.WriteLine($"\t{file}"); Repack(zipDataMap[file]); } } } // Is this file ready to be signed? That is are all of the items that it depends on already // signed? bool isReadyToSign(FileName fileName) { if (!fileName.IsZipContainer) { return(true); } var zipData = zipDataMap[fileName]; return(zipData.NestedParts.All(x => signedSet.Contains(x.FileName))); } // Extract the next set of files that should be signed. This is the set of files for which all of the // dependencies have been signed. List <FileName> extractNextGroup() { var list = new List <FileName>(); var i = 0; while (i < toSignList.Count) { var current = toSignList[i]; if (isReadyToSign(current)) { list.Add(current); toSignList.RemoveAt(i); } else { i++; } } return(list); } try { while (toSignList.Count > 0) { var list = extractNextGroup(); if (list.Count == 0) { throw new Exception("No progress made on signing which indicates a bug"); } repackFiles(list); signFiles(list); round++; list.ForEach(x => signedSet.Add(x)); } return(true); } catch (Exception ex) { textWriter.WriteLine($"Signing failed: {ex.Message}"); return(false); } }