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.
19 #include "pkcs12bags.h"
21 using namespace PKCS12;
22 ///////////////////////// KeyBag ////////////////////////////////
24 CDecPkcs12KeyBag::CDecPkcs12KeyBag()
28 EXPORT_C CDecPkcs12KeyBag* CDecPkcs12KeyBag::NewL(const TDesC8& aSafeBagData)
30 CDecPkcs12KeyBag* self = new(ELeave) CDecPkcs12KeyBag;
31 CleanupStack::PushL(self);
32 self->ConstructL(aSafeBagData);
33 CleanupStack::Pop(self);
37 CDecPkcs12KeyBag::~CDecPkcs12KeyBag()
41 void CDecPkcs12KeyBag::ConstructL(const TDesC8& aSafeBagData)
43 CDecPkcs12SafeBag::ConstructL(aSafeBagData);
46 EXPORT_C CDecPKCS8Data* CDecPkcs12KeyBag::PrivateKeyInfoL() const
48 TASN1DecGeneric seqGen(iBagValue);
50 if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
52 User::Leave(KErrArgument);
55 return TASN1DecPKCS8::DecodeDERL(seqGen.Encoding());
58 ////////////////////////// ShroudedKeyBag ////////////////////////
59 CDecPkcs12ShroudedKeyBag::CDecPkcs12ShroudedKeyBag()
63 EXPORT_C CDecPkcs12ShroudedKeyBag* CDecPkcs12ShroudedKeyBag::NewL(const TDesC8& aSafeBagData)
65 CDecPkcs12ShroudedKeyBag* self = new(ELeave) CDecPkcs12ShroudedKeyBag;
66 CleanupStack::PushL(self);
67 self->ConstructL(aSafeBagData);
68 CleanupStack::Pop(self);
72 CDecPkcs12ShroudedKeyBag::~CDecPkcs12ShroudedKeyBag()
76 void CDecPkcs12ShroudedKeyBag::ConstructL(const TDesC8& aSafeBagData)
78 CDecPkcs12SafeBag::ConstructL(aSafeBagData);
79 TASN1DecGeneric seqGen(iBagValue);
81 if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
83 User::Leave(KErrArgument);
87 CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
89 TInt shroudedKeyBagSeqCount = shroudedKeyBagSeq->Count();
90 if (seqIndex >= shroudedKeyBagSeqCount)
92 User::Leave(KErrArgument);
94 CleanupStack::PopAndDestroy(shroudedKeyBagSeq);
97 EXPORT_C CDecPKCS8Data* CDecPkcs12ShroudedKeyBag::PrivateKeyInfoL(TDesC& aPassword) const
99 TASN1DecGeneric seqGen(iBagValue);
101 TASN1DecSequence dec;
102 CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
103 // Get the first part of the sequence -> PKCS5 data
104 const TASN1DecGeneric* shroudedKeyBagSeqAt0 = shroudedKeyBagSeq->At(0);
105 TPtrC8 theContent(shroudedKeyBagSeqAt0->Encoding());// expect this to be a sequence
106 CPBEncryptParms* encryptParams = TASN1DecPKCS5::DecodeDERL(theContent);
107 CleanupStack::PushL(encryptParams);
109 CPBEncryptElement* encryptElement;
110 HBufC8* pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(aPassword);
111 if(encryptParams->Kdf() == CPBEncryptParms::EKdfPkcs12)
113 TPtrC8 iv = encryptParams->IV();
114 HBufC8* ivValue = HBufC8::NewMaxLC(iv.Length());
115 TPtr8 encryptKeyBuf = ivValue->Des();
117 switch(encryptParams->Cipher())
119 case ECipherARC4_128:
122 //derive only key it is unnecessary to derive an IV for RC4
125 case ECipher3DES_CBC:
126 case ECipher2Key3DES_CBC:
127 case ECipherRC2_CBC_128_16:
128 case ECipherRC2_CBC_40_5:
130 PKCS12KDF::DeriveKeyL(encryptKeyBuf, PKCS12KDF::EIDByteIV, *pkcs12Pwd, encryptParams->Salt(), encryptParams->Iterations());
131 encryptParams->SetIV(encryptKeyBuf);
136 User::Leave(KErrNotSupported);
140 CleanupStack::PopAndDestroy(ivValue);
141 // Create the decryptor
142 encryptElement = CPBEncryptElement::NewLC(*pkcs12Pwd, *encryptParams);
146 TPBPassword password(aPassword);
147 // Create the decryptor
148 encryptElement = CPBEncryptElement::NewLC(password.Password(), *encryptParams);
150 CPBDecryptor* decryptor = encryptElement->NewDecryptLC();
151 // Decrypt the final part of the sequence -> encrypted PKCS8 object
152 const TASN1DecGeneric* shroudedKeyBagSeqAt1 = shroudedKeyBagSeq->At(1);
153 if (shroudedKeyBagSeqAt1->Tag() != EASN1OctetString || shroudedKeyBagSeqAt1->Class() != EUniversal)
155 User::Leave(KErrArgument);
157 TPtrC8 encryptedKey(shroudedKeyBagSeqAt1->GetContentDER());
158 TUint encryptLength = encryptedKey.Length();
159 TUint maxDecryptLength = decryptor->MaxOutputLength(encryptLength);
160 if ( maxDecryptLength <= 0 )
162 User::Leave(KErrGeneral);
164 HBufC8* decryptedContent = HBufC8::NewLC(encryptLength);
165 TPtr8 dcDes(decryptedContent->Des());
166 decryptor->Process(encryptedKey, dcDes);
168 CDecPKCS8Data* privateKeyInfo = TASN1DecPKCS8::DecodeDERL(dcDes);
170 CleanupStack::PopAndDestroy(6,shroudedKeyBagSeq);//shroudedKeyBagSeq, encryptParams,pkcs12Pwd
171 // encryptElement, decryptor, decryptedContent.
172 return privateKeyInfo;
175 ///////////////////////////// CertBag ///////////////////////////////
177 CDecPkcs12CertBag::CDecPkcs12CertBag()
181 EXPORT_C CDecPkcs12CertBag* CDecPkcs12CertBag::NewL(const TDesC8& aSafeBagData)
183 CDecPkcs12CertBag* self = new (ELeave) CDecPkcs12CertBag;
184 CleanupStack::PushL(self);
185 self->ConstructL(aSafeBagData);
186 CleanupStack::Pop(self);
190 CDecPkcs12CertBag::~CDecPkcs12CertBag()
195 void CDecPkcs12CertBag::ConstructL(const TDesC8& aSafeBagData)
197 CDecPkcs12SafeBag::ConstructL(aSafeBagData);
199 TASN1DecGeneric seqGen(iBagValue);
201 if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
203 User::Leave(KErrArgument);
206 TASN1DecSequence seq;
207 CArrayPtr<TASN1DecGeneric>* certBagSequence = seq.DecodeDERLC(seqGen);
208 const TASN1DecGeneric* certBagSequenceAt0 = certBagSequence->At(0);
209 if (certBagSequenceAt0->Tag() != EASN1ObjectIdentifier || certBagSequenceAt0->Class() != EUniversal)
211 User::Leave(KErrArgument);
215 TASN1DecObjectIdentifier oid;
216 iCertId = oid.DecodeDERL(*certBagSequenceAt0);
218 const TASN1DecGeneric* certBagSequenceAt1 = certBagSequence->At(1);
219 if (certBagSequenceAt1->Tag() != EASN1EOC || certBagSequenceAt1->Class() != EContextSpecific)
221 User::Leave(KErrArgument);
224 TASN1DecGeneric certBagSeq(certBagSequenceAt1->GetContentDER());
226 if (certBagSeq.Tag() != EASN1OctetString || certBagSeq.Class() != EUniversal)
228 User::Leave(KErrArgument);
232 iCertValue.Set(certBagSeq.GetContentDER());
234 CleanupStack::PopAndDestroy(certBagSequence);
237 EXPORT_C const TDesC& CDecPkcs12CertBag::CertId() const
242 EXPORT_C const TDesC8& CDecPkcs12CertBag::CertValue() const
247 EXPORT_C CX509Certificate* CDecPkcs12CertBag::X509CertificateL() const
249 return (*iCertId == KX509CertificateOID) ? CX509Certificate::NewL(iCertValue) : NULL;
252 /////////////////////// SafeContentsBag ///////////////////////
254 CDecPkcs12SafeContentsBag::CDecPkcs12SafeContentsBag()
258 EXPORT_C CDecPkcs12SafeContentsBag* CDecPkcs12SafeContentsBag::NewL(const TDesC8& aSafeContentsBagData)
260 CDecPkcs12SafeContentsBag* self = new(ELeave) CDecPkcs12SafeContentsBag;
261 CleanupStack::PushL(self);
262 self->ConstructL(aSafeContentsBagData);
263 CleanupStack::Pop(self);
267 CDecPkcs12SafeContentsBag::~CDecPkcs12SafeContentsBag()
269 iSafeBags.ResetAndDestroy();
273 void CDecPkcs12SafeContentsBag::ConstructL(const TDesC8& aSafeBagData)
275 CDecPkcs12SafeBag::ConstructL(aSafeBagData);
276 // This is SafeBag Sequence containing a SafeContents Bag
277 TASN1DecGeneric seqGen(iBagValue);
280 // Check if this is a Sequence
281 if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
283 User::Leave(KErrArgument);
286 TASN1DecSequence seq;
287 CArrayPtrFlat<TASN1DecGeneric>* safeContentsBagSeq = seq.DecodeDERLC(seqGen);
289 // Find out the number of SafeBags present in the SafeContents Bag
290 TInt safeContentsBagCount = safeContentsBagSeq->Count();
291 const TASN1DecGeneric* safeContentsBagSeqAtPos;
292 for (TInt index = 0; index < safeContentsBagCount; index++)
294 safeContentsBagSeqAtPos = safeContentsBagSeq->At(index);
295 if (safeContentsBagSeqAtPos->Tag() != EASN1Sequence || safeContentsBagSeqAtPos->Class() != EUniversal)
297 User::Leave(KErrArgument);
300 const TDesC8& safeBag(safeContentsBagSeqAtPos->Encoding());
301 // Decode this sequence, This is a SafeBag.
302 CDecPkcs12SafeBag* safeBagObject = CDecPkcs12SafeBag::NewL(safeBag);
303 CleanupStack::PushL(safeBagObject);
304 iSafeBags.AppendL(safeBagObject);
305 CleanupStack::Pop(safeBagObject);
307 CleanupStack::PopAndDestroy(safeContentsBagSeq);
310 EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContentsBag::SafeBags() const
315 ///////////////////////////// Safe Contents ///////////////////////////////
316 CDecPkcs12SafeContents::CDecPkcs12SafeContents()
320 CDecPkcs12SafeContents::~CDecPkcs12SafeContents()
322 delete iDecryptedData;
323 iSafeBags.ResetAndDestroy();
327 EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData)
329 CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
330 CleanupStack::PushL(self);
331 self->ConstructL(aSafeContentsBagData.ContentData());
332 CleanupStack::Pop(self);
336 EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData, const TDesC& aPassword)
338 CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
339 CleanupStack::PushL(self);
340 self->DecodeEncryptedDataL(aSafeContentsBagData,aPassword);
341 CleanupStack::Pop(self);
345 EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const TDesC8& aSafeContent)
347 CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
348 CleanupStack::PushL(self);
349 self->ConstructL(aSafeContent);
350 CleanupStack::Pop(self);
354 void CDecPkcs12SafeContents::ConstructL(const TDesC8& aSafeContent)
356 TASN1DecGeneric decGen(aSafeContent);
359 if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
361 User::Leave(KErrArgument);
364 TASN1DecGeneric decGen2(decGen.GetContentDER());
367 if(decGen2.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
369 User ::Leave(KErrArgument);
373 TASN1DecSequence seq;
374 CArrayPtr<TASN1DecGeneric>* safeBagSequences = seq.DecodeDERLC(decGen);
376 // A Sequence of SafeBags are present within the SafeContents Bag Sequence
377 TInt safeBagCount = safeBagSequences->Count();
379 for(TInt index = 0; index < safeBagCount; index++)
381 CDecPkcs12SafeBag* safeBag = CDecPkcs12SafeBag::NewL(safeBagSequences->At(index)->Encoding());
382 CleanupStack::PushL(safeBag);
383 iSafeBags.AppendL(safeBag);
384 CleanupStack::Pop(safeBag);
386 CleanupStack::PopAndDestroy(safeBagSequences); // safeBagSequences
389 void CDecPkcs12SafeContents::DecodeEncryptedDataL(const CPKCS7ContentInfo& aContentInfo, const TDesC& aPassword)
391 CPKCS7EncryptedDataObject* pkcs7EncryptedData = CPKCS7EncryptedDataObject::NewL(aContentInfo);
392 CleanupStack::PushL(pkcs7EncryptedData);
393 iDecryptedData = pkcs7EncryptedData->DecryptDataL(aPassword);
394 ConstructL(iDecryptedData->Des());
395 CleanupStack::PopAndDestroy(pkcs7EncryptedData);
398 EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContents::SafeContentsBags() const
403 EXPORT_C const TDesC8* CDecPkcs12SafeContents::DecryptedData() const
405 return iDecryptedData;