sl@0: /* sl@0: * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #include "pkcs12.h" sl@0: #include "pkcs7signedobject.h" sl@0: sl@0: using namespace PKCS12; sl@0: sl@0: CDecPkcs12::CDecPkcs12() sl@0: { sl@0: } sl@0: sl@0: EXPORT_C CDecPkcs12* CDecPkcs12::NewL(const TDesC8& aRawData) sl@0: { sl@0: CDecPkcs12* self = NewLC(aRawData); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(const TDesC8& aRawData) sl@0: { sl@0: CDecPkcs12* self = new (ELeave) CDecPkcs12; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aRawData); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CDecPkcs12* CDecPkcs12::NewL(RReadStream& aStream) sl@0: { sl@0: CDecPkcs12* self = NewLC(aStream); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(RReadStream& aStream) sl@0: { sl@0: CDecPkcs12* self = new (ELeave) CDecPkcs12; sl@0: CleanupStack::PushL(self); sl@0: self->InternalizeL(aStream); sl@0: return self; sl@0: } sl@0: sl@0: CDecPkcs12::~CDecPkcs12() sl@0: { sl@0: iContentInfos.ResetAndDestroy(); sl@0: iContentInfos.Close(); sl@0: delete iAuthenticatedSafeData; sl@0: delete iMacData; sl@0: } sl@0: sl@0: void CDecPkcs12::ConstructL(const TDesC8& aRawData) sl@0: { sl@0: TASN1DecGeneric decGen(aRawData); sl@0: decGen.InitL(); sl@0: if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // aRawData conatins PFX Sequence sl@0: TASN1DecSequence decSeq; sl@0: CArrayPtr* seqContents = decSeq.DecodeDERLC(decGen); sl@0: sl@0: // Check if both the version and the authSafe are present, since macData is optional, sl@0: TInt pfxCount = seqContents->Count(); sl@0: if (pfxCount > 3 || pfxCount < 2) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // Decodes Version, Version is an Integer sl@0: const TASN1DecGeneric* seqContentsAt0 = seqContents->At(0); sl@0: if (seqContentsAt0->Tag() != EASN1Integer || seqContentsAt0->Class() != EUniversal) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: TASN1DecInteger intDecoder; sl@0: iVersion = intDecoder.DecodeDERShortL(*seqContentsAt0); sl@0: if (iVersion != KPkcs12Version) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // Decodes the AuthSafe, AuthSafe is a Sequence sl@0: // If AuthSafe is not present then leave sl@0: const TASN1DecGeneric* seqContentsAt1 = seqContents->At(1); sl@0: if(seqContentsAt1->Tag() != EASN1Sequence || seqContentsAt1->Class() != EUniversal) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: TASN1DecSequence authSafeSeq; sl@0: CArrayPtr* authSafeContents = authSafeSeq.DecodeDERLC(*seqContentsAt1); sl@0: const TASN1DecGeneric* authSafeContentsAt0 = authSafeContents->At(0); sl@0: if(authSafeContentsAt0->Tag() == EASN1ObjectIdentifier || authSafeContentsAt0->Class() == EUniversal) sl@0: { sl@0: TASN1DecObjectIdentifier oid; sl@0: HBufC* objectId = oid.DecodeDERL(*authSafeContentsAt0); sl@0: CleanupStack::PushL(objectId); sl@0: if(*objectId == KPkcs7DataOID || *objectId == KPkcs7SignedDataOID) sl@0: { sl@0: // Decode this Sequence, If there is an OID for Data/Signed Data then use PKCS7 library sl@0: iAuthenticatedSafeData = CPKCS7ContentInfo::NewL(seqContentsAt1->Encoding()); sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: CleanupStack::PopAndDestroy(objectId); sl@0: } sl@0: // AuthSafe is absent sl@0: else sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // Integrity Mode sl@0: if(iAuthenticatedSafeData->ContentType() == KPkcs7Data) sl@0: { sl@0: iMode = EPasswordIntegrityMode; sl@0: } sl@0: else if(iAuthenticatedSafeData->ContentType() == KPkcs7SignedData) sl@0: { sl@0: iMode = EPublicKeyIntegrityMode; sl@0: } sl@0: sl@0: TPtrC8 contentData(KNullDesC8); sl@0: // In case of Password Integrity Mode, ContentType is Data sl@0: if(iMode == EPasswordIntegrityMode) sl@0: { sl@0: // Check if MacData is present, Decodes MacData sl@0: if (seqContents->Count() == 3) sl@0: { sl@0: const TASN1DecGeneric* seqContentsAt2 = seqContents->At(2); sl@0: if (seqContentsAt2->Tag() != EASN1Null || seqContentsAt2->Class() == EUniversal) sl@0: { sl@0: iMacData = CDecPkcs12MacData::NewL(seqContentsAt2->Encoding(),iAuthenticatedSafeData->ContentData()); sl@0: } sl@0: } sl@0: contentData.Set(iAuthenticatedSafeData->ContentData()); sl@0: } sl@0: // Public-Key Integrity Mode, ContentType is SignedData sl@0: else if(iMode == EPublicKeyIntegrityMode) sl@0: { sl@0: // Create a pkcs7signed data object sl@0: CPKCS7SignedObject* signedData = CPKCS7SignedObject::NewL(*iAuthenticatedSafeData); sl@0: CleanupStack::PushL(signedData); sl@0: // Obtain the ContentInfo present in Signed Data sl@0: const CPKCS7ContentInfo* contentInfo = &(signedData->ContentInfo()); sl@0: sl@0: // Get the type of ContentInfo sl@0: if (contentInfo->ContentType() != KPkcs7Data) sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: contentData.Set(contentInfo->ContentData()); sl@0: CleanupStack::PopAndDestroy(signedData); sl@0: } sl@0: else sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: TASN1DecGeneric decGen1(contentData); sl@0: decGen1.InitL(); sl@0: if(decGen1.Tag() != EASN1Sequence || decGen1.Class() != EUniversal) sl@0: { sl@0: User::Leave(KErrArgument); sl@0: } sl@0: sl@0: // Desequence the ContentData present in ContentInfo which is in AuthSafe sl@0: TASN1DecSequence seq; sl@0: CArrayPtr* contentInfoSequences = seq.DecodeDERLC(decGen1); sl@0: sl@0: // The number of ContentInfos present sl@0: TInt contentInfoCount = contentInfoSequences->Count(); sl@0: sl@0: for(TInt index =0; index < contentInfoCount; index++) sl@0: { sl@0: CPKCS7ContentInfo* contentInfo = CPKCS7ContentInfo::NewL(contentInfoSequences->At(index)->Encoding()); sl@0: CleanupStack::PushL(contentInfo); sl@0: iContentInfos.AppendL(contentInfo); sl@0: CleanupStack::Pop(contentInfo); sl@0: } sl@0: CleanupStack::PopAndDestroy(3,seqContents); // seqContents, authSafeContents, contentInfoSequences sl@0: } sl@0: sl@0: void CDecPkcs12::InternalizeL(RReadStream& aStream) sl@0: { sl@0: MStreamBuf* streamBuf = aStream.Source(); sl@0: TInt pos = streamBuf->SizeL(); sl@0: streamBuf->SeekL(MStreamBuf::ERead, EStreamBeginning, 0); sl@0: HBufC8* temp= HBufC8::NewLC(pos); sl@0: TPtr8 ptr = temp->Des(); sl@0: aStream.ReadL(ptr,pos); sl@0: ConstructL(*temp); sl@0: CleanupStack::PopAndDestroy(temp); sl@0: } sl@0: sl@0: EXPORT_C TInt CDecPkcs12::Version() const sl@0: { sl@0: return iVersion; sl@0: } sl@0: sl@0: EXPORT_C CDecPkcs12::TIntegrityMode CDecPkcs12::IntegrityMode() const sl@0: { sl@0: return iMode; sl@0: } sl@0: sl@0: EXPORT_C const RPointerArray& CDecPkcs12::AuthenticatedSafeContents() const sl@0: { sl@0: return iContentInfos; sl@0: } sl@0: sl@0: EXPORT_C const CPKCS7ContentInfo& CDecPkcs12::AuthenticatedSafe() const sl@0: { sl@0: return *iAuthenticatedSafeData; sl@0: } sl@0: sl@0: EXPORT_C const CDecPkcs12MacData* CDecPkcs12::MacData() const sl@0: { sl@0: return iMacData; sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: