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: * PKIXCERTCHAIN.H sl@0: * PKIX certificate chain implementation sl@0: * sl@0: */ sl@0: sl@0: sl@0: /** sl@0: @file sl@0: @publishedAll sl@0: @released sl@0: */ sl@0: sl@0: #ifndef __PKIXCERTCHAIN_H__ sl@0: #define __PKIXCERTCHAIN_H__ sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: //implements key validation according to RFC 2459 (PKIX cert/CRL profile), section 6 sl@0: class CPKIXValidationState; sl@0: class CPKIXChainBuilder; sl@0: class CPKIXCertChainAO; sl@0: class CPKIXCertChainHelper; sl@0: class MCertStore; sl@0: sl@0: /** sl@0: * Base class for CPKIXCertChain sl@0: */ sl@0: class CPKIXCertChainBase : public CX509CertChain sl@0: { sl@0: public: sl@0: //constructors sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts. sl@0: * sl@0: * @param aCertStore The certificate store to use when looking for root certificates. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. The sl@0: * individual certificates can be retrieved since each one contains its own length. sl@0: * @param aClient The Uid identifying the purpose for which the chain will be used. sl@0: * This value will be used to select a subset of stored certificates, by way of their trust sl@0: * settings, to be used as candidate root certificates. */ sl@0: IMPORT_C static CPKIXCertChainBase* NewL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, sl@0: const TUid aClient); sl@0: sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts, and puts sl@0: * a pointer to the new object onto the cleanup stack. sl@0: * sl@0: * @param aCertStore The certificate store to use when looking for root certificates. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. The sl@0: * individual certificates can be retrieved since each one contains its own length. sl@0: * @param aClient The Uid identifying the purpose for which the chain will be used. sl@0: * This value will be used to select a subset of stored certificates, by way of their trust sl@0: * settings, to be used as candidate root certificates. */ sl@0: IMPORT_C static CPKIXCertChainBase* NewLC(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, sl@0: const TUid aClient); sl@0: sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts. sl@0: * sl@0: * @param aCertStore The certificate store to use when looking for root certificates. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. Any sl@0: * self signed certificates supplied here after the first one will be discarded, sl@0: * as self signed certificates cannot by definition be intermediate certificates. sl@0: * The individual certificates can be retrieved since each one contains its own sl@0: * length. sl@0: * @param aRootCerts An array of certificates which the chain will treat as candidate root sl@0: * certificates. If one of these overloads is used, the chain will not look in sl@0: * stores for root certificates, but will only use the certificates supplied here. */ sl@0: IMPORT_C static CPKIXCertChainBase* NewL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, sl@0: const RPointerArray& aRootCerts); sl@0: sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts and puts sl@0: * a pointer to the new object onto the cleanup stack. sl@0: * sl@0: * @param aCertStore The certificate store to use when looking for root certificates. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. Any sl@0: * self signed certificates supplied here after the first one will be discarded sl@0: * as self signed certificates cannot by definition be intermediate certificates. sl@0: * The individual certificates can be retrieved since each one contains its own sl@0: * length. sl@0: * @param aRootCerts An array of certificates which the chain will treat as candidate root sl@0: * certificates. If one of these overloads is used, the chain will not look in sl@0: * stores for root certificates, but will only use the certificates supplied here. */ sl@0: IMPORT_C static CPKIXCertChainBase* NewLC(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, sl@0: const RPointerArray& aRootCerts); sl@0: sl@0: /** Destructor. sl@0: * sl@0: * Frees all resources owned by the object. */ sl@0: IMPORT_C ~CPKIXCertChainBase(); sl@0: //validation sl@0: sl@0: /** Validates the chain. sl@0: * sl@0: * @param aValidationResult On completion, this contains the result of the validation. sl@0: * @param aValidationTime The time that should be presumed to be the current time when checking timestamps. sl@0: * @param aStatus An asynchronous request status object. */ sl@0: IMPORT_C void ValidateL(CPKIXValidationResultBase& aValidationResult, sl@0: const TTime& aValidationTime, TRequestStatus& aStatus); sl@0: sl@0: /** Validates the chain. sl@0: * sl@0: * @param aValidationResult On completion, this contains the result of the validation. sl@0: * @param aValidationTime The time that should be presumed to be the current time when checking timestamps. sl@0: * @param aInitialPolicies The policies we want to be present in the certificate chain. sl@0: * @param aStatus An asynchronous request status object. */ sl@0: IMPORT_C void ValidateL(CPKIXValidationResultBase& aValidationResult, sl@0: const TTime& aValidationTime, const CArrayPtr& aInitialPolicies, sl@0: TRequestStatus& aStatus); sl@0: sl@0: /** Cancels an asynchronous ValidateL() operation. */ sl@0: IMPORT_C void CancelValidate(); sl@0: sl@0: /** Adds one or more intermediate certificates to use when building the chain . sl@0: * sl@0: * Any self signed certs are ignored. sl@0: * sl@0: * @param aEncodedCerts The concatenation of one or more DER encoded X.509 certificates. */ sl@0: IMPORT_C void AddCertL(const TPtrC8& aEncodedCerts); sl@0: sl@0: /** Tests whether the root certificate of the chain is locatable. sl@0: * sl@0: * Note that the value is only significant after a successful call to ValidateL(). sl@0: * sl@0: * @return ETrue if the chain has a root; EFalse, otherwise. */ sl@0: IMPORT_C TBool ChainHasRoot() const; sl@0: sl@0: /** Returns a list of the critical extension OIDs that are supported by the sl@0: * chain validator. If a critical extension is encountered in a certificate sl@0: * chain whose OID matches an element in this set then the chain validator sl@0: * shall treat this as a warning instead of an error. sl@0: * sl@0: * If CPKIXCertChain::SetSupportedCriticalExtensionsL() has not been called, this sl@0: * list will return the default set of supported critical extensions which sl@0: * includes the X.509 standard and Symbian specific SIS file critical extensions. sl@0: * These extensions may change in the future and should not be relied upon. sl@0: * sl@0: * @return The current list of supported critical extension OIDs. Ownership is not sl@0: * transferred to the caller. */ sl@0: IMPORT_C const RPointerArray& SupportedCriticalExtensions() const; sl@0: sl@0: /** Adds one or more critical extension OIDs to the list of supported critical sl@0: * extensions. Duplicate OID values are not added. sl@0: * sl@0: * @param aCriticalExtOids A list of the critical extensions OIDs to append to the supported sl@0: * list. Ownership is not transferred from the caller. */ sl@0: IMPORT_C void AddSupportedCriticalExtensionsL(const RPointerArray& aCriticalExtOids); sl@0: sl@0: /** Removes one or more critical extension OIDs from the list of supported critical extensions. sl@0: * sl@0: * @param aCriticalExts A list of the critical extensions OIDs to remove from the supported list. sl@0: * Ownership is with the original caller. Oids will not be destroyed. */ sl@0: IMPORT_C void RemoveSupportedCriticalExtensions(const RPointerArray& aCriticalExtOids); sl@0: sl@0: /** Completely replaces the set of supported critical extensions for certificate validation. If a critical sl@0: * extension is encountered matching one of these OIDs then its occurrence is treated as a warning rather sl@0: * than an error. The results of which can be queried through a call to CPKIXValidationResult::ValidationWarnings(). sl@0: * sl@0: * @param aCriticalExtOids A list of the critical extensions OIDs for the class to support. Ownership is sl@0: * not transferred from the caller. */ sl@0: IMPORT_C void SetSupportedCriticalExtensionsL(const RPointerArray& aCriticalExtOids); sl@0: sl@0: /** Resets the current list of supported critical extensions and re-populates it with the default set sl@0: * which includes the X.509 standard and Symbian specific SIS file critical extensions. These extensions sl@0: * may change in the future and should not be relied upon. */ sl@0: IMPORT_C void ResetSupportedCriticalExtsToDefaultL(); sl@0: sl@0: /** Specify if a failed check on the certificate validity date is treated as an error or a warning. sl@0: * sl@0: * @param aIsFatal ETrue for reporting as an error; EFalse for a warning.*/ sl@0: IMPORT_C void SetValidityPeriodCheckFatal(TBool aIsFatal); sl@0: sl@0: /** Returns whether or not validity period check failures will be reported as an error or a warning. sl@0: * sl@0: * @param aIsFatal ETrue if failure is reported as an error; EFalse for a warning.*/ sl@0: IMPORT_C TBool ValidityPeriodCheckFatal() const; sl@0: sl@0: protected: sl@0: IMPORT_C CPKIXCertChainBase(); sl@0: IMPORT_C void ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, TUid aClient); sl@0: IMPORT_C void ConstructL(MCertStore& aCertStore, const TPtrC8& aEncodedCerts, const RPointerArray& aRootCerts); sl@0: sl@0: public: sl@0: // Public non-exported methods called by CPKIXCertChainAO sl@0: CArrayPtrFlat& Chain(); sl@0: const RPointerArray& IntermediateCerts(); sl@0: TBool ChainHasRoot(); sl@0: void RemoveLastCerts(TInt aNumberOfCertsToRemove); sl@0: void SetChainHasRoot(TBool aHasRoot); sl@0: sl@0: private: sl@0: void DoConstructL(const TPtrC8& aEncodedCerts); sl@0: sl@0: /** sl@0: * This function adds certificates to the chain but only the ones that are not sl@0: * self-signed. sl@0: * sl@0: * @param aEncodedCerts The encoded certificates. sl@0: */ sl@0: void AddIntermediateCertsL(const TPtrC8& aEncodedCerts); sl@0: sl@0: private: sl@0: /** sl@0: * Holds a list of candiate intermediate certs - these come from the encoded sl@0: * certs passed at construction time, and also any added with AddCertL(). sl@0: */ sl@0: RPointerArray iIntermediateCerts; sl@0: sl@0: /** sl@0: * This is ETrue if the chain has a root and EFalse if it hasn't. The value sl@0: * is only significant after a successfull call to ValidateL(). sl@0: */ sl@0: TBool iChainHasRoot; sl@0: sl@0: /** sl@0: * Most of the fucntionality of the class is asynchronous and is in fact sl@0: * delegated to iActiveObject which will deal with all the asynchronous sl@0: * functions. sl@0: */ sl@0: CPKIXCertChainAO* iActiveObject; sl@0: sl@0: /** sl@0: * Holds a list of supported critical extensions set by the client. sl@0: */ sl@0: RPointerArray iSupportedCriticalExts; sl@0: sl@0: /** sl@0: * When true (the defaut) indicates that a failed check on the validity period of a sl@0: * certificate will result in a fatal error. When false this instead results in a sl@0: * warning. sl@0: */ sl@0: TBool iDateTimeCheckFatal; sl@0: }; sl@0: sl@0: sl@0: /** sl@0: * This class implements a PKIX certificate chain. sl@0: * sl@0: * @since v6.0 sl@0: */ sl@0: class CPKIXCertChain : public CPKIXCertChainBase sl@0: { sl@0: public: sl@0: sl@0: //constructors sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts. sl@0: * sl@0: * @param aFs An open file server session. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. The sl@0: * individual certificates can be retrieved since each one contains its own length. sl@0: * @param aClient The Uid identifying the purpose for which the chain will be used. sl@0: * This value will be used to select a subset of stored certificates, by way of their trust sl@0: * settings, to be used as candidate root certificates. */ sl@0: IMPORT_C static CPKIXCertChain* NewL(RFs& aFs, const TPtrC8& aEncodedCerts, sl@0: const TUid aClient); sl@0: sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts, and puts sl@0: * a pointer to the new object onto the cleanup stack. sl@0: * sl@0: * @param aFs An open file server session sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. The sl@0: * individual certificates can be retrieved since each one contains its own length. sl@0: * @param aClient The Uid identifying the purpose for which the chain will be used. sl@0: * This value will be used to select a subset of stored certificates, by way of their trust sl@0: * settings, to be used as candidate root certificates. */ sl@0: IMPORT_C static CPKIXCertChain* NewLC(RFs& aFs, const TPtrC8& aEncodedCerts, sl@0: const TUid aClient); sl@0: sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts. sl@0: * sl@0: * @param aFs An open file server session. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. Any sl@0: * self signed certificates supplied here after the first one will be discarded, sl@0: * as self signed certificates cannot by definition be intermediate certificates. sl@0: * The individual certificates can be retrieved since each one contains its own sl@0: * length. sl@0: * @param aRootCerts An array of certificates which the chain will treat as candidate root sl@0: * certificates. If one of these overloads is used, the chain will not look in sl@0: * stores for root certificates, but will only use the certificates supplied here. */ sl@0: IMPORT_C static CPKIXCertChain* NewL(RFs& aFs, const TPtrC8& aEncodedCerts, sl@0: const RPointerArray& aRootCerts); sl@0: sl@0: /** Creates a certificate chain using the binary data in aEncodedCerts and puts sl@0: * a pointer to the new object onto the cleanup stack. sl@0: * sl@0: * @param aFs An open file server session. sl@0: * @param aEncodedCerts One or more concatenated DER encoded X.509 certificates. sl@0: * The first certificate will be interpreted as the end entity certificate to sl@0: * be validated; subsequent certificates may be in any order and may be used sl@0: * by the chain as intermediate certificates, but not root certificates. Any sl@0: * self signed certificates supplied here after the first one will be discarded sl@0: * as self signed certificates cannot by definition be intermediate certificates. sl@0: * The individual certificates can be retrieved since each one contains its own sl@0: * length. sl@0: * @param aRootCerts An array of certificates which the chain will treat as candidate root sl@0: * certificates. If one of these overloads is used, the chain will not look in sl@0: * stores for root certificates, but will only use the certificates supplied here. */ sl@0: IMPORT_C static CPKIXCertChain* NewLC(RFs& aFs, const TPtrC8& aEncodedCerts, sl@0: const RPointerArray& aRootCerts); sl@0: sl@0: //destructor sl@0: /** Destructor. sl@0: * sl@0: * Frees all resources owned by the object. */ sl@0: IMPORT_C ~CPKIXCertChain(); sl@0: //validation sl@0: sl@0: /** Validates the chain. sl@0: * sl@0: * @param aValidationResult On completion, this contains the result of the validation. sl@0: * @param aValidationTime The time that should be presumed to be the current time when checking timestamps. sl@0: * @param aStatus An asynchronous request status object. */ sl@0: IMPORT_C void ValidateL(CPKIXValidationResult& aValidationResult, sl@0: const TTime& aValidationTime, TRequestStatus& aStatus); sl@0: sl@0: /** Validates the chain. sl@0: * sl@0: * @param aValidationResult On completion, this contains the result of the validation. sl@0: * @param aValidationTime The time that should be presumed to be the current time when checking timestamps. sl@0: * @param aInitialPolicies The policies we want to be present in the certificate chain. sl@0: * @param aStatus An asynchronous request status object. */ sl@0: IMPORT_C void ValidateL(CPKIXValidationResult& aValidationResult, sl@0: const TTime& aValidationTime, const CArrayPtr& aInitialPolicies, sl@0: TRequestStatus& aStatus); sl@0: sl@0: /** Cancels an asynchronous ValidateL() operation. */ sl@0: IMPORT_C void CancelValidate(); sl@0: sl@0: /** Adds a certificate (if it is not self-signed) to the chain . sl@0: * sl@0: * @param aEncodedCerts A DER encoded X.509 certificate. */ sl@0: IMPORT_C void AddCertL(const TPtrC8& aEncodedCerts); sl@0: sl@0: /** Tests whether the root certificate of the chain is locatable. sl@0: * sl@0: * Note that the value is only significant after a successfull call to ValidateL(). sl@0: * sl@0: * @return ETrue if the chain has a root; EFalse, otherwise. */ sl@0: IMPORT_C TBool ChainHasRoot() const; sl@0: sl@0: /** Returns a list of the critical extension OIDs that are supported by the sl@0: * chain validator. If a critical extension is encountered in a certificate sl@0: * chain whose OID matches an element in this set then the chain validator sl@0: * shall treat this as a warning instead of an error. sl@0: * sl@0: * If CPKIXCertChain::SetSupportedCriticalExtensionsL() has not been called, this sl@0: * list will return the default set of supported critical extensions which sl@0: * includes the X.509 standard and Symbian specific SIS file critical extensions. sl@0: * These extensions may change in the future and should not be relied upon. sl@0: * sl@0: * @return The current list of supported critical extension OIDs. Ownership is not sl@0: * transferred to the caller. */ sl@0: IMPORT_C const RPointerArray& SupportedCriticalExtensions() const; sl@0: sl@0: /** Adds one or more critical extension OIDs to the list of supported critical sl@0: * extensions. Duplicate OID values are not added. sl@0: * sl@0: * @param aCriticalExtOids A list of the critical extensions OIDs to append to the supported sl@0: * list. Ownership is not transferred from the caller. */ sl@0: IMPORT_C void AddSupportedCriticalExtensionsL(const RPointerArray& aCriticalExtOids); sl@0: sl@0: /** Removes one or more critical extension OIDs from the list of supported critical extensions. sl@0: * sl@0: * @param aCriticalExts A list of the critical extensions OIDs to remove from the supported list. sl@0: * Ownership is with the original caller. Oids will not be destroyed. */ sl@0: IMPORT_C void RemoveSupportedCriticalExtensions(const RPointerArray& aCriticalExtOids); sl@0: sl@0: /** Completely replaces the set of supported critical extensions for certificate validation. If a critical sl@0: * extension is encountered matching one of these OIDs then its occurrence is treated as a warning rather sl@0: * than an error. The results of which can be queried through a call to CPKIXValidationResult::ValidationWarnings(). sl@0: * sl@0: * @param aCriticalExtOids A list of the critical extensions OIDs for the class to support. Ownership is sl@0: * not transferred from the caller. */ sl@0: IMPORT_C void SetSupportedCriticalExtensionsL(const RPointerArray& aCriticalExtOids); sl@0: sl@0: /** Resets the current list of supported critical extensions and re-populates it with the default set sl@0: * which includes the X.509 standard and Symbian specific SIS file critical extensions. These extensions sl@0: * may change in the future and should not be relied upon. */ sl@0: IMPORT_C void ResetSupportedCriticalExtsToDefaultL(); sl@0: sl@0: /** Specify if a failed check on the certificate validity date is treated as an error or a warning. sl@0: * sl@0: * @param aIsFatal ETrue for reporting as an error; EFalse for a warning.*/ sl@0: IMPORT_C void SetValidityPeriodCheckFatal(TBool aIsFatal); sl@0: sl@0: private: sl@0: CPKIXCertChain(); sl@0: void ConstructL(RFs& aFs, const TPtrC8& aEncodedCerts, TUid aClient); sl@0: void ConstructL(RFs& aFs, const TPtrC8& aEncodedCerts, sl@0: const RPointerArray& aRootCerts); sl@0: sl@0: private: sl@0: CPKIXCertChainHelper* iHelper; sl@0: }; sl@0: sl@0: #endif