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:
nils 2005-09-17 10:44:45 +00:00
parent 47d2baf5a3
commit 6abeaf1f1c
14 changed files with 50 additions and 26 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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");

View File

@ -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);
}

View File

@ -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
}

View File

@ -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

View File

@ -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;

View File

@ -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;