os/security/cryptoservices/asnpkcs/source/asnpkcs5.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/cryptoservices/asnpkcs/source/asnpkcs5.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,504 @@
     1.4 +/*
     1.5 +* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of the License "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: 
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +
    1.22 +#include <asn1enc.h>
    1.23 +#include <asn1dec.h>
    1.24 +#include <pbedata.h>
    1.25 +#include <rc2.h>
    1.26 +
    1.27 +#include "asnpkcs.h"
    1.28 +
    1.29 +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
    1.30 +
    1.31 +/** OpenSSL PKCS8 Effective Key Length Compatibility.*/
    1.32 +const TUint KPkcs8CompatibilityBits = 128;
    1.33 +
    1.34 +#endif
    1.35 +
    1.36 +
    1.37 +_LIT(Kpkcs5PBES2, "1.2.840.113549.1.5.13");
    1.38 +_LIT(Kpkcs5PBKDF2, "1.2.840.113549.1.5.12");
    1.39 +_LIT(KDESCBC, "1.3.14.3.2.7");
    1.40 +_LIT(K3DESCBC, "1.2.840.113549.3.7");
    1.41 +_LIT(KRC2CBC, "1.2.840.113549.3.2");
    1.42 +
    1.43 +// pbe12Algorithm Ids
    1.44 +_LIT(KPbeWithSHA1And128BitRC4, "1.2.840.113549.1.12.1.1");
    1.45 +_LIT(KPbeWithSHA1And40BitRC4, "1.2.840.113549.1.12.1.2");
    1.46 +_LIT(KPbeWithSHA1And3_KeyTripleDES_CBC, "1.2.840.113549.1.12.1.3");
    1.47 +_LIT(KPbeWithSHA1And2_KeyTripleDES_CBC, "1.2.840.113549.1.12.1.4");
    1.48 +_LIT(KPbeWithSHA1And128BitRC2_CBC, "1.2.840.113549.1.12.1.5");
    1.49 +_LIT(KPbeWithSHA1And40BitRC2_CBC, "1.2.840.113549.1.12.1.6");
    1.50 +//The size of the Initialization vector
    1.51 +const TInt KIvSize = 8;
    1.52 +
    1.53 +
    1.54 +/*
    1.55 +* //For RC2
    1.56 +* SEQUENCE
    1.57 +* 	OID -- pkcs5PBES2
    1.58 +*	SEQUENCE
    1.59 +*		SEQUENCE
    1.60 +*		OID -- pkcs5PBKDF2
    1.61 +*		SEQUENCE
    1.62 +*			OCTET STRING -- salt
    1.63 +*			INTEGER -- iteration count
    1.64 +*			INTEGER -- effective key length in octets
    1.65 +* 	SEQUENCE
    1.66 +*		OID -- algorithm id (rc2)
    1.67 +*		SEQUENCE
    1.68 +*			INTEGER -- RC2 parameter version 58 = 128, 160 = 40
    1.69 +*			OCTET STRING -- iv
    1.70 +*
    1.71 +* //For DES and 3DES
    1.72 +* SEQUENCE
    1.73 +* 	OID -- pkcs5PBES2
    1.74 +*	SEQUENCE
    1.75 +*		SEQUENCE
    1.76 +*		OID -- pkcs5PBKDF2
    1.77 +*		SEQUENCE
    1.78 +*			OCTET STRING -- salt
    1.79 +*			INTEGER -- iteration count
    1.80 +* 	SEQUENCE
    1.81 +*		OID -- algorithm id (des, 3des)
    1.82 +*		OCTET STRING -- iv
    1.83 +*/
    1.84 +
    1.85 +EXPORT_C CASN1EncSequence* TASN1EncPKCS5::EncodeDERL(const CPBEncryptParms& aParms)
    1.86 +	{
    1.87 +	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
    1.88 +	CASN1EncObjectIdentifier* pbes2 = CASN1EncObjectIdentifier::NewLC(Kpkcs5PBES2);
    1.89 +	seq->AddChildL(pbes2);
    1.90 +	CleanupStack::Pop(pbes2);
    1.91 +
    1.92 +	CASN1EncSequence* seq1 = CASN1EncSequence::NewLC();
    1.93 +	seq->AddChildL(seq1);
    1.94 +	CleanupStack::Pop(seq1);
    1.95 +
    1.96 +	CASN1EncSequence* seq2 = CASN1EncSequence::NewLC();
    1.97 +	seq1->AddChildL(seq2);
    1.98 +	CleanupStack::Pop(seq2);
    1.99 +
   1.100 +	CASN1EncObjectIdentifier* pbkdf2 = CASN1EncObjectIdentifier::NewLC(Kpkcs5PBKDF2);
   1.101 +	seq2->AddChildL(pbkdf2);
   1.102 +	CleanupStack::Pop(pbkdf2);
   1.103 +
   1.104 +	CASN1EncSequence* seq3 = CASN1EncSequence::NewLC();
   1.105 +	seq2->AddChildL(seq3);
   1.106 +	CleanupStack::Pop(seq3);
   1.107 +
   1.108 +	CASN1EncOctetString* salt = CASN1EncOctetString::NewLC(aParms.Salt());
   1.109 +	seq3->AddChildL(salt);
   1.110 +	CleanupStack::Pop(salt);
   1.111 +
   1.112 +	CASN1EncInt* iterations = CASN1EncInt::NewLC(aParms.Iterations());
   1.113 +	seq3->AddChildL(iterations);
   1.114 +	CleanupStack::Pop(iterations);
   1.115 +
   1.116 +	CASN1EncInt* keysize = 0;
   1.117 +	switch(aParms.Cipher())
   1.118 +		{
   1.119 +		case ECipherDES_CBC:
   1.120 +		case ECipher3DES_CBC: 
   1.121 +			break;
   1.122 +		case ECipherRC2_CBC_40:
   1.123 + 			keysize = CASN1EncInt::NewLC(KSSLCompatibilityBits/8);  // effective key length in *octets*
   1.124 +			seq3->AddChildL(keysize);
   1.125 +			CleanupStack::Pop(keysize);
   1.126 +			break;
   1.127 +		case ECipherRC2_CBC_128:
   1.128 + 			keysize = CASN1EncInt::NewLC(KSSLCompatibilityBits/8);  // effective key length in *octets*
   1.129 +			seq3->AddChildL(keysize);
   1.130 +			CleanupStack::Pop(keysize);
   1.131 +			break;
   1.132 +		case ECipherRC2_CBC_40_16:
   1.133 + 			keysize = CASN1EncInt::NewLC(KPkcs8CompatibilityBits/8);  // effective key length in *octets*
   1.134 +			seq3->AddChildL(keysize);
   1.135 +			CleanupStack::Pop(keysize);
   1.136 +			break;
   1.137 +		case ECipherRC2_CBC_128_16:
   1.138 + 			keysize = CASN1EncInt::NewLC(KPkcs8CompatibilityBits/8);  // effective key length in *octets*
   1.139 +			seq3->AddChildL(keysize);
   1.140 +			CleanupStack::Pop(keysize);
   1.141 +			break;
   1.142 +		default:
   1.143 +			User::Leave(KErrNotSupported);
   1.144 +			break;
   1.145 +		}
   1.146 +
   1.147 +	CASN1EncSequence* seq4 = CASN1EncSequence::NewLC();
   1.148 +	seq1->AddChildL(seq4);
   1.149 +	CleanupStack::Pop(seq4);
   1.150 +
   1.151 +	CASN1EncObjectIdentifier* algid = 0;
   1.152 +	switch(aParms.Cipher())
   1.153 +		{
   1.154 +		case ECipherDES_CBC:
   1.155 +			algid = CASN1EncObjectIdentifier::NewLC(KDESCBC);
   1.156 +			break;
   1.157 +		case ECipher3DES_CBC:
   1.158 +			algid = CASN1EncObjectIdentifier::NewLC(K3DESCBC);
   1.159 +			break;
   1.160 +		case ECipherRC2_CBC_40:
   1.161 +		case ECipherRC2_CBC_128:
   1.162 +		case ECipherRC2_CBC_40_16:
   1.163 +		case ECipherRC2_CBC_128_16:
   1.164 +			algid = CASN1EncObjectIdentifier::NewLC(KRC2CBC);
   1.165 +			break;
   1.166 +		default:
   1.167 +			User::Leave(KErrNotSupported);
   1.168 +			break;
   1.169 +		}
   1.170 +	seq4->AddChildL(algid);
   1.171 +	CleanupStack::Pop(algid);
   1.172 +
   1.173 +	CASN1EncSequence* seq5 = 0;
   1.174 +	CASN1EncInt* keysize1 = 0;
   1.175 +	CASN1EncOctetString* iv = 0;
   1.176 +	switch(aParms.Cipher())
   1.177 +		{
   1.178 +		case ECipherDES_CBC:
   1.179 +		case ECipher3DES_CBC:
   1.180 +			iv = CASN1EncOctetString::NewLC(aParms.IV());
   1.181 +			seq4->AddChildL(iv);
   1.182 +			CleanupStack::Pop(iv);
   1.183 +			break;
   1.184 +		case ECipherRC2_CBC_40:
   1.185 +		case ECipherRC2_CBC_40_16:
   1.186 +			seq5 = CASN1EncSequence::NewLC();
   1.187 +			seq4->AddChildL(seq5);
   1.188 +			CleanupStack::Pop(seq5);
   1.189 +
   1.190 +			keysize1 = CASN1EncInt::NewLC(160); //encoding for 40 bit
   1.191 +			seq5->AddChildL(keysize1);
   1.192 +			CleanupStack::Pop(keysize1);
   1.193 +
   1.194 +			iv = CASN1EncOctetString::NewLC(aParms.IV());
   1.195 +			seq5->AddChildL(iv);
   1.196 +			CleanupStack::Pop(iv);
   1.197 +			break;
   1.198 +		case ECipherRC2_CBC_128:
   1.199 +		case ECipherRC2_CBC_128_16:
   1.200 +			seq5 = CASN1EncSequence::NewLC();
   1.201 +			seq4->AddChildL(seq5);
   1.202 +			CleanupStack::Pop(seq5);
   1.203 +			
   1.204 +			keysize1 = CASN1EncInt::NewLC(58); //encoding for 128 bit
   1.205 +			seq5->AddChildL(keysize1);
   1.206 +			CleanupStack::Pop(keysize1);
   1.207 +
   1.208 +			iv = CASN1EncOctetString::NewLC(aParms.IV());
   1.209 +			seq5->AddChildL(iv);
   1.210 +			CleanupStack::Pop(iv);
   1.211 +			break;
   1.212 +		default:
   1.213 +			User::Leave(KErrNotSupported);
   1.214 +			break;
   1.215 +		}
   1.216 +	CleanupStack::Pop(seq);
   1.217 +	return seq;
   1.218 +	}
   1.219 +
   1.220 +EXPORT_C CPBEncryptParms* TASN1DecPKCS5::DecodeDERL(const TDesC8& aBinaryData)
   1.221 +	{
   1.222 +	TASN1DecGeneric seqGen(aBinaryData);
   1.223 +	seqGen.InitL();
   1.224 +	if (seqGen.Tag() != EASN1Sequence)
   1.225 +		{
   1.226 +		User::Leave(KErrArgument);
   1.227 +		}
   1.228 +	
   1.229 +	//Decode the Algorithm Identifier Sequence
   1.230 +	TASN1DecSequence seq;
   1.231 +	CArrayPtrFlat<TASN1DecGeneric>* seqContents = seq.DecodeDERLC(seqGen);
   1.232 +
   1.233 +	//PbeAlgorithm Id
   1.234 +	if (seqContents->At(0)->Tag() != EASN1ObjectIdentifier)
   1.235 +		{
   1.236 +		User::Leave(KErrArgument);
   1.237 +		}	
   1.238 +	CPBEncryptParms* params = NULL;	
   1.239 +	TASN1DecObjectIdentifier oid;
   1.240 +	HBufC* oiddes = oid.DecodeDERL(*(seqContents->At(0)));
   1.241 +	CleanupStack::PushL(oiddes);
   1.242 +	//Algorithm Id is a pkcs-12Pbe Algorithm Id.
   1.243 +	if(*oiddes != Kpkcs5PBES2)
   1.244 +		{
   1.245 +		// Initialise to impossible value
   1.246 +		TPBECipher cipher = (TPBECipher) -1; 
   1.247 +		// Pbe12Algorithm Ids
   1.248 +		if(*oiddes == KPbeWithSHA1And128BitRC4)
   1.249 +			{
   1.250 +			cipher = ECipherARC4_128;
   1.251 +			}
   1.252 +		else if(*oiddes == KPbeWithSHA1And40BitRC4)
   1.253 +			{
   1.254 +			cipher = ECipherARC4_40;
   1.255 +			}
   1.256 +		else if(*oiddes == KPbeWithSHA1And3_KeyTripleDES_CBC)
   1.257 +			{
   1.258 +			cipher = ECipher3DES_CBC;
   1.259 +			}
   1.260 +		else if(*oiddes == KPbeWithSHA1And2_KeyTripleDES_CBC)
   1.261 +			{
   1.262 +			cipher = ECipher2Key3DES_CBC;
   1.263 +			}
   1.264 +		else if(*oiddes == KPbeWithSHA1And128BitRC2_CBC)
   1.265 +			{
   1.266 +			cipher = ECipherRC2_CBC_128_16; 
   1.267 +			}
   1.268 +		else if(*oiddes == KPbeWithSHA1And40BitRC2_CBC)
   1.269 +			{
   1.270 +			cipher = ECipherRC2_CBC_40_5; 
   1.271 +			}
   1.272 +	    else
   1.273 +        	{
   1.274 +        	User::Leave(KErrNotSupported);
   1.275 +        	}	 
   1.276 +        
   1.277 +        TInt seqContentsCount = seqContents->Count();
   1.278 +		
   1.279 +		//All pkcs-12Pbe algorithms require the Algorithm Parameters.
   1.280 +		//Algorithm Parameters are not OPTIONAL for pkcs-12Pbe algorithms.
   1.281 +		
   1.282 +		//seqContentsCount should be equal to 2.That is, the Algorithm Id 
   1.283 +		//and associated Algorithm Parameters have to be present.
   1.284 +		if(seqContentsCount != 2)
   1.285 +			{
   1.286 +			User::Leave(KErrArgument);	
   1.287 +			}
   1.288 +		//This if statement checks if the pkcs-12PbeParams Sequence is present in the 
   1.289 +		//AlgorithmIdentifier Sequence Since pkcs-12PbeParams are OPTIONAL
   1.290 +		else 
   1.291 +			{
   1.292 +			//Set the Initialization vector size to 8 bytes.
   1.293 +			TBuf8<KIvSize> iv(KIvSize);
   1.294 +			// Initialized to NULL, if salt is not present.
   1.295 +			TPtrC8 salt;
   1.296 +			TInt iterations; 
   1.297 +
   1.298 +			const TASN1DecGeneric* seqContentsAt1 = seqContents->At(1);
   1.299 +			if (seqContentsAt1->Tag() != EASN1Sequence || seqContentsAt1->Class() != EUniversal)
   1.300 +				{
   1.301 +				User::Leave(KErrArgument);
   1.302 +				}
   1.303 +				
   1.304 +			CArrayPtrFlat<TASN1DecGeneric>* seq1Contents = seq.DecodeDERLC(*seqContentsAt1);
   1.305 +			const TASN1DecGeneric* seq1ContentsAt0 = seq1Contents->At(0);
   1.306 +			if (seq1ContentsAt0->Tag() != EASN1OctetString || seq1ContentsAt0->Class() != EUniversal)
   1.307 +				{
   1.308 +				User::Leave(KErrArgument);
   1.309 +				}
   1.310 +			salt.Set(seq1ContentsAt0->GetContentDER());
   1.311 +			const TASN1DecGeneric* seq1ContentsAt1 = seq1Contents->At(1);
   1.312 +			if (seq1ContentsAt1->Tag() != EASN1Integer || seq1ContentsAt1->Class() != EUniversal)
   1.313 +				{
   1.314 +				User::Leave(KErrArgument);
   1.315 +				}
   1.316 +			TASN1DecInteger integer;
   1.317 +			iterations = integer.DecodeDERShortL(*seq1ContentsAt1);
   1.318 +			if (iterations <= 0)
   1.319 +				{
   1.320 +				User::Leave(KErrArgument);
   1.321 +				}
   1.322 +			params = CPBEncryptParms::NewL(cipher, salt, iv, iterations);
   1.323 +			params->SetKdf(CPBEncryptParms::EKdfPkcs12);
   1.324 +			CleanupStack::PopAndDestroy(seq1Contents);
   1.325 +			}
   1.326 +		}
   1.327 +	//Algorithm Id is a pkcs-5Pbe Algorithm Id.
   1.328 +   	 else if (*oiddes == Kpkcs5PBES2)
   1.329 +    	{
   1.330 +    	if (seqContents->At(1)->Tag() != EASN1Sequence)
   1.331 +			{
   1.332 +			User::Leave(KErrArgument);
   1.333 +			}
   1.334 +		CArrayPtrFlat<TASN1DecGeneric>* seq1Contents = seq.DecodeDERLC(*(seqContents->At(1)));
   1.335 +
   1.336 +		if (seq1Contents->At(0)->Tag() != EASN1Sequence)
   1.337 +			{
   1.338 +			User::Leave(KErrArgument);
   1.339 +			}
   1.340 +		CArrayPtrFlat<TASN1DecGeneric>* seq2Contents = seq.DecodeDERLC(*(seq1Contents->At(0)));
   1.341 +
   1.342 +		if (seq2Contents->At(0)->Tag() != EASN1ObjectIdentifier)
   1.343 +			{
   1.344 +			User::Leave(KErrArgument);
   1.345 +			}
   1.346 +		HBufC* oid1des = oid.DecodeDERL(*(seq2Contents->At(0)));
   1.347 +		CleanupStack::PushL(oid1des);
   1.348 +		
   1.349 +		if(*oid1des != Kpkcs5PBKDF2)
   1.350 +			{
   1.351 +			User::Leave(KErrNotSupported);
   1.352 +			}
   1.353 +		if (seq2Contents->At(1)->Tag() != EASN1Sequence)
   1.354 +			{
   1.355 +			User::Leave(KErrArgument);
   1.356 +			}
   1.357 +		CArrayPtrFlat<TASN1DecGeneric>* seq3Contents = seq.DecodeDERLC(*(seq2Contents->At(1)));
   1.358 +
   1.359 +		if (seq3Contents->At(0)->Tag() != EASN1OctetString)
   1.360 +			{
   1.361 +			User::Leave(KErrArgument);
   1.362 +			}
   1.363 +		TASN1DecOctetString octet;
   1.364 +		HBufC8* salt = octet.DecodeDERL(*(seq3Contents->At(0)));
   1.365 +		CleanupStack::PushL(salt);
   1.366 +		
   1.367 +		if (seq3Contents->At(1)->Tag() != EASN1Integer)
   1.368 +			{
   1.369 +			User::Leave(KErrArgument);
   1.370 +			}
   1.371 +		TASN1DecInteger integer;
   1.372 +		TInt iterations = integer.DecodeDERShortL(*(seq3Contents->At(1)));
   1.373 +
   1.374 +		if (seq1Contents->At(1)->Tag() != EASN1Sequence)
   1.375 +			{
   1.376 +			User::Leave(KErrArgument);
   1.377 +			}
   1.378 +		CArrayPtrFlat<TASN1DecGeneric>* seq4Contents = seq.DecodeDERLC(*(seq1Contents->At(1)));
   1.379 +	
   1.380 +		TPBECipher cipher = (TPBECipher) -1; // Initialise to impossible value
   1.381 +		if (seq4Contents->At(0)->Tag() != EASN1ObjectIdentifier)
   1.382 +			{
   1.383 +			User::Leave(KErrArgument);
   1.384 +			}
   1.385 +		HBufC* oid2des = oid.DecodeDERL(*(seq4Contents->At(0)));
   1.386 +		CleanupStack::PushL(oid2des);
   1.387 +		
   1.388 +		CArrayPtrFlat<TASN1DecGeneric>* seq5Contents = 0; 
   1.389 +
   1.390 +		if(*oid2des == K3DESCBC)
   1.391 +			{
   1.392 +			cipher = ECipher3DES_CBC;
   1.393 +		CleanupStack::PushL(seq5Contents);
   1.394 +			}
   1.395 +		else if(*oid2des == KDESCBC)
   1.396 +			{
   1.397 +			cipher = ECipherDES_CBC;
   1.398 +		CleanupStack::PushL(seq5Contents);
   1.399 +			}
   1.400 +		else if(*oid2des == KRC2CBC)
   1.401 +			{
   1.402 +			// RC2 has an additional parameter, the effective key lenght in octets.
   1.403 +			if (seq3Contents->At(2)->Tag() != EASN1Integer)
   1.404 +				{
   1.405 +				User::Leave(KErrArgument);
   1.406 +				}		
   1.407 +			TInt effectiveKeyLength =  integer.DecodeDERShortL(*(seq3Contents->At(2)));
   1.408 +
   1.409 +			if (seq4Contents->At(1)->Tag() != EASN1Sequence)
   1.410 +				{
   1.411 +				User::Leave(KErrArgument);
   1.412 +				}
   1.413 +			seq5Contents = seq.DecodeDERLC(*(seq4Contents->At(1)));
   1.414 +			if (seq5Contents->At(0)->Tag() != EASN1Integer)
   1.415 +				{
   1.416 +				User::Leave(KErrArgument);
   1.417 +				}
   1.418 +			TInt keysize = integer.DecodeDERShortL(*(seq5Contents->At(0)));
   1.419 +			switch(keysize)
   1.420 +				{
   1.421 +				// These values come from the PKCS#5 v2 specs
   1.422 +				case 160:
   1.423 +					if (effectiveKeyLength == 16)
   1.424 +						{
   1.425 +						cipher = ECipherRC2_CBC_40_16;					
   1.426 +						}
   1.427 +					else 
   1.428 +						{
   1.429 +						if (effectiveKeyLength == 128)
   1.430 +							{
   1.431 +							cipher = ECipherRC2_CBC_40;
   1.432 +							}
   1.433 +						else 
   1.434 +							{
   1.435 +							User::Leave(KErrNotSupported); // Unsupported effective key length!						
   1.436 +							}
   1.437 +						}
   1.438 +					break;
   1.439 +				case 58:
   1.440 +					if (effectiveKeyLength == 16)
   1.441 +						{
   1.442 +						cipher = ECipherRC2_CBC_128_16;					
   1.443 +						}
   1.444 +					else 
   1.445 +						{
   1.446 +						if (effectiveKeyLength == 128)
   1.447 +							{
   1.448 +							cipher = ECipherRC2_CBC_128;
   1.449 +							}
   1.450 +						else 
   1.451 +							{
   1.452 +							User::Leave(KErrNotSupported); // Unsupported effective key length!						
   1.453 +							}
   1.454 +						}			
   1.455 +					break;
   1.456 +				case 120:
   1.457 +					//would be RC_CBC_64 but we don't support that
   1.458 +				default:
   1.459 +					User::Leave(KErrNotSupported);
   1.460 +					break;
   1.461 +				}
   1.462 +			}
   1.463 +		else 
   1.464 +			{
   1.465 +			User::Leave(KErrNotSupported);
   1.466 +			}	
   1.467 +
   1.468 +		HBufC8* iv = 0;
   1.469 +		switch(cipher)
   1.470 +			{
   1.471 +			case ECipher3DES_CBC:
   1.472 +			case ECipherDES_CBC:
   1.473 +				if (seq4Contents->At(1)->Tag() != EASN1OctetString)
   1.474 +					{
   1.475 +					User::Leave(KErrArgument);
   1.476 +					}
   1.477 +				iv = octet.DecodeDERL(*(seq4Contents->At(1)));	
   1.478 +			CleanupStack::PushL(iv);
   1.479 +				break;
   1.480 +			case ECipherRC2_CBC_40:
   1.481 +			case ECipherRC2_CBC_128:
   1.482 +			case ECipherRC2_CBC_40_16:
   1.483 +			case ECipherRC2_CBC_128_16:	
   1.484 +				if (seq5Contents->At(1)->Tag() != EASN1OctetString)
   1.485 +					{
   1.486 +					User::Leave(KErrArgument);
   1.487 +					}
   1.488 +				iv = octet.DecodeDERL(*(seq5Contents->At(1)));
   1.489 +			CleanupStack::PushL(iv);
   1.490 +				break;
   1.491 +			default:
   1.492 +				User::Leave(KErrNotSupported);
   1.493 +				break;
   1.494 +			}
   1.495 +
   1.496 +		params = CPBEncryptParms::NewL(cipher, *salt, *iv,
   1.497 +		iterations);
   1.498 +	CleanupStack::PopAndDestroy(9); //iv, seq5contents, oid2des, seq4Contents,
   1.499 +	//salt, seq3Contents, oid1des, seq2Contents, seq1Contents
   1.500 +    	}
   1.501 +	else
   1.502 +		{
   1.503 +		User::Leave(KErrNotSupported);
   1.504 +		}
   1.505 +	CleanupStack::PopAndDestroy(2, seqContents);
   1.506 +	return params;
   1.507 +	}