/*
 * Copyright (C) 2015 The Guava Authors
 *
 * 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.google.common.hash;

import static com.google.common.base.Charsets.UTF_8;
import static com.google.common.io.BaseEncoding.base16;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
import com.google.common.testing.NullPointerTester;
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import junit.framework.TestCase;
import sun.security.jca.ProviderList;
import sun.security.jca.Providers;

/**
 * Tests for the MacHashFunction.
 *
 * @author Kurt Alfred Kluever
 */
public class MacHashFunctionTest extends TestCase {

  private static final ImmutableSet<String> INPUTS = ImmutableSet.of("", "Z", "foobar");

  private static final SecretKey MD5_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacMD5");
  private static final SecretKey SHA1_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacSHA1");
  private static final SecretKey SHA256_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacSHA256");
  private static final SecretKey SHA512_KEY =
      new SecretKeySpec("secret key".getBytes(UTF_8), "HmacSHA512");

  // From http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#Mac
  private static final ImmutableTable<String, SecretKey, HashFunction> ALGORITHMS =
      new ImmutableTable.Builder<String, SecretKey, HashFunction>()
          .put("HmacMD5", MD5_KEY, Hashing.hmacMd5(MD5_KEY))
          .put("HmacSHA1", SHA1_KEY, Hashing.hmacSha1(SHA1_KEY))
          .put("HmacSHA256", SHA256_KEY, Hashing.hmacSha256(SHA256_KEY))
          .put("HmacSHA512", SHA512_KEY, Hashing.hmacSha512(SHA512_KEY))
          .build();

  public void testNulls() {
    NullPointerTester tester =
        new NullPointerTester().setDefault(String.class, "HmacMD5").setDefault(Key.class, MD5_KEY);
    tester.testAllPublicConstructors(MacHashFunction.class);
    tester.testAllPublicInstanceMethods(new MacHashFunction("HmacMD5", MD5_KEY, "toString"));
  }

  public void testHashing() throws Exception {
    for (String stringToTest : INPUTS) {
      for (Table.Cell<String, SecretKey, HashFunction> cell : ALGORITHMS.cellSet()) {
        String algorithm = cell.getRowKey();
        SecretKey key = cell.getColumnKey();
        HashFunction hashFunc = cell.getValue();
        assertMacHashing(HashTestUtils.ascii(stringToTest), algorithm, key, hashFunc);
      }
    }
  }

  @AndroidIncompatible // sun.security
  public void testNoProviders() {
    ProviderList providers = Providers.getProviderList();
    Providers.setProviderList(ProviderList.newList());
    try {
      Hashing.hmacMd5(MD5_KEY);
      fail("expected ISE");
    } catch (IllegalStateException expected) {
    } finally {
      Providers.setProviderList(providers);
    }
  }

  public void testMultipleUpdates() throws Exception {
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(SHA1_KEY);
    mac.update("hello".getBytes(UTF_8));
    mac.update("world".getBytes(UTF_8));

    assertEquals(
        HashCode.fromBytes(mac.doFinal()),
        Hashing.hmacSha1(SHA1_KEY)
            .newHasher()
            .putString("hello", UTF_8)
            .putString("world", UTF_8)
            .hash());
  }

  public void testMultipleUpdatesDoFinal() throws Exception {
    Mac mac = Mac.getInstance("HmacSHA1");
    mac.init(SHA1_KEY);
    mac.update("hello".getBytes(UTF_8));
    mac.update("world".getBytes(UTF_8));

    assertEquals(
        HashCode.fromBytes(mac.doFinal("!!!".getBytes(UTF_8))),
        Hashing.hmacSha1(SHA1_KEY)
            .newHasher()
            .putString("hello", UTF_8)
            .putString("world", UTF_8)
            .putString("!!!", UTF_8)
            .hash());
  }

  public void testCustomKey() throws Exception {
    SecretKey customKey =
        new SecretKey() {
          @Override
          public String getAlgorithm() {
            return "HmacMD5";
          }

          @Override
          public byte[] getEncoded() {
            return new byte[8];
          }

          @Override
          public String getFormat() {
            return "RAW";
          }
        };
    assertEquals(
        "ad262969c53bc16032f160081c4a07a0",
        Hashing.hmacMd5(customKey)
            .hashString("The quick brown fox jumps over the lazy dog", UTF_8)
            .toString());
  }

