Merge changes Id4b6122a,Ibac47013
* changes:
Switch to port 4500 if both NAT-T and MOBIKE are supported
Support injecting ConnectivityManager to IkeNattKeepalive
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java
index 23dcd02..2c15996 100644
--- a/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java
+++ b/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java
@@ -34,11 +34,17 @@
new EapAkaPrimeTypeDataDecoder();
@VisibleForTesting
- EapAkaPrimeTypeData(
- int eapSubType, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
+ EapAkaPrimeTypeData(int eapSubType, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
super(eapSubType, attributeMap);
}
+ private EapAkaPrimeTypeData(
+ int eapSubType,
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
+ super(eapSubType, attributeMap, reservedBytes);
+ }
+
/**
* Creates and returns an EapAkaPrimeTypeData instance with the given subtype and attributes.
*
@@ -88,8 +94,10 @@
@Override
protected EapAkaPrimeTypeData getInstance(
- int eapSubtype, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
- return new EapAkaPrimeTypeData(eapSubtype, attributeMap);
+ int eapSubtype,
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
+ return new EapAkaPrimeTypeData(eapSubtype, attributeMap, reservedBytes);
}
}
}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java
index e3ce817..0fb2aa4 100644
--- a/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java
+++ b/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java
@@ -73,6 +73,13 @@
super(eapSubType, attributeMap);
}
+ protected EapAkaTypeData(
+ int eapSubType,
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
+ super(eapSubType, attributeMap, reservedBytes);
+ }
+
/**
* Creates and returns an EapAkaTypeData instance with the given subtype and attributes.
*
@@ -130,8 +137,9 @@
@Override
protected EapAkaTypeData getInstance(
int eapSubtype,
- LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
- return new EapAkaTypeData(eapSubtype, attributeMap);
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
+ return new EapAkaTypeData(eapSubtype, attributeMap, reservedBytes);
}
}
}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java
index 73d6752..cd41287 100644
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java
+++ b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java
@@ -23,6 +23,7 @@
import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
import com.android.internal.net.eap.exceptions.simaka.EapSimInvalidAtRandException;
+import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
@@ -132,6 +133,64 @@
*/
public abstract void encode(ByteBuffer byteBuffer);
+ /**
+ * EapSimAkaReservedBytesAttribute represents any EAP-SIM/AKA attribute that is of the format:
+ *
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Attribute Type (1B) | Length (1B) | Reserved (2B) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Value...
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * <p>Note: This Attribute type ignores (but preserves) the Reserved bytes. This is needed for
+ * calculating MACs in EAP-SIM/AKA.
+ */
+ protected abstract static class EapSimAkaReservedBytesAttribute extends EapSimAkaAttribute {
+ protected static final int RESERVED_BYTES_LEN = 2;
+
+ @VisibleForTesting public final byte[] reservedBytes = new byte[RESERVED_BYTES_LEN];
+
+ protected EapSimAkaReservedBytesAttribute(
+ int attributeType, int lengthInBytes, ByteBuffer buffer)
+ throws EapSimAkaInvalidAttributeException {
+ super(attributeType, lengthInBytes);
+
+ try {
+ buffer.get(reservedBytes);
+ } catch (BufferUnderflowException e) {
+ throw new EapSimAkaInvalidAttributeException("Invalid attribute length", e);
+ }
+ }
+
+ protected EapSimAkaReservedBytesAttribute(int attributeType, int lengthInBytes)
+ throws EapSimAkaInvalidAttributeException {
+ super(attributeType, lengthInBytes);
+ }
+
+ protected EapSimAkaReservedBytesAttribute(
+ int attributeType, int lengthInBytes, byte[] reservedBytes)
+ throws EapSimAkaInvalidAttributeException {
+ this(attributeType, lengthInBytes);
+
+ if (reservedBytes.length != RESERVED_BYTES_LEN) {
+ throw new EapSimAkaInvalidAttributeException("Invalid attribute length");
+ }
+ System.arraycopy(
+ reservedBytes,
+ 0 /* srcPos */,
+ this.reservedBytes,
+ 0 /* destPos */,
+ RESERVED_BYTES_LEN);
+ }
+
+ @Override
+ public void encode(ByteBuffer buffer) {
+ encodeAttributeHeader(buffer);
+
+ buffer.put(reservedBytes);
+ }
+ }
+
protected void encodeAttributeHeader(ByteBuffer byteBuffer) {
byteBuffer.put((byte) attributeType);
byteBuffer.put((byte) (lengthInBytes / LENGTH_SCALING));
@@ -286,9 +345,8 @@
/**
* AtNonceMt represents the AT_NONCE_MT attribute defined in RFC 4186#10.4
*/
- public static class AtNonceMt extends EapSimAkaAttribute {
+ public static class AtNonceMt extends EapSimAkaReservedBytesAttribute {
private static final int LENGTH = 5 * LENGTH_SCALING;
- private static final int RESERVED_BYTES = 2;
public static final int NONCE_MT_LENGTH = 16;
@@ -296,13 +354,11 @@
public AtNonceMt(int lengthInBytes, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_NONCE_MT, LENGTH);
+ super(EAP_AT_NONCE_MT, LENGTH, byteBuffer);
if (lengthInBytes != LENGTH) {
throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
}
- // next two bytes are reserved (RFC 4186 Section 10.4)
- byteBuffer.get(new byte[RESERVED_BYTES]);
byteBuffer.get(nonceMt);
}
@@ -318,38 +374,28 @@
@Override
public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
+ super.encode(byteBuffer);
+
byteBuffer.put(nonceMt);
}
}
- private abstract static class AtIdReq extends EapSimAkaAttribute {
+ private abstract static class AtIdReq extends EapSimAkaReservedBytesAttribute {
private static final int ATTR_LENGTH = LENGTH_SCALING;
- private static final int RESERVED_BYTES = 2;
protected AtIdReq(int lengthInBytes, int attributeType, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(attributeType, ATTR_LENGTH);
+ super(attributeType, ATTR_LENGTH, byteBuffer);
if (lengthInBytes != ATTR_LENGTH) {
throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
}
-
- // next two bytes are reserved (RFC 4186 Section 10.5-10.7)
- byteBuffer.get(new byte[RESERVED_BYTES]);
}
@VisibleForTesting
protected AtIdReq(int attributeType) throws EapSimAkaInvalidAttributeException {
super(attributeType, ATTR_LENGTH);
}
-
- @Override
- public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
- }
}
/**
@@ -454,9 +500,8 @@
/**
* AtRandSim represents the AT_RAND attribute for EAP-SIM defined in RFC 4186#10.9
*/
- public static class AtRandSim extends EapSimAkaAttribute {
+ public static class AtRandSim extends EapSimAkaReservedBytesAttribute {
private static final int RAND_LENGTH = 16;
- private static final int RESERVED_BYTES = 2;
private static final int MIN_RANDS = 2;
private static final int MAX_RANDS = 3;
@@ -464,10 +509,7 @@
public AtRandSim(int lengthInBytes, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_RAND, lengthInBytes);
-
- // next two bytes are reserved (RFC 4186 Section 10.9)
- byteBuffer.get(new byte[RESERVED_BYTES]);
+ super(EAP_AT_RAND, lengthInBytes, byteBuffer);
int numRands = (lengthInBytes - MIN_ATTR_LENGTH) / RAND_LENGTH;
if (!isValidNumRands(numRands)) {
@@ -510,8 +552,7 @@
@Override
public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
+ super.encode(byteBuffer);
for (byte[] rand : rands) {
byteBuffer.put(rand);
@@ -522,24 +563,20 @@
/**
* AtRandAka represents the AT_RAND attribute for EAP-AKA defined in RFC 4187#10.6
*/
- public static class AtRandAka extends EapSimAkaAttribute {
+ public static class AtRandAka extends EapSimAkaReservedBytesAttribute {
private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
private static final int RAND_LENGTH = 16;
- private static final int RESERVED_BYTES = 2;
public final byte[] rand = new byte[RAND_LENGTH];
public AtRandAka(int lengthInBytes, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_RAND, lengthInBytes);
+ super(EAP_AT_RAND, lengthInBytes, byteBuffer);
if (lengthInBytes != ATTR_LENGTH) {
throw new EapSimAkaInvalidAttributeException("Length must be 20B");
}
- // next two bytes are reserved (RFC 4187#10.6)
- byteBuffer.get(new byte[RESERVED_BYTES]);
-
byteBuffer.get(rand);
}
@@ -557,8 +594,8 @@
@Override
public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
+ super.encode(byteBuffer);
+
byteBuffer.put(rand);
}
}
@@ -598,9 +635,8 @@
/**
* AtMac represents the AT_MAC attribute defined in RFC 4186#10.14 and RFC 4187#10.15
*/
- public static class AtMac extends EapSimAkaAttribute {
+ public static class AtMac extends EapSimAkaReservedBytesAttribute {
private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
- private static final int RESERVED_BYTES = 2;
public static final int MAC_LENGTH = 4 * LENGTH_SCALING;
@@ -608,41 +644,52 @@
public AtMac(int lengthInBytes, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_MAC, lengthInBytes);
+ super(EAP_AT_MAC, lengthInBytes, byteBuffer);
if (lengthInBytes != ATTR_LENGTH) {
throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
}
- // next two bytes are reserved (RFC 4186 Section 10.14)
- byteBuffer.get(new byte[RESERVED_BYTES]);
-
mac = new byte[MAC_LENGTH];
byteBuffer.get(mac);
}
- // Used for calculating MACs. Per RFC 4186 Section 10.14, the MAC should be calculated over
- // the entire packet, with the value field of the MAC attribute set to zero.
+ // Constructs an AtMac with an empty MAC and empty RESERVED bytes. Should only be used for
+ // calculating MACs in outbound messages.
public AtMac() throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_MAC, ATTR_LENGTH);
- mac = new byte[MAC_LENGTH];
+ this(new byte[MAC_LENGTH]);
}
public AtMac(byte[] mac) throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_MAC, ATTR_LENGTH);
- this.mac = mac;
+ this(new byte[RESERVED_BYTES_LEN], mac);
+ }
+
+ @VisibleForTesting
+ public AtMac(byte[] reservedBytes, byte[] mac) throws EapSimAkaInvalidAttributeException {
+ super(EAP_AT_MAC, ATTR_LENGTH, reservedBytes);
if (mac.length != MAC_LENGTH) {
throw new EapSimAkaInvalidAttributeException("Invalid length for MAC");
}
+ this.mac = mac;
}
@Override
public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
+ super.encode(byteBuffer);
+
byteBuffer.put(mac);
}
+
+ /**
+ * Returns a copy of this AtMac with the MAC cleared (and the reserved bytes preserved).
+ *
+ * <p>Per RFC 4186 Section 10.14, the MAC should be calculated over the entire packet, with
+ * the value field of the MAC attribute set to zero.
+ */
+ public AtMac getAtMacWithMacCleared() throws EapSimAkaInvalidAttributeException {
+ return new AtMac(reservedBytes, new byte[MAC_LENGTH]);
+ }
}
/**
@@ -712,23 +759,20 @@
*
* <p>This Nonce is generated by the server and used for fast re-authentication only.
*/
- public static class AtNonceS extends EapSimAkaAttribute {
+ public static class AtNonceS extends EapSimAkaReservedBytesAttribute {
private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
private static final int NONCE_S_LENGTH = 4 * LENGTH_SCALING;
- private static final int RESERVED_BYTES = 2;
public final byte[] nonceS = new byte[NONCE_S_LENGTH];
public AtNonceS(int lengthInBytes, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_NONCE_S, lengthInBytes);
+ super(EAP_AT_NONCE_S, lengthInBytes, byteBuffer);
if (lengthInBytes != ATTR_LENGTH) {
throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
}
- // next two bytes are reserved (RFC 4186 Section 10.17)
- byteBuffer.get(new byte[RESERVED_BYTES]);
byteBuffer.get(nonceS);
}
@@ -745,8 +789,8 @@
@Override
public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
+ super.encode(byteBuffer);
+
byteBuffer.put(nonceS);
}
}
@@ -888,24 +932,20 @@
/**
* AtAutn represents the AT_AUTN attribute defined in RFC 4187#10.7
*/
- public static class AtAutn extends EapSimAkaAttribute {
+ public static class AtAutn extends EapSimAkaReservedBytesAttribute {
private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
private static final int AUTN_LENGTH = 16;
- private static final int RESERVED_BYTES = 2;
public final byte[] autn = new byte[AUTN_LENGTH];
public AtAutn(int lengthInBytes, ByteBuffer byteBuffer)
throws EapSimAkaInvalidAttributeException {
- super(EAP_AT_AUTN, lengthInBytes);
+ super(EAP_AT_AUTN, lengthInBytes, byteBuffer);
if (lengthInBytes != ATTR_LENGTH) {
throw new EapSimAkaInvalidAttributeException("Length must be 20B");
}
- // next two bytes are reserved (RFC 4187#10.7)
- byteBuffer.get(new byte[RESERVED_BYTES]);
-
byteBuffer.get(autn);
}
@@ -922,8 +962,8 @@
@Override
public void encode(ByteBuffer byteBuffer) {
- encodeAttributeHeader(byteBuffer);
- byteBuffer.put(new byte[RESERVED_BYTES]);
+ super.encode(byteBuffer);
+
byteBuffer.put(autn);
}
}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java
index 56d2447..b90cd0b 100644
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java
+++ b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java
@@ -39,19 +39,30 @@
*/
public abstract class EapSimAkaTypeData {
private static final int MIN_LEN_BYTES = 3; // subtype (1B) + reserved bytes (2B)
- private static final int RESERVED_BYTES = 2; // RFC 4186#8.1, RFC 4187#8.1
+ private static final int RESERVED_BYTES_LEN = 2; // RFC 4186#8.1, RFC 4187#8.1
public final int eapSubtype;
+ /** Save (but ignore) the 2B reserved section after EAP-Type and EAP-SIM/AKA subtype. */
+ final byte[] mReservedBytes;
+
// LinkedHashMap used to preserve encoded ordering of attributes. This is necessary for checking
// the MAC value for the message
public final LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap;
+ protected EapSimAkaTypeData(
+ int eapSubType, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
+ this(eapSubType, attributeMap, new byte[RESERVED_BYTES_LEN]);
+ }
+
public EapSimAkaTypeData(
int eapSubType,
- LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
this.eapSubtype = eapSubType;
this.attributeMap = attributeMap;
+
+ mReservedBytes = reservedBytes.clone();
}
/**
@@ -69,7 +80,7 @@
output.put((byte) eapSubtype);
// two reserved bytes (RFC 4186#8.1, RFC 4187#8.1)
- output.put(new byte[RESERVED_BYTES]);
+ output.put(mReservedBytes);
for (EapSimAkaAttribute attribute : attributeMap.values()) {
attribute.encode(output);
@@ -118,7 +129,8 @@
}
// next two bytes are reserved (RFC 4186#8.1, RFC 4187#8.1)
- byteBuffer.get(new byte[RESERVED_BYTES]);
+ byte[] reservedBytes = new byte[RESERVED_BYTES_LEN];
+ byteBuffer.get(reservedBytes);
// read attributes
LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap = new LinkedHashMap<>();
@@ -138,7 +150,7 @@
attributeMap.put(attribute.attributeType, attribute);
}
- T eapSimAkaTypeData = getInstance(eapSubType, attributeMap);
+ T eapSimAkaTypeData = getInstance(eapSubType, attributeMap, reservedBytes);
logDecodedEapSimAkaTypeData(eapSimAkaTypeData);
@@ -157,7 +169,8 @@
protected abstract T getInstance(
int eapSubType,
- LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap);
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes);
private void logDecodedEapSimAkaTypeData(EapSimAkaTypeData eapSimAkaTypeData) {
StringBuilder msg = new StringBuilder();
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java
index ff1be60..09e03c7 100644
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java
+++ b/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java
@@ -67,6 +67,13 @@
super(eapSubType, attributeMap);
}
+ private EapSimTypeData(
+ int eapSubType,
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
+ super(eapSubType, attributeMap, reservedBytes);
+ }
+
public EapSimTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
super(eapSubtype, new LinkedHashMap<>());
@@ -118,8 +125,9 @@
@Override
protected EapSimTypeData getInstance(
int eapSubtype,
- LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
- return new EapSimTypeData(eapSubtype, attributeMap);
+ LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap,
+ byte[] reservedBytes) {
+ return new EapSimTypeData(eapSubtype, attributeMap, reservedBytes);
}
}
}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java
index b2459ab..8089ea7 100644
--- a/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java
+++ b/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java
@@ -243,7 +243,7 @@
// cache original Mac so it can be restored after calculating the Mac
AtMac originalMac = (AtMac) typeData.attributeMap.get(EAP_AT_MAC);
- typeData.attributeMap.put(EAP_AT_MAC, new AtMac());
+ typeData.attributeMap.put(EAP_AT_MAC, originalMac.getAtMacWithMacCleared());
byte[] typeDataWithEmptyMac = typeData.encode();
EapData eapData = new EapData(getEapMethod(), typeDataWithEmptyMac);
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java
index 6a9e517..d5aa9d1 100644
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java
@@ -56,14 +56,25 @@
private static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN);
private static final String MAC = "95FEB9E70427F34B4FAC8F2C7A65A302";
private static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
+
private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST =
hexStringToByteArray(
+ "010A0B" // Challenge | 2B padding
+ + "01051A1B" + RAND // AT_RAND attribute
+ + "02052A2B" + AUTN // AT_AUTN attribute
+ + "1704000B" + NETWORK_NAME_HEX + "00" // AT_KDF_INPUT
+ + "18010001" // AT_KDF
+ + "0B053A3B" + MAC); // AT_MAC attribute
+
+ private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST_EMPTY_RESERVED =
+ hexStringToByteArray(
"010000" // Challenge | 2B padding
+ "01050000" + RAND // AT_RAND attribute
+ "02050000" + AUTN // AT_AUTN attribute
+ "1704000B" + NETWORK_NAME_HEX + "00" // AT_KDF_INPUT
+ "18010001" // AT_KDF
+ "0B050000" + MAC); // AT_MAC attribute
+
private static final byte[] EAP_AKA_PRIME_MULTIPLE_AT_KDF =
hexStringToByteArray(
"010000" // Challenge | 2B padding
@@ -117,6 +128,15 @@
}
@Test
+ public void testDecodeEncode() {
+ DecodeResult<EapAkaTypeData> result =
+ mTypeDataDecoder.decode(EAP_AKA_PRIME_CHALLENGE_REQUEST);
+ assertTrue(result.isSuccessfulDecode());
+
+ assertArrayEquals(EAP_AKA_PRIME_CHALLENGE_REQUEST, result.eapTypeData.encode());
+ }
+
+ @Test
public void testDecodeMultipleAtKdfAttributes() {
DecodeResult<EapAkaTypeData> result =
mTypeDataDecoder.decode(EAP_AKA_PRIME_MULTIPLE_AT_KDF);
@@ -137,6 +157,6 @@
new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, attributes);
byte[] result = eapAkaPrimeTypeData.encode();
- assertArrayEquals(EAP_AKA_PRIME_CHALLENGE_REQUEST, result);
+ assertArrayEquals(EAP_AKA_PRIME_CHALLENGE_REQUEST_EMPTY_RESERVED, result);
}
}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java
index b2d89d1..cb27cd1 100644
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java
@@ -68,12 +68,12 @@
private static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
private static final byte[] EAP_AKA_REQUEST =
hexStringToByteArray(
- "010000" // Challenge | 2B padding
- + "01050000" + RAND // AT_RAND attribute
- + "02050000" + AUTN // AT_AUTN attribute
+ "010A0B" // Challenge | 2B reserved
+ + "01051A1B" + RAND // AT_RAND attribute
+ + "02052A2B" + AUTN // AT_AUTN attribute
+ "8B010002" // AT_RESULT_IND attribute (TS 124 302#8.2.3.1)
- + "0B050000" + MAC // AT_MAC attribute
- + "86010000"); // AT_CHECKCODE attribute
+ + "0B053A3B" + MAC // AT_MAC attribute
+ + "86014A4B"); // AT_CHECKCODE attribute
private EapAkaTypeDataDecoder mEapAkaTypeDataDecoder;
@@ -106,6 +106,14 @@
}
@Test
+ public void testDecodeEncode() {
+ DecodeResult<EapAkaTypeData> result = mEapAkaTypeDataDecoder.decode(EAP_AKA_REQUEST);
+ assertTrue(result.isSuccessfulDecode());
+
+ assertArrayEquals(EAP_AKA_REQUEST, result.eapTypeData.encode());
+ }
+
+ @Test
public void testDecodeWithOptionalAttributes() {
DecodeResult<EapAkaTypeData> result = mEapAkaTypeDataDecoder.decode(EAP_AKA_REQUEST);
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java
index 678a812..bd6352a 100644
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java
@@ -16,6 +16,7 @@
package com.android.internal.net.eap.message.simaka;
+import static com.android.internal.net.TestUtils.hexStringToByteArray;
import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_START_DUPLICATE_ATTRIBUTES;
import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_START_SUBTYPE;
import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_SUBTYPE;
@@ -24,6 +25,8 @@
import static com.android.internal.net.eap.message.EapTestMessageDefinitions.TYPE_DATA_INVALID_AT_RAND;
import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST;
+import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1;
+import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2;
import static junit.framework.TestCase.fail;
@@ -52,6 +55,12 @@
private static final int EAP_SIM_START = 10;
private static final int INVALID_SUBTYPE_INT = -1;
+ private static final byte[] EAP_SIM_CHALLENGE_REQUEST =
+ hexStringToByteArray(
+ "0b0A0B" // Challenge | 2B padding
+ + "01091A1B" + RAND_1 + RAND_2 // EAP-SIM AT_RAND attribute
+ + "0B052A2BFFEEDDCCBBAA998877665544332211FF"); // AT_MAC attribute
+
private EapSimTypeDataDecoder mEapSimTypeDataDecoder;
@Before
@@ -100,6 +109,15 @@
}
@Test
+ public void testDecodeEncode() {
+ DecodeResult<EapSimTypeData> result =
+ mEapSimTypeDataDecoder.decode(EAP_SIM_CHALLENGE_REQUEST);
+ assertTrue(result.isSuccessfulDecode());
+
+ assertArrayEquals(EAP_SIM_CHALLENGE_REQUEST, result.eapTypeData.encode());
+ }
+
+ @Test
public void testDecodeNullTypeData() {
DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(null);
assertFalse(result.isSuccessfulDecode());
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java
index 82b066d..042519a 100644
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java
+++ b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java
@@ -43,6 +43,7 @@
private static final int MAC_LENGTH = 16;
private static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
private static final byte[] INVALID_MAC = {(byte) 1, (byte) 2, (byte) 3};
+ private static final byte[] RESERVED_BYTES = {(byte) 0x0A, (byte) 0x0B};
private EapSimAkaAttributeFactory mAttributeFactory;
@@ -107,4 +108,13 @@
atMac.encode(result);
assertArrayEquals(AT_MAC, result.array());
}
+
+ @Test
+ public void testGetAtMacWithMacCleared() throws Exception {
+ AtMac original = new AtMac(RESERVED_BYTES, MAC_BYTES);
+
+ AtMac clearedMac = original.getAtMacWithMacCleared();
+ assertArrayEquals(RESERVED_BYTES, clearedMac.reservedBytes);
+ assertArrayEquals(new byte[MAC_LENGTH], clearedMac.mac);
+ }
}