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 @showfuncdesc{gnutls_pubkey_export}
76 An important function is @funcref{gnutls_pubkey_import_url} which will import
77 public keys from URLs that identify objects stored in tokens (see @ref{Smart cards and HSMs} and @ref{Trusted platform module}).
78 A function to check for a supported by GnuTLS URL is @funcref{gnutls_url_is_supported}.
80 @showfuncdesc{gnutls_url_is_supported}
82 Additional functions are available that will return
83 information over a public key, as well as a function that given a public
84 key fingerprint would provide a memorable sketch.
86 @showfuncD{gnutls_pubkey_get_pk_algorithm,gnutls_pubkey_get_preferred_hash_algorithm,gnutls_pubkey_get_key_id,gnutls_random_art}
90 @node Abstract private keys
91 @subsection Private keys
92 An abstract @code{gnutls_privkey_t} can be initialized
93 using the functions below. It can be imported through
94 an existing structure like @code{gnutls_x509_privkey_t},
95 but unlike public keys it cannot be exported. That is
96 to allow abstraction over keys stored in hardware that
97 makes available only operations.
99 @showfuncC{gnutls_privkey_import_x509,gnutls_privkey_import_openpgp,gnutls_privkey_import_pkcs11}
101 Other helper functions that allow directly importing from raw X.509 or
102 OpenPGP structures are shown below. Again, as with public keys, private keys
103 can be imported from a hardware module using URLs.
105 @showfuncB{gnutls_privkey_import_x509_raw,gnutls_privkey_import_openpgp_raw}
107 @showfuncdesc{gnutls_privkey_import_url}
109 @showfuncB{gnutls_privkey_get_pk_algorithm,gnutls_privkey_get_type}
111 In order to support cryptographic operations using
112 an external API, the following function is provided.
113 This allows for a simple extensibility API without
114 resorting to @acronym{PKCS} #11.
116 @showfuncdesc{gnutls_privkey_import_ext2}
119 @subsection Operations
120 The abstract key types can be used to access signing and
121 signature verification operations with the underlying keys.
123 @showfuncdesc{gnutls_pubkey_verify_data2}
124 @showfuncdesc{gnutls_pubkey_verify_hash2}
125 @showfuncdesc{gnutls_pubkey_encrypt_data}
127 @showfuncdesc{gnutls_privkey_sign_data}
128 @showfuncdesc{gnutls_privkey_sign_hash}
129 @showfuncdesc{gnutls_privkey_decrypt_data}
131 Signing existing structures, such as certificates, CRLs,
132 or certificate requests, as well as associating public
133 keys with structures is also possible using the
136 @showfuncdesc{gnutls_x509_crq_set_pubkey}
137 @showfuncdesc{gnutls_x509_crt_set_pubkey}
138 @showfuncC{gnutls_x509_crt_privkey_sign,gnutls_x509_crl_privkey_sign,gnutls_x509_crq_privkey_sign}
140 @node Smart cards and HSMs
141 @section Smart cards and HSMs
142 @cindex PKCS #11 tokens
143 @cindex hardware tokens
144 @cindex hardware security modules
147 In this section we present the smart-card and hardware security module (HSM) support
148 in @acronym{GnuTLS} using @acronym{PKCS} #11 @xcite{PKCS11}. Hardware security
149 modules and smart cards provide a way to store private keys and perform
150 operations on them without exposing them. This decouples cryptographic
151 keys from the applications that use them and provide an additional
152 security layer against cryptographic key extraction.
153 Since this can also be achieved in software components such as in Gnome keyring,
154 we will use the term security module to describe any cryptographic key
155 separation subsystem.
157 @acronym{PKCS} #11 is plugin API allowing applications to access cryptographic
158 operations on a security module, as well as to objects residing on it. PKCS
159 #11 modules exist for hardware tokens such as smart cards@footnote{@url{http://www.opensc-project.org}},
160 cryptographic tokens, as well as for software modules like @acronym{Gnome Keyring}.
161 The objects residing on a security module may be certificates, public keys,
162 private keys or secret keys. Of those certificates and public/private key
163 pairs can be used with @acronym{GnuTLS}. PKCS #11's main advantage is that
164 it allows operations on private key objects such as decryption
165 and signing without exposing the key. In GnuTLS the PKCS #11 functionality is
166 available in @code{gnutls/pkcs11.h}.
168 Moreover @acronym{PKCS} #11 can be (ab)used to allow all applications in the same operating system to access
169 shared cryptographic keys and certificates in a uniform way, as in @ref{fig:pkcs11-vision}.
170 That way applications could load their trusted certificate list, as well as user
171 certificates from a common PKCS #11 module. Such a provider exists in the @acronym{Gnome}
172 system, being the @acronym{Gnome Keyring}.
174 @float Figure,fig:pkcs11-vision
175 @image{pkcs11-vision,9cm}
176 @caption{PKCS #11 module usage.}
180 * PKCS11 Initialization::
181 * Accessing objects that require a PIN::
184 * Using a PKCS11 token with TLS::
185 * p11tool Invocation:: Invoking p11tool
188 @node PKCS11 Initialization
189 @subsection Initialization
190 To allow all the @acronym{GnuTLS} applications to access @acronym{PKCS} #11 tokens
191 you can use a configuration per module, stored in @code{/etc/pkcs11/modules/}.
192 These are the configuration files of @acronym{p11-kit}@footnote{@url{http://p11-glue.freedesktop.org/}}.
193 For example a file that will load the @acronym{OpenSC} module, could be named
194 @code{/etc/pkcs11/modules/opensc} and contain the following:
197 module: /usr/lib/opensc-pkcs11.so
200 If you use this file, then there is no need for other initialization in
201 @acronym{GnuTLS}, except for the PIN and token functions (see next section).
202 However, you may manually initialize the PKCS #11 subsystem if the default
203 settings are not desirable.
205 @showfuncdesc{gnutls_pkcs11_init}
207 Note that PKCS #11 modules must be reinitialized on the child processes
208 after a @funcintref{fork}. @acronym{GnuTLS} provides @funcref{gnutls_pkcs11_reinit}
209 to be called for this purpose.
211 @showfuncdesc{gnutls_pkcs11_reinit}
213 @node Accessing objects that require a PIN
214 @subsection Accessing objects that require a PIN
216 Objects stored in token such as a private keys are typically protected
217 from access by a PIN or password. This PIN may be required to either read
218 the object (if allowed) or to perform operations with it. To allow obtaining
219 the PIN when accessing a protected object, as well as probe
220 the user to insert the token the following functions allow to set a callback.
222 @showfuncD{gnutls_pkcs11_set_token_function,gnutls_pkcs11_set_pin_function,gnutls_pkcs11_add_provider,gnutls_pkcs11_get_pin_function}
224 The callback is of type @funcintref{gnutls_pin_callback_t} and will have as
225 input the provided userdata, the PIN attempt number, a URL describing the
226 token, a label describing the object and flags. The PIN must be at most
227 of @code{pin_max} size and must be copied to pin variable. The function must
228 return 0 on success or a negative error code otherwise.
231 typedef int (*gnutls_pin_callback_t) (void *userdata, int attempt,
232 const char *token_url,
233 const char *token_label,
235 char *pin, size_t pin_max);
238 The flags are of @code{gnutls_pin_flag_t} type and are explained below.
240 @showenumdesc{gnutls_pin_flag_t,The @code{gnutls_pin_@-flag_t} enumeration.}
242 Note that due to limitations of @acronym{PKCS} #11 there are issues when multiple libraries
243 are sharing a module. To avoid this problem GnuTLS uses @acronym{p11-kit}
244 that provides a middleware to control access to resources over the
247 To avoid conflicts with multiple registered callbacks for PIN functions,
248 @funcref{gnutls_pkcs11_get_pin_function} may be used to check for any previously
249 set functions. In addition context specific PIN functions are allowed, e.g., by
250 using functions below.
252 @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}
254 @node Reading objects
255 @subsection Reading objects
257 All @acronym{PKCS} #11 objects are referenced by @acronym{GnuTLS} functions by
258 URLs as described in @xcite{PKCS11URI}.
259 This allows for a consistent naming of objects across systems and applications
260 in the same system. For example a public
261 key on a smart card may be referenced as:
264 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
265 manufacturer=EnterSafe;object=test1;objecttype=public;\
266 id=32f153f3e37990b08624141077ca5dec2d15faed
269 while the smart card itself can be referenced as:
271 pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe
274 Objects stored in a @acronym{PKCS} #11 token can be extracted
275 if they are not marked as sensitive. Usually only private keys are marked as
276 sensitive and cannot be extracted, while certificates and other data can
277 be retrieved. The functions that can be used to access objects
280 @showfuncB{gnutls_pkcs11_obj_import_url,gnutls_pkcs11_obj_export_url}
282 @showfuncdesc{gnutls_pkcs11_obj_get_info}
284 @showfuncC{gnutls_x509_crt_import_pkcs11,gnutls_x509_crt_import_pkcs11_url,gnutls_x509_crt_list_import_pkcs11}
286 Properties of the physical token can also be accessed and altered with @acronym{GnuTLS}.
287 For example data in a token can be erased (initialized), PIN can be altered, etc.
289 @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}
291 The following examples demonstrate the usage of the API. The first example
292 will list all available PKCS #11 tokens in a system and the latter will
293 list all certificates in a token that have a corresponding private key.
299 gnutls_global_init();
303 ret = gnutls_pkcs11_token_get_url(i, &url);
304 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
310 fprintf(stdout, "Token[%d]: URL: %s\n", i, url);
313 gnutls_global_deinit();
316 @verbatiminclude examples/ex-pkcs11-list.c
318 @node Writing objects
319 @subsection Writing objects
321 With @acronym{GnuTLS} you can copy existing private keys and certificates
322 to a token. Note that when copying private keys it is recommended to mark
323 them as sensitive using the @code{GNUTLS_@-PKCS11_OBJ_@-FLAG_@-MARK_@-SENSITIVE}
324 to prevent its extraction. An object can be marked as private using the flag
325 @code{GNUTLS_@-PKCS11_OBJ_@-FLAG_@-MARK_@-PRIVATE}, to require PIN to be
326 entered before accessing the object (for operations or otherwise).
328 @showfuncdesc{gnutls_pkcs11_copy_x509_privkey}
330 @showfuncdesc{gnutls_pkcs11_copy_x509_crt}
331 @showfuncdesc{gnutls_pkcs11_delete_url}
334 @node Using a PKCS11 token with TLS
335 @subsection Using a @acronym{PKCS} #11 token with TLS
337 It is possible to use a @acronym{PKCS} #11 token to a TLS
338 session, as shown in @ref{ex:pkcs11-client}. In addition
339 the following functions can be used to load PKCS #11 key and
340 certificates by specifying a PKCS #11 URL instead of a filename.
342 @showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_key_file}
343 @showfuncdesc{gnutls_certificate_set_x509_system_trust}
345 @include invoke-p11tool.texi
347 @node Trusted platform module
348 @section Trusted platform module
349 @cindex trusted platform module
352 In this section we present the Trusted Platform Module (TPM) support
353 in @acronym{GnuTLS}. The TPM chip allows for storing and using RSA keys in a
354 similar way as a @acronym{PKCS} #11 module, but with slight differences
355 that require different handling. The basic operations supported, and used
356 by GnuTLS, are key generation and signing.
358 In GnuTLS the TPM functionality is available in @code{gnutls/tpm.h}.
364 * tpmtool Invocation:: Invoking tpmtool
368 @subsection Keys in TPM
370 The RSA keys in the TPM module may either be stored in a flash memory
371 within TPM or stored in a file in disk. In the former case the key can
372 provide operations as with @acronym{PKCS} #11 and is identified by
373 a URL. The URL is of the following form.
375 tpmkey:uuid=42309df8-d101-11e1-a89a-97bb33c23ad1;storage=user
378 It consists from a unique identifier of the key as well as the part of the
379 flash memory the key is stored at. The two options for the storage field are
380 `user' and `system'. The user keys are typically only available to the generating
381 user and the system keys to all users. The stored in TPM keys are called
384 The keys that are stored in the disk are exported from the TPM but in an
385 encrypted form. To access them two passwords are required. The first is the TPM
386 Storage Root Key (SRK), and the other is a key-specific password. Also those keys are
387 identified by a URL of the form:
389 tpmkey:file=/path/to/file
392 When objects require a PIN to be accessed the same callbacks as with PKCS #11
393 objects are expected (see @ref{Accessing objects that require a PIN}).
396 @subsection Key generation
398 All keys used by the TPM must be generated by the TPM. This can be
399 done using @funcref{gnutls_tpm_privkey_generate}.
401 @showfuncdesc{gnutls_tpm_privkey_generate}
403 @showfuncC{gnutls_tpm_get_registered,gnutls_tpm_key_list_deinit,gnutls_tpm_key_list_get_url}
405 @showfuncdesc{gnutls_tpm_privkey_delete}
408 @subsection Using keys
410 @subsubheading Importing keys
412 The TPM keys can be used directly by the abstract key types and do not require
413 any special structures. Moreover functions like @funcref{gnutls_certificate_set_x509_key_file}
416 @showfuncB{gnutls_privkey_import_tpm_raw,gnutls_pubkey_import_tpm_raw}
418 @showfuncdesc{gnutls_privkey_import_tpm_url}
419 @showfuncdesc{gnutls_pubkey_import_tpm_url}
421 @subsubheading Listing and deleting keys
423 The registered keys (that are stored in the TPM) can be listed using one of
424 the following functions. Those keys are unfortunately only identified by
425 their UUID and have no label or other human friendly identifier.
426 Keys can be deleted from permament storage using @funcref{gnutls_tpm_privkey_delete}.
428 @showfuncC{gnutls_tpm_get_registered,gnutls_tpm_key_list_deinit,gnutls_tpm_key_list_get_url}
430 @showfuncdesc{gnutls_tpm_privkey_delete}
433 @include invoke-tpmtool.texi