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