aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java')
-rw-r--r--src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java612
1 files changed, 0 insertions, 612 deletions
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java
deleted file mode 100644
index b26c8e95..00000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_AUTHENTICATION_REJECT;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CLIENT_ERROR;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_SYNCHRONIZATION_FAILURE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_BIDDING;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ENCR_DATA;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_FULLAUTH_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IV;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.crypto.Fips186_2Prf;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.simaka.EapAkaInvalidAuthenticationResponse;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAuts;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * EapAkaMethodStateMachine represents the valid paths possible for the EAP-AKA protocol.
- *
- * <p>EAP-AKA sessions will always follow the path:
- *
- * Created --+--> Identity --+--> Challenge --> Final
- * | |
- * +---------------+
- *
- * Note: If the EAP-Request/AKA-Challenge message contains an AUTN with an invalid sequence number,
- * the peer will indicate a synchronization failure to the server and a new challenge will be
- * attempted.
- *
- * Note: EAP-Request/Notification messages can be received at any point in the above state machine
- * At most one EAP-AKA/Notification message is allowed per EAP-AKA session.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication
- * Protocol for Authentication and Key Agreement (EAP-AKA)</a>
- */
-class EapAkaMethodStateMachine extends EapSimAkaMethodStateMachine {
- private static final String TAG = EapAkaMethodStateMachine.class.getSimpleName();
-
- // EAP-AKA identity prefix (RFC 4187#4.1.1.6)
- private static final String AKA_IDENTITY_PREFIX = "0";
-
- private final EapAkaTypeDataDecoder mEapAkaTypeDataDecoder;
- private final boolean mSupportsEapAkaPrime;
-
- protected EapAkaMethodStateMachine(
- Context context, byte[] eapIdentity, EapAkaConfig eapAkaConfig) {
- this(context, eapIdentity, eapAkaConfig, false);
- }
-
- EapAkaMethodStateMachine(
- Context context,
- byte[] eapIdentity,
- EapAkaConfig eapAkaConfig,
- boolean supportsEapAkaPrime) {
- this(
- (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
- eapIdentity,
- eapAkaConfig,
- EapAkaTypeData.getEapAkaTypeDataDecoder(),
- supportsEapAkaPrime);
- }
-
- @VisibleForTesting
- protected EapAkaMethodStateMachine(
- TelephonyManager telephonyManager,
- byte[] eapIdentity,
- EapAkaConfig eapAkaConfig,
- EapAkaTypeDataDecoder eapAkaTypeDataDecoder,
- boolean supportsEapAkaPrime) {
- super(
- telephonyManager.createForSubscriptionId(eapAkaConfig.subId),
- eapIdentity,
- eapAkaConfig);
- mEapAkaTypeDataDecoder = eapAkaTypeDataDecoder;
- mSupportsEapAkaPrime = supportsEapAkaPrime;
-
- transitionTo(new CreatedState());
- }
-
- @Override
- @EapMethod
- int getEapMethod() {
- return EAP_TYPE_AKA;
- }
-
- protected DecodeResult<EapAkaTypeData> decode(byte[] typeData) {
- return mEapAkaTypeDataDecoder.decode(typeData);
- }
-
- /**
- * This exists so we can override the identity prefix in the EapAkaPrimeMethodStateMachine.
- *
- * @return the Identity prefix for this EAP method
- */
- protected String getIdentityPrefix() {
- return AKA_IDENTITY_PREFIX;
- }
-
- protected ChallengeState buildChallengeState() {
- return new ChallengeState();
- }
-
- protected ChallengeState buildChallengeState(byte[] identity) {
- return new ChallengeState(identity);
- }
-
- protected class CreatedState extends EapMethodState {
- private final String mTAG = CreatedState.class.getSimpleName();
-
- public EapResult process(EapMessage message) {
- EapResult result = handleEapSuccessFailureNotification(mTAG, message);
- if (result != null) {
- return result;
- }
-
- DecodeResult<? extends EapAkaTypeData> decodeResult =
- decode(message.eapData.eapTypeData);
- if (!decodeResult.isSuccessfulDecode()) {
- return buildClientErrorResponse(
- message.eapIdentifier, getEapMethod(), decodeResult.atClientErrorCode);
- }
-
- EapAkaTypeData eapAkaTypeData = decodeResult.eapTypeData;
- switch (eapAkaTypeData.eapSubtype) {
- case EAP_AKA_IDENTITY:
- return transitionAndProcess(new IdentityState(), message);
- case EAP_AKA_CHALLENGE:
- return transitionAndProcess(buildChallengeState(), message);
- case EAP_AKA_NOTIFICATION:
- return handleEapSimAkaNotification(
- mTAG,
- true, // isPreChallengeState
- message.eapIdentifier,
- eapAkaTypeData);
- default:
- return buildClientErrorResponse(
- message.eapIdentifier,
- getEapMethod(),
- AtClientErrorCode.UNABLE_TO_PROCESS);
- }
- }
- }
-
- protected class IdentityState extends EapMethodState {
- private final String mTAG = IdentityState.class.getSimpleName();
-
- private byte[] mIdentity;
-
- public EapResult process(EapMessage message) {
- EapResult result = handleEapSuccessFailureNotification(mTAG, message);
- if (result != null) {
- return result;
- }
-
- DecodeResult<? extends EapAkaTypeData> decodeResult =
- decode(message.eapData.eapTypeData);
- if (!decodeResult.isSuccessfulDecode()) {
- return buildClientErrorResponse(
- message.eapIdentifier, getEapMethod(), decodeResult.atClientErrorCode);
- }
-
- EapAkaTypeData eapAkaTypeData = decodeResult.eapTypeData;
- switch (eapAkaTypeData.eapSubtype) {
- case EAP_AKA_IDENTITY:
- break;
- case EAP_AKA_CHALLENGE:
- return transitionAndProcess(buildChallengeState(mIdentity), message);
- case EAP_AKA_NOTIFICATION:
- return handleEapSimAkaNotification(
- mTAG,
- true, // isPreChallengeState
- message.eapIdentifier,
- eapAkaTypeData);
- default:
- return buildClientErrorResponse(
- message.eapIdentifier,
- getEapMethod(),
- AtClientErrorCode.UNABLE_TO_PROCESS);
- }
-
- if (!isValidIdentityAttributes(eapAkaTypeData)) {
- LOG.e(mTAG, "Invalid attributes: " + eapAkaTypeData.attributeMap.keySet());
- return buildClientErrorResponse(
- message.eapIdentifier,
- EAP_TYPE_AKA,
- AtClientErrorCode.UNABLE_TO_PROCESS);
- }
-
- String imsi = mTelephonyManager.getSubscriberId();
- if (imsi == null) {
- LOG.e(mTAG, "Unable to get IMSI for subId=" + mEapUiccConfig.subId);
- return new EapError(
- new EapSimAkaIdentityUnavailableException(
- "IMSI for subId (" + mEapUiccConfig.subId + ") not available"));
- }
- String identityString = getIdentityPrefix() + imsi;
- mIdentity = identityString.getBytes(StandardCharsets.US_ASCII);
- LOG.d(mTAG, "EAP-AKA/Identity=" + LOG.pii(identityString));
-
- AtIdentity atIdentity;
- try {
- atIdentity = AtIdentity.getAtIdentity(mIdentity);
- } catch (EapSimAkaInvalidAttributeException ex) {
- LOG.wtf(mTAG, "Exception thrown while making AtIdentity attribute", ex);
- return new EapError(ex);
- }
-
- return buildResponseMessage(
- getEapMethod(),
- EAP_AKA_IDENTITY,
- message.eapIdentifier,
- Arrays.asList(atIdentity));
- }
-
- private boolean isValidIdentityAttributes(EapAkaTypeData eapAkaTypeData) {
- Set<Integer> attrs = eapAkaTypeData.attributeMap.keySet();
-
- // exactly one ID request type required
- int idRequests = 0;
- idRequests += attrs.contains(EAP_AT_PERMANENT_ID_REQ) ? 1 : 0;
- idRequests += attrs.contains(EAP_AT_ANY_ID_REQ) ? 1 : 0;
- idRequests += attrs.contains(EAP_AT_FULLAUTH_ID_REQ) ? 1 : 0;
-
- if (idRequests != 1) {
- return false;
- }
-
- // can't contain mac, iv, encr data
- if (attrs.contains(EAP_AT_MAC)
- || attrs.contains(EAP_AT_IV)
- || attrs.contains(EAP_AT_ENCR_DATA)) {
- return false;
- }
- return true;
- }
- }
-
- protected class ChallengeState extends EapMethodState {
- private final String mTAG = ChallengeState.class.getSimpleName();
-
- @VisibleForTesting boolean mHadSuccessfulChallenge = false;
- @VisibleForTesting protected final byte[] mIdentity;
-
- // IK and CK lengths defined as 16B (RFC 4187#1)
- private final int mIkLenBytes = 16;
- private final int mCkLenBytes = 16;
-
- // Tags for Successful and Synchronization responses
- private final byte mSuccess = (byte) 0xDB;
- private final byte mSynchronization = (byte) 0xDC;
-
- ChallengeState() {
- // use the EAP-Identity for the default value (RFC 4187#7)
- this(mEapIdentity);
- }
-
- ChallengeState(byte[] identity) {
- this.mIdentity = identity;
- }
-
- public EapResult process(EapMessage message) {
- if (message.eapCode == EAP_CODE_SUCCESS) {
- if (!mHadSuccessfulChallenge) {
- LOG.e(mTAG, "Received unexpected EAP-Success");
- return new EapError(
- new EapInvalidRequestException(
- "Received an EAP-Success in the ChallengeState"));
- }
- transitionTo(new FinalState());
- return new EapSuccess(mMsk, mEmsk);
- } else if (message.eapCode == EAP_CODE_FAILURE) {
- transitionTo(new FinalState());
- return new EapFailure();
- } else if (message.eapData.eapType == EAP_NOTIFICATION) {
- return handleEapNotification(mTAG, message);
- }
-
- if (message.eapData.eapType != getEapMethod()) {
- return new EapError(new EapInvalidRequestException(
- "Expected EAP Type " + getEapMethod()
- + ", received " + message.eapData.eapType));
- }
-
- DecodeResult<? extends EapAkaTypeData> decodeResult =
- decode(message.eapData.eapTypeData);
- if (!decodeResult.isSuccessfulDecode()) {
- return buildClientErrorResponse(
- message.eapIdentifier, getEapMethod(), decodeResult.atClientErrorCode);
- }
-
- EapAkaTypeData eapAkaTypeData = decodeResult.eapTypeData;
- switch (eapAkaTypeData.eapSubtype) {
- case EAP_AKA_CHALLENGE:
- break;
- case EAP_AKA_NOTIFICATION:
- return handleEapSimAkaNotification(
- mTAG,
- false, // isPreChallengeState
- message.eapIdentifier,
- eapAkaTypeData);
- default:
- return buildClientErrorResponse(
- message.eapIdentifier,
- getEapMethod(),
- AtClientErrorCode.UNABLE_TO_PROCESS);
- }
-
- if (!isValidChallengeAttributes(eapAkaTypeData)) {
- LOG.e(mTAG, "Invalid attributes: " + eapAkaTypeData.attributeMap.keySet());
- return buildClientErrorResponse(
- message.eapIdentifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
- }
-
- return handleChallengeAuthentication(message, eapAkaTypeData);
- }
-
- protected EapResult handleChallengeAuthentication(
- EapMessage message, EapAkaTypeData eapAkaTypeData) {
- RandChallengeResult result;
- try {
- result = getRandChallengeResult(eapAkaTypeData);
- } catch (EapAkaInvalidAuthenticationResponse ex) {
- return new EapError(ex);
- } catch (EapSimAkaInvalidLengthException | BufferUnderflowException ex) {
- LOG.e(mTAG, "Invalid response returned from SIM", ex);
- return buildClientErrorResponse(
- message.eapIdentifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
- } catch (EapSimAkaAuthenticationFailureException ex) {
- // Return EAP-Response/AKA-Authentication-Reject when the AUTN is rejected
- // (RFC 4187#6.3.1)
- return buildAuthenticationRejectMessage(message.eapIdentifier);
- }
-
- if (!result.isSuccessfulResult()) {
- try {
- return buildResponseMessage(
- getEapMethod(),
- EAP_AKA_SYNCHRONIZATION_FAILURE,
- message.eapIdentifier,
- Arrays.asList(new AtAuts(result.auts)));
- } catch (EapSimAkaInvalidAttributeException ex) {
- LOG.wtf(mTAG, "Error creating an AtAuts attr", ex);
- return new EapError(ex);
- }
- }
-
- EapResult eapResult =
- generateAndPersistEapAkaKeys(result, message.eapIdentifier, eapAkaTypeData);
- if (eapResult != null) {
- return eapResult;
- }
-
- try {
- if (!isValidMac(mTAG, message, eapAkaTypeData, new byte[0])) {
- return buildClientErrorResponse(
- message.eapIdentifier,
- getEapMethod(),
- AtClientErrorCode.UNABLE_TO_PROCESS);
- }
- } catch (GeneralSecurityException
- | EapSilentException
- | EapSimAkaInvalidAttributeException ex) {
- // if the MAC can't be generated, we can't continue
- LOG.e(mTAG, "Error computing MAC for EapMessage", ex);
- return new EapError(ex);
- }
-
- // before sending a response, check for bidding-down attacks (RFC 5448#4)
- if (mSupportsEapAkaPrime) {
- AtBidding atBidding = (AtBidding) eapAkaTypeData.attributeMap.get(EAP_AT_BIDDING);
- if (atBidding != null && atBidding.doesServerSupportEapAkaPrime) {
- LOG.w(
- mTAG,
- "Potential bidding down attack. AT_BIDDING attr included and EAP-AKA'"
- + " is supported");
- return buildAuthenticationRejectMessage(message.eapIdentifier);
- }
- }
-
- // server has been authenticated, so we can send a response
- try {
- mHadSuccessfulChallenge = true;
- return buildResponseMessageWithMac(
- message.eapIdentifier,
- EAP_AKA_CHALLENGE,
- new byte[0],
- Arrays.asList(AtRes.getAtRes(result.res)));
- } catch (EapSimAkaInvalidAttributeException ex) {
- LOG.wtf(mTAG, "Error creating AtRes value", ex);
- return new EapError(ex);
- }
- }
-
- @VisibleForTesting
- class RandChallengeResult {
- public final byte[] res;
- public final byte[] ik;
- public final byte[] ck;
- public final byte[] auts;
-
- RandChallengeResult(byte[] res, byte[] ik, byte[] ck)
- throws EapSimAkaInvalidLengthException {
- if (!AtRes.isValidResLen(res.length)) {
- throw new EapSimAkaInvalidLengthException("Invalid RES length");
- } else if (ik.length != mIkLenBytes) {
- throw new EapSimAkaInvalidLengthException("Invalid IK length");
- } else if (ck.length != mCkLenBytes) {
- throw new EapSimAkaInvalidLengthException("Invalid CK length");
- }
-
- this.res = res;
- this.ik = ik;
- this.ck = ck;
- this.auts = null;
- }
-
- RandChallengeResult(byte[] auts) throws EapSimAkaInvalidLengthException {
- if (auts.length != AtAuts.AUTS_LENGTH) {
- throw new EapSimAkaInvalidLengthException("Invalid AUTS length");
- }
-
- this.res = null;
- this.ik = null;
- this.ck = null;
- this.auts = auts;
- }
-
- private boolean isSuccessfulResult() {
- return res != null && ik != null && ck != null;
- }
- }
-
- private boolean isValidChallengeAttributes(EapAkaTypeData eapAkaTypeData) {
- Set<Integer> attrs = eapAkaTypeData.attributeMap.keySet();
-
- // must contain: AT_RAND, AT_AUTN, AT_MAC
- return attrs.contains(EAP_AT_RAND)
- && attrs.contains(EAP_AT_AUTN)
- && attrs.contains(EAP_AT_MAC);
- }
-
- private RandChallengeResult getRandChallengeResult(EapAkaTypeData eapAkaTypeData)
- throws EapSimAkaAuthenticationFailureException, EapSimAkaInvalidLengthException {
- AtRandAka atRandAka = (AtRandAka) eapAkaTypeData.attributeMap.get(EAP_AT_RAND);
- AtAutn atAutn = (AtAutn) eapAkaTypeData.attributeMap.get(EAP_AT_AUTN);
-
- // pre-Base64 formatting needs to be: [Length][RAND][Length][AUTN]
- int randLen = atRandAka.rand.length;
- int autnLen = atAutn.autn.length;
- ByteBuffer formattedChallenge = ByteBuffer.allocate(1 + randLen + 1 + autnLen);
- formattedChallenge.put((byte) randLen);
- formattedChallenge.put(atRandAka.rand);
- formattedChallenge.put((byte) autnLen);
- formattedChallenge.put(atAutn.autn);
-
- byte[] challengeResponse =
- processUiccAuthentication(
- mTAG,
- TelephonyManager.AUTHTYPE_EAP_AKA,
- formattedChallenge.array());
- ByteBuffer buffer = ByteBuffer.wrap(challengeResponse);
- byte tag = buffer.get();
-
- switch (tag) {
- case mSuccess:
- // response format: [tag][RES length][RES][IK length][IK][CK length][CK]
- break;
- case mSynchronization:
- // response format: [tag][AUTS length][AUTS]
- byte[] auts = new byte[Byte.toUnsignedInt(buffer.get())];
- buffer.get(auts);
-
- LOG.i(mTAG, "Synchronization Failure");
- LOG.d(
- mTAG,
- "RAND=" + LOG.pii(atRandAka.rand)
- + " AUTN=" + LOG.pii(atAutn.autn)
- + " AUTS=" + LOG.pii(auts));
-
- return new RandChallengeResult(auts);
- default:
- throw new EapAkaInvalidAuthenticationResponse(
- "Invalid tag for UICC response: " + String.format("%02X", tag));
- }
-
- byte[] res = new byte[Byte.toUnsignedInt(buffer.get())];
- buffer.get(res);
-
- byte[] ik = new byte[Byte.toUnsignedInt(buffer.get())];
- buffer.get(ik);
-
- byte[] ck = new byte[Byte.toUnsignedInt(buffer.get())];
- buffer.get(ck);
-
- LOG.d(
- mTAG,
- "RAND=" + LOG.pii(atRandAka.rand)
- + " AUTN=" + LOG.pii(atAutn.autn)
- + " RES=" + LOG.pii(res)
- + " IK=" + LOG.pii(ik)
- + " CK=" + LOG.pii(ck));
-
- return new RandChallengeResult(res, ik, ck);
- }
-
- protected EapResult buildAuthenticationRejectMessage(int eapIdentifier) {
- return buildResponseMessage(
- getEapMethod(),
- EAP_AKA_AUTHENTICATION_REJECT,
- eapIdentifier,
- new ArrayList<>());
- }
-
- @Nullable
- protected EapResult generateAndPersistEapAkaKeys(
- RandChallengeResult result, int eapIdentifier, EapAkaTypeData eapAkaTypeData) {
- try {
- MessageDigest sha1 = MessageDigest.getInstance(MASTER_KEY_GENERATION_ALG);
- byte[] mkInputData = getMkInputData(result);
- generateAndPersistKeys(mTAG, sha1, new Fips186_2Prf(), mkInputData);
- return null;
- } catch (NoSuchAlgorithmException | BufferUnderflowException ex) {
- LOG.e(mTAG, "Error while creating keys", ex);
- return buildClientErrorResponse(
- eapIdentifier, EAP_TYPE_AKA, AtClientErrorCode.UNABLE_TO_PROCESS);
- }
- }
-
- private byte[] getMkInputData(RandChallengeResult result) {
- int numInputBytes = mIdentity.length + result.ik.length + result.ck.length;
- ByteBuffer buffer = ByteBuffer.allocate(numInputBytes);
- buffer.put(mIdentity);
- buffer.put(result.ik);
- buffer.put(result.ck);
- return buffer.array();
- }
- }
-
- EapAkaTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) {
- return new EapAkaTypeData(EAP_AKA_CLIENT_ERROR, Arrays.asList(clientErrorCode));
- }
-
- EapAkaTypeData getEapSimAkaTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
- return new EapAkaTypeData(eapSubtype, attributes);
- }
-}