os/security/cryptoservices/certificateandkeymgmt/pkixcertbase/pkixCertChain.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) 1998-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 <pkixcertchain.h>
sl@0
    20
#include "pkixcertchainao.h"
sl@0
    21
#include "pkixCons.h"
sl@0
    22
#include "pkixcertstate.h"
sl@0
    23
#include "pkixcerts.h"
sl@0
    24
sl@0
    25
//**********************************************************************************//
sl@0
    26
EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewL(MCertStore& aCertStore,
sl@0
    27
													  const TPtrC8& aEncodedCerts, 
sl@0
    28
													  const TUid aClient)
sl@0
    29
	{
sl@0
    30
	CPKIXCertChainBase* self = CPKIXCertChainBase::NewLC(aCertStore, aEncodedCerts, aClient);
sl@0
    31
	CleanupStack::Pop(self);
sl@0
    32
	return self;
sl@0
    33
	}
sl@0
    34
sl@0
    35
EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewLC(MCertStore& aCertStore,
sl@0
    36
													   const TPtrC8& aEncodedCerts,
sl@0
    37
													   const TUid aClient)
sl@0
    38
	{
sl@0
    39
	CPKIXCertChainBase* self = new(ELeave) CPKIXCertChainBase();
sl@0
    40
	CleanupStack::PushL(self);
sl@0
    41
	self->ConstructL(aCertStore, aEncodedCerts, aClient);
sl@0
    42
	return self;
sl@0
    43
	}
sl@0
    44
sl@0
    45
EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewL(MCertStore& aCertStore,
sl@0
    46
													  const TPtrC8& aEncodedCerts,
sl@0
    47
													  const RPointerArray<CX509Certificate>& aRootCerts)
sl@0
    48
	{
sl@0
    49
	CPKIXCertChainBase* self = CPKIXCertChainBase::NewLC(aCertStore, aEncodedCerts, aRootCerts);
sl@0
    50
	CleanupStack::Pop(self);
sl@0
    51
	return self;
sl@0
    52
	}
sl@0
    53
sl@0
    54
EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewLC(MCertStore& aCertStore,
sl@0
    55
													   const TPtrC8& aEncodedCerts,
sl@0
    56
													   const RPointerArray<CX509Certificate>& aRootCerts)
sl@0
    57
	{
sl@0
    58
	CPKIXCertChainBase* self = new(ELeave) CPKIXCertChainBase();
sl@0
    59
	CleanupStack::PushL(self);
sl@0
    60
	self->ConstructL(aCertStore, aEncodedCerts, aRootCerts);
sl@0
    61
	return self;
sl@0
    62
	}
sl@0
    63
sl@0
    64
EXPORT_C CPKIXCertChainBase::~CPKIXCertChainBase()
sl@0
    65
	{
sl@0
    66
	iIntermediateCerts.ResetAndDestroy();
sl@0
    67
	iIntermediateCerts.Close();
sl@0
    68
	iSupportedCriticalExts.Close();
sl@0
    69
	
sl@0
    70
	delete iActiveObject;
sl@0
    71
	}
sl@0
    72
sl@0
    73
//end of ctors & dtor
sl@0
    74
sl@0
    75
EXPORT_C void CPKIXCertChainBase::ValidateL(CPKIXValidationResultBase& aValidationResult,
sl@0
    76
										const TTime& aValidationTime,
sl@0
    77
										TRequestStatus& aStatus)
sl@0
    78
	{
sl@0
    79
	iActiveObject->ValidateL(aValidationResult, aValidationTime, NULL, aStatus);
sl@0
    80
	}
sl@0
    81
sl@0
    82
EXPORT_C void CPKIXCertChainBase::ValidateL(CPKIXValidationResultBase& aValidationResult,
sl@0
    83
										const TTime& aValidationTime,								 
sl@0
    84
										const CArrayPtr<HBufC>& aInitialPolicies,
sl@0
    85
										TRequestStatus& aStatus)
sl@0
    86
	{
sl@0
    87
	iActiveObject->ValidateL(aValidationResult, aValidationTime, &aInitialPolicies, aStatus);
sl@0
    88
	}
sl@0
    89
sl@0
    90
EXPORT_C void CPKIXCertChainBase::CancelValidate()
sl@0
    91
	{
sl@0
    92
	iActiveObject->CancelValidate();
sl@0
    93
	}
sl@0
    94
sl@0
    95
EXPORT_C TBool CPKIXCertChainBase::ChainHasRoot() const
sl@0
    96
	{
sl@0
    97
	return iChainHasRoot;
sl@0
    98
	}
sl@0
    99
sl@0
   100
EXPORT_C void CPKIXCertChainBase::AddCertL(const TPtrC8& aEncodedCerts)
sl@0
   101
	{
sl@0
   102
	AddIntermediateCertsL(aEncodedCerts);
sl@0
   103
	}
sl@0
   104
sl@0
   105
EXPORT_C const RPointerArray<TDesC>& CPKIXCertChainBase::SupportedCriticalExtensions() const
sl@0
   106
	{
sl@0
   107
	return iSupportedCriticalExts;
sl@0
   108
	}
