1 @node Hardware security modules and abstract key types
2 @chapter Hardware security modules and abstract key types
4 In several cases storing the long term cryptographic keys in a hard disk or
5 even in memory poses a significant risk. Once the system they are stored
6 is compromised the keys must be replaced as the secrecy of future sessions
7 is no longer guarranteed. Moreover, past sessions that were not protected by a
8 perfect forward secrecy offering ciphersuite are also to be assumed compromised.
10 If such threats need to be addressed, then it may be wise storing the keys in a security
11 module such as a smart card, an HSM or the TPM chip. Those modules ensure the
12 protection of the cryptographic keys by only allowing operations on them and
13 preventing their extraction.
16 * Abstract key types::
17 * Smart cards and HSMs::
18 * Trusted Platform Module::
21 @node Abstract key types
22 @section Abstract key types
23 @cindex abstract types
25 Since there are many forms of a public or private keys supported by @acronym{GnuTLS} such as
26 @acronym{X.509}, @acronym{OpenPGP}, @acronym{PKCS} #11 or TPM it is desirable to allow common operations
27 on them. For these reasons the abstract @code{gnutls_privkey_t} and @code{gnutls_pubkey_t} were
28 introduced in @code{gnutls/abstract.h} header. Those types are initialized using a specific type of
29 key and then can be used to perform operations in an abstract way. For example in order
30 to sign an X.509 certificate with a key that resides in a token the following steps must be
34 #inlude <gnutls/abstract.h>
36 void sign_cert( gnutls_x509_crt_t to_be_signed)
38 gnutls_x509_crt_t ca_cert;
39 gnutls_privkey_t abs_key;
41 /* initialize the abstract key */
42 gnutls_privkey_init(&abs_key);
44 /* keys stored in tokens are identified by URLs */
45 gnutls_privkey_import_url(abs_key, key_url);
47 gnutls_x509_crt_init(&ca_cert);
48 gnutls_x509_crt_import_pkcs11_url(&ca_cert, cert_url);
50 /* sign the certificate to be signed */
51 gnutls_x509_crt_privkey_sign(to_be_signed, ca_cert, abs_key,
52 GNUTLS_DIG_SHA256, 0);
57 * Abstract public keys::
58 * Abstract private keys::
62 @node Abstract public keys
63 @subsection Public keys
64 An abstract @code{gnutls_pubkey_t} can be initialized
65 using the functions below. It can be imported through
66 an existing structure like @code{gnutls_x509_crt_t},
67 or through an ASN.1 encoding of the X.509 @code{SubjectPublicKeyInfo}
70 @showfuncC{gnutls_pubkey_import_x509,gnutls_pubkey_import_openpgp,gnutls_pubkey_import_pkcs11}
72 @showfuncC{gnutls_pubkey_import_url,gnutls_pubkey_import_privkey,gnutls_pubkey_import}
74 @showfuncB{gnutls_pubkey_export,gnutls_pubkey_export2}
76 Other helper functions that allow directly importing from raw X.509 or
77 OpenPGP structures are shown below.
79 @showfuncB{gnutls_pubkey_import_x509_raw,gnutls_pubkey_import_openpgp_raw}
81 An important function is @funcref{gnutls_pubkey_import_url} which will import
82 public keys from URLs that identify objects stored in tokens (see @ref{Smart cards and HSMs} and @ref{Trusted Platform Module}).
83 A function to check for a supported by GnuTLS URL is @funcref{gnutls_url_is_supported}.
85 @showfuncdesc{gnutls_url_is_supported}
87 Additional functions are available that will return
88 information over a public key, as well as a function that given a public
89 key fingerprint would provide a memorable sketch.
91 @showfuncD{gnutls_pubkey_get_pk_algorithm,gnutls_pubkey_get_preferred_hash_algorithm,gnutls_pubkey_get_key_id,gnutls_random_art}
95 @node Abstract private keys
96 @subsection Private keys
97 An abstract @code{gnutls_privkey_t} can be initialized
98 using the functions below. It can be imported through
99 an existing structure like @code{gnutls_x509_privkey_t},
100 but unlike public keys it cannot be exported. That is
101 to allow abstraction over keys stored in hardware that
102 makes available only operations.
104 @showfuncC{gnutls_privkey_import_x509,gnutls_privkey_import_openpgp,gnutls_privkey_import_pkcs11}
106 Other helper functions that allow directly importing from raw X.509 or
107 OpenPGP structures are shown below. Again, as with public keys, private keys
108 can be imported from a hardware module using URLs.
110 @showfuncB{gnutls_privkey_import_x509_raw,gnutls_privkey_import_openpgp_raw}
112 @showfuncdesc{gnutls_privkey_import_url}
114 @showfuncB{gnutls_privkey_get_pk_algorithm,gnutls_privkey_get_type}
116 In order to support cryptographic operations using
117 an external API, the following function is provided.
118 This allows for a simple extensibility API without
119 resorting to @acronym{PKCS} #11.
121 @showfuncdesc{gnutls_privkey_import_ext2}
124 @subsection Operations
125 The abstract key types can be used to access signing and
126 signature verification operations with the underlying keys.
128 @showfuncdesc{gnutls_pubkey_verify_data2}
129 @showfuncdesc{gnutls_pubkey_verify_hash2}
130 @showfuncdesc{gnutls_pubkey_encrypt_data}
132 @showfuncdesc{gnutls_privkey_sign_data}
133 @showfuncdesc{gnutls_privkey_sign_hash}
134 @showfuncdesc{gnutls_privkey_decrypt_data}
136 Signing existing structures, such as certificates, CRLs,
137 or certificate requests, as well as associating public
138 keys with structures is also possible using the
141 @showfuncdesc{gnutls_x509_crq_set_pubkey}
142 @showfuncdesc{gnutls_x509_crt_set_pubkey}
143 @showfuncC{gnutls_x509_crt_privkey_sign,gnutls_x509_crl_privkey_sign,gnutls_x509_crq_privkey_sign}
145 @node Smart cards and HSMs
146 @section Smart cards and HSMs
147 @cindex PKCS #11 tokens
148 @cindex hardware tokens
149 @cindex hardware security modules
152 In this section we present the smart-card and hardware security module (HSM) support
153 in @acronym{GnuTLS} using @acronym{PKCS} #11 @xcite{PKCS11}. Hardware security
154 modules and smart cards provide a way to store private keys and perform
155 operations on them without exposing them. This decouples cryptographic
156 keys from the applications that use them and provide an additional
157 security layer against cryptographic key extraction.
158 Since this can also be achieved in software components such as in Gnome keyring,
159 we will use the term security module to describe any cryptographic key
160 separation subsystem.
162 @acronym{PKCS} #11 is plugin API allowing applications to access cryptographic
163 operations on a security module, as well as to objects residing on it. PKCS
164 #11 modules exist for hardware tokens such as smart cards@footnote{@url{http://www.opensc-project.org}},
165 cryptographic tokens, as well as for software modules like @acronym{Gnome Keyring}.
166 The objects residing on a security module may be certificates, public keys,
167 private keys or secret keys. Of those certificates and public/private key
168 pairs can be used with @acronym{GnuTLS}. PKCS #11's main advantage is that
169 it allows operations on private key objects such as decryption
170 and signing without exposing the key. In GnuTLS the PKCS #11 functionality is
171 available in @code{gnutls/pkcs11.h}.
173 Moreover @acronym{PKCS} #11 can be (ab)used to allow all applications in the same operating system to access
174 shared cryptographic keys and certificates in a uniform way, as in @ref{fig:pkcs11-vision}.
175 That way applications could load their trusted certificate list, as well as user
176 certificates from a common PKCS #11 module. Such a provider exists in the @acronym{Gnome}
177 system, being the @acronym{Gnome Keyring}.
179 @float Figure,fig:pkcs11-vision
180 @image{pkcs11-vision,9cm}
181 @caption{PKCS #11 module usage.}
185 * PKCS11 Initialization::
186 * Accessing objects that require a PIN::
189 * Using a PKCS11 token with TLS::
190 * p11tool Invocation:: Invoking p11tool
193 @node PKCS11 Initialization
194 @subsection Initialization
195 To allow all the @acronym{GnuTLS} applications to access @acronym{PKCS} #11 tokens
196 you can use a configuration per module, stored in @code{/etc/pkcs11/modules/}.
197 These are the configuration files of @acronym{p11-kit}@footnote{@url{http://p11-glue.freedesktop.org/}}.
198 For example a file that will load the @acronym{OpenSC} module, could be named
199 @code{/etc/pkcs11/modules/opensc} and contain the following:
202 module: /usr/lib/opensc-pkcs11.so
205 If you use this file, then there is no need for other initialization in
206 @acronym{GnuTLS}, except for the PIN and token functions (see next section).
207 However, you may manually initialize the PKCS #11 subsystem if the default
208 settings are not desirable.
210 @showfuncdesc{gnutls_pkcs11_init}
212 Note that PKCS #11 modules must be reinitialized on the child processes
213 after a @funcintref{fork}. @acronym{GnuTLS} provides @funcref{gnutls_pkcs11_reinit}
214 to be called for this purpose.
216 @showfuncdesc{gnutls_pkcs11_reinit}
218 @node Accessing objects that require a PIN
219 @subsection Accessing objects that require a PIN
221 Objects stored in token such as a private keys are typically protected
222 from access by a PIN or password. This PIN may be required to either read
223 the object (if allowed) or to perform operations with it. To allow obtaining
224 the PIN when accessing a protected object, as well as probe
225 the user to insert the token the following functions allow to set a callback.
227 @showfuncD{gnutls_pkcs11_set_token_function,gnutls_pkcs11_set_pin_function,gnutls_pkcs11_add_provider,gnutls_pkcs11_get_pin_function}
229 The callback is of type @funcintref{gnutls_pin_callback_t} and will have as
230 input the provided userdata, the PIN attempt number, a URL describing the
231 token, a label describing the object and flags. The PIN must be at most
232 of @code{pin_max} size and must be copied to pin variable. The function must
233 return 0 on success or a negative error code otherwise.
236 typedef int (*gnutls_pin_callback_t) (void *userdata, int attempt,
237 const char *token_url,
238 const char *token_label,
240 char *pin, size_t pin_max);
243 The flags are of @code{gnutls_pin_flag_t} type and are explained below.
245 @showenumdesc{gnutls_pin_flag_t,The @code{gnutls_pin_@-flag_t} enumeration.}
247 Note that due to limitations of @acronym{PKCS} #11 there are issues when multiple libraries
248 are sharing a module. To avoid this problem GnuTLS uses @acronym{p11-kit}
249 that provides a middleware to control access to resources over the
252 To avoid conflicts with multiple registered callbacks for PIN functions,
253 @funcref{gnutls_pkcs11_get_pin_function} may be used to check for any previously
254 set functions. In addition context specific PIN functions are allowed, e.g., by
255 using functions below.
257 @showfuncE{gnutls_certificate_set_pin_function,gnutls_pubkey_set_pin_function,gnutls_privkey_set_pin_function,gnutls_pkcs11_obj_set_pin_function,gnutls_x509_crt_set_pin_function}
259 @node Reading objects
260 @subsection Reading objects
262 All @acronym{PKCS} #11 objects are referenced by @acronym{GnuTLS} functions by
263 URLs as described in @xcite{PKCS11URI}.
264 This allows for a consistent naming of objects across systems and applications
265 in the same system. For example a public
266 key on a smart card may be referenced as:
269 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
270 manufacturer=EnterSafe;object=test1;objecttype=public;\
271 id=32f153f3e37990b08624141077ca5dec2d15faed
274 while the smart card itself can be referenced as:
276 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe
279 Objects stored in a @acronym{PKCS} #11 token can be extracted
280 if they are not marked as sensitive. Usually only private keys are marked as
281 sensitive and cannot be extracted, while certificates and other data can
282 be retrieved. The functions that can be used to access objects
285 @showfuncB{gnutls_pkcs11_obj_import_url,gnutls_pkcs11_obj_export_url}
287 @showfuncdesc{gnutls_pkcs11_obj_get_info}
289 @showfuncC{gnutls_x509_crt_import_pkcs11,gnutls_x509_crt_import_pkcs11_url,gnutls_x509_crt_list_import_pkcs11}
291 Properties of the physical token can also be accessed and altered with @acronym{GnuTLS}.
292 For example data in a token can be erased (initialized), PIN can be altered, etc.
294 @showfuncE{gnutls_pkcs11_token_init,gnutls_pkcs11_token_get_url,gnutls_pkcs11_token_get_info,gnutls_pkcs11_token_get_flags,gnutls_pkcs11_token_set_pin}
296 The following examples demonstrate the usage of the API. The first example
297 will list all available PKCS #11 tokens in a system and the latter will
298 list all certificates in a token that have a corresponding private key.
304 gnutls_global_init();
308 ret = gnutls_pkcs11_token_get_url(i, &url);
309 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
315 fprintf(stdout, "Token[%d]: URL: %s\n", i, url);
318 gnutls_global_deinit();
321 @verbatiminclude examples/ex-pkcs11-list.c
323 @node Writing objects
324 @subsection Writing objects
326 With @acronym{GnuTLS} you can copy existing private keys and certificates
327 to a token. Note that when copying private keys it is recommended to mark
328 them as sensitive using the @code{GNUTLS_@-PKCS11_OBJ_@-FLAG_@-MARK_@-SENSITIVE}
329 to prevent its extraction. An object can be marked as private using the flag
330 @code{GNUTLS_@-PKCS11_OBJ_@-FLAG_@-MARK_@-PRIVATE}, to require PIN to be
331 entered before accessing the object (for operations or otherwise).
333 @showfuncdesc{gnutls_pkcs11_copy_x509_privkey}
335 @showfuncdesc{gnutls_pkcs11_copy_x509_crt}
336 @showfuncdesc{gnutls_pkcs11_delete_url}
339 @node Using a PKCS11 token with TLS
340 @subsection Using a @acronym{PKCS} #11 token with TLS
342 It is possible to use a @acronym{PKCS} #11 token to a TLS
343 session, as shown in @ref{ex:pkcs11-client}. In addition
344 the following functions can be used to load PKCS #11 key and
345 certificates by specifying a PKCS #11 URL instead of a filename.
347 @showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_key_file}
348 @showfuncdesc{gnutls_certificate_set_x509_system_trust}
350 @include invoke-p11tool.texi
352 @node Trusted Platform Module
353 @section Trusted Platform Module (TPM)
354 @cindex trusted platform module
357 In this section we present the Trusted Platform Module (TPM) support
358 in @acronym{GnuTLS}. There was a big hype when the TPM chip was introduced into
359 computers. Briefly it is a co-processor in your PC that allows it to perform
360 calculations independently of the main processor. This has good and bad
361 side-effects. In this section we focus on the good ones, which are the fact that
362 you can use it to perform cryptographic operations the similarly to a
363 @acronym{PKCS} #11 smart card.
364 It allows for storing and using RSA keys but with slight differences
365 from a @acronym{PKCS} #11 module that require different handling.
366 The basic operations supported, and used by GnuTLS, are key generation and signing.
368 In GnuTLS the TPM functionality is available in @code{gnutls/tpm.h}.
374 * tpmtool Invocation:: Invoking tpmtool
378 @subsection Keys in TPM
380 The RSA keys in the TPM module may either be stored in a flash memory
381 within TPM or stored in a file in disk. In the former case the key can
382 provide operations as with @acronym{PKCS} #11 and is identified by
383 a URL. The URL is of the following form.
385 tpmkey:uuid=42309df8-d101-11e1-a89a-97bb33c23ad1;storage=user
388 It consists from a unique identifier of the key as well as the part of the
389 flash memory the key is stored at. The two options for the storage field are
390 `user' and `system'. The user keys are typically only available to the generating
391 user and the system keys to all users. The stored in TPM keys are called
394 The keys that are stored in the disk are exported from the TPM but in an
395 encrypted form. To access them two passwords are required. The first is the TPM
396 Storage Root Key (SRK), and the other is a key-specific password. Also those keys are
397 identified by a URL of the form:
399 tpmkey:file=/path/to/file
402 When objects require a PIN to be accessed the same callbacks as with PKCS #11
403 objects are expected (see @ref{Accessing objects that require a PIN}).
406 @subsection Key generation
408 All keys used by the TPM must be generated by the TPM. This can be
409 done using @funcref{gnutls_tpm_privkey_generate}.
411 @showfuncdesc{gnutls_tpm_privkey_generate}
413 @showfuncC{gnutls_tpm_get_registered,gnutls_tpm_key_list_deinit,gnutls_tpm_key_list_get_url}
415 @showfuncdesc{gnutls_tpm_privkey_delete}
418 @subsection Using keys
420 @subsubheading Importing keys
422 The TPM keys can be used directly by the abstract key types and do not require
423 any special structures. Moreover functions like @funcref{gnutls_certificate_set_x509_key_file}
426 @showfuncB{gnutls_privkey_import_tpm_raw,gnutls_pubkey_import_tpm_raw}
428 @showfuncdesc{gnutls_privkey_import_tpm_url}
429 @showfuncdesc{gnutls_pubkey_import_tpm_url}
431 @subsubheading Listing and deleting keys
433 The registered keys (that are stored in the TPM) can be listed using one of
434 the following functions. Those keys are unfortunately only identified by
435 their UUID and have no label or other human friendly identifier.
436 Keys can be deleted from permament storage using @funcref{gnutls_tpm_privkey_delete}.
438 @showfuncC{gnutls_tpm_get_registered,gnutls_tpm_key_list_deinit,gnutls_tpm_key_list_get_url}
440 @showfuncdesc{gnutls_tpm_privkey_delete}
443 @include invoke-tpmtool.texi