Example #1
0
static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data * data)
{
	int r;
	sc_apdu_t apdu;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x02, 0x00);
	apdu.cla = 0x84;
	apdu.data = (u8*)&data->data.ef;
	apdu.lc = apdu.datalen = sizeof(data->data.ef);

	r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
Example #2
0
/*
 * Create a DF
 */
static int
setcos_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
{
	struct sc_context *ctx = p15card->card->ctx;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

        r = sc_pkcs15init_fixup_file(profile, p15card, df);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS file ACL fixup failed");

	r = sc_create_file(p15card->card, df);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "SetCOS create file failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #3
0
/*
 * Create a new PIN inside a DF
 */
static int
cflex_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df,
		sc_pkcs15_object_t *pin_obj,
		const u8 *pin, size_t pin_len,
		const u8 *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;
	struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin;
	sc_file_t	*dummies[2];
	int		ndummies, pin_type, puk_type, r;
	sc_file_t       *file;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;

	/* If the profile doesn't specify a reference for this PIN, guess */
	if (pin_attrs->flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
		pin_type = SC_PKCS15INIT_SO_PIN;
		puk_type = SC_PKCS15INIT_SO_PUK;
		if (pin_attrs->reference != 2)
			return SC_ERROR_INVALID_ARGUMENTS;
	} else {
		pin_type = SC_PKCS15INIT_USER_PIN;
		puk_type = SC_PKCS15INIT_USER_PUK;
		if (pin_attrs->reference != 1)
			return SC_ERROR_INVALID_ARGUMENTS;
	}

	/* Get file definition from the profile */
	if (sc_profile_get_file(profile, (pin_attrs->reference == 1)? "CHV1" : "CHV2", &file) < 0
			&& sc_profile_get_file(profile, "CHV", &file) < 0)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_FILE_NOT_FOUND, "profile does not define pin file ACLs");

	ndummies = cflex_create_dummy_chvs(profile, p15card, file, SC_AC_OP_CREATE, dummies);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, ndummies, "Unable to create dummy CHV file");

	r = cflex_create_pin_file(profile, p15card, &df->path, pin_attrs->reference,
			pin, pin_len, sc_profile_get_pin_retries(profile, pin_type),
			puk, puk_len, sc_profile_get_pin_retries(profile, puk_type),
			NULL, 0);

	cflex_delete_dummy_chvs(profile, p15card, ndummies, dummies);
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Example #4
0
CK_RV session_get_operation(struct sc_pkcs11_session * session, int type, sc_pkcs11_operation_t ** operation)
{
	sc_pkcs11_operation_t *op;

	SC_FUNC_CALLED(context, SC_LOG_DEBUG_NORMAL);

	if (type < 0 || type >= SC_PKCS11_OPERATION_MAX)
		return CKR_ARGUMENTS_BAD;

	if (!(op = session->operation[type]))
		return CKR_OPERATION_NOT_INITIALIZED;

	if (operation)
		*operation = op;

	return CKR_OK;
}
Example #5
0
int
sc_card_ctl(sc_card_t *card, unsigned long cmd, void *args)
{
	int r = SC_ERROR_NOT_SUPPORTED;

	assert(card != NULL);
	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL);
	if (card->ops->card_ctl != NULL)
		r = card->ops->card_ctl(card, cmd, args);

	/* suppress "not supported" error messages */
	if (r == SC_ERROR_NOT_SUPPORTED) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "card_ctl(%lu) not supported", cmd);
		return r;
	}
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Example #6
0
/*
 * Create a faux pin file
 */
static int
cflex_create_empty_pin_file(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
			sc_path_t *path, int ref, sc_file_t **file_ret)
{
	int		r;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_NORMAL);
	*file_ret = NULL;
	r = cflex_create_pin_file(profile, p15card, path, ref,
			dummy_pin_value, sizeof(dummy_pin_value), 8,
			NULL, 0, 0,
			file_ret, 1);
	if (r == SC_ERROR_FILE_ALREADY_EXISTS)
		SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, r);

	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Example #7
