| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server.wifi.passpoint; |
| |
| import android.content.Context; |
| import android.content.BroadcastReceiver; |
| import android.net.wifi.passpoint.WifiPasspointCredential; |
| import android.net.wifi.passpoint.WifiPasspointDmTree; |
| import android.net.wifi.passpoint.WifiPasspointManager; |
| import android.net.wifi.passpoint.WifiPasspointManager.ParcelableString; |
| import android.net.wifi.WifiInfo; |
| import android.net.wifi.WifiManager; |
| import android.net.Uri; |
| import android.os.Message; |
| import android.os.SystemProperties; |
| import android.security.Credentials; |
| import android.telephony.TelephonyManager; |
| import android.text.TextUtils; |
| import android.util.Base64; |
| import android.util.Log; |
| |
| import com.android.org.bouncycastle.asn1.ASN1Encodable; |
| import com.android.org.bouncycastle.asn1.ASN1InputStream; |
| import com.android.org.bouncycastle.asn1.ASN1Object; |
| |
| import com.android.org.bouncycastle.asn1.DERIA5String; |
| import com.android.org.bouncycastle.asn1.DERObjectIdentifier; |
| import com.android.org.bouncycastle.asn1.DEROctetString; |
| import com.android.org.bouncycastle.asn1.DERSequence; |
| import com.android.org.bouncycastle.asn1.DERTaggedObject; |
| import com.android.org.bouncycastle.asn1.DERUTF8String; |
| import com.android.org.bouncycastle.asn1.util.ASN1Dump; |
| import com.android.org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; |
| import com.android.org.bouncycastle.asn1.x509.KeyPurposeId; |
| import com.android.org.bouncycastle.asn1.x509.GeneralName; |
| |
| import com.android.org.bouncycastle.jce.PKCS10CertificationRequest; |
| import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider; |
| import com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException; |
| |
| import com.android.internal.util.StateMachine; |
| import com.android.server.wifi.passpoint.WifiPasspointClient.AuthenticationElement; |
| import com.android.org.conscrypt.TrustManagerImpl; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Enumeration; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Vector; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| |
| import java.net.UnknownHostException; |
| import java.net.URI; |
| |
| import java.security.cert.X509Certificate; |
| import java.security.cert.CertificateException; |
| import java.security.KeyStore; |
| import java.security.cert.CertStore; |
| import java.security.cert.CertificateFactory; |
| import java.security.cert.CertificateParsingException; |
| |
| import javax.net.ssl.TrustManager; |
| import javax.net.ssl.X509TrustManager; |
| |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| import javax.xml.transform.TransformerConfigurationException; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.transform.OutputKeys; |
| |
| import org.apache.http.auth.UsernamePasswordCredentials; |
| import org.apache.http.Header; |
| import org.apache.http.HttpResponse; |
| import org.apache.http.message.BasicHeader; |
| |
| import org.ksoap2.SoapEnvelope; |
| import org.ksoap2.serialization.AttributeInfo; |
| import org.ksoap2.serialization.SoapObject; |
| import org.ksoap2.serialization.SoapSerializationEnvelope; |
| import org.ksoap2.transport.HttpTransportSE; |
| |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| |
| /** |
| * TODO: doc |
| */ |
| public class WifiPasspointSoapClient implements WifiPasspointClient.SoapClient { |
| private StateMachine mTarget; |
| private WifiPasspointClient.DmClient mDmClient; |
| private static final String TAG = "WifiPasspointSoapClient"; |
| private static final String TAG2 = "WifiPasspointSoapClientAdvance"; |
| private static final String NAMESPACE_NS = "http://www.wi-fi.org/specifications/hotspot2dot0/v1.0/spp"; |
| private static final String NAMESPACE_DM = "http://www.openmobilealliance.org/tech/DTD/dm_ddf-v1_2.dtd"; |
| private static final String WIFI_SOAP_POST_DEV_DATA = "sppPostDevData"; |
| private static final String WIFI_SOAP_UPDATE_RESPONSE = "sppUpdateResponse"; |
| private static final String WIFI_SOAP_USER_INPUT_RESPONSE = "sppUserInputResponse"; |
| private static final String WIFI_SOAP_ERROR_CODE = "errorCode"; |
| private static final String WIFI_SOAP_MGMTREE = "MgmtTree"; |
| private static final String WIFI_SOAP_REQ_REASON = "requestReason"; |
| private static final String WIFI_SOAP_REDIRECTURL = "redirectURI"; |
| private static final String WIFI_SOAP_SESSIONID = "sessionID"; |
| private static final String WIFI_SOAP_SYNCML_DMDDF_1_2 = "syncml:dmddf1.2"; |
| private static final String WIFI_SOAP_S_SPP_VERSION = "supportedSPPVersions"; |
| private static final String WIFI_SOAP_S_MOLIST = "supportedMOList"; |
| private static final String WIFI_SOAP_S_MODEVINFO = "urn:oma:mo:oma-dm-devinfo:1.0"; |
| private static final String WIFI_SOAP_S_MODEVDETAIL = "urn:oma:mo:oma-dm-devdetail:1.0"; |
| private static final String WIFI_SOAP_S_MOSUBSCRIPTION = "urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0"; |
| private static final String WIFI_SOAP_S_MOHS20 = "urn:wfa:mo-ext:hotspot2dot0-devdetail-ext:1.0"; |
| private static final String WIFI_SOAP_MO_CONTAINER = "moContainer"; |
| private static final String WIFI_SOAP_MO_URN = "moURN"; |
| private static final String WIFI_SOAP_MO_XMLNS = "xmlns"; |
| private static final String WIFI_SOAP_SPP_VERSION = "sppVersion"; |
| private static final String WIFI_SOAP_SPP_EXCHANGE_COMPLETE = "sppExchangeComplete"; |
| private static final String WIFI_SOAP_SPP_ERROR = "sppError"; |
| private static final String WIFI_SOAP_SPP_NOMOUPDATE = "noMOUpdate"; |
| private static final String WIFI_SOAP_SPP_STATUS = "sppStatus"; |
| private static final String WIFI_SOAP_SPP_STATUS_OK = "OK"; |
| private static final String WIFI_SOAP_SPP_STATUS_PROVISION_COMPLETE = "Provisioning complete, request sppUpdateResponse"; |
| private static final String WIFI_SOAP_SPP_STATUS_REMEDIATION_COMPLETE = "Remediation complete, request sppUpdateResponse"; |
| private static final String WIFI_SOAP_SPP_STATUS_UPDATE_COMPLETE = "Update complete, request sppUpdateResponse"; |
| private static final String WIFI_SOAP_SPP_STATUS_NO_UPDATE_AVAILABLE = "No update available at this time"; |
| private static final String WIFI_SOAP_SPP_STATUS_EXCHANGE_COMPLETE = "Exchange complete, release TLS connection"; |
| private static final String WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED = "Error occurred"; |
| private static final String DEVICE_OBJECT = "The interior node holding all devinfo objects"; |
| private static final String CONTENT_TYPE_XML_CHARSET_UTF_8 = "text/xml;charset=utf-8"; |
| private static final String CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8 = "application/soap+xml;charset=utf-8"; |
| |
| // Subscription Provisioning request reason |
| public static final String SUB_REGISTER = "Subscription registration"; |
| public static final String CERT_ENROLL_SUCCESS = "Certificate enrollment completed"; |
| public static final String CERT_ENROLL_FAIL = "Certificate enrollment failed"; |
| public static final String USER_INPUT_COMPLETED = "User input completed"; |
| public static final String SUB_REMEDIATION = "Subscription remediation"; |
| |
| // for EAP-SIM |
| public static final String SUB_PROVISION = "Subscription provisioning"; |
| public static final String SUB_MO_UPLOAD = "MO upload"; |
| |
| // Policy Provisioning request reason |
| public static final String POL_UPDATE = "Policy update"; |
| public static final String POL_MO_UPLOAD = "MO upload"; |
| |
| // send response error message |
| public static final String WIFI_SOAP_UPDATE_RESPONSE_OK = "OK"; |
| public static final String WIFI_SOAP_UPDATE_RESPONSE_PERMISSION_DENY = "Permission denied"; |
| public static final String WIFI_SOAP_UPDATE_RESPONSE_MO_ADD_UPDATE_FAIL = "MO addition or update failed"; |
| |
| private int mProcedureType; |
| private static final int SUBSCRIPTION_PROVISION = 1; |
| private static final int SUBSCRIPTION_REMEDIATION = 2; |
| private static final int POLICY_UPDATE = 3; |
| private static final int SUBSCRIPTION_SIM_PROVISION = 4; |
| private PpsmoParser mPpsmoParser = new PpsmoParser(); |
| |
| private Context mContext; |
| private String mRedirectUrl; |
| private String mDigestUsername; |
| private String mDigestPassword; |
| private String mSessionID; |
| private String mRequestReason; |
| private String mEnrollmentServerURI; |
| private String mEnrollmentServerCert; |
| private String mOSUFriendlyName; |
| private String mServerUrl; |
| |
| TrustManager[] myTrustManagerArray = new TrustManager[] { |
| new CertTrustManager() |
| }; |
| private static KeyStore sHs20Pkcs12KeyStore; |
| private String mSpFqdn; |
| private String mSpFqdnFromMo; |
| private static String mOSULanguage; |
| private static String iconFileName; |
| private static String iconHash; |
| private static String enrollDigestUsername; |
| private static String enrollDigestPassword; |
| private WifiPasspointCertificate mPasspointCertificate; |
| private static final int NO_CLIENT_AUTH = 0; |
| private static final int CLIENT_CERT = 1; |
| private static final int RENEGOTIATE_CERT = 2; |
| // pre-provisioned certificate by a provider |
| private static String providerIssuerName; |
| |
| private WifiPasspointDmTree mSoapTree; |
| private WifiPasspointDmTreeHelper mTreeHelper; |
| private WifiPasspointCredential mCred; |
| private WifiPasspointCertificate.FileOperationUtil mFileOperation; |
| |
| public WifiPasspointSoapClient(Context context, WifiPasspointClient.DmClient client) { |
| mContext = context; |
| mDmClient = client; |
| } |
| |
| @Override |
| public void init(StateMachine target) { |
| Log.d(TAG, "[init]"); |
| mTarget = target; |
| mTreeHelper = new WifiPasspointDmTreeHelper(); |
| mRequestReason = null; |
| mDigestUsername = null; |
| mDigestPassword = null; |
| |
| // Credential |
| mServerUrl = null; |
| // Certificate |
| mPasspointCertificate = WifiPasspointCertificate.getInstance(null); |
| mFileOperation = mPasspointCertificate.new FileOperationUtil(); |
| } |
| |
| @Override |
| public void startSubscriptionProvision(String serverUrl) { |
| Log.d(TAG, "Run startSubscriptionProvision with " + serverUrl); |
| mProcedureType = SUBSCRIPTION_PROVISION; |
| mServerUrl = serverUrl; |
| mSpFqdnFromMo = null; |
| mRequestReason = SUB_REGISTER; |
| subscriptionProvision(serverUrl); |
| } |
| |
| @Override |
| public void startRemediation(String serverUrl, WifiPasspointCredential cred) { |
| Log.d(TAG, "Run startRemediation with " + serverUrl); |
| mProcedureType = SUBSCRIPTION_REMEDIATION; |
| mServerUrl = serverUrl; |
| mSpFqdnFromMo = null; |
| |
| if ("SIM".equals(cred.getType())) { |
| mRequestReason = SUB_PROVISION; |
| } else { |
| mRequestReason = SUB_REMEDIATION; |
| } |
| |
| if (cred != null) { |
| mCred = cred; |
| } else { |
| Log.d(TAG, "cred is null"); |
| return; |
| } |
| |
| remediation(serverUrl); |
| } |
| |
| @Override |
| public void startPolicyProvision(String serverUrl, WifiPasspointCredential cred) { |
| Log.d(TAG, "Run startPolicyProvision with " + serverUrl); |
| mProcedureType = POLICY_UPDATE; |
| mSpFqdnFromMo = null; |
| mRequestReason = POL_UPDATE; |
| mServerUrl = serverUrl; |
| |
| if (cred != null) { |
| mCred = cred; |
| } else { |
| Log.d(TAG, "cred is null"); |
| return; |
| } |
| |
| policyProvision(serverUrl); |
| } |
| |
| @Override |
| public void setWifiTree(WifiPasspointDmTree tree) { |
| mSoapTree = tree; |
| } |
| |
| @Override |
| public void notifyBrowserRedirected() { |
| mRequestReason = USER_INPUT_COMPLETED; |
| if (mProcedureType == SUBSCRIPTION_PROVISION) { |
| subscriptionProvision(mServerUrl); |
| } else if (mProcedureType == SUBSCRIPTION_REMEDIATION) { |
| remediation(mServerUrl); |
| } |
| } |
| |
| @Override |
| public void setBrowserRedirectUri(String uri) { |
| mRedirectUrl = uri; |
| } |
| |
| @Override |
| public void setAuthenticationElement(AuthenticationElement ae) { |
| Log.d(TAG, "set SPFQDN:" + ae.spFqdn); |
| Log.d(TAG, "OSU Friendly Name:" + ae.osuFriendlyName); |
| Log.d(TAG, "Default language name:" + ae.osuDefaultLanguage); |
| |
| mSpFqdn = ae.spFqdn; |
| mOSUFriendlyName = ae.osuFriendlyName; |
| mOSULanguage = ae.osuDefaultLanguage; |
| try { |
| iconFileName = ae.osuIconfileName; |
| iconHash = mPasspointCertificate.computeHash( |
| mFileOperation.Read(new File("/data/misc/wifi/icon/" + iconFileName)), |
| "SHA-256");// ext: image/xxx |
| Log.d(TAG, "Icon file name:" + iconFileName + " icon hash:" + iconHash); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| private void setRemediationHttpDigest() { |
| Log.d(TAG, "[setRemediationHttpDigest]"); |
| mDigestUsername = null; |
| mDigestPassword = null; |
| String eapType = mCred.getType(); |
| Log.d(TAG, "eapType = " + eapType); |
| if (eapType.equals("TTLS")) { |
| String subscriptionUpdateUsername = mCred.getSubscriptionUpdateUsername(); |
| String subscriptionUpdatePassword = mCred.getSubscriptionUpdatePassword(); |
| String credentialUsername = mCred.getUserName(); |
| String credentialPassword = mCred.getPassword(); |
| |
| if (subscriptionUpdateUsername != null) { |
| Log.d(TAG, "subscriptionUpdateUsername = " + subscriptionUpdateUsername |
| + ", subscriptionUpdatePassword = " + subscriptionUpdatePassword); |
| if (!subscriptionUpdateUsername.isEmpty()) { |
| mDigestUsername = subscriptionUpdateUsername; |
| mDigestPassword = subscriptionUpdatePassword; |
| Log.d(TAG, |
| "digest using Subscription Update, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| } else if (credentialUsername != null && !credentialUsername.isEmpty()) { |
| Log.d(TAG, "credentialUsername = " + credentialUsername |
| + ", credentialPassword = " + credentialPassword); |
| mDigestUsername = credentialUsername; |
| mDigestPassword = credentialPassword; |
| Log.d(TAG, "digest using credential, mDigestUsername/digestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| } |
| } else if (credentialUsername != null && !credentialUsername.isEmpty()) { |
| Log.d(TAG, "credentialUsername = " + credentialUsername + ", credentialPassword = " |
| + credentialPassword); |
| mDigestUsername = credentialUsername; |
| mDigestPassword = credentialPassword; |
| Log.d(TAG, "digest using credential, mDigestUsername/digestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| } |
| } |
| } |
| |
| private void setPolicyUpdateHttpDigest() { |
| mDigestUsername = null; |
| mDigestPassword = null; |
| |
| String eapType = mCred.getType(); |
| if (eapType.equals("TTLS")) { |
| String policyUpdateUsername = mCred.getPolicyUpdateUsername(); |
| String policyUpdatePassword = mCred.getPolicyUpdatePassword(); |
| String credentialUsername = mCred.getUserName(); |
| String credentialPassword = mCred.getPassword(); |
| |
| if (policyUpdateUsername != null) { |
| if (!policyUpdateUsername.isEmpty()) { |
| mDigestUsername = policyUpdateUsername; |
| mDigestPassword = policyUpdatePassword; |
| Log.d(TAG, "digest using Policy Update, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| } else if (credentialUsername != null && !credentialUsername.isEmpty()) { |
| mDigestUsername = credentialUsername; |
| mDigestPassword = credentialPassword; |
| Log.d(TAG, "digest using credential, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| } |
| } else if (credentialUsername != null && !credentialUsername.isEmpty()) { |
| mDigestUsername = credentialUsername; |
| mDigestPassword = credentialPassword; |
| Log.d(TAG, "digest using credential, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| } |
| } |
| |
| } |
| |
| private String getDeviceId() { |
| TelephonyManager tm = |
| (TelephonyManager) (mContext.getSystemService(Context.TELEPHONY_SERVICE)); |
| if (null == tm) { |
| return new String("000000000000000"); |
| } |
| |
| String imei = tm.getDeviceId(); |
| if (imei == null || imei.isEmpty()) { |
| return new String("000000000000000"); |
| } |
| |
| return imei; |
| } |
| |
| private void startCertificateEnroll(String serverUrl, String operation) { |
| Log.d(TAG, "enrollmentServerURI: " + mEnrollmentServerURI + ", operation: " + operation); |
| WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); |
| boolean enrollSuccess; |
| Message msg = null; |
| if (wifiManager != null) { |
| WifiInfo wifiInfo = wifiManager.getConnectionInfo(); |
| if (wifiInfo == null) { |
| Log.d(TAG, "no ConnectionInfo found"); |
| return; |
| } |
| mPasspointCertificate.setMacAddress(wifiInfo.getMacAddress()); |
| mPasspointCertificate.setImeiOrMeid(getDeviceId()); |
| if (operation.equals(mPasspointCertificate.ENROLL)) { |
| enrollSuccess = mPasspointCertificate.connectESTServer(mEnrollmentServerURI, |
| operation, enrollDigestUsername, enrollDigestPassword, null); |
| } else { |
| String credentialCertSHA256Fingerprint = mCred.getCertSha256Fingerprint(); |
| |
| String subjectDN = mPasspointCertificate |
| .getSubjectX500PrincipalFromPKCS12Keystore(credentialCertSHA256Fingerprint); |
| Log.d(TAG, "subjectDN:" + subjectDN); |
| if (subjectDN == null) { |
| enrollSuccess = false; |
| } else { |
| enrollSuccess = mPasspointCertificate.connectESTServer(mEnrollmentServerURI, |
| operation, enrollDigestUsername, enrollDigestPassword, subjectDN); |
| } |
| } |
| Log.d(TAG, "Certificate Enrolled :" + enrollSuccess); |
| |
| if (!enrollSuccess) { |
| Log.d(TAG, "Certificate Enroll fail!!!"); |
| } |
| } else { |
| Log.d(TAG, "Wifi service not exist, OSU stops"); |
| return; |
| } |
| |
| if (enrollSuccess) { |
| // success |
| mRequestReason = CERT_ENROLL_SUCCESS; |
| if (mProcedureType == SUBSCRIPTION_PROVISION) { |
| subscriptionProvision(serverUrl); |
| } else if (mProcedureType == SUBSCRIPTION_REMEDIATION) { |
| remediation(serverUrl); |
| } |
| } else { |
| // fail |
| mRequestReason = CERT_ENROLL_FAIL; |
| if (mProcedureType == SUBSCRIPTION_PROVISION) { |
| subscriptionProvision(serverUrl); |
| } else if (mProcedureType == SUBSCRIPTION_REMEDIATION) { |
| remediation(serverUrl); |
| } |
| } |
| } |
| |
| private void subscriptionProvision(final String serverUrl) { |
| new Thread(new Runnable() { |
| public void run() { |
| try { |
| SoapObject request = createOsuRequest(mRequestReason); |
| String response = null; |
| |
| response = connectSoapServer(serverUrl, request, null, null, NO_CLIENT_AUTH); |
| |
| if (response == null) { |
| Log.e(TAG, "[startSubscriptionProvisioning] Fail to get soap resonse"); |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_OSU_DONE, 9, 0, null);// "Not found" |
| return; |
| } |
| |
| Document doc = mPpsmoParser.getDocument(response); |
| String status = checkStatus(doc); |
| |
| // get OSU server page to fill form |
| // while certificate enrollment fail, go to OSU server |
| // page to do user-managed user/pass credential |
| // registration again |
| if (WIFI_SOAP_SPP_STATUS_OK.equals(status)) { |
| if (isLaunchBrowserExecution(doc)) { |
| Log.d(TAG, "[New] redirect to browser"); |
| } else if (isUseClientCertTlsExecution(doc)) { |
| // to use pre-installed client certificate |
| } else if (isEnrollmentExecution(doc)) { |
| startCertificateEnroll(serverUrl, mPasspointCertificate.ENROLL); |
| } |
| } |
| // addMO from server |
| // while certificate enrollment success, just send |
| // sppUpdateResponse |
| // while certificate enrollment fail, install |
| // machine-managed user/pass credential, then send |
| // sppUpdateResponse |
| else if (WIFI_SOAP_SPP_STATUS_PROVISION_COMPLETE.equals(status)) { |
| if (isWifiSpFqdnForAddMo(doc)) { |
| Document docMgmtTree = mPpsmoParser.extractMgmtTree(response); |
| String moTree = mPpsmoParser.xmlToString(docMgmtTree); |
| String treeUri = getSppTreeUri(doc, "addMO"); |
| int injStatus = mDmClient.injectSoapPackage(treeUri, "addMO", moTree); |
| |
| if (injStatus == 0) { |
| mSoapTree = mDmClient.getWifiTree(); |
| sendUpdateResponse(serverUrl, true, SUBSCRIPTION_PROVISION, |
| WIFI_SOAP_UPDATE_RESPONSE_OK); |
| } else { |
| sendUpdateResponse(serverUrl, true, SUBSCRIPTION_PROVISION, |
| WIFI_SOAP_UPDATE_RESPONSE_MO_ADD_UPDATE_FAIL); |
| } |
| } else { |
| sendUpdateResponse(serverUrl, false, SUBSCRIPTION_PROVISION, |
| WIFI_SOAP_UPDATE_RESPONSE_PERMISSION_DENY); |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_EXCHANGE_COMPLETE.equals(status)) { |
| // abort provisioning |
| // while certificate enrollment fail |
| String err = checkErrorCode(doc); |
| Log.e(TAG, |
| "[startSubscriptionProvisioning] Exchange complete, release TLS connection error occurred: " |
| + err); |
| } else if (WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED.equals(status)) { |
| Log.e(TAG, "[startSubscriptionProvisioning] Error occurred"); |
| getErrorCode(doc); |
| } else { |
| status = checkStatus(doc, NAMESPACE_NS, WIFI_SOAP_USER_INPUT_RESPONSE); |
| if (WIFI_SOAP_SPP_STATUS_OK.equals(status)) { |
| if (isEnrollmentExecution(doc)) { |
| startCertificateEnroll(serverUrl, mPasspointCertificate.ENROLL); |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED.equals(status)) { |
| Log.e(TAG, |
| "[startSubscriptionProvisioning] checkStatus of sppUserInputResponse Error occurred"); |
| getErrorCode(doc); |
| } else { |
| Log.e(TAG, "[startSubscriptionProvisioning] unknown status"); |
| } |
| |
| } |
| return; |
| |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| }).start(); |
| } |
| |
| private void remediation(final String serverUrl) { |
| if (!USER_INPUT_COMPLETED.equals(mRequestReason) && !SUB_MO_UPLOAD.equals(mRequestReason)) { |
| setRemediationHttpDigest(); |
| } |
| |
| new Thread(new Runnable() { |
| public void run() { |
| int managementTreeUpdateCount = 0; |
| try { |
| SoapObject request = createRemediationRequest(serverUrl, mRequestReason); |
| String response = null; |
| |
| String eapType = null; |
| if (mCred != null) { |
| eapType = mCred.getType(); |
| } |
| |
| if ("SIM".equals(eapType)) { |
| Log.d(TAG, "EAP-SIM, no digest or client certifcate"); |
| response = connectSoapServer(serverUrl, request, null, null, NO_CLIENT_AUTH); |
| } else if ("TTLS".equals(eapType)) { |
| if (mDigestUsername != null && !mDigestUsername.isEmpty()) { |
| Log.d(TAG, |
| "digest using U/P or Subscription update credential, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| response = connectSoapServer(serverUrl, request, mDigestUsername, |
| mDigestPassword, NO_CLIENT_AUTH); |
| } |
| } else if ("TLS".equals(eapType)) { |
| String credentialCertSHA256Fingerprint = mCred |
| .getCertSha256Fingerprint(); |
| Log.d(TAG, "digest using client cert credential, SHA256 fingerprint: " |
| + credentialCertSHA256Fingerprint); |
| sHs20Pkcs12KeyStore = mPasspointCertificate |
| .getCredentialCertKeyStore(credentialCertSHA256Fingerprint); |
| |
| if (sHs20Pkcs12KeyStore != null) { |
| response = connectSoapServer(serverUrl, request, null, null, CLIENT_CERT); |
| } else { |
| Log.d(TAG, "client certifcate not found"); |
| } |
| } else { |
| Log.d(TAG, "unknow credential type"); |
| return; |
| } |
| |
| if (response == null) { |
| Log.e(TAG, "[startRemediation] Fail to get soap resonse"); |
| return; |
| } |
| |
| Document doc = mPpsmoParser.getDocument(response); |
| String status = checkStatus(doc); |
| if (WIFI_SOAP_SPP_STATUS_REMEDIATION_COMPLETE.equals(status)) { |
| if (isNoMoUpdate(doc)) { |
| Log.d(TAG, WIFI_SOAP_SPP_NOMOUPDATE); |
| } else if (isLaunchBrowserExecution(doc)) { |
| Log.d(TAG, "[New] launch browser"); |
| } else { |
| if (isWifiSpFqdnForUpdateMo(doc)) { |
| Vector<Document> sppUpdateNodes = mPpsmoParser.getSPPNodes(doc, |
| NAMESPACE_NS, "updateNode"); |
| for (Document docNodes : sppUpdateNodes) { |
| ++managementTreeUpdateCount; |
| Document docMgmtTree = mPpsmoParser.extractMgmtTree(docNodes); |
| String moTree = mPpsmoParser.xmlToString(docMgmtTree); |
| Log.d(TAG2, moTree); |
| String sppTreeUri = getSppTreeUri(docNodes, "updateNode"); |
| int injStatus = mDmClient.injectSoapPackage(sppTreeUri, |
| "updateNode", moTree); |
| |
| if (injStatus == 0) { |
| --managementTreeUpdateCount; |
| } |
| } |
| |
| if (sppUpdateNodes.size() != 0 && managementTreeUpdateCount == 0) { |
| mSoapTree = mDmClient.getWifiTree(); |
| sendUpdateResponse(serverUrl, true, SUBSCRIPTION_REMEDIATION, |
| WIFI_SOAP_UPDATE_RESPONSE_OK); |
| } else { |
| sendUpdateResponse(serverUrl, false, SUBSCRIPTION_REMEDIATION, |
| WIFI_SOAP_UPDATE_RESPONSE_MO_ADD_UPDATE_FAIL); |
| } |
| } else { |
| sendUpdateResponse(serverUrl, false, SUBSCRIPTION_REMEDIATION, |
| WIFI_SOAP_UPDATE_RESPONSE_PERMISSION_DENY); |
| } |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_OK.equals(status)) { |
| if (isUploadMO(doc)) { |
| mRequestReason = SUB_MO_UPLOAD; |
| remediation(serverUrl); |
| } else if (isLaunchBrowserExecution(doc)) { |
| Log.d(TAG, "[New] redirect to browser"); |
| } else if (isEnrollmentExecution(doc)) { |
| startCertificateEnroll(serverUrl, mPasspointCertificate.REENROLL); |
| } else { |
| if (isWifiSpFqdnForUpdateMo(doc)) { |
| Vector<Document> sppUpdateNodes = mPpsmoParser.getSPPNodes(doc, |
| NAMESPACE_NS, "updateNode"); |
| for (Document docNodes : sppUpdateNodes) { |
| ++managementTreeUpdateCount; |
| Document docMgmtTree = mPpsmoParser.extractMgmtTree(docNodes); |
| String moTree = mPpsmoParser.xmlToString(docMgmtTree); |
| Log.d(TAG2, moTree); |
| String sppTreeUri = getSppTreeUri(docNodes, "updateNode"); |
| int injStatus = mDmClient.injectSoapPackage(sppTreeUri, |
| "updateNode", moTree); |
| |
| if (injStatus == 0) { |
| --managementTreeUpdateCount; |
| } |
| } |
| |
| if (sppUpdateNodes.size() != 0 && managementTreeUpdateCount == 0) { |
| mSoapTree = mDmClient.getWifiTree(); |
| sendUpdateResponse(serverUrl, true, SUBSCRIPTION_REMEDIATION, |
| WIFI_SOAP_UPDATE_RESPONSE_OK); |
| } else { |
| sendUpdateResponse(serverUrl, false, SUBSCRIPTION_REMEDIATION, |
| WIFI_SOAP_UPDATE_RESPONSE_MO_ADD_UPDATE_FAIL); |
| } |
| } else { |
| sendUpdateResponse(serverUrl, false, SUBSCRIPTION_REMEDIATION, |
| WIFI_SOAP_UPDATE_RESPONSE_PERMISSION_DENY); |
| } |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_PROVISION_COMPLETE.equals(status)) { |
| Document docMgmtTree = mPpsmoParser.extractMgmtTree(response); |
| String moTree = mPpsmoParser.xmlToString(docMgmtTree); |
| String treeUri = getSppTreeUri(doc, "addMO"); |
| int injStatus = mDmClient.injectSoapPackage(treeUri, "addMO", moTree); |
| |
| if (injStatus == 0) { |
| mSoapTree = mDmClient.getWifiTree(); |
| sendUpdateResponse(serverUrl, true, SUBSCRIPTION_SIM_PROVISION, |
| WIFI_SOAP_UPDATE_RESPONSE_OK); |
| } else { |
| sendUpdateResponse(serverUrl, false, SUBSCRIPTION_SIM_PROVISION, |
| WIFI_SOAP_UPDATE_RESPONSE_MO_ADD_UPDATE_FAIL); |
| |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_EXCHANGE_COMPLETE.equals(status)) { |
| Log.d(TAG, WIFI_SOAP_SPP_STATUS_EXCHANGE_COMPLETE); |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_REMEDIATION_DONE, 0, 0, mSoapTree);// "NoUpdate" |
| } else if (WIFI_SOAP_SPP_STATUS_NO_UPDATE_AVAILABLE.equals(status)) { |
| Log.d(TAG, WIFI_SOAP_SPP_STATUS_NO_UPDATE_AVAILABLE); |
| } else if (WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED.equals(status)) { |
| Log.e(TAG, "[startRemediation] Error occurred"); |
| getErrorCode(doc); |
| } else { |
| Log.e(TAG, "[startRemediation] unknown status"); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| }).start(); |
| } |
| |
| private void policyProvision(final String serverUrl) { |
| if (POL_UPDATE.equals(mRequestReason)) { |
| setPolicyUpdateHttpDigest(); |
| } |
| |
| new Thread(new Runnable() { |
| public void run() { |
| int managementTreeUpdateCount = 0; |
| try { |
| SoapObject request = createPolicyUpdateRequest(serverUrl, mRequestReason); |
| String response = null; |
| |
| if (mDigestUsername != null && !mDigestUsername.isEmpty()) { |
| Log.d(TAG, |
| "digest using U/P Credential or Policy update, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| response = connectSoapServer(serverUrl, request, mDigestUsername, mDigestPassword, |
| NO_CLIENT_AUTH); |
| } |
| |
| if (response != null && !response.isEmpty()) { |
| Document doc = mPpsmoParser.getDocument(response); |
| String status = checkStatus(doc); |
| if (WIFI_SOAP_SPP_STATUS_OK.equals(status)) { |
| if (isUploadMO(doc)) { |
| if (isWifiSpFqdnForUploadMo(doc)) { |
| mRequestReason = POL_MO_UPLOAD; |
| policyProvision(serverUrl); |
| return; |
| } else { |
| sendUpdateResponse(serverUrl, false, POLICY_UPDATE, |
| WIFI_SOAP_UPDATE_RESPONSE_PERMISSION_DENY); |
| return; |
| } |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_UPDATE_COMPLETE.equals(status)) { |
| if (isWifiSpFqdnForUpdateMo(doc)) { |
| Vector<Document> sppUpdateNodes = mPpsmoParser.getSPPNodes(doc, |
| NAMESPACE_NS, "updateNode"); |
| for (Document docNodes : sppUpdateNodes) { |
| ++managementTreeUpdateCount; |
| Document docMgmtTree = mPpsmoParser.extractMgmtTree(docNodes); |
| String moTree = mPpsmoParser.xmlToString(docMgmtTree); |
| Log.d(TAG2, moTree); |
| String sppTreeUri = getSppTreeUri(docNodes, "updateNode"); |
| int injStatus = mDmClient.injectSoapPackage(sppTreeUri, |
| "updateNode", moTree); |
| |
| if (injStatus == 0) { |
| --managementTreeUpdateCount; |
| } |
| } |
| |
| if (sppUpdateNodes.size() != 0 && managementTreeUpdateCount == 0) { |
| mSoapTree = mDmClient.getWifiTree(); |
| sendUpdateResponse(serverUrl, true, POLICY_UPDATE, |
| WIFI_SOAP_UPDATE_RESPONSE_OK); |
| } else { |
| sendUpdateResponse(serverUrl, false, POLICY_UPDATE, |
| WIFI_SOAP_UPDATE_RESPONSE_MO_ADD_UPDATE_FAIL); |
| } |
| } else { |
| sendUpdateResponse(serverUrl, false, POLICY_UPDATE, |
| WIFI_SOAP_UPDATE_RESPONSE_PERMISSION_DENY); |
| } |
| |
| return; |
| } else if (WIFI_SOAP_SPP_STATUS_NO_UPDATE_AVAILABLE.equals(status)) { |
| Log.d(TAG, WIFI_SOAP_SPP_STATUS_NO_UPDATE_AVAILABLE); |
| } else if (WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED.equals(status)) { |
| Log.e(TAG, "[startPolicyProvision] Error occurred"); |
| getErrorCode(doc); |
| } else { |
| Log.e(TAG, "[startPolicyProvision] unknown status"); |
| } |
| } else { |
| Log.e(TAG, "[startPolicyProvision] Fail to get soap resonse"); |
| } |
| |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| |
| if (mTarget != null) { |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_POLICY_UPDATE_DONE, 0, 0, mSoapTree); |
| } else { |
| Log.e(TAG, |
| "[startPolicyProvision] send CMD_POLICY_UPDATE_DONE fail, mTarget null"); |
| } |
| } |
| }).start(); |
| } |
| |
| private String connectSoapServer(String serverUrl, SoapObject request, String digestUsername, |
| String digestPassword, int clientCertType) { |
| if (mRedirectUrl == null) { |
| Log.e(TAG, "Failed to connect due to null redirect URL"); |
| return null; |
| } |
| |
| Log.d(TAG, "[connectSoapServer]: request:" + request); |
| String response = null; |
| SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER12); |
| envelope.setAddAdornments(false); |
| envelope.implicitTypes = true; |
| envelope.dotNet = false; |
| envelope.setOutputSoapObject(request); |
| |
| Log.d(TAG, "Server url:" + serverUrl); |
| |
| if (serverUrl.startsWith("HTTPS://") || serverUrl.startsWith("https://")) { |
| try { |
| int retryCount = 5; |
| boolean isConnected = false; |
| |
| WifiPasspointHttpClient hc = null; |
| UsernamePasswordCredentials credentials = null; |
| |
| if (digestUsername != null && digestPassword != null) { |
| credentials = new UsernamePasswordCredentials(digestUsername, digestPassword); |
| hc = new WifiPasspointHttpClient(credentials); |
| } else if (clientCertType == CLIENT_CERT) { |
| if (sHs20Pkcs12KeyStore.aliases().hasMoreElements()) { |
| hc = new WifiPasspointHttpClient(sHs20Pkcs12KeyStore, |
| mPasspointCertificate.passWord.toCharArray()); |
| } else { |
| Log.d(TAG, "client cert is not installed in passpoint PKCS12 keystore"); |
| return null; |
| } |
| } else { |
| hc = new WifiPasspointHttpClient(); |
| } |
| |
| while (retryCount > 0 && !isConnected) { |
| try { |
| URI requestUri = new URI(serverUrl); |
| HttpResponse httpResp = null; |
| byte[] requestData = |
| (new HttpTransportSE(serverUrl)) |
| .getRequestData(envelope, "UTF-8"); |
| Header[] requestHeaders; |
| List<BasicHeader> basicHeaders = new ArrayList<BasicHeader>(); |
| |
| if (requestData == null) { |
| break; |
| } |
| |
| basicHeaders.add(new BasicHeader(hc.CONNECTION, "close")); |
| basicHeaders.add(new BasicHeader(hc.ACCEPT_ENCODING_HEADER, "gzip")); |
| |
| requestHeaders = basicHeaders.toArray(new Header[basicHeaders.size()]); |
| |
| if (envelope.version == SoapSerializationEnvelope.VER12) { |
| httpResp = hc.post(requestUri, CONTENT_TYPE_SOAP_XML_CHARSET_UTF_8, |
| requestData, requestHeaders); |
| } else { |
| httpResp = hc.post(requestUri, CONTENT_TYPE_XML_CHARSET_UTF_8, |
| requestData, requestHeaders); |
| } |
| |
| InputStream is = httpResp.getEntity().getContent(); |
| |
| ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
| byte[] buf = new byte[8192]; |
| |
| while (true) { |
| int rd = is.read(buf, 0, 8192); |
| if (rd == -1) { |
| break; |
| } |
| bos.write(buf, 0, rd); |
| } |
| |
| bos.flush(); |
| response = bos.toString(); |
| isConnected = true; |
| Log.d(TAG, "soap connect by TLS"); |
| } catch (UnknownHostException ee) { |
| retryCount--; |
| Log.d(TAG, "Wait for retry:" + retryCount); |
| Thread.sleep(3 * 1000); |
| } |
| } |
| |
| if (!isConnected) { |
| Log.e(TAG, "Failed to connect"); |
| return null; |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| return response; |
| } |
| |
| private void sendUpdateResponse(final String serverUrl, final boolean success, final int procedureType, final String reason) { |
| Log.d(TAG, "[sendUpdateResponse] start, success = " + success + ", procedureType = " |
| + procedureType + ", reason = " + reason); |
| |
| new Thread(new Runnable() { |
| public void run() { |
| try { |
| SoapObject request = new SoapObject(); |
| String response = null; |
| |
| if (success == true) { |
| request = createUpdateResponseRequest(false, null); |
| } else { |
| request = createUpdateResponseRequest(true, reason); |
| } |
| |
| if (procedureType == POLICY_UPDATE || procedureType == SUBSCRIPTION_REMEDIATION) { |
| String eapType = mCred.getType(); |
| String credentialCertSHA256Fingerprint = mCred.getCertSha256Fingerprint(); |
| |
| if (mDigestUsername != null && !mDigestUsername.isEmpty()) { |
| Log.d(TAG, |
| "digest using U/P or Policy update credential, mDigestUsername/mDigestPassword: " |
| + mDigestUsername + "/" + mDigestPassword); |
| response = connectSoapServer(serverUrl, request, mDigestUsername, mDigestPassword, |
| NO_CLIENT_AUTH); |
| } |
| else if ("TLS".equals(eapType)) { |
| Log.d(TAG, "digest using client cert credential, SHA256 fingerprint: " |
| + credentialCertSHA256Fingerprint); |
| response = connectSoapServer(serverUrl, request, null, null, CLIENT_CERT); |
| } |
| } else { |
| // procedureType == SUBSCRIPTION_PROVISION || |
| // procedureType == SUBSCRIPTION_SIM_PROVISION |
| Log.d(TAG, "OSU, no need to set digest"); |
| response = connectSoapServer(serverUrl, request, null, null, NO_CLIENT_AUTH); |
| } |
| |
| if (response == null || response.isEmpty()) { |
| Log.e(TAG, "[sendUpdateResponse] Fail to get soap resonse"); |
| return; |
| } |
| |
| Document doc = mPpsmoParser.getDocument(response); |
| String status = checkStatus(doc, NAMESPACE_NS, WIFI_SOAP_SPP_EXCHANGE_COMPLETE); |
| |
| if (WIFI_SOAP_SPP_STATUS_EXCHANGE_COMPLETE.equals(status)) { |
| Log.d(TAG, "[sendUpdateResponse] exchange complete"); |
| if (procedureType == SUBSCRIPTION_PROVISION) { |
| Log.d(TAG, |
| "[sendUpdateResponse] exchange complete:procedureType == SUBSCRIPTION_PROVISION"); |
| |
| boolean result = true; |
| |
| Collection<WifiPasspointDmTree.CredentialInfo> creds = mTreeHelper |
| .getCredentialInfo(mTreeHelper.getSp(mSoapTree, |
| mSpFqdnFromMo)); |
| for (WifiPasspointDmTree.CredentialInfo credInfo : creds) { |
| // Save mapping of enrolled certificate |
| // alias and SHA256 fingerprint |
| if (credInfo.credential.digitalCertificate.CertificateType |
| .equals("x509v3")) { |
| mPasspointCertificate.saveMappingOfEnrollCertAliasAndSha256( |
| mPasspointCertificate.getEnrollCertAlias(), |
| credInfo.credential.digitalCertificate.CertSHA256Fingerprint); |
| } |
| |
| for (WifiPasspointDmTree.AAAServerTrustRoot aaaTrustRoot : credInfo.aAAServerTrustRoot |
| .values()) { |
| result &= mPasspointCertificate.installServerTrustRoot( |
| aaaTrustRoot.CertURL, |
| aaaTrustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.AAA_ROOT, false); |
| } |
| result &= mPasspointCertificate |
| .installServerTrustRoot( |
| credInfo.subscriptionUpdate.trustRoot.CertURL, |
| credInfo.subscriptionUpdate.trustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.SUBSCRIPTION_ROOT, false); |
| result &= mPasspointCertificate |
| .installServerTrustRoot( |
| credInfo.policy.policyUpdate.trustRoot.CertURL, |
| credInfo.policy.policyUpdate.trustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.POLICY_ROOT, false); |
| result &= success; |
| } |
| |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_OSU_DONE, result ? 0 : 1, 0, |
| result ? mSoapTree : null); |
| } else if (procedureType == SUBSCRIPTION_SIM_PROVISION) { |
| Log.d(TAG, |
| "[sendUpdateResponse] exchange complete:procedureType == SUBSCRIPTION_SIM_PROVISION"); |
| |
| boolean result = true; |
| |
| Collection<WifiPasspointDmTree.CredentialInfo> creds = mTreeHelper |
| .getCredentialInfo(mTreeHelper.getSp(mSoapTree, |
| mSpFqdnFromMo)); |
| for (WifiPasspointDmTree.CredentialInfo credInfo : creds) { |
| for (WifiPasspointDmTree.AAAServerTrustRoot aaaTrustRoot : credInfo.aAAServerTrustRoot |
| .values()) { |
| result &= mPasspointCertificate.installServerTrustRoot( |
| aaaTrustRoot.CertURL, |
| aaaTrustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.AAA_ROOT, false); |
| } |
| result &= mPasspointCertificate |
| .installServerTrustRoot( |
| credInfo.subscriptionUpdate.trustRoot.CertURL, |
| credInfo.subscriptionUpdate.trustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.SUBSCRIPTION_ROOT, false); |
| result &= mPasspointCertificate |
| .installServerTrustRoot( |
| credInfo.policy.policyUpdate.trustRoot.CertURL, |
| credInfo.policy.policyUpdate.trustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.POLICY_ROOT, false); |
| result &= success; |
| } |
| |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_SIM_PROVISION_DONE, result ? 0 : 1, |
| 0, |
| result ? mSoapTree : null); |
| } else if (procedureType == SUBSCRIPTION_REMEDIATION) { |
| Log.d(TAG, |
| "[sendUpdateResponse] exchange complete:procedureType == SUBSCRIPTION_REMEDIATION"); |
| |
| boolean result = true; |
| |
| WifiPasspointDmTree.CredentialInfo credInfo = mTreeHelper.getCredentialInfo( |
| mSoapTree, mCred.getWifiSpFqdn(), mCred.getCredName()); |
| if (credInfo == null) { |
| Log.d(TAG, "credInfo is null while retrieving AAA trust root"); |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_REMEDIATION_DONE, 3, 0, |
| null);// "MO addition or update failed" |
| return; |
| } else { |
| for (WifiPasspointDmTree.AAAServerTrustRoot aaaTrustRoot : credInfo.aAAServerTrustRoot |
| .values()) { |
| result &= mPasspointCertificate.installServerTrustRoot( |
| aaaTrustRoot.CertURL, |
| aaaTrustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.AAA_ROOT, true); |
| } |
| result &= mPasspointCertificate |
| .installServerTrustRoot( |
| credInfo.subscriptionUpdate.trustRoot.CertURL, |
| credInfo.subscriptionUpdate.trustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.SUBSCRIPTION_ROOT, false); |
| result &= mPasspointCertificate |
| .installServerTrustRoot( |
| credInfo.policy.policyUpdate.trustRoot.CertURL, |
| credInfo.policy.policyUpdate.trustRoot.CertSHA256Fingerprint, |
| WifiPasspointCertificate.POLICY_ROOT, false); |
| result &= success; |
| |
| } |
| |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_REMEDIATION_DONE, success ? 0 : 1, 0, |
| success ? mSoapTree : null);// "MO addition or update failed" |
| } else if (procedureType == POLICY_UPDATE) { |
| Log.d(TAG, |
| "[sendUpdateResponse] exchange complete:procedureType == POLICY_UPDATE"); |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_POLICY_UPDATE_DONE, success ? 0 : 1, |
| 0, |
| success ? mSoapTree : null); |
| } |
| } else if (WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED.equals(status)) { |
| Log.e(TAG, "[sendUpdateResponse] Error occurred"); |
| getErrorCode(doc); |
| } else { |
| Log.e(TAG, "[sendUpdateResponse] unknown status"); |
| } |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| } |
| }).start(); |
| |
| } |
| |
| private SoapObject createOsuRequest(String requestReason) { |
| // Construct sppPostDevData element |
| SoapObject request = new SoapObject(NAMESPACE_NS, WIFI_SOAP_POST_DEV_DATA); |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_SPP_VERSION); |
| attributeInfo.setValue("1.0"); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(attributeInfo); |
| //requestReason |
| request.addAttribute(WIFI_SOAP_REQ_REASON, requestReason); |
| |
| //redirectURL |
| request.addAttribute(WIFI_SOAP_REDIRECTURL, mRedirectUrl); |
| |
| //sessionID (adding all packages except for the first one) |
| if (!SUB_REGISTER.equals(requestReason)) { |
| AttributeInfo sessionIDattributeInfo = new AttributeInfo(); |
| sessionIDattributeInfo.setName(WIFI_SOAP_SESSIONID); |
| sessionIDattributeInfo.setValue(mSessionID); |
| sessionIDattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| sessionIDattributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(sessionIDattributeInfo); |
| } |
| |
| //New supportedSPPVersions element |
| request.addProperty(WIFI_SOAP_S_SPP_VERSION, "1.0"); |
| //New supportedMOList |
| request.addProperty(WIFI_SOAP_S_MOLIST, WIFI_SOAP_S_MOSUBSCRIPTION |
| + " " + WIFI_SOAP_S_MODEVINFO |
| + " " + WIFI_SOAP_S_MODEVDETAIL |
| + " " + WIFI_SOAP_S_MOHS20); |
| |
| //New moContainer |
| //Construct moContainer |
| SoapObject moInfo = createDevInfo(); |
| SoapObject moDetail = createDevDetail(); |
| request.addSoapObject(moInfo); |
| request.addSoapObject(moDetail); |
| |
| return request; |
| } |
| |
| private SoapObject createRemediationRequest(String serverUrl, String requestReason) { |
| // Construct sppPostDevData element |
| SoapObject request = new SoapObject(NAMESPACE_NS, WIFI_SOAP_POST_DEV_DATA); |
| //sppVersion |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_SPP_VERSION); |
| attributeInfo.setValue("1.0"); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(attributeInfo); |
| //requestReason |
| request.addAttribute(WIFI_SOAP_REQ_REASON, requestReason); |
| //redirectURL |
| request.addAttribute(WIFI_SOAP_REDIRECTURL, mRedirectUrl); |
| |
| //sessionID |
| if (!SUB_PROVISION.equals(requestReason) && !SUB_REMEDIATION.equals(requestReason)) { |
| AttributeInfo sessionIDattributeInfo = new AttributeInfo(); |
| sessionIDattributeInfo.setName(WIFI_SOAP_SESSIONID); |
| sessionIDattributeInfo.setValue(mSessionID); |
| sessionIDattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| sessionIDattributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(sessionIDattributeInfo); |
| } |
| |
| //New supportedSPPVersions element |
| request.addProperty(WIFI_SOAP_S_SPP_VERSION, "1.0"); |
| //New supportedMOList |
| request.addProperty(WIFI_SOAP_S_MOLIST, WIFI_SOAP_S_MOSUBSCRIPTION |
| + " " + WIFI_SOAP_S_MODEVINFO |
| + " " + WIFI_SOAP_S_MODEVDETAIL |
| + " " + WIFI_SOAP_S_MOHS20); |
| |
| //New moContainer |
| //Construct moContainer |
| SoapObject moInfo = createDevInfo(); |
| SoapObject moDetail = createDevDetail(); |
| request.addSoapObject(moInfo); |
| request.addSoapObject(moDetail); |
| |
| //New moContainer |
| //Construct moContainer |
| if (SUB_MO_UPLOAD.equals(requestReason)) { |
| SoapObject moSub = createSubscription(serverUrl); |
| request.addSoapObject(moSub); |
| } |
| |
| return request; |
| } |
| |
| private SoapObject createSubscription(String serverUrl) { |
| WifiPasspointDmTree.CredentialInfo credInfo = mTreeHelper.getCredentialInfo(mSoapTree, |
| mCred.getWifiSpFqdn(), mCred.getCredName()); |
| SoapObject nsRequest = new SoapObject(NAMESPACE_NS, WIFI_SOAP_MO_CONTAINER); |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_MO_URN); |
| attributeInfo.setValue(WIFI_SOAP_S_MOSUBSCRIPTION); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| nsRequest.addAttribute(attributeInfo); |
| |
| SoapObject MgmtTreeRequest = new SoapObject(null, WIFI_SOAP_MGMTREE); |
| //xmlns |
| AttributeInfo ppsMoattributeInfo = new AttributeInfo(); |
| ppsMoattributeInfo.setName(WIFI_SOAP_MO_XMLNS); |
| ppsMoattributeInfo.setValue(WIFI_SOAP_SYNCML_DMDDF_1_2); |
| ppsMoattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| MgmtTreeRequest.addAttribute(ppsMoattributeInfo); |
| MgmtTreeRequest.addProperty("VerDTD", "1.2"); |
| |
| SoapObject PerProviderSubscriptionRequest = new SoapObject(null, "Node"); |
| PerProviderSubscriptionRequest.addProperty("NodeName", "PerProviderSubscription"); |
| |
| SoapObject rtPropertiesRequest = new SoapObject(null, "RTProperties"); |
| SoapObject typeRequest = new SoapObject(null, "Type"); |
| typeRequest.addProperty("DDFName", WIFI_SOAP_S_MOSUBSCRIPTION); |
| rtPropertiesRequest.addSoapObject(typeRequest); |
| PerProviderSubscriptionRequest.addSoapObject(rtPropertiesRequest); |
| |
| SoapObject x1Request = new SoapObject(null, "Node"); |
| x1Request.addProperty("NodeName", "x1"); |
| |
| SoapObject SubscriptionPriorityRequest = new SoapObject(null, "Node"); |
| SubscriptionPriorityRequest.addProperty("NodeName", "SubscriptionPriority"); |
| SubscriptionPriorityRequest.addProperty("Value", credInfo.credentialPriority); |
| x1Request.addSoapObject(SubscriptionPriorityRequest); |
| |
| SoapObject SubscriptionRemediationRequest = new SoapObject(null, "Node"); |
| SubscriptionRemediationRequest.addProperty("NodeName", "SubscriptionRemediation"); |
| |
| SoapObject RemURIRequest = new SoapObject(null, "Node"); |
| RemURIRequest.addProperty("NodeName", "URI"); |
| RemURIRequest.addProperty("Value", serverUrl); |
| SubscriptionRemediationRequest.addSoapObject(RemURIRequest); |
| |
| SoapObject certURLRequest = new SoapObject(null, "Node"); |
| certURLRequest.addProperty("NodeName", "certURL"); |
| certURLRequest.addProperty("Value", credInfo.subscriptionUpdate.trustRoot.CertURL); |
| SubscriptionRemediationRequest.addSoapObject(certURLRequest); |
| |
| SoapObject certSHA256FingerprintRequest = new SoapObject(null, "Node"); |
| certSHA256FingerprintRequest.addProperty("NodeName", "certSHA256Fingerprint"); |
| certSHA256FingerprintRequest.addProperty("Value", |
| credInfo.subscriptionUpdate.trustRoot.CertSHA256Fingerprint); |
| SubscriptionRemediationRequest.addSoapObject(certSHA256FingerprintRequest); |
| |
| x1Request.addSoapObject(SubscriptionRemediationRequest); |
| |
| SoapObject SubscriptionUpdateRequest = new SoapObject(null, "Node"); |
| SubscriptionUpdateRequest.addProperty("NodeName", "SubscriptionUpdate"); |
| |
| SoapObject UpdateIntervalRequest = new SoapObject(null, "Node"); |
| UpdateIntervalRequest.addProperty("NodeName", "UpdateInterval"); |
| UpdateIntervalRequest.addProperty("Value", credInfo.subscriptionUpdate.UpdateInterval); |
| SubscriptionUpdateRequest.addSoapObject(UpdateIntervalRequest); |
| |
| SoapObject UpdateMethodRequest = new SoapObject(null, "Node"); |
| UpdateMethodRequest.addProperty("NodeName", "UpdateMethod"); |
| UpdateMethodRequest.addProperty("Value", credInfo.subscriptionUpdate.UpdateMethod); |
| SubscriptionUpdateRequest.addSoapObject(UpdateMethodRequest); |
| |
| SoapObject RestrictionRequest = new SoapObject(null, "Node"); |
| RestrictionRequest.addProperty("NodeName", "Restriction"); |
| RestrictionRequest.addProperty("Value", credInfo.subscriptionUpdate.Restriction); |
| SubscriptionUpdateRequest.addSoapObject(RestrictionRequest); |
| |
| SoapObject UpdURIRequest = new SoapObject(null, "Node"); |
| UpdURIRequest.addProperty("NodeName", "URI"); |
| UpdURIRequest.addProperty("Value", credInfo.subscriptionUpdate.URI); |
| SubscriptionUpdateRequest.addSoapObject(UpdURIRequest); |
| |
| x1Request.addSoapObject(SubscriptionUpdateRequest); |
| |
| SoapObject HomeSPRequest = new SoapObject(null, "Node"); |
| HomeSPRequest.addProperty("NodeName", "HomeSP"); |
| |
| SoapObject FriendlyNameRequest = new SoapObject(null, "Node"); |
| FriendlyNameRequest.addProperty("NodeName", "FriendlyName"); |
| FriendlyNameRequest.addProperty("Value", credInfo.homeSP.FriendlyName); |
| HomeSPRequest.addSoapObject(FriendlyNameRequest); |
| |
| SoapObject FQDNNameRequest = new SoapObject(null, "Node"); |
| FQDNNameRequest.addProperty("NodeName", "FQDN"); |
| FQDNNameRequest.addProperty("Value", credInfo.homeSP.FQDN); |
| HomeSPRequest.addSoapObject(FQDNNameRequest); |
| |
| SoapObject HomeOIListRequest = new SoapObject(null, "Node"); |
| HomeOIListRequest.addProperty("NodeName", "HomeOIList"); |
| |
| Collection<WifiPasspointDmTree.HomeOIList> oil = mTreeHelper.getHomeOIList(credInfo); |
| for (WifiPasspointDmTree.HomeOIList oi : oil) { |
| SoapObject HomeOIListx1Request = new SoapObject(null, "Node"); |
| HomeOIListx1Request.addProperty("NodeName", oi.nodeName); |
| |
| SoapObject HomeOIx1Request = new SoapObject(null, "Node"); |
| HomeOIx1Request.addProperty("NodeName", "HomeOI"); |
| HomeOIx1Request.addProperty("Value", oi.HomeOI); |
| HomeOIx1Request.addProperty("NodeName", "HomeOIRequired"); |
| HomeOIx1Request.addProperty("Value", Boolean.toString(oi.HomeOIRequired)); |
| HomeOIListx1Request.addSoapObject(HomeOIx1Request); |
| |
| HomeOIListRequest.addSoapObject(HomeOIListx1Request.newInstance()); |
| } |
| |
| HomeSPRequest.addSoapObject(HomeOIListRequest); |
| |
| x1Request.addSoapObject(HomeSPRequest); |
| |
| SoapObject SubscriptionParametersRequest = new SoapObject(null, "Node"); |
| SubscriptionParametersRequest.addProperty("NodeName", "SubscriptionParameters"); |
| x1Request.addSoapObject(SubscriptionParametersRequest); |
| |
| SoapObject CredentialRequest = new SoapObject(null, "Node"); |
| CredentialRequest.addProperty("NodeName", "Credential"); |
| |
| SoapObject CreationDateRequest = new SoapObject(null, "Node"); |
| CreationDateRequest.addProperty("NodeName", "CreationDate"); |
| CreationDateRequest.addProperty("Value", credInfo.credential.CreationDate); |
| CredentialRequest.addSoapObject(CreationDateRequest); |
| |
| SoapObject UsernamePasswordRequest = new SoapObject(null, "Node"); |
| UsernamePasswordRequest.addProperty("NodeName", "UsernamePassword"); |
| |
| SoapObject UsernameRequest = new SoapObject(null, "Node"); |
| UsernameRequest.addProperty("NodeName", "Username"); |
| UsernameRequest.addProperty("Value", credInfo.credential.usernamePassword.Username); |
| UsernamePasswordRequest.addSoapObject(UsernameRequest); |
| |
| SoapObject PasswordRequest = new SoapObject(null, "Node"); |
| PasswordRequest.addProperty("NodeName", "Password"); |
| PasswordRequest.addProperty("Value", credInfo.credential.usernamePassword.Password); |
| UsernamePasswordRequest.addSoapObject(PasswordRequest); |
| |
| SoapObject MachineManagedRequest = new SoapObject(null, "Node"); |
| MachineManagedRequest.addProperty("NodeName", "MachineManaged"); |
| if (credInfo.credential.usernamePassword.MachineManaged) { |
| MachineManagedRequest.addProperty("Value", "TRUE"); |
| } else { |
| MachineManagedRequest.addProperty("Value", "FALSE"); |
| } |
| UsernamePasswordRequest.addSoapObject(MachineManagedRequest); |
| |
| SoapObject EAPMethodRequest = new SoapObject(null, "Node"); |
| EAPMethodRequest.addProperty("NodeName", "EAPMethod"); |
| |
| SoapObject EAPTypeRequest = new SoapObject(null, "Node"); |
| EAPTypeRequest.addProperty("NodeName", "EAPType"); |
| EAPTypeRequest.addProperty("Value", credInfo.credential.usernamePassword.eAPMethod.EAPType); |
| EAPMethodRequest.addSoapObject(EAPTypeRequest); |
| |
| SoapObject InnerMethodRequest = new SoapObject(null, "Node"); |
| InnerMethodRequest.addProperty("NodeName", "InnerMethod"); |
| InnerMethodRequest.addProperty("Value", |
| credInfo.credential.usernamePassword.eAPMethod.InnerMethod); |
| EAPMethodRequest.addSoapObject(InnerMethodRequest); |
| UsernamePasswordRequest.addSoapObject(EAPMethodRequest); |
| |
| CredentialRequest.addSoapObject(UsernamePasswordRequest); |
| |
| SoapObject RealmRequest = new SoapObject(null, "Node"); |
| RealmRequest.addProperty("NodeName", "Realm"); |
| RealmRequest.addProperty("Value", credInfo.credential.Realm); |
| CredentialRequest.addSoapObject(RealmRequest); |
| |
| x1Request.addSoapObject(CredentialRequest); |
| |
| PerProviderSubscriptionRequest.addSoapObject(x1Request); |
| |
| MgmtTreeRequest.addSoapObject(PerProviderSubscriptionRequest); |
| |
| nsRequest.addSoapObject(MgmtTreeRequest); |
| |
| return nsRequest; |
| } |
| |
| private SoapObject createPolicyUpdateRequest(String serverUrl, String requestReason) { |
| // Construct sppPostDevData element |
| SoapObject request = new SoapObject(NAMESPACE_NS, WIFI_SOAP_POST_DEV_DATA); |
| //sppVersion |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_SPP_VERSION); |
| attributeInfo.setValue("1.0"); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(attributeInfo); |
| //requestReason |
| request.addAttribute(WIFI_SOAP_REQ_REASON, requestReason); |
| //sessionID |
| if (!POL_UPDATE.equals(requestReason)) { |
| AttributeInfo sessionIDattributeInfo = new AttributeInfo(); |
| sessionIDattributeInfo.setName(WIFI_SOAP_SESSIONID); |
| sessionIDattributeInfo.setValue(mSessionID); |
| sessionIDattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| sessionIDattributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(sessionIDattributeInfo); |
| } |
| |
| //New supportedSPPVersions element |
| request.addProperty(WIFI_SOAP_S_SPP_VERSION, "1.0"); |
| //New supportedMOList |
| request.addProperty(WIFI_SOAP_S_MOLIST, WIFI_SOAP_S_MOSUBSCRIPTION |
| + " " + WIFI_SOAP_S_MODEVINFO |
| + " " + WIFI_SOAP_S_MODEVDETAIL |
| + " " + WIFI_SOAP_S_MOHS20); |
| |
| //New moContainer |
| //Construct moContainer |
| SoapObject moInfo = createDevInfo(); |
| SoapObject moDetail = createDevDetail(); |
| request.addSoapObject(moInfo); |
| request.addSoapObject(moDetail); |
| |
| //New moContainer |
| //Construct moContainer |
| if (POL_MO_UPLOAD.equals(requestReason)) { |
| SoapObject subscription = createSubscription(serverUrl); |
| request.addSoapObject(subscription); |
| } |
| return request; |
| } |
| |
| private SoapObject createUpdateResponseRequest(boolean errorOccur, String reason) { |
| // Construct sppUpdateResponse element |
| SoapObject request = new SoapObject(NAMESPACE_NS, WIFI_SOAP_UPDATE_RESPONSE); |
| //sppVersion |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_SPP_VERSION); |
| attributeInfo.setValue("1.0"); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(attributeInfo); |
| //sppStatus |
| AttributeInfo attributeSppStatus = new AttributeInfo(); |
| attributeSppStatus.setName(WIFI_SOAP_SPP_STATUS); |
| if (errorOccur == true) { |
| attributeSppStatus.setValue(WIFI_SOAP_SPP_STATUS_ERROR_OCCURRED); |
| } |
| else { |
| attributeSppStatus.setValue(WIFI_SOAP_SPP_STATUS_OK); |
| } |
| attributeSppStatus.setType("PropertyInfo.STRING_CLASS"); |
| attributeSppStatus.setNamespace(NAMESPACE_NS); |
| request.addAttribute(attributeSppStatus); |
| //sessionID |
| AttributeInfo sessionIDattributeInfo = new AttributeInfo(); |
| sessionIDattributeInfo.setName(WIFI_SOAP_SESSIONID); |
| sessionIDattributeInfo.setValue(mSessionID); |
| sessionIDattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| sessionIDattributeInfo.setNamespace(NAMESPACE_NS); |
| request.addAttribute(sessionIDattributeInfo); |
| |
| if (errorOccur == true) { |
| //sppError |
| SoapObject sppError = new SoapObject(NAMESPACE_NS, WIFI_SOAP_SPP_ERROR); |
| //errorCode |
| AttributeInfo attributeInfoErrorCode = new AttributeInfo(); |
| attributeInfoErrorCode.setName(WIFI_SOAP_ERROR_CODE); |
| attributeInfoErrorCode.setValue(reason); |
| attributeInfoErrorCode.setType("PropertyInfo.STRING_CLASS"); |
| sppError.addAttribute(attributeInfoErrorCode); |
| |
| request.addSoapObject(sppError); |
| } |
| |
| return request; |
| } |
| |
| private SoapObject createDevInfo() { |
| //New moContainer |
| //Construct moContainer |
| SoapObject dmMoRequest = new SoapObject(NAMESPACE_NS, WIFI_SOAP_MO_CONTAINER); |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_MO_URN); |
| attributeInfo.setValue(WIFI_SOAP_S_MODEVINFO); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| dmMoRequest.addAttribute(attributeInfo); |
| |
| //DevInfo |
| /* |
| sample: |
| <![CDATA[ <MgmtTree> |
| <VerDTD>1.2</VerDTD> |
| <Node> |
| <NodeName>DevInfo</NodeName> |
| <RTProperties> |
| <Type> |
| <DDFName>urn:oma:mo:oma-dm-devinfo:1.0</DDFName> |
| </Type> |
| </RTProperties> |
| <Node> |
| <NodeName>DevID</NodeName> |
| <Value>urn:acme:00-11-22-33-44-55</Value> |
| </Node> |
| <Node> |
| <NodeName>Man</NodeName> |
| <Value>ACME</Value> |
| </Node> |
| <Node> |
| <NodeName>Mod</NodeName> |
| <Value>HS2.0-01</Value> |
| </Node> |
| <Node> |
| <NodeName>DmV</NodeName> |
| <Value>1.2</Value> |
| </Node> |
| <Node> |
| <NodeName>Lang</NodeName> |
| <Value>en-US</Value> |
| </Node> |
| </Node> |
| </MgmtTree> ]]> |
| */ |
| |
| SoapObject devInfoRequest = new SoapObject(null, WIFI_SOAP_MGMTREE); |
| //xmlns |
| AttributeInfo MoDetailattributeInfo = new AttributeInfo(); |
| MoDetailattributeInfo.setName(WIFI_SOAP_MO_XMLNS); |
| MoDetailattributeInfo.setValue(WIFI_SOAP_SYNCML_DMDDF_1_2); |
| MoDetailattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| devInfoRequest.addAttribute(MoDetailattributeInfo); |
| |
| devInfoRequest.addProperty("VerDTD", "1.2"); |
| |
| SoapObject node1Request = new SoapObject(null, "Node"); |
| node1Request.addProperty("NodeName", "DevInfo"); |
| |
| SoapObject rtPropertiesRequest = new SoapObject(null, "RTProperties"); |
| SoapObject typeRequest = new SoapObject(null, "Type"); |
| typeRequest.addProperty("DDFName", WIFI_SOAP_S_MODEVINFO); |
| rtPropertiesRequest.addSoapObject(typeRequest); |
| node1Request.addSoapObject(rtPropertiesRequest); |
| |
| SoapObject node1aRequest = new SoapObject(null, "Node"); |
| node1aRequest.addProperty("NodeName", "DevId"); |
| node1aRequest.addProperty("Value", "imei:" + getDeviceId()); |
| node1Request.addSoapObject(node1aRequest); |
| |
| SoapObject node1bRequest = new SoapObject(null, "Node"); |
| node1bRequest.addProperty("NodeName", "Man"); |
| node1bRequest.addProperty("Value", "Google"); |
| node1Request.addSoapObject(node1bRequest); |
| |
| SoapObject node1cRequest = new SoapObject(null, "Node"); |
| node1cRequest.addProperty("NodeName", "Mod"); |
| node1cRequest.addProperty("Value", "HS20-station"); |
| node1Request.addSoapObject(node1cRequest); |
| |
| SoapObject node1dRequest = new SoapObject(null, "Node"); |
| node1dRequest.addProperty("NodeName", "DmV"); |
| node1dRequest.addProperty("Value", "1.2"); |
| node1Request.addSoapObject(node1dRequest); |
| |
| SoapObject node1eRequest = new SoapObject(null, "Node"); |
| node1eRequest.addProperty("NodeName", "Lang"); |
| //node1eRequest.addProperty("Value", "en-US"); |
| node1eRequest.addProperty("Value", get2LettersSystemLanguageCode()); |
| node1Request.addSoapObject(node1eRequest); |
| |
| devInfoRequest.addSoapObject(node1Request); |
| |
| //Add to DM tree |
| dmMoRequest.addSoapObject(devInfoRequest); |
| |
| return dmMoRequest; |
| } |
| |
| private SoapObject createDevDetail() { |
| //New moContainer |
| //Construct moContainer |
| Log.d(TAG, "[createDevDetail]"); |
| SoapObject dmMoRequest = new SoapObject(NAMESPACE_NS, WIFI_SOAP_MO_CONTAINER); |
| AttributeInfo attributeInfo = new AttributeInfo(); |
| attributeInfo.setName(WIFI_SOAP_MO_URN); |
| attributeInfo.setValue(WIFI_SOAP_S_MODEVDETAIL); |
| attributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| attributeInfo.setNamespace(NAMESPACE_NS); |
| dmMoRequest.addAttribute(attributeInfo); |
| |
| //DevDetail |
| /* |
| sample: |
| <![CDATA[ <MgmtTree> |
| <VerDTD>1.2</VerDTD> |
| <Node> |
| <NodeName>DevDetail</NodeName> |
| <RTProperties> |
| <Type> |
| <DDFName>urn:oma:mo:oma-dm-devdetail:1.0</DDFName> |
| </Type> |
| </RTProperties> |
| </Node> |
| <Node> |
| <NodeName>URI</NodeName> |
| <Node> |
| <NodeName>MaxDepth</NodeName> |
| <Value> 32 </Value> |
| </Node> |
| <Node> |
| <NodeName>MaxTotLen</NodeName> |
| <Value> 2048 </Value> |
| </Node> |
| <Node> |
| <NodeName>MaxSegLen</NodeName> |
| <Value> 64 </Value> |
| </Node> |
| </Node> |
| <Node> |
| <NodeName>DevType</NodeName> |
| <Value> Smartphone </Value> |
| </Node> |
| <Node> |
| <NodeName>OEM</NodeName> |
| <Value> ACME </Value> |
| </Node> |
| <Node> |
| <NodeName>FmV</NodeName> |
| <Value> 1.2.100.5 </Value> |
| </Node> |
| <Node> |
| <NodeName>SmV</NodeName> |
| <Value> 9.11.130 </Value> |
| </Node> |
| <Node> |
| <NodeName>HmV</NodeName> |
| <Value> 1.0 </Value> |
| </Node> |
| <Node> |
| <NodeName>LrgObj</NodeName> |
| <Value>FALSE</Value> |
| </Node> |
| </MgmtTree> ]]> |
| */ |
| SoapObject MgmtTreeRequest = new SoapObject(null, WIFI_SOAP_MGMTREE); |
| //xmlns |
| AttributeInfo MoDetailattributeInfo = new AttributeInfo(); |
| MoDetailattributeInfo.setName(WIFI_SOAP_MO_XMLNS); |
| MoDetailattributeInfo.setValue(WIFI_SOAP_SYNCML_DMDDF_1_2); |
| MoDetailattributeInfo.setType("PropertyInfo.STRING_CLASS"); |
| MgmtTreeRequest.addAttribute(MoDetailattributeInfo); |
| |
| //VerDTD |
| MgmtTreeRequest.addProperty("VerDTD", "1.2"); |
| |
| //DevDetail |
| SoapObject DevDetailRequest = new SoapObject(null, "Node"); |
| DevDetailRequest.addProperty("NodeName", "DevDetail"); |
| |
| SoapObject rtPerpertiesRequest = new SoapObject(null, "RTProperties"); |
| SoapObject typePerpertiesRequest = new SoapObject(null, "Type"); |
| typePerpertiesRequest.addProperty("DDFName", WIFI_SOAP_S_MODEVDETAIL); |
| rtPerpertiesRequest.addSoapObject(typePerpertiesRequest); |
| DevDetailRequest.addSoapObject(rtPerpertiesRequest); |
| |
| //Ext |
| SoapObject extRequest = new SoapObject(null, "Node"); |
| extRequest.addProperty("NodeName", "Ext"); |
| |
| SoapObject wifiOrgRequest = new SoapObject(null, "Node"); |
| wifiOrgRequest.addProperty("NodeName", "org.wi-fi"); |
| |
| SoapObject wifiRequest = new SoapObject(null, "Node"); |
| wifiRequest.addProperty("NodeName", "Wi-Fi"); |
| //EAPMethodList |
| SoapObject eapMethodListRequest = new SoapObject(null, "Node"); |
| eapMethodListRequest.addProperty("NodeName", "EAPMethodList"); |
| |
| SoapObject eapMethod1Request = new SoapObject(null, "Node"); |
| eapMethod1Request.addProperty("NodeName", "EAPMethod1"); |
| |
| SoapObject eapMethod1 = new SoapObject(null, "Node"); |
| eapMethod1.addProperty("NodeName", "EAPMethod");//TLS |
| eapMethod1.addProperty("Value", "13"); |
| eapMethod1Request.addSoapObject(eapMethod1); |
| eapMethodListRequest.addSoapObject(eapMethod1Request); |
| |
| SoapObject eapMethod2Request = new SoapObject(null, "Node"); |
| eapMethod2Request.addProperty("NodeName", "EAPMethod2"); |
| |
| SoapObject eapMethod2 = new SoapObject(null, "Node"); |
| eapMethod2.addProperty("NodeName", "EAPMethod");//TTLS |
| eapMethod2.addProperty("Value", "21"); |
| eapMethod2.addProperty("NodeName", "InnerEAPMethod");//MSCHAPv2 |
| eapMethod2.addProperty("Value", "27"); |
| eapMethod2Request.addSoapObject(eapMethod2); |
| eapMethodListRequest.addSoapObject(eapMethod2Request); |
| |
| SoapObject eapMethod3Request = new SoapObject(null, "Node"); |
| eapMethod3Request.addProperty("NodeName", "EAPMethod3"); |
| |
| SoapObject eapMethod3 = new SoapObject(null, "Node"); |
| eapMethod3.addProperty("NodeName", "EAPMethod");//SIM |
| eapMethod3.addProperty("Value", "18"); |
| eapMethod3Request.addSoapObject(eapMethod3); |
| eapMethodListRequest.addSoapObject(eapMethod3Request); |
| |
| SoapObject eapMethod4Request = new SoapObject(null, "Node"); |
| eapMethod4Request.addProperty("NodeName", "EAPMethod4"); |
| |
| SoapObject eapMethod4 = new SoapObject(null, "Node"); |
| eapMethod4.addProperty("NodeName", "EAPMethod");//AKA |
| eapMethod4.addProperty("Value", "23"); |
| eapMethod4Request.addSoapObject(eapMethod4); |
| eapMethodListRequest.addSoapObject(eapMethod4Request); |
| |
| wifiRequest.addSoapObject(eapMethodListRequest); |
| |
| //IMSI |
| if ("false".equals(SystemProperties.get("persist.service.manual.ut.rem"))) { |
| WifiPasspointDmTree.CredentialInfo credInfo = mTreeHelper.getCredentialInfo(mSoapTree, |
| mCred.getWifiSpFqdn(), mCred.getCredName()); |
| if (credInfo != null && |
| credInfo.credential != null && |
| credInfo.credential.sim != null) { |
| String imsi = credInfo.credential.sim.IMSI; |
| SoapObject imsiRequest = new SoapObject(null, "Node"); |
| imsiRequest.addProperty("NodeName", "IMSI"); |
| imsiRequest.addProperty("Value", imsi); |
| wifiRequest.addSoapObject(imsiRequest); |
| } |
| } else { |
| SoapObject imsiRequest = new SoapObject(null, "Node"); |
| imsiRequest.addProperty("NodeName", "IMSI"); |
| imsiRequest.addProperty("Value", "40002600000004"); |
| wifiRequest.addSoapObject(imsiRequest); |
| } |
| |
| //ManufacturingCertificate |
| SoapObject manufactCertRequest = new SoapObject(null, "Node"); |
| manufactCertRequest.addProperty("NodeName", "ManufacturingCertificate"); |
| manufactCertRequest.addProperty("Value", "false"); |
| wifiRequest.addSoapObject(manufactCertRequest); |
| |
| // Wi-FiMACAddress |
| SoapObject wifiMacAddressRequest = new SoapObject(null, "Node"); |
| wifiMacAddressRequest.addProperty("NodeName", "Wi-FiMACAddress"); |
| WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); |
| WifiInfo wifiInfo = wifiManager.getConnectionInfo(); |
| if (wifiInfo == null) { |
| Log.d(TAG, "no ConnectionInfo found"); |
| return null; |
| } |
| wifiMacAddressRequest.addProperty("Value", wifiInfo.getMacAddress().replace(":", "") |
| .toLowerCase()); |
| wifiRequest.addSoapObject(wifiMacAddressRequest); |
| //ClientTriggerRedirectURI |
| //wifiRequest.addProperty("ClientTriggerRedirectURI", "http://127.0.0.1:54685"); |
| wifiOrgRequest.addSoapObject(wifiRequest); |
| extRequest.addSoapObject(wifiOrgRequest); |
| DevDetailRequest.addSoapObject(extRequest); |
| |
| //URI |
| SoapObject URIRequest = new SoapObject(null, "Node"); |
| URIRequest.addProperty("NodeName", "URI"); |
| |
| SoapObject MaxDepthRequest = new SoapObject(null, "Node"); |
| MaxDepthRequest.addProperty("NodeName", "MaxDepth"); |
| MaxDepthRequest.addProperty("Value", "32"); |
| URIRequest.addSoapObject(MaxDepthRequest); |
| |
| SoapObject MaxTotLenRequest = new SoapObject(null, "Node"); |
| MaxTotLenRequest.addProperty("NodeName", "MaxTotLen"); |
| MaxTotLenRequest.addProperty("Value", "2048"); |
| URIRequest.addSoapObject(MaxTotLenRequest); |
| |
| SoapObject MaxSegLenRequest = new SoapObject(null, "Node"); |
| MaxSegLenRequest.addProperty("NodeName", "MaxSegLen"); |
| MaxSegLenRequest.addProperty("Value", "64"); |
| URIRequest.addSoapObject(MaxSegLenRequest); |
| |
| DevDetailRequest.addSoapObject(URIRequest); |
| |
| //Required property |
| SoapObject DevTypeRequest = new SoapObject(null, "Node"); |
| DevTypeRequest.addProperty("NodeName", "DevType"); |
| DevTypeRequest.addProperty("Value", "MobilePhone"); |
| DevDetailRequest.addSoapObject(DevTypeRequest); |
| |
| SoapObject OEMRequest = new SoapObject(null, "Node"); |
| OEMRequest.addProperty("NodeName", "OEM"); |
| OEMRequest.addProperty("Value", "GOOGLE"); |
| DevDetailRequest.addSoapObject(OEMRequest); |
| |
| SoapObject FwVRequest = new SoapObject(null, "Node"); |
| FwVRequest.addProperty("NodeName", "FwV"); |
| FwVRequest.addProperty("Value", "1.0"); |
| DevDetailRequest.addSoapObject(FwVRequest); |
| |
| SoapObject SwVRequest = new SoapObject(null, "Node"); |
| SwVRequest.addProperty("NodeName", "SwV"); |
| SwVRequest.addProperty("Value", "1.0"); |
| DevDetailRequest.addSoapObject(SwVRequest); |
| |
| SoapObject HwVRequest = new SoapObject(null, "Node"); |
| HwVRequest.addProperty("NodeName", "HwV"); |
| HwVRequest.addProperty("Value", "1.0"); |
| DevDetailRequest.addSoapObject(HwVRequest); |
| |
| SoapObject LrgObjRequest = new SoapObject(null, "Node"); |
| LrgObjRequest.addProperty("NodeName", "LrgObj"); |
| LrgObjRequest.addProperty("Value", "FALSE"); |
| DevDetailRequest.addSoapObject(LrgObjRequest); |
| MgmtTreeRequest.addSoapObject(DevDetailRequest); |
| |
| //Add to DM tree |
| dmMoRequest.addSoapObject(MgmtTreeRequest); |
| |
| return dmMoRequest; |
| } |
| |
| private String checkErrorCode(Document doc) { |
| return null; |
| } |
| |
| private String checkStatus(Document doc) { |
| if (doc == null) { |
| return null; |
| } |
| |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, "sppPostDevDataResponse"); |
| if (list.getLength() != 0) { |
| Element element = (Element) list.item(0); |
| String sppStatus = element.getAttributeNS(NAMESPACE_NS, WIFI_SOAP_SPP_STATUS); |
| Log.d(TAG, "sppStatus: " + sppStatus); |
| if (WIFI_SOAP_SPP_STATUS_OK.equals(sppStatus) |
| || WIFI_SOAP_SPP_STATUS_PROVISION_COMPLETE.equals(sppStatus) |
| || WIFI_SOAP_SPP_STATUS_REMEDIATION_COMPLETE.equals(sppStatus) |
| || WIFI_SOAP_SPP_STATUS_UPDATE_COMPLETE.equals(sppStatus)) { |
| mSessionID = element.getAttributeNS(NAMESPACE_NS, "sessionID"); |
| Log.d(TAG, "sessionID: " + mSessionID); |
| } |
| return sppStatus; |
| } |
| |
| return null; |
| } |
| |
| private String checkStatus(Document doc, String tagName) { |
| if (doc == null) { |
| return null; |
| } |
| |
| NodeList list = doc.getElementsByTagName(tagName); |
| |
| if (list.getLength() == 0) { |
| return null; |
| } |
| |
| Element element = (Element) list.item(0); |
| String att = element.getAttribute("spp:sppStatus"); |
| Log.d(TAG, "att:" + att); |
| return att; |
| } |
| |
| private String checkStatus(Document doc, String namespace, String tagName) { |
| if (doc == null) { |
| return null; |
| } |
| |
| NodeList list = doc.getElementsByTagNameNS(namespace, tagName); |
| |
| if (list.getLength() == 0) { |
| return null; |
| } |
| |
| Element element = (Element) list.item(0); |
| String att = element.getAttributeNS(namespace, WIFI_SOAP_SPP_STATUS); |
| Log.d(TAG, "att:" + att); |
| return att; |
| } |
| |
| private String getErrorCode(Document doc) { |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, WIFI_SOAP_SPP_ERROR); |
| if (list.getLength() != 0) { |
| Element element = (Element) list.item(0); |
| String errorCode = element.getAttribute(WIFI_SOAP_SPP_ERROR); |
| Log.d(TAG, "errorCode: " + errorCode); |
| return errorCode; |
| } |
| return null; |
| } |
| |
| private boolean isNoMoUpdate(Document doc) { |
| Log.d(TAG, "[isNoMoUpdate]"); |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, WIFI_SOAP_SPP_NOMOUPDATE); |
| if (list.getLength() != 0) { |
| mTarget.sendMessage( |
| WifiPasspointStateMachine.CMD_REMEDIATION_DONE, 0, 0, mSoapTree);// "DoUpdate" |
| return true; |
| } |
| return false; |
| } |
| |
| private boolean isUploadMO(Document doc) { |
| Log.d(TAG, "[isUploadMO]"); |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, "uploadMO"); |
| if (list.getLength() != 0) { |
| Element element = (Element) list.item(0); |
| String uploadMO = element.getAttributeNS(NAMESPACE_NS, WIFI_SOAP_MO_URN); |
| Log.d(TAG, "Upload MO: " + uploadMO); |
| if (uploadMO != null || !uploadMO.isEmpty()) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| private boolean isEnrollmentExecution(Document doc) { |
| Log.d(TAG, "[isEnrollmentExecution]"); |
| try { |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, "getCertificate"); |
| if (list.getLength() != 0) { |
| Log.d(TAG, "[isEnrollmentExecution] got getCertificate:"); |
| Element eElement = (Element) list.item(0); |
| String att = eElement.getAttribute("enrollmentProtocol"); |
| if (!"EST".equals(att)) { // EST is allowed only |
| return false; |
| } |
| mEnrollmentServerURI = mPpsmoParser.getTagValue(NAMESPACE_NS, |
| "enrollmentServerURI", eElement); |
| Log.d(TAG, "EnrollmentServerURI: " + mEnrollmentServerURI); |
| mEnrollmentServerCert = mPpsmoParser.getTagValue(NAMESPACE_NS, |
| "caCertificate", eElement); |
| Log.d(TAG, "caCertificate: " + mEnrollmentServerCert); |
| enrollDigestUsername = mPpsmoParser.getTagValue(NAMESPACE_NS, "estUserID", |
| eElement); |
| if (enrollDigestUsername == null) { |
| enrollDigestUsername = null; |
| } |
| Log.d(TAG, "enrollDigestUsername: " + enrollDigestUsername); |
| String enrollDigestPasswordBase64 = mPpsmoParser.getTagValue(NAMESPACE_NS, |
| "estPassword", eElement); |
| if (enrollDigestPasswordBase64 == null) { |
| enrollDigestPassword = null; |
| } else { |
| enrollDigestPassword = new String(Base64.decode(enrollDigestPasswordBase64, Base64.DEFAULT)); |
| } |
| Log.d(TAG, "enrollDigestPassword: " + enrollDigestPassword); |
| } else { |
| return false; |
| } |
| return true; |
| } catch (Exception ee) { |
| ee.printStackTrace(); |
| return false; |
| } |
| } |
| |
| private boolean isUseClientCertTlsExecution(Document doc) { |
| Log.d(TAG, "[isUseClientCertTlsExecution]"); |
| try { |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, "useClientCertTLS"); |
| if (list.getLength() != 0) { |
| Element eElement = (Element) list.item(0); |
| String attAcceptMfgCerts = eElement.getAttributeNS(NAMESPACE_NS, "acceptMfgCerts");// true/false |
| String attAcceptProviderCerts = eElement.getAttributeNS(NAMESPACE_NS, |
| "acceptProviderCerts"); // providerIssuerName |
| |
| if (attAcceptProviderCerts.equalsIgnoreCase("true")) { |
| providerIssuerName = mPpsmoParser.getTagValue(NAMESPACE_NS, |
| "providerIssuerName", eElement); |
| } else { |
| providerIssuerName = null; |
| } |
| } else { |
| return false; |
| } |
| return true; |
| } catch (Exception ee) { |
| ee.printStackTrace(); |
| return false; |
| } |
| } |
| |
| private String getSppTreeUri(Document doc, String execution) { |
| // ex: spp:addMO |
| // spp:managementTreeURI="./Wi-Fi/wi-fi.org/PerProviderSubscription" |
| Log.d(TAG, "[getSppTreeUri]"); |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, execution); |
| if (list.getLength() != 0) { |
| Element element = (Element) list.item(0); |
| String sppTreeUri = element.getAttributeNS(NAMESPACE_NS, "managementTreeURI"); |
| Log.d(TAG, "managementTreeURI: " + sppTreeUri); |
| |
| if (sppTreeUri != null && !sppTreeUri.isEmpty()) { |
| return sppTreeUri; |
| } |
| } |
| |
| return null; |
| } |
| |
| private String getWifiSpFqdnFromMoTree(Document doc, String execution) { |
| // ex: spp:addMO |
| // spp:managementTreeURI="./Wi-Fi/wi-fi.org/PerProviderSubscription" |
| Log.d(TAG, "[getWifiSpFqdnFromMoTree]"); |
| String sppTreeUri = getSppTreeUri(doc, execution); |
| |
| if (sppTreeUri != null && !sppTreeUri.isEmpty()) { |
| String[] words = sppTreeUri.split("/"); |
| Log.d(TAG, "wifiSPFQDN: " + words[2]); |
| return words[2]; |
| } |
| |
| return null; |
| } |
| |
| private boolean isWifiSpFqdnForAddMo(Document doc) { |
| Log.d(TAG, "[isWifiSpFqdnForAddMo]"); |
| mSpFqdnFromMo = getWifiSpFqdnFromMoTree(doc, "addMO"); |
| Log.d(TAG, "current wifiSPFQDN: " + mSpFqdn + ", wifiSPFQDN From MO: " + mSpFqdnFromMo); |
| if (mSpFqdnFromMo != null && mSpFqdn.endsWith(mSpFqdnFromMo)) { |
| Log.d(TAG, "[isWifiSpFqdnForAddMo] pass"); |
| return true; |
| } |
| Log.d(TAG, "[isWifiSpFqdnForAddMo] fail"); |
| return false; |
| } |
| |
| private boolean isWifiSpFqdnForUpdateMo(Document doc) { |
| Log.d(TAG, "[isWifiSpFqdnForUpdateMo]"); |
| mSpFqdnFromMo = getWifiSpFqdnFromMoTree(doc, "updateNode"); |
| Log.d(TAG, "current wifiSPFQDN: " + mSpFqdn + ", wifiSPFQDN From MO: " + mSpFqdnFromMo); |
| if (mSpFqdnFromMo != null && mSpFqdn.endsWith(mSpFqdnFromMo)) { |
| Log.d(TAG, "[isWifiSpFqdnForUpdateMo] pass"); |
| return true; |
| } |
| Log.d(TAG, "[isWifiSpFqdnForUpdateMo] fail"); |
| return false; |
| } |
| |
| private boolean isWifiSpFqdnForUploadMo(Document doc) { |
| Log.d(TAG, "[isWifiSpFqdnForUploadMo]"); |
| mSpFqdnFromMo = getWifiSpFqdnFromMoTree(doc, "uploadMO"); |
| Log.d(TAG, "current wifiSPFQDN: " + mSpFqdn + ", wifiSPFQDN From MO: " + mSpFqdnFromMo); |
| if (mSpFqdnFromMo != null && mSpFqdn.endsWith(mSpFqdnFromMo)) { |
| Log.d(TAG, "[isWifiSpFqdnForUploadMo] pass"); |
| return true; |
| } |
| Log.d(TAG, "[isWifiSpFqdnForUploadMo] fail"); |
| return false; |
| } |
| |
| private boolean isLaunchBrowserExecution(Document doc) { |
| Log.d(TAG, "[isLaunchBrowserExecution]"); |
| NodeList list = doc.getElementsByTagNameNS(NAMESPACE_NS, "exec"); |
| |
| for (int tmp = 0; tmp < list.getLength(); tmp++) { |
| Node nNode = list.item(tmp); |
| if (nNode.getNodeType() == Node.ELEMENT_NODE) { |
| try { |
| Element eElement = (Element) nNode; |
| Log.d(TAG, "launchBrowserToURI : " + |
| mPpsmoParser.getTagValue(NAMESPACE_NS, "launchBrowserToURI", eElement)); |
| String uri = mPpsmoParser.getTagValue(NAMESPACE_NS, |
| "launchBrowserToURI", eElement); |
| if (uri == null) { |
| return false; |
| } |
| ParcelableString launchBrowserUri = new WifiPasspointManager.ParcelableString(); |
| launchBrowserUri.string = uri; |
| mTarget.sendMessage(WifiPasspointStateMachine.CMD_LAUNCH_BROWSER, launchBrowserUri); |
| |
| Log.d(TAG, "value : " + launchBrowserUri); |
| return true; |
| } catch (Exception ee) { |
| ee.printStackTrace(); |
| return false; |
| } |
| } |
| } |
| |
| return false; |
| } |
| |
| private String get2LettersSystemLanguageCode() { |
| Locale loc = Locale.getDefault(); |
| return loc.getLanguage(); |
| } |
| |
| private String filenameFromURI(String uri) { |
| String filename = uri.substring(uri.lastIndexOf("/") + 1); |
| return filename; |
| } |
| |
| private boolean isServerAuthMatched(X509Certificate x509Cert) { |
| boolean result = true; |
| try { |
| List<String> extKeyUsages = x509Cert.getExtendedKeyUsage(); |
| if (extKeyUsages != null) { |
| result = false; |
| for (String extKeyUsage : extKeyUsages) { |
| Log.d(TAG2, "ExtendedKeyUsage:" + extKeyUsage); |
| if (extKeyUsage.equals(KeyPurposeId.id_kp_serverAuth.toString())) { |
| Log.d(TAG, "Server certificate EKU includes id_kp_serverAuth, true"); |
| result = true; |
| break; |
| } |
| } |
| } |
| |
| } catch (CertificateParsingException e) { |
| e.printStackTrace(); |
| } |
| |
| if (!result) |
| Log.d(TAG, "Server certificate EKU not includes id_kp_serverAuth, false"); |
| return result; |
| |
| } |
| |
| private boolean isLanguageAndNamesMatched(X509Certificate x509Cert) { |
| boolean result = false; |
| |
| if (mOSUFriendlyName == null) { |
| return false; |
| } else if (mOSUFriendlyName.isEmpty()) { |
| return false; |
| } |
| |
| try { |
| Collection c = x509Cert.getSubjectAlternativeNames(); |
| |
| if (c != null) { |
| Iterator it = c.iterator(); |
| while (it.hasNext()) { |
| List gn = (List) it.next(); |
| Integer tag = (Integer) gn.get(0); |
| if (tag == GeneralName.otherName) { |
| Log.d(TAG2, "SubjectAltName OtherName:" |
| + gn.get(1).toString()); |
| |
| ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) gn.get(1)); |
| ASN1InputStream asn1_is = new ASN1InputStream(bais); |
| Object asn1Obj = (Object) asn1_is.readObject(); |
| Log.d(TAG2, ASN1Dump.dumpAsString(asn1Obj, true)); |
| |
| DERTaggedObject derTagObj = (DERTaggedObject) asn1Obj; |
| DERSequence derSeq = (DERSequence) derTagObj.getObject(); |
| Enumeration enu = derSeq.getObjects(); |
| DERObjectIdentifier oid = (DERObjectIdentifier) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, " OID:" + oid.toString()); |
| |
| if ("1.3.6.1.4.1.40808.1.1.1".equals(oid.toString())) { // id-wfa-hotspot-friendly-name |
| DERTaggedObject dertagObj = (DERTaggedObject) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| ASN1Object derObj = dertagObj.getObject(); |
| String spLangFriendlyName; |
| if (derObj instanceof DERUTF8String) { |
| DERUTF8String spLangFriendlyNameDERString = (DERUTF8String) (dertagObj |
| .getObject()); |
| spLangFriendlyName = spLangFriendlyNameDERString.toString(); |
| } else { |
| DEROctetString spLangFriendlyNameDERString = (DEROctetString) (dertagObj |
| .getObject()); |
| spLangFriendlyName = spLangFriendlyNameDERString.toString(); |
| } |
| |
| Log.d(TAG, |
| "language code and friendly name:" |
| + spLangFriendlyName.toString()); |
| |
| // check language code |
| Log.d(TAG, "mOSULanguage = " + mOSULanguage); |
| if (spLangFriendlyName.substring(0, 3).equals( |
| mOSULanguage.toLowerCase())) { // ISO639 |
| Log.d(TAG, "Language code match"); |
| |
| // check friendly name |
| Log.d(TAG, "mOSUFriendlyName = " + mOSUFriendlyName); |
| if (mOSUFriendlyName != null && !mOSUFriendlyName.isEmpty() |
| && mOSUFriendlyName.length() != 0) { |
| if (spLangFriendlyName.substring(3).equals(mOSUFriendlyName)) { |
| Log.d(TAG, "OSU friendly name match"); |
| result = true; |
| return result; |
| } else { |
| Log.d(TAG, "OSU friendly name not match"); |
| } |
| } |
| } else { |
| Log.d(TAG, "Language code not match"); |
| } |
| } |
| } |
| } |
| Log.d(TAG2, "Subject Alternative Names:" + c.toString()); |
| } |
| } catch (CertificateParsingException e) { |
| e.printStackTrace(); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| } |
| |
| return result; |
| } |
| |
| private boolean isDnsNameMatched(X509Certificate x509Cert, String fqdn, |
| boolean suffixMatch) { |
| boolean result = false; |
| |
| try { |
| Collection c = x509Cert.getSubjectAlternativeNames(); |
| |
| if (c != null) { |
| Log.d(TAG2, "Subject Alternative Names:" + c.toString()); |
| |
| Iterator it = c.iterator(); |
| while (it.hasNext()) { |
| List gn = (List) it.next(); |
| Integer tag = (Integer) gn.get(0); |
| if (tag == GeneralName.dNSName) { |
| Log.d(TAG2, "Subject Alternative Name:" + gn.get(1)); |
| if (suffixMatch) { |
| String value = (String) (gn.get(1)); |
| if (value.endsWith(fqdn)) { |
| Log.d(TAG, "Subject Alternative DNS Name suffix match SPFQDN"); |
| result = true; |
| } |
| } else {// complete match |
| if (gn.get(1).equals(fqdn)) { |
| Log.d(TAG, "Subject Alternative DNS Name complete match SPFQDN"); |
| result = true; |
| } |
| } |
| |
| } |
| } |
| } |
| } catch (CertificateParsingException e) { |
| e.printStackTrace(); |
| } |
| |
| return result; |
| } |
| |
| private boolean isLogoTypeExtensionMatched(X509Certificate x509Cert) { |
| if (iconHash == null) { // icon doesn't successfully downloaded and |
| // displayed, bypass the check |
| return true; |
| } |
| |
| boolean result = true; |
| |
| try { |
| // Extension Value |
| |
| byte[] logoType = x509Cert.getExtensionValue("1.3.6.1.5.5.7.1.12"); |
| if (logoType != null) { |
| ByteArrayInputStream bais = new ByteArrayInputStream(logoType); |
| ASN1InputStream asn1_is = new ASN1InputStream(bais); |
| DEROctetString derObj = (DEROctetString) asn1_is.readObject(); |
| |
| bais = (ByteArrayInputStream) derObj.getOctetStream(); |
| asn1_is = new ASN1InputStream(bais); |
| DERSequence logoTypeExt = (DERSequence) asn1_is.readObject(); |
| Log.d(TAG2, "LogotypeExtn:" + logoTypeExt.toString()); |
| |
| Enumeration LogotypeExtnSequence = logoTypeExt.getObjects(); |
| while (LogotypeExtnSequence.hasMoreElements()) { |
| |
| DERTaggedObject LogotypeExtnTaggedObj = (DERTaggedObject) ((ASN1Encodable) LogotypeExtnSequence |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "LogotypeExtnTaggedObj:" + LogotypeExtnTaggedObj.toString()); |
| Log.d(TAG2, "LogotypeExtnTaggedObj CHOICE: " + LogotypeExtnTaggedObj.getTagNo()); |
| |
| /* |
| * LogotypeExtn ::= SEQUENCE { communityLogos [0] EXPLICIT |
| * SEQUENCE OF LogotypeInfo OPTIONAL, issuerLogo [1] |
| * EXPLICIT LogotypeInfo OPTIONAL, subjectLogo [2] EXPLICIT |
| * LogotypeInfo OPTIONAL, otherLogos [3] EXPLICIT SEQUENCE |
| * OF OtherLogotypeInfo OPTIONAL } |
| */ |
| if (LogotypeExtnTaggedObj.getTagNo() == 0) {// communityLogos |
| |
| Log.d(TAG2, ""); |
| DERSequence CommunityLogos = (DERSequence) LogotypeExtnTaggedObj |
| .getObject(); |
| Log.d(TAG2, "communityLogos:" + CommunityLogos.toString()); |
| |
| Enumeration enu; |
| Enumeration CommunityLogosEnu = CommunityLogos.getObjects(); |
| while (CommunityLogosEnu.hasMoreElements()) { |
| result = true; |
| |
| DERTaggedObject CommunityLogosTaggedObj = (DERTaggedObject) ((ASN1Encodable) CommunityLogosEnu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "CommunityLogosTaggedObj CHOICE: " |
| + CommunityLogosTaggedObj.getTagNo()); |
| /* |
| * LogotypeInfo ::= CHOICE { direct [0] |
| * LogotypeData, indirect [1] LogotypeReference } |
| */ |
| if (CommunityLogosTaggedObj.getTagNo() == 0) {// direct |
| /********************************************* |
| ************ image ************* |
| *********************************************/ |
| /* |
| * LogotypeData ::= SEQUENCE { image SEQUENCE OF |
| * LogotypeImage OPTIONAL, audio [1] SEQUENCE OF |
| * LogotypeAudio OPTIONAL } |
| */ |
| DERSequence LogotypeData = (DERSequence) CommunityLogosTaggedObj |
| .getObject(); |
| ; |
| Log.d(TAG2, "LogotypeImage:" + LogotypeData.toString()); |
| Enumeration LogotypeDataEnu = LogotypeData.getObjects(); |
| while (LogotypeDataEnu.hasMoreElements()) { |
| /* |
| * LogotypeImage ::= SEQUENCE { imageDetails |
| * LogotypeDetails, imageInfo |
| * LogotypeImageInfo OPTIONAL } |
| */ |
| DERSequence LogotypeImage = (DERSequence) ((ASN1Encodable) LogotypeDataEnu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "LogotypeImage:" + LogotypeImage.toString()); |
| Enumeration LogotypeImageEnu = LogotypeImage.getObjects(); |
| while (LogotypeImageEnu.hasMoreElements()) { |
| DERSequence imageDetails = (DERSequence) ((ASN1Encodable) LogotypeImageEnu |
| .nextElement()).toASN1Primitive(); |
| /* |
| * LogotypeImageInfo ::= SEQUENCE { type |
| * [0] LogotypeImageType DEFAULT color, |
| * fileSize INTEGER, -- In octets xSize |
| * INTEGER, -- Horizontal size in pixels |
| * ySize INTEGER, -- Vertical size in |
| * pixels resolution |
| * LogotypeImageResolution OPTIONAL, |
| * language [4] IA5String OPTIONAL } -- |
| * RFC 3066 Language Tag |
| */ |
| DERSequence imageInfo = (DERSequence) ((ASN1Encodable) LogotypeImageEnu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "imageInfo:" + imageInfo.toString()); |
| enu = imageInfo.getObjects(); |
| while (enu.hasMoreElements()) { |
| ASN1Object info = ((ASN1Encodable) enu.nextElement()) |
| .toASN1Primitive(); |
| Log.d(TAG2, "object:" + info.toString()); |
| if (info instanceof DERTaggedObject) { |
| if (((DERTaggedObject) info).getTagNo() == 4) { |
| DEROctetString language = (DEROctetString) ((DERTaggedObject) info) |
| .getObject(); |
| String languageCode = new String( |
| language.getEncoded()).substring(2); |
| Log.d(TAG2, "imageInfo language code:" |
| + languageCode); |
| } |
| } |
| } |
| |
| /* |
| * LogotypeDetails ::= SEQUENCE { |
| * mediaType IA5String, -- MIME media |
| * type name and optional -- parameters |
| * logotypeHash SEQUENCE SIZE (1..MAX) |
| * OF HashAlgAndValue, logotypeURI |
| * SEQUENCE SIZE (1..MAX) OF IA5String } |
| */ |
| Log.d(TAG2, "imageDetails:" + imageDetails.toString()); |
| enu = imageDetails.getObjects(); |
| |
| // mediaType |
| DERIA5String mediaType = (DERIA5String) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "mediaType:" + mediaType.toString()); |
| DERSequence logotypeHash = (DERSequence) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "logotypeHash:" + logotypeHash.toString()); |
| DERSequence logotypeURI = (DERSequence) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "logotypeURI:" + logotypeURI.toString()); |
| |
| // logotypeURI |
| enu = logotypeURI.getObjects(); |
| DERIA5String logotypeURIStr = (DERIA5String) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "logotypeURIStr:" + logotypeURIStr.toString()); |
| Log.d(TAG2, |
| "filename : (" |
| + filenameFromURI(logotypeURI.toString()) |
| + ")"); |
| if (iconFileName.equals(filenameFromURI(logotypeURIStr |
| .toString()))) { |
| Log.d(TAG, "Icon filename match"); |
| result = true; |
| } else { |
| Log.d(TAG, "Icon filename not match"); |
| result = false; |
| continue; |
| } |
| |
| // logotypeHash |
| enu = logotypeHash.getObjects(); |
| DERSequence HashAlgAndValue = (DERSequence) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "HashAlgAndValue:" + HashAlgAndValue.toString()); |
| enu = HashAlgAndValue.getObjects(); |
| // hashAlg |
| DERSequence hashAlg = (DERSequence) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "hashAlg:" + hashAlg.toString()); |
| // hashValue |
| DEROctetString hashValue = (DEROctetString) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, "hashValue:" + hashValue.toString()); |
| // hashAlg --> AlgorithmIdentifier |
| enu = hashAlg.getObjects(); |
| DERObjectIdentifier AlgorithmIdentifier = (DERObjectIdentifier) ((ASN1Encodable) enu |
| .nextElement()).toASN1Primitive(); |
| Log.d(TAG2, |
| "AlgorithmIdentifier:" |
| + AlgorithmIdentifier.toString()); |
| // hashValue --> OctetString |
| byte[] hashValueOctetString = hashValue.getOctets(); |
| Log.d(TAG2, |
| "hashValueOctetString:" |
| + hashValueOctetString.toString()); |
| // String certIconHash = |
| // octetStringToString(hashValue.toString().substring(1)); |
| String certIconHash = hashValue.toString().substring(1); |
| Log.d(TAG2, "hashValue String:" + certIconHash); |
| if (iconHash.equals(certIconHash)) { |
| Log.d(TAG, "Icon hash match"); |
| return true; |
| } else { |
| Log.d(TAG, "Icon hash not match"); |
| result = false; |
| continue; |
| } |
| |
| } |
| |
| } |
| |
| } |
| |
| } |
| } |
| } |
| Log.d(TAG2, "LogotypeExtn parsing done"); |
| return result; |
| } |
| } catch (SecurityException e) { |
| e.printStackTrace(); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| |
| return false; |
| } |
| |
| /** |
| * A helper class for accessing the raw data in the intent extra and handling |
| * certificates. |
| */ |
| private class PpsmoParser { |
| |
| PpsmoParser() {} |
| |
| public Document getDocument(String XML) { |
| |
| try { |
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
| factory.setCoalescing(true); |
| factory.setNamespaceAware(true); |
| DocumentBuilder builder = factory.newDocumentBuilder(); |
| Document doc = null; |
| |
| XML = tearDownSpecialChars(XML); |
| Log.d(TAG, "parseXML:" + XML); |
| |
| StringReader sr = new StringReader(XML); |
| InputSource is = new InputSource(sr); |
| |
| try { |
| doc = (Document) builder.parse(is); |
| } catch (IOException e) { |
| Log.e("PasspointPpsmoParser", "getDocument IOException:" + e); |
| } catch (SAXException e) { |
| Log.e("PasspointPpsmoParser", "getDocument SAXException:" + e); |
| } |
| |
| return doc; |
| } catch (Exception e) { |
| Log.e(TAG, "getDocument err:" + e); |
| } |
| |
| return null; |
| } |
| |
| public Vector<Document> getSPPNodes(Document doc, String namespace, String sTag) { |
| Vector<Document> sppNodes = new Vector<Document>(); |
| NodeList tagElements = doc.getElementsByTagNameNS(namespace, sTag); |
| if (tagElements.getLength() != 0) { |
| try { |
| for (int i = 0; i < tagElements.getLength(); i++) { |
| Node nNode = tagElements.item(i); |
| Document newXmlDocument = DocumentBuilderFactory.newInstance() |
| .newDocumentBuilder().newDocument(); |
| Element root = newXmlDocument.createElementNS(namespace, "root"); |
| newXmlDocument.appendChild(root); |
| |
| Node copyNode = newXmlDocument.importNode(nNode, true); |
| root.appendChild(copyNode); |
| |
| sppNodes.add(newXmlDocument); |
| } |
| } catch (Exception e) { |
| Log.e(TAG, "getSPPNodes err:" + e); |
| } |
| return sppNodes; |
| } |
| return null; |
| } |
| |
| private String tearDownSpecialChars(String XML) { |
| //restore escaping symbol first (format v6) |
| XML = XML.replaceAll("<", "<"); |
| XML = XML.replaceAll(">", ">"); |
| XML = XML.replaceAll("\\Q<![CDATA[\\E", ""); |
| XML = XML.replaceAll("\\Q]]>\\E", ""); |
| |
| return XML; |
| } |
| |
| public String getTagValue(String sTag, Element eElement) { |
| try { |
| NodeList tagElements = eElement.getElementsByTagName(sTag); |
| if (tagElements != null && tagElements.item(0) != null) { |
| NodeList nlList = tagElements.item(0).getChildNodes(); |
| Node nValue = (Node) nlList.item(0); |
| |
| return nValue.getNodeValue(); |
| } else { |
| return null; |
| } |
| |
| } catch (Exception e) { |
| Log.e(TAG, "getTagValue err:" + e); |
| } |
| return null; |
| } |
| |
| public String getTagValue(String namespace, String sTag, Element eElement) { |
| try { |
| NodeList tagElements = eElement.getElementsByTagNameNS(namespace, sTag); |
| if (tagElements != null && tagElements.item(0) != null) { |
| NodeList nlList = tagElements.item(0).getChildNodes(); |
| Node nValue = (Node) nlList.item(0); |
| |
| return nValue.getNodeValue(); |
| } else { |
| return null; |
| } |
| |
| } catch (Exception e) { |
| Log.e(TAG, "getTagValue err:" + e); |
| } |
| return null; |
| } |
| |
| public Document extractMgmtTree(String XML) { |
| try { |
| Document doc = getDocument(XML); |
| Document newXmlDocument = DocumentBuilderFactory.newInstance() |
| .newDocumentBuilder().newDocument(); |
| Element root = newXmlDocument.createElement("MgmtTree"); |
| newXmlDocument.appendChild(root); |
| |
| NodeList verDtd = doc.getElementsByTagName("VerDTD"); |
| Node copyNode = newXmlDocument.importNode(verDtd.item(0), true); |
| root.appendChild(copyNode); |
| |
| NodeList nodes = doc.getElementsByTagName("Node"); |
| copyNode = newXmlDocument.importNode(nodes.item(0), true); |
| root.appendChild(copyNode); |
| |
| return newXmlDocument; |
| } catch (Exception e) { |
| Log.e(TAG, "extractMgmtTree err:" + e); |
| } |
| return null; |
| } |
| |
| public Document extractMgmtTree(Document doc) { |
| try { |
| Document newXmlDocument = DocumentBuilderFactory.newInstance() |
| .newDocumentBuilder().newDocument(); |
| Element root = newXmlDocument.createElement("MgmtTree"); |
| newXmlDocument.appendChild(root); |
| |
| NodeList verDtd = doc.getElementsByTagName("VerDTD"); |
| Node copyNode = newXmlDocument.importNode(verDtd.item(0), true); |
| root.appendChild(copyNode); |
| |
| NodeList nodes = doc.getElementsByTagName("Node"); |
| copyNode = newXmlDocument.importNode(nodes.item(0), true); |
| root.appendChild(copyNode); |
| |
| return newXmlDocument; |
| } catch (Exception e) { |
| Log.e(TAG, "extractMgmtTree err:" + e); |
| } |
| return null; |
| } |
| |
| public String xmlToString(Document doc) { |
| try { |
| TransformerFactory tf = TransformerFactory.newInstance(); |
| Transformer transformer = tf.newTransformer(); |
| transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); |
| StringWriter writer = new StringWriter(); |
| transformer.transform(new DOMSource(doc), new StreamResult(writer)); |
| String output = removeComment(writer.getBuffer().toString().replaceAll("\n|\r", "")); |
| return output; |
| } catch (TransformerConfigurationException e) { |
| Log.e(TAG, "xmlToString TransformerConfigurationException:" + e); |
| } catch (TransformerException e) { |
| Log.e(TAG, "xmlToString TransformerException:" + e); |
| } |
| return null; |
| } |
| |
| private String removeComment(String XML) { |
| XML = XML.replaceAll("(?s)<!--.*?-->", ""); |
| |
| return XML; |
| } |
| } |
| |
| private class CertTrustManager implements X509TrustManager { |
| public void checkClientTrusted(X509Certificate[] arg0, String arg1) { |
| Log.d(TAG, "[checkClientTrusted] " + arg0 + arg1); |
| } |
| |
| public void checkServerTrusted(X509Certificate[] arg0, String arg1) |
| throws CertificateException { |
| Log.d(TAG, "[checkServerTrusted] X509Certificate amount:" + arg0.length |
| + ", cryptography: " + arg1); |
| try { |
| int i; |
| for (i = 0; i < arg0.length; i++) |
| { |
| Log.d(TAG, "X509Certificate: " + arg0[i]); |
| Log.d(TAG, "===================="); |
| |
| // check validity (not before and not after) |
| arg0[i].checkValidity(); |
| } |
| |
| // check root CA chaining |
| KeyStore ks = KeyStore.getInstance("AndroidCAStore"); |
| ks.load(null, null); |
| TrustManagerImpl tm = new TrustManagerImpl(ks); |
| tm.checkServerTrusted(arg0, arg0[0].getPublicKey().getAlgorithm()); |
| |
| // only check on OSU |
| if (mServerUrl != null && !mServerUrl.isEmpty()) { |
| // check SP friendly name and Language code |
| if (!isLanguageAndNamesMatched(arg0[0])) { |
| throw new RuntimeException("id-wfa-hotspot-friendly-name check fail"); |
| } |
| |
| // check icon type hash value |
| if (!isLogoTypeExtensionMatched(arg0[0])) { |
| throw new RuntimeException("Certificate Logo icon hash doesn't match"); |
| } |
| } |
| |
| // check id-kp-serverAuth |
| if (!isServerAuthMatched(arg0[0])) { |
| throw new RuntimeException("id-kp-serverAuth found"); |
| } |
| |
| // check SPFQDN |
| boolean suffixMatch; |
| |
| // check complete host name on OSU server |
| if (mServerUrl != null && !mServerUrl.isEmpty()) { |
| suffixMatch = false; |
| } else { |
| // check SPFQDN on subscription and policy server |
| suffixMatch = true; |
| } |
| if (!isDnsNameMatched(arg0[0], mSpFqdn, suffixMatch)) { |
| throw new RuntimeException( |
| "Certificate Subject Alternative Name doesn't include SP-FQDN"); |
| } |
| } catch (CertificateException e) { |
| throw e; |
| } catch (Exception e) { |
| e.printStackTrace(); |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public X509Certificate[] getAcceptedIssuers() { |
| Log.d(TAG, "[getAcceptedIssuers] "); |
| return null; |
| } |
| } |
| } |