diff -r 000000000000 -r 164170e6151a pkiutilities/PKCS12/CrBer/Src/crber.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkiutilities/PKCS12/CrBer/Src/crber.cpp Tue Jan 26 15:20:08 2010 +0200 @@ -0,0 +1,1735 @@ +/* +* Copyright (c) 2000, 2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: This module contains the implementation of CCrBer class. +* +*/ + + + +// INCLUDE FILES +#include "crber.h" +#include // Pow + + +// ----------------------------------------------------------------------------- +// CCrBer +// Constructor +// This function constructs CCrBer object +// ----------------------------------------------------------------------------- +CCrBer::CCrBer(TInt aLevel /* = 0 */) + { + TReal size = 0; + + Math::Pow(size, 256, sizeof(TUint)); + iMaxUint = STATIC_CAST(TUint, size - 1); + + Math::Pow(size, 128, sizeof(TInt)); + iMaxInt = STATIC_CAST(TInt, size - 1); + + + iEOCBytes[0] = 0x00; + iEOCBytes[1] = 0x00; + + iType = KBerUnknown; + + iIndefinite = EFalse; + + iObjectBegin = 0; + iContentBegin = 0; + iContentLen = 0; + iObjectLen = 0; + + iLevel = aLevel; + + iData = NULL; + } + +// ----------------------------------------------------------------------------- +// CCrBer +// Destructor +// This function destructs CCrBer object +// ----------------------------------------------------------------------------- +EXPORT_C CCrBer::~CCrBer() + { + iData = NULL; + iInt.Close(); + } + +// ----------------------------------------------------------------------------- +// CCrBer::ConstructL +// This function initializes CCrBer object's member objects. +// ----------------------------------------------------------------------------- +TAny CCrBer::ConstructL() + { + } +// ----------------------------------------------------------------------------- +// CCrBer::NewLC +// ----------------------------------------------------------------------------- +EXPORT_C CCrBer* CCrBer::NewLC(TInt aLevel /* = 0 */) + { + CCrBer* self = new (ELeave) CCrBer(aLevel); + CleanupStack::PushL(self); + + self->ConstructL(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CCrBer::NewL +// ----------------------------------------------------------------------------- +EXPORT_C CCrBer* CCrBer::NewL(TInt aLevel /* = 0 */) + { + CCrBer* self = NewLC(aLevel); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CCrBer::Read +// Read next BER encoded object from the current position of +// given CCrData to this object. Return the type of the BER +// object, or KBerUnknown, if not of any known type. Only pointer +// to aData is stored into this object, so Get* functions are +// meaningful only if original data object is still existing, +// when these functions are used. +// ----------------------------------------------------------------------------- +EXPORT_C TUint8 CCrBer::Read(CCrData* aData) + { + if ((iType = ReadType(aData)) != KBerUnknown) + { + TInt move; + TInt pos = 0; + TBool conLenKnown; + + + // If type is known, this object begins right here, + // well, to be exact, one byte before this point. + if ((aData->Seek(ESeekCurrent, pos)) == KErrNone) + { + conLenKnown = ETrue; + + // Now we have at least something sensible. Store pointer to + // the data object (and hope that the caller doesn't delete it :) + iData = aData; + + iObjectBegin = pos - 1; + + // Read length. + iContentLen = ReadLen(aData, iIndefinite, &iLenLen); + + // Content begins right after type tag and length bytes. + iContentBegin = pos + iLenLen; + + // If length is indefinite and type isn't set, sequence, + // or explicit/implicit constructed, find next end-of-content + // tag to define exact length. + if (iIndefinite) + { + if ((iType != KBerSeq) && + (iType != KBerSet) && + (iType != KBerImplicitConstructed) && + (iType != KBerExplicitConstructed)) + { + // Give special treatment to constructed encoding. + if ((iType & KBerConstructedBit) || + (iType & KBerImplicitConstructed)) + { + iContentLen = OpenConstructedEncodingWithTagL( + aData, *this); + + } + else + { + iContentLen = FindEndOfContent(aData); + } + } + else + { + // We really can't know what the length is, + // until we open up the whole inner content. + conLenKnown = EFalse; + } + } + + // Now, if we know content length, then we can calculate whole + // object's length; it is tag + length bytes + content length. + if (conLenKnown) + { + SetObjectLen(); + + // Also move data pointer at the end of this object, except + // if object was set or sequence, in which case don't move, + // because we still have to open inner items. + // At indefinite case this is already done (other than + // sequence or set) or this can't be done (sequence or + // set). So, if not indefinite and not sequence or set, + // move data pointer the amount of content length. + if (!(iIndefinite) && !(IsSeqOrSet(iType))) + { + move = iContentLen; + + aData->Seek(ESeekCurrent, move); + } + } + + // If tag was end-of-content tag, check that also length + // was 0 and not indefinite, this guarantees that we really + // have an end-of-content tag (00 00). + if (iType == KBerEndOfContent) + { + if ((iContentLen != 0) || (iIndefinite)) + { + iType = KBerUnknown; + } + } + } + + + + } + return iType; + } + + + +// ----------------------------------------------------------------------------- +// CCrBer::ReadType +// Read type tag from current position in given CCrData. +// Returns type tag or KBerUnknown, if not of any known type. +// ----------------------------------------------------------------------------- +EXPORT_C TUint8 CCrBer::ReadType(CCrData* aData) + { + TBuf8<1> byte; + TUint8 type = KBerUnknown; // By default we are pessimists. + + // Read type. + if ((aData != 0) && + (aData->Read(byte, 1) == KErrNone) && + (byte.Length() > 0)) + { + type = byte[0]; + + if (!IsKnownType(type)) + { + // Don't let type to be whatever byte happened to be + // at that place. Set it to unknown, which we all know. + type = KBerUnknown; + } + } + + return type; + } + +// ----------------------------------------------------------------------------- +// CCrBer::ReadLen +// Read length tags from current position in given CCrData. +// Returns length. If length is indefinite, aIndefinite is set +// to true, otherwise to false. In indefinite case length is 0. +// Also sets amount of length bytes in aLenLen, if given. +// ----------------------------------------------------------------------------- +EXPORT_C TUint CCrBer::ReadLen( + CCrData* aData, + TBool& aIndefinite, + TUint8* aLenLen/* = 0 */) + { + TBuf8 bytes; + TUint8 byte = 0; + TUint len = 0; + + // Originally assume that length is definite, + aIndefinite = EFalse; + + // First byte tells if the length bytes are in short or in long form. + if ((aData != 0) && (aData->Read(bytes, 1) == KErrNone)) + { + if (bytes.Length() <= 0) + { + User::Leave(KErrArgument); + } + byte = bytes[0]; + + // We have at least one length byte. + if (aLenLen != 0) + { + *aLenLen = 1; + } + + if (byte & KBerLongLengthBit) + { + // We have length bytes, but how many? + TUint8 lenBytes = (TUint8)(byte & ~KBerLongLengthBit); + + // If length is in long form, but there are zero + // length bytes, then length is indefinite. + if (lenBytes == 0) + { + aIndefinite = ETrue; + } + else + { + if (aLenLen != 0) + { + // Add amount of actual length bytes to one, + // which was for long length form byte. + for (TInt i = 0; i < lenBytes; i++) + { + (*aLenLen)++; + } + } + + // Otherwise we have to interpret length bytes and + // move the result into len variable. First check + // that there aren't more bytes than fits to + // unsigned integer, we don't want any troubles here. + if (lenBytes > sizeof(TUint)) + { + // Return max uint, caller can then decide + // what to do with this huge pile of... + return iMaxUint; + } + + // Read length bytes + if (aData->Read(bytes, lenBytes) == KErrNone) + { + TUint8 i; + + // and move them to len. + for (i = 0; i < lenBytes; i++) + { + len = len << 8; + + len += bytes[i]; + } + } + } + } + else + { + // Otherwise length was in short form and length + // byte alone tells us the length of the contens. + len = byte; + } + } + + return len; + } + + +// ----------------------------------------------------------------------------- +// CCrBer::IsKnownType +// Returns true if given BER tag is identified one. +// Returns: ETrue of EFalse. +// ----------------------------------------------------------------------------- +EXPORT_C TBool CCrBer::IsKnownType(TBerTag aTag) + { + TBool isKnown = EFalse; + + // Remove constructed bit, if it is on without other upper byte tags. + if ((aTag & 0xF0) == KBerConstructedBit) + { + aTag &= ~KBerConstructedBit; + } + + // Remove implicit/explicit constructed bit, + // if it is on without other upper byte tags. + if ((aTag & 0xF0) == KBerImplicitConstructed) + { + aTag &= ~KBerImplicitConstructed; + } + + switch (aTag) + { + case KBerEndOfContent: + case KBerBoolean: + case KBerInteger: + case KBerBitString: + case KBerOctetString: + case KBerNull: + case KBerOid: + case KBerNumS: + case KBerPrS: + case KBerT61S: + case KBerVideoS: + case KBerIA5S: + case KBerUtc: + case KBerGenTime: + case KBerGraphS: + case KBerVisibleS: + case KBerGeneralS: + case KBerBmpS: + case KBerSeq: + case KBerSet: + case KBerImplicitConstructed: + // Same as KBerExplicitConstructed + case KBerImplicit: + // Same as KBerExplicit + { + isKnown = ETrue; + break; + } + default: + { + isKnown = EFalse; + break; + } + } + + return isKnown; + } + + + +// ----------------------------------------------------------------------------- +// CCrBer::IsSeqOrSet +// Returns true if given BER tag is set, sequence, +// implicit contructed, or explicit constructed tag. +// ----------------------------------------------------------------------------- +EXPORT_C TBool CCrBer::IsSeqOrSet(TBerTag aTag) + { + TBool isSeqOrSet = EFalse; + + if ((aTag == KBerSeq) || + (aTag == KBerSet) || + (aTag == KBerImplicit) || + (aTag == KBerExplicit) || + (aTag == KBerImplicitConstructed) || + (aTag == KBerExplicitConstructed)) + + { + isSeqOrSet = ETrue; + } + + return isSeqOrSet; + } + +// ----------------------------------------------------------------------------- +// CCrBer::FindEndOfContent +// Finds next end-of-content (00 00) tag from given data. +// Returns the distance between current place and the tag, +// or 0, if not found. Moves data pointer to the next byte +// _after_ the tag, i.e. two bytes longer than you might +// except from the return value. +// ----------------------------------------------------------------------------- +EXPORT_C TUint CCrBer::FindEndOfContent(CCrData* aData) + { + TBool go = ETrue; + TInt bufferOffset = 0; + TInt dataOffset = 0; + TInt move = 0; + + TBuf8 bytes; + + if (aData == 0) + { + return dataOffset; + } + + // Read buffer of data. Go on, if there is something to go with. + while ((aData->Read(bytes, KReadBufMax) == KErrNone) && + (bytes.Length() != 0) && go) + { + TBuf8<2> EOCBytes; + + EOCBytes.Append(iEOCBytes[0]); + EOCBytes.Append(iEOCBytes[1]); + + // Try to find end-of-content tag. + bufferOffset = bytes.Find(EOCBytes); + + // If found, move data pointer right _after_ + // the place of founded tag, and break. + if (bufferOffset != KErrNotFound) + { + move = bufferOffset - + bytes.Length() + + EOCBytes.Length(); + + aData->Seek(ESeekCurrent, move); + + dataOffset += bufferOffset; + + go = EFalse; //break; + } + else + { + // Otherwise keep searching. First check that the last + // character of the buffer isn't 00. If it is, move the + // data pointer one byte backwards to prevent us from + // missing end-of-content tag, if it is divided between + // buffers. + if (bytes[bytes.Length() - 1] == KBerEndOfContent) + { + move = -1; + + aData->Seek(ESeekCurrent, move); + + dataOffset--; + } + + dataOffset += bytes.Length(); + } + } + + // If nothing was found, move data pointer back + // to where it was and return 0. + if (bytes.Length() == 0) + { + dataOffset = -dataOffset; + + aData->Seek(ESeekCurrent, dataOffset); + + dataOffset = 0; + } + + return dataOffset; + } + +// ----------------------------------------------------------------------------- +// CCrBer::OpenConstructedEncodingL +// Open constructed encoding from this object. +// Parameters: aTarget; target for contentbytes. +// Return Values: Number of objects in this contructed object. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::OpenConstructedEncodingL(CCrData& aTarget) + { + TInt err = KErrNone; + TInt count = 0; + TInt offset = iContentBegin; + TInt objectNum = 0; + TInt type = Type(); + CCrBer* object = NULL; + + if (type <= KBerConstructed) // not valid type + { + User::Leave(KErrArgument); + } + else + { + type -= KBerConstructed; // type what we are looking for + } + + CCrBerSet* newSet = CCrBerSet::NewL(1); + CleanupStack::PushL(newSet); + iData->Seek(ESeekStart, offset); // seek right place; content begin + newSet->OpenL(iData, KOpenAllLevels); + count = newSet->Count(); + + HBufC8* obj = NULL; // buffer for CCrBer-objects + + for (objectNum = 0; (objectNum < count); objectNum++) + { + object = newSet->At(objectNum); // select object + + if (object->Type() == type) + { + obj = HBufC8::NewLC(object->ContentLen()); + TPtr8 pObj = obj->Des(); + + err = iData->Read(object->ContentBegin(), pObj, object->ContentLen()); + + if (err < KErrNone) // if error -> leave + { + CleanupStack::PopAndDestroy(2); // delete newSet, obj; + User::Leave(err); + } + err = aTarget.Write(pObj); // write content to CCrData + + CleanupStack::PopAndDestroy(); // delete obj; + obj = NULL; + + if (err < KErrNone) // if error -> leave + { + CleanupStack::PopAndDestroy(); // delete newSet; + User::Leave(err); + } + + } + else + { + count = objectNum; + } + } + CleanupStack::PopAndDestroy(); // delete newSet; + + return count; + } + +// ----------------------------------------------------------------------------- +// CCrBer::OpenConstructedEncodingWithTagL +// Open constructed encoding with given tag from given data. +// Add all founded octets into the parameter string, if given. +// Return amount of bytes read. +// ----------------------------------------------------------------------------- +EXPORT_C TUint CCrBer::OpenConstructedEncodingWithTagL( + CCrData* aData, + CCrBer& parentObj, + HBufC8* aBuf /* = 0 */) + { + TInt read = 0; + CCrBer temp; + TBerTag parentTag = KBerUnknown; + TBerTag tempTag = KBerUnknown; + HBufC8* tempBuf = NULL; + + parentTag = parentObj.Type(); + + // Check given object. It should have constructed tag. + if (parentTag & KBerConstructedBit) + { + TUint len = 0; + TUint totalLen = iMaxUint; + TBool isIndefinite = parentObj.Indefinite(); + + TBufC8<4> buf = _L8("Test"); + TPtr8 ptr = buf.Des(); + + if (aBuf != 0) + { + ptr = aBuf->Des(); + } + + tempBuf = HBufC8::NewLC(KReadBufMax); + + // After that we know that object either contains length or + // it is indefinite. Set max int to len even in the case of + // indefinite length to prevent this loop from going on forever. + if (!isIndefinite) + { + totalLen = parentObj.ContentLen(); + } + + while (len < totalLen) + { + // Read objects one by one, calculate content lengths together, + // add contents to target buffer, if given, and calculate also + // total object lengths together to know when stop. In indefinite + // case stop when end-of-content tag found. + temp.Read(aData); + + tempTag = temp.Type(); + + if ((tempTag == KBerEndOfContent) || + (tempTag == KBerUnknown) || + (!(tempTag & parentTag))) + { + CleanupStack::PopAndDestroy(); // delete tempBuf; + return read; // break + } + + len += temp.ObjectLen(); + read += temp.ContentLen(); + + if (aBuf != 0) + { + // Resize buffer, if needed, and append data to it. + if (aBuf->Length() < read) + { + // It is impossible to know how long buffer should be, + // but add some extra space, so reallocation won't occur + // each time. + aBuf->ReAllocL(read + (read / 5)); + ptr = aBuf->Des(); + } + + temp.Content(tempBuf); + ptr.Append(*tempBuf); + } + } + + CleanupStack::PopAndDestroy(); // delete tempBuf; + } + + return read; + } + + + +// ----------------------------------------------------------------------------- +// CCrBer::Type +// Get type of the object. +// ----------------------------------------------------------------------------- +EXPORT_C TBerTag CCrBer::Type() + { + return iType; + } + +// ----------------------------------------------------------------------------- +// CCrBer::Value +// Get value of the object. Used in encoding. +// ----------------------------------------------------------------------------- +TInt CCrBer::Value() + { + return iValue; + } +// ----------------------------------------------------------------------------- +// CCrBer::GetBigInt +// ----------------------------------------------------------------------------- +RInteger CCrBer::GetBigInt() + { + return iInt; + } + +// ----------------------------------------------------------------------------- +// CCrBer::SetValue +// Set value of the object. +// ----------------------------------------------------------------------------- +TAny CCrBer::SetValue(TInt aInt) + { + iValue = aInt; + } + +// ----------------------------------------------------------------------------- +// CCrBer::ValuePtr +// Get valuePtr of the object. (encoding) +// ----------------------------------------------------------------------------- +TDesC8* CCrBer::ValuePtr() + { + return iValuePtr; + } + +// ----------------------------------------------------------------------------- +// CCrBer::LenLen +// Get amount of length bytes. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::LenLen() + { + return iLenLen; + } + +// ----------------------------------------------------------------------------- +// CCrBer::ObjectBegin +// Return begin of the whole object. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::ObjectBegin() + { + return iObjectBegin; + } + +// ----------------------------------------------------------------------------- +// CCrBer::ContentBegin +// Return begin of the content. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::ContentBegin() + { + return iContentBegin; + } + +// ----------------------------------------------------------------------------- +// CCrBer::ObjectLen +// Get length of the whole object. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::ObjectLen() + { + return iObjectLen; + } + +// ----------------------------------------------------------------------------- +// CCrBer::ContentLen +// Get length of the content. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::ContentLen() + { + return iContentLen; + } + +// ----------------------------------------------------------------------------- +// CCrBer::Indefinite +// Returns true if this object is indefinite length. +// ----------------------------------------------------------------------------- +EXPORT_C TBool CCrBer::Indefinite() + { + return iIndefinite; + } + +// ----------------------------------------------------------------------------- +// CCrBer::Data +// Return pointer to data object. +// ----------------------------------------------------------------------------- +EXPORT_C CCrData* CCrBer::Data() + { + return iData; + } + +// ----------------------------------------------------------------------------- +// CCrBer::Object +// Return whole BER object with tag and stuff. For implementation +// reasons ObjectL returns only max 255 bytes of data. +// ----------------------------------------------------------------------------- + +EXPORT_C TInt CCrBer::Object(HBufC8* aBuf) + { + return BufferL(aBuf, iData, iObjectBegin, iObjectLen); + } + +// ----------------------------------------------------------------------------- +// CCrBer::Object +// Return whole BER object with tag and stuff. For implementation +// reasons ObjectL returns only max 255 bytes of data. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::ObjectL(HBufC* aBuf) + { + TUint8 len = 255; + + + if (iObjectLen < 255) + { + len = (TUint8)iObjectLen; + } + + return BufferL(aBuf, iData, iObjectBegin, len); + } + +// ----------------------------------------------------------------------------- +// CCrBer::Content +// Return content of this object. For implementation reasons +// ContentL returns only max 255 bytes of data. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::Content(HBufC8* aBuf) + { + return BufferL(aBuf, iData, iContentBegin, iContentLen); + } + +// ----------------------------------------------------------------------------- +// CCrBer::ContentL +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::ContentL(HBufC* aBuf) + { + TUint8 len = 255; + + if (iContentLen < 255) + { + len = (TUint8)iContentLen; + } + + return BufferL(aBuf, iData, iContentBegin, len); + } + +// ----------------------------------------------------------------------------- +// CCrBer::BufferL +// Read aAmount of data starting from begin to the buffer. +// Return amount of data read. For implementation reasons +// BufferL can be used only to read max 256 bytes of data. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::BufferL( + HBufC8* aBuf, + CCrData* aData, + TUint aBegin /* = 0 */, + TUint aAmount /* = KReadBufMax */) + { + TInt pos = 0; + TInt begin = aBegin; + TInt amount = aAmount; + TInt read = 0; + + if ((aBuf == 0) || (aData == 0)) + { + // Don't bother to continue. + return read; + } + + // Store current position, + if ((aData->Seek(ESeekCurrent, pos)) != KErrNone) + { + // Don't bother to continue. + return read; + } + + // Set data pointer to wanted position. + if (aData->Seek(ESeekStart, begin) == KErrNone) + { + // Resize buffer, if needed, and read data. + if (aBuf->Length() < amount) + { + aBuf->ReAllocL(amount); + } + + TPtr8 ptr = aBuf->Des(); + + if (aData->Read(ptr, amount) == KErrNone) + { + read = aBuf->Length(); + } + } + + // Put data pointer back to previous position. + aData->Seek(ESeekStart, pos); + + return read; + } + +EXPORT_C TInt CCrBer::BufferL( + HBufC* aBuf, + CCrData* aData, + TUint aBegin /* = 0 */, + TUint8 aAmount /* = 255 */) + { + TInt index = 0; + TInt len = 0; + TInt amount = NULL; + TBuf<255> buf; + HBufC8* heapBuf = NULL; + + heapBuf = HBufC8::NewLC(255); + + amount = BufferL(heapBuf, aData, aBegin, aAmount); + + len = heapBuf->Length(); + + for (index = 0; index < len; index++) + { + buf.Append((*heapBuf)[index]); + } + + *aBuf = buf; + + CleanupStack::PopAndDestroy(); // delete heapBuf; + // heapBuf = NULL; + + return amount; + } + + +// ----------------------------------------------------------------------------- +// CCrBer::Level +// Return nesting level of this object. +// ----------------------------------------------------------------------------- +EXPORT_C TUint CCrBer::Level() + { + return iLevel; + } + +// ----------------------------------------------------------------------------- +// CCrBer::SetLevel +// Set nesting level of this object. +// ----------------------------------------------------------------------------- +EXPORT_C TUint CCrBer::SetLevel(TUint aLevel) + { + iLevel = aLevel; + + return iLevel; + } + +// ----------------------------------------------------------------------------- +// CCrBer::AddToContentLen +// Add given integer to content length of this object. +// ----------------------------------------------------------------------------- +EXPORT_C TAny CCrBer::AddToContentLen(TInt iLen) + { + iContentLen += iLen; + } + +// ----------------------------------------------------------------------------- +// CCrBer::SetObjectLen +// Calculate object length from tag, length's length, and +// content's length. Used to 'close' indefinite objects, meaning +// that their end-of-contents tag is finally found, so their +// length can be calculated. +// ----------------------------------------------------------------------------- +EXPORT_C TAny CCrBer::SetObjectLen() + { + // Objects length is tag len (always 1) + length byte + // amount + content length. + iObjectLen = 1 + iLenLen + iContentLen; + + // If object was of indefinite length, there are + // two additional end-of-contents bytes at the end. + if (iIndefinite) + { + iObjectLen += 2; + } + } + +// ----------------------------------------------------------------------------- +// CCrBer::SetObjLenWithOutContent +// Parameters: Content length. +// ----------------------------------------------------------------------------- +TAny CCrBer::SetObjLenWithOutContent(TUint aContentLen) + { + iObjectLen = KBerShortLen; // Tag + len + if (aContentLen >= KBerLongLengthBit) + { + while (aContentLen > 0) + { + aContentLen >>= 8; // Next byte + iObjectLen++; + } + } + } + +// ----------------------------------------------------------------------------- +// Get content functions. +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// CCrBer::GetBooleanL +// Returns value of Boolean object. +// ----------------------------------------------------------------------------- +EXPORT_C TBool CCrBer::GetBooleanL() + { + TInt err = KErrNone; + TASN1DecBoolean dec; // ASN1 lib (Symbian) + TInt pos = NULL; + TBool ret = EFalse; + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + + TPtr8 ptr = buf->Des(); + + err = iData->Read(iObjectBegin,ptr,iObjectLen); // Read object + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// CCrBer::GetIntegerL +// Returns value of Integer object. +// ----------------------------------------------------------------------------- +EXPORT_C TInt CCrBer::GetIntegerL() + { + TInt err = KErrNone; + TASN1DecInteger dec; // ASN1 lib (Symbian) + TInt pos = NULL; + TInt ret = NULL; + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + + TPtr8 ptr = buf->Des(); + + err = iData->Read(iObjectBegin,ptr,iObjectLen); // Read object + + if (err == KErrNone) + { + ret = dec.DecodeDERShortL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// CCrBer::GetIntegerL +// Returns value of Long Integer object. +// ----------------------------------------------------------------------------- +EXPORT_C RInteger CCrBer::GetLongIntegerL() + { + TInt err = KErrNone; + TInt pos = NULL; + TASN1DecInteger dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + + TPtr8 ptr = buf->Des(); + RInteger value; + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + value = dec.DecodeDERLongL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return value; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetOidL +// Returns value of object identifier. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetOidL() + { + TInt err = KErrNone; + TInt pos = NULL; + HBufC* ret = NULL; + TASN1DecObjectIdentifier dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC8* CCrBer::GetOctetStringL +// Returns value of octet string. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC8* CCrBer::GetOctetStringL() + { + TInt pos = NULL; + HBufC8* ret = NULL; + TInt err = KErrNone; + TASN1DecOctetString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(buf); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(buf); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC8* CCrBer::GetOctetStringL +// Returns value of octet string. +// ----------------------------------------------------------------------------- +EXPORT_C TAny CCrBer::GetOctetStringL(CCrData& Trg) + { + TUint pos = iContentBegin; + TUint end = iContentBegin + iContentLen; + TInt err = KErrNone; + TInt len = KBufSize; + HBufC8* buf = HBufC8::NewL(KBufSize); // buffer to object + CleanupStack::PushL(buf); + + TPtr8 ptr = buf->Des(); + // Read object to buf + while (pos < end) + { + len = end - pos; + + if (len > KBufSize) + { + len = KBufSize; + } + + err = iData->Read(pos, ptr, len); + + if (err == KErrNone) + { + Trg.Write(ptr); + } + if (err < KErrNone) + { + CleanupStack::PopAndDestroy(); + // buf = NULL; + User::Leave(err); + } + pos += KBufSize; + } + CleanupStack::PopAndDestroy(); // buf + } + +// ----------------------------------------------------------------------------- +// HBufC8* CCrBer::GetContentStringLC +// Note buf is left to CleanupStack. +// Returns value of content string. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC8* CCrBer::GetContentStringLC() + { + HBufC8* buf = HBufC8::NewL(iContentLen); // buffer to Content + CleanupStack::PushL(buf); + + TPtr8 ptr = buf->Des(); + + // Read object to buf + iData->Read(iContentBegin, ptr, iContentLen); + + return buf; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetIA5StringL +// Returns value of IA5 string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetIA5StringL() + { + TInt err = KErrNone; + TInt pos = NULL; + HBufC* ret = NULL; + TASN1DecIA5String dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// TTime CCrBer::GetUTCTimeL +// Returns value of UTC time object. +// ----------------------------------------------------------------------------- +EXPORT_C TTime CCrBer::GetUTCTimeL() + { + TInt err = KErrNone; + TInt pos = NULL; + TTime ret = TTime(0); + TASN1DecUTCTime dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + + + +// ----------------------------------------------------------------------------- +// TTime CCrBer::GetGeneralizedTimeL +// Returns value of generalised time object. +// ----------------------------------------------------------------------------- +EXPORT_C TTime CCrBer::GetGeneralizedTimeL() + { + TInt err = KErrNone; + TInt pos = NULL; + TTime ret = TTime(0); + TASN1DecGeneralizedTime dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetPrintStringL +// Returns value of printable string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetPrintStringL() + { + HBufC* ret = NULL; + TInt err = KErrNone; + TInt pos = NULL; + TASN1DecPrintableString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetTeletextStringL +// Returns value of teletext string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetTeletextStringL() + { + TInt err = KErrNone; + TInt pos = NULL; + HBufC* ret = NULL; + TASN1DecTeletexString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + + + +// ----------------------------------------------------------------------------- +// HBufC8* CCrBer::GetSequence +// Returns value of segunce object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC8* CCrBer::GetSequenceL() + { + TInt err = KErrNone; + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(ContentBegin(),ptr,ContentLen()); + + if (err < KErrNone) + { + CleanupStack::PopAndDestroy(); // delete buf; + // buf = NULL; + User::Leave(err); + } + CleanupStack::PopAndDestroy(); // delete buf; + // buf = NULL; + + return ptr.AllocL(); + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetVideoString +// Returns value of video string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetVideoStringL() + { + TInt err = KErrNone; + HBufC* ret = NULL; + TInt pos = NULL; + TASN1DecVideotexString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetGeneralString +// Returns value of general string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetGeneralStringL() + { + TInt err = KErrNone; + TInt pos = NULL; + HBufC* ret = NULL; + TASN1DecGeneralString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetVisibleStringL +// Returns value of visible string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetVisibleStringL() + { + TInt err = KErrNone; + HBufC* ret = NULL; + TInt pos = NULL; + TASN1DecVisibleString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetGraphicsStringL +// Returns value of graphical string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetGraphicsStringL() + { + TInt err = KErrNone; + HBufC* ret = NULL; + TInt pos = NULL; + TASN1DecGraphicString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + + + +// ----------------------------------------------------------------------------- +// HBufC* CCrBer::GetNumericStringL +// Returns value of numeric string object. +// ----------------------------------------------------------------------------- +EXPORT_C HBufC* CCrBer::GetNumericStringL() + { + TInt err = KErrNone; + HBufC* ret = NULL; + TInt pos = NULL; + TASN1DecNumericString dec; // ASN1 lib (Symbian) + + HBufC8* buf = HBufC8::NewLC(iObjectLen); // buffer to object + TPtr8 ptr = buf->Des(); + + // Read object to buf + err = iData->Read(iObjectBegin,ptr,iObjectLen); + + if (err == KErrNone) + { + ret = dec.DecodeDERL(ptr, pos); // decode object + } + else + { + CleanupStack::PopAndDestroy(); // delete buf; + User::Leave(err); + } + + CleanupStack::PopAndDestroy(); // delete buf; + + return ret; + } + +// ----------------------------------------------------------------------------- +// Encoding +// ----------------------------------------------------------------------------- + +// ----------------------------------------------------------------------------- +// CCrBer::CreateBool +// Paremeters: Value of the boolean object. True or False. +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateBool(TBool aBool) + { + iType = KBerBoolean; + iObjectLen = KBerBooleanLen; // Boolean object len is always 3 + iValue = aBool; + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateInt +// Paremeters: Value of the object (positive, null or negative) +// e.g. 234 or 0xFFF or -45676. +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateInt(TInt aInt) + { + iType = KBerInteger; + iValue = aInt; + + // Find out object len. Tag + len + value. + if (aInt == 0 || (aInt > (-0x81) && aInt < 0x80 )) + iObjectLen = 0x03; + + else if (aInt > (-0x8001) && aInt < 0x8000) + iObjectLen = 0x04; + + else if (aInt > (-0x800001) && aInt < 0x800000) + iObjectLen = 0x05; + + else + iObjectLen = 0x06; + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateInt +// Paremeters: Value of the object (positive, null or negative) +// e.g. 234 or 0xFFF or -45676. +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateLongInt(RInteger& aData) + { + TInt len = aData.ByteCount(); + iType = KBerInteger; + iValue = NULL; + iInt = RInteger::NewL(aData); + + iObjectLen = KBerShortLen + len; // Tag + len(lenlen) + string + + if (len >= KBerLongLengthBit) + { + while (len > NULL) // add number of lenbytes + { + len >>= KOctetWidth; // Next byte + iObjectLen++; + } + } + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateNull +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateNull() + { + iType = KBerNull; // Tag + iObjectLen = KBerNullLen; // 05 00 + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateOId +// Paremeters: Pointer to string. e.g.(1.2.43.4335.242) +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateOIdL(TDesC8* aString) + { + CCrBerSet* set = CCrBerSet::NewLC(1); + TInt len = set->AppendObjectIdL(*aString, ETrue);// ask Oid content len + iType = KBerOid; + iValuePtr = aString; + + iObjectLen = (len > NULL) ? KBerShortLen + len : 0; // tag + len + content + + CleanupStack::PopAndDestroy(); // delete set; + // set = NULL; + } + + + +// ----------------------------------------------------------------------------- +// CCrBer::CreateString +// Paremeters: Type of object and pointer to string. +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateString(TBerTag aTag, TDesC8* aString) + { + TInt len = aString->Length(); + iType = aTag; + iValuePtr = aString; + iObjectLen = KBerShortLen + len; // Tag + len(lenlen) + string + + if (len >= KBerLongLengthBit) + { + while (len > NULL) // add number of lenbytes + { + len >>= KOctetWidth; // Next byte + iObjectLen++; + } + } + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateString +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateString(TBerTag aTag, CCrData* aData) + { + TInt len = 0; + aData->Size(len); + iType = aTag; + iData = aData; + iObjectLen = KBerShortLen + len; // Tag + len(lenlen) + string + + if (len >= KBerLongLengthBit) + { + while (len > NULL) // add number of lenbytes + { + len >>= KOctetWidth; // Next byte + iObjectLen++; + } + } + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateStart +// Paremeters: First parameter is tag type (e.g. seq). Second param is +// True if definite length is wanted. +// False if indefinite (xx 80) . +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateStart(TBerTag aTag, TBool aDefinite) + { + iType = aTag; + + // Definite object length = 0 (set rigth length later). + // Indefinite object length is always 4 (Tag + 80 + 00 + 00) + if (!aDefinite) + { + iObjectLen = KBerIndefiniteLen; + } + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateEnd +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateEnd() + { + iType = KBerEndOfContent; // =0x00 + iValue = KBerEndOfContent; + } + +// ----------------------------------------------------------------------------- +// CCrBer::CreateBEREncodedObject +// This fuction can be used to create a BER object +// from buffer, which already contains a full BER +// encoded object. +// Paremeters: Buffer containing BER encoded object. +// ----------------------------------------------------------------------------- +TAny CCrBer::CreateBEREncodedObject(TDesC8* aBuffer) + { + iType = KBerEncodedObject; + iValuePtr = aBuffer; + iObjectLen = aBuffer->Length(); + } + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// --------------------------------------------------------- +// E32Dll +// DLL entry point +// --------------------------------------------------------- +// +#ifndef EKA2 +GLDEF_C TInt E32Dll(TDllReason /*aReason*/) + { + return KErrNone; + } +#endif