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