use of com.android.hotspot2.osu.HTTPHandler in project android_frameworks_base by ResurrectionRemix.
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);
}
}
use of com.android.hotspot2.osu.HTTPHandler in project android_frameworks_base by ResurrectionRemix.
the class OSUClient method createHandler.
private HTTPHandler createHandler(Network network, HomeSP homeSP, KeyManager km, int flowType) 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 (flowType == OSUManager.FLOW_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(mKeyStore, homeSP, flowType, network, mURL, km, true), user, password);
case EAP_TLS:
return new HTTPHandler(StandardCharsets.UTF_8, OSUSocketFactory.getSocketFactory(mKeyStore, homeSP, flowType, network, mURL, km, true));
default:
throw new IOException("Cannot remediate account with " + credential.getEAPMethod().getEAPMethodID());
}
}
use of com.android.hotspot2.osu.HTTPHandler in project android_frameworks_base by crdroidandroid.
the class ESTHandler method execute.
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());
}
}
}
use of com.android.hotspot2.osu.HTTPHandler in project android_frameworks_base by crdroidandroid.
the class ESTHandler method buildCSR.
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();
}
use of com.android.hotspot2.osu.HTTPHandler in project android_frameworks_base by crdroidandroid.
the class OSUClient method createHandler.
private HTTPHandler createHandler(Network network, HomeSP homeSP, KeyManager km, int flowType) 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 (flowType == OSUManager.FLOW_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(mKeyStore, homeSP, flowType, network, mURL, km, true), user, password);
case EAP_TLS:
return new HTTPHandler(StandardCharsets.UTF_8, OSUSocketFactory.getSocketFactory(mKeyStore, homeSP, flowType, network, mURL, km, true));
default:
throw new IOException("Cannot remediate account with " + credential.getEAPMethod().getEAPMethodID());
}
}
Aggregations