/*
 * Copyright (C) 2019 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 com.android.internal.net.ipsec.test.ike.message;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;

import android.net.ipsec.test.ike.SaProposal;
import android.net.ipsec.test.ike.exceptions.InvalidSyntaxException;

import com.android.internal.net.TestUtils;
import com.android.internal.net.ipsec.test.ike.crypto.IkeCipher;
import com.android.internal.net.ipsec.test.ike.crypto.IkeMacIntegrity;
import com.android.internal.net.ipsec.test.ike.crypto.IkeNormalModeCipher;
import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload.EncryptionTransform;
import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload.IntegrityTransform;

import org.junit.Before;
import org.junit.Test;

import java.nio.ByteBuffer;
import java.util.Arrays;

public final class IkeSkfPayloadTest {
    private static final String IKE_FRAG_MSG_HEX_STRING =
            "bb3d5237aa558779db24aeb6c9ea183e352023200000000100000134"
                    + "0000011800020002c1471fc7714a3b77a2bfd78dd2df4c048dfed913"
                    + "c5de76cb1f4463ef541df2442b43c65308a47b873502268cc1195f99"
                    + "4f6f1a945f56cb342969936af97d79c560c8e0f8bb1a0874ebfb5d0e"
                    + "610b0fcff96d4197c06e7aef07a3a9ae487555bec95c78b87fe6483c"
                    + "be07e3d132f8594c34dba5b5b463b871d0272af6a1ee701fc6b7b70a"
                    + "22a1b8f63eed50ce6b2253ee63fe2cf0289a5eb715e56b389f72b5ba"
                    + "ecfb7340f4abf9253a8c973d281ed62f3516d130fcaaf2c2145b3047"
                    + "f3a243e60beb2fc28bf05183839caf46bfbfc4f28c9a2224e7d49686"
                    + "52a236a403ecb203a1de1e2144a6f5ce28acc2f93989608af17381fc"
                    + "f965cabe1a448274264b22167abfa047dc88e4bfdc5a492847d36d8b";

    private static final String IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING =
            "dc89d82f4fccff8d3f0c4f4848571e57205f7dbdce954203983d2147"
                    + "3a9e10ba36876b860d33afbdfe6ebf000240e31f2039f4213e882d1f"
                    + "6f0a24887aed0584f4b50a016d989990fd58297757c7b842cd72b57c"
                    + "2f68cba8a5f06d899ce3fcfbd0419402a1d59f1c5b5b23bd0a4ed525"
                    + "27ed6cef9fd238552fcf6e4cd9f794d2b01ba61438fd21714fbc3e3f"
                    + "443a816751e55d46009ae7fb9f52db0977e453a2d28b0453a9393778"
                    + "3a0b625c27d186c052a7169807537d97e731a3543fc10dca605ca86d"
                    + "1496882e1d009a9216d07d0000001801850014120a00000f02000200"
                    + "0100000d010000";

    private static final String IKE_FRAG_MSG_CHECKSUM = "7abfa047dc88e4bfdc5a492847d36d8b";
    private static final String IKE_FRAG_MSG_PADDING = "05d925c1b3804aee08";

    private static final int FRAGMENT_NUM = 2;
    private static final int TOTAL_FRAGMENTS = 2;

    private static final int FRAGMENT_NUM_OFFSET =
            IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH;
    private static final int TOTAL_FRAGMENTS_OFFET = FRAGMENT_NUM_OFFSET + 2;

    private byte[] mDecryptedData;

    private IkeMacIntegrity mSpyHmacSha256IntegrityMac;
    private IkeNormalModeCipher mSpyAesCbcCipher;

    @Before
    public void setUp() throws Exception {
        mDecryptedData = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING);

        // Set up integrity algorithm
        mSpyHmacSha256IntegrityMac =
                spy(
                        IkeMacIntegrity.create(
                                new IntegrityTransform(
                                        SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)));
        byte[] expectedChecksum = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_CHECKSUM);
        doReturn(expectedChecksum).when(mSpyHmacSha256IntegrityMac).generateChecksum(any(), any());

        // Set up encryption algorithm
        mSpyAesCbcCipher =
                spy(
                        (IkeNormalModeCipher)
                                IkeCipher.create(
                                        new EncryptionTransform(
                                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
                                                SaProposal.KEY_LEN_AES_128)));
        byte[] expectedDecryptedPaddedData =
                TestUtils.hexStringToByteArray(
                        IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING + IKE_FRAG_MSG_PADDING);
        doReturn(expectedDecryptedPaddedData).when(mSpyAesCbcCipher).decrypt(any(), any(), any());
    }

    private IkeSkfPayload decodeAndDecryptFragMsg(byte[] message) throws Exception {
        IkeSkfPayload payload =
                (IkeSkfPayload)
                        IkePayloadFactory.getIkeSkPayload(
                                        true /*isSkf*/,
                                        message,
                                        mSpyHmacSha256IntegrityMac,
                                        mSpyAesCbcCipher,
                                        new byte[0] /*integrityKey*/,
                                        new byte[0] /*decryptionKey*/)
                                .first;
        return payload;
    }

    @Test
    public void testDecode() throws Exception {
        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);

        IkeSkfPayload payload = decodeAndDecryptFragMsg(message);

        assertEquals(IkePayload.PAYLOAD_TYPE_SKF, payload.payloadType);
        assertEquals(FRAGMENT_NUM, payload.fragmentNum);
        assertEquals(TOTAL_FRAGMENTS, payload.totalFragments);
        assertArrayEquals(mDecryptedData, payload.getUnencryptedData());
    }

    @Test
    public void testDecodeThrowsForZeroFragNum() throws Exception {
        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);

        // Set Fragment Number to zero
        message[FRAGMENT_NUM_OFFSET] = 0;
        message[FRAGMENT_NUM_OFFSET + 1] = 0;

        try {
            decodeAndDecryptFragMsg(message);
            fail("Expected to fail because Fragment Number is zero.");
        } catch (InvalidSyntaxException expected) {
        }
    }

    @Test
    public void testDecodeThrowsForZeroTotalFragments() throws Exception {
        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);

        // Set Total Fragments Number to zero
        message[TOTAL_FRAGMENTS_OFFET] = 0;
        message[TOTAL_FRAGMENTS_OFFET + 1] = 0;

        try {
            decodeAndDecryptFragMsg(message);
            fail("Expected to fail because Total Fragments Number is zero.");
        } catch (InvalidSyntaxException expected) {
        }
    }

    @Test
    public void testDecodeThrowsWhenFragNumIsLargerThanTotalFragments() throws Exception {
        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);

        // Set Fragment Number to 5
        message[FRAGMENT_NUM_OFFSET] = 0;
        message[FRAGMENT_NUM_OFFSET + 1] = 5;

        // Set Total Fragments Number to 2
        message[TOTAL_FRAGMENTS_OFFET] = 0;
        message[TOTAL_FRAGMENTS_OFFET + 1] = 2;

        try {
            decodeAndDecryptFragMsg(message);
            fail(
                    "Expected to fail because Fragment Number is larger than"
                            + " Total Fragments Number");
        } catch (InvalidSyntaxException expected) {
        }
    }

    @Test
    public void testEncode() throws Exception {
        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);
        IkeSkfPayload payload = decodeAndDecryptFragMsg(message);

        int payloadLength = payload.getPayloadLength();
        ByteBuffer buffer = ByteBuffer.allocate(payloadLength);
        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, buffer);

        byte[] expectedPayloadBytes =
                Arrays.copyOfRange(message, IkeHeader.IKE_HEADER_LENGTH, message.length);
        assertArrayEquals(expectedPayloadBytes, buffer.array());
    }
}
