// 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.signature;

import com.google.crypto.tink.proto.EcdsaParams;
import com.google.crypto.tink.proto.EcdsaSignatureEncoding;
import com.google.crypto.tink.proto.EllipticCurveType;
import com.google.crypto.tink.proto.HashType;
import com.google.crypto.tink.proto.RsaSsaPkcs1Params;
import com.google.crypto.tink.proto.RsaSsaPssParams;
import com.google.crypto.tink.subtle.EllipticCurves;
import com.google.crypto.tink.subtle.Enums;
import java.security.GeneralSecurityException;

final class SigUtil {
  static final String INVALID_PARAMS = "Invalid ECDSA parameters";

  /**
   * Validates Ecdsa's parameters. The hash's strength must not be weaker than the curve's strength.
   *
   * @param params the Ecdsa's parameters protocol buffer.
   * @throws GeneralSecurityException iff it's invalid.
   */
  public static void validateEcdsaParams(EcdsaParams params) throws GeneralSecurityException {
    EcdsaSignatureEncoding encoding = params.getEncoding();
    HashType hash = params.getHashType();
    EllipticCurveType curve = params.getCurve();
    switch (encoding) {
      case DER: // fall through
      case IEEE_P1363:
        break;
      default:
        throw new GeneralSecurityException("unsupported signature encoding");
    }
    switch (curve) {
      case NIST_P256:
        // Using SHA512 for curve P256 is fine. However, only the 256 leftmost bits of the hash is
        // used in signature computation. Therefore, we don't allow it here to prevent security
        // illusion.
        if (hash != HashType.SHA256) {
          throw new GeneralSecurityException(INVALID_PARAMS);
        }
        break;
      case NIST_P384:
        if (hash != HashType.SHA384 && hash != HashType.SHA512) {
          throw new GeneralSecurityException(INVALID_PARAMS);
        }
        break;
      case NIST_P521:
        if (hash != HashType.SHA512) {
          throw new GeneralSecurityException(INVALID_PARAMS);
        }
        break;
      default:
        throw new GeneralSecurityException(INVALID_PARAMS);
    }
  }

  /**
   * Validates RsaSsaPkcs1's parameters. As SHA1 is unsafe, we will only support SHA256 and SHA512
   * for digital signature.
   *
   * @param params the RsaSsaPkcs1Params protocol buffer.
   * @throws GeneralSecurityException iff it's invalid.
   */
  public static void validateRsaSsaPkcs1Params(RsaSsaPkcs1Params params)
      throws GeneralSecurityException {
    toHashType(params.getHashType());
  }

  /**
   * Validates RsaSsaPss's parameters.
   *
   * <ul>
   *   <li>As SHA1 is unsafe, we will only support SHA256 and SHA512 for digital signature.
   *   <li>The most common use case is that MGF1 hash is the same as signature hash. This is
   *       recommended by RFC https://tools.ietf.org/html/rfc8017#section-8.1. While using different
   *       hashes doesn't cause security vulnerabilities, there is also no good reason to support
   *       different hashes. Furthermore:
   *       <ul>
   *         <li>Golang does not support different hashes.
   *         <li>BoringSSL supports different hashes just because of historical reason. There is no
   *             real use case.
   *         <li>Conscrypt/BouncyCastle do not support different hashes.
   *       </ul>
   * </ul>
   *
   * @param params the RsaSsaPssParams protocol buffer.
   * @throws GeneralSecurityException iff it's invalid.
   */
  public static void validateRsaSsaPssParams(RsaSsaPssParams params)
      throws GeneralSecurityException {
    toHashType(params.getSigHash());
    if (params.getSigHash() != params.getMgf1Hash()) {
      throw new GeneralSecurityException("MGF1 hash is different from signature hash");
    }
  }

  /** Converts protobuf enum {@code HashType} to raw Java enum {@code Enums.HashType}. */
  public static Enums.HashType toHashType(HashType hash) throws GeneralSecurityException {
    switch (hash) {
      case SHA256:
        return Enums.HashType.SHA256;
      case SHA384:
        return Enums.HashType.SHA384;
      case SHA512:
        return Enums.HashType.SHA512;
      default:
        break;
    }
    throw new GeneralSecurityException("unsupported hash type: " + hash.name());
  }

  /** Converts protobuf enum {@code EllipticCurveType} to raw Java enum {code CurveType}. */
  public static EllipticCurves.CurveType toCurveType(EllipticCurveType type)
      throws GeneralSecurityException {
    switch (type) {
      case NIST_P256:
        return EllipticCurves.CurveType.NIST_P256;
      case NIST_P384:
        return EllipticCurves.CurveType.NIST_P384;
      case NIST_P521:
        return EllipticCurves.CurveType.NIST_P521;
      default:
        throw new GeneralSecurityException("unknown curve type: " + type);
    }
  }

  /**
   * Converts protobuf enum {@code EcdsaSignatureEncoding} to raw Java enum {code
   * EllipticCurves.EcdsaEncoding}.
   */
  public static EllipticCurves.EcdsaEncoding toEcdsaEncoding(EcdsaSignatureEncoding encoding)
      throws GeneralSecurityException {
    switch (encoding) {
      case IEEE_P1363:
        return EllipticCurves.EcdsaEncoding.IEEE_P1363;
      case DER:
        return EllipticCurves.EcdsaEncoding.DER;
      default:
        throw new GeneralSecurityException("unknown ECDSA encoding: " + encoding);
    }
  }
}
