#2 Added a section on usage of Hardware Security Modules (HSM).
Closed 6 years ago by mjahoda. Opened 7 years ago by nmav.
nmav/defensive-coding-guide update-hsms  into  master

@@ -27,6 +27,7 @@ 

      <title>Implementing Security Features</title>

      <xi:include href="Features-Authentication.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

      <xi:include href="Features-TLS.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

+     <xi:include href="Features-HSM.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

    </part>

      <xi:include href="Revision_History.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />

  </book>

file added
+187
@@ -0,0 +1,187 @@ 

+ <?xml version='1.0' encoding='utf-8' ?>

+ <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [

+ ]>

+ <chapter id="chap-Defensive_Coding-HSM">

+   <title>Hardware Security Modules and Smart Cards</title>

+   <para>

+       Hardware Security Modules (HSMs) are specialized hardware intended

+       to protect private keys on server systems. They store internally

+       the private keys (e.g., RSA keys), and provide access to operations

+       with the keys without exposing the keys. That access, is provided using

+       a standardized API, which across Fedora is PKCS#11.

+   </para>

+   <para>

+       Smart cards are small cards with a micro processor, often combined with a

+       USB reader ressembling a USB stick. They are very similar in nature with

+       HSMs as they can also be used to protect private keys and are almost

+       universally accessed via the PKCS#11 API. The main distinguishers from HSMs

+       is their inferior performance and often, the available hardware protection mechanisms.

+   </para>

+   <para>

+       Typically a smart card or HSM relies on a shared library to provide functionality.

+       This shared library follows the PKCS#11 API and thus is often referred to as 

+       a PKCS#11 module. In Fedora the <literal>opensc</literal>

+       shared module (<literal>opensc-pkcs11.so</literal>) can be used for the majority

+       of smart cards available in the market. By convention these modules are located

+       at <literal>/usr/lib64/pkcs11</literal>. They can be used directly, or via

+       a higher level library.

+   </para>

+   <para>

+       All the major crypto libraries (NSS, GnuTLS and OpenSSL in Fedora) support

+       hardware security modules and smart cards, by providing wrappers over the

+       PKCS#11 API. However, the level of support varies, as well as the ease of

+       use of such modules and its integration to the overall library API.

+   </para>

+   <itemizedlist>

+     <listitem>

+     <para>

+       The PKCS#11 API does provide an API to access HSMs or smart cards, but

+       does not provide any method of discovering which HSMs or smart cards are

+       available in the system. In Fedora and modules are registered via <ulink url="https://p11-glue.freedesktop.org/doc/p11-kit/pkcs11-conf.html">p11-kit

+       configuration files</ulink>, stored at <literal>/etc/pkcs11/modules/</literal>. For applications using

+       <literal>engine_pkcs11</literal> or GnuTLS the registered modules are

+       available without further configuration. Other applications will have to load

+       the <literal>p11-kit-proxy.so</literal> module.

+     </para>

+     </listitem>

+     <listitem>

+     <para>

+       Most crypto libraries support the <ulink url="https://tools.ietf.org/html/rfc7512">PKCS#11 URLs scheme</ulink>

+       to identify objects stored in an HSM, however that support is not yet universal.

+       Some support transparent usage of PKCS#11 objects, e.g., specifying

+       a PKCS#11 object instead of a file, while others require to use

+       specialized APIs for such objects.

+     </para>

+     </listitem>

+     <listitem>

+     <para>

+        Objects stored in an HSM or smart card can be protected with a PIN. As such,

+        libraries typically require to set a PIN handling function for accessing private keys,

+        or the PIN can be passed along with a PKCS#11 URL and the pin-value parameter.

+     </para>

+     </listitem>

+     <listitem>

+     <para>

+ 	Obtaining a Hardware Security Module, or including it on a continuous integration

+ 	testing is not always feasible. For testing purposes smart cards supported by the OpenSC

+ 	project can be used, as well as software modules like <literal>softhsm</literal> which

+ 	provides a tool to setup a software HSM, and a PKCS#11 library.

+     </para>

+     </listitem>

+     <listitem>

+     <para>

+ 	The PKCS#11 API requires applications that use fork to reinitialize the used PKCS#11

