1ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpackage com.android.hotspot2.omadm; 2ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 3ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport android.util.Base64; 4ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport android.util.Log; 5ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 6ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.anqp.eap.EAP; 7ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.anqp.eap.EAPMethod; 8ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.anqp.eap.ExpandedEAPMethod; 9ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.anqp.eap.InnerAuthEAP; 10ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.anqp.eap.NonEAPInnerAuth; 11ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.IMSIParameter; 12ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.Utils; 13ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.osu.OSUManager; 14ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.osu.commands.MOData; 15ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.pps.Credential; 16ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.pps.HomeSP; 17ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.pps.Policy; 18ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.pps.SubscriptionParameters; 19ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport com.android.hotspot2.pps.UpdateInfo; 20ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 21ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport org.xml.sax.SAXException; 22ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 23ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.BufferedInputStream; 24ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.BufferedOutputStream; 25ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.File; 26ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.FileInputStream; 27ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.FileNotFoundException; 28ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.FileOutputStream; 29ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.io.IOException; 30ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.nio.charset.StandardCharsets; 31ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.text.DateFormat; 32ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.text.ParseException; 33ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.text.SimpleDateFormat; 34ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.ArrayList; 35ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Arrays; 36ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Collection; 37ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Collections; 38ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Date; 39ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.HashMap; 40ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.HashSet; 41ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.LinkedList; 42ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.List; 43ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Map; 44ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.Set; 45ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistimport java.util.TimeZone; 46ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 47ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist/** 48ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * Handles provisioning of PerProviderSubscription data. 49ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist */ 50ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvistpublic class MOManager { 51ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 52ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_AAAServerTrustRoot = "AAAServerTrustRoot"; 53ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_AbleToShare = "AbleToShare"; 54ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_CertificateType = "CertificateType"; 55ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_CertSHA256Fingerprint = "CertSHA256Fingerprint"; 56ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_CertURL = "CertURL"; 57ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_CheckAAAServerCertStatus = "CheckAAAServerCertStatus"; 58ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Country = "Country"; 59ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_CreationDate = "CreationDate"; 60ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Credential = "Credential"; 61ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_CredentialPriority = "CredentialPriority"; 62ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_DataLimit = "DataLimit"; 63ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_DigitalCertificate = "DigitalCertificate"; 64ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_DLBandwidth = "DLBandwidth"; 65ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_EAPMethod = "EAPMethod"; 66ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_EAPType = "EAPType"; 67ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_ExpirationDate = "ExpirationDate"; 68ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Extension = "Extension"; 69ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_FQDN = "FQDN"; 70ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_FQDN_Match = "FQDN_Match"; 71ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_FriendlyName = "FriendlyName"; 72ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_HESSID = "HESSID"; 73ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_HomeOI = "HomeOI"; 74ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_HomeOIList = "HomeOIList"; 75ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_HomeOIRequired = "HomeOIRequired"; 76ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_HomeSP = "HomeSP"; 77ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_IconURL = "IconURL"; 78ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_IMSI = "IMSI"; 79ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_InnerEAPType = "InnerEAPType"; 80ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_InnerMethod = "InnerMethod"; 81ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_InnerVendorID = "InnerVendorID"; 82ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_InnerVendorType = "InnerVendorType"; 83ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_IPProtocol = "IPProtocol"; 84ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_MachineManaged = "MachineManaged"; 85ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_MaximumBSSLoadValue = "MaximumBSSLoadValue"; 86ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_MinBackhaulThreshold = "MinBackhaulThreshold"; 87ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_NetworkID = "NetworkID"; 88ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_NetworkType = "NetworkType"; 89ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Other = "Other"; 90ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_OtherHomePartners = "OtherHomePartners"; 91ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Password = "Password"; 92ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_PerProviderSubscription = "PerProviderSubscription"; 93ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Policy = "Policy"; 94ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_PolicyUpdate = "PolicyUpdate"; 95ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_PortNumber = "PortNumber"; 96ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_PreferredRoamingPartnerList = "PreferredRoamingPartnerList"; 97ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Priority = "Priority"; 98ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Realm = "Realm"; 99ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_RequiredProtoPortTuple = "RequiredProtoPortTuple"; 100ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Restriction = "Restriction"; 101ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_RoamingConsortiumOI = "RoamingConsortiumOI"; 102ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_SIM = "SIM"; 103ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_SoftTokenApp = "SoftTokenApp"; 104ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_SPExclusionList = "SPExclusionList"; 105ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_SSID = "SSID"; 106ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_StartDate = "StartDate"; 107ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_SubscriptionParameters = "SubscriptionParameters"; 108ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_SubscriptionUpdate = "SubscriptionUpdate"; 109ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_TimeLimit = "TimeLimit"; 110ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_TrustRoot = "TrustRoot"; 111ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_TypeOfSubscription = "TypeOfSubscription"; 112ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_ULBandwidth = "ULBandwidth"; 113ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_UpdateIdentifier = "UpdateIdentifier"; 114ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_UpdateInterval = "UpdateInterval"; 115ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_UpdateMethod = "UpdateMethod"; 116ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_URI = "URI"; 117ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_UsageLimits = "UsageLimits"; 118ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_UsageTimePeriod = "UsageTimePeriod"; 119ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_Username = "Username"; 120ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_UsernamePassword = "UsernamePassword"; 121ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_VendorId = "VendorId"; 122ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final String TAG_VendorType = "VendorType"; 123ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 124ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static final long IntervalFactor = 60000L; // All MO intervals are in minutes 125ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 126ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static final DateFormat DTFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 127ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 128ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static final Map<String, Map<String, Object>> sSelectionMap; 129ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 130ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist static { 131ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist DTFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 132ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 133ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sSelectionMap = new HashMap<>(); 134ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 135ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist setSelections(TAG_FQDN_Match, 136ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "exactmatch", Boolean.FALSE, 137ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "includesubdomains", Boolean.TRUE); 138ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist setSelections(TAG_UpdateMethod, 139ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "oma-dm-clientinitiated", Boolean.FALSE, 140ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "spp-clientinitiated", Boolean.TRUE); 141ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist setSelections(TAG_Restriction, 142ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "homesp", UpdateInfo.UpdateRestriction.HomeSP, 143ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "roamingpartner", UpdateInfo.UpdateRestriction.RoamingPartner, 144ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist "unrestricted", UpdateInfo.UpdateRestriction.Unrestricted); 145ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 146ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 147ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static void setSelections(String key, Object... pairs) { 148ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Map<String, Object> kvp = new HashMap<>(); 149ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sSelectionMap.put(key, kvp); 150ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (int n = 0; n < pairs.length; n += 2) { 151ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist kvp.put(pairs[n].toString(), pairs[n + 1]); 152ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 153ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 154ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 155ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private final File mPpsFile; 156ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private final boolean mEnabled; 157ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private final Map<String, HomeSP> mSPs; 158ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 159ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public MOManager(File ppsFile, boolean hs2enabled) { 160ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mPpsFile = ppsFile; 161ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mEnabled = hs2enabled; 162ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mSPs = new HashMap<>(); 163ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 164ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 165ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public File getPpsFile() { 166ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return mPpsFile; 167ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 168ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 169ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public boolean isEnabled() { 170ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return mEnabled; 171ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 172ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 173ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public boolean isConfigured() { 174ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return mEnabled && !mSPs.isEmpty(); 175ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 176ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 177ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public Map<String, HomeSP> getLoadedSPs() { 178ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Collections.unmodifiableMap(mSPs); 179ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 180ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 181ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public List<HomeSP> loadAllSPs() throws IOException { 182ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 183ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!mEnabled || !mPpsFile.exists()) { 184ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Collections.emptyList(); 185ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 186ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 187ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) { 188ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree moTree = MOTree.unmarshal(in); 189ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mSPs.clear(); 190ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (moTree == null) { 191ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Collections.emptyList(); // Empty file 192ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 193ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 194ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<HomeSP> sps = buildSPs(moTree); 195ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (sps != null) { 196ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (HomeSP sp : sps) { 197ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (mSPs.put(sp.getFQDN(), sp) != null) { 198ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Multiple SPs for FQDN '" + sp.getFQDN() + "'"); 199ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 200ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Log.d(OSUManager.TAG, "retrieved " + sp.getFQDN() + " from PPS"); 201ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 202ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 203ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return sps; 204ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 205ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 206ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Failed to build HomeSP"); 207ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 208ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 209ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 210ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 211ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static HomeSP buildSP(String xml) throws IOException, SAXException { 212ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAParser omaParser = new OMAParser(); 213ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree tree = omaParser.parse(xml, OMAConstants.PPS_URN); 214ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<HomeSP> spList = buildSPs(tree); 215ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (spList.size() != 1) { 216ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Expected exactly one HomeSP, got " + spList.size()); 217ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 218ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return spList.iterator().next(); 219ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 220ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 221ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public HomeSP addSP(String xml, OSUManager osuManager) throws IOException, SAXException { 222ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAParser omaParser = new OMAParser(); 223ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return addSP(omaParser.parse(xml, OMAConstants.PPS_URN), osuManager); 224ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 225ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 226ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static final List<String> FQDNPath = Arrays.asList(TAG_HomeSP, TAG_FQDN); 227ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 228ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist /** 229ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * R1 *only* addSP method. 230ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * 231ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * @param homeSP 232ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * @throws IOException 233ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist */ 234ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public void addSP(HomeSP homeSP, OSUManager osuManager) throws IOException { 235ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!mEnabled) { 236ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("HS2.0 not enabled on this device"); 237ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 238ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (mSPs.containsKey(homeSP.getFQDN())) { 239ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Log.d(OSUManager.TAG, "HS20 profile for " + 240ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSP.getFQDN() + " already exists"); 241ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return; 242ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 243ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Log.d(OSUManager.TAG, "Adding new HS20 profile for " + homeSP.getFQDN()); 244ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 245ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed dummyRoot = new OMAConstructed(null, TAG_PerProviderSubscription, null); 246ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist buildHomeSPTree(homeSP, dummyRoot, mSPs.size() + 1); 247ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 248ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist addSP(dummyRoot, osuManager); 249ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (FileNotFoundException fnfe) { 250ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree tree = 251ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree.buildMgmtTree(OMAConstants.PPS_URN, OMAConstants.OMAVersion, dummyRoot); 252ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // No file to load a pre-build MO tree from, create a new one and save it. 253ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist //MOTree tree = new MOTree(OMAConstants.PPS_URN, OMAConstants.OMAVersion, dummyRoot); 254ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist writeMO(tree, mPpsFile, osuManager); 255ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 256ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist mSPs.put(homeSP.getFQDN(), homeSP); 257ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 258ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 259ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public HomeSP addSP(MOTree instanceTree, OSUManager osuManager) throws IOException { 260ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<HomeSP> spList = buildSPs(instanceTree); 261ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (spList.size() != 1) { 262ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Expected exactly one HomeSP, got " + spList.size()); 263ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 264ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 265ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist HomeSP sp = spList.iterator().next(); 266ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String fqdn = sp.getFQDN(); 267ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (mSPs.put(fqdn, sp) != null) { 268ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("SP " + fqdn + " already exists"); 269ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 270ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 271ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed pps = (OMAConstructed) instanceTree.getRoot(). 272ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist getChild(TAG_PerProviderSubscription); 273ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 274ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 275ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist addSP(pps, osuManager); 276ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (FileNotFoundException fnfe) { 277ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree tree = new MOTree(instanceTree.getUrn(), instanceTree.getDtdRev(), 278ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist instanceTree.getRoot()); 279ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist writeMO(tree, mPpsFile, osuManager); 280ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 281ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 282ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return sp; 283ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 284ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 285ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist /** 286ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * Add an SP sub-tree. mo must be PPS with an immediate instance child (e.g. Cred01) and an 287ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * optional UpdateIdentifier, 288ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * 289ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * @param mo The new MO 290ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist * @throws IOException 291ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist */ 292ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private void addSP(OMANode mo, OSUManager osuManager) throws IOException { 293ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree moTree; 294ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) { 295ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree = MOTree.unmarshal(in); 296ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree.getRoot().addChild(mo); 297ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 298ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist /* 299ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed ppsRoot = (OMAConstructed) 300ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree.getRoot().addChild(TAG_PerProviderSubscription, "", null, null); 301ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode child : mo.getChildren()) { 302ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist ppsRoot.addChild(child); 303ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!child.isLeaf()) { 304ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree.getRoot().addChild(child); 305ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 306ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist else if (child.getName().equals(TAG_UpdateIdentifier)) { 307ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode currentUD = moTree.getRoot().getChild(TAG_UpdateIdentifier); 308ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (currentUD != null) { 309ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree.getRoot().replaceNode(currentUD, child); 310ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 311ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist else { 312ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree.getRoot().addChild(child); 313ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 314ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 315ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 316ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist */ 317ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 318ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist writeMO(moTree, mPpsFile, osuManager); 319ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 320ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 321ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static OMAConstructed findTargetTree(MOTree moTree, String fqdn) throws OMAException { 322ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode pps = moTree.getRoot(); 323ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode node : pps.getChildren()) { 324ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode instance = null; 325ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (node.getName().equals(TAG_PerProviderSubscription)) { 326ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist instance = getInstanceNode((OMAConstructed) node); 327ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (!node.isLeaf()) { 328ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist instance = node; 329ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 330ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (instance != null) { 331ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String nodeFqdn = getString(instance.getListValue(FQDNPath.iterator())); 332ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (fqdn.equalsIgnoreCase(nodeFqdn)) { 333ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return (OMAConstructed) node; 334ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // targetTree is rooted at the PPS 335ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 336ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 337ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 338ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return null; 339ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 340ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 341ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static OMAConstructed getInstanceNode(OMAConstructed root) throws OMAException { 342ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode child : root.getChildren()) { 343ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!child.isLeaf()) { 344ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return (OMAConstructed) child; 345ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 346ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 347ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Cannot find instance node"); 348ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 349ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 350ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public HomeSP modifySP(HomeSP homeSP, Collection<MOData> mods, OSUManager osuManager) 351ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throws IOException { 352ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 353ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Log.d(OSUManager.TAG, "modifying SP: " + mods); 354ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree moTree; 355ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int ppsMods = 0; 356ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int updateIdentifier = 0; 357ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) { 358ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree = MOTree.unmarshal(in); 359ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // moTree is PPS/?/provider-data 360ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 361ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed targetTree = findTargetTree(moTree, homeSP.getFQDN()); 362ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (targetTree == null) { 363ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("Failed to find PPS tree for " + homeSP.getFQDN()); 364ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 365ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed instance = getInstanceNode(targetTree); 366ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 367ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (MOData mod : mods) { 368ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist LinkedList<String> tailPath = 369ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist getTailPath(mod.getBaseURI(), TAG_PerProviderSubscription); 370ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed modRoot = mod.getMOTree().getRoot(); 371ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // modRoot is the MgmtTree with the actual object as a direct child 372ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // (e.g. Credential) 373ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 374ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (tailPath.getFirst().equals(TAG_UpdateIdentifier)) { 375ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist updateIdentifier = getInteger(modRoot.getChildren().iterator().next()); 376ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode oldUdi = targetTree.getChild(TAG_UpdateIdentifier); 377ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (getInteger(oldUdi) != updateIdentifier) { 378ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist ppsMods++; 379ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 380ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (oldUdi != null) { 381ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist targetTree.replaceNode(oldUdi, modRoot.getChild(TAG_UpdateIdentifier)); 382ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 383ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist targetTree.addChild(modRoot.getChild(TAG_UpdateIdentifier)); 384ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 385ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 386ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist tailPath.removeFirst(); // Drop the instance 387ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode current = instance.getListValue(tailPath.iterator()); 388ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (current == null) { 389ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("No previous node for " + tailPath + " in " + 390ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSP.getFQDN()); 391ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 392ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode newNode : modRoot.getChildren()) { 393ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // newNode is something like Credential 394ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // current is the same existing node 395ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode old = current.getParent().replaceNode(current, newNode); 396ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist ppsMods++; 397ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 398ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 399ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 400ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 401ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist writeMO(moTree, mPpsFile, osuManager); 402ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 403ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (ppsMods == 0) { 404ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return null; // HomeSP not modified. 405ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 406ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 407ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // Return a new rebuilt HomeSP 408ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<HomeSP> sps = buildSPs(moTree); 409ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (sps != null) { 410ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (HomeSP sp : sps) { 411ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (sp.getFQDN().equals(homeSP.getFQDN())) { 412ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return sp; 413ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 414ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 415ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 416ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Failed to build HomeSP"); 417ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 418ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return null; 419ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 420ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 421ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static LinkedList<String> getTailPath(String pathString, String rootName) 422ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throws IOException { 423ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String[] path = pathString.split("/"); 424ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int pathIndex; 425ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (pathIndex = 0; pathIndex < path.length; pathIndex++) { 426ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (path[pathIndex].equalsIgnoreCase(rootName)) { 427ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist pathIndex++; 428ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist break; 429ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 430ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 431ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (pathIndex >= path.length) { 432ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("Bad node-path: " + pathString); 433ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 434ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist LinkedList<String> tailPath = new LinkedList<>(); 435ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist while (pathIndex < path.length) { 436ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist tailPath.add(path[pathIndex]); 437ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist pathIndex++; 438ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 439ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return tailPath; 440ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 441ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 442ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public HomeSP getHomeSP(String fqdn) { 443ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return mSPs.get(fqdn); 444ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 445ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 446ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public void removeSP(String fqdn, OSUManager osuManager) throws IOException { 447ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (mSPs.remove(fqdn) == null) { 448ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Log.d(OSUManager.TAG, "No HS20 profile to delete for " + fqdn); 449ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return; 450ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 451ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 452ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Log.d(OSUManager.TAG, "Deleting HS20 profile for " + fqdn); 453ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 454ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree moTree; 455ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) { 456ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree = MOTree.unmarshal(in); 457ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed tbd = findTargetTree(moTree, fqdn); 458ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (tbd == null) { 459ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("Node " + fqdn + " doesn't exist in MO tree"); 460ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 461ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed pps = moTree.getRoot(); 462ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode removed = pps.removeNode("?", tbd); 463ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (removed == null) { 464ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("Failed to remove " + fqdn + " out of MO tree"); 465ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 466ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 467ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist writeMO(moTree, mPpsFile, osuManager); 468ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist osuManager.spDeleted(fqdn); 469ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 470ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 471ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public MOTree getMOTree(HomeSP homeSP) throws IOException { 472ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(mPpsFile))) { 473ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist MOTree moTree = MOTree.unmarshal(in); 474ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed target = findTargetTree(moTree, homeSP.getFQDN()); 475ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (target == null) { 476ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new IOException("Can't find " + homeSP.getFQDN() + " in MO tree"); 477ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 478ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return MOTree.buildMgmtTree(OMAConstants.PPS_URN, OMAConstants.OMAVersion, target); 479ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 480ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 481ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 482ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static void writeMO(MOTree moTree, File f, OSUManager osuManager) throws IOException { 483ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try (BufferedOutputStream out = 484ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist new BufferedOutputStream(new FileOutputStream(f, false))) { 485ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist moTree.marshal(out); 486ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist out.flush(); 487ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 488ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 489ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 490ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static String fqdnList(Collection<HomeSP> sps) { 491ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist StringBuilder sb = new StringBuilder(); 492ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist boolean first = true; 493ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (HomeSP sp : sps) { 494ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (first) { 495ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist first = false; 496ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 497ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sb.append(", "); 498ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 499ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist sb.append(sp.getFQDN()); 500ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 501ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return sb.toString(); 502ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 503ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 504ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static OMANode buildHomeSPTree(HomeSP homeSP, OMAConstructed root, int instanceID) 505ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throws IOException { 506ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode providerSubNode = root.addChild(getInstanceString(instanceID), 507ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null, null, null); 508ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 509ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // The HomeSP: 510ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode homeSpNode = providerSubNode.addChild(TAG_HomeSP, null, null, null); 511ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!homeSP.getSSIDs().isEmpty()) { 512ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed nwkIDNode = 513ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) homeSpNode.addChild(TAG_NetworkID, null, null, null); 514ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int instance = 0; 515ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (Map.Entry<String, Long> entry : homeSP.getSSIDs().entrySet()) { 516ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed inode = 517ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) nwkIDNode 518ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist .addChild(getInstanceString(instance++), null, null, null); 519ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_SSID, null, entry.getKey(), null); 520ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (entry.getValue() != null) { 521ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_HESSID, null, 522ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String.format("%012x", entry.getValue()), null); 523ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 524ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 525ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 526ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 527ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSpNode.addChild(TAG_FriendlyName, null, homeSP.getFriendlyName(), null); 528ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 529ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (homeSP.getIconURL() != null) { 530ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSpNode.addChild(TAG_IconURL, null, homeSP.getIconURL(), null); 531ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 532ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 533ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSpNode.addChild(TAG_FQDN, null, homeSP.getFQDN(), null); 534ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 535ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!homeSP.getMatchAllOIs().isEmpty() || !homeSP.getMatchAnyOIs().isEmpty()) { 536ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed homeOIList = 537ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) homeSpNode.addChild(TAG_HomeOIList, null, null, null); 538ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 539ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int instance = 0; 540ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (Long oi : homeSP.getMatchAllOIs()) { 541ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed inode = 542ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) homeOIList.addChild(getInstanceString(instance++), 543ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null, null, null); 544ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_HomeOI, null, String.format("%x", oi), null); 545ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_HomeOIRequired, null, "TRUE", null); 546ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 547ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (Long oi : homeSP.getMatchAnyOIs()) { 548ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed inode = 549ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) homeOIList.addChild(getInstanceString(instance++), 550ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null, null, null); 551ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_HomeOI, null, String.format("%x", oi), null); 552ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_HomeOIRequired, null, "FALSE", null); 553ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 554ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 555ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 556ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!homeSP.getOtherHomePartners().isEmpty()) { 557ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed otherPartners = 558ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) homeSpNode.addChild(TAG_OtherHomePartners, null, null, null); 559ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int instance = 0; 560ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (String fqdn : homeSP.getOtherHomePartners()) { 561ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed inode = 562ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist (OMAConstructed) otherPartners.addChild(getInstanceString(instance++), 563ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null, null, null); 564ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist inode.addChild(TAG_FQDN, null, fqdn, null); 565ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 566ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 567ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 568ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!homeSP.getRoamingConsortiums().isEmpty()) { 569ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSpNode.addChild(TAG_RoamingConsortiumOI, null, 570ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist getRCList(homeSP.getRoamingConsortiums()), null); 571ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 572ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 573ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // The Credential: 574ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode credentialNode = providerSubNode.addChild(TAG_Credential, null, null, null); 575ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Credential cred = homeSP.getCredential(); 576ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist EAPMethod method = cred.getEAPMethod(); 577ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 578ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (cred.getCtime() > 0) { 579ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist credentialNode.addChild(TAG_CreationDate, 580ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null, DTFormat.format(new Date(cred.getCtime())), null); 581ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 582ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (cred.getExpTime() > 0) { 583ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist credentialNode.addChild(TAG_ExpirationDate, 584ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null, DTFormat.format(new Date(cred.getExpTime())), null); 585ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 586ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 587ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (method.getEAPMethodID() == EAP.EAPMethodID.EAP_SIM 588ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist || method.getEAPMethodID() == EAP.EAPMethodID.EAP_AKA 589ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist || method.getEAPMethodID() == EAP.EAPMethodID.EAP_AKAPrim) { 590ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 591ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode simNode = credentialNode.addChild(TAG_SIM, null, null, null); 592ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist simNode.addChild(TAG_IMSI, null, cred.getImsi().toString(), null); 593ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist simNode.addChild(TAG_EAPType, null, 594ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Integer.toString(EAP.mapEAPMethod(method.getEAPMethodID())), null); 595ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 596ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (method.getEAPMethodID() == EAP.EAPMethodID.EAP_TTLS) { 597ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 598ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode unpNode = credentialNode.addChild(TAG_UsernamePassword, null, null, null); 599ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist unpNode.addChild(TAG_Username, null, cred.getUserName(), null); 600ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist unpNode.addChild(TAG_Password, null, 601ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Base64.encodeToString(cred.getPassword().getBytes(StandardCharsets.UTF_8), 602ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Base64.DEFAULT), null); 603ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode eapNode = unpNode.addChild(TAG_EAPMethod, null, null, null); 604ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist eapNode.addChild(TAG_EAPType, null, 605ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Integer.toString(EAP.mapEAPMethod(method.getEAPMethodID())), null); 606ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist eapNode.addChild(TAG_InnerMethod, null, 607ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist ((NonEAPInnerAuth) method.getAuthParam()).getOMAtype(), null); 608ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 609ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (method.getEAPMethodID() == EAP.EAPMethodID.EAP_TLS) { 610ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 611ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode certNode = credentialNode.addChild(TAG_DigitalCertificate, null, null, null); 612ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist certNode.addChild(TAG_CertificateType, null, Credential.CertTypeX509, null); 613ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist certNode.addChild(TAG_CertSHA256Fingerprint, null, 614ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Utils.toHex(cred.getFingerPrint()), null); 615ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 616ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 617ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Invalid credential on " + homeSP.getFQDN()); 618ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 619ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 620ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist credentialNode.addChild(TAG_Realm, null, cred.getRealm(), null); 621ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 622ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // !!! Note: This node defines CRL checking through OSCP, I suspect we won't be able 623ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // to do that so it is commented out: 624ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist //credentialNode.addChild(TAG_CheckAAAServerCertStatus, null, "TRUE", null); 625ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return providerSubNode; 626ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 627ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 628ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static String getInstanceString(int instance) { 629ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return "r1i" + instance; 630ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 631ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 632ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static String getRCList(Collection<Long> rcs) { 633ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist StringBuilder builder = new StringBuilder(); 634ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist boolean first = true; 635ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (Long roamingConsortium : rcs) { 636ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (first) { 637ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist first = false; 638ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 639ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist builder.append(','); 640ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 641ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist builder.append(String.format("%x", roamingConsortium)); 642ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 643ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return builder.toString(); 644ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 645ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 646ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static List<HomeSP> buildSPs(MOTree moTree) throws OMAException { 647ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMAConstructed spList; 648ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<HomeSP> homeSPs = new ArrayList<>(); 649ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (moTree.getRoot().getName().equals(TAG_PerProviderSubscription)) { 650ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist // The old PPS file was rooted at PPS instead of MgmtTree to conserve space 651ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist spList = moTree.getRoot(); 652ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 653ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (spList == null) { 654ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return homeSPs; 655ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 656ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 657ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode node : spList.getChildren()) { 658ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!node.isLeaf()) { 659ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSPs.add(buildHomeSP(node, 0)); 660ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 661ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 662ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 663ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode ppsRoot : moTree.getRoot().getChildren()) { 664ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (ppsRoot.getName().equals(TAG_PerProviderSubscription)) { 665ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Integer updateIdentifier = null; 666ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode instance = null; 667ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode child : ppsRoot.getChildren()) { 668ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (child.getName().equals(TAG_UpdateIdentifier)) { 669ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist updateIdentifier = getInteger(child); 670ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (!child.isLeaf()) { 671ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist instance = child; 672ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 673ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 674ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (instance == null) { 675ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("PPS node missing instance node"); 676ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 677ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist homeSPs.add(buildHomeSP(instance, 678ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist updateIdentifier != null ? updateIdentifier : 0)); 679ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 680ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 681ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 682ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 683ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return homeSPs; 684ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 685ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 686ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static HomeSP buildHomeSP(OMANode ppsRoot, int updateIdentifier) throws OMAException { 687ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode spRoot = ppsRoot.getChild(TAG_HomeSP); 688ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 689ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String fqdn = spRoot.getScalarValue(Arrays.asList(TAG_FQDN).iterator()); 690ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String friendlyName = spRoot.getScalarValue(Arrays.asList(TAG_FriendlyName).iterator()); 691ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String iconURL = spRoot.getScalarValue(Arrays.asList(TAG_IconURL).iterator()); 692ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 693ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist HashSet<Long> roamingConsortiums = new HashSet<>(); 694ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String oiString = spRoot.getScalarValue(Arrays.asList(TAG_RoamingConsortiumOI).iterator()); 695ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (oiString != null) { 696ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (String oi : oiString.split(",")) { 697ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist roamingConsortiums.add(Long.parseLong(oi.trim(), 16)); 698ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 699ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 700ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 701ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Map<String, Long> ssids = new HashMap<>(); 702ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 703ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode ssidListNode = spRoot.getListValue(Arrays.asList(TAG_NetworkID).iterator()); 704ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (ssidListNode != null) { 705ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode ssidRoot : ssidListNode.getChildren()) { 706ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode hessidNode = ssidRoot.getChild(TAG_HESSID); 707ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist ssids.put(ssidRoot.getChild(TAG_SSID).getValue(), getMac(hessidNode)); 708ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 709ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 710ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 711ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Set<Long> matchAnyOIs = new HashSet<>(); 712ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist List<Long> matchAllOIs = new ArrayList<>(); 713ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode homeOIListNode = spRoot.getListValue(Arrays.asList(TAG_HomeOIList).iterator()); 714ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (homeOIListNode != null) { 715ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode homeOIRoot : homeOIListNode.getChildren()) { 716ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String homeOI = homeOIRoot.getChild(TAG_HomeOI).getValue(); 717ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (Boolean.parseBoolean(homeOIRoot.getChild(TAG_HomeOIRequired).getValue())) { 718ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist matchAllOIs.add(Long.parseLong(homeOI, 16)); 719ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 720ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist matchAnyOIs.add(Long.parseLong(homeOI, 16)); 721ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 722ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 723ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 724ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 725ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Set<String> otherHomePartners = new HashSet<>(); 726ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode otherListNode = 727ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist spRoot.getListValue(Arrays.asList(TAG_OtherHomePartners).iterator()); 728ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (otherListNode != null) { 729ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode fqdnNode : otherListNode.getChildren()) { 730ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist otherHomePartners.add(fqdnNode.getChild(TAG_FQDN).getValue()); 731ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 732ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 733ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 734ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Credential credential = buildCredential(ppsRoot.getChild(TAG_Credential)); 735ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 736ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode policyNode = ppsRoot.getChild(TAG_Policy); 737ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Policy policy = policyNode != null ? new Policy(policyNode) : null; 738ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 739ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Map<String, String> aaaTrustRoots; 740ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode aaaRootNode = ppsRoot.getChild(TAG_AAAServerTrustRoot); 741ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (aaaRootNode == null) { 742ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist aaaTrustRoots = null; 743ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 744ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist aaaTrustRoots = new HashMap<>(aaaRootNode.getChildren().size()); 745ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist for (OMANode child : aaaRootNode.getChildren()) { 746ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist aaaTrustRoots.put(getString(child, TAG_CertURL), 747ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist getString(child, TAG_CertSHA256Fingerprint)); 748ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 749ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 750ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 751ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode updateNode = ppsRoot.getChild(TAG_SubscriptionUpdate); 752ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist UpdateInfo subscriptionUpdate = updateNode != null ? new UpdateInfo(updateNode) : null; 753ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode subNode = ppsRoot.getChild(TAG_SubscriptionParameters); 754ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist SubscriptionParameters subscriptionParameters = subNode != null ? 755ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist new SubscriptionParameters(subNode) : null; 756ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 757ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return new HomeSP(ssids, fqdn, roamingConsortiums, otherHomePartners, 758ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist matchAnyOIs, matchAllOIs, friendlyName, iconURL, credential, 759ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist policy, getInteger(ppsRoot.getChild(TAG_CredentialPriority), 0), 760ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist aaaTrustRoots, subscriptionUpdate, subscriptionParameters, updateIdentifier); 761ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 762ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 763ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static Credential buildCredential(OMANode credNode) throws OMAException { 764ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist long ctime = getTime(credNode.getChild(TAG_CreationDate)); 765ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist long expTime = getTime(credNode.getChild(TAG_ExpirationDate)); 766ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String realm = getString(credNode.getChild(TAG_Realm)); 767ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist boolean checkAAACert = getBoolean(credNode.getChild(TAG_CheckAAAServerCertStatus)); 768ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 769ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode unNode = credNode.getChild(TAG_UsernamePassword); 770ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode certNode = credNode.getChild(TAG_DigitalCertificate); 771ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode simNode = credNode.getChild(TAG_SIM); 772ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 773ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int alternatives = 0; 774ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist alternatives += unNode != null ? 1 : 0; 775ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist alternatives += certNode != null ? 1 : 0; 776ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist alternatives += simNode != null ? 1 : 0; 777ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (alternatives != 1) { 778ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Expected exactly one credential type, got " + alternatives); 779ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 780ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 781ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (unNode != null) { 782ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String userName = getString(unNode.getChild(TAG_Username)); 783ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String password = getString(unNode.getChild(TAG_Password)); 784ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist boolean machineManaged = getBoolean(unNode.getChild(TAG_MachineManaged)); 785ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String softTokenApp = getString(unNode.getChild(TAG_SoftTokenApp)); 786ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist boolean ableToShare = getBoolean(unNode.getChild(TAG_AbleToShare)); 787ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 788ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode eapMethodNode = unNode.getChild(TAG_EAPMethod); 789ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist int eapID = getInteger(eapMethodNode.getChild(TAG_EAPType)); 790ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 791ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist EAP.EAPMethodID eapMethodID = EAP.mapEAPMethod(eapID); 792ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (eapMethodID == null) { 793ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Unknown EAP method: " + eapID); 794ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 795ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 796ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Long vid = getOptionalInteger(eapMethodNode.getChild(TAG_VendorId)); 797ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Long vtype = getOptionalInteger(eapMethodNode.getChild(TAG_VendorType)); 798ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Long innerEAPType = getOptionalInteger(eapMethodNode.getChild(TAG_InnerEAPType)); 799ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist EAP.EAPMethodID innerEAPMethod = null; 800ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (innerEAPType != null) { 801ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist innerEAPMethod = EAP.mapEAPMethod(innerEAPType.intValue()); 802ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (innerEAPMethod == null) { 803ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Bad inner EAP method: " + innerEAPType); 804ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 805ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 806ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 807ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Long innerVid = getOptionalInteger(eapMethodNode.getChild(TAG_InnerVendorID)); 808ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Long innerVtype = getOptionalInteger(eapMethodNode.getChild(TAG_InnerVendorType)); 809ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String innerNonEAPMethod = getString(eapMethodNode.getChild(TAG_InnerMethod)); 810ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 811ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist EAPMethod eapMethod; 812ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (innerEAPMethod != null) { 813ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist eapMethod = new EAPMethod(eapMethodID, new InnerAuthEAP(innerEAPMethod)); 814ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (vid != null) { 815ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist eapMethod = new EAPMethod(eapMethodID, 816ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist new ExpandedEAPMethod(EAP.AuthInfoID.ExpandedEAPMethod, 817ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist vid.intValue(), vtype)); 818ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (innerVid != null) { 819ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist eapMethod = 820ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist new EAPMethod(eapMethodID, new ExpandedEAPMethod(EAP.AuthInfoID 821ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist .ExpandedInnerEAPMethod, innerVid.intValue(), innerVtype)); 822ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (innerNonEAPMethod != null) { 823ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist eapMethod = new EAPMethod(eapMethodID, new NonEAPInnerAuth(innerNonEAPMethod)); 824ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 825ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Incomplete set of EAP parameters"); 826ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 827ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 828ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return new Credential(ctime, expTime, realm, checkAAACert, eapMethod, userName, 829ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist password, machineManaged, softTokenApp, ableToShare); 830ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 831ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (certNode != null) { 832ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 833ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String certTypeString = getString(certNode.getChild(TAG_CertificateType)); 834ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist byte[] fingerPrint = getOctets(certNode.getChild(TAG_CertSHA256Fingerprint)); 835ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 836ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist EAPMethod eapMethod = new EAPMethod(EAP.EAPMethodID.EAP_TLS, null); 837ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 838ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return new Credential(ctime, expTime, realm, checkAAACert, eapMethod, 839ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Credential.mapCertType(certTypeString), fingerPrint); 840ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (NumberFormatException nfe) { 841ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Bad hex string: " + nfe.toString()); 842ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 843ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 844ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (simNode != null) { 845ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 846ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist IMSIParameter imsi = new IMSIParameter(getString(simNode.getChild(TAG_IMSI))); 847ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 848ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist EAPMethod eapMethod = 849ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist new EAPMethod(EAP.mapEAPMethod(getInteger(simNode.getChild(TAG_EAPType))), 850ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist null); 851ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 852ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return new Credential(ctime, expTime, realm, checkAAACert, eapMethod, imsi); 853ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (IOException ioe) { 854ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Failed to parse IMSI: " + ioe); 855ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 856ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 857ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Missing credential parameters"); 858ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 859ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 860ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static OMANode getChild(OMANode node, String key) throws OMAException { 861ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode child = node.getChild(key); 862ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (child == null) { 863ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("No such node: " + key); 864ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 865ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return child; 866ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 867ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 868ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static String getString(OMANode node, String key) throws OMAException { 869ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode child = node.getChild(key); 870ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (child == null) { 871ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Missing value for " + key); 872ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (!child.isLeaf()) { 873ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException(key + " is not a leaf node"); 874ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 875ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return child.getValue(); 876ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 877ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 878ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static long getLong(OMANode node, String key, Long dflt) throws OMAException { 879ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode child = node.getChild(key); 880ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (child == null) { 881ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (dflt != null) { 882ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return dflt; 883ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 884ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Missing value for " + key); 885ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 886ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else { 887ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (!child.isLeaf()) { 888ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException(key + " is not a leaf node"); 889ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 890ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String value = child.getValue(); 891ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 892ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist long result = Long.parseLong(value); 893ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (result < 0) { 894ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Negative value for " + key); 895ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 896ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return result; 897ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (NumberFormatException nfe) { 898ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Value for " + key + " is non-numeric: " + value); 899ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 900ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 901ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 902ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 903ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static <T> T getSelection(OMANode node, String key) throws OMAException { 904ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist OMANode child = node.getChild(key); 905ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (child == null) { 906ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Missing value for " + key); 907ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } else if (!child.isLeaf()) { 908ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException(key + " is not a leaf node"); 909ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 910ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return getSelection(key, child.getValue()); 911ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 912ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 913ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static <T> T getSelection(String key, String value) throws OMAException { 914ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (value == null) { 915ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("No value for " + key); 916ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 917ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Map<String, Object> kvp = sSelectionMap.get(key); 918ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist T result = (T) kvp.get(value.toLowerCase()); 919ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (result == null) { 920ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Invalid value '" + value + "' for " + key); 921ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 922ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return result; 923ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 924ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 925ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static boolean getBoolean(OMANode boolNode) { 926ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return boolNode != null && Boolean.parseBoolean(boolNode.getValue()); 927ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 928ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 929ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static String getString(OMANode stringNode) { 930ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return stringNode != null ? stringNode.getValue() : null; 931ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 932ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 933ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static int getInteger(OMANode intNode, int dflt) throws OMAException { 934ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (intNode == null) { 935ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return dflt; 936ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 937ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return getInteger(intNode); 938ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 939ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 940ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static int getInteger(OMANode intNode) throws OMAException { 941ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (intNode == null) { 942ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Missing integer value"); 943ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 944ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 945ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Integer.parseInt(intNode.getValue()); 946ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (NumberFormatException nfe) { 947ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Invalid integer: " + intNode.getValue()); 948ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 949ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 950ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 951ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static Long getMac(OMANode macNode) throws OMAException { 952ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (macNode == null) { 953ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return null; 954ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 955ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 956ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Long.parseLong(macNode.getValue(), 16); 957ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (NumberFormatException nfe) { 958ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Invalid MAC: " + macNode.getValue()); 959ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 960ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 961ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 962ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static Long getOptionalInteger(OMANode intNode) throws OMAException { 963ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (intNode == null) { 964ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return null; 965ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 966ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 967ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Long.parseLong(intNode.getValue()); 968ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (NumberFormatException nfe) { 969ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Invalid integer: " + intNode.getValue()); 970ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 971ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 972ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 973ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist public static long getTime(OMANode timeNode) throws OMAException { 974ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (timeNode == null) { 975ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Utils.UNSET_TIME; 976ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 977ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist String timeText = timeNode.getValue(); 978ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist try { 979ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist Date date = DTFormat.parse(timeText); 980ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return date.getTime(); 981ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } catch (ParseException pe) { 982ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Badly formatted time: " + timeText); 983ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 984ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 985ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist 986ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist private static byte[] getOctets(OMANode octetNode) throws OMAException { 987ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist if (octetNode == null) { 988ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist throw new OMAException("Missing byte value"); 989ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 990ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist return Utils.hexToBytes(octetNode.getValue()); 991ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist } 992ee699a61a5687d7c8518b639a940c8e9d1b384ddJan Nordqvist} 993