summaryrefslogtreecommitdiff
path: root/doc/cha-tokens.texi
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2012-07-18 20:40:02 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2012-07-18 20:52:33 +0200
commit84889edffbe7efa4b141249b6365fbc74394cd45 (patch)
tree70f09ae1a519dd9e500b050af2c14592fb675e25 /doc/cha-tokens.texi
parent8e5417ad28fd3821e830446f2c74ccc22adde70e (diff)
downloadgnutls-84889edffbe7efa4b141249b6365fbc74394cd45.tar.gz
Added documentation for TPM keys.
Diffstat (limited to 'doc/cha-tokens.texi')
-rw-r--r--doc/cha-tokens.texi396
1 files changed, 396 insertions, 0 deletions
diff --git a/doc/cha-tokens.texi b/doc/cha-tokens.texi
new file mode 100644
index 0000000000..b9c25dbf44
--- /dev/null
+++ b/doc/cha-tokens.texi
@@ -0,0 +1,396 @@
+@node Hardware security modules and abstract key types
+@chapter Hardware security modules and abstract key types
+
+In several cases storing the long term cryptographic keys in a hard disk or
+even in memory poses a significant risk. Once the system they are stored
+is compromised the keys must be replaced as the secrecy of future sessions
+is no longer guarranteed. Moreover, past sessions that were not protected by a
+perfect forward secrecy offering ciphersuite are also to be assumed compromised.
+
+If such threats need to be addressed, then it may be wise storing the keys in a security
+module such as a smart card, an HSM or the TPM chip. Those modules ensure the
+protection of the cryptographic keys by only allowing operations on them and
+preventing their extraction.
+
+@menu
+* Abstract key types::
+* Smart cards and HSMs::
+* Trusted platform module::
+@end menu
+
+@node Abstract key types
+@section Abstract key types
+@cindex abstract types
+
+Since there are many forms of a public or private keys supported by @acronym{GnuTLS} such as
+@acronym{X.509}, @acronym{OpenPGP}, @acronym{PKCS} #11 or TPM it is desirable to allow common operations
+on them. For these reasons the abstract @code{gnutls_privkey_t} and @code{gnutls_pubkey_t} were
+introduced in @code{gnutls/abstract.h} header. Those types are initialized using a specific type of
+key and then can be used to perform operations in an abstract way. For example in order
+to sign an X.509 certificate with a key that resides in a token the following steps must be
+used.
+
+@example
+#inlude <gnutls/abstract.h>
+
+void sign_cert( gnutls_x509_crt_t to_be_signed)
+@{
+gnutls_x509_crt_t ca_cert;
+gnutls_privkey_t abs_key;
+
+ /* initialize the abstract key */
+ gnutls_privkey_init(&abs_key);
+
+ /* keys stored in tokens are identified by URLs */
+ gnutls_privkey_import_url(abs_key, key_url);
+
+ gnutls_x509_crt_init(&ca_cert);
+ gnutls_x509_crt_import_pkcs11_url(&ca_cert, cert_url);
+
+ /* sign the certificate to be signed */
+ gnutls_x509_crt_privkey_sign(to_be_signed, ca_cert, abs_key,
+ GNUTLS_DIG_SHA256, 0);
+@}
+@end example
+
+@menu
+* Abstract public keys::
+* Abstract private keys::
+* Operations::
+@end menu
+
+@node Abstract public keys
+@subsection Public keys
+An abstract @code{gnutls_pubkey_t} can be initialized
+using the functions below. It can be imported through
+an existing structure like @code{gnutls_x509_crt_t},
+or through an ASN.1 encoding of the X.509 @code{SubjectPublicKeyInfo}
+sequence.
+
+@showfuncC{gnutls_pubkey_import_x509,gnutls_pubkey_import_openpgp,gnutls_pubkey_import_pkcs11}
+
+@showfuncC{gnutls_pubkey_import_url,gnutls_pubkey_import_privkey,gnutls_pubkey_import}
+
+@showfuncdesc{gnutls_pubkey_export}
+
+An important function is @funcref{gnutls_pubkey_import_url} which will import
+public keys from URLs that identify objects stored in tokens (see @ref{Smart cards and HSMs,Trusted platform module}).
+A function to check for a supported by GnuTLS URL is @funcref{gnutls_url_is_supported}.
+
+@showfuncdesc{gnutls_url_is_supported}
+
+Additional functions are available that will return
+information over a public key.
+
+@showfuncC{gnutls_pubkey_get_pk_algorithm,gnutls_pubkey_get_preferred_hash_algorithm,gnutls_pubkey_get_key_id}
+
+@node Abstract private keys
+@subsection Private keys
+An abstract @code{gnutls_privkey_t} can be initialized
+using the functions below. It can be imported through
+an existing structure like @code{gnutls_x509_privkey_t},
+but unlike public keys it cannot be exported. That is
+to allow abstraction over keys stored in hardware that
+makes available only operations.
+
+@showfuncC{gnutls_privkey_import_x509,gnutls_privkey_import_openpgp,gnutls_privkey_import_pkcs11}
+
+Other helper functions that allow directly importing from raw X.509 or
+OpenPGP structures are shown below. Again, as with public keys, private keys
+can be imported from a hardware module using URLs.
+
+@showfuncB{gnutls_privkey_import_x509_raw,gnutls_privkey_import_openpgp_raw}
+
+@showfuncdesc{gnutls_privkey_import_url}
+
+@showfuncB{gnutls_privkey_get_pk_algorithm,gnutls_privkey_get_type}
+
+In order to support cryptographic operations using
+an external API, the following function is provided.
+This allows for a simple extensibility API without
+resorting to @acronym{PKCS} #11.
+
+@showfuncdesc{gnutls_privkey_import_ext2}
+
+@node Operations
+@subsection Operations
+The abstract key types can be used to access signing and
+signature verification operations with the underlying keys.
+
+@showfuncdesc{gnutls_pubkey_verify_data2}
+@showfuncdesc{gnutls_pubkey_verify_hash2}
+@showfuncdesc{gnutls_pubkey_encrypt_data}
+
+@showfuncdesc{gnutls_privkey_sign_data}
+@showfuncdesc{gnutls_privkey_sign_hash}
+@showfuncdesc{gnutls_privkey_decrypt_data}
+
+Signing existing structures, such as certificates, CRLs,
+or certificate requests, as well as associating public
+keys with structures is also possible using the
+key abstractions.
+
+@showfuncdesc{gnutls_x509_crq_set_pubkey}
+@showfuncdesc{gnutls_x509_crt_set_pubkey}
+@showfuncC{gnutls_x509_crt_privkey_sign,gnutls_x509_crl_privkey_sign,gnutls_x509_crq_privkey_sign}
+
+@node Smart cards and HSMs
+@section Smart cards and HSMs
+@cindex PKCS #11 tokens
+@cindex hardware tokens
+@cindex hardware security modules
+@cindex smart cards
+
+In this section we present the smart-card and hardware security module (HSM) support
+in @acronym{GnuTLS} using @acronym{PKCS} #11 @xcite{PKCS11}. Hardware security
+modules and smart cards provide a way to store private keys and perform
+operations on them without exposing them. This decouples cryptographic
+keys from the applications that use them and provide an additional
+security layer against cryptographic key extraction.
+Since this can also be achieved in software components such as in Gnome keyring,
+we will use the term security module to describe any cryptographic key
+separation subsystem.
+
+@acronym{PKCS} #11 is plugin API allowing applications to access cryptographic
+operations on a security module, as well as to objects residing on it. PKCS
+#11 modules exist for hardware tokens such as smart cards@footnote{@url{http://www.opensc-project.org}},
+cryptographic tokens, as well as for software modules like @acronym{Gnome Keyring}.
+The objects residing on a security module may be certificates, public keys,
+private keys or secret keys. Of those certificates and public/private key
+pairs can be used with @acronym{GnuTLS}. PKCS #11's main advantage is that
+it allows operations on private key objects such as decryption
+and signing without exposing the key. In GnuTLS the PKCS #11 functionality is
+available in @code{gnutls/pkcs11.h}.
+
+Moreover @acronym{PKCS} #11 can be (ab)used to allow all applications in the same operating system to access
+shared cryptographic keys and certificates in a uniform way, as in @ref{fig:pkcs11-vision}.
+That way applications could load their trusted certificate list, as well as user
+certificates from a common PKCS #11 module. Such a provider exists in the @acronym{Gnome}
+system, being the @acronym{Gnome Keyring}.
+
+@float Figure,fig:pkcs11-vision
+@image{pkcs11-vision,9cm}
+@caption{PKCS #11 module usage.}
+@end float
+
+@menu
+* PKCS11 Initialization::
+* Reading objects::
+* Writing objects::
+* Using a PKCS11 token with TLS::
+* p11tool Invocation:: Invoking p11tool
+@end menu
+
+@node PKCS11 Initialization
+@subsection Initialization
+To allow all the @acronym{GnuTLS} applications to access @acronym{PKCS} #11 tokens
+you can use a configuration per module, stored in @code{/etc/pkcs11/modules/}.
+These are the configuration files of @acronym{p11-kit}@footnote{@url{http://p11-glue.freedesktop.org/}}.
+For example a file that will load the @acronym{OpenSC} module, could be named
+@code{/etc/pkcs11/modules/opensc} and contain the following:
+
+@example
+module: /usr/lib/opensc-pkcs11.so
+@end example
+
+If you use this file, then there is no need for other initialization in
+@acronym{GnuTLS}, except for the PIN and token functions. Those allow retrieving a PIN
+when accessing a protected object, such as a private key, as well as probe
+the user to insert the token. All the initialization functions are below.
+
+@showfuncdesc{gnutls_pkcs11_init}
+@showfuncD{gnutls_pkcs11_set_token_function,gnutls_pkcs11_set_pin_function,gnutls_pkcs11_add_provider,gnutls_pkcs11_get_pin_function}
+
+Note that due to limitations of @acronym{PKCS} #11 there are issues when multiple libraries
+are sharing a module. To avoid this problem GnuTLS uses @acronym{p11-kit}
+that provides a middleware to control access to resources over the
+multiple users.
+
+To avoid conflicts with multiple registered callbacks for PIN functions,
+@funcref{gnutls_pkcs11_get_pin_function} may be used to check for any previously
+set functions.
+
+Moreover PKCS #11 modules must be reinitialized on the child processes
+after a @funcintref{fork}. @acronym{GnuTLS} provides @funcref{gnutls_pkcs11_reinit}
+to be called for this purpose.
+
+@showfuncdesc{gnutls_pkcs11_reinit}
+
+@node Reading objects
+@subsection Reading objects
+
+All @acronym{PKCS} #11 objects are referenced by @acronym{GnuTLS} functions by
+URLs as described in @xcite{PKCS11URI}.
+This allows for a consistent naming of objects across systems and applications
+in the same system. For example a public
+key on a smart card may be referenced as:
+
+@example
+pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315; \
+manufacturer=EnterSafe;object=test1;objecttype=public;\
+id=32f153f3e37990b08624141077ca5dec2d15faed
+@end example
+
+while the smart card itself can be referenced as:
+@example
+pkcs11:token=Nikos;serial=307521161601031;model=PKCS%2315;manufacturer=EnterSafe
+@end example
+
+Objects stored in a @acronym{PKCS} #11 token can be extracted
+if they are not marked as sensitive. Usually only private keys are marked as
+sensitive and cannot be extracted, while certificates and other data can
+be retrieved. The functions that can be used to access objects
+are shown below.
+
+@showfuncB{gnutls_pkcs11_obj_import_url,gnutls_pkcs11_obj_export_url}
+
+@showfuncdesc{gnutls_pkcs11_obj_get_info}
+
+@showfuncC{gnutls_x509_crt_import_pkcs11,gnutls_x509_crt_import_pkcs11_url,gnutls_x509_crt_list_import_pkcs11}
+
+Properties of the physical token can also be accessed and altered with @acronym{GnuTLS}.
+For example data in a token can be erased (initialized), PIN can be altered, etc.
+
+@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}
+
+The following examples demonstrate the usage of the API. The first example
+will list all available PKCS #11 tokens in a system and the latter will
+list all certificates in a token that have a corresponding private key.
+
+@example
+int i;
+char* url;
+
+gnutls_global_init();
+
+for (i=0;;i++)
+ @{
+ ret = gnutls_pkcs11_token_get_url(i, &url);
+ if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+ break;
+
+ if (ret < 0)
+ exit(1);
+
+ fprintf(stdout, "Token[%d]: URL: %s\n", i, url);
+ gnutls_free(url);
+ @}
+gnutls_global_deinit();
+@end example
+
+@verbatiminclude examples/ex-pkcs11-list.c
+
+@node Writing objects
+@subsection Writing objects
+
+With @acronym{GnuTLS} you can copy existing private keys and certificates
+to a token. Note that when copying private keys it is recommended to mark
+them as sensitive using the @code{GNUTLS_@-PKCS11_OBJ_@-FLAG_@-MARK_@-SENSITIVE}
+to prevent its extraction. An object can be marked as private using the flag
+@code{GNUTLS_@-PKCS11_OBJ_@-FLAG_@-MARK_@-PRIVATE}, to require PIN to be
+entered before accessing the object (for operations or otherwise).
+
+@showfuncdesc{gnutls_pkcs11_copy_x509_privkey}
+
+@showfuncdesc{gnutls_pkcs11_copy_x509_crt}
+@showfuncdesc{gnutls_pkcs11_delete_url}
+
+
+@node Using a PKCS11 token with TLS
+@subsection Using a @acronym{PKCS} #11 token with TLS
+
+It is possible to use a @acronym{PKCS} #11 token to a TLS
+session, as shown in @ref{ex:pkcs11-client}. In addition
+the following functions can be used to load PKCS #11 key and
+certificates by specifying a PKCS #11 URL instead of a filename.
+
+@showfuncB{gnutls_certificate_set_x509_trust_file,gnutls_certificate_set_x509_key_file}
+@showfuncdesc{gnutls_certificate_set_x509_system_trust}
+
+@include invoke-p11tool.texi
+
+@node Trusted platform module
+@section Trusted platform module
+@cindex trusted platform module
+@cindex TPM
+
+In this section we present the Trusted Platform Module (TPM) support
+in @acronym{GnuTLS}. The TPM chip allows for storing and using RSA keys in a
+similar way as a @acronym{PKCS} #11 module, but with slight differences
+that require different handling. The basic operations supported, and used
+by GnuTLS, are key generation and signing.
+
+In GnuTLS the TPM functionality is available in @code{gnutls/tpm.h}.
+
+@menu
+* Keys in TPM::
+* Key generation::
+* Using keys::
+* tpmtool Invocation:: Invoking tpmtool
+@end menu
+
+@node Keys in TPM
+@subsection Keys in TPM
+
+The RSA keys in the TPM module may either be stored in a flash memory
+within TPM or stored in a file in disk. In the former case the key can
+provide operations as with @acronym{PKCS} #11 and is identified by
+a URL. The URL is of the following form.
+@verbatim
+tpmkey:uuid=42309df8-d101-11e1-a89a-97bb33c23ad1;storage=user
+@end verbatim
+
+It consists from a unique identifier of the key as well as the part of the
+flash memory the key is stored at. The two options for the storage field are
+`user' and `system'. The user keys are typically only available to the generating
+user and the system keys to all users. The stored in TPM keys are called
+registered keys.
+
+The keys that are stored in the disk are exported from the TPM but in an
+encrypted form. To access them two passwords are required. The first is the TPM
+Storage Root Key (SRK), and the other is a key-specific password. Also those keys are
+identified by a URL of the form:
+@verbatim
+tpmkey:file=/path/to/file
+@end verbatim
+
+@node Key generation
+@subsection Key generation
+
+All keys used by the TPM must be generated by the TPM. This can be
+done using @funcref{gnutls_tpm_privkey_generate}.
+
+@showfuncdesc{gnutls_tpm_privkey_generate}
+
+@showfuncC{gnutls_tpm_get_registered,gnutls_tpm_key_list_deinit,gnutls_tpm_key_list_get_url}
+
+@showfuncdesc{gnutls_tpm_privkey_delete}
+
+@node Using keys
+@subsection Using keys
+
+@subsubheading Importing keys
+
+The TPM keys can be used directly by the abstract key types and do not require
+any special structures. Moreover functions like @funcref{gnutls_certificate_set_x509_key_file}
+can access TPM URLs.
+
+@showfuncB{gnutls_privkey_import_tpm_raw,gnutls_pubkey_import_tpm_raw}
+
+@showfuncdesc{gnutls_privkey_import_tpm_url}
+@showfuncdesc{gnutls_pubkey_import_tpm_url}
+
+@subsubheading Listing and accessing keys
+
+The registered keys (that are stored in the TPM) can be listed using one of
+the following functions. Those keys are unfortunately only identified by
+their UUID and have no label or other human friendly identifier.
+Keys can be deleted from permament storage using @funcref{gnutls_tpm_privkey_delete}.
+
+@showfuncC{gnutls_tpm_get_registered,gnutls_tpm_key_list_deinit,gnutls_tpm_key_list_get_url}
+
+@showfuncdesc{gnutls_tpm_privkey_delete}
+
+
+@include invoke-tpmtool.texi
+