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