0
File: ctx.c Project: AktivCo/OpenSC
int sc_release_context(sc_context_t *ctx)
{
	unsigned int i;

	if (ctx == NULL) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	while (list_size(&ctx->readers)) {
		sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0);
		_sc_delete_reader(ctx, rdr);
	}

	if (ctx->reader_driver->ops->finish != NULL)
		ctx->reader_driver->ops->finish(ctx);

	for (i = 0; ctx->card_drivers[i]; i++) {
		struct sc_card_driver *drv = ctx->card_drivers[i];

		if (drv->atr_map)
			_sc_free_atr(ctx, drv);
		if (drv->dll)
			sc_dlclose(drv->dll);
	}
	if (ctx->preferred_language != NULL)
		free(ctx->preferred_language);
	if (ctx->mutex != NULL) {
		int r = sc_mutex_destroy(ctx, ctx->mutex);
		if (r != SC_SUCCESS) {
			sc_log(ctx, "unable to destroy mutex");
			return r;
		}
	}
	if (ctx->conf != NULL)
		scconf_free(ctx->conf);
	if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr))
		fclose(ctx->debug_file);
	if (ctx->debug_filename != NULL)
		free(ctx->debug_filename);
	if (ctx->app_name != NULL)
		free(ctx->app_name);
	list_destroy(&ctx->readers);
	sc_mem_clear(ctx, sizeof(*ctx));
	free(ctx);
	return SC_SUCCESS;
}
Example #8
0
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card,
				  sc_pkcs15emu_opt_t *opts)
{
	sc_card_t   *card = p15card->card;
	sc_context_t    *ctx = card->ctx;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
		return sc_pkcs15emu_piv_init(p15card);
	else {
		int r = piv_detect_card(p15card);
		if (r)
			return SC_ERROR_WRONG_CARD;
		return sc_pkcs15emu_piv_init(p15card);
	}
}
Example #9
0
static int sc_hsm_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		unsigned op, struct sc_pkcs15_object *object)
{
	struct sc_context *ctx = p15card->card->ctx;
	int rv = SC_ERROR_NOT_SUPPORTED;

	SC_FUNC_CALLED(ctx, 1);
	switch(op)   {
	case SC_AC_OP_ERASE:
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; erase object('%s',type:%X)", object->label, object->type);
		switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
		case SC_PKCS15_TYPE_PRKEY:
			rv = sc_hsm_delete_ef(p15card, PRKD_PREFIX, ((struct sc_pkcs15_prkey_info *)object->data)->key_reference);
			break;
		case SC_PKCS15_TYPE_PUBKEY:
			rv = SC_SUCCESS;
			break;
		case SC_PKCS15_TYPE_CERT:
			rv = sc_hsm_emu_delete_cd(profile, p15card, object);
			break;
		case SC_PKCS15_TYPE_DATA_OBJECT:
			rv = sc_hsm_delete_ef(p15card, DCOD_PREFIX, ((struct sc_pkcs15_data_info *)object->data)->path.value[1]);
			break;
		}
		break;
	case SC_AC_OP_UPDATE:
	case SC_AC_OP_CREATE:
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Update DF; create object('%s',type:%X)", object->label, object->type);
		switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
		case SC_PKCS15_TYPE_PUBKEY:
			rv = SC_SUCCESS;
			break;
		case SC_PKCS15_TYPE_PRKEY:
			rv = sc_hsm_emu_update_prkd(profile, p15card, object);
			break;
		case SC_PKCS15_TYPE_CERT:
			rv = sc_hsm_emu_update_cd(profile, p15card, object);
			break;
		case SC_PKCS15_TYPE_DATA_OBJECT:
			rv = sc_hsm_emu_update_dcod(profile, p15card, object);
			break;
		}
		break;
	}
	SC_FUNC_RETURN(ctx, 1, rv);
}
int card_sync_card_to_virtual_fs_certificate_file_callback( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs )
{
  int r = SC_SUCCESS;
  unsigned char *card_data = NULL;
  unsigned char *uncompressed_data = NULL;
  size_t card_data_length = 0;
  size_t uncompressed_data_length = 0;
  sc_path_t *path=NULL;

  SC_FUNC_CALLED(card->ctx, 1);

  if(!card || !virtual_file)
    return SC_ERROR_INVALID_ARGUMENTS;

  path=NULL;
  path = map_path_to_path_find(DRVDATA(card)->virtual_fs_to_card_path_map, &virtual_file->path);
  if(!path) {
    r = SC_ERROR_OBJECT_NOT_FOUND;
    goto end;
  }

  /* get file */
  r = card_helper_read_certificate_file(card, path, &card_data, &card_data_length);
  if (r!=SC_SUCCESS)
    goto end;
  if (card_data_length>0) {     
    r = file_uncompress_data(card, card_data, card_data_length, &uncompressed_data, &uncompressed_data_length); 
    if(r < 0)
      goto end;
    
    r = virtual_file_data_update(virtual_file, 0, uncompressed_data, uncompressed_data_length);
    if(r != SC_SUCCESS)
      goto end;
  }
 end:
  if(card_data) {
    free(card_data);
    card_data = NULL;
  }

  if(uncompressed_data) {
    free(uncompressed_data);
    uncompressed_data = NULL;
  }
  SC_FUNC_RETURN(card->ctx, 1, r);
}
int card_sync_virtual_fs_to_card_filter_pukey( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs, sc_pkcs15_object_t *obj )
{
  int r = SC_SUCCESS;
  struct sc_pkcs15_pubkey_info *pukey = NULL;
  sc_pkcs15_der_t *der = NULL;
  sc_path_t *path = NULL;
  sc_pkcs15_id_t *ckaid = NULL;

  SC_FUNC_CALLED(card->ctx, 1);

  if(!card || !virtual_file)
    return SC_ERROR_INVALID_ARGUMENTS;
  
  pukey = (struct sc_pkcs15_pubkey_info *) obj->data;
  if(pukey) {
    sc_pkcs15_free_object_content(obj);

    /* try to find an old der if present */
    der = map_id_to_der_find(DRVDATA(card)->pukdf_card_ckaid_to_card_der_map, &pukey->id);
    if(der) {
      sc_der_copy(&obj->content, der);
    }

    path = map_path_to_path_find(DRVDATA(card)->virtual_fs_to_card_path_map, &pukey->path);
    if(path) {
      /* replace path data */
      memcpy(&pukey->path, path, sizeof(sc_path_t));
    }

    ckaid = map_opensc_id_to_id_find(DRVDATA(card)->virtual_fs_to_card_ckaid_map, &pukey->id);
    if(ckaid) {
      /* replace ckaid */
      memcpy(&pukey->id, ckaid, sizeof(struct sc_pkcs15_id));
    }
        /* add manual flags */
    pukey->native = 0x01;
    pukey->access_flags |= SC_PKCS15_PRKEY_ACCESS_LOCAL;
    pukey->access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
    pukey->key_reference = pukey->path.value[pukey->path.len-1];
  } else {
    sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Pointer to pukey info was empty");
  }

  SC_FUNC_RETURN(card->ctx, 1, r);
}
Example #12
0
static int 
myeid_init_card(sc_profile_t *profile, 
			   sc_pkcs15_card_t *p15card)
{
	struct sc_path path;
	struct sc_file *file = NULL;
	int r;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);

	sc_format_path("3F00", &path);
	r = sc_select_file(p15card->card, &path, &file);

	if (file)
		sc_file_free(file);
		
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);	
}
Example #13
0
static int entersafe_create_file(sc_card_t *card, sc_file_t *file)
{	
	 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	 
	 if (file->type == SC_FILE_TYPE_WORKING_EF) {
		  sc_entersafe_create_data data;
		  memset(&data,0,sizeof(data));

		  data.data.ef.file_id[0] = (file->id>>8)&0xFF;	
		  data.data.ef.file_id[1] = file->id&0xFF;	
		  data.data.ef.size[0] = (file->size>>8)&0xFF;
		  data.data.ef.size[1] = file->size&0xFF;
		  memset(data.data.ef.ac,ENTERSAFE_AC_ALWAYS,sizeof(data.data.ef.ac));
		  data.data.ef.ac[0] = process_acl_entry(file,SC_AC_OP_READ,ENTERSAFE_AC_ALWAYS);
		  data.data.ef.ac[1] = process_acl_entry(file,SC_AC_OP_UPDATE,ENTERSAFE_AC_ALWAYS);

		  return entersafe_create_ef(card, &data);
	 } else
int 
sc_pkcs15emu_oberthur_init_ex(struct sc_pkcs15_card * p15card,
				   struct sc_pkcs15emu_opt * opts)
{
	int rv; 
	
	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)   {
		rv = sc_pkcs15emu_oberthur_init(p15card);
	}
	else {
		rv = oberthur_detect_card(p15card);
		if (!rv)
			rv = sc_pkcs15emu_oberthur_init(p15card);
	}
	
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, rv);
}
Example #15
0
/* Add a PIN to the PIN cache related to the card. Some operations can trigger re-authentication later. */
void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *pin_obj,
	const u8 *pin, size_t pinlen)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
	struct sc_pkcs15_object *obj = NULL;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);

	if (!p15card->opts.use_pin_cache)   {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN caching not enabled");
		return;
	}

	/* If the PIN protects an object with user consent, don't cache it */

	obj = p15card->obj_list;
	while (obj != NULL) {
		/* Compare 'sc_pkcs15_object.auth_id' with 'sc_pkcs15_pin_info.auth_id'.
		 * In accordance with PKCS#15 "6.1.8 CommonObjectAttributes" and
		 * "6.1.16 CommonAuthenticationObjectAttributes" with the exception that
		 * "CommonObjectAttributes.accessControlRules" are not taken into account. */

		if (sc_pkcs15_compare_id(&obj->auth_id, &auth_info->auth_id)) {
			/* Caching is refused, if the protected object requires user consent */
			if (obj->user_consent > 0) {
				sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "caching refused (user consent)");
				return;
			}
		}

		obj = obj->next;
	}

	r = sc_pkcs15_allocate_object_content(pin_obj, pin, pinlen);
	if (r != SC_SUCCESS)   {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to allocate object content");
		return;
	} 

	pin_obj->usage_counter = 0;
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN(%s) cached", pin_obj->label);
}
static int pcsc_unlock(sc_reader_t *reader, sc_slot_info_t *slot)
{
	long rv;
	struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
	struct pcsc_private_data *priv = GET_PRIV_DATA(reader);

	SC_FUNC_CALLED(reader->ctx, 3);
	assert(pslot != NULL);

	rv = priv->gpriv->SCardEndTransaction(pslot->pcsc_card, priv->gpriv->transaction_reset ?
                           SCARD_RESET_CARD : SCARD_LEAVE_CARD);

	pslot->locked = 0;
	if (rv != SCARD_S_SUCCESS) {
		PCSC_ERROR(reader->ctx, "SCardEndTransaction failed", rv);
		return pcsc_ret_to_error(rv);
	}
	return SC_SUCCESS;
}
Example #17
0
/*
 * Erase the card via rm
 */
