Search in sources :

Example 1 with MOData

use of com.android.hotspot2.osu.commands.MOData in project android_frameworks_base by ResurrectionRemix.

the class OSUClient method remediate.

public void remediate(OSUManager osuManager, Network network, KeyManager km, HomeSP homeSP, int flowType) throws IOException, GeneralSecurityException {
    try (HTTPHandler httpHandler = createHandler(network, homeSP, km, flowType)) {
        URL redirectURL = osuManager.prepareUserInput(homeSP.getFriendlyName());
        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(TAG, "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 (flowType == OSUManager.FLOW_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, mKeyStore, homeSP, flowType)) {
                    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<MOData> mods = new ArrayList<>();
        for (OSUCommand command : pddResponse.getCommands()) {
            if (command.getOSUCommand() == OSUCommandID.UpdateNode) {
                mods.add((MOData) 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);
        }
        // the network is lost and the remediation flow fails.
        try {
            osuManager.remediationComplete(homeSP, mods, certs, clientKey);
        } catch (IOException | GeneralSecurityException e) {
            osuManager.provisioningFailed(homeSP.getFriendlyName(), e.getMessage(), homeSP, OSUManager.FLOW_REMEDIATION);
            error = OSUError.CommandFailed;
        }
    }
}
Also used : PrivateKey(java.security.PrivateKey) HashMap(java.util.HashMap) ESTHandler(com.android.hotspot2.est.ESTHandler) GeneralSecurityException(java.security.GeneralSecurityException) ArrayList(java.util.ArrayList) IOException(java.io.IOException) OMADMAdapter(com.android.hotspot2.OMADMAdapter) URL(java.net.URL) MOData(com.android.hotspot2.osu.commands.MOData) BrowserURI(com.android.hotspot2.osu.commands.BrowserURI) ArrayList(java.util.ArrayList) List(java.util.List) GetCertData(com.android.hotspot2.osu.commands.GetCertData)

Example 2 with MOData

use of com.android.hotspot2.osu.commands.MOData in project android_frameworks_base by ResurrectionRemix.

the class OSUManager method provisioningComplete.

public void provisioningComplete(OSUInfo osuInfo, MOData moData, Map<OSUCertType, List<X509Certificate>> certs, PrivateKey privateKey, Network osuNetwork) {
    synchronized (mWifiNetworkAdapter) {
        mProvisioningThread = null;
    }
    try {
        Log.d("ZXZ", "MOTree.toXML: " + moData.getMOTree().toXml());
        HomeSP homeSP = mWifiNetworkAdapter.addSP(moData.getMOTree());
        Integer spNwk = mWifiNetworkAdapter.addNetwork(homeSP, certs, privateKey, osuNetwork);
        if (spNwk == null) {
            notifyUser(OSUOperationStatus.ProvisioningFailure, "Failed to save network configuration", osuInfo.getName(LOCALE));
            mWifiNetworkAdapter.removeSP(homeSP.getFQDN());
        } else {
            Set<X509Certificate> rootCerts = OSUSocketFactory.getRootCerts(mKeyStore);
            X509Certificate remCert = getCert(certs, OSUCertType.Remediation);
            X509Certificate polCert = getCert(certs, OSUCertType.Policy);
            if (privateKey != null) {
                X509Certificate cltCert = getCert(certs, OSUCertType.Client);
                mKeyStore.setKeyEntry(CERT_CLT_KEY_ALIAS + homeSP, privateKey.getEncoded(), new X509Certificate[] { cltCert });
                mKeyStore.setCertificateEntry(CERT_CLT_CERT_ALIAS, cltCert);
            }
            boolean usingShared = false;
            int newCerts = 0;
            if (remCert != null) {
                if (!rootCerts.contains(remCert)) {
                    if (remCert.equals(polCert)) {
                        mKeyStore.setCertificateEntry(CERT_SHARED_ALIAS + homeSP.getFQDN(), remCert);
                        usingShared = true;
                        newCerts++;
                    } else {
                        mKeyStore.setCertificateEntry(CERT_REM_ALIAS + homeSP.getFQDN(), remCert);
                        newCerts++;
                    }
                }
            }
            if (!usingShared && polCert != null) {
                if (!rootCerts.contains(polCert)) {
                    mKeyStore.setCertificateEntry(CERT_POLICY_ALIAS + homeSP.getFQDN(), remCert);
                    newCerts++;
                }
            }
            if (newCerts > 0) {
                try (FileOutputStream out = new FileOutputStream(KEYSTORE_FILE)) {
                    mKeyStore.store(out, null);
                }
            }
            notifyUser(OSUOperationStatus.ProvisioningSuccess, null, osuInfo.getName(LOCALE));
            Log.d(TAG, "Provisioning complete.");
        }
    } catch (IOException | GeneralSecurityException | SAXException e) {
        Log.e(TAG, "Failed to provision: " + e, e);
        notifyUser(OSUOperationStatus.ProvisioningFailure, e.toString(), osuInfo.getName(LOCALE));
    }
}
Also used : HomeSP(com.android.hotspot2.pps.HomeSP) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FileOutputStream(java.io.FileOutputStream) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) SAXException(org.xml.sax.SAXException)

Example 3 with MOData

use of com.android.hotspot2.osu.commands.MOData in project android_frameworks_base by DirtyUnicorns.

the class OSUClient method provision.

public void provision(OSUManager osuManager, Network network, KeyManager km) throws IOException, GeneralSecurityException {
    try (HTTPHandler httpHandler = new HTTPHandler(StandardCharsets.UTF_8, OSUSocketFactory.getSocketFactory(mKeyStore, null, OSUManager.FLOW_PROVISIONING, network, mURL, km, true))) {
        SPVerifier spVerifier = new SPVerifier(mOSUInfo);
        spVerifier.verify(httpHandler.getOSUCertificate(mURL));
        URL redirectURL = osuManager.prepareUserInput(mOSUInfo.getName(Locale.getDefault()));
        OMADMAdapter omadmAdapter = osuManager.getOMADMAdapter();
        String regRequest = SOAPBuilder.buildPostDevDataResponse(RequestReason.SubRegistration, null, redirectURL.toString(), omadmAdapter.getMO(OMAConstants.DevInfoURN), omadmAdapter.getMO(OMAConstants.DevDetailURN));
        Log.d(TAG, "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;
        MOData moData;
        if (estData == null) {
            moData = (MOData) provResponse.getCommandData();
        } else {
            try (ESTHandler estHandler = new ESTHandler((GetCertData) provResponse.getCommandData(), network, osuManager.getOMADMAdapter(), km, mKeyStore, null, OSUManager.FLOW_PROVISIONING)) {
                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 = (MOData) 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, mKeyStore);
        osuManager.provisioningComplete(mOSUInfo, moData, certs, clientKey, network);
    }
}
Also used : PrivateKey(java.security.PrivateKey) HashMap(java.util.HashMap) ESTHandler(com.android.hotspot2.est.ESTHandler) IOException(java.io.IOException) OMADMAdapter(com.android.hotspot2.OMADMAdapter) URL(java.net.URL) ClientCertInfo(com.android.hotspot2.osu.commands.ClientCertInfo) MOData(com.android.hotspot2.osu.commands.MOData) BrowserURI(com.android.hotspot2.osu.commands.BrowserURI) ArrayList(java.util.ArrayList) List(java.util.List) GetCertData(com.android.hotspot2.osu.commands.GetCertData)

Example 4 with MOData

use of com.android.hotspot2.osu.commands.MOData in project android_frameworks_base by DirtyUnicorns.

the class OSUManager method remediationComplete.

public void remediationComplete(HomeSP homeSP, Collection<MOData> mods, Map<OSUCertType, List<X509Certificate>> certs, PrivateKey privateKey) throws IOException, GeneralSecurityException {
    HomeSP altSP = mWifiNetworkAdapter.modifySP(homeSP, 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) {
            // No MO mods, only certs and key
            altSP = homeSP;
        }
        mWifiNetworkAdapter.updateNetwork(altSP, caCert, clientCerts, privateKey);
    }
    notifyUser(OSUOperationStatus.ProvisioningSuccess, null, homeSP.getFriendlyName());
}
Also used : HomeSP(com.android.hotspot2.pps.HomeSP) X509Certificate(java.security.cert.X509Certificate)

Example 5 with MOData

use of com.android.hotspot2.osu.commands.MOData in project android_frameworks_base by DirtyUnicorns.

the class OSUManager method provisioningComplete.

public void provisioningComplete(OSUInfo osuInfo, MOData moData, Map<OSUCertType, List<X509Certificate>> certs, PrivateKey privateKey, Network osuNetwork) {
    synchronized (mWifiNetworkAdapter) {
        mProvisioningThread = null;
    }
    try {
        Log.d("ZXZ", "MOTree.toXML: " + moData.getMOTree().toXml());
        HomeSP homeSP = mWifiNetworkAdapter.addSP(moData.getMOTree());
        Integer spNwk = mWifiNetworkAdapter.addNetwork(homeSP, certs, privateKey, osuNetwork);
        if (spNwk == null) {
            notifyUser(OSUOperationStatus.ProvisioningFailure, "Failed to save network configuration", osuInfo.getName(LOCALE));
            mWifiNetworkAdapter.removeSP(homeSP.getFQDN());
        } else {
            Set<X509Certificate> rootCerts = OSUSocketFactory.getRootCerts(mKeyStore);
            X509Certificate remCert = getCert(certs, OSUCertType.Remediation);
            X509Certificate polCert = getCert(certs, OSUCertType.Policy);
            if (privateKey != null) {
                X509Certificate cltCert = getCert(certs, OSUCertType.Client);
                mKeyStore.setKeyEntry(CERT_CLT_KEY_ALIAS + homeSP, privateKey.getEncoded(), new X509Certificate[] { cltCert });
                mKeyStore.setCertificateEntry(CERT_CLT_CERT_ALIAS, cltCert);
            }
            boolean usingShared = false;
            int newCerts = 0;
            if (remCert != null) {
                if (!rootCerts.contains(remCert)) {
                    if (remCert.equals(polCert)) {
                        mKeyStore.setCertificateEntry(CERT_SHARED_ALIAS + homeSP.getFQDN(), remCert);
                        usingShared = true;
                        newCerts++;
                    } else {
                        mKeyStore.setCertificateEntry(CERT_REM_ALIAS + homeSP.getFQDN(), remCert);
                        newCerts++;
                    }
                }
            }
            if (!usingShared && polCert != null) {
                if (!rootCerts.contains(polCert)) {
                    mKeyStore.setCertificateEntry(CERT_POLICY_ALIAS + homeSP.getFQDN(), remCert);
                    newCerts++;
                }
            }
            if (newCerts > 0) {
                try (FileOutputStream out = new FileOutputStream(KEYSTORE_FILE)) {
                    mKeyStore.store(out, null);
                }
            }
            notifyUser(OSUOperationStatus.ProvisioningSuccess, null, osuInfo.getName(LOCALE));
            Log.d(TAG, "Provisioning complete.");
        }
    } catch (IOException | GeneralSecurityException | SAXException e) {
        Log.e(TAG, "Failed to provision: " + e, e);
        notifyUser(OSUOperationStatus.ProvisioningFailure, e.toString(), osuInfo.getName(LOCALE));
    }
}
Also used : HomeSP(com.android.hotspot2.pps.HomeSP) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FileOutputStream(java.io.FileOutputStream) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) X509Certificate(java.security.cert.X509Certificate) SAXException(org.xml.sax.SAXException)

Aggregations

IOException (java.io.IOException)20 MOData (com.android.hotspot2.osu.commands.MOData)15 HomeSP (com.android.hotspot2.pps.HomeSP)15 OMADMAdapter (com.android.hotspot2.OMADMAdapter)10 ESTHandler (com.android.hotspot2.est.ESTHandler)10 BrowserURI (com.android.hotspot2.osu.commands.BrowserURI)10 GetCertData (com.android.hotspot2.osu.commands.GetCertData)10 URL (java.net.URL)10 GeneralSecurityException (java.security.GeneralSecurityException)10 PrivateKey (java.security.PrivateKey)10 X509Certificate (java.security.cert.X509Certificate)10 ArrayList (java.util.ArrayList)10 HashMap (java.util.HashMap)10 List (java.util.List)10 ClientCertInfo (com.android.hotspot2.osu.commands.ClientCertInfo)5 BufferedInputStream (java.io.BufferedInputStream)5 FileInputStream (java.io.FileInputStream)5 FileOutputStream (java.io.FileOutputStream)5 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)5 SAXException (org.xml.sax.SAXException)5