Check for duplicate EAP-SIM attributes.

When decoding EAP-SIM type data, duplicate attributes are not allowed.
Per RFC 4186 Section 6.3.1, a Client-Error packet must be returned if
duplicate attributes are detected in a received EAP-SIM packet.

Bug: 135637161
Test: atest EapSimTypeDataTest
Change-Id: I9d81d24e94716da801cdf796bb4d6681851e2bb0
diff --git a/src/java/com/android/ike/eap/message/EapSimAttribute.java b/src/java/com/android/ike/eap/message/EapSimAttribute.java
index 7095b39..bce4f93 100644
--- a/src/java/com/android/ike/eap/message/EapSimAttribute.java
+++ b/src/java/com/android/ike/eap/message/EapSimAttribute.java
@@ -746,7 +746,7 @@
     }
 
     /**
-     * AtClientErrorCode reprents the AT_CLIENT_ERROR_CODE attribute defined in RFC 4186 Section
+     * AtClientErrorCode represents the AT_CLIENT_ERROR_CODE attribute defined in RFC 4186 Section
      * 10.19
      */
     public static class AtClientErrorCode extends EapSimAttribute {
diff --git a/src/java/com/android/ike/eap/message/EapSimTypeData.java b/src/java/com/android/ike/eap/message/EapSimTypeData.java
index 639354e..b60a8f7 100644
--- a/src/java/com/android/ike/eap/message/EapSimTypeData.java
+++ b/src/java/com/android/ike/eap/message/EapSimTypeData.java
@@ -134,9 +134,15 @@
                 // read attributes
                 LinkedHashMap<Integer, EapSimAttribute> attributeMap = new LinkedHashMap<>();
                 while (byteBuffer.hasRemaining()) {
-                    // TODO(b/135637161): check for duplicate attributes
                     EapSimAttribute attribute = EapSimAttributeFactory.getInstance()
                             .getEapSimAttribute(byteBuffer);
+
+                    if (attributeMap.containsKey(attribute.attributeType)) {
+                        // Duplicate attributes are not allowed (RFC 4186#6.3.1)
+                        Log.d(TAG, "Duplicate attribute in parsed EAP-Message");
+                        return new DecodeResult(AtClientErrorCode.UNABLE_TO_PROCESS);
+                    }
+
                     if (attribute instanceof EapSimUnsupportedAttribute) {
                         Log.d(TAG, "Unsupported EAP-SIM attribute during decoding: "
                                 + attribute.attributeType);
diff --git a/tests/iketests/src/java/com/android/ike/eap/message/EapSimTypeDataTest.java b/tests/iketests/src/java/com/android/ike/eap/message/EapSimTypeDataTest.java
index e0b2078..3317574 100644
--- a/tests/iketests/src/java/com/android/ike/eap/message/EapSimTypeDataTest.java
+++ b/tests/iketests/src/java/com/android/ike/eap/message/EapSimTypeDataTest.java
@@ -19,6 +19,7 @@
 import static com.android.ike.eap.message.EapSimAttribute.EAP_AT_PERMANENT_ID_REQ;
 import static com.android.ike.eap.message.EapSimAttribute.EAP_AT_VERSION_LIST;
 import static com.android.ike.eap.message.EapSimTypeData.EAP_SIM_START;
+import static com.android.ike.eap.message.EapTestMessageDefinitions.EAP_SIM_START_DUPLICATE_ATTRIBUTES;
 import static com.android.ike.eap.message.EapTestMessageDefinitions.EAP_SIM_START_SUBTYPE;
 import static com.android.ike.eap.message.EapTestMessageDefinitions.INVALID_SUBTYPE;
 import static com.android.ike.eap.message.EapTestMessageDefinitions.SHORT_TYPE_DATA;
@@ -143,4 +144,11 @@
         byte[] result = eapSimTypeData.encode();
         assertArrayEquals(EAP_SIM_START_SUBTYPE, result);
     }
+
+    @Test
+    public void testDecodeDuplicateAttributes() {
+        DecodeResult result = mEapSimTypeDataDecoder.decode(EAP_SIM_START_DUPLICATE_ATTRIBUTES);
+        assertFalse(result.isSuccessfulDecode());
+        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
+    }
 }
diff --git a/tests/iketests/src/java/com/android/ike/eap/message/EapTestMessageDefinitions.java b/tests/iketests/src/java/com/android/ike/eap/message/EapTestMessageDefinitions.java
index a067402..36ba313 100644
--- a/tests/iketests/src/java/com/android/ike/eap/message/EapTestMessageDefinitions.java
+++ b/tests/iketests/src/java/com/android/ike/eap/message/EapTestMessageDefinitions.java
@@ -95,6 +95,8 @@
     public static final byte[] SHORT_TYPE_DATA = hexStringToByteArray("0A");
     public static final byte[] TYPE_DATA_INVALID_ATTRIBUTE =
             hexStringToByteArray("0A00007F01");
+    public static final byte[] EAP_SIM_START_DUPLICATE_ATTRIBUTES =
+            hexStringToByteArray("0A00000F02" + "0A010000" + "0A010000");
 
     // RAND Challenge Results
     public static final String SRES_1 = "11223344";