static int cflex_erase_card(struct sc_profile *profile, sc_pkcs15_card_t *p15card)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_file_t  *df = profile->df_info->file, *dir, *userpinfile = NULL;
	int             r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
	/* Delete EF(DIR). This may not be very nice
         * against other applications that use this file, but
         * extremely useful for testing :)
         * Note we need to delete if before the DF because we create
         * it *after* the DF.
         * */
        if (sc_profile_get_file(profile, "DIR", &dir) >= 0) {
                r = cflex_delete_file(profile, p15card, dir);
                sc_file_free(dir);
                if (r < 0 && r != SC_ERROR_FILE_NOT_FOUND)
                        goto out;
        }

	r=cflex_delete_file(profile, p15card, df);

	/* If the user pin file isn't in a sub-DF of the pkcs15 DF, delete it */
	if (sc_profile_get_file(profile, "pinfile-1", &userpinfile) >= 0 &&
	    userpinfile->path.len <= profile->df_info->file->path.len + 2 &&
	    memcmp(userpinfile->path.value, profile->df_info->file->path.value,
	           userpinfile->path.len) != 0) {
           	r = cflex_delete_file(profile, p15card, userpinfile);
		sc_file_free(userpinfile);
		userpinfile=NULL;
	}


out:	/* Forget all cached keys, the pin files on card are all gone. */
	if (userpinfile)
		sc_file_free(userpinfile);

        sc_free_apps(p15card->card);
        if (r == SC_ERROR_FILE_NOT_FOUND)
                r=0;

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Example #18
0
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid,
		sc_pkcs15emu_opt_t *opts)
{
	sc_card_t *card = p15card->card;
	SC_FUNC_CALLED(card->ctx, 1);

	/* Check card */
	if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
		if (! (
				(card->type > SC_CARD_TYPE_ITACNS_BASE &&
				card->type < SC_CARD_TYPE_ITACNS_BASE + 1000)
			|| card->type == SC_CARD_TYPE_CARDOS_CIE_V1)
			)
			return SC_ERROR_WRONG_CARD;
	}

	/* Init card */
	return itacns_init(p15card);
}
/*
 * Create a DF
 */
