pkiutilities/PKCS12/CrBer/Src/crber.cpp
changeset 0 164170e6151a
--- /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 <e32math.h>    // 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<LEN_BYTES_MAX> 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<KReadBufMax> 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