cryptoservices/certificateandkeymgmt/pkixcertbase/pkixCertChain.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cryptoservices/certificateandkeymgmt/pkixcertbase/pkixCertChain.cpp	Wed Jul 08 11:25:26 2009 +0100
@@ -0,0 +1,287 @@
+/*
+* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+#include <pkixcertchain.h>
+#include "pkixcertchainao.h"
+#include "pkixCons.h"
+#include "pkixcertstate.h"
+#include "pkixcerts.h"
+
+//**********************************************************************************//
+EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewL(MCertStore& aCertStore,
+													  const TPtrC8& aEncodedCerts, 
+													  const TUid aClient)
+	{
+	CPKIXCertChainBase* self = CPKIXCertChainBase::NewLC(aCertStore, aEncodedCerts, aClient);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewLC(MCertStore& aCertStore,
+													   const TPtrC8& aEncodedCerts,
+													   const TUid aClient)
+	{
+	CPKIXCertChainBase* self = new(ELeave) CPKIXCertChainBase();
+	CleanupStack::PushL(self);
+	self->ConstructL(aCertStore, aEncodedCerts, aClient);
+	return self;
+	}
+
+EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewL(MCertStore& aCertStore,
+													  const TPtrC8& aEncodedCerts,
+													  const RPointerArray<CX509Certificate>& aRootCerts)
+	{
+	CPKIXCertChainBase* self = CPKIXCertChainBase::NewLC(aCertStore, aEncodedCerts, aRootCerts);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewLC(MCertStore& aCertStore,
+													   const TPtrC8& aEncodedCerts,
+													   const RPointerArray<CX509Certificate>& aRootCerts)
+	{
+	CPKIXCertChainBase* self = new(ELeave) CPKIXCertChainBase();
+	CleanupStack::PushL(self);
+	self->ConstructL(aCertStore, aEncodedCerts, aRootCerts);
+	return self;
+	}
+
+EXPORT_C CPKIXCertChainBase::~CPKIXCertChainBase()
+	{
+	iIntermediateCerts.ResetAndDestroy();
+	iIntermediateCerts.Close();
+	iSupportedCriticalExts.Close();
+	
+	delete iActiveObject;
+	}
+
+//end of ctors & dtor
+
+EXPORT_C void CPKIXCertChainBase::ValidateL(CPKIXValidationResultBase& aValidationResult,
+										const TTime& aValidationTime,
+										TRequestStatus& aStatus)
+	{
+	iActiveObject->ValidateL(aValidationResult, aValidationTime, NULL, aStatus);
+	}
+
+EXPORT_C void CPKIXCertChainBase::ValidateL(CPKIXValidationResultBase& aValidationResult,
+										const TTime& aValidationTime,								 
+										const CArrayPtr<HBufC>& aInitialPolicies,
+										TRequestStatus& aStatus)
+	{
+	iActiveObject->ValidateL(aValidationResult, aValidationTime, &aInitialPolicies, aStatus);
+	}
+
+EXPORT_C void CPKIXCertChainBase::CancelValidate()
+	{
+	iActiveObject->CancelValidate();
+	}
+
+EXPORT_C TBool CPKIXCertChainBase::ChainHasRoot() const
+	{
+	return iChainHasRoot;
+	}
+
+EXPORT_C void CPKIXCertChainBase::AddCertL(const TPtrC8& aEncodedCerts)
+	{
+	AddIntermediateCertsL(aEncodedCerts);
+	}
+
+EXPORT_C const RPointerArray<TDesC>& CPKIXCertChainBase::SupportedCriticalExtensions() const
+	{
+	return iSupportedCriticalExts;
+	}
+
+EXPORT_C void CPKIXCertChainBase::AddSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids)
+	{
+	TBool notPresent;
+	TInt count = aCriticalExtOids.Count();
+	for (TInt x=0; x < count; ++x)
+		{
+		notPresent = ETrue;
+		for (TInt y=0; y < iSupportedCriticalExts.Count(); ++y)
+			{
+			if (*aCriticalExtOids[x] == *iSupportedCriticalExts[y])
+				{
+				notPresent = EFalse;
+				break;
+				}
+			}
+		if (notPresent)
+			{
+			iSupportedCriticalExts.AppendL(aCriticalExtOids[x]);
+			}
+		}
+	}
+
+EXPORT_C void CPKIXCertChainBase::RemoveSupportedCriticalExtensions(const RPointerArray<TDesC>& aCriticalExtOids)
+	{
+	TInt count = iSupportedCriticalExts.Count();
+	TInt newCount = aCriticalExtOids.Count();
+	if (count > 0)
+		{
+		for (TInt x=count - 1; x >= 0; --x)
+			{
+			for (TInt y=0; y < newCount; ++y)
+				{
+				if (*aCriticalExtOids[y] == *iSupportedCriticalExts[x])
+					{
+					iSupportedCriticalExts.Remove(x);
+					break;
+					}
+				}
+			}
+		}
+	}
+
+EXPORT_C void CPKIXCertChainBase::SetSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids)
+	{
+	iSupportedCriticalExts.Reset();
+	AddSupportedCriticalExtensionsL(aCriticalExtOids);
+	}
+
+EXPORT_C void CPKIXCertChainBase::ResetSupportedCriticalExtsToDefaultL()
+	{
+	iSupportedCriticalExts.Reset();
+	// standard X.509 extensions
+	iSupportedCriticalExts.AppendL(&KExtendedKeyUsage);
+	iSupportedCriticalExts.AppendL(&KPolicyMapping);		// RFC - MUST be non-critical
+	iSupportedCriticalExts.AppendL(&KSubjectAltName);
+	iSupportedCriticalExts.AppendL(&KKeyUsage);	
+	iSupportedCriticalExts.AppendL(&KBasicConstraints);
+	iSupportedCriticalExts.AppendL(&KNameConstraints);
+	iSupportedCriticalExts.AppendL(&KPolicyConstraints);
+	iSupportedCriticalExts.AppendL(&KCertPolicies);	
+	iSupportedCriticalExts.AppendL(&KInhibitAnyPolicy);
+	// Symbian critical extensions
+	iSupportedCriticalExts.AppendL(&KDeviceIdListConstraint);
+	iSupportedCriticalExts.AppendL(&KSidListConstraint);
+	iSupportedCriticalExts.AppendL(&KVidListConstraint);
+	iSupportedCriticalExts.AppendL(&KCapabilitiesConstraint);
+	}
+
+
+EXPORT_C void CPKIXCertChainBase::SetValidityPeriodCheckFatal(TBool aIsFatal)
+	{
+	iDateTimeCheckFatal = aIsFatal;
+	}
+
+
+EXPORT_C TBool CPKIXCertChainBase::ValidityPeriodCheckFatal() const
+	{
+	return iDateTimeCheckFatal;
+	}
+
+//private functions
+//************************************************************************//
+
+EXPORT_C CPKIXCertChainBase::CPKIXCertChainBase()
+	: iChainHasRoot(EFalse), iDateTimeCheckFatal(ETrue)
+	{
+	}
+
+EXPORT_C void CPKIXCertChainBase::ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, 
+											 TUid aClient)
+	{
+	iActiveObject = CPKIXCertChainAO::NewL(aCertStore, *this, aClient);
+	DoConstructL(aEncodedCerts);
+	}
+
+/**
+ * Second-phase constructor
+ * This constructor takes a set of root certificates we trust. We don't take into account 
+ * the certificates in the certificate store because we are not interested in the
+ * trust model of that store (where each certificates comes with a set of uid of the 
+ * applications that trust this certificate)
+ * this is consistent with the fact that in FindIssuer, we only look for non-root
+ * certs in the store
+ */
+EXPORT_C void CPKIXCertChainBase::ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
+											 const RPointerArray<CX509Certificate>& aRootCerts)
+	{
+	iActiveObject = CPKIXCertChainAO::NewL(aCertStore, *this, aRootCerts);
+	DoConstructL(aEncodedCerts);
+	}
+
+void CPKIXCertChainBase::DoConstructL(const TPtrC8& aEncodedCerts)
+	{
+	iChain = new(ELeave) CArrayPtrFlat<CX509Certificate> (1);
+
+	TInt pos = 0;
+	CX509Certificate* eeCert = CX509Certificate::NewLC(aEncodedCerts, pos);
+	iChain->AppendL(eeCert);
+	CleanupStack::Pop(eeCert);
+	AddIntermediateCertsL(aEncodedCerts);
+	ResetSupportedCriticalExtsToDefaultL();
+	}
+
+void CPKIXCertChainBase::AddIntermediateCertsL(const TPtrC8& aEncodedCerts)
+	{
+//decode aEncodedCerts, and add any that aren't self-signed
+	TInt pos = 0;
+	TInt end = aEncodedCerts.Length();
+	while (pos < end)
+		{
+		CX509Certificate* decoded = CX509Certificate::NewLC(aEncodedCerts, pos);
+		if (decoded->IsSelfSignedL())
+			{
+			// Then it's no use to us because it cannot be part of a chain with a
+			// root certificate we trust.
+			CleanupStack::PopAndDestroy(decoded);
+			}
+		else
+			{
+			User::LeaveIfError(iIntermediateCerts.Append(decoded));
+			CleanupStack::Pop(decoded);
+			}
+		}
+	}
+
+void CPKIXCertChainBase::RemoveLastCerts(TInt aNumberOfCertsToRemove)
+	{
+	__ASSERT_DEBUG(iChain->Count() >= aNumberOfCertsToRemove,
+		User::Panic(_L("CPKIXCertChain"), 1));
+
+	// We don't have to change i because it is the count of the array that decreases
+	for (TInt i = iChain->Count() - aNumberOfCertsToRemove; i < iChain->Count(); )
+		{
+		delete (*iChain)[i];
+		iChain->Delete(i);
+		}
+	}
+
+CArrayPtrFlat<CX509Certificate>& CPKIXCertChainBase::Chain()
+	{
+	__ASSERT_ALWAYS(iChain, User::Panic(_L("CPKICCertChainBase"), 1));
+	return *iChain;
+	}
+
+const RPointerArray<CX509Certificate>& CPKIXCertChainBase::IntermediateCerts()
+	{
+	return iIntermediateCerts;
+	}
+
+TBool CPKIXCertChainBase::ChainHasRoot()
+	{
+	return iChainHasRoot;
+	}
+
+void CPKIXCertChainBase::SetChainHasRoot(TBool aHasRoot)
+	{
+	iChainHasRoot = aHasRoot;
+	}