+ 	modules. This is an uncommon requirement, which has led to several bugs across

+ 	applications in Fedora which used PKCS#11 directly. To make things more complicated

+ 	software PKCS#11 module like <literal>softhsm</literal> do not require this re-initialization

+ 	leading to applications working against software modules but failing with hardware

+ 	modules or smart cards. The wrapper PKCS#11 APIs provided by NSS, GNUTLS and

+ 	engine_pkcs11 (OpenSSL) handle the reinitialization after fork requirement transparently.

+     </para>

+     </listitem>

+   </itemizedlist>

+   <section id="sect-Defensive_Coding-HSM-OpenSSL">

+     <title>OpenSSL HSM Support</title>

+     <para>

+ 	OpenSSL does not have native support for PKCS#11. It can

+ 	provide PKCS#11 support through the OpenSC's project 

+ 	<literal>pkcs11</literal> engine (formerly known as <literal>engine_pkcs11</literal>).

+ 	As such software intended to use HSMs, must utilize that engine.

+     </para>

+     <para>

+         Engine <literal>pkcs11</literal> supports loading stored objects via PKCS#11 URLs.

+         If no PKCS#11 module is specified the engine will use the system-wide registered

+         modules via <literal>p11-kit-proxy.so</literal>. 

+     </para>

+     <important>

+       <title>Possible conflict with SELinux</title>

+       <para>

+         The <literal>p11-kit-proxy.so</literal> module relies on code generation (function rewrite),

+         and as such it may fail to operate in contexts where pages can be written but not executed.

+         This is often the SELinux context under which servers like apache are executed.

+       </para>

+     </important>

+     <para>

+       The following example demonstrates the initialization of the pkcs11 engine

+       and its usage to sign data.

+     </para>

+     <example id="ex-Defensive_Coding-HSM-OpenSSL">

+ 	<title>Signing data with HSM and OpenSSL</title>

+ 	<xi:include href="snippets/Features-HSM-OpenSSL.xml"

+ 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

+     </example>

+ 

+   </section>

+   <section id="sect-Defensive_Coding-HSM-GNUTLS">

+     <title>GNUTLS HSM Support</title>

+     <para>

+ 	GNUTLS supports PKCS#11 natively. Most of the API functions

+ 	accepting certificate files, can also accept PKCS#11 URLs, thus

+ 	requiring minor or no modifications to applications in order

+ 	to support HSMs. In most cases applications must be modified

+ 	to install a PIN callback function.

+     </para>

+     <para>

+       The following example demonstrates the initialization of the pkcs11 engine

+       and its usage to sign data.

+     </para>

+     <example id="ex-Defensive_Coding-HSM-GNUTLS">

+ 	<title>Signing data with HSM and GnuTLS</title>

+ 	<xi:include href="snippets/Features-HSM-GNUTLS.xml"

+ 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

+     </example>

+     <para>

+       The PIN callback function can be either set globally as in

+       the example above or locally by utilizing functions such as <literal>gnutls_privkey_set_pin_function</literal>.

+       An example PIN callback function is shown below.

+     </para>

+     <example id="ex-Defensive_Coding-HSM-GNUTLS-PIN">

+ 	<title>An example PIN callback with GNUTLS</title>

+ 	<xi:include href="snippets/Features-HSM-GNUTLS-PIN.xml"

+ 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

+     </example>

+   </section>

+   <section id="sect-Defensive_Coding-HSM-NSS">

+     <title>NSS HSM Support</title>

+     <para>

+ 	NSS supports PKCS#11 natively. In fact all NSS crypto operations,

+         including builtin operations, go through PKCS #11 modules. NSS provides

+         its own software PKCS #11 module called softoken. NSS automatically

+         loads any PKCS #11 module specified in its module database, which can

+         be manipulated with the modutil command. NSS uses the PKCS #11 module

+         that contains the requested keys to do the crypto operations. As long as

+         the application opens an NSS database and properly sets a pin callback. If

+         it runs with native NSS, it should be able to use HSMs that provide PKCS #11

+         modules. Modules can also be loaded programatically, though this is less common.

+     </para>

+     <para>

+       The following example demonstrates a typical NSS application for signing.

+     </para>

