pkiutilities/PKCS12/CrBer/Src/Crberset.cpp
changeset 0 164170e6151a
child 5 3b17fc5c9564
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/PKCS12/CrBer/Src/Crberset.cpp	Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,1367 @@
+/*
+* 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 CCrBerSet class. 
+*
+*/
+
+
+
+//  INCLUDE FILES
+
+#include "crber.h"
+
+
+// -----------------------------------------------------------------------------
+//CCrBerSet
+//Constructor
+// -----------------------------------------------------------------------------
+CCrBerSet::CCrBerSet(TInt aGranularity)
+    : CArrayPtrSeg<CCrBer>(aGranularity), iLevel(0)
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet
+// Destructor
+// This function destructs CCrBerSet object
+// -----------------------------------------------------------------------------
+CCrBerSet::~CCrBerSet()
+    {
+    ResetAndDestroy();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::ConstructL
+// This function initializes CCrBerSet object's member objects.
+// -----------------------------------------------------------------------------
+TAny CCrBerSet::ConstructL()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::NewLC
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBerSet* CCrBerSet::NewLC(TInt aGranularity)
+    {
+    CCrBerSet* self = new (ELeave) CCrBerSet(aGranularity);
+    CleanupStack::PushL(self);
+
+    self->ConstructL();
+
+    return self; 
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::NewL
+// -----------------------------------------------------------------------------
+EXPORT_C CCrBerSet* CCrBerSet::NewL(TInt aGranularity)
+    {
+    CCrBerSet* self = NewLC(aGranularity);
+    CleanupStack::Pop();
+
+    return self; 
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::OpenL
+// 
+// Opens next BER encoded object from the current position of
+// given CCrData to this object set. Opens also all nested BER
+// objects as deep as aRecursionLevel tells. If it is zero, one
+// object is read, if it is one, all objects at first level are
+// read, and if it is 0xff, all objects at 255 first levels are
+// extracted. This function cannot be used to extract deeper
+// structures than that, if you want to go deeper, implement
+// a function of your own. Returns the amount of extracted
+// objects. The data pointer of CCrData points right after the
+// opened BER object after this function is finished.
+// Parameters: CCrData* aData    Data object containing the BER
+//                               object to be opened.
+// Returns:    TUint             Amount of BER objects extracted.
+// -----------------------------------------------------------------------------
+EXPORT_C TUint CCrBerSet::OpenL(
+    CCrData* aData,
+    TUint8   aRecursionLevel /* = 1 */)
+    {
+    TInt    i       = 0;
+    TUint   level   = 0;
+    TUint8  amount  = 0;
+    TInt definiteObjectEnd [255]= {0};
+    TBerTag  type    = KBerEndOfContent;
+    CCrBer* newObject = 0;
+
+    while (type != KBerUnknown)
+        {
+        // Don't create new object if old is to be recycled.
+        if (newObject == 0)
+            {
+            newObject = CCrBer::NewLC(level);
+            }
+
+        // Read next BER object.
+        if ((type = newObject->Read(aData)) != KBerUnknown)
+            {                   
+            i = 0;
+            // check definite seq(e.g) end, and if so, take away 1 level. 
+            while (definiteObjectEnd[i] != 0)
+                {
+                if ((definiteObjectEnd[i]  <= newObject->ObjectLen() 
+                    + newObject->ObjectBegin()) &&
+                    (definiteObjectEnd[i]) &&
+                   !(newObject->IsSeqOrSet(type)))                                    
+                    {                
+                    level--;                
+                    definiteObjectEnd[i] = 0;
+                    }
+                i++;
+                }
+            // If type is explicit or implicit constructed or sequence
+            // or set with indefinite length, we are one level deeper.
+            if (CCrBer::IsSeqOrSet(type))
+                 {
+                if (newObject->Indefinite())
+                    {
+                    level++;
+                    }
+                else 
+                    {               
+                    level++;
+                    i = 0;
+                    while (definiteObjectEnd[i] != 0)
+                        {
+                        i++;
+                        }
+                    definiteObjectEnd[i] = newObject->ObjectLen() 
+                        + newObject->ObjectBegin();                                      
+                    }
+				// Changed by junuutin on 3.5.2004:				
+				if ((type == KBerImplicit) || (type == KBerExplicit))
+					{
+						// Don't try to parse the content of context-specified stuff
+			            // Jump to next object.
+						TInt currentPos = 0;
+						aData->Seek(ESeekCurrent, currentPos);
+                        TInt pos = currentPos + newObject->ContentLen(); 
+                        aData->Seek(ESeekStart, pos);
+                        level--;
+					} 
+				else if ((type == KBerImplicitConstructed) || (type == KBerExplicitConstructed))
+                    {
+                     TInt currentPos = 0;
+                     aData->Seek(ESeekCurrent, currentPos);
+                     CCrBer* tempObject = CCrBer::NewL();
+                     
+                     // Read next BER object.
+                     TBerTag tempType = tempObject->Read(aData);
+                     if (!(CCrBer::IsKnownType(tempType)))
+                        {
+                        // Jump to next object.
+                        TInt pos = currentPos + newObject->ContentLen(); 
+                        aData->Seek(ESeekStart, pos);
+                        level--;
+
+                        }
+                     else // return current position.
+                         {
+                         aData->Seek(ESeekStart, currentPos);
+                         }
+
+                    delete tempObject;
+                    tempObject = NULL;
+                    } 
+                } 
+
+            // If type is end-of-content tag, last constructed object,
+            // sequence or set with indefinite length has ended, we
+            // are one level lower.
+            if (type == KBerEndOfContent)
+                {
+                level--;
+
+                // Also set new object's level to current,
+                // because that's where it actually belongs.
+                newObject->SetLevel(level);
+            
+            
+                // Close last sequence or set.
+                CloseLastSeqOrSet(level);
+                }
+
+            // If it is of known type, append object to this set,
+            // null the pointer and continue to look for next objects.
+            // Append only if wanted recursion level not exceeded.
+            if ((level <= aRecursionLevel) || (aRecursionLevel == 255))
+                {
+                AppendAndUpdateL(newObject);
+                CleanupStack::Pop(); //newObject
+                newObject = NULL;
+                }
+            else
+                {
+                // Anyway previous open objects have to be
+                // updated with the length of this object.
+                Update(newObject);
+                }
+
+            // Anyway we have one item more.
+            
+            amount++;
+            }
+        else
+            {
+            // Otherwise delete object and stop the whole thing.
+            // Don't return those bloody errors, because we cannot
+            // know what the caller was looking for, let him evaluate
+            // the results and decide whether this was a failure or not.
+            //delete newObject;
+            CleanupStack::PopAndDestroy();
+
+            // go to return 
+            type = KBerUnknown;         
+            }
+        }
+
+    return amount;
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendAndUpdateL
+// Appends given new object into this set. Updates all previous
+// items in this set, which have indefinite length, with the
+// length of the new object.
+// Parameters: CCrBer* aBerObject    New BER object to be added to this set
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::AppendAndUpdateL(CCrBer* aBerObject)
+    {
+    Update(aBerObject);
+
+    AppendL(aBerObject);
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::Update
+// Updates all previous items in this set, which have
+// indefinite length, with the length of the new object.
+// Parameters: CCrBer* aBerObject    New BER object with whom
+//                                   this set is updated.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::Update(CCrBer* aBerObject)
+    {
+    TInt  add = 0;
+    TInt  index = 0;
+    TInt  size = 0;
+    TUint berObjectLevel = 0; 
+
+    CCrBer* obj;
+
+    if (aBerObject == 0)
+        {
+        return;
+        }
+
+    // Loop backwards through set and append length of the new object
+    // to the lengths of each found upper constructed, sequence or set
+    // objects with indefinite lengths, until first 'closed' from upper
+    // level found.
+
+    // Use object length, unless this is an object, whose total length is
+    // not yet known. In that case use tag length (always 1) combined with
+    // the amount of the length bytes.
+    if ((add = aBerObject->ObjectLen()) == 0)
+        {
+        add = 1 + aBerObject->LenLen();
+
+        // If new object is of indefinite length, still
+        // add two more bytes for the end-of-content tag.
+        if (aBerObject->Indefinite())
+            {
+            add += 2;
+            }
+        }
+
+    berObjectLevel = aBerObject->Level();
+
+    size = Count();
+
+    for (index = size - 1; index >= 0; index--)
+        {
+        obj = At(index);
+
+        if ((obj != 0) &&
+            (obj->Level() < berObjectLevel) &&
+            (obj->Indefinite()))
+            {
+            if ((obj->Type() == KBerSeq) ||
+                (obj->Type() == KBerSet) ||
+                (obj->Type() == KBerImplicitConstructed) ||
+                (obj->Type() == KBerExplicitConstructed))
+                {
+                if (obj->ObjectLen() == 0)
+                    {
+                    obj->AddToContentLen(add);
+                    }
+                else
+                    {
+                    index = -1;                 // break;
+                    }
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CloseLastSeqOrSet
+// Finds last open indefinite length sequence
+// or set from this set at given level and closes it.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CloseLastSeqOrSet(TUint aLevel)
+    {
+    TInt    index = 0;
+    TInt    size  = 0;
+    TBerTag type  = KBerUnknown;
+
+    CCrBer* obj = NULL;
+
+    // Loop backwards through set and find first sequence or set with
+    // indefinite length at same level. 'Close' it by setting its object
+    // length.
+    size = Count();
+
+    for (index = size - 1; index >= 0; index--)
+        {
+        obj = At(index);
+
+        if ((obj != 0) &&
+            (obj->Level() == aLevel) &&
+            (obj->Indefinite()))
+            {
+            type = obj->Type();
+
+            if ((type == KBerSeq) ||
+                (type == KBerSet) ||
+                (type == KBerImplicitConstructed) ||
+                (type == KBerExplicitConstructed))
+                {
+                obj->SetObjectLen();
+
+                // Update upper objects with closed object.
+                Update(obj);
+
+                index = -1;             // break;
+                }
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+//  Encoding
+// -----------------------------------------------------------------------------
+    
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendBool
+// Write boolean object to CCrData.
+// Parameters:     Boolean value. ETrue or EFalse ( 0 / 1 ).
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendBoolL(TBool aBool)
+    {
+    TInt err = KErrNone;
+    TBuf8<1> value;
+
+    if (aBool)           
+        {
+        value.Append(KBerBooleanTrue);            
+        }
+    else                  
+        {
+        value.Append(KBerBooleanFalse);
+        }
+
+    err = AppendStringL(KBerBoolean, value);                       
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendInt
+// Write integer (0x02) object to CCrData. Parameter is either
+// a positive whole number, or a negative whole number, or zero.
+// value : from - 0xFFFFFFF to +0xFFF FFFF
+// Parameters:     Integer value e.g. 1024 or 0xABC. 
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendIntL(TInt aData)
+    {
+    TInt err = KErrNone;
+    TBuf8<8> indexBuf;
+    TUint len   = 0;
+ 
+    HBufC8* buf = NULL;
+    
+    buf = HBufC8::NewLC(KIntBufSize);
+    TPtr8 data  = buf->Des();
+              
+    if (aData >= 0)
+        { 
+        if (aData >= KBerLongLengthBit)
+            {      
+            while (aData > 0)                    
+                {
+                TInt8 byte;
+                byte = TInt8(aData);        // Take byte
+                indexBuf.Append(byte);      // and add it to indexBuf   
+                aData >>= KOctetWidth;      // Next byte
+                len++;                 
+                }       
+            if (indexBuf[len-1] >= KBerLongLengthBit)   // if high order bit=1
+                {
+                indexBuf.Append(0);         // e.g. content 00 FF no FF 
+                len++;                      // (FF = neg num)
+                }
+            }
+        else                                // only one byte
+            {
+            indexBuf.Append(aData);         // so add directly
+            len++;
+            }
+        }
+   
+    else
+        {
+        aData = -(aData + 1);               // convert to positive
+
+        while ((aData > 0) || (len < 1))    // (len < 1) because -1 -> 0 ->FF            
+            {
+            TInt8 byte;
+            byte = TInt8(aData);            // Take byte
+            indexBuf.Append(~byte);         // and add complement to buf
+            aData >>= KOctetWidth;          // Next byte
+            len++;                 
+            }
+        if (indexBuf[len-1] < KBerLongLengthBit) // if high order bit=0
+                {
+                indexBuf.Append(0xFF);  
+                len++;                  
+                }
+        }
+
+    for (TInt i=len ; i > 0 ; i--)
+        {
+        data.Append(indexBuf[i - 1]);       // add data to buffer
+        }
+
+    err = AppendStringL(KBerInteger, data);        // write data to file
+    
+    CleanupStack::PopAndDestroy();
+    buf = NULL;
+
+    return err;
+    }
+
+
+
+TInt CCrBerSet::AppendLongIntL(RInteger& aData)
+    {
+    TInt err = KErrNone;
+    
+    err = AppendStringL(KBerInteger, *aData.BufferLC());
+    
+    CleanupStack::PopAndDestroy(); 
+
+    return err;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendNull
+// Write null (05 00) object to CCrData.
+// Parameters:     None
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendNull()
+    {
+    TInt err = KErrNone;
+    TBuf8<2> data;
+     
+    data.Append(KBerNull);                      // Add Null tag 05
+    data.Append(KBerNullContent);               // and null;    00
+    
+    err = iTarget->Write(data);                 // write data-buffer to CCrData 
+    
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CloseIndefinite
+// Write end of indefinite length (add 00 00) to CCrData.
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::CloseIndefinite()
+    {   
+    TInt err = KErrNone;
+    TBuf8<2> data;                  
+    data.Append(KBerEndOfContent);              // add end of indefinite length 
+    data.Append(KBerEndOfContent);              // ( 00 00 )
+    err = iTarget->Write(data);                 // write data-buffer to file
+    
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendConstructed
+// Write constructed type to CCrData.
+// Parameters:     First param is type of constructed tag
+//                 e.g. 04 for octetS.  Second parameter is length or 0 for
+//                 indefinite length. e.g. if params are 4 and 0 --> 24 00
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendConstructedL(TBerTag aTag, TUint aLength)
+    {
+    TInt err    = KErrNone;
+    HBufC8* buf = NULL; 
+    
+    buf = HBufC8::NewLC(8);
+    TPtr8 data  = buf->Des();
+
+    if (aTag < KBerConstructedBit)      // if tag not consist ConstructedBit
+        {
+        aTag += KBerConstructedBit;     // add ConstructedBit
+        }
+
+    if (aLength == KBerEndOfContent)            // indefinite length 
+        {
+        data.Append(aTag);                      // add Tag
+        data.Append(KBerLongLengthBit);         // add indefinite length
+        }
+
+    else if (aLength < KBerLongLengthBit)       // if short len
+        {
+        data.Append(aTag);                      // add Tag    
+        data.Append(aLength);                   // add len
+        }
+
+    else                                        // else we have long len
+        {
+        TBuf8<6> indexBuf;              
+        TInt lenlen = 0;                        // number of length bytes
+
+        while (aLength > 0)
+            {
+            TInt8 byte;           
+            byte = TInt8(aLength);                
+            indexBuf.Append(byte);
+            aLength >>= KOctetWidth;
+            lenlen++;
+            }
+
+        data.Append(aTag);                          // Add Tag 
+        data.Append(lenlen + KBerLongLengthBit);    // Lenlen byte
+            
+        for (TInt i = lenlen ; i > 0 ; i--)
+            {
+            data.Append(indexBuf[i - 1]);       // length bytes
+            }
+        }                                           
+        
+    err = iTarget->Write(data);                 // write to CCrData
+                  
+    CleanupStack::PopAndDestroy();
+    buf = NULL;
+
+    return err;
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendObjectId
+// Write object id object to CCrData.
+// Parameters:     Object ID. e.g. _L8("1.2.3.4.5"). Second parameter is 
+//                 true if you don't want write object to CCrData.
+// Return Values:  Error code (or length of object if aOnlyLen is true).
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendObjectIdL(const TDesC8& aString, TBool aOnlyLen)
+    {
+    TChar ch   = NULL;
+    TUint num  = 0;
+    TUint sum  = 0; 
+    TInt index = 0;
+    TInt len   = 0;
+    TInt i     = 0;
+    TInt start = 0;
+    TInt err   = KErrNone;
+    TBuf8<16> outbuf;
+
+    HBufC8* fileBuf  = NULL;
+    HBufC8* str = NULL;
+
+    fileBuf = HBufC8::NewLC(aString.Length() + 1);
+    str = aString.AllocLC();
+  
+    TPtr8 ptrFileBuf = fileBuf->Des();
+    TPtr8 strptr = str->Des();
+    
+    // Check valid ( string must start "x.z.*", x < 10 and z < 10)
+    if ((len = strptr.Locate('.')) == KObjectIDDot)            
+        { 
+        ch  = strptr[i];                            // take first number
+        num = ch.GetNumericValue();                 // convert ascii to num                     
+
+        // First byte = (first number * 40) + second number  
+        sum = num * KObjectIDFirstFactor;           // num * 4                              
+       
+        strptr.Delete(start, len + 1);              // delete 'x.'
+
+        // also second num must be smaller than 10
+        if (!((strptr.Locate('.')) == KObjectIDDot))                   
+            {
+            err = KErrArgument;
+            }
+
+        while (strptr.Length() > 0)          
+            {
+            len = strptr.Locate('.');               // Find next dot
+            
+            if (len == KErrNotFound)                // if not found: take all 
+                {
+                len = strptr.Length();              // string len
+                } 
+
+            for (i = 0; i < len; i++)               
+                {
+                ch  = strptr[i];
+                num = ch.GetNumericValue();        
+                sum = sum * KObjectIDSecondFactor + num;    // sum * 10 + num           
+                num = 0;
+                }
+       
+            strptr.Delete(start, len + 1);          // delete also dot
+
+            for (index = 0; (sum >= KBerLongLengthBit); index++)
+                {   
+                outbuf.Append(sum % KBerLongLengthBit);        // add remainder 
+                sum = (sum - outbuf[index]) / KBerLongLengthBit;// take new 
+                }
+
+            outbuf.Append(sum);
+
+            for (; index >= 0 ; index--)
+                {
+                if (!index)                      
+                    {
+                    ptrFileBuf.Append(outbuf[index]);
+                    }
+                else                        
+                    {
+                    ptrFileBuf.Append(outbuf[index] + KBerLongLengthBit);
+                    }   
+                }
+            
+            sum = 0;
+            outbuf.Delete(start, outbuf.Length());       
+            }
+        
+        if ((!aOnlyLen && ptrFileBuf.Length()) && (err == KErrNone))
+            {
+            err = AppendStringL(KBerOid, ptrFileBuf);   // write object to CCrData
+            }
+        else if (err == KErrNone)
+            {
+            len = ptrFileBuf.Length();              // return object length 
+            err = len;
+            }                                       // else return error
+        }
+    else                                            
+        {                                           
+        err = KErrArgument;                         // return argument error
+        }
+
+    CleanupStack::PopAndDestroy(2);                  // delete fileBuf, str;
+    return err;                                     // return error code
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendString
+// Write string object to CCrData.
+// Parameters:     Object type (tag) and string. e.g. (KBerIA5S, _L("Hello"))      
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendStringL(TBerTag aTag, const TDesC8& aString)
+    {
+    TInt err = KErrNone;
+    TInt len = aString.Length();
+
+    HBufC8* buf  = NULL;
+    
+    buf = HBufC8::NewLC(KBerShortLen + LEN_BYTES_MAX);
+    TPtr8   data = buf->Des();
+ 
+    if (len < KBerLongLengthBit)                    // If short len:
+        {
+        data.Append(aTag);                          // Add Tag
+        data.Append(len);                           // length 
+        }                                                  
+    else                                            // Else long
+        {
+        TBuf8<8> indexBuf;
+        TUint lenlen = 0;                           // number of len bytes
+              
+        while (len > 0)
+            {
+            TInt8 byte;                             
+            byte = TInt8(len);                      // Take byte
+            indexBuf.Append(byte);                  // append it to buf
+            len >>= KOctetWidth;                    // next byte
+            lenlen++;                                                        
+            }
+
+        data.Append(aTag);                          // Add tag
+        data.Append(lenlen + KBerLongLengthBit);    // now add lenlen byte
+                                                    // 0x80 + lenlen
+
+        for (TInt i=lenlen ; i > 0 ; i--)
+            {
+            data.Append(indexBuf[i - 1]);           // add len bytes
+            }
+
+        len = aString.Length();
+        }
+
+    err = iTarget->Write(data);                     // write buffer to file
+    err = iTarget->Write(aString);                     // write buffer to file
+                  
+    CleanupStack::PopAndDestroy();                  // delete buf;                         
+    buf = NULL;    
+
+    return err;
+    }
+ 
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendString
+// Write string object to CCrData.
+// Parameters:     Object type (tag) and CCrData      
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendStringL(TBerTag aTag, CCrData* const aData)
+    {
+    TInt err = KErrNone;
+    TInt len = 0;
+    aData->Size(len);
+
+    HBufC8* buf  = NULL;
+    buf = HBufC8::NewLC(KBerShortLen + LEN_BYTES_MAX);
+    TPtr8 data = buf->Des();
+ 
+    if (len < KBerLongLengthBit)                    // If short len:
+        {
+        data.Append(aTag);                          // Add Tag
+        data.Append(len);                           // length 
+
+        }                                                  
+    else                                            // Else long
+        {
+        TBuf8<8> indexBuf;
+        TUint lenlen = 0;                           // number of len bytes
+              
+        while (len > 0)
+            {
+            TInt8 byte;                             
+            byte = TInt8(len);                      // Take byte
+            indexBuf.Append(byte);                  // append it to buf
+            len >>= KOctetWidth;                    // next byte
+            lenlen++;                                                        
+            }
+
+        data.Append(aTag);                          // Add tag
+        data.Append(lenlen + KBerLongLengthBit);    // now add lenlen byte
+                                                    // 0x80 + lenlen
+
+        for (TInt i=lenlen ; i > 0 ; i--)
+            {
+            data.Append(indexBuf[i - 1]);           // add len bytes
+            }
+
+        aData->Size(len);
+
+        }
+
+    err = iTarget->Write(data);                     // write buffer to file
+    
+    // Write aData to iTarget
+    HBufC8* tempBuf = tempBuf = HBufC8::NewLC(KBufSize);
+    
+    // write aData to iTarget in loop.
+    TPtr8 ptr = tempBuf->Des();
+    TInt size = 0;
+    aData->Size(size);
+    TInt left = size;
+    TInt handleThisTime = 0;
+    TInt handled = 0;
+
+    while (left > 0)
+        {
+        if (left > KBufSize)
+            {
+            handleThisTime = KBufSize;
+            }
+        else
+            {
+            handleThisTime = left;
+            }
+        aData->Read(handled, ptr, handleThisTime);
+        iTarget->Write(ptr);
+        ptr.Zero();
+
+        handled = handled + handleThisTime;
+        left = size - handled;
+        }
+
+    CleanupStack::PopAndDestroy(2);
+    return err;
+    }
+ 
+// -----------------------------------------------------------------------------
+// CCrBerSet::AppendBerEncodedObject
+// Write BER encoded object to CCrData.
+// Parameters:     Buffer containing BER encoded object.      
+// Return Values:  Error code
+// -----------------------------------------------------------------------------
+TInt CCrBerSet::AppendBerEncodedObject(const TDesC8& aString)
+    {
+    TInt err = KErrNone;
+
+    err = iTarget->Write(aString); // write buffer to file
+                  
+    return err;
+    }
+ 
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateBoolL
+// Function creates Ber encoded boolean object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Value of the object
+// Return Values:  None 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateBoolL(TBool aValue)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateBool(aValue);
+    
+    AppendL(newObject);              // add to set
+    
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateIntL
+// Function creates Ber encoded integer object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Value of the object
+// Return Values:  None 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateIntL(TInt aValue)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateInt(aValue);
+    
+    AppendL(newObject);              // add to set
+    
+    CleanupStack::Pop();
+    }
+
+
+EXPORT_C TAny CCrBerSet::CreateLongIntL(RInteger& aValue)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    
+    newObject->CreateLongInt(aValue);
+    
+    AppendL(newObject);              // add to set
+    
+    CleanupStack::Pop();
+    }
+
+
+// -----------------------------------------------------------------------------        
+// CCrBerSet::CreateNullL
+// Function creates Ber encoded null object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateNullL()
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateNull();                
+    
+    AppendL(newObject);              // add to set
+    
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateIA5L
+// Function creates Ber encoded IA5 string object (CCrBer object).
+// Write a object to CCrData  by Flush(..) 
+// Parameters:     IA5 string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateIA5L(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerIA5S, &aString);
+    
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateNumericL
+// Function creates Ber encoded Numeric string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Numeric string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateNumericL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerNumS, &aString);
+        
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreatePrintableL
+// Function creates Ber encoded Printable string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Printable string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreatePrintableL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerPrS, &aString);
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateT61L
+// Function creates Ber encoded T61 string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     T61 string (= a teletext string)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateT61L(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerT61S, &aString);
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateVideoTexL
+// Function creates Ber encoded Video text object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     VideoTex string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateVideoTexL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerVideoS, &aString);
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateUTCL
+// Function creates Ber encoded UTC time object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     UTC time (string)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateUTCL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerUtc, &aString);
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateGenTimeL
+// Function creates Ber encoded generalised time object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Generalised time (string)
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateGenTimeL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerGenTime, &aString);
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateGraphicalL
+// Function creates Ber encoded graphical string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Graphical string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateGraphicalL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerGraphS, &aString);
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateVisibleL
+// Function creates Ber encoded visible string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Visible string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateVisibleL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerVisibleS, &aString);    // save type & pointer
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateGeneralL
+// Function creates Ber encoded general string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Generalised string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateGeneralL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerGeneralS, &aString);    // save type & pointer
+    AppendL(newObject);              // add to set
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateOctetL
+// Function creates Ber encoded octet string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     Octet string
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateOctetL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerOctetString, &aString); // save type & pointer
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateOctetL
+// Function creates Ber encoded octet string object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     CCrData* 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateOctetL(CCrData* aData)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateString(KBerOctetString, aData); // save type & pointer
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateOIdL
+// Function creates Ber encoded object identifier object (CCrBer object).
+// Write a object to CCrData (file) by Flush(..) 
+// Parameters:     object identifier content e.g.(_L8("1.2.3.4445"))
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateOIdL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateOIdL(&aString);         // save type and pointer to data
+
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateSeqStartL
+// Function creates start of sequence (0x30). End this by EndL().
+// Parameters:     True for definite length sequence, false for indefinite
+//                 length 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateSeqStartL(TBool aDefinite)
+    {
+    CCrBer* newObject = CCrBer::NewLC(++iLevel);
+    newObject->CreateStart(KBerSeq, aDefinite); 
+        
+    if (iLevel > iMaxLevel) 
+        {
+        iMaxLevel = iLevel;                 // iMaxLevel is used in Flush(..)
+        }
+
+    AppendL(newObject);              // add to set
+
+    CleanupStack::Pop();
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateSetStartL
+// Start set (31 xx) object. End this set by EndL(). 
+// Parameters:     Parameter is true for definite length, false for
+//                 indefinite length. 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateSetStartL(TBool aDefinite)
+    {
+    CCrBer* newObject = CCrBer::NewLC(++iLevel);
+    newObject->CreateStart(KBerSet, aDefinite);   
+        
+    if (iLevel > iMaxLevel) 
+        {
+        iMaxLevel = iLevel;                 // iMaxLevel is used in Flush(..)
+        }
+
+    AppendL(newObject);                     // add to set
+
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateConstructedStartL
+// Function creates start of constructed type object. End this by EndL(). 
+// Parameters:     First parameter is object type (tag), Second parameter is 
+//                 true for definite length, false for indefinite length. 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateConstructedStartL(TBerTag aTag, TBool aDefinite)
+    {
+    CCrBer* newObject = CCrBer::NewLC(++iLevel);
+    if (aTag < KBerConstructed)
+        {
+        aTag += KBerConstructedBit;         // e.g. 0x04 --> 0x24
+        }
+
+    newObject->CreateStart(aTag, aDefinite);   
+        
+    if (iLevel > iMaxLevel) 
+        {
+        iMaxLevel = iLevel;                 // iMaxLevel is used in Flush(..)
+        }
+    AppendL(newObject);              // add to set
+    CleanupStack::Pop();
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateEndL
+// Function close last constructed (e.g. seq) object. 
+// (definite or indefinite). 
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateEndL()
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel--);
+    newObject->CreateEnd();
+
+    AppendL(newObject);              // add to set
+    CleanupStack::Pop();
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::CreateBEREncodedObjectL
+// This fuction can be used to create a BER object
+// from buffer, which already contains a full BER
+// encoded object.
+// Parameters:     Buffer containing BER encoded object.
+// -----------------------------------------------------------------------------
+EXPORT_C TAny CCrBerSet::CreateBEREncodedObjectL(TDesC8& aString)
+    {
+    CCrBer* newObject = CCrBer::NewLC(iLevel);
+    newObject->CreateBEREncodedObject(&aString); // save pointer
+    AppendL(newObject);                          // add to set
+    CleanupStack::Pop();                         // newObject
+    }
+
+// -----------------------------------------------------------------------------
+// CCrBerSet::Flush
+// Function writes all created crber objects (which are AppendL to set)
+// to file. Function also set length for definite lengths.
+// Call this function then crberSet is ready (all berObjects are given).
+// Parameters:     Reference to target CCrData (file)
+// Return Values:  Number of written objects or error code. 
+// -----------------------------------------------------------------------------
+EXPORT_C TInt CCrBerSet::FlushL(CCrData* aTarget)
+    {
+    TInt index = 0;
+    TInt i = 0;
+    TUint level = 0;
+    TUint8 type = 0;
+    TInt err = KErrNone;
+    CCrBer* berObject = NULL;
+    CCrBer* newObject = NULL;
+    TInt size = Count();                    // number of the ber-objects
+
+    iTarget = aTarget;
+
+    if (iLevel || !size)                    // end count != start count
+        {                                   // or if no CrBer objects 
+        return KErrArgument;
+        }
+    
+    // Set definite lengths  
+    for (level = iMaxLevel; level > 0; level--)     // check levels (except 0)
+        {                                           
+        for (index = 0 ; index < size ; index++)    // all objects
+            {
+            berObject = At(index);                  
+        
+            if ((berObject->Type() >= KBerConstructed) &&   // Constructed 
+                (!berObject->ObjectLen())              &&   // definite len
+                (berObject->Level() == level))              // same level
+                {
+                for (i = index + 1; i < size; i++)
+                    {
+                    newObject = At(i);
+ 
+                    if ((newObject->Type() == KBerEndOfContent) &&
+                        (newObject->Level() == berObject->Level()) &&
+                        (newObject->Value() >= 0))
+                        {
+                        berObject->SetObjLenWithOutContent(
+                            berObject->ContentLen());
+                        newObject->SetValue(-1);    // this end is now used
+                        i = size;                   // end found, go away
+                        }
+                    else                                
+                        {
+                        berObject->AddToContentLen(newObject->ObjectLen());
+                        }                       
+                    }
+                }
+            }
+        }
+
+
+    // Write objects to file
+    for (index = 0; index < size; index++)
+        {
+        berObject = At(index);
+        type = berObject->Type();
+
+        if (type > KBerConstructed && type != KBerEncodedObject )
+            {
+            type = KBerConstructed;
+            }
+        
+        switch (type)
+            {
+            case KBerBoolean:
+                {
+                err += AppendBoolL(berObject->Value());
+                break;
+                }
+            case KBerInteger:
+                {
+                if (!berObject->Value() && (berObject->GetBigInt() != NULL))
+                    {
+					RInteger integer = berObject->GetBigInt();
+                    err += AppendLongIntL(integer);
+                    }
+                else
+                    {
+                    err += AppendIntL(berObject->Value());
+                    }
+                break;
+                }  
+            case KBerNull:
+                {
+                err += AppendNull();
+                break;
+                }
+            case KBerOid:
+                {
+                err += AppendObjectIdL(*berObject->ValuePtr());
+                break;
+                }
+            case KBerBitString:
+            case KBerOctetString:             
+		    case KBerNumS:
+            case KBerPrS:
+            case KBerT61S:
+		    case KBerVideoS:
+            case KBerIA5S:
+            case KBerUtc:
+		    case KBerGenTime:                                
+		    case KBerGraphS: 
+		    case KBerVisibleS:
+		    case KBerGeneralS:
+                {
+                CCrData* tempData = berObject->Data();
+                if (tempData != NULL)
+                    {
+                    err += AppendStringL((berObject->Type()),
+                                    (berObject->Data()));
+                    }
+                else
+                    {
+                    err += AppendStringL((berObject->Type()),
+                                    (*berObject->ValuePtr()));
+                    }
+                break;
+                }
+            case KBerSeq:
+            case KBerSet:
+            case KBerConstructed:
+                {
+                err += AppendConstructedL((berObject->Type()), 
+                                         (berObject->ContentLen()));
+                break;
+                }
+            case KBerEncodedObject:
+                {
+                err += AppendBerEncodedObject(
+                    (*berObject->ValuePtr()));
+                break;
+                }
+            case KBerEndOfContent:
+                {
+                if (!berObject->Value())            // Indefinite len
+                    {   
+                    err += CloseIndefinite();
+                    }
+                break;
+                }
+            }
+        }
+    if (err < KErrNone)
+        {
+        return KErrGeneral;
+        }
+    else    
+        {
+        return size;
+        }
+    }