Continuing unit tests and minor bug fixes

* Support unit tests on Yubikey NEO
* Test ykpiv_get_version
* Test ykpiv_import_private_key
* Test ykpiv_sign_data
* Test ykpiv_decipher_data
* Test ykpiv_change_pin
* Test ykpiv_change_puk
* Test ykpiv_get_pin_retries
* Test ykpiv_set_pin_retries
* Test ykpiv_verify
* Fix segfault when |tries| is NULL
* Fix segfault when import_private_key algorithm is wrong
This commit is contained in:
Trevor Bentley
2017-08-07 14:04:45 +02:00
parent 89e8e7864e
commit 16d0a519c4
5 changed files with 440 additions and 14 deletions
+13
View File
@@ -43,12 +43,19 @@ lib/tests/parse_key
lib/tests/parse_key.log
lib/tests/parse_key.o
lib/tests/parse_key.trs
lib/tests/util
lib/tests/util.log
lib/tests/util.o
lib/tests/util.trs
lib/tests/test-suite.log
lib/error.lo
lib/error.o
lib/libykpiv.la
lib/version.lo
lib/version.o
lib/util.la
lib/util.lo
lib/util.o
lib/ykpiv-version.h
lib/ykpiv.lo
lib/ykpiv.o
@@ -97,3 +104,9 @@ ykcs11/tests/ykcs11_tests.o
ykcs11/tests/ykcs11_tests.trs
ykcs11/tests/test-suite.log
yubico-piv-tool.1.txt
*.plist
.libs
GPATH
GRTAGS
GTAGS
+3 -3
View File
@@ -25,11 +25,11 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
AM_CFLAGS = $(WARN_CFLAGS) @CHECK_CFLAGS@
AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_builddir)/lib
AM_CFLAGS = $(WARN_CFLAGS) @CHECK_CFLAGS@ $(OPENSSL_CFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_builddir)/lib $(OPENSSL_CFLAGS)
AM_LDFLAGS = -no-install @CHECK_LIBS@
LDADD = ../libykpiv.la
LDADD = ../libykpiv.la $(OPENSSL_LIBS)
check_PROGRAMS = basic parse_key util
TESTS = $(check_PROGRAMS)
+367 -3
View File
@@ -79,10 +79,32 @@ void teardown(void) {
}
START_TEST(test_devicemodel) {
ykpiv_rc res;
ykpiv_devmodel model;
char version[256];
char reader_buf[2048];
size_t num_readers = sizeof(reader_buf);
res = ykpiv_get_version(g_state, version, sizeof(version));
ck_assert_int_eq(res, YKPIV_OK);
fprintf(stderr, "Version: %s\n", version);
model = ykpiv_util_devicemodel(g_state);
fprintf(stdout, "Model: %u\n", model);
ck_assert(model == DEVTYPE_YK4);
ck_assert(model == DEVTYPE_YK4 || model == DEVTYPE_NEOr3);
res = ykpiv_list_readers(g_state, reader_buf, &num_readers);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_gt(num_readers, 0);
if (model == DEVTYPE_YK4) {
ck_assert_ptr_nonnull(strnstr(reader_buf, "Yubikey 4", strlen(reader_buf)));
ck_assert(version[0] == '4'); // Verify app version 4.x
ck_assert(version[1] == '.');
}
else {
ck_assert_ptr_nonnull(strnstr(reader_buf, "Yubikey NEO", strlen(reader_buf)));
ck_assert(version[0] == '1'); // Verify app version 1.x
ck_assert(version[1] == '.');
}
}
END_TEST
@@ -162,6 +184,229 @@ START_TEST(test_read_write_list_delete_cert) {
}
END_TEST
#include <openssl/des.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/rand.h>
// RSA2048 private key, generated with: `openssl genrsa 2048 -out private.pem`
static const char *private_key_pem =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEpAIBAAKCAQEAwVUwmVbc+ffOy2+RivxBpgleTVN6bUa0q7jNYB+AseFQYaYq\n"
"EGfa+VGdxSGo+8DV1KT9+fNEd5243gXn/tcjtMItKeB+oAQc64s9lIFlYuR8bpq1\n"
"ibr33iW2elnnv9mpecqohdCVwM2McWveoPyb7MwlwVuhqexOzJO29bqJcazLbtkf\n"
"ZETK0oBx53/ylA4Y6nE9Pa46jW2qhj+KShf1iBg+gAyt3eI+wI2Wmub1WxLLH8D2\n"
"w+kow8QhQOa8dHCkRRw771JxVO5+d+Y/Y+x9B1HgF4q0q9xUlhWLK2TR4ChBFzXe\n"
"47sAHsSqi/pl5JbwYrHPOE/VEBLukmjL8NFCSQIDAQABAoIBADmEyOK2DyRnb6Ti\n"
"2qBJEJb/boj+7wuX36S/ZIrWlIlXiXyj3RvoaiOG/rNpokbURknvlIhKsfIMgLW9\n"
"eBo/k6Xxp1IwMjwVPS1uzbFjFfDoHYUijiQd9iSnf7TDDsnrThqoCp9VQViNTt1n\n"
"xGKNBS7cRddTFbPiVEdVIzfUeZPR2oRrc4maBCRCrQgg8WNknawmc8zhkf2NiPj3\n"
"tWLQHMy1/MgW2W1LM9sgzllEtS5CZUnyGy2HbbhS2tbZ6j9kPzOp0pPxxTTzJmmV\n"
"fi1vkJcVW4+MdXjWmhALcPA4dO7Y2Ljiu6VxIxQORRO1DyiCjAs1AVMQxgPAAY41\n"
"YR4Q2EkCgYEA4zE0oytg97aVaBY9CKi7/PqR+NI/uEvfoQCnT+ddaJgp/qsspuXo\n"
"tJt94p13ANd8O7suqQTVNvbZq1rX10xQjJZ9nvlqQa6iHkN6Epq31XBK3Z+acjIV\n"
"A2rAgKBByjz9/CpKHqnOsrTWU1Y7x416IG4BZt42hHdrxRH98/wiDH8CgYEA2djj\n"
"AjwgK+MwDnshwT1NNgCSP/2ZHatBAykZ5BCs9BJ6MNYqqXVGYoqs5Z5kSkow+Db3\n"
"pipkEieo5w2Rd5zkolTThaVCvRkSe5wRiBpZhaeY+b0UFwavGCb6zU/MmJIMDPiI\n"
"2iRGeCXgQDvIS/icIqzbTtp6dZaoMgG7LdSR7TcCgYBtxGhaLas8A8tL7vKuLFgn\n"
"cij0vyBqOr5hW596y54l2t7vXGTGfm5gVIAN7WaB0ZsEgPuaTet2Eu44DDwcmZKR\n"
"WmR3Wqor8eQCGzfvpTEMvqRtT5+fbPMaI4m+m68ttyo/m28UQZbMYPLscM2RLJnE\n"
"8WFcAiD0/33iST8ZksggoQKBgQDE/7Yhsj+hkHxHzB+1QPtOp2uaBHnvc4uCESwB\n"
"qvbMbN0kxrejsJLqz98UcozdBYSNIiAHmvQN2uGJuCJhGXdEORNjGxRkLoUhVPwh\n"
"qTplfC8BQHQncnrqi21oNw6ctg3BuQsAwaccRZwqWiWCVhrT3J8iCr6NEaWeOySK\n"
"iF1CNwKBgQCRpkkZArlccwS0kMvkK+tQ1rG2xWm7c05G34gP/g6dHFRy0gPNMyvi\n"
"SkiLTJmQIEZSAEiq0FFgcVwM6o556ftvQZuwDp5rHUbwqnHCpMJKpD9aJpStvfPi\n"
"4p9JbYdaGqnq4eoNKemmGnbUof0dR9Zr0lGmcMTwwzBib+4E1d7soA==\n"
"-----END RSA PRIVATE KEY-----\n";
// Certificate signed with key above:
// `openssl req -x509 -key private.pem -out cert.pem -subj "/CN=bar/OU=test/O=example.com/" -new`
static const char *certificate_pem =
"-----BEGIN CERTIFICATE-----\n"
"MIIC5zCCAc+gAwIBAgIJAOq8A/cmpxF5MA0GCSqGSIb3DQEBCwUAMDMxDDAKBgNV\n"
"BAMMA2JhcjENMAsGA1UECwwEdGVzdDEUMBIGA1UECgwLZXhhbXBsZS5jb20wHhcN\n"
"MTcwODAzMTE1MDI2WhcNMTgwODAzMTE1MDI2WjAzMQwwCgYDVQQDDANiYXIxDTAL\n"
"BgNVBAsMBHRlc3QxFDASBgNVBAoMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B\n"
"AQEFAAOCAQ8AMIIBCgKCAQEAwVUwmVbc+ffOy2+RivxBpgleTVN6bUa0q7jNYB+A\n"
"seFQYaYqEGfa+VGdxSGo+8DV1KT9+fNEd5243gXn/tcjtMItKeB+oAQc64s9lIFl\n"
"YuR8bpq1ibr33iW2elnnv9mpecqohdCVwM2McWveoPyb7MwlwVuhqexOzJO29bqJ\n"
"cazLbtkfZETK0oBx53/ylA4Y6nE9Pa46jW2qhj+KShf1iBg+gAyt3eI+wI2Wmub1\n"
"WxLLH8D2w+kow8QhQOa8dHCkRRw771JxVO5+d+Y/Y+x9B1HgF4q0q9xUlhWLK2TR\n"
"4ChBFzXe47sAHsSqi/pl5JbwYrHPOE/VEBLukmjL8NFCSQIDAQABMA0GCSqGSIb3\n"
"DQEBCwUAA4IBAQCamrwdEhNmY2GCQWq6U90Q3XQT6w0HHW/JmtuGeF+BTpVr12gN\n"
"/UvEXTo9geWbGcCTjaMMURTa7mUjVUIttIWEVHZMKqBuvsUM1RcuOEX/vitaJJ8K\n"
"Sw4upjCNa3ZxUXmSA1FBixZgDzFqjEeSiaJjMU0yX5W2p1T4iNYtF3YqzMF5AWSI\n"
"qCO7gP5ezPyg5kDnrO3V7DBgnDiqawq7Pyn9DynKNULX/hc1yls/R+ebb2u8Z+h5\n"
"W4YXbzGZb8qdT27qIZaHD638tL6liLkI6UE4KCXH8X8e3fqdbmqvwrq403nOGmsP\n"
"cbJb2PEXibNEQG234riKxm7x7vNDLL79Jwtc\n"
"-----END CERTIFICATE-----\n";
bool set_component(unsigned char *in_ptr, const BIGNUM *bn, int element_len) {
int real_len = BN_num_bytes(bn);
if(real_len > element_len) {
return false;
}
memset(in_ptr, 0, (size_t)(element_len - real_len));
in_ptr += element_len - real_len;
BN_bn2bin(bn, in_ptr);
return true;
}
bool prepare_rsa_signature(const unsigned char *in, unsigned int in_len, unsigned char *out, unsigned int *out_len, int nid) {
X509_SIG digestInfo;
X509_ALGOR algor;
ASN1_TYPE parameter;
ASN1_OCTET_STRING digest;
unsigned char data[1024];
memcpy(data, in, in_len);
digestInfo.algor = &algor;
digestInfo.algor->algorithm = OBJ_nid2obj(nid);
digestInfo.algor->parameter = &parameter;
digestInfo.algor->parameter->type = V_ASN1_NULL;
digestInfo.algor->parameter->value.ptr = NULL;
digestInfo.digest = &digest;
digestInfo.digest->data = data;
digestInfo.digest->length = (int)in_len;
*out_len = (unsigned int)i2d_X509_SIG(&digestInfo, &out);
return true;
}
START_TEST(test_import_key) {
ykpiv_rc res;
{
unsigned char pp = YKPIV_PINPOLICY_DEFAULT;
unsigned char tp = YKPIV_TOUCHPOLICY_DEFAULT;
EVP_PKEY *private_key = NULL;
BIO *bio = NULL;
RSA *rsa_private_key = NULL;
unsigned char e[4];
unsigned char p[128];
unsigned char q[128];
unsigned char dmp1[128];
unsigned char dmq1[128];
unsigned char iqmp[128];
int element_len = 128;
bio = BIO_new_mem_buf(private_key_pem, strlen(private_key_pem));
private_key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
ck_assert_ptr_nonnull(private_key);
BIO_free(bio);
rsa_private_key = EVP_PKEY_get1_RSA(private_key);
ck_assert_ptr_nonnull(rsa_private_key);
ck_assert(set_component(e, rsa_private_key->e, 3));
ck_assert(set_component(p, rsa_private_key->p, element_len));
ck_assert(set_component(q, rsa_private_key->q, element_len));
ck_assert(set_component(dmp1, rsa_private_key->dmp1, element_len));
ck_assert(set_component(dmq1, rsa_private_key->dmq1, element_len));
ck_assert(set_component(iqmp, rsa_private_key->iqmp, element_len));
// Try wrong algorithm, fail.
res = ykpiv_import_private_key(g_state,
0x9e,
YKPIV_ALGO_RSA1024,
p, element_len,
q, element_len,
dmp1, element_len,
dmq1, element_len,
iqmp, element_len,
NULL, 0,
pp, tp);
ck_assert_int_eq(res, YKPIV_ALGORITHM_ERROR);
// Try right algorithm
res = ykpiv_import_private_key(g_state,
0x9e,
YKPIV_ALGO_RSA2048,
p, element_len,
q, element_len,
dmp1, element_len,
dmq1, element_len,
iqmp, element_len,
NULL, 0,
pp, tp);
ck_assert_int_eq(res, YKPIV_OK);
EVP_PKEY_free(private_key);
}
// Verify certificate
{
BIO *bio = NULL;
X509 *cert = NULL;
RSA *rsa = NULL;
EVP_PKEY *pub_key = NULL;
const EVP_MD *md = EVP_sha256();
EVP_MD_CTX *mdctx;
unsigned char signature[1024];
unsigned char encoded[1024];
unsigned char data[1024];
unsigned char signinput[1024];
unsigned char rand[128];
size_t sig_len = sizeof(signature);
size_t padlen = 256;
unsigned int enc_len;
unsigned int data_len;
bio = BIO_new_mem_buf(certificate_pem, strlen(certificate_pem));
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
ck_assert_ptr_nonnull(cert);
BIO_free(bio);
pub_key = X509_get_pubkey(cert);
ck_assert_ptr_nonnull(pub_key);
rsa = EVP_PKEY_get1_RSA(pub_key);
ck_assert_ptr_nonnull(rsa);
ck_assert_int_gt(RAND_pseudo_bytes(rand, 128), 0);
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, rand, 128);
EVP_DigestFinal_ex(mdctx, data, &data_len);
prepare_rsa_signature(data, data_len, encoded, &enc_len, EVP_MD_type(md));
ck_assert_int_ne(RSA_padding_add_PKCS1_type_1(signinput, padlen, encoded, enc_len), 0);
res = ykpiv_sign_data(g_state, signinput, padlen, signature, &sig_len, YKPIV_ALGO_RSA2048, 0x9e);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_eq(RSA_verify(EVP_MD_type(md), data, data_len, signature, sig_len, rsa), 1);
X509_free(cert);
}
// Use imported key to decrypt a thing. See that it works.
{
BIO *bio = NULL;
X509 *cert = NULL;
EVP_PKEY *pub_key = NULL;
unsigned char secret[32];
unsigned char secret2[32];
unsigned char data[256];
int len;
size_t len2 = sizeof(data);
RSA *rsa = NULL;
bio = BIO_new_mem_buf(certificate_pem, strlen(certificate_pem));
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
ck_assert_ptr_nonnull(cert);
BIO_free(bio);
pub_key = X509_get_pubkey(cert);
ck_assert_ptr_nonnull(pub_key);
rsa = EVP_PKEY_get1_RSA(pub_key);
ck_assert_ptr_nonnull(rsa);
ck_assert_int_gt(RAND_pseudo_bytes(secret, sizeof(secret)), 0);
len = RSA_public_encrypt(sizeof(secret), secret, data, rsa, RSA_PKCS1_PADDING);
ck_assert_int_ge(len, 0);
res = ykpiv_decipher_data(g_state, data, (size_t)len, data, &len2, YKPIV_ALGO_RSA2048, 0x9e);
ck_assert_int_eq(res, YKPIV_OK);
len = RSA_padding_check_PKCS1_type_2(secret2, sizeof(secret2), data + 1, len2 - 1, RSA_size(rsa));
ck_assert_int_eq(len, sizeof(secret));
ck_assert_int_eq(memcmp(secret, secret2, sizeof(secret)), 0);
X509_free(cert);
}
}
END_TEST
START_TEST(test_generate_key) {
ykpiv_rc res;
uint8_t *mod, *exp;
@@ -241,17 +486,78 @@ START_TEST(test_authenticate) {
}
END_TEST
START_TEST(test_reset) {
START_TEST(test_change_pin) {
ykpiv_rc res;
res = ykpiv_verify(g_state, "123456", NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_change_pin(g_state, "123456", 6, "ABCDEF", 6, NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_verify(g_state, "123456", NULL);
ck_assert_int_eq(res, YKPIV_WRONG_PIN);
res = ykpiv_verify(g_state, "ABCDEF", NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_change_pin(g_state, "ABCDEF", 6, "123456", 6, NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_verify(g_state, "ABCDEF", NULL);
ck_assert_int_eq(res, YKPIV_WRONG_PIN);
res = ykpiv_verify(g_state, "123456", NULL);
ck_assert_int_eq(res, YKPIV_OK);
}
END_TEST
START_TEST(test_change_puk) {
ykpiv_rc res;
res = ykpiv_unblock_pin(g_state, "12345678", 8, "123456", 6, NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_change_puk(g_state, "12345678", 8, "ABCDEFGH", 8, NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_unblock_pin(g_state, "12345678", 8, "123456", 6, NULL);
ck_assert_int_eq(res, YKPIV_WRONG_PIN);
res = ykpiv_unblock_pin(g_state, "ABCDEFGH", 8, "123456", 6, NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_change_puk(g_state, "ABCDEFGH", 8, "12345678", 8, NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_unblock_pin(g_state, "ABCDEFGH", 8, "123456", 6, NULL);
ck_assert_int_eq(res, YKPIV_WRONG_PIN);
res = ykpiv_unblock_pin(g_state, "12345678", 8, "123456", 6, NULL);
ck_assert_int_eq(res, YKPIV_OK);
}
END_TEST
static int block_and_reset() {
ykpiv_rc res;
int tries = 100;
int i;
int tries_until_blocked;
tries_until_blocked = 0;
while (tries) {
res = ykpiv_verify(g_state, "AAAAAA", &tries);
if (res == YKPIV_PIN_LOCKED)
break;
ck_assert_int_eq(res, YKPIV_WRONG_PIN);
tries_until_blocked++;
}
// Verify no PIN retries remaining
tries = 100;
res = ykpiv_get_pin_retries(g_state, &tries);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_eq(tries, 0);
tries = 100;
while (tries) {
res = ykpiv_change_puk(g_state, "AAAAAAAA", 8, "AAAAAAAA", 8, &tries);
@@ -261,6 +567,61 @@ START_TEST(test_reset) {
}
res = ykpiv_util_reset(g_state);
ck_assert_int_eq(res, YKPIV_OK);
return tries_until_blocked;
}
START_TEST(test_reset) {
ykpiv_rc res;
int tries = 100;
int tries_until_blocked;
// Block and reset, with default PIN retries
tries_until_blocked = block_and_reset();
ck_assert_int_eq(tries_until_blocked, 3);
// Authenticate and increase PIN retries
test_authenticate(0);
res = ykpiv_verify(g_state, "123456", NULL);
ck_assert_int_eq(res, YKPIV_OK);
res = ykpiv_set_pin_retries(g_state, 8);
ck_assert_int_eq(res, YKPIV_OK);
// Block and reset again, verifying increased PIN retries
tries_until_blocked = block_and_reset();
ck_assert_int_eq(tries_until_blocked, 8);
// Note: defaults back to 3 retries after reset
// Verify default (3) PIN retries remaining
tries = 0;
res = ykpiv_get_pin_retries(g_state, &tries);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_eq(tries, 3);
// Verify still (3) PIN retries remaining
tries = 0;
res = ykpiv_get_pin_retries(g_state, &tries);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_eq(tries, 3);
// Try wrong PIN
res = ykpiv_verify(g_state, "AAAAAA", &tries);
// Verify 2 PIN retries remaining
tries = 0;
res = ykpiv_get_pin_retries(g_state, &tries);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_eq(tries, 2);
// Verify correct PIN
tries = 100;
res = ykpiv_verify(g_state, "123456", &tries);
ck_assert_int_eq(res, YKPIV_OK);
// Verify back to 3 PIN retries remaining
tries = 0;
res = ykpiv_get_pin_retries(g_state, &tries);
ck_assert_int_eq(res, YKPIV_OK);
ck_assert_int_eq(tries, 3);
}
END_TEST
@@ -390,10 +751,13 @@ Suite *test_suite(void) {
tcase_add_test(tc, test_authenticate);
// Test util functionality
tcase_add_test(tc, test_change_pin);
tcase_add_test(tc, test_change_puk);
tcase_add_test(tc, test_devicemodel);
tcase_add_test(tc, test_get_set_cardid);
tcase_add_test(tc, test_list_readers);
tcase_add_test(tc, test_read_write_list_delete_cert);
tcase_add_test(tc, test_import_key);
tcase_add_test(tc, test_generate_key);
// Must be last: tear down and re-test with custom memory allocator
+49 -1
View File
@@ -864,6 +864,7 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
}
strcpy(state->pin, pin);
}
if (tries) *tries = (sw & 0xf);
return YKPIV_OK;
} else if((sw >> 8) == 0x63) {
if (tries) *tries = (sw & 0xf);
@@ -876,6 +877,48 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
}
}
ykpiv_rc ykpiv_get_pin_retries(ykpiv_state *state, int* tries) {
ykpiv_rc res;
ykpiv_rc ykrc;
if (NULL == state || NULL == tries) {
return YKPIV_ARGUMENT_ERROR;
}
res = _ykpiv_select_application(state);
ykrc = ykpiv_verify(state, NULL, tries);
// WRONG_PIN is expected on successful query.
return ykrc == YKPIV_WRONG_PIN ? YKPIV_OK : ykrc;
}
ykpiv_rc ykpiv_set_pin_retries(ykpiv_state *state, const int tries) {
ykpiv_rc res = YKPIV_OK;
unsigned char templ[] = {0, YKPIV_INS_SET_PIN_RETRIES, (unsigned char)tries, YKPIV_RETRIES_DEFAULT};
unsigned char data[0xff];
unsigned long recv_len = sizeof(data);
int sw;
if (0 == tries) {
//zero value means no change in retry count according to minidriver spec
return YKPIV_OK;
}
if (tries > YKPIV_RETRIES_MAX || tries < 1) {
return YKPIV_RANGE_ERROR;
}
res = ykpiv_transfer_data(state, templ, NULL, 0, data, &recv_len, &sw);
if (YKPIV_OK == res) {
if (SW_SUCCESS == sw) {
return YKPIV_OK;
} else if (sw == SW_ERR_AUTH_BLOCKED) {
return YKPIV_AUTHENTICATION_ERROR;
} else if (sw == SW_ERR_SECURITY_STATUS) {
return YKPIV_AUTHENTICATION_ERROR;
}
return YKPIV_GENERIC_ERROR;
}
return res;
}
#define CHREF_ACT_CHANGE_PIN 0
#define CHREF_ACT_UNBLOCK_PIN 1
#define CHREF_ACT_CHANGE_PUK 2
@@ -912,7 +955,7 @@ static ykpiv_rc change_pin_internal(ykpiv_state *state, int action, const char *
return res;
} else if(sw != SW_SUCCESS) {
if((sw >> 8) == 0x63) {
*tries = sw & 0xf;
if (tries) *tries = sw & 0xf;
return YKPIV_WRONG_PIN;
} else if(sw == SW_ERR_AUTH_BLOCKED) {
return YKPIV_PIN_LOCKED;
@@ -1110,9 +1153,14 @@ ykpiv_rc ykpiv_import_private_key(ykpiv_state *state, const unsigned char key, u
return YKPIV_ALGORITHM_ERROR;
for (i = 0; i < n_params; i++) {
size_t remaining;
*in_ptr++ = param_tag + i;
in_ptr += _ykpiv_set_length(in_ptr, elem_len);
padding = elem_len - lens[i];
remaining = (uintptr_t)key_data + sizeof(key_data) - (uintptr_t)in_ptr;
if (padding > remaining) {
return YKPIV_ALGORITHM_ERROR;
}
memset(in_ptr, 0, padding);
in_ptr += padding;
memcpy(in_ptr, params[i], lens[i]);
+5 -4
View File
@@ -92,9 +92,7 @@ extern "C"
ykpiv_rc ykpiv_sign_data(ykpiv_state *state, const unsigned char *sign_in,
size_t in_len, unsigned char *sign_out, size_t *out_len,
unsigned char algorithm, unsigned char key);
ykpiv_rc ykpiv_sign_data2(ykpiv_state *state, const unsigned char *sign_in,
size_t in_len, unsigned char *sign_out, size_t *out_len,
unsigned char algorithm, unsigned char key, int padding); // Allow not to add padding
// TODO (TREV): minidriver has ykpiv_sign_data2
ykpiv_rc ykpiv_decipher_data(ykpiv_state *state, const unsigned char *enc_in,
size_t in_len, unsigned char *enc_out, size_t *out_len,
unsigned char algorithm, unsigned char key);
@@ -123,6 +121,8 @@ extern "C"
const unsigned char *qinv, size_t qinv_len,
const unsigned char *ec_data, unsigned char ec_data_len,
const unsigned char pin_policy, const unsigned char touch_policy);
ykpiv_rc ykpiv_get_pin_retries(ykpiv_state *state, int* tries);
ykpiv_rc ykpiv_set_pin_retries(ykpiv_state *state, const int tries);
#define YKPIV_ALGO_TAG 0x80
#define YKPIV_ALGO_3DES 0x03
@@ -234,7 +234,8 @@ extern "C"
#define YKPIV_IS_EC(a) ((a == YKPIV_ALGO_ECCP256 || a == YKPIV_ALGO_ECCP384))
#define YKPIV_IS_RSA(a) ((a == YKPIV_ALGO_RSA1024 || a == YKPIV_ALGO_RSA2048))
#define YKPIV_RETRIES_DEFAULT 3
#define YKPIV_RETRIES_MAX 0xff
//