Cleanup function names. Make PIN cache optional.
This commit is contained in:
+8
-14
@@ -2,8 +2,14 @@
|
|||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <wincrypt.h>
|
#include <wincrypt.h>
|
||||||
|
#include <ntstatus.h>
|
||||||
|
#define WIN32_NO_STATUS
|
||||||
|
#include <bcrypt.h>
|
||||||
#else
|
#else
|
||||||
#include <openssl/des.h>
|
#include <openssl/des.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -274,7 +280,7 @@ des_rc des_encrypt(des_key* key, const unsigned char* in, const size_t inlen, un
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
/* openssl returns void */
|
/* openssl returns void */
|
||||||
DES_ecb3_encrypt(in, out, &(key->ks1), &(key->ks2), &(key->ks3), 1);
|
DES_ecb3_encrypt((const_DES_cblock *)in, (DES_cblock*)out, &(key->ks1), &(key->ks2), &(key->ks3), 1);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -306,7 +312,7 @@ des_rc des_decrypt(des_key* key, const unsigned char* in, const size_t inlen, un
|
|||||||
#else
|
#else
|
||||||
|
|
||||||
/* openssl returns void */
|
/* openssl returns void */
|
||||||
DES_ecb3_encrypt(in, out, &(key->ks1), &(key->ks2), &(key->ks3), 0);
|
DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &(key->ks1), &(key->ks2), &(key->ks3), 0);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -372,7 +378,6 @@ bool yk_des_is_weak_key(const unsigned char *key, const size_t cb_key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
prng_rc prng_generate(unsigned char *buffer, const size_t cb_req) {
|
prng_rc prng_generate(unsigned char *buffer, const size_t cb_req) {
|
||||||
// TREV TODO: ykpiv.c needs to use this
|
|
||||||
prng_rc rc = PRNG_OK;
|
prng_rc rc = PRNG_OK;
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
@@ -399,17 +404,6 @@ prng_rc prng_generate(unsigned char *buffer, const size_t cb_req) {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TREV TODO: what to do with this?
|
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#include <ntstatus.h>
|
|
||||||
#define WIN32_NO_STATUS
|
|
||||||
#include <windows.h>
|
|
||||||
#include <bcrypt.h>
|
|
||||||
#else
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pkcs5_rc pkcs5_pbkdf2_sha1(const unsigned char* password, const size_t cb_password, const unsigned char* salt, const size_t cb_salt, unsigned long long iterations, unsigned char* key, const size_t cb_key) {
|
pkcs5_rc pkcs5_pbkdf2_sha1(const unsigned char* password, const size_t cb_password, const unsigned char* salt, const size_t cb_salt, unsigned long long iterations, unsigned char* key, const size_t cb_key) {
|
||||||
pkcs5_rc rc = PKCS5_OK;
|
pkcs5_rc rc = PKCS5_OK;
|
||||||
|
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ des_rc des_encrypt(des_key* key, const unsigned char* in, const size_t inlen, un
|
|||||||
des_rc des_decrypt(des_key* key, const unsigned char* in, const size_t inlen, unsigned char* out, size_t* outlen);
|
des_rc des_decrypt(des_key* key, const unsigned char* in, const size_t inlen, unsigned char* out, size_t* outlen);
|
||||||
bool yk_des_is_weak_key(const unsigned char *key, const size_t cb_key);
|
bool yk_des_is_weak_key(const unsigned char *key, const size_t cb_key);
|
||||||
pkcs5_rc pkcs5_pbkdf2_sha1(const unsigned char* password, const size_t cb_password, const unsigned char* salt, const size_t cb_salt, unsigned long long iterations, unsigned char* key, const size_t cb_key);
|
pkcs5_rc pkcs5_pbkdf2_sha1(const unsigned char* password, const size_t cb_password, const unsigned char* salt, const size_t cb_salt, unsigned long long iterations, unsigned char* key, const size_t cb_key);
|
||||||
|
prng_rc prng_generate(unsigned char *buffer, const size_t cb_req);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
+38
-29
@@ -156,7 +156,7 @@ ykpiv_rc ykpiv_init_with_allocator(ykpiv_state **state, int verbose, const ykpiv
|
|||||||
s->pin = NULL;
|
s->pin = NULL;
|
||||||
s->allocator = *allocator;
|
s->allocator = *allocator;
|
||||||
s->verbose = verbose;
|
s->verbose = verbose;
|
||||||
s->context = SCARD_E_INVALID_HANDLE; // TREV TODO -1 on Windows
|
s->context = SCARD_E_INVALID_HANDLE;
|
||||||
*state = s;
|
*state = s;
|
||||||
return YKPIV_OK;
|
return YKPIV_OK;
|
||||||
}
|
}
|
||||||
@@ -167,8 +167,7 @@ ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) {
|
|||||||
|
|
||||||
ykpiv_rc ykpiv_done(ykpiv_state *state) {
|
ykpiv_rc ykpiv_done(ykpiv_state *state) {
|
||||||
ykpiv_disconnect(state);
|
ykpiv_disconnect(state);
|
||||||
if (state->pin)
|
_cache_pin(state, NULL, 0);
|
||||||
_ykpiv_free(state, state->pin);
|
|
||||||
_ykpiv_free(state, state);
|
_ykpiv_free(state, state);
|
||||||
return YKPIV_OK;
|
return YKPIV_OK;
|
||||||
}
|
}
|
||||||
@@ -234,7 +233,7 @@ ykpiv_rc _ykpiv_ensure_application_selected(ykpiv_state *state) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ykpiv_rc _connect_internal(ykpiv_state *state, uintptr_t context, uintptr_t card) {
|
static ykpiv_rc _connect_internal(ykpiv_state *state, uint64_t context, uint64_t card) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
|
|
||||||
if (NULL == state) {
|
if (NULL == state) {
|
||||||
@@ -272,7 +271,12 @@ static ykpiv_rc _connect_internal(ykpiv_state *state, uintptr_t context, uintptr
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_connect_with_card(ykpiv_state *state, uint64_t context, uint64_t card) {
|
||||||
|
return _connect_internal(state, context, card);
|
||||||
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) {
|
||||||
|
// TREV TODO: use _connect_internal
|
||||||
unsigned long active_protocol;
|
unsigned long active_protocol;
|
||||||
char reader_buf[2048];
|
char reader_buf[2048];
|
||||||
size_t num_readers = sizeof(reader_buf);
|
size_t num_readers = sizeof(reader_buf);
|
||||||
@@ -330,7 +334,6 @@ static ykpiv_rc reconnect(ykpiv_state *state) {
|
|||||||
long rc;
|
long rc;
|
||||||
ykpiv_rc res;
|
ykpiv_rc res;
|
||||||
int tries;
|
int tries;
|
||||||
|
|
||||||
if(state->verbose) {
|
if(state->verbose) {
|
||||||
fprintf(stderr, "trying to reconnect to current reader.\n");
|
fprintf(stderr, "trying to reconnect to current reader.\n");
|
||||||
}
|
}
|
||||||
@@ -884,6 +887,29 @@ ykpiv_rc ykpiv_get_version(ykpiv_state *state, char *version, size_t len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ykpiv_rc _cache_pin(ykpiv_state *state, const char *pin, size_t len) {
|
||||||
|
#ifdef DISABLE_PIN_CACHE
|
||||||
|
// Some embedded applications of this library may not want to keep the PIN
|
||||||
|
// data in RAM for security reasons.
|
||||||
|
return YKPIV_OK;
|
||||||
|
#else
|
||||||
|
if (!state)
|
||||||
|
return YKPIV_ARGUMENT_ERROR;
|
||||||
|
if (state->pin) {
|
||||||
|
_ykpiv_free(state, state->pin);
|
||||||
|
state->pin = NULL;
|
||||||
|
}
|
||||||
|
if (pin && len > 0) {
|
||||||
|
state->pin = _ykpiv_alloc(state, len * sizeof(char) + 1);
|
||||||
|
if (state->pin == NULL) {
|
||||||
|
return YKPIV_MEMORY_ERROR;
|
||||||
|
}
|
||||||
|
memcpy(state->pin, pin, len + 1);
|
||||||
|
}
|
||||||
|
return YKPIV_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
|
ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
|
||||||
// TREV TODO: pin len?
|
// TREV TODO: pin len?
|
||||||
APDU apdu;
|
APDU apdu;
|
||||||
@@ -914,14 +940,9 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) {
|
|||||||
if((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
if((res = _send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) {
|
||||||
return res;
|
return res;
|
||||||
} else if(sw == SW_SUCCESS) {
|
} else if(sw == SW_SUCCESS) {
|
||||||
if (pin) {
|
// Intentionally ignore errors. If the PIN fails to save, it will only
|
||||||
_ykpiv_free(state, state->pin);
|
// be a problem if a reconnect is attempted. Failure deferred until then.
|
||||||
state->pin = _ykpiv_alloc(state, len * sizeof(char) + 1);
|
_cache_pin(state, pin, len + 1);
|
||||||
if (state->pin == NULL) {
|
|
||||||
return YKPIV_MEMORY_ERROR;
|
|
||||||
}
|
|
||||||
memcpy(state->pin, pin, len + 1);
|
|
||||||
}
|
|
||||||
if (tries) *tries = (sw & 0xf);
|
if (tries) *tries = (sw & 0xf);
|
||||||
return YKPIV_OK;
|
return YKPIV_OK;
|
||||||
} else if((sw >> 8) == 0x63) {
|
} else if((sw >> 8) == 0x63) {
|
||||||
@@ -1026,12 +1047,9 @@ static ykpiv_rc change_pin_internal(ykpiv_state *state, int action, const char *
|
|||||||
ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) {
|
||||||
ykpiv_rc res = change_pin_internal(state, CHREF_ACT_CHANGE_PIN, current_pin, current_pin_len, new_pin, new_pin_len, tries);
|
ykpiv_rc res = change_pin_internal(state, CHREF_ACT_CHANGE_PIN, current_pin, current_pin_len, new_pin, new_pin_len, tries);
|
||||||
if (res == YKPIV_OK && new_pin != NULL) {
|
if (res == YKPIV_OK && new_pin != NULL) {
|
||||||
_ykpiv_free(state, state->pin);
|
// Intentionally ignore errors. If the PIN fails to save, it will only
|
||||||
state->pin = _ykpiv_alloc(state, new_pin_len * sizeof(char) + 1);
|
// be a problem if a reconnect is attempted. Failure deferred until then.
|
||||||
if (state->pin == NULL) {
|
_cache_pin(state, new_pin, new_pin_len + 1);
|
||||||
return YKPIV_MEMORY_ERROR;
|
|
||||||
}
|
|
||||||
memcpy(state->pin, new_pin, new_pin_len + 1);
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1252,16 +1270,11 @@ ykpiv_rc ykpiv_done2(ykpiv_state *state, bool disconnect) {
|
|||||||
// TODO: why is this needed? windows unit tests pass without it
|
// TODO: why is this needed? windows unit tests pass without it
|
||||||
if (disconnect)
|
if (disconnect)
|
||||||
ykpiv_disconnect(state);
|
ykpiv_disconnect(state);
|
||||||
if (state->pin)
|
_cache_pin(state, NULL, 0);
|
||||||
_ykpiv_free(state, state->pin);
|
|
||||||
_ykpiv_free(state, state);
|
_ykpiv_free(state, state);
|
||||||
return YKPIV_OK;
|
return YKPIV_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_init2(ykpiv_state **state, int verbose, const ykpiv_allocator *allocator) {
|
|
||||||
return ykpiv_init_with_allocator(state, verbose, allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
ykpiv_rc ykpiv_verify_select(ykpiv_state *state, const uint8_t *pin, const size_t pin_len, int *tries, bool force_select) {
|
ykpiv_rc ykpiv_verify_select(ykpiv_state *state, const uint8_t *pin, const size_t pin_len, int *tries, bool force_select) {
|
||||||
ykpiv_rc res = YKPIV_OK;
|
ykpiv_rc res = YKPIV_OK;
|
||||||
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) goto Cleanup;
|
if (YKPIV_OK != (res = _ykpiv_begin_transaction(state))) goto Cleanup;
|
||||||
@@ -1277,7 +1290,3 @@ Cleanup:
|
|||||||
_ykpiv_end_transaction(state);
|
_ykpiv_end_transaction(state);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
ykpiv_rc ykpiv_connect2(ykpiv_state *state, uintptr_t context, uintptr_t card) {
|
|
||||||
return _connect_internal(state, context, card);
|
|
||||||
}
|
|
||||||
|
|||||||
+2
-2
@@ -452,11 +452,11 @@ extern "C"
|
|||||||
ykpiv_rc ykpiv_util_block_puk(ykpiv_state *state);
|
ykpiv_rc ykpiv_util_block_puk(ykpiv_state *state);
|
||||||
|
|
||||||
|
|
||||||
|
ykpiv_rc ykpiv_connect_with_card(ykpiv_state *state, uint64_t context, uint64_t card);
|
||||||
|
|
||||||
// TREV TODO: remove
|
// TREV TODO: remove
|
||||||
ykpiv_rc ykpiv_done2(ykpiv_state *state, bool disconnect);
|
ykpiv_rc ykpiv_done2(ykpiv_state *state, bool disconnect);
|
||||||
ykpiv_rc ykpiv_init2(ykpiv_state **state, int verbose, const ykpiv_allocator *allocator);
|
|
||||||
ykpiv_rc ykpiv_verify_select(ykpiv_state *state, const uint8_t *pin, const size_t pin_len, int *tries, bool force_select);
|
ykpiv_rc ykpiv_verify_select(ykpiv_state *state, const uint8_t *pin, const size_t pin_len, int *tries, bool force_select);
|
||||||
ykpiv_rc ykpiv_connect2(ykpiv_state *state, uintptr_t context, uintptr_t card);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user