Merge branch 'development' of gitlab.yubico.com:/Yubico/yubico-piv-tool into development
Conflicts: ykcs11/ykcs11.c
This commit is contained in:
+50
-88
@@ -128,60 +128,15 @@ ykpiv_rc ykpiv_disconnect(ykpiv_state *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
||||||
return ykpiv_connect2(state, wanted, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ykpiv_rc ykpiv_connect2(ykpiv_state *state, const char *wanted, unsigned char **readers, unsigned long *len) {
|
|
||||||
unsigned long num_readers = 0;
|
|
||||||
unsigned long active_protocol;
|
unsigned long active_protocol;
|
||||||
char reader_buf[1024];
|
char reader_buf[2048];
|
||||||
|
size_t num_readers = sizeof(reader_buf);
|
||||||
long rc;
|
long rc;
|
||||||
int i;
|
|
||||||
char *reader_ptr;
|
char *reader_ptr;
|
||||||
|
|
||||||
rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &state->context);
|
ykpiv_rc ret = ykpiv_list_readers(state, reader_buf, &num_readers);
|
||||||
if (rc != SCARD_S_SUCCESS) {
|
if(ret != YKPIV_OK) {
|
||||||
if(state->verbose) {
|
return ret;
|
||||||
fprintf (stderr, "error: SCardEstablishContext failed, rc=%08lx\n", rc);
|
|
||||||
}
|
|
||||||
return YKPIV_PCSC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = SCardListReaders(state->context, NULL, NULL, &num_readers);
|
|
||||||
if (rc != SCARD_S_SUCCESS) {
|
|
||||||
if(state->verbose) {
|
|
||||||
fprintf (stderr, "error: SCardListReaders failed, rc=%08lx\n", rc);
|
|
||||||
}
|
|
||||||
SCardReleaseContext(state->context);
|
|
||||||
return YKPIV_PCSC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_readers > sizeof(reader_buf)) {
|
|
||||||
num_readers = sizeof(reader_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = SCardListReaders(state->context, NULL, reader_buf, &num_readers);
|
|
||||||
if (rc != SCARD_S_SUCCESS)
|
|
||||||
{
|
|
||||||
if(state->verbose) {
|
|
||||||
fprintf (stderr, "error: SCardListReaders failed, rc=%08lx\n", rc);
|
|
||||||
}
|
|
||||||
SCardReleaseContext(state->context);
|
|
||||||
return YKPIV_PCSC_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save available readers (aka PKCS11 slots)
|
|
||||||
if (readers != NULL) {
|
|
||||||
*readers = malloc(sizeof(char) * num_readers);
|
|
||||||
if (*readers == NULL) {
|
|
||||||
if(state->verbose) {
|
|
||||||
fprintf (stderr, "error: malloc failed");
|
|
||||||
}
|
|
||||||
SCardReleaseContext(state->context);
|
|
||||||
return YKPIV_MEMORY_ERROR;
|
|
||||||
}
|
|
||||||
memcpy(*readers, reader_buf, num_readers);
|
|
||||||
*len = num_readers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(reader_ptr = reader_buf; *reader_ptr != '\0'; reader_ptr += strlen(reader_ptr) + 1) {
|
for(reader_ptr = reader_buf; *reader_ptr != '\0'; reader_ptr += strlen(reader_ptr) + 1) {
|
||||||
@@ -245,6 +200,48 @@ ykpiv_rc ykpiv_connect2(ykpiv_state *state, const char *wanted, unsigned char **
|
|||||||
return YKPIV_GENERIC_ERROR;
|
return YKPIV_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) {
|
||||||
|
unsigned long num_readers = 0;
|
||||||
|
long rc;
|
||||||
|
|
||||||
|
if(SCardIsValidContext(state->context) != SCARD_S_SUCCESS) {
|
||||||
|
rc = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &state->context);
|
||||||
|
if (rc != SCARD_S_SUCCESS) {
|
||||||
|
if(state->verbose) {
|
||||||
|
fprintf (stderr, "error: SCardEstablishContext failed, rc=%08lx\n", rc);
|
||||||
|
}
|
||||||
|
return YKPIV_PCSC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = SCardListReaders(state->context, NULL, NULL, &num_readers);
|
||||||
|
if (rc != SCARD_S_SUCCESS) {
|
||||||
|
if(state->verbose) {
|
||||||
|
fprintf (stderr, "error: SCardListReaders failed, rc=%08lx\n", rc);
|
||||||
|
}
|
||||||
|
SCardReleaseContext(state->context);
|
||||||
|
return YKPIV_PCSC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_readers > *len) {
|
||||||
|
num_readers = *len;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = SCardListReaders(state->context, NULL, readers, &num_readers);
|
||||||
|
if (rc != SCARD_S_SUCCESS)
|
||||||
|
{
|
||||||
|
if(state->verbose) {
|
||||||
|
fprintf (stderr, "error: SCardListReaders failed, rc=%08lx\n", rc);
|
||||||
|
}
|
||||||
|
SCardReleaseContext(state->context);
|
||||||
|
return YKPIV_PCSC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = num_readers;
|
||||||
|
|
||||||
|
return YKPIV_OK;
|
||||||
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||||
const unsigned char *in_data, long in_len,
|
const unsigned char *in_data, long in_len,
|
||||||
unsigned char *out_data, unsigned long *out_len, int *sw) {
|
unsigned char *out_data, unsigned long *out_len, int *sw) {
|
||||||
@@ -536,7 +533,7 @@ ykpiv_rc ykpiv_hex_decode(const char *hex_in, size_t in_len,
|
|||||||
static ykpiv_rc _general_authenticate(ykpiv_state *state,
|
static ykpiv_rc _general_authenticate(ykpiv_state *state,
|
||||||
const unsigned char *sign_in, size_t in_len,
|
const unsigned char *sign_in, size_t in_len,
|
||||||
unsigned char *out, size_t *out_len,
|
unsigned char *out, size_t *out_len,
|
||||||
unsigned char algorithm, unsigned char key, bool decipher, bool padding) {
|
unsigned char algorithm, unsigned char key, bool decipher) {
|
||||||
unsigned char indata[1024];
|
unsigned char indata[1024];
|
||||||
unsigned char *dataptr = indata;
|
unsigned char *dataptr = indata;
|
||||||
unsigned char data[1024];
|
unsigned char data[1024];
|
||||||
@@ -642,25 +639,14 @@ ykpiv_rc ykpiv_sign_data(ykpiv_state *state,
|
|||||||
unsigned char algorithm, unsigned char key) {
|
unsigned char algorithm, unsigned char key) {
|
||||||
|
|
||||||
return _general_authenticate(state, raw_in, in_len, sign_out, out_len,
|
return _general_authenticate(state, raw_in, in_len, sign_out, out_len,
|
||||||
algorithm, key, false, true);
|
algorithm, key, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_sign_data2(ykpiv_state *state,
|
|
||||||
const unsigned char *raw_in, size_t in_len,
|
|
||||||
unsigned char *sign_out, size_t *out_len,
|
|
||||||
unsigned char algorithm, unsigned char key,
|
|
||||||
int padding) {
|
|
||||||
|
|
||||||
return _general_authenticate(state, raw_in, in_len, sign_out, out_len,
|
|
||||||
algorithm, key, false, padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *in,
|
ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *in,
|
||||||
size_t in_len, unsigned char *out, size_t *out_len,
|
size_t in_len, unsigned char *out, size_t *out_len,
|
||||||
unsigned char algorithm, unsigned char key) {
|
unsigned char algorithm, unsigned char key) {
|
||||||
return _general_authenticate(state, in, in_len, out, out_len,
|
return _general_authenticate(state, in, in_len, out, out_len,
|
||||||
algorithm, key, true, true);
|
algorithm, key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len) {
|
ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len) {
|
||||||
@@ -791,27 +777,3 @@ ykpiv_rc ykpiv_save_object(ykpiv_state *state, int object_id,
|
|||||||
return YKPIV_GENERIC_ERROR;
|
return YKPIV_GENERIC_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_get_reader_slot_number(ykpiv_state *state, unsigned long *slots, unsigned long *total) {
|
|
||||||
if (state == NULL)
|
|
||||||
return YKPIV_MEMORY_ERROR;
|
|
||||||
|
|
||||||
*slots = state->n_readers;
|
|
||||||
*total = state->tot_readers_len;
|
|
||||||
|
|
||||||
return YKPIV_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ykpiv_rc ykpiv_get_reader_slot(ykpiv_state *state, unsigned long slot, char *reader) {
|
|
||||||
if (state == NULL)
|
|
||||||
return YKPIV_MEMORY_ERROR;
|
|
||||||
|
|
||||||
if (slot >= state->n_readers)
|
|
||||||
return YKPIV_SIZE_ERROR;
|
|
||||||
|
|
||||||
strcpy(reader, state->readers[slot]);
|
|
||||||
|
|
||||||
return YKPIV_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-2
@@ -65,8 +65,7 @@ extern "C"
|
|||||||
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose);
|
ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose);
|
||||||
ykpiv_rc ykpiv_done(ykpiv_state *state);
|
ykpiv_rc ykpiv_done(ykpiv_state *state);
|
||||||
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted);
|
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted);
|
||||||
ykpiv_rc ykpiv_connect2(ykpiv_state *state, const char *wanted,
|
ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len);
|
||||||
unsigned char **readers, unsigned long *len); // Allow to return a reader string
|
|
||||||
ykpiv_rc ykpiv_disconnect(ykpiv_state *state);
|
ykpiv_rc ykpiv_disconnect(ykpiv_state *state);
|
||||||
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||||
const unsigned char *in_data, long in_len,
|
const unsigned char *in_data, long in_len,
|
||||||
|
|||||||
+1
-2
@@ -53,12 +53,11 @@ YKPIV_0.2.0
|
|||||||
{
|
{
|
||||||
global:
|
global:
|
||||||
ykpiv_decipher_data;
|
ykpiv_decipher_data;
|
||||||
ykpiv_connect2;
|
|
||||||
ykpiv_sign_data2;
|
|
||||||
} YKPIV_0.1.0;
|
} YKPIV_0.1.0;
|
||||||
|
|
||||||
YKPIV_1.1.0
|
YKPIV_1.1.0
|
||||||
{
|
{
|
||||||
global:
|
global:
|
||||||
ykpiv_set_mgmkey2;
|
ykpiv_set_mgmkey2;
|
||||||
|
ykpiv_list_readers;
|
||||||
} YKPIV_0.1.0;
|
} YKPIV_0.1.0;
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ option "action" a "Action to take" values="version","generate","set-mgm-key",
|
|||||||
"reset","pin-retries","import-key","import-certificate","set-chuid",
|
"reset","pin-retries","import-key","import-certificate","set-chuid",
|
||||||
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
|
"request-certificate","verify-pin","change-pin","change-puk","unblock-pin",
|
||||||
"selfsign-certificate","delete-certificate","read-certificate","status",
|
"selfsign-certificate","delete-certificate","read-certificate","status",
|
||||||
"test-signature","test-decipher" enum multiple
|
"test-signature","test-decipher","list-readers" enum multiple
|
||||||
text "
|
text "
|
||||||
Multiple actions may be given at once and will be executed in order
|
Multiple actions may be given at once and will be executed in order
|
||||||
for example --action=verify-pin --action=request-certificate\n"
|
for example --action=verify-pin --action=request-certificate\n"
|
||||||
|
|||||||
+46
-9
@@ -85,6 +85,25 @@ static void print_version(ykpiv_state *state, const char *output_file_name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool sign_data(ykpiv_state *state, const unsigned char *in, size_t len, unsigned char *out,
|
||||||
|
size_t *out_len, unsigned char algorithm, int key) {
|
||||||
|
|
||||||
|
unsigned char signinput[1024];
|
||||||
|
if(YKPIV_IS_RSA(algorithm)) {
|
||||||
|
size_t padlen = algorithm == YKPIV_ALGO_RSA1024 ? 128 : 256;
|
||||||
|
if(RSA_padding_add_PKCS1_type_1(signinput, padlen, in, len) == 0) {
|
||||||
|
fprintf(stderr, "Failed adding padding.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
in = signinput;
|
||||||
|
len = padlen;
|
||||||
|
}
|
||||||
|
if(ykpiv_sign_data(state, signinput, len, out, out_len, algorithm, key) == YKPIV_OK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool generate_key(ykpiv_state *state, const char *slot,
|
static bool generate_key(ykpiv_state *state, const char *slot,
|
||||||
enum enum_algorithm algorithm, const char *output_file_name,
|
enum enum_algorithm algorithm, const char *output_file_name,
|
||||||
enum enum_key_format key_format, enum enum_pin_policy pin_policy,
|
enum enum_key_format key_format, enum enum_pin_policy pin_policy,
|
||||||
@@ -692,8 +711,7 @@ static bool request_certificate(ykpiv_state *state, enum enum_key_format key_for
|
|||||||
{
|
{
|
||||||
unsigned char signature[1024];
|
unsigned char signature[1024];
|
||||||
size_t sig_len = sizeof(signature);
|
size_t sig_len = sizeof(signature);
|
||||||
if(ykpiv_sign_data(state, signinput, len, signature, &sig_len, algorithm, key)
|
if(!sign_data(state, signinput, len, signature, &sig_len, algorithm, key)) {
|
||||||
!= YKPIV_OK) {
|
|
||||||
fprintf(stderr, "Failed signing request.\n");
|
fprintf(stderr, "Failed signing request.\n");
|
||||||
goto request_out;
|
goto request_out;
|
||||||
}
|
}
|
||||||
@@ -845,8 +863,7 @@ static bool selfsign_certificate(ykpiv_state *state, enum enum_key_format key_fo
|
|||||||
{
|
{
|
||||||
unsigned char signature[1024];
|
unsigned char signature[1024];
|
||||||
size_t sig_len = sizeof(signature);
|
size_t sig_len = sizeof(signature);
|
||||||
if(ykpiv_sign_data(state, signinput, len, signature, &sig_len, algorithm, key)
|
if(!sign_data(state, signinput, len, signature, &sig_len, algorithm, key)) {
|
||||||
!= YKPIV_OK) {
|
|
||||||
fprintf(stderr, "Failed signing certificate.\n");
|
fprintf(stderr, "Failed signing certificate.\n");
|
||||||
goto selfsign_out;
|
goto selfsign_out;
|
||||||
}
|
}
|
||||||
@@ -1122,9 +1139,8 @@ static bool sign_file(ykpiv_state *state, const char *input, const char *output,
|
|||||||
{
|
{
|
||||||
unsigned char buf[1024];
|
unsigned char buf[1024];
|
||||||
size_t len = sizeof(buf);
|
size_t len = sizeof(buf);
|
||||||
ykpiv_rc rc = ykpiv_sign_data(state, hashed, hash_len, buf, &len, algo, key);
|
if(!sign_data(state, hashed, hash_len, buf, &len, algo, key)) {
|
||||||
if(rc != YKPIV_OK) {
|
fprintf(stderr, "failed signing file\n");
|
||||||
fprintf(stderr, "failed signing file: %s\n", ykpiv_strerror(rc));
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1373,8 +1389,7 @@ static bool test_signature(ykpiv_state *state, enum enum_slot slot,
|
|||||||
} else {
|
} else {
|
||||||
enc_len = data_len;
|
enc_len = data_len;
|
||||||
}
|
}
|
||||||
if(ykpiv_sign_data(state, ptr, enc_len, signature, &sig_len, algorithm, key)
|
if(!sign_data(state, ptr, enc_len, signature, &sig_len, algorithm, key)) {
|
||||||
!= YKPIV_OK) {
|
|
||||||
fprintf(stderr, "Failed signing test data.\n");
|
fprintf(stderr, "Failed signing test data.\n");
|
||||||
goto test_out;
|
goto test_out;
|
||||||
}
|
}
|
||||||
@@ -1569,6 +1584,21 @@ decipher_out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool list_readers(ykpiv_state *state) {
|
||||||
|
char readers[2048];
|
||||||
|
char *reader_ptr;
|
||||||
|
size_t len = sizeof(readers);
|
||||||
|
ykpiv_rc rc = ykpiv_list_readers(state, readers, &len);
|
||||||
|
if(rc != YKPIV_OK) {
|
||||||
|
fprintf(stderr, "Failed listing readers.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(reader_ptr = readers; *reader_ptr != '\0'; reader_ptr += strlen(reader_ptr) + 1) {
|
||||||
|
printf("%s\n", reader_ptr);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
struct gengetopt_args_info args_info;
|
struct gengetopt_args_info args_info;
|
||||||
ykpiv_state *state;
|
ykpiv_state *state;
|
||||||
@@ -1622,6 +1652,7 @@ int main(int argc, char *argv[]) {
|
|||||||
case action_arg_version:
|
case action_arg_version:
|
||||||
case action_arg_reset:
|
case action_arg_reset:
|
||||||
case action_arg_status:
|
case action_arg_status:
|
||||||
|
case action_arg_listMINUS_readers:
|
||||||
case action__NULL:
|
case action__NULL:
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
@@ -1666,6 +1697,7 @@ int main(int argc, char *argv[]) {
|
|||||||
case action_arg_status:
|
case action_arg_status:
|
||||||
case action_arg_testMINUS_signature:
|
case action_arg_testMINUS_signature:
|
||||||
case action_arg_testMINUS_decipher:
|
case action_arg_testMINUS_decipher:
|
||||||
|
case action_arg_listMINUS_readers:
|
||||||
case action__NULL:
|
case action__NULL:
|
||||||
default:
|
default:
|
||||||
if(verbosity) {
|
if(verbosity) {
|
||||||
@@ -1850,6 +1882,11 @@ int main(int argc, char *argv[]) {
|
|||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case action_arg_listMINUS_readers:
|
||||||
|
if(list_readers(state) == false) {
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case action__NULL:
|
case action__NULL:
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "Wrong action. %d.\n", action);
|
fprintf(stderr, "Wrong action. %d.\n", action);
|
||||||
|
|||||||
+10
-4
@@ -47,8 +47,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
DIN;
|
DIN;
|
||||||
CK_CHAR_PTR readers;
|
char readers[2048];
|
||||||
CK_ULONG len;
|
CK_ULONG len = sizeof(readers);
|
||||||
|
|
||||||
// TODO: check for locks and mutexes
|
// TODO: check for locks and mutexes
|
||||||
|
|
||||||
@@ -60,7 +60,12 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
|
|||||||
return CKR_FUNCTION_FAILED; // TODO: better error?
|
return CKR_FUNCTION_FAILED; // TODO: better error?
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ykpiv_connect2(piv_state, NULL, &readers, &len) != YKPIV_OK) {
|
if (ykpiv_list_readers(piv_state, readers, &len) != YKPIV_OK) {
|
||||||
|
DBG(("Unable to list readers"));
|
||||||
|
return CKR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ykpiv_connect(piv_state, NULL) != YKPIV_OK) {
|
||||||
DBG(("Unable to connect to reader"));
|
DBG(("Unable to connect to reader"));
|
||||||
return CKR_FUNCTION_FAILED;
|
return CKR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
@@ -1701,7 +1706,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_Sign)(
|
|||||||
dump_hex(op_info.buf, op_info.buf_len, stderr, CK_TRUE);
|
dump_hex(op_info.buf, op_info.buf_len, stderr, CK_TRUE);
|
||||||
|
|
||||||
*pulSignatureLen = sizeof(op_info.buf);
|
*pulSignatureLen = sizeof(op_info.buf);
|
||||||
piv_rv = ykpiv_sign_data2(piv_state, op_info.buf, op_info.buf_len, pSignature, pulSignatureLen, op_info.op.sign.algo, op_info.op.sign.key_id, 0);
|
|
||||||
|
piv_rv = ykpiv_sign_data(piv_state, op_info.buf, op_info.buf_len, pSignature, pulSignatureLen, op_info.op.sign.algo, op_info.op.sign.key_id);
|
||||||
if (piv_rv != YKPIV_OK) {
|
if (piv_rv != YKPIV_OK) {
|
||||||
if (piv_rv == YKPIV_AUTHENTICATION_ERROR) {
|
if (piv_rv == YKPIV_AUTHENTICATION_ERROR) {
|
||||||
DBG(("Operation requires authentication or touch"));
|
DBG(("Operation requires authentication or touch"));
|
||||||
|
|||||||
Reference in New Issue
Block a user