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 long exponent, flags, kg;
unsigned char info[13]; 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) if (card->drv_data == NULL)
return SC_ERROR_OUT_OF_MEMORY; return SC_ERROR_OUT_OF_MEMORY;
memset(priv, 0, sizeof(*priv));
/* read/write/update binary expect offset to be the /* read/write/update binary expect offset to be the
* number of 32 bit words. * number of 32 bit words.
@ -816,9 +815,9 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu,
memcpy(crycks1, out, 3); memcpy(crycks1, out, 3);
des_cleanse(k1); des_cleanse(k1);
des_cleanse(k2); des_cleanse(k2);
memset(in, 0, sizeof(in)); sc_mem_clear(in, sizeof(in));
memset(out, 0, sizeof(out)); sc_mem_clear(out, sizeof(out));
memset(block, 0, sizeof(block)); sc_mem_clear(block, sizeof(block));
return 0; return 0;
} }
@ -959,7 +958,7 @@ gpk_set_filekey(const u8 *key, const u8 *challenge,
des_cleanse(k1); des_cleanse(k1);
des_cleanse(k2); des_cleanse(k2);
memset(out, 0, sizeof(out)); sc_mem_clear(out, sizeof(out));
return r; 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; priv->key_reference = key_sfi;
} }
memset(resp, 0, sizeof(resp)); sc_mem_clear(resp, sizeof(resp));
return r; 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); 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"); SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
rv = sc_check_sw(card, apdu.sw1, apdu.sw2); 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.lc = pinfo.pad_length;
apdu.sensitive = 1; apdu.sensitive = 1;
rv = sc_transmit_apdu(card, &apdu); 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"); SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) 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; apdu.sensitive = 1;
rv = sc_transmit_apdu(card, &apdu); 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"); SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) 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; apdu.sensitive = 1;
rv = sc_transmit_apdu(card, &apdu); 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"); SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
rv = sc_check_sw(card, apdu.sw1, apdu.sw2); rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
@ -2093,7 +2093,7 @@ auth_create_reference_data (sc_card_t *card,
apdu.sensitive = 1; apdu.sensitive = 1;
rv = sc_transmit_apdu(card, &apdu); 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"); SC_TEST_RET(card->ctx, rv, "APDU transmit failed");
rv = sc_check_sw(card, apdu.sw1, apdu.sw2); 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, sendsize, rbuf, &recvsize,
apdu->control); apdu->control);
if (apdu->sensitive) if (apdu->sensitive)
memset(sbuf, 0, sendsize); sc_mem_clear(sbuf, sendsize);
SC_TEST_RET(card->ctx, r, "Unable to transmit"); SC_TEST_RET(card->ctx, r, "Unable to transmit");
assert(recvsize >= 2); assert(recvsize >= 2);
@ -239,7 +239,7 @@ static int sc_transceive(sc_card_t *card, sc_apdu_t *apdu)
if (recvsize > 0) { if (recvsize > 0) {
memcpy(apdu->resp, rbuf, data_bytes); memcpy(apdu->resp, rbuf, data_bytes);
if (apdu->sensitive) if (apdu->sensitive)
memset(rbuf, 0, recvsize); sc_mem_clear(rbuf, recvsize);
} }
return 0; return 0;
} }
@ -354,7 +354,7 @@ static void sc_card_free(sc_card_t *card)
if (card->algorithms != NULL) if (card->algorithms != NULL)
free(card->algorithms); free(card->algorithms);
sc_mutex_free(card->mutex); sc_mutex_free(card->mutex);
memset(card, 0, sizeof(*card)); sc_mem_clear(card, sizeof(*card));
free(card); free(card);
} }

View File

@ -740,7 +740,7 @@ int sc_release_context(sc_context_t *ctx)
scconf_free(ctx->conf); scconf_free(ctx->conf);
sc_mutex_free(ctx->mutex); sc_mutex_free(ctx->mutex);
free(ctx->app_name); free(ctx->app_name);
memset(ctx, 0, sizeof(*ctx)); sc_mem_clear(ctx, sizeof(*ctx));
free(ctx); free(ctx);
return SC_SUCCESS; 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); r = sc_transmit_apdu(card, apdu);
/* Clear the buffer - it may contain pins */ /* Clear the buffer - it may contain pins */
memset(sbuf, 0, sizeof(sbuf)); sc_mem_clear(sbuf, sizeof(sbuf));
} else { } else {
/* Call the reader driver to collect /* Call the reader driver to collect
* the PIN and pass on the APDU to the card */ * 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_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); 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_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize);
int sc_make_cache_dir(sc_context_t *ctx); 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); free(key->u.dsa.priv.data);
break; break;
} }
memset(key, 0, sizeof(key)); sc_mem_clear(key, sizeof(key));
} }
void void