+     <example id="ex-Defensive_Coding-HSM-NSS">

+ 	<title>Signing data with HSM and NSS</title>

+ 	<xi:include href="snippets/Features-HSM-NSS.xml"

+ 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

+     </example>

+     <para>

+       To use the example above with an HSM or smart card you will need to do the following.

+     </para>

+     <informalexample>

+       <programlisting language="Bash">

+ # add your HSM or token library to an NSS database (in the sample code the database is

+ # located in the current directory'.')

+ $ modutil -add "My HSM" -libfile ${path_to_pkcs11_file} -dbdir .

+ # Find the token name on your HSM

+ $ modutil -list -dbdir .

+ # find the cert on your token

+ $ certutil -L -h ${token_name} -d .

+ # pass the cert to your signing program

+ $ NSS_Sign_Example "${token_name}:${cert_name}"

+       </programlisting>

+     </informalexample>

+     <example id="ex-Defensive_Coding-HSM-NSS-PIN">

+ 	<title>An example PIN callback with NSS</title>

+ 	<xi:include href="snippets/Features-HSM-NSS-PIN.xml"

+ 		    xmlns:xi="http://www.w3.org/2001/XInclude" />

+     </example>

+   </section>

+ </chapter>

file modified
+1 -1
@@ -1,6 +1,6 @@ 

  xml_lang: en-US

  #brand: RedHat-EngServices

- brand: fedora

+ brand: common

  chunk_section_depth: 3

  #product: Defensive_Coding

  #mainfile: Defensive_Coding

file added
+100
@@ -0,0 +1,100 @@ 

+ #include <stdio.h>

+ #include <stdlib.h>

+ #include <stdint.h>

+ #include <string.h>

+ #include <gnutls/gnutls.h>

+ #include <gnutls/abstract.h>

+ #include <gnutls/pkcs11.h>

+ 

+ //+ Features HSM-GNUTLS-PIN

+ int pin_function(void *userdata, int attempt, const char *token_url,

+                  const char *token_label, unsigned flags, char *pin, size_t pin_max)

+ {

+   if (flags & GNUTLS_PIN_FINAL_TRY)

+     printf("This is the final try before locking!\n");

+   if (flags & GNUTLS_PIN_COUNT_LOW)

+     printf("Only few tries left before locking!\n");

+   if (flags & GNUTLS_PIN_WRONG)

+     printf("Wrong PIN has been provided in the previous attempt\n");

+ 

+   /* userdata is the second value passed to gnutls_pkcs11_set_pin_function()

+    * in this example we passed the PIN as a null terminated value.

+    */

+   snprintf(pin, pin_max, "%s", (char*)userdata);

+   return 0;

+ }

+ //-

+ 

+ /* This program accepts on the command line:

+  *  1. A PKCS#11 URL specifying a private key

+  *  2. A PIN

+  *  3. A PKCS#11 shared module (optional)

+  *

+  * And signs test data with the provided key.

+  *

+  * Example: ./a.out "pkcs11:object=myobject" 1234 /usr/lib64/pkcs11/opensc-pkcs11.so

+  */

+ int main(int argc, char **argv)

+ {

+   gnutls_privkey_t private_key;

+   char *private_key_name;

+   char *key_pass = NULL;

+   const char *module_path = NULL;

+   gnutls_datum_t testdata = {(void*)"TESTDATA", sizeof("TESTDATA")-1};

+   gnutls_datum_t signature;

+   int ret;

+ 

+   if (argc < 2) {

+     fprintf(stderr, "usage: %s [private key URL] [PIN] [module]\n", argv[0]);

+     fprintf(stderr, "\n");

+     exit(1);

+   }

+ 

+   private_key_name = argv[1];

+   key_pass = argv[2];

+   if (argc >= 3)

+     module_path = argv[3];

+ 

+   //+ Features HSM-GNUTLS

+   if (module_path) {

+     ret = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);

+     if (ret < 0) {

+       fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+       exit(1);

+     }

+ 

+     ret = gnutls_pkcs11_add_provider(module_path, NULL);

+     if (ret < 0) {

+       fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+       exit(1);

+     }

+   }

+ 

+   if (key_pass)

+     gnutls_pkcs11_set_pin_function(pin_function, key_pass);

