First public contribution.
2 * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
4 * This component and the accompanying materials are made available
5 * under the terms of the License "Eclipse Public License v1.0"
6 * which accompanies this distribution, and is available
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
16 * PKIX certificate chain implementation
27 #ifndef __PKIXCERTCHAIN_H__
28 #define __PKIXCERTCHAIN_H__
31 #include <x509certchain.h>
32 #include <pkixvalidationresult.h>
34 //implements key validation according to RFC 2459 (PKIX cert/CRL profile), section 6
35 class CPKIXValidationState;
36 class CPKIXChainBuilder;
37 class CPKIXCertChainAO;
38 class CPKIXCertChainHelper;
42 * Base class for CPKIXCertChain
44 class CPKIXCertChainBase : public CX509CertChain
48 /** Creates a certificate chain using the binary data in aEncodedCerts.
50 * @param aCertStore The certificate store to use when looking for root certificates.
51 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
52 * The first certificate will be interpreted as the end entity certificate to
53 * be validated; subsequent certificates may be in any order and may be used
54 * by the chain as intermediate certificates, but not root certificates. The
55 * individual certificates can be retrieved since each one contains its own length.
56 * @param aClient The Uid identifying the purpose for which the chain will be used.
57 * This value will be used to select a subset of stored certificates, by way of their trust
58 * settings, to be used as candidate root certificates. */
59 IMPORT_C static CPKIXCertChainBase* NewL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
62 /** Creates a certificate chain using the binary data in aEncodedCerts, and puts
63 * a pointer to the new object onto the cleanup stack.
65 * @param aCertStore The certificate store to use when looking for root certificates.
66 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
67 * The first certificate will be interpreted as the end entity certificate to
68 * be validated; subsequent certificates may be in any order and may be used
69 * by the chain as intermediate certificates, but not root certificates. The
70 * individual certificates can be retrieved since each one contains its own length.
71 * @param aClient The Uid identifying the purpose for which the chain will be used.
72 * This value will be used to select a subset of stored certificates, by way of their trust
73 * settings, to be used as candidate root certificates. */
74 IMPORT_C static CPKIXCertChainBase* NewLC(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
77 /** Creates a certificate chain using the binary data in aEncodedCerts.
79 * @param aCertStore The certificate store to use when looking for root certificates.
80 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
81 * The first certificate will be interpreted as the end entity certificate to
82 * be validated; subsequent certificates may be in any order and may be used
83 * by the chain as intermediate certificates, but not root certificates. Any
84 * self signed certificates supplied here after the first one will be discarded,
85 * as self signed certificates cannot by definition be intermediate certificates.
86 * The individual certificates can be retrieved since each one contains its own
88 * @param aRootCerts An array of certificates which the chain will treat as candidate root
89 * certificates. If one of these overloads is used, the chain will not look in
90 * stores for root certificates, but will only use the certificates supplied here. */
91 IMPORT_C static CPKIXCertChainBase* NewL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
92 const RPointerArray<CX509Certificate>& aRootCerts);
94 /** Creates a certificate chain using the binary data in aEncodedCerts and puts
95 * a pointer to the new object onto the cleanup stack.
97 * @param aCertStore The certificate store to use when looking for root certificates.
98 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
99 * The first certificate will be interpreted as the end entity certificate to
100 * be validated; subsequent certificates may be in any order and may be used
101 * by the chain as intermediate certificates, but not root certificates. Any
102 * self signed certificates supplied here after the first one will be discarded
103 * as self signed certificates cannot by definition be intermediate certificates.
104 * The individual certificates can be retrieved since each one contains its own
106 * @param aRootCerts An array of certificates which the chain will treat as candidate root
107 * certificates. If one of these overloads is used, the chain will not look in
108 * stores for root certificates, but will only use the certificates supplied here. */
109 IMPORT_C static CPKIXCertChainBase* NewLC(MCertStore& aCertStore, const TPtrC8& aEncodedCerts,
110 const RPointerArray<CX509Certificate>& aRootCerts);
114 * Frees all resources owned by the object. */
115 IMPORT_C ~CPKIXCertChainBase();
118 /** Validates the chain.
120 * @param aValidationResult On completion, this contains the result of the validation.
121 * @param aValidationTime The time that should be presumed to be the current time when checking timestamps.
122 * @param aStatus An asynchronous request status object. */
123 IMPORT_C void ValidateL(CPKIXValidationResultBase& aValidationResult,
124 const TTime& aValidationTime, TRequestStatus& aStatus);
126 /** Validates the chain.
128 * @param aValidationResult On completion, this contains the result of the validation.
129 * @param aValidationTime The time that should be presumed to be the current time when checking timestamps.
130 * @param aInitialPolicies The policies we want to be present in the certificate chain.
131 * @param aStatus An asynchronous request status object. */
132 IMPORT_C void ValidateL(CPKIXValidationResultBase& aValidationResult,
133 const TTime& aValidationTime, const CArrayPtr<HBufC>& aInitialPolicies,
134 TRequestStatus& aStatus);
136 /** Cancels an asynchronous ValidateL() operation. */
137 IMPORT_C void CancelValidate();
139 /** Adds one or more intermediate certificates to use when building the chain .
141 * Any self signed certs are ignored.
143 * @param aEncodedCerts The concatenation of one or more DER encoded X.509 certificates. */
144 IMPORT_C void AddCertL(const TPtrC8& aEncodedCerts);
146 /** Tests whether the root certificate of the chain is locatable.
148 * Note that the value is only significant after a successful call to ValidateL().
150 * @return ETrue if the chain has a root; EFalse, otherwise. */
151 IMPORT_C TBool ChainHasRoot() const;
153 /** Returns a list of the critical extension OIDs that are supported by the
154 * chain validator. If a critical extension is encountered in a certificate
155 * chain whose OID matches an element in this set then the chain validator
156 * shall treat this as a warning instead of an error.
158 * If CPKIXCertChain::SetSupportedCriticalExtensionsL() has not been called, this
159 * list will return the default set of supported critical extensions which
160 * includes the X.509 standard and Symbian specific SIS file critical extensions.
161 * These extensions may change in the future and should not be relied upon.
163 * @return The current list of supported critical extension OIDs. Ownership is not
164 * transferred to the caller. */
165 IMPORT_C const RPointerArray<TDesC>& SupportedCriticalExtensions() const;
167 /** Adds one or more critical extension OIDs to the list of supported critical
168 * extensions. Duplicate OID values are not added.
170 * @param aCriticalExtOids A list of the critical extensions OIDs to append to the supported
171 * list. Ownership is not transferred from the caller. */
172 IMPORT_C void AddSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids);
174 /** Removes one or more critical extension OIDs from the list of supported critical extensions.
176 * @param aCriticalExts A list of the critical extensions OIDs to remove from the supported list.
177 * Ownership is with the original caller. Oids will not be destroyed. */
178 IMPORT_C void RemoveSupportedCriticalExtensions(const RPointerArray<TDesC>& aCriticalExtOids);
180 /** Completely replaces the set of supported critical extensions for certificate validation. If a critical
181 * extension is encountered matching one of these OIDs then its occurrence is treated as a warning rather
182 * than an error. The results of which can be queried through a call to CPKIXValidationResult::ValidationWarnings().
184 * @param aCriticalExtOids A list of the critical extensions OIDs for the class to support. Ownership is
185 * not transferred from the caller. */
186 IMPORT_C void SetSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids);
188 /** Resets the current list of supported critical extensions and re-populates it with the default set
189 * which includes the X.509 standard and Symbian specific SIS file critical extensions. These extensions
190 * may change in the future and should not be relied upon. */
191 IMPORT_C void ResetSupportedCriticalExtsToDefaultL();
193 /** Specify if a failed check on the certificate validity date is treated as an error or a warning.
195 * @param aIsFatal ETrue for reporting as an error; EFalse for a warning.*/
196 IMPORT_C void SetValidityPeriodCheckFatal(TBool aIsFatal);
198 /** Returns whether or not validity period check failures will be reported as an error or a warning.
200 * @param aIsFatal ETrue if failure is reported as an error; EFalse for a warning.*/
201 IMPORT_C TBool ValidityPeriodCheckFatal() const;
204 IMPORT_C CPKIXCertChainBase();
205 IMPORT_C void ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, TUid aClient);
206 IMPORT_C void ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, const RPointerArray<CX509Certificate>& aRootCerts);
209 // Public non-exported methods called by CPKIXCertChainAO
210 CArrayPtrFlat<CX509Certificate>& Chain();
211 const RPointerArray<CX509Certificate>& IntermediateCerts();
212 TBool ChainHasRoot();
213 void RemoveLastCerts(TInt aNumberOfCertsToRemove);
214 void SetChainHasRoot(TBool aHasRoot);
217 void DoConstructL(const TPtrC8& aEncodedCerts);
220 * This function adds certificates to the chain but only the ones that are not
223 * @param aEncodedCerts The encoded certificates.
225 void AddIntermediateCertsL(const TPtrC8& aEncodedCerts);
229 * Holds a list of candiate intermediate certs - these come from the encoded
230 * certs passed at construction time, and also any added with AddCertL().
232 RPointerArray<CX509Certificate> iIntermediateCerts;
235 * This is ETrue if the chain has a root and EFalse if it hasn't. The value
236 * is only significant after a successfull call to ValidateL().
241 * Most of the fucntionality of the class is asynchronous and is in fact
242 * delegated to iActiveObject which will deal with all the asynchronous
245 CPKIXCertChainAO* iActiveObject;
248 * Holds a list of supported critical extensions set by the client.
250 RPointerArray<TDesC> iSupportedCriticalExts;
253 * When true (the defaut) indicates that a failed check on the validity period of a
254 * certificate will result in a fatal error. When false this instead results in a
257 TBool iDateTimeCheckFatal;
262 * This class implements a PKIX certificate chain.
266 class CPKIXCertChain : public CPKIXCertChainBase
271 /** Creates a certificate chain using the binary data in aEncodedCerts.
273 * @param aFs An open file server session.
274 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
275 * The first certificate will be interpreted as the end entity certificate to
276 * be validated; subsequent certificates may be in any order and may be used
277 * by the chain as intermediate certificates, but not root certificates. The
278 * individual certificates can be retrieved since each one contains its own length.
279 * @param aClient The Uid identifying the purpose for which the chain will be used.
280 * This value will be used to select a subset of stored certificates, by way of their trust
281 * settings, to be used as candidate root certificates. */
282 IMPORT_C static CPKIXCertChain* NewL(RFs& aFs, const TPtrC8& aEncodedCerts,
285 /** Creates a certificate chain using the binary data in aEncodedCerts, and puts
286 * a pointer to the new object onto the cleanup stack.
288 * @param aFs An open file server session
289 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
290 * The first certificate will be interpreted as the end entity certificate to
291 * be validated; subsequent certificates may be in any order and may be used
292 * by the chain as intermediate certificates, but not root certificates. The
293 * individual certificates can be retrieved since each one contains its own length.
294 * @param aClient The Uid identifying the purpose for which the chain will be used.
295 * This value will be used to select a subset of stored certificates, by way of their trust
296 * settings, to be used as candidate root certificates. */
297 IMPORT_C static CPKIXCertChain* NewLC(RFs& aFs, const TPtrC8& aEncodedCerts,
300 /** Creates a certificate chain using the binary data in aEncodedCerts.
302 * @param aFs An open file server session.
303 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
304 * The first certificate will be interpreted as the end entity certificate to
305 * be validated; subsequent certificates may be in any order and may be used
306 * by the chain as intermediate certificates, but not root certificates. Any
307 * self signed certificates supplied here after the first one will be discarded,
308 * as self signed certificates cannot by definition be intermediate certificates.
309 * The individual certificates can be retrieved since each one contains its own
311 * @param aRootCerts An array of certificates which the chain will treat as candidate root
312 * certificates. If one of these overloads is used, the chain will not look in
313 * stores for root certificates, but will only use the certificates supplied here. */
314 IMPORT_C static CPKIXCertChain* NewL(RFs& aFs, const TPtrC8& aEncodedCerts,
315 const RPointerArray<CX509Certificate>& aRootCerts);
317 /** Creates a certificate chain using the binary data in aEncodedCerts and puts
318 * a pointer to the new object onto the cleanup stack.
320 * @param aFs An open file server session.
321 * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates.
322 * The first certificate will be interpreted as the end entity certificate to
323 * be validated; subsequent certificates may be in any order and may be used
324 * by the chain as intermediate certificates, but not root certificates. Any
325 * self signed certificates supplied here after the first one will be discarded
326 * as self signed certificates cannot by definition be intermediate certificates.
327 * The individual certificates can be retrieved since each one contains its own
329 * @param aRootCerts An array of certificates which the chain will treat as candidate root
330 * certificates. If one of these overloads is used, the chain will not look in
331 * stores for root certificates, but will only use the certificates supplied here. */
332 IMPORT_C static CPKIXCertChain* NewLC(RFs& aFs, const TPtrC8& aEncodedCerts,
333 const RPointerArray<CX509Certificate>& aRootCerts);
338 * Frees all resources owned by the object. */
339 IMPORT_C ~CPKIXCertChain();
342 /** Validates the chain.
344 * @param aValidationResult On completion, this contains the result of the validation.
345 * @param aValidationTime The time that should be presumed to be the current time when checking timestamps.
346 * @param aStatus An asynchronous request status object. */
347 IMPORT_C void ValidateL(CPKIXValidationResult& aValidationResult,
348 const TTime& aValidationTime, TRequestStatus& aStatus);
350 /** Validates the chain.
352 * @param aValidationResult On completion, this contains the result of the validation.
353 * @param aValidationTime The time that should be presumed to be the current time when checking timestamps.
354 * @param aInitialPolicies The policies we want to be present in the certificate chain.
355 * @param aStatus An asynchronous request status object. */
356 IMPORT_C void ValidateL(CPKIXValidationResult& aValidationResult,
357 const TTime& aValidationTime, const CArrayPtr<HBufC>& aInitialPolicies,
358 TRequestStatus& aStatus);
360 /** Cancels an asynchronous ValidateL() operation. */
361 IMPORT_C void CancelValidate();
363 /** Adds a certificate (if it is not self-signed) to the chain .
365 * @param aEncodedCerts A DER encoded X.509 certificate. */
366 IMPORT_C void AddCertL(const TPtrC8& aEncodedCerts);
368 /** Tests whether the root certificate of the chain is locatable.
370 * Note that the value is only significant after a successfull call to ValidateL().
372 * @return ETrue if the chain has a root; EFalse, otherwise. */
373 IMPORT_C TBool ChainHasRoot() const;
375 /** Returns a list of the critical extension OIDs that are supported by the
376 * chain validator. If a critical extension is encountered in a certificate
377 * chain whose OID matches an element in this set then the chain validator
378 * shall treat this as a warning instead of an error.
380 * If CPKIXCertChain::SetSupportedCriticalExtensionsL() has not been called, this
381 * list will return the default set of supported critical extensions which
382 * includes the X.509 standard and Symbian specific SIS file critical extensions.
383 * These extensions may change in the future and should not be relied upon.
385 * @return The current list of supported critical extension OIDs. Ownership is not
386 * transferred to the caller. */
387 IMPORT_C const RPointerArray<TDesC>& SupportedCriticalExtensions() const;
389 /** Adds one or more critical extension OIDs to the list of supported critical
390 * extensions. Duplicate OID values are not added.
392 * @param aCriticalExtOids A list of the critical extensions OIDs to append to the supported
393 * list. Ownership is not transferred from the caller. */
394 IMPORT_C void AddSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids);
396 /** Removes one or more critical extension OIDs from the list of supported critical extensions.
398 * @param aCriticalExts A list of the critical extensions OIDs to remove from the supported list.
399 * Ownership is with the original caller. Oids will not be destroyed. */
400 IMPORT_C void RemoveSupportedCriticalExtensions(const RPointerArray<TDesC>& aCriticalExtOids);
402 /** Completely replaces the set of supported critical extensions for certificate validation. If a critical
403 * extension is encountered matching one of these OIDs then its occurrence is treated as a warning rather
404 * than an error. The results of which can be queried through a call to CPKIXValidationResult::ValidationWarnings().
406 * @param aCriticalExtOids A list of the critical extensions OIDs for the class to support. Ownership is
407 * not transferred from the caller. */
408 IMPORT_C void SetSupportedCriticalExtensionsL(const RPointerArray<TDesC>& aCriticalExtOids);
410 /** Resets the current list of supported critical extensions and re-populates it with the default set
411 * which includes the X.509 standard and Symbian specific SIS file critical extensions. These extensions
412 * may change in the future and should not be relied upon. */
413 IMPORT_C void ResetSupportedCriticalExtsToDefaultL();
415 /** Specify if a failed check on the certificate validity date is treated as an error or a warning.
417 * @param aIsFatal ETrue for reporting as an error; EFalse for a warning.*/
418 IMPORT_C void SetValidityPeriodCheckFatal(TBool aIsFatal);
422 void ConstructL(RFs& aFs, const TPtrC8& aEncodedCerts, TUid aClient);
423 void ConstructL(RFs& aFs, const TPtrC8& aEncodedCerts,
424 const RPointerArray<CX509Certificate>& aRootCerts);
427 CPKIXCertChainHelper* iHelper;