cryptoservices/certificateandkeymgmt/asn1/oidenc.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * Methods for encoding object identifiers
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 #include "base128enc.h"
       
    21 #include "panic.h"
       
    22 
       
    23 #include <asn1enc.h>
       
    24 
       
    25 const TInt KArrayGranularity = 5;
       
    26 
       
    27 const TUint KSecondTermBigLimit = 175;
       
    28 const TUint KFirstTermMultiplier = 40;
       
    29 const TUint KFirstTermMax = 2;
       
    30 
       
    31 
       
    32 EXPORT_C CASN1EncObjectIdentifier* CASN1EncObjectIdentifier::NewLC(const TDesC& aStr)
       
    33 	{
       
    34 	CASN1EncObjectIdentifier* self = new (ELeave) CASN1EncObjectIdentifier();
       
    35 	CleanupStack::PushL(self);
       
    36 	self->ConstructL(aStr);
       
    37 	return self;
       
    38 	}
       
    39 
       
    40 EXPORT_C CASN1EncObjectIdentifier* CASN1EncObjectIdentifier::NewL(const TDesC& aStr)
       
    41 	{
       
    42 	CASN1EncObjectIdentifier* self = NewLC(aStr);
       
    43 	CleanupStack::Pop(self);
       
    44 	return self;
       
    45 	}
       
    46 
       
    47 EXPORT_C CASN1EncObjectIdentifier::~CASN1EncObjectIdentifier()
       
    48 	{
       
    49 	iData.Close();
       
    50 	}
       
    51 
       
    52 
       
    53 CASN1EncObjectIdentifier::CASN1EncObjectIdentifier()
       
    54 : CASN1EncPrimitive(EASN1ObjectIdentifier), iData(KArrayGranularity)
       
    55 	{
       
    56 	}
       
    57 
       
    58 
       
    59 // Takes ints in a string, delimited by '.' characters in between (not at ends)
       
    60 void CASN1EncObjectIdentifier::ConstructL(const TDesC& aStr)
       
    61 	{
       
    62 	iData.Reset();
       
    63 	TInt index = 0;
       
    64 	TLex lex(aStr);
       
    65 
       
    66 	// First term
       
    67 	__ASSERT_ALWAYS(!lex.Eos(), User::Leave(KErrBadDescriptor));
       
    68 	TUint first;
       
    69 	User::LeaveIfError(lex.Val(first));
       
    70 	__ASSERT_ALWAYS(first <= KFirstTermMax, User::Leave(KErrBadDescriptor));
       
    71 	// Static cast takes 8 least sig bits
       
    72 	iFirstOctet = STATIC_CAST(TUint8, KFirstTermMultiplier * first);
       
    73 
       
    74 	// A '.' to delimit
       
    75 	__ASSERT_ALWAYS(!lex.Eos() && lex.Get() == '.',	User::Leave(KErrBadDescriptor));
       
    76 
       
    77 	// Second term
       
    78 	__ASSERT_ALWAYS(!lex.Eos(), User::Leave(KErrBadDescriptor));
       
    79 	TUint second;
       
    80 	User::LeaveIfError(lex.Val(second));
       
    81 	__ASSERT_ALWAYS((first < KFirstTermMax && second < KFirstTermMultiplier)
       
    82 		|| (first == KFirstTermMax && second <= KSecondTermBigLimit),
       
    83 		User::Leave(KErrBadDescriptor));
       
    84 	// Static cast takes 8 least sig bits
       
    85 	iFirstOctet = STATIC_CAST(TUint8, iFirstOctet + second);
       
    86 
       
    87 	// Remaining terms
       
    88 	while (!lex.Eos())
       
    89 		{
       
    90 		// Delimiter, and check we're not at end after that
       
    91 		__ASSERT_ALWAYS(lex.Get() == '.' && !lex.Eos(),	User::Leave(KErrBadDescriptor));
       
    92 
       
    93 		TUint value;
       
    94 		User::LeaveIfError(lex.Val(value));
       
    95 		++index;
       
    96 
       
    97 		// Store the data away for later
       
    98 		TASN1EncBase128DER encoder(value);
       
    99 		User::LeaveIfError(iData.Append(encoder));
       
   100 		}
       
   101 
       
   102 	// Remainder of ConstructL is here - safe to call CalculateContentsLengthDER now.
       
   103 	CASN1EncPrimitive::ConstructL();
       
   104 	}
       
   105 
       
   106 
       
   107 void CASN1EncObjectIdentifier::CalculateContentsLengthDER()
       
   108 	{
       
   109 	iContentsLengthDER = 1;
       
   110 	for (TInt i = iData.Count() - 1; i >= 0; --i)
       
   111 		{
       
   112 		iContentsLengthDER += iData[i].LengthDER();
       
   113 		}
       
   114 	}
       
   115 
       
   116 
       
   117 void CASN1EncObjectIdentifier::WriteContentsDERL(TDes8& aBuf) const
       
   118 	{
       
   119 	aBuf[0] = iFirstOctet;
       
   120 	TUint cursor = 1;
       
   121 	TInt count = iData.Count();
       
   122 	for (TInt i = 0; i < count; ++i)
       
   123 		{
       
   124 		iData[i].WriteDERL(aBuf, cursor);
       
   125 		}
       
   126 	}