os/security/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12bags.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) 2005-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 "pkcs12bags.h"
sl@0
    20
sl@0
    21
using namespace PKCS12;
sl@0
    22
///////////////////////// KeyBag ////////////////////////////////	
sl@0
    23
sl@0
    24
CDecPkcs12KeyBag::CDecPkcs12KeyBag()
sl@0
    25
	{
sl@0
    26
	}
sl@0
    27
	
sl@0
    28
EXPORT_C CDecPkcs12KeyBag* CDecPkcs12KeyBag::NewL(const TDesC8& aSafeBagData)
sl@0
    29
	{
sl@0
    30
	CDecPkcs12KeyBag* self = new(ELeave) CDecPkcs12KeyBag;
sl@0
    31
	CleanupStack::PushL(self);
sl@0
    32
	self->ConstructL(aSafeBagData);
sl@0
    33
	CleanupStack::Pop(self);
sl@0
    34
	return self;
sl@0
    35
	}
sl@0
    36
sl@0
    37
CDecPkcs12KeyBag::~CDecPkcs12KeyBag()
sl@0
    38
	{		
sl@0
    39
	}
sl@0
    40
	
sl@0
    41
void CDecPkcs12KeyBag::ConstructL(const TDesC8& aSafeBagData)
sl@0
    42
	{
sl@0
    43
	CDecPkcs12SafeBag::ConstructL(aSafeBagData);	
sl@0
    44
	}
sl@0
    45
	
sl@0
    46
EXPORT_C CDecPKCS8Data* CDecPkcs12KeyBag::PrivateKeyInfoL() const
sl@0
    47
	{
sl@0
    48
	TASN1DecGeneric seqGen(iBagValue);
sl@0
    49
	seqGen.InitL();
sl@0
    50
	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
sl@0
    51
		{
sl@0
    52
		User::Leave(KErrArgument);
sl@0
    53
		}
sl@0
    54
			
sl@0
    55
	return TASN1DecPKCS8::DecodeDERL(seqGen.Encoding());
sl@0
    56
	}
sl@0
    57
		
sl@0
    58
////////////////////////// ShroudedKeyBag ////////////////////////	
sl@0
    59
CDecPkcs12ShroudedKeyBag::CDecPkcs12ShroudedKeyBag()
sl@0
    60
	{
sl@0
    61
	}
sl@0
    62
sl@0
    63
EXPORT_C CDecPkcs12ShroudedKeyBag* CDecPkcs12ShroudedKeyBag::NewL(const TDesC8& aSafeBagData)
sl@0
    64
	{
sl@0
    65
	CDecPkcs12ShroudedKeyBag* self = new(ELeave) CDecPkcs12ShroudedKeyBag;
sl@0
    66
	CleanupStack::PushL(self);
sl@0
    67
	self->ConstructL(aSafeBagData);
sl@0
    68
	CleanupStack::Pop(self);
sl@0
    69
	return self;
sl@0
    70
	}
sl@0
    71
sl@0
    72
CDecPkcs12ShroudedKeyBag::~CDecPkcs12ShroudedKeyBag()
sl@0
    73
	{
sl@0
    74
	}
sl@0
    75
	
sl@0
    76
void CDecPkcs12ShroudedKeyBag::ConstructL(const TDesC8& aSafeBagData)
sl@0
    77
	{
sl@0
    78
	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
sl@0
    79
	TASN1DecGeneric seqGen(iBagValue);
sl@0
    80
	seqGen.InitL();
sl@0
    81
	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
sl@0
    82
		{
sl@0
    83
		User::Leave(KErrArgument);
sl@0
    84
		}
sl@0
    85
	
sl@0
    86
	TASN1DecSequence dec;
sl@0
    87
	CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
sl@0
    88
	TInt seqIndex = 0;
sl@0
    89
	TInt shroudedKeyBagSeqCount = shroudedKeyBagSeq->Count();
sl@0
    90
	if (seqIndex >= shroudedKeyBagSeqCount)
sl@0
    91
		{
sl@0
    92
		User::Leave(KErrArgument);		
sl@0
    93
		}
sl@0
    94
	CleanupStack::PopAndDestroy(shroudedKeyBagSeq);
sl@0
    95
	}
