cryptoservices/certificateandkeymgmt/docs/doxygen_docs/UnifiedStores.dox
changeset 0 2c201484c85f
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /**
       
     2 
       
     3 @page UnifiedStores The unified stores
       
     4 
       
     5 @section intro Introduction
       
     6 
       
     7 This document describes the unified certificate store and unified key store.
       
     8 
       
     9 A Symbian OS device may contain zero or more individual cert stores, and zero or
       
    10 more key stores.  Software implementations for both of these are supplied, and
       
    11 licensees may add their own, perhaps using special hardware on the device - for
       
    12 example using a WIM.  The unified store classes acts as an central interfaces
       
    13 for certificate and key management, so that application writers do not need to
       
    14 know details of the specific implementations present.  They automatically
       
    15 discovers all implementations of the relevant interface on the device using the
       
    16 crypto token framework.
       
    17 
       
    18 These stores are unified in the sense that client requests which related to all
       
    19 store implementations (such as "list keys" or "list certificates") are passed to
       
    20 every implementation in turn, and the results collated.  Requests that relate to
       
    21 a specific store are routed to the correct implementation.
       
    22 
       
    23 Clients should only use the unified store class to access certificates and keys.
       
    24 There is no need to use the crypto token framework directly, and although this
       
    25 is possible, it is not recommended.
       
    26 
       
    27 This document gives a description of how to perform basic certificate and key
       
    28 operations using the unified stores.  
       
    29 
       
    30 @section programmingUnifiedStores Programming with the unified stores
       
    31 
       
    32 The ctframework component provides the interfaces for key store and cert store
       
    33 implementations, and the unified stores themselves are implemented in certman's
       
    34 certstore component.  Programs wishing to use the unified stores should
       
    35 therefore be linked against both certstore.lib and ctframework.lib.  Note that
       
    36 certstore.lib provides both the unified cert store and the unified key store.
       
    37 
       
    38 The software cert store implementation supplied with Symbian OS is provided by
       
    39 filecertstore.dll, and this runs entirely in the client application.  The
       
    40 software key store runs in a separate server process - this is implemented by
       
    41 fstokenserver.dll, and the client side part that communicates with the server is
       
    42 provided by fstokencli.dll.  The unified stores use the ECom framework to load
       
    43 these DLLs automatically, so there is no need to link against them in client
       
    44 applications.
       
    45 
       
    46 The main header files used are unifiedcertstore.h and unfiedkeystore.h, and you
       
    47 should refer to them while reading the example code.
       
    48 
       
    49 Most methods are asynchronous and this means that clients need to be implemented
       
    50 as active objects to work.  All calls to asynchronous methods must be called
       
    51 from the context of active objects - the active scheduler will call the client's
       
    52 RunL() method when the asynchronous method completes.
       
    53 
       
    54 This means that the following code will not work:
       
    55 
       
    56 @code 
       
    57 // Broken!
       
    58 TRequestStatus status;
       
    59 certStore->DoSomething(parameters, status);
       
    60 User::WaitForRequest(&status);
       
    61 @endcode
       
    62 
       
    63 @section commonConcepts Common concepts
       
    64 
       
    65 This section describes concepts common to both unified stores.
       
    66 
       
    67 @subsection tokenObjectHandler Token object handle - TCTTokenObjectHandle
       
    68 
       
    69 A token object handle is a concept from the crypto token framework that is used
       
    70 to identify an object associated with a particular token.  It consists of a
       
    71 token identifier and an object identifier which is unique among all objects with
       
    72 that token.  The object is lightweight and can be easily passed between
       
    73 processes.
       
    74 
       
    75 These are used to identify keys and certificates.  This allows the unified store
       
    76 to route client requests that concern a particular object onto the token that
       
    77 actually has that object.
       
    78 
       
    79 This class is defined in tcttokenobjecthandle.h.
       
    80 
       
    81 @section unifiedKeyStore The unified key store
       
    82 
       
    83 @subsection limiatations Limitations
       
    84 
       
    85 Currently, this document does not cover owners and users, authentication or
       
    86 private key export.
       
    87 
       
    88 @subsection sec2 Key store concepts
       
    89 
       
    90 @subsubsection sec21 Key info - CCTKeyInfo
       
    91 
       
    92 Detailed information about a key is represented as a CCTKeyInfo object.  Objects
       
    93 of this type are passed back to the client by "list" and "get key info"
       
    94 operations.  The class is defined in the mctkeystore.h header file.  It has
       
    95 accessors for the following attributes:
       
    96 
       
    97 @li ID - a SHA-1 hash of the public key, used to uniquely identify it.
       
    98 @li Usage - a bitfield representing the allowed usages of the key.  This is of
       
    99 	type TKeyUsagePKCS15, defined in securitydefs.h.
       
   100 @li Size - the size of the key in bits.
       
   101 @li Label - a text string to identify the key to users.
       
   102 @li Owner - the UID of the application that created or imported the key.  
       
   103 @li Users - a list of UIDs of applications that are allowed to use the key.
       
   104 @li Algorithm - the key algorithm: RSA, DSA or DH.
       
   105 @li AccessType - a bitfield that determines the sensitivity of the key.
       
   106 @li Native - indicates whether cryptographic operations involving the key are
       
   107 	carried out within the key store implementation itself (ie in hardware if
       
   108 	the key store is implemented in hardware).
       
   109 @li StartDate - the start of the validity period of the key.
       
   110 @li EndDate - the end of the validity period of the key.
       
   111 @li PKCS8AttributeSet - additional key attributes as a DER-encoded set.
       
   112 @li Protector - an MCTAuthenticationObject that can be used to access the
       
   113 	authentication mechanism for the key store.
       
   114 @li Token - an MCTToken object that represents the actual key store
       
   115 	implementation the key is in.  It is possible to use this to get access to the
       
   116 	key store implementation, but this is not recommended.
       
   117 
       
   118 For a description of owners, users and authentication objects, please see the
       
   119 functional specification and architecture analysis documents.
       
   120 
       
   121 CCTKeyInfo has a conversion operator to TCTTokenObjectHandle, so instances of
       
   122 this class can be passed to any methods in the unified key store requiring a
       
   123 token object handle.
       
   124 
       
   125 @subsubsection authObject Authentication objects - MCTAuthenticationObject
       
   126 
       
   127 Authentication objects are used to control the authentication mechanism of the
       
   128 key store.  They are accessed by calling the Protector() method of a CCTKeyInfo.
       
   129 The authentication object returned is owned by the keystore implementation and
       
   130 you should not attempt to free it yourself - this is managed automatically.
       
   131 They may also be shared between keys - ie, the same object may be returned for
       
   132 more than one key.  The software key store implementation works like this - it
       
   133 associates one auth object instance with each key owner application.  In other
       
   134 words, every key with the same owner has the same auth object.  This is because
       
   135 authetication properties like the passphrase timeout are set on a per-owner
       
   136 basis in this implementation.
       
   137 
       
   138 @subsection sec3 Creating a CUnifiedKeyStore
       
   139 
       
   140 The object is created in the usual way, by calling the static NewL() or NewLC()
       
   141 methods, and then must be initialised by calling the asynchronous Initialize()
       
   142 method.  
       
   143 
       
   144 For example, a client might use the following code to create and initialise a
       
   145 unified key store object:
       
   146 
       
   147 @code
       
   148 void CKeyStoreExample::CreateUnifiedKeystoreL()
       
   149 	{
       
   150 	// iKeyStore is a CUnifiedKeyStore* 
       
   151 	// iFS is an RFs (file server client)
       
   152 	// iState is an enum that records the state of the active object
       
   153 
       
   154 	iKeyStore = CUnifiedKeyStore::NewL(iFs);
       
   155 	iKeyStore->Initialize(iStatus);
       
   156 	iState = EInitializingKeystore;
       
   157 	SetActive();
       
   158 
       
   159 	// RunL called when this completes
       
   160 	}
       
   161 @endcode
       
   162 
       
   163 @subsection sec4 Finding keys
       
   164 
       
   165 The unified key store allows a client to search all keys on a device regardless
       
   166 of which physical store they are in.  A filter object is specified which determines
       
   167 which keys are returned - you can filter on:
       
   168 
       
   169 @li The key indentifier - used when you are searching for a particular key.
       
   170 @li The key usage
       
   171 @li Tke key owner UID
       
   172 @li The key algorithm
       
   173 
       
   174 All of these default to "don't care".  So, an application that wishes to find
       
   175 all DSA keys owned by a certain application that are usable for signing might do
       
   176 the following:
       
   177 
       
   178 @code
       
   179 void CKeyStoreExample::FindSomeKeys()
       
   180 {
       
   181 	// KApplicationUID is UID of key owner application
       
   182 	// iKeys is an RMPointerArray<CCTKeyInfo> that is filled with the keys found
       
   183 
       
   184 	TCTKeyAttributeFilter filter;
       
   185 	filter.iOwner = KApplicationUID;
       
   186 	filter.iUsage = EPKCS15UsageSign;
       
   187 	filter.iKeyAlgorithm = CCTKeyInfo::EDSA;
       
   188 
       
   189 	iKeyStore->List(iKeys, filter, iStatus);
       
   190 	iState = EFindingKeys;
       
   191 	SetActive();
       
   192 
       
   193 	// RunL called when this completes
       
   194 }
       
   195 @endcode
       
   196 
       
   197 @subsection sec5 Performing cryptographic operations with keys
       
   198 
       
   199 Performing a cryptographic operation is a two stage process.  First, the key
       
   200 must be "opened", which creates an object capable of performing the required
       
   201 operation.  Then the new object's methods are called to actually execute
       
   202 it. Below is a list of the supported operations together with the objects
       
   203 created:
       
   204 
       
   205 @li DSA Sign - MDSASigner
       
   206 @li RSA Sign - MRSASigner
       
   207 @li RSA Decrypt - MCTDecryptor
       
   208 @li DH agreement - MCTDH
       
   209 
       
   210 These interfaces are defined in the header file mkeystore.h.
       
   211 
       
   212 The created objects are owned by the client, and hence must be disposed of by
       
   213 calling their Release() method when they are no longer required.
       
   214 
       
   215 To perform an RSA signing operation, the key is opened to create an MRSASigner
       
   216 object.  This object supports two signing methods:
       
   217 
       
   218 @li SignMessage, which computes a SHA-1 digest of the input data and signs that.
       
   219 @li Sign, which takes as input a message digest to sign (ie does a raw RSA sign
       
   220 operation).
       
   221 
       
   222 These signing methods create a CRSASignature object as output.
       
   223 
       
   224 For example, to RSA sign some data in iDataToSign:
       
   225 
       
   226 @code
       
   227 void CKeyStoreExample::RSASign(const CCTKeyInfo& aKey)
       
   228 {
       
   229 	// iRSASigner is an MRSASigner*
       
   230 	// iDataToSign is a HBufC8* containing data to be signed
       
   231 	// iRSASignature is a CRSASignature* which will contain the result
       
   232 
       
   233 	iKeyStore->Open(aKey, iRSASigner, iStatus);
       
   234 	iState = EOpenRSAKeyForSigning;
       
   235 	SetActive();
       
   236 }
       
   237 
       
   238 void CKeyStoreExample::RunL()
       
   239 {
       
   240 	switch (iState)
       
   241 	{
       
   242 		...
       
   243 
       
   244 		case EOpenRSAKeyForSigning:
       
   245 			PerformRSASignOperation();
       
   246 			break;
       
   247 
       
   248 		...
       
   249 	}
       
   250 }
       
   251 
       
   252 void CKeyStoreExample::PerformRSASignOperation()
       
   253 {
       
   254 	iRSASigner->SignMessage(*iData, iRSASignature, iStatus);
       
   255 	iState = EPerformRSASignOperation;
       
   256 	SetActive();
       
   257 
       
   258 	// RunL called again when this completes
       
   259 }
       
   260 @endcode
       
   261 
       
   262 DSA Signing works much the same as for RSA Signing described above.  The only
       
   263 difference is that the Open() method creates an MDSASigner object (The Open()
       
   264 methods are overloaded on the type of the created object).  The DSA signer
       
   265 differs from an MRSASigner only in that the signing method creates a
       
   266 CDSASignature object.
       
   267 
       
   268 RSA encryption and Diffie-Hellman key agreement are analogous.
       
   269 
       
   270 @subsection sec6 Generating keys
       
   271 
       
   272 For this operation it is necessary to know in advance which of the key stores
       
   273 implementations on the device the new key should be stored in.  The application
       
   274 could ask the user for this information, or it could choose a store itself based
       
   275 on some policy.  Either way, the available key stores that support write
       
   276 operations can be found using the KeyStoreManagerCount() and KeyStoreManager()
       
   277 accessor methods.
       
   278 
       
   279 A key store manager object is a token interface (see MCTTokenInteface defined in
       
   280 mcttokeninterface.h), and from this it is possible the get the token via the
       
   281 Token() method and hence the token label.  So, in order to ask the user which
       
   282 key store they wanted a key to be created in, a list of the labels of available
       
   283 key stores could be built up like this:
       
   284 
       
   285 @code
       
   286 void CKeyStoreExample::GetKeyStoreManagerLabelsL()
       
   287 {
       
   288 	// iLabelList is a RPointerArray<HBufC8>
       
   289 
       
   290 	for (TInt index = 0 ; index < iKeyStore->KeyStoreManagerCount() ; ++i)
       
   291 	{
       
   292 		MCTKeyStoreManager& manager = iKeyStore->KeyStoreManager(index);
       
   293 		MCTToken& token = manager->Token();
       
   294 		HBufC* label = token->Label().AllocLC();
       
   295 		User::LeaveIfError(iLabelList.Append(label));
       
   296 		CleanupStack::Pop(label);
       
   297 	}
       
   298 }
       
   299 @endcode
       
   300 
       
   301 Once the index of the key store manager has been determined, the key can be
       
   302 created by calling the CreateKey() method.  Among other things it takes the
       
   303 following parameters that are a subset of the attributes of a CCTKeyInfo:
       
   304 
       
   305 @li aUsage - The key usage flags in the PKCS15 format.
       
   306 @li aSize - The key size in bits.
       
   307 @li aLabel - The textual label for the key.
       
   308 @li aAlgorithm - The key algorithm - RSA, DSA or DH.
       
   309 @li aAccessType - The key's access type bitfield.  Only two of the bits defined
       
   310 	may be set when creating a key - EExtractable and ESensitive.
       
   311 @li aStartDate - the start of the validity period of the key.
       
   312 @li aEndDate - the end of the validity period of the key.
       
   313 
       
   314 For example:
       
   315 
       
   316 @code
       
   317 void CKeyStoreExample::CreateRSAKey(TInt aKeyStoreIndex)
       
   318 {
       
   319 	// iKey is a CCTKeyInfo* that will be set if the method succeeds
       
   320 
       
   321 	_LIT(KMyKeyName, "Example key");
       
   322 
       
   323 	TTime startDate, endDate;
       
   324 	startDate.UniversalTime();
       
   325 	endDate.UniversalTime();
       
   326 	endDate += TTimeIntervalYears(1); // key valid for a year
       
   327 
       
   328 	iKeyStore->CreateKey(
       
   329 		aKeyStoreIndex,
       
   330 		EPKCS15UsageSign,
       
   331 		1024,
       
   332 		KMyKeyName,
       
   333 		CCTKeyInfo::ERSA,
       
   334 		CCTKeyInfo::EExtractable,
       
   335 		startDate,
       
   336 		endDate,
       
   337 		iKey,
       
   338 		iStatus);
       
   339 	iState = ECreateKey;
       
   340 	SetActive();
       
   341 
       
   342 	// RunL called when this completes
       
   343 }
       
   344 @endcode
       
   345 
       
   346 @subsection importKey Importing keys
       
   347 
       
   348 Importing keys is very similar to creating keys, except that the ImportKey()
       
   349 method takes an additional two parameters:
       
   350 
       
   351 @li aKeyData - the key data in pkcs#8 format.
       
   352 @li aIsEncrypted - whether the key data is pkcs#5 encrypted.
       
   353 
       
   354 @subsection deleteKey Deleting keys
       
   355 
       
   356 Keys can be deleted with the DeleteKey() method, for example:
       
   357 
       
   358 @code
       
   359 void CKeyStoreExample::DeleteKey()
       
   360 {
       
   361 	// iKey is a CCTKeyInfo*
       
   362 
       
   363 	iKeyStore->DeleteKey(*iKey, iStatus);
       
   364 	iState = EDeleteKey;
       
   365 	SetActive();
       
   366 	
       
   367 	// RunL called when this completes
       
   368 }
       
   369 @endcode
       
   370 
       
   371 @subsection exportPublicKey Getting the public key
       
   372 
       
   373 The ExportPublic() method allows the public key to be exported, in DER-encoded
       
   374 ASN.1 format.  To export an RSA public key, and then reconstruct a useful key
       
   375 object from it, an application might do the following:
       
   376 
       
   377 @code
       
   378 CKeyStoreExample::ExportRSAPublicKey()
       
   379 {
       
   380 	// iKey is a CCTKeyInfo*
       
   381 	// iPublicKeyData is an HBufC8*
       
   382 
       
   383 	iKeyStore->ExportPublic(*iKey, iPublicKeyData, iStatus);
       
   384 	iState = EExportPublic;
       
   385 	SetActive();
       
   386 }
       
   387 
       
   388 void CKeyStoreExample::RunL()
       
   389 {
       
   390 	switch (iState)
       
   391 	{
       
   392 		...
       
   393 
       
   394 		case EExportPublic:
       
   395 			DecodeRSAPublicKeyData();
       
   396 			break;
       
   397 
       
   398 		...
       
   399 	}
       
   400 }
       
   401 
       
   402 void CKeyStoreExample::DecodeRSAPublicKeyData()
       
   403 {
       
   404 	// iRSAPublicKey is a CRSAPublicKey*
       
   405 
       
   406 	TX509KeyFactory factory; 
       
   407 	iRSAPublicKey = factory.RSAPublicKeyL(*iPublicKeyData);
       
   408 }
       
   409 @endcode
       
   410 
       
   411 @subsection changePassphrase Changing the passphrase
       
   412 
       
   413 Changing the passphrase is accomplished by telling a key store to ask the user
       
   414 for the new passphrase.  This is done by obtaining the authentication object for
       
   415 a key in the appropriate key store, and calling its ChangeReferenceData()
       
   416 method.  The keystore will then prompt the user for the old and new passphrases,
       
   417 and it the old passphrase is entered correctly, the passphrase is changed.  The
       
   418 old and new passphrases are never seen by the calling application.
       
   419 
       
   420 For example:
       
   421 
       
   422 @code
       
   423 void ChangePassphraseL(CCTKeyInfo& aKey)
       
   424 {
       
   425 	MCTAuthenticationObject* authObject = aKey.Protector();
       
   426 	if (authObject == NULL)
       
   427 		User::Leave(KErrNotSupported);
       
   428 
       
   429 	authObject->ChangeReferenceData(iStatus);
       
   430 	iState = EChangePassphrase;
       
   431 	SetActive();
       
   432 
       
   433 	// RunL called when this completes
       
   434 }
       
   435 @endcode
       
   436 
       
   437 @section unifiedCertStore The Unified Certificate Store
       
   438 
       
   439 @subsection certstoreConcepts Certificate store concepts
       
   440 
       
   441 @subsubsection certTypes Supported certificate types
       
   442 
       
   443 The certificate store APIs support X509 and WTLS certificates.  Certificates can
       
   444 be physically present in the store (as is normally the case), or they can be
       
   445 referenced by a URL.  There are three "owner types" supported:
       
   446 
       
   447 @li CA - CA certs are used as trust roots when validating certificate chains.
       
   448 @li User - User certs are used to establish the user's identity with a remote server.
       
   449 @li Peer - Peer certs are a third party's user certs.
       
   450 
       
   451 @subsubsection certInfo Certificate info - CCTCertInfo
       
   452 
       
   453 This class holds information about a certificate, and is used to represent that
       
   454 certificate in the unified cert store API.  It has accessors for the following
       
   455 attributes:
       
   456 
       
   457 @li Label - a text string to identify the cert to users.
       
   458 @li SubjectKeyId - A hash of the subject's public key.
       
   459 @li IssuerKeyId - A hash of the issuer's public key
       
   460 @li CertificateFormat - The format of the certificate - X509, WTLS X509 URL or
       
   461 	WTLS URL - as defined by the TCertificateFormat enum.
       
   462 @li CertificateOwnerType - The type of the certificate - CA, user or peer - as
       
   463 	defined by the TCertificateOwnerType enum
       
   464 @li Size - The size of the actual certificate data in bytes.
       
   465 @li IsDeletable - Whether it is possible to delete this certificate.
       
   466 @li IssuerHash - A hash of the issuer's X500 distinguished name, or NULL if it is
       
   467 	unknown.
       
   468 @li Token - an MCTToken object that represents the actual cert store
       
   469 	implementation the cert is in.  It is possible to use this to get access to the
       
   470 	cert store implementation, but this is not recommended.
       
   471 
       
   472 Like CCTKeyInfo, this object has a conversion operator to TCTTokenObjectHandle.
       
   473 
       
   474 @subsubsection appTrustConcept Applicability and trust
       
   475 
       
   476 Certificates are marked to indicate what purpose they are to be used for - these
       
   477 uses are referred to as "applications".  Examples of applications include
       
   478 "software install" and "TLS client authentication".  Certs also have a "trust"
       
   479 setting - this indicates whether or not the certificate should be trusted for
       
   480 any of its application.  The idea is that a program will look for all
       
   481 certificates which have the correct application and that are trusted, in order
       
   482 to restrict its search to relevant certificates.
       
   483 
       
   484 @subsection creatingUnifiedCertStore Creating a Unified Certificate Store
       
   485 
       
   486 The unified cert store can be opened in two modes - writeable and read only.
       
   487 The mode is determined by a parameter passed to the NewL() and NewLC() methods.
       
   488 Once the object has been created, it must be initialised, and this is done by
       
   489 the asynchronous Initialize() method.
       
   490 
       
   491 For example, to create and open a unified cert store in writable mode a client
       
   492 might use the following code:
       
   493 
       
   494 @code
       
   495 void CCertStoreExample::OpenUnifiedCertStoreL()
       
   496 	{
       
   497 	// iCertStore is a CUnifiedCertStore* 
       
   498 	// iFS is an RFs (file server client)
       
   499 	// iState is an enum that records the state of the active object
       
   500 
       
   501 	iCertStore = CUnifiedCertStore::NewL(iFs, ETrue);
       
   502 	iCertStore->Initialize(iStatus);
       
   503 	iState = EInitializingCertStore;
       
   504 	SetActive();
       
   505 
       
   506 	// RunL called when this completes
       
   507 	}
       
   508 @endcode
       
   509 
       
   510 @subsection listCerts Finding certificates
       
   511 
       
   512 The unified cert store supplies a List() methods to find certificates in the
       
   513 stores.  A filter object of type CCertAttibuteFilter is passed in to restrict
       
   514 the certificates returned.  This is defined in ccertattributefilter.h.  It has
       
   515 setter methods for the following attributes:
       
   516 
       
   517 @li Label - The label to match.
       
   518 @li Uid - The UID of an application the certificates must support.
       
   519 @li Format - The desired format.
       
   520 @li OwnerType - The desired owner type.
       
   521 @li KeyUsage - The key usage the certificates must support.
       
   522 @li SubjectKeyId - Used when searching for a certificate that matches a key.
       
   523 @li IssuerKeyId - Used when searching for all certs issued by particular cert.
       
   524 
       
   525 These attributes default to a "don't care" setting.  All attributes that have
       
   526 been set must match for a certificate to be returned.
       
   527 
       
   528 The first version of the list method just takes a filter and a reference to an
       
   529 array of cert info objects which it populates with the results of the search.
       
   530 For example to list all X509 CA certs on a device:
       
   531 
       
   532 @code
       
   533 void CCertStoreExample::ListCertsL()
       
   534 {
       
   535 	// iCerts is an RMPointerArray<CCTCertInfo> which will be filled with the certs found 
       
   536 	// iCertFilter is a CCertAttributeFilter*, initially set to NULL
       
   537 
       
   538 	// Create filter object
       
   539 	iCertFilter = CCertAttributeFilter::NewL();		
       
   540 	iCertFilter->SetFormat(EX509Certificate);
       
   541 	iCertFilter->SetOwnerType(ECACertificate);
       
   542 
       
   543 	iCertStore->List(iCerts, *iCertFilter, iStatus);
       
   544 	iState = EListCerts;
       
   545 	SetActive();		
       
   546 
       
   547 	// RunL called when this completes
       
   548 }
       
   549 @endcode
       
   550 
       
   551 There are two further List() overloads that allow filtering based on the
       
   552 issuer's distinguished name.  These take a single DN to match, and a list of
       
   553 possible DNs to match.
       
   554 
       
   555 @subsection addCert Adding certificates
       
   556 
       
   557 To add a certificate it is first necessary to determine which actual certificate
       
   558 store the new certificate should reside in.  The unified cert store gives access
       
   559 to all writable cert stores through the WritableCertStoreCount() and
       
   560 WritableCertStore() methods.  Note that if the unified cert store has been
       
   561 opened in readonly mode, it will report that there are no writable cert stores
       
   562 available.  Writable cert store implement the MCTWritableCertStore interface,
       
   563 defined in mctwritablecertstore.h.
       
   564 
       
   565 Using these methods is much the same as for the equivalent methods to get key
       
   566 store managers in the unified key store.  So, to compile a list of the available
       
   567 writable cert store, an application might use the following code:
       
   568 
       
   569 @code
       
   570 void CCertStoreExample::GetWritableCertStoreLabelsL()
       
   571 {
       
   572 	// iLabelList is a RPointerArray<HBufC8>
       
   573 
       
   574 	for (TInt index = 0 ; index < iCertStore->WritableCertStoreCount() ; ++i)
       
   575 	{
       
   576 		MCTWritableCertStore& store = iCertStore->WritableCertStore(index);
       
   577 		MCTToken& token = store->Token();
       
   578 		HBufC* label = token->Label().AllocLC();
       
   579 		User::LeaveIfError(iLabelList.Append(label));
       
   580 		CleanupStack::Pop(label);
       
   581 	}
       
   582 }
       
   583 @endcode
       
   584 
       
   585 When a writable cert store has been chosen, the certificate can be added.  The
       
   586 Add method takes the following parameters:
       
   587 
       
   588 @li Label - The label used to refer to the cert in the user interface.
       
   589 @li OwnerType - Whether it's a CA, user or peer certificate.
       
   590 @li SubjectKeyId - The hash of the subject public key - mandatory for URL certs, optional otherwise
       
   591 @li IssuerKeyId - The hash of the issuer public key - optional.
       
   592 @li Cert - The certificate data in DER encoded ASN.1.
       
   593 
       
   594 For example, to add an X509 CA cert, an application might do the following:
       
   595 
       
   596 @code
       
   597 void CCertStoreExample::AddCert()
       
   598 {
       
   599 	// iCertData is an HBufC8* containing the certificate
       
   600 	// iCertLabel is an HBufC* containing the label
       
   601 
       
   602 	iCertStore->Add(*iCertLabel, ECACert, NULL, NULL, *iCertData, iStatus);
       
   603 	iState = EAddingCert;
       
   604 	SetActive();
       
   605 
       
   606 	// RunL called when this completes
       
   607 }
       
   608 @endcode
       
   609 
       
   610 @subsection removeCert Removing certificates
       
   611 
       
   612 Removing a certificate is done by simply calling the Remove() method and passing
       
   613 it the CCTCertInfo of the certificate to be removed.  For example:
       
   614 
       
   615 @code
       
   616 void CCertStoreExample::RemoveCert()
       
   617 {
       
   618 	// iCert is a CCTCertInfo*
       
   619 
       
   620 	iCertStore->Remove(iCert, iStatus);
       
   621 	iState = ERemovingCert;
       
   622 	SetActive();
       
   623 
       
   624 	// RunL called when this completes
       
   625 }
       
   626 @endcode
       
   627 
       
   628 @subsection retrieveCert Retrieving certificates
       
   629 
       
   630 There are two Retrieve() methods - one allows the caller to retrieve the ASN.1
       
   631 certificate data and the other the parsed representation, a CCertificate-derived
       
   632 object (CCertificate is defined in signed.h).
       
   633 
       
   634 It is not possible to retrieve the parsed representation of URL certificates -
       
   635 the method will complete with KErrNotSupported in this case.
       
   636 
       
   637 For example, to get the ASN.1 data for a certificate:
       
   638 
       
   639 @code
       
   640 void CCertStoreExample::RetrieveCertData()
       
   641 {
       
   642 	// iCert is a CCTCertInfo*
       
   643 	// iCertData is an HBufC8*
       
   644 
       
   645 	// Allocate buffer of appropriate length
       
   646 	iCertData = HBufC8::NewMaxL(iCert->Size());
       
   647 
       
   648 	iCertStore->Retrieve(iCert, iCertData->Des(), iStatus);
       
   649 	iState = ERetrievingCertData;
       
   650 	SetActive();
       
   651 
       
   652 	// RunL called when this completes
       
   653 }
       
   654 @endcode
       
   655 
       
   656 And to get the parsed representation:
       
   657 
       
   658 @code
       
   659 void CCertStoreExample::RetrieveCertObject()
       
   660 {
       
   661 	// iCert is a CCTCertInfo*
       
   662 	// iCertObject is an CCertificate*
       
   663 
       
   664 	iCertStore->Retrieve(iCert, iCertObject, iStatus);
       
   665 	iState = ERetrievingCertObject;
       
   666 	SetActive();
       
   667 
       
   668 	// RunL called when this completes
       
   669 }
       
   670 @endcode
       
   671 
       
   672 @subsection certApps Certificate applications and trust
       
   673 
       
   674 The unified cert store API provides the following methods to get and set the
       
   675 applicability and trust settings for certificates:
       
   676 
       
   677 @li Applications - Get a list of application UIDs for a cert
       
   678 @li IsApplicable - Determine whether a cert has a specific application UID
       
   679 @li Trused - Determine whether a cert is trusted
       
   680 @li SetApplicability - Set the list of application UIDs
       
   681 @li SetTrust - Set the trust flag
       
   682 
       
   683 */