cryptoservices/certificateandkeymgmt/pkcs7/pkcs7encrypteddataobject.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     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".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "pkcs7encrypteddataobject.h"
       
    20 
       
    21 /** The last character in the PKCS7 EncryptedData OID */
       
    22 const TInt KPkcs7EncryptedData = 6;
       
    23 
       
    24 EXPORT_C CPKCS7EncryptedDataObject* CPKCS7EncryptedDataObject::NewL(const CPKCS7ContentInfo& aContentInfo)
       
    25 	{
       
    26 	CPKCS7EncryptedDataObject* self = new (ELeave) CPKCS7EncryptedDataObject();
       
    27 	CleanupStack::PushL(self);
       
    28 	self->ConstructL(aContentInfo);
       
    29 	CleanupStack::Pop(self);
       
    30 	return self;	
       
    31 	}
       
    32 
       
    33 CPKCS7EncryptedDataObject::CPKCS7EncryptedDataObject(void)
       
    34 	{
       
    35 	}
       
    36 
       
    37 CPKCS7EncryptedDataObject::~CPKCS7EncryptedDataObject()
       
    38 	{
       
    39 	delete iEncryptParams;
       
    40 	}
       
    41 
       
    42 EXPORT_C TInt CPKCS7EncryptedDataObject::Version() const
       
    43 	{
       
    44 	return iVersion;
       
    45 	}
       
    46 	
       
    47 EXPORT_C CPKCS7EncryptedDataObject::TContentType CPKCS7EncryptedDataObject::ContentType() const
       
    48 	{
       
    49 	return iContentType;
       
    50 	}
       
    51 	
       
    52 EXPORT_C const TDesC8& CPKCS7EncryptedDataObject::EncryptedContentInfoData() const
       
    53 	{
       
    54 	return iEncryptedContent;
       
    55 	}	
       
    56 
       
    57 EXPORT_C const CPBEncryptParms& CPKCS7EncryptedDataObject::EncryptParams() const
       
    58 	{
       
    59 	return *iEncryptParams;
       
    60 	}
       
    61 
       
    62 CPBEncryptParms* CPKCS7EncryptedDataObject::DecodeContentEncryptionAlgorithmL(const TDesC8& aBinaryData) const
       
    63 	{
       
    64 	TASN1DecGeneric seqGen(aBinaryData);
       
    65 	seqGen.InitL();
       
    66 	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
       
    67 		{
       
    68 		User::Leave(KErrArgument);
       
    69 		}
       
    70 	
       
    71     TPtrC8 theContent(seqGen.Encoding());
       
    72     CPBEncryptParms* encryptParams =  TASN1DecPKCS5::DecodeDERL(theContent);
       
    73     return encryptParams;
       
    74 	}	
       
    75 
       
    76 EXPORT_C HBufC8* CPKCS7EncryptedDataObject::DecryptDataL(const TDesC& aPassword) const
       
    77 	{
       
    78 	CPBEncryptElement* encryptElement;
       
    79     HBufC8* pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(aPassword);
       
    80     if(iEncryptParams->Kdf() == CPBEncryptParms::EKdfPkcs12)
       
    81 		{
       
    82 	 	TPtrC8 iv = iEncryptParams->IV();
       
    83 	    HBufC8* ivValue = HBufC8::NewMaxLC(iv.Length());
       
    84 	    TPtr8 encryptKeyBuf = ivValue->Des();
       
    85 
       
    86 	 	switch(iEncryptParams->Cipher())	
       
    87 			{
       
    88 	 		case ECipherARC4_128:
       
    89 	 		case ECipherARC4_40:
       
    90 	 			{
       
    91 	 	    	//derive only key it is unnecessary to derive an IV for RC4
       
    92 	 	    	break;
       
    93 	 			}
       
    94 			case ECipher3DES_CBC:
       
    95 			case ECipher2Key3DES_CBC:
       
    96 			case ECipherRC2_CBC_128_16:	 
       
    97 			case ECipherRC2_CBC_40_5:	
       
    98 				{
       
    99 				PKCS12KDF::DeriveKeyL(encryptKeyBuf, PKCS12KDF::EIDByteIV, *pkcs12Pwd, iEncryptParams->Salt(), iEncryptParams->Iterations());
       
   100 				iEncryptParams->SetIV(encryptKeyBuf);
       
   101 		    	break;
       
   102 				}
       
   103 			default:
       
   104 				{
       
   105 		    	User::Leave(KErrNotSupported);
       
   106 		    	break;
       
   107 				}
       
   108 	 		}
       
   109 	 	CleanupStack::PopAndDestroy(ivValue);
       
   110 		// Create the decryptor	
       
   111 		encryptElement = CPBEncryptElement::NewLC(*pkcs12Pwd, *iEncryptParams);
       
   112 		}
       
   113 	else
       
   114 		{
       
   115 		TPBPassword password(aPassword);
       
   116 		// Create the decryptor	
       
   117 		encryptElement = CPBEncryptElement::NewLC(password.Password(), *iEncryptParams);	
       
   118 		}
       
   119 	 
       
   120 	CPBDecryptor* decryptor = encryptElement->NewDecryptLC();
       
   121    	
       
   122 	TPtrC8 encryptedKey(iEncryptedContent);
       
   123 	TUint encryptLength = encryptedKey.Length();
       
   124 	TUint maxDecryptLength = decryptor->MaxOutputLength(encryptLength);
       
   125 	
       
   126 	if ( maxDecryptLength <= 0 )
       
   127 		{
       
   128 		User::Leave(KErrGeneral);		
       
   129 		}
       
   130 	
       
   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;
       
   137    	}
       
   138 
       
   139  void CPKCS7EncryptedDataObject::ConstructL(const CPKCS7ContentInfo& aContentInfo)
       
   140 	{
       
   141 	if(aContentInfo.ContentType() != KPkcs7EncryptedData)
       
   142 		{
       
   143 		User::Leave(KErrArgument);
       
   144 		}
       
   145     
       
   146 	// EncryptedData SEQUENCE
       
   147 	TASN1DecGeneric decGen(aContentInfo.ContentData());
       
   148 	decGen.InitL();
       
   149 	if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
       
   150 		{
       
   151 	    User::Leave(KErrArgument);
       
   152 		}
       
   153     TASN1DecSequence seq1;
       
   154     CArrayPtrFlat<TASN1DecGeneric>* EncryptedDataContents = seq1.DecodeDERLC(decGen);       					
       
   155 			    
       
   156 	// Both version and encryptedContentInfo should be present
       
   157 	if (EncryptedDataContents->Count() != 2)
       
   158 		{
       
   159 		User::Leave(KErrArgument);
       
   160 		}
       
   161 		            
       
   162 	// VERSION
       
   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)
       
   166 		{
       
   167 		User::Leave(KErrArgument);
       
   168 		}
       
   169 	 
       
   170 	TASN1DecInteger intDecoder;
       
   171 	iVersion = intDecoder.DecodeDERShortL(*EncryptedDataContentsAt0);
       
   172 	if (iVersion != 0)
       
   173 		{
       
   174 	    User::Leave(KErrArgument);		
       
   175 	    }
       
   176 		                
       
   177     // ENCRYPTED CONTENT INFO a SEQUENCE
       
   178     const TASN1DecGeneric* EncryptedDataContentsAt1 = EncryptedDataContents->At(1);
       
   179 	if (EncryptedDataContentsAt1->Tag() != EASN1Sequence || EncryptedDataContentsAt1->Class() != EUniversal)
       
   180 		{
       
   181 	    User::Leave(KErrArgument);
       
   182 	    }		               
       
   183 	TASN1DecSequence seq2;
       
   184     CArrayPtrFlat<TASN1DecGeneric>* EncryptedContentInfo = seq2.DecodeDERLC(*EncryptedDataContentsAt1);       
       
   185 		        
       
   186     // CONTENT TYPE IDENTIFIED BY AN OBJECT IDENTIFIER
       
   187 	// Gets the oid
       
   188 	TASN1DecObjectIdentifier ContentTypeoidDec;
       
   189 	HBufC* contentType = ContentTypeoidDec.DecodeDERL(*EncryptedContentInfo->At(0));
       
   190 	if(contentType->Compare(KPkcs7DataOID()) == 0)
       
   191 		{
       
   192 		iContentType = EPkcs7Data;
       
   193 		}
       
   194 	else
       
   195 		{
       
   196 		User::Leave(KErrNotSupported);
       
   197 		}
       
   198 	delete contentType;	        
       
   199 	// CONTENT ENCRYPTION ALGORITHM
       
   200 	// Get the Cipher used and the encoded params in it
       
   201     iEncryptParams = DecodeContentEncryptionAlgorithmL(EncryptedContentInfo->At(1)->Encoding());
       
   202                 
       
   203     // ENCRYPTED CONTENT
       
   204 	// This is an OPTIONAL field
       
   205 	TInt encryptedContentInfoCount = EncryptedContentInfo->Count();
       
   206 	if(encryptedContentInfoCount == 3)
       
   207 		{
       
   208 		TASN1DecGeneric decOctetString(*EncryptedContentInfo->At(2));
       
   209 		decOctetString.InitL();
       
   210 	    iEncryptedContent.Set(decOctetString.GetContentDER());
       
   211 	   	}
       
   212 	else if(encryptedContentInfoCount > 3 || encryptedContentInfoCount < 2)
       
   213 	    {
       
   214 	    User::Leave(KErrArgument);
       
   215 	    }
       
   216 	else if(encryptedContentInfoCount == 2)
       
   217 		{
       
   218 		iEncryptedContent.Set(KNullDesC8());
       
   219 		}
       
   220 
       
   221 	CleanupStack::PopAndDestroy(2, EncryptedDataContents); //EncryptedDataContents, EncryptedContentInfo    	
       
   222 	}