summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Nordqvist <jannq@google.com>2016-02-09 17:24:20 +0000
committerAndroid Partner Code Review <android-gerrit-partner@google.com>2016-02-09 17:24:21 +0000
commit676d664bf4b5f59279a53a986ce94363e2bc4fd2 (patch)
tree2c21d2b4e1f25b27081ecfbd36dea4808a81829e
parent68cb8c02b4ad079c54a2ffd4407da921d18c7af9 (diff)
parent3fff4c9bd5db730141e75706a7229814d403b363 (diff)
Merge "Removing Hotspot 2.0 OSU client code from framework." into mm-wireless-dev
-rw-r--r--service/java/com/android/server/wifi/FrameworkFacade.java12
-rw-r--r--service/java/com/android/server/wifi/hotspot2/AlarmHandler.java5
-rw-r--r--service/java/com/android/server/wifi/hotspot2/Chronograph.java154
-rw-r--r--service/java/com/android/server/wifi/hotspot2/OMADMAdapter.java6
-rw-r--r--service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java7
-rw-r--r--service/java/com/android/server/wifi/hotspot2/WifiNetworkAdapter.java216
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Boolean.java30
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Class.java5
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Constructed.java54
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Decoder.java211
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1ID.java19
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Integer.java58
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Object.java89
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Octets.java49
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Oid.java198
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1String.java33
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/Asn1Tag.java31
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/DecodeException.java17
-rw-r--r--service/java/com/android/server/wifi/hotspot2/asn1/OidMappings.java184
-rw-r--r--service/java/com/android/server/wifi/hotspot2/est/ESTHandler.java508
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/OMAConstants.java66
-rw-r--r--service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java27
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/ClientKeyManager.java201
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/ExchangeCompleteResponse.java28
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/ExecCommand.java3
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/HTTPHandler.java176
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/IconCache.java357
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUCertType.java10
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUClient.java494
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUCommand.java120
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUCommandID.java5
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUError.java22
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUInfo.java220
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUListener.java5
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUManager.java1088
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUMessageType.java6
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUOperationStatus.java8
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUResponse.java97
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUSocketFactory.java369
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/OSUStatus.java5
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/PostDevDataResponse.java52
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/RequestReason.java16
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/ResponseFactory.java8
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/SOAPBuilder.java183
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/SOAPParser.java325
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/SPVerifier.java329
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/UserInputListener.java44
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/WiFiKeyManager.java184
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/XMLParser.java67
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/commands/BrowserURI.java32
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/commands/ClientCertInfo.java94
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/commands/GetCertData.java75
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/commands/MOURN.java33
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/commands/OSUCommandData.java7
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/commands/PasspointManagementObjectData.java54
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/service/RedirectListener.java204
-rw-r--r--service/java/com/android/server/wifi/hotspot2/osu/service/SubscriptionTimer.java118
-rw-r--r--service/java/com/android/server/wifi/hotspot2/utils/HTTPMessage.java33
-rw-r--r--service/java/com/android/server/wifi/hotspot2/utils/HTTPRequest.java288
-rw-r--r--service/java/com/android/server/wifi/hotspot2/utils/HTTPResponse.java178
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java6
61 files changed, 19 insertions, 7504 deletions
diff --git a/service/java/com/android/server/wifi/FrameworkFacade.java b/service/java/com/android/server/wifi/FrameworkFacade.java
index 7a301c3da..2ecfe07cc 100644
--- a/service/java/com/android/server/wifi/FrameworkFacade.java
+++ b/service/java/com/android/server/wifi/FrameworkFacade.java
@@ -11,11 +11,6 @@ import android.os.IBinder;
import android.os.ServiceManager;
import android.provider.Settings;
-import com.android.internal.util.StateMachine;
-import com.android.server.wifi.hotspot2.SupplicantBridge;
-import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager;
-import com.android.server.wifi.hotspot2.osu.OSUManager;
-
/**
* This class allows overriding objects with mocks to write unit tests
*/
@@ -50,13 +45,6 @@ public class FrameworkFacade {
return PendingIntent.getBroadcast(context, requestCode, intent, flags);
}
- public OSUManager makeOsuManager(WifiConfigStore wifiConfigStore, Context context,
- SupplicantBridge supplicantBridge, PasspointManagementObjectManager moManager,
- WifiStateMachine wifiStateMachine) {
- return new OSUManager(wifiConfigStore, context,
- supplicantBridge, moManager, wifiStateMachine);
- }
-
public SupplicantStateTracker makeSupplicantStateTracker(Context context,
WifiStateMachine wifiStateMachine, WifiConfigStore configStore, Handler handler) {
return new SupplicantStateTracker(context, wifiStateMachine, configStore, handler);
diff --git a/service/java/com/android/server/wifi/hotspot2/AlarmHandler.java b/service/java/com/android/server/wifi/hotspot2/AlarmHandler.java
deleted file mode 100644
index 5fae519f6..000000000
--- a/service/java/com/android/server/wifi/hotspot2/AlarmHandler.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.android.server.wifi.hotspot2;
-
-public interface AlarmHandler {
- public void wake(Object token);
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/Chronograph.java b/service/java/com/android/server/wifi/hotspot2/Chronograph.java
deleted file mode 100644
index 92bc95fd3..000000000
--- a/service/java/com/android/server/wifi/hotspot2/Chronograph.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package com.android.server.wifi.hotspot2;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-
-public class Chronograph extends Thread {
- private final Map<Long, Set<AlarmEntry>> mAlarmEntryMap = new TreeMap<Long, Set<AlarmEntry>>();
- private boolean mRecalculate;
-
- private static class AlarmEntry {
- private final long mAt;
- private final AlarmHandler mAlarmHandler;
- private final Object mToken;
-
- private AlarmEntry(long at, AlarmHandler alarmHandler, Object token) {
- mAt = at;
- mAlarmHandler = alarmHandler;
- mToken = token;
- }
-
- private void callout() {
- mAlarmHandler.wake(mToken);
- }
- }
-
- public Chronograph()
- {
- setName("Chronograph");
- setDaemon(true);
- }
-
- public Object addAlarm(long interval, AlarmHandler handler, Object token) {
- long at = System.currentTimeMillis() + interval;
- synchronized (mAlarmEntryMap) {
- AlarmEntry alarmEntry = new AlarmEntry(at, handler, token);
- Set<AlarmEntry> entries = mAlarmEntryMap.get(at);
- if (entries == null) {
- entries = new HashSet<AlarmEntry>(1);
- mAlarmEntryMap.put(at, entries);
- }
- entries.add(alarmEntry);
- mRecalculate = true;
- mAlarmEntryMap.notifyAll();
- return alarmEntry;
- }
- }
-
- public boolean cancelAlarm(Object key) {
- if (key == null || key.getClass() != AlarmEntry.class) {
- throw new IllegalArgumentException("Not an alarm key");
- }
-
- AlarmEntry alarmEntry = (AlarmEntry)key;
-
- synchronized (mAlarmEntryMap) {
- Set<AlarmEntry> entries = mAlarmEntryMap.get(alarmEntry.mAt);
- if (entries == null) {
- return false;
- }
- if (entries.remove(alarmEntry)) {
- mRecalculate = true;
- mAlarmEntryMap.notifyAll();
- return true;
- }
- return false;
- }
- }
-
- @Override
- public void run() {
-
- for(;;) {
-
- long now = System.currentTimeMillis();
- List<Set<AlarmEntry>> pending = new ArrayList<Set<AlarmEntry>>();
-
- long nextExpiration = 0;
-
- synchronized (mAlarmEntryMap) {
-
- Iterator<Map.Entry<Long,Set<AlarmEntry>>> entries =
- mAlarmEntryMap.entrySet().iterator();
-
- while (entries.hasNext()) {
- Map.Entry<Long,Set<AlarmEntry>> entry = entries.next();
- if (entry.getKey() <= now) {
- pending.add(entry.getValue());
- entries.remove();
- }
- else {
- nextExpiration = entry.getKey();
- break;
- }
- }
- }
-
- for (Set<AlarmEntry> alarmEntries : pending) {
- for (AlarmEntry alarmEntry : alarmEntries) {
- alarmEntry.callout();
- }
- }
-
- now = System.currentTimeMillis();
-
- synchronized (mAlarmEntryMap) {
- long sleep = nextExpiration - now;
- while (sleep > 0 && !mRecalculate) {
- try {
- mAlarmEntryMap.wait(sleep);
- }
- catch (InterruptedException ie) {
- /**/
- }
- sleep = nextExpiration - System.currentTimeMillis();
- }
- }
- }
- }
-
- public static void main(String[] args) throws InterruptedException{
- Chronograph chronograph = new Chronograph();
- chronograph.start();
-
- chronograph.addAlarm(3000L, new AlarmHandler() {
- @Override
- public void wake(Object token) {
- System.out.println("3: " + token);
- }
- }, "3s" );
-
- Object key = chronograph.addAlarm(7500L, new AlarmHandler() {
- @Override
- public void wake(Object token) {
- System.out.println("7: " + token);
- }
- }, "7.5s" );
-
- chronograph.addAlarm(10000L, new AlarmHandler() {
- @Override
- public void wake(Object token) {
- System.out.println("10: " + token);
- }
- }, "10.00s" );
-
- System.out.println(chronograph.cancelAlarm(key));
-
- chronograph.join();
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/OMADMAdapter.java b/service/java/com/android/server/wifi/hotspot2/OMADMAdapter.java
index d970cfa2f..9e1a582c9 100644
--- a/service/java/com/android/server/wifi/hotspot2/OMADMAdapter.java
+++ b/service/java/com/android/server/wifi/hotspot2/OMADMAdapter.java
@@ -12,7 +12,6 @@ import com.android.server.wifi.anqp.eap.EAP;
import com.android.server.wifi.hotspot2.omadm.MOTree;
import com.android.server.wifi.hotspot2.omadm.OMAConstants;
import com.android.server.wifi.hotspot2.omadm.OMAConstructed;
-import com.android.server.wifi.hotspot2.osu.OSUManager;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@@ -140,7 +139,8 @@ public class OMADMAdapter {
if (strDevId != null && strDevId.length() >= IMEI_Length) {
strDevId = strDevId.substring(0, IMEI_Length);
} else {
- Log.w(OSUManager.TAG, "MEID cannot be extracted from DeviceId " + strDevId);
+ Log.w(Utils.hs2LogTag(getClass()),
+ "MEID cannot be extracted from DeviceId " + strDevId);
}
} else {
if (isPhoneTypeLTE()) {
@@ -275,7 +275,7 @@ public class OMADMAdapter {
}
}
catch (IOException ioe) {
- Log.e(OSUManager.TAG, "Caught exception building OMA Tree: " + ioe, ioe);
+ Log.e(Utils.hs2LogTag(getClass()), "Caught exception building OMA Tree: " + ioe, ioe);
return null;
}
diff --git a/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java b/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java
index cfd846ea3..8b98a8d07 100644
--- a/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java
+++ b/service/java/com/android/server/wifi/hotspot2/SupplicantBridge.java
@@ -12,7 +12,6 @@ import com.android.server.wifi.anqp.Constants;
import com.android.server.wifi.anqp.eap.AuthParam;
import com.android.server.wifi.anqp.eap.EAP;
import com.android.server.wifi.anqp.eap.EAPMethod;
-import com.android.server.wifi.hotspot2.osu.OSUManager;
import com.android.server.wifi.hotspot2.pps.Credential;
import java.io.BufferedReader;
@@ -119,7 +118,7 @@ public class SupplicantBridge {
String command = String.format("GET_HS20_ICON %s %s %d %d",
Utils.macToString(iconEvent.getBSSID()), iconEvent.getFileName(),
offset, size);
- Log.d(OSUManager.TAG, "Issuing '" + command + "'");
+ Log.d(Utils.hs2LogTag(getClass()), "Issuing '" + command + "'");
String response = mSupplicantHook.doCustomSupplicantCommand(command);
if (response == null) {
throw new IOException("No icon data returned");
@@ -141,12 +140,12 @@ public class SupplicantBridge {
}
}
if (offset != iconEvent.getSize()) {
- Log.w(OSUManager.TAG, "Partial icon data: " + offset +
+ Log.w(Utils.hs2LogTag(getClass()), "Partial icon data: " + offset +
", expected " + iconEvent.getSize());
}
}
finally {
- Log.d(OSUManager.TAG, "Deleting icon for " + iconEvent);
+ Log.d(Utils.hs2LogTag(getClass()), "Deleting icon for " + iconEvent);
String result = mSupplicantHook.doCustomSupplicantCommand("DEL_HS20_ICON " +
Utils.macToString(iconEvent.getBSSID()) + " " + iconEvent.getFileName());
}
diff --git a/service/java/com/android/server/wifi/hotspot2/WifiNetworkAdapter.java b/service/java/com/android/server/wifi/hotspot2/WifiNetworkAdapter.java
deleted file mode 100644
index 2f7cbc9e4..000000000
--- a/service/java/com/android/server/wifi/hotspot2/WifiNetworkAdapter.java
+++ /dev/null
@@ -1,216 +0,0 @@
-package com.android.server.wifi.hotspot2;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.Network;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiEnterpriseConfig;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.util.Log;
-
-import com.android.server.wifi.WifiConfigStore;
-import com.android.server.wifi.WifiStateMachine;
-import com.android.server.wifi.configparse.ConfigBuilder;
-import com.android.server.wifi.hotspot2.osu.OSUInfo;
-import com.android.server.wifi.hotspot2.osu.OSUManager;
-import com.android.server.wifi.hotspot2.pps.HomeSP;
-
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.Collection;
-import java.util.List;
-
-public class WifiNetworkAdapter {
- private final Context mContext;
- private final OSUManager mOSUManager;
- private final WifiStateMachine mWifiStateMachine;
- private WifiConfigStore mWifiConfigStore;
- private OSUInfo mCurrentOSUInfo;
-
- public WifiNetworkAdapter(Context context, OSUManager osuManager,
- WifiStateMachine wifiStateMachine, WifiConfigStore wifiConfigStore) {
- mOSUManager = osuManager;
- mContext = context;
- mWifiStateMachine = wifiStateMachine;
- mWifiConfigStore = wifiConfigStore;
- }
-
- public void initialize() {
- IntentFilter filter = new IntentFilter();
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
-
- mContext.registerReceiver(new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- // This is a current mock implementation that blindly starts an OSU flow as soon
- // as an SSID associated with an OSU is connected to.
-
- if (OSUManager.R2_TEST) {
- OSUInfo osuInfo = getCurrentOSU();
-
- if (!compareOSUs(mCurrentOSUInfo, osuInfo)) {
- mCurrentOSUInfo = osuInfo;
- Network network = osuInfo != null ? getCurrentNetwork() : null;
- Log.d(OSUManager.TAG, "OSU changed to " + osuInfo + ", network " + network);
- try {
- mOSUManager.initiateProvisioning(osuInfo, network);
- } catch (Throwable t) {
- Log.e(OSUManager.TAG, "Failed to initiate provisioning on " +
- osuInfo + ": " + t, t);
- }
- }
- }
- }
- }, filter);
- }
-
- public Network getCurrentNetwork() {
- return mWifiStateMachine.getCurrentNetwork();
- }
-
- public WifiInfo getConnectionInfo() {
- return mWifiStateMachine.getWifiInfo();
- }
-
- public WifiConfiguration getWifiConfig(HomeSP homeSP) {
- List<WifiConfiguration> networks = mWifiConfigStore.getConfiguredNetworks();
- for (WifiConfiguration current : networks) {
- if (current.isPasspoint() && current.FQDN.equals(homeSP.getFQDN())) {
- return current;
- }
- }
- return null;
- }
-
- public void updateNetwork(HomeSP homeSP, X509Certificate caCert,
- List<X509Certificate> clientCerts, PrivateKey privateKey)
- throws IOException, GeneralSecurityException {
-
- WifiConfiguration config = getWifiConfig(homeSP);
- if (config == null) {
- throw new IOException("Failed to find matching network config");
- }
- Log.d(OSUManager.TAG, "Found matching config " + config.networkId + ", updating");
-
- WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
- WifiConfiguration newConfig = ConfigBuilder.buildConfig(homeSP,
- caCert != null ? caCert : enterpriseConfig.getCaCertificate(),
- clientCerts, privateKey);
- newConfig.networkId = config.networkId;
-
- WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- wifiManager.save(newConfig, null);
- wifiManager.saveConfiguration();
- }
-
- public void detachOSUNetwork(Network osuNetwork, int newNwkId) {
- WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- wifiManager.disableNetwork(osuNetwork.netId);
- if (newNwkId != WifiConfiguration.INVALID_NETWORK_ID) {
- wifiManager.enableNetwork(newNwkId, true);
- }
- }
-
- /**
- * Set the re-authentication hold off time for the current network
- * @param holdoff hold off time in milliseconds
- * @param ess set if the hold off pertains to an ESS rather than a BSS
- */
- public void setHoldoffTime(long holdoff, boolean ess) {
-
- }
-
- private OSUInfo getCurrentOSU() {
- WifiConfiguration active = getActiveNetwork();
- mOSUManager.setActiveNetwork(active);
- if (active == null) {
- return null;
- }
-
- Collection<OSUInfo> osus = mOSUManager.getAvailableOSUs();
-
- String ssid = Utils.unquote(active.SSID);
- String bssidString = mWifiStateMachine.getWifiInfo().getBSSID();
- long bssid = bssidString != null ? Utils.parseMac(bssidString) : -1;
-
- Log.d(OSUManager.TAG, String.format("Connection event for %012x '%s', OSUs: %s",
- bssid, ssid, osus));
-
- for (OSUInfo osu : osus) {
- if (osu.getSSID().equals(ssid)) {
- //if (osu.getBSSID() == bssid) // ??? Can BSSID be bound to AP somehow?
- Log.d(OSUManager.TAG, "OSU match: " + osu);
- return osu;
- }
- }
- return null;
- }
-
- private WifiConfiguration getActiveNetwork() {
- List<WifiConfiguration> networks = mWifiConfigStore.getConfiguredNetworks();
- for (WifiConfiguration wifiConfiguration : networks) {
- if (wifiConfiguration.status == WifiConfiguration.Status.CURRENT) {
- return wifiConfiguration;
- }
- }
- return null;
- }
-
- private static boolean compareOSUs(OSUInfo o1, OSUInfo o2) {
- if (o1 == null) {
- return o2 == null;
- }
- else {
- return o2 != null && o1.getBSSID() == o2.getBSSID() && o1.getSSID().equals(o2.getSSID());
- }
- }
-
- /*
- public void associate(String ssid, long bssid, String nai) {
- Log.d("HS2OSU", "Requesting association with '" + ssid + "'");
- NetworkRequest.Builder nwkRequestBuilder = new NetworkRequest.Builder();
- nwkRequestBuilder = nwkRequestBuilder.
- clearCapabilities().
- addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
- // setNetworkSpecifier(ssid);
- // 07-29 19:13:33.211 D/ConnectivityService( 1121): listenForNetwork for Listen from uid/pid:1000/1121 for NetworkRequest [ id=6, legacyType=-1, [ Transports: WIFI Specifier: <third>] ]
- ConnectivityManager connectivityManager = (ConnectivityManager) mContext.
- getSystemService(Context.CONNECTIVITY_SERVICE);
- connectivityManager.registerNetworkCallback(nwkRequestBuilder.build(), this);
-
- WifiManager wifiMgr = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- WifiConfiguration configuration = new WifiConfiguration();
- configuration.SSID = ssid;
- configuration.BSSID = Utils.macToString(bssid);
- int id = wifiMgr.addNetwork(configuration);
-
- wifiMgr.enableNetwork(id, true);
-
- synchronized (mNetworks) {
- mNetworks.put(bssid, new NetworkInfo(id, bssid, ssid));
- }
- }
-
- public void dropNetwork(long bssid) {
- NetworkInfo networkInfo;
- synchronized (mNetworks) {
- networkInfo = mNetworks.remove(bssid);
- if (networkInfo == null) {
- return;
- }
- }
-
- WifiManager wifiMgr = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- wifiMgr.disableNetwork(networkInfo.getID());
- ConnectivityManager connectivityManager = (ConnectivityManager) mContext.
- getSystemService(Context.CONNECTIVITY_SERVICE);
- connectivityManager.unregisterNetworkCallback(this);
- }
- */
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Boolean.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Boolean.java
deleted file mode 100644
index d66a7b51c..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Boolean.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.util.Collection;
-
-public class Asn1Boolean extends Asn1Object {
- private final boolean mBoolean;
-
- public Asn1Boolean(int tag, Asn1Class asn1Class, int length, ByteBuffer data) throws DecodeException {
- super(tag, asn1Class, false, length);
- if (length != 1) {
- throw new DecodeException("Boolean length != 1: " + length, data.position());
- }
- mBoolean = data.get() != 0;
- }
-
- public boolean getValue() {
- return mBoolean;
- }
-
- @Override
- public Collection<Asn1Object> getChildren() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String toString() {
- return super.toString() + "=" + Boolean.toString(mBoolean);
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Class.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Class.java
deleted file mode 100644
index c8cb25976..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Class.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-public enum Asn1Class {
- Universal, Application, Context, Private
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Constructed.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Constructed.java
deleted file mode 100644
index e8a8f911d..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Constructed.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.util.*;
-
-public class Asn1Constructed extends Asn1Object {
- private final int mTagPosition;
- private final List<Asn1Object> mChildren;
-
- public Asn1Constructed(int tag, Asn1Class asn1Class, int length,
- ByteBuffer payload, int tagPosition) {
- super(tag, asn1Class, true, length, payload);
- mTagPosition = tagPosition;
- mChildren = new ArrayList<>();
- }
-
- public void addChild(Asn1Object object) {
- mChildren.add(object);
- }
-
- @Override
- public Collection<Asn1Object> getChildren() {
- return Collections.unmodifiableCollection(mChildren);
- }
-
- public ByteBuffer getEncoding() {
- return getPayload(mTagPosition);
- }
-
- private void toString(int level, StringBuilder sb) {
- sb.append(indent(level)).append(super.toString()).append(":\n");
- for (Asn1Object child : mChildren) {
- if (child.isConstructed()) {
- ((Asn1Constructed) child).toString(level+1, sb);
- }
- else {
- sb.append(indent(level+1)).append(child.toString()).append('\n');
- }
- }
- }
-
- public static String indent(int level) {
- char[] indent = new char[level*2];
- Arrays.fill(indent, ' ');
- return new String(indent);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- toString(0, sb);
- return sb.toString();
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Decoder.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Decoder.java
deleted file mode 100644
index 4c4cff0ed..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Decoder.java
+++ /dev/null
@@ -1,211 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class Asn1Decoder {
- public static final int TAG_UNIVZERO = 0x00;
- public static final int TAG_BOOLEAN = 0x01;
- public static final int TAG_INTEGER = 0x02;
- public static final int TAG_BITSTRING = 0x03;
- public static final int TAG_OCTET_STRING = 0x04;
- public static final int TAG_NULL = 0x05;
- public static final int TAG_OID = 0x06;
- public static final int TAG_ObjectDescriptor = 0x07;
- public static final int TAG_EXTERNAL = 0x08;
- public static final int TAG_REAL = 0x09;
- public static final int TAG_ENUMERATED = 0x0a;
- public static final int TAG_UTF8String = 0x0c; // * (*) are X.509 DirectoryString's
- public static final int TAG_RelativeOID = 0x0d;
- public static final int TAG_SEQ = 0x10; // 30 if constructed
- public static final int TAG_SET = 0x11;
- public static final int TAG_NumericString = 0x12; // [UNIVERSAL 18]
- public static final int TAG_PrintableString = 0x13; // * [UNIVERSAL 19]
- public static final int TAG_T61String = 0x14; // * TeletexString [UNIVERSAL 20]
- public static final int TAG_VideotexString = 0x15; // [UNIVERSAL 21]
- public static final int TAG_IA5String = 0x16; // [UNIVERSAL 22]
- public static final int TAG_UTCTime = 0x17;
- public static final int TAG_GeneralizedTime = 0x18;
- public static final int TAG_GraphicString = 0x19; // [UNIVERSAL 25]
- public static final int TAG_VisibleString = 0x1a; // ISO64String [UNIVERSAL 26]
- public static final int TAG_GeneralString = 0x1b; // [UNIVERSAL 27]
- public static final int TAG_UniversalString = 0x1c; // * [UNIVERSAL 28]
- public static final int TAG_BMPString = 0x1e; // * [UNIVERSAL 30]
-
- public static final int IntOverflow = 0xffff0000;
- public static final int MoreBit = 0x80;
- public static final int MoreData = 0x7f;
- public static final int ConstructedBit = 0x20;
- public static final int ClassShift = 6;
- public static final int ClassMask = 0x3;
- public static final int MoreWidth = 7;
- public static final int ByteWidth = 8;
- public static final int ByteMask = 0xff;
- public static final int ContinuationTag = 31;
-
- public static final int IndefiniteLength = -1;
-
- private static final Map<Integer, Asn1Tag> sTagMap = new HashMap<>();
-
- static {
- sTagMap.put(TAG_UNIVZERO, Asn1Tag.UNIVZERO);
- sTagMap.put(TAG_BOOLEAN, Asn1Tag.BOOLEAN);
- sTagMap.put(TAG_INTEGER, Asn1Tag.INTEGER);
- sTagMap.put(TAG_BITSTRING, Asn1Tag.BITSTRING);
- sTagMap.put(TAG_OCTET_STRING, Asn1Tag.OCTET_STRING);
- sTagMap.put(TAG_NULL, Asn1Tag.NULL);
- sTagMap.put(TAG_OID, Asn1Tag.OID);
- sTagMap.put(TAG_ObjectDescriptor, Asn1Tag.ObjectDescriptor);
- sTagMap.put(TAG_EXTERNAL, Asn1Tag.EXTERNAL);
- sTagMap.put(TAG_REAL, Asn1Tag.REAL);
- sTagMap.put(TAG_ENUMERATED, Asn1Tag.ENUMERATED);
- sTagMap.put(TAG_UTF8String, Asn1Tag.UTF8String);
- sTagMap.put(TAG_RelativeOID, Asn1Tag.RelativeOID);
- sTagMap.put(TAG_SEQ, Asn1Tag.SEQUENCE);
- sTagMap.put(TAG_SET, Asn1Tag.SET);
- sTagMap.put(TAG_NumericString, Asn1Tag.NumericString);
- sTagMap.put(TAG_PrintableString, Asn1Tag.PrintableString);
- sTagMap.put(TAG_T61String, Asn1Tag.T61String);
- sTagMap.put(TAG_VideotexString, Asn1Tag.VideotexString);
- sTagMap.put(TAG_IA5String, Asn1Tag.IA5String);
- sTagMap.put(TAG_UTCTime, Asn1Tag.UTCTime);
- sTagMap.put(TAG_GeneralizedTime, Asn1Tag.GeneralizedTime);
- sTagMap.put(TAG_GraphicString, Asn1Tag.GraphicString);
- sTagMap.put(TAG_VisibleString, Asn1Tag.VisibleString);
- sTagMap.put(TAG_GeneralString, Asn1Tag.GeneralString);
- sTagMap.put(TAG_UniversalString, Asn1Tag.UniversalString);
- sTagMap.put(TAG_BMPString, Asn1Tag.BMPString);
- }
-
- public static Asn1Tag mapTag(int tag) {
- return sTagMap.get(tag);
- }
-
- public static Collection<Asn1Object> decode(ByteBuffer data) throws DecodeException {
- Asn1Constructed root = new Asn1Constructed(0, null, data.remaining(), data, data.position());
- decode(0, root);
- return root.getChildren();
- }
-
- private static void decode(int level, Asn1Constructed parent) throws DecodeException {
- ByteBuffer data = parent.getPayload();
- while (data.hasRemaining()) {
- int tagPosition = data.position();
- int propMask = data.get(tagPosition) & ByteMask;
- if (propMask == 0 && parent.isIndefiniteLength() && data.get(tagPosition + 1) == 0) {
- //System.out.printf("%seod @ %d\n", Asn1Constructed.indent(level), tagPosition);
- parent.setEndOfData(tagPosition);
- return;
- }
- Asn1Class asn1Class = Asn1Class.values()[(propMask >> ClassShift) & ClassMask];
- boolean constructed = (propMask & ConstructedBit) != 0;
-
- int tag = decodeTag(data);
- int length = decodeLength(data);
- //System.out.printf("%s%s %d, len %d @ %d\n", Asn1Constructed.indent(level), asn1Class, tag, length, tagPosition);
-
- if (constructed) {
- ByteBuffer payload = peelOff(data, length);
- Asn1Constructed root = new Asn1Constructed(tag, asn1Class, length, payload, tagPosition);
- decode(level + 1, root);
- if (length == IndefiniteLength) {
- //System.out.printf("%sClosing %s %d, len %d, eod %d @ %d\n", Asn1Constructed.indent(level), asn1Class, tag, length, payload.limit() + 2, tagPosition);
- data.position(root.getEndOfData() + 2); // advance past '00'
- }
- parent.addChild(root);
- } else {
- if (asn1Class != Asn1Class.Universal) {
- parent.addChild(new Asn1Octets(tag, asn1Class, length, data));
- } else {
- parent.addChild(buildScalar(tag, asn1Class, length, data));
- }
- }
- }
- }
-
- private static ByteBuffer peelOff(ByteBuffer base, int length) {
- ByteBuffer copy = base.duplicate();
- if (length == IndefiniteLength) {
- return copy;
- }
- copy.limit(copy.position() + length);
- base.position(base.position() + length);
- return copy;
- }
-
- private static Asn1Object buildScalar(int tag, Asn1Class asn1Class, int length, ByteBuffer data)
- throws DecodeException {
- switch (tag) {
- case TAG_BOOLEAN:
- return new Asn1Boolean(tag, asn1Class, length, data);
- case TAG_INTEGER:
- case TAG_ENUMERATED:
- return new Asn1Integer(tag, asn1Class, length, data);
- case TAG_BITSTRING:
- int bitResidual = data.get() & ByteMask;
- return new Asn1Octets(tag, asn1Class, length, data, bitResidual);
- case TAG_OCTET_STRING:
- return new Asn1Octets(tag, asn1Class, length, data);
- case TAG_OID:
- return new Asn1Oid(tag, asn1Class, length, data);
- case TAG_UTF8String:
- case TAG_NumericString:
- case TAG_PrintableString:
- case TAG_T61String:
- case TAG_VideotexString:
- case TAG_IA5String:
- case TAG_GraphicString:
- case TAG_VisibleString:
- case TAG_GeneralString:
- case TAG_UniversalString:
- case TAG_BMPString:
- return new Asn1String(tag, asn1Class, length, data);
- case TAG_GeneralizedTime:
- case TAG_UTCTime:
- return new Asn1String(tag, asn1Class, length, data); // Should really be a dedicated time object
- default:
- return new Asn1Octets(tag, asn1Class, length, data);
- }
- }
-
- private static int decodeTag(ByteBuffer data) throws DecodeException {
- int tag;
- byte tag0 = data.get();
-
- if ((tag = (tag0 & ContinuationTag)) == ContinuationTag) {
- int tagByte;
- tag = 0;
- while (((tagByte = data.get() & ByteMask) & MoreBit) != 0) {
- tag = (tag << MoreWidth) | (tagByte & MoreData);
- if ((tag & IntOverflow) != 0)
- throw new DecodeException("Tag overflow", data.position());
- }
- tag = (tag << MoreWidth) | tagByte;
- }
- return tag;
- }
-
- private static int decodeLength(ByteBuffer data) throws DecodeException {
- int length;
- int lenlen = data.get() & ByteMask;
-
- if ((lenlen & MoreBit) == 0) // One byte encoding
- length = lenlen;
- else {
- lenlen &= MoreData;
- if (lenlen == 0) {
- return IndefiniteLength;
- }
- length = 0;
- while (lenlen-- > 0) {
- length = (length << ByteWidth) | (data.get() & ByteMask);
- if ((length & IntOverflow) != 0 && lenlen > 0)
- throw new DecodeException("Length overflow", data.position());
- }
- }
- return length;
- }
-
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1ID.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1ID.java
deleted file mode 100644
index 6e2e632ee..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1ID.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-public class Asn1ID {
- private final int mTag;
- private final Asn1Class mClass;
-
- public Asn1ID(int tag, Asn1Class asn1Class) {
- mTag = tag;
- mClass = asn1Class;
- }
-
- public int getTag() {
- return mTag;
- }
-
- public Asn1Class getAsn1Class() {
- return mClass;
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Integer.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Integer.java
deleted file mode 100644
index a7339e71b..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Integer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-
-public class Asn1Integer extends Asn1Object {
- private static final int SignBit = 0x80;
-
- private final long mValue;
- private final BigInteger mBigValue;
-
- public Asn1Integer(int tag, Asn1Class asn1Class, int length, ByteBuffer data) {
- super(tag, asn1Class, false, length);
-
- if (length <= 8) {
- long value = (data.get(data.position()) & SignBit) != 0 ? -1 : 0;
- for (int n = 0; n < length; n++) {
- value = (value << Byte.SIZE) | data.get();
- }
- mValue = value;
- mBigValue = null;
- }
- else {
- byte[] payload = new byte[length];
- data.get(payload);
- mValue = 0;
- mBigValue = new BigInteger(payload);
- }
- }
-
- public boolean isBigValue() {
- return mBigValue != null;
- }
-
- public long getValue() {
- return mValue;
- }
-
- public BigInteger getBigValue() {
- return mBigValue;
- }
-
- @Override
- public Collection<Asn1Object> getChildren() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String toString() {
- if (isBigValue()) {
- return super.toString() + '=' + mBigValue.toString(16);
- }
- else {
- return super.toString() + '=' + mValue;
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Object.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Object.java
deleted file mode 100644
index aec250e71..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Object.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.util.Collection;
-
-public abstract class Asn1Object {
- private final int mTag;
- private final Asn1Class mClass;
- private final boolean mConstructed;
- private final int mLength;
- private final ByteBuffer mPayload;
-
- protected Asn1Object(int tag, Asn1Class asn1Class, boolean constructed, int length) {
- this(tag, asn1Class, constructed, length, null);
- }
-
- protected Asn1Object(int tag, Asn1Class asn1Class, boolean constructed, int length, ByteBuffer payload) {
- mTag = tag;
- mClass = asn1Class;
- mConstructed = constructed;
- mLength = length;
- mPayload = payload != null ? payload.duplicate() : null;
- }
-
- public int getTag() {
- return mTag;
- }
-
- public Asn1Class getAsn1Class() {
- return mClass;
- }
-
- public boolean isConstructed() {
- return mConstructed;
- }
-
- public boolean isIndefiniteLength() {
- return mLength == Asn1Decoder.IndefiniteLength;
- }
-
- public int getLength() {
- return mLength;
- }
-
- public ByteBuffer getPayload() {
- return mPayload != null ? mPayload.duplicate() : null;
- }
-
- protected ByteBuffer getPayload(int position) {
- if (mPayload == null) {
- return null;
- }
- ByteBuffer encoding = mPayload.duplicate();
- encoding.position(position);
- return encoding;
- }
-
- protected void setEndOfData(int position) {
- mPayload.limit(position);
- }
-
- protected int getEndOfData() {
- return mPayload.limit();
- }
-
- public boolean matches(Asn1ID id) {
- return mTag == id.getTag() && mClass == id.getAsn1Class();
- }
-
- public String toSimpleString() {
- Asn1Tag tag = mClass == Asn1Class.Universal ? Asn1Decoder.mapTag(mTag) : null;
- if (tag != null) {
- return tag.name();
- }
- else if (mClass == Asn1Class.Universal) {
- return String.format("[%d]", mTag);
- }
- else {
- return String.format("[%s %d]", mClass, mTag);
- }
- }
-
- public abstract Collection<Asn1Object> getChildren();
-
- @Override
- public String toString() {
- return toSimpleString();
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Octets.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Octets.java
deleted file mode 100644
index 3c130d21a..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Octets.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.util.Collection;
-
-public class Asn1Octets extends Asn1Object {
- private final byte[] mOctets;
- private final int mBitResidual;
-
- public Asn1Octets(int tag, Asn1Class asn1Class, int length, ByteBuffer data) {
- super(tag, asn1Class, false, length);
- mOctets = new byte[length];
- data.get(mOctets);
- mBitResidual = -1;
- }
-
- public Asn1Octets(int tag, Asn1Class asn1Class, int length, ByteBuffer data, int bitResidual) {
- super(tag, asn1Class, false, length);
- mOctets = new byte[length-1];
- data.get(mOctets);
- mBitResidual = bitResidual;
- }
-
- public byte[] getOctets() {
- return mOctets;
- }
-
- @Override
- public Collection<Asn1Object> getChildren() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (byte b : mOctets) {
- sb.append(String.format(" %02x", b & Asn1Decoder.ByteMask));
- }
- if (mBitResidual >= 0) {
- return super.toString() + '=' + sb + '/' + mBitResidual;
- }
- else if (getTag() == Asn1Decoder.TAG_NULL && getLength() == 0) {
- return super.toString();
- }
- else {
- return super.toString() + '=' + sb;
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Oid.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Oid.java
deleted file mode 100644
index 1973dd126..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Oid.java
+++ /dev/null
@@ -1,198 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.util.*;
-
-public class Asn1Oid extends Asn1Object {
- public static final int OidMaxOctet1 = 2;
- public static final int OidOctet1Modulus = 40;
-
- private final List<Long> mArcs;
- private final int mHashcode;
-
- private static final Map<Asn1Oid, String> sOidMap = new HashMap<>();
-
- public Asn1Oid(int tag, Asn1Class asn1Class, int length, ByteBuffer data) throws DecodeException {
- super(tag, asn1Class, false, length);
-
- if (length == 0)
- throw new DecodeException("oid-encoding length is zero", data.position());
-
- mArcs = new ArrayList<>();
-
- ByteBuffer payload = data.duplicate();
- payload.limit(payload.position() + length);
- data.position(data.position() + length);
-
- byte current = payload.get();
- long seg01 = current & Asn1Decoder.ByteMask;
- long segValue = seg01 / OidOctet1Modulus;
- int hashcode = (int) segValue;
- mArcs.add(segValue);
- segValue = seg01 - segValue * OidOctet1Modulus;
- hashcode = hashcode * 31 + (int) segValue;
- mArcs.add(segValue);
-
- current = 0;
- segValue = 0L;
-
- while (payload.hasRemaining()) {
- current = payload.get();
- segValue |= current & Asn1Decoder.MoreData;
- if ((current & Asn1Decoder.MoreBit) == 0) {
- hashcode = hashcode * 31 + (int) segValue;
- mArcs.add(segValue);
- segValue = 0L;
- } else
- segValue <<= Asn1Decoder.MoreWidth;
- }
- if ((current & Asn1Decoder.MoreBit) != 0)
- throw new DecodeException("Illegal (end of) oid-encoding", payload.position());
- mHashcode = hashcode;
- }
-
- public Asn1Oid(Long ... arcs) {
- super(Asn1Decoder.TAG_OID, Asn1Class.Universal, false, -1);
- mArcs = Arrays.asList(arcs);
- int hashcode = 0;
- for (long arc : arcs) {
- hashcode = hashcode * 31 + (int) arc;
- }
- mHashcode = hashcode;
- }
-
- @Override
- public int hashCode() {
- return mHashcode;
- }
-
- @Override
- public boolean equals(Object thatObject) {
- return !(thatObject == null || thatObject.getClass() != Asn1Oid.class) &&
- mArcs.equals(((Asn1Oid) thatObject).mArcs);
- }
-
- public String toOIDString() {
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (long arc : mArcs) {
- if (first) {
- first = false;
- }
- else {
- sb.append('.');
- }
- sb.append(arc);
- }
- return sb.toString();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(toOIDString());
- String name = sOidMap.get(this);
- if (name != null) {
- sb.append(" (").append(name).append(')');
- }
- return super.toString() + '=' + sb.toString();
- }
-
- @Override
- public Collection<Asn1Object> getChildren() {
- throw new UnsupportedOperationException();
- }
-
- public static final Asn1Oid PKCS7Data = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L, 1L);
- public static final Asn1Oid PKCS7SignedData = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L, 2L);
- public static final Asn1Oid OidMacAddress = new Asn1Oid(1L, 3L, 6L, 1L, 1L, 1L, 1L, 22L); // encoded as an IA5STRING type
- public static final Asn1Oid OidImei = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 3L); // encoded as an IA5STRING type
- public static final Asn1Oid OidMeid = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 4L); // encoded as a BITSTRING type
- public static final Asn1Oid OidDevId = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 5L); // encoded as a PRINTABLESTRING type
-
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L), "algo_id_dsa");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L), "algo_id_dsawithsha1");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L), "algo_id_ecPublicKey");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L), "eccdaWithSHA384");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L), "algo_id_rsaEncryption");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L), "algo_id_md2WithRSAEncryption");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L), "algo_id_md5WithRSAEncryption");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L), "algo_id_sha1WithRSAEncryption");
- //sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L), "algo_id_sha256WithRSAEncryption");
-
- static {
- sOidMap.put(new Asn1Oid(0L, 0L), "NullOid");
- sOidMap.put(new Asn1Oid(0L, 9L, 2342L, 19200300L, 100L, 1L, 25L), "domComp");
-
- sOidMap.put(OidMacAddress, "mac-address");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L), "algo_id_dsa");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L), "algo_id_dsawithsha1");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L), "algo_id_ecPublicKey");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L), "eccdaWithSHA384");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 10046L, 2L, 1L), "algo_id_dhpublicnumber");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L), "algo_id_rsaEncryption");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L), "algo_id_md2WithRSAEncryption");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L), "algo_id_md5WithRSAEncryption");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L), "algo_id_sha1WithRSAEncryption");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L), "algo_id_sha256WithRSAEncryption");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 7L), "pkcs7");
- sOidMap.put(PKCS7Data, "pkcs7-data");
- sOidMap.put(PKCS7SignedData, "pkcs7-signedData");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 1L), "emailAddress");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 7L), "challengePassword");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 14L), "extensionRequest");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 2L), "algo_id_RC2_CBC");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 4L), "algo_id_RC4_ENC");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 7L), "algo_id_DES_EDE3_CBC");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 9L), "algo_id_RC5_CBC_PAD");
- sOidMap.put(new Asn1Oid(1L, 2L, 840L, 113549L, 3L, 10L), "algo_id_desCDMF");
- sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 2L), "id-kp-HS2.0Auth");
- sOidMap.put(OidImei, "imei");
- sOidMap.put(OidMeid, "meid");
- sOidMap.put(OidDevId, "DevId");
- sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L), "certAuthorityInfoAccessSyntax");
- sOidMap.put(new Asn1Oid(1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L), "certSubjectInfoAccessSyntax");
- sOidMap.put(new Asn1Oid(1L, 3L, 14L, 3L, 2L, 26L), "algo_id_SHA1");
- sOidMap.put(new Asn1Oid(1L, 3L, 132L, 0L, 34L), "secp384r1");
-
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 3L), "x500_CN");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 4L), "x500_SN");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 5L), "x500_serialNum");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 6L), "x500_C");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 7L), "x500_L");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 8L), "x500_ST");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 9L), "x500_STREET");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 10L), "x500_O");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 11L), "x500_OU");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 12L), "x500_title");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 13L), "x500_description");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 17L), "x500_postalCode");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 18L), "x500_poBox");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 20L), "x500_phone");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 41L), "x500_name");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 42L), "x500_givenName");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 44L), "x500_genQual");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 43L), "x500_initials");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 46L), "x500_dnQualifier");
- sOidMap.put(new Asn1Oid(2L, 5L, 4L, 65L), "x500_pseudonym");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 9L), "certSubjectDirectoryAttributes");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 14L), "certSubjectKeyIdentifier ");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 15L), "certKeyUsage");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 16L), "certPrivateKeyUsagePeriod");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 17L), "certSubjectAltName");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 18L), "certIssuerAltName");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 19L), "certBasicConstraints");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 30L), "certNameConstraints");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 31L), "certCRLDistributionPoints");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 32L), "certificatePolicies");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 33L), "certPolicyMappings");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 35L), "certAuthorityKeyIdentifier ");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 36L), "certPolicyConstraints");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 37L), "certExtKeyUsageSyntax");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 46L), "certFreshestCRL");
- sOidMap.put(new Asn1Oid(2L, 5L, 29L, 54L), "certInhibitAnyPolicy");
- sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 2L), "algo_id_aes128");
- sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 22L), "algo_id_aes192");
- sOidMap.put(new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 42L), "algo_id_aes256");
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1String.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1String.java
deleted file mode 100644
index 7b8e4cdf1..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1String.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.Collection;
-
-public class Asn1String extends Asn1Object {
- private final String mString;
-
- public Asn1String(int tag, Asn1Class asn1Class, int length, ByteBuffer data) {
- super(tag, asn1Class, false, length);
-
- byte[] octets = new byte[length];
- data.get(octets);
- Charset charset = tag == Asn1Decoder.TAG_UTF8String ? StandardCharsets.UTF_8 : StandardCharsets.ISO_8859_1;
- mString = new String(octets, charset);
- }
-
- public String getString() {
- return mString;
- }
-
- @Override
- public Collection<Asn1Object> getChildren() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String toString() {
- return super.toString() + "='" + mString + '\'';
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Tag.java b/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Tag.java
deleted file mode 100644
index cc9960302..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/Asn1Tag.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-public enum Asn1Tag {
- UNIVZERO,
- BOOLEAN,
- INTEGER,
- BITSTRING,
- OCTET_STRING,
- NULL,
- OID,
- ObjectDescriptor,
- EXTERNAL,
- REAL,
- ENUMERATED,
- UTF8String,
- RelativeOID,
- SEQUENCE,
- SET,
- NumericString,
- PrintableString,
- T61String,
- VideotexString,
- IA5String,
- UTCTime,
- GeneralizedTime,
- GraphicString,
- VisibleString,
- GeneralString,
- UniversalString,
- BMPString
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/DecodeException.java b/service/java/com/android/server/wifi/hotspot2/asn1/DecodeException.java
deleted file mode 100644
index e2d06294f..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/DecodeException.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.io.IOException;
-
-public class DecodeException extends IOException {
- private final int mOffset;
-
- public DecodeException(String message, int offset) {
- super(message);
- mOffset = offset;
- }
-
- @Override
- public String toString() {
- return super.toString() + " at " + mOffset;
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/asn1/OidMappings.java b/service/java/com/android/server/wifi/hotspot2/asn1/OidMappings.java
deleted file mode 100644
index 9d369ce79..000000000
--- a/service/java/com/android/server/wifi/hotspot2/asn1/OidMappings.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package com.android.server.wifi.hotspot2.asn1;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-public class OidMappings {
- public static class SigEntry {
- private final String mSigAlgo;
- private final Asn1Oid mKeyAlgo;
-
- private SigEntry(String sigAlgo, Asn1Oid keyAlgo) {
- mSigAlgo = sigAlgo;
- mKeyAlgo = keyAlgo;
- }
-
- public String getSigAlgo() {
- return mSigAlgo;
- }
-
- public Asn1Oid getKeyAlgo() {
- return mKeyAlgo;
- }
- }
-
- public static final String IdPeLogotype = "1.3.6.1.5.5.7.1.12";
- public static final String IdCeSubjectAltName = "2.5.29.17";
-
- private static final Map<Asn1Oid, String> sCryptoMapping = new HashMap<>();
- private static final Map<Asn1Oid, String> sNameMapping = new HashMap<>();
- private static final Set<Asn1Oid> sIDMapping = new HashSet<>();
- private static final Map<Asn1Oid, SigEntry> sSigAlgos = new HashMap<>();
-
- // DSA
- private static final Asn1Oid sAlgo_DSA = new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 1L);
- private static final Asn1Oid sAlgo_SHA1withDSA = new Asn1Oid(1L, 2L, 840L, 10040L, 4L, 3L);
-
- // RSA
- public static final Asn1Oid sAlgo_RSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 1L);
- private static final Asn1Oid sAlgo_MD2withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 2L);
- private static final Asn1Oid sAlgo_MD5withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 4L);
- private static final Asn1Oid sAlgo_SHA1withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 5L);
- private static final Asn1Oid sAlgo_SHA224withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 14L); // n/a
- private static final Asn1Oid sAlgo_SHA256withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 11L);
- private static final Asn1Oid sAlgo_SHA384withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 12L);
- private static final Asn1Oid sAlgo_SHA512withRSA = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 1L, 13L);
-
- // ECC
- public static final Asn1Oid sAlgo_EC = new Asn1Oid(1L, 2L, 840L, 10045L, 2L, 1L);
- private static final Asn1Oid sAlgo_SHA1withECDSA = new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 1L);
- private static final Asn1Oid sAlgo_SHA224withECDSA = new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 1L); // n/a
- private static final Asn1Oid sAlgo_SHA256withECDSA = new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 2L);
- private static final Asn1Oid sAlgo_SHA384withECDSA = new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 3L);
- private static final Asn1Oid sAlgo_SHA512withECDSA = new Asn1Oid(1L, 2L, 840L, 10045L, 4L, 3L, 4L);
-
- private static final Asn1Oid sAlgo_MD2 = new Asn1Oid(1L, 2L, 840L, 113549L, 2L, 2L);
- private static final Asn1Oid sAlgo_MD5 = new Asn1Oid(1L, 2L, 840L, 113549L, 2L, 5L);
- private static final Asn1Oid sAlgo_SHA1 = new Asn1Oid(1L, 3L, 14L, 3L, 2L, 26L);
- private static final Asn1Oid sAlgo_SHA256 = new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 1L);
- private static final Asn1Oid sAlgo_SHA384 = new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 2L);
- private static final Asn1Oid sAlgo_SHA512 = new Asn1Oid(2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 3L);
-
- // HS2.0 stuff:
- public static final Asn1Oid sPkcs9AtChallengePassword = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 7L);
- public static final Asn1Oid sExtensionRequest = new Asn1Oid(1L, 2L, 840L, 113549L, 1L, 9L, 14L);
-
- public static final Asn1Oid sMAC = new Asn1Oid(1L, 3L, 6L, 1L, 1L, 1L, 1L, 22L);
- public static final Asn1Oid sIMEI = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 3L);
- public static final Asn1Oid sMEID = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 4L);
- public static final Asn1Oid sDevID = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 5L);
-
- public static final Asn1Oid sIdWfaHotspotFriendlyName = new Asn1Oid(1L, 3L, 6L, 1L, 4L, 1L, 40808L, 1L, 1L, 1L);
-
- static {
- sCryptoMapping.put(sAlgo_DSA, "DSA");
- sCryptoMapping.put(sAlgo_RSA, "RSA");
- sCryptoMapping.put(sAlgo_EC, "EC");
-
- sSigAlgos.put(sAlgo_SHA1withDSA, new SigEntry("SHA1withDSA", sAlgo_DSA));
-
- sSigAlgos.put(sAlgo_MD2withRSA, new SigEntry("MD2withRSA", sAlgo_RSA));
- sSigAlgos.put(sAlgo_MD5withRSA, new SigEntry("MD5withRSA", sAlgo_RSA));
- sSigAlgos.put(sAlgo_SHA1withRSA, new SigEntry("SHA1withRSA", sAlgo_RSA));
- sSigAlgos.put(sAlgo_SHA224withRSA, new SigEntry(null, sAlgo_RSA));
- sSigAlgos.put(sAlgo_SHA256withRSA, new SigEntry("SHA256withRSA", sAlgo_RSA));
- sSigAlgos.put(sAlgo_SHA384withRSA, new SigEntry("SHA384withRSA", sAlgo_RSA));
- sSigAlgos.put(sAlgo_SHA512withRSA, new SigEntry("SHA512withRSA", sAlgo_RSA));
-
- sSigAlgos.put(sAlgo_SHA1withECDSA, new SigEntry("SHA1withECDSA", sAlgo_EC));
- sSigAlgos.put(sAlgo_SHA224withECDSA, new SigEntry(null, sAlgo_EC));
- sSigAlgos.put(sAlgo_SHA256withECDSA, new SigEntry("SHA256withECDSA", sAlgo_EC));
- sSigAlgos.put(sAlgo_SHA384withECDSA, new SigEntry("SHA384withECDSA", sAlgo_EC));
- sSigAlgos.put(sAlgo_SHA512withECDSA, new SigEntry("SHA512withECDSA", sAlgo_EC));
-
- sIDMapping.add(sMAC);
- sIDMapping.add(sIMEI);
- sIDMapping.add(sMEID);
- sIDMapping.add(sDevID);
-
- for (Map.Entry<Asn1Oid, String> entry : sCryptoMapping.entrySet()) {
- sNameMapping.put(entry.getKey(), entry.getValue());
- }
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 1L), "sect163k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 2L), "sect163r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 3L), "sect239k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 4L), "sect113r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 5L), "sect113r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 6L), "secp112r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 7L), "secp112r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 8L), "secp160r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 9L), "secp160k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 10L), "secp256k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 15L), "sect163r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 16L), "sect283k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 17L), "sect283r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 22L), "sect131r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 23L), "sect131r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 24L), "sect193r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 25L), "sect193r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 26L), "sect233k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 27L), "sect233r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 28L), "secp128r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 29L), "secp128r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 30L), "secp160r2");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 31L), "secp192k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 32L), "secp224k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 33L), "secp224r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 34L), "secp384r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 35L), "secp521r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 36L), "sect409k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 37L), "sect409r1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 38L), "sect571k1");
- sNameMapping.put(new Asn1Oid(1L, 3L, 132L, 0L, 39L), "sect571r1");
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 1L), "secp192r1");
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 7L), "secp256r1");
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 2L), "prime192v2"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 3L), "prime192v3"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 4L), "prime239v1"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 5L), "prime239v2"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 1L, 6L), "prime239v3"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 5L), "c2tnb191v1"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 6L), "c2tnb191v2"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 7L), "c2tnb191v3"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 11L), "c2tnb239v1"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 12L), "c2tnb239v2"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 13L), "c2tnb239v3"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 18L), "c2tnb359v1"); // X9.62
- sNameMapping.put(new Asn1Oid(1L, 2L, 840L, 10045L, 3L, 0L, 20L), "c2tnb431r1"); // X9.62
-
- sNameMapping.put(sAlgo_MD2, "MD2");
- sNameMapping.put(sAlgo_MD5, "MD5");
- sNameMapping.put(sAlgo_SHA1, "SHA-1");
- sNameMapping.put(sAlgo_SHA256, "SHA-256");
- sNameMapping.put(sAlgo_SHA384, "SHA-384");
- sNameMapping.put(sAlgo_SHA512, "SHA-512");
- }
-
- public static SigEntry getSigEntry(Asn1Oid oid) {
- return sSigAlgos.get(oid);
- }
-
- public static String getCryptoID(Asn1Oid oid) {
- return sCryptoMapping.get(oid);
- }
-
- public static String getJCEName(Asn1Oid oid) {
- return sNameMapping.get(oid);
- }
-
- public static String getSigAlgoName(Asn1Oid oid) {
- SigEntry sigEntry = sSigAlgos.get(oid);
- return sigEntry != null ? sigEntry.getSigAlgo() : null;
- }
-
- public static String getKeyAlgoName(Asn1Oid oid) {
- SigEntry sigEntry = sSigAlgos.get(oid);
- return sigEntry != null ? sNameMapping.get(sigEntry.getKeyAlgo()) : null;
- }
-
- public static boolean isIDAttribute(Asn1Oid oid) {
- return sIDMapping.contains(oid);
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/est/ESTHandler.java b/service/java/com/android/server/wifi/hotspot2/est/ESTHandler.java
deleted file mode 100644
index 58d015ef9..000000000
--- a/service/java/com/android/server/wifi/hotspot2/est/ESTHandler.java
+++ /dev/null
@@ -1,508 +0,0 @@
-package com.android.server.wifi.hotspot2.est;
-
-import android.net.Network;
-import android.util.Base64;
-import android.util.Log;
-
-import com.android.org.bouncycastle.asn1.ASN1Encodable;
-import com.android.org.bouncycastle.asn1.ASN1EncodableVector;
-import com.android.org.bouncycastle.asn1.ASN1Set;
-import com.android.org.bouncycastle.asn1.DERBitString;
-import com.android.org.bouncycastle.asn1.DEREncodableVector;
-import com.android.org.bouncycastle.asn1.DERIA5String;
-import com.android.org.bouncycastle.asn1.DERObjectIdentifier;
-import com.android.org.bouncycastle.asn1.DERPrintableString;
-import com.android.org.bouncycastle.asn1.DERSet;
-import com.android.org.bouncycastle.asn1.x509.Attribute;
-import com.android.org.bouncycastle.jce.PKCS10CertificationRequest;
-import com.android.server.wifi.hotspot2.OMADMAdapter;
-import com.android.server.wifi.hotspot2.asn1.Asn1Class;
-import com.android.server.wifi.hotspot2.asn1.Asn1Constructed;
-import com.android.server.wifi.hotspot2.asn1.Asn1Decoder;
-import com.android.server.wifi.hotspot2.asn1.Asn1ID;
-import com.android.server.wifi.hotspot2.asn1.Asn1Integer;
-import com.android.server.wifi.hotspot2.asn1.Asn1Object;
-import com.android.server.wifi.hotspot2.asn1.Asn1Oid;
-import com.android.server.wifi.hotspot2.asn1.OidMappings;
-import com.android.server.wifi.hotspot2.osu.HTTPHandler;
-import com.android.server.wifi.hotspot2.osu.OSUSocketFactory;
-import com.android.server.wifi.hotspot2.osu.commands.GetCertData;
-import com.android.server.wifi.hotspot2.utils.HTTPMessage;
-import com.android.server.wifi.hotspot2.utils.HTTPResponse;
-
-import com.android.org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.AlgorithmParameters;
-import java.security.GeneralSecurityException;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.net.ssl.KeyManager;
-import javax.security.auth.x500.X500Principal;
-
-//import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
-
-public class ESTHandler implements AutoCloseable {
- private static final String TAG = "HS2EST";
- private static final int MinRSAKeySize = 2048;
-
- private static final String CACERT_PATH = "/cacerts";
- private static final String CSR_PATH = "/csrattrs";
- private static final String SIMPLE_ENROLL_PATH = "/simpleenroll";
- private static final String SIMPLE_REENROLL_PATH = "/simplereenroll";
-
- private final URL mURL;
- private final String mUser;
- private final byte[] mPassword;
- private final OSUSocketFactory mSocketFactory;
- private final OMADMAdapter mOMADMAdapter;
-
- private final List<X509Certificate> mCACerts = new ArrayList<>();
- private final List<X509Certificate> mClientCerts = new ArrayList<>();
- private PrivateKey mClientKey;
-
- public ESTHandler(GetCertData certData, Network network, OMADMAdapter omadmAdapter,
- KeyManager km) throws IOException, GeneralSecurityException {
- mURL = new URL(certData.getServer());
- mUser = certData.getUserName();
- mPassword = certData.getPassword();
- mSocketFactory = OSUSocketFactory.getSocketFactory(network, mURL, km, true);
- mOMADMAdapter = omadmAdapter;
- }
-
- @Override
- public void close() throws IOException {
- }
-
- public List<X509Certificate> getCACerts() {
- return mCACerts;
- }
-
- public List<X509Certificate> getClientCerts() {
- return mClientCerts;
- }
-
- public PrivateKey getClientKey() {
- return mClientKey;
- }
-
- private static String indent(int amount) {
- char[] indent = new char[amount*2];
- Arrays.fill(indent, ' ');
- return new String(indent);
- }
-
- public void execute(boolean reenroll) throws IOException, GeneralSecurityException {
- URL caURL = new URL(mURL.getProtocol(), mURL.getHost(), mURL.getPort(),
- mURL.getFile() + CACERT_PATH);
-
- HTTPResponse response;
- try (HTTPHandler httpHandler = new HTTPHandler(StandardCharsets.ISO_8859_1, mSocketFactory,
- mUser, mPassword)) {
- response = httpHandler.doGetHTTP(caURL);
-
- if (!"application/pkcs7-mime".equals(response.getHeaders().
- get(HTTPMessage.ContentTypeHeader))) {
- throw new IOException("Unexpected Content-Type: " +
- response.getHeaders().get(HTTPMessage.ContentTypeHeader));
- }
- ByteBuffer octetBuffer = response.getBinaryPayload();
- Collection<Asn1Object> pkcs7Content1 = Asn1Decoder.decode(octetBuffer);
- for (Asn1Object asn1Object : pkcs7Content1) {
- Log.d(TAG, "---");
- Log.d(TAG, asn1Object.toString());
- }
- Log.d(TAG, CACERT_PATH);
-
- mCACerts.addAll(unpackPkcs7(octetBuffer));
- for (X509Certificate certificate : mCACerts) {
- Log.d(TAG, "CA-Cert: " + certificate.getSubjectX500Principal());
- }
-
- /*
- byte[] octets = new byte[octetBuffer.remaining()];
- octetBuffer.duplicate().get(octets);
- for (byte b : octets) {
- System.out.printf("%02x ", b & 0xff);
- }
- Log.d(TAG, );
- */
-
- /* + BC
- try {
- byte[] octets = new byte[octetBuffer.remaining()];
- octetBuffer.duplicate().get(octets);
- ASN1InputStream asnin = new ASN1InputStream(octets);
- for (int n = 0; n < 100; n++) {
- ASN1Primitive object = asnin.readObject();
- if (object == null) {
- break;
- }
- parseObject(object, 0);
- }
- }
- catch (Throwable t) {
- t.printStackTrace();
- }
-
- Collection<Asn1Object> pkcs7Content = Asn1Decoder.decode(octetBuffer);
- for (Asn1Object asn1Object : pkcs7Content) {
- Log.d(TAG, asn1Object);
- }
-
- if (pkcs7Content.size() != 1) {
- throw new IOException("Unexpected pkcs 7 container: " + pkcs7Content.size());
- }
-
- Asn1Constructed pkcs7Root = (Asn1Constructed) pkcs7Content.iterator().next();
- Iterator<Asn1ID> certPath = Arrays.asList(Pkcs7CertPath).iterator();
- Asn1Object certObject = pkcs7Root.findObject(certPath);
- if (certObject == null || certPath.hasNext()) {
- throw new IOException("Failed to find cert; returned object " + certObject +
- ", path " + (certPath.hasNext() ? "short" : "exhausted"));
- }
-
- ByteBuffer certOctets = certObject.getPayload();
- if (certOctets == null) {
- throw new IOException("No cert payload in: " + certObject);
- }
-
- byte[] certBytes = new byte[certOctets.remaining()];
- certOctets.get(certBytes);
-
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- Certificate cert = certFactory.generateCertificate(new ByteArrayInputStream(certBytes));
- Log.d(TAG, "EST Cert: " + cert);
- */
-
- URL csrURL = new URL(mURL.getProtocol(), mURL.getHost(), mURL.getPort(),
- mURL.getFile() + CSR_PATH);
- response = httpHandler.doGetHTTP(csrURL);
-
- octetBuffer = response.getBinaryPayload();
- byte[] csrData = buildCSR(octetBuffer, mOMADMAdapter, httpHandler);
-
- /**/
- Collection<Asn1Object> o = Asn1Decoder.decode(ByteBuffer.wrap(csrData));
- Log.d(TAG, "CSR:");
- Log.d(TAG, o.iterator().next().toString());
- Log.d(TAG, "End CSR.");
- /**/
-
- URL enrollURL = new URL(mURL.getProtocol(), mURL.getHost(), mURL.getPort(),
- mURL.getFile() + (reenroll ? SIMPLE_REENROLL_PATH : SIMPLE_ENROLL_PATH));
- String data = Base64.encodeToString(csrData, Base64.DEFAULT);
- octetBuffer = httpHandler.exchangeBinary(enrollURL, data, "application/pkcs10");
-
- Collection<Asn1Object> pkcs7Content2 = Asn1Decoder.decode(octetBuffer);
- for (Asn1Object asn1Object : pkcs7Content2) {
- Log.d(TAG, "---");
- Log.d(TAG, asn1Object.toString());
- }
- mClientCerts.addAll(unpackPkcs7(octetBuffer));
- for (X509Certificate cert : mClientCerts) {
- Log.d(TAG, cert.toString());
- }
- }
- }
-
- private static final Asn1ID sSEQUENCE = new Asn1ID(Asn1Decoder.TAG_SEQ, Asn1Class.Universal);
- private static final Asn1ID sCTXT0 = new Asn1ID(0, Asn1Class.Context);
- private static final int PKCS7DataVersion = 1;
- private static final int PKCS7SignedDataVersion = 3;
-
- private static List<X509Certificate> unpackPkcs7(ByteBuffer pkcs7)
- throws IOException, GeneralSecurityException {
- Collection<Asn1Object> pkcs7Content = Asn1Decoder.decode(pkcs7);
-
- if (pkcs7Content.size() != 1) {
- throw new IOException("Unexpected pkcs 7 container: " + pkcs7Content.size());
- }
-
- Asn1Object data = pkcs7Content.iterator().next();
- if (!data.isConstructed() || !data.matches(sSEQUENCE)) {
- throw new IOException("Expected SEQ OF, got " + data.toSimpleString());
- }
- else if (data.getChildren().size() != 2) {
- throw new IOException("Expected content info to have two children, got " +
- data.getChildren().size());
- }
-
- Iterator<Asn1Object> children = data.getChildren().iterator();
- Asn1Object contentType = children.next();
- if (!contentType.equals(Asn1Oid.PKCS7SignedData)) {
- throw new IOException("Content not PKCS7 signed data");
- }
- Asn1Object content = children.next();
- if (!content.isConstructed() || !content.matches(sCTXT0)) {
- throw new IOException("Expected [CONTEXT 0] with one child, got " +
- content.toSimpleString() + ", " + content.getChildren().size());
- }
-
- Asn1Object signedData = content.getChildren().iterator().next();
- Map<Integer, Asn1Object> itemMap = new HashMap<>();
- for (Asn1Object item : signedData.getChildren()) {
- if (itemMap.put(item.getTag(), item) != null && item.getTag() != Asn1Decoder.TAG_SET) {
- throw new IOException("Duplicate item in SignedData: " + item.toSimpleString());
- }
- }
-
- Asn1Object versionObject = itemMap.get(Asn1Decoder.TAG_INTEGER);
- if (versionObject == null || !(versionObject instanceof Asn1Integer)) {
- throw new IOException("Bad or missing PKCS7 version: " + versionObject);
- }
- int pkcs7version = (int)((Asn1Integer) versionObject).getValue();
- Asn1Object innerContentInfo = itemMap.get(Asn1Decoder.TAG_SEQ);
- if (innerContentInfo == null ||
- !innerContentInfo.isConstructed() ||
- !innerContentInfo.matches(sSEQUENCE) ||
- innerContentInfo.getChildren().size() != 1) {
- throw new IOException("Bad or missing PKCS7 contentInfo");
- }
- Asn1Object contentID = innerContentInfo.getChildren().iterator().next();
- if (pkcs7version == PKCS7DataVersion && !contentID.equals(Asn1Oid.PKCS7Data) ||
- pkcs7version == PKCS7SignedDataVersion && !contentID.equals(Asn1Oid.PKCS7SignedData)) {
- throw new IOException("Inner PKCS7 content (" + contentID +
- ") not expected for version " + pkcs7version);
- }
- Asn1Object certWrapper = itemMap.get(0);
- if (certWrapper == null || !certWrapper.isConstructed() || !certWrapper.matches(sCTXT0)) {
- throw new IOException("Expected [CONTEXT 0], got: " + certWrapper);
- }
-
- List<X509Certificate> certList = new ArrayList<>(certWrapper.getChildren().size());
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- for (Asn1Object certObject : certWrapper.getChildren()) {
- ByteBuffer certOctets = ((Asn1Constructed) certObject).getEncoding();
- if (certOctets == null) {
- throw new IOException("No cert payload in: " + certObject);
- }
- byte[] certBytes = new byte[certOctets.remaining()];
- certOctets.get(certBytes);
-
- certList.add((X509Certificate) certFactory.
- generateCertificate(new ByteArrayInputStream(certBytes)));
- }
- return certList;
- }
-
- private byte[] buildCSR(ByteBuffer octetBuffer, OMADMAdapter omadmAdapter,
- HTTPHandler httpHandler) throws IOException, GeneralSecurityException {
-
- //Security.addProvider(new BouncyCastleProvider());
-
- Log.d(TAG, "/csrattrs:");
- /*
- byte[] octets = new byte[octetBuffer.remaining()];
- octetBuffer.duplicate().get(octets);
- for (byte b : octets) {
- System.out.printf("%02x ", b & 0xff);
- }
- */
- Collection<Asn1Object> csrs = Asn1Decoder.decode(octetBuffer);
- for (Asn1Object asn1Object : csrs) {
- Log.d(TAG, asn1Object.toString());
- }
-
- if (csrs.size() != 1) {
- throw new IOException("Unexpected object count in CSR attributes response: " +
- csrs.size());
- }
- Asn1Object sequence = csrs.iterator().next();
- if (sequence.getClass() != Asn1Constructed.class) {
- throw new IOException("Unexpected CSR attribute container: " + sequence);
- }
-
- String keyAlgo = null;
- Asn1Oid keyAlgoOID = null;
- String sigAlgo = null;
- String curveName = null;
- Asn1Oid pubCrypto = null;
- int keySize = -1;
- Map<Asn1Oid, ASN1Encodable> idAttributes = new HashMap<>();
-
- for (Asn1Object child : sequence.getChildren()) {
- if (child.getTag() == Asn1Decoder.TAG_OID) {
- Asn1Oid oid = (Asn1Oid) child;
- OidMappings.SigEntry sigEntry = OidMappings.getSigEntry(oid);
- if (sigEntry != null) {
- sigAlgo = sigEntry.getSigAlgo();
- keyAlgoOID = sigEntry.getKeyAlgo();
- keyAlgo = OidMappings.getJCEName(keyAlgoOID);
- }
- else if (oid.equals(OidMappings.sPkcs9AtChallengePassword)) {
- byte[] tlsUnique = httpHandler.getTLSUnique();
- if (tlsUnique != null) {
- idAttributes.put(oid, new DERPrintableString(
- Base64.encodeToString(tlsUnique, Base64.DEFAULT)));
- }
- else {
- Log.w(TAG, "Cannot retrieve TLS unique channel binding");
- }
- }
- }
- else if (child.getTag() == Asn1Decoder.TAG_SEQ) {
- Asn1Oid oid = null;
- Set<Asn1Oid> oidValues = new HashSet<>();
- List<Asn1Object> values = new ArrayList<>();
-
- for (Asn1Object attributeSeq : child.getChildren()) {
- if (attributeSeq.getTag() == Asn1Decoder.TAG_OID) {
- oid = (Asn1Oid) attributeSeq;
- }
- else if (attributeSeq.getTag() == Asn1Decoder.TAG_SET) {
- for (Asn1Object value : attributeSeq.getChildren()) {
- if (value.getTag() == Asn1Decoder.TAG_OID) {
- oidValues.add((Asn1Oid) value);
- }
- else {
- values.add(value);
- }
- }
- }
- }
- if (oid == null) {
- throw new IOException("Invalid attribute, no OID");
- }
- if (oid.equals(OidMappings.sExtensionRequest)) {
- for (Asn1Oid subOid : oidValues) {
- if (OidMappings.isIDAttribute(subOid)) {
- if (subOid.equals(OidMappings.sMAC)) {
- idAttributes.put(subOid, new DERIA5String(omadmAdapter.getMAC()));
- }
- else if (subOid.equals(OidMappings.sIMEI)) {
- idAttributes.put(subOid, new DERIA5String(omadmAdapter.getImei()));
- }
- else if (subOid.equals(OidMappings.sMEID)) {
- idAttributes.put(subOid, new DERBitString(omadmAdapter.getMeid()));
- }
- else if (subOid.equals(OidMappings.sDevID)) {
- idAttributes.put(subOid,
- new DERPrintableString(omadmAdapter.getDevID()));
- }
- }
- }
- }
- else if (OidMappings.getCryptoID(oid) != null) {
- pubCrypto = oid;
- if (!values.isEmpty()) {
- for (Asn1Object value : values) {
- if (value.getTag() == Asn1Decoder.TAG_INTEGER) {
- keySize = (int)((Asn1Integer) value).getValue();
- }
- }
- }
- if (oid.equals(OidMappings.sAlgo_EC)) {
- if (oidValues.isEmpty()) {
- throw new IOException("No ECC curve name provided");
- }
- for (Asn1Oid value : oidValues) {
- curveName = OidMappings.getJCEName(value);
- if (curveName != null) {
- break;
- }
- }
- if (curveName == null) {
- throw new IOException("Found no ECC curve for " + oidValues);
- }
- }
- }
- }
- }
-
- if (keyAlgoOID == null) {
- throw new IOException("No public key algorithm specified");
- }
- if (pubCrypto != null && !pubCrypto.equals(keyAlgoOID)) {
- throw new IOException("Mismatching key algorithms");
- }
-
- if (keyAlgoOID.equals(OidMappings.sAlgo_RSA)) {
- if (keySize < MinRSAKeySize) {
- if (keySize >= 0) {
- Log.i(TAG, "Upgrading suggested RSA key size from " +
- keySize + " to " + MinRSAKeySize);
- }
- keySize = MinRSAKeySize;
- }
- }
-
- Log.d(TAG, String.format("pub key '%s', signature '%s', ECC curve '%s', id-atts %s",
- keyAlgo, sigAlgo, curveName, idAttributes));
-
- /*
- Ruckus:
- SEQUENCE:
- OID=1.2.840.113549.1.1.11 (algo_id_sha256WithRSAEncryption)
-
- RFC-7030:
- SEQUENCE:
- OID=1.2.840.113549.1.9.7 (challengePassword)
- SEQUENCE:
- OID=1.2.840.10045.2.1 (algo_id_ecPublicKey)
- SET:
- OID=1.3.132.0.34 (secp384r1)
- SEQUENCE:
- OID=1.2.840.113549.1.9.14 (extensionRequest)
- SET:
- OID=1.3.6.1.1.1.1.22 (mac-address)
- OID=1.2.840.10045.4.3.3 (eccdaWithSHA384)
-
- 1L, 3L, 6L, 1L, 1L, 1L, 1L, 22
- */
-
- // ECC Does not appear to be supported currently
- KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyAlgo);
- if (curveName != null) {
- AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance(keyAlgo);
- algorithmParameters.init(new ECNamedCurveGenParameterSpec(curveName));
- kpg.initialize(algorithmParameters.getParameterSpec(ECNamedCurveGenParameterSpec.class));
- }
- else {
- kpg.initialize(keySize);
- }
- KeyPair kp = kpg.generateKeyPair();
-
- X500Principal subject = new X500Principal("CN=Android, O=Google, C=US");
-
- mClientKey = kp.getPrivate();
-
- // !!! Map the idAttributes into an ASN1Set of values to pass to
- // the PKCS10CertificationRequest - this code is using outdated BC classes and
- // has *not* been tested.
- ASN1Set attributes;
- if (!idAttributes.isEmpty()) {
- ASN1EncodableVector payload = new DEREncodableVector();
- for (Map.Entry<Asn1Oid, ASN1Encodable> entry : idAttributes.entrySet()) {
- DERObjectIdentifier type = new DERObjectIdentifier(entry.getKey().toOIDString());
- ASN1Set values = new DERSet(entry.getValue());
- Attribute attribute = new Attribute(type, values);
- payload.add(attribute);
- }
- attributes = new DERSet(payload);
- }
- else {
- attributes = null;
- }
-
- return new PKCS10CertificationRequest(sigAlgo, subject, kp.getPublic(),
- attributes, mClientKey).getEncoded();
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstants.java b/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstants.java
index 6f2f62b75..6d00edd97 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstants.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/OMAConstants.java
@@ -1,17 +1,10 @@
package com.android.server.wifi.hotspot2.omadm;
-import com.android.server.wifi.hotspot2.osu.OSUError;
-import com.android.server.wifi.hotspot2.osu.OSUStatus;
-
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Map;
public class OMAConstants {
private OMAConstants() {
@@ -45,65 +38,6 @@ public class OMAConstants {
private static final byte[] INDENT = new byte[1024];
- private static final Map<OSUStatus, String> sStatusStrings = new EnumMap<>(OSUStatus.class);
- private static final Map<String, OSUStatus> sStatusEnums = new HashMap<>();
- private static final Map<OSUError, String> sErrorStrings = new EnumMap<>(OSUError.class);
- private static final Map<String, OSUError> sErrorEnums = new HashMap<>();
-
- static {
- sStatusStrings.put(OSUStatus.OK, "OK");
- sStatusStrings.put(OSUStatus.ProvComplete, "Provisioning complete, request sppUpdateResponse");
- sStatusStrings.put(OSUStatus.RemediationComplete, "Remediation complete, request sppUpdateResponse");
- sStatusStrings.put(OSUStatus.UpdateComplete, "Update complete, request sppUpdateResponse");
- sStatusStrings.put(OSUStatus.ExchangeComplete, "Exchange complete, release TLS connection");
- sStatusStrings.put(OSUStatus.Unknown, "No update available at this time");
- sStatusStrings.put(OSUStatus.Error, "Error occurred");
-
- for (Map.Entry<OSUStatus, String> entry : sStatusStrings.entrySet()) {
- sStatusEnums.put(entry.getValue().toLowerCase(), entry.getKey());
- }
-
- sErrorStrings.put(OSUError.SPPversionNotSupported, "SPP version not supported");
- sErrorStrings.put(OSUError.MOsNotSupported, "One or more mandatory MOs not supported");
- sErrorStrings.put(OSUError.CredentialsFailure, "Credentials cannot be provisioned at this time");
- sErrorStrings.put(OSUError.RemediationFailure, "Remediation cannot be completed at this time");
- sErrorStrings.put(OSUError.ProvisioningFailed, "Provisioning cannot be completed at this time");
- sErrorStrings.put(OSUError.ExistingCertificate, "Continue to use existing certificate");
- sErrorStrings.put(OSUError.CookieInvalid, "Cookie invalid");
- sErrorStrings.put(OSUError.WebSessionID, "No corresponding web-browser-connection Session ID");
- sErrorStrings.put(OSUError.PermissionDenied, "Permission denied");
- sErrorStrings.put(OSUError.CommandFailed, "Command failed");
- sErrorStrings.put(OSUError.MOaddOrUpdateFailed, "MO addition or update failed");
- sErrorStrings.put(OSUError.DeviceFull, "Device full");
- sErrorStrings.put(OSUError.BadTreeURI, "Bad management tree URI");
- sErrorStrings.put(OSUError.TooLarge, "Requested entity too large");
- sErrorStrings.put(OSUError.CommandNotAllowed, "Command not allowed");
- sErrorStrings.put(OSUError.UserAborted, "Command not executed due to user");
- sErrorStrings.put(OSUError.NotFound, "Not found");
- sErrorStrings.put(OSUError.Other, "Other");
-
- for (Map.Entry<OSUError, String> entry : sErrorStrings.entrySet()) {
- sErrorEnums.put(entry.getValue().toLowerCase(), entry.getKey());
- }
- Arrays.fill(INDENT, (byte) ' ');
- }
-
- public static String mapStatus(OSUStatus status) {
- return sStatusStrings.get(status);
- }
-
- public static OSUStatus mapStatus(String status) {
- return sStatusEnums.get(status.toLowerCase());
- }
-
- public static String mapError(OSUError error) {
- return sErrorStrings.get(error);
- }
-
- public static OSUError mapError(String error) {
- return sErrorEnums.get(error.toLowerCase());
- }
-
public static void serializeString(String s, OutputStream out) throws IOException {
byte[] octets = s.getBytes(StandardCharsets.UTF_8);
byte[] prefix = String.format("%x:", octets.length).getBytes(StandardCharsets.UTF_8);
diff --git a/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java b/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java
index 6f528e2ae..f26e83cbf 100644
--- a/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java
+++ b/service/java/com/android/server/wifi/hotspot2/omadm/PasspointManagementObjectManager.java
@@ -11,7 +11,6 @@ import com.android.server.wifi.anqp.eap.ExpandedEAPMethod;
import com.android.server.wifi.anqp.eap.InnerAuthEAP;
import com.android.server.wifi.anqp.eap.NonEAPInnerAuth;
import com.android.server.wifi.hotspot2.Utils;
-import com.android.server.wifi.hotspot2.osu.commands.PasspointManagementObjectData;
import com.android.server.wifi.hotspot2.pps.Credential;
import com.android.server.wifi.hotspot2.pps.HomeSP;
import com.android.server.wifi.hotspot2.pps.Policy;
@@ -224,15 +223,6 @@ public class PasspointManagementObjectManager {
return addSP(omaParser.parse(xml, OMAConstants.PPS_URN));
}
- public int modifySP(String fqdn, List<PasspointManagementObjectDefinition> mods)
- throws IOException, SAXException {
- List<PasspointManagementObjectData> moData = new ArrayList<>();
- for (PasspointManagementObjectDefinition mod : mods) {
- moData.add(new PasspointManagementObjectData(mod));
- }
- return modifySP(fqdn, moData);
- }
-
private static final List<String> FQDNPath = Arrays.asList(TAG_HomeSP, TAG_FQDN);
/**
@@ -333,7 +323,8 @@ public class PasspointManagementObjectManager {
throw new OMAException("Cannot find instance node");
}
- public int modifySP(String fqdn, Collection<PasspointManagementObjectData> mods) throws IOException {
+ public int modifySP(String fqdn, Collection<PasspointManagementObjectDefinition> mods)
+ throws IOException, SAXException {
Log.d(Utils.hs2LogTag(getClass()), "modifying SP: " + mods);
MOTree moTree;
@@ -349,10 +340,10 @@ public class PasspointManagementObjectManager {
}
OMAConstructed instance = getInstanceNode(targetTree);
- for (PasspointManagementObjectData mod : mods) {
- LinkedList<String> tailPath = getTailPath(mod.getBaseURI(),
+ for (PasspointManagementObjectDefinition mod : mods) {
+ LinkedList<String> tailPath = getTailPath(mod.getBaseUri(),
TAG_PerProviderSubscription);
- OMAConstructed modRoot = mod.getMOTree().getRoot();
+ OMAConstructed modRoot = buildMoTree(mod).getRoot();
// modRoot is the MgmtTree with the actual object as a
// direct child (e.g. Credential)
@@ -387,6 +378,14 @@ public class PasspointManagementObjectManager {
return ppsMods;
}
+ private static MOTree buildMoTree(PasspointManagementObjectDefinition
+ managementObjectDefinition)
+ throws IOException, SAXException {
+
+ OMAParser omaParser = new OMAParser();
+ return omaParser.parse(managementObjectDefinition.getMoTree(), OMAConstants.PPS_URN);
+ }
+
private static LinkedList<String> getTailPath(String pathString, String rootName)
throws IOException {
String[] path = pathString.split("/");
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/ClientKeyManager.java b/service/java/com/android/server/wifi/hotspot2/osu/ClientKeyManager.java
deleted file mode 100644
index d705bfe9b..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/ClientKeyManager.java
+++ /dev/null
@@ -1,201 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiEnterpriseConfig;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.security.GeneralSecurityException;
-import java.security.Key;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.net.ssl.X509KeyManager;
-
-public class ClientKeyManager implements X509KeyManager {
- private final KeyStore mKeyStore;
- private final Map<OSUCertType, String> mAliasMap;
- private final Map<OSUCertType, Object> mTempKeys;
-
- private static final String sTempAlias = "client-alias";
- private static final Map<String, OSUCertType> sConfigMapping = new HashMap<>();
-
- static {
- sConfigMapping.put(WifiEnterpriseConfig.CLIENT_CERT_KEY, OSUCertType.Client);
- sConfigMapping.put(WifiEnterpriseConfig.CA_CERT_KEY, OSUCertType.CA);
- sConfigMapping.put(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, OSUCertType.PrivateKey);
- }
-
- public ClientKeyManager(WifiConfiguration config) throws IOException {
- android.security.keystore.AndroidKeyStoreProvider.install();
- try {
- mKeyStore = android.security.keystore.AndroidKeyStoreProvider.getKeyStoreForUid(android.os.Process.WIFI_UID);
- }
- catch (GeneralSecurityException gse) {
- throw new IOException("Failed to instantiate KeyStore: " + gse, gse);
- }
-
- WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
- if (enterpriseConfig == null) {
- throw new IOException("Missing enterprise configuration");
- }
- mAliasMap = populateAliases(enterpriseConfig.getFields());
- mTempKeys = new HashMap<>();
- //dumpKeyStore(mKeyStore, mAliasMap);
- }
-
- public void reloadKeys(Map<OSUCertType, List<X509Certificate>> certs, PrivateKey key)
- throws IOException {
- List<X509Certificate> clientCerts = certs.get(OSUCertType.Client);
- X509Certificate[] certArray = new X509Certificate[clientCerts.size()];
- int n = 0;
- for (X509Certificate cert : clientCerts) {
- certArray[n++] = cert;
- }
- mTempKeys.put(OSUCertType.Client, certArray);
- mTempKeys.put(OSUCertType.PrivateKey, key);
- }
-
- private static Map<OSUCertType, String> populateAliases(Map<String, String> configFields)
- throws IOException {
-
- Map<OSUCertType, String> aliasMap = new HashMap<>();
- for (Map.Entry<String, OSUCertType> entry : sConfigMapping.entrySet()) {
- String alias = getAlias(entry.getKey(), configFields);
- if (alias != null) {
- aliasMap.put(entry.getValue(), alias);
- }
- }
- return aliasMap;
- }
-
- private static String getAlias(String key, Map<String, String> configFields) throws IOException {
- String alias = configFields.get(key);
- if (alias == null) {
- return null;
- }
- if (alias.endsWith("\"")) {
- alias = alias.substring(0, alias.length() - 1);
- }
- int aliasStart = alias.indexOf('_');
- return aliasStart < 0 ? alias : alias.substring(aliasStart + 1);
- }
-
- private static void dumpKeyStore(KeyStore keyStore, Map<OSUCertType, String> aliasMap) {
- for (Map.Entry<OSUCertType, String> entry : aliasMap.entrySet()) {
- try {
- switch (entry.getKey()) {
- case Client:
- Certificate[] certs = keyStore.getCertificateChain(entry.getValue());
- for (Certificate cert : certs) {
- Log.d("ZXZ", "Cert " + cert);
- }
- break;
- case PrivateKey:
- Key key = keyStore.getKey(entry.getValue(), null);
- Log.d("ZXZ", "Key: " + key);
- break;
- case CA:
- Certificate cert = keyStore.getCertificate(entry.getValue());
- Log.d("ZXZ", "CA Cert " + cert);
- break;
- }
- }
- catch (GeneralSecurityException gse) {
- Log.w("ZXZ", "Caught exception: " + gse);
- }
- }
- }
-
- @Override
- public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
- if (mTempKeys.isEmpty()) {
- return mAliasMap.get(OSUCertType.Client);
- }
- else {
- return sTempAlias;
- }
- }
-
- @Override
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- if (mTempKeys.isEmpty()) {
- String alias = mAliasMap.get(OSUCertType.Client);
- return alias != null ? new String[]{alias} : null;
- }
- else {
- return new String[] {sTempAlias};
- }
- }
-
- @Override
- public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public X509Certificate[] getCertificateChain(String alias) {
- if (mTempKeys.isEmpty()) {
- if (!mAliasMap.get(OSUCertType.Client).equals(alias)) {
- Log.w(OSUManager.TAG, "Bad cert alias requested: '" + alias + "'");
- return null;
- }
- try {
- List<X509Certificate> certs = new ArrayList<>();
- for (Certificate certificate :
- mKeyStore.getCertificateChain(mAliasMap.get(OSUCertType.Client))) {
- if (certificate instanceof X509Certificate) {
- certs.add((X509Certificate) certificate);
- }
- }
- return certs.toArray(new X509Certificate[certs.size()]);
- } catch (KeyStoreException kse) {
- Log.w(OSUManager.TAG, "Failed to retrieve certificates: " + kse);
- return null;
- }
- }
- else if (sTempAlias.equals(alias)) {
- return (X509Certificate[]) mTempKeys.get(OSUCertType.Client);
- }
- else {
- Log.w(OSUManager.TAG, "Bad cert alias requested: '" + alias + "'");
- return null;
- }
- }
-
- @Override
- public PrivateKey getPrivateKey(String alias) {
- if (mTempKeys.isEmpty()) {
- if (!mAliasMap.get(OSUCertType.Client).equals(alias)) {
- Log.w(OSUManager.TAG, "Bad key alias requested: '" + alias + "'");
- }
- try {
- return (PrivateKey) mKeyStore.getKey(mAliasMap.get(OSUCertType.PrivateKey), null);
- } catch (GeneralSecurityException gse) {
- Log.w(OSUManager.TAG, "Failed to retrieve private key: " + gse);
- return null;
- }
- }
- else if (sTempAlias.equals(alias)) {
- return (PrivateKey) mTempKeys.get(OSUCertType.PrivateKey);
- }
- else {
- Log.w(OSUManager.TAG, "Bad cert alias requested: '" + alias + "'");
- return null;
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/ExchangeCompleteResponse.java b/service/java/com/android/server/wifi/hotspot2/osu/ExchangeCompleteResponse.java
deleted file mode 100644
index cee9ea9e8..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/ExchangeCompleteResponse.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
- /*
- <xsd:element name="sppExchangeComplete">
- <xsd:annotation>
- <xsd:documentation>SOAP method used by SPP server to end session.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element ref="sppError" minOccurs="0"/>
- <xsd:any namespace="##other" maxOccurs="unbounded" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute ref="sppVersion" use="required"/>
- <xsd:attribute ref="sppStatus" use="required"/>
- <xsd:attribute ref="sessionID" use="required"/>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- */
-
-public class ExchangeCompleteResponse extends OSUResponse {
- public ExchangeCompleteResponse(XMLNode root) throws OMAException {
- super(root, OSUMessageType.ExchangeComplete);
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/ExecCommand.java b/service/java/com/android/server/wifi/hotspot2/osu/ExecCommand.java
deleted file mode 100644
index c1a3a0515..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/ExecCommand.java
+++ /dev/null
@@ -1,3 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum ExecCommand { Browser, GetCert, UseClientCertTLS, UploadMO }
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/HTTPHandler.java b/service/java/com/android/server/wifi/hotspot2/osu/HTTPHandler.java
deleted file mode 100644
index 55570f4b4..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/HTTPHandler.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.util.Log;
-
-import com.android.server.wifi.hotspot2.utils.HTTPMessage;
-import com.android.server.wifi.hotspot2.utils.HTTPRequest;
-import com.android.server.wifi.hotspot2.utils.HTTPResponse;
-
-import com.android.org.conscrypt.OpenSSLSocketImpl;
-import org.xml.sax.SAXException;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLSocket;
-import javax.xml.parsers.ParserConfigurationException;
-
-public class HTTPHandler implements AutoCloseable {
- private final Charset mCharset;
- private final OSUSocketFactory mSocketFactory;
- private Socket mSocket;
- private BufferedOutputStream mOut;
- private BufferedInputStream mIn;
- private final String mUser;
- private final byte[] mPassword;
- private boolean mHTTPAuthPerformed;
- private static final AtomicInteger sSequence = new AtomicInteger();
-
- public HTTPHandler(Charset charset, OSUSocketFactory socketFactory) throws IOException {
- this(charset, socketFactory, null, null);
- }
-
- public HTTPHandler(Charset charset, OSUSocketFactory socketFactory,
- String user, byte[] password) throws IOException {
- mCharset = charset;
- mSocketFactory = socketFactory;
- mSocket = mSocketFactory.createSocket();
- mOut = new BufferedOutputStream(mSocket.getOutputStream());
- mIn = new BufferedInputStream(mSocket.getInputStream());
- mUser = user;
- mPassword = password;
- }
-
- public boolean isHTTPAuthPerformed() {
- return mHTTPAuthPerformed;
- }
-
- public X509Certificate getOSUCertificate(URL osu) throws GeneralSecurityException {
- return mSocketFactory.getOSUCertificate(osu);
- }
-
- public void renegotiate(Map<OSUCertType, List<X509Certificate>> certs, PrivateKey key)
- throws IOException {
- if (!(mSocket instanceof SSLSocket)) {
- throw new IOException("Not a TLS connection");
- }
- if (certs != null) {
- mSocketFactory.reloadKeys(certs, key);
- }
- ((SSLSocket) mSocket).startHandshake();
- }
-
- public byte[] getTLSUnique() throws SSLException {
- if (mSocket instanceof OpenSSLSocketImpl) {
- return ((OpenSSLSocketImpl) mSocket).getChannelId();
- }
- return null;
- }
-
- public OSUResponse exchangeSOAP(URL url, String message) throws IOException {
- HTTPResponse response = exchangeWithRetry(url, message, HTTPMessage.Method.POST,
- HTTPMessage.ContentTypeSOAP);
- if (response.getStatusCode() >= 300) {
- throw new IOException("Bad HTTP status code " + response.getStatusCode());
- }
- try {
- SOAPParser parser = new SOAPParser(response.getPayloadStream());
- return parser.getResponse();
- }
- catch (ParserConfigurationException | SAXException e) {
- ByteBuffer x = response.getPayload();
- byte[] b = new byte[x.remaining()];
- x.get(b);
- Log.w("XML", "Bad: '" + new String(b, StandardCharsets.ISO_8859_1));
- throw new IOException(e);
- }
- }
-
- public ByteBuffer exchangeBinary(URL url, String message, String contentType) throws IOException {
- HTTPResponse response = exchangeWithRetry(url, message, HTTPMessage.Method.POST, contentType);
- return response.getBinaryPayload();
- }
-
- public InputStream doGet(URL url) throws IOException {
- HTTPResponse response = exchangeWithRetry(url, null, HTTPMessage.Method.GET, null);
- return response.getPayloadStream();
- }
-
- public HTTPResponse doGetHTTP(URL url) throws IOException {
- return exchangeWithRetry(url, null, HTTPMessage.Method.GET, null);
- }
-
- private HTTPResponse exchangeWithRetry(URL url, String message, HTTPMessage.Method method,
- String contentType) throws IOException {
- HTTPResponse response = null;
- int retry = 0;
- for (;;) {
- try {
- response = httpExchange(url, message, method, contentType);
- break;
- }
- catch (IOException ioe) {
- close();
- retry++;
- if (retry > 3) {
- break;
- }
- Log.d(OSUManager.TAG, "Failed HTTP exchange, retry " + retry);
- mSocket = mSocketFactory.createSocket();
- mOut = new BufferedOutputStream(mSocket.getOutputStream());
- mIn = new BufferedInputStream(mSocket.getInputStream());
- }
- }
- if (response == null) {
- throw new IOException("Failed to establish connection to peer");
- }
- return response;
- }
-
- private HTTPResponse httpExchange(URL url, String message, HTTPMessage.Method method, String contentType)
- throws IOException {
- HTTPRequest request = new HTTPRequest(message, mCharset, method, url, contentType, false);
- request.send(mOut);
- HTTPResponse response = new HTTPResponse(mIn);
- Log.d(OSUManager.TAG, "HTTP code " + response.getStatusCode() + ", user " + mUser +
- ", pw " + (mPassword != null ? '\'' + new String(mPassword) + '\'' : "-" ));
- if (response.getStatusCode() == 401) {
- if (mUser == null) {
- throw new IOException("Missing user name for HTTP authentication");
- }
- try {
- request = new HTTPRequest(message, StandardCharsets.ISO_8859_1, method, url,
- contentType, true);
- request.doAuthenticate(response, mUser, mPassword, url, sSequence.incrementAndGet());
- request.send(mOut);
- mHTTPAuthPerformed = true;
- }
- catch (GeneralSecurityException gse) {
- throw new IOException(gse);
- }
-
- response = new HTTPResponse(mIn);
- }
- return response;
- }
-
- public void close() throws IOException {
- mIn.close();
- mOut.close();
- mSocket.close();
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/IconCache.java b/service/java/com/android/server/wifi/hotspot2/osu/IconCache.java
deleted file mode 100644
index c3e3be030..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/IconCache.java
+++ /dev/null
@@ -1,357 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.util.Log;
-
-import com.android.server.wifi.anqp.ANQPFactory;
-import com.android.server.wifi.anqp.HSIconFileElement;
-import com.android.server.wifi.anqp.IconInfo;
-import com.android.server.wifi.hotspot2.IconEvent;
-import com.android.server.wifi.hotspot2.SupplicantBridge;
-import com.android.server.wifi.hotspot2.Utils;
-
-import java.io.IOException;
-import java.net.ProtocolException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import static com.android.server.wifi.anqp.Constants.ANQPElementType.HSIconFile;
-
-public class IconCache extends Thread {
- private static final int CacheSize = 64;
-
- private final OSUManager mOSUManager;
- private final Map<Long, LinkedList<IconQuery>> mPendingQueries = new HashMap<>();
- private final Map<IconKey, HSIconFileElement> mCache = new LinkedHashMap<IconKey, HSIconFileElement>() {
- @Override
- protected boolean removeEldestEntry(Map.Entry eldest) {
- return size() > CacheSize;
- }
- };
-
- public IconCache(OSUManager osuManager) {
- mOSUManager = osuManager;
- }
-
- /**
- * Enqueue a query for this BSSID
- * @param query the query to stash in current BSSID bucket. Queries need to be serialized per
- * BSSID since there is no way of tying a response back to the file name.
- * @return true if the added query is the current one.
- */
- private boolean enqueueQuery(IconQuery query) {
- long bssid = query.getBSSID();
- LinkedList<IconQuery> requests = mPendingQueries.get(bssid);
- if (requests == null || requests.isEmpty()) {
- requests = new LinkedList<>();
- requests.add(query);
- mPendingQueries.put(bssid, requests);
- return true;
- }
- else {
- requests.addLast(query);
- return false;
- }
- }
-
- private IconQuery dropCurrentQuery(long bssid) {
- IconQuery current = null;
- LinkedList<IconQuery> requests = mPendingQueries.get(bssid);
- if (requests != null) {
- if (!requests.isEmpty()) {
- current = requests.removeFirst(); // Remove the associated request
- }
-
- if (requests.isEmpty()) {
- mPendingQueries.remove(bssid);
- }
- }
- return current;
- }
-
- private IconQuery getNextQuery(long bssid) {
- LinkedList<IconQuery> requests = mPendingQueries.get(bssid);
- if (requests != null) {
- if (!requests.isEmpty()) {
- return requests.getFirst();
- }
- else {
- mPendingQueries.remove(bssid);
- }
- }
- return null;
- }
-
- public void startIconQuery(OSUInfo osuInfo, List<IconInfo> icons) {
- Log.d(Utils.hs2LogTag(getClass()),
- String.format("Icon query on %012x for %s", osuInfo.getBSSID(), icons));
- if (icons == null || icons.isEmpty()) {
- return;
- }
-
- HSIconFileElement cached;
- IconQuery query = null;
-
- synchronized (mCache) {
- IconInfo iconInfo = icons.iterator().next();
- IconKey key = new IconKey(osuInfo.getBSSID(), iconInfo.getFileName());
- cached = mCache.get(key);
- if (cached != null) {
- osuInfo.setIconFileElement(cached, iconInfo.getFileName());
- }
- else {
- query = new IconQuery(osuInfo, icons);
- if (!enqueueQuery(new IconQuery(osuInfo, icons))) {
- query = null;
- }
- osuInfo.setIconStatus(OSUInfo.IconStatus.InProgress);
- }
- }
- if (cached != null) {
- mOSUManager.iconResult(osuInfo);
- }
-
- Log.d(Utils.hs2LogTag(getClass()),
- String.format("Instant icon query for %012x: %s", osuInfo.getBSSID(), query));
-
- if (query != null) {
- doIconQuery(osuInfo.getBSSID(), query);
- }
- }
-
- public void notifyIconReceived(IconEvent iconEvent) {
- byte[] iconData;
- try {
- iconData = mOSUManager.getSupplicantBridge().retrieveIcon(iconEvent);
- }
- catch (IOException ioe) {
- Log.w(Utils.hs2LogTag(getClass()), "Icon retrieval failed: " + ioe, ioe);
- return;
- }
-
- IconQuery current;
- synchronized (mCache) {
- current = dropCurrentQuery(iconEvent.getBSSID());
- if (current == null) {
- Log.w(Utils.hs2LogTag(getClass()), "Spurious icon data");
- return;
- }
-
- try {
- HSIconFileElement iconFileElement = (HSIconFileElement)
- ANQPFactory.buildHS20Element(HSIconFile,
- ByteBuffer.wrap(iconData).order(ByteOrder.LITTLE_ENDIAN));
-
- String fileName = current.getIconInfo().getFileName();
- Log.d(Utils.hs2LogTag(getClass()), "Icon file " + fileName + ": " +
- iconFileElement);
- current.getOSUInfo().setIconFileElement(iconFileElement, fileName);
-
- mCache.put(new IconKey(iconEvent.getBSSID(), fileName), iconFileElement);
- }
- catch (ProtocolException | BufferUnderflowException e) {
- Log.e(Utils.hs2LogTag(SupplicantBridge.class),
- "Failed to parse ANQP icon file: " + e);
- current.getOSUInfo().setIconStatus(OSUInfo.IconStatus.NotAvailable);
- }
- }
-
- mOSUManager.iconResult(current.getOSUInfo());
-
- IconQuery next;
- synchronized (mCache) {
- next = getNextQuery(iconEvent.getBSSID());
- }
-
- if (next != null) {
- doIconQuery(iconEvent.getBSSID(), next);
- }
- }
-
- public void notifyIconFailed(long bssid) {
- doIconQuery(bssid, null);
- }
-
- private static final long RequeryTimeLow = 6000L;
- private static final long RequeryTimeHigh = 15000L;
-
- public void tickle(boolean wifiOff) {
- long now = System.currentTimeMillis();
- synchronized (mCache) {
- if (wifiOff) {
- mPendingQueries.clear();
- // Not sure it makes sense to clear the icon cache.
- }
- else {
- for (Map.Entry<Long, LinkedList<IconQuery>> entry : mPendingQueries.entrySet()) {
- Iterator<IconQuery> queries = entry.getValue().iterator();
- while (queries.hasNext()) {
- IconQuery query = queries.next();
- long age = now - query.getLastSent();
- if (age > RequeryTimeHigh) {
- queries.remove();
- }
- else if (age > RequeryTimeLow) {
- doIconQuery(entry.getKey(), query);
- break;
- }
- }
- if (entry.getValue().isEmpty()) {
- mPendingQueries.remove(entry.getKey());
- }
- }
- }
- }
- }
-
- private void doIconQuery(long bssid, IconQuery query) {
- boolean success;
- do {
- IconQuery current = query;
- synchronized (mCache) {
- if (query == null) {
- current = getNextQuery(bssid);
- }
-
- while (current != null) {
- if (current.getRetry() < IconRetries) {
- current.bumpRetry();
- break;
- } else if (current.hasRemaining()) {
- current.bumpIndex();
- break;
- } else {
- current.getOSUInfo().setIconStatus(OSUInfo.IconStatus.NotAvailable);
- dropCurrentQuery(bssid);
- current = getNextQuery(bssid);
- }
- }
- }
- Log.d(Utils.hs2LogTag(getClass()), String.format("Resulting icon request to %012x: %s",
- bssid, current));
-
- if (current != null) {
- HSIconFileElement iconFileElement;
- String fileName = current.getIconInfo().getFileName();
- synchronized (mCache) {
- iconFileElement =
- mCache.get(new IconKey(bssid, fileName));
- }
-
- if (iconFileElement != null) {
- // A "sub-ordinate" icon could have been cached before.
- current.getOSUInfo().setIconFileElement(iconFileElement, fileName);
- mOSUManager.iconResult(current.getOSUInfo());
- success = true;
- }
- else {
- success = mOSUManager.getSupplicantBridge().doIconQuery(current.getBSSID(),
- current.getIconInfo().getFileName());
- }
- }
- else {
- break;
- }
- }
- while (!success);
- }
-
- private static class IconKey {
- private final long mBSSID;
- private final String mFileName;
-
- private IconKey(long bssid, String fileName) {
- mBSSID = bssid;
- mFileName = fileName;
- }
-
- @Override
- public boolean equals(Object thatObject) {
- if (this == thatObject) {
- return true;
- }
- if (thatObject == null || getClass() != thatObject.getClass()) {
- return false;
- }
-
- IconKey that = (IconKey) thatObject;
- return mBSSID == that.mBSSID && mFileName.equals(that.mFileName);
- }
-
- @Override
- public int hashCode() {
- int result = (int) (mBSSID ^ (mBSSID >>> 32));
- result = 31 * result + mFileName.hashCode();
- return result;
- }
- }
-
- private static final int IconRetries = 3;
-
- private static class IconQuery {
- private final OSUInfo mOSUInfo;
- private final List<IconInfo> mIconInfos;
- private int mIndex;
- private int mRetry;
- private long mLastSent;
-
- private IconQuery(OSUInfo osuInfo, List<IconInfo> iconInfos) {
- mOSUInfo = osuInfo;
- mIconInfos = iconInfos;
- mLastSent = System.currentTimeMillis();
- }
-
- public IconInfo getIconInfo() {
- return mIconInfos.get(mIndex);
- }
-
- private void bumpRetry() {
- mRetry++;
- mLastSent = System.currentTimeMillis();
- }
-
- private void bumpIndex() {
- mIndex++;
- mRetry = 0;
- mLastSent = System.currentTimeMillis();
- }
-
- public OSUInfo getOSUInfo() {
- return mOSUInfo;
- }
-
- private boolean hasRemaining() {
- return mIndex < mIconInfos.size() - 1;
- }
-
- public int getRetry() {
- return mRetry;
- }
-
- public long getBSSID() {
- return mOSUInfo.getBSSID();
- }
-
- private long getLastSent() {
- return mLastSent;
- }
-
- @Override
- public String toString() {
- return "IconQuery{" +
- "OSUInfo=" + mOSUInfo +
- ", IconInfos=" + mIconInfos +
- ", Index=" + mIndex +
- ", Retry=" + mRetry +
- ", LastSent=" + mLastSent +
- '}';
- }
- }
-
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUCertType.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUCertType.java
deleted file mode 100644
index c1be4179b..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUCertType.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum OSUCertType {
- CA,
- Client,
- AAA,
- Remediation,
- Policy,
- PrivateKey
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUClient.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUClient.java
deleted file mode 100644
index d301ce304..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUClient.java
+++ /dev/null
@@ -1,494 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-/*
- * policy-server.r2-testbed IN A 10.123.107.107
- * remediation-server.r2-testbed IN A 10.123.107.107
- * subscription-server.r2-testbed IN A 10.123.107.107
- * www.r2-testbed IN A 10.123.107.107
- * osu-server.r2-testbed-rks IN A 10.123.107.107
- * policy-server.r2-testbed-rks IN A 10.123.107.107
- * remediation-server.r2-testbed-rks IN A 10.123.107.107
- * subscription-server.r2-testbed-rks IN A 10.123.107.107
- */
-
-import android.net.Network;
-import android.util.Log;
-
-import com.android.server.wifi.hotspot2.OMADMAdapter;
-import com.android.server.wifi.hotspot2.est.ESTHandler;
-import com.android.server.wifi.hotspot2.omadm.OMAConstants;
-import com.android.server.wifi.hotspot2.omadm.OMANode;
-import com.android.server.wifi.hotspot2.osu.commands.BrowserURI;
-import com.android.server.wifi.hotspot2.osu.commands.ClientCertInfo;
-import com.android.server.wifi.hotspot2.osu.commands.GetCertData;
-import com.android.server.wifi.hotspot2.osu.commands.PasspointManagementObjectData;
-import com.android.server.wifi.hotspot2.pps.Credential;
-import com.android.server.wifi.hotspot2.pps.HomeSP;
-import com.android.server.wifi.hotspot2.pps.UpdateInfo;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.net.ssl.KeyManager;
-
-public class OSUClient {
- private static final String TAG = "OSUCLT";
- private static final String TTLS_OSU = "https://osu-server.r2-testbed-rks.wi-fi.org:9447/OnlineSignup/services/newUser/digest";
- private static final String TLS_OSU = "https://osu-server.r2-testbed-rks.wi-fi.org:9446/OnlineSignup/services/newUser/certificate";
-
- private final OSUInfo mOSUInfo;
- private final URL mURL;
-
- public OSUClient(OSUInfo osuInfo) throws MalformedURLException {
- mOSUInfo = osuInfo;
- mURL = new URL(osuInfo.getOSUProvider().getOSUServer());
- }
-
- public OSUClient(String osu) throws MalformedURLException {
- mOSUInfo = null;
- mURL = new URL(osu);
- }
-
- public void provision(OSUManager osuManager, Network network, KeyManager km)
- throws IOException, GeneralSecurityException {
- try (HTTPHandler httpHandler = new HTTPHandler(StandardCharsets.UTF_8,
- OSUSocketFactory.getSocketFactory(network, mURL, km, true))) {
-
- SPVerifier spVerifier = new SPVerifier(mOSUInfo);
- spVerifier.verify(httpHandler.getOSUCertificate(mURL));
-
- URL redirectURL = osuManager.prepareUserInput();
- OMADMAdapter omadmAdapter = osuManager.getOMADMAdapter();
-
- String regRequest = SOAPBuilder.buildPostDevDataResponse(RequestReason.SubRegistration,
- null,
- redirectURL.toString(),
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
- Log.d("ZXZ", "Registration request: " + regRequest);
- OSUResponse osuResponse = httpHandler.exchangeSOAP(mURL, regRequest);
-
- Log.d(TAG, "Response: " + osuResponse);
- if (osuResponse.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Expected a PostDevDataResponse");
- }
- PostDevDataResponse regResponse = (PostDevDataResponse) osuResponse;
- String sessionID = regResponse.getSessionID();
- if (regResponse.getExecCommand() == ExecCommand.UseClientCertTLS) {
- ClientCertInfo ccInfo = (ClientCertInfo) regResponse.getCommandData();
- if (ccInfo.doesAcceptMfgCerts()) {
- throw new IOException("Mfg certs are not supported in Android");
- }
- else if (ccInfo.doesAcceptProviderCerts()) {
- ((WiFiKeyManager) km).enableClientAuth(ccInfo.getIssuerNames());
- httpHandler.renegotiate(null, null);
- }
- else {
- throw new IOException("Neither manufacturer nor provider cert specified");
- }
- regRequest = SOAPBuilder.buildPostDevDataResponse(RequestReason.SubRegistration,
- sessionID,
- redirectURL.toString(),
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
-
- osuResponse = httpHandler.exchangeSOAP(mURL, regRequest);
- if (osuResponse.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Expected a PostDevDataResponse");
- }
- regResponse = (PostDevDataResponse) osuResponse;
- }
-
- if (regResponse.getExecCommand() != ExecCommand.Browser) {
- throw new IOException("Expected a launchBrowser command");
- }
- Log.d(TAG, "Exec: " + regResponse.getExecCommand() + ", for '" +
- regResponse.getCommandData() + "'");
-
- if (!osuResponse.getSessionID().equals(sessionID)) {
- throw new IOException("Mismatching session IDs");
- }
- String webURL = ((BrowserURI) regResponse.getCommandData()).getURI();
-
- if (webURL == null) {
- throw new IOException("No web-url");
- } else if (!webURL.contains(sessionID)) {
- throw new IOException("Bad or missing session ID in webURL");
- }
-
- if (!osuManager.startUserInput(new URL(webURL), network)) {
- throw new IOException("User session failed");
- }
-
- Log.d(TAG, " -- Sending user input complete:");
- String userComplete = SOAPBuilder.buildPostDevDataResponse(RequestReason.InputComplete,
- sessionID, null,
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
- OSUResponse moResponse1 = httpHandler.exchangeSOAP(mURL, userComplete);
- if (moResponse1.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Bad user input complete response: " + moResponse1);
- }
- PostDevDataResponse provResponse = (PostDevDataResponse) moResponse1;
- GetCertData estData = checkResponse(provResponse);
-
- Map<OSUCertType, List<X509Certificate>> certs = new HashMap<>();
- PrivateKey clientKey = null;
-
- PasspointManagementObjectData moData;
- if (estData == null) {
- moData = (PasspointManagementObjectData) provResponse.getCommandData();
- }
- else {
- try (ESTHandler estHandler = new ESTHandler((GetCertData) provResponse.
- getCommandData(), network, osuManager.getOMADMAdapter(), km)) {
- estHandler.execute(false);
- certs.put(OSUCertType.CA, estHandler.getCACerts());
- certs.put(OSUCertType.Client, estHandler.getClientCerts());
- clientKey = estHandler.getClientKey();
- }
-
- Log.d(TAG, " -- Sending provisioning cert enrollment complete:");
- String certComplete =
- SOAPBuilder.buildPostDevDataResponse(RequestReason.CertEnrollmentComplete,
- sessionID, null,
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
- OSUResponse moResponse2 = httpHandler.exchangeSOAP(mURL, certComplete);
- if (moResponse2.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Bad cert enrollment complete response: " + moResponse2);
- }
- PostDevDataResponse provComplete = (PostDevDataResponse) moResponse2;
- if (provComplete.getStatus() != OSUStatus.ProvComplete ||
- provComplete.getOSUCommand() != OSUCommandID.AddMO) {
- throw new IOException("Expected addMO: " + provComplete);
- }
- moData = (PasspointManagementObjectData) provComplete.getCommandData();
- }
-
- // !!! How can an ExchangeComplete be sent w/o knowing the fate of the certs???
- String updateResponse = SOAPBuilder.buildUpdateResponse(sessionID, null);
- Log.d(TAG, " -- Sending updateResponse:");
- OSUResponse exComplete = httpHandler.exchangeSOAP(mURL, updateResponse);
- Log.d(TAG, "exComplete response: " + exComplete);
- if (exComplete.getMessageType() != OSUMessageType.ExchangeComplete) {
- throw new IOException("Expected ExchangeComplete: " + exComplete);
- }
- else if (exComplete.getStatus() != OSUStatus.ExchangeComplete) {
- throw new IOException("Bad ExchangeComplete status: " + exComplete);
- }
-
- retrieveCerts(moData.getMOTree().getRoot(), certs, network, km);
- osuManager.provisioningComplete(moData, certs, clientKey, network);
- }
- }
-
- public void remediate(OSUManager osuManager, Network network, KeyManager km, HomeSP homeSP,
- boolean policy)
- throws IOException, GeneralSecurityException {
- try (HTTPHandler httpHandler = createHandler(network, homeSP, km, policy)) {
- URL redirectURL = osuManager.prepareUserInput();
- OMADMAdapter omadmAdapter = osuManager.getOMADMAdapter();
-
- String regRequest = SOAPBuilder.buildPostDevDataResponse(RequestReason.SubRemediation,
- null,
- redirectURL.toString(),
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
-
- OSUResponse serverResponse = httpHandler.exchangeSOAP(mURL, regRequest);
- if (serverResponse.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Expected a PostDevDataResponse");
- }
- String sessionID = serverResponse.getSessionID();
-
- PostDevDataResponse pddResponse = (PostDevDataResponse) serverResponse;
- Log.d(TAG, "Remediation response: " + pddResponse);
-
- Map<OSUCertType, List<X509Certificate>> certs = null;
- PrivateKey clientKey = null;
-
- if (pddResponse.getStatus() != OSUStatus.RemediationComplete) {
- if (pddResponse.getExecCommand() == ExecCommand.UploadMO) {
- String ulMessage = SOAPBuilder.buildPostDevDataResponse(RequestReason.MOUpload,
- null,
- redirectURL.toString(),
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN),
- osuManager.getMOTree(homeSP));
-
- Log.d("ZXZ", "Upload MO: " + ulMessage);
-
- OSUResponse ulResponse = httpHandler.exchangeSOAP(mURL, ulMessage);
- if (ulResponse.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Expected a PostDevDataResponse to MOUpload");
- }
- pddResponse = (PostDevDataResponse) ulResponse;
- }
-
- if (pddResponse.getExecCommand() == ExecCommand.Browser) {
- if (policy) {
- throw new IOException("Browser launch requested in policy flow");
- }
- String webURL = ((BrowserURI) pddResponse.getCommandData()).getURI();
-
- if (webURL == null) {
- throw new IOException("No web-url");
- } else if (!webURL.contains(sessionID)) {
- throw new IOException("Bad or missing session ID in webURL");
- }
-
- if (!osuManager.startUserInput(new URL(webURL), network)) {
- throw new IOException("User session failed");
- }
-
- Log.d(TAG, " -- Sending user input complete:");
- String userComplete = SOAPBuilder.buildPostDevDataResponse(RequestReason.InputComplete,
- sessionID, null,
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
-
- OSUResponse udResponse = httpHandler.exchangeSOAP(mURL, userComplete);
- if (udResponse.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Bad user input complete response: " + udResponse);
- }
- pddResponse = (PostDevDataResponse) udResponse;
- }
- else if (pddResponse.getExecCommand() == ExecCommand.GetCert) {
- certs = new HashMap<>();
- try (ESTHandler estHandler = new ESTHandler((GetCertData) pddResponse.
- getCommandData(), network, osuManager.getOMADMAdapter(), km)) {
- estHandler.execute(true);
- certs.put(OSUCertType.CA, estHandler.getCACerts());
- certs.put(OSUCertType.Client, estHandler.getClientCerts());
- clientKey = estHandler.getClientKey();
- }
-
- if (httpHandler.isHTTPAuthPerformed()) { // 8.4.3.6
- httpHandler.renegotiate(certs, clientKey);
- }
-
- Log.d(TAG, " -- Sending remediation cert enrollment complete:");
- // 8.4.3.5 in the spec actually prescribes that an update URI is sent here,
- // but there is no remediation flow that defines user interaction after EST
- // so for now a null is passed.
- String certComplete =
- SOAPBuilder.buildPostDevDataResponse(RequestReason.CertEnrollmentComplete,
- sessionID, null,
- omadmAdapter.getMO(OMAConstants.DevInfoURN),
- omadmAdapter.getMO(OMAConstants.DevDetailURN));
- OSUResponse ceResponse = httpHandler.exchangeSOAP(mURL, certComplete);
- if (ceResponse.getMessageType() != OSUMessageType.PostDevData) {
- throw new IOException("Bad cert enrollment complete response: " + ceResponse);
- }
- pddResponse = (PostDevDataResponse) ceResponse;
- }
- else {
- throw new IOException("Unexpected command: " + pddResponse.getExecCommand());
- }
- }
-
- if (pddResponse.getStatus() != OSUStatus.RemediationComplete) {
- throw new IOException("Expected a PostDevDataResponse to MOUpload");
- }
-
- Log.d(TAG, "Remediation response: " + pddResponse);
-
- List<PasspointManagementObjectData> mods = new ArrayList<>();
- for (OSUCommand command : pddResponse.getCommands()) {
- if (command.getOSUCommand() == OSUCommandID.UpdateNode) {
- mods.add((PasspointManagementObjectData)command.getCommandData());
- }
- else if (command.getOSUCommand() != OSUCommandID.NoMOUpdate) {
- throw new IOException("Unexpected OSU response: " + command);
- }
- }
-
- // 1. Machine remediation: Remediation complete + replace node
- // 2a. User remediation with upload: ExecCommand.UploadMO
- // 2b. User remediation without upload: ExecCommand.Browser
- // 3. User remediation only: -> sppPostDevData user input complete
- //
- // 4. Update node
- // 5. -> Update response
- // 6. Exchange complete
-
- OSUError error = null;
-
- String updateResponse = SOAPBuilder.buildUpdateResponse(sessionID, error);
- Log.d(TAG, " -- Sending updateResponse:");
- OSUResponse exComplete = httpHandler.exchangeSOAP(mURL, updateResponse);
- Log.d(TAG, "exComplete response: " + exComplete);
- if (exComplete.getMessageType() != OSUMessageType.ExchangeComplete) {
- throw new IOException("Expected ExchangeComplete: " + exComplete);
- }
- else if (exComplete.getStatus() != OSUStatus.ExchangeComplete) {
- throw new IOException("Bad ExchangeComplete status: " + exComplete);
- }
-
- // There's a chicken and egg here: If the config is saved before sending update complete
- // the network is lost and the remediation flow fails.
- try {
- osuManager.remediationComplete(homeSP, mods, certs, clientKey);
- }
- catch (IOException | GeneralSecurityException e) {
- osuManager.provisioningFailed(e.getMessage(), homeSP, OSUManager.FlowType.Remediation);
- error = OSUError.CommandFailed;
- }
- }
- }
-
- private HTTPHandler createHandler(Network network, HomeSP homeSP, KeyManager km, boolean policy)
- throws GeneralSecurityException, IOException {
- Credential credential = homeSP.getCredential();
-
- Log.d(TAG, "Credential method " + credential.getEAPMethod().getEAPMethodID());
- switch (credential.getEAPMethod().getEAPMethodID()) {
- case EAP_TTLS:
- String user;
- byte[] password;
- UpdateInfo subscriptionUpdate;
- if (policy) {
- subscriptionUpdate = homeSP.getPolicy() != null ?
- homeSP.getPolicy().getPolicyUpdate() : null;
- }
- else {
- subscriptionUpdate = homeSP.getSubscriptionUpdate();
- }
- if (subscriptionUpdate != null && subscriptionUpdate.getUsername() != null) {
- user = subscriptionUpdate.getUsername();
- password = subscriptionUpdate.getPassword() != null ?
- subscriptionUpdate.getPassword().getBytes(StandardCharsets.UTF_8) :
- new byte[0];
- }
- else {
- user = credential.getUserName();
- password = credential.getPassword().getBytes(StandardCharsets.UTF_8);
- }
- return new HTTPHandler(StandardCharsets.UTF_8,
- OSUSocketFactory.getSocketFactory(network, mURL, km, true), user, password);
- case EAP_TLS:
- return new HTTPHandler(StandardCharsets.UTF_8,
- OSUSocketFactory.getSocketFactory(network, mURL, km, true));
- default:
- throw new IOException("Cannot remediate account with " +
- credential.getEAPMethod().getEAPMethodID());
- }
- }
-
- private static GetCertData checkResponse(PostDevDataResponse response) throws IOException {
- if (response.getStatus() == OSUStatus.ProvComplete &&
- response.getOSUCommand() == OSUCommandID.AddMO) {
- return null;
- }
-
- if (response.getOSUCommand() == OSUCommandID.Exec &&
- response.getExecCommand() == ExecCommand.GetCert) {
- return (GetCertData) response.getCommandData();
- }
- else {
- throw new IOException("Unexpected command: " + response);
- }
- }
-
- private static final String[] AAACertPath = { "PerProviderSubscription", "?", "AAAServerTrustRoot", "*", "CertURL" };
- private static final String[] RemdCertPath = { "PerProviderSubscription", "?", "SubscriptionUpdate", "TrustRoot", "CertURL" };
- private static final String[] PolicyCertPath = { "PerProviderSubscription", "?", "Policy", "PolicyUpdate", "TrustRoot", "CertURL" };
-
- private static void retrieveCerts(OMANode ppsRoot,
- Map<OSUCertType, List<X509Certificate>> certs,
- Network network, KeyManager km)
- throws GeneralSecurityException, IOException {
-
- List<X509Certificate> aaaCerts = getCerts(ppsRoot, AAACertPath, network, km);
- certs.put(OSUCertType.AAA, aaaCerts);
- certs.put(OSUCertType.Remediation, getCerts(ppsRoot, RemdCertPath, network, km));
- certs.put(OSUCertType.Policy, getCerts(ppsRoot, PolicyCertPath, network, km));
-
- boolean oneMatch = false;
- List<X509Certificate> caCerts = certs.get(OSUCertType.CA);
- if (caCerts != null) {
- for (X509Certificate caCert : caCerts) {
- for (X509Certificate aaaRoot : aaaCerts) {
- if (caCert.equals(aaaRoot)) {
- oneMatch = true;
- Log.d(TAG, "AAA certs match!");
- break;
- }
- }
- }
- if (!oneMatch) {
- Log.d(TAG, "No AAA cert matches!");
- }
- }
- }
-
- private static List<X509Certificate> getCerts(OMANode ppsRoot, String[] path, Network network,
- KeyManager km)
- throws GeneralSecurityException, IOException {
- List<String> urls = new ArrayList<>();
- getCertURLs(ppsRoot, Arrays.asList(path).iterator(), urls);
- Log.d(TAG, Arrays.toString(path) + ": " + urls);
-
- List<X509Certificate> certs = new ArrayList<>(urls.size());
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- for (String urlString : urls) {
- URL url = new URL(urlString);
- HTTPHandler httpHandler = new HTTPHandler(StandardCharsets.UTF_8,
- OSUSocketFactory.getSocketFactory(network, url, km, false));
-
- certs.add((X509Certificate) certFactory.generateCertificate(httpHandler.doGet(url)));
- }
- return certs;
- }
-
- private static void getCertURLs(OMANode root, Iterator<String> path, List<String> urls)
- throws IOException {
-
- String name = path.next();
- // Log.d(TAG, "Pulling '" + name + "' out of '" + root.getName() + "'");
- Collection<OMANode> nodes = null;
- switch (name) {
- case "?":
- for (OMANode node : root.getChildren()) {
- if (!node.isLeaf()) {
- nodes = Arrays.asList(node);
- break;
- }
- }
- break;
- case "*":
- nodes = root.getChildren();
- break;
- default:
- nodes = Arrays.asList(root.getChild(name));
- break;
- }
-
- if (nodes == null) {
- throw new IllegalArgumentException("No matching node in " + root.getName() + " for " + name);
- }
-
- for (OMANode node : nodes) {
- if (path.hasNext()) {
- getCertURLs(node, path, urls);
- }
- else {
- urls.add(node.getValue());
- }
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUCommand.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUCommand.java
deleted file mode 100644
index 62f978f1b..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUCommand.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-import com.android.server.wifi.hotspot2.osu.commands.*;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class OSUCommand {
- private final OSUCommandID mOSUCommand;
- private final ExecCommand mExecCommand;
- private final OSUCommandData mCommandData;
-
- private static final Map<String, OSUCommandID> sCommands = new HashMap<>();
- private static final Map<String, ExecCommand> sExecs = new HashMap<>();
-
- static {
- sCommands.put("exec", OSUCommandID.Exec);
- sCommands.put("addmo", OSUCommandID.AddMO);
- sCommands.put("updatenode", OSUCommandID.UpdateNode); // Multi
- sCommands.put("nomoupdate", OSUCommandID.NoMOUpdate);
-
- sExecs.put("launchbrowsertouri", ExecCommand.Browser);
- sExecs.put("getcertificate", ExecCommand.GetCert);
- sExecs.put("useclientcerttls", ExecCommand.UseClientCertTLS);
- sExecs.put("uploadmo", ExecCommand.UploadMO);
- }
-
- public OSUCommand(XMLNode child) throws OMAException {
- mOSUCommand = sCommands.get(child.getStrippedTag());
-
- switch (mOSUCommand) {
- case Exec:
- /*
- * Receipt of this element by a mobile device causes the following command to be executed.
- */
- child = child.getSoleChild();
- mExecCommand = sExecs.get(child.getStrippedTag());
- if (mExecCommand == null) {
- throw new OMAException("Unrecognized exec command: " + child.getStrippedTag());
- }
- switch (mExecCommand) {
- case Browser:
- /*
- * When the mobile device receives this command, it launches its default browser to the URI
- * contained in this element. The URI must use HTTPS as the protocol and must contain an FQDN.
- */
- mCommandData = new BrowserURI(child);
- break;
- case GetCert:
- mCommandData = new GetCertData(child);
- break;
- case UploadMO:
- mCommandData = new MOURN(child);
- break;
- case UseClientCertTLS:
- /*
- * Command to mobile to re-negotiate the TLS connection using a client certificate of the
- * accepted type or Issuer to authenticate with the Subscription server.
- */
- mCommandData = new ClientCertInfo(child);
- break;
- default:
- mCommandData = null;
- break;
- }
- break;
- case AddMO:
- /*
- * This command causes an management object in the mobile devices management tree at the specified
- * location to be added.
- * If there is already a management object at that location, the object is replaced.
- */
- mExecCommand = null;
- mCommandData = new PasspointManagementObjectData(child);
- break;
- case UpdateNode:
- /*
- * This command causes the update of an interior node and its child nodes (if any) at the location
- * specified in the management tree URI attribute. The content of this element is the MO node XML.
- */
- mExecCommand = null;
- mCommandData = new PasspointManagementObjectData(child);
- break;
- case NoMOUpdate:
- /*
- * This response is used when there is no command to be executed nor update of any MO required.
- */
- mExecCommand = null;
- mCommandData = null;
- break;
- default:
- mExecCommand = null;
- mCommandData = null;
- break;
- }
- }
-
- public OSUCommandID getOSUCommand() {
- return mOSUCommand;
- }
-
- public ExecCommand getExecCommand() {
- return mExecCommand;
- }
-
- public OSUCommandData getCommandData() {
- return mCommandData;
- }
-
- @Override
- public String toString() {
- return "OSUCommand{" +
- "OSUCommand=" + mOSUCommand +
- ", execCommand=" + mExecCommand +
- ", commandData=" + mCommandData +
- '}';
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUCommandID.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUCommandID.java
deleted file mode 100644
index c708e25ba..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUCommandID.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum OSUCommandID {
- Exec, AddMO, UpdateNode, NoMOUpdate
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUError.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUError.java
deleted file mode 100644
index 819cd5630..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUError.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum OSUError {
- SPPversionNotSupported,
- MOsNotSupported,
- CredentialsFailure,
- RemediationFailure,
- ProvisioningFailed,
- ExistingCertificate,
- CookieInvalid,
- WebSessionID,
- PermissionDenied,
- CommandFailed,
- MOaddOrUpdateFailed,
- DeviceFull,
- BadTreeURI,
- TooLarge,
- CommandNotAllowed,
- UserAborted,
- NotFound,
- Other
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUInfo.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUInfo.java
deleted file mode 100644
index 87a6431d4..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUInfo.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.util.Log;
-
-import com.android.server.wifi.anqp.HSIconFileElement;
-import com.android.server.wifi.anqp.I18Name;
-import com.android.server.wifi.anqp.IconInfo;
-import com.android.server.wifi.anqp.OSUProvider;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Set;
-
-public class OSUInfo {
- public static final String GenericLocale = "zxx";
-
- public enum IconStatus {
- NotQueried, //
- InProgress, // Query pending
- NotAvailable, // Deterministically unavailable
- Available // Icon data retrieved
- }
-
- private final long mBSSID;
- private final String mSSID;
- private final OSUProvider mOSUProvider;
- private final int mOsuID;
- private IconStatus mIconStatus = IconStatus.NotQueried;
- private HSIconFileElement mIconFileElement;
- private IconInfo mIconInfo;
-
- public OSUInfo(long bssid, String ssid, OSUProvider osuProvider, int osuID) {
- mOsuID = osuID;
- mBSSID = bssid;
- mSSID = ssid;
- mOSUProvider = osuProvider;
- }
-
- public Set<Locale> getNameLocales() {
- Set<Locale> locales = new HashSet<>(mOSUProvider.getNames().size());
- for (I18Name name : mOSUProvider.getNames()) {
- locales.add(name.getLocale());
- }
- return locales;
- }
-
- public Set<Locale> getServiceLocales() {
- Set<Locale> locales = new HashSet<>(mOSUProvider.getServiceDescriptions().size());
- for (I18Name name : mOSUProvider.getServiceDescriptions()) {
- locales.add(name.getLocale());
- }
- return locales;
- }
-
- public Set<String> getIconLanguages() {
- Set<String> locales = new HashSet<>(mOSUProvider.getIcons().size());
- for (IconInfo iconInfo : mOSUProvider.getIcons()) {
- locales.add(iconInfo.getLanguage());
- }
- return locales;
- }
-
- public String getName(Locale locale) {
- for (I18Name name : mOSUProvider.getNames()) {
- if (locale == null || name.getLocale().equals(locale)) {
- return name.getText();
- }
- }
- return null;
- }
-
- public String getServiceDescription(Locale locale) {
- for (I18Name service : mOSUProvider.getServiceDescriptions()) {
- if (locale == null || service.getLocale().equals(locale)) {
- return service.getText();
- }
- }
- return null;
- }
-
- public int getOsuID() {
- return mOsuID;
- }
-
- public void setIconStatus(IconStatus iconStatus) {
- synchronized (mOSUProvider) {
- mIconStatus = iconStatus;
- }
- }
-
- public IconStatus getIconStatus() {
- synchronized (mOSUProvider) {
- return mIconStatus;
- }
- }
-
- public HSIconFileElement getIconFileElement() {
- synchronized (mOSUProvider) {
- return mIconFileElement;
- }
- }
-
- public IconInfo getIconInfo() {
- synchronized (mOSUProvider) {
- return mIconInfo;
- }
- }
-
- public void setIconFileElement(HSIconFileElement iconFileElement, String fileName) {
- synchronized (mOSUProvider) {
- mIconFileElement = iconFileElement;
- for (IconInfo iconInfo : mOSUProvider.getIcons()) {
- if (iconInfo.getFileName().equals(fileName)) {
- mIconInfo = iconInfo;
- break;
- }
- }
- mIconStatus = IconStatus.Available;
- }
- }
-
- private static class ScoredIcon implements Comparable<ScoredIcon> {
- private final IconInfo mIconInfo;
- private final int mScore;
-
- private ScoredIcon(IconInfo iconInfo, int score) {
- mIconInfo = iconInfo;
- mScore = score;
- }
-
- public IconInfo getIconInfo() {
- return mIconInfo;
- }
-
- @Override
- public int compareTo(ScoredIcon other) {
- return Integer.compare(mScore, other.mScore);
- }
- }
-
- public List<IconInfo> getIconInfo(Locale locale, Set<String> types, int width, int height) {
- if (mOSUProvider.getIcons().isEmpty()) {
- return null;
- }
- Log.d(OSUManager.TAG, "Matching icons against " + locale + ", types " + types + ", " + width + "*" + height);
-
- List<ScoredIcon> matches = new ArrayList<>();
- for (IconInfo iconInfo : mOSUProvider.getIcons()) {
- Log.d(OSUManager.TAG, "Checking icon " + iconInfo.toString());
- if (!types.contains(iconInfo.getIconType())) {
- continue;
- }
-
- int score = languageScore(iconInfo, locale);
- int delta = iconInfo.getWidth() - width;
- // Best size score is 1024 for a exact match, i.e. 2048 if both sides match
- if (delta >= 0) {
- score += (256 - delta) * 4; // Prefer down-scaling
- }
- else {
- score += 256 + delta; // Before up-scaling
- }
- delta = iconInfo.getHeight() - height;
- if (delta >= 0) {
- score += (256 - delta) * 4;
- }
- else {
- score += 256 + delta;
- }
- matches.add(new ScoredIcon(iconInfo, score));
- }
- if (matches.isEmpty()) {
- return Collections.emptyList();
- }
- Collections.sort(matches);
- List<IconInfo> icons = new ArrayList<>(matches.size());
- for (ScoredIcon scoredIcon : matches) {
- icons.add(scoredIcon.getIconInfo());
- }
- return icons;
- }
-
- private static int languageScore(IconInfo iconInfo, Locale locale) {
- String iconLanguage = iconInfo.getLanguage();
- if (iconLanguage.length() == 3 && iconLanguage.equalsIgnoreCase(locale.getISO3Language()) ||
- iconLanguage.length() == 2 && iconLanguage.equalsIgnoreCase(locale.getLanguage())) {
- return 4096;
- }
- else if (iconLanguage.equalsIgnoreCase(GenericLocale)) {
- return 3072;
- }
- else if (iconLanguage.equalsIgnoreCase("eng")) {
- return 2048;
- }
- else {
- return 1024;
- }
- }
-
- public long getBSSID() {
- return mBSSID;
- }
-
- public String getSSID() {
- return mSSID;
- }
-
- public OSUProvider getOSUProvider() {
- return mOSUProvider;
- }
-
- @Override
- public String toString() {
- return String.format("OSU Info '%s' %012x -> %s",
- mSSID, mBSSID, mOSUProvider.getOSUServer());
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUListener.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUListener.java
deleted file mode 100644
index 6775450d5..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUListener.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public interface OSUListener {
- public void osuNotification(int count);
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUManager.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUManager.java
deleted file mode 100644
index ae6386219..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUManager.java
+++ /dev/null
@@ -1,1088 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.CaptivePortal;
-import android.net.ConnectivityManager;
-import android.net.ICaptivePortal;
-import android.net.Network;
-import android.net.wifi.WifiConfiguration;
-import android.net.wifi.WifiInfo;
-import android.net.wifi.WifiManager;
-import android.os.UserHandle;
-import android.util.Log;
-
-import com.android.server.ConnectivityService;
-import com.android.server.wifi.ScanDetail;
-import com.android.server.wifi.WifiConfigStore;
-import com.android.server.wifi.WifiMonitor;
-import com.android.server.wifi.WifiStateMachine;
-import com.android.server.wifi.anqp.ANQPElement;
-import com.android.server.wifi.anqp.Constants;
-import com.android.server.wifi.anqp.HSOsuProvidersElement;
-import com.android.server.wifi.anqp.OSUProvider;
-import com.android.server.wifi.configparse.ConfigBuilder;
-import com.android.server.wifi.hotspot2.IconEvent;
-import com.android.server.wifi.hotspot2.NetworkDetail;
-import com.android.server.wifi.hotspot2.OMADMAdapter;
-import com.android.server.wifi.hotspot2.PasspointMatch;
-import com.android.server.wifi.hotspot2.SupplicantBridge;
-import com.android.server.wifi.hotspot2.Utils;
-import com.android.server.wifi.hotspot2.WifiNetworkAdapter;
-import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager;
-import com.android.server.wifi.hotspot2.omadm.MOTree;
-import com.android.server.wifi.hotspot2.osu.commands.PasspointManagementObjectData;
-import com.android.server.wifi.hotspot2.osu.service.RedirectListener;
-import com.android.server.wifi.hotspot2.osu.service.SubscriptionTimer;
-import com.android.server.wifi.hotspot2.pps.HomeSP;
-import com.android.server.wifi.hotspot2.pps.UpdateInfo;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.net.ssl.KeyManager;
-
-import static com.android.server.wifi.anqp.Constants.ANQPElementType.ANQPDomName;
-import static com.android.server.wifi.anqp.Constants.ANQPElementType.HSOSUProviders;
-
-public class OSUManager {
- public static final String TAG = "OSUMGR";
- public static final boolean R2_TEST = false;
-
- private static final int MAX_SCAN_MISSES = 15;
- private static final long REMEDIATION_TIMEOUT = 120000L;
- // How many scan result batches to hang on to
- private static final int SCAN_BATCH_HISTORY = 3;
-
- public enum FlowType {Provisioning, Remediation, Policy}
-
- private static final Set<String> IconTypes = new HashSet<>(Arrays.asList("image/png", "image/jpeg"));
- private static final int IconWidth = 16;
- private static final int IconHeight = 16;
- private static final Locale Locale = java.util.Locale.getDefault();
-
- private final WifiNetworkAdapter mWifiNetworkAdapter;
-
- private final boolean mEnabled;
- private final Context mContext;
- private final SupplicantBridge mSupplicantBridge;
- private final WifiConfigStore mWifiConfigStore;
- private final IconCache mIconCache;
- private final PasspointManagementObjectManager mMOManager;
- private final SubscriptionTimer mSubscriptionTimer;
- private final Map<OSUListener, Boolean> mOSUListeners = new IdentityHashMap<>();
- private final Set<String> mOSUSSIDs = new HashSet<>();
- private final Map<OSUProvider, OSUInfo> mOSUMap = new HashMap<>();
- private RedirectListener mRedirectListener;
- private volatile UserInputListener mUserInputListener;
- private volatile boolean mIconQueryEnable;
- private WifiConfiguration mActiveConfig;
- private final Object mRemediationLock = new Object();
- private long mRemediationBSSID;
- private String mRemediationURL;
- private final AtomicInteger mOSUSequence = new AtomicInteger();
- private OSUThread mProvisioningThread;
- private final Map<String, OSUThread> mServiceThreads = new HashMap<>();
-
- // Variables that holds transient data during scans
- private boolean mScanComplete;
- private boolean mNewScan;
- private final Set<Long> mOutstandingQueries = new HashSet<>();
- private final Map<Long, AtomicInteger> mScanHistory = new HashMap<>(); // BSSID -> missing scan count
- private final Map<Long, HSOsuProvidersElement> mTransientOSUMap = new HashMap<>();
- private final Map<Long, HSOsuProvidersElement> mCachedOSUMap = new HashMap<>();
- private final Map<Long, NetworkDetail> mLastScanBatch = new HashMap<>();
- private final LinkedList<Map<Long, NetworkDetail>> mLastScanBatches = new LinkedList<>();
-
- public OSUManager(WifiConfigStore wifiConfigStore, Context context,
- SupplicantBridge supplicantBridge, PasspointManagementObjectManager moManager,
- WifiStateMachine wifiStateMachine) {
- mWifiConfigStore = wifiConfigStore;
- mContext = context;
- mSupplicantBridge = supplicantBridge;
- mIconCache = new IconCache(this);
- mWifiNetworkAdapter = new WifiNetworkAdapter(context, this, wifiStateMachine, wifiConfigStore);
- mMOManager = moManager;
- mSubscriptionTimer = new SubscriptionTimer(this, moManager, context);
- mEnabled = moManager.isEnabled();
- mNewScan = true;
- mIconQueryEnable = true; // For testing only
- }
-
- private static class OSUThread extends Thread {
- private final OSUClient mOSUClient;
- private final OSUManager mOSUManager;
- private final HomeSP mHomeSP;
- private final FlowType mFlowType;
- private final KeyManager mKeyManager;
- private final long mLaunchTime;
- private final Object mLock = new Object();
- private boolean mLocalAddressSet;
- private Network mNetwork;
-
- private OSUThread(OSUInfo osuInfo, OSUManager osuManager, KeyManager km) throws MalformedURLException {
- mOSUClient = new OSUClient(osuInfo);
- mOSUManager = osuManager;
- mHomeSP = null;
- mFlowType = FlowType.Provisioning;
- mKeyManager = km;
- mLaunchTime = System.currentTimeMillis();
-
- setDaemon(true);
- setName("OSU Client Thread");
- }
-
- private OSUThread(String osuURL, OSUManager osuManager, KeyManager km, HomeSP homeSP,
- FlowType flowType) throws MalformedURLException {
- mOSUClient = new OSUClient(osuURL);
- mOSUManager = osuManager;
- mHomeSP = homeSP;
- mFlowType = flowType;
- mKeyManager = km;
- mLaunchTime = System.currentTimeMillis();
-
- setDaemon(true);
- setName("OSU Client Thread");
- }
-
- public long getLaunchTime() {
- return mLaunchTime;
- }
-
- private void connect(Network network) {
- synchronized (mLock) {
- mNetwork = network;
- mLocalAddressSet = true;
- mLock.notifyAll();
- }
- Log.d(TAG, "Client notified...");
- }
-
- @Override
- public void run() {
- Log.d(TAG, mFlowType + "-" + getName() + " running.");
- Network network;
- synchronized (mLock) {
- while (!mLocalAddressSet) {
- try {
- mLock.wait();
- }
- catch (InterruptedException ie) {
- /**/
- }
- Log.d(TAG, "Good morning!");
- }
- network = mNetwork;
- }
-
- long remaining = 10000L;
- long until = System.currentTimeMillis() + remaining;
- while (remaining > 0) {
- try {
- Thread.sleep(remaining);
- } catch (InterruptedException ie) {
-
- }
- remaining = until - System.currentTimeMillis();
- }
- Log.d(TAG, "OK, off we go...");
-
- if (network == null) {
- Log.d(TAG, "Association failed, exiting OSU flow");
- mOSUManager.provisioningFailed("Network cannot be reached", mHomeSP, mFlowType);
- return;
- }
-
- Log.d(TAG, "OSU SSID Associated at " + network.toString());
- try {
- switch (mFlowType) {
- case Provisioning:
- mOSUClient.provision(mOSUManager, network, mKeyManager);
- break;
- case Remediation:
- mOSUClient.remediate(mOSUManager, network, mKeyManager, mHomeSP, false);
- break;
- case Policy:
- mOSUClient.remediate(mOSUManager, network, mKeyManager, mHomeSP, true);
- break;
- }
- }
- catch (Throwable t) {
- Log.w(TAG, "OSU flow failed: " + t, t);
- mOSUManager.provisioningFailed(t.getMessage(), mHomeSP, mFlowType);
- }
- }
- }
-
- public void addMockOSUEnvironment(final OSUManager osuManager) {
- osuManager.registerUserInputListener(new UserInputListener() {
- @Override
- public void requestUserInput(URL target, Network network, URL endRedirect) {
- Log.d(TAG, "Browser to " + target + ", land at " + endRedirect);
-
- final Intent intent = new Intent(
- ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK, network);
- intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
- new CaptivePortal(new ICaptivePortal.Stub() {
- @Override
- public void appResponse(int response) {
- }
- }));
- //intent.setData(Uri.parse(target.toString())); !!! Doesn't work!
- intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL, target.toString());
- intent.setFlags(
- Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivityAsUser(intent, UserHandle.CURRENT);
- }
-
- @Override
- public String operationStatus(OSUOperationStatus status, String message) {
- Log.d(TAG, "OSU OP Status: " + status + ", message " + message);
- return null;
- }
-
- @Override
- public void deAuthNotification(boolean ess, URL url) {
- Log.i(TAG, "De-authentication imminent for " + (ess ? "ess" : "bss") +
- ", redirect to " + url);
- }
- });
- osuManager.addOSUListener(new OSUListener() {
- @Override
- public void osuNotification(int count) {
- }
- });
- mWifiNetworkAdapter.initialize();
- //mSubscriptionTimer.checkUpdates(); // !!! Looks like there's a bug associated with this.
- }
-
- public boolean enableOSUQueries() {
- return mUserInputListener != null;
- }
-
- public void addOSUListener(OSUListener listener) {
- synchronized (mOSUListeners) {
- mOSUListeners.put(listener, Boolean.TRUE);
- }
- }
-
- public void removeOSUListener(OSUListener listener) {
- synchronized (mOSUListeners) {
- mOSUListeners.remove(listener);
- }
- }
-
- public void registerUserInputListener(UserInputListener listener) {
- mUserInputListener = listener;
- }
-
- public void recheckTimers() {
- mSubscriptionTimer.checkUpdates();
- }
-
- /**
- * Called when an OSU has been selected and the associated network is fully connected.
- * @param osuInfo The selected OSUInfo or null if the current OSU flow is cancelled externally,
- * e.g. WiFi is turned off or the OSU network is otherwise detected as
- * unreachable.
- * @param network The currently associated network (for the OSU SSID).
- * @throws IOException
- * @throws GeneralSecurityException
- */
- public void initiateProvisioning(OSUInfo osuInfo, Network network)
- throws IOException, GeneralSecurityException {
- if (mUserInputListener == null) {
- throw new RuntimeException("No user input handler specified");
- }
-
- synchronized (mWifiNetworkAdapter) {
- if (mProvisioningThread != null) {
- mProvisioningThread.connect(null);
- mProvisioningThread = null;
- }
- if (mRedirectListener != null) {
- mRedirectListener.abort();
- mRedirectListener = null;
- }
- if (osuInfo != null) {
- //new ConnMonitor().start();
- mProvisioningThread = new OSUThread(osuInfo, this, getKeyManager(null));
- mProvisioningThread.start();
- //mWifiNetworkAdapter.associate(osuInfo.getSSID(),
- // osuInfo.getBSSID(), osuInfo.getOSUProvider().getOsuNai());
- mProvisioningThread.connect(network);
- }
- }
- }
-
- /**
- * !!! Get a KeyManager for TLS client side auth.
- * @param config The configuration associated with the keying material in question. Passing
- * null currently returns a null KeyManager, but to support pre-provisioned certs
- * in the future an appropriate KeyManager should be created which needs to check
- * for the correct key-pair during the provisioning phase based on the issuer
- * names retrieved from the ClientCertInfo request.
- * @return A key manager suitable for the given configuration (or pre-provisioned keys).
- */
- private static KeyManager getKeyManager(WifiConfiguration config) throws IOException {
- return config != null ? new ClientKeyManager(config) : new WiFiKeyManager();
- }
-
- private static class ConnMonitor extends Thread {
- private ConnMonitor() {
- }
-
- @Override
- public void run() {
- for (;;) {
- try {
- ProcessBuilder psb = new ProcessBuilder("/system/bin/netstat", "-tn");
- psb.redirectErrorStream();
- Process ps = psb.start();
- try (BufferedReader in = new BufferedReader(new InputStreamReader(ps.getInputStream()))) {
- String line;
- StringBuilder sb = new StringBuilder();
- while ((line = in.readLine()) != null) {
- sb.append(line).append('\n');
- }
- Log.d("CNI", sb.toString());
- Log.d("CNI", "*eof*");
- }
- }
- catch (IOException ioe) {
- Log.d("CNI", "IOE: " + ioe);
- }
-
- long remaining = 1000L;
- long until = System.currentTimeMillis() + remaining;
- while (remaining > 0) {
- try {
- Thread.sleep(remaining);
- }
- catch (InterruptedException ie) { /**/ }
- remaining = until - System.currentTimeMillis();
- }
- }
- }
- }
-
- public Collection<OSUInfo> getAvailableOSUs() {
- synchronized (mOSUMap) {
- List<OSUInfo> completeOSUs = new ArrayList<>();
- for (OSUInfo osuInfo : mOSUMap.values()) {
- if (osuInfo.getIconStatus() == OSUInfo.IconStatus.Available) {
- completeOSUs.add(osuInfo);
- }
- }
- return completeOSUs;
- }
- }
-
- public boolean isOSU(String ssid) {
- synchronized (mOSUMap) {
- return mOSUSSIDs.contains(ssid);
- }
- }
-
- public void setOSUSelection(int osuID) {
-
- }
-
- public void addScanResult(NetworkDetail networkDetail) {
- if (mNewScan) {
- mOutstandingQueries.clear();
- mNewScan = false;
- }
- Map<Constants.ANQPElementType, ANQPElement> anqpElements = networkDetail.getANQPElements();
- if (anqpElements != null) {
- HSOsuProvidersElement osuProviders =
- (HSOsuProvidersElement) anqpElements.get(HSOSUProviders);
- if (osuProviders != null) {
- mTransientOSUMap.put(networkDetail.getBSSID(), osuProviders);
- }
- }
- mLastScanBatch.put(networkDetail.getBSSID(), networkDetail);
- }
-
- /**
- * Notification that the current scan is complete. MUST be called after any ANQP queries have
- * been initiated.
- */
- public void scanComplete() {
- if (!mEnabled) {
- return;
- }
- mScanComplete = true;
- mNewScan = true;
-
- Log.d("ZYX", "Scan complete: " + toBSSIDStrings(mOutstandingQueries));
- if (mOutstandingQueries.isEmpty()) {
- updateAvailableOSUs();
- }
- }
-
- private static String toBSSIDStrings(Set<Long> bssids) {
- StringBuilder sb = new StringBuilder();
- for (Long bssid : bssids) {
- sb.append(String.format(" %012x", bssid));
- }
- return sb.toString();
- }
-
- public void anqpInitiated(ScanDetail scanDetail) {
- Log.d("ZYX+", String.format("%012x", scanDetail.getNetworkDetail().getBSSID()));
- mOutstandingQueries.add(scanDetail.getNetworkDetail().getBSSID());
- }
-
- public void anqpDone(ScanDetail scanDetail,
- Map<Constants.ANQPElementType, ANQPElement> elements) {
- long bssid = scanDetail.getNetworkDetail().getBSSID();
- Log.d("ZYX-", String.format("%012x", bssid));
- mOutstandingQueries.remove(bssid);
- if (elements != null) {
- HSOsuProvidersElement osuProviders =
- (HSOsuProvidersElement) elements.get(HSOSUProviders);
- Log.d(TAG, "ANQP OSU result: " + osuProviders);
- if (osuProviders != null) {
- mTransientOSUMap.put(bssid, osuProviders);
- }
- }
- if (mOutstandingQueries.isEmpty() && mScanComplete) {
- updateAvailableOSUs();
- }
- }
-
- private static <T> List<T> additions(List<T> oldList, List<T> newList) {
- if (oldList == null) {
- return newList;
- }
- List<T> additions = new ArrayList<>();
- for (T element : newList) {
- if (!oldList.contains(element)) {
- additions.add(element);
- }
- }
- return additions;
- }
-
- private static <T> List<T> deletions(List<T> oldList, List<T> newList) {
- List<T> deletions = new ArrayList<>();
- if (oldList == null) {
- return deletions;
- }
- for (T element : oldList) {
- if (!newList.contains(element)) {
- deletions.add(element);
- }
- }
- return deletions;
- }
-
- private void updateAvailableOSUs() {
- boolean change = false;
- int osuCount;
-
- Log.d(TAG, "OSU Provider update: " + mTransientOSUMap);
- synchronized (mOSUMap) {
- for (Map.Entry<Long, HSOsuProvidersElement> entry : mTransientOSUMap.entrySet()) {
- HSOsuProvidersElement osuProviders = entry.getValue();
- long bssid = entry.getKey();
-
- HSOsuProvidersElement cached = mCachedOSUMap.get(bssid);
- List<OSUProvider> cachedProviders = cached != null ? cached.getProviders() : null;
- List<OSUProvider> added = additions(cachedProviders, osuProviders.getProviders());
- List<OSUProvider> dropped = deletions(cachedProviders, osuProviders.getProviders());
-
- boolean anyValid = false;
- if (!added.isEmpty()) {
- for (OSUProvider osuProvider : added) {
- if (osuProvider.getOSUMethods().contains(OSUProvider.OSUMethod.SoapXml)) {
- anyValid = true;
- if (!mOSUMap.containsKey(osuProvider)) {
- mOSUMap.put(osuProvider,
- new OSUInfo(bssid, osuProviders.getSSID(),
- osuProvider, mOSUSequence.getAndIncrement()));
- change = true;
- }
- }
- }
- }
- if (!dropped.isEmpty()) {
- for (OSUProvider osuProvider : dropped) {
- if (mOSUMap.remove(osuProvider) != null) {
- change = true;
- }
- }
- }
-
- if (anyValid) {
- mCachedOSUMap.put(bssid, osuProviders);
- mScanHistory.put(bssid, new AtomicInteger(1));
- }
- }
-
- // Scan results tend to disappear intermittently from scan batches.
- // To demote OSUs coming and going, mScanHistory contains historical OSU information and
- // is augmented by mScanHistory that is a parallel map that contains a "retention count"
- // per BSSID.
- // Missing scan results are removed from the cached map only after MAX_SCAN_MISSES.
-
- Iterator<Map.Entry<Long, HSOsuProvidersElement>> entries =
- mCachedOSUMap.entrySet().iterator();
-
- while (entries.hasNext()) {
- Map.Entry<Long, HSOsuProvidersElement> entry = entries.next();
- long bssid = entry.getKey();
- if (!mTransientOSUMap.containsKey(bssid)) {
- AtomicInteger skipCount = mScanHistory.get(bssid);
- if (skipCount.incrementAndGet() > MAX_SCAN_MISSES) {
- mScanHistory.remove(bssid);
- for (OSUProvider osuProvider : entry.getValue().getProviders()) {
- mOSUMap.remove(osuProvider);
- }
- entries.remove();
- change = true;
- Log.d(TAG, "Removed cached OSU provider " + entry.getValue());
- }
- }
- }
-
- mTransientOSUMap.clear();
- mLastScanBatches.addFirst(new HashMap<>(mLastScanBatch));
- if (mLastScanBatches.size() > SCAN_BATCH_HISTORY) {
- mLastScanBatches.removeLast();
- }
- mLastScanBatch.clear();
- mScanComplete = false;
-
- if (change) {
- mOSUSSIDs.clear();
- for (OSUInfo osuInfo : mOSUMap.values()) {
- mOSUSSIDs.add(osuInfo.getSSID());
- }
- }
-
- if (mIconQueryEnable) {
- initiateIconQueries();
- }
- osuCount = mOSUMap.size();
- }
-
- if (change) {
- List<OSUListener> listeners;
- synchronized (mOSUListeners) {
- listeners = new ArrayList<>(mOSUListeners.keySet());
- }
- Log.d(TAG, "OSU Update: " + mOSUMap);
- for (OSUListener listener : listeners) {
- listener.osuNotification(osuCount);
- }
- }
- }
-
- private void initiateIconQueries() {
- for (OSUInfo osuInfo : mOSUMap.values()) {
- if (osuInfo.getIconStatus() == OSUInfo.IconStatus.NotQueried) {
- mIconCache.startIconQuery(osuInfo,
- osuInfo.getIconInfo(Locale, IconTypes, IconWidth, IconHeight));
- }
- }
- }
-
- public void tickleIconCache(boolean all) {
- mIconCache.tickle(all);
- }
-
- public void enableIconQuery(boolean on) {
- mIconQueryEnable = on;
- if (mIconQueryEnable) {
- initiateIconQueries();
- }
- }
-
- public SupplicantBridge getSupplicantBridge() {
- return mSupplicantBridge;
- }
-
- public void setActiveNetwork(WifiConfiguration wifiConfiguration) {
- long bssid;
- String url;
- synchronized (mRemediationLock) {
- mActiveConfig = wifiConfiguration;
- bssid = mRemediationBSSID;
- url = mRemediationURL;
- if (wifiConfiguration != null) {
- mRemediationBSSID = 0L;
- mRemediationURL = null;
- }
- }
- if (bssid != 0L && url != null && wifiConfiguration != null) {
- try {
- wnmRemediate(bssid, url, wifiConfiguration);
- } catch (IOException ioe) {
- Log.w(TAG, "Failed to execute remediation request: " + ioe.getMessage());
- }
- }
- /*
- // !!! Hack to force start remediation at connection time
- else if (wifiConfiguration != null && wifiConfiguration.isPasspoint()) {
- HomeSP homeSP = mWifiConfigStore.getHomeSPForConfig(wifiConfiguration);
- if (homeSP != null && homeSP.getSubscriptionUpdate() != null) {
- if (!mServiceThreads.containsKey(homeSP.getFQDN())) {
- try {
- remediate(homeSP);
- } catch (IOException ioe) {
- Log.w(TAG, "Failed to remediate: " + ioe);
- }
- }
- }
- }
- */
- else if (wifiConfiguration == null) {
- mServiceThreads.clear();
- }
- }
-
- public void wnmReceived(String event){
- try {
- Log.d(TAG, "Received WNM: " + event);
- decodeWnmFrame(event);
- }
- catch (IOException | NumberFormatException e) {
- Log.w(TAG, "Bad WNM event '" + event + "': " + e.toString());
- }
- }
-
- public void decodeWnmFrame(String event) throws IOException {
- // %012x HS20-SUBSCRIPTION-REMEDIATION "%u %s", osu_method, url
- // %012x HS20-DEAUTH-IMMINENT-NOTICE "%u %u %s", code, reauth_delay, url
-
- String[] segments = event.split(" ");
- if (segments.length < 2) {
- throw new IOException("Short event");
- }
-
- long bssid = Long.parseLong(segments[0], 16);
-
- switch (segments[1]) {
- case WifiMonitor.HS20_SUB_REM_STR: {
- if (segments.length != 4) {
- throw new IOException("Expected 4 segments");
- }
- int protoID = Integer.parseInt(segments[2]);
- if (protoID >= OSUProvider.OSUMethod.values().length || protoID < 0) {
- throw new IOException("Unknown OSU Method");
- }
- OSUProvider.OSUMethod method = OSUProvider.OSUMethod.values()[protoID];
- if (method != OSUProvider.OSUMethod.SoapXml) {
- throw new IOException(method + " is not supported");
- }
-
- String url = segments[3];
-
- WifiConfiguration current;
- synchronized (mRemediationLock) {
- current = mActiveConfig;
- if (current == null) {
- mRemediationBSSID = bssid;
- mRemediationURL = url;
- }
- else {
- mRemediationBSSID = 0L;
- mRemediationURL = null;
- }
- }
- Log.d(TAG, String.format(
- "Subscription remediation %012x using %s to '%s', current %s",
- bssid, method, url, current != null ? current.SSID : "-"));
- if (current != null) {
- try {
- wnmRemediate(bssid, url, current);
- } catch (IOException ioe) {
- Log.w(TAG, "Failed to execute remediation request: " + ioe.getMessage());
- }
- }
- break;
- }
- case WifiMonitor.HS20_DEAUTH_STR: {
- if (segments.length != 5) {
- throw new IOException("Expected 5 segments");
- }
- int codeID = Integer.parseInt(segments[2]);
- if (codeID < 0 || codeID > 1) {
- throw new IOException("Unknown code");
- }
- boolean ess = codeID == 1; // Otherwise BSS
- int delay = Integer.parseInt(segments[3]);
- String url = segments[4];
- Log.d(TAG, String.format("De-auth imminent on %s, delay %ss to '%s'",
- ess ? "ess" : "bss",
- delay,
- url));
- mWifiNetworkAdapter.setHoldoffTime(delay * Constants.MILLIS_IN_A_SEC, ess);
- mUserInputListener.deAuthNotification(ess, new URL(url));
- break;
- }
- default:
- throw new IOException("Unknown event type");
- }
- }
-
- private void wnmRemediate(long bssid, String url, WifiConfiguration config) throws IOException {
- HomeSP homeSP = mWifiConfigStore.getHomeSPForConfig(config);
- if (homeSP == null) {
- throw new IOException("Remediation request for unidentified Passpoint network " +
- config.networkId);
- }
- Network network = mWifiNetworkAdapter.getCurrentNetwork();
- if (network == null) {
- throw new IOException("Failed to determine current network");
- }
- WifiInfo wifiInfo = mWifiNetworkAdapter.getConnectionInfo();
- if (wifiInfo == null || Utils.parseMac(wifiInfo.getBSSID()) != bssid) {
- throw new IOException("Mismatching BSSID");
- }
- Log.d(TAG, "WNM Remediation on " + network.netId + " FQDN " + homeSP.getFQDN());
-
- doRemediate(url, network, homeSP, false);
- }
-
- public void remediate(HomeSP homeSP, boolean policy) throws IOException {
- UpdateInfo updateInfo;
- if (policy) {
- if (homeSP.getPolicy() == null) {
- throw new IOException("No policy object");
- }
- updateInfo = homeSP.getPolicy().getPolicyUpdate();
- }
- else {
- updateInfo = homeSP.getSubscriptionUpdate();
- }
- switch (updateInfo.getUpdateRestriction()) {
- case HomeSP: {
- Network network = mWifiNetworkAdapter.getCurrentNetwork();
- if (network == null) {
- throw new IOException("Failed to determine current network");
- }
-
- WifiConfiguration config = mActiveConfig;
- if (config == null) {
- throw new IOException("No network association, cannot remediate at this time");
- }
-
- HomeSP activeSP = mWifiConfigStore.getHomeSPForConfig(config);
-
- if (activeSP == null || !activeSP.getFQDN().equals(homeSP.getFQDN())) {
- throw new IOException("Remediation restricted to HomeSP");
- }
- doRemediate(updateInfo.getURI(), network, homeSP, policy);
- break;
- }
- case RoamingPartner: {
- Network network = mWifiNetworkAdapter.getCurrentNetwork();
- if (network == null) {
- throw new IOException("Failed to determine current network");
- }
-
- WifiInfo wifiInfo = mWifiNetworkAdapter.getConnectionInfo();
- if (wifiInfo == null) {
- throw new IOException("Unable to determine WiFi info");
- }
- long bssid = Utils.parseMac(wifiInfo.getBSSID());
- NetworkDetail networkDetail = null;
- for (Map<Long, NetworkDetail> map : mLastScanBatches) {
- networkDetail = map.get(bssid);
- if (networkDetail != null) {
- break;
- }
- }
- if (networkDetail == null) {
- throw new IOException("Failed to find information for current network");
- }
- Map<Constants.ANQPElementType, ANQPElement> anqpData =
- networkDetail.getANQPElements();
- if (anqpData == null || !anqpData.containsKey(ANQPDomName)) {
- anqpData = mWifiConfigStore.getANQPData(networkDetail);
- }
- if (anqpData == null || !anqpData.containsKey(ANQPDomName)) {
- throw new IOException("Can't determine current network capabilities");
- }
- PasspointMatch match = homeSP.match(networkDetail, anqpData,
- mWifiConfigStore.getSIMAccessor());
- if (match == PasspointMatch.HomeProvider ||
- match == PasspointMatch.RoamingProvider) {
- doRemediate(updateInfo.getURI(), network, homeSP, policy);
- } else {
- throw new IOException("No roaming network match: " + match);
- }
- break;
- }
- case Unrestricted: {
- ConnectivityService connService = (ConnectivityService)
- mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- Network network = connService.getActiveNetwork();
-
- doRemediate(updateInfo.getURI(), network, homeSP, policy);
- break;
- }
- }
- }
-
- private void doRemediate(String url, Network network, HomeSP homeSP, boolean policy)
- throws IOException {
- synchronized (mWifiNetworkAdapter) {
- OSUThread existing = mServiceThreads.get(homeSP.getFQDN());
- if (existing != null) {
- if (System.currentTimeMillis() - existing.getLaunchTime() > REMEDIATION_TIMEOUT) {
- throw new IOException("Ignoring recurring remediation request");
- }
- else {
- existing.connect(null);
- }
- }
-
- try {
- OSUThread osuThread = new OSUThread(url, this,
- getKeyManager(mWifiNetworkAdapter.getWifiConfig(homeSP)),
- homeSP, policy ? FlowType.Policy : FlowType.Remediation);
- osuThread.start();
- osuThread.connect(network);
- mServiceThreads.put(homeSP.getFQDN(), osuThread);
- }
- catch (MalformedURLException me) {
- throw new IOException("Failed to start remediation: " + me);
- }
- }
- }
-
- public MOTree getMOTree(HomeSP homeSP) throws IOException {
- return mMOManager.getMOTree(homeSP);
- }
-
- public void notifyIconReceived(IconEvent iconEvent) {
- mIconCache.notifyIconReceived(iconEvent);
- }
-
- public void notifyIconFailed(long bssid) {
- mIconCache.notifyIconFailed(bssid);
- }
-
- public void iconResult(OSUInfo osuInfo) {
-
- }
-
- // SCAN_RESULTS_AVAILABLE_ACTION
-
- protected URL prepareUserInput() throws IOException {
- mRedirectListener = new RedirectListener(this);
- return mRedirectListener.getURL();
- }
-
- protected boolean startUserInput(URL target, Network network) throws IOException {
- mRedirectListener.startService();
- mUserInputListener.requestUserInput(target, network, mRedirectListener.getURL());
- return mRedirectListener.waitForUser();
- }
-
- public String notifyUser(OSUOperationStatus status, String message) {
- return mUserInputListener.operationStatus(status, message);
- }
-
- public void provisioningFailed(String message, HomeSP homeSP, FlowType flowType) {
- synchronized (mWifiNetworkAdapter) {
- switch (flowType) {
- case Provisioning:
- mProvisioningThread = null;
- if (mRedirectListener != null) {
- mRedirectListener.abort();
- mRedirectListener = null;
- }
- break;
- case Remediation:
- mServiceThreads.remove(homeSP.getFQDN());
- if (mServiceThreads.isEmpty() && mRedirectListener != null) {
- mRedirectListener.abort();
- mRedirectListener = null;
- }
- break;
- }
- }
- mUserInputListener.operationStatus(OSUOperationStatus.ProvisioningFailure, message);
- }
-
- public void provisioningComplete(PasspointManagementObjectData moData, Map<OSUCertType, List<X509Certificate>> certs,
- PrivateKey privateKey, Network osuNetwork) {
- synchronized (mWifiNetworkAdapter) {
- mProvisioningThread = null;
- }
- try {
- HomeSP homeSP = mMOManager.addSP(moData.getMOTree());
-
- WifiConfiguration config = ConfigBuilder.buildConfig(homeSP,
- certs.get(OSUCertType.AAA).iterator().next(),
- certs.get(OSUCertType.Client), privateKey);
-
- WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
- int nwkId = wifiManager.addNetwork(config);
- boolean saved = false;
- if (nwkId >= 0) {
- saved = wifiManager.saveConfiguration();
- }
- Log.d(TAG, "Wifi configuration " + nwkId + " " + (saved ? "saved" : "not saved"));
-
- if (!saved) {
- mUserInputListener.operationStatus(OSUOperationStatus.ProvisioningFailure,
- "Failed to save network configuration " + nwkId);
- mMOManager.removeSP(homeSP.getFQDN());
- mWifiNetworkAdapter.detachOSUNetwork(osuNetwork,
- WifiConfiguration.INVALID_NETWORK_ID);
- return;
- }
-
- mUserInputListener.operationStatus(OSUOperationStatus.ProvisioningSuccess, null);
-
- mWifiNetworkAdapter.detachOSUNetwork(osuNetwork, nwkId);
-
- Log.d(TAG, "Done, done.");
- Log.d(TAG, "Private key: " + privateKey);
- for (Map.Entry<OSUCertType, List<X509Certificate>> certEntry : certs.entrySet()) {
- StringBuilder sb = new StringBuilder();
- sb.append(certEntry.getKey()).append('\n');
- for (X509Certificate cert : certEntry.getValue()) {
- sb.append(" issued by ").append(cert.getIssuerX500Principal()).
- append(" to ").append(cert.getSubjectX500Principal()).append('\n');
- }
- Log.d(TAG, sb.toString());
- }
- }
- catch (IOException | GeneralSecurityException e) {
- mUserInputListener.operationStatus(OSUOperationStatus.ProvisioningFailure, e.toString());
- }
- }
-
- public void remediationComplete(HomeSP homeSP, Collection<PasspointManagementObjectData> mods,
- Map<OSUCertType, List<X509Certificate>> certs,
- PrivateKey privateKey)
- throws IOException, GeneralSecurityException {
-
- HomeSP altSP = null; //mMOManager.modifySP(homeSP.getFQDN(), mods);
- X509Certificate caCert = null;
- List<X509Certificate> clientCerts = null;
- if (certs != null) {
- List<X509Certificate> certList = certs.get(OSUCertType.AAA);
- caCert = certList != null && !certList.isEmpty() ? certList.iterator().next() : null;
- clientCerts = certs.get(OSUCertType.Client);
- }
- if (altSP != null || certs != null) {
- if (altSP == null) {
- altSP = homeSP; // No MO mods, only certs and key
- }
- mWifiNetworkAdapter.updateNetwork(altSP, caCert, clientCerts, privateKey);
- }
- mUserInputListener.operationStatus(OSUOperationStatus.ProvisioningSuccess, null);
- }
-
- /*
- TLS Server cert (from handshake):
- Issuer: C=US, O=WFA Hotspot 2.0, CN=Hotspot 2.0 Trust Root CA - 01
- Subject: C=US, O=NetworkFX, Inc., OU=OSU CA - 01, CN=NetworkFX, Inc. Hotspot 2.0 Intermediate CA
- X509v3 extensions:
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- Authority Information Access:
- OCSP - URI:http://wfa-ocsp.symauth.com
- X509v3 Basic Constraints: critical
- CA:TRUE, pathlen:0
- X509v3 Subject Alternative Name:
- DirName:/CN=SymantecPKI-1-557
- X509v3 Subject Key Identifier:
- 5D:0A:92:01:8F:4D:3F:05:11:5D:1F:1D:25:2A:19:49:A7:EE:07:EA
- X509v3 Authority Key Identifier:
- keyid:F9:18:C6:55:96:DE:6E:3A:73:10:F7:ED:85:A4:CB:A9:BB:D7:32:21
-
-
- AAA:
- Issuer: C=US, ST=California, L=Santa Clara, O=Wi-Fi Alliance, CN=WFA Root Certificate/emailAddress=support@wi-fi.org
- Subject: C=US, ST=California, L=Santa Clara, O=Wi-Fi Alliance, CN=WFA Root Certificate/emailAddress=support@wi-fi.org
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 0B:03:C2:3E:54:A2:28:BD:3E:49:DE:72:F1:5F:8E:AB:0E:97:67:82
- X509v3 Authority Key Identifier:
- keyid:0B:03:C2:3E:54:A2:28:BD:3E:49:DE:72:F1:5F:8E:AB:0E:97:67:82
- X509v3 Basic Constraints:
- CA:TRUE
-
- CA:
- Issuer: C=US, ST=California, L=Santa Clara, O=Wi-Fi Alliance, CN=WFA Root Certificate/emailAddress=support@wi-fi.org
- Subject: C=US, ST=California, L=Santa Clara, O=Wi-Fi Alliance, CN=WFA Root Certificate/emailAddress=support@wi-fi.org
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 0B:03:C2:3E:54:A2:28:BD:3E:49:DE:72:F1:5F:8E:AB:0E:97:67:82
- X509v3 Authority Key Identifier:
- keyid:0B:03:C2:3E:54:A2:28:BD:3E:49:DE:72:F1:5F:8E:AB:0E:97:67:82
- X509v3 Basic Constraints:
- CA:TRUE
-
- Client (for EAP-TLS):
- Issuer: CN=RuckusCA, O=Ruckus, C=IL
- Subject: CN=ccbba6cd-ecf4-47f3-85b4-fc85c2f6c5d1, O=Google, C=US
- X509v3 extensions:
- X509v3 Subject Key Identifier:
- 63:7C:DE:C6:FB:C4:F5:8B:38:D4:16:E2:BD:0C:58:78:E7:74:63:DC
- X509v3 Basic Constraints: critical
- CA:FALSE
- X509v3 Authority Key Identifier:
- keyid:C8:A3:66:47:55:A4:2C:3A:4F:42:23:75:F0:66:2B:6A:0B:E8:47:DE
- X509v3 Key Usage: critical
- Digital Signature, Non Repudiation, Key Encipherment
- X509v3 Extended Key Usage:
- TLS Web Client Authentication, E-mail Protection
-
- Policy:
- Issuer: C=US, O=WFA Hotspot 2.0, CN=Hotspot 2.0 Trust Root CA - 01
- Validity
- Subject: C=US, O=WFA Hotspot 2.0, CN=Hotspot 2.0 Trust Root CA - 01
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- F9:18:C6:55:96:DE:6E:3A:73:10:F7:ED:85:A4:CB:A9:BB:D7:32:21
-
- Remediation:
- Issuer: C=US, O=WFA Hotspot 2.0, CN=Hotspot 2.0 Trust Root CA - 01
- Subject: C=US, O=WFA Hotspot 2.0, CN=Hotspot 2.0 Trust Root CA - 01
- X509v3 extensions:
- X509v3 Basic Constraints: critical
- CA:TRUE
- X509v3 Key Usage: critical
- Certificate Sign, CRL Sign
- X509v3 Subject Key Identifier:
- F9:18:C6:55:96:DE:6E:3A:73:10:F7:ED:85:A4:CB:A9:BB:D7:32:21
- */
-
- protected OMADMAdapter getOMADMAdapter() {
- return OMADMAdapter.getInstance(mContext);
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUMessageType.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUMessageType.java
deleted file mode 100644
index 9eaee5062..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUMessageType.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum OSUMessageType {
- PostDevData, ExchangeComplete, GetCertificate, Error
-
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUOperationStatus.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUOperationStatus.java
deleted file mode 100644
index b62f7f451..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUOperationStatus.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum OSUOperationStatus {
- UserInputComplete,
- UserInputAborted,
- ProvisioningSuccess,
- ProvisioningFailure
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUResponse.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUResponse.java
deleted file mode 100644
index 4a1a3ebd1..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUResponse.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.OMAConstants;
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public abstract class OSUResponse {
- private static final String SPPVersionAttribute = "sppVersion";
- private static final String SPPStatusAttribute = "sppStatus";
- private static final String SPPSessionIDAttribute = "sessionID";
-
- private final OSUMessageType mMessageType;
- private final String mVersion;
- private final String mSessionID;
- private final OSUStatus mStatus;
- private final OSUError mError;
- private final Map<String,String> mAttributes;
-
- protected OSUResponse(XMLNode root, OSUMessageType messageType, String ... attributes) throws OMAException {
- mMessageType = messageType;
- String ns = root.getNameSpace() + ":";
- mVersion = root.getAttributeValue(ns + SPPVersionAttribute);
- mSessionID = root.getAttributeValue(ns + SPPSessionIDAttribute);
-
- String status = root.getAttributeValue(ns + SPPStatusAttribute);
- if (status == null) {
- throw new OMAException("Missing status");
- }
- mStatus = OMAConstants.mapStatus(status);
-
- if (mVersion == null || mSessionID == null || mStatus == null) {
- throw new OMAException("Incomplete request: " + root.getAttributes());
- }
-
- if (attributes != null) {
- mAttributes = new HashMap<>();
- for (String attribute : attributes) {
- String value = root.getAttributeValue(ns + attribute);
- if (value == null) {
- throw new OMAException("Missing attribute: " + attribute);
- }
- mAttributes.put(attribute, value);
- }
- }
- else {
- mAttributes = null;
- }
-
- if (mStatus == OSUStatus.Error) {
- OSUError error = null;
- String errorTag = ns + "sppError";
- for (XMLNode child : root.getChildren()) {
- if (child.getTag().equals(errorTag)) {
- error = OMAConstants.mapError(child.getAttributeValue("errorCode"));
- break;
- }
- }
- mError = error;
- }
- else {
- mError = null;
- }
- }
-
- public OSUMessageType getMessageType() {
- return mMessageType;
- }
-
- public String getVersion() {
- return mVersion;
- }
-
- public String getSessionID() {
- return mSessionID;
- }
-
- public OSUStatus getStatus() {
- return mStatus;
- }
-
- public OSUError getError() {
- return mError;
- }
-
- protected Map<String, String> getAttributes() {
- return mAttributes;
- }
-
- @Override
- public String toString() {
- return String.format("%s version '%s', status %s, session-id '%s'%s",
- mMessageType, mVersion, mStatus, mSessionID, mError != null ? (" (" + mError + ")") : "");
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUSocketFactory.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUSocketFactory.java
deleted file mode 100644
index a37113383..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUSocketFactory.java
+++ /dev/null
@@ -1,369 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.net.Network;
-import android.util.Base64;
-import android.util.Log;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.URL;
-import java.security.GeneralSecurityException;
-import java.security.PrivateKey;
-import java.security.cert.CertPath;
-import java.security.cert.CertPathValidator;
-import java.security.cert.CertPathValidatorException;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.PKIXCertPathChecker;
-import java.security.cert.PKIXParameters;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.net.SocketFactory;
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-
-public class OSUSocketFactory {
- private static final String SecureHTTP = "https";
- private static final String UnsecureHTTP = "http";
- private static final String EKU_ID = "2.5.29.37";
- private static final Set<String> EKU_ID_SET = new HashSet<>(Arrays.asList(EKU_ID));
- private static final EKUChecker sEKUChecker = new EKUChecker();
-
- private final Network mNetwork;
- private final SocketFactory mSocketFactory;
- private final KeyManager mKeyManager;
- private final WFATrustManager mTrustManager;
- private final List<InetSocketAddress> mRemotes;
-
- private static Set<TrustAnchor> buildCertSet() {
- try {
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- Set<TrustAnchor> set = new HashSet<>();
- for (String b64 : WFACerts) {
- ByteArrayInputStream bis = new ByteArrayInputStream(Base64.decode(b64, Base64.DEFAULT));
- X509Certificate cert = (X509Certificate) certFactory.generateCertificate(bis);
- set.add(new TrustAnchor(cert, null));
- }
- return set;
- }
- catch (CertificateException ce) {
- Log.e(OSUManager.TAG, "Cannot build CA cert set");
- return null;
- }
- }
-
- public static OSUSocketFactory getSocketFactory(Network network, URL url, KeyManager km,
- boolean enforceSecurity)
- throws GeneralSecurityException, IOException {
-
- if (enforceSecurity && !url.getProtocol().equalsIgnoreCase(SecureHTTP)) {
- throw new IOException("Protocol '" + url.getProtocol() + "' is not secure");
- }
- return new OSUSocketFactory(network, url, km);
- }
-
- private OSUSocketFactory(Network network, URL url, KeyManager km)
- throws GeneralSecurityException, IOException {
- mNetwork = network;
- mKeyManager = km;
- mTrustManager = new WFATrustManager();
- int port;
- switch (url.getProtocol()) {
- case UnsecureHTTP:
- mSocketFactory = new DefaultSocketFactory();
- port = url.getPort() > 0 ? url.getPort() : 80;
- break;
- case SecureHTTP:
- SSLContext tlsContext = SSLContext.getInstance("TLSv1");
- tlsContext.init(km != null ? new KeyManager[] { km } : null,
- new TrustManager[] {mTrustManager}, null);
- mSocketFactory = tlsContext.getSocketFactory();
- port = url.getPort() > 0 ? url.getPort() : 443;
- break;
- default:
- throw new IOException("Bad URL: " + url);
- }
- if (OSUManager.R2_TEST && url.getHost().endsWith(".wi-fi.org")) { // !!! Warning: Ruckus hack!
- mRemotes = new ArrayList<>(1);
- mRemotes.add(new InetSocketAddress(InetAddress.getByName("10.123.107.107"), port));
- }
- else {
- InetAddress[] remotes = mNetwork.getAllByName(url.getHost());
- android.util.Log.d(OSUManager.TAG, "'" + url.getHost() + "' resolves to " +
- Arrays.toString(remotes));
- if (remotes == null || remotes.length == 0) {
- throw new IOException("Failed to look up host from " + url);
- }
- mRemotes = new ArrayList<>(remotes.length);
- for (InetAddress remote : remotes) {
- mRemotes.add(new InetSocketAddress(remote, port));
- }
- }
- Collections.shuffle(mRemotes);
- }
-
- public void reloadKeys(Map<OSUCertType, List<X509Certificate>> certs, PrivateKey key)
- throws IOException {
- if (mKeyManager instanceof ClientKeyManager) {
- ((ClientKeyManager) mKeyManager).reloadKeys(certs, key);
- }
- }
-
- public Socket createSocket() throws IOException {
- Socket socket = mSocketFactory.createSocket();
- mNetwork.bindSocket(socket);
-
- for (InetSocketAddress remote : mRemotes) {
- try {
- socket.connect(remote);
- android.util.Log.d(OSUManager.TAG, "Connection " + socket.getLocalSocketAddress() +
- " to " + socket.getRemoteSocketAddress());
- break;
- }
- catch (IOException ioe) { /**/ }
- }
- return socket;
- }
-
- public X509Certificate getOSUCertificate(URL url) throws GeneralSecurityException {
- String fqdn = url.getHost();
- for (X509Certificate certificate : mTrustManager.getTrustChain()) {
- for (List<?> name : certificate.getSubjectAlternativeNames()) {
- if (name.size() >= SPVerifier.DNSName &&
- name.get(0).getClass() == Integer.class &&
- name.get(1).toString().equals(fqdn)) {
- return certificate;
- }
- }
- }
- return null;
- }
-
- final class DefaultSocketFactory extends SocketFactory {
-
- DefaultSocketFactory() {
- }
-
- @Override
- public Socket createSocket() throws IOException {
- return new Socket();
- }
-
- @Override
- public Socket createSocket(String host, int port) throws IOException {
- return new Socket(host, port);
- }
-
- @Override
- public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
- throws IOException {
- return new Socket(host, port, localHost, localPort);
- }
-
- @Override
- public Socket createSocket(InetAddress host, int port) throws IOException {
- return new Socket(host, port);
- }
-
- @Override
- public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
- int localPort) throws IOException {
- return new Socket(address, port, localAddress, localPort);
- }
- }
-
- private static class WFATrustManager implements X509TrustManager {
- private X509Certificate[] mTrustChain;
-
- private WFATrustManager() throws CertificateException {
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- // N/A
- }
-
- @Override
- public void checkServerTrusted(X509Certificate[] chain, String authType)
- throws CertificateException {
- Log.d("TLSOSU", "Checking " + chain.length + " certs.");
-
- try {
- CertPathValidator validator =
- CertPathValidator.getInstance(CertPathValidator.getDefaultType());
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- CertPath path = certFactory.generateCertPath(
- Arrays.asList(chain));
- PKIXParameters params = new PKIXParameters(sTrustAnchors);
- params.setRevocationEnabled(false);
- params.addCertPathChecker(sEKUChecker);
- validator.validate(path, params);
- mTrustChain = chain;
- }
- catch (GeneralSecurityException gse) {
- throw new SecurityException(gse);
- }
- }
-
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- public X509Certificate[] getTrustChain() {
- return mTrustChain;
- }
- }
-
- private static class EKUChecker extends PKIXCertPathChecker {
- @Override
- public void init(boolean forward) throws CertPathValidatorException {
-
- }
-
- @Override
- public boolean isForwardCheckingSupported() {
- return true;
- }
-
- @Override
- public Set<String> getSupportedExtensions() {
- return EKU_ID_SET;
- }
-
- @Override
- public void check(Certificate cert, Collection<String> unresolvedCritExts)
- throws CertPathValidatorException {
- Log.d(OSUManager.TAG, "Checking EKU " + unresolvedCritExts);
- unresolvedCritExts.remove(EKU_ID);
- }
- }
-
- /*
- *
- Subject: CN=osu-server.r2-testbed-rks.wi-fi.org, O=Intel Corporation CCG DRD, C=US
- Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
- Validity: [From: Wed Jan 28 16:00:00 PST 2015,
- To: Sat Jan 28 15:59:59 PST 2017]
- Issuer: CN="NetworkFX, Inc. Hotspot 2.0 Intermediate CA", OU=OSU CA - 01, O="NetworkFX, Inc.", C=US
- SerialNumber: [ 312af3db 138eae19 1defbce2 e2b88b55]
- *
- *
- Subject: CN="NetworkFX, Inc. Hotspot 2.0 Intermediate CA", OU=OSU CA - 01, O="NetworkFX, Inc.", C=US
- Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
- Validity: [From: Tue Nov 19 16:00:00 PST 2013,
- To: Sun Nov 19 15:59:59 PST 2023]
- Issuer: CN=Hotspot 2.0 Trust Root CA - 01, O=WFA Hotspot 2.0, C=US
- SerialNumber: [ 4152b1b0 301495f3 8fa76428 2ef41046]
- */
-
- private static final String[] WFACerts = {
- "MIIFbDCCA1SgAwIBAgIQDLMPcPKGpDPguQmJ3gHttzANBgkqhkiG9w0BAQsFADBQ" +
- "MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhvdHNwb3QgMi4wMScwJQYDVQQD" +
- "Ex5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0gMDMwHhcNMTMxMjA4MTIwMDAw" +
- "WhcNNDMxMjA4MTIwMDAwWjBQMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhv" +
- "dHNwb3QgMi4wMScwJQYDVQQDEx5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0g" +
- "MDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsdEtReIUbMlO+hR6b" +
- "yQk4nGVITv3meYTaDeVwZnQVal8EjHuu4Kd89g8yRYVTv3J1kq9ukE7CDrDehrXK" +
- "ym+8VlR7ro0lB/lwRyNk3W7yNccg3AknQ0x5fKVwcFznwD/FYg37owGmhGFtpMTB" +
- "cxzreQaLXvLta8YNlJU10ZkfputBpzi9bLPWsLOkIrQw7KH1Wc+Oiy4hUMUbTlSi" +
- "cjqacKPR188mVIoxxUoICHyVV1KvMmYZrVdc/b5dbmd0haMHxC0VSqbydXxxS7vv" +
- "/lCrC2d5qbKE66PiuBPkhzyU7SI9C8GU/S7akYm1MMSTn5W7lSp2AWRDnf9LQg51" +
- "dLvDxJ7t2fruXtSkkqG/cwY1yQI8O+WZYPDThKPcDmNbaxVE9lOizAHXFVsfYrXA" +
- "PbbMOkzKehYwaIikmNgcpxtQNw+wikJiZb9N8VwwtwHK71XEFi+n5DGlPa9VDYgB" +
- "YkBcxvVo2rbE3i3teQgHm+pWZNP08aFNWwMk9yQkm/SOGdLq1jLbQA9yd7fyR1Ct" +
- "W1GLzKi1Ojr/6XiB9/noL3oxP/+gb8OSgcqVfkZp4QLvrGdlKiOI2fE7Bslmzn6l" +
- "B3UTpApjab7BQ99rCXzDwt3Xd7IrCtAJNkxi302J7k6hnGlW8S4oPQBElkOtoH9y" +
- "XEhp9rNS0lZiuwtFmWW2q50fkQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G" +
- "A1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUZw5JLGEXnuvt4FTnhNmbrWRgc2UwDQYJ" +
- "KoZIhvcNAQELBQADggIBAFPoGFDyzFg9B9+jJUPGW32omftBhChVcgjllI07RCie" +
- "KTMBi47+auuLgiMox3xRyP7/dX7YaUeMXEQ1BMv6nlrsXWv1lH4yu+RNuehPlqRs" +
- "fY351mAfPtQ654SBUi0Wg++9iyTOfgF5a9IWEDt4lnSZMvA4vlw8pUCz6zpKXHnA" +
- "RXKrpY3bU+2dnrFDKR0XQhmAQdo7UvdsT1elVoFIxHhLpwfzx+kpEhtrXw3nGgt+" +
- "M4jNp684XoWpxVGaQ4Vvv00Sm2DQ8jq2sf9F+kRWszZpQOTiMGKZr0lX2CI5cww1" +
- "dfmd1BkAjI9cIWLkD8YSeaggZzvYe1o9d7e7lKfdJmjDlSQ0uBiG77keUK4tF2fi" +
- "xFTxibtPux56p3GYQ2GdRsBaKjH3A3HMJSKXwIGR+wb1sgz/bBdlyJSylG8hYD//" +
- "0Hyo+UrMUszAdszoPhMY+4Ol3QE3QRWzXi+W/NtKeYD2K8xUzjZM10wMdxCfoFOa" +
- "8bzzWnxZQlnu880ULUSHIxDPeE+DDZYYOaN1hV2Rh/hrFKvvV+gJj2eXHF5G7y9u" +
- "Yg7nHYCCf7Hy8UTIXDtAAeDCQNon1ReN8G+XOqhLQ9TalmnJ5U5ARtC0MdQDht7T" +
- "DZpWeEVv+pQHARX9GDV/T85MV2RPJWKqfZ6kK0gvQDkunADdg8IhZAjwMMx3k6B/",
-
- "MIIFbDCCA1SgAwIBAgIQaAV8NQv/Xdusi4IU+tpUfjANBgkqhkiG9w0BAQsFADBQ" +
- "MQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhvdHNwb3QgMi4wMScwJQYDVQQD" +
- "Ex5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0gMDEwHhcNMTMxMTIwMDAwMDAw" +
- "WhcNNDMxMTE5MjM1OTU5WjBQMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPV0ZBIEhv" +
- "dHNwb3QgMi4wMScwJQYDVQQDEx5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0g" +
- "MDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/gf4CHxWjr2EcktAZ" +
- "pHT4z1yFYZILD3ZVqvzzXBK+YKjWhjsgZ28Z1VwXqu51JvVzwTGDalPf5m7zMcJW" +
- "CpPtPBdxxwQ/cBDPK4w+/sCuYYSddlMLzwZ/IgwFike12tKTR7Kk7Nk6ghrYaxCG" +
- "R+QEZDVrxITj79vGpgk2otVnMI4d3H9mWt1o6Lx+hVioyBgOvmo2OWHR2uKkbg5h" +
- "tktXqmBEtzK+qDqIIUY4WRRZHxlOaF2/EdIIGhXlf+Vlr13aPqOPiDiE08o+GARz" +
- "TIp8BrW2boo0+2kpEFUKiqc427vOYEkUdSMfwu4aGOcuOewc8sk6ztquL/JcPROL" +
- "VSFSSFR3HKhUto8EJcHEEG9wzcOi1OO/OOSVxjNwiaV/hB9Ed1wvoBhiJ+C+Q8/K" +
- "HXmoH/ankXDaB06yjt2Ojemt0nO45qlarRj8tO7zbpghJuJxztur47U7PJta7Zcg" +
- "z7kOPJPTAbzmOU2TXt1pXO1hVnSlV+M1rRwe7qivnSMMrTnkX15YWmyK27/tgJeu" +
- "muR2YzvPwPtF/m1N0bRKI7FW05NYg3smItFq0E/eyf/orgolcXTZ7zNRyRGnjWNs" +
- "/w9SDbdby0uVUfdN4V/5uC4HBmA1rikoBbGZ+nzCtesY4yW8eEwMfguVpNT3ueaU" +
- "q30nufeY2VnA3Rv1WH8TaeZU+wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G" +
- "A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU+RjGVZbebjpzEPfthaTLqbvXMiEwDQYJ" +
- "KoZIhvcNAQELBQADggIBABj3LP1UXVa16HYeXC1+GU1dX/cla1n1bwpIlxRnCZ5/" +
- "3I3zGw/nRnsLUTkGf8q3XCgin+jX22kyzzQNrgepn0zqBsmAj+pjUUwWzYQUzphc" +
- "Uzmg4PJRWaEaGG3kvD+wJEC0pWvIhe48qcq8FZCCmjbvecEVn5mM0smPzPyUjf/o" +
- "fjUMQvVWqug/Ff5HT6kbyDWhC3nD+8IZ5PjyO85OnoBnQkr8WYwr24XJgO2HS2rs" +
- "W40CzQe3Kdg7HHyef+/iyLYTBJH7EUJPCHGVQtZ3q0aNqURkutXJ/CxKJYMcNTEB" +
- "x+a09EhZ6DOHQDqsdTuAqGh3VyrxhFk+3suNsxoh6XaRK10VslvdNB/1YKfU8DWe" +
- "V6XfDH/TR0NIL04exUp3rER8sERulpJGBOnaG6OQKh4bFYDB406+QfusQnvO0aYR" +
- "UXJzf01B15HRJgpZsggpIuex0UDcJhTTpkRfTj8L4ayUce2ZRsGn3dBaT9ZMx4o9" +
- "E/YsQyOpfw28gM5u+zZt4BJz4gAaRGbp4r4sk5Vm/P1/0EXJ70Du6K9d0HAHtpEv" +
- "Y94Ww5W6fpMDdyAKYTXZBgTX3cqtikNkLX/kHH8l4o/XW2sXqU3X7vOYqgeVYoD9" +
- "NnhZXYCerH4Se5Lgj8/KhXxRWtcn3XduMdkC6UTApMooA64Vs508173Z3lJn2SeQ",
-
- "MIIFXTCCA0WgAwIBAgIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEY" +
- "MBYGA1UECgwPV0ZBIEhvdHNwb3QgMi4wMScwJQYDVQQDDB5Ib3RzcG90IDIuMCBU" +
- "cnVzdCBSb290IENBIC0gMDIwHhcNMTMxMjAyMjA1NzU3WhcNNDMxMjAyMjA1NTAz" +
- "WjBQMQswCQYDVQQGEwJVUzEYMBYGA1UECgwPV0ZBIEhvdHNwb3QgMi4wMScwJQYD" +
- "VQQDDB5Ib3RzcG90IDIuMCBUcnVzdCBSb290IENBIC0gMDIwggIiMA0GCSqGSIb3" +
- "DQEBAQUAA4ICDwAwggIKAoICAQDCSoMqNhtTwbnIsINp6nUhx5UFuq9ZQoTv+KDk" +
- "vAajT0di6+cQG3sAVvZLySmJoiBAv3PizYYLOD4eGMrFQRqi7PmSJ83WqNv23ZYF" +
- "ryFFJiy/URXc/ALDuB3dgElPt24Mx7n2xDPAh9t82HTmuskpQRrsyg9QPoi5rRRS" +
- "Djm5mjFJjKChq99RWcweNV/KGH1sTwcmlDmNMScK16A+BBNiSvmZlsGJgAlP369k" +
- "lnNqt6UiDhepcktuKpHmSvNel+c/xqzR0gURfUnXcZhzjzS94Rx5O+CNWL4EGiJq" +
- "qKAfk99j/lbD0MWYo7Rh0UKQlXSdohWDiV93hxvvfugej8KUOIb+1wmd1Fi+lwDZ" +
- "bR2yg2f0qyxbC/tAV4JJNnuDLFb19leD78x+68eAnlbMi+xMH5lINs15+26s2H5d" +
- "lx9kwRDBJq02LuHnen6FLafWjejnnBQ/PuGD0ACvBegSsDKDaCuTAnTNS6MDmQr4" +
- "wza08iX360ZN+BbSAnCK1YGa/7J7fhyydwxLJ7s5Eo0b6SUMY87FMc5XmkAk4xxL" +
- "MLqS2HMtqsGBI5JQT0SgH0ghE6DjMWArBTZcD+swuzTi1/Cz5+Z9Es8xJ3MPvSZW" +
- "pJi6VVB2eVMAqfHOj4ozHoVpvJypIVGRwWBzVRWom76R47utuRK6uKzoLiB1jwE5" +
- "vwHpUQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBxjAd" +
- "BgNVHQ4EFgQU5C9c1OMsB+/MOwl9OKG2D/XSwrUwDQYJKoZIhvcNAQELBQADggIB" +
- "AGULYE/VrnA3K0ptgHrWlQoPfp5wGvScgsmy0wp9qE3b6n/4bLehBKb5w4Y3JVA9" +
- "gjxoQ5xE2ssDtULZ3nKnGWmMN3qOBoRZCA6KjKs1860p09tm1ScUsajDJ15Tp1nI" +
- "zfR0oP63+2bJx+JXM8fPKOJe245hj2rs1c3JXsGCe+UVrlGsotG+wR0PdrejaXJ8" +
- "HbhBQHcbhgjsD1Gb6Egm4YxRKAtcVY3q9EKKWAGhbC1qvCh1iLNKo3FeGgm2r3EG" +
- "L4cYJBb2fhSKltjISqCDhYq4tplOIeQSJJyJC8gfW/BnMU39lTjNgnSjjGPLQXGV" +
- "+Ulb/CgNMJ3RhRJdBoLcpIm/EeLx6JLq/2Erxy7CxjaSOcD0UKa14+dzLSHVsXft" +
- "HZuOy548X8m18KruSZsf5uAT3c7NqlXtr9YgOVUqSJykNAHTGi/BHB1dC2clKvxN" +
- "ElfLWWrG9yaAd5TFW0+3wsaDIwRZL584AsFwwAD3KMo1oU/2zRvtm0E+VghsuD/Z" +
- "IE1xaVGTPaL7ph/YgC9+0rGHieauT8SXz6Ryp3h0RtYMLFZOMTKM7xjmcbMZDwrO" +
- "c+J/XjK9dbiCqlx5/B8P0xWaYYHzvE5/fafiPYzoGyFVUXquu0dFCCQrvjF/y0tC" +
- "TPm4hQim3k1F+5NChcbeNggN+kq+VdlSqPhQEuOY+kNv"
- };
-
- private static final Set<TrustAnchor> sTrustAnchors = buildCertSet();
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/OSUStatus.java b/service/java/com/android/server/wifi/hotspot2/osu/OSUStatus.java
deleted file mode 100644
index 449bcde15..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/OSUStatus.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum OSUStatus {
- OK, ProvComplete, RemediationComplete, UpdateComplete, ExchangeComplete, Unknown, Error
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/PostDevDataResponse.java b/service/java/com/android/server/wifi/hotspot2/osu/PostDevDataResponse.java
deleted file mode 100644
index cd8682ae4..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/PostDevDataResponse.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.MOTree;
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-import com.android.server.wifi.hotspot2.osu.commands.*;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class PostDevDataResponse extends OSUResponse {
- private final List<OSUCommand> mOSUCommands;
-
- public PostDevDataResponse(XMLNode root) throws OMAException {
- super(root, OSUMessageType.PostDevData);
-
- if (getStatus() == OSUStatus.Error) {
- mOSUCommands = null;
- return;
- }
-
- mOSUCommands = new ArrayList<>();
- for (XMLNode child : root.getChildren()) {
- mOSUCommands.add(new OSUCommand(child));
- }
- }
-
- public OSUCommandID getOSUCommand() {
- return mOSUCommands.size() == 1 ? mOSUCommands.get(0).getOSUCommand() : null;
- }
-
- public ExecCommand getExecCommand() {
- return mOSUCommands.size() == 1 ? mOSUCommands.get(0).getExecCommand() : null;
- }
-
- public OSUCommandData getCommandData() {
- return mOSUCommands.size() == 1 ? mOSUCommands.get(0).getCommandData() : null;
- }
-
- public Collection<OSUCommand> getCommands() {
- return Collections.unmodifiableCollection(mOSUCommands);
- }
-
- @Override
- public String toString() {
- return super.toString() + ", commands " + mOSUCommands;
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/RequestReason.java b/service/java/com/android/server/wifi/hotspot2/osu/RequestReason.java
deleted file mode 100644
index 688fe0f38..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/RequestReason.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-public enum RequestReason {
- SubRegistration,
- SubProvisioning,
- SubRemediation,
- InputComplete,
- NoClientCert,
- CertEnrollmentComplete,
- CertEnrollmentFailed,
- SubMetaDataUpdate,
- PolicyUpdate,
- NextCommand,
- MOUpload,
- Unspecified
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/ResponseFactory.java b/service/java/com/android/server/wifi/hotspot2/osu/ResponseFactory.java
deleted file mode 100644
index 246308b21..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/ResponseFactory.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-public interface ResponseFactory {
- public OSUResponse buildResponse(XMLNode root) throws OMAException;
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/SOAPBuilder.java b/service/java/com/android/server/wifi/hotspot2/osu/SOAPBuilder.java
deleted file mode 100644
index a17b2266c..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/SOAPBuilder.java
+++ /dev/null
@@ -1,183 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.MOTree;
-import com.android.server.wifi.hotspot2.omadm.OMAConstants;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Map;
-
-public class SOAPBuilder {
- private static final String EnvelopeTag = "s12:Envelope";
- private static final String BodyTag = "s12:Body";
-
- private static final Map<String, String> sEnvelopeAttributes = new HashMap<>(2);
- private static final Map<RequestReason, String> sRequestReasons = new EnumMap<>(RequestReason.class);
-
- static {
- sEnvelopeAttributes.put("xmlns:s12", "http://www.w3.org/2003/05/soap-envelope");
- sEnvelopeAttributes.put("xmlns:spp", "http://www.wi-fi.org/specifications/hotspot2dot0/v1.0/spp");
-
- sRequestReasons.put(RequestReason.SubRegistration, "Subscription registration");
- sRequestReasons.put(RequestReason.SubProvisioning, "Subscription provisioning");
- sRequestReasons.put(RequestReason.SubRemediation, "Subscription remediation");
- sRequestReasons.put(RequestReason.InputComplete, "User input completed");
- sRequestReasons.put(RequestReason.NoClientCert, "No acceptable client certificate");
- sRequestReasons.put(RequestReason.CertEnrollmentComplete, "Certificate enrollment completed");
- sRequestReasons.put(RequestReason.CertEnrollmentFailed, "Certificate enrollment failed");
- sRequestReasons.put(RequestReason.SubMetaDataUpdate, "Subscription metadata update");
- sRequestReasons.put(RequestReason.PolicyUpdate, "Policy update");
- sRequestReasons.put(RequestReason.NextCommand, "Retrieve next command");
- sRequestReasons.put(RequestReason.MOUpload, "MO upload");
- sRequestReasons.put(RequestReason.Unspecified, "Unspecified");
- }
-
- public static String buildPostDevDataResponse(RequestReason reason, String sessionID,
- String redirURI, MOTree ... mos) {
- XMLNode envelope = buildEnvelope();
- buildSppPostDevData(envelope.getChildren().get(0), sessionID, reason, redirURI, mos);
- return envelope.toString();
- }
-
- public static String buildUpdateResponse(String sessionID, OSUError error) {
- XMLNode envelope = buildEnvelope();
- buildSppUpdateResponse(envelope.getChildren().get(0), sessionID, error);
- return envelope.toString();
- }
-
- private static XMLNode buildEnvelope() {
- XMLNode envelope = new XMLNode(null, EnvelopeTag, sEnvelopeAttributes);
- envelope.addChild(new XMLNode(envelope, BodyTag, (Map<String, String>)null));
- return envelope;
- }
-
- private static XMLNode buildSppPostDevData(XMLNode parent, String sessionID,
- RequestReason reason, String redirURI, MOTree ... mos) {
- Map<String, String> pddAttributes = new HashMap<>();
- pddAttributes.put(OMAConstants.TAG_Version, OMAConstants.MOVersion);
- pddAttributes.put("requestReason", sRequestReasons.get(reason));
- if (sessionID != null) {
- pddAttributes.put(OMAConstants.TAG_SessionID, sessionID);
- }
- if (redirURI != null) {
- pddAttributes.put("redirectURI", redirURI);
- }
-
- XMLNode pddNode = new XMLNode(parent, OMAConstants.TAG_PostDevData, pddAttributes);
-
- XMLNode vNode = new XMLNode(pddNode, OMAConstants.TAG_SupportedVersions, (HashMap<String, String>)null);
- vNode.setText("1.0");
- pddNode.addChild(vNode);
-
- XMLNode moNode = new XMLNode(pddNode, OMAConstants.TAG_SupportedMOs, (HashMap<String, String>)null);
- StringBuilder sb = new StringBuilder();
- boolean first = true;
- for (String urn : OMAConstants.SupportedMO_URNs) {
- if (first) {
- first = false;
- }
- else {
- sb.append(' ');
- }
- sb.append(urn);
- }
- moNode.setText(sb.toString());
- pddNode.addChild(moNode);
-
- if (mos != null) {
- for (MOTree moTree : mos) {
- Map<String, String> map = null;
- if (moTree.getUrn() != null) {
- map = new HashMap<>(1);
- map.put(OMAConstants.SppMOAttribute, moTree.getUrn());
- }
- moNode = new XMLNode(pddNode, OMAConstants.TAG_MOContainer, map);
- moNode.setText(moTree.toXml());
- pddNode.addChild(moNode);
- }
- }
-
- parent.addChild(pddNode);
- return pddNode;
- }
-
- private static XMLNode buildSppUpdateResponse(XMLNode parent, String sessionID, OSUError error) {
- Map<String, String> urAttributes = new HashMap<>();
- urAttributes.put(OMAConstants.TAG_Version, OMAConstants.MOVersion);
- if (sessionID != null) {
- urAttributes.put(OMAConstants.TAG_SessionID, sessionID);
- }
- if (error == null) {
- urAttributes.put(OMAConstants.TAG_Status, OMAConstants.mapStatus(OSUStatus.OK));
- }
- else {
- urAttributes.put(OMAConstants.TAG_Status, OMAConstants.mapStatus(OSUStatus.Error));
- }
-
- XMLNode urNode = new XMLNode(parent, OMAConstants.TAG_UpdateResponse, urAttributes);
-
- if (error != null) {
- Map<String, String> errorAttributes = new HashMap<>();
- errorAttributes.put("errorCode", OMAConstants.mapError(error));
- XMLNode errorNode = new XMLNode(urNode, OMAConstants.TAG_Error, errorAttributes);
- urNode.addChild(errorNode);
- }
-
- parent.addChild(urNode);
- return urNode;
- }
-
- /*
- <xsd:element name="sppUpdateResponse">
- <xsd:annotation>
- <xsd:documentation>SOAP method used by SPP client to confirm installation of MO addition or update.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element ref="sppError" minOccurs="0"/>
- <xsd:any namespace="##other" maxOccurs="unbounded" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute ref="sppVersion" use="required"/>
- <xsd:attribute ref="sppStatus" use="required"/>
- <xsd:attribute ref="sessionID" use="required"/>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
-
- <xsd:element name="sppError">
- <xsd:annotation>
- <xsd:documentation>Error response.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:attribute name="errorCode" use="required">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="SPP version not supported"/>
- <xsd:enumeration value="One or more mandatory MOs not supported"/>
- <xsd:enumeration value="Credentials cannot be provisioned at this time"/>
- <xsd:enumeration value="Remediation cannot be completed at this time"/>
- <xsd:enumeration value="Provisioning cannot be completed at this time"/>
- <xsd:enumeration value="Continue to use existing certificate"/>
- <xsd:enumeration value="Cookie invalid"/>
- <xsd:enumeration value="No corresponding web-browser-connection Session ID"/>
- <xsd:enumeration value="Permission denied"/>
- <xsd:enumeration value="Command failed"/>
- <xsd:enumeration value="MO addition or update failed"/>
- <xsd:enumeration value="Device full"/>
- <xsd:enumeration value="Bad management tree URI"/>
- <xsd:enumeration value="Requested entity too large"/>
- <xsd:enumeration value="Command not allowed"/>
- <xsd:enumeration value="Command not executed due to user"/>
- <xsd:enumeration value="Not found"/>
- <xsd:enumeration value="Other"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
-
-
- */
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/SOAPParser.java b/service/java/com/android/server/wifi/hotspot2/osu/SOAPParser.java
deleted file mode 100644
index d324c2605..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/SOAPParser.java
+++ /dev/null
@@ -1,325 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-public class SOAPParser {
-
- private static final String EnvelopeTag = "envelope";
- private static final String BodyTag = "body";
-
- private static final Map<String, ResponseFactory> sResponseMap = new HashMap<>();
-
- static {
- sResponseMap.put("spppostdevdataresponse", new ResponseFactory() {
- @Override
- public OSUResponse buildResponse(XMLNode root) throws OMAException {
- return new PostDevDataResponse(root);
- }
- });
- sResponseMap.put("sppexchangecomplete", new ResponseFactory() {
- @Override
- public OSUResponse buildResponse(XMLNode root) throws OMAException {
- return new ExchangeCompleteResponse(root);
- }
- });
- sResponseMap.put("getcertificate", new ResponseFactory() {
- @Override
- public OSUResponse buildResponse(XMLNode root) {
- return null;
- }
- });
- sResponseMap.put("spperror", new ResponseFactory() {
- @Override
- public OSUResponse buildResponse(XMLNode root) {
- return null;
- }
- });
- }
-
- private final XMLNode mResponseNode;
-
- public SOAPParser(InputStream in) throws ParserConfigurationException, SAXException, IOException {
- XMLNode root;
-
- try {
- XMLParser parser = new XMLParser(in);
- root = parser.getRoot();
- }
- finally {
- in.close();
- }
-
- String[] nsn = root.getTag().split(":");
- if (nsn.length > 2) {
- throw new OMAException("Bad root tag syntax: '" + root.getTag() + "'");
- }
- else if (! EnvelopeTag.equalsIgnoreCase(nsn[nsn.length-1])) {
- throw new OMAException("Expected envelope: '" + root.getTag() + "'");
- }
-
- String bodyTag = nsn.length > 1 ? ( nsn[0] + ":" + BodyTag ) : BodyTag;
- XMLNode body = null;
-
- for (XMLNode child : root.getChildren()) {
- if (bodyTag.equalsIgnoreCase(child.getTag())) {
- body = child;
- break;
- }
- }
-
- if (body == null || body.getChildren().isEmpty()) {
- throw new OMAException("Missing SOAP body");
- }
-
- mResponseNode = body.getSoleChild();
- }
-
- public OSUResponse getResponse() throws OMAException {
- ResponseFactory responseFactory = sResponseMap.get(mResponseNode.getStrippedTag());
- if (responseFactory == null) {
- throw new OMAException("Unknown response type: '" + mResponseNode.getStrippedTag() + "'");
- }
- return responseFactory.buildResponse(mResponseNode);
- }
-
- public XMLNode getResponseNode() {
- return mResponseNode;
- }
-
-
- /*
- <xsd:element name="sppPostDevDataResponse">
- <xsd:annotation>
- <xsd:documentation>SOAP method response from SPP server.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:choice>
- <xsd:element ref="sppError"/>
- <xsd:element name="exec">
- <xsd:annotation>
- <xsd:documentation>Receipt of this element by a mobile device causes the following command to be executed.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:choice>
- <xsd:element name="launchBrowserToURI" type="httpsURIType">
- <xsd:annotation>
- <xsd:documentation>When the mobile device receives this command, it launches its default browser to the URI contained in this element. The URI must use HTTPS as the protocol and must contain an FQDN.</xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- <xsd:element ref="getCertificate"/>
- <xsd:element name="useClientCertTLS">
- <xsd:annotation>
- <xsd:documentation>Command to mobile to re-negotiate the TLS connection using a client certificate of the accepted type or Issuer to authenticate with the Subscription server.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="providerIssuerName" minOccurs="0"
- maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:attribute name="name" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation>The issuer name of an acceptable provider-issued certificate. The text of this element is formatted in accordance with the Issuer Name field in RFC-3280. This element is present only when acceptProviderCerts is true.</xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:any namespace="##other" minOccurs="0"
- maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="acceptMfgCerts" type="xsd:boolean"
- use="optional" default="false">
- <xsd:annotation>
- <xsd:documentation>When this boolean is true, IEEE 802.1ar manufacturing certificates are acceptable for mobile device authentication.</xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="acceptProviderCerts" type="xsd:boolean"
- use="optional" default="true">
- <xsd:annotation>
- <xsd:documentation>When this boolean is true, X509v3 certificates issued by providers identified in the providerIssuerName child element(s) are acceptable for mobile device authentication.</xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="uploadMO" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation>Command to mobile to upload the MO named in the moURN attribute to the SPP server.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:attribute ref="moURN"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:any namespace="##other" maxOccurs="unbounded" minOccurs="0">
- <xsd:annotation>
- <xsd:documentation>Element to allow the addition of new commands in the future.</xsd:documentation>
- </xsd:annotation>
- </xsd:any>
- </xsd:choice>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="addMO">
- <xsd:annotation>
- <xsd:documentation>This command causes an management object in the mobile devices management tree at the specified location to be added. If there is already a management object at that location, the object is replaced.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute ref="managementTreeURI"/>
- <xsd:attribute ref="moURN"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:element maxOccurs="unbounded" name="updateNode">
- <xsd:annotation>
- <xsd:documentation>This command causes the update of an interior node and its child nodes (if any) at the location specified in the management tree URI attribute. The content of this element is the MO node XML.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:simpleContent>
- <xsd:extension base="xsd:string">
- <xsd:attribute ref="managementTreeURI"/>
- </xsd:extension>
- </xsd:simpleContent>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="noMOUpdate">
- <xsd:annotation>
- <xsd:documentation>This response is used when there is no command to be executed nor update of any MO required.</xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation>For vendor-specific extensions or future needs.</xsd:documentation>
- </xsd:annotation>
- </xsd:any>
- </xsd:choice>
- <xsd:attribute ref="sppVersion" use="required"/>
- <xsd:attribute ref="sppStatus" use="required"/>
- <xsd:attribute ref="moreCommands" use="optional"/>
- <xsd:attribute ref="sessionID" use="required"/>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="sppUpdateResponse">
- <xsd:annotation>
- <xsd:documentation>SOAP method used by SPP client to confirm installation of MO addition or update.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element ref="sppError" minOccurs="0"/>
- <xsd:any namespace="##other" maxOccurs="unbounded" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute ref="sppVersion" use="required"/>
- <xsd:attribute ref="sppStatus" use="required"/>
- <xsd:attribute ref="sessionID" use="required"/>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="sppExchangeComplete">
- <xsd:annotation>
- <xsd:documentation>SOAP method used by SPP server to end session.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element ref="sppError" minOccurs="0"/>
- <xsd:any namespace="##other" maxOccurs="unbounded" minOccurs="0"/>
- </xsd:sequence>
- <xsd:attribute ref="sppVersion" use="required"/>
- <xsd:attribute ref="sppStatus" use="required"/>
- <xsd:attribute ref="sessionID" use="required"/>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="getCertificate">
- <xsd:annotation>
- <xsd:documentation>Command to mobile to initiate certificate enrollment or re-enrollment and is a container for metadata to enable enrollment.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="enrollmentServerURI" type="httpsURIType">
- <xsd:annotation>
- <xsd:documentation>HTTPS URI of the server to be contacted to initiate certificate enrollment. The URI must contain an FQDN.</xsd:documentation>
- </xsd:annotation>
- </xsd:element>
- <xsd:element name="estUserID" minOccurs="0">
- <xsd:annotation>
- <xsd:documentation>Temporary userid used by an EST client to authenticate to the EST server using HTTP Digest authentication. This element must be used for initial certificate enrollment; its use is optional for certificate re-enrollment.</xsd:documentation>
- </xsd:annotation>
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:maxLength value="255"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:element>
- <xsd:element name="estPassword" minOccurs="0">
- <xsd:annotation>
- <xsd:documentation>Temporary password used by an EST client to authenticate to the EST server using HTTP Digest authentication. This element must be used for initial certificate enrollment; its use is optional for certificate re-enrollment.</xsd:documentation>
- </xsd:annotation>
- <xsd:simpleType>
- <xsd:restriction base="xsd:base64Binary">
- <xsd:maxLength value="340"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:element>
- <xsd:any namespace="##other" minOccurs="0" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation>For vendor-specific extensions or future needs.</xsd:documentation>
- </xsd:annotation>
- </xsd:any>
- </xsd:sequence>
- <xsd:attribute name="enrollmentProtocol" use="required">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="EST"/>
- <xsd:enumeration value="Other"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:element name="sppError">
- <xsd:annotation>
- <xsd:documentation>Error response.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:attribute name="errorCode" use="required">
- <xsd:simpleType>
- <xsd:restriction base="xsd:string">
- <xsd:enumeration value="SPP version not supported"/>
- <xsd:enumeration value="One or more mandatory MOs not supported"/>
- <xsd:enumeration value="Credentials cannot be provisioned at this time"/>
- <xsd:enumeration value="Remediation cannot be completed at this time"/>
- <xsd:enumeration value="Provisioning cannot be completed at this time"/>
- <xsd:enumeration value="Continue to use existing certificate"/>
- <xsd:enumeration value="Cookie invalid"/>
- <xsd:enumeration value="No corresponding web-browser-connection Session ID"/>
- <xsd:enumeration value="Permission denied"/>
- <xsd:enumeration value="Command failed"/>
- <xsd:enumeration value="MO addition or update failed"/>
- <xsd:enumeration value="Device full"/>
- <xsd:enumeration value="Bad management tree URI"/>
- <xsd:enumeration value="Requested entity too large"/>
- <xsd:enumeration value="Command not allowed"/>
- <xsd:enumeration value="Command not executed due to user"/>
- <xsd:enumeration value="Not found"/>
- <xsd:enumeration value="Other"/>
- </xsd:restriction>
- </xsd:simpleType>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
-
- */
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/SPVerifier.java b/service/java/com/android/server/wifi/hotspot2/osu/SPVerifier.java
deleted file mode 100644
index bf8d36d7d..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/SPVerifier.java
+++ /dev/null
@@ -1,329 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.util.Log;
-
-import com.android.server.wifi.anqp.HSIconFileElement;
-import com.android.server.wifi.anqp.I18Name;
-import com.android.server.wifi.anqp.IconInfo;
-import com.android.server.wifi.hotspot2.Utils;
-import com.android.server.wifi.hotspot2.asn1.Asn1Class;
-import com.android.server.wifi.hotspot2.asn1.Asn1Constructed;
-import com.android.server.wifi.hotspot2.asn1.Asn1Decoder;
-import com.android.server.wifi.hotspot2.asn1.Asn1Integer;
-import com.android.server.wifi.hotspot2.asn1.Asn1Object;
-import com.android.server.wifi.hotspot2.asn1.Asn1Octets;
-import com.android.server.wifi.hotspot2.asn1.Asn1Oid;
-import com.android.server.wifi.hotspot2.asn1.Asn1String;
-import com.android.server.wifi.hotspot2.asn1.OidMappings;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-public class SPVerifier {
- public static final int OtherName = 0;
- public static final int DNSName = 2;
-
- private final OSUInfo mOSUInfo;
-
- public SPVerifier(OSUInfo osuInfo) {
- mOSUInfo = osuInfo;
- }
-
- /*
- SEQUENCE:
- [Context 0]:
- SEQUENCE:
- [Context 0]: -- LogotypeData
- SEQUENCE:
- SEQUENCE:
- SEQUENCE:
- IA5String='image/png'
- SEQUENCE:
- SEQUENCE:
- SEQUENCE:
- OID=2.16.840.1.101.3.4.2.1
- NULL
- OCTET_STRING= cf aa 74 a8 ad af 85 82 06 c8 f5 b5 bf ee 45 72 8a ee ea bd 47 ab 50 d3 62 0c 92 c1 53 c3 4c 6b
- SEQUENCE:
- IA5String='http://www.r2-testbed.wi-fi.org/icon_orange_zxx.png'
- SEQUENCE:
- INTEGER=4184
- INTEGER=-128
- INTEGER=61
- [Context 4]= 7a 78 78
- [Context 0]: -- LogotypeData
- SEQUENCE:
- SEQUENCE: -- LogotypeImage
- SEQUENCE: -- LogoTypeDetails
- IA5String='image/png'
- SEQUENCE:
- SEQUENCE: -- HashAlgAndValue
- SEQUENCE:
- OID=2.16.840.1.101.3.4.2.1
- NULL
- OCTET_STRING= cb 35 5c ba 7a 21 59 df 8e 0a e1 d8 9f a4 81 9e 41 8f af 58 0c 08 d6 28 7f 66 22 98 13 57 95 8d
- SEQUENCE:
- IA5String='http://www.r2-testbed.wi-fi.org/icon_orange_eng.png'
- SEQUENCE: -- LogotypeImageInfo
- INTEGER=11635
- INTEGER=-96
- INTEGER=76
- [Context 4]= 65 6e 67
- */
-
- private static class LogoTypeImage {
- private final String mMimeType;
- private final List<HashAlgAndValue> mHashes = new ArrayList<>();
- private final List<String> mURIs = new ArrayList<>();
- private final int mFileSize;
- private final int mXsize;
- private final int mYsize;
- private final String mLanguage;
-
- private LogoTypeImage(Asn1Constructed sequence) throws IOException {
- Iterator<Asn1Object> children = sequence.getChildren().iterator();
-
- Iterator<Asn1Object> logoTypeDetails =
- castObject(children.next(), Asn1Constructed.class).getChildren().iterator();
- mMimeType = castObject(logoTypeDetails.next(), Asn1String.class).getString();
-
- Asn1Constructed hashes = castObject(logoTypeDetails.next(), Asn1Constructed.class);
- for (Asn1Object hash : hashes.getChildren()) {
- mHashes.add(new HashAlgAndValue(castObject(hash, Asn1Constructed.class)));
- }
- Asn1Constructed urls = castObject(logoTypeDetails.next(), Asn1Constructed.class);
- for (Asn1Object url : urls.getChildren()) {
- mURIs.add(castObject(url, Asn1String.class).getString());
- }
-
- boolean imageInfoSet = false;
- int fileSize = -1;
- int xSize = -1;
- int ySize = -1;
- String language = null;
-
- if (children.hasNext()) {
- Iterator<Asn1Object> imageInfo =
- castObject(children.next(), Asn1Constructed.class).getChildren().iterator();
-
- Asn1Object first = imageInfo.next();
- if (first.getTag() == 0) {
- first = imageInfo.next(); // Ignore optional LogotypeImageType
- }
-
- fileSize = (int) castObject(first, Asn1Integer.class).getValue();
- xSize = (int) castObject(imageInfo.next(), Asn1Integer.class).getValue();
- ySize = (int) castObject(imageInfo.next(), Asn1Integer.class).getValue();
- imageInfoSet = true;
-
- if (imageInfo.hasNext()) {
- Asn1Object next = imageInfo.next();
- if (next.getTag() != 4) {
- next = imageInfo.hasNext() ? imageInfo.next() : null; // Skip resolution
- }
- if (next != null && next.getTag() == 4) {
- language = new String(castObject(next, Asn1Octets.class).getOctets(),
- StandardCharsets.US_ASCII);
- }
- }
- }
-
- if (imageInfoSet) {
- mFileSize = complement(fileSize);
- mXsize = complement(xSize);
- mYsize = complement(ySize);
- } else {
- mFileSize = mXsize = mYsize = -1;
- }
- mLanguage = language;
- }
-
- private boolean verify(OSUInfo osuInfo) throws GeneralSecurityException, IOException {
- IconInfo iconInfo = osuInfo.getIconInfo();
- HSIconFileElement iconData = osuInfo.getIconFileElement();
- if (!iconInfo.getIconType().equals(mMimeType) ||
- !iconInfo.getLanguage().equals(mLanguage) ||
- iconData.getIconData().length != mFileSize) {
- return false;
- }
- for (HashAlgAndValue hash : mHashes) {
- if (hash.getJCEName() != null) {
- MessageDigest digest = MessageDigest.getInstance(hash.getJCEName());
- byte[] computed = digest.digest(iconData.getIconData());
- if (!Arrays.equals(computed, hash.getHash())) {
- throw new IOException("Icon hash mismatch");
- } else {
- Log.d(OSUManager.TAG, "Icon verified with " + hash.getJCEName());
- return true;
- }
- }
- }
- return false;
- }
-
- @Override
- public String toString() {
- return "LogoTypeImage{" +
- "MimeType='" + mMimeType + '\'' +
- ", hashes=" + mHashes +
- ", URIs=" + mURIs +
- ", fileSize=" + mFileSize +
- ", xSize=" + mXsize +
- ", ySize=" + mYsize +
- ", language='" + mLanguage + '\'' +
- '}';
- }
- }
-
- private static class HashAlgAndValue {
- private final String mJCEName;
- private final byte[] mHash;
-
- private HashAlgAndValue(Asn1Constructed sequence) throws IOException {
- if (sequence.getChildren().size() != 2) {
- throw new IOException("Bad HashAlgAndValue");
- }
- Iterator<Asn1Object> children = sequence.getChildren().iterator();
- mJCEName = OidMappings.getJCEName(getFirstInner(children.next(), Asn1Oid.class));
- mHash = castObject(children.next(), Asn1Octets.class).getOctets();
- }
-
- public String getJCEName() {
- return mJCEName;
- }
-
- public byte[] getHash() {
- return mHash;
- }
-
- @Override
- public String toString() {
- return "HashAlgAndValue{" +
- "JCEName='" + mJCEName + '\'' +
- ", hash=" + Utils.toHex(mHash) +
- '}';
- }
- }
-
- private static int complement(int value) {
- return value >= 0 ? value : (~value) + 1;
- }
-
- private static <T extends Asn1Object> T castObject(Asn1Object object, Class<T> klass)
- throws IOException {
- if (object.getClass() != klass) {
- throw new IOException("Object is an " + object.getClass().getSimpleName() +
- " expected an " + klass.getSimpleName());
- }
- return klass.cast(object);
- }
-
- private static <T extends Asn1Object> T getFirstInner(Asn1Object container, Class<T> klass)
- throws IOException {
- if (container.getClass() != Asn1Constructed.class) {
- throw new IOException("Not a container");
- }
- Iterator<Asn1Object> children = container.getChildren().iterator();
- if (!children.hasNext()) {
- throw new IOException("No content");
- }
- return castObject(children.next(), klass);
- }
-
- public void verify(X509Certificate osuCert) throws IOException, GeneralSecurityException {
- if (osuCert == null) {
- throw new IOException("No OSU cert found");
- }
-
- checkName(castObject(getExtension(osuCert, OidMappings.IdCeSubjectAltName),
- Asn1Constructed.class));
-
- List<LogoTypeImage> logos = getImageData(getExtension(osuCert, OidMappings.IdPeLogotype));
- Log.d(OSUManager.TAG, "Logos: " + logos);
- for (LogoTypeImage logoTypeImage : logos) {
- if (logoTypeImage.verify(mOSUInfo)) {
- return;
- }
- }
- throw new IOException("Failed to match icon against any cert logo");
- }
-
- private static List<LogoTypeImage> getImageData(Asn1Object logoExtension) throws IOException {
- Asn1Constructed logo = castObject(logoExtension, Asn1Constructed.class);
- Asn1Constructed communityLogo = castObject(logo.getChildren().iterator().next(),
- Asn1Constructed.class);
- if (communityLogo.getTag() != 0) {
- throw new IOException("Expected tag [0] for communityLogos");
- }
-
- List<LogoTypeImage> images = new ArrayList<>();
- Asn1Constructed communityLogoSeq = castObject(communityLogo.getChildren().iterator().next(),
- Asn1Constructed.class);
- for (Asn1Object logoTypeData : communityLogoSeq.getChildren()) {
- if (logoTypeData.getTag() != 0) {
- throw new IOException("Expected tag [0] for LogotypeData");
- }
- for (Asn1Object logoTypeImage : castObject(logoTypeData.getChildren().iterator().next(),
- Asn1Constructed.class).getChildren()) {
- // only read the image SEQUENCE and skip any audio [1] tags
- if (logoTypeImage.getAsn1Class() == Asn1Class.Universal) {
- images.add(new LogoTypeImage(castObject(logoTypeImage, Asn1Constructed.class)));
- }
- }
- }
- return images;
- }
-
- private void checkName(Asn1Constructed altName) throws IOException {
- Map<String, I18Name> friendlyNames = new HashMap<>();
- for (Asn1Object name : altName.getChildren()) {
- if (name.getAsn1Class() == Asn1Class.Context && name.getTag() == OtherName) {
- Asn1Constructed otherName = (Asn1Constructed) name;
- Iterator<Asn1Object> children = otherName.getChildren().iterator();
- if (children.hasNext()) {
- Asn1Object oidObject = children.next();
- if (OidMappings.sIdWfaHotspotFriendlyName.equals(oidObject) &&
- children.hasNext()) {
- Asn1Constructed value = castObject(children.next(), Asn1Constructed.class);
- String text = castObject(value.getChildren().iterator().next(),
- Asn1String.class).getString();
- I18Name friendlyName = new I18Name(text);
- friendlyNames.put(friendlyName.getLanguage(), friendlyName);
- }
- }
- }
- }
- Log.d(OSUManager.TAG, "Friendly names: " + friendlyNames.values());
- for (I18Name osuName : mOSUInfo.getOSUProvider().getNames()) {
- I18Name friendlyName = friendlyNames.get(osuName.getLanguage());
- if (!osuName.equals(friendlyName)) {
- throw new IOException("Friendly name '" + osuName + " not in certificate");
- }
- }
- }
-
- private static Asn1Object getExtension(X509Certificate certificate, String extension)
- throws GeneralSecurityException, IOException {
- byte[] data = certificate.getExtensionValue(extension);
- if (data == null) {
- return null;
- }
- Asn1Octets octetString = (Asn1Octets) Asn1Decoder.decode(ByteBuffer.wrap(data)).
- iterator().next();
- Asn1Constructed sequence = castObject(Asn1Decoder.decode(
- ByteBuffer.wrap(octetString.getOctets())).iterator().next(),
- Asn1Constructed.class);
- Log.d(OSUManager.TAG, "Extension " + extension + ": " + sequence);
- return sequence;
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/UserInputListener.java b/service/java/com/android/server/wifi/hotspot2/osu/UserInputListener.java
deleted file mode 100644
index 74d0cb3b6..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/UserInputListener.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.net.Network;
-
-import java.net.URL;
-
-public interface UserInputListener {
- /**
- * Launch an appropriate application to handle user input and HTTP exchanges to the target
- * URL. Under normal circumstances this implies that a web-browser is started and pointed at
- * the target URL from which it is supposed to perform an initial HTTP GET operation.
- * This call must not block beyond the time it takes to launch the user agent, i.e. must return
- * well before the HTTP exchange terminates.
- * @param target A fully encoded URL to which to send an initial HTTP GET and then handle
- * subsequent HTTP exchanges.
- * @param endRedirect A URL to which the user agent will be redirected upon completion of
- * the HTTP exchange. This parameter is for informational purposes only
- * as the redirect to the URL is the responsibility of the remote server.
- */
- public void requestUserInput(URL target, Network network, URL endRedirect);
-
- /**
- * Notification that status of the OSU operation has changed. The implementation may choose to
- * return a string that will be passed to the user agent. Please note that the string is
- * passed as the payload of (the redirect) HTTP connection to the agent and must be formatted
- * appropriately (e.g. as well formed HTML).
- * Returning a null string on the initial status update of UserInputComplete or UserInputAborted
- * will cause the local "redirect" web-server to terminate and any further strings returned will
- * be ignored.
- * If programmatic termination of the user agent is desired, it should be initiated from within
- * the implementation of this method.
- * @param status
- * @param message
- * @return
- */
- public String operationStatus(OSUOperationStatus status, String message);
-
- /**
- * Notify the user that a de-authentication event is imminent.
- * @param ess set to indicate that the de-authentication is for an ESS instead of a BSS
- * @param url a URL to which to redirect the user
- */
- public void deAuthNotification(boolean ess, URL url);
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/WiFiKeyManager.java b/service/java/com/android/server/wifi/hotspot2/osu/WiFiKeyManager.java
deleted file mode 100644
index 7add9a8da..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/WiFiKeyManager.java
+++ /dev/null
@@ -1,184 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import android.net.wifi.WifiEnterpriseConfig;
-import android.util.Log;
-
-import java.io.IOException;
-import java.net.Socket;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.net.ssl.X509KeyManager;
-import javax.security.auth.x500.X500Principal;
-
-public class WiFiKeyManager implements X509KeyManager {
- private final KeyStore mKeyStore;
- private final Map<X500Principal, String[]> mAliases = new HashMap<>();
-
- public WiFiKeyManager() throws IOException {
- android.security.keystore.AndroidKeyStoreProvider.install();
-
- try {
- mKeyStore = android.security.keystore.AndroidKeyStoreProvider.getKeyStoreForUid(android.os.Process.WIFI_UID);
- }
- catch (GeneralSecurityException gse) {
- throw new IOException("Failed to instantiate KeyStore: " + gse, gse);
- }
- }
-
- public void enableClientAuth(List<String> issuerNames) throws GeneralSecurityException,
- IOException {
-
- Set<X500Principal> acceptedIssuers = new HashSet<>();
- for (String issuerName : issuerNames) {
- acceptedIssuers.add(new X500Principal(issuerName));
- }
-
- Enumeration<String> aliases = mKeyStore.aliases();
- while (aliases.hasMoreElements()) {
- String alias = aliases.nextElement();
- Certificate cert = mKeyStore.getCertificate(alias);
- if ((cert instanceof X509Certificate) && mKeyStore.getKey(alias, null) != null) {
- X509Certificate x509Certificate = (X509Certificate) cert;
- X500Principal issuer = x509Certificate.getIssuerX500Principal();
- if (acceptedIssuers.contains(issuer)) {
- mAliases.put(issuer, new String[] {alias, cert.getPublicKey().getAlgorithm()});
- }
- }
- }
-
- if (mAliases.isEmpty()) {
- throw new IOException("No aliases match requested issuers: " + issuerNames);
- }
- }
-
- private static class AliasEntry implements Comparable<AliasEntry> {
- private final int mPreference;
- private final String mAlias;
-
- private AliasEntry(int preference, String alias) {
- mPreference = preference;
- mAlias = alias;
- }
-
- public int getPreference() {
- return mPreference;
- }
-
- public String getAlias() {
- return mAlias;
- }
-
- @Override
- public int compareTo(AliasEntry other) {
- return Integer.compare(getPreference(), other.getPreference());
- }
- }
-
- @Override
- public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) {
-
- Map<String, Integer> keyPrefs = new HashMap<>(keyTypes.length);
- int pref = 0;
- for (String keyType : keyTypes) {
- keyPrefs.put(keyType, pref++);
- }
-
- List<AliasEntry> aliases = new ArrayList<>();
- if (issuers != null) {
- for (Principal issuer : issuers) {
- if (issuer instanceof X500Principal) {
- String[] aliasAndKey = mAliases.get((X500Principal) issuer);
- if (aliasAndKey != null) {
- Integer preference = keyPrefs.get(aliasAndKey[1]);
- if (preference != null) {
- aliases.add(new AliasEntry(preference, aliasAndKey[0]));
- }
- }
- }
- }
- }
- else {
- for (String[] aliasAndKey : mAliases.values()) {
- Integer preference = keyPrefs.get(aliasAndKey[1]);
- if (preference != null) {
- aliases.add(new AliasEntry(preference, aliasAndKey[0]));
- }
- }
- }
- Collections.sort(aliases);
- return aliases.isEmpty() ? null : aliases.get(0).getAlias();
- }
-
- @Override
- public String[] getClientAliases(String keyType, Principal[] issuers) {
- List<String> aliases = new ArrayList<>();
- if (issuers != null) {
- for (Principal issuer : issuers) {
- if (issuer instanceof X500Principal) {
- String[] aliasAndKey = mAliases.get((X500Principal) issuer);
- if (aliasAndKey != null) {
- aliases.add(aliasAndKey[0]);
- }
- }
- }
- }
- else {
- for (String[] aliasAndKey : mAliases.values()) {
- aliases.add(aliasAndKey[0]);
- }
- }
- return aliases.isEmpty() ? null : aliases.toArray(new String[aliases.size()]);
- }
-
- @Override
- public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String[] getServerAliases(String keyType, Principal[] issuers) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public X509Certificate[] getCertificateChain(String alias) {
- try {
- List<X509Certificate> certs = new ArrayList<>();
- for (Certificate certificate : mKeyStore.getCertificateChain(alias)) {
- if (certificate instanceof X509Certificate) {
- certs.add((X509Certificate) certificate);
- }
- }
- return certs.toArray(new X509Certificate[certs.size()]);
- }
- catch (KeyStoreException kse) {
- Log.w(OSUManager.TAG, "Failed to retrieve certificates: " + kse);
- return null;
- }
- }
-
- @Override
- public PrivateKey getPrivateKey(String alias) {
- try {
- return (PrivateKey) mKeyStore.getKey(alias, null);
- }
- catch (GeneralSecurityException gse) {
- Log.w(OSUManager.TAG, "Failed to retrieve private key: " + gse);
- return null;
- }
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/XMLParser.java b/service/java/com/android/server/wifi/hotspot2/osu/XMLParser.java
deleted file mode 100644
index c8e0e4a7f..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/XMLParser.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.android.server.wifi.hotspot2.osu;
-
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.helpers.DefaultHandler;
-
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
-
-public class XMLParser extends DefaultHandler {
- private final SAXParser mParser;
- private final InputSource mInputSource;
-
- private XMLNode mRoot;
- private XMLNode mCurrent;
-
- public XMLParser(InputStream in) throws ParserConfigurationException, SAXException {
- mParser = SAXParserFactory.newInstance().newSAXParser();
- mInputSource = new InputSource(new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8)));
- }
-
- public XMLNode getRoot() throws SAXException, IOException {
- mParser.parse(mInputSource, this);
- return mRoot;
- }
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
- XMLNode parent = mCurrent;
-
- mCurrent = new XMLNode(mCurrent, qName, attributes);
- //System.out.println("Added " + mCurrent.getTag() + ", atts " + mCurrent.getAttributes());
-
- if (mRoot == null)
- mRoot = mCurrent;
- else
- parent.addChild(mCurrent);
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (!qName.equals(mCurrent.getTag()))
- throw new SAXException("End tag '" + qName + "' doesn't match current node: " +
- mCurrent);
-
- try {
- mCurrent.close();
- } catch (IOException ioe) {
- throw new SAXException("Failed to close element", ioe);
- }
-
- mCurrent = mCurrent.getParent();
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- mCurrent.addText(ch, start, length);
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/commands/BrowserURI.java b/service/java/com/android/server/wifi/hotspot2/osu/commands/BrowserURI.java
deleted file mode 100644
index b98841dfa..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/commands/BrowserURI.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.commands;
-
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-/*
- <spp:sppPostDevDataResponse xmlns:spp="http://www.wi-fi.org/specifications/hotspot2dot0/v1.0/spp"
- spp:sessionID="D74A7B03005645DAA516191DEE77B94F" spp:sppStatus="OK"
- spp:sppVersion="1.0">
- <spp:exec>
- <spp:launchBrowserToURI>
- https://subscription-server.r2-testbed-rks.wi-fi.org:8443/web/ruckuswireles/home/-/onlinesignup/subscriberDetails?Credentials=USERNAME_PASSWORD&amp;SessionID=D74A7B03005645DAA516191DEE77B94F&amp;RedirectURI=http://127.0.0.1:12345/index.htm&amp;UpdateMethod=SPP-ClientInitiated
- </spp:launchBrowserToURI>
- </spp:exec>
- </spp:sppPostDevDataResponse>
- */
-
-public class BrowserURI implements OSUCommandData {
- private final String mURI;
-
- public BrowserURI(XMLNode commandNode) {
- mURI = commandNode.getText();
- }
-
- public String getURI() {
- return mURI;
- }
-
- @Override
- public String toString() {
- return "URI: " + mURI;
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/commands/ClientCertInfo.java b/service/java/com/android/server/wifi/hotspot2/osu/commands/ClientCertInfo.java
deleted file mode 100644
index 94a60ecdf..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/commands/ClientCertInfo.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.commands;
-
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/*
-<xsd:element name="useClientCertTLS">
- <xsd:annotation>
- <xsd:documentation>Command to mobile to re-negotiate the TLS connection using a client certificate of the accepted type or Issuer to authenticate with the Subscription server.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:sequence>
- <xsd:element name="providerIssuerName" minOccurs="0"
- maxOccurs="unbounded">
- <xsd:complexType>
- <xsd:attribute name="name" type="xsd:string">
- <xsd:annotation>
- <xsd:documentation>The issuer name of an acceptable provider-issued certificate. The text of this element is formatted in accordance with the Issuer Name field in RFC-3280. This element is present only when acceptProviderCerts is true.</xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
- </xsd:element>
- <xsd:any namespace="##other" minOccurs="0"
- maxOccurs="unbounded"/>
- </xsd:sequence>
- <xsd:attribute name="acceptMfgCerts" type="xsd:boolean"
- use="optional" default="false">
- <xsd:annotation>
- <xsd:documentation>When this boolean is true, IEEE 802.1ar manufacturing certificates are acceptable for mobile device authentication.</xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:attribute name="acceptProviderCerts" type="xsd:boolean"
- use="optional" default="true">
- <xsd:annotation>
- <xsd:documentation>When this boolean is true, X509v3 certificates issued by providers identified in the providerIssuerName child element(s) are acceptable for mobile device authentication.</xsd:documentation>
- </xsd:annotation>
- </xsd:attribute>
- <xsd:anyAttribute namespace="##other"/>
- </xsd:complexType>
-</xsd:element>
- */
-
-public class ClientCertInfo implements OSUCommandData {
- private final boolean mAcceptMfgCerts;
- private final boolean mAcceptProviderCerts;
- /*
- * The issuer name of an acceptable provider-issued certificate.
- * The text of this element is formatted in accordance with the Issuer Name field in RFC-3280.
- * This element is present only when acceptProviderCerts is true.
- */
- private final List<String> mIssuerNames;
-
- public ClientCertInfo(XMLNode commandNode) throws OMAException {
- mAcceptMfgCerts = Boolean.parseBoolean(commandNode.getAttributeValue("acceptMfgCerts"));
- mAcceptProviderCerts = Boolean.parseBoolean(commandNode.getAttributeValue("acceptProviderCerts"));
-
- if (mAcceptMfgCerts) {
- mIssuerNames = new ArrayList<>();
- for (XMLNode node : commandNode.getChildren()) {
- if (node.getStrippedTag().equals("providerIssuerName")) {
- mIssuerNames.add(node.getAttributeValue("name"));
- }
- }
- }
- else {
- mIssuerNames = null;
- }
- }
-
- public boolean doesAcceptMfgCerts() {
- return mAcceptMfgCerts;
- }
-
- public boolean doesAcceptProviderCerts() {
- return mAcceptProviderCerts;
- }
-
- public List<String> getIssuerNames() {
- return mIssuerNames;
- }
-
- @Override
- public String toString() {
- return "ClientCertInfo{" +
- "acceptMfgCerts=" + mAcceptMfgCerts +
- ", acceptProviderCerts=" + mAcceptProviderCerts +
- ", issuerNames=" + mIssuerNames +
- '}';
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/commands/GetCertData.java b/service/java/com/android/server/wifi/hotspot2/osu/commands/GetCertData.java
deleted file mode 100644
index 0699c944e..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/commands/GetCertData.java
+++ /dev/null
@@ -1,75 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.commands;
-
-import android.util.Base64;
-
-import com.android.server.wifi.hotspot2.omadm.OMAException;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-/*
- <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
- <env:Header/>
- <env:Body>
- <spp:sppPostDevDataResponse xmlns:spp="http://www.wi-fi.org/specifications/hotspot2dot0/v1.0/spp"
- spp:sessionID="A40103ACEDE94C45BA127A41239BD60F" spp:sppStatus="OK"
- spp:sppVersion="1.0">
- <spp:exec>
- <spp:getCertificate enrollmentProtocol="EST">
- <spp:enrollmentServerURI>https://osu-server.r2-testbed-rks.wi-fi.org:9446/.well-known/est
- </spp:enrollmentServerURI>
- <spp:estUserID>a88c4830-aafd-420b-b790-c08f457a0fa3</spp:estUserID>
- <spp:estPassword>cnVja3VzMTIzNA==</spp:estPassword>
- </spp:getCertificate>
- </spp:exec>
- </spp:sppPostDevDataResponse>
- </env:Body>
- </env:Envelope>
- */
-
-public class GetCertData implements OSUCommandData {
- private final String mProtocol;
- private final String mServer;
- private final String mUserName;
- private final byte[] mPassword;
-
- public GetCertData(XMLNode commandNode) throws OMAException {
- mProtocol = commandNode.getAttributeValue("enrollmentProtocol");
-
- Map<String, String> values = new HashMap<>(3);;
- for (XMLNode node : commandNode.getChildren()) {
- values.put(node.getStrippedTag(), node.getText());
- }
-
- mServer = values.get("enrollmentserveruri");
- mUserName = values.get("estuserid");
- mPassword = Base64.decode(values.get("estpassword"), Base64.DEFAULT);
- }
-
- public String getProtocol() {
- return mProtocol;
- }
-
- public String getServer() {
- return mServer;
- }
-
- public String getUserName() {
- return mUserName;
- }
-
- public byte[] getPassword() {
- return mPassword;
- }
-
- @Override
- public String toString() {
- return "GetCertData " +
- "protocol='" + mProtocol + '\'' +
- ", server='" + mServer + '\'' +
- ", userName='" + mUserName + '\'' +
- ", password='" + new String(mPassword, StandardCharsets.ISO_8859_1) + '\'';
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/commands/MOURN.java b/service/java/com/android/server/wifi/hotspot2/osu/commands/MOURN.java
deleted file mode 100644
index fb75db21a..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/commands/MOURN.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.commands;
-
-/*
-<xsd:element name="uploadMO" maxOccurs="unbounded">
- <xsd:annotation>
- <xsd:documentation>Command to mobile to upload the MO named in the moURN attribute to the SPP server.</xsd:documentation>
- </xsd:annotation>
- <xsd:complexType>
- <xsd:attribute ref="moURN"/>
- </xsd:complexType>
-</xsd:element>
- */
-
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-public class MOURN implements OSUCommandData {
- private final String mURN;
-
- public MOURN(XMLNode root) {
- mURN = root.getAttributeValue("spp:moURN");
- }
-
- public String getURN() {
- return mURN;
- }
-
- @Override
- public String toString() {
- return "MOURN{" +
- "URN='" + mURN + '\'' +
- '}';
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/commands/OSUCommandData.java b/service/java/com/android/server/wifi/hotspot2/osu/commands/OSUCommandData.java
deleted file mode 100644
index edfdf6a10..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/commands/OSUCommandData.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.commands;
-
-/**
- * Marker interface
- */
-public interface OSUCommandData {
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/commands/PasspointManagementObjectData.java b/service/java/com/android/server/wifi/hotspot2/osu/commands/PasspointManagementObjectData.java
deleted file mode 100644
index 8b341721e..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/commands/PasspointManagementObjectData.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.commands;
-
-import android.net.wifi.PasspointManagementObjectDefinition;
-
-import com.android.server.wifi.hotspot2.omadm.MOTree;
-import com.android.server.wifi.hotspot2.omadm.OMAConstants;
-import com.android.server.wifi.hotspot2.omadm.OMAParser;
-import com.android.server.wifi.hotspot2.omadm.XMLNode;
-
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-
-/**
- * This object describes a partial tree structure in the Hotspot 2.0 release 2 management object.
- * The object is used during subscription remediation to modify parts of an existing PPS MO
- * tree (Hotspot 2.0 specification section 9.1
- */
-public class PasspointManagementObjectData implements OSUCommandData {
- private final String mBaseURI;
- private final String mURN;
- private final MOTree mMOTree;
-
- public PasspointManagementObjectData(XMLNode root) {
- mBaseURI = root.getAttributeValue("spp:managementTreeURI");
- mURN = root.getAttributeValue("spp:moURN");
- mMOTree = root.getMOTree();
- }
-
- public PasspointManagementObjectData(PasspointManagementObjectDefinition moDef)
- throws IOException, SAXException {
- mBaseURI = moDef.getmBaseUri();
- mURN = moDef.getmUrn();
- OMAParser omaParser = new OMAParser();
- mMOTree = omaParser.parse(moDef.getmMoTree(), OMAConstants.PPS_URN);
- }
-
- public String getBaseURI() {
- return mBaseURI;
- }
-
- public String getURN() {
- return mURN;
- }
-
- public MOTree getMOTree() {
- return mMOTree;
- }
-
- @Override
- public String toString() {
- return "Base URI: " + mBaseURI + ", MO: " + mMOTree;
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/service/RedirectListener.java b/service/java/com/android/server/wifi/hotspot2/osu/service/RedirectListener.java
deleted file mode 100644
index 2117922e2..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/service/RedirectListener.java
+++ /dev/null
@@ -1,204 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.service;
-
-import android.util.Log;
-
-import com.android.server.wifi.hotspot2.osu.OSUManager;
-import com.android.server.wifi.hotspot2.osu.OSUOperationStatus;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.net.InetAddress;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import java.util.Random;
-
-public class RedirectListener extends Thread {
- private static final long ThreadTimeout = 3000L;
- private static final long UserTimeout = 3600000L;
- private static final int MaxRetry = 5;
- private static final String TAG = "OSULSN";
-
- private static final String HTTPResponseHeader =
- "HTTP/1.1 304 Not Modified\r\n" +
- "Server: dummy\r\n" +
- "Keep-Alive: timeout=500, max=5\r\n\r\n";
-
- private static final String GoodBye =
- "<html>" +
- "<head><title>Goodbye</title></head>" +
- "<body>" +
- "<h3>Killing browser...</h3>" +
- "</body>" +
- "</html>\r\n";
-
- private final OSUManager mOSUManager;
- private final ServerSocket mServerSocket;
- private final String mPath;
- private final URL mURL;
- private final Object mLock = new Object();
-
- private boolean mListening;
- private OSUOperationStatus mUserStatus;
- private volatile boolean mAborted;
-
- public RedirectListener(OSUManager osuManager) throws IOException {
- mOSUManager = osuManager;
- mServerSocket = new ServerSocket(0, 5, InetAddress.getLocalHost());
- Random rnd = new Random(System.currentTimeMillis());
- mPath = "rnd" + Integer.toString(Math.abs(rnd.nextInt()), Character.MAX_RADIX);
- mURL = new URL("http", mServerSocket.getInetAddress().getHostAddress(),
- mServerSocket.getLocalPort(), mPath);
-
- Log.d(TAG, "Redirect URL: " + mURL);
- setName("HS20-Redirect-Listener");
- setDaemon(true);
- }
-
- public void startService() throws IOException {
- start();
- synchronized (mLock) {
- long bail = System.currentTimeMillis() + ThreadTimeout;
- long remainder = ThreadTimeout;
- while (remainder > 0 && !mListening) {
- try {
- mLock.wait(remainder);
- }
- catch (InterruptedException ie) {
- /**/
- }
- if (mListening) {
- break;
- }
- remainder = bail - System.currentTimeMillis();
- }
- if (!mListening) {
- throw new IOException("Failed to start listener");
- }
- else {
- Log.d(TAG, "OSU Redirect listener running");
- }
- }
- }
-
- public boolean waitForUser() {
- boolean success;
- synchronized (mLock) {
- long bail = System.currentTimeMillis() + UserTimeout;
- long remainder = UserTimeout;
- while (remainder > 0 && mUserStatus == null) {
- try {
- mLock.wait(remainder);
- }
- catch (InterruptedException ie) {
- /**/
- }
- if (mUserStatus != null) {
- break;
- }
- remainder = bail - System.currentTimeMillis();
- }
- success = mUserStatus == OSUOperationStatus.UserInputComplete;
- }
- abort();
- return success;
- }
-
- public void abort() {
- try {
- mAborted = true;
- mServerSocket.close();
- }
- catch (IOException ioe) {
- /**/
- }
- }
-
- public URL getURL() {
- return mURL;
- }
-
- @Override
- public void run() {
- int count = 0;
- synchronized (mLock) {
- mListening = true;
- mLock.notifyAll();
- }
-
- boolean terminate = false;
-
- for (;;) {
- count++;
- try (Socket instance = mServerSocket.accept()) {
- try (BufferedReader in = new BufferedReader(
- new InputStreamReader(instance.getInputStream(), StandardCharsets.UTF_8))) {
- boolean detected = false;
- StringBuilder sb = new StringBuilder();
- String s;
- while ((s = in.readLine()) != null) {
- sb.append(s).append('\n');
- if (!detected && s.startsWith("GET")) {
- String[] segments = s.split(" ");
- if (segments.length == 3 &&
- segments[2].startsWith("HTTP/") &&
- segments[1].regionMatches(1, mPath, 0, mPath.length())) {
- detected = true;
- }
- }
- if (s.length() == 0) {
- break;
- }
- }
- Log.d(TAG, "Redirect receive: " + sb);
- String response = null;
- if (detected) {
- response = status(OSUOperationStatus.UserInputComplete);
- if (response == null) {
- response = GoodBye;
- terminate = true;
- }
- }
- try (BufferedWriter out = new BufferedWriter(
- new OutputStreamWriter(instance.getOutputStream(),
- StandardCharsets.UTF_8))) {
-
- out.write(HTTPResponseHeader);
- if (response != null) {
- out.write(response);
- }
- }
- if (terminate) {
- break;
- }
- else if (count > MaxRetry) {
- status(OSUOperationStatus.UserInputAborted);
- break;
- }
- }
- }
- catch (IOException ioe) {
- if (mAborted) {
- return;
- }
- else if (count > MaxRetry) {
- status(OSUOperationStatus.UserInputAborted);
- break;
- }
- }
- }
- }
-
- private String status(OSUOperationStatus status) {
- Log.d(TAG, "User input status: " + status);
- synchronized (mLock) {
- mUserStatus = status;
- mLock.notifyAll();
- }
- return mOSUManager.notifyUser(status, null);
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/osu/service/SubscriptionTimer.java b/service/java/com/android/server/wifi/hotspot2/osu/service/SubscriptionTimer.java
deleted file mode 100644
index 5e24dac3f..000000000
--- a/service/java/com/android/server/wifi/hotspot2/osu/service/SubscriptionTimer.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package com.android.server.wifi.hotspot2.osu.service;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.util.Log;
-
-import com.android.server.wifi.hotspot2.Utils;
-import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager;
-import com.android.server.wifi.hotspot2.osu.OSUManager;
-import com.android.server.wifi.hotspot2.pps.HomeSP;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-public class SubscriptionTimer {
- private final AlarmManager mAlarmManager;
- private final OSUManager mOSUManager;
- private final PasspointManagementObjectManager mMOManager;
- private final PendingIntent mTimerIntent;
- private final Map<HomeSP, UpdateAction> mOutstanding = new HashMap<>();
-
- private static class UpdateAction {
- private final long mRemediation;
- private final long mPolicy;
-
- private UpdateAction(HomeSP homeSP, long now) {
- mRemediation = homeSP.getSubscriptionUpdate() != null ?
- now + homeSP.getSubscriptionUpdate().getInterval() : -1;
- mPolicy = homeSP.getPolicy() != null ?
- now + homeSP.getPolicy().getPolicyUpdate().getInterval() : -1;
-
- Log.d(OSUManager.TAG, "Timer set for " + homeSP .getFQDN() +
- ", remediation: " + Utils.toUTCString(mRemediation) +
- ", policy: " + Utils.toUTCString(mPolicy));
- }
-
- private boolean remediate(long now) {
- return mRemediation > 0 && now >= mRemediation;
- }
-
- private boolean policyUpdate(long now) {
- return mPolicy > 0 && now >= mPolicy;
- }
-
- private long nextExpiry(long now) {
- long min = Long.MAX_VALUE;
- if (mRemediation > now) {
- min = mRemediation;
- }
- if (mPolicy > now) {
- min = Math.min(min, mPolicy);
- }
- return min;
- }
- }
-
- private static final String ACTION_TIMER =
- "com.android.server.wifi.hotspot2.osu.service.SubscriptionTimer.action.TICK";
-
- public SubscriptionTimer(OSUManager osuManager, PasspointManagementObjectManager moManager, Context context) {
- mOSUManager = osuManager;
- mMOManager = moManager;
- mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
-
- Intent intent = new Intent(ACTION_TIMER, null);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- intent.setPackage("android");
- mTimerIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
-
- context.registerReceiver(
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- tick();
- }
- },
- new IntentFilter(ACTION_TIMER));
- }
-
- public void checkUpdates() {
- mAlarmManager.cancel(mTimerIntent);
- long now = System.currentTimeMillis();
- long next = Long.MAX_VALUE;
- for (HomeSP homeSP : mMOManager.getLoadedSPs().values()) {
- UpdateAction updateAction = mOutstanding.get(homeSP);
- try {
- if (updateAction == null) {
- updateAction = new UpdateAction(homeSP, now);
- mOutstanding.put(homeSP, updateAction);
- } else if (updateAction.remediate(now)) {
- mOSUManager.remediate(homeSP, false);
- mOutstanding.put(homeSP, new UpdateAction(homeSP, now));
- } else if (updateAction.policyUpdate(now)) {
- mOSUManager.remediate(homeSP, true);
- mOutstanding.put(homeSP, new UpdateAction(homeSP, now));
- }
- next = Math.min(next, updateAction.nextExpiry(now));
- }
- catch (IOException ioe) {
- Log.d(OSUManager.TAG, "Failed subscription update: " + ioe.getMessage());
- }
- }
- setAlarm(next);
- }
-
- private void setAlarm(long tod) {
- mAlarmManager.set(AlarmManager.RTC_WAKEUP, tod, mTimerIntent);
- }
-
- private void tick() {
- checkUpdates();
- }
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/utils/HTTPMessage.java b/service/java/com/android/server/wifi/hotspot2/utils/HTTPMessage.java
deleted file mode 100644
index 685f973d7..000000000
--- a/service/java/com/android/server/wifi/hotspot2/utils/HTTPMessage.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.android.server.wifi.hotspot2.utils;
-
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.util.Map;
-
-public interface HTTPMessage {
- public static final String HTTPVersion = "HTTP/1.1";
- public static final String AgentHeader = "User-Agent";
- public static final String AgentName = "Android HS Client";
- public static final String HostHeader = "Host";
- public static final String AcceptHeader = "Accept";
- public static final String LengthHeader = "Content-Length";
- public static final String ContentTypeHeader = "Content-Type";
- public static final String ContentLengthHeader = "Content-Length";
- public static final String ContentEncodingHeader = "Content-Transfer-Encoding";
- public static final String AuthHeader = "WWW-Authenticate";
- public static final String AuthorizationHeader = "Authorization";
-
- public static final String ContentTypeSOAP = "application/soap+xml";
-
- public static final int RX_BUFFER = 32768;
- public static final String CRLF = "\r\n";
- public static final int BODY_SEPARATOR = 0x0d0a0d0a;
- public static final int BODY_SEPARATOR_LENGTH = 4;
-
- public enum Method { GET, PUT, POST }
-
- public Map<String,String> getHeaders();
- public InputStream getPayloadStream();
- public ByteBuffer getPayload();
- public ByteBuffer getBinaryPayload();
-}
diff --git a/service/java/com/android/server/wifi/hotspot2/utils/HTTPRequest.java b/service/java/com/android/server/wifi/hotspot2/utils/HTTPRequest.java
deleted file mode 100644
index 353560e05..000000000
--- a/service/java/com/android/server/wifi/hotspot2/utils/HTTPRequest.java
+++ /dev/null
@@ -1,288 +0,0 @@
-package com.android.server.wifi.hotspot2.utils;
-
-import android.util.Base64;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.SecureRandom;
-import java.util.*;
-
-public class HTTPRequest implements HTTPMessage {
- private static final Charset HeaderCharset = StandardCharsets.US_ASCII;
- private static final int HTTPS_PORT = 443;
-
- private final String mMethodLine;
- private final Map<String, String> mHeaderFields;
- private final byte[] mBody;
-
- public HTTPRequest(Method method, URL url) {
- this(null, null, method, url, null, false);
- }
-
- public HTTPRequest(String payload, Charset charset, Method method, URL url, String contentType, boolean base64) {
- mBody = payload != null ? payload.getBytes(charset) : null;
-
- mHeaderFields = new LinkedHashMap<>();
- mHeaderFields.put(AgentHeader, AgentName);
- if (url.getPort() != HTTPS_PORT) {
- mHeaderFields.put(HostHeader, url.getHost() + ':' + url.getPort());
- } else {
- mHeaderFields.put(HostHeader, url.getHost());
- }
- mHeaderFields.put(AcceptHeader, "*/*");
- if (payload != null) {
- if (base64) {
- mHeaderFields.put(ContentTypeHeader, contentType);
- mHeaderFields.put(ContentEncodingHeader, "base64");
- } else {
- mHeaderFields.put(ContentTypeHeader, contentType + "; charset=" + charset.displayName().toLowerCase());
- }
- mHeaderFields.put(ContentLengthHeader, Integer.toString(mBody.length));
- }
-
- mMethodLine = method.name() + ' ' + url.getPath() + ' ' + HTTPVersion + CRLF;
- }
-
- public void doAuthenticate(HTTPResponse httpResponse, String userName, byte[] password,
- URL url, int sequence) throws IOException, GeneralSecurityException {
- mHeaderFields.put(HTTPMessage.AuthorizationHeader,
- generateAuthAnswer(httpResponse, userName, password, url, sequence));
- }
-
- private static String generateAuthAnswer(HTTPResponse httpResponse, String userName, byte[] password,
- URL url, int sequence) throws IOException, GeneralSecurityException {
-
- String authRequestLine = httpResponse.getHeader(HTTPMessage.AuthHeader);
- if (authRequestLine == null) {
- throw new IOException("Missing auth line");
- }
- String[] tokens = authRequestLine.split("[ ,]+");
- //System.out.println("Tokens: " + Arrays.toString(tokens));
- if (tokens.length < 3 || !tokens[0].equalsIgnoreCase("digest")) {
- throw new IOException("Bad " + HTTPMessage.AuthHeader + ": '" + authRequestLine + "'");
- }
-
- Map<String, String> itemMap = new HashMap<>();
- for (int n = 1; n < tokens.length; n++) {
- String s = tokens[n];
- int split = s.indexOf('=');
- if (split < 0) {
- continue;
- }
- itemMap.put(s.substring(0, split).trim().toLowerCase(), unquote(s.substring(split + 1).trim()));
- }
-
- Set<String> qops = splitValue(itemMap.remove("qop"));
- if (!qops.contains("auth")) {
- throw new IOException("Unsupported quality of protection value(s): '" + qops + "'");
- }
- String algorithm = itemMap.remove("algorithm");
- if (algorithm != null && !algorithm.equalsIgnoreCase("md5")) {
- throw new IOException("Unsupported algorithm: '" + algorithm + "'");
- }
- String realm = itemMap.remove("realm");
- String nonceText = itemMap.remove("nonce");
- if (realm == null || nonceText == null) {
- throw new IOException("realm and/or nonce missing: '" + authRequestLine + "'");
- }
- //System.out.println("Remaining tokens: " + itemMap);
-
- byte[] cnonce = new byte[16];
- SecureRandom prng = new SecureRandom();
- prng.nextBytes(cnonce);
-
- /*
- * H(data) = MD5(data)
- * KD(secret, data) = H(concat(secret, ":", data))
- *
- * A1 = unq(username-value) ":" unq(realm-value) ":" passwd
- * A2 = Method ":" digest-uri-value
- *
- * response = KD ( H(A1), unq(nonce-value) ":" nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" H(A2) )
- */
-
- String nc = String.format("%08d", sequence);
-
- /*
- * This bears witness to the ingenuity of the emerging "web generation" and the authors of RFC-2617:
- * Strings are treated as a sequence of octets in blind ignorance of character encoding, whereas
- * octets strings apparently aren't "good enough" and expanded to "hex strings"...
- * As a wild guess I apply UTF-8 below.
- */
- String passwordString = new String(password, StandardCharsets.UTF_8);
- String cNonceString = bytesToHex(cnonce);
-
- byte[] a1 = hash(userName, realm, passwordString);
- byte[] a2 = hash("POST", url.getPath());
- byte[] response = hash(a1, nonceText, nc, cNonceString, "auth", a2);
-
- StringBuilder authLine = new StringBuilder();
- authLine.append("Digest ")
- .append("username=\"").append(userName).append("\", ")
- .append("realm=\"").append(realm).append("\", ")
- .append("nonce=\"").append(nonceText).append("\", ")
- .append("uri=\"").append(url.getPath()).append("\", ")
- .append("qop=\"auth\", ")
- .append("nc=").append(nc).append(", ")
- .append("cnonce=\"").append(cNonceString).append("\", ")
- .append("response=\"").append(bytesToHex(response)).append('"');
- String opaque = itemMap.get("opaque");
- if (opaque != null) {
- authLine.append(", \"").append(opaque).append('"');
- }
-
- return authLine.toString();
- }
-
- private static Set<String> splitValue(String value) {
- Set<String> result = new HashSet<>();
- if (value != null) {
- for (String s : value.split(",")) {
- result.add(s.trim());
- }
- }
- return result;
- }
-
- private static byte[] hash(Object... objects) throws GeneralSecurityException {
- MessageDigest hash = MessageDigest.getInstance("MD5");
-
- //System.out.println("<Hash>");
- boolean first = true;
- for (Object object : objects) {
- byte[] octets;
- if (object.getClass() == String.class) {
- //System.out.println("+= '" + object + "'");
- octets = ((String) object).getBytes(StandardCharsets.UTF_8);
- } else {
- octets = bytesToHexBytes((byte[]) object);
- //System.out.println("+= " + new String(octets, StandardCharsets.ISO_8859_1));
- }
- if (first) {
- first = false;
- } else {
- hash.update((byte) ':');
- }
- hash.update(octets);
- }
- //System.out.println("</Hash>");
- return hash.digest();
- }
-
- private static String unquote(String s) {
- return s.startsWith("\"") ? s.substring(1, s.length() - 1) : s;
- }
-
- private static byte[] bytesToHexBytes(byte[] octets) {
- return bytesToHex(octets).getBytes(StandardCharsets.ISO_8859_1);
- }
-
- private static String bytesToHex(byte[] octets) {
- StringBuilder sb = new StringBuilder(octets.length * 2);
- for (byte b : octets) {
- sb.append(String.format("%02x", b & 0xff));
- }
- return sb.toString();
- }
-
- private byte[] buildHeader() {
- StringBuilder header = new StringBuilder();
- header.append(mMethodLine);
- for (Map.Entry<String, String> entry : mHeaderFields.entrySet()) {
- header.append(entry.getKey()).append(": ").append(entry.getValue()).append(CRLF);
- }
- header.append(CRLF);
-
- //System.out.println("HTTP Request:");
- StringBuilder sb2 = new StringBuilder();
- sb2.append(header);
- if (mBody != null) {
- sb2.append(new String(mBody, StandardCharsets.ISO_8859_1));
- }
- //System.out.println(sb2);
- //System.out.println("End HTTP Request.");
-
- return header.toString().getBytes(HeaderCharset);
- }
-
- public void send(OutputStream out) throws IOException {
- out.write(buildHeader());
- if (mBody != null) {
- out.write(mBody);
- }
- out.flush();
- }
-
- @Override
- public Map<String, String> getHeaders() {
- return Collections.unmodifiableMap(mHeaderFields);
- }
-
- @Override
- public InputStream getPayloadStream() {
- return mBody != null ? new ByteArrayInputStream(mBody) : null;
- }
-
- @Override
- public ByteBuffer getPayload() {
- return mBody != null ? ByteBuffer.wrap(mBody) : null;
- }
-
- @Override
- public ByteBuffer getBinaryPayload() {
- byte[] binary = Base64.decode(mBody, Base64.DEFAULT);
- return ByteBuffer.wrap(binary);
- }
-
- public static void main(String[] args) throws GeneralSecurityException {
- test("Mufasa", "testrealm@host.com", "Circle Of Life", "GET", "/dir/index.html", "dcd98b7102dd2f0e8b11d0f600bfb0c093", "0a4f113b", "00000001", "auth", "6629fae49393a05397450978507c4ef1");
-
- // WWW-Authenticate: Digest realm="wi-fi.org", qop="auth", nonce="MTQzMTg1MTIxMzUyNzo0OGFhNGU5ZTg4Y2M4YmFhYzM2MzAwZDg5MGNiYTJlNw=="
- // Authorization: Digest
- // username="1c7e1582-604d-4c00-b411-bb73735cbcb0"
- // realm="wi-fi.org"
- // nonce="MTQzMTg1MTIxMzUyNzo0OGFhNGU5ZTg4Y2M4YmFhYzM2MzAwZDg5MGNiYTJlNw=="
- // uri="/.well-known/est/simpleenroll"
- // cnonce="NzA3NDk0"
- // nc=00000001
- // qop="auth"
- // response="2c485d24076452e712b77f4e70776463"
-
- String nonce = "MTQzMTg1MTIxMzUyNzo0OGFhNGU5ZTg4Y2M4YmFhYzM2MzAwZDg5MGNiYTJlNw==";
- String cnonce = "NzA3NDk0";
- test("1c7e1582-604d-4c00-b411-bb73735cbcb0", "wi-fi.org", "ruckus1234", "POST", "/.well-known/est/simpleenroll",
- /*new String(Base64.getDecoder().decode(nonce), StandardCharsets.ISO_8859_1)*/ nonce,
- /*new String(Base64.getDecoder().decode(cnonce), StandardCharsets.ISO_8859_1) */ cnonce, "00000001", "auth", "2c485d24076452e712b77f4e70776463");
- }
-
- private static void test(String user, String realm, String password, String method, String path, String nonce, String cnonce, String nc, String qop, String expect) throws GeneralSecurityException {
- byte[] a1 = hash(user, realm, password);
- System.out.println("HA1: " + bytesToHex(a1));
- byte[] a2 = hash(method, path);
- System.out.println("HA2: " + bytesToHex(a2));
- byte[] response = hash(a1, nonce, nc, cnonce, qop, a2);
-
- StringBuilder authLine = new StringBuilder();
- String responseString = bytesToHex(response);
- authLine.append("Digest ")
- .append("username=\"").append(user).append("\", ")
- .append("realm=\"").append(realm).append("\", ")
- .append("nonce=\"").append(nonce).append("\", ")
- .append("uri=\"").append(path).append("\", ")
- .append("qop=\"").append(qop).append("\", ")
- .append("nc=").append(nc).append(", ")
- .append("cnonce=\"").append(cnonce).append("\", ")
- .append("response=\"").append(responseString).append('"');
-
- System.out.println(authLine);
- System.out.println("Success: " + responseString.equals(expect));
- }
-} \ No newline at end of file
diff --git a/service/java/com/android/server/wifi/hotspot2/utils/HTTPResponse.java b/service/java/com/android/server/wifi/hotspot2/utils/HTTPResponse.java
deleted file mode 100644
index 4d8dd2d46..000000000
--- a/service/java/com/android/server/wifi/hotspot2/utils/HTTPResponse.java
+++ /dev/null
@@ -1,178 +0,0 @@
-package com.android.server.wifi.hotspot2.utils;
-
-import android.util.Base64;
-import android.util.Log;
-
-import com.android.server.wifi.hotspot2.osu.OSUManager;
-
-import java.io.ByteArrayInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
-import java.util.*;
-
-public class HTTPResponse implements HTTPMessage {
- private final int mStatusCode;
- private final Map<String, String> mHeaders = new LinkedHashMap<>();
- private final ByteBuffer mBody;
-
- private static final String csIndicator = "charset=";
-
- public HTTPResponse(InputStream in) throws IOException {
- int expected = Integer.MAX_VALUE;
- int offset = 0;
- int body = -1;
- byte[] input = new byte[RX_BUFFER];
-
- int statusCode = -1;
- int bodyPattern = 0;
-
- while (offset < expected) {
- int amount = in.read(input, offset, input.length - offset);
- Log.d(OSUManager.TAG, String.format("Reading into %d from %d, amount %d -> %d", input.length, offset, input.length - offset, amount));
- if (amount < 0) {
- throw new EOFException();
- }
- //Log.d("ZXZ", "HTTP response: '" + new String(input, 0, offset + amount, StandardCharsets.ISO_8859_1));
-
- if (body < 0) {
- for (int n = offset; n < offset + amount; n++) {
- bodyPattern = (bodyPattern << 8) | (input[n] & 0xff);
- if (bodyPattern == 0x0d0a0d0a) {
- body = n + 1;
- statusCode = parseHeader(input, body, mHeaders);
- expected = calculateLength(body, mHeaders);
- if (expected > input.length) {
- input = Arrays.copyOf(input, expected);
- }
- break;
- }
- }
- }
- offset += amount;
- if (offset < expected && offset == input.length) {
- input = Arrays.copyOf(input, input.length * 2);
- }
- }
- mStatusCode = statusCode;
- mBody = ByteBuffer.wrap(input, body, expected - body);
- }
-
- private static int parseHeader(byte[] input, int body, Map<String, String> headers) throws IOException {
- String headerText = new String(input, 0, body - BODY_SEPARATOR_LENGTH, StandardCharsets.ISO_8859_1);
- //System.out.println("Received header: " + headerText);
- Iterator<String> headerLines = Arrays.asList(headerText.split(CRLF)).iterator();
- if (!headerLines.hasNext()) {
- throw new IOException("Bad HTTP Request");
- }
-
- int statusCode;
- String line0 = headerLines.next();
- String[] status = line0.split(" ");
- if (status.length != 3 || !"HTTP/1.1".equals(status[0]) ) {
- throw new IOException("Bad HTTP Result: " + line0);
- }
- try {
- statusCode = Integer.parseInt(status[1].trim());
- }
- catch (NumberFormatException nfe) {
- throw new IOException("Bad HTTP header line: '" + line0 + "'");
- }
-
- while(headerLines.hasNext()) {
- String line = headerLines.next();
- int keyEnd = line.indexOf(':');
- if (keyEnd < 0) {
- throw new IOException("Bad header line: '" + line + "'");
- }
- String key = line.substring(0, keyEnd).trim();
- String value = line.substring(keyEnd + 1).trim();
- headers.put(key, value);
- }
- return statusCode;
- }
-
- private static int calculateLength(int body, Map<String, String> headers) throws IOException {
- String contentLength = headers.get(LengthHeader);
- if (contentLength == null) {
- throw new IOException("No " + LengthHeader);
- }
- try {
- return body + Integer.parseInt(contentLength);
- }
- catch (NumberFormatException nfe) {
- throw new IOException("Bad " + LengthHeader + ": " + contentLength);
- }
- }
-
- public int getStatusCode() {
- return mStatusCode;
- }
-
- @Override
- public Map<String, String> getHeaders() {
- return Collections.unmodifiableMap(mHeaders);
- }
-
- public String getHeader(String key) {
- return mHeaders.get(key);
- }
-
- @Override
- public InputStream getPayloadStream() {
- return new ByteArrayInputStream(mBody.array(), mBody.position(), mBody.limit() - mBody.position());
- }
-
- @Override
- public ByteBuffer getPayload() {
- return mBody.duplicate();
- }
-
- @Override
- public ByteBuffer getBinaryPayload() {
- byte[] data = new byte[mBody.remaining()];
- mBody.duplicate().get(data);
- byte[] binary = Base64.decode(data, Base64.DEFAULT);
- return ByteBuffer.wrap(binary);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("Status: ").append(mStatusCode).append(CRLF);
- for (Map.Entry<String,String> entry : mHeaders.entrySet()) {
- sb.append(entry.getKey()).append(": ").append(entry.getValue()).append(CRLF);
- }
- sb.append(CRLF);
- Charset charset;
- try {
- charset = Charset.forName(getCharset());
- }
- catch (IllegalArgumentException iae) {
- charset = StandardCharsets.ISO_8859_1;
- }
- sb.append(new String(mBody.array(), mBody.position(), mBody.limit() - mBody.position(), charset));
- return sb.toString();
- }
-
- public String getCharset() {
- String contentType = mHeaders.get(ContentTypeHeader);
- if (contentType == null) {
- return null;
- }
- int csPos = contentType.indexOf(csIndicator);
- return csPos < 0 ? null : contentType.substring(csPos + csIndicator.length()).trim();
- }
-
- private static boolean equals(byte[] b1, int offset, byte[] pattern) {
- for (int n = 0; n < pattern.length; n++) {
- if (b1[n+offset] != pattern[n]) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
index 13df114be..9f99cbf93 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiStateMachineTest.java
@@ -67,7 +67,6 @@ import com.android.server.wifi.hotspot2.NetworkDetail;
import com.android.server.wifi.hotspot2.SupplicantBridge;
import com.android.server.wifi.hotspot2.Utils;
import com.android.server.wifi.hotspot2.omadm.PasspointManagementObjectManager;
-import com.android.server.wifi.hotspot2.osu.OSUManager;
import com.android.server.wifi.p2p.WifiP2pServiceImpl;
import org.junit.After;
@@ -161,11 +160,6 @@ public class WifiStateMachineTest {
IBinder batteryStatsBinder = mockService(BatteryStats.class, IBatteryStats.class);
when(facade.getService(BatteryStats.SERVICE_NAME)).thenReturn(batteryStatsBinder);
- when(facade.makeOsuManager(any(WifiConfigStore.class), any(Context.class), any(
- SupplicantBridge.class),
- any(PasspointManagementObjectManager.class), any(WifiStateMachine.class)))
- .thenReturn(mock(OSUManager.class));
-
when(facade.makeIpManager(any(Context.class), anyString(), any(IpManager.Callback.class)))
.then(new AnswerWithArguments<IpManager>() {
public IpManager answer(