os/security/cryptoservices/asnpkcs/source/asnpkcs5.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/*
sl@0
     2
* Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     3
* All rights reserved.
sl@0
     4
* This component and the accompanying materials are made available
sl@0
     5
* under the terms of the License "Eclipse Public License v1.0"
sl@0
     6
* which accompanies this distribution, and is available
sl@0
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     8
*
sl@0
     9
* Initial Contributors:
sl@0
    10
* Nokia Corporation - initial contribution.
sl@0
    11
*
sl@0
    12
* Contributors:
sl@0
    13
*
sl@0
    14
* Description: 
sl@0
    15
*
sl@0
    16
*/
sl@0
    17
sl@0
    18
sl@0
    19
#include <asn1enc.h>
sl@0
    20
#include <asn1dec.h>
sl@0
    21
#include <pbedata.h>
sl@0
    22
#include <rc2.h>
sl@0
    23
sl@0
    24
#include "asnpkcs.h"
sl@0
    25
sl@0
    26
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
sl@0
    27
sl@0
    28
/** OpenSSL PKCS8 Effective Key Length Compatibility.*/
sl@0
    29
const TUint KPkcs8CompatibilityBits = 128;
sl@0
    30
sl@0
    31
#endif
sl@0
    32
sl@0
    33
sl@0
    34
_LIT(Kpkcs5PBES2, "1.2.840.113549.1.5.13");
sl@0
    35
_LIT(Kpkcs5PBKDF2, "1.2.840.113549.1.5.12");
sl@0
    36
_LIT(KDESCBC, "1.3.14.3.2.7");
sl@0
    37
_LIT(K3DESCBC, "1.2.840.113549.3.7");
sl@0
    38
_LIT(KRC2CBC, "1.2.840.113549.3.2");
sl@0
    39
sl@0
    40
// pbe12Algorithm Ids
sl@0
    41
_LIT(KPbeWithSHA1And128BitRC4, "1.2.840.113549.1.12.1.1");
sl@0
    42
_LIT(KPbeWithSHA1And40BitRC4, "1.2.840.113549.1.12.1.2");
sl@0
    43
_LIT(KPbeWithSHA1And3_KeyTripleDES_CBC, "1.2.840.113549.1.12.1.3");
sl@0
    44
_LIT(KPbeWithSHA1And2_KeyTripleDES_CBC, "1.2.840.113549.1.12.1.4");
sl@0
    45
_LIT(KPbeWithSHA1And128BitRC2_CBC, "1.2.840.113549.1.12.1.5");
sl@0
    46
_LIT(KPbeWithSHA1And40BitRC2_CBC, "1.2.840.113549.1.12.1.6");
sl@0
    47
//The size of the Initialization vector
sl@0
    48
const TInt KIvSize = 8;
sl@0
    49
sl@0
    50
sl@0
    51
/*
sl@0
    52
* //For RC2
sl@0
    53
* SEQUENCE
sl@0
    54
* 	OID -- pkcs5PBES2
sl@0
    55
*	SEQUENCE
sl@0
    56
*		SEQUENCE
sl@0
    57
*		OID -- pkcs5PBKDF2
sl@0
    58
*		SEQUENCE
sl@0
    59
*			OCTET STRING -- salt
sl@0
    60
*			INTEGER -- iteration count
sl@0
    61
*			INTEGER -- effective key length in octets
sl@0
    62
* 	SEQUENCE
sl@0
    63
*		OID -- algorithm id (rc2)
sl@0
    64
*		SEQUENCE
sl@0
    65
*			INTEGER -- RC2 parameter version 58 = 128, 160 = 40
sl@0
    66
*			OCTET STRING -- iv
sl@0
    67
*
sl@0
    68
* //For DES and 3DES
sl@0
    69
* SEQUENCE
sl@0
    70
* 	OID -- pkcs5PBES2
sl@0
    71
*	SEQUENCE
sl@0
    72
*		SEQUENCE
sl@0
    73
*		OID -- pkcs5PBKDF2
sl@0
    74
*		SEQUENCE
sl@0
    75
*			OCTET STRING -- salt
sl@0
    76
*			INTEGER -- iteration count
sl@0
    77
* 	SEQUENCE
sl@0
    78
*		OID -- algorithm id (des, 3des)
sl@0
    79
*		OCTET STRING -- iv
sl@0
    80
*/
sl@0
    81
