Exemplo n.º 1
0
		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;
		}
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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;
            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);
        }