Building a certificate store

Revision 0.02

1.	Purpose 

This note describes how to build a certificate store in Symbian OS version 7 and above which contains appropriate values for your application.

2.	Overview
2.1 Clients and root certificates

To do certificate validation a client must have at least one certificate which it trusts directly. This is called a root certificate. It's pretty clear that different clients are going to trust different certificates: so TLS might trust VeriSign's secure server root, but software install would not. 

To handle this situation, the certificate store contains zero or more 'clients' (sometimes known as 'applications' in the documentation). Each client consists of a UID and a human-readable name, and represents an application which is going to use the certificate validation interface. For example, TLS is a client, as is software installation. Each certificate is marked as trusted by zero or more of these clients: this is what makes it a root certificate for that application. 

The clients are stored in a file called certclients.dat. Certificates are stored in a separate file called cacerts.dat.

The way it works is this: the application using the certificate validation interface will supply the appropriate UID to the certificate validation object, which will use this to select the subset of certificates which are trusted by that application: these form the set of 'candidate' root certificates. The UID can be anything at all, as long as the same UID is used in the store as is supplied to certificate validation. (In particular, it doesn't need to be the app UID, although this might be a sensible choice.)

So to get your app working with certificate validation, you need to:
•	add an entry for your app into the list of clients
•	add any certificates you need 
•	mark them as trusted by your client

2.2 Using the test code

In Symbian OS v7 and above, you should use the test code for the certificate store to do this. 
The test code takes a script file and  the name of an log file as input, then executes the actions specified in the script file, checks the results and logs them to the log file.

So the steps are:
•	create appropriate script files
•	build the test code
•	run the test code

3.	Creating the scripts

Each action in the test script will have:
•	the action name, used to log the action: this can be anything
•	the action type: an identifier for the type of action to be performed
•	the action body, whose syntax is dependent on the type of action
•	the expected result: this consists of a return value, which will always be KErrNone in these scripts, and extra fields which depend on the action type

See the appendix for sample scripts. Your best bet is probably to edit these. Although the scripts to add clients and add certificates are described separately, it is possible to have a single script that does both - just append one to the other.
3.1	Adding clients
To add clients, you need the script to execute the following actions:
•	create the client manager
•	add each client
•	list the clients, optionally (this is useful as it shows you whether you have successfully added the right set of clients)
•	delete the client manager
3.1.1 Creating the client manager
•	identifier: initappmanager
•	body: empty
3.1.2 Adding clients
For each client you wish to add, you need to have a separate 'add client' action. 
•	identifier: addclient
•	body:
	name: the name of your client
	UID: your client's UID, specified in decimal
3.1.3	Listing clients
•	identifier: getclients
•	body: empty
•	expected result: for each client you have added, its UID (this enables it to check that the contents of the store are what you expect)
3.1.4 Deleting the client manager
•	identifier: deleteappmanager
•	body: empty
3.2	Adding certificates
To add certificates, you need the script to execute the following actions:
•	create a new file cert store (this is optional: if you want to add certificates to an existing store, do not include this action)
•	initialise the store
•	add the certificates
•	set your client as a truster for each certificate you wish to use as a root
•	mark as trusted each each certificate you wish to use as a root
•	optionally, check that the new certificates exist and are trusted
•	delete the store manager
3.2.1 Create file cert store
•	identifier: createfilecertstore
•	body:
	filename: full path and filename for where the store should be created
3.2.2 Initialise store
•	identifier: init
•	body:
	mode: should be write
3.2.3 Add certificate
For each certificate you want to add, you need a separate add certificate action.
•	identifier: addcert
•	body:
	format: X509 or WTLS
	label: human-readable label, must be unique to that store
	issuer key: only needed for user certificates
	subject key: only needed for user certificates
	certstore: identifies which store to add it to: use 0
	certfile: full path and filename for the certificate to add. The certificate needs to be DER-encoded ASN.1 (i.e. not PEM). The path is the emulator's view, so 'c:\' corresponds to \epoc32\release\win\c'
	the type of certificate: CA or user: use CA here 
3.2.4 Set applications
•	identifier: setapplications
•	body:
label: the label of the relevant certificate 
UID: the UID for the relevant application
3.2.5 Set trust
•	identifier: settrust
•	body:
label: the label of the relevant certificate 
	trust: 1 to trust this certificate
3.2.6 Get trusters
This is optional. It will show you the list of clients which trust a specified certificate. 
•	identifier: getapplications
•	body:
label: the label of the relevant certificate 
•	result
	the UID of each application we expect
3.2.7 Deleting the store manager
•	identifier: delete
•	body: empty

4	Building and running the test code
4.1	Building the test framework
The test framework used by the certificate store test code is located in 'security\testframework'. From security\testframework\group, type:

bldmake bldfiles
able test build

4.2	Building the certificate store test code
The test framework used by the certificate store test code is located in 'security\certman'. From security\certman\group, type:

bldmake bldfiles
able test build
4.3	Running the test code
The test harness to run is t_certstore.exe (it is located in \epoc32\release\wins\udeb\). The test harness takes two command line arguments : the name of the script to run and the name of a log file. In order to run a script called script.txt and output the result to log.txt, you have to type the following command:

t_certstore script.txt log.txt
Because the test code runs in the emulator, its view of the file system is that c:\ is found at NT's \epoc32\wins\c. So in the example above, script needs to be placed at \epoc32\wins\c, and log will be created in \epoc32\wins\c.  The ‘console’ option is necessary to ensure the tool can operate independently of the UI environment.

By default, the test harness runs and closes the emulator immediately. This makes it impossible to view the results on the screen (but they are in the log) but makes it possible to run the test unattended. It is possible to request that the test harness waits for a key press before closing the emulator by adding a –w at the end of the command line. You would then type
t_certstore script.txt log.txt -w
and you have to press a key to close the emulator after the end of the tests.

Appendix: Sample scripts
Adding clients

The following script will add a single client called 'MyClient' with a UID of 123456.

<action>
	<actionname>Creating a CertificateAppInfoManager</actionname>
	<actiontype>initappmanager</actiontype>
	<actionbody></actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>
<action>
	<actionname>Adding client MyClient</actionname>
	<actiontype>addclient</actiontype>
	<actionbody>
		<name>MyClient</name>
		<uid>123456</uid>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

<action>
	<actionname>Retrieving the clients</actionname>
	<actiontype>getclients</actiontype>
	<actionbody></actionbody>
	<actionresult>
		<return>KErrNone</return>
		<uid>123456</uid>
	</actionresult>
</action>

<action>
	<actionname>Deleting the CertificateAppInfoManager</actionname>
	<actiontype>deleteappmanager</actiontype>
	<actionbody></actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

Adding certificates
The following script will create a new certificate store, and add the X.509 certificate found in c:\thawtetest.crt as a CA certificate with the label 'Thawte Root', trusted by the client with UID 123456. 

<action>
	<actionname>Creating a new file certstore</actionname>
	<actiontype>createfilecertstore</actiontype>
	<actionbody>
		<filename>c:\cacerts.dat</filename>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

<action>
	<actionname>Initializing a CUnifiedCertStore</actionname>
	<actiontype>init</actiontype>
	<actionbody>
		<mode>write</mode>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

<action>
	<actionname>Add the certificate Thawte Root</actionname>
	<actiontype>addcert</actiontype>
	<actionbody>
		<format>X509</format>
		<label>Thawte Root</label>
		<issuerkey></issuerkey>
		<subjectkey></subjectkey>
		<certstore>0</certstore>
		<certfile>c:\thawtetest.crt</certfile>
		<certowner>CA</certowner>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

<action>
	<actionname>Set applications for Thawte Root</actionname>
	<actiontype>setapplications</actiontype>
	<actionbody>
		<label>Thawte Root</label>
		<uid>123456</uid>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

<action>
	<actionname>Set the trust for Thawte Root </actionname>
	<actiontype>settrust</actiontype>
	<actionbody>
		<label>Thawte Root</label>
		<trust>1</trust>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>

<action>
	<actionname>Get applications for Thawte Root</actionname>
	<actiontype>getapplications</actiontype>
	<actionbody>
		<label>Thawte Root</label>
	</actionbody>
	<actionresult>
		<return>KErrNone</return>
		<uid>123456</uid>
	</actionresult>
</action>

<action>
	<actionname>Deleting the certificate store manager</actionname>
	<actiontype>delete</actiontype>
	<actionbody></actionbody>
	<actionresult>
		<return>KErrNone</return>
	</actionresult>
</action>