sl@0
    82
EXPORT_C CASN1EncSequence* TASN1EncPKCS5::EncodeDERL(const CPBEncryptParms& aParms)
sl@0
    83
	{
sl@0
    84
	CASN1EncSequence* seq = CASN1EncSequence::NewLC();
sl@0
    85
	CASN1EncObjectIdentifier* pbes2 = CASN1EncObjectIdentifier::NewLC(Kpkcs5PBES2);
sl@0
    86
	seq->AddChildL(pbes2);
sl@0
    87
	CleanupStack::Pop(pbes2);
sl@0
    88
sl@0
    89
	CASN1EncSequence* seq1 = CASN1EncSequence::NewLC();
sl@0
    90
	seq->AddChildL(seq1);
sl@0
    91
	CleanupStack::Pop(seq1);
sl@0
    92
sl@0
    93
	CASN1EncSequence* seq2 = CASN1EncSequence::NewLC();
sl@0
    94
	seq1->AddChildL(seq2);
sl@0
    95
	CleanupStack::Pop(seq2);
sl@0
    96
sl@0
    97
	CASN1EncObjectIdentifier* pbkdf2 = CASN1EncObjectIdentifier::NewLC(Kpkcs5PBKDF2);
sl@0
    98
	seq2->AddChildL(pbkdf2);
sl@0
    99
	CleanupStack::Pop(pbkdf2);
sl@0
   100
sl@0
   101
	CASN1EncSequence* seq3 = CASN1EncSequence::NewLC();
sl@0
   102
	seq2->AddChildL(seq3);
sl@0
   103
	CleanupStack::Pop(seq3);
sl@0
   104
sl@0
   105
	CASN1EncOctetString* salt = CASN1EncOctetString::NewLC(aParms.Salt());
sl@0
   106
	seq3->AddChildL(salt);
sl@0
   107
	CleanupStack::Pop(salt);
sl@0
   108
sl@0
   109
	CASN1EncInt* iterations = CASN1EncInt::NewLC(aParms.Iterations());
sl@0
   110
	seq3->AddChildL(iterations);
sl@0
   111
	CleanupStack::Pop(iterations);
sl@0
   112
sl@0
   113
	CASN1EncInt* keysize = 0;
sl@0
   114
	switch(aParms.Cipher())
sl@0
   115
		{
sl@0
   116
		case ECipherDES_CBC:
sl@0
   117
		case ECipher3DES_CBC: 
sl@0
   118
			break;
sl@0
   119
		case ECipherRC2_CBC_40:
sl@0
   120
 			keysize = CASN1EncInt::NewLC(KSSLCompatibilityBits/8);  // effective key length in *octets*
sl@0
   121
			seq3->AddChildL(keysize);
sl@0
   122
			CleanupStack::Pop(keysize);
sl@0
   123
			break;
sl@0
   124
		case ECipherRC2_CBC_128:
sl@0
   125
 			keysize = CASN1EncInt::NewLC(KSSLCompatibilityBits/8);  // effective key length in *octets*
sl@0
   126
			seq3->AddChildL(keysize);
sl@0
   127
			CleanupStack::Pop(keysize);
sl@0
   128
			break;
sl@0
   129
		case ECipherRC2_CBC_40_16:
sl@0
   130
 			keysize = CASN1EncInt::NewLC(KPkcs8CompatibilityBits/8);  // effective key length in *octets*
sl@0
   131
			seq3->AddChildL(keysize);
sl@0
   132
			CleanupStack::Pop(keysize);
sl@0
   133
			break;
sl@0
   134
		case ECipherRC2_CBC_128_16:
sl@0
   135
 			keysize = CASN1EncInt::NewLC(KPkcs8CompatibilityBits/8);  // effective key length in *octets*
sl@0
   136
			seq3->AddChildL(keysize);
sl@0
   137
			CleanupStack::Pop(keysize);
sl@0
   138
			break;
sl@0
   139
		default:
sl@0
   140
			User::Leave(KErrNotSupported);
sl@0
   141
			break;
sl@0
   142
		}
sl@0
   143
sl@0
   144
	CASN1EncSequence* seq4 = CASN1EncSequence::NewLC();
sl@0
   145
	seq1->AddChildL(seq4);
sl@0
   146
	CleanupStack::Pop(seq4);
sl@0
   147
sl@0
   148
	CASN1EncObjectIdentifier* algid = 0;
sl@0
   149
	switch(aParms.Cipher())
sl@0
   150
		{
sl@0
   151
		case ECipherDES_CBC:
sl@0
   152
			algid = CASN1EncObjectIdentifier::NewLC(KDESCBC);
sl@0
   153
			break;
sl@0
   154
		case ECipher3DES_CBC:
sl@0
   155
			algid = CASN1EncObjectIdentifier::NewLC(K3DESCBC);
sl@0
   156
			break;
sl@0
   157
		case ECipherRC2_CBC_40:
sl@0
   158
		case ECipherRC2_CBC_128:
sl@0
   159
		case ECipherRC2_CBC_40_16:
sl@0
   160
		case ECipherRC2_CBC_128_16:
sl@0
   161
			algid = CASN1EncObjectIdentifier::NewLC(KRC2CBC);
sl@0
   162
			break;
sl@0
   163
		default:
sl@0
   164
			User::Leave(KErrNotSupported);
sl@0
   165
			break;
sl@0
   166
		}
sl@0
   167
	seq4->AddChildL(algid);
sl@0
   168
	CleanupStack::Pop(algid);
sl@0
   169
sl@0
   170
	CASN1EncSequence* seq5 = 0;
sl@0
   171
	CASN1EncInt* keysize1 = 0;
sl@0
   172
	CASN1EncOctetString* iv = 0;
sl@0
   173
	switch(aParms.Cipher())
sl@0
   174
		{
sl@0
   175
		case ECipherDES_CBC:
sl@0
   176
		case ECipher3DES_CBC:
sl@0
   177
			iv = CASN1EncOctetString::NewLC(aParms.IV());
sl@0
   178
			seq4->AddChildL(iv);
sl@0
   179
			CleanupStack::Pop(iv);
sl@0
   180
			break;
sl@0
   181
		case ECipherRC2_CBC_40:
sl@0
   182
		case ECipherRC2_CBC_40_16:
sl@0
   183
			seq5 = CASN1EncSequence::NewLC();
sl@0
   184
			seq4->AddChildL(seq5);
sl@0
   185
			CleanupStack::Pop(seq5);
sl@0
   186
sl@0
   187
			keysize1 = CASN1EncInt::NewLC(160); //encoding for 40 bit
sl@0
   188
			seq5->AddChildL(keysize1);
sl@0
   189
			CleanupStack::Pop(keysize1);
sl@0
   190
sl@0
   191
			iv = CASN1EncOctetString::NewLC(aParms.IV());
sl@0
   192
			seq5->AddChildL(iv);
sl@0
   193
			CleanupStack::Pop(iv);
sl@0
   194
			break;
sl@0
   195
		case ECipherRC2_CBC_128:
sl@0
   196
		case ECipherRC2_CBC_128_16:
sl@0
   197
			seq5 = CASN1EncSequence::NewLC();
sl@0
   198
			seq4->AddChildL(seq5);
sl@0
   199
			CleanupStack::Pop(seq5);
sl@0
   200
			
sl@0
   201
			keysize1 = CASN1EncInt::NewLC(58); //encoding for 128 bit
sl@0
   202
			seq5->AddChildL(keysize1);
sl@0
   203
			CleanupStack::Pop(keysize1);
sl@0
   204
sl@0
   205
			iv = CASN1EncOctetString::NewLC(aParms.IV());
sl@0
   206
			seq5->AddChildL(iv);
sl@0
   207
			CleanupStack::Pop(iv);
sl@0
   208
			break;
sl@0
   209
		default:
sl@0
   210
			User::Leave(KErrNotSupported);
sl@0
   211
			break;
sl@0
   212
		}
sl@0
   213
	CleanupStack::Pop(seq);
sl@0
   214
	return seq;
sl@0
   215
	}
