/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt'
 * which is part of this source code package
 */

package com.scytl.slogger.crypto;

import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

/**
 * A default secure logger keystore backed by the JCE keystore.
 */
public class DefaultSecureLoggerKeyStore implements SecureLoggerKeyStore {

  private static final int DIGITAL_SIGNATURE_INDEX = 0;
  private static final int NON_REPUDIATION_INDEX = 1;

  private static final int KEY_ENCIPHERMENT_INDEX = 2;
  private static final int DATA_ENCIPHERMENT_INDEX = 3;


  private static final int KEY_CERTIFICATE_SIGN = 5;
  private static final int CRL_SIGN = 6;

  private final KeyStore keyStore;

  /**
   * Constructor.
   *
   * @param keyStore the key store.
   */
  public DefaultSecureLoggerKeyStore(final KeyStore keyStore) {
    this.keyStore = keyStore;
  }

  @Override
  public KeyStore getKeyStore() {
    return keyStore;
  }

  @Override
  public boolean isForCipherOnly() {
    boolean[] keyUsage = getKeyUsage();
    return keyUsage != null && keyUsage[KEY_ENCIPHERMENT_INDEX]
        && !keyUsage[DIGITAL_SIGNATURE_INDEX] && !keyUsage[NON_REPUDIATION_INDEX]
        && !keyUsage[KEY_CERTIFICATE_SIGN] && !keyUsage[CRL_SIGN];
  }

  @Override
  public boolean isForSignatureOnly() {
    boolean[] keyUsage = getKeyUsage();
    return keyUsage != null && keyUsage[DIGITAL_SIGNATURE_INDEX] && keyUsage[NON_REPUDIATION_INDEX]
        && !keyUsage[KEY_ENCIPHERMENT_INDEX] && !keyUsage[DATA_ENCIPHERMENT_INDEX]
        && !keyUsage[KEY_CERTIFICATE_SIGN] && !keyUsage[CRL_SIGN];
  }

  private boolean[] getKeyUsage() {
    try {
      Enumeration<String> aliases = keyStore.aliases();
      if (aliases.hasMoreElements()) {
        String alias = aliases.nextElement();
        // by the current implementation just one alias should be inside the keystore
        Certificate cert = keyStore.getCertificate(alias);
        if (cert instanceof X509Certificate) {
          return ((X509Certificate) cert).getKeyUsage();
        }
      }
    } catch (KeyStoreException e) {
      throw new IllegalStateException("The key store has not been loaded.", e);
    }
    return null;
  }

}