  public void testBadKey_emptyKey() throws Exception {
    SecretKey badKey =
        new SecretKey() {
          @Override
          public String getAlgorithm() {
            return "HmacMD5";
          }

          @Override
          public byte[] getEncoded() {
            return null;
          }

          @Override
          public String getFormat() {
            return "RAW";
          }
        };
    try {
      Hashing.hmacMd5(badKey);
      fail();
    } catch (IllegalArgumentException expected) {
    } catch (NullPointerException toleratedOnAndroid) {
      // TODO(cpovirk): In an ideal world, we'd check here that we're running on Android.
    }
  }

  public void testEmptyInputs() throws Exception {
    String knownOutput = "8cbf764cbe2e4623d99a41354adfd390";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(MD5_KEY);
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(MD5_KEY).newHasher().hash().toString());
  }

  public void testEmptyInputs_mixedAlgorithms() throws Exception {
    String knownOutput = "8cbf764cbe2e4623d99a41354adfd390";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(SHA1_KEY);
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(SHA1_KEY).newHasher().hash().toString());
  }

  public void testKnownInputs() throws Exception {
    String knownOutput = "9753980fe94daa8ecaa82216519393a9";
    String input = "The quick brown fox jumps over the lazy dog";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(MD5_KEY);
    mac.update(input.getBytes(UTF_8));
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal(input.getBytes(UTF_8))).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(MD5_KEY).hashString(input, UTF_8).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(MD5_KEY).hashBytes(input.getBytes(UTF_8)).toString());
  }

  public void testKnownInputs_mixedAlgorithms() throws Exception {
    String knownOutput = "9753980fe94daa8ecaa82216519393a9";
    String input = "The quick brown fox jumps over the lazy dog";

    Mac mac = Mac.getInstance("HmacMD5");
    mac.init(SHA1_KEY);
    mac.update(input.getBytes(UTF_8));
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal()).toString());
    assertEquals(knownOutput, HashCode.fromBytes(mac.doFinal(input.getBytes(UTF_8))).toString());
    assertEquals(knownOutput, Hashing.hmacMd5(SHA1_KEY).hashString(input, UTF_8).toString());
    assertEquals(
        knownOutput, Hashing.hmacMd5(SHA1_KEY).hashBytes(input.getBytes(UTF_8)).toString());
  }

  public void testPutAfterHash() {
    Hasher hasher = Hashing.hmacMd5(MD5_KEY).newHasher();

    assertEquals(
        "9753980fe94daa8ecaa82216519393a9",
        hasher.putString("The quick brown fox jumps over the lazy dog", UTF_8).hash().toString());
    try {
      hasher.putInt(42);
      fail();
    } catch (IllegalStateException expected) {
    }
  }

  public void testHashTwice() {
    Hasher hasher = Hashing.hmacMd5(MD5_KEY).newHasher();

    assertEquals(
        "9753980fe94daa8ecaa82216519393a9",
        hasher.putString("The quick brown fox jumps over the lazy dog", UTF_8).hash().toString());
    try {
      hasher.hash();
      fail();
    } catch (IllegalStateException expected) {
    }
  }

  public void testToString() {
    byte[] keyData = "secret key".getBytes(UTF_8);

    assertEquals(
        "Hashing.hmacMd5(Key[algorithm=HmacMD5, format=RAW])", Hashing.hmacMd5(MD5_KEY).toString());
    assertEquals(
        "Hashing.hmacMd5(Key[algorithm=HmacMD5, format=RAW])", Hashing.hmacMd5(keyData).toString());

    assertEquals(
        "Hashing.hmacSha1(Key[algorithm=HmacSHA1, format=RAW])",
        Hashing.hmacSha1(SHA1_KEY).toString());
    assertEquals(
        "Hashing.hmacSha1(Key[algorithm=HmacSHA1, format=RAW])",
        Hashing.hmacSha1(keyData).toString());

    assertEquals(
        "Hashing.hmacSha256(Key[algorithm=HmacSHA256, format=RAW])",
        Hashing.hmacSha256(SHA256_KEY).toString());
    assertEquals(
        "Hashing.hmacSha256(Key[algorithm=HmacSHA256, format=RAW])",
        Hashing.hmacSha256(keyData).toString());

    assertEquals(
        "Hashing.hmacSha512(Key[algorithm=HmacSHA512, format=RAW])",
        Hashing.hmacSha512(SHA512_KEY).toString());
    assertEquals(
        "Hashing.hmacSha512(Key[algorithm=HmacSHA512, format=RAW])",
        Hashing.hmacSha512(keyData).toString());
  }

  private static void assertMacHashing(
      byte[] input, String algorithm, SecretKey key, HashFunction hashFunc) throws Exception {
    Mac mac = Mac.getInstance(algorithm);
    mac.init(key);
    mac.update(input);

    assertEquals(HashCode.fromBytes(mac.doFinal()), hashFunc.hashBytes(input));
    assertEquals(HashCode.fromBytes(mac.doFinal(input)), hashFunc.hashBytes(input));
  }

  // Tests from RFC2022: https://tools.ietf.org/html/rfc2202

  public void testRfc2202_hmacSha1_case1() {
    byte[] key = fillByteArray(20, 0x0b);
    String data = "Hi There";

    checkSha1("b617318655057264e28bc0b6fb378c8ef146be00", key, data);
  }

  public void testRfc2202_hmacSha1_case2() {
    byte[] key = "Jefe".getBytes(UTF_8);
    String data = "what do ya want for nothing?";

    checkSha1("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", key, data);
  }

  public void testRfc2202_hmacSha1_case3() {
    byte[] key = fillByteArray(20, 0xaa);
    byte[] data = fillByteArray(50, 0xdd);

    checkSha1("125d7342b9ac11cd91a39af48aa17b4f63f175d3", key, data);
  }

  public void testRfc2202_hmacSha1_case4() {
    byte[] key = base16().lowerCase().decode("0102030405060708090a0b0c0d0e0f10111213141516171819");
    byte[] data = fillByteArray(50, 0xcd);

    checkSha1("4c9007f4026250c6bc8414f9bf50c86c2d7235da", key, data);
  }

  public void testRfc2202_hmacSha1_case5() {
    byte[] key = fillByteArray(20, 0x0c);
    String data = "Test With Truncation";

    checkSha1("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04", key, data);
  }

  public void testRfc2202_hmacSha1_case6() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key - Hash Key First";

    checkSha1("aa4ae5e15272d00e95705637ce8a3b55ed402112", key, data);
  }

  public void testRfc2202_hmacSha1_case7() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";

    checkSha1("e8e99d0f45237d786d6bbaa7965c7808bbff1a91", key, data);
  }

  public void testRfc2202_hmacMd5_case1() {
    byte[] key = fillByteArray(16, 0x0b);
    String data = "Hi There";

    checkMd5("9294727a3638bb1c13f48ef8158bfc9d", key, data);
  }

  public void testRfc2202_hmacMd5_case2() {
    byte[] key = "Jefe".getBytes(UTF_8);
    String data = "what do ya want for nothing?";

    checkMd5("750c783e6ab0b503eaa86e310a5db738", key, data);
  }

  public void testRfc2202_hmacMd5_case3() {
    byte[] key = fillByteArray(16, 0xaa);
    byte[] data = fillByteArray(50, 0xdd);

    checkMd5("56be34521d144c88dbb8c733f0e8b3f6", key, data);
  }

  public void testRfc2202_hmacMd5_case4() {
    byte[] key = base16().lowerCase().decode("0102030405060708090a0b0c0d0e0f10111213141516171819");
    byte[] data = fillByteArray(50, 0xcd);

    checkMd5("697eaf0aca3a3aea3a75164746ffaa79", key, data);
  }

  public void testRfc2202_hmacMd5_case5() {
    byte[] key = fillByteArray(16, 0x0c);
    String data = "Test With Truncation";

    checkMd5("56461ef2342edc00f9bab995690efd4c", key, data);
  }

  public void testRfc2202_hmacMd5_case6() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key - Hash Key First";

    checkMd5("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd", key, data);
  }

  public void testRfc2202_hmacMd5_case7() {
    byte[] key = fillByteArray(80, 0xaa);
    String data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data";

    checkMd5("6f630fad67cda0ee1fb1f562db3aa53e", key, data);
  }

  private static void checkSha1(String expected, byte[] key, String data) {
    checkSha1(expected, key, data.getBytes(UTF_8));
  }

  private static void checkSha1(String expected, byte[] key, byte[] data) {
    checkHmac(expected, Hashing.hmacSha1(key), data);
  }

  private static void checkMd5(String expected, byte[] key, String data) {
    checkMd5(expected, key, data.getBytes(UTF_8));
  }

  private static void checkMd5(String expected, byte[] key, byte[] data) {
    checkHmac(expected, Hashing.hmacMd5(key), data);
  }

  private static void checkHmac(String expected, HashFunction hashFunc, byte[] data) {
    assertEquals(HashCode.fromString(expected), hashFunc.hashBytes(data));
  }

  private static byte[] fillByteArray(int size, int toFillWith) {
    byte[] array = new byte[size];
    Arrays.fill(array, (byte) toFillWith);
    return array;
  }
}
