1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/security/cryptoservices/certificateandkeymgmt/pkixcertbase/pkixCertChain.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,287 @@
1.4 +/*
1.5 +* Copyright (c) 1998-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 <pkixcertchain.h>
1.23 +#include "pkixcertchainao.h"
1.24 +#include "pkixCons.h"
1.25 +#include "pkixcertstate.h"
1.26 +#include "pkixcerts.h"
1.27 +
1.28 +//**********************************************************************************//
1.29 +EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewL(MCertStore& aCertStore,
1.30 + const TPtrC8& aEncodedCerts,
1.31 + const TUid aClient)
1.32 + {
1.33 + CPKIXCertChainBase* self = CPKIXCertChainBase::NewLC(aCertStore, aEncodedCerts, aClient);
1.34 + CleanupStack::Pop(self);
1.35 + return self;
1.36 + }
1.37 +
1.38 +EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewLC(MCertStore& aCertStore,
1.39 + const TPtrC8& aEncodedCerts,
1.40 + const TUid aClient)
1.41 + {
1.42 + CPKIXCertChainBase* self = new(ELeave) CPKIXCertChainBase();
1.43 + CleanupStack::PushL(self);
1.44 + self->ConstructL(aCertStore, aEncodedCerts, aClient);
1.45 + return self;
1.46 + }
1.47 +
1.48 +EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewL(MCertStore& aCertStore,
1.49 + const TPtrC8& aEncodedCerts,
1.50 + const RPointerArray<CX509Certificate>& aRootCerts)
1.51 + {
1.52 + CPKIXCertChainBase* self = CPKIXCertChainBase::NewLC(aCertStore, aEncodedCerts, aRootCerts);
1.53 + CleanupStack::Pop(self);
1.54 + return self;
1.55 + }
1.56 +
1.57 +EXPORT_C CPKIXCertChainBase* CPKIXCertChainBase::NewLC(MCertStore& aCertStore,
1.58 + const TPtrC8& aEncodedCerts,
1.59 + const RPointerArray<CX509Certificate>& aRootCerts)
1.60 + {
1.61 + CPKIXCertChainBase* self = new(ELeave) CPKIXCertChainBase();
1.62 + CleanupStack::PushL(self);
1.63 + self->ConstructL(aCertStore, aEncodedCerts, aRootCerts);
1.64 + return self;
1.65 + }
1.66 +
1.67 +EXPORT_C CPKIXCertChainBase::~CPKIXCertChainBase()
1.68 + {
1.69 + iIntermediateCerts.ResetAndDestroy();
1.70 + iIntermediateCerts.Close();
1.71 + iSupportedCriticalExts.Close();
1.72 +
1.73 + delete iActiveObject;
1.74 + }
1.75 +
1.76 +//end of ctors & dtor
1.77 +
1.78 +EXPORT_C void CPKIXCertChainBase::ValidateL(CPKIXValidationResultBase& aValidationResult,
1.79 + const TTime& aValidationTime,
1.80 + TRequestStatus& aStatus)
1.81 + {
1.82 + iActiveObject->ValidateL(aValidationResult, aValidationTime, NULL, aStatus);
1.83 + }
1.84 +
1.85 +EXPORT_C void CPKIXCertChainBase::ValidateL(CPKIXValidationResultBase& aValidationResult,
1.86 + const TTime& aValidationTime,
1.87 + const CArrayPtr<HBufC>& aInitialPolicies,
1.88 + TRequestStatus& aStatus)
1.89 + {
1.90 + iActiveObject->ValidateL(aValidationResult, aValidationTime, &aInitialPolicies, aStatus);
1.91 + }
1.92 +
1.93 +EXPORT_C void CPKIXCertChainBase::CancelValidate()
1.94 + {
1.95 + iActiveObject->CancelValidate();
1.96 + }
1.97 +
1.98 +EXPORT_C TBool CPKIXCertChainBase::ChainHasRoot() const
1.99 + {
1.100 + return iChainHasRoot;
1.101 + }
1.102 +
1.103 +EXPORT_C void CPKIXCertChainBase::AddCertL(const TPtrC8& aEncodedCerts)
1.104 + {
1.105 + AddIntermediateCertsL(aEncodedCerts);
1.106 + }
1.107 +
1.108 +EXPORT_C const RPointerArray<TDesC>& CPKIXCertChainBase::SupportedCriticalExtensions() const
1.109 + {
1.110 + return iSupportedCriticalExts;
1.111 + }
1.112 +
1.113 +EXPORT_C void CPKIXCertChainBase::AddSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids)
1.114 + {
1.115 + TBool notPresent;
1.116 + TInt count = aCriticalExtOids.Count();
1.117 + for (TInt x=0; x < count; ++x)
1.118 + {
1.119 + notPresent = ETrue;
1.120 + for (TInt y=0; y < iSupportedCriticalExts.Count(); ++y)
1.121 + {
1.122 + if (*aCriticalExtOids[x] == *iSupportedCriticalExts[y])
1.123 + {
1.124 + notPresent = EFalse;
1.125 + break;
1.126 + }
1.127 + }
1.128 + if (notPresent)
1.129 + {
1.130 + iSupportedCriticalExts.AppendL(aCriticalExtOids[x]);
1.131 + }
1.132 + }
1.133 + }
1.134 +
1.135 +EXPORT_C void CPKIXCertChainBase::RemoveSupportedCriticalExtensions(const RPointerArray<TDesC>& aCriticalExtOids)
1.136 + {
1.137 + TInt count = iSupportedCriticalExts.Count();
1.138 + TInt newCount = aCriticalExtOids.Count();
1.139 + if (count > 0)
1.140 + {
1.141 + for (TInt x=count - 1; x >= 0; --x)
1.142 + {
1.143 + for (TInt y=0; y < newCount; ++y)
1.144 + {
1.145 + if (*aCriticalExtOids[y] == *iSupportedCriticalExts[x])
1.146 + {
1.147 + iSupportedCriticalExts.Remove(x);
1.148 + break;
1.149 + }
1.150 + }
1.151 + }
1.152 + }
1.153 + }
1.154 +
1.155 +EXPORT_C void CPKIXCertChainBase::SetSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids)
1.156 + {
1.157 + iSupportedCriticalExts.Reset();
1.158 + AddSupportedCriticalExtensionsL(aCriticalExtOids);
1.159 + }
1.160 +
1.161 +EXPORT_C void CPKIXCertChainBase::ResetSupportedCriticalExtsToDefaultL()
1.162 + {
1.163 + iSupportedCriticalExts.Reset();
1.164 + // standard X.509 extensions
1.165 + iSupportedCriticalExts.AppendL(&KExtendedKeyUsage);
1.166 + iSupportedCriticalExts.AppendL(&KPolicyMapping); // RFC - MUST be non-critical
1.167 + iSupportedCriticalExts.AppendL(&KSubjectAltName);
1.168 + iSupportedCriticalExts.AppendL(&KKeyUsage);
1.169 + iSupportedCriticalExts.AppendL(&KBasicConstraints);
1.170 + iSupportedCriticalExts.AppendL(&KNameConstraints);
1.171 + iSupportedCriticalExts.AppendL(&KPolicyConstraints);
1.172 + iSupportedCriticalExts.AppendL(&KCertPolicies);
1.173 + iSupportedCriticalExts.AppendL(&KInhibitAnyPolicy);
1.174 + // Symbian critical extensions
1.175 + iSupportedCriticalExts.AppendL(&KDeviceIdListConstraint);
1.176 + iSupportedCriticalExts.AppendL(&KSidListConstraint);
1.177 + iSupportedCriticalExts.AppendL(&KVidListConstraint);
1.178 + iSupportedCriticalExts.AppendL(&KCapabilitiesConstraint);
1.179 + }
1.180 +
1.181 +
1.182 +EXPORT_C void CPKIXCertChainBase::SetValidityPeriodCheckFatal(TBool aIsFatal)
1.183 + {
1.184 + iDateTimeCheckFatal = aIsFatal;
1.185 + }
1.186 +
1.187 +
1.188 +EXPORT_C TBool CPKIXCertChainBase::ValidityPeriodCheckFatal() const
1.189 + {
1.190 + return iDateTimeCheckFatal;
1.191 + }
1.192 +
1.193 +//private functions
1.194 +//************************************************************************//
1.195 +
1.196 +EXPORT_C CPKIXCertChainBase::CPKIXCertChainBase()
1.197 + : iChainHasRoot(EFalse), iDateTimeCheckFatal(ETrue)
1.198 + {
1.199 + }
1.200 +
1.201 +EXPORT_C void CPKIXCertChainBase::ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
1.202 + TUid aClient)
1.203 + {
1.204 + iActiveObject = CPKIXCertChainAO::NewL(aCertStore, *this, aClient);
1.205 + DoConstructL(aEncodedCerts);
1.206 + }
1.207 +
1.208 +/**
1.209 + * Second-phase constructor
1.210 + * This constructor takes a set of root certificates we trust. We don't take into account
1.211 + * the certificates in the certificate store because we are not interested in the
1.212 + * trust model of that store (where each certificates comes with a set of uid of the
1.213 + * applications that trust this certificate)
1.214 + * this is consistent with the fact that in FindIssuer, we only look for non-root
1.215 + * certs in the store
1.216 + */
1.217 +EXPORT_C void CPKIXCertChainBase::ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
1.218 + const RPointerArray<CX509Certificate>& aRootCerts)
1.219 + {
1.220 + iActiveObject = CPKIXCertChainAO::NewL(aCertStore, *this, aRootCerts);
1.221 + DoConstructL(aEncodedCerts);
1.222 + }
1.223 +
1.224 +void CPKIXCertChainBase::DoConstructL(const TPtrC8& aEncodedCerts)
1.225 + {
1.226 + iChain = new(ELeave) CArrayPtrFlat<CX509Certificate> (1);
1.227 +
1.228 + TInt pos = 0;
1.229 + CX509Certificate* eeCert = CX509Certificate::NewLC(aEncodedCerts, pos);
1.230 + iChain->AppendL(eeCert);
1.231 + CleanupStack::Pop(eeCert);
1.232 + AddIntermediateCertsL(aEncodedCerts);
1.233 + ResetSupportedCriticalExtsToDefaultL();
1.234 + }
1.235 +
1.236 +void CPKIXCertChainBase::AddIntermediateCertsL(const TPtrC8& aEncodedCerts)
1.237 + {
1.238 +//decode aEncodedCerts, and add any that aren't self-signed
1.239 + TInt pos = 0;
1.240 + TInt end = aEncodedCerts.Length();
1.241 + while (pos < end)
1.242 + {
1.243 + CX509Certificate* decoded = CX509Certificate::NewLC(aEncodedCerts, pos);
1.244 + if (decoded->IsSelfSignedL())
1.245 + {
1.246 + // Then it's no use to us because it cannot be part of a chain with a
1.247 + // root certificate we trust.
1.248 + CleanupStack::PopAndDestroy(decoded);
1.249 + }
1.250 + else
1.251 + {
1.252 + User::LeaveIfError(iIntermediateCerts.Append(decoded));
1.253 + CleanupStack::Pop(decoded);
1.254 + }
1.255 + }
1.256 + }
1.257 +
1.258 +void CPKIXCertChainBase::RemoveLastCerts(TInt aNumberOfCertsToRemove)
1.259 + {
1.260 + __ASSERT_DEBUG(iChain->Count() >= aNumberOfCertsToRemove,
1.261 + User::Panic(_L("CPKIXCertChain"), 1));
1.262 +
1.263 + // We don't have to change i because it is the count of the array that decreases
1.264 + for (TInt i = iChain->Count() - aNumberOfCertsToRemove; i < iChain->Count(); )
1.265 + {
1.266 + delete (*iChain)[i];
1.267 + iChain->Delete(i);
1.268 + }
1.269 + }
1.270 +
1.271 +CArrayPtrFlat<CX509Certificate>& CPKIXCertChainBase::Chain()
1.272 + {
1.273 + __ASSERT_ALWAYS(iChain, User::Panic(_L("CPKICCertChainBase"), 1));
1.274 + return *iChain;
1.275 + }
1.276 +
1.277 +const RPointerArray<CX509Certificate>& CPKIXCertChainBase::IntermediateCerts()
1.278 + {
1.279 + return iIntermediateCerts;
1.280 + }
1.281 +
1.282 +TBool CPKIXCertChainBase::ChainHasRoot()
1.283 + {
1.284 + return iChainHasRoot;
1.285 + }
1.286 +
1.287 +void CPKIXCertChainBase::SetChainHasRoot(TBool aHasRoot)
1.288 + {
1.289 + iChainHasRoot = aHasRoot;
1.290 + }