#include "cryptoki.h"
#include "SlotList.h"
#include "Pkcs11Exceptions.h"
#include "P15CDF.h"
#include "Communicator.h"
#include "ObjList.h"
#include "CertificateObject.h"
#include "CertificateObjectCERES.h"

//CertificateObject *m_asn1CDF;

extern SCARDCONTEXT g_hContext;
extern CSlotList &g_rSlotList;

extern CObjList gListaObjetos;

CP15CDF::CP15CDF(CSlot &slot):CP15File(slot)
{
	CP15CDF();
}

CP15CDF::CP15CDF(void)
{
	// Inicializamos las variables miembro
	m_loaded	= false;
	m_ushFileId	= 0x6004;
}

CP15CDF::~CP15CDF(void)
{
}


// Método para codificar una cadena de bytes y convertirla a formato ASN1
int CP15CDF::EncodeASN1( CPKCS11Object *pObj11, byteBuffer & efEncoded )
{
	bool bObjAttrib		 = 0;

	byteBuffer *bbAttribute = NULL;
	byteBuffer bbAux;

	asn_enc_rval_t ret_val;

	unsigned long ulEncodedCertLen = 1024;
	byte *bEncodedCert = new (byte[ulEncodedCertLen]);

	memset(bEncodedCert, 0x00, ulEncodedCertLen);

	int * index		= NULL;
	int * iFileLen	= NULL;

	CertificateObject		* pCertASN1Object	   = NULL;
	CertificateObjectCERES  * pCertASN1ObjectCeres = NULL;

	// Diferenciaremos si la escritura debe ser en formato ISO o CERES
	//if(m_asn1Type == ASN1TYPE_ISO)
	if(GetASN1Type() == ASN1TYPE_ISO)
	{
		// Codificación ASN1 ISO
		pCertASN1Object = (CertificateObject*)calloc(1,sizeof(CertificateObject));

		// Atributos comunes de todos los objetos P11
		// CKA_CLASS
		// CKA_TOKEN
		pCertASN1Object->commonObjectAttributes.flags = (CommonObjectFlags_t*)calloc(1,sizeof(CommonObjectFlags_t));
		pCertASN1Object->commonObjectAttributes.flags->buf = (uint8_t*)calloc(1,sizeof(uint8_t));
		pCertASN1Object->commonObjectAttributes.flags->size = 1;

		// CKA_PRIVATE
		// flags->private
		bObjAttrib = pObj11->GetAttributeBool( CKA_PRIVATE );
		CUtil::SetBit( pCertASN1Object->commonObjectAttributes.flags, CommonObjectFlags_private, bObjAttrib );

		// CKA_MODIFIABLE
		// flags->modifiable
		bObjAttrib = pObj11->GetAttributeBool( CKA_MODIFIABLE );
		CUtil::SetBit( pCertASN1Object->commonObjectAttributes.flags, CommonObjectFlags_modifiable, bObjAttrib );

		// flags->bits_unused
		pCertASN1Object->commonObjectAttributes.flags->bits_unused = 0x06;

		// CKA_LABEL
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_LABEL );

		pCertASN1Object->commonObjectAttributes.label = (LabelCERES*)calloc(1,sizeof(LabelCERES));
		pCertASN1Object->commonObjectAttributes.label->present = LabelCERES_PR_tipoutf8string; //LabelCERES_PR_tipot61string
		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			//pCertASN1Object->commonObjectAttributes.label = (LabelCERES*)calloc(1,sizeof(LabelCERES));
			pCertASN1Object->commonObjectAttributes.label->choice.tipoutf8string.size = bbAttribute->size();
			pCertASN1Object->commonObjectAttributes.label->choice.tipoutf8string.buf = (byte *)malloc( bbAttribute->size() );
			memset( pCertASN1Object->commonObjectAttributes.label->choice.tipoutf8string.buf, 0,
					bbAttribute->size());
			memcpy( pCertASN1Object->commonObjectAttributes.label->choice.tipoutf8string.buf, bbAttribute[0],
					bbAttribute->size());
			pCertASN1Object->commonObjectAttributes.label->present = LabelCERES_PR_tipoutf8string; //LabelCERES_PR_tipot61string
		}

		// CKA_ID
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_ID );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			pCertASN1Object->classAttributes.iD.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1Object->classAttributes.iD.size = bbAttribute->size();

			memset( pCertASN1Object->classAttributes.iD.buf, 0, bbAttribute->size());
			memcpy( pCertASN1Object->classAttributes.iD.buf, bbAttribute[0], bbAttribute->size());
		}

		// CKA_SUBJECT
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_SUBJECT );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			pCertASN1Object->typeAttributes.subject.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1Object->typeAttributes.subject.size = bbAttribute->size();

			memset( pCertASN1Object->typeAttributes.subject.buf, 0, bbAttribute->size());
			memcpy( pCertASN1Object->typeAttributes.subject.buf, bbAttribute[0], bbAttribute->size());
		}

		// CKA_ISSUER
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_ISSUER );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			//pCertASN1Object->typeAttributes.issuer = (OCTET_STRING*)calloc(1,sizeof(OCTET_STRING));
			pCertASN1Object->typeAttributes.issuer.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1Object->typeAttributes.issuer.size = bbAttribute->size();

			memset( pCertASN1Object->typeAttributes.issuer.buf, 0, bbAttribute->size());
			memcpy( pCertASN1Object->typeAttributes.issuer.buf, bbAttribute[0], bbAttribute->size());
		}

		// CKA_SERIAL_NUMBER
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_SERIAL_NUMBER );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			//pCertASN1Object->typeAttributes.serialNumber = (OCTET_STRING*)calloc(1,sizeof(OCTET_STRING));
			pCertASN1Object->typeAttributes.serialNumber.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1Object->typeAttributes.serialNumber.size = bbAttribute->size();

			memset( pCertASN1Object->typeAttributes.serialNumber.buf, 0, bbAttribute->size());
			memcpy( pCertASN1Object->typeAttributes.serialNumber.buf, bbAttribute[0], bbAttribute->size());
		}

		// Value--> Path
		bbAttribute = NULL;
		bbAttribute = pObj11->GetValuePath();

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			// Si estamos trabajando sobre formatos de Path en ASCII,
			// habrá que hacer la conversión en bbAttribute.
			if( GetPathEncodingType() == PATHENC_BIN )
				// Mantenemos el formato BINARIO (ej: 0x60 0x61 0x70 0x04)
				bbAux.assign(&bbAttribute->at(0), bbAttribute->size());
			else
				// Hacemos la conversión a format ASCII (ej: "\6061\7004")
				bbAux = CUtil::PathBin2ASCII(bbAttribute[0]);

			pCertASN1Object->typeAttributes.value.path.buf = (byte *)malloc( bbAux.size() );
			pCertASN1Object->typeAttributes.value.path.size = bbAux.size();

			memset( pCertASN1Object->typeAttributes.value.path.buf, 0, bbAux.size());
			memcpy( pCertASN1Object->typeAttributes.value.path.buf, &bbAux[0], bbAux.size());
		}

		// Value--> index
		index = pObj11->GetValueIndex();
		if(index != NULL)
		{
			pCertASN1Object->typeAttributes.value.index = (INTEGER_t*)calloc(1,sizeof(INTEGER_t));
			pCertASN1Object->typeAttributes.value.index->buf = (byte *)malloc( 1 );
			pCertASN1Object->typeAttributes.value.index->size = 1;

			memset( pCertASN1Object->typeAttributes.value.index->buf, 0, 1);
			memcpy( pCertASN1Object->typeAttributes.value.index->buf, index, 1);
		}

		// Value--> length
		iFileLen = pObj11->GetValueLength();
		if(iFileLen != NULL)
		{
			bbAux.clear();
			bbAux.append(iFileLen[0]>>8);
			bbAux.append(iFileLen[0]%0x100);

			pCertASN1Object->typeAttributes.value.length = (INTEGER_t*)calloc(1,sizeof(INTEGER_t));
			pCertASN1Object->typeAttributes.value.length->buf = (byte *)malloc( 2 );
			pCertASN1Object->typeAttributes.value.length->size = 2;

			memset( pCertASN1Object->typeAttributes.value.length->buf, 0, 2);
			memcpy( pCertASN1Object->typeAttributes.value.length->buf, bbAux, bbAux.size());
		}

		// Codificamos los atributos del objeto P11 a parsear
		ret_val = der_encode_to_buffer(&asn_DEF_CertificateObject, pCertASN1Object, bEncodedCert, ulEncodedCertLen);

		// Liberamos la estructura anterior
		asn_DEF_CertificateObject.free_struct( &asn_DEF_CertificateObject, pCertASN1Object, 0 );
	}
	else
	{
		// Codificación ASN1 CERES
		pCertASN1ObjectCeres = (CertificateObjectCERES*)calloc(1,sizeof(CertificateObjectCERES));

		// Atributos comunes de todos los objetos P11
		// CKA_CLASS
		// CKA_TOKEN

		// CKA_LABEL
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_LABEL );

		pCertASN1ObjectCeres->commonObjectAttributes.label = (LabelCERES*)calloc(1,sizeof(LabelCERES));
		pCertASN1ObjectCeres->commonObjectAttributes.label->present = LabelCERES_PR_tipot61string; //LabelCERES_PR_tipot61string
		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			pCertASN1ObjectCeres->commonObjectAttributes.label->choice.tipot61string.size = bbAttribute->size();
			pCertASN1ObjectCeres->commonObjectAttributes.label->choice.tipot61string.buf = (byte *)malloc( bbAttribute->size() );
			memset( pCertASN1ObjectCeres->commonObjectAttributes.label->choice.tipot61string.buf, 0, bbAttribute->size());
			memcpy( pCertASN1ObjectCeres->commonObjectAttributes.label->choice.tipot61string.buf, bbAttribute[0], bbAttribute->size());
		}

		// flags:
		pCertASN1ObjectCeres->commonObjectAttributes.flags = (CommonObjectFlags_t*)calloc(1,sizeof(CommonObjectFlags_t));
		pCertASN1ObjectCeres->commonObjectAttributes.flags->buf = (uint8_t*)calloc(1,sizeof(uint8_t));
		pCertASN1ObjectCeres->commonObjectAttributes.flags->size = 1;

		// CKA_PRIVATE
		// flags->private
		bObjAttrib = pObj11->GetAttributeBool( CKA_PRIVATE );
		CUtil::SetBit( pCertASN1ObjectCeres->commonObjectAttributes.flags, CommonObjectFlags_private, bObjAttrib );

		// CKA_MODIFIABLE
		// flags->modifiable
		bObjAttrib = pObj11->GetAttributeBool( CKA_MODIFIABLE );
		CUtil::SetBit( pCertASN1ObjectCeres->commonObjectAttributes.flags, CommonObjectFlags_modifiable, bObjAttrib );

		// flags->bits_unused
		pCertASN1ObjectCeres->commonObjectAttributes.flags->bits_unused = 0x06;

		// CKA_ID
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_ID );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			pCertASN1ObjectCeres->classAttributes.iD.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1ObjectCeres->classAttributes.iD.size = bbAttribute->size();

			memset( pCertASN1ObjectCeres->classAttributes.iD.buf, 0, bbAttribute->size());
			memcpy( pCertASN1ObjectCeres->classAttributes.iD.buf, bbAttribute[0], bbAttribute->size());
		}

		// Value--> Path
		bbAttribute = NULL;
		bbAttribute = pObj11->GetValuePath();
		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			if( GetPathEncodingType() == PATHENC_BIN )
				// Mantenemos el formato BINARIO (ej: 0x60 0x61 0x70 0x04)
				bbAux.assign(&bbAttribute->at(0), bbAttribute->size());
			else
				// Hacemos la conversión a format ASCII (ej: "\6061\7004")
				bbAux = CUtil::PathBin2ASCII(bbAttribute[0]);

			pCertASN1ObjectCeres->typeAttributes.value.path.buf = (byte *)malloc( bbAux.size() );
			pCertASN1ObjectCeres->typeAttributes.value.path.size = bbAux.size();

			memset( pCertASN1ObjectCeres->typeAttributes.value.path.buf, 0, bbAux.size());
			memcpy( pCertASN1ObjectCeres->typeAttributes.value.path.buf, &bbAux[0], bbAux.size());
		}

		// Value--> index
		index = pObj11->GetValueIndex();
		if(index != NULL)
		{
			pCertASN1ObjectCeres->typeAttributes.value.index = (INTEGER_t*)calloc(1,sizeof(INTEGER_t));
			pCertASN1ObjectCeres->typeAttributes.value.index->buf = (byte *)malloc( 1 );
			pCertASN1ObjectCeres->typeAttributes.value.index->size = 1;

			memset( pCertASN1ObjectCeres->typeAttributes.value.index->buf, 0, 1);
			memcpy( pCertASN1ObjectCeres->typeAttributes.value.index->buf, index, 1);
		}

		// Value--> length
		iFileLen = pObj11->GetValueLength();
		if(iFileLen != NULL)
		{
			bbAux.clear();
			bbAux.append(iFileLen[0]>>8);
			bbAux.append(iFileLen[0]%0x100);

			pCertASN1ObjectCeres->typeAttributes.value.length = (INTEGER_t*)calloc(1,sizeof(INTEGER_t));
			pCertASN1ObjectCeres->typeAttributes.value.length->buf = (byte *)malloc( 2 );
			pCertASN1ObjectCeres->typeAttributes.value.length->size = 2;

			memset( pCertASN1ObjectCeres->typeAttributes.value.length->buf, 0, 2);
			memcpy( pCertASN1ObjectCeres->typeAttributes.value.length->buf, bbAux, bbAux.size());
		}

		// CKA_ISSUER
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_ISSUER );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			//pCertASN1ObjectCeres->typeAttributes.issuer = (OCTET_STRING*)calloc(1,sizeof(OCTET_STRING));
			pCertASN1ObjectCeres->typeAttributes.issuer.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1ObjectCeres->typeAttributes.issuer.size = bbAttribute->size();

			memset( pCertASN1ObjectCeres->typeAttributes.issuer.buf, 0, bbAttribute->size());
			memcpy( pCertASN1ObjectCeres->typeAttributes.issuer.buf, bbAttribute[0], bbAttribute->size());
		}

		// CKA_SUBJECT
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_SUBJECT );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			pCertASN1ObjectCeres->typeAttributes.subject.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1ObjectCeres->typeAttributes.subject.size = bbAttribute->size();

			memset( pCertASN1ObjectCeres->typeAttributes.subject.buf, 0, bbAttribute->size());
			memcpy( pCertASN1ObjectCeres->typeAttributes.subject.buf, bbAttribute[0], bbAttribute->size());
		}

		// CKA_SERIAL_NUMBER
		bbAttribute = NULL;
		bbAttribute = pObj11->GetAttribute( CKA_SERIAL_NUMBER );

		if(( bbAttribute != 0 ) && ( bbAttribute->size() != 0 ))
		{
			//pCertASN1ObjectCeres->typeAttributes.serialNumber = (OCTET_STRING*)calloc(1,sizeof(OCTET_STRING));
			pCertASN1ObjectCeres->typeAttributes.serialNumber.buf  = (byte *)malloc( bbAttribute->size() );
			pCertASN1ObjectCeres->typeAttributes.serialNumber.size = bbAttribute->size();

			memset( pCertASN1ObjectCeres->typeAttributes.serialNumber.buf, 0, bbAttribute->size());
			memcpy( pCertASN1ObjectCeres->typeAttributes.serialNumber.buf, bbAttribute[0], bbAttribute->size());
		}

		// Codificamos los atributos del objeto P11 a parsear
		ret_val = der_encode_to_buffer(&asn_DEF_CertificateObjectCERES, pCertASN1ObjectCeres, bEncodedCert, ulEncodedCertLen);

		// Liberamos la estructura anterior
		asn_DEF_CertificateObjectCERES.free_struct( &asn_DEF_CertificateObjectCERES, pCertASN1ObjectCeres, 0 );
	}

	// Comprobamos el resultado del parseo
	if(ret_val.encoded == -1)
	{
		// Liberamos la memoria reservada
		if(bEncodedCert)
			delete(bEncodedCert);

		// Ha ocurrido algún error
		//return ret_val.encoded;
		return RC_FAIL;
	}

	// Una vez realizado el parseo copiamos la respuesta a devolver
	efEncoded.resize(ret_val.encoded);
	efEncoded.assign(bEncodedCert, ret_val.encoded);

	// Liberamos la memoria reservada
	if(bEncodedCert)
		delete(bEncodedCert);

	return RC_OK;
}