+ 

+   ret = gnutls_privkey_init(&private_key);

+   if (ret < 0) {

+     fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+     exit(1);

+   }

+ 

+   ret = gnutls_privkey_import_url(private_key, private_key_name, 0);

+   if (ret < 0) {

+     fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+     exit(1);

+   }

+ 

+   ret = gnutls_privkey_sign_data(private_key, GNUTLS_DIG_SHA256, 0,

+                                  &testdata, &signature);

+   if (ret < 0) {

+     fprintf(stderr, "error in %d: %s\n", __LINE__, gnutls_strerror(ret));

+     exit(1);

+   }

+ 

+   gnutls_privkey_deinit(private_key);

+   gnutls_free(signature.data);

+   //-

+ 

+   return 0;

+ }

file added
+158
@@ -0,0 +1,158 @@ 

+ /* Example code to illustrate PKI crypto ops (encrypt with public key,

+  * decrypt with private key)

+  *

+  * Code assumes that you have set up a NSS database with a certificate

+  * and a private key. 

+  * Here is one way of doing it:

+  *   # create CA cert db, if -f not provided, prompts for passwd

+  *   $ certutil -N -d .

+  *

+  *   # load your hsm (optional) To do so you need to know where your

+  *   # pkcs #11 module lives. replace {path_to_pkcs11_library} with

+  *   # the actual path and library name (example /usr/lib64/libcoolkeypk11.so

+  *   $ modultil -add "HSM Module" -libfile {path_to_pkcs11_library} -dbdir .

+  *

+  *   # create CA cert, self-signed, generates key-pair, prompts for key

+  *   # type, cert type etc

+  *   # {token_name} is the name of your PKCS #11 token. You can find

+  *   #  the token name using 'modutil --list -dbdir .'. If you are using

+  *   #  softoken you can skip the -h {token_name}

+  *   # answers for prompts: 5,9,n,y,-1,n,5,6,7,9,n

+  *   $ certutil -S -s -h {token_name} \

+  *     "CN=Test CA, O=BOGUS Inc, L=Mtn View, ST=CA, C=US"  \

+  *     -n TestCA -t CTu,CTu,CTu -v 60 -x -d . -1 -2 -5

+  *

+  *   Run the program with "{token_name}:TestCA" as the command line argument.

+  *   You will be prompted for the pin.

+  *

+  * There are many ways to setup a public/private key to use - this

+  * example shows one of them.

+  *

+  * This example does not do any padding. It simply encrypts/decrypts a block

+  * of length equal to modulus length of the public/private key.

+  */

+ 

+ #include <stdio.h>

+ #include <unistd.h>

+ #include <prerror.h>

+ #include <nss.h>

+ #include <nssutil.h>

+ #include <cert.h>

+ #include <cryptohi.h>

+ #include <keyhi.h>

+ #include <pk11pub.h>

+ #include <secoidt.h>

+ 

+ static char *pin = NULL;

+ /* this callback is responsible for returning the password to the NSS

+  * key database. for example purposes, this function hardcodes the password.

+  * In a real app, this function should obtain the password using secure means

+  * such as prompting an operator, or retrieving it over a secure communication

+  * channel

+  */

+ char *passwdcb(PK11SlotInfo * info, PRBool retry, void *arg);

+ 

+ int main(int argc, char **argv)

+ {

+   //+ Features HSM-NSS

+   SECStatus rv;

+   CERTCertificate *cert = NULL;

+   SECKEYPrivateKey *pvtkey = NULL;

+   SECItem signature = { siBuffer, NULL, 0 };

+   SECOidTag algTag;

+   int r = 1;

+   unsigned char buf[] = "test data to sign";

+   const char *cert_name;

+   unsigned i;

+ 

+   if (argc < 3) {

+     fprintf(stderr, "usage: %s [cert name] [PIN]\n\n", argv[0]);

+     exit(1);

+   }

+ 

+   cert_name = argv[1];

+   pin = argv[2];

+ 

+   PK11_SetPasswordFunc(passwdcb);

+   NSS_InitializePRErrorTable();

+   rv = NSS_Init(".");

+   if (rv != SECSuccess) {

+     fprintf(stderr, "NSS initialization failed (err %d)\n", PR_GetError());

+     goto cleanup;

+   }

+ 

+   cert = PK11_FindCertFromNickname(cert_name, NULL);

+   if (cert == NULL) {

+     fprintf(stderr, "Couldn't find cert %s in NSS db (err %d: %s)\n",

+ 	    cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));

+     goto cleanup;

+   }