static int myeid_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df)
{
	int	r=0;
	struct sc_file *file;

	SC_FUNC_CALLED(card->ctx, 1);
	if (!profile || !card || !df)
		return SC_ERROR_INVALID_ARGUMENTS;

	sc_debug(card->ctx, "id (%x)\n",df->id);

	if(df->id == 0x5015)
	{
	  sc_debug(card->ctx, "only Select (%x)\n",df->id);
	   r = sc_select_file(card, &df->path, NULL);
	}

	SC_FUNC_RETURN(card->ctx, 1, r);
}
Example #20
0
/* Validate the PIN code associated with an object */
int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_object_t *pin_obj;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);

	if (!p15card->opts.use_pin_cache)
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;

	if (obj->user_consent)
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;

	if (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;

	r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj);
	if (r != SC_SUCCESS) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Could not find pin object for auth_id %s", sc_pkcs15_print_id(&obj->auth_id));
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	
	if (pin_obj->usage_counter >= p15card->opts.pin_cache_counter) {
		sc_pkcs15_free_object_content(pin_obj);
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}

	if (!pin_obj->content.value || !pin_obj->content.len)
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;

	pin_obj->usage_counter++;
	r = sc_pkcs15_verify_pin(p15card, pin_obj, pin_obj->content.value, pin_obj->content.len);
	if (r != SC_SUCCESS) {
		/* Ensure that wrong PIN isn't used again */ 
		sc_pkcs15_free_object_content(pin_obj);

		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Verify PIN error %i", r);
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
}
Example #21
0
static int itacns_add_prkey(sc_pkcs15_card_t *p15card,
                const sc_pkcs15_id_t *id,
                const char *label,
                int type, unsigned int modulus_length, int usage,
		const sc_path_t *path, int ref,
                const sc_pkcs15_id_t *auth_id, int obj_flags)
{
	sc_pkcs15_prkey_info_t info;
	sc_pkcs15_object_t obj;

	SC_FUNC_CALLED(p15card->card->ctx, 1);

	if(type != SC_PKCS15_TYPE_PRKEY_RSA) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
			"Cannot add a private key of a type other than RSA");
		return 1;
	}

	memset(&info, 0, sizeof(info));
	memset(&obj,  0, sizeof(obj));

	info.id			= *id;
	info.modulus_length	= modulus_length;
	info.usage		= usage;
	info.native		= 1;
	info.key_reference	= ref;
	info.access_flags	=
			SC_PKCS15_PRKEY_ACCESS_SENSITIVE
			| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
			| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
			| SC_PKCS15_PRKEY_ACCESS_LOCAL;

	if (path)
	        info.path = *path;

	obj.flags = obj_flags;
	strlcpy(obj.label, label, sizeof(obj.label));
	if (auth_id != NULL)
		obj.auth_id = *auth_id;

	return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info);
}
Example #22
0
static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file,
                               const u8 *buf, size_t len)
{
    int        r;
    size_t     tlen;
    const u8   *tag = NULL, *p = buf;
    const char *type;
    struct sc_context *ctx = card->ctx;

    SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

    r = iso_ops->process_fci(card, file, buf, len);
    if (r < 0)
        return r;
    sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
             "processing GemSAFE V1 specific FCI information\n");


    tag = sc_asn1_find_tag(ctx, p, len, 0x82, &tlen);
    if (!tag) {
        /* no FDB => we have a DF */
        type = "DF";
        file->type = SC_FILE_TYPE_DF;
    } else {
        type = "EF";
        file->type = SC_FILE_TYPE_WORKING_EF;
    }

    sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "file type: %s\n", type);

    tag = sc_asn1_find_tag(ctx, p, len, 0x8C, &tlen);
    if (tag) {
        r = gemsafe_setacl(card, file, tag, strcmp(type, "DF") ? 0 : 1);
        if (r < 0) {
            sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to set ACL\n");
            return SC_ERROR_INTERNAL;
        }
    } else
        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "error: AM and SC bytes missing\n");

    return SC_SUCCESS;
}
static int openct_reader_unlock(sc_reader_t *reader, sc_slot_info_t *slot)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	struct slot_data *slot_data = (struct slot_data *) slot->drv_data;
	int rc;

	SC_FUNC_CALLED(reader->ctx, 1);

	/* Not connected */
	if (data->h == NULL)
		return 0;

	rc = ct_card_unlock(data->h, slot->id, slot_data->excl_lock);

	/* We couldn't care less */
	if (rc == IFD_ERROR_NOT_CONNECTED)
		return 0;

	return openct_error(reader, rc);
}
Example #24
0
static int 
myeid_init_card(sc_profile_t *profile, 
			   sc_pkcs15_card_t *p15card)
{
	struct sc_path path;
	struct sc_file *file = NULL;
	int r;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);

	sc_format_path("3F00", &path);
	r = sc_select_file(p15card->card, &path, &file);

	p15card->tokeninfo->flags = SC_PKCS15_TOKEN_PRN_GENERATION | SC_PKCS15_TOKEN_EID_COMPLIANT;

	if (file)
		sc_file_free(file);
		
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);	
}
static int 
sc_oberthur_parse_publicinfo (struct sc_pkcs15_card *p15card, 
		unsigned char *buff, size_t len, int postpone_allowed)
{
	struct sc_context *ctx = p15card->card->ctx;
	size_t ii;
	int rv;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	for (ii=0; ii<len; ii+=5)   {
		unsigned int file_id, size;
		
		if(*(buff+ii) != 0xFF)
			continue;
		
		file_id = 0x100 * *(buff+ii + 1) + *(buff+ii + 2);
		size = 0x100 * *(buff+ii + 3) + *(buff+ii + 4);
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "add public object(file-id:%04X,size:%X)", file_id, size);

		switch (*(buff+ii + 1))   {
		case BASE_ID_PUB_RSA :
			rv = sc_pkcs15emu_oberthur_add_pubkey(p15card, file_id, size);
			SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse public key info");
			break;
		case BASE_ID_CERT :
			rv = sc_pkcs15emu_oberthur_add_cert(p15card, file_id);
			SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse certificate info");
			break;
		case BASE_ID_PUB_DES :
			break;
		case BASE_ID_PUB_DATA :
			rv = sc_pkcs15emu_oberthur_add_data(p15card, file_id, size, 0);
			SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot parse data info");
			break;
		default:
			SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Public object parse error");
		}
	}

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}
Example #26
0
/*
 * Create a new DF
 * This will usually be the application DF
 */