sl@0
    96
sl@0
    97
EXPORT_C CDecPKCS8Data* CDecPkcs12ShroudedKeyBag::PrivateKeyInfoL(TDesC& aPassword) const
sl@0
    98
	{
sl@0
    99
	TASN1DecGeneric seqGen(iBagValue);
sl@0
   100
	seqGen.InitL();
sl@0
   101
	TASN1DecSequence dec;
sl@0
   102
	CArrayPtrFlat<TASN1DecGeneric>* shroudedKeyBagSeq = dec.DecodeDERLC(seqGen);
sl@0
   103
	// Get the first part of the sequence -> PKCS5 data
sl@0
   104
	const TASN1DecGeneric* shroudedKeyBagSeqAt0 = shroudedKeyBagSeq->At(0);
sl@0
   105
	TPtrC8 theContent(shroudedKeyBagSeqAt0->Encoding());//	expect this to be a sequence
sl@0
   106
	CPBEncryptParms* encryptParams =  TASN1DecPKCS5::DecodeDERL(theContent);
sl@0
   107
	CleanupStack::PushL(encryptParams);
sl@0
   108
	
sl@0
   109
	CPBEncryptElement* encryptElement;
sl@0
   110
	HBufC8* pkcs12Pwd = PKCS12KDF::GeneratePasswordLC(aPassword);
sl@0
   111
	if(encryptParams->Kdf() == CPBEncryptParms::EKdfPkcs12)
sl@0
   112
		{
sl@0
   113
	 	TPtrC8 iv = encryptParams->IV();
sl@0
   114
	    HBufC8* ivValue = HBufC8::NewMaxLC(iv.Length());
sl@0
   115
	    TPtr8 encryptKeyBuf = ivValue->Des();
sl@0
   116
	 		 
sl@0
   117
	 	switch(encryptParams->Cipher())	
sl@0
   118
	 		{
sl@0
   119
	 		case ECipherARC4_128:
sl@0
   120
	 		case ECipherARC4_40:
sl@0
   121
				{
sl@0
   122
	 		    //derive only key it is unnecessary to derive an IV for RC4
sl@0
   123
				break;
sl@0
   124
				}
sl@0
   125
			case ECipher3DES_CBC:
sl@0
   126
			case ECipher2Key3DES_CBC:
sl@0
   127
			case ECipherRC2_CBC_128_16:	 
sl@0
   128
			case ECipherRC2_CBC_40_5:	
sl@0
   129
				{
sl@0
   130
			    PKCS12KDF::DeriveKeyL(encryptKeyBuf, PKCS12KDF::EIDByteIV, *pkcs12Pwd, encryptParams->Salt(), encryptParams->Iterations());
sl@0
   131
				encryptParams->SetIV(encryptKeyBuf);
sl@0
   132
			    break;
sl@0
   133
				}
sl@0
   134
			default:
sl@0
   135
				{
sl@0
   136
			    User::Leave(KErrNotSupported);
sl@0
   137
			    break;
sl@0
   138
				}
sl@0
   139
	 		}
sl@0
   140
	 	CleanupStack::PopAndDestroy(ivValue);
sl@0
   141
		// Create the decryptor	
sl@0
   142
		encryptElement = CPBEncryptElement::NewLC(*pkcs12Pwd, *encryptParams);
sl@0
   143
		}
sl@0
   144
	else
sl@0
   145
		{
sl@0
   146
		TPBPassword password(aPassword);
sl@0
   147
		// Create the decryptor	
sl@0
   148
		encryptElement = CPBEncryptElement::NewLC(password.Password(), *encryptParams);	
sl@0
   149
		}
sl@0
   150
	CPBDecryptor* decryptor = encryptElement->NewDecryptLC();
sl@0
   151
	// Decrypt the final part of the sequence -> encrypted PKCS8 object
sl@0
   152
	const TASN1DecGeneric* shroudedKeyBagSeqAt1 = shroudedKeyBagSeq->At(1);
sl@0
   153
	if (shroudedKeyBagSeqAt1->Tag() != EASN1OctetString || shroudedKeyBagSeqAt1->Class() != EUniversal)
sl@0
   154
		{
sl@0
   155
		User::Leave(KErrArgument);
sl@0
   156
		}
sl@0
   157
	TPtrC8 encryptedKey(shroudedKeyBagSeqAt1->GetContentDER());
sl@0
   158
	TUint encryptLength = encryptedKey.Length();
sl@0
   159
	TUint maxDecryptLength = decryptor->MaxOutputLength(encryptLength);
sl@0
   160
	if ( maxDecryptLength <= 0 )
sl@0
   161
		{
sl@0
   162
		User::Leave(KErrGeneral);		
sl@0
   163
		}
sl@0
   164
	HBufC8* decryptedContent = HBufC8::NewLC(encryptLength);
sl@0
   165
	TPtr8 dcDes(decryptedContent->Des());
sl@0
   166
	decryptor->Process(encryptedKey, dcDes);
sl@0
   167
	
sl@0
   168
	CDecPKCS8Data* privateKeyInfo = TASN1DecPKCS8::DecodeDERL(dcDes);	
sl@0
   169
		
sl@0
   170
	CleanupStack::PopAndDestroy(6,shroudedKeyBagSeq);//shroudedKeyBagSeq, encryptParams,pkcs12Pwd
sl@0
   171
													// encryptElement, decryptor, decryptedContent.
sl@0
   172
	return privateKeyInfo;
sl@0
   173
	}
