|
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 */ |