+ 

+   fprintf(stderr, "Buffer being signed = \n%s\n", buf);

+ 

+   pvtkey = PK11_FindKeyByAnyCert(cert, NULL);

+   if (pvtkey == NULL) {

+     fprintf(stderr, "Couldn't find private key for cert %s (err %d: %s)\n",

+ 	    cert_name, PR_GetError(), PORT_ErrorToString(PR_GetError()));

+     goto cleanup;

+   }

+ 

+   /* get the algtag. Pick the default hash algorithm */

+   algTag = SEC_GetSignatureAlgorithmOidTag(pvtkey->keyType, SEC_OID_UNKNOWN);

+ 

+   fprintf(stderr, "Signing with alg = %s (%d)\n",

+ 	  SECOID_FindOIDTagDescription(algTag), algTag);

+ 

+   rv = SEC_SignData(&signature, buf, sizeof(buf)-1, pvtkey, algTag);

+   if (rv != SECSuccess) {

+     fprintf(stderr, "sign with Private Key failed (err %d: %s)\n",

+ 	    PR_GetError(), PORT_ErrorToString(PR_GetError()));

+     goto cleanup;

+   }

+   //-

+ 

+   fprintf(stderr, "Signature len = %d\n", signature.len);

+   fprintf(stderr, "Signature data = ");

+   /* dump signature.data */

+   for (i = 0; i < signature.len; i++) {

+     if ((i & 0xf) == 0)

+       printf("\n");

+     printf("%02x ", signature.data[i]);

+   }

+   printf("\n");

+ 

+   r = 0;

+ 

+  cleanup:

+   if (cert)

+     CERT_DestroyCertificate(cert);

+   if (pvtkey)

+     SECKEY_DestroyPrivateKey(pvtkey);

+   if (signature.data)

+     SECITEM_FreeItem(&signature, PR_FALSE);

+   exit(r);

+ }

+ 

+ //+ Features HSM-NSS-PIN

+ char *passwdcb(PK11SlotInfo * slot, PRBool retry, void *arg)

+ {

+   if (!isatty(STDIN_FILENO) && retry) {

+     /* we're just reading from a file, and the value is known to be wrong,

+      * don't keep bounding the token with the wrong password. */

+     return NULL;

+   }

+ 

+   if (retry) {

+     printf("Warning: Wrong PIN has been provided in the previous attempt\n");

+     if (PK11_IsHW(slot)) {

+       printf

+ 	  ("  NOTE: multiple pin failures could result in locking your device\n");

+     }

+   }

+ 

+   if (pin == NULL)

+     return pin;

+   else

+     return strdup(pin);

+ }

+ //-

file added
+129
@@ -0,0 +1,129 @@ 

+ #include <stdio.h>

+ #include <stdlib.h>

+ #include <stdint.h>

+ #include <stdbool.h>

+ #include <string.h>

+ #include <err.h>

+ #include <arpa/inet.h>

+ #include <openssl/bio.h>

+ #include <openssl/evp.h>

+ #include <openssl/pem.h>

+ #include <openssl/err.h>

+ #include <openssl/engine.h>

+ #include <openssl/conf.h>

+ 

+ static void display_openssl_errors(int l)

+ {

+   const char *file;

+   char buf[120];

+   int e, line;

+ 

+   if (ERR_peek_error() == 0)

+     return;

+   fprintf(stderr, "At %s:%d:\n", __FILE__, l);

+ 

+   while ((e = ERR_get_error_line(&file, &line))) {

+     ERR_error_string(e, buf);

+     fprintf(stderr, "- SSL %s: %s:%d\n", buf, file, line);

+   }

+ }

+ 

+ /* This program accepts on the command line:

+  *  1. A PKCS#11 URL specifying a private key

+  *  2. A PIN

+  *  3. A PKCS#11 shared module (optional)

+  *

+  * And signs test data with the provided key.

+  *

+  * Example: ./a.out "pkcs11:object=myobject" 1234 /usr/lib64/pkcs11/opensc-pkcs11.so

+  */