sl@0
   216
sl@0
   217
EXPORT_C CPBEncryptParms* TASN1DecPKCS5::DecodeDERL(const TDesC8& aBinaryData)
sl@0
   218
	{
sl@0
   219
	TASN1DecGeneric seqGen(aBinaryData);
sl@0
   220
	seqGen.InitL();
sl@0
   221
	if (seqGen.Tag() != EASN1Sequence)
sl@0
   222
		{
sl@0
   223
		User::Leave(KErrArgument);
sl@0
   224
		}
sl@0
   225
	
sl@0
   226
	//Decode the Algorithm Identifier Sequence
sl@0
   227
	TASN1DecSequence seq;
sl@0
   228
	CArrayPtrFlat<TASN1DecGeneric>* seqContents = seq.DecodeDERLC(seqGen);
sl@0
   229
sl@0
   230
	//PbeAlgorithm Id
sl@0
   231
	if (seqContents->At(0)->Tag() != EASN1ObjectIdentifier)
sl@0
   232
		{
sl@0
   233
		User::Leave(KErrArgument);
sl@0
   234
		}	
sl@0
   235
	CPBEncryptParms* params = NULL;	
sl@0
   236
	TASN1DecObjectIdentifier oid;
sl@0
   237
	HBufC* oiddes = oid.DecodeDERL(*(seqContents->At(0)));
sl@0
   238
	CleanupStack::PushL(oiddes);
sl@0
   239
	//Algorithm Id is a pkcs-12Pbe Algorithm Id.
sl@0
   240
	if(*oiddes != Kpkcs5PBES2)
sl@0
   241
		{
sl@0
   242
		// Initialise to impossible value
sl@0
   243
		TPBECipher cipher = (TPBECipher) -1; 
sl@0
   244
		// Pbe12Algorithm Ids
sl@0
   245
		if(*oiddes == KPbeWithSHA1And128BitRC4)
sl@0
   246
			{
sl@0
   247
			cipher = ECipherARC4_128;
sl@0
   248
			}
sl@0
   249
		else if(*oiddes == KPbeWithSHA1And40BitRC4)
sl@0
   250
			{
sl@0
   251
			cipher = ECipherARC4_40;
sl@0
   252
			}
sl@0
   253
		else if(*oiddes == KPbeWithSHA1And3_KeyTripleDES_CBC)
sl@0
   254
			{
sl@0
   255
			cipher = ECipher3DES_CBC;
sl@0
   256
			}
sl@0
   257
		else if(*oiddes == KPbeWithSHA1And2_KeyTripleDES_CBC)
sl@0
   258
			{
sl@0
   259
			cipher = ECipher2Key3DES_CBC;
sl@0
   260
			}
sl@0
   261
		else if(*oiddes == KPbeWithSHA1And128BitRC2_CBC)
sl@0
   262
			{
sl@0
   263
			cipher = ECipherRC2_CBC_128_16; 
sl@0
   264
			}
sl@0
   265
		else if(*oiddes == KPbeWithSHA1And40BitRC2_CBC)
sl@0
   266
			{
sl@0
   267
			cipher = ECipherRC2_CBC_40_5; 
sl@0
   268
			}
sl@0
   269
	    else
sl@0
   270
        	{
sl@0
   271
        	User::Leave(KErrNotSupported);
sl@0
   272
        	}	 
sl@0
   273
        
sl@0
   274
        TInt seqContentsCount = seqContents->Count();
sl@0
   275
		
sl@0
   276
		//All pkcs-12Pbe algorithms require the Algorithm Parameters.
sl@0
   277
		//Algorithm Parameters are not OPTIONAL for pkcs-12Pbe algorithms.
sl@0
   278
		
sl@0
   279
		//seqContentsCount should be equal to 2.That is, the Algorithm Id 
sl@0
   280
		//and associated Algorithm Parameters have to be present.
sl@0
   281
		if(seqContentsCount != 2)
sl@0
   282
			{
sl@0
   283
			User::Leave(KErrArgument);	
sl@0
   284
			}
sl@0
   285
		//This if statement checks if the pkcs-12PbeParams Sequence is present in the 
sl@0
   286
		//AlgorithmIdentifier Sequence Since pkcs-12PbeParams are OPTIONAL
sl@0
   287
		else 
sl@0
   288
			{
sl@0
   289
			//Set the Initialization vector size to 8 bytes.
sl@0
   290
			TBuf8<KIvSize> iv(KIvSize);
sl@0
   291
			// Initialized to NULL, if salt is not present.
sl@0
   292
			TPtrC8 salt;
sl@0
   293
			TInt iterations; 
sl@0
   294
sl@0
   295
			const TASN1DecGeneric* seqContentsAt1 = seqContents->At(1);
sl@0
   296
			if (seqContentsAt1->Tag() != EASN1Sequence || seqContentsAt1->Class() != EUniversal)
sl@0
   297
				{
sl@0
   298
				User::Leave(KErrArgument);
sl@0
   299
				}
sl@0
   300
				
sl@0
   301
			CArrayPtrFlat<TASN1DecGeneric>* seq1Contents = seq.DecodeDERLC(*seqContentsAt1);
sl@0
   302
			const TASN1DecGeneric* seq1ContentsAt0 = seq1Contents->At(0);
sl@0
   303
			if (seq1ContentsAt0->Tag() != EASN1OctetString || seq1ContentsAt0->Class() != EUniversal)
sl@0
   304
				{
sl@0
   305
				User::Leave(KErrArgument);
sl@0
   306
				}
sl@0
   307
			salt.Set(seq1ContentsAt0->GetContentDER());
sl@0
   308
			const TASN1DecGeneric* seq1ContentsAt1 = seq1Contents->At(1);
sl@0
   309
			if (seq1ContentsAt1->Tag() != EASN1Integer || seq1ContentsAt1->Class() != EUniversal)
sl@0
   310
				{
sl@0
   311
				User::Leave(KErrArgument);
sl@0
   312
				}
sl@0
   313
			TASN1DecInteger integer;
sl@0
   314
			iterations = integer.DecodeDERShortL(*seq1ContentsAt1);
sl@0
   315
			if (iterations <= 0)
sl@0
   316
				{
sl@0
   317
				User::Leave(KErrArgument);
sl@0
   318
				}
sl@0
   319
			params = CPBEncryptParms::NewL(cipher, salt, iv, iterations);
sl@0
   320
			params->SetKdf(CPBEncryptParms::EKdfPkcs12);
sl@0
   321
			CleanupStack::PopAndDestroy(seq1Contents);
sl@0
   322
			}
sl@0
   323
		}
sl@0
   324
	//Algorithm Id is a pkcs-5Pbe Algorithm Id.
sl@0
   325
   	 else if (*oiddes == Kpkcs5PBES2)
sl@0
   326
    	{
sl@0
   327
    	if (seqContents->At(1)->Tag() != EASN1Sequence)
sl@0
   328
			{
sl@0
   329
			User::Leave(KErrArgument);
sl@0
   330
			}
sl@0
   331
		CArrayPtrFlat<TASN1DecGeneric>* seq1Contents = seq.DecodeDERLC(*(seqContents->At(1)));
sl@0
   332
sl@0
   333
		if (seq1Contents->At(0)->Tag() != EASN1Sequence)
sl@0
   334
			{
sl@0
   335
			User::Leave(KErrArgument);
sl@0
   336
			}
sl@0
   337
		CArrayPtrFlat<TASN1DecGeneric>* seq2Contents = seq.DecodeDERLC(*(seq1Contents->At(0)));
sl@0
   338
sl@0
   339
		if (seq2Contents->At(0)->Tag() != EASN1ObjectIdentifier)
sl@0
   340
			{
sl@0
   341
			User::Leave(KErrArgument);
sl@0
   342
			}
sl@0
   343
		HBufC* oid1des = oid.DecodeDERL(*(seq2Contents->At(0)));
sl@0
   344
		CleanupStack::PushL(oid1des);
sl@0
   345
		
sl@0
   346
		if(*oid1des != Kpkcs5PBKDF2)
sl@0
   347
			{
sl@0
   348
			User::Leave(KErrNotSupported);
sl@0
   349
			}
sl@0
   350
		if (seq2Contents->At(1)->Tag() != EASN1Sequence)
sl@0
   351
			{
sl@0
   352
			User::Leave(KErrArgument);
sl@0
   353
			}
sl@0
   354
		CArrayPtrFlat<TASN1DecGeneric>* seq3Contents = seq.DecodeDERLC(*(seq2Contents->At(1)));
sl@0
   355
sl@0
   356
		if (seq3Contents->At(0)->Tag() != EASN1OctetString)
sl@0
   357
			{
sl@0
   358
			User::Leave(KErrArgument);
sl@0
   359
			}
sl@0
   360
		TASN1DecOctetString octet;
sl@0
   361
		HBufC8* salt = octet.DecodeDERL(*(seq3Contents->At(0)));
sl@0
   362
		CleanupStack::PushL(salt);
sl@0
   363
		
sl@0
   364
		if (seq3Contents->At(1)->Tag() != EASN1Integer)
sl@0
   365
			{
sl@0
   366
			User::Leave(KErrArgument);
sl@0
   367
			}
sl@0
   368
		TASN1DecInteger integer;
sl@0
   369
		TInt iterations = integer.DecodeDERShortL(*(seq3Contents->At(1)));
sl@0
   370
sl@0
   371
		if (seq1Contents->At(1)->Tag() != EASN1Sequence)
sl@0
   372
			{
sl@0
   373
			User::Leave(KErrArgument);
sl@0
   374
			}
sl@0
   375
		CArrayPtrFlat<TASN1DecGeneric>* seq4Contents = seq.DecodeDERLC(*(seq1Contents->At(1)));
sl@0
   376
	
sl@0
   377
		TPBECipher cipher = (TPBECipher) -1; // Initialise to impossible value
sl@0
   378
		if (seq4Contents->At(0)->Tag() != EASN1ObjectIdentifier)
sl@0
   379
			{
sl@0
   380
			User::Leave(KErrArgument);
sl@0
   381
			}
sl@0
   382
		HBufC* oid2des = oid.DecodeDERL(*(seq4Contents->At(0)));
sl@0
   383
		CleanupStack::PushL(oid2des);
sl@0
   384
		
sl@0
   385
		CArrayPtrFlat<TASN1DecGeneric>* seq5Contents = 0; 
sl@0
   386
sl@0
   387
		if(*oid2des == K3DESCBC)
sl@0
   388
			{
sl@0
   389
			cipher = ECipher3DES_CBC;
sl@0
   390
		CleanupStack::PushL(seq5Contents);
sl@0
   391
			}
sl@0
   392
		else if(*oid2des == KDESCBC)
sl@0
   393
			{
sl@0
   394
			cipher = ECipherDES_CBC;
sl@0
   395
		CleanupStack::PushL(seq5Contents);
sl@0
   396
			}
sl@0
   397
		else if(*oid2des == KRC2CBC)
sl@0
   398
			{
sl@0
   399
			// RC2 has an additional parameter, the effective key lenght in octets.
sl@0
   400
			if (seq3Contents->At(2)->Tag() != EASN1Integer)
sl@0
   401
				{
sl@0
   402
				User::Leave(KErrArgument);
sl@0
   403
				}		
sl@0
   404
			TInt effectiveKeyLength =  integer.DecodeDERShortL(*(seq3Contents->At(2)));
sl@0
   405
sl@0
   406
			if (seq4Contents->At(1)->Tag() != EASN1Sequence)
sl@0
   407
				{
sl@0
   408
				User::Leave(KErrArgument);
sl@0
   409
				}
sl@0
   410
			seq5Contents = seq.DecodeDERLC(*(seq4Contents->At(1)));
sl@0
   411
			if (seq5Contents->At(0)->Tag() != EASN1Integer)
sl@0
   412
				{
sl@0
   413
				User::Leave(KErrArgument);
sl@0
   414
				}
sl@0
   415
			TInt keysize = integer.DecodeDERShortL(*(seq5Contents->At(0)));
sl@0
   416
			switch(keysize)
sl@0
   417
				{
sl@0
   418
				// These values come from the PKCS#5 v2 specs
sl@0
   419
				case 160:
sl@0
   420
					if (effectiveKeyLength == 16)
sl@0
   421
						{
sl@0
   422
						cipher = ECipherRC2_CBC_40_16;					
sl@0
   423
						}
sl@0
   424
					else 
sl@0
   425
						{
sl@0
   426
						if (effectiveKeyLength == 128)
sl@0
   427
							{
sl@0
   428
							cipher = ECipherRC2_CBC_40;
sl@0
   429
							}
sl@0
   430
						else 
sl@0
   431
							{
sl@0
   432
							User::Leave(KErrNotSupported); // Unsupported effective key length!						
sl@0
   433
							}
sl@0
   434
						}
sl@0
   435
					break;
sl@0
   436
				case 58:
sl@0
   437
					if (effectiveKeyLength == 16)
sl@0
   438
						{
sl@0
   439
						cipher = ECipherRC2_CBC_128_16;					
sl@0
   440
						}
sl@0
   441
					else 
sl@0
   442
						{
sl@0
   443
						if (effectiveKeyLength == 128)
sl@0
   444
							{
sl@0
   445
							cipher = ECipherRC2_CBC_128;
sl@0
   446
							}
sl@0
   447
						else 
sl@0
   448
							{
sl@0
   449
							User::Leave(KErrNotSupported); // Unsupported effective key length!						
sl@0
   450
							}
sl@0
   451
						}			
sl@0
   452
					break;
sl@0
   453
				case 120:
sl@0
   454
					//would be RC_CBC_64 but we don't support that
sl@0
   455
				default:
sl@0
   456
					User::Leave(KErrNotSupported);
sl@0
   457
					break;
sl@0
   458
				}
sl@0
   459
			}
sl@0
   460
		else 
sl@0
   461
			{
sl@0
   462
			User::Leave(KErrNotSupported);
sl@0
   463
			}	
sl@0
   464
sl@0
   465
		HBufC8* iv = 0;
sl@0
   466
		switch(cipher)
sl@0
   467
			{
sl@0
   468
			case ECipher3DES_CBC:
sl@0
   469
			case ECipherDES_CBC:
sl@0
   470
				if (seq4Contents->At(1)->Tag() != EASN1OctetString)
sl@0
   471
					{
sl@0
   472
					User::Leave(KErrArgument);
sl@0
   473
					}
sl@0
   474
				iv = octet.DecodeDERL(*(seq4Contents->At(1)));	
sl@0
   475
			CleanupStack::PushL(iv);
sl@0
   476
				break;
sl@0
   477
			case ECipherRC2_CBC_40:
sl@0
   478
			case ECipherRC2_CBC_128:
sl@0
   479
			case ECipherRC2_CBC_40_16:
sl@0
   480
			case ECipherRC2_CBC_128_16:	
sl@0
   481
				if (seq5Contents->At(1)->Tag() != EASN1OctetString)
sl@0
   482
					{
sl@0
   483
					User::Leave(KErrArgument);
sl@0
   484
					}
sl@0
   485
				iv = octet.DecodeDERL(*(seq5Contents->At(1)));
sl@0
   486
			CleanupStack::PushL(iv);
sl@0
   487
				break;
sl@0
   488
			default:
sl@0
   489
				User::Leave(KErrNotSupported);
sl@0
   490
				break;
sl@0
   491
			}
sl@0
   492
sl@0
   493
		params = CPBEncryptParms::NewL(cipher, *salt, *iv,
sl@0
   494
		iterations);
sl@0
   495
	CleanupStack::PopAndDestroy(9); //iv, seq5contents, oid2des, seq4Contents,
sl@0
   496
	//salt, seq3Contents, oid1des, seq2Contents, seq1Contents
sl@0
   497
    	}
sl@0
   498
	else
sl@0
   499
		{
sl@0
   500
		User::Leave(KErrNotSupported);
sl@0
   501
		}
sl@0
   502
	CleanupStack::PopAndDestroy(2, seqContents);
sl@0
   503
	return params;
sl@0
   504
	}