diff -r 000000000000 -r 2c201484c85f cryptoservices/certificateandkeymgmt/asn1/baseenc.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cryptoservices/certificateandkeymgmt/asn1/baseenc.cpp Wed Jul 08 11:25:26 2009 +0100 @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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: +* Define methods for asn1-encoding base class +* +*/ + + +#include "base128enc.h" +#include "panic.h" + +#include + +const TUint KMaxLowNumberFormTag = 30; +const TUint KMaxShortFormLength = 127; + + +EXPORT_C CASN1EncBase::CASN1EncBase(const TTagType aType, const TASN1Class aClass) +: iType(aType), iClass(aClass) + { + CalculateTagLengthDER(); + } + + +EXPORT_C CASN1EncBase::~CASN1EncBase() + { + } + + +EXPORT_C void CASN1EncBase::ConstructL() + { + ContentsLengthChanged(); + } + + +void CASN1EncBase::ContentsLengthChanged() + { + CalculateContentsLengthDER(); + CalculateLengthLengthDER(); + + if (iParent) + { + iParent->ContentsLengthChanged(); + } + } + + +// Set tagging scheme/tag/class +EXPORT_C void CASN1EncBase::SetTag(const TTagType aType, const TASN1Class aClass) + { + iType = aType; + iClass = aClass; + + CalculateTagLengthDER(); + } + + +// Gives total number of octets in the DER encoding of this object +EXPORT_C TUint CASN1EncBase::LengthDER() const + { + return iTagLengthDER + iLengthLengthDER + iContentsLengthDER; + } + + +// Writes entire DER encoding of this object into the given buffer +EXPORT_C void CASN1EncBase::WriteDERL(TDes8& aBuf, TUint& aPos) const + { + __ASSERT_ALWAYS(aBuf.Length() - STATIC_CAST(TInt, aPos) >= STATIC_CAST(TInt, LengthDER()), + Panic(KErrDescriptorTooShort)); + + WriteHelperL(aBuf, aPos, iTagLengthDER, &CASN1EncBase::WriteTagDERL); + WriteHelperL(aBuf, aPos, iLengthLengthDER, &CASN1EncBase::WriteLengthDER); + WriteHelperL(aBuf, aPos, iContentsLengthDER, &CASN1EncBase::WriteContentsDERL); + } + + +// Internal helper method, used for efficiency +void CASN1EncBase::WriteHelperL(TDes8& aBuf, TUint& aPos, const TUint aLength, + WriteFunc aWriteFunc) const + { + if (aLength) + { + // Get the middle bit of buffer we should be using + TPtr8 ptr(&aBuf[aPos], aLength, aLength); + + // Call the function to actually write the data + (this->*aWriteFunc)(ptr); + + aPos += aLength; + } + } + + +// Give number of octets in tag section +void CASN1EncBase::CalculateTagLengthDER() + { + if (iType <= KMaxLowNumberFormTag) + { + // Low tag number form + iTagLengthDER = 1; + } + else + { + // High tag number form + TASN1EncBase128DER encoder(iType); + iTagLengthDER = encoder.LengthDER() + 1; + } + } + + +// Give number of octets in length section +// Only called after contents length is worked out +void CASN1EncBase::CalculateLengthLengthDER() + { + iLengthLengthDER = 1; + if (iContentsLengthDER > KMaxShortFormLength) + { + // Long form - need number of octets in base256 representation + // of length, plus 1. + + TUint working = iContentsLengthDER; + do + { + ++iLengthLengthDER; + } + while (working >>= 8); + } + } + + +// Writes the tag section into the given buffer +void CASN1EncBase::WriteTagDERL(TDes8& aBuf) const + { + // Write class - bits 7-8 + aBuf[0] = STATIC_CAST(TUint8, iClass << 6); + + // Write constructed/primitive flag in bit 6 + if (IsConstructed()) + { + aBuf[0] |= 0x20; + } + + // Write length + if (iType <= KMaxLowNumberFormTag) + { + aBuf[0] |= iType; + } + else + { + // First byte signals more to come + aBuf[0] |= 0x1F; + + // The rest we delegate + TASN1EncBase128DER encoder(iType); + TUint offset = 1; + encoder.WriteDERL(aBuf, offset); + } + } + + +// Writes the length section into the given buffer +void CASN1EncBase::WriteLengthDER(TDes8& aBuf) const + { + if (iContentsLengthDER > KMaxShortFormLength) + { + // First byte is the number of other bytes, with top bit also set + TUint octets = iLengthLengthDER - 1; + + // Cast takes 8 least sig bits + aBuf[0] = STATIC_CAST(TUint8, octets); + aBuf[0] |= 0x80; + + // Other bytes are base 256 representation of length, most significant first + TUint working = iContentsLengthDER; + do + { + // Cast to TUint8 takes 8 least sig bits + aBuf[octets] = STATIC_CAST(TUint8, working); + working >>= 8; + } + while (--octets); + } + else + { + // Short form, nice and easy - take least sig 8 bits with a cast + aBuf[0] = STATIC_CAST(TUint8, iContentsLengthDER); + } + } + + +// Sets the parent (can only do this once) +void CASN1EncBase::SetParent(CASN1EncBase* aParent) + { + __ASSERT_ALWAYS(iParent == 0, Panic(KErrAlreadyHasParent)); + iParent = aParent; + }