IList<MobileProvision> GetProvisioningProfiles (MobileProvisionPlatform platform, MobileProvisionDistributionType type, CodeSignIdentity identity, IList<X509Certificate2> certs) { var failures = new List<string> (); IList<MobileProvision> profiles; if (identity.BundleId != null) { if (certs.Count > 0) profiles = MobileProvisionIndex.GetMobileProvisions (platform, identity.BundleId, type, certs, unique: true, failures: failures); else profiles = MobileProvisionIndex.GetMobileProvisions (platform, identity.BundleId, type, unique: true, failures: failures); } else if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions (platform, type, certs, unique: true, failures: failures); } else { profiles = MobileProvisionIndex.GetMobileProvisions (platform, type, unique: true, failures: failures); } if (profiles.Count == 0) { foreach (var f in failures) Log.LogMessage (MessageImportance.Low, "{0}", f); Log.LogError (MSBStrings.E0131, AppBundleName, PlatformName); return null; } Log.LogMessage (MessageImportance.Low, "Available profiles:"); foreach (var p in profiles) Log.LogMessage (MessageImportance.Low, " {0}", p.Name); return profiles; }
public override bool Execute() { var profile = MobileProvisionIndex.GetMobileProvision(GetMobileProvisionPlatform(), ProvisioningProfile); if (profile == null) { Log.LogError(MSBStrings.E0049, ProvisioningProfile); return(false); } var embedded = EmbeddedProvisionProfilePath; if (File.Exists(embedded)) { var embeddedProfile = MobileProvision.LoadFromFile(embedded); if (embeddedProfile.Uuid == profile.Uuid) { return(true); } } Directory.CreateDirectory(Path.GetDirectoryName(embedded)); profile.Save(embedded); return(true); }
public void TestOpenIndex() { var index = MobileProvisionIndex.OpenIndex("../../TestData/Provisioning Profiles", "profiles.index"); Assert.AreEqual(2, index.ProvisioningProfiles.Count); Assert.AreEqual("YHT9CR87YA.com.companyname.*", index.ProvisioningProfiles[0].ApplicationIdentifier); Assert.AreEqual(new DateTime(2017, 07, 19, 19, 43, 45, DateTimeKind.Utc), index.ProvisioningProfiles[0].CreationDate); Assert.AreEqual(1, index.ProvisioningProfiles[0].DeveloperCertificates.Count); Assert.AreEqual("iPhone Developer: Jeffrey Stedfast (FZ77UAV9SW)", index.ProvisioningProfiles[0].DeveloperCertificates[0].Name); Assert.AreEqual("2097D37F4D16AB7D8D927E7C1872F2A94D8DC718", index.ProvisioningProfiles[0].DeveloperCertificates[0].Thumbprint); Assert.AreEqual(MobileProvisionDistributionType.Development, index.ProvisioningProfiles[0].Distribution); Assert.AreEqual(new DateTime(2018, 07, 19, 19, 43, 45, DateTimeKind.Utc), index.ProvisioningProfiles[0].ExpirationDate); Assert.AreEqual("29cbf4b4-a170-4c74-a29a-64ecd55b102e.mobileprovision", Path.GetFileName(index.ProvisioningProfiles[0].FileName)); //Assert.AreEqual (index.ProvisioningProfiles[0].LastModified); Assert.AreEqual("CompanyName Development Profile", index.ProvisioningProfiles[0].Name); Assert.AreEqual(1, index.ProvisioningProfiles[0].Platforms.Count); Assert.AreEqual(MobileProvisionPlatform.iOS, index.ProvisioningProfiles[0].Platforms[0]); Assert.AreEqual("29cbf4b4-a170-4c74-a29a-64ecd55b102e", index.ProvisioningProfiles[0].Uuid); Assert.AreEqual("YHT9CR87YA.com.xamarin.*", index.ProvisioningProfiles[1].ApplicationIdentifier); Assert.AreEqual(new DateTime(2017, 07, 19, 19, 44, 0, DateTimeKind.Utc), index.ProvisioningProfiles[1].CreationDate); Assert.AreEqual(1, index.ProvisioningProfiles[1].DeveloperCertificates.Count); Assert.AreEqual("iPhone Developer: Jeffrey Stedfast (FZ77UAV9SW)", index.ProvisioningProfiles[1].DeveloperCertificates[0].Name); Assert.AreEqual("2097D37F4D16AB7D8D927E7C1872F2A94D8DC718", index.ProvisioningProfiles[1].DeveloperCertificates[0].Thumbprint); Assert.AreEqual(MobileProvisionDistributionType.Development, index.ProvisioningProfiles[1].Distribution); Assert.AreEqual(new DateTime(2018, 07, 19, 19, 44, 0, DateTimeKind.Utc), index.ProvisioningProfiles[1].ExpirationDate); Assert.AreEqual("7079f389-6ff4-4290-bf76-c8a222947616.mobileprovision", Path.GetFileName(index.ProvisioningProfiles[1].FileName)); //Assert.AreEqual (index.ProvisioningProfiles[0].LastModified); Assert.AreEqual("Xamarin Development Profile", index.ProvisioningProfiles[1].Name); Assert.AreEqual(1, index.ProvisioningProfiles[1].Platforms.Count); Assert.AreEqual(MobileProvisionPlatform.iOS, index.ProvisioningProfiles[1].Platforms[0]); Assert.AreEqual("7079f389-6ff4-4290-bf76-c8a222947616", index.ProvisioningProfiles[1].Uuid); }
public override bool Execute() { Log.LogTaskName("EmbedMobileProvision"); Log.LogTaskProperty("AppBundleDir", AppBundleDir); Log.LogTaskProperty("ProvisioningProfile", ProvisioningProfile); var profile = MobileProvisionIndex.GetMobileProvision(MobileProvisionPlatform.iOS, ProvisioningProfile); if (profile == null) { Log.LogError("Could not locate the provisioning profile with a Name or UUID of {0}.", ProvisioningProfile); return(false); } var embedded = Path.Combine(AppBundleDir, "embedded.mobileprovision"); if (File.Exists(embedded)) { var embeddedProfile = MobileProvision.LoadFromFile(embedded); if (embeddedProfile.Uuid == profile.Uuid) { return(true); } } Directory.CreateDirectory(AppBundleDir); profile.Save(embedded); return(true); }
public override bool Execute() { MobileProvisionPlatform platform; switch (SdkPlatform) { case "AppleTVSimulator": case "AppleTVOS": platform = MobileProvisionPlatform.tvOS; break; case "iPhoneSimulator": case "WatchSimulator": case "iPhoneOS": case "WatchOS": platform = MobileProvisionPlatform.iOS; break; case "MacCatalyst": platform = MobileProvisionPlatform.MacOS; break; default: Log.LogError(MSBStrings.E0048, SdkPlatform); return(false); } var profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (profile == null) { Log.LogError(MSBStrings.E0049, ProvisioningProfile); return(false); } var embedded = Path.Combine(AppBundleDir, "embedded.mobileprovision"); if (File.Exists(embedded)) { var embeddedProfile = MobileProvision.LoadFromFile(embedded); if (embeddedProfile.Uuid == profile.Uuid) { return(true); } } Directory.CreateDirectory(AppBundleDir); profile.Save(embedded); return(true); }
public override bool Execute() { MobileProvisionPlatform platform; switch (SdkPlatform) { case "AppleTVSimulator": case "AppleTVOS": platform = MobileProvisionPlatform.tvOS; break; case "iPhoneSimulator": case "WatchSimulator": case "iPhoneOS": case "WatchOS": platform = MobileProvisionPlatform.iOS; break; default: Log.LogError("Unknown SDK platform: {0}", SdkPlatform); return(false); } var profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (profile == null) { Log.LogError("Could not locate the provisioning profile with a Name or UUID of {0}.", ProvisioningProfile); return(false); } var embedded = Path.Combine(AppBundleDir, "embedded.mobileprovision"); if (File.Exists(embedded)) { var embeddedProfile = MobileProvision.LoadFromFile(embedded); if (embeddedProfile.Uuid == profile.Uuid) { return(true); } } Directory.CreateDirectory(AppBundleDir); profile.Save(embedded); return(true); }
public override bool Execute() { var profile = MobileProvisionIndex.GetMobileProvision(MobileProvisionPlatform.MacOS, ProvisioningProfile); if (profile == null) { Log.LogError(MSBStrings.E0049, ProvisioningProfile); return(false); } var embedded = Path.Combine(AppBundleDir, "Contents", "embedded.provisionprofile"); Directory.CreateDirectory(AppBundleDir); profile.Save(embedded); return(true); }
IList <MobileProvision> GetProvisioningProfiles(MobileProvisionPlatform platform, MobileProvisionDistributionType type, CodeSignIdentity identity, IList <X509Certificate2> certs) { var failures = new List <string> (); IList <MobileProvision> profiles; if (identity.BundleId != null) { if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions(platform, identity.BundleId, type, certs, unique: true, failures: failures); } else { profiles = MobileProvisionIndex.GetMobileProvisions(platform, identity.BundleId, type, unique: true, failures: failures); } } else if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions(platform, type, certs, unique: true, failures: failures); } else { profiles = MobileProvisionIndex.GetMobileProvisions(platform, type, unique: true, failures: failures); } if (profiles.Count == 0) { foreach (var f in failures) { Log.LogMessage(MessageImportance.Low, "{0}", f); } Log.LogError($"Could not find any available provisioning profiles for {PlatformName}. Please enable Automatic Provisioning from the iOS Bundle Signing page."); return(null); } Log.LogMessage(MessageImportance.Low, "Available profiles:"); foreach (var p in profiles) { Log.LogMessage(MessageImportance.Low, " {0}", p.Name); } return(profiles); }
public override bool Execute() { var profile = MobileProvisionIndex.GetMobileProvision(MobileProvisionPlatform.MacOS, ProvisioningProfile); if (profile == null) { Log.LogError("Could not locate the provisioning profile with a Name or UUID of {0}.", ProvisioningProfile); return(false); } var embedded = Path.Combine(AppBundleDir, "Contents", "embedded.provisionprofile"); Directory.CreateDirectory(AppBundleDir); profile.Save(embedded); return(true); }
protected virtual MobileProvision GetMobileProvision(MobileProvisionPlatform platform, string name) { return(MobileProvisionIndex.GetMobileProvision(platform, name)); }
public override bool Execute() { PDictionary plist; IList <MobileProvision> profiles; IList <X509Certificate2> certs; List <CodeSignIdentity> pairs; var type = GetProvisioningDistributionType(); var platform = MobileProvisionPlatform.iOS; var identity = new CodeSignIdentity(); hotRestartClient = new HotRestartClient(); try { plist = PDictionary.FromFile(AppManifest); } catch (Exception ex) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Error loading '{0}': {1}", AppManifest, ex.Message); return(false); } identity.BundleId = plist.GetCFBundleIdentifier(); if (string.IsNullOrEmpty(identity.BundleId)) { if (GenerateApplicationManifest && !string.IsNullOrEmpty(ApplicationId)) { identity.BundleId = ApplicationId; } else { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "{0} does not define CFBundleIdentifier", AppManifest); return(false); } } DetectedBundleId = identity.BundleId; var appDisplayName = plist.GetCFBundleDisplayName(); if (string.IsNullOrEmpty(appDisplayName)) { if (GenerateApplicationManifest && !string.IsNullOrEmpty(ApplicationTitle)) { appDisplayName = ApplicationTitle; } } DetectedAppDisplayName = appDisplayName; if (!TryGetSigningCertificates(out certs, false)) { return(false); } Log.LogMessage(MessageImportance.Low, "Available certificates:"); foreach (var cert in certs) { Log.LogMessage(MessageImportance.Low, " {0}", GetCertificateCommonName(cert)); } if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError("The specified " + PlatformName + " provisioning profile '{0}' could not be found. Please enable Automatic Provisioning from the iOS Bundle Signing page.", ProvisioningProfile); return(false); } var profile = identity.Profile; // capture ref for lambda if (certs.Count > 0) { identity.SigningKey = certs.FirstOrDefault(c => profile.DeveloperCertificates.Any(p => p.Thumbprint == c.Thumbprint)); if (identity.SigningKey == null) { Log.LogError("No " + PlatformName + " signing identities match the specified provisioning profile '{0}'.", ProvisioningProfile); return(false); } } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Project bundle identifier '{0}' does not match specified provisioning profile '{1}'. Please enable Automatic Provisioning from the iOS Bundle Signing page.", identity.BundleId, ProvisioningProfile); return(false); } if (identity.SigningKey != null) { codesignCommonName = GetCertificateCommonName(identity.SigningKey); DetectedCodeSigningPath = Path.Combine(CertificatesPath, $"{identity.SigningKey.SerialNumber}.p12"); } provisioningProfileName = identity.Profile.Name; DetectedAppId = identity.AppId; DetectedProvisioningProfileId = identity.Profile.Uuid; DetectedProvisioningProfilePath = Path.Combine(ProfilesPath, $"{DetectedProvisioningProfileId}.mobileprovision"); ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if ((profiles = GetProvisioningProfiles(platform, type, identity, certs)) == null) { return(false); } if ((pairs = GetCodeSignIdentityPairs(profiles, certs)) == null) { return(false); } identity = GetBestMatch(pairs, identity); if (identity.Profile != null && identity.AppId != null) { codesignCommonName = identity.SigningKey != null?GetCertificateCommonName(identity.SigningKey) : null; provisioningProfileName = identity.Profile.Name; DetectedAppId = identity.AppId; DetectedCodeSigningPath = identity.SigningKey != null?Path.Combine(CertificatesPath, $"{identity.SigningKey.SerialNumber}.p12") : string.Empty; DetectedProvisioningProfileId = identity.Profile.Uuid; DetectedProvisioningProfilePath = Path.Combine(ProfilesPath, $"{DetectedProvisioningProfileId}.mobileprovision"); ReportDetectedCodesignInfo(); } else { if (identity.SigningKey != null) { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile for selected signing identity '{0}'. Please enable Automatic Provisioning from the iOS Bundle Signing page.", identity.BundleId, identity.SigningKey); } else { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile. Please enable Automatic Provisioning from the iOS Bundle Signing page.", identity.BundleId); } } return(!Log.HasLoggedErrors); }
public override bool Execute() { var type = MobileProvisionDistributionType.Any; var identity = new CodeSignIdentity(); MobileProvisionPlatform platform; IList <MobileProvision> profiles; IList <X509Certificate2> certs; List <CodeSignIdentity> pairs; switch (SdkPlatform) { case "AppleTVSimulator": case "AppleTVOS": platform = MobileProvisionPlatform.tvOS; break; case "iPhoneSimulator": case "WatchSimulator": case "iPhoneOS": case "WatchOS": platform = MobileProvisionPlatform.iOS; break; case "MacOSX": platform = MobileProvisionPlatform.MacOS; break; case "MacCatalyst": platform = MobileProvisionPlatform.MacOS; break; default: Log.LogError(MSBStrings.E0048, SdkPlatform); return(false); } if (ProvisioningProfile == AutomaticAppStoreProvision) { type = MobileProvisionDistributionType.AppStore; } else if (ProvisioningProfile == AutomaticInHouseProvision) { type = MobileProvisionDistributionType.InHouse; } else if (ProvisioningProfile == AutomaticAdHocProvision) { type = MobileProvisionDistributionType.AdHoc; } DetectedCodesignAllocate = Path.Combine(DeveloperRoot, "Toolchains", "XcodeDefault.xctoolchain", "usr", "bin", "codesign_allocate"); DetectedDistributionType = type.ToString(); identity.BundleId = BundleIdentifier; DetectedAppId = BundleIdentifier; // default value that can be changed below if (Platform == ApplePlatform.MacOSX) { if (!RequireCodeSigning || !string.IsNullOrEmpty(DetectedCodeSigningKey)) { ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } } else if (Platform == ApplePlatform.MacCatalyst) { var doesNotNeedCodeSigningCertificate = !RequireCodeSigning || !string.IsNullOrEmpty(DetectedCodeSigningKey); if (RequireProvisioningProfile) { doesNotNeedCodeSigningCertificate = false; } if (doesNotNeedCodeSigningCertificate) { DetectedCodeSigningKey = "-"; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } } else { // Framework is either iOS, tvOS or watchOS if (SdkIsSimulator) { if (AppleSdkSettings.XcodeVersion.Major >= 8 && RequireProvisioningProfile) { // Note: Starting with Xcode 8.0, we need to codesign iOS Simulator builds that enable Entitlements // in order for them to run. The "-" key is a special value allowed by the codesign utility that // allows us to get away with not having an actual codesign key. DetectedCodeSigningKey = "-"; if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError(MSBStrings.E0140, PlatformName, ProvisioningProfile); return(false); } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(MSBStrings.E0141, identity.BundleId, ProvisioningProfile); return(false); } provisioningProfileName = identity.Profile.Name; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedDistributionType = identity.Profile.DistributionType.ToString(); } else { certs = new X509Certificate2[0]; if ((profiles = GetProvisioningProfiles(platform, type, identity, certs)) == null) { return(false); } if ((pairs = GetCodeSignIdentityPairs(profiles, certs)) == null) { return(false); } var match = GetBestMatch(pairs, identity); identity.Profile = match.Profile; identity.AppId = match.AppId; if (identity.Profile != null) { DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedProvisioningProfile = identity.Profile.Uuid; provisioningProfileName = identity.Profile.Name; } DetectedAppId = identity.AppId; } } else { // Note: Do not codesign. Codesigning seems to break the iOS Simulator in older versions of Xcode. DetectedCodeSigningKey = null; } ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } } // Note: if we make it this far, we absolutely need a codesigning certificate if (!TryGetSigningCertificates(out certs, false)) { return(false); } Log.LogMessage(MessageImportance.Low, "Available certificates:"); foreach (var cert in certs) { Log.LogMessage(MessageImportance.Low, " {0}", SecKeychain.GetCertificateCommonName(cert)); } if (!RequireProvisioningProfile) { if (certs.Count > 1) { if (!string.IsNullOrEmpty(SigningKey)) { Log.LogMessage(MessageImportance.Normal, MSBStrings.M0142, SigningKey); } else { Log.LogMessage(MessageImportance.Normal, MSBStrings.M0143); } for (int i = 0; i < certs.Count; i++) { Log.LogMessage(MessageImportance.Normal, "{0,3}. Signing Identity: {1} ({2})", i + 1, SecKeychain.GetCertificateCommonName(certs[i]), certs[i].Thumbprint); } } codesignCommonName = SecKeychain.GetCertificateCommonName(certs[0]); DetectedCodeSigningKey = certs[0].Thumbprint; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError(MSBStrings.E0144, PlatformName, ProvisioningProfile); return(false); } var profile = identity.Profile; // capture ref for lambda if (certs.Count > 0) { identity.SigningKey = certs.FirstOrDefault(c => profile.DeveloperCertificates.Any(p => p.Thumbprint == c.Thumbprint)); if (identity.SigningKey == null) { Log.LogError(MSBStrings.E0145, PlatformName, ProvisioningProfile); return(false); } } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(MSBStrings.E0141, identity.BundleId, ProvisioningProfile); return(false); } if (identity.SigningKey != null) { codesignCommonName = SecKeychain.GetCertificateCommonName(identity.SigningKey); DetectedCodeSigningKey = identity.SigningKey.Thumbprint; } provisioningProfileName = identity.Profile.Name; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if ((profiles = GetProvisioningProfiles(platform, type, identity, certs)) == null) { return(false); } if ((pairs = GetCodeSignIdentityPairs(profiles, certs)) == null) { return(false); } identity = GetBestMatch(pairs, identity); if (identity.Profile != null && identity.AppId != null) { codesignCommonName = identity.SigningKey != null?SecKeychain.GetCertificateCommonName(identity.SigningKey) : null; provisioningProfileName = identity.Profile.Name; DetectedCodeSigningKey = identity.SigningKey?.Thumbprint; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); } else { if (identity.SigningKey != null) { Log.LogError(MSBStrings.E0146, identity.BundleId, identity.SigningKey); } else { Log.LogError(MSBStrings.E0148, identity.BundleId); } } return(!Log.HasLoggedErrors); }
public override bool Execute() { var type = MobileProvisionDistributionType.Any; var identity = new CodeSignIdentity(); MobileProvisionPlatform platform; IList <MobileProvision> profiles; IList <X509Certificate2> certs; PDictionary plist; switch (SdkPlatform) { case "AppleTVSimulator": case "AppleTVOS": platform = MobileProvisionPlatform.tvOS; break; case "iPhoneSimulator": case "WatchSimulator": case "iPhoneOS": case "WatchOS": platform = MobileProvisionPlatform.iOS; break; case "MacOSX": platform = MobileProvisionPlatform.MacOS; break; default: Log.LogError("Unknown SDK platform: {0}", SdkPlatform); return(false); } if (ProvisioningProfile == AutomaticAppStoreProvision) { type = MobileProvisionDistributionType.AppStore; } else if (ProvisioningProfile == AutomaticInHouseProvision) { type = MobileProvisionDistributionType.InHouse; } else if (ProvisioningProfile == AutomaticAdHocProvision) { type = MobileProvisionDistributionType.AdHoc; } try { plist = PDictionary.FromFile(AppManifest); } catch (Exception ex) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Error loading '{0}': {1}", AppManifest, ex.Message); return(false); } DetectedCodesignAllocate = Path.Combine(DeveloperRoot, "Toolchains", "XcodeDefault.xctoolchain", "usr", "bin", "codesign_allocate"); DetectedBundleVersion = plist.GetCFBundleVersion(); DetectedDistributionType = type.ToString(); identity.BundleId = plist.GetCFBundleIdentifier(); if (string.IsNullOrEmpty(identity.BundleId)) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "{0} does not define CFBundleIdentifier", AppManifest); return(false); } if (Framework == PlatformFramework.MacOS && !RequireCodeSigning) { DetectedBundleId = identity.BundleId; DetectedAppId = DetectedBundleId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if (!RequireProvisioningProfile && string.IsNullOrEmpty(ProvisioningProfile)) { if (SdkIsSimulator && AppleSdkSettings.XcodeVersion.Major >= 8) { // Note: Starting with Xcode 8.0, we need to codesign iOS Simulator builds in order for them to run. // The "-" key is a special value allowed by the codesign utility that allows us to get away with // not having an actual codesign key. As far as we know, this only works with Xcode >= 8. DetectedCodeSigningKey = "-"; } else { // Try and get a valid codesigning certificate... if (!TryGetSigningCertificates(out certs, SdkIsSimulator)) { return(false); } if (certs.Count > 0) { if (certs.Count > 1) { if (!string.IsNullOrEmpty(SigningKey)) { Log.LogMessage(MessageImportance.Normal, "Multiple signing identities match '{0}'; using the first match.", SigningKey); } else { Log.LogMessage(MessageImportance.Normal, "Multiple signing identities found; using the first identity."); } for (int i = 0; i < certs.Count; i++) { Log.LogMessage(MessageImportance.Normal, "{0,3}. Signing Identity: {1} ({2})", i + 1, SecKeychain.GetCertificateCommonName(certs[i]), certs[i].Thumbprint); } } codesignCommonName = SecKeychain.GetCertificateCommonName(certs[0]); DetectedCodeSigningKey = certs[0].Thumbprint; } else { // Note: We don't have to codesign for iOS Simulator builds meant to run on Xcode iOS Simulators // older than 8.0, so it's non-fatal if we don't find any... } } DetectedBundleId = identity.BundleId; DetectedAppId = DetectedBundleId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } // Note: if we make it this far, we absolutely need a codesigning certificate if (!TryGetSigningCertificates(out certs, false)) { return(false); } if (certs.Count > 0) { Log.LogMessage(MessageImportance.Low, "Available certificates:"); foreach (var cert in certs) { Log.LogMessage(MessageImportance.Low, " {0}", Xamarin.MacDev.Keychain.GetCertificateCommonName(cert)); } } if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError("The specified " + PlatformName + " provisioning profile '{0}' could not be found", ProvisioningProfile); return(false); } var profile = identity.Profile; // capture ref for lambda if (certs.Count > 0) { identity.SigningKey = certs.FirstOrDefault(c => profile.DeveloperCertificates.Any(p => p.Thumbprint == c.Thumbprint)); if (identity.SigningKey == null) { Log.LogError("No " + PlatformName + " signing identities match the specified provisioning profile '{0}'.", ProvisioningProfile); return(false); } } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Project bundle identifier '{0}' does not match specified provisioning profile '{1}'", identity.BundleId, ProvisioningProfile); return(false); } if (identity.SigningKey != null) { codesignCommonName = SecKeychain.GetCertificateCommonName(identity.SigningKey); DetectedCodeSigningKey = identity.SigningKey.Thumbprint; } provisioningProfileName = identity.Profile.Name; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } List <string> failures = new List <string> (); if (identity.BundleId != null) { if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions(platform, identity.BundleId, type, certs, unique: true, failures: failures); } else { profiles = MobileProvisionIndex.GetMobileProvisions(platform, identity.BundleId, type, unique: true, failures: failures); } } else if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions(platform, type, certs, unique: true, failures: failures); } else { profiles = MobileProvisionIndex.GetMobileProvisions(platform, type, unique: true, failures: failures); } if (profiles.Count == 0) { foreach (var f in failures) { Log.LogMessage(MessageImportance.Low, "{0}", f); } Log.LogError($"Could not find any available provisioning profiles for {PlatformName}."); return(false); } else { Log.LogMessage(MessageImportance.Low, "Available profiles:"); foreach (var p in profiles) { Log.LogMessage(MessageImportance.Low, " {0}", p.Name); } } List <CodeSignIdentity> pairs; if (certs.Count > 0) { pairs = (from p in profiles from c in certs where p.DeveloperCertificates.Any(d => d.Thumbprint == c.Thumbprint) select new CodeSignIdentity { SigningKey = c, Profile = p }).ToList(); if (pairs.Count == 0) { Log.LogError("No installed provisioning profiles match the installed " + PlatformName + " signing identities."); return(false); } } else { pairs = (from p in profiles select new CodeSignIdentity { Profile = p }).ToList(); } var matches = new List <CodeSignIdentity> (); int bestMatchLength = 0; int matchLength; // find matching provisioning profiles with compatible appid, keeping only those with the longest matching (wildcard) ids foreach (var pair in pairs) { var appid = ConstructValidAppId(pair.Profile, identity.BundleId, out matchLength); if (appid != null && matchLength >= bestMatchLength) { if (matchLength > bestMatchLength) { bestMatchLength = matchLength; matches.Clear(); } var match = identity.Clone(); match.SigningKey = pair.SigningKey; match.Profile = pair.Profile; match.AppId = appid; matches.Add(match); } } if (matches.Count == 0) { Log.LogWarning(null, null, null, AppManifest, 0, 0, 0, 0, "No installed provisioning profiles match the bundle identifier."); } else { if (matches.Count > 1) { var spaces = new string (' ', 3); Log.LogMessage(MessageImportance.Normal, "Multiple provisioning profiles match the bundle identifier; using the first match."); matches.Sort(new SigningIdentityComparer()); for (int i = 0; i < matches.Count; i++) { Log.LogMessage(MessageImportance.Normal, "{0,3}. Provisioning Profile: \"{1}\" ({2})", i + 1, matches[i].Profile.Name, matches[i].Profile.Uuid); if (matches[i].SigningKey != null) { Log.LogMessage(MessageImportance.Normal, "{0} Signing Identity: \"{1}\"", spaces, SecKeychain.GetCertificateCommonName(matches[i].SigningKey)); } } } identity = matches[0]; } if (identity.Profile != null && identity.AppId != null) { codesignCommonName = identity.SigningKey != null?SecKeychain.GetCertificateCommonName(identity.SigningKey) : null; provisioningProfileName = identity.Profile.Name; DetectedCodeSigningKey = identity.SigningKey?.Thumbprint; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); } else { if (identity.SigningKey != null) { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile for selected signing identity '{0}'.", identity.BundleId, identity.SigningKey); } else { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile.", identity.BundleId); } } return(!Log.HasLoggedErrors); }
public override bool Execute() { var type = MobileProvisionDistributionType.Any; var identity = new CodeSignIdentity(); MobileProvisionPlatform platform; IList <MobileProvision> profiles; IList <X509Certificate2> certs; List <CodeSignIdentity> pairs; PDictionary plist; switch (SdkPlatform) { case "AppleTVSimulator": case "AppleTVOS": platform = MobileProvisionPlatform.tvOS; break; case "iPhoneSimulator": case "WatchSimulator": case "iPhoneOS": case "WatchOS": platform = MobileProvisionPlatform.iOS; break; case "MacOSX": platform = MobileProvisionPlatform.MacOS; break; default: Log.LogError("Unknown SDK platform: {0}", SdkPlatform); return(false); } if (ProvisioningProfile == AutomaticAppStoreProvision) { type = MobileProvisionDistributionType.AppStore; } else if (ProvisioningProfile == AutomaticInHouseProvision) { type = MobileProvisionDistributionType.InHouse; } else if (ProvisioningProfile == AutomaticAdHocProvision) { type = MobileProvisionDistributionType.AdHoc; } try { plist = PDictionary.FromFile(AppManifest); } catch (Exception ex) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Error loading '{0}': {1}", AppManifest, ex.Message); return(false); } DetectedCodesignAllocate = Path.Combine(DeveloperRoot, "Toolchains", "XcodeDefault.xctoolchain", "usr", "bin", "codesign_allocate"); DetectedBundleVersion = plist.GetCFBundleVersion(); DetectedDistributionType = type.ToString(); identity.BundleId = plist.GetCFBundleIdentifier(); if (string.IsNullOrEmpty(identity.BundleId)) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "{0} does not define CFBundleIdentifier", AppManifest); return(false); } if (Framework == PlatformFramework.MacOS) { if (!RequireCodeSigning) { DetectedBundleId = identity.BundleId; DetectedAppId = DetectedBundleId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } } else { // Framework is either iOS, tvOS or watchOS if (SdkIsSimulator) { if (AppleSdkSettings.XcodeVersion.Major >= 8 && RequireProvisioningProfile) { // Note: Starting with Xcode 8.0, we need to codesign iOS Simulator builds that enable Entitlements // in order for them to run. The "-" key is a special value allowed by the codesign utility that // allows us to get away with not having an actual codesign key. DetectedCodeSigningKey = "-"; if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError("The specified " + PlatformName + " provisioning profile '{0}' could not be found", ProvisioningProfile); return(false); } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Project bundle identifier '{0}' does not match specified provisioning profile '{1}'", identity.BundleId, ProvisioningProfile); return(false); } provisioningProfileName = identity.Profile.Name; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedBundleId = identity.BundleId; DetectedAppId = DetectedBundleId; } else { certs = new X509Certificate2[0]; if ((profiles = GetProvisioningProfiles(platform, type, identity, certs)) == null) { return(false); } if ((pairs = GetCodeSignIdentityPairs(profiles, certs)) == null) { return(false); } var match = GetBestMatch(pairs, identity); identity.Profile = match.Profile; identity.AppId = match.AppId; if (identity.Profile != null) { DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedProvisioningProfile = identity.Profile.Uuid; provisioningProfileName = identity.Profile.Name; } DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; } } else { // Note: Do not codesign. Codesigning seems to break the iOS Simulator in older versions of Xcode. DetectedCodeSigningKey = null; DetectedBundleId = identity.BundleId; DetectedAppId = DetectedBundleId; } ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } } // Note: if we make it this far, we absolutely need a codesigning certificate if (!TryGetSigningCertificates(out certs, false)) { return(false); } Log.LogMessage(MessageImportance.Low, "Available certificates:"); foreach (var cert in certs) { Log.LogMessage(MessageImportance.Low, " {0}", SecKeychain.GetCertificateCommonName(cert)); } if (!RequireProvisioningProfile) { if (certs.Count > 1) { if (!string.IsNullOrEmpty(SigningKey)) { Log.LogMessage(MessageImportance.Normal, "Multiple signing identities match '{0}'; using the first match.", SigningKey); } else { Log.LogMessage(MessageImportance.Normal, "Multiple signing identities found; using the first identity."); } for (int i = 0; i < certs.Count; i++) { Log.LogMessage(MessageImportance.Normal, "{0,3}. Signing Identity: {1} ({2})", i + 1, SecKeychain.GetCertificateCommonName(certs[i]), certs[i].Thumbprint); } } codesignCommonName = SecKeychain.GetCertificateCommonName(certs[0]); DetectedCodeSigningKey = certs[0].Thumbprint; DetectedBundleId = identity.BundleId; DetectedAppId = DetectedBundleId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError("The specified " + PlatformName + " provisioning profile '{0}' could not be found", ProvisioningProfile); return(false); } var profile = identity.Profile; // capture ref for lambda if (certs.Count > 0) { identity.SigningKey = certs.FirstOrDefault(c => profile.DeveloperCertificates.Any(p => p.Thumbprint == c.Thumbprint)); if (identity.SigningKey == null) { Log.LogError("No " + PlatformName + " signing identities match the specified provisioning profile '{0}'.", ProvisioningProfile); return(false); } } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Project bundle identifier '{0}' does not match specified provisioning profile '{1}'", identity.BundleId, ProvisioningProfile); return(false); } if (identity.SigningKey != null) { codesignCommonName = SecKeychain.GetCertificateCommonName(identity.SigningKey); DetectedCodeSigningKey = identity.SigningKey.Thumbprint; } provisioningProfileName = identity.Profile.Name; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if ((profiles = GetProvisioningProfiles(platform, type, identity, certs)) == null) { return(false); } if ((pairs = GetCodeSignIdentityPairs(profiles, certs)) == null) { return(false); } identity = GetBestMatch(pairs, identity); if (identity.Profile != null && identity.AppId != null) { codesignCommonName = identity.SigningKey != null?SecKeychain.GetCertificateCommonName(identity.SigningKey) : null; provisioningProfileName = identity.Profile.Name; DetectedCodeSigningKey = identity.SigningKey?.Thumbprint; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); } else { if (identity.SigningKey != null) { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile for selected signing identity '{0}'.", identity.BundleId, identity.SigningKey); } else { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile.", identity.BundleId); } } return(!Log.HasLoggedErrors); }
public override bool Execute() { var type = MobileProvisionDistributionType.Any; var identity = new CodeSignIdentity(); MobileProvisionPlatform platform; IList <MobileProvision> profiles; IList <X509Certificate2> certs; PDictionary plist; Log.LogTaskName("DetectSigningIdentity"); Log.LogTaskProperty("AppBundleName", AppBundleName); Log.LogTaskProperty("AppManifest", AppManifest); Log.LogTaskProperty("Keychain", Keychain); Log.LogTaskProperty("ProvisioningProfile", ProvisioningProfile); Log.LogTaskProperty("RequireCodesigning", RequireCodeSigning); Log.LogTaskProperty("RequireProvisioningProfile", RequireProvisioningProfile); Log.LogTaskProperty("SdkPlatform", SdkPlatform); Log.LogTaskProperty("SdkIsSimulator", SdkIsSimulator); Log.LogTaskProperty("SigningKey", SigningKey); switch (SdkPlatform) { case "AppleTVSimulator": case "AppleTVOS": platform = MobileProvisionPlatform.tvOS; break; case "iPhoneSimulator": case "WatchSimulator": case "iPhoneOS": case "WatchOS": platform = MobileProvisionPlatform.iOS; break; case "MacOSX": platform = MobileProvisionPlatform.MacOS; break; default: Log.LogError("Unknown SDK platform: {0}", SdkPlatform); return(false); } if (ProvisioningProfile == AutomaticAppStoreProvision) { type = MobileProvisionDistributionType.AppStore; } else if (ProvisioningProfile == AutomaticInHouseProvision) { type = MobileProvisionDistributionType.InHouse; } else if (ProvisioningProfile == AutomaticAdHocProvision) { type = MobileProvisionDistributionType.AdHoc; } try { plist = PDictionary.FromFile(AppManifest); } catch (Exception ex) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Error loading '{0}': {1}", AppManifest, ex.Message); return(false); } DetectedCodesignAllocate = Path.Combine(DeveloperRoot, "Toolchains", "XcodeDefault.xctoolchain", "usr", "bin", "codesign_allocate"); DetectedBundleVersion = plist.GetCFBundleVersion(); DetectedDistributionType = type.ToString(); identity.BundleId = plist.GetCFBundleIdentifier(); if (string.IsNullOrEmpty(identity.BundleId)) { identity.BundleId = null; } if (Framework == PlatformFramework.MacOS && !RequireCodeSigning) { DetectedBundleId = identity.BundleId ?? GetDefaultBundleId(AppBundleName, null); DetectedAppId = DetectedBundleId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } try { var keychain = !string.IsNullOrEmpty(Keychain) ? SecKeychain.Open(Keychain) : SecKeychain.Default; if (string.IsNullOrEmpty(SigningKey) || MatchesAny(SigningKey, DevelopmentPrefixes)) { // Note: we treat an empty signing key as "developer automatic". if (!TryGetSigningCertificates(keychain, out certs, DevelopmentPrefixes)) { return(false); } } else if (MatchesAny(SigningKey, AppStoreDistributionPrefixes)) { if (!TryGetSigningCertificates(keychain, out certs, AppStoreDistributionPrefixes)) { return(false); } } else if (MatchesAny(SigningKey, DirectDistributionPrefixes)) { if (!TryGetSigningCertificates(keychain, out certs, DirectDistributionPrefixes)) { return(false); } } else { // The user has specified an exact name to match... if (!TryGetSigningCertificates(keychain, out certs, SigningKey)) { return(false); } } } catch (Exception ex) { Log.LogError("{0}", ex.Message); return(false); } if (!RequireProvisioningProfile && string.IsNullOrEmpty(ProvisioningProfile)) { if (certs.Count > 1) { if (!string.IsNullOrEmpty(SigningKey)) { Log.LogMessage(MessageImportance.Normal, "Multiple signing identities match '{0}'; using the first match.", SigningKey); } else { Log.LogMessage(MessageImportance.Normal, "Multiple signing identities found; using the first identity."); } for (int i = 0; i < certs.Count; i++) { Log.LogMessage(MessageImportance.Normal, "{0,3}. Signing Identity: {1} ({2})", i + 1, SecKeychain.GetCertificateCommonName(certs[i]), certs[i].Thumbprint); } } codesignCommonName = SecKeychain.GetCertificateCommonName(certs[0]); DetectedCodeSigningKey = certs[0].Thumbprint; DetectedBundleId = identity.BundleId ?? GetDefaultBundleId(AppBundleName, null); DetectedAppId = DetectedBundleId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if (!IsAutoCodeSignProfile(ProvisioningProfile)) { identity.Profile = MobileProvisionIndex.GetMobileProvision(platform, ProvisioningProfile); if (identity.Profile == null) { Log.LogError("The specified " + PlatformName + " provisioning profile '{0}' could not be found", ProvisioningProfile); return(false); } var profile = identity.Profile; // capture ref for lambda if (certs.Count > 0) { identity.SigningKey = certs.FirstOrDefault(c => profile.DeveloperCertificates.Any(p => p.Thumbprint == c.Thumbprint)); if (identity.SigningKey == null) { Log.LogError("No " + PlatformName + " signing identities match the specified provisioning profile '{0}'.", ProvisioningProfile); return(false); } } if (identity.BundleId == null) { identity.BundleId = GetDefaultBundleId(AppBundleName, GetProfileBundleId(identity.Profile)); Log.LogWarning(null, null, null, AppManifest, 0, 0, 0, 0, "Project does not have bundle identifier specified. Using '{0}' to match provisioning profile.", identity.BundleId); } identity.AppId = ConstructValidAppId(identity.Profile, identity.BundleId); if (identity.AppId == null) { Log.LogError(null, null, null, AppManifest, 0, 0, 0, 0, "Project bundle identifier '{0}' does not match specified provisioning profile '{1}'", identity.BundleId, ProvisioningProfile); return(false); } if (identity.SigningKey != null) { codesignCommonName = SecKeychain.GetCertificateCommonName(identity.SigningKey); DetectedCodeSigningKey = identity.SigningKey.Thumbprint; } provisioningProfileName = identity.Profile.Name; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedDistributionType = identity.Profile.DistributionType.ToString(); DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); return(!Log.HasLoggedErrors); } if (identity.BundleId != null) { if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions(platform, identity.BundleId, type, certs); } else { profiles = MobileProvisionIndex.GetMobileProvisions(platform, identity.BundleId, type); } } else if (certs.Count > 0) { profiles = MobileProvisionIndex.GetMobileProvisions(platform, type, certs); } else { profiles = MobileProvisionIndex.GetMobileProvisions(platform, type); } List <CodeSignIdentity> pairs; if (certs.Count > 0) { pairs = (from p in profiles from c in certs where p.DeveloperCertificates.Any(d => d.Thumbprint == c.Thumbprint) select new CodeSignIdentity { SigningKey = c, Profile = p }).ToList(); if (pairs.Count == 0) { Log.LogError("No installed provisioning profiles match the installed " + PlatformName + " signing identities."); return(false); } } else { pairs = (from p in profiles select new CodeSignIdentity { Profile = p }).ToList(); } if (identity.BundleId != null) { var matches = new List <CodeSignIdentity> (); int bestMatchLength = 0; int matchLength; // find matching provisioning profiles with compatible appid, keeping only those with the longest matching (wildcard) ids foreach (var pair in pairs) { var appid = ConstructValidAppId(pair.Profile, identity.BundleId, out matchLength); if (appid != null && matchLength >= bestMatchLength) { if (matchLength > bestMatchLength) { bestMatchLength = matchLength; matches.Clear(); } var match = identity.Clone(); match.SigningKey = pair.SigningKey; match.Profile = pair.Profile; match.AppId = appid; matches.Add(match); } } if (matches.Count == 0) { Log.LogWarning(null, null, null, AppManifest, 0, 0, 0, 0, "No installed provisioning profiles match the bundle identifier."); } else { if (matches.Count > 1) { var spaces = new string (' ', 3); Log.LogMessage(MessageImportance.Normal, "Multiple provisioning profiles match the bundle identifier; using the first match."); matches.Sort(new SigningIdentityComparer()); for (int i = 0; i < matches.Count; i++) { Log.LogMessage(MessageImportance.Normal, "{0,3}. Provisioning Profile: \"{1}\" ({2})", i + 1, matches[i].Profile.Name, matches[i].Profile.Uuid); if (matches[i].SigningKey != null) { Log.LogMessage(MessageImportance.Normal, "{0} Signing Identity: \"{1}\"", spaces, SecKeychain.GetCertificateCommonName(matches[i].SigningKey)); } } } identity = matches[0]; } } else { // pick a provisioning profile to provide appid and better default bundle identifier, preferring wildcard bundle identifiers foreach (var pair in pairs) { var suggestion = GetProfileBundleId(pair.Profile); bool wildcard = (suggestion != null) && suggestion.EndsWith("*", StringComparison.Ordinal); if (wildcard || identity.Profile == null) { identity.Profile = pair.Profile; identity.SigningKey = pair.SigningKey; identity.BundleId = GetDefaultBundleId(AppBundleName, suggestion); identity.AppId = ConstructValidAppId(pair.Profile, identity.BundleId); } if (wildcard) { break; } } Log.LogWarning(null, null, null, AppManifest, 0, 0, 0, 0, "No bundle identifier specified. Using '{0}' to match an installed provisioning profile.", identity.BundleId); } if (identity.Profile != null && identity.AppId != null) { codesignCommonName = identity.SigningKey != null?SecKeychain.GetCertificateCommonName(identity.SigningKey) : null; provisioningProfileName = identity.Profile.Name; DetectedCodeSigningKey = identity.SigningKey?.Thumbprint; DetectedProvisioningProfile = identity.Profile.Uuid; DetectedBundleId = identity.BundleId; DetectedAppId = identity.AppId; ReportDetectedCodesignInfo(); } else { if (identity.SigningKey != null) { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile for selected signing identity '{0}'.", identity.BundleId, identity.SigningKey); } else { Log.LogError("Bundle identifier '{0}' does not match any installed provisioning profile.", identity.BundleId); } } return(!Log.HasLoggedErrors); }