static int
gpk_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
{
	struct sc_file	*pinfile;
	int		r, locked;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	if (sc_card_ctl(p15card->card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0
			&& locked) {
		sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
			"This card is already personalized, unable to "
			"create PKCS#15 structure.");
		return SC_ERROR_NOT_SUPPORTED;
	}

	/* Create the DF. */
	r = sc_pkcs15init_create_file(profile, p15card, df);
	if (r < 0)
		return r;

	/* See if there's a file called "pinfile" that resides within
	 * this DF. If so, create it */
	if (sc_profile_get_file(profile, "pinfile", &pinfile) >= 0) {
		/* Build the pin file's path from the DF path + its
		 * file ID */
		pinfile->path = df->path;
		sc_append_file_id(&pinfile->path, pinfile->id);

		r = gpk_init_pinfile(profile, p15card, pinfile);
		sc_file_free(pinfile);
		if (r < 0)
			return r;

		/* TODO: What for it was used ?
		for (i = 0; i < GPK_MAX_PINS; i++)
		*	sc_keycache_put_pin(&df->path, GPK_PIN_SCOPE|i, (const u8 *) "        ");
		*/
	}

	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #27
0
int sc_disconnect_card(sc_card_t *card)
{
	sc_context_t *ctx;
	ctx = card->ctx;
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	assert(card->lock_count == 0);
	if (card->ops->finish) {
		int r = card->ops->finish(card);
		if (r)
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "card driver finish() failed: %s",
			      sc_strerror(r));
	}
	if (card->reader->ops->disconnect) {
		int r = card->reader->ops->disconnect(card->reader);
		if (r)
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "disconnect() failed: %s",
			      sc_strerror(r));
	}
	sc_card_free(card);
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, 0);
}
/*
 * Called when releasing a reader.  release() has to
 * deallocate the private data.  Other fields will be
 * freed by OpenSC.
 */