sl@0
   174
	
sl@0
   175
///////////////////////////// CertBag ///////////////////////////////
sl@0
   176
sl@0
   177
CDecPkcs12CertBag::CDecPkcs12CertBag()
sl@0
   178
	{
sl@0
   179
	}
sl@0
   180
	
sl@0
   181
EXPORT_C CDecPkcs12CertBag* CDecPkcs12CertBag::NewL(const TDesC8& aSafeBagData) 
sl@0
   182
    {
sl@0
   183
    CDecPkcs12CertBag* self = new (ELeave) CDecPkcs12CertBag;
sl@0
   184
	CleanupStack::PushL(self);
sl@0
   185
	self->ConstructL(aSafeBagData);
sl@0
   186
	CleanupStack::Pop(self);
sl@0
   187
	return self;
sl@0
   188
	}
sl@0
   189
sl@0
   190
CDecPkcs12CertBag::~CDecPkcs12CertBag()
sl@0
   191
	{	
sl@0
   192
	delete iCertId;
sl@0
   193
	}
sl@0
   194
sl@0
   195
void CDecPkcs12CertBag::ConstructL(const TDesC8& aSafeBagData)
sl@0
   196
	{
sl@0
   197
	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
sl@0
   198
	
sl@0
   199
	TASN1DecGeneric seqGen(iBagValue);
sl@0
   200
	seqGen.InitL();
sl@0
   201
		if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
sl@0
   202
		{
sl@0
   203
		User::Leave(KErrArgument);
sl@0
   204
		}
sl@0
   205
	
sl@0
   206
    TASN1DecSequence seq;
sl@0
   207
	CArrayPtr<TASN1DecGeneric>* certBagSequence = seq.DecodeDERLC(seqGen);
sl@0
   208
  	const TASN1DecGeneric* certBagSequenceAt0 = certBagSequence->At(0);
sl@0
   209
  	if (certBagSequenceAt0->Tag() != EASN1ObjectIdentifier || certBagSequenceAt0->Class() != EUniversal)
sl@0
   210
  		{
sl@0
   211
		User::Leave(KErrArgument);
sl@0
   212
		}
sl@0
   213
	  			
sl@0
   214
  	// Obtain the CertId		
sl@0
   215
  	TASN1DecObjectIdentifier oid;
sl@0
   216
  	iCertId = oid.DecodeDERL(*certBagSequenceAt0);
sl@0
   217
sl@0
   218
	const TASN1DecGeneric* certBagSequenceAt1 = certBagSequence->At(1);
sl@0
   219
	if (certBagSequenceAt1->Tag() != EASN1EOC || certBagSequenceAt1->Class() != EContextSpecific)
sl@0
   220
  		{
sl@0
   221
		User::Leave(KErrArgument);
sl@0
   222
		}
sl@0
   223
	
sl@0
   224
	TASN1DecGeneric certBagSeq(certBagSequenceAt1->GetContentDER());
sl@0
   225
	certBagSeq.InitL();
sl@0
   226
	if (certBagSeq.Tag() != EASN1OctetString || certBagSeq.Class() != EUniversal)
sl@0
   227
		{
sl@0
   228
		User::Leave(KErrArgument);
sl@0
   229
		}
sl@0
   230
	else 
sl@0
   231
		{
sl@0
   232
		iCertValue.Set(certBagSeq.GetContentDER());
sl@0
   233
		}
sl@0
   234
    CleanupStack::PopAndDestroy(certBagSequence);
sl@0
   235
	}