sl@0
   109
sl@0
   110
EXPORT_C void CPKIXCertChainBase::AddSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids)
sl@0
   111
	{
sl@0
   112
	TBool notPresent;
sl@0
   113
	TInt count = aCriticalExtOids.Count();
sl@0
   114
	for (TInt x=0; x < count; ++x)
sl@0
   115
		{
sl@0
   116
		notPresent = ETrue;
sl@0
   117
		for (TInt y=0; y < iSupportedCriticalExts.Count(); ++y)
sl@0
   118
			{
sl@0
   119
			if (*aCriticalExtOids[x] == *iSupportedCriticalExts[y])
sl@0
   120
				{
sl@0
   121
				notPresent = EFalse;
sl@0
   122
				break;
sl@0
   123
				}
sl@0
   124
			}
sl@0
   125
		if (notPresent)
sl@0
   126
			{
sl@0
   127
			iSupportedCriticalExts.AppendL(aCriticalExtOids[x]);
sl@0
   128
			}
sl@0
   129
		}
sl@0
   130
	}
sl@0
   131
sl@0
   132
EXPORT_C void CPKIXCertChainBase::RemoveSupportedCriticalExtensions(const RPointerArray<TDesC>& aCriticalExtOids)
sl@0
   133
	{
sl@0
   134
	TInt count = iSupportedCriticalExts.Count();
sl@0
   135
	TInt newCount = aCriticalExtOids.Count();
sl@0
   136
	if (count > 0)
sl@0
   137
		{
sl@0
   138
		for (TInt x=count - 1; x >= 0; --x)
sl@0
   139
			{
sl@0
   140
			for (TInt y=0; y < newCount; ++y)
sl@0
   141
				{
sl@0
   142
				if (*aCriticalExtOids[y] == *iSupportedCriticalExts[x])
sl@0
   143
					{
sl@0
   144
					iSupportedCriticalExts.Remove(x);
sl@0
   145
					break;
sl@0
   146
					}
sl@0
   147
				}
sl@0
   148
			}
sl@0
   149
		}
sl@0
   150
	}
sl@0
   151
sl@0
   152
EXPORT_C void CPKIXCertChainBase::SetSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids)
sl@0
   153
	{
sl@0
   154
	iSupportedCriticalExts.Reset();
sl@0
   155
	AddSupportedCriticalExtensionsL(aCriticalExtOids);
sl@0
   156
	}
sl@0
   157
sl@0
   158
EXPORT_C void CPKIXCertChainBase::ResetSupportedCriticalExtsToDefaultL()
sl@0
   159
	{
sl@0
   160
	iSupportedCriticalExts.Reset();
sl@0
   161
	// standard X.509 extensions
sl@0
   162
	iSupportedCriticalExts.AppendL(&KExtendedKeyUsage);
sl@0
   163
	iSupportedCriticalExts.AppendL(&KPolicyMapping);		// RFC - MUST be non-critical
sl@0
   164
	iSupportedCriticalExts.AppendL(&KSubjectAltName);
sl@0
   165
	iSupportedCriticalExts.AppendL(&KKeyUsage);	
sl@0
   166
	iSupportedCriticalExts.AppendL(&KBasicConstraints);
sl@0
   167
	iSupportedCriticalExts.AppendL(&KNameConstraints);
sl@0
   168
	iSupportedCriticalExts.AppendL(&KPolicyConstraints);
sl@0
   169
	iSupportedCriticalExts.AppendL(&KCertPolicies);	
sl@0
   170
	iSupportedCriticalExts.AppendL(&KInhibitAnyPolicy);
sl@0
   171
	// Symbian critical extensions
sl@0
   172
	iSupportedCriticalExts.AppendL(&KDeviceIdListConstraint);
sl@0
   173
	iSupportedCriticalExts.AppendL(&KSidListConstraint);
sl@0
   174
	iSupportedCriticalExts.AppendL(&KVidListConstraint);
sl@0
   175
	iSupportedCriticalExts.AppendL(&KCapabilitiesConstraint);
sl@0
   176
	}
sl@0
   177
sl@0
   178
sl@0
   179
EXPORT_C void CPKIXCertChainBase::SetValidityPeriodCheckFatal(TBool aIsFatal)
sl@0
   180
	{
sl@0
   181
	iDateTimeCheckFatal = aIsFatal;
sl@0
   182
	}
sl@0
   183
sl@0
   184
sl@0
   185
EXPORT_C TBool CPKIXCertChainBase::ValidityPeriodCheckFatal() const
sl@0
   186
	{
sl@0
   187
	return iDateTimeCheckFatal;
sl@0
   188
	}
sl@0
   189
sl@0
   190
//private functions
sl@0
   191
//************************************************************************//
sl@0
   192
sl@0
   193
EXPORT_C CPKIXCertChainBase::CPKIXCertChainBase()
sl@0
   194
	: iChainHasRoot(EFalse), iDateTimeCheckFatal(ETrue)
sl@0
   195
	{
sl@0
   196
	}
sl@0
   197
sl@0
   198
