Exemple #1
0
        public static int SignFile(string hash, string container, string str_store, string pin, string timestamp_url, string str_mode, string fileToSign, string timestamp_algorithm)
        {
            var certHash           = hash ?? options.hash;
            var containerName      = container ?? options.container ?? Properties.Settings.Default.Container;
            var targetStore        = str_store ?? options.store ?? Properties.Settings.Default.Store;
            var tokenPin           = pin ?? options.pin;
            var timestampUrl       = timestamp_url ?? options.timestamp_url ?? Properties.Settings.Default.TimestampUrl;
            var mode               = str_mode ?? options.mode ?? Properties.Settings.Default.Mode;
            var timestampAlgorithm = timestamp_algorithm ?? options.timestamp_argorithm ?? Properties.Settings.Default.TimestampAlgorithm;
            var verbose            = options.verbose;

            try
            {
                var signMode = ParseMode(mode);
                var store    = ParseStore(targetStore);

                // string szOID_NIST_sha256 = "2.16.840.1.101.3.4.2.1";
                CodeSigner.SignFile(certHash, tokenPin, containerName, store, fileToSign, timestampUrl,
                                    signMode, null, new Logger(verbose), timestampAlgorithm);

                return(0);
            }
            catch (SigningException ex)
            {
                Console.Error.WriteLine("Signing operation failed. Error details:");
                Console.Error.WriteLine(ex.GetBaseException().Message);

                return(2);
            }
        }
