os/security/cryptoservices/certificateandkeymgmt/pkcs7/pkcs7encrypteddataobject.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	}
   223