First public contribution.
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
20 #include "pkcs7signedobject.h"
22 using namespace PKCS12;
24 CDecPkcs12::CDecPkcs12()
28 EXPORT_C CDecPkcs12* CDecPkcs12::NewL(const TDesC8& aRawData)
30 CDecPkcs12* self = NewLC(aRawData);
31 CleanupStack::Pop(self);
35 EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(const TDesC8& aRawData)
37 CDecPkcs12* self = new (ELeave) CDecPkcs12;
38 CleanupStack::PushL(self);
39 self->ConstructL(aRawData);
43 EXPORT_C CDecPkcs12* CDecPkcs12::NewL(RReadStream& aStream)
45 CDecPkcs12* self = NewLC(aStream);
46 CleanupStack::Pop(self);
50 EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(RReadStream& aStream)
52 CDecPkcs12* self = new (ELeave) CDecPkcs12;
53 CleanupStack::PushL(self);
54 self->InternalizeL(aStream);
58 CDecPkcs12::~CDecPkcs12()
60 iContentInfos.ResetAndDestroy();
61 iContentInfos.Close();
62 delete iAuthenticatedSafeData;
66 void CDecPkcs12::ConstructL(const TDesC8& aRawData)
68 TASN1DecGeneric decGen(aRawData);
70 if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
72 User::Leave(KErrArgument);
75 // aRawData conatins PFX Sequence
76 TASN1DecSequence decSeq;
77 CArrayPtr<TASN1DecGeneric>* seqContents = decSeq.DecodeDERLC(decGen);
79 // Check if both the version and the authSafe are present, since macData is optional,
80 TInt pfxCount = seqContents->Count();
81 if (pfxCount > 3 || pfxCount < 2)
83 User::Leave(KErrArgument);
86 // Decodes Version, Version is an Integer
87 const TASN1DecGeneric* seqContentsAt0 = seqContents->At(0);
88 if (seqContentsAt0->Tag() != EASN1Integer || seqContentsAt0->Class() != EUniversal)
90 User::Leave(KErrArgument);
92 TASN1DecInteger intDecoder;
93 iVersion = intDecoder.DecodeDERShortL(*seqContentsAt0);
94 if (iVersion != KPkcs12Version)
96 User::Leave(KErrArgument);
99 // Decodes the AuthSafe, AuthSafe is a Sequence
100 // If AuthSafe is not present then leave
101 const TASN1DecGeneric* seqContentsAt1 = seqContents->At(1);
102 if(seqContentsAt1->Tag() != EASN1Sequence || seqContentsAt1->Class() != EUniversal)
104 User::Leave(KErrArgument);
107 TASN1DecSequence authSafeSeq;
108 CArrayPtr<TASN1DecGeneric>* authSafeContents = authSafeSeq.DecodeDERLC(*seqContentsAt1);
109 const TASN1DecGeneric* authSafeContentsAt0 = authSafeContents->At(0);
110 if(authSafeContentsAt0->Tag() == EASN1ObjectIdentifier || authSafeContentsAt0->Class() == EUniversal)
112 TASN1DecObjectIdentifier oid;
113 HBufC* objectId = oid.DecodeDERL(*authSafeContentsAt0);
114 CleanupStack::PushL(objectId);
115 if(*objectId == KPkcs7DataOID || *objectId == KPkcs7SignedDataOID)
117 // Decode this Sequence, If there is an OID for Data/Signed Data then use PKCS7 library
118 iAuthenticatedSafeData = CPKCS7ContentInfo::NewL(seqContentsAt1->Encoding());
122 User::Leave(KErrArgument);
124 CleanupStack::PopAndDestroy(objectId);
126 // AuthSafe is absent
129 User::Leave(KErrArgument);
133 if(iAuthenticatedSafeData->ContentType() == KPkcs7Data)
135 iMode = EPasswordIntegrityMode;
137 else if(iAuthenticatedSafeData->ContentType() == KPkcs7SignedData)
139 iMode = EPublicKeyIntegrityMode;
142 TPtrC8 contentData(KNullDesC8);
143 // In case of Password Integrity Mode, ContentType is Data
144 if(iMode == EPasswordIntegrityMode)
146 // Check if MacData is present, Decodes MacData
147 if (seqContents->Count() == 3)
149 const TASN1DecGeneric* seqContentsAt2 = seqContents->At(2);
150 if (seqContentsAt2->Tag() != EASN1Null || seqContentsAt2->Class() == EUniversal)
152 iMacData = CDecPkcs12MacData::NewL(seqContentsAt2->Encoding(),iAuthenticatedSafeData->ContentData());
155 contentData.Set(iAuthenticatedSafeData->ContentData());
157 // Public-Key Integrity Mode, ContentType is SignedData
158 else if(iMode == EPublicKeyIntegrityMode)
160 // Create a pkcs7signed data object
161 CPKCS7SignedObject* signedData = CPKCS7SignedObject::NewL(*iAuthenticatedSafeData);
162 CleanupStack::PushL(signedData);
163 // Obtain the ContentInfo present in Signed Data
164 const CPKCS7ContentInfo* contentInfo = &(signedData->ContentInfo());
166 // Get the type of ContentInfo
167 if (contentInfo->ContentType() != KPkcs7Data)
169 User::Leave(KErrNotSupported);
171 contentData.Set(contentInfo->ContentData());
172 CleanupStack::PopAndDestroy(signedData);
176 User::Leave(KErrArgument);
179 TASN1DecGeneric decGen1(contentData);
181 if(decGen1.Tag() != EASN1Sequence || decGen1.Class() != EUniversal)
183 User::Leave(KErrArgument);
186 // Desequence the ContentData present in ContentInfo which is in AuthSafe
187 TASN1DecSequence seq;
188 CArrayPtr<TASN1DecGeneric>* contentInfoSequences = seq.DecodeDERLC(decGen1);
190 // The number of ContentInfos present
191 TInt contentInfoCount = contentInfoSequences->Count();
193 for(TInt index =0; index < contentInfoCount; index++)
195 CPKCS7ContentInfo* contentInfo = CPKCS7ContentInfo::NewL(contentInfoSequences->At(index)->Encoding());
196 CleanupStack::PushL(contentInfo);
197 iContentInfos.AppendL(contentInfo);
198 CleanupStack::Pop(contentInfo);
200 CleanupStack::PopAndDestroy(3,seqContents); // seqContents, authSafeContents, contentInfoSequences
203 void CDecPkcs12::InternalizeL(RReadStream& aStream)
205 MStreamBuf* streamBuf = aStream.Source();
206 TInt pos = streamBuf->SizeL();
207 streamBuf->SeekL(MStreamBuf::ERead, EStreamBeginning, 0);
208 HBufC8* temp= HBufC8::NewLC(pos);
209 TPtr8 ptr = temp->Des();
210 aStream.ReadL(ptr,pos);
212 CleanupStack::PopAndDestroy(temp);
215 EXPORT_C TInt CDecPkcs12::Version() const
220 EXPORT_C CDecPkcs12::TIntegrityMode CDecPkcs12::IntegrityMode() const
225 EXPORT_C const RPointerArray<CPKCS7ContentInfo>& CDecPkcs12::AuthenticatedSafeContents() const
227 return iContentInfos;
230 EXPORT_C const CPKCS7ContentInfo& CDecPkcs12::AuthenticatedSafe() const
232 return *iAuthenticatedSafeData;
235 EXPORT_C const CDecPkcs12MacData* CDecPkcs12::MacData() const