1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.wifi.hotspot2.anqp.eap;
18
19import static org.junit.Assert.assertEquals;
20
21import android.net.wifi.EAPConstants;
22import android.test.suitebuilder.annotation.SmallTest;
23
24import org.junit.Test;
25
26import java.net.ProtocolException;
27import java.nio.BufferUnderflowException;
28import java.nio.ByteBuffer;
29import java.util.HashMap;
30import java.util.HashSet;
31import java.util.Map;
32import java.util.Set;
33
34/**
35 * Unit tests for {@link com.android.server.wifi.hotspot2.anqp.eap.EAPMethod}.
36 */
37@SmallTest
38public class EAPMethodTest {
39    /**
40     * Setup basic test data - contained multiple parameters of the same type.
41     */
42    private static final byte[] TEST_DATA1_BYTES =
43            new byte[] {0x0B /* length */, 0x0D /* EAP_TLS */, 0x03 /* Auth Param Count */,
44                        0x05 /* CredentialType */, 0x01, 0x02 /* USIM */,
45                        0x05 /* CredentialType */, 0x01, 0x06 /* Certificate */,
46                        0x06 /* Tunneled CredentialType */, 0x01, 0x03 /* NFC */};
47    private static final Map<Integer, Set<AuthParam>> TEST_DATA1_AUTH_PARAMS =
48            new HashMap<>();
49    private static final Set<AuthParam> TEST_DATA1_CREDENTIAL_TYPE_PARAMS = new HashSet<>();
50    private static final Set<AuthParam> TEST_DATA1_TUNNELED_CREDENTIAL_TYPE_PARAMS =
51            new HashSet<>();
52    static {
53        TEST_DATA1_CREDENTIAL_TYPE_PARAMS.add(new CredentialType(
54                AuthParam.PARAM_TYPE_CREDENTIAL_TYPE, CredentialType.CREDENTIAL_TYPE_USIM));
55        TEST_DATA1_CREDENTIAL_TYPE_PARAMS.add(new CredentialType(
56                AuthParam.PARAM_TYPE_CREDENTIAL_TYPE, CredentialType.CREDENTIAL_TYPE_CERTIFICATE));
57
58        TEST_DATA1_TUNNELED_CREDENTIAL_TYPE_PARAMS.add(new CredentialType(
59                AuthParam.PARAM_TYPE_TUNNELED_EAP_METHOD_CREDENTIAL_TYPE,
60                CredentialType.CREDENTIAL_TYPE_NFC));
61
62        TEST_DATA1_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_CREDENTIAL_TYPE,
63                TEST_DATA1_CREDENTIAL_TYPE_PARAMS);
64        TEST_DATA1_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_TUNNELED_EAP_METHOD_CREDENTIAL_TYPE,
65                TEST_DATA1_TUNNELED_CREDENTIAL_TYPE_PARAMS);
66    }
67    private static final EAPMethod TEST_DATA1_EAP_METHOD = new EAPMethod(
68            EAPConstants.EAP_TLS, TEST_DATA1_AUTH_PARAMS);
69
70    /**
71     * Setup test data for testing an EAP Method containing all types of authentication parameters.
72     */
73    private static final byte[] TEST_DATA2_BYTES =
74            new byte[] {0x26 /* length */, 0x0D /* EAP_TLS */, 0x07,
75                        // Expanded EAP Method
76                        0x01, 0x07, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
77                        // Non-EAP Inner Auth Type
78                        0x02, 0x01, 0x03 /* AUTH_TYPE_MSCHAP */,
79                        // Inner Auth EAP Method
80                        0x03, 0x01, 0x1D /* EAP_PEAP */,
81                        // Expanded Inner EAP Method
82                        0x04, 0x07, 0x01, 0x23, 0x45, 0x56, 0x78, 0x56, 0x12,
83                        // Credential Type
84                        0x05, 0x01, 0x02 /* USIM */,
85                        // Tunneled Credential Type
86                        0x06, 0x01, 0x03 /* NFC */,
87                        // Vendor Specific
88                        (byte) 0xDD, 0x04, 0x12, 0x23, 0x45, 0x56};
89    private static final Map<Integer, Set<AuthParam>> TEST_DATA2_AUTH_PARAMS =
90            new HashMap<>();
91    private static final Set<AuthParam> TEST_DATA2_EXPANDED_EAP_METHOD_PARAMS = new HashSet<>();
92    private static final Set<AuthParam> TEST_DATA2_NON_EAP_INNER_AUTH_PARAMS = new HashSet<>();
93    private static final Set<AuthParam> TEST_DATA2_INNER_AUTH_EAP_PARAMS = new HashSet<>();
94    private static final Set<AuthParam> TEST_DATA2_EXPANDED_INNER_EAP_PARAMS = new HashSet<>();
95    private static final Set<AuthParam> TEST_DATA2_CREDENTIAL_TYPE_PARAMS = new HashSet<>();
96    private static final Set<AuthParam> TEST_DATA2_TUNNELED_CREDENTIAL_TYPE_PARAMS =
97            new HashSet<>();
98    private static final Set<AuthParam> TEST_DATA2_VENDOR_SPECIFIC_PARAMS = new HashSet<>();
99    static {
100        TEST_DATA2_EXPANDED_EAP_METHOD_PARAMS.add(new ExpandedEAPMethod(
101                AuthParam.PARAM_TYPE_EXPANDED_EAP_METHOD, 0x122334, 0x45566778L));
102        TEST_DATA2_NON_EAP_INNER_AUTH_PARAMS.add(new NonEAPInnerAuth(
103                NonEAPInnerAuth.AUTH_TYPE_MSCHAP));
104        TEST_DATA2_INNER_AUTH_EAP_PARAMS.add(new InnerAuthEAP(EAPConstants.EAP_PEAP));
105        TEST_DATA2_EXPANDED_INNER_EAP_PARAMS.add(new ExpandedEAPMethod(
106                AuthParam.PARAM_TYPE_EXPANDED_INNER_EAP_METHOD, 0x012345, 0x56785612L));
107        TEST_DATA2_CREDENTIAL_TYPE_PARAMS.add(new CredentialType(
108                AuthParam.PARAM_TYPE_CREDENTIAL_TYPE, CredentialType.CREDENTIAL_TYPE_USIM));
109        TEST_DATA2_TUNNELED_CREDENTIAL_TYPE_PARAMS.add(new CredentialType(
110                AuthParam.PARAM_TYPE_TUNNELED_EAP_METHOD_CREDENTIAL_TYPE,
111                CredentialType.CREDENTIAL_TYPE_NFC));
112        TEST_DATA2_VENDOR_SPECIFIC_PARAMS.add(new VendorSpecificAuth(
113                new byte[] {0x12, 0x23, 0x45, 0x56}));
114
115        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_EXPANDED_EAP_METHOD,
116                TEST_DATA2_EXPANDED_EAP_METHOD_PARAMS);
117        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_NON_EAP_INNER_AUTH_TYPE,
118                TEST_DATA2_NON_EAP_INNER_AUTH_PARAMS);
119        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_INNER_AUTH_EAP_METHOD_TYPE,
120                TEST_DATA2_INNER_AUTH_EAP_PARAMS);
121        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_EXPANDED_INNER_EAP_METHOD,
122                TEST_DATA2_EXPANDED_INNER_EAP_PARAMS);
123        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_CREDENTIAL_TYPE,
124                TEST_DATA2_CREDENTIAL_TYPE_PARAMS);
125        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_TUNNELED_EAP_METHOD_CREDENTIAL_TYPE,
126                TEST_DATA2_TUNNELED_CREDENTIAL_TYPE_PARAMS);
127        TEST_DATA2_AUTH_PARAMS.put(AuthParam.PARAM_TYPE_VENDOR_SPECIFIC,
128                TEST_DATA2_VENDOR_SPECIFIC_PARAMS);
129    }
130    private static final EAPMethod TEST_DATA2_EAP_METHOD = new EAPMethod(
131            EAPConstants.EAP_TLS, TEST_DATA2_AUTH_PARAMS);
132
133    /**
134     * Verify that BufferUnderflowException will be thrown when parsing from an empty buffer.
135     *
136     * @throws Exception
137     */
138    @Test(expected = BufferUnderflowException.class)
139    public void parseEmptyBuffer() throws Exception {
140        EAPMethod.parse(ByteBuffer.wrap(new byte[0]));
141    }
142
143    /**
144     * Verify that ProtocolException will be thrown when parsing a truncated buffer
145     * (missing a byte at the end).
146     *
147     * @throws Exception
148     */
149    @Test(expected = ProtocolException.class)
150    public void parseTruncatedBuffer() throws Exception {
151        ByteBuffer buffer = ByteBuffer.wrap(TEST_DATA1_BYTES, 0, TEST_DATA1_BYTES.length - 1);
152        EAPMethod.parse(buffer);
153    }
154
155    /**
156     * Verify that the expected EAPMethod is return when parsing a buffer contained
157     * {@link #TEST_DATA1_BYTES}.
158     *
159     * @throws Exception
160     */
161    @Test
162    public void parseBufferWithTestData1() throws Exception {
163        assertEquals(TEST_DATA1_EAP_METHOD, EAPMethod.parse(ByteBuffer.wrap(TEST_DATA1_BYTES)));
164    }
165
166    /**
167     * Verify that the expected EAPMethod is return when parsing a buffer contained
168     * {@link #TEST_DATA2_BYTES}.
169     *
170     * @throws Exception
171     */
172    @Test
173    public void parseBufferWithTestData2() throws Exception {
174        assertEquals(TEST_DATA2_EAP_METHOD, EAPMethod.parse(ByteBuffer.wrap(TEST_DATA2_BYTES)));
175    }
176}
177