mirror of
https://github.com/stefanberger/swtpm.git
synced 2025-08-22 19:04:35 +00:00
swtpm: Implement --print-info to run TPMLIB_GetInfo with flags
Implement --print-info that takes a number as argument and uses this number as flags to call TPMLIB_GetInfo with. Display the JSON string and exit. Extend the man page and update other parts where swtpm_ioctl is not necessary anymore to use. Extend a test case to also check that swtpm now returns the same result as swtpm_ioctl does. Append cmdarg-print-info to printed out capabilties. Adjust test cases. (Expect 'profiles' to always be part of capabilties JSON.) Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
parent
770abf3ff0
commit
3f551e1dc1
@ -336,7 +336,8 @@ may contain the following:
|
||||
"rsa-keysize-3072",
|
||||
"cmdarg-profile",
|
||||
"cmdarg-print-profiles",
|
||||
"profile-opt-remove-disabled"
|
||||
"profile-opt-remove-disabled",
|
||||
"cmdarg-print-info",
|
||||
],
|
||||
"version": "0.7.0"
|
||||
}
|
||||
@ -413,18 +414,22 @@ rsa-keysize verbs is shown then only RSA 2048 bit keys are supported.
|
||||
|
||||
=item B<cmdarg-profile> (since v0.10)
|
||||
|
||||
The option <--profile> is supported to set a profile for a TPM 2 with either
|
||||
The option I<--profile> is supported to set a profile for a TPM 2 with either
|
||||
one of the option parameters I<name=>, I<profile=>, I<fd=>, or I<file=>.
|
||||
|
||||
=item B<cmdarg-print-profiles> (since v0.10)
|
||||
|
||||
The option <--print-profiles> is supported.
|
||||
The option I<--print-profiles> is supported.
|
||||
|
||||
=item B<profile-opt-remove-disabled>
|
||||
=item B<profile-opt-remove-disabled> (since v0.10)
|
||||
|
||||
The I<--profile> option supports the I<remove-disabled> option
|
||||
parameter.
|
||||
|
||||
=item B<cmdard-print-info> (since v0.10)
|
||||
|
||||
The option I<--print-info> is supported.
|
||||
|
||||
=back
|
||||
|
||||
=item B<--print-states> (since v0.7)
|
||||
@ -528,10 +533,9 @@ require a certain StateFormatLevel, it is recommended to omit the
|
||||
StateFormatLevel field from the profile.
|
||||
|
||||
To see the list of algorithms that are supported and can be disabled, one
|
||||
may use I<swtpm_ioctl> as follows. A swtpm instance is assumed to be
|
||||
listening for control commands on port 2322:
|
||||
may use I<swtpm> as follows.
|
||||
|
||||
$ swtpm_ioctl --tcp :2322 --info 0x08 | jq
|
||||
$ swtpm socket --tpmstate dir=./ --tpm2 --print-info 0x08 | jq
|
||||
{
|
||||
"RuntimeAlgorithms": {
|
||||
"Implemented": "rsa,rsa-min-size=1024,tdes,tdes-min-size=128,sha1,hmac,aes,aes-min-size=128,mgf1,keyedhash,xor,sha256,sha384,sha512,null,rsassa,rsaes,rsapss,oaep,ecdsa,ecdh,ecdaa,sm2,ecschnorr,ecmqv,kdf1-sp800-56a,kdf2,kdf1-sp800-108,ecc,ecc-min-size=192,ecc-nist,ecc-bn,ecc-nist-p192,ecc-nist-p224,ecc-nist-p256,ecc-nist-p384,ecc-nist-p521,ecc-bn-p256,ecc-bn-p638,ecc-sm2-p256,symcipher,camellia,camellia-min-size=128,cmac,ctr,ofb,cbc,cfb,ecb",
|
||||
@ -543,7 +547,7 @@ listening for control commands on port 2322:
|
||||
|
||||
To see the list of supported commands:
|
||||
|
||||
$ swtpm_ioctl --tcp :2322 --info 0x10 | jq
|
||||
$ swtpm socket --tpmstate dir=./ --tpm2 --print-info 0x10 | jq
|
||||
{
|
||||
"RuntimeCommands": {
|
||||
"Implemented": "0x11f-0x122,0x124-0x12e,0x130-0x140,0x142-0x159,0x15b-0x15e,0x160-0x165,0x167-0x174,0x176-0x178,0x17a-0x193,0x197,0x199-0x19c",
|
||||
@ -555,7 +559,7 @@ To see the list of supported commands:
|
||||
|
||||
To see the list of supported attributes:
|
||||
|
||||
$swtpm_ioctl --tcp :2322 --info 0x80 | jq
|
||||
$ swtpm socket --tpmstate dir=./ --tpm2 --print-info 0x80 | jq
|
||||
{
|
||||
"RuntimeAttributes": {
|
||||
"Implemented": "no-unpadded-encryption,no-sha1-signing,no-sha1-verification,no-sha1-hmac-creation,no-sha1-hmac-verification,no-sha1-hmac,fips-host",
|
||||
@ -570,7 +574,7 @@ entry, which is similar to the "Algorithms" and "Commands" entries.
|
||||
|
||||
To see the list of available profiles:
|
||||
|
||||
$ swtpm_ioctl --tcp :2322 --info 0x40 | jq
|
||||
$ swtpm socket --tpm2 --print-info 0x40 | jq
|
||||
{
|
||||
"AvailableProfiles": [
|
||||
{
|
||||
@ -597,7 +601,8 @@ To see the list of available profiles:
|
||||
]
|
||||
}
|
||||
|
||||
To see the current active profile:
|
||||
To see the current active profile querying swtpm listening for control
|
||||
message on port 2322:
|
||||
|
||||
$ swtpm_ioctl --tcp :2322 --info 0x20 | jq
|
||||
{
|
||||
@ -619,6 +624,37 @@ none of them relies on disabled commands or algorithms.
|
||||
|
||||
Display the profiles supported by libtpms. Use with I<--tpm2> option.
|
||||
|
||||
=item B<--print-info> (since v0.10)
|
||||
|
||||
Display information about the TPM from libtpms TPMLIB_GetInfo call and exit.
|
||||
Use the I<--tpm2> option for information about TPM 2. If the I<--tpmstate>
|
||||
option is also provided then the output will show information about the profile
|
||||
as well. Note that with this option a TPM state may be created if none existed
|
||||
before.
|
||||
|
||||
The following values can be provided. All of the values can be
|
||||
or'ed (or added) together to get information about all of them in one query.
|
||||
|
||||
=over 2
|
||||
|
||||
=item * 0x1: information about the specification the TPM implementation followed
|
||||
|
||||
=item * 0x2: information about the manufacturer, model and version of the TPM
|
||||
|
||||
=item * 0x4: lists supported RSA and Camellia key sizes
|
||||
|
||||
=item * 0x8: describes supported and enabled algorithms
|
||||
|
||||
=item * 0x10: describes supported and enabled commands
|
||||
|
||||
=item * 0x20: describes the active profile
|
||||
|
||||
=item * 0x40: lists all built-in profiles
|
||||
|
||||
=item * 0x80: describes supported attributes
|
||||
|
||||
=back
|
||||
|
||||
=item B<-h|--help>
|
||||
|
||||
Display usage info.
|
||||
|
@ -270,7 +270,7 @@ int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
|
||||
"{ "
|
||||
"\"type\": \"swtpm\", "
|
||||
"\"features\": [ "
|
||||
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
|
||||
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"
|
||||
" ], "
|
||||
"\"profiles\": { %s}, "
|
||||
"\"version\": \"" VERSION "\" "
|
||||
@ -293,6 +293,7 @@ int capabilities_print_json(bool cusetpm, TPMLIB_TPMVersion tpmversion)
|
||||
true ? ", \"cmdarg-profile\"" : "",
|
||||
true ? ", \"cmdarg-print-profiles\"" : "",
|
||||
true ? ", \"profile-opt-remove-disabled\"" : "",
|
||||
true ? ", \"cmdarg-print-info\"" : "",
|
||||
profiles ? profiles : ""
|
||||
);
|
||||
|
||||
|
@ -284,7 +284,9 @@ static const char *usage =
|
||||
" algorithms first\n"
|
||||
"--print-profiles\n"
|
||||
" : print all profiles supported by libtpms\n"
|
||||
"-h|--help : display this help screen and terminate\n"
|
||||
"--print-info <info flags>\n"
|
||||
" : print information about the TPM and profiles and exit\n"
|
||||
"-h|--help : display this help screen and terminate\n"
|
||||
"\n";
|
||||
|
||||
static TPM_RESULT
|
||||
@ -1594,6 +1596,7 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
|
||||
{
|
||||
#endif
|
||||
int opt, longindex = 0;
|
||||
enum TPMLIB_InfoFlags infoflags = 0;
|
||||
static struct option longopts[] = {
|
||||
{"maj" , required_argument, 0, 'M'},
|
||||
{"min" , required_argument, 0, 'm'},
|
||||
@ -1619,16 +1622,19 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
|
||||
{"print-states" , no_argument, 0, 'e'},
|
||||
{"profile" , required_argument, 0, 'I'},
|
||||
{"print-profiles", no_argument, 0, 'N'},
|
||||
{"print-info" , required_argument, 0, 'x'},
|
||||
{NULL , 0 , 0, 0 },
|
||||
};
|
||||
struct cuse_info cinfo;
|
||||
struct cuse_param param = {
|
||||
.startupType = _TPM_ST_NONE,
|
||||
};
|
||||
g_autofree gchar *jsoninfo = NULL;
|
||||
const char *devname = NULL;
|
||||
char *cinfo_argv[1] = { 0 };
|
||||
unsigned int num;
|
||||
const char *uri = NULL;
|
||||
char *end_ptr = NULL;
|
||||
int n, tpmfd;
|
||||
char path[PATH_MAX];
|
||||
int ret = 0;
|
||||
@ -1753,6 +1759,16 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
|
||||
case 'N': /* --print-profiles */
|
||||
printprofiles = true;
|
||||
break;
|
||||
case 'x': /* --print-info */
|
||||
errno = 0;
|
||||
infoflags = strtoul(optarg, &end_ptr, 0);
|
||||
if (infoflags != (unsigned int)infoflags || errno || end_ptr[0] != '\0') {
|
||||
logprintf(STDERR_FILENO,
|
||||
"Cannot parse info value '%s'.\n", optarg);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
break;
|
||||
case 'v': /* version */
|
||||
fprintf(stdout, "TPM emulator CUSE interface version %d.%d.%d, "
|
||||
"Copyright (c) 2014-2015 IBM Corp.\n",
|
||||
@ -1898,7 +1914,7 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
|
||||
|
||||
g_mutex_lock(FILE_OPS_LOCK);
|
||||
|
||||
if (!need_init_cmd) {
|
||||
if (!need_init_cmd || (infoflags && tpmstate_get_backend_uri())) {
|
||||
if (tpm_start(0, tpmversion, g_json_profile, &res) < 0) {
|
||||
ret = -1;
|
||||
goto err_unlock;
|
||||
@ -1907,6 +1923,13 @@ int swtpm_cuse_main(int argc, char **argv, const char *prgname, const char *ifac
|
||||
SWTPM_G_FREE(g_json_profile);
|
||||
}
|
||||
|
||||
if (infoflags) {
|
||||
/* returns more information with tpmstate active */
|
||||
jsoninfo = TPMLIB_GetInfo(infoflags);
|
||||
printf("%s\n", jsoninfo);
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
if (param.startupType != _TPM_ST_NONE) {
|
||||
if (ptm_send_startup(param.startupType, tpmversion) < 0) {
|
||||
ret = -1;
|
||||
|
@ -205,6 +205,8 @@ static void usage(FILE *file, const char *prgname, const char *iface)
|
||||
" algorithms first\n"
|
||||
"--print-profiles\n"
|
||||
" : print all profiles supported by libtpms\n"
|
||||
"--print-info <info flags>\n"
|
||||
" : print information about the TPM and profiles and exit\n"
|
||||
"-h|--help : display this help screen and terminate\n"
|
||||
"\n",
|
||||
prgname, iface);
|
||||
@ -239,6 +241,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
|
||||
.incoming_migration = false,
|
||||
.storage_locked = false,
|
||||
};
|
||||
g_autofree gchar *jsoninfo = NULL;
|
||||
struct server *server = NULL;
|
||||
unsigned long val;
|
||||
char *end_ptr;
|
||||
@ -266,6 +269,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
|
||||
bool printstates = false;
|
||||
bool printprofiles = false;
|
||||
bool tpm_running = false;
|
||||
enum TPMLIB_InfoFlags infoflags = 0;
|
||||
static struct option longopts[] = {
|
||||
{"daemon" , no_argument, 0, 'd'},
|
||||
{"help" , no_argument, 0, 'h'},
|
||||
@ -293,6 +297,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
|
||||
{"print-states", no_argument, 0, 'e'},
|
||||
{"profile" , required_argument, 0, 'I'},
|
||||
{"print-profiles", no_argument, 0, 'N'},
|
||||
{"print-info", required_argument, 0, 'x'},
|
||||
{NULL , 0 , 0, 0 },
|
||||
};
|
||||
|
||||
@ -447,6 +452,16 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
|
||||
printprofiles = true;
|
||||
break;
|
||||
|
||||
case 'x': /* --print-info */
|
||||
errno = 0;
|
||||
infoflags = strtoul(optarg, &end_ptr, 0);
|
||||
if (infoflags != (unsigned int)infoflags || errno || end_ptr[0] != '\0') {
|
||||
logprintf(STDERR_FILENO,
|
||||
"Cannot parse info value '%s'.\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(stderr, prgname, iface);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -565,7 +580,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
|
||||
if ((rc = tpmlib_register_callbacks(&callbacks)))
|
||||
goto error_no_tpm;
|
||||
|
||||
if (!need_init_cmd) {
|
||||
if (!need_init_cmd || (infoflags && tpmstate_get_backend_uri())) {
|
||||
mlp.storage_locked = !mlp.incoming_migration;
|
||||
|
||||
if ((rc = tpmlib_start(0, mlp.tpmversion, mlp.storage_locked,
|
||||
@ -575,6 +590,13 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
|
||||
SWTPM_G_FREE(mlp.json_profile);
|
||||
}
|
||||
|
||||
if (infoflags) {
|
||||
/* returns more information with tpmstate active */
|
||||
jsoninfo = TPMLIB_GetInfo(infoflags);
|
||||
printf("%s\n", jsoninfo);
|
||||
goto error_no_sighandlers;
|
||||
}
|
||||
|
||||
if (install_sighandlers(notify_fd, sigterm_handler) < 0)
|
||||
goto error_no_sighandlers;
|
||||
|
||||
|
@ -226,6 +226,8 @@ static void usage(FILE *file, const char *prgname, const char *iface)
|
||||
" algorithms first\n"
|
||||
"--print-profiles\n"
|
||||
" : print all profiles supported by libtpms\n"
|
||||
"--print-info <info flags>\n"
|
||||
" : print information about the TPM and profiles and exit\n"
|
||||
"-h|--help : display this help screen and terminate\n"
|
||||
"\n",
|
||||
prgname, iface);
|
||||
@ -297,6 +299,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
|
||||
.incoming_migration = false,
|
||||
.storage_locked = false,
|
||||
};
|
||||
g_autofree gchar *jsoninfo = NULL;
|
||||
unsigned long val;
|
||||
char *end_ptr;
|
||||
char *keydata = NULL;
|
||||
@ -324,6 +327,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
|
||||
bool printstates = false;
|
||||
bool printprofiles = false;
|
||||
bool tpm_running = false;
|
||||
enum TPMLIB_InfoFlags infoflags = 0;
|
||||
static struct option longopts[] = {
|
||||
{"daemon" , no_argument, 0, 'd'},
|
||||
{"help" , no_argument, 0, 'h'},
|
||||
@ -352,6 +356,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
|
||||
{"print-states", no_argument, 0, 'e'},
|
||||
{"profile" , required_argument, 0, 'I'},
|
||||
{"print-profiles", no_argument, 0, 'N'},
|
||||
{"print-info", required_argument, 0, 'x'},
|
||||
{NULL , 0 , 0, 0 },
|
||||
};
|
||||
|
||||
@ -497,6 +502,18 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
|
||||
printprofiles = true;
|
||||
break;
|
||||
|
||||
case 'x': /* --print-info */
|
||||
errno = 0;
|
||||
infoflags = strtoul(optarg, &end_ptr, 0);
|
||||
if (infoflags != (unsigned int)infoflags || errno || end_ptr[0] != '\0') {
|
||||
logprintf(STDERR_FILENO,
|
||||
"Cannot parse info value '%s'.\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (mlp.fd < 0)
|
||||
mlp.fd = open("/dev/zero", O_RDWR);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(stderr, prgname, iface);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -613,7 +630,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
|
||||
if ((rc = tpmlib_register_callbacks(&callbacks)))
|
||||
goto error_no_tpm;
|
||||
|
||||
if (!need_init_cmd) {
|
||||
if (!need_init_cmd || (infoflags && tpmstate_get_backend_uri())) {
|
||||
mlp.storage_locked = !mlp.incoming_migration;
|
||||
|
||||
if ((rc = tpmlib_start(0, mlp.tpmversion, mlp.storage_locked,
|
||||
@ -623,6 +640,13 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
|
||||
SWTPM_G_FREE(mlp.json_profile);
|
||||
}
|
||||
|
||||
if (infoflags) {
|
||||
/* returns more information with tpmstate active */
|
||||
jsoninfo = TPMLIB_GetInfo(infoflags);
|
||||
printf("%s\n", jsoninfo);
|
||||
goto error_no_sighandlers;
|
||||
}
|
||||
|
||||
if (install_sighandlers(notify_fd, sigterm_handler) < 0)
|
||||
goto error_no_sighandlers;
|
||||
|
||||
|
@ -29,8 +29,8 @@ exp='\{ "type": "swtpm", '\
|
||||
'"flags-opt-disable-auto-shutdown", "ctrl-opt-terminate", '${seccomp}'"cmdarg-key-fd", '\
|
||||
'"cmdarg-pwd-fd", "cmdarg-print-states", "cmdarg-chroot", "cmdarg-migration", '\
|
||||
'"nvram-backend-dir", "nvram-backend-file", "cmdarg-profile", '\
|
||||
'"cmdarg-print-profiles", "profile-opt-remove-disabled" \],'\
|
||||
'( "profiles": \{ \},)? '\
|
||||
'"cmdarg-print-profiles", "profile-opt-remove-disabled", "cmdarg-print-info" \], '\
|
||||
'"profiles": \{ \}, '\
|
||||
'"version": "[^"]*" \}'
|
||||
if ! [[ ${msg} =~ ${exp} ]]; then
|
||||
echo "Unexpected response from ${SWTPM_IFACE} TPM to --print-capabilities:"
|
||||
@ -53,8 +53,8 @@ exp='\{ "type": "swtpm_setup", '\
|
||||
'"tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files", '\
|
||||
'"cmdarg-reconfigure-pcr-banks"'\
|
||||
'(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")?, "cmdarg-profile", '\
|
||||
'"cmdarg-profile-remove-disabled" \],'\
|
||||
'( "profiles": \[ [^]]*\],)? '\
|
||||
'"cmdarg-profile-remove-disabled" \], '\
|
||||
'"profiles": \[ [^]]*\], '\
|
||||
'"version": "[^"]*" \}'
|
||||
if ! [[ ${msg} =~ ${exp} ]]; then
|
||||
echo "Unexpected response from ${SWTPM_SETUP} to --print-capabilities:"
|
||||
|
@ -31,8 +31,8 @@ exp='\{ "type": "swtpm", '\
|
||||
'"cmdarg-pwd-fd", "cmdarg-print-states", "cmdarg-chroot", "cmdarg-migration", '\
|
||||
'"nvram-backend-dir", "nvram-backend-file"'\
|
||||
'(, "rsa-keysize-1024")?(, "rsa-keysize-2048")?(, "rsa-keysize-3072")?, "cmdarg-profile", '\
|
||||
'"cmdarg-print-profiles", "profile-opt-remove-disabled" \],'\
|
||||
'( "profiles": \{ "names": \[ [^]]*\], "algorithms": \{ [^\}]*\}, "commands": \{ [^\}]*\} },)? '\
|
||||
'"cmdarg-print-profiles", "profile-opt-remove-disabled", "cmdarg-print-info" \], '\
|
||||
'"profiles": \{ "names": \[ [^]]*\], "algorithms": \{ [^\}]*\}, "commands": \{ [^\}]*\} }, '\
|
||||
'"version": "[^"]*" \}'
|
||||
if ! [[ ${msg} =~ ${exp} ]]; then
|
||||
echo "Unexpected response from ${SWTPM_IFACE} TPM to --print-capabilities:"
|
||||
@ -54,8 +54,8 @@ exp='\{ "type": "swtpm_setup", '\
|
||||
'"features": \[( "tpm-1.2",)? "tpm-2.0", "cmdarg-keyfile-fd", "cmdarg-pwdfile-fd", '\
|
||||
'"tpm12-not-need-root", "cmdarg-write-ek-cert-files", "cmdarg-create-config-files", '\
|
||||
'"cmdarg-reconfigure-pcr-banks"(, "tpm2-rsa-keysize-2048")?(, "tpm2-rsa-keysize-3072")?, '\
|
||||
'"cmdarg-profile", "cmdarg-profile-remove-disabled" \],'\
|
||||
'( "profiles": \[ [^]]*\],)? '\
|
||||
'"cmdarg-profile", "cmdarg-profile-remove-disabled" \], '\
|
||||
'"profiles": \[ [^]]*\], '\
|
||||
'"version": "[^"]*" \}'
|
||||
if ! [[ ${msg} =~ ${exp} ]]; then
|
||||
echo "Unexpected response from ${SWTPM_SETUP} to --print-capabilities:"
|
||||
|
@ -128,6 +128,20 @@ test_swtpm_setup_profile()
|
||||
echo "Error: ${SWTPM_INTERFACE} TPM should not be running anymore."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Expecting same results from swtpm directly
|
||||
if [ -n "${exp_response}" ]; then
|
||||
response=$(${SWTPM_EXE} socket \
|
||||
--tpmstate "dir=${workdir}" \
|
||||
--tpm2 \
|
||||
--print-info 0x20)
|
||||
if ! [[ "${response}" =~ ${exp_response} ]]; then
|
||||
echo "Error: Response does not match expected response regular expression (swtpm)"
|
||||
echo "Actual : ${response}"
|
||||
echo "Expected : ${exp_response}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Get available profiles and algorithms that are implemented and those that can be disabled
|
||||
|
Loading…
Reference in New Issue
Block a user