EXPORT_C void CPKIXCertChainBase::ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, 
sl@0
   199
											 TUid aClient)
sl@0
   200
	{
sl@0
   201
	iActiveObject = CPKIXCertChainAO::NewL(aCertStore, *this, aClient);
sl@0
   202
	DoConstructL(aEncodedCerts);
sl@0
   203
	}
sl@0
   204
sl@0
   205
/**
sl@0
   206
 * Second-phase constructor
sl@0
   207
 * This constructor takes a set of root certificates we trust. We don't take into account 
sl@0
   208
 * the certificates in the certificate store because we are not interested in the
sl@0
   209
 * trust model of that store (where each certificates comes with a set of uid of the 
sl@0
   210
 * applications that trust this certificate)
sl@0
   211
 * this is consistent with the fact that in FindIssuer, we only look for non-root
sl@0
   212
 * certs in the store
sl@0
   213
 */
sl@0
   214
EXPORT_C void CPKIXCertChainBase::ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
sl@0
   215
											 const RPointerArray<CX509Certificate>& aRootCerts)
sl@0
   216
	{
sl@0
   217
	iActiveObject = CPKIXCertChainAO::NewL(aCertStore, *this, aRootCerts);
sl@0
   218
	DoConstructL(aEncodedCerts);
sl@0
   219
	}
sl@0
   220
sl@0
   221
void CPKIXCertChainBase::DoConstructL(const TPtrC8& aEncodedCerts)
sl@0
   222
	{
sl@0
   223
	iChain = new(ELeave) CArrayPtrFlat<CX509Certificate> (1);
sl@0
   224
sl@0
   225
	TInt pos = 0;
sl@0
   226
	CX509Certificate* eeCert = CX509Certificate::NewLC(aEncodedCerts, pos);
sl@0
   227
	iChain->AppendL(eeCert);
sl@0
   228
	CleanupStack::Pop(eeCert);
sl@0
   229
	AddIntermediateCertsL(aEncodedCerts);
sl@0
   230
	ResetSupportedCriticalExtsToDefaultL();
sl@0
   231
	}
sl@0
   232
sl@0
   233
void CPKIXCertChainBase::AddIntermediateCertsL(const TPtrC8& aEncodedCerts)
sl@0
   234
	{
sl@0
   235
//decode aEncodedCerts, and add any that aren't self-signed
sl@0
   236
	TInt pos = 0;
sl@0
   237
	TInt end = aEncodedCerts.Length();
sl@0
   238
	while (pos < end)
sl@0
   239
		{
sl@0
   240
		CX509Certificate* decoded = CX509Certificate::NewLC(aEncodedCerts, pos);
sl@0
   241
		if (decoded->IsSelfSignedL())
sl@0
   242
			{
sl@0
   243
			// Then it's no use to us because it cannot be part of a chain with a
sl@0
   244
			// root certificate we trust.
sl@0
   245
			CleanupStack::PopAndDestroy(decoded);
sl@0
   246
			}
sl@0
   247
		else
sl@0
   248
			{
sl@0
   249
			User::LeaveIfError(iIntermediateCerts.Append(decoded));
sl@0
   250
			CleanupStack::Pop(decoded);
sl@0
   251
			}
sl@0
   252
		}
sl@0
   253
	}
sl@0
   254
sl@0
   255
void CPKIXCertChainBase::RemoveLastCerts(TInt aNumberOfCertsToRemove)
sl@0
   256
	{
sl@0
   257
	__ASSERT_DEBUG(iChain->Count() >= aNumberOfCertsToRemove,
sl@0
   258
		User::Panic(_L("CPKIXCertChain"), 1));
sl@0
   259
sl@0
   260
	// We don't have to change i because it is the count of the array that decreases
sl@0
   261
	for (TInt i = iChain->Count() - aNumberOfCertsToRemove; i < iChain->Count(); )
sl@0
   262
		{
sl@0
   263
		delete (*iChain)[i];
sl@0
   264
		iChain->Delete(i);
sl@0
   265
		}
sl@0
   266
	}
sl@0
   267
sl@0
   268
CArrayPtrFlat<CX509Certificate>& CPKIXCertChainBase::Chain()
sl@0
   269
	{
sl@0
   270
	__ASSERT_ALWAYS(iChain, User::Panic(_L("CPKICCertChainBase"), 1));
sl@0
   271
	return *iChain;
sl@0
   272
	}
sl@0
   273
sl@0
   274
const RPointerArray<CX509Certificate>& CPKIXCertChainBase::IntermediateCerts()
sl@0
   275
	{
sl@0
   276
	return iIntermediateCerts;
sl@0
   277
	}
sl@0
   278
sl@0
   279
TBool CPKIXCertChainBase::ChainHasRoot()
sl@0
   280
	{
sl@0
   281
	return iChainHasRoot;
sl@0
   282
	}
sl@0
   283
sl@0
   284
void CPKIXCertChainBase::SetChainHasRoot(TBool aHasRoot)
sl@0
   285
	{
sl@0
   286
	iChainHasRoot = aHasRoot;
sl@0
   287
	}