+ int main(int argc, char **argv)

+ {

+   char *private_key_name;

+   unsigned char buf[4096];

+   const EVP_MD *digest_algo;

+   EVP_PKEY *private_key;

+   char *key_pass = NULL;

+   unsigned n;

+   ENGINE *e;

+   EVP_MD_CTX ctx;

+   const char *module_path = NULL;

+ 

+   if (argc < 2) {

+     fprintf(stderr, "usage: %s [private key URL] [PIN] [module]\n", argv[0]);

+     fprintf(stderr, "\n");

+     exit(1);

+   }

+ 

+   private_key_name = argv[1];

+   key_pass = argv[2];

+   if (argc >= 3)

+     module_path = argv[3];

+ 

+   //+ Features HSM-OpenSSL

+   OpenSSL_add_all_algorithms();

+   ERR_load_crypto_strings();

+   ERR_clear_error();

+   ENGINE_load_builtin_engines();

+ 

+   e = ENGINE_by_id("pkcs11");

+   if (!e) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   if (module_path) {

+     fprintf(stderr, "loading: %s\n", module_path);

+     if (!ENGINE_ctrl_cmd_string(e, "MODULE_PATH", module_path, 0)) {

+       display_openssl_errors(__LINE__);

+       exit(1);

+     }

+   }

+ 

+   if (!ENGINE_init(e)) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   if (key_pass && !ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   private_key = ENGINE_load_private_key(e, private_key_name, NULL, NULL);

+   if (!private_key) {

+     fprintf(stderr, "cannot load: %s\n", private_key_name);

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   display_openssl_errors(__LINE__);

+ 

+   digest_algo = EVP_get_digestbyname("sha256");

+ 

+   EVP_MD_CTX_init(&ctx);

+   if (EVP_DigestInit(&ctx, digest_algo) <= 0) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   EVP_SignInit(&ctx, digest_algo);

+ 

+ #define TEST_DATA "test data"

+   if (EVP_SignUpdate(&ctx, TEST_DATA, sizeof(TEST_DATA) - 1) <= 0) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   n = sizeof(buf);

+   if (EVP_SignFinal(&ctx, buf, &n, private_key) <= 0) {

+     display_openssl_errors(__LINE__);

+     exit(1);

+   }

+ 

+   EVP_PKEY_free(private_key);

+   ENGINE_finish(e);

+   //-

+ 

+   return 0;

+ }

file modified
+7 -3
@@ -32,13 +32,17 @@ 

  # List fiels which will be compiled and linked, together with

  # additional dependencies.

  compile_and_link += C-String-Functions

- compile_and_link += TLS-Client-OpenSSL

+ compile_and_link += TLS-Client-OpenSSL HSM-OpenSSL

  LIBS_TLS-Client-OpenSSL = -lssl -lcrypto

- compile_and_link += TLS-Client-GNUTLS

+ LIBS_HSM-OpenSSL = -lssl -lcrypto

+ compile_and_link += TLS-Client-GNUTLS HSM-GNUTLS

  LIBS_TLS-Client-GNUTLS = -lgnutls

- compile_and_link += TLS-Client-NSS

+ LIBS_HSM-GNUTLS = -lgnutls

+ compile_and_link += TLS-Client-NSS HSM-NSS

  CFLAGS_TLS-Client-NSS = -I/usr/include/nspr4 -I/usr/include/nss3

  LIBS_TLS-Client-NSS = -lnss3 -lnspr4 -lssl3

+ CFLAGS_HSM-NSS = -I/usr/include/nss3 -I/usr/include/nspr4 

+ LIBS_HSM-NSS = -lnss3 -lnspr4 -lssl3 -lnssutil3

  compile_and_link += XML-Parser-Expat

  LIBS_XML-Parser-Expat = -lexpat

  compile_and_link += XML-Parser-Qt

This adds a section on using Hardware Security Modules and smart cards with applications using the OpenSSL, NSS and GnuTLS libraries.

The NSS parts were contributed by Robert Relyea.

Pull-Request has been closed by mjahoda

6 years ago