sl@0
   236
	
sl@0
   237
EXPORT_C const TDesC& CDecPkcs12CertBag::CertId() const
sl@0
   238
	{
sl@0
   239
	return *iCertId;	
sl@0
   240
   	}
sl@0
   241
sl@0
   242
EXPORT_C const TDesC8& CDecPkcs12CertBag::CertValue() const
sl@0
   243
   	{
sl@0
   244
   	return iCertValue;		
sl@0
   245
   	}
sl@0
   246
   	
sl@0
   247
EXPORT_C CX509Certificate* CDecPkcs12CertBag::X509CertificateL() const
sl@0
   248
	{
sl@0
   249
	return (*iCertId == KX509CertificateOID) ? CX509Certificate::NewL(iCertValue) : NULL;
sl@0
   250
	}
sl@0
   251
sl@0
   252
/////////////////////// SafeContentsBag ///////////////////////
sl@0
   253
sl@0
   254
CDecPkcs12SafeContentsBag::CDecPkcs12SafeContentsBag()
sl@0
   255
	{
sl@0
   256
	}
sl@0
   257
	
sl@0
   258
EXPORT_C CDecPkcs12SafeContentsBag* CDecPkcs12SafeContentsBag::NewL(const TDesC8& aSafeContentsBagData)
sl@0
   259
	{
sl@0
   260
	CDecPkcs12SafeContentsBag* self = new(ELeave) CDecPkcs12SafeContentsBag;
sl@0
   261
	CleanupStack::PushL(self);
sl@0
   262
	self->ConstructL(aSafeContentsBagData);
sl@0
   263
	CleanupStack::Pop(self);
sl@0
   264
	return self;
sl@0
   265
	}
sl@0
   266
sl@0
   267
CDecPkcs12SafeContentsBag::~CDecPkcs12SafeContentsBag()
sl@0
   268
	{
sl@0
   269
	iSafeBags.ResetAndDestroy();
sl@0
   270
	iSafeBags.Close();
sl@0
   271
	}
sl@0
   272
sl@0
   273
