blob: 48e9c532fa5078d7f384b898b91b8a899ab354c4 [file]
/*
* 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 android.net.eap;
import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.telephony.Annotation.UiccAppType;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.eap.message.EapData.EapMethod;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* EapSessionConfig represents a container for EAP method configuration.
*
* <p>The EAP authentication server decides which EAP method is used, so clients are encouraged to
* provide configs for several EAP methods.
*
* @hide
*/
@SystemApi
public final class EapSessionConfig {
/** @hide */
@VisibleForTesting static final byte[] DEFAULT_IDENTITY = new byte[0];
// IANA -> EapMethodConfig for that method
/** @hide */
public final Map<Integer, EapMethodConfig> eapConfigs;
/** @hide */
public final byte[] eapIdentity;
/** @hide */
@VisibleForTesting
public EapSessionConfig(Map<Integer, EapMethodConfig> eapConfigs, byte[] eapIdentity) {
this.eapConfigs = Collections.unmodifiableMap(eapConfigs);
this.eapIdentity = eapIdentity;
}
/** This class can be used to incrementally construct an {@link EapSessionConfig}. */
public static final class Builder {
private final Map<Integer, EapMethodConfig> mEapConfigs;
private byte[] mEapIdentity;
/** Constructs and returns a new Builder for constructing an {@link EapSessionConfig}. */
public Builder() {
mEapConfigs = new HashMap<>();
mEapIdentity = DEFAULT_IDENTITY;
}
/**
* Sets the client's EAP Identity.
*
* @param eapIdentity byte[] representing the client's EAP Identity.
* @return Builder this, to facilitate chaining.
*/
@NonNull
public Builder setEapIdentity(@NonNull byte[] eapIdentity) {
this.mEapIdentity = eapIdentity.clone();
return this;
}
/**
* Sets the configuration for EAP SIM.
*
* @param subId int the client's subId to be authenticated.
* @param apptype the {@link UiccAppType} apptype to be used for authentication.
* @return Builder this, to facilitate chaining.
*/
@NonNull
public Builder setEapSimConfig(int subId, @UiccAppType int apptype) {
mEapConfigs.put(EAP_TYPE_SIM, new EapSimConfig(subId, apptype));
return this;
}
/**
* Sets the configuration for EAP AKA.
*
* @param subId int the client's subId to be authenticated.
* @param apptype the {@link UiccAppType} apptype to be used for authentication.
* @return Builder this, to facilitate chaining.
*/
@NonNull
public Builder setEapAkaConfig(int subId, @UiccAppType int apptype) {
mEapConfigs.put(EAP_TYPE_AKA, new EapAkaConfig(subId, apptype));
return this;
}
/**
* Sets the configuration for EAP AKA'.
*
* @param subId int the client's subId to be authenticated.
* @param apptype the {@link UiccAppType} apptype to be used for authentication.
* @param networkName String the network name to be used for authentication.
* @param allowMismatchedNetworkNames indicates whether the EAP library can ignore potential
* mismatches between the given network name and that received in an EAP-AKA' session.
* If false, mismatched network names will be handled as an Authentication Reject
* message.
* @return Builder this, to facilitate chaining.
*/
@NonNull
public Builder setEapAkaPrimeConfig(
int subId,
@UiccAppType int apptype,
@NonNull String networkName,
boolean allowMismatchedNetworkNames) {
mEapConfigs.put(
EAP_TYPE_AKA_PRIME,
new EapAkaPrimeConfig(
subId, apptype, networkName, allowMismatchedNetworkNames));
return this;
}
/**
* Sets the configuration for EAP MSCHAPv2.
*
* @param username String the client account's username to be authenticated.
* @param password String the client account's password to be authenticated.
* @return Builder this, to faciliate chaining.
*/
@NonNull
public Builder setEapMsChapV2Config(@NonNull String username, @NonNull String password) {
mEapConfigs.put(EAP_TYPE_MSCHAP_V2, new EapMsChapV2Config(username, password));
return this;
}
/**
* Constructs and returns an EapSessionConfig with the configurations applied to this
* Builder.
*
* @return the EapSessionConfig constructed by this Builder.
*/
@NonNull
public EapSessionConfig build() {
if (mEapConfigs.isEmpty()) {
throw new IllegalStateException("Must have at least one EAP method configured");
}
return new EapSessionConfig(mEapConfigs, mEapIdentity);
}
}
/**
* EapMethodConfig represents a generic EAP method configuration.
*/
public abstract static class EapMethodConfig {
/** @hide */
@EapMethod public final int methodType;
/** @hide */
EapMethodConfig(@EapMethod int methodType) {
this.methodType = methodType;
}
/**
* Retrieves the EAP method type
*
* @return the IANA-defined EAP method constant
*/
public int getMethodType() {
return methodType;
}
}
/**
* EapUiccConfig represents the configs needed for EAP methods that rely on UICC cards for
* authentication.
*/
public abstract static class EapUiccConfig extends EapMethodConfig {
/** @hide */
public final int subId;
/** @hide */
public final int apptype;
private EapUiccConfig(@EapMethod int methodType, int subId, @UiccAppType int apptype) {
super(methodType);
this.subId = subId;
this.apptype = apptype;
}
/**
* Retrieves the subId
*
* @return the subId
*/
public int getSubId() {
return subId;
}
/**
* Retrieves the UICC app type
*
* @return the {@link UiccAppType} constant
*/
public int getAppType() {
return apptype;
}
}
/**
* EapSimConfig represents the configs needed for an EAP SIM session.
*/
public static class EapSimConfig extends EapUiccConfig {
/** @hide */
@VisibleForTesting
public EapSimConfig(int subId, @UiccAppType int apptype) {
super(EAP_TYPE_SIM, subId, apptype);
}
}
/**
* EapAkaConfig represents the configs needed for an EAP AKA session.
*/
public static class EapAkaConfig extends EapUiccConfig {
/** @hide */
@VisibleForTesting
public EapAkaConfig(int subId, @UiccAppType int apptype) {
super(EAP_TYPE_AKA, subId, apptype);
}
}
/**
* EapAkaPrimeConfig represents the configs needed for an EAP-AKA' session.
*/
public static class EapAkaPrimeConfig extends EapAkaConfig {
/** @hide */
@NonNull public final String networkName;
/** @hide */
public final boolean allowMismatchedNetworkNames;
/** @hide */
@VisibleForTesting
public EapAkaPrimeConfig(
int subId,
@UiccAppType int apptype,
@NonNull String networkName,
boolean allowMismatchedNetworkNames) {
super(subId, apptype);
if (networkName == null) {
throw new IllegalArgumentException("NetworkName was null");
}
this.networkName = networkName;
this.allowMismatchedNetworkNames = allowMismatchedNetworkNames;
}
/**
* Retrieves the UICC app type
*
* @return the {@link UiccAppType} constant
*/
@NonNull
public String getNetworkName() {
return networkName;
}
/**
* Checks if mismatched network names are allowed
*
* @return whether network name mismatches are allowed
*/
public boolean allowsMismatchedNetworkNames() {
return allowMismatchedNetworkNames;
}
}
/**
* EapMsChapV2Config represents the configs needed for an EAP MSCHAPv2 session.
*/
public static class EapMsChapV2Config extends EapMethodConfig {
/** @hide */
@NonNull public final String username;
/** @hide */
@NonNull public final String password;
/** @hide */
@VisibleForTesting
public EapMsChapV2Config(String username, String password) {
super(EAP_TYPE_MSCHAP_V2);
if (username == null || password == null) {
throw new IllegalArgumentException("Username or password was null");
}
this.username = username;
this.password = password;
}
/**
* Retrieves the username
*
* @return the username to be used by MSCHAPV2
*/
@NonNull
public String getUsername() {
return username;
}
/**
* Retrieves the password
*
* @return the password to be used by MSCHAPV2
*/
@NonNull
public String getPassword() {
return password;
}
}
}