private void ResignIPA(IPAFile ipaFile, byte[] mobileProvisionBytes, byte[] signingCertificateBytes, string certificatePassword, string outputIPAPath) { // Validate that the mobileprovision match the given certificate MobileProvisionFile mobileProvision; if (mobileProvisionBytes == null) { mobileProvision = ipaFile.GetMobileProvision(); } else { mobileProvision = new MobileProvisionFile(mobileProvisionBytes); } List <byte[]> developerCertificates = mobileProvision.PList.DeveloperCertificates; if (developerCertificates.Count == 0) { MessageBox.Show("Mobile Provision does not contain developer certificate information", "Error"); return; } AsymmetricKeyEntry privateKey; X509Certificate signingCertificate = CertificateHelper.GetCertificateAndKeyFromBytes(signingCertificateBytes, certificatePassword, out privateKey); if (signingCertificate == null) { MessageBox.Show("Failed to parse the given signing certificate", "Error"); return; } bool foundMatchingCertificate = false; for (int index = 0; index < developerCertificates.Count; index++) { X509Certificate provisionedCertificate = CertificateHelper.GetCertificatesFromBytes(developerCertificates[index]); if (provisionedCertificate.Equals(signingCertificate)) { foundMatchingCertificate = true; } } if (!foundMatchingCertificate) { MessageBox.Show("The signing certificate given does not match any specified in the Mobile Provision file", "Error"); return; } List <X509Certificate> certificateStore; try { certificateStore = ReadCertificatesDirectory(); } catch { MessageBox.Show("Failed to read certificate directory", "Error"); return; } List <X509Certificate> certificateChain = CertificateHelper.BuildCertificateChain(signingCertificate, certificateStore); if (mobileProvisionBytes != null) { ipaFile.ReplaceMobileProvision(mobileProvisionBytes); } if (ipaFile.HasFrameworksFolder) { MessageBox.Show("Signing an IPA containing a framework is not supported", "Not supported"); return; } ipaFile.ResignIPA(certificateChain, privateKey); try { ipaFile.Save(outputIPAPath); } catch (IOException ex) { MessageBox.Show("Failed to save output IPA: " + ex.Message, "Error"); return; } MessageBox.Show("Done!"); }
private void ResignIPA(IPAFile ipaFile, byte[] mobileProvisionBytes, byte[] signingCertificateBytes, string certificatePassword, string outputIPAPath) { // Validate that the mobileprovision match the given certificate MobileProvisionFile mobileProvision; if (mobileProvisionBytes == null) { mobileProvision = ipaFile.GetMobileProvision(); } else { mobileProvision = new MobileProvisionFile(mobileProvisionBytes); } if (mobileProvision.PList.DeveloperCertificates.Count == 0) { MessageBox.Show("Mobile Provision does not contain developer certificate information", "Error"); return; } X509Certificate provisionedCertificate = CertificateHelper.GetCertificatesFromBytes(mobileProvision.PList.DeveloperCertificates[0]); AsymmetricKeyEntry privateKey; X509Certificate signingCertificate = CertificateHelper.GetCertificateAndKeyFromBytes(signingCertificateBytes, certificatePassword, out privateKey); if (signingCertificate == null) { MessageBox.Show("Failed to parse the given signing certificate", "Error"); return; } if (!provisionedCertificate.Equals(signingCertificate)) { MessageBox.Show("The signing certificate given does not match the one specified in the Mobile Provision file", "Error"); return; } List <X509Certificate> certificateStore; try { certificateStore = ReadCertificatesDirectory(); } catch { MessageBox.Show("Failed to read certificate directory", "Error"); return; } List <X509Certificate> certificateChain = CertificateHelper.BuildCertificateChain(signingCertificate, certificateStore); if (mobileProvisionBytes != null) { ipaFile.ReplaceMobileProvision(mobileProvisionBytes); } ipaFile.ResignIPA(certificateChain, privateKey); try { ipaFile.Save(outputIPAPath); } catch (IOException ex) { MessageBox.Show("Failed to save output IPA: " + ex.Message, "Error"); return; } MessageBox.Show("Done!"); }