Add support for RSA decryption using PKCS #11 tokens

Add support for loading RSA private key files from PKCS #11 tokens,
identified by PKCS #11 URIs. Add a new 'pkcs11_libs' UAT which can
dynamically load PKCS #11 provider libraries that are not found by
p11-kit.

The configuration GUI will need additional code to discover available
PKCS #11 tokens and will be added later.

This feature requires GnuTLS 3.4 with PKCS #11 support, so Windows,
macOS via Homebrew, Ubuntu 16.04, Debian Stretch. Not supported: RHEL7.
Currently macOS via official packages disables PKCS #11 support, so that
will also not work.

Change-Id: I20646bfd69c6bd13c8c2d27cb65c164a4b0b7a66
Reviewed-on: https://code.wireshark.org/review/30855
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
Peter Wu 2018-12-12 14:34:00 +01:00
parent 53d8e6dcf8
commit ac58eafa32
11 changed files with 431 additions and 15 deletions

View File

@ -59,8 +59,9 @@ before_install:
- echo $TRAVIS_OS_NAME
# macos
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then ./tools/macos-setup-brew.sh; fi
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install softhsm; fi
# linux
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ./tools/debian-setup.sh --install-optional -q; fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ./tools/debian-setup.sh --install-optional --install-test-deps -q; fi
- sudo gem install asciidoctor --no-ri --no-rdoc
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -y python3-pip; fi
- sudo pip3 install pytest pytest-xdist

View File

@ -990,7 +990,7 @@ if(ENABLE_SMI)
set(PACKAGELIST ${PACKAGELIST} SMI)
endif()
# GNU SSL/TLS support
# Support for TLS decryption using RSA private keys.
if(ENABLE_GNUTLS)
set(PACKAGELIST ${PACKAGELIST} GNUTLS)
# Minimum version needed.
@ -1167,6 +1167,22 @@ if(HAVE_LIBLUA)
set(HAVE_LUA_H 1)
set(HAVE_LUA 1)
endif()
if(GNUTLS_FOUND AND NOT GNUTLS_VERSION VERSION_LESS "3.4.0")
# While all Linux and Windows builds have PKCS #11 support enabled,
# macos-setup.sh explicitly disables it using --without-p11-kit.
#
# Require at least GnuTLS 3.4.0 such that public keys can be calculated
# from PKCS #11 private keys.
include(CheckSymbolExists)
cmake_push_check_state()
if(WIN32)
set(CMAKE_REQUIRED_DEFINITIONS -Dssize_t=int)
endif()
set(CMAKE_REQUIRED_INCLUDES ${GNUTLS_INCLUDE_DIRS})
set(CMAKE_REQUIRED_LIBRARIES ${GNUTLS_LIBRARIES})
check_symbol_exists(gnutls_pkcs11_obj_list_import_url4 gnutls/pkcs11.h HAVE_GNUTLS_PKCS11)
cmake_pop_check_state()
endif()
if(HAVE_LIBKERBEROS)
set(HAVE_KERBEROS 1)
endif()

View File

@ -69,7 +69,7 @@ option(ENABLE_SNAPPY "Build with Snappy compression support" ON)
option(ENABLE_NGHTTP2 "Build with HTTP/2 header decompression support" ON)
option(ENABLE_LUA "Build with Lua dissector support" ON)
option(ENABLE_SMI "Build with libsmi snmp support" ON)
option(ENABLE_GNUTLS "Build with GNU TLS support" ON)
option(ENABLE_GNUTLS "Build with RSA decryption support" ON)
if(WIN32)
option(ENABLE_WINSPARKLE "Enable WinSparkle support" ON)
endif()

View File

@ -29,6 +29,9 @@ install:
# Py2 fails the test_tshark_unicode_display_filter test, so use Py3.
- set PATH=C:\Python37-x64;C:\Python37-x64\Scripts;%PATH%
- pip install pytest pytest-xdist
- ps: | # For pkcs11 tests.
Invoke-WebRequest -Uri https://github.com/disig/SoftHSM2-for-Windows/releases/download/v2.5.0/SoftHSM2-2.5.0.msi -OutFile $Env:WIRESHARK_BASE_DIR\SoftHSM2-2.5.0.msi
& msiexec /qn /i $Env:WIRESHARK_BASE_DIR\SoftHSM2-2.5.0.msi
# Note: the NSIS installer lacks debug dlls for Debug builds.
configuration: RelWithDebInfo

