blob: e3d774328d0c83e75f8d70d2ef97103c56b55825 [file] [log] [blame]
/*
* 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.ike.eap;
import static com.android.ike.eap.message.EapData.EAP_TYPE_AKA;
import static com.android.ike.eap.message.EapData.EAP_TYPE_AKA_PRIME;
import static com.android.ike.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
import static com.android.ike.eap.message.EapData.EAP_TYPE_SIM;
import android.telephony.TelephonyManager.UiccAppType;
import com.android.ike.eap.message.EapData.EapMethod;
import com.android.internal.annotations.VisibleForTesting;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* EapSessionConfig represents a container for EAP method configs to be used within an IKEv2
* session.
*
* <p>The EAP authentication server decides which EAP method is used, so clients are encouraged to
* provide configs for several EAP methods.
*/
public final class EapSessionConfig {
@VisibleForTesting
static final byte[] DEFAULT_IDENTITY = new byte[0];
// IANA -> EapMethodConfig for that method
public final Map<Integer, EapMethodConfig> eapConfigs;
public final byte[] eapIdentity;
@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 EapSessionConfig. */
public static final class Builder {
private final Map<Integer, EapMethodConfig> mEapConfigs;
private byte[] mEapIdentity;
/**
* Constructs and returns a new Builder for constructing an 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.
*/
public Builder setEapIdentity(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.
*/
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
*/
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. The String must
* be a UTF-8 String value
* @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
*/
public Builder setEapAkaPrimeConfig(
int subId,
@UiccAppType int apptype,
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
*/
public Builder setEapMsChapV2Config(String username, 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
* @throws IllegalStateException iff no EAP methods have been configured
*/
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 {
@EapMethod public final int methodType;
protected EapMethodConfig(@EapMethod int methodType) {
this.methodType = methodType;
}
}
/**
* EapUiccConfig represents the configs needed for EAP methods that rely on UICC cards for
* authentication.
*/
public abstract static class EapUiccConfig extends EapMethodConfig {
public final int subId;
public final int apptype;
private EapUiccConfig(@EapMethod int methodType, int subId, @UiccAppType int apptype) {
super(methodType);
this.subId = subId;
this.apptype = apptype;
}
}
/**
* EapSimConfig represents the configs needed for an EAP SIM session.
*/
public static class EapSimConfig extends EapUiccConfig {
@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 {
@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 {
public final String networkName;
public final boolean allowMismatchedNetworkNames;
@VisibleForTesting
public EapAkaPrimeConfig(
int subId,
@UiccAppType int apptype,
String networkName,
boolean allowMismatchedNetworkNames) {
super(subId, apptype);
this.networkName = networkName;
this.allowMismatchedNetworkNames = allowMismatchedNetworkNames;
}
}
/**
* EapMsChapV2Config represents the configs needed for an EAP MSCHAPv2 session.
*/
public static class EapMsChapV2Config extends EapMethodConfig {
public final String username;
public final String password;
@VisibleForTesting
public EapMsChapV2Config(String username, String password) {
super(EAP_TYPE_MSCHAP_V2);
this.username = username;
this.password = password;
}
}
}