int CP15CDF::DecodeObject( byteBuffer & cdfEntry )
{
	// Variables locales
	int nRet = 0;
	asn_dec_rval_t ret_val;
	CertificateObject		* asn1CDF	   = NULL;
	CertificateObjectCERES  * asn1CDFCeres = NULL;

	CPKCS11CertificateObject * pCertificateObject = NULL;

	// Realizamos la decodificación BER de los datos miembros
	ret_val = ber_decode( NULL,
						  &asn_DEF_CertificateObject,
						  (void**)&asn1CDF,
						  (void*)&cdfEntry[0],
						  cdfEntry.size() );

	// Si la decodificación ha ido bien, rellenamos los campos de la estructura pInfo
	if( ret_val.code == RC_OK )
	{
		// Dejaremos indicado que la codificación de este fichero es tipo ISO
		//m_asn1Type = ASN1TYPE_ISO;
		SetASN1Type(ASN1TYPE_ISO);

		pCertificateObject = new CPKCS11CertificateObject();

		// Atributos comunes de todos los objetos P11
		pCertificateObject->SetAttribute( CKA_PRIVATE,
										  CUtil::GetBit( asn1CDF->commonObjectAttributes.flags, CommonObjectFlags_private ) );
		pCertificateObject->SetAttribute( CKA_MODIFIABLE,
										  CUtil::GetBit( asn1CDF->commonObjectAttributes.flags, CommonObjectFlags_modifiable ) );
		if(asn1CDF->commonObjectAttributes.label)
		{
			pCertificateObject->SetAttribute( CKA_LABEL,
											  asn1CDF->commonObjectAttributes.label->choice.tipot61string.buf,
											  asn1CDF->commonObjectAttributes.label->choice.tipot61string.size );
		}

		// Atributos de certificados X.509
		pCertificateObject->SetAttribute( CKA_CERTIFICATE_TYPE, (ulong)CKC_X_509 );
		pCertificateObject->SetAttribute( CKA_SUBJECT,
										  asn1CDF->typeAttributes.subject.buf,
										  asn1CDF->typeAttributes.subject.size );
		pCertificateObject->SetAttribute( CKA_ID,
									      asn1CDF->classAttributes.iD.buf,
										  asn1CDF->classAttributes.iD.size );
		pCertificateObject->SetAttribute( CKA_ISSUER,
										  asn1CDF->typeAttributes.issuer.buf,
										  asn1CDF->typeAttributes.issuer.size );
		pCertificateObject->SetAttribute( CKA_SERIAL_NUMBER,
										  asn1CDF->typeAttributes.serialNumber.buf,
										  asn1CDF->typeAttributes.serialNumber.size );

		if(asn1CDF->typeAttributes.value.path.size > 4)
			SetPathEncodingType(PATHENC_ASCII);

		pCertificateObject->SetValuePath( asn1CDF->typeAttributes.value.path.buf,
										  asn1CDF->typeAttributes.value.path.size,
										  CUtil::GetInt32( asn1CDF->typeAttributes.value.index ),
										  CUtil::GetInt32( (INTEGER_t *)asn1CDF->typeAttributes.value.length ) );

		m_P11Objects.push_back( pCertificateObject );
		if( asn1CDF )
		{
			asn_DEF_CertificateObject.free_struct( &asn_DEF_CertificateObject, asn1CDF, 0 );
			asn1CDF = NULL;
		}

		// Fin del parseo PKCS#15 estándar
		return 1;
	}

	if(asn1CDF)
	{
		// Liberamos la estructura anterior
		asn_DEF_CertificateObject.free_struct( &asn_DEF_CertificateObject, asn1CDF, 0 );
		asn1CDF = NULL;
	}

	// Una vez realizado el cambio intentaremos parsear de nuevo el CDF y la estructura Ceres
	ret_val = ber_decode( NULL,
						  &asn_DEF_CertificateObjectCERES,
						  (void**)&asn1CDFCeres,
						  (void*)&cdfEntry[0],
						  cdfEntry.size() );

	// Si la decodificación ha ido bien, rellenamos los campos de la estructura pInfo
	if( ret_val.code == RC_OK )
	{
		// Dejaremos indicado que la codificación de este fichero es tipo CERES
		//m_asn1Type = ASN1TYPE_CERES;
		SetASN1Type(ASN1TYPE_CERES);

		pCertificateObject = new CPKCS11CertificateObject();

		// Atributos comunes de todos los objetos P11
		pCertificateObject->SetAttribute( CKA_PRIVATE,
										  CUtil::GetBit( asn1CDFCeres->commonObjectAttributes.flags, CommonObjectFlags_private ) );
		pCertificateObject->SetAttribute( CKA_MODIFIABLE,
										  CUtil::GetBit( asn1CDFCeres->commonObjectAttributes.flags, CommonObjectFlags_modifiable ) );
		if(asn1CDFCeres->commonObjectAttributes.label)
		{
			pCertificateObject->SetAttribute( CKA_LABEL,
											  asn1CDFCeres->commonObjectAttributes.label->choice.tipot61string.buf,
											  asn1CDFCeres->commonObjectAttributes.label->choice.tipot61string.size );
		}

		// Atributos de certificados X.509
		pCertificateObject->SetAttribute( CKA_CERTIFICATE_TYPE, (ulong)CKC_X_509 );
		pCertificateObject->SetAttribute( CKA_SUBJECT,
										  asn1CDFCeres->typeAttributes.subject.buf,
										  asn1CDFCeres->typeAttributes.subject.size );
		pCertificateObject->SetAttribute( CKA_ID,
									      asn1CDFCeres->classAttributes.iD.buf,
										  asn1CDFCeres->classAttributes.iD.size );
		pCertificateObject->SetAttribute( CKA_ISSUER,
										  asn1CDFCeres->typeAttributes.issuer.buf,
										  asn1CDFCeres->typeAttributes.issuer.size );
		pCertificateObject->SetAttribute( CKA_SERIAL_NUMBER,
										  asn1CDFCeres->typeAttributes.serialNumber.buf,
										  asn1CDFCeres->typeAttributes.serialNumber.size );

		if(asn1CDFCeres->typeAttributes.value.path.size > 4)
			SetPathEncodingType(PATHENC_ASCII);

		pCertificateObject->SetValuePath( asn1CDFCeres->typeAttributes.value.path.buf,
										  asn1CDFCeres->typeAttributes.value.path.size,
										  CUtil::GetInt32( asn1CDFCeres->typeAttributes.value.index ),
										  CUtil::GetInt32( (INTEGER_t *)asn1CDFCeres->typeAttributes.value.length ) );

		m_P11Objects.push_back( pCertificateObject );

		// Fin del parseo PKCS#15 CERES
		nRet = 1;
	}

	if( asn1CDFCeres )
	{
		asn_DEF_CertificateObjectCERES.free_struct( &asn_DEF_CertificateObjectCERES, asn1CDFCeres, 0 );
		asn1CDFCeres = NULL;
	}

	return nRet;
}