/* ====================================================================
   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.poi.poifs.crypt.agile;

import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.poifs.crypt.ChainingMode;
import org.apache.poi.poifs.crypt.CipherAlgorithm;
import org.apache.poi.poifs.crypt.EncryptionVerifier;
import org.apache.poi.poifs.crypt.HashAlgorithm;

/**
 * Used when checking if a key is valid for a document
 */
public class AgileEncryptionVerifier extends EncryptionVerifier {

    private int keyBits = -1;
    private int blockSize = -1;

    @SuppressWarnings("unused")
    public AgileEncryptionVerifier(String descriptor) {
        this(AgileEncryptionInfoBuilder.parseDescriptor(descriptor));
    }

    protected AgileEncryptionVerifier(EncryptionDocument ed) {
        PasswordKeyEncryptor keyData = null;
        for (KeyEncryptor ke : ed.getKeyEncryptors()) {
            keyData = ke.getPasswordKeyEncryptor();
            if (keyData != null) {
                break;
            }
        }

        if (keyData == null) {
            throw new NullPointerException("encryptedKey not set");
        }

        setCipherAlgorithm(keyData.getCipherAlgorithm());
        setKeySize(keyData.getKeyBits());

        int blockSize = keyData.getBlockSize();
        setBlockSize(blockSize);

        int hashSize = keyData.getHashSize();

        HashAlgorithm ha = keyData.getHashAlgorithm();
        setHashAlgorithm(ha);

        if (getHashAlgorithm().hashSize != hashSize) {
            throw new EncryptedDocumentException("Unsupported hash algorithm: " +
                    keyData.getHashAlgorithm() + " @ " + hashSize + " bytes");
        }

        setSpinCount(keyData.getSpinCount());
        setEncryptedVerifier(keyData.getEncryptedVerifierHashInput());
        setSalt(keyData.getSaltValue());
        setEncryptedKey(keyData.getEncryptedKeyValue());
        setEncryptedVerifierHash(keyData.getEncryptedVerifierHashValue());

        int saltSize = keyData.getSaltSize();
        if (saltSize != getSalt().length) {
            throw new EncryptedDocumentException("Invalid salt size");
        }

        setChainingMode(keyData.getCipherChaining());
        if (keyData.getCipherChaining() != ChainingMode.cbc && keyData.getCipherChaining() != ChainingMode.cfb) {
            throw new EncryptedDocumentException("Unsupported chaining mode - "+ keyData.getCipherChaining());
        }
    }

    public AgileEncryptionVerifier(CipherAlgorithm cipherAlgorithm, HashAlgorithm hashAlgorithm, int keyBits, int blockSize, ChainingMode chainingMode) {
        setCipherAlgorithm(cipherAlgorithm);
        setHashAlgorithm(hashAlgorithm);
        setChainingMode(chainingMode);
        setKeySize(keyBits);
        setBlockSize(blockSize);
        setSpinCount(100000); // TODO: use parameter
    }

    public AgileEncryptionVerifier(AgileEncryptionVerifier other) {
        super(other);
        keyBits = other.keyBits;
        blockSize = other.blockSize;
    }

    @Override
    public void setSalt(byte[] salt) {
        if (salt == null || salt.length != getCipherAlgorithm().blockSize) {
            throw new EncryptedDocumentException("invalid verifier salt");
        }
        super.setSalt(salt);
    }

    // make method visible for this package
    @Override
    public void setEncryptedVerifier(byte[] encryptedVerifier) {
        super.setEncryptedVerifier(encryptedVerifier);
    }

    // make method visible for this package
    @Override
    public void setEncryptedVerifierHash(byte[] encryptedVerifierHash) {
        super.setEncryptedVerifierHash(encryptedVerifierHash);
    }

    // make method visible for this package
    @Override
    public void setEncryptedKey(byte[] encryptedKey) {
        super.setEncryptedKey(encryptedKey);
    }

    @Override
    public AgileEncryptionVerifier copy() {
        return new AgileEncryptionVerifier(this);
    }


    /**
     * The keysize (in bits) of the verifier data. This usually equals the keysize of the header,
     * but only on a few exceptions, like files generated by Office for Mac, can be
     * different.
     *
     * @return the keysize (in bits) of the verifier.
     */
    public int getKeySize() {
        return keyBits;
    }


    /**
     * The blockSize (in bytes) of the verifier data.
     * This usually equals the blocksize of the header.
     *
     * @return the blockSize (in bytes) of the verifier,
     */
    public int getBlockSize() {
        return blockSize;
    }

    /**
     * Sets the keysize (in bits) of the verifier
     *
     * @param keyBits the keysize (in bits)
     */
    public void setKeySize(int keyBits) {
        this.keyBits = keyBits;
        for (int allowedBits : getCipherAlgorithm().allowedKeySize) {
            if (allowedBits == keyBits) {
                return;
            }
        }
        throw new EncryptedDocumentException("KeySize "+keyBits+" not allowed for cipher "+getCipherAlgorithm());
    }


    /**
     * Sets the blockSize (in bytes) of the verifier
     *
     * @param blockSize the blockSize (in bytes)
     */
    public void setBlockSize(int blockSize) {
        this.blockSize = blockSize;
    }

    @Override
    public final void setCipherAlgorithm(CipherAlgorithm cipherAlgorithm) {
        super.setCipherAlgorithm(cipherAlgorithm);
        if (cipherAlgorithm.allowedKeySize.length == 1) {
            setKeySize(cipherAlgorithm.defaultKeySize);
        }
    }
}
