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