From 82c3470df946ab1c6876f78dd62f02c6d8a8dcd4 Mon Sep 17 00:00:00 2001 From: Nathan Harold Date: Thu, 9 Nov 2017 16:49:33 -0800 Subject: [PATCH] Validate IpSecAlgorithm Length Improve the Validation of IpSecAlgorithm by explicitly checking the length in addition to the truncation length (previously an oversight). In addition, we now check the lengths during un-parceling, which will catch someone maliciously manually building a parcel and passing it, bypassing the checks in the constructor. Bug: 68780091 Test: runtest -x IpSecAlgorithmTest.java Change-Id: I8172762617264d34f47d5144336464510f07a701 --- .../java/android/net/IpSecAlgorithmTest.java | 115 ++++++++++++++++++ .../net/java/android/net/IpSecConfigTest.java | 4 +- 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 tests/net/java/android/net/IpSecAlgorithmTest.java diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java new file mode 100644 index 0000000000..6bdfdc6db2 --- /dev/null +++ b/tests/net/java/android/net/IpSecAlgorithmTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2017 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 android.net; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import android.os.Parcel; +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import java.util.Arrays; +import java.util.Random; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** Unit tests for {@link IpSecAlgorithm}. */ +@SmallTest +@RunWith(AndroidJUnit4.class) +public class IpSecAlgorithmTest { + + private static final byte[] KEY_MATERIAL; + + static { + KEY_MATERIAL = new byte[128]; + new Random().nextBytes(KEY_MATERIAL); + }; + + @Test + public void testDefaultTruncLen() throws Exception { + IpSecAlgorithm explicit = + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA256, Arrays.copyOf(KEY_MATERIAL, 256 / 8), 256); + IpSecAlgorithm implicit = + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA256, Arrays.copyOf(KEY_MATERIAL, 256 / 8)); + assertTrue( + "Default Truncation Length Incorrect, Explicit: " + + explicit + + "implicit: " + + implicit, + IpSecAlgorithm.equals(explicit, implicit)); + } + + @Test + public void testTruncLenValidation() throws Exception { + for (int truncLen : new int[] {256, 512}) { + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA512, + Arrays.copyOf(KEY_MATERIAL, 512 / 8), + truncLen); + } + + for (int truncLen : new int[] {255, 513}) { + try { + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA512, + Arrays.copyOf(KEY_MATERIAL, 512 / 8), + truncLen); + fail("Invalid truncation length not validated"); + } catch (IllegalArgumentException pass) { + } + } + } + + @Test + public void testLenValidation() throws Exception { + for (int len : new int[] {128, 192, 256}) { + new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, Arrays.copyOf(KEY_MATERIAL, len / 8)); + } + try { + new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, Arrays.copyOf(KEY_MATERIAL, 384 / 8)); + fail("Invalid key length not validated"); + } catch (IllegalArgumentException pass) { + } + } + + @Test + public void testAlgoNameValidation() throws Exception { + try { + new IpSecAlgorithm("rot13", Arrays.copyOf(KEY_MATERIAL, 128 / 8)); + fail("Invalid algorithm name not validated"); + } catch (IllegalArgumentException pass) { + } + } + + @Test + public void testParcelUnparcel() throws Exception { + IpSecAlgorithm init = + new IpSecAlgorithm( + IpSecAlgorithm.AUTH_HMAC_SHA512, Arrays.copyOf(KEY_MATERIAL, 512 / 8), 256); + + Parcel p = Parcel.obtain(); + p.setDataPosition(0); + init.writeToParcel(p, 0); + + p.setDataPosition(0); + IpSecAlgorithm fin = IpSecAlgorithm.CREATOR.createFromParcel(p); + assertTrue("Parcel/Unparcel failed!", IpSecAlgorithm.equals(init, fin)); + p.recycle(); + } +} diff --git a/tests/net/java/android/net/IpSecConfigTest.java b/tests/net/java/android/net/IpSecConfigTest.java index 1b4bef5d2f..efc01f2ace 100644 --- a/tests/net/java/android/net/IpSecConfigTest.java +++ b/tests/net/java/android/net/IpSecConfigTest.java @@ -71,7 +71,7 @@ public class IpSecConfigTest { c.setAuthentication( IpSecTransform.DIRECTION_OUT, new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA1, + IpSecAlgorithm.AUTH_HMAC_MD5, new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0})); c.setSpiResourceId(IpSecTransform.DIRECTION_OUT, 1984); c.setEncryption( @@ -82,7 +82,7 @@ public class IpSecConfigTest { c.setAuthentication( IpSecTransform.DIRECTION_IN, new IpSecAlgorithm( - IpSecAlgorithm.AUTH_HMAC_SHA1, + IpSecAlgorithm.AUTH_HMAC_MD5, new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 1})); c.setSpiResourceId(IpSecTransform.DIRECTION_IN, 99); assertParcelingIsLossless(c);