os/security/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/security/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,255 @@
     1.4 +/*
     1.5 +* Copyright (c) 2005-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 "pkcs12.h"
    1.23 +#include "pkcs7signedobject.h"
    1.24 +
    1.25 +using namespace PKCS12;
    1.26 +
    1.27 +CDecPkcs12::CDecPkcs12()
    1.28 +	{
    1.29 +	}
    1.30 +	
    1.31 +EXPORT_C CDecPkcs12* CDecPkcs12::NewL(const TDesC8& aRawData) 
    1.32 +    {
    1.33 +    CDecPkcs12* self = NewLC(aRawData);
    1.34 +    CleanupStack::Pop(self);
    1.35 +    return self;
    1.36 +    }
    1.37 +
    1.38 +EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(const TDesC8& aRawData) 
    1.39 +    { 
    1.40 +    CDecPkcs12* self = new (ELeave) CDecPkcs12;
    1.41 +    CleanupStack::PushL(self);
    1.42 +    self->ConstructL(aRawData);
    1.43 +    return self;
    1.44 +    }
    1.45 +
    1.46 +EXPORT_C CDecPkcs12* CDecPkcs12::NewL(RReadStream& aStream) 
    1.47 +    {
    1.48 +    CDecPkcs12* self = NewLC(aStream);
    1.49 +    CleanupStack::Pop(self);
    1.50 +    return self;
    1.51 +    }
    1.52 +
    1.53 +EXPORT_C CDecPkcs12* CDecPkcs12::NewLC(RReadStream& aStream) 
    1.54 +    { 
    1.55 +    CDecPkcs12* self = new (ELeave) CDecPkcs12;
    1.56 +    CleanupStack::PushL(self);
    1.57 +    self->InternalizeL(aStream);
    1.58 +    return self;
    1.59 +    }
    1.60 +
    1.61 +CDecPkcs12::~CDecPkcs12()
    1.62 +	{
    1.63 +	iContentInfos.ResetAndDestroy();
    1.64 +	iContentInfos.Close();
    1.65 +	delete iAuthenticatedSafeData;
    1.66 +	delete iMacData;	
    1.67 +	}
    1.68 +    
    1.69 +void CDecPkcs12::ConstructL(const TDesC8& aRawData)
    1.70 +	{	
    1.71 +	TASN1DecGeneric decGen(aRawData);
    1.72 +	decGen.InitL();
    1.73 +	if(decGen.Tag() != EASN1Sequence || decGen.Class() != EUniversal)
    1.74 +		{
    1.75 +		User::Leave(KErrArgument);
    1.76 +		}
    1.77 +		
    1.78 +	// aRawData conatins PFX Sequence
    1.79 +	TASN1DecSequence decSeq;
    1.80 +	CArrayPtr<TASN1DecGeneric>* seqContents = decSeq.DecodeDERLC(decGen);
    1.81 +
    1.82 +    // Check if both the version and the authSafe are present, since macData is optional, 
    1.83 +	TInt pfxCount = seqContents->Count();
    1.84 +	if (pfxCount > 3 || pfxCount < 2)
    1.85 +		{
    1.86 +		User::Leave(KErrArgument);
    1.87 +		}
    1.88 +				
    1.89 +	// Decodes Version, Version is an Integer
    1.90 +	const TASN1DecGeneric* seqContentsAt0 = seqContents->At(0);
    1.91 +	if (seqContentsAt0->Tag() != EASN1Integer || seqContentsAt0->Class() != EUniversal)
    1.92 +		{
    1.93 +		User::Leave(KErrArgument);
    1.94 +		}
    1.95 +	TASN1DecInteger intDecoder;
    1.96 +	iVersion = intDecoder.DecodeDERShortL(*seqContentsAt0);
    1.97 +	if (iVersion != KPkcs12Version)
    1.98 +		{
    1.99 +		User::Leave(KErrArgument);
   1.100 +		}
   1.101 +	
   1.102 +	// Decodes the AuthSafe, AuthSafe is a Sequence
   1.103 +	// If AuthSafe is not present then leave
   1.104 +	const TASN1DecGeneric* seqContentsAt1 = seqContents->At(1);
   1.105 +	if(seqContentsAt1->Tag() != EASN1Sequence || seqContentsAt1->Class() != EUniversal)
   1.106 +		{
   1.107 +		User::Leave(KErrArgument);
   1.108 +		}
   1.109 +	
   1.110 +	TASN1DecSequence authSafeSeq;
   1.111 +	CArrayPtr<TASN1DecGeneric>* authSafeContents = authSafeSeq.DecodeDERLC(*seqContentsAt1);
   1.112 +	const TASN1DecGeneric* authSafeContentsAt0 = authSafeContents->At(0);
   1.113 +	if(authSafeContentsAt0->Tag() == EASN1ObjectIdentifier || authSafeContentsAt0->Class() == EUniversal)
   1.114 +		{
   1.115 +		TASN1DecObjectIdentifier oid;
   1.116 +		HBufC* objectId = oid.DecodeDERL(*authSafeContentsAt0);
   1.117 +		CleanupStack::PushL(objectId);
   1.118 +		if(*objectId == KPkcs7DataOID || *objectId == KPkcs7SignedDataOID)
   1.119 +			{
   1.120 +			// Decode this Sequence, If there is an OID for Data/Signed Data then use PKCS7 library
   1.121 +			iAuthenticatedSafeData = CPKCS7ContentInfo::NewL(seqContentsAt1->Encoding());
   1.122 +			}
   1.123 +		else
   1.124 +			{
   1.125 +			User::Leave(KErrArgument);
   1.126 +			}
   1.127 +		CleanupStack::PopAndDestroy(objectId);
   1.128 +		}
   1.129 +	// AuthSafe is absent
   1.130 +	else 
   1.131 +		{
   1.132 +		User::Leave(KErrArgument);
   1.133 +		}
   1.134 +	
   1.135 +	// Integrity Mode	
   1.136 +	if(iAuthenticatedSafeData->ContentType() == KPkcs7Data)
   1.137 +		{
   1.138 +		iMode = EPasswordIntegrityMode;	
   1.139 +		}
   1.140 +	else if(iAuthenticatedSafeData->ContentType() == KPkcs7SignedData)
   1.141 +		{
   1.142 +		iMode = EPublicKeyIntegrityMode;
   1.143 +		}
   1.144 +	
   1.145 +	TPtrC8 contentData(KNullDesC8);
   1.146 +	// In case of Password Integrity Mode, ContentType is Data
   1.147 +	if(iMode == EPasswordIntegrityMode)
   1.148 +		{
   1.149 +		// Check if MacData is present, Decodes MacData
   1.150 +		if (seqContents->Count() == 3)
   1.151 +  			{
   1.152 +  			const TASN1DecGeneric* seqContentsAt2 = seqContents->At(2);
   1.153 +    		if (seqContentsAt2->Tag() != EASN1Null || seqContentsAt2->Class() == EUniversal)
   1.154 +				{
   1.155 +				iMacData = CDecPkcs12MacData::NewL(seqContentsAt2->Encoding(),iAuthenticatedSafeData->ContentData());
   1.156 +			    } 
   1.157 +			}
   1.158 +		contentData.Set(iAuthenticatedSafeData->ContentData());
   1.159 +		}
   1.160 +    // Public-Key Integrity Mode, ContentType is SignedData
   1.161 +	else if(iMode == EPublicKeyIntegrityMode)
   1.162 +		{
   1.163 +		// Create a pkcs7signed data object
   1.164 +		CPKCS7SignedObject* signedData = CPKCS7SignedObject::NewL(*iAuthenticatedSafeData);
   1.165 +		CleanupStack::PushL(signedData);
   1.166 +		// Obtain the ContentInfo present in Signed Data
   1.167 +		const CPKCS7ContentInfo* contentInfo = &(signedData->ContentInfo());
   1.168 +		
   1.169 +		// Get the type of ContentInfo
   1.170 +		if (contentInfo->ContentType() != KPkcs7Data)
   1.171 +			{
   1.172 +			User::Leave(KErrNotSupported);
   1.173 +			}
   1.174 +		contentData.Set(contentInfo->ContentData());
   1.175 +		CleanupStack::PopAndDestroy(signedData);
   1.176 +		}
   1.177 +	else
   1.178 +		{
   1.179 +		User::Leave(KErrArgument);
   1.180 +		}
   1.181 +
   1.182 +	TASN1DecGeneric decGen1(contentData);
   1.183 +	decGen1.InitL(); 					
   1.184 +	if(decGen1.Tag() != EASN1Sequence || decGen1.Class() != EUniversal)      
   1.185 +		{
   1.186 +		User::Leave(KErrArgument);
   1.187 +		}
   1.188 +	
   1.189 +	// Desequence the ContentData present in ContentInfo which is in AuthSafe
   1.190 +    TASN1DecSequence seq;
   1.191 +    CArrayPtr<TASN1DecGeneric>* contentInfoSequences = seq.DecodeDERLC(decGen1);
   1.192 +    
   1.193 +    // The number of ContentInfos present         
   1.194 +    TInt contentInfoCount = contentInfoSequences->Count();
   1.195 +                    
   1.196 +    for(TInt index =0; index < contentInfoCount; index++)
   1.197 +    	{
   1.198 +        CPKCS7ContentInfo* contentInfo = CPKCS7ContentInfo::NewL(contentInfoSequences->At(index)->Encoding());
   1.199 +        CleanupStack::PushL(contentInfo);
   1.200 +        iContentInfos.AppendL(contentInfo);
   1.201 +        CleanupStack::Pop(contentInfo);
   1.202 +        }
   1.203 +	CleanupStack::PopAndDestroy(3,seqContents); // seqContents, authSafeContents, contentInfoSequences
   1.204 +  	} 
   1.205 +
   1.206 +void CDecPkcs12::InternalizeL(RReadStream& aStream)
   1.207 +	{
   1.208 +	MStreamBuf* streamBuf = aStream.Source();
   1.209 +	TInt pos = streamBuf->SizeL();
   1.210 +	streamBuf->SeekL(MStreamBuf::ERead, EStreamBeginning, 0);
   1.211 +	HBufC8* temp= HBufC8::NewLC(pos);	
   1.212 +	TPtr8 ptr = temp->Des();	
   1.213 +	aStream.ReadL(ptr,pos);	
   1.214 +    ConstructL(*temp);    
   1.215 +	CleanupStack::PopAndDestroy(temp); 
   1.216 +	}	
   1.217 +
   1.218 +EXPORT_C TInt CDecPkcs12::Version() const
   1.219 +	{
   1.220 +	return iVersion;
   1.221 +   	}
   1.222 +
   1.223 +EXPORT_C CDecPkcs12::TIntegrityMode CDecPkcs12::IntegrityMode() const
   1.224 +	{
   1.225 +	return iMode;
   1.226 +   	}
   1.227 +	
   1.228 +EXPORT_C const RPointerArray<CPKCS7ContentInfo>& CDecPkcs12::AuthenticatedSafeContents() const
   1.229 +	{
   1.230 +	return iContentInfos;
   1.231 +	}
   1.232 +
   1.233 +EXPORT_C const CPKCS7ContentInfo& CDecPkcs12::AuthenticatedSafe() const
   1.234 +	{
   1.235 +	return *iAuthenticatedSafeData;
   1.236 +	}
   1.237 +
   1.238 +EXPORT_C const CDecPkcs12MacData* CDecPkcs12::MacData() const
   1.239 +	{
   1.240 +	return iMacData;
   1.241 +	}
   1.242 +
   1.243 +
   1.244 +
   1.245 +
   1.246 +
   1.247 +
   1.248 +
   1.249 +
   1.250 +
   1.251 +
   1.252 +
   1.253 +
   1.254 +
   1.255 +
   1.256 +
   1.257 +
   1.258 +