void CDecPkcs12SafeContentsBag::ConstructL(const TDesC8& aSafeBagData)
sl@0
   274
	{
sl@0
   275
	CDecPkcs12SafeBag::ConstructL(aSafeBagData);
sl@0
   276
	// This is SafeBag Sequence containing a SafeContents Bag
sl@0
   277
	TASN1DecGeneric seqGen(iBagValue);
sl@0
   278
	seqGen.InitL();
sl@0
   279
	
sl@0
   280
	// Check if this is a Sequence
sl@0
   281
	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
sl@0
   282
		{
sl@0
   283
		User::Leave(KErrArgument);
sl@0
   284
		}
sl@0
   285
	
sl@0
   286
	TASN1DecSequence seq;
sl@0
   287
	CArrayPtrFlat<TASN1DecGeneric>* safeContentsBagSeq = seq.DecodeDERLC(seqGen);
sl@0
   288
			        
sl@0
   289
    // Find out the number of SafeBags present in the SafeContents Bag
sl@0
   290
    TInt safeContentsBagCount = safeContentsBagSeq->Count();
sl@0
   291
    const TASN1DecGeneric* safeContentsBagSeqAtPos;
sl@0
   292
    for (TInt index = 0; index < safeContentsBagCount; index++)
sl@0
   293
   		{
sl@0
   294
   		safeContentsBagSeqAtPos = safeContentsBagSeq->At(index);
sl@0
   295
   	 	if (safeContentsBagSeqAtPos->Tag() != EASN1Sequence || safeContentsBagSeqAtPos->Class() != EUniversal)
sl@0
   296
			{
sl@0
   297
			User::Leave(KErrArgument);
sl@0
   298
			}
sl@0
   299
					
sl@0
   300
		const TDesC8& safeBag(safeContentsBagSeqAtPos->Encoding());
sl@0
   301
  		// Decode this sequence, This is a SafeBag.
sl@0
   302
  		CDecPkcs12SafeBag* safeBagObject = CDecPkcs12SafeBag::NewL(safeBag);
sl@0
   303
  		CleanupStack::PushL(safeBagObject);
sl@0
   304
   	 	iSafeBags.AppendL(safeBagObject);
sl@0
   305
   	 	CleanupStack::Pop(safeBagObject);
sl@0
   306
   		}
sl@0
   307
   	CleanupStack::PopAndDestroy(safeContentsBagSeq);
sl@0
   308
    }
sl@0
   309
sl@0
   310
EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContentsBag::SafeBags() const
sl@0
   311
	 {
sl@0
   312
	 return iSafeBags;
sl@0
   313
	 } 
sl@0
   314
	 
sl@0
   315
///////////////////////////// Safe Contents ///////////////////////////////
sl@0
   316
CDecPkcs12SafeContents::CDecPkcs12SafeContents()
sl@0
   317
	{
sl@0
   318
	}
sl@0
   319
sl@0
   320
CDecPkcs12SafeContents::~CDecPkcs12SafeContents()
sl@0
   321
	{
sl@0
   322
	delete iDecryptedData;
sl@0
   323
	iSafeBags.ResetAndDestroy();
sl@0
   324
	iSafeBags.Close();
sl@0
   325
	}
sl@0
   326
sl@0
   327
EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData)
sl@0
   328
	{
sl@0
   329
	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
sl@0
   330
	CleanupStack::PushL(self);
sl@0
   331
	self->ConstructL(aSafeContentsBagData.ContentData());
sl@0
   332
	CleanupStack::Pop(self);
sl@0
   333
	return self;
sl@0
   334
	}
sl@0
   335
sl@0
   336
EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const CPKCS7ContentInfo& aSafeContentsBagData, const TDesC& aPassword)
sl@0
   337
	{
sl@0
   338
	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
sl@0
   339
	CleanupStack::PushL(self);
sl@0
   340
	self->DecodeEncryptedDataL(aSafeContentsBagData,aPassword);
sl@0
   341
	CleanupStack::Pop(self);
sl@0
   342
	return self;
sl@0
   343
	}
sl@0
   344
	
sl@0
   345