Exemple #2
0
        /**
         * Using the stub IPA previously compiled on the Mac, create a new IPA with assets
         */
        static public void RepackageIPAFromStub()
        {
            if (string.IsNullOrEmpty(Config.RepackageStagingDirectory) || !Directory.Exists(Config.RepackageStagingDirectory))
            {
                Program.Error("Directory specified with -stagedir could not be found!");
                return;
            }


            DateTime             StartTime  = DateTime.Now;
            CodeSignatureBuilder CodeSigner = null;

            // Clean the staging directory
            Program.ExecuteCommand("Clean", null);

            // Create a copy of the IPA so as to not trash the original
            ZipFile Zip = SetupWorkIPA();

            if (Zip == null)
            {
                return;
            }

            string ZipWorkingDir = String.Format("Payload/{0}{1}.app/", Program.GameName, Program.Architecture);

            FileOperations.ZipFileSystem FileSystem = new FileOperations.ZipFileSystem(Zip, ZipWorkingDir);

            // Check for a staged plist that needs to be merged into the main one
            {
                // Determine if there is a staged one we should try to use instead
                string PossiblePList = Path.Combine(Config.RepackageStagingDirectory, "Info.plist");
                if (File.Exists(PossiblePList))
                {
                    if (Config.bPerformResignWhenRepackaging)
                    {
                        Program.Log("Found Info.plist ({0}) in stage, which will be merged in with stub plist contents", PossiblePList);

                        // Merge the two plists, using the staged one as the authority when they conflict
                        byte[] StagePListBytes = File.ReadAllBytes(PossiblePList);
                        string StageInfoString = Encoding.UTF8.GetString(StagePListBytes);

                        byte[] StubPListBytes          = FileSystem.ReadAllBytes("Info.plist");
                        Utilities.PListHelper StubInfo = new Utilities.PListHelper(Encoding.UTF8.GetString(StubPListBytes));

                        StubInfo.MergePlistIn(StageInfoString);

                        // Write it back to the cloned stub, where it will be used for all subsequent actions
                        byte[] MergedPListBytes = Encoding.UTF8.GetBytes(StubInfo.SaveToString());
                        FileSystem.WriteAllBytes("Info.plist", MergedPListBytes);
                    }
                    else
                    {
                        Program.Warning("Found Info.plist ({0}) in stage that will be ignored; IPP cannot combine it with the stub plist since -sign was not specified", PossiblePList);
                    }
                }
            }

            // Get the name of the executable file
            string CFBundleExecutable;

            {
                // Load the .plist from the stub
                byte[] RawInfoPList = FileSystem.ReadAllBytes("Info.plist");

                Utilities.PListHelper Info = new Utilities.PListHelper(Encoding.UTF8.GetString(RawInfoPList));

                // Get the name of the executable file
                if (!Info.GetString("CFBundleExecutable", out CFBundleExecutable))
                {
                    throw new InvalidDataException("Info.plist must contain the key CFBundleExecutable");
                }
            }

            // Tell the file system about the executable file name so that we can set correct attributes on
            // the file when zipping it up
            FileSystem.ExecutableFileName = CFBundleExecutable;

            // Prepare for signing if requested
            if (Config.bPerformResignWhenRepackaging)
            {
                // Start the resign process (load the mobileprovision and info.plist, find the cert, etc...)
                CodeSigner            = new CodeSignatureBuilder();
                CodeSigner.FileSystem = FileSystem;

                CodeSigner.PrepareForSigning();

                // Merge in any user overrides that exist
                UpdateVersion(CodeSigner.Info);
            }

            // Empty the current staging directory
            FileOperations.DeleteDirectory(new DirectoryInfo(Config.PCStagingRootDir));

            // we will zip files in the pre-staged payload dir
            string ZipSourceDir = Config.RepackageStagingDirectory;

            // Save the zip
            Program.Log("Saving IPA ...");

            FilesBeingModifiedToPrintOut.Clear();
            Zip.SaveProgress += UpdateSaveProgress;

            Zip.CompressionLevel = (Ionic.Zlib.CompressionLevel)Config.RecompressionSetting;

            // Add all of the payload files, replacing existing files in the stub IPA if necessary (should only occur for icons)
            {
                string   SourceDir    = Path.GetFullPath(ZipSourceDir);
                string[] PayloadFiles = Directory.GetFiles(SourceDir, "*.*", SearchOption.AllDirectories);
                foreach (string Filename in PayloadFiles)
                {
                    // Get the relative path to the file (this implementation only works because we know the files are all
                    // deeper than the base dir, since they were generated from a search)
                    string AbsoluteFilename = Path.GetFullPath(Filename);
                    string RelativeFilename = AbsoluteFilename.Substring(SourceDir.Length + 1).Replace('\\', '/');

                    string ZipAbsolutePath = String.Format("Payload/{0}{1}.app/{1}",
                                                           Program.GameName,
                                                           Program.Architecture,
                                                           RelativeFilename);

                    byte[] FileContents = File.ReadAllBytes(AbsoluteFilename);
                    if (FileContents.Length == 0)
                    {
                        // Zero-length files added by Ionic cause installation/upgrade to fail on device with error 0xE8000050
                        // We store a single byte in the files as a workaround for now
                        FileContents    = new byte[1];
                        FileContents[0] = 0;
                    }

                    FileSystem.WriteAllBytes(RelativeFilename, FileContents);

                    if ((FileContents.Length >= 1024 * 1024) || (Config.bVerbose))
                    {
                        FilesBeingModifiedToPrintOut.Add(ZipAbsolutePath);
                    }
                }
            }

            // Re-sign the executable if there is a signing context
            if (CodeSigner != null)
            {
                if (Config.OverrideBundleName != null)
                {
                    CodeSigner.Info.SetString("CFBundleDisplayName", Config.OverrideBundleName);
                    string CFBundleIdentifier;
                    if (CodeSigner.Info.GetString("CFBundleIdentifier", out CFBundleIdentifier))
                    {
                        CodeSigner.Info.SetString("CFBundleIdentifier", CFBundleIdentifier + "_" + Config.OverrideBundleName);
                    }
                }
                CodeSigner.PerformSigning();
            }

            // Stick in the iTunesArtwork PNG if available
            string iTunesArtworkPath = Path.Combine(Config.BuildDirectory, "iTunesArtwork");

            if (File.Exists(iTunesArtworkPath))
            {
                Zip.UpdateFile(iTunesArtworkPath, "");
            }

            // Save the Zip

            Program.Log("Compressing files into IPA (-compress={1}).{0}", Config.bVerbose ? "" : "  Only large files will be listed next, but other files are also being packaged.", Config.RecompressionSetting);
            FileSystem.Close();

            TimeSpan ZipLength = DateTime.Now - StartTime;

            FileInfo FinalZipInfo = new FileInfo(Zip.Name);


            Program.Log(String.Format("Finished repackaging into {2:0.00} MB IPA, written to '{0}' (took {1:0.00} s for all steps)",
                                      Zip.Name,
                                      ZipLength.TotalSeconds,
                                      FinalZipInfo.Length / (1024.0f * 1024.0f)));
        }