/**
 * 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.
 */

/*
 * XSEC
 *
 * TXFMCipher := Class that performs encryption and decryption transforms
 *
 * $Id$
 *
 */

// XSEC

#include <xsec/framework/XSECDefs.hpp>
#include <xsec/transformers/TXFMCipher.hpp>
#include <xsec/utils/XSECPlatformUtils.hpp>
#include <xsec/framework/XSECException.hpp>

XERCES_CPP_NAMESPACE_USE

TXFMCipher::TXFMCipher(DOMDocument *doc, 
					   const XSECCryptoKey * key,
					   bool encrypt,
                       XSECCryptoSymmetricKey::SymmetricKeyMode mode,
                       unsigned int taglen) : 
TXFMBase(doc),
m_doEncrypt(encrypt),
m_taglen(taglen),
mp_cipher(NULL),
m_remaining(0) {

    if (key && key->getKeyType() == XSECCryptoKey::KEY_SYMMETRIC)
	    mp_cipher = key->clone();
	
	if (!mp_cipher) {
		throw XSECException(XSECException::CryptoProviderError, 
				"Error cloning key, or not a symmetric key");
	}

	m_complete = false;

	try {
		if (m_doEncrypt)
			((XSECCryptoSymmetricKey *) (mp_cipher))->encryptInit((mode != XSECCryptoSymmetricKey::MODE_GCM), mode);
		else
			((XSECCryptoSymmetricKey *) (mp_cipher))->decryptInit((mode != XSECCryptoSymmetricKey::MODE_GCM), mode);
	}
	catch (...) {
		delete mp_cipher;
		mp_cipher = NULL;
		throw;
	}

};

TXFMCipher::~TXFMCipher() {

		delete mp_cipher;

};

	// Methods to set the inputs

void TXFMCipher::setInput(TXFMBase *newInput) {

	input = newInput;

	// Set up for comments
	keepComments = input->getCommentsStatus();

}

	// Methods to get tranform output type and input requirement

TXFMBase::ioType TXFMCipher::getInputType(void) const {

	return TXFMBase::BYTE_STREAM;

}
TXFMBase::ioType TXFMCipher::getOutputType(void) const {

	return TXFMBase::BYTE_STREAM;

}


TXFMBase::nodeType TXFMCipher::getNodeType(void) const {

	return TXFMBase::DOM_NODE_NONE;

}

// Methods to get output data

unsigned int TXFMCipher::readBytes(XMLByte * const toFill, unsigned int maxToFill) {
	
	unsigned int ret, fill, leftToFill;

	ret = 0;					// How much have we copied?
	leftToFill = maxToFill;		// Still have to copy in entire thing

	while (ret != maxToFill && (m_complete == false || m_remaining > 0)) {
	
		if (m_remaining != 0) {

			// Copy anything remaining in the buffer to the output

			fill = (leftToFill > m_remaining ? m_remaining : leftToFill);
			memcpy(&toFill[ret], m_outputBuffer, fill);

			if (fill < m_remaining)
				memmove(m_outputBuffer, m_outputBuffer + fill, (m_remaining - fill));

			m_remaining -= fill;
			leftToFill -= fill;
			ret += fill;
		}

		// Now do some crypting

		if (m_complete == false && m_remaining == 0) {

			unsigned int sz = input->readBytes(m_inputBuffer, 2048);
		
			XSECCryptoSymmetricKey * symCipher = 
				(XSECCryptoSymmetricKey*) mp_cipher;
			if (m_doEncrypt) {
					
				if (sz == 0) {
					m_complete = true;
					m_remaining = symCipher->encryptFinish(m_outputBuffer, 3072, m_taglen);
				}
				else
					m_remaining = symCipher->encrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
			}
			else {

				if (sz == 0) {
					m_complete = true;
					m_remaining = symCipher->decryptFinish(m_outputBuffer, 3072);
				}
				else
					m_remaining = symCipher->decrypt(m_inputBuffer, m_outputBuffer, sz, 3072);
			}
		}

	}

	return ret;

}
