/// <summary> /// Extracts the dict values for the Entitlements key and creates a new full .plist file /// from them (with outer plist and dict keys as well as doctype, etc...) /// </summary> public string GetEntitlementsString(string CFBundleIdentifier) { PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = PListHelper.CloneDictionaryRootedAt(ValueNode); }); // Modify the application-identifier to be fully qualified if needed string CurrentApplicationIdentifier; XCentPList.GetString("application-identifier", out CurrentApplicationIdentifier); if (CurrentApplicationIdentifier.Contains("*")) { // Replace the application identifier string NewApplicationIdentifier = String.Format("{0}.{1}", ApplicationIdentifierPrefix, CFBundleIdentifier); XCentPList.SetString("application-identifier", NewApplicationIdentifier); // Replace the keychain access groups // Note: This isn't robust, it ignores the existing value in the wildcard and uses the same value for // each entry. If there is a legitimate need for more than one entry in the access group list, then // don't use a wildcard! List <string> KeyGroups = XCentPList.GetArray("keychain-access-groups", "string"); for (int i = 0; i < KeyGroups.Count; ++i) { string Entry = KeyGroups[i]; if (Entry.Contains("*")) { Entry = NewApplicationIdentifier; } KeyGroups[i] = Entry; } XCentPList.SetValueForKey("keychain-access-groups", KeyGroups); } return(XCentPList.SaveToString()); }
/// <summary> /// Constructs a MobileProvision from an xml blob extracted from the real ASN.1 file /// </summary> public MobileProvision(string EmbeddedPListText) { Data = new PListHelper(EmbeddedPListText); // Now extract things // Key: ApplicationIdentifierPrefix, Array<String> List <string> PrefixList = Data.GetArray("ApplicationIdentifierPrefix", "string"); if (PrefixList.Count > 1) { UnityEngine.Debug.LogWarning("Found more than one entry for ApplicationIdentifierPrefix in the .mobileprovision, using the first one found"); } if (PrefixList.Count > 0) { ApplicationIdentifierPrefix = PrefixList[0]; } // Key: DeveloperCertificates, Array<Data> (uuencoded) string CertificatePassword = ""; List <string> CertificateList = Data.GetArray("DeveloperCertificates", "data"); foreach (string EncodedCert in CertificateList) { byte[] RawCert = Convert.FromBase64String(EncodedCert); DeveloperCertificates.Add(new X509Certificate2(RawCert, CertificatePassword)); } // Key: Name, String if (!Data.GetString("Name", out ProvisionName)) { ProvisionName = "(unknown)"; } if (!Data.GetString("UUID", out ProvisionUUID)) { ProvisionUUID = "(unknown)"; } PListHelper XCentPList = null; Data.ProcessValueForKey("Entitlements", "dict", delegate(XmlNode ValueNode) { XCentPList = PListHelper.CloneDictionaryRootedAt(ValueNode); }); XCentPList.GetString("application-identifier", out ApplicationIdentifier); ApplicationIdentifier = ApplicationIdentifier.Replace(ApplicationIdentifierPrefix + ".", ""); XCentPList.GetString("aps-environment", out ApsEnvironment); if (string.IsNullOrEmpty(ApsEnvironment)) { UnityEngine.Debug.LogError(">>>>>>>>>>aps-environment is null"); } // Key: ProvisionedDevices, Array<String> ProvisionedDeviceIDs = Data.GetArray("ProvisionedDevices", "string"); string certificates = DeveloperCertificates[0].SubjectName.Decode(X500DistinguishedNameFlags.UseUTF8Encoding); ProvisionDeveloper = JenkinsBuild.GetParam(certificates.Split(','), "CN=", ""); string log = string.Empty; log += string.Format("ProvisionName={0}\n", ProvisionName); log += string.Format("from={0}, to={1}\n", DeveloperCertificates[0].NotBefore, DeveloperCertificates[0].NotAfter); log += string.Format("ProvisionUUID={0}\n", ProvisionUUID); log += string.Format("ProvisionDeveloper={0}\n", ProvisionDeveloper); log += string.Format("aps-environment={0}\n", ApsEnvironment); log += string.Format("certificates={0}\n", certificates); UnityEngine.Debug.Log(log); }