/*
 * 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.products.ov.channel.cc.commons.keymanagement;

import java.security.KeyManagementException;
import java.security.KeyStore.PasswordProtection;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.annotation.concurrent.ThreadSafe;

import com.scytl.cryptolib.elgamal.bean.ElGamalPrivateKey;
import com.scytl.cryptolib.elgamal.bean.ElGamalPublicKey;

/**
 * Codec.
 */
@ThreadSafe
interface Codec {
    /**
     * Decodes election signing keys from given bytes. Client must provide the
     * original password which was used when the keys were encoded.
     * 
     * @param bytes
     *            the bytes
     * @param password
     *            the password
     * @return the keys
     * @throws InvalidPasswordException
     *             the password is invalid
     * @throws KeyManagementException
     *             failed to decode the keys.
     */
    ElectionSigningKeys decodeElectionSigningKeys(byte[] bytes,
            PasswordProtection password)
            throws InvalidPasswordException, KeyManagementException;

    /**
     * Decodes ElGamal private key from given bytes. Client has to supply the
     * private key matching the public key which was used to when the key was
     * encoded.
     * 
     * @param bytes
     *            the bytes
     * @param encryptionKey
     *            the encryption key
     * @return the keys
     * @throws KeyManagementException
     *             failed to decode the keys.
     */
    ElGamalPrivateKey decodeElGamalPrivateKey(byte[] bytes,
            PrivateKey encryptionKey)
            throws KeyManagementException;

    /**
     * Decodes ElGamal public key from given bytes.
     * 
     * @param bytes
     *            the bytes
     * @return the keys
     * @throws KeyManagementException
     *             failed to decode the keys.
     */
    ElGamalPublicKey decodeElGamalPublicKey(byte[] bytes)
            throws KeyManagementException;

    /**
     * Decodes node keys from given bytes. Client must provide the same password
     * which was used when the keys were encoded.
     * 
     * @param bytes
     *            the bytes
     * @param password
     *            the password
     * @return the keys
     * @throws InvalidPasswordException
     *             the password is invalid
     * @throws KeyManagementException
     *             failed to encode the keys.
     */
    NodeKeys decodeNodeKeys(byte[] bytes, PasswordProtection password)
            throws InvalidPasswordException, KeyManagementException;

    /**
     * Decodes the password from given bytes encrypted with the specified key.
     * 
     * @param bytes
     *            the bytes
     * @param encryptionKey
     *            th encryption key
     * @return the password
     * @throws KeyManagementException
     *             failed to decode the password.
     */
    PasswordProtection decodePassword(byte[] bytes,
            PrivateKey encryptionKey)
            throws KeyManagementException;

    /**
     * Encodes given election signing keys and protects them with the specified
     * password.
     * 
     * @param keys
     *            the keys
     * @param password
     *            the password
     * @return the encoded keys
     * @throws KeyManagementException
     *             failed to encode the keys.
     */
    byte[] encodeElectionSigningKeys(ElectionSigningKeys keys,
            PasswordProtection password)
            throws KeyManagementException;

    /**
     * Encodes a given private ElGamal key and encrypts it with the specified
     * encryption key.
     * 
     * @param key
     *            the key
     * @param encryptionKey
     *            the encryption key
     * @return the encoded key
     * @throws KeyManagementException
     *             failed to encode the key.
     */
    byte[] encodeElGamalPrivateKey(ElGamalPrivateKey key,
            PublicKey encryptionKey)
            throws KeyManagementException;

    /**
     * Encodes a given public ElGamal key.
     * 
     * @param key
     *            the key
     * @return the encoded key.
     * @throws KeyManagementException
     *             failed to encode the key.
     */
    byte[] encodeElGamalPublicKey(ElGamalPublicKey key)
            throws KeyManagementException;

    /**
     * Encodes given node keys and protects them with the specified password.
     * 
     * @param keys
     *            the keys
     * @param password
     *            the password
     * @return the encoded keys
     * @throws KeyManagementException
     *             failed to encode the keys.
     */
    byte[] encodeNodeKeys(NodeKeys keys, PasswordProtection password)
            throws KeyManagementException;

    /**
     * Encodes a given password and encrypts it with the specified encryption
     * key.
     * 
     * @param password
     *            the password
     * @param encryptionKey
     *            the encryption key
     * @return the encoded password
     * @throws KeyManagementException
     *             failed to encode the password.
     */
    byte[] encodePassword(PasswordProtection password,
            PublicKey encryptionKey)
            throws KeyManagementException;
}
