/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You 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 org.apache.geode.security.templates;

import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.logging.log4j.Logger;

import org.apache.geode.LogWriter;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.security.AuthenticationFailedException;
import org.apache.geode.security.Authenticator;

/**
 * An implementation of {@link Authenticator} that uses PKCS.
 */
public class PKCSAuthenticator implements Authenticator {

  private static final Logger logger = LogService.getLogger();

  public static final String PUBLIC_KEY_FILE = "security-publickey-filepath";
  public static final String PUBLIC_KEYSTORE_PASSWORD = "security-publickey-pass";

  private String pubKeyFilePath;
  private String pubKeyPass;
  private Map aliasCertificateMap;

  private LogWriter systemLogWriter;
  private LogWriter securityLogWriter;

  public static Authenticator create() {
    return new PKCSAuthenticator();
  }

  @Override
  public void init(final Properties securityProperties, final LogWriter systemLogWriter,
      final LogWriter securityLogWriter) throws AuthenticationFailedException {
    this.systemLogWriter = systemLogWriter;
    this.securityLogWriter = securityLogWriter;

    this.pubKeyFilePath = securityProperties.getProperty(PUBLIC_KEY_FILE);
    if (this.pubKeyFilePath == null) {
      throw new AuthenticationFailedException("PKCSAuthenticator: property " + PUBLIC_KEY_FILE
          + " not specified as the public key file.");
    }

    this.pubKeyPass = securityProperties.getProperty(PUBLIC_KEYSTORE_PASSWORD);
    this.aliasCertificateMap = new HashMap();

    populateMap();
  }

  @Override
  public Principal authenticate(final Properties credentials, final DistributedMember member)
      throws AuthenticationFailedException {
    final String alias = (String) credentials.get(PKCSAuthInit.KEYSTORE_ALIAS);
    if (alias == null || alias.length() <= 0) {
      throw new AuthenticationFailedException("No alias received");
    }

    try {
      final X509Certificate cert = getCertificate(alias);
      if (cert == null) {
        throw newException("No certificate found for alias:" + alias);
      }

      final byte[] signatureBytes = (byte[]) credentials.get(PKCSAuthInit.SIGNATURE_DATA);
      if (signatureBytes == null) {
        throw newException(
            "signature data property [" + PKCSAuthInit.SIGNATURE_DATA + "] not provided");
      }

      final Signature sig = Signature.getInstance(cert.getSigAlgName());
      sig.initVerify(cert);
      sig.update(alias.getBytes("UTF-8"));

      if (!sig.verify(signatureBytes)) {
        throw newException("verification of client signature failed");
      }

      return new PKCSPrincipal(alias);

    } catch (Exception ex) {
      throw newException(ex.toString(), ex);
    }
  }

  @Override
  public void close() {}

  private void populateMap() {
    try {
      final KeyStore keyStore = KeyStore.getInstance("JKS");
      final char[] passPhrase = this.pubKeyPass != null ? this.pubKeyPass.toCharArray() : null;
      final FileInputStream keyStoreFile = new FileInputStream(this.pubKeyFilePath);

      try {
        keyStore.load(keyStoreFile, passPhrase);
      } finally {
        keyStoreFile.close();
      }

      for (Enumeration e = keyStore.aliases(); e.hasMoreElements();) {
        final Object alias = e.nextElement();
        final Certificate cert = keyStore.getCertificate((String) alias);
        if (cert instanceof X509Certificate) {
          this.aliasCertificateMap.put(alias, cert);
        }
      }

    } catch (Exception e) {
      throw new AuthenticationFailedException(
          "Exception while getting public keys: " + e.getMessage(), e);
    }
  }

  private AuthenticationFailedException newException(final String message, final Exception cause) {
    final String fullMessage =
        "PKCSAuthenticator: Authentication of client failed due to: " + message;
    if (cause != null) {
      return new AuthenticationFailedException(fullMessage, cause);
    } else {
      return new AuthenticationFailedException(fullMessage);
    }
  }

  private AuthenticationFailedException newException(final String message) {
    return newException(message, null);
  }

  private X509Certificate getCertificate(final String alias)
      throws NoSuchAlgorithmException, InvalidKeySpecException {
    if (this.aliasCertificateMap.containsKey(alias)) {
      return (X509Certificate) this.aliasCertificateMap.get(alias);
    }
    return null;
  }
}
