// Copyright 2017 Google Inc.
//
// 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.crypto.tink.subtle;

import com.google.crypto.tink.subtle.Enums.HashType;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Arrays;

/** Helper methods. */
public class SubtleUtil {

  /**
   * Returns the Ecdsa algorithm name corresponding to a hash type.
   *
   * @param hash the hash type
   * @return the JCE's Ecdsa algorithm name for the hash.
   * @throw GeneralSecurityExceptio if {@code hash} is not supported or is not safe for digital
   *     signature.
   */
  public static String toEcdsaAlgo(HashType hash) throws GeneralSecurityException {
    Validators.validateSignatureHash(hash);
    return hash + "withECDSA";
  }

  /**
   * Returns the RSA SSA (Signature with Appendix) PKCS1 algorithm name corresponding to a hash
   * type.
   *
   * @param hash the hash type.
   * @return the JCE's RSA SSA PKCS1 algorithm name for the hash.
   * @throw GeneralSecurityException if {@code hash} is not supported or is not safe for digital
   *     signature.
   */
  public static String toRsaSsaPkcs1Algo(HashType hash) throws GeneralSecurityException {
    Validators.validateSignatureHash(hash);
    return hash + "withRSA";
  }

  /**
   * Returns the digest algorithm name corresponding to a hash type.
   *
   * @param hash the hash type.
   * @return theh JCE's hash algorithm name.
   * @throw GeneralSecurityException if {@code hash} is not supported.
   */
  public static String toDigestAlgo(HashType hash) throws GeneralSecurityException {
    switch (hash) {
      case SHA1:
        return "SHA-1";
      case SHA256:
        return "SHA-256";
      case SHA384:
        return "SHA-384";
      case SHA512:
        return "SHA-512";
    }
    throw new GeneralSecurityException("Unsupported hash " + hash);
  }

  /**
   * Best-effort checks that this is Android.
   *
   * @return true if running on Android.
   */
  public static boolean isAndroid() {
    try {
      Class.forName("android.app.Application", /*initialize=*/ false, null);
      return true;
    } catch (Exception e) {
      // If Application isn't loaded, it might as well not be Android.
      return false;
    }
  }

  /**
   * Converts an byte array to a nonnegative integer
   * (https://tools.ietf.org/html/rfc8017#section-4.1).
   *
   * @param bs the byte array to be converted to integer.
   * @return the corresponding integer.
   */
  public static BigInteger bytes2Integer(byte[] bs) {
    return new BigInteger(1, bs);
  }

  /**
   * Converts a nonnegative integer to a byte array of a specified length
   * (https://tools.ietf.org/html/rfc8017#section-4.2).
   *
   * @param num nonnegative integer to be converted.
   * @param intendedLength intended length of the resulting integer.
   * @return the corresponding byte array of length {@code intendedLength}.
   */
  public static byte[] integer2Bytes(BigInteger num, int intendedLength)
      throws GeneralSecurityException {
    byte[] b = num.toByteArray();
    if (b.length == intendedLength) {
      return b;
    }
    if (b.length > intendedLength + 1 /* potential leading zero */) {
      throw new GeneralSecurityException("integer too large");
    }
    if (b.length == intendedLength + 1) {
      if (b[0] == 0 /* leading zero */) {
        return Arrays.copyOfRange(b, 1, b.length);
      } else {
        throw new GeneralSecurityException("integer too large");
      }
    }
    // Left zero pad b.
    byte[] res = new byte[intendedLength];
    System.arraycopy(b, 0, res, intendedLength - b.length, b.length);
    return res;
  }

  /** Computes MGF1 as defined at https://tools.ietf.org/html/rfc8017#appendix-B.2.1. */
  public static byte[] mgf1(byte[] mgfSeed, int maskLen, HashType mgfHash)
      throws GeneralSecurityException {
    MessageDigest digest =
        EngineFactory.MESSAGE_DIGEST.getInstance(SubtleUtil.toDigestAlgo(mgfHash));
    int hLen = digest.getDigestLength();
    // Step 1. Check maskLen.
    // As max integer is only 2^31 - 1 which is smaller than the limit 2^32, this step is skipped.

    // Step 2, 3. Compute t.
    byte[] t = new byte[maskLen];
    int tPos = 0;
    for (int counter = 0; counter <= (maskLen - 1) / hLen; counter++) {
      digest.reset();
      digest.update(mgfSeed);
      digest.update(SubtleUtil.integer2Bytes(BigInteger.valueOf(counter), 4));
      byte[] c = digest.digest();
      System.arraycopy(c, 0, t, tPos, Math.min(c.length, t.length - tPos));
      tPos += c.length;
    }
    return t;
  }

  /**
   * Inserts {@code value} as unsigned into into {@code buffer}.
   *
   * <p>@throws GeneralSecurityException if not 0 <= value < 2^32.
   */
  public static void putAsUnsigedInt(ByteBuffer buffer, long value)
      throws GeneralSecurityException {
    if (!(0 <= value && value < 0x100000000L)) {
      throw new GeneralSecurityException("Index out of range");
    }
    buffer.putInt((int) value);
  }
}
