16a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistpackage com.android.server.wifi.anqp.eap; 26a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 3866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist 46a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport com.android.server.wifi.anqp.Constants; 571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport com.android.server.wifi.hotspot2.AuthMatch; 66a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 76a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.net.ProtocolException; 86a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.nio.ByteBuffer; 97b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvistimport java.nio.ByteOrder; 106a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.Collections; 116a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.EnumMap; 1271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvistimport java.util.HashMap; 136a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.HashSet; 146a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.Map; 156a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistimport java.util.Set; 166a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 176a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist/** 186a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist * An EAP Method, part of the NAI Realm ANQP element, specified in 196a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist * IEEE802.11-2012 section 8.4.4.10, figure 8-420 206a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist */ 216a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvistpublic class EAPMethod { 226a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist private final EAP.EAPMethodID mEAPMethodID; 236a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist private final Map<EAP.AuthInfoID, Set<AuthParam>> mAuthParams; 246a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 256a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public EAPMethod(ByteBuffer payload) throws ProtocolException { 266a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist if (payload.remaining() < 3) { 276a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist throw new ProtocolException("Runt EAP Method: " + payload.remaining()); 286a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 296a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 306a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int length = payload.get() & Constants.BYTE_MASK; 316a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int methodID = payload.get() & Constants.BYTE_MASK; 326a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int count = payload.get() & Constants.BYTE_MASK; 336a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 346a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist mEAPMethodID = EAP.mapEAPMethod(methodID); 35a7ead3d4be45cb69bb5851f1a6f9673e93607fc2Jan Nordqvist mAuthParams = new EnumMap<>(EAP.AuthInfoID.class); 366a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 376a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int realCount = 0; 386a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 397b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist ByteBuffer paramPayload = payload.duplicate().order(ByteOrder.LITTLE_ENDIAN); 40777f4fc037d3ebd555f10041f8acfb41515b2f4bJan Nordqvist paramPayload.limit(paramPayload.position() + length - 2); 41777f4fc037d3ebd555f10041f8acfb41515b2f4bJan Nordqvist payload.position(payload.position() + length - 2); 426a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist while (paramPayload.hasRemaining()) { 436a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist int id = paramPayload.get() & Constants.BYTE_MASK; 446a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 453be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist EAP.AuthInfoID authInfoID = EAP.mapAuthMethod(id); 463be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist if (authInfoID == null) { 476a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist throw new ProtocolException("Unknown auth parameter ID: " + id); 486a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 496a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 503be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist int len = paramPayload.get() & Constants.BYTE_MASK; 513be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist if (len == 0 || len > paramPayload.remaining()) { 523be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist throw new ProtocolException("Bad auth method length: " + len); 533be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist } 543be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist 556a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist switch (authInfoID) { 566a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case ExpandedEAPMethod: 573be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new ExpandedEAPMethod(authInfoID, len, paramPayload)); 586a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 596a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case NonEAPInnerAuthType: 603be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new NonEAPInnerAuth(len, paramPayload)); 616a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 626a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case InnerAuthEAPMethodType: 633be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new InnerAuthEAP(len, paramPayload)); 646a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 656a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case ExpandedInnerEAPMethod: 663be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new ExpandedEAPMethod(authInfoID, len, paramPayload)); 676a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 686a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case CredentialType: 693be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new Credential(authInfoID, len, paramPayload)); 706a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 716a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case TunneledEAPMethodCredType: 723be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new Credential(authInfoID, len, paramPayload)); 736a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 746a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist case VendorSpecific: 753be1b3fc037bef7fb4448dec89aea3f2e1318853Jan Nordqvist addAuthParam(new VendorSpecificAuth(len, paramPayload)); 766a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist break; 776a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 786a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 796a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist realCount++; 806a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 816a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist if (realCount != count) 826a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist throw new ProtocolException("Invalid parameter count: " + realCount + 836a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist ", expected " + count); 846a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 856a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 8671a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist public EAPMethod(EAP.EAPMethodID eapMethodID, AuthParam authParam) { 8771a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist mEAPMethodID = eapMethodID; 88a7ead3d4be45cb69bb5851f1a6f9673e93607fc2Jan Nordqvist mAuthParams = new HashMap<>(1); 8971a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist if (authParam != null) { 90a7ead3d4be45cb69bb5851f1a6f9673e93607fc2Jan Nordqvist Set<AuthParam> authParams = new HashSet<>(); 9171a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist authParams.add(authParam); 9271a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist mAuthParams.put(authParam.getAuthInfoID(), authParams); 9371a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 9471a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist } 9571a988c8e9859244b83cd55bb6b6ee913fcaf95cJan Nordqvist 966a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist private void addAuthParam(AuthParam param) { 976a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist Set<AuthParam> authParams = mAuthParams.get(param.getAuthInfoID()); 986a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist if (authParams == null) { 99a7ead3d4be45cb69bb5851f1a6f9673e93607fc2Jan Nordqvist authParams = new HashSet<>(); 1006a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist mAuthParams.put(param.getAuthInfoID(), authParams); 1016a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1026a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist authParams.add(param); 1036a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1046a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 1056a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public Map<EAP.AuthInfoID, Set<AuthParam>> getAuthParams() { 1066a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist return Collections.unmodifiableMap(mAuthParams); 1076a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1086a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 1096a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public EAP.EAPMethodID getEAPMethodID() { 1106a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist return mEAPMethodID; 1116a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1126a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 113c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist public int match(com.android.server.wifi.hotspot2.pps.Credential credential) { 1146a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 115866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist EAPMethod credMethod = credential.getEAPMethod(); 116866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist if (mEAPMethodID != credMethod.getEAPMethodID()) { 117866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist return AuthMatch.None; 118866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 1196a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 120866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist switch (mEAPMethodID) { 121866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist case EAP_TTLS: 122866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist if (mAuthParams.isEmpty()) { 123c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return AuthMatch.Method; 124866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 125c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist int paramCount = 0; 126866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist for (Map.Entry<EAP.AuthInfoID, Set<AuthParam>> entry : 127866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist credMethod.getAuthParams().entrySet()) { 128866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist Set<AuthParam> params = mAuthParams.get(entry.getKey()); 129c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist if (params == null) { 130866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist continue; 131c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist } 132866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist 133866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist if (!Collections.disjoint(params, entry.getValue())) { 134c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return AuthMatch.MethodParam; 135866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 136c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist paramCount += params.size(); 137866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist } 138c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return paramCount > 0 ? AuthMatch.None : AuthMatch.Method; 139866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist case EAP_TLS: 140c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return AuthMatch.MethodParam; 141866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist case EAP_SIM: 142866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist case EAP_AKA: 143866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist case EAP_AKAPrim: 144c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return AuthMatch.Method; 145866c5b061e6e762f2627e3467afc0fe6f29c2668Jan Nordqvist default: 146c2db1a4ff61fdf72be070e0c1cb739e755760bf3Jan Nordqvist return AuthMatch.Method; 1476a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1486a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1496a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist 15077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist public AuthParam getAuthParam() { 15177f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (mAuthParams.isEmpty()) { 15277f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return null; 15377f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 15477f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist Set<AuthParam> params = mAuthParams.values().iterator().next(); 15577f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist if (params.isEmpty()) { 15677f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return null; 15777f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 15877f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist return params.iterator().next(); 15977f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist } 16077f2b82a2e80af8da52c22d69a76def6d4209757Jan Nordqvist 1616a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist @Override 162820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist public boolean equals(Object thatObject) { 163820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist if (this == thatObject) { 164820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist return true; 165820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist } 166820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist else if (thatObject == null || getClass() != thatObject.getClass()) { 167820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist return false; 168820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist } 169820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist 170820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist EAPMethod that = (EAPMethod) thatObject; 171820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist return mEAPMethodID == that.mEAPMethodID && mAuthParams.equals(that.mAuthParams); 172820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist } 173820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist 174820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist @Override 175820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist public int hashCode() { 176820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist int result = mEAPMethodID.hashCode(); 177820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist result = 31 * result + mAuthParams.hashCode(); 178820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist return result; 179820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist } 180820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist 181820d73615f338d6c71f2d75aba0ad8410e9eed3eJan Nordqvist @Override 1826a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist public String toString() { 1837b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist StringBuilder sb = new StringBuilder(); 1847b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist sb.append("EAP Method ").append(mEAPMethodID).append('\n'); 1857b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist for (Set<AuthParam> paramSet : mAuthParams.values()) { 1867b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist for (AuthParam param : paramSet) { 1877b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist sb.append(" ").append(param.toString()); 1887b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist } 1897b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist } 1907b2caa25fb57f2d95e0d0421704c49d3af4b8e6fJan Nordqvist return sb.toString(); 1916a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist } 1926a3903fed590e369b576bddbe1ae2d788768ddfeJan Nordqvist} 193