EXPORT_C CDecPkcs12SafeContents* CDecPkcs12SafeContents::NewL(const TDesC8& aSafeContent)
sl@0
   346
	{
sl@0
   347
	CDecPkcs12SafeContents* self = new(ELeave) CDecPkcs12SafeContents;
sl@0
   348
	CleanupStack::PushL(self);
sl@0
   349
	self->ConstructL(aSafeContent);
sl@0
   350
	CleanupStack::Pop(self);
sl@0
   351
	return self;
sl@0
   352
	}
sl@0
   353
sl@0
   354
void CDecPkcs12SafeContents::ConstructL(const TDesC8& aSafeContent)
sl@0
   355
	{
sl@0
   356
	TASN1DecGeneric decGen(aSafeContent);
sl@0
   357
    decGen.InitL(); 
sl@0
   358
			
sl@0
   359
	if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)      
sl@0
   360
		{
sl@0
   361
		User::Leave(KErrArgument);
sl@0
   362
		}
sl@0
   363
          		 
sl@0
   364
    TASN1DecGeneric decGen2(decGen.GetContentDER());
sl@0
   365
	decGen2.InitL(); 
sl@0
   366
			
sl@0
   367
	if(decGen2.Tag() != EASN1Sequence || decGen.Class() != EUniversal)      
sl@0
   368
		{
sl@0
   369
		User ::Leave(KErrArgument);
sl@0
   370
	    }
sl@0
   371
				
sl@0
   372
	// Decode sequence
sl@0
   373
	TASN1DecSequence seq;
sl@0
   374
 	CArrayPtr<TASN1DecGeneric>* safeBagSequences = seq.DecodeDERLC(decGen);
sl@0
   375
 	
sl@0
   376
 	// A Sequence of SafeBags are present within the SafeContents Bag Sequence
sl@0
   377
 	TInt safeBagCount = safeBagSequences->Count();
sl@0
   378
 	
sl@0
   379
 	for(TInt index = 0; index < safeBagCount; index++)
sl@0
   380
 	  	{
sl@0
   381
 	  	CDecPkcs12SafeBag* safeBag = CDecPkcs12SafeBag::NewL(safeBagSequences->At(index)->Encoding());
sl@0
   382
 	  	CleanupStack::PushL(safeBag);
sl@0
   383
 	   	iSafeBags.AppendL(safeBag);
sl@0
   384
 	   	CleanupStack::Pop(safeBag);
sl@0
   385
 	   	}	
sl@0
   386
 	CleanupStack::PopAndDestroy(safeBagSequences); // safeBagSequences
sl@0
   387
	}
sl@0
   388
sl@0
   389
void CDecPkcs12SafeContents::DecodeEncryptedDataL(const CPKCS7ContentInfo& aContentInfo, const TDesC& aPassword)
sl@0
   390
	{
sl@0
   391
	CPKCS7EncryptedDataObject* pkcs7EncryptedData = CPKCS7EncryptedDataObject::NewL(aContentInfo);
sl@0
   392
	CleanupStack::PushL(pkcs7EncryptedData);
sl@0
   393
	iDecryptedData = pkcs7EncryptedData->DecryptDataL(aPassword);	
sl@0
   394
	ConstructL(iDecryptedData->Des());
sl@0
   395
	CleanupStack::PopAndDestroy(pkcs7EncryptedData); 
sl@0
   396
	}
sl@0
   397
sl@0
   398
EXPORT_C const RPointerArray<CDecPkcs12SafeBag>& CDecPkcs12SafeContents::SafeContentsBags() const
sl@0
   399
	{
sl@0
   400
	return iSafeBags;
sl@0
   401
	}
sl@0
   402
sl@0
   403
EXPORT_C const TDesC8* CDecPkcs12SafeContents::DecryptedData() const
sl@0
   404
	{
sl@0
   405
	return iDecryptedData;	
sl@0
   406
	}
sl@0
   407