View File

@ -112,6 +112,9 @@
/* Define to use GnuTLS library */
#cmakedefine HAVE_LIBGNUTLS 1
/* Define to 1 if GnuTLS was built with pkcs11 support. */
#cmakedefine HAVE_GNUTLS_PKCS11 1
/* Enable libnl support */
#cmakedefine HAVE_LIBNL 1

View File

@ -715,6 +715,9 @@ epan_get_compiled_version_info(GString *str)
g_string_append(str, ", ");
#ifdef HAVE_LIBGNUTLS
g_string_append(str, "with GnuTLS " LIBGNUTLS_VERSION);
#ifdef HAVE_GNUTLS_PKCS11
g_string_append(str, " and PKCS #11 support");
#endif /* HAVE_GNUTLS_PKCS11 */
#else
g_string_append(str, "without GnuTLS");
#endif /* HAVE_LIBGNUTLS */

View File

@ -51,6 +51,19 @@ static guint uat_num_rsa_privkeys;
static void register_rsa_uats(void);
#endif /* HAVE_LIBGNUTLS */
#ifdef HAVE_GNUTLS_PKCS11
/** PINs for PKCS #11 keys in rsa_privkeys. Must be cleared after rsa_privkeys. */
static GSList *rsa_privkeys_pkcs11_pins;
typedef struct {
char *library_path; /**< PKCS #11 library path. */
} pkcs11_lib_record_t;
static uat_t *pkcs11_libs_uat;
static pkcs11_lib_record_t *uat_pkcs11_libs;
static guint uat_num_pkcs11_libs;
#endif /* HAVE_GNUTLS_PKCS11 */
void
secrets_init(void)
{
@ -69,6 +82,10 @@ secrets_cleanup(void)
#ifdef HAVE_LIBGNUTLS
g_hash_table_destroy(rsa_privkeys);
rsa_privkeys = NULL;
#ifdef HAVE_GNUTLS_PKCS11
g_slist_free_full(rsa_privkeys_pkcs11_pins, g_free);
rsa_privkeys_pkcs11_pins = NULL;
#endif /* HAVE_GNUTLS_PKCS11 */
#endif /* HAVE_LIBGNUTLS */
}
@ -125,6 +142,182 @@ rsa_privkey_add(const cert_key_id_t *key_id, gnutls_privkey_t pkey)
g_htonl(dw[1]), g_htonl(dw[2]), g_htonl(dw[3]), g_htonl(dw[4]));
}
#ifdef HAVE_GNUTLS_PKCS11
/** Provides a fixed PIN to the caller (or failure if the fixed PIN is NULL). */
static int
set_pin_callback(void *userdata, int attempt _U_,
const char *token_url _U_, const char *token_label _U_,
unsigned int flags, char *pin, size_t pin_max)
{
const char *fixed_pin = (const char *)userdata;
size_t fixed_pin_len = fixed_pin ? strlen(fixed_pin) : 0;
/* Fail if the PIN was not provided, wrong or too long. */
if (!fixed_pin || (flags & GNUTLS_PIN_WRONG) || fixed_pin_len >= pin_max) {
return GNUTLS_E_PKCS11_PIN_ERROR;
}
memcpy(pin, fixed_pin, fixed_pin_len + 1);
return 0;
}
/**
* Load private RSA keys from a PKCS #11 token. Returns zero on success and a
* negative error code on failure.
*/
static int
pkcs11_load_keys_from_token(const char *token_uri, const char *pin, char **err)
{
gnutls_pkcs11_obj_t *list = NULL;
unsigned int nlist = 0;
int ret;
/* An empty/NULL PIN means that none is necessary. */
char *fixed_pin = pin && pin[0] ? g_strdup(pin) : NULL;
gboolean pin_in_use = FALSE;
/* Set PIN via a global callback since import_url can prompt for one. */
gnutls_pkcs11_set_pin_function(set_pin_callback, fixed_pin);
/* This might already result in callback for the PIN. */
ret = gnutls_pkcs11_obj_list_import_url4(&list, &nlist, token_uri,
GNUTLS_PKCS11_OBJ_FLAG_PRIVKEY|GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
if (ret < 0) {
*err = g_strdup_printf("Failed to iterate through objects for %s: %s", token_uri, gnutls_strerror(ret));
goto cleanup;
}
for (unsigned j = 0; j < nlist; j++) {
char *obj_uri = NULL;
gnutls_privkey_t privkey = NULL;
gnutls_pubkey_t pubkey = NULL;
cert_key_id_t key_id;
size_t size;
if (gnutls_pkcs11_obj_get_type(list[j]) != GNUTLS_PKCS11_OBJ_PRIVKEY) {
/* Should not happen since we requested private keys only. */
goto cont;
}
ret = gnutls_pkcs11_obj_export_url(list[j], GNUTLS_PKCS11_URL_GENERIC, &obj_uri);
if (ret < 0) {
/* Should not happen either if the object is valid. */
goto cont;
}
ret = gnutls_privkey_init(&privkey);
if (ret < 0) {
/* Out of memory? */
goto cont;
}
/* Set the PIN to be used during decryption. */
gnutls_privkey_set_pin_function(privkey, set_pin_callback, fixed_pin);
/* Can prompt for PIN. Can also invoke the token function set by
* gnutls_pkcs11_set_token_function (if not set, it will just fail
* immediately rather than retrying). */
ret = gnutls_privkey_import_url(privkey, obj_uri, 0);
if (ret < 0) {
/* Bad PIN or some other system error? */
g_debug("Failed to import private key %s: %s", obj_uri, gnutls_strerror(ret));
goto cont;
}
if (gnutls_privkey_get_pk_algorithm(privkey, NULL) != GNUTLS_PK_RSA) {
g_debug("Skipping private key %s, not RSA.", obj_uri);
goto cont;
}
ret = gnutls_pubkey_init(&pubkey);
if (ret < 0) {
/* Out of memory? */
goto cont;
}
/* This requires GnuTLS 3.4.0 and will fail on older versions. */
ret = gnutls_pubkey_import_privkey(pubkey, privkey, 0, 0);
if (ret < 0) {
g_debug("Failed to import public key %s: %s", obj_uri, gnutls_strerror(ret));
goto cont;
}
size = sizeof(key_id);
ret = gnutls_pubkey_get_key_id(pubkey, GNUTLS_KEYID_USE_SHA1, key_id.key_id, &size);
if (ret < 0 || size != sizeof(key_id)) {
g_debug("Failed to calculate Key ID for %s: %s", obj_uri, gnutls_strerror(ret));
goto cont;
}
/* Remember the private key. */
rsa_privkey_add(&key_id, privkey);
privkey = NULL;
pin_in_use = TRUE;
cont:
gnutls_privkey_deinit(privkey);
gnutls_pubkey_deinit(pubkey);
gnutls_free(obj_uri);
gnutls_pkcs11_obj_deinit(list[j]);
}
gnutls_free(list);
if (pin_in_use) {
/* Remember PINs such they can be freed later. */
rsa_privkeys_pkcs11_pins = g_slist_prepend(rsa_privkeys_pkcs11_pins, fixed_pin);
fixed_pin = NULL;
}
ret = 0;
cleanup:
/* Forget about the PIN. */
gnutls_pkcs11_set_pin_function(NULL, NULL);
g_free(fixed_pin);
return ret;
}
/** Load all libraries specified in a UAT. */
static void
uat_pkcs11_libs_load_all(void)
{
int ret;
GString *err = NULL;
for (guint i = 0; i < uat_num_pkcs11_libs; i++) {
const pkcs11_lib_record_t *rec = &uat_pkcs11_libs[i];
const char *libname = rec->library_path;
/* Note: should return success for already loaded libraries. */
ret = gnutls_pkcs11_add_provider(libname, NULL);
if (ret) {
if (!err) {
err = g_string_new("Error loading PKCS #11 libraries:");
}
g_string_append_printf(err, "\n%s: %s", libname, gnutls_strerror(ret));
}
}
if (err) {
report_failure("%s", err->str);
g_string_free(err, TRUE);
}
}
UAT_FILENAME_CB_DEF(pkcs11_libs_uats, library_path, pkcs11_lib_record_t)
static void *
uat_pkcs11_lib_copy_str_cb(void *dest, const void *source, size_t len _U_)
{
pkcs11_lib_record_t *d = (pkcs11_lib_record_t *)dest;
const pkcs11_lib_record_t *s = (const pkcs11_lib_record_t *)source;
d->library_path = g_strdup(s->library_path);
return dest;
}
static void
uat_pkcs11_lib_free_str_cb(void *record)
{
pkcs11_lib_record_t *rec = (pkcs11_lib_record_t *)record;
g_free(rec->library_path);
}
#endif /* HAVE_GNUTLS_PKCS11 */
UAT_FILENAME_CB_DEF(rsa_privkeys_uats, uri, rsa_privkey_record_t)
UAT_CSTRING_CB_DEF(rsa_privkeys_uats, password, rsa_privkey_record_t)
@ -202,6 +395,10 @@ uat_rsa_privkeys_post_update(void)
{
/* Clear previous keys. */
g_hash_table_remove_all(rsa_privkeys);
#ifdef HAVE_GNUTLS_PKCS11
g_slist_free_full(rsa_privkeys_pkcs11_pins, g_free);
rsa_privkeys_pkcs11_pins = NULL;
#endif /* HAVE_GNUTLS_PKCS11 */
GString *errors = NULL;
for (guint i = 0; i < uat_num_rsa_privkeys; i++) {
@ -210,6 +407,9 @@ uat_rsa_privkeys_post_update(void)
char *err = NULL;
if (g_str_has_prefix(token_uri, "pkcs11:")) {
#ifdef HAVE_GNUTLS_PKCS11
pkcs11_load_keys_from_token(token_uri, rec->password, &err);
#endif /* HAVE_GNUTLS_PKCS11 */
} else {
load_rsa_keyfile(token_uri, rec->password, &err);
}
@ -236,6 +436,27 @@ uat_rsa_privkeys_post_update(void)
static void
register_rsa_uats(void)
{
#ifdef HAVE_GNUTLS_PKCS11
static uat_field_t uat_pkcs11_libs_fields[] = {
UAT_FLD_FILENAME_OTHER(pkcs11_libs_uats, library_path, "Library Path", NULL, "PKCS #11 provider library file"),
UAT_END_FIELDS
};
pkcs11_libs_uat = uat_new("PKCS #11 Provider Libraries",
sizeof(pkcs11_lib_record_t),
"pkcs11_libs", /* filename */
FALSE, /* from_profile */
&uat_pkcs11_libs, /* data_ptr */
&uat_num_pkcs11_libs, /* numitems_ptr */
0, /* does not directly affect dissection */
NULL, /* Help section (currently a wiki page) */
uat_pkcs11_lib_copy_str_cb, /* copy_cb */
NULL, /* update_cb */
uat_pkcs11_lib_free_str_cb, /* free_cb */
uat_pkcs11_libs_load_all, /* post_update_cb */
NULL, /* reset_cb */
uat_pkcs11_libs_fields);
#endif /* HAVE_GNUTLS_PKCS11 */
static uat_field_t uat_rsa_privkeys_fields[] = {
UAT_FLD_FILENAME_OTHER(rsa_privkeys_uats, uri, "Keyfile or Token URI", NULL, "RSA Key File or PKCS #11 URI for token"),
UAT_FLD_FILENAME_OTHER(rsa_privkeys_uats, password, "Password", NULL, "RSA Key File password or PKCS #11 Token PIN"),

View File

@ -145,12 +145,14 @@ def features(cmd_tshark, make_env):
tshark_v = ''
gcry_m = re.search(r'with +Gcrypt +([0-9]+\.[0-9]+)', tshark_v)
return types.SimpleNamespace(
have_x64='Compiled (64-bit)' in tshark_v,
have_lua='with Lua' in tshark_v,
have_nghttp2='with nghttp2' in tshark_v,
have_kerberos='with MIT Kerberos' in tshark_v or 'with Heimdal Kerberos' in tshark_v,
have_libgcrypt16=gcry_m and float(gcry_m.group(1)) >= 1.6,
have_libgcrypt17=gcry_m and float(gcry_m.group(1)) >= 1.7,
have_gnutls='with GnuTLS' in tshark_v,
have_pkcs11='and PKCS #11 support' in tshark_v,
)

16
test/keys/rsa-p-lt-q.p8 Normal file
View File

@ -0,0 +1,16 @@
-----BEGIN PRIVATE KEY-----
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOE/58jJArmp9xd6
M42ttJk+tbzG5U47pHfj9wFVMoPPUP5/9Mfl9PGBm7GdnGxW//9wQrphEjrqrwya
st6OBO5yb1DotLAl8FecN6eJxSTMPPS108A2D52kXdZohFgn8OjDhi3wR09L42vC
1w7hPJOHIIuzPbywLauhqB7H/OazAgMBAAECgYEAgEnza0oBAVmqX3a8Ef9TEszC
mWf2hd42SApQTjQF90iGaszZz1hLb5lP4ZNQ2eubFhMMDjbnOSMc2+Ln6RWd/Fb1
Oy8mYkXYwPH+a2PHwa0yQ6IWuqRgZ09EijO+DxRlk8pn5hBj7YC8gU9hIce/PAkx
z50FS6yEPT3U7xouJ9ECQQDm2BAoJasJBOKpYTHbPN4fhZ9m5DV65+nvu9ZgbxeR
FfrBbYRva9KX9q/E03sSPkoEEHV21KYCMYz2g0FipqqXAkEA+cvGNz2upzwX8Ty5
WKR323NHEVSMerEbbAQikamcCYnR5vdeJ2w3OMYNWTOQrNE9+Rk3gfaMCxwqER1l
eW/0RQJAIzPLsvObk3KFRiMmQTKVBOWRm1UtuqJnEEHqvSXzyBI7/QdAbOVaZgYe
Y7uERxHso5YG86oV7ruzrVvyuqKD3QJAH4do7XALq3AaVYiknFumBTz3q2hQkuvn
2iprcpdF6q5KoCx45eDy12eoJ6oqiKWgfOCB8RV9d6mGZcKgHEPVQQJALFi49VGr
qyX5SCcfS6c+XgX/VuJGS6eFxhpXHolAG3O1FmbQMKJ618bOGt8jYjGYR0bM5Kgd
sDXwcu06rODBIA==
-----END PRIVATE KEY-----

View File

@ -10,7 +10,12 @@
'''Decryption tests'''
import os.path
import shutil
import subprocess
import subprocesstest
import sys
import sysconfig
import types
import unittest
import fixtures
@ -862,3 +867,122 @@ class case_decrypt_knxip(subprocesstest.SubprocessTestCase):
self.assertTrue(self.grepOutput('^IA 1[.]1[.]4 SeqNr 12345$'))
self.assertTrue(self.grepOutput('^IA 2[.]1[.]0 key B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF$'))
self.assertTrue(self.grepOutput('^IA 2[.]1[.]0 SeqNr 1234$'))
@fixtures.fixture(scope='session')
def softhsm_paths(features):
if sys.platform == 'win32':
search_path = os.getenv('PATH') + r';C:\SoftHSM2\bin'
else:
search_path = None
softhsm_tool = shutil.which('softhsm2-util', path=search_path)
if not softhsm_tool:
# Note: do not fallback to SoftHSMv1. While available on Ubuntu 14.04
# (and 16.04), it is built with botan < 1.11.10 which causes a crash due
# to a conflict with the GMP library that is also used by GnuTLS/nettle.
# See https://github.com/randombit/botan/issues/1090
fixtures.skip('SoftHSM is not found')
# Find provider library path.
bindir = os.path.dirname(softhsm_tool)
libdir = os.path.join(os.path.dirname(bindir), 'lib')
if sys.platform == 'win32':
libdirs = [libdir, bindir]
if features.have_x64:
name = 'softhsm2-x64.dll'
else:
name = 'softhsm2.dll'
else:
# Debian/Ubuntu-specific paths
madir = sysconfig.get_config_var('multiarchsubdir')
libdir64_sub = os.path.join(libdir + '64', 'softhsm')
libdir_sub = os.path.join(libdir, 'softhsm')
libdirs = [os.path.join(libdir + madir, 'softhsm')] if madir else []
libdirs += [libdir_sub, libdir64_sub]
name = 'libsofthsm2.so'
for libdir in libdirs:
provider = os.path.join(libdir, name)
if os.path.exists(provider):
break
else:
# Even if p11-kit can automatically locate it, do not rely on it.
fixtures.skip('SoftHSM provider library not detected')
# Now check whether the import tool is usable. SoftHSM < 2.3.0 did not
# set CKA_DECRYPT when using softhsm2-tool --import and therefore cannot be
# used to import keys for decryption. Use GnuTLS p11tool as workaround.
softhsm_version = subprocess.check_output([softhsm_tool, '--version'],
universal_newlines=True).strip()
use_p11tool = softhsm_version in ('2.0.0', '2.1.0', '2.2.0')
if use_p11tool and not shutil.which('p11tool'):
fixtures.skip('SoftHSM available, but GnuTLS p11tool is unavailable')
return use_p11tool, softhsm_tool, provider
@fixtures.fixture
def softhsm(softhsm_paths, home_path, base_env):
'''Creates a temporary SoftHSM token store (and set it in the environment),
returns a function to populate that token store and the path to the PKCS #11
provider library.'''
use_p11tool, softhsm_tool, provider = softhsm_paths
conf_path = os.path.join(home_path, 'softhsm-test.conf')
db_path = os.path.join(home_path, 'softhsm-test-tokens')
os.makedirs(db_path)
with open(conf_path, 'w') as f:
f.write('directories.tokendir = %s\n' % db_path)
f.write('objectstore.backend = file\n')
# Avoid syslog spam
f.write('log.level = ERROR\n')
base_env['SOFTHSM2_CONF'] = conf_path
tool_env = base_env.copy()
if sys.platform == 'win32':
# Ensure that softhsm2-util can find the library.
tool_env['PATH'] += ';%s' % os.path.dirname(provider)
# Initialize tokens store.
token_name = 'Wireshark-Test-Tokens'
pin = 'Secret'
subprocess.check_call([softhsm_tool, '--init-token', '--slot', '0',
'--label', token_name, '--so-pin', 'Supersecret', '--pin', pin],
env=tool_env)
if use_p11tool:
tool_env['GNUTLS_PIN'] = pin
# Arbitrary IDs and labels.
ids = iter(range(0xab12, 0xffff))
def import_key(keyfile):
'''Returns a PKCS #11 URI to identify the imported key.'''
label = os.path.basename(keyfile)
obj_id = '%x' % next(ids)
if not use_p11tool:
tool_args = [softhsm_tool, '--import', keyfile, '--label', label,
'--id', obj_id, '--pin', pin, '--token', token_name]
else:
# Fallback for SoftHSM < 2.3.0
tool_args = ['p11tool', '--provider', provider, '--batch',
'--login', '--write', 'pkcs11:token=%s' % token_name,
'--load-privkey', keyfile, '--label', label, '--id', obj_id]
subprocess.check_call(tool_args, env=tool_env)
id_str = '%{}{}%{}{}'.format(*obj_id)
return 'pkcs11:token=%s;id=%s;type=private' % (token_name, id_str)
return types.SimpleNamespace(import_key=import_key, provider=provider, pin=pin)
@fixtures.mark_usefixtures('test_env')
@fixtures.uses_fixtures
class case_decrypt_pkcs11(subprocesstest.SubprocessTestCase):
def test_tls_pkcs11(self, cmd_tshark, dirs, capture_file, features, softhsm):
'''Check that a RSA key in a PKCS #11 token enables decryption.'''
if not features.have_pkcs11:
self.skipTest('Requires GnuTLS with PKCS #11 support.')
key_file = os.path.join(dirs.key_dir, 'rsa-p-lt-q.p8')
key_uri = softhsm.import_key(key_file)
proc = self.assertRun((cmd_tshark,
'-r', capture_file('rsa-p-lt-q.pcap'),
'-o', 'uat:pkcs11_libs:"{}"'.format(softhsm.provider.replace('\\', '\\x5c')),
'-o', 'uat:rsa_keys:"{}","{}"'.format(key_uri, softhsm.pin),
'-Tfields',
'-e', 'http.request.uri',
'-Y', 'http',
))
self.assertIn('/', proc.stdout_str)

View File

@ -18,6 +18,7 @@ then
printf "Usage: %s [--install-optional] [--install-deb-deps] [...other options...]\\n" "$0"
printf "\\t--install-optional: install optional software as well\\n"
printf "\\t--install-deb-deps: install packages required to build the .deb file\\n"
printf "\\t--install-test-deps: install packages required to run all tests\\n"
printf "\\t[other]: other options are passed as-is to apt\\n"
exit 1
fi
@ -29,17 +30,24 @@ then
exit 1
fi
for op
do
if [ "$op" = "--install-optional" ]
then
ADDITIONAL=1
elif [ "$op" = "--install-deb-deps" ]
then
DEBDEPS=1
else
OPTIONS="$OPTIONS $op"
fi
ADDITIONAL=0
DEBDEPS=0
TESTDEPS=0
for arg; do
case $arg in
--install-optional)
ADDITIONAL=1
;;
--install-deb-deps)
DEBDEPS=1
;;
--install-test-deps)
TESTDEPS=1
;;
*)
OPTIONS="$OPTIONS $arg"
;;
esac
done
BASIC_LIST="libglib2.0-dev \
@ -83,6 +91,8 @@ DEBDEPS_LIST="debhelper \
libxml2-utils \
quilt"
TESTDEPS_LIST=
# Adds package $2 to list variable $1 if the package is found.
# If $3 is given, then this version requirement must be satisfied.
add_package() {
@ -122,7 +132,7 @@ echo "libssh-gcrypt-dev and libssh-dev are unavailable" >&2
add_package ADDITIONAL_LIST libgnutls28-dev ||
echo "libgnutls28-dev is unavailable" >&2
# mmdbresolve
# Debian >= jessie-backports, Ubuntu >= 16.04
add_package ADDITIONAL_LIST libmaxminddb-dev ||
echo "libmaxminddb-dev is unavailable" >&2
@ -132,6 +142,18 @@ add_package DEBDEPS_LIST libsystemd-dev ||
add_package DEBDEPS_LIST libsystemd-journal-dev ||
echo "libsystemd-dev is unavailable"
# softhsm2 2.0.0: Ubuntu 16.04
# softhsm2 2.2.0: Debian >= jessie-backports, Ubuntu 18.04
# softhsm2 >= 2.4.0: Debian >= buster, Ubuntu >= 18.10
if ! add_package TESTDEPS_LIST softhsm2 '>= 2.3.0'; then
if add_package TESTDEPS_LIST softhsm2; then
# If SoftHSM 2.3.0 is unavailble, install p11tool.
TESTDEPS_LIST="$TESTDEPS_LIST gnutls-bin"
else
echo "softhsm2 is unavailable" >&2
fi
fi
ACTUAL_LIST=$BASIC_LIST
# Now arrange for optional support libraries
@ -145,6 +167,11 @@ then
ACTUAL_LIST="$ACTUAL_LIST $DEBDEPS_LIST"
fi
if [ $TESTDEPS ]
then
ACTUAL_LIST="$ACTUAL_LIST $TESTDEPS_LIST"
fi
apt-get update || exit 2
# shellcheck disable=SC2086
apt-get install $ACTUAL_LIST $OPTIONS || exit 2