os/security/cryptoservices/certificateandkeymgmt/pkcs7/pkcs7encrypteddataobject.cpp
Update contrib.
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 "pkcs7encrypteddataobject.h"
21 /** The last character in the PKCS7 EncryptedData OID */
22 const TInt KPkcs7EncryptedData = 6;
24 EXPORT_C CPKCS7EncryptedDataObject* CPKCS7EncryptedDataObject::NewL(const CPKCS7ContentInfo& aContentInfo)
26 CPKCS7EncryptedDataObject* self = new (ELeave) CPKCS7EncryptedDataObject();
27 CleanupStack::PushL(self);
28 self->ConstructL(aContentInfo);
29 CleanupStack::Pop(self);
33 CPKCS7EncryptedDataObject::CPKCS7EncryptedDataObject(void)
37 CPKCS7EncryptedDataObject::~CPKCS7EncryptedDataObject()
39 delete iEncryptParams;
42 EXPORT_C TInt CPKCS7EncryptedDataObject::Version() const
47 EXPORT_C CPKCS7EncryptedDataObject::TContentType CPKCS7EncryptedDataObject::ContentType() const
52 EXPORT_C const TDesC8& CPKCS7EncryptedDataObject::EncryptedContentInfoData() const
54 return iEncryptedContent;
57 EXPORT_C const CPBEncryptParms& CPKCS7EncryptedDataObject::EncryptParams() const
59 return *iEncryptParams;
62 CPBEncryptParms* CPKCS7EncryptedDataObject::DecodeContentEncryptionAlgorithmL(const TDesC8& aBinaryData) const
64 TASN1DecGeneric seqGen(aBinaryData);
66 if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
68 User::Leave(KErrArgument);
71 TPtrC8 theContent(seqGen.Encoding());
72 CPBEncryptParms* encryptParams = TASN1DecPKCS5::DecodeDERL(theContent);
76 EXPORT_C HBufC8* CPKCS7EncryptedDataObject::DecryptDataL(const TDesC& aPassword) const
78 CPBEncryptElement* encryptElement;
79 HBufC8* pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(aPassword);
80 if(iEncryptParams->Kdf() == CPBEncryptParms::EKdfPkcs12)
82 TPtrC8 iv = iEncryptParams->IV();
83 HBufC8* ivValue = HBufC8::NewMaxLC(iv.Length());
84 TPtr8 encryptKeyBuf = ivValue->Des();
86 switch(iEncryptParams->Cipher())
91 //derive only key it is unnecessary to derive an IV for RC4
95 case ECipher2Key3DES_CBC:
96 case ECipherRC2_CBC_128_16:
97 case ECipherRC2_CBC_40_5:
99 PKCS12KDF::DeriveKeyL(encryptKeyBuf, PKCS12KDF::EIDByteIV, *pkcs12Pwd, iEncryptParams->Salt(), iEncryptParams->Iterations());
100 iEncryptParams->SetIV(encryptKeyBuf);
105 User::Leave(KErrNotSupported);
109 CleanupStack::PopAndDestroy(ivValue);
110 // Create the decryptor
111 encryptElement = CPBEncryptElement::NewLC(*pkcs12Pwd, *iEncryptParams);
115 TPBPassword password(aPassword);
116 // Create the decryptor
117 encryptElement = CPBEncryptElement::NewLC(password.Password(), *iEncryptParams);
120 CPBDecryptor* decryptor = encryptElement->NewDecryptLC();
122 TPtrC8 encryptedKey(iEncryptedContent);
123 TUint encryptLength = encryptedKey.Length();
124 TUint maxDecryptLength = decryptor->MaxOutputLength(encryptLength);
126 if ( maxDecryptLength <= 0 )
128 User::Leave(KErrGeneral);
131 HBufC8* decryptedContent = HBufC8::NewLC(maxDecryptLength);
132 TPtr8 dcDes(decryptedContent->Des());
133 decryptor->Process(encryptedKey, dcDes);
134 CleanupStack::Pop(decryptedContent);
135 CleanupStack::PopAndDestroy(3, pkcs12Pwd); // pkcs12Pwd, encryptElement, decryptor
136 return decryptedContent;
139 void CPKCS7EncryptedDataObject::ConstructL(const CPKCS7ContentInfo& aContentInfo)
141 if(aContentInfo.ContentType() != KPkcs7EncryptedData)
143 User::Leave(KErrArgument);
146 // EncryptedData SEQUENCE
147 TASN1DecGeneric decGen(aContentInfo.ContentData());
149 if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
151 User::Leave(KErrArgument);
153 TASN1DecSequence seq1;
154 CArrayPtrFlat<TASN1DecGeneric>* EncryptedDataContents = seq1.DecodeDERLC(decGen);
156 // Both version and encryptedContentInfo should be present
157 if (EncryptedDataContents->Count() != 2)
159 User::Leave(KErrArgument);
163 // version is the syntax version number. It shall be 0 for this version of the standard
164 const TASN1DecGeneric* EncryptedDataContentsAt0 = EncryptedDataContents->At(0);
165 if(EncryptedDataContentsAt0->Tag() != EASN1Integer || EncryptedDataContentsAt0->Class() != EUniversal)
167 User::Leave(KErrArgument);
170 TASN1DecInteger intDecoder;
171 iVersion = intDecoder.DecodeDERShortL(*EncryptedDataContentsAt0);
174 User::Leave(KErrArgument);
177 // ENCRYPTED CONTENT INFO a SEQUENCE
178 const TASN1DecGeneric* EncryptedDataContentsAt1 = EncryptedDataContents->At(1);
179 if (EncryptedDataContentsAt1->Tag() != EASN1Sequence || EncryptedDataContentsAt1->Class() != EUniversal)
181 User::Leave(KErrArgument);
183 TASN1DecSequence seq2;
184 CArrayPtrFlat<TASN1DecGeneric>* EncryptedContentInfo = seq2.DecodeDERLC(*EncryptedDataContentsAt1);
186 // CONTENT TYPE IDENTIFIED BY AN OBJECT IDENTIFIER
188 TASN1DecObjectIdentifier ContentTypeoidDec;
189 HBufC* contentType = ContentTypeoidDec.DecodeDERL(*EncryptedContentInfo->At(0));
190 if(contentType->Compare(KPkcs7DataOID()) == 0)
192 iContentType = EPkcs7Data;
196 User::Leave(KErrNotSupported);
199 // CONTENT ENCRYPTION ALGORITHM
200 // Get the Cipher used and the encoded params in it
201 iEncryptParams = DecodeContentEncryptionAlgorithmL(EncryptedContentInfo->At(1)->Encoding());
204 // This is an OPTIONAL field
205 TInt encryptedContentInfoCount = EncryptedContentInfo->Count();
206 if(encryptedContentInfoCount == 3)
208 TASN1DecGeneric decOctetString(*EncryptedContentInfo->At(2));
209 decOctetString.InitL();
210 iEncryptedContent.Set(decOctetString.GetContentDER());
212 else if(encryptedContentInfoCount > 3 || encryptedContentInfoCount < 2)
214 User::Leave(KErrArgument);
216 else if(encryptedContentInfoCount == 2)
218 iEncryptedContent.Set(KNullDesC8());
221 CleanupStack::PopAndDestroy(2, EncryptedDataContents); //EncryptedDataContents, EncryptedContentInfo