/**
 * 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
 *
 * OpenSSLCryptoBase64 := Base virtual class to define a base64 encoder/decoder
 *
 * Author(s): Berin Lautenbach
 *
 * $ID$
 *
 * $LOG$
 *
 */

#include <xsec/framework/XSECDefs.hpp>
#if defined (XSEC_HAVE_OPENSSL)

#include <xsec/enc/OpenSSL/OpenSSLCryptoBase64.hpp>
#include <xsec/enc/XSECCryptoException.hpp>
#include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
#include <xsec/framework/XSECError.hpp>

#include <xercesc/util/Janitor.hpp>

#include <openssl/err.h>

XERCES_CPP_NAMESPACE_USE

// --------------------------------------------------------------------------------
//           Construction/Destruction
// --------------------------------------------------------------------------------

#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
OpenSSLCryptoBase64::OpenSSLCryptoBase64() : mp_ectx(&m_ectx_store), mp_dctx(&m_dctx_store) { }
OpenSSLCryptoBase64::~OpenSSLCryptoBase64() { }
#else
OpenSSLCryptoBase64::OpenSSLCryptoBase64() : mp_ectx(EVP_ENCODE_CTX_new()), mp_dctx(EVP_ENCODE_CTX_new()) {
    if (!mp_ectx || !mp_dctx)
        throw XSECCryptoException(XSECCryptoException::ECError, "OpenSSL:CrypoBase64 - cannot allocate contexts");
};
OpenSSLCryptoBase64::~OpenSSLCryptoBase64() {
    EVP_ENCODE_CTX_free(mp_ectx);
    EVP_ENCODE_CTX_free(mp_dctx);
}

#endif
// --------------------------------------------------------------------------------
//           Decoding
// --------------------------------------------------------------------------------

void OpenSSLCryptoBase64::decodeInit(void) {

	EVP_DecodeInit(mp_dctx);

}

unsigned int OpenSSLCryptoBase64::decode(const unsigned char * inData, 
						 	    unsigned int inLength,
								unsigned char * outData,
								unsigned int outLength) {

	int rc;
	int outLen;

	if (outLength < inLength) {

		throw XSECCryptoException(XSECCryptoException::MemoryError,
			"OpenSSL:Base64 - Output buffer not big enough for Base64 decode");

	}

	rc = EVP_DecodeUpdate(mp_dctx,
						  outData, 
						  &outLen, 
						  (unsigned char *) inData, 
						  inLength);

	if (rc < 0) {

		throw XSECCryptoException(XSECCryptoException::Base64Error,
			"OpenSSL:Base64 - Error during Base64 Decode");
	}

	if (outLen > (int) outLength) {

		throw XSECCryptoException(XSECCryptoException::MemoryError,
			"OpenSSL:Base64 - Output buffer not big enough for Base64 decode and overflowed");

	}
		
	return outLen;

}

unsigned int OpenSSLCryptoBase64::decodeFinish(unsigned char * outData,
							 	      unsigned int outLength) {

	int outLen;
	outLen = outLength;

	EVP_DecodeFinal(mp_dctx, outData, &outLen);

	return outLen;

}

// --------------------------------------------------------------------------------
//           Encoding
// --------------------------------------------------------------------------------

void OpenSSLCryptoBase64::encodeInit(void) {

	EVP_EncodeInit(mp_ectx);

}


unsigned int OpenSSLCryptoBase64::encode(const unsigned char * inData, 
						 	    unsigned int inLength,
								unsigned char * outData,
								unsigned int outLength) {

	int outLen;

	if (outLength + 24 < inLength) {

		throw XSECCryptoException(XSECCryptoException::MemoryError,
			"OpenSSL:Base64 - Output buffer not big enough for Base64 encode");

	}

	EVP_EncodeUpdate( mp_ectx,
					  outData, 
					 &outLen, 
					  (unsigned char *) inData, 
					  inLength);

	if (outLen > (int) outLength) {

		throw XSECCryptoException(XSECCryptoException::MemoryError,
			"OpenSSL:Base64 - Output buffer not big enough for Base64 encode and overflowed");

	}
		
	return outLen;

}

unsigned int OpenSSLCryptoBase64::encodeFinish(unsigned char * outData,
							 	      unsigned int outLength) {

	int outLen;
	outLen = outLength;

	EVP_EncodeFinal(mp_ectx, outData, &outLen); 

	return outLen;

}

// --------------------------------------------------------------------------------
//           Utility functions
// --------------------------------------------------------------------------------

BIGNUM * OpenSSLCryptoBase64::b642BN(char * b64in, unsigned int len) {

	if (len > 1024)
		return NULL;

	int bufLen;
	unsigned char buf[1024];
/*
	EVP_ENCODE_CTX m_dctx;
	EVP_DecodeInit(&m_dctx);
	int rc = EVP_DecodeUpdate(&m_dctx, 
						  buf, 
						  &bufLen, 
						  (unsigned char *) b64in, 
						  len);

	if (rc < 0) {

		throw XSECCryptoException(XSECCryptoException::Base64Error,
			"OpenSSL:Base64 - Error during Base64 Decode of BIGNUMS");
	}

	int finalLen;
	EVP_DecodeFinal(&m_dctx, &buf[bufLen], &finalLen); 

	bufLen += finalLen;
*/
	XSCryptCryptoBase64 *b64;
	XSECnew(b64, XSCryptCryptoBase64);
	Janitor<XSCryptCryptoBase64> j_b64(b64);

	b64->decodeInit();
	bufLen = b64->decode((unsigned char *) b64in, len, buf, len);
	bufLen += b64->decodeFinish(&buf[bufLen], len-bufLen);

	// Now translate to a bignum
	return BN_bin2bn(buf, bufLen, NULL);

}

#endif /* XSEC_HAVE_OPENSSL */