View File

@ -433,7 +433,7 @@ void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key)
break; break;
} }
free(key->data.value); 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) 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; tmpin = tmpout;
} }
r = sc_compute_signature(p15card->card, tmpin, inlen, out, outlen); 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_unlock(p15card->card);
SC_TEST_RET(ctx, r, "sc_compute_signature() failed"); 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) {
if (data->h) if (data->h)
ct_reader_disconnect(data->h); ct_reader_disconnect(data->h);
memset(data, 0, sizeof(*data)); sc_mem_clear(data, sizeof(*data));
reader->drv_data = NULL; reader->drv_data = NULL;
free(data); free(data);
} }

View File

@ -18,6 +18,10 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "internal.h" #include "internal.h"
#include "asn1.h" #include "asn1.h"
#include <stdio.h> #include <stdio.h>
@ -25,6 +29,10 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#ifdef HAVE_OPENSSL
#include <openssl/crypto.h> /* for OPENSSL_cleanse */
#endif
#ifdef VERSION #ifdef VERSION
const char *sc_version = VERSION; const char *sc_version = VERSION;
#else #else
@ -580,3 +588,12 @@ int _sc_parse_atr(sc_context_t *ctx, sc_slot_info_t *slot)
slot->atr_info.hist_bytes = p; slot->atr_info.hist_bytes = p;
return 0; 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); *out = strdup(pin);
memset(pin, 0, len); sc_mem_clear(pin, len);
if (!(flags & SC_UI_PIN_RETYPE)) if (!(flags & SC_UI_PIN_RETYPE))
break; break;
pin = getpass("Please type again to verify: "); pin = getpass("Please type again to verify: ");
if (!strcmp(*out, pin)) { if (!strcmp(*out, pin)) {
memset(pin, 0, len); sc_mem_clear(pin, len);
break; break;
} }
@ -345,7 +345,7 @@ __sc_ui_read_pin(sc_context_t *ctx, const char *prompt,
fprintf(stderr, fprintf(stderr,
"Sorry, the two pins did not match. " "Sorry, the two pins did not match. "
"Please try again.\n"); "Please try again.\n");
memset(pin, 0, strlen(pin)); sc_mem_clear(pin, strlen(pin));
/* Currently, there's no way out of this dialog. /* Currently, there's no way out of this dialog.
* We should allow the user to bail out after n * 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) if (--(obj->refcount) != 0)
return obj->refcount; return obj->refcount;
memset(obj, 0xAA, obj->size); sc_mem_clear(obj, obj->size);
free(obj); free(obj);
return 0; return 0;

View File

@ -333,7 +333,7 @@ sc_keycache_forget_key(const sc_path_t *path, int type, int ref)
*prev = s->next; *prev = s->next;
if (s->named_pin != -1 && s->ref == -1) if (s->named_pin != -1 && s->ref == -1)
named_pin[s->named_pin] = NULL; named_pin[s->named_pin] = NULL;
memset(s, 0, sizeof(*s)); sc_mem_clear(s, sizeof(*s));
free(s); free(s);
} else { } else {
prev = &s->next; prev = &s->next;