cryptoservices/certificateandkeymgmt/pkcs12/pkcs12.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 "pkcs12.h"
       
    20 
       
    21 using namespace PKCS12;
       
    22 
       
    23 CDecPkcs12::CDecPkcs12()
       
    24 	{
       
    25 	}
       
    26 	
       
    27 EXPORT_C CDecPkcs12* CDecPkcs12::NewL(const TDesC8& aRawData) 
       
    28     {
       
    29     CDecPkcs12* self = NewLC(aRawData);
       
    30     CleanupStack::Pop(self);
       
    31     return self;
       
    32     }
       
    33 
       
    34 EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(const TDesC8& aRawData) 
       
    35     { 
       
    36     CDecPkcs12* self = new (ELeave) CDecPkcs12;
       
    37     CleanupStack::PushL(self);
       
    38     self->ConstructL(aRawData);
       
    39     return self;
       
    40     }
       
    41 
       
    42 EXPORT_C CDecPkcs12* CDecPkcs12::NewL(RReadStream& aStream) 
       
    43     {
       
    44     CDecPkcs12* self = NewLC(aStream);
       
    45     CleanupStack::Pop(self);
       
    46     return self;
       
    47     }
       
    48 
       
    49 EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(RReadStream& aStream) 
       
    50     { 
       
    51     CDecPkcs12* self = new (ELeave) CDecPkcs12;
       
    52     CleanupStack::PushL(self);
       
    53     self->InternalizeL(aStream);
       
    54     return self;
       
    55     }
       
    56 
       
    57 CDecPkcs12::~CDecPkcs12()
       
    58 	{
       
    59 	iContentInfos.ResetAndDestroy();
       
    60 	iContentInfos.Close();
       
    61 	delete iAuthenticatedSafeData;
       
    62 	delete iMacData;	
       
    63 	}
       
    64     
       
    65 void CDecPkcs12::ConstructL(const TDesC8& aRawData)
       
    66 	{	
       
    67 	TASN1DecGeneric decGen(aRawData);
       
    68 	decGen.InitL();
       
    69 	if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
       
    70 		{
       
    71 		User::Leave(KErrArgument);
       
    72 		}
       
    73 		
       
    74 	// aRawData conatins PFX Sequence
       
    75 	TASN1DecSequence decSeq;
       
    76 	CArrayPtr<TASN1DecGeneric>* seqContents = decSeq.DecodeDERLC(decGen);
       
    77 
       
    78     // Check if both the version and the authSafe are present, since macData is optional, 
       
    79 	TInt pfxCount = seqContents->Count();
       
    80 	if (pfxCount > 3 || pfxCount < 2)
       
    81 		{
       
    82 		User::Leave(KErrArgument);
       
    83 		}
       
    84 				
       
    85 	// Decodes Version, Version is an Integer
       
    86 	const TASN1DecGeneric* seqContentsAt0 = seqContents->At(0);
       
    87 	if (seqContentsAt0->Tag() != EASN1Integer || seqContentsAt0->Class() != EUniversal)
       
    88 		{
       
    89 		User::Leave(KErrArgument);
       
    90 		}
       
    91 	TASN1DecInteger intDecoder;
       
    92 	iVersion = intDecoder.DecodeDERShortL(*seqContentsAt0);
       
    93 	if (iVersion != KPkcs12Version)
       
    94 		{
       
    95 		User::Leave(KErrArgument);
       
    96 		}
       
    97 	
       
    98 	// Decodes the AuthSafe, AuthSafe is a Sequence
       
    99 	// If AuthSafe is not present then leave
       
   100 	const TASN1DecGeneric* seqContentsAt1 = seqContents->At(1);
       
   101 	if(seqContentsAt1->Tag() != EASN1Sequence || seqContentsAt1->Class() != EUniversal)
       
   102 		{
       
   103 		User::Leave(KErrArgument);
       
   104 		}
       
   105 	
       
   106 	TASN1DecSequence authSafeSeq;
       
   107 	CArrayPtr<TASN1DecGeneric>* authSafeContents = authSafeSeq.DecodeDERLC(*seqContentsAt1);
       
   108 	const TASN1DecGeneric* authSafeContentsAt0 = authSafeContents->At(0);
       
   109 	if(authSafeContentsAt0->Tag() == EASN1ObjectIdentifier || authSafeContentsAt0->Class() == EUniversal)
       
   110 		{
       
   111 		TASN1DecObjectIdentifier oid;
       
   112 		HBufC* objectId = oid.DecodeDERL(*authSafeContentsAt0);
       
   113 		CleanupStack::PushL(objectId);
       
   114 		if(*objectId == KPkcs7DataOID || *objectId == KPkcs7SignedDataOID)
       
   115 			{
       
   116 			// Decode this Sequence, If there is an OID for Data/Signed Data then use PKCS7 library
       
   117 			iAuthenticatedSafeData = CPKCS7ContentInfo::NewL(seqContentsAt1->Encoding());
       
   118 			}
       
   119 		else
       
   120 			{
       
   121 			User::Leave(KErrArgument);
       
   122 			}
       
   123 		CleanupStack::PopAndDestroy(objectId);
       
   124 		}
       
   125 	// AuthSafe is absent
       
   126 	else 
       
   127 		{
       
   128 		User::Leave(KErrArgument);
       
   129 		}
       
   130 	
       
   131 	// Integrity Mode	
       
   132 	if(iAuthenticatedSafeData->ContentType() == KPkcs7Data)
       
   133 		{
       
   134 		iMode = EPasswordIntegrityMode;	
       
   135 		}
       
   136 	else if(iAuthenticatedSafeData->ContentType() == KPkcs7SignedData)
       
   137 		{
       
   138 		iMode = EPublicKeyIntegrityMode;
       
   139 		}
       
   140 	
       
   141 	TPtrC8 contentData(KNullDesC8);
       
   142 	// In case of Password Integrity Mode, ContentType is Data
       
   143 	if(iMode == EPasswordIntegrityMode)
       
   144 		{
       
   145 		// Check if MacData is present, Decodes MacData
       
   146 		if (seqContents->Count() == 3)
       
   147   			{
       
   148   			const TASN1DecGeneric* seqContentsAt2 = seqContents->At(2);
       
   149     		if (seqContentsAt2->Tag() != EASN1Null || seqContentsAt2->Class() == EUniversal)
       
   150 				{
       
   151 				iMacData = CDecPkcs12MacData::NewL(seqContentsAt2->Encoding(),iAuthenticatedSafeData->ContentData());
       
   152 			    } 
       
   153 			}
       
   154 		contentData.Set(iAuthenticatedSafeData->ContentData());
       
   155 		}
       
   156     // Public-Key Integrity Mode, ContentType is SignedData
       
   157 	else if(iMode == EPublicKeyIntegrityMode)
       
   158 		{
       
   159 		// Create a pkcs7signed data object
       
   160 		CPKCS7SignedObject* signedData = CPKCS7SignedObject::NewL(*iAuthenticatedSafeData);
       
   161 		CleanupStack::PushL(signedData);
       
   162 		// Obtain the ContentInfo present in Signed Data
       
   163 		const CPKCS7ContentInfo* contentInfo = &(signedData->ContentInfo());
       
   164 		
       
   165 		// Get the type of ContentInfo
       
   166 		if (contentInfo->ContentType() != KPkcs7Data)
       
   167 			{
       
   168 			User::Leave(KErrNotSupported);
       
   169 			}
       
   170 		contentData.Set(contentInfo->ContentData());
       
   171 		CleanupStack::PopAndDestroy(signedData);
       
   172 		}
       
   173 	else
       
   174 		{
       
   175 		User::Leave(KErrArgument);
       
   176 		}
       
   177 
       
   178 	TASN1DecGeneric decGen1(contentData);
       
   179 	decGen1.InitL(); 					
       
   180 	if(decGen1.Tag() != EASN1Sequence || decGen1.Class() != EUniversal)      
       
   181 		{
       
   182 		User::Leave(KErrArgument);
       
   183 		}
       
   184 	
       
   185 	// Desequence the ContentData present in ContentInfo which is in AuthSafe
       
   186     TASN1DecSequence seq;
       
   187     CArrayPtr<TASN1DecGeneric>* contentInfoSequences = seq.DecodeDERLC(decGen1);
       
   188     
       
   189     // The number of ContentInfos present         
       
   190     TInt contentInfoCount = contentInfoSequences->Count();
       
   191                     
       
   192     for(TInt index =0; index < contentInfoCount; index++)
       
   193     	{
       
   194         CPKCS7ContentInfo* contentInfo = CPKCS7ContentInfo::NewL(contentInfoSequences->At(index)->Encoding());
       
   195         CleanupStack::PushL(contentInfo);
       
   196         iContentInfos.AppendL(contentInfo);
       
   197         CleanupStack::Pop(contentInfo);
       
   198         }
       
   199 	CleanupStack::PopAndDestroy(3,seqContents); // seqContents, authSafeContents, contentInfoSequences
       
   200   	} 
       
   201 
       
   202 void CDecPkcs12::InternalizeL(RReadStream& aStream)
       
   203 	{
       
   204 	MStreamBuf* streamBuf = aStream.Source();
       
   205 	TInt pos = streamBuf->SizeL();
       
   206 	streamBuf->SeekL(MStreamBuf::ERead, EStreamBeginning, 0);
       
   207 	HBufC8* temp= HBufC8::NewLC(pos);	
       
   208 	TPtr8 ptr = temp->Des();	
       
   209 	aStream.ReadL(ptr,pos);	
       
   210     ConstructL(*temp);    
       
   211 	CleanupStack::PopAndDestroy(temp); 
       
   212 	}	
       
   213 
       
   214 EXPORT_C TInt CDecPkcs12::Version() const
       
   215 	{
       
   216 	return iVersion;
       
   217    	}
       
   218 
       
   219 EXPORT_C CDecPkcs12::TIntegrityMode CDecPkcs12::IntegrityMode() const
       
   220 	{
       
   221 	return iMode;
       
   222    	}
       
   223 	
       
   224 EXPORT_C const RPointerArray<CPKCS7ContentInfo>& CDecPkcs12::AuthenticatedSafeContents() const
       
   225 	{
       
   226 	return iContentInfos;
       
   227 	}
       
   228 
       
   229 EXPORT_C const CPKCS7ContentInfo& CDecPkcs12::AuthenticatedSafe() const
       
   230 	{
       
   231 	return *iAuthenticatedSafeData;
       
   232 	}
       
   233 
       
   234 EXPORT_C const CDecPkcs12MacData* CDecPkcs12::MacData() const
       
   235 	{
       
   236 	return iMacData;
       
   237 	}