static int openct_reader_release(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int i;

	SC_FUNC_CALLED(reader->ctx, 1);
	if (data) {
		if (data->h)
			ct_reader_disconnect(data->h);
		sc_mem_clear(data, sizeof(*data));
		reader->drv_data = NULL;
		free(data);
	}

	for (i = 0; i < SC_MAX_SLOTS; i++) {
		if(reader->slot[i].drv_data)
			free(reader->slot[i].drv_data);
	}
	
	return SC_NO_ERROR;
}
Example #29
0
static int itacns_add_pin(sc_pkcs15_card_t *p15card,
	char *label,
	int id,
	int auth_id,
	int reference,
	sc_path_t *path,
	int flags)
{
	struct sc_pkcs15_auth_info pin_info;
	struct sc_pkcs15_object pin_obj;

	SC_FUNC_CALLED(p15card->card->ctx, 1);

	memset(&pin_info, 0, sizeof(pin_info));
	pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
	pin_info.auth_id.len = 1;
	pin_info.auth_id.value[0] = id;
	pin_info.attrs.pin.reference = reference;
	pin_info.attrs.pin.flags = flags;
	pin_info.attrs.pin.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
	pin_info.attrs.pin.min_length = 5;
	pin_info.attrs.pin.stored_length = 8;
	pin_info.attrs.pin.max_length = 8;
	pin_info.attrs.pin.pad_char = 0xff;
	pin_info.logged_in = SC_PIN_STATE_UNKNOWN;
	if(path)
        pin_info.path = *path;

	memset(&pin_obj, 0, sizeof(pin_obj));
	strlcpy(pin_obj.label, label, sizeof(pin_obj.label));
	pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE |
		(auth_id ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0);
	if (auth_id) {
		pin_obj.auth_id.len = 1;
		pin_obj.auth_id.value[0] = auth_id;
	} else
		pin_obj.auth_id.len = 0;

	return sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
}
Example #30
0
static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data * data)
{
	int r;
	sc_apdu_t apdu;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	memcpy(data->data.df.init_key, init_key, sizeof(init_key));

	sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0xE0,0x00,0x00);
	apdu.cla=0x84;
	apdu.data=(u8*)&data->data.df;
	apdu.datalen=apdu.lc=sizeof(data->data.df);

	switch(card->type)
	{
	case SC_CARD_TYPE_ENTERSAFE_3K:
	{
		 r = entersafe_transmit_apdu(card, &apdu,trans_code_3k,sizeof(trans_code_3k),0,1);
	}break;
	case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C:
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C:
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0:	
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1:
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1:
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1:
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1:
	case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1:	
	{
		 r = entersafe_transmit_apdu(card, &apdu,trans_code_ftcos_pk_01c,sizeof(trans_code_ftcos_pk_01c),0,1);
	}break;
	default:
	{
		 r = SC_ERROR_INTERNAL;
	}break;
	}

	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	return sc_check_sw(card, apdu.sw1, apdu.sw2);
}