Exemplo n.º 1
0
        public static void TryInstallingMobileProvision(string ProvisionFilename, bool ShowPrompt = true)
        {
            if (!String.IsNullOrEmpty(ProvisionFilename) || ShowOpenFileDialog(MobileProvisionFilter, "Choose a mobile provision to install", "mobileprovision", "", ref ChoosingFilesToInstallDirectory, out ProvisionFilename))
            {
                try
                {
                    // Determine if this is a development or distribution certificate
                    bool            bIsDistribution = false;
                    MobileProvision Provision       = MobileProvisionParser.ParseFile(ProvisionFilename);
                    bIsDistribution = IsProfileForDistribution(Provision);

                    // use the input filename if the GameName is empty
                    string DestName = string.IsNullOrEmpty(Program.GameName) ? Path.GetFileNameWithoutExtension(ProvisionFilename) : Program.GameName;

                    // Copy the file into the destination location
                    string EffectivePrefix     = bIsDistribution ? "Distro_" : Config.SigningPrefix;
                    string DestinationFilename = Path.Combine(Config.ProvisionDirectory, EffectivePrefix + DestName + ".mobileprovision");

                    DestinationFilename = DestinationFilename.Replace("\\", "/");
                    if (File.Exists(DestinationFilename))
                    {
                        MobileProvision OldProvision = MobileProvisionParser.ParseFile(DestinationFilename);

                        string MessagePrompt = String.Format(
                            "{0} already contains a {1} mobile provision file.  Do you want to replace the provision '{2}' with '{3}'?",
                            Config.BuildDirectory,
                            bIsDistribution ? "distribution" : "development",
                            OldProvision.ProvisionName,
                            Provision.ProvisionName);

                        if (ShowPrompt && System.Windows.Forms.MessageBox.Show(MessagePrompt, Config.AppDisplayName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                        {
                            return;
                        }

                        if (DestinationFilename != ProvisionFilename)
                        {
                            FileOperations.DeleteFile(DestinationFilename);
                        }
                    }

                    if (DestinationFilename != ProvisionFilename)
                    {
                        FileOperations.CopyRequiredFile(ProvisionFilename, DestinationFilename);
                    }
                }
                catch (Exception ex)
                {
                    ShowError(String.Format("Encountered an error '{0} while trying to install a mobile provision", ex.Message));
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Merges a certificate and private key into a single combined certificate
        /// </summary>
        public static X509Certificate2 CombineKeyAndCert(string CertificateFilename, string KeyFilename)
        {
            // Load the certificate
            string           CertificatePassword = "";
            X509Certificate2 Cert = new X509Certificate2(CertificateFilename, CertificatePassword, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);

            // Make sure we have a useful friendly name
            string FriendlyName = Cert.FriendlyName;

            if ((FriendlyName == "") || (FriendlyName == null))
            {
                FriendlyName = GetCommonNameFromCert(Cert);
            }

            // Create a PKCS#12 store with both the certificate and the private key in it
            Pkcs12Store Store = new Pkcs12StoreBuilder().Build();

            X509CertificateEntry[] CertChain = new X509CertificateEntry[1];
            Org.BouncyCastle.X509.X509Certificate BouncyCert = DotNetUtilities.FromX509Certificate(Cert);
            CertChain[0] = new X509CertificateEntry(BouncyCert);

            AsymmetricCipherKeyPair KeyPair = LoadKeyPairFromDiskBouncy(KeyFilename);

            Store.SetKeyEntry(FriendlyName, new AsymmetricKeyEntry(KeyPair.Private), CertChain);

            // Verify the public key from the key pair matches the certificate's public key
            AsymmetricKeyParameter CertPublicKey = BouncyCert.GetPublicKey();

            if (!(KeyPair.Public as RsaKeyParameters).Equals(CertPublicKey as RsaKeyParameters))
            {
                throw new InvalidDataException("The key pair provided does not match the certificate.  Make sure you provide the same key pair that was used to generate the original certificate signing request");
            }

            // Export the merged cert as a .p12
            string TempFileName = Path.GetTempFileName();

            string ReexportedPassword = "******";

            Stream OutStream = File.OpenWrite(TempFileName);

            Store.Save(OutStream, ReexportedPassword.ToCharArray(), new Org.BouncyCastle.Security.SecureRandom());
            OutStream.Close();

            // Load it back in and delete the temporary file
            X509Certificate2 Result = new X509Certificate2(TempFileName, ReexportedPassword, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

            FileOperations.DeleteFile(TempFileName);
            return(Result);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a copy of a source IPA to a working path and opens it up as a Zip for further modifications
        /// </summary>
        static private ZipFile CreateWorkingIPA(string SourceIPAPath, string WorkIPAPath)
        {
            FileInfo ReferenceInfo = new FileInfo(SourceIPAPath);

            if (!ReferenceInfo.Exists)
            {
                Program.Error(String.Format("Failed to find stub IPA '{0}'", SourceIPAPath));
                return(null);
            }
            else
            {
                Program.Log(String.Format("Loaded stub IPA from '{0}' ...", SourceIPAPath));
            }

            if (Program.GameName == "UE4Game")
            {
                WorkIPAPath = Config.RemapIPAPath(".ipa");
            }

            // Make sure there are no stale working copies around
            FileOperations.DeleteFile(WorkIPAPath);

            // Create a working copy of the IPA
            FileOperations.CopyRequiredFile(SourceIPAPath, WorkIPAPath);

            // Open up the zip file
            ZipFile Stub = ZipFile.Read(WorkIPAPath);

            // Do a few quick spot checks to catch problems that may have occurred earlier
            bool bHasCodeSignature   = Stub[Config.AppDirectoryInZIP + "/_CodeSignature/CodeResources"] != null;
            bool bHasMobileProvision = Stub[Config.AppDirectoryInZIP + "/embedded.mobileprovision"] != null;

            if (!bHasCodeSignature || !bHasMobileProvision)
            {
                Program.Error("Stub IPA does not appear to be signed correctly (missing mobileprovision or CodeResources)");
                Program.ReturnCode = (int)ErrorCodes.Error_StubNotSignedCorrectly;
            }

            // Set encoding to support unicode filenames
            Stub.AlternateEncodingUsage = ZipOption.Always;
            Stub.AlternateEncoding      = Encoding.UTF8;

            return(Stub);
        }
Exemplo n.º 4
0
        private void ResignButton_Click(object sender, EventArgs e)
        {
            saveFileDialog1.DefaultExt = "ipa";
            saveFileDialog1.FileName   = "";
            saveFileDialog1.Filter     = ToolsHub.IpaFilter;
            saveFileDialog1.Title      = "Choose a filename for the re-signed IPA";

            string CWD = Directory.GetCurrentDirectory();
            bool   bDialogSucceeded = (saveFileDialog1.ShowDialog() == DialogResult.OK);

            Directory.SetCurrentDirectory(CWD);

            if (bDialogSucceeded)
            {
                bool bSavedVerbose = Config.bVerbose;
                Config.bVerbose = true;
                Program.ProgressDialog.OnBeginBackgroundWork = delegate
                {
                    string SrcFilename  = IPAFilenameEdit.Text;
                    string DestFilename = saveFileDialog1.FileName;

                    // Delete the target location and copy the source there
                    FileOperations.DeleteFile(DestFilename);
                    FileOperations.CopyRequiredFile(SrcFilename, DestFilename);

                    // Open the file
                    FileOperations.ZipFileSystem FileSystem = new FileOperations.ZipFileSystem(DestFilename);
                    FileSystem.SetCompression(CBCompressModifiedFiles.Checked ? Ionic.Zlib.CompressionLevel.BestCompression : Ionic.Zlib.CompressionLevel.None);

                    // Resign and save the file
                    ResignIPA(FileSystem);
                    FileSystem.Close();
                };
                Config.bVerbose = bSavedVerbose;

                Program.ProgressDialog.ShowDialog();
            }
        }