Skip to content

Commit

Permalink
PIV: get authentication key via fread_to_eof
Browse files Browse the repository at this point in the history
Note that this removes the use of `sc_right_trim()`. There is no need to
assume the keyfile contains non printable characters if it is hex
encoded.
  • Loading branch information
frankmorgner committed Dec 2, 2021
1 parent 99325e6 commit c9ade70
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 84 deletions.
80 changes: 20 additions & 60 deletions src/libopensc/card-piv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1225,13 +1225,9 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l
{

int r;
size_t fsize;
FILE *f = NULL;
size_t keylen, expected_keylen;
char * keyfilename = NULL;
size_t expected_keylen;
size_t keylen, readlen;
u8 * keybuf = NULL;
u8 * tkey = NULL;

SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

Expand All @@ -1251,79 +1247,43 @@ static int piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *l
goto err;
}

f = fopen(keyfilename, "rb");
if (!f) {
r = fread_to_eof(keyfilename, &keybuf, &keylen);
if (r != 1) {
sc_log(card->ctx, " Unable to load key from file\n");
r = SC_ERROR_FILE_NOT_FOUND;
goto err;
}

if (0 > fseek(f, 0L, SEEK_END))
r = SC_ERROR_INTERNAL;
fsize = ftell(f);
if (0 > (long) fsize)
r = SC_ERROR_INTERNAL;
if (0 > fseek(f, 0L, SEEK_SET))
r = SC_ERROR_INTERNAL;
if(r) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read %s\n", keyfilename);
goto err;
}

keybuf = malloc(fsize+1); /* if not binary, need null to make it a string */
if (!keybuf) {
sc_log(card->ctx, " Unable to allocate key memory");
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
keybuf[fsize] = 0x00; /* in case it is text need null */

if ((readlen = fread(keybuf, 1, fsize, f)) != fsize) {
sc_log(card->ctx, " Unable to read key\n");
r = SC_ERROR_WRONG_LENGTH;
goto err;
}
keybuf[readlen] = '\0';

tkey = malloc(expected_keylen);
if (!tkey) {
sc_log(card->ctx, " Unable to allocate key memory");
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}

if (fsize == expected_keylen) { /* it must be binary */
memcpy(tkey, keybuf, expected_keylen);
} else {
if (keylen != expected_keylen) {
/* if the key-length is larger then binary length, we assume hex encoded */
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Treating key as hex-encoded!\n");
sc_right_trim(keybuf, fsize);
keylen = expected_keylen;
r = sc_hex_to_bin((char *)keybuf, tkey, &keylen);
if (keylen !=expected_keylen || r != 0 ) {

char *hexkey = malloc(keylen + 1);
if (!hexkey) {
sc_log(card->ctx, " Unable to allocate key memory");
r = SC_ERROR_OUT_OF_MEMORY;
goto err;
}
memcpy(hexkey, keybuf, keylen);
hexkey[keylen] = '\0'; /* NUL termination is needed to avoid OOB read */

r = sc_hex_to_bin(hexkey, keybuf, &keylen);
free(hexkey);
if (r != 0 || keylen != expected_keylen) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error formatting key\n");
if (r == 0)
r = SC_ERROR_INCOMPATIBLE_KEY;
goto err;
}
}
*key = tkey;
tkey = NULL;
*len = expected_keylen;
*key = keybuf;
*len = keylen;
r = SC_SUCCESS;

err:
if (f)
fclose(f);
if (keybuf) {
free(keybuf);
}
if (tkey) {
free(tkey);
}
free(keybuf);

LOG_FUNC_RETURN(card->ctx, r);
return r;
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/libopensc/opensc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1497,7 +1497,7 @@ int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen);
* writes to out: [0x33, 0x66, 0x3A, 0x30, 0x31, 0x00] which reads as "3f:01"
*/
int sc_bin_to_hex(const u8 *, size_t, char *, size_t, int separator);
size_t sc_right_trim(u8 *buf, size_t len);

scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char *name2, int priority);

/**
Expand Down
23 changes: 0 additions & 23 deletions src/libopensc/sc.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,29 +158,6 @@ int sc_bin_to_hex(const u8 *in, size_t in_len, char *out, size_t out_len,
return SC_SUCCESS;
}

/*
* Right trim all non-printable characters
*/
size_t sc_right_trim(u8 *buf, size_t len) {

size_t i;

if (!buf)
return 0;

if (len > 0) {
for(i = len-1; i > 0; i--) {
if(!isprint(buf[i])) {
buf[i] = '\0';
len--;
continue;
}
break;
}
}
return len;
}

u8 *ulong2bebytes(u8 *buf, unsigned long x)
{
if (buf != NULL) {
Expand Down

0 comments on commit c9ade70

Please sign in to comment.