diff options
Diffstat (limited to 'doc/cha-tokens.texi')
-rw-r--r-- | doc/cha-tokens.texi | 396 |
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 + |