aboutsummaryrefslogtreecommitdiff
path: root/src/java/com/android/ike/eap/EapSessionConfig.java
blob: 285dc799fd3a79a974992d33e92a595cb530d6aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/*
 * 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
    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;
        }
    }
}