add a new function
void sc_mem_clear(void *ptr, size_t len); to clear a memory buffer. If OpenSSL is used this function is a wrapper for OPENSSL_cleanse, otherwise memset is currenlty used. Use this function to clear memory buffers with sensitive content. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2601 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
47d2baf5a3
commit
6abeaf1f1c
|
@ -159,10 +159,9 @@ gpk_init(sc_card_t *card)
|
|||
unsigned long exponent, flags, kg;
|
||||
unsigned char info[13];
|
||||
|
||||
card->drv_data = priv = (struct gpk_private_data *) malloc(sizeof(*priv));
|
||||
card->drv_data = priv = (struct gpk_private_data *) calloc(1, sizeof(*priv));
|
||||
if (card->drv_data == NULL)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
memset(priv, 0, sizeof(*priv));
|
||||
|
||||
/* read/write/update binary expect offset to be the
|
||||
* number of 32 bit words.
|
||||
|
@ -816,9 +815,9 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu,
|
|||
memcpy(crycks1, out, 3);
|
||||
des_cleanse(k1);
|
||||
des_cleanse(k2);
|
||||
memset(in, 0, sizeof(in));
|
||||
memset(out, 0, sizeof(out));
|
||||
memset(block, 0, sizeof(block));
|
||||
sc_mem_clear(in, sizeof(in));
|
||||
sc_mem_clear(out, sizeof(out));
|
||||
sc_mem_clear(block, sizeof(block));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -959,7 +958,7 @@ gpk_set_filekey(const u8 *key, const u8 *challenge,
|
|||
|
||||
des_cleanse(k1);
|
||||
des_cleanse(k2);
|
||||
memset(out, 0, sizeof(out));
|
||||
sc_mem_clear(out, sizeof(out));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -1008,7 +1007,7 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen)
|
|||
priv->key_reference = key_sfi;
|
||||
}
|
||||
|
||||
memset(resp, 0, sizeof(resp));
|
||||
sc_mem_clear(resp, sizeof(resp));
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -1712,7 +1712,7 @@ auth_update_component(sc_card_t *card, struct sc_cardctl_oberthur_updatekey_info
|
|||
}
|
||||
|
||||
rv = sc_transmit_apdu(card, &apdu);
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
sc_mem_clear(sbuf, sizeof(sbuf));
|
||||
SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
|
||||
|
||||
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
@ -1937,7 +1937,7 @@ auth_verify(sc_card_t *card, unsigned int type,
|
|||
apdu.lc = pinfo.pad_length;
|
||||
apdu.sensitive = 1;
|
||||
rv = sc_transmit_apdu(card, &apdu);
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
sc_mem_clear(sbuf, sizeof(sbuf));
|
||||
SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
|
||||
|
||||
if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0)
|
||||
|
@ -1979,7 +1979,7 @@ auth_change_reference_data (sc_card_t *card, unsigned int type,
|
|||
apdu.sensitive = 1;
|
||||
|
||||
rv = sc_transmit_apdu(card, &apdu);
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
sc_mem_clear(sbuf, sizeof(sbuf));
|
||||
SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
|
||||
|
||||
if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0)
|
||||
|
@ -2030,7 +2030,7 @@ auth_reset_retry_counter(sc_card_t *card, unsigned int type,
|
|||
apdu.sensitive = 1;
|
||||
|
||||
rv = sc_transmit_apdu(card, &apdu);
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
sc_mem_clear(sbuf, sizeof(sbuf));
|
||||
SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
|
||||
|
||||
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
@ -2093,7 +2093,7 @@ auth_create_reference_data (sc_card_t *card,
|
|||
apdu.sensitive = 1;
|
||||
|
||||
rv = sc_transmit_apdu(card, &apdu);
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
sc_mem_clear(sbuf, sizeof(sbuf));
|
||||
SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
|
||||
|
||||
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
|
|
@ -223,7 +223,7 @@ static int sc_transceive(sc_card_t *card, sc_apdu_t *apdu)
|
|||
sendsize, rbuf, &recvsize,
|
||||
apdu->control);
|
||||
if (apdu->sensitive)
|
||||
memset(sbuf, 0, sendsize);
|
||||
sc_mem_clear(sbuf, sendsize);
|
||||
SC_TEST_RET(card->ctx, r, "Unable to transmit");
|
||||
|
||||
assert(recvsize >= 2);
|
||||
|
@ -239,7 +239,7 @@ static int sc_transceive(sc_card_t *card, sc_apdu_t *apdu)
|
|||
if (recvsize > 0) {
|
||||
memcpy(apdu->resp, rbuf, data_bytes);
|
||||
if (apdu->sensitive)
|
||||
memset(rbuf, 0, recvsize);
|
||||
sc_mem_clear(rbuf, recvsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ static void sc_card_free(sc_card_t *card)
|
|||
if (card->algorithms != NULL)
|
||||
free(card->algorithms);
|
||||
sc_mutex_free(card->mutex);
|
||||
memset(card, 0, sizeof(*card));
|
||||
sc_mem_clear(card, sizeof(*card));
|
||||
free(card);
|
||||
}
|
||||
|
||||
|
|
|
@ -740,7 +740,7 @@ int sc_release_context(sc_context_t *ctx)
|
|||
scconf_free(ctx->conf);
|
||||
sc_mutex_free(ctx->mutex);
|
||||
free(ctx->app_name);
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
sc_mem_clear(ctx, sizeof(*ctx));
|
||||
free(ctx);
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -896,7 +896,7 @@ static int iso7816_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
|
|||
r = sc_transmit_apdu(card, apdu);
|
||||
|
||||
/* Clear the buffer - it may contain pins */
|
||||
memset(sbuf, 0, sizeof(sbuf));
|
||||
sc_mem_clear(sbuf, sizeof(sbuf));
|
||||
} else {
|
||||
/* Call the reader driver to collect
|
||||
* the PIN and pass on the APDU to the card */
|
||||
|
|
|
@ -890,6 +890,14 @@ int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen);
|
|||
int sc_bin_to_hex(const u8 *, size_t, char *, size_t, int separator);
|
||||
int sc_compare_oid(const struct sc_object_id *oid1, const struct sc_object_id *oid2);
|
||||
|
||||
/**
|
||||
* Clears a memory buffer (note: when OpenSSL is used this is
|
||||
* currently a wrapper for OPENSSL_cleanse() ).
|
||||
* @param ptr pointer to the memory buffer
|
||||
* @param len length of the memory buffer
|
||||
*/
|
||||
void sc_mem_clear(void *ptr, size_t len);
|
||||
|
||||
int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize);
|
||||
int sc_make_cache_dir(sc_context_t *ctx);
|
||||
|
||||
|
|
|
@ -402,7 +402,7 @@ sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key)
|
|||
free(key->u.dsa.priv.data);
|
||||
break;
|
||||
}
|
||||
memset(key, 0, sizeof(key));
|
||||
sc_mem_clear(key, sizeof(key));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -433,7 +433,7 @@ void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
|
|||
break;
|
||||
}
|
||||
free(key->data.value);
|
||||
memset(key, 0, sizeof(*key));
|
||||
sc_mem_clear(key, sizeof(*key));
|
||||
}
|
||||
|
||||
void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *key)
|
||||
|
|
|
@ -326,7 +326,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
|||
tmpin = tmpout;
|
||||
}
|
||||
r = sc_compute_signature(p15card->card, tmpin, inlen, out, outlen);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
sc_mem_clear(buf, sizeof(buf));
|
||||
sc_unlock(p15card->card);
|
||||
SC_TEST_RET(ctx, r, "sc_compute_signature() failed");
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ openct_reader_release(sc_reader_t *reader)
|
|||
if (data) {
|
||||
if (data->h)
|
||||
ct_reader_disconnect(data->h);
|
||||
memset(data, 0, sizeof(*data));
|
||||
sc_mem_clear(data, sizeof(*data));
|
||||
reader->drv_data = NULL;
|
||||
free(data);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#include "asn1.h"
|
||||
#include <stdio.h>
|
||||
|
@ -25,6 +29,10 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/crypto.h> /* for OPENSSL_cleanse */
|
||||
#endif
|
||||
|
||||
#ifdef VERSION
|
||||
const char *sc_version = VERSION;
|
||||
#else
|
||||
|
@ -580,3 +588,12 @@ int _sc_parse_atr(sc_context_t *ctx, sc_slot_info_t *slot)
|
|||
slot->atr_info.hist_bytes = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sc_mem_clear(void *ptr, size_t len)
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
OPENSSL_cleanse(ptr, len);
|
||||
#else
|
||||
memset(ptr, 0, len);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -323,14 +323,14 @@ __sc_ui_read_pin(sc_context_t *ctx, const char *prompt,
|
|||
}
|
||||
|
||||
*out = strdup(pin);
|
||||
memset(pin, 0, len);
|
||||
sc_mem_clear(pin, len);
|
||||
|
||||
if (!(flags & SC_UI_PIN_RETYPE))
|
||||
break;
|
||||
|
||||
pin = getpass("Please type again to verify: ");
|
||||
if (!strcmp(*out, pin)) {
|
||||
memset(pin, 0, len);
|
||||
sc_mem_clear(pin, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -345,7 +345,7 @@ __sc_ui_read_pin(sc_context_t *ctx, const char *prompt,
|
|||
fprintf(stderr,
|
||||
"Sorry, the two pins did not match. "
|
||||
"Please try again.\n");
|
||||
memset(pin, 0, strlen(pin));
|
||||
sc_mem_clear(pin, strlen(pin));
|
||||
|
||||
/* Currently, there's no way out of this dialog.
|
||||
* We should allow the user to bail out after n
|
||||
|
|
|
@ -248,7 +248,7 @@ __pkcs15_release_object(struct pkcs15_any_object *obj)
|
|||
if (--(obj->refcount) != 0)
|
||||
return obj->refcount;
|
||||
|
||||
memset(obj, 0xAA, obj->size);
|
||||
sc_mem_clear(obj, obj->size);
|
||||
free(obj);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -333,7 +333,7 @@ sc_keycache_forget_key(const sc_path_t *path, int type, int ref)
|
|||
*prev = s->next;
|
||||
if (s->named_pin != -1 && s->ref == -1)
|
||||
named_pin[s->named_pin] = NULL;
|
||||
memset(s, 0, sizeof(*s));
|
||||
sc_mem_clear(s, sizeof(*s));
|
||||
free(s);
|
||||
} else {
|
||||
prev = &s->next;
|
||||
|
|
Loading…
Reference in New Issue