コード例 #1
0
int card_sync_card_to_virtual_fs_data_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;
  size_t card_data_length = 0;
  sc_path_t *path=NULL;

  SC_FUNC_CALLED(card->ctx, 1);

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

  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_file(card, path, &card_data, &card_data_length);
  if (r!=SC_SUCCESS)
    goto end;
  if (card_data_length>0) {
    r = virtual_file_data_update(virtual_file, 0, card_data, card_data_length);
    if(r != SC_SUCCESS)
      goto end;
  }
 end:
  if(card_data) {
    free(card_data);
    card_data = NULL;
  }

  SC_FUNC_RETURN(card->ctx, 1, r);
}
コード例 #2
0
ファイル: card-mcrd.c プロジェクト: Hubitronic/OpenSC
/* Return the DF_info for the current path.  If does not yet exist,
   create it.  Returns NULL on error. */
static struct df_info_s *get_df_info(sc_card_t * card)
{
	sc_context_t *ctx = card->ctx;
	struct mcrd_priv_data *priv = DRVDATA(card);
	struct df_info_s *dfi;

	assert(!priv->is_ef);

	if (!priv->curpathlen) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no current path to find the df_info\n");
		return NULL;
	}

	for (dfi = priv->df_infos; dfi; dfi = dfi->next) {
		if (dfi->pathlen == priv->curpathlen
		    && !memcmp(dfi->path, priv->curpath,
			       dfi->pathlen * sizeof *dfi->path))
			return dfi;
	}
	/* Not found, create it. */
	dfi = calloc(1, sizeof *dfi);
	if (!dfi) {
		sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "out of memory while allocating df_info\n");
		return NULL;
	}
	dfi->pathlen = priv->curpathlen;
	memcpy(dfi->path, priv->curpath, dfi->pathlen * sizeof *dfi->path);
	dfi->next = priv->df_infos;
	priv->df_infos = dfi;
	return dfi;
}
コード例 #3
0
ファイル: card-esteid2018.c プロジェクト: OpenSC/OpenSC
static int esteid_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num) {
	struct esteid_priv_data *priv;
	struct sc_apdu apdu;

	// XXX: could be const
	unsigned char cse_crt_aut[] = {0x80, 0x04, 0xFF, 0x20, 0x08, 0x00, 0x84, 0x01, 0x81};
	unsigned char cse_crt_sig[] = {0x80, 0x04, 0xFF, 0x15, 0x08, 0x00, 0x84, 0x01, 0x9F};
	unsigned char cse_crt_dec[] = {0x80, 0x04, 0xFF, 0x30, 0x04, 0x00, 0x84, 0x01, 0x81};

	LOG_FUNC_CALLED(card->ctx);

	if (card == NULL || env == NULL || env->key_ref_len != 1)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);

	sc_log(card->ctx, "algo: %d operation: %d keyref: %d", env->algorithm, env->operation, env->key_ref[0]);

	if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 1) {
		sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xA4, cse_crt_aut, sizeof(cse_crt_aut), NULL, 0);
	} else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_SIGN && env->key_ref[0] == 2) {
		sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB6, cse_crt_sig, sizeof(cse_crt_sig), NULL, 0);
	} else if (env->algorithm == SC_ALGORITHM_EC && env->operation == SC_SEC_OPERATION_DERIVE && env->key_ref[0] == 1) {
		sc_format_apdu_ex(card, &apdu, 0x22, 0x41, 0xB8, cse_crt_dec, sizeof(cse_crt_dec), NULL, 0);
	} else {
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
	}
	SC_TRANSMIT_TEST_RET(card, apdu, "SET SECURITY ENV failed");

	priv = DRVDATA(card);
	priv->sec_env = *env;
	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
コード例 #4
0
ファイル: card-itacns.c プロジェクト: pawmas/opensc
static int itacns_match_cns_card(sc_card_t *card, unsigned int i)
{
	unsigned char *atr = card->atr.value;
	sc_context_t *ctx;
	ctx = card->ctx;


	itacns_atr_match(i, 0x01); /* H7 */
	i += 2; /* H8, H9 */
	itacns_atr_match(i, 'C'); /* H10 */
	itacns_atr_match(i, 'N'); /* H11 */
	itacns_atr_match(i, 'S'); /* H12 */

	/* H13 */
	/* Version byte: h.l, h in the high nibble, l in the low nibble. */
	if(card->driver) {
		DRVDATA(card)->cns_version = atr[i];
	}
	/* Warn if the version is not 1.0. */
	if(atr[i] != 0x10) {
		char version[8];
		_snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f);
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CNS card version %s; no official specifications "
			"are published. Proceeding anyway.\n", version);
	}
コード例 #5
0
ファイル: card-esteid2018.c プロジェクト: OpenSC/OpenSC
static int esteid_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, u8 *out, size_t outlen) {
	struct esteid_priv_data *priv = DRVDATA(card);
	struct sc_security_env *env = NULL;
	struct sc_apdu apdu;
	u8 sbuf[SIGNATURE_PAYLOAD_SIZE];
	int le = MIN(SC_MAX_APDU_RESP_SIZE, MIN(SIGNATURE_PAYLOAD_SIZE * 2, outlen));

	LOG_FUNC_CALLED(card->ctx);
	if (data == NULL || out == NULL || datalen > SIGNATURE_PAYLOAD_SIZE)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);

	env = &priv->sec_env;
	// left-pad if necessary
	memcpy(&sbuf[SIGNATURE_PAYLOAD_SIZE - datalen], data, MIN(datalen, SIGNATURE_PAYLOAD_SIZE));
	memset(sbuf, 0x00, SIGNATURE_PAYLOAD_SIZE - datalen);
	datalen = SIGNATURE_PAYLOAD_SIZE;

	switch (env->key_ref[0]) {
	case 1: /* authentication key */
		sc_format_apdu_ex(card, &apdu, 0x88, 0, 0, sbuf, datalen, out, le);
		break;
	default:
		sc_format_apdu_ex(card, &apdu, 0x2A, 0x9E, 0x9A, sbuf, datalen, out, le);
	}

	SC_TRANSMIT_TEST_RET(card, apdu, "PSO CDS/INTERNAL AUTHENTICATE failed");

	LOG_FUNC_RETURN(card->ctx, (int)apdu.resplen);
}
コード例 #6
0
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);
}
コード例 #7
0
ファイル: card-isoApplet.c プロジェクト: BradPID/OpenSC
static int
isoApplet_finish(sc_card_t *card)
{
	struct isoApplet_drv_data *drvdata=DRVDATA(card);

	LOG_FUNC_CALLED(card->ctx);
	if (drvdata)
	{
		free(drvdata);
		card->drv_data=NULL;
	}
	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
コード例 #8
0
ファイル: card-belpic.c プロジェクト: securez/opendnie
static int belpic_pin_cmd_usage(sc_card_t *card, struct sc_pin_cmd_data *data,
				int *tries_left, int pin_usage)
{
#ifdef BELPIC_PIN_PAD
	sc_apdu_t apdu;
	int r;

	struct belpic_priv_data *priv = DRVDATA(card);
	int lang = belpic_calculate_lang(card);
	if (card->reader->capabilities & SC_READER_CAP_PIN_PAD && priv->scr_init != NULL) {
		LONG r;
		SCR_Card scr_card = {
			priv->pcsc_card,
			lang_codes[lang],
			{NULL, 0}
			,
			NULL
		};

		scr_app_belpic.longString = app_id_longstr[lang];

		switch (data->cmd) {
		case SC_PIN_CMD_VERIFY:
			r = belpic_pp_verify(card, &scr_card,
					     priv, data->pin_reference, pin_usage, tries_left);
			break;
		case SC_PIN_CMD_CHANGE:
			r = belpic_pp_change(card, &scr_card,
					     priv, data->pin_reference, tries_left);
			break;
		default:
			r = SC_ERROR_NOT_SUPPORTED;
		}

		if (r == SC_ERROR_AUTH_METHOD_BLOCKED && (priv->options & PP_MSG_PIN_BLOCKED))
			scgui_ask_message(app_msg[lang], " ", pin_blocked_msgs[lang],
					  btn_msg_close[lang], NULL, card->reader->name);
		return r;
	}
#endif	/* BELPIC_PIN_PAD */

	data->pin1.encoding = data->pin2.encoding = BELPIC_PIN_ENCODING;
	data->pin1.pad_char = data->pin2.pad_char = BELPIC_PAD_CHAR;
	data->pin1.min_length = data->pin2.min_length = BELPIC_MIN_USER_PIN_LEN;
	data->pin1.max_length = data->pin2.max_length = BELPIC_MAX_USER_PIN_LEN;
	data->apdu = NULL;

	return iso_ops->pin_cmd(card, data, tries_left);
}
コード例 #9
0
ファイル: card-mcrd.c プロジェクト: Hubitronic/OpenSC
static int mcrd_finish(sc_card_t * card)
{
	struct mcrd_priv_data *priv;

	if (card == NULL)
		return 0;
	priv = DRVDATA(card);
	while (priv->df_infos) {
		struct df_info_s *tmp = priv->df_infos->next;
		clear_special_files(priv->df_infos);
		priv->df_infos = tmp;
	}
	free(priv);
	return 0;
}
コード例 #10
0
ファイル: card-isoApplet.c プロジェクト: BradPID/OpenSC
static int
isoApplet_compute_signature(struct sc_card *card,
                            const u8 *data, size_t datalen,
                            u8 *out, size_t outlen)
{
	struct sc_context *ctx = card->ctx;
	struct isoApplet_drv_data *drvdata = DRVDATA(card);
	int r;

	LOG_FUNC_CALLED(ctx);

	r = iso_ops->compute_signature(card, data, datalen, out, outlen);
	if(r < 0)
	{
		LOG_FUNC_RETURN(ctx, r);
	}

	/* If ECDSA was used, the ASN.1 sequence of integers R,S returned by the
	 * card needs to be converted to the raw concatenation of R,S for PKCS#11. */
	if(drvdata->sec_env_alg_ref == ISOAPPLET_ALG_REF_ECDSA)
	{
		u8* p = NULL;
		size_t len = (drvdata->sec_env_ec_field_length + 7) / 8 * 2;

		if (len > outlen)
			LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL);

		p = calloc(1,len);
		if (!p)
			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);

		r = sc_asn1_sig_value_sequence_to_rs(ctx, out, r, p, len);
		if (!r)   {
			memcpy(out, p, len);
			r = len;
		}

		free(p);
	}
	LOG_FUNC_RETURN(ctx, r);
}
コード例 #11
0
int card_sync_card_to_virtual_fs_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_path_t def_path;
  /* This flag identifies the FIRMA public key */
  u8 flag_id[1] = "F";

  SC_FUNC_CALLED(card->ctx, 1);

  memset(&def_path, 0, sizeof(struct sc_path));

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

  pukey = (struct sc_pkcs15_pubkey_info *) obj->data;
  if(pukey) {
    /* set asn1 to map */
    r = map_id_to_der_set_item(DRVDATA(card)->pukdf_card_ckaid_to_card_der_map, &pukey->id, &obj->content);
    if(r != SC_SUCCESS)
      goto end;


    if(pukey->path.len > 0) {

      if(pukey->path.len == 4) {
        sc_format_path("3F00", &def_path);
   	r = sc_append_path(&def_path, &pukey->path);

	if(r!=SC_SUCCESS)
	  goto end;

        memcpy(pukey->path.value, def_path.value, def_path.len);
        pukey->path.len = 6;

      } else {
        memcpy(&def_path, &pukey->path, sizeof(pukey->path));      
      }

      /* append empty file */
      r = virtual_fs_append_new_virtual_file(virtual_fs, 
					     &def_path, 
					     obj->content.value, 
					     obj->content.len, 
					     obj->content.len, 
					     1, 
					     virtual_file_sync_state_unknown, 
					     NULL, 
					     virtual_file_sync_state_unknown, 
					     NULL);
      if(r != SC_SUCCESS)
	goto end;

      /* correct length in PKCS#15 */
      pukey->path.count = 0;

      /* Fixed key usage for FIRMA public key */
      if(memcmp(pukey->id.value, flag_id, 1)==0)
	pukey->usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;

    } else {
      sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Path length is 0");
    }
  } else {
    sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Pointer to pukey info was empty");
  }

 end:
  SC_FUNC_RETURN(card->ctx, 1, r);
}
コード例 #12
0
ファイル: card-belpic.c プロジェクト: securez/opendnie
/* Called by belpic_set_security_env() when a NonRep signature will be done,
 * or by belpic-compute_signature the first fime an auth signature is done
 * and the allow_sso is true
 */
static int belpic_askpin_verify(sc_card_t *card, int pin_usage)
{
	struct sc_pin_cmd_data data;
	sc_apdu_t apdu;
	u8 pin_data[BELPIC_MAX_USER_PIN_LEN + 1];
	int pin_len;
	int tries_left;
	int r;
	struct belpic_priv_data *priv = DRVDATA(card);
	int lang = belpic_calculate_lang(card);
	char *enter_pin_msg = (pin_usage == SCR_USAGE_AUTH ?
			       enter_pin_msg_auth[lang] : enter_pin_msg_sign[lang]);
	scgui_param_t icon = (pin_usage == SCR_USAGE_AUTH ? SCGUI_NO_ICON : SCGUI_SIGN_ICON);

	data.pin1.encoding = BELPIC_PIN_ENCODING;
	data.pin1.pad_char = BELPIC_PAD_CHAR;
	data.pin1.min_length = BELPIC_MIN_USER_PIN_LEN;
	data.pin1.max_length = BELPIC_MAX_USER_PIN_LEN;

	data.cmd = SC_PIN_CMD_VERIFY;
	data.flags = 0;
	data.pin_type = SC_AC_CHV;
	data.pin_reference = 1;


#ifdef BELPIC_PIN_PAD
	/* In case of a pinpad reader */
	if (card->reader->capabilities & SC_READER_CAP_PIN_PAD && priv->scr_init != NULL) {
		data.pin1.data = NULL;
		data.pin1.len = 0;

		return belpic_pin_cmd_usage(card, &data, &tries_left, pin_usage);
	}
#endif

	pin_len = BELPIC_MAX_USER_PIN_LEN + 1;
	r = scgui_enterpin(app_msg[lang], enter_pin_msg, pin_data, &pin_len,
			   btn_msg_ok[lang], btn_msg_cancel[lang], wrong_pin_len_msgs[lang], icon);
	if (r == SCGUI_CANCEL)
		return SC_ERROR_KEYPAD_CANCELLED;
	if (r != SCGUI_OK)
		return SC_ERROR_INTERNAL;

	data.pin1.data = pin_data;
	data.pin1.len = pin_len;
	r = belpic_pin_cmd_usage(card, &data, &tries_left, pin_usage);

	/* card->ctx->allow_sso = true: we do PIN mgmnt ourselves */
	while (r == SC_ERROR_PIN_CODE_INCORRECT && SSO_OK(card->ctx)) {
		int r1;
		char msg[200];

		sprintf(msg, wrong_pin_msgs[lang], tries_left);
		r1 = scgui_ask_message(app_msg[lang], pin_usg_auth[lang], msg,
				       btn_msg_retry[lang], btn_msg_cancel[lang],
				       card->reader->name);
		if (r1 == SCGUI_CANCEL)
			return r;
		else if (r1 != SCGUI_OK) {
			sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "scgui_ask_message returned %d\n", r1);
			return SC_ERROR_INTERNAL;
		}

		pin_len = BELPIC_MAX_USER_PIN_LEN + 1;
		r = scgui_enterpin(app_msg[lang], enter_pin_msg, pin_data, &pin_len,
				   btn_msg_ok[lang], btn_msg_cancel[lang], wrong_pin_len_msgs[lang],
				   icon);
		if (r == SCGUI_CANCEL)
			return SC_ERROR_KEYPAD_CANCELLED;
		if (r != SCGUI_OK)
			return SC_ERROR_INTERNAL;

		data.pin1.data = pin_data;
		data.pin1.len = pin_len;
		r = belpic_pin_cmd_usage(card, &data, &tries_left, pin_usage);
		if (tries_left == 0)
			r = SC_ERROR_AUTH_METHOD_BLOCKED;
	}

	if (r == SC_ERROR_AUTH_METHOD_BLOCKED && SSO_OK(card->ctx))
		scgui_ask_message(app_msg[lang], " ", pin_blocked_msgs[lang],
				  btn_msg_close[lang], NULL, card->reader->name);

	return r;
}
コード例 #13
0
ファイル: card-belpic.c プロジェクト: securez/opendnie
static int belpic_calculate_lang(sc_card_t *card)
{
	struct belpic_priv_data *priv = DRVDATA(card);
	int lang = priv->lang;
	return lang;
}
コード例 #14
0
int card_sync_virtual_fs_to_card_certificate_file_callback( sc_card_t *card, struct _virtual_file_t *virtual_file, virtual_fs_t *virtual_fs )
{
  int r = SC_SUCCESS;
  unsigned char *compressed_data = NULL;
  size_t compressed_data_length = 0;
  struct _virtual_file_t *certificate_virtual_file=NULL;
  sc_pkcs15_id_t *card_ckaid=NULL;
  sc_path_t *cert_path=NULL;

  SC_FUNC_CALLED(card->ctx, 1);

  if(!card || !virtual_file)
    return SC_ERROR_INVALID_ARGUMENTS;
  
  r = file_compress_data(card, virtual_file->data, virtual_file->data_size, &compressed_data, &compressed_data_length); 
  if(r!=SC_SUCCESS)
    goto cert_vfs2c_end;

  /* create certificate file into card */
  r = card_helper_create_cert_file(card, virtual_file, compressed_data_length, &certificate_virtual_file);
  if(r!=SC_SUCCESS)
    goto cert_vfs2c_end;

  /* set file data to card */
  r = card_helper_update_file(card, &certificate_virtual_file->path, compressed_data, compressed_data_length);
  if(r!=SC_SUCCESS)
    goto cert_vfs2c_end;

  /* add path_to_path */
  r = map_path_to_path_set_item(DRVDATA(card)->virtual_fs_to_card_path_map, &virtual_file->path, &certificate_virtual_file->path);
  if(r != SC_SUCCESS)
    goto cert_vfs2c_end;

  /* get ckaid from certificate (computeing a sha1 form public key modulus) */
  card_ckaid = calloc(1, sizeof(struct sc_pkcs15_id));
  if (!card_ckaid) {
    r = SC_ERROR_OUT_OF_MEMORY;
    goto cert_vfs2c_end;
  }
  r = get_ckaid_from_certificate( card, virtual_file->data, virtual_file->data_size, card_ckaid );
  if(r!=SC_SUCCESS)
    goto cert_vfs2c_end;

  cert_path = calloc(1, sizeof(struct sc_path));
  if(!cert_path) {
    r = SC_ERROR_OUT_OF_MEMORY;
    goto cert_vfs2c_end;
  }
  memcpy(cert_path, &certificate_virtual_file->path, sizeof(struct sc_path));
  r = map_path_to_id_set_item(DRVDATA(card)->card_path_to_card_ckaid_map, cert_path, card_ckaid);
  if(r!=SC_SUCCESS)
    goto cert_vfs2c_end;

  /* ownership regards to vfs */
  certificate_virtual_file=NULL;
  card_ckaid=NULL;
  cert_path=NULL;
    
 cert_vfs2c_end:
  if(compressed_data) {
    free(compressed_data);
    compressed_data = NULL;
  }
  if(certificate_virtual_file) {
    free(certificate_virtual_file);
    certificate_virtual_file=NULL;
  }
  if(card_ckaid) {
    free(card_ckaid);
    card_ckaid=NULL;
  }
  if(cert_path) {
    free(cert_path);
    cert_path=NULL;
  }
  SC_FUNC_RETURN(card->ctx, 1, r);
}
コード例 #15
0
ファイル: card-belpic.c プロジェクト: securez/opendnie
static int belpic_finish(sc_card_t *card)
{
	free(DRVDATA(card));
	return 0;
}
コード例 #16
0
int card_sync_virtual_fs_to_card_filter_cert( 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_cert_info *cert = NULL;
  sc_pkcs15_der_t *der = NULL;
  sc_path_t *path = NULL;
  sc_pkcs15_id_t *ckaid = NULL;
  struct _virtual_file_t *tmp_vf=NULL;
  unsigned char *compressed_data = NULL;
  size_t compressed_data_length = 0;

  SC_FUNC_CALLED(card->ctx, 1);

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

  cert = (struct sc_pkcs15_cert_info *) obj->data;
  if(cert) {
    sc_pkcs15_free_object_content(obj);

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

    path = map_path_to_path_find(DRVDATA(card)->virtual_fs_to_card_path_map, &cert->path);
    if(path) {
      /* replace path data */
      memcpy(&cert->path, path, sizeof(sc_path_t));
      
      tmp_vf=virtual_fs_find_by_path(virtual_fs, &cert->path);
      if(!tmp_vf) {
	r = SC_ERROR_INVALID_DATA;
	goto end;
      }
      
      r = file_compress_data(card, tmp_vf->data, tmp_vf->data_size, &compressed_data, &compressed_data_length); 
      if(r!=SC_SUCCESS)
	goto end;

      /* certificate file has an info header */
      cert->path.count = compressed_data_length+8;
    }

    ckaid = map_opensc_id_to_id_find(DRVDATA(card)->virtual_fs_to_card_ckaid_map, &cert->id);
    if(ckaid) {
      /* replace ckaid */
      memcpy(&cert->id, ckaid, sizeof(struct sc_pkcs15_id));
    } else {
      ckaid = map_path_to_id_find(DRVDATA(card)->card_path_to_card_ckaid_map, &cert->path);
      if (ckaid) {
	/* replace ckaid */
	memcpy(&cert->id, ckaid, sizeof(struct sc_pkcs15_id));
      }
    }
  }

 end:
  if(compressed_data) {
    free(compressed_data);
    compressed_data = NULL;
  }
  SC_FUNC_RETURN(card->ctx, 1, r);
}
コード例 #17
0
ファイル: card-isoApplet.c プロジェクト: BradPID/OpenSC
static int
isoApplet_set_security_env(sc_card_t *card,
                           const sc_security_env_t *env, int se_num)
{
	sc_apdu_t apdu;
	u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
	u8 *p;
	int r;
	struct isoApplet_drv_data *drvdata = DRVDATA(card);

	LOG_FUNC_CALLED(card->ctx);

	if(se_num != 0)
	{
		LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED,
		             "IsoApplet does not support storing of security environments.");
	}
	assert(card != NULL && env != NULL);
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
	switch (env->operation)
	{
	case SC_SEC_OPERATION_DECIPHER:
		apdu.p2 = 0xB8;
		break;
	case SC_SEC_OPERATION_SIGN:
		apdu.p2 = 0xB6;
		break;
	default:
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	p = sbuf;

	if (env->flags & SC_SEC_ENV_ALG_PRESENT)
	{

		switch(env->algorithm)
		{

		case SC_ALGORITHM_RSA:
			if( env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1 )
			{
				drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_RSA_PAD_PKCS1;
			}
			else
			{
				LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports RSA with PKCS1 padding.");
			}
			break;

		case SC_ALGORITHM_EC:
			if( env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW )
			{
				drvdata->sec_env_alg_ref = ISOAPPLET_ALG_REF_ECDSA;
				drvdata->sec_env_ec_field_length = env->algorithm_ref;
			}
			else
			{
				LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "IsoApplet only supports raw ECDSA.");
			}
			break;

		default:
			LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported algorithm.");
		}

		*p++ = 0x80; /* algorithm reference */
		*p++ = 0x01;
		*p++ = drvdata->sec_env_alg_ref;
	}

	if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT)
	{
		*p++ = 0x81;
		*p++ = env->file_ref.len;
		assert(sizeof(sbuf) - (p - sbuf) >= env->file_ref.len);
		memcpy(p, env->file_ref.value, env->file_ref.len);
		p += env->file_ref.len;
	}

	if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
	{
		if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC)
			*p++ = 0x83;
		else
			*p++ = 0x84;
		*p++ = env->key_ref_len;
		assert(sizeof(sbuf) - (p - sbuf) >= env->key_ref_len);
		memcpy(p, env->key_ref, env->key_ref_len);
		p += env->key_ref_len;
	}
	r = p - sbuf;
	apdu.lc = r;
	apdu.datalen = r;
	apdu.data = sbuf;

	if (apdu.datalen != 0)
	{
		r = sc_transmit_apdu(card, &apdu);
		LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
		r = sc_check_sw(card, apdu.sw1, apdu.sw2);
		LOG_TEST_RET(card->ctx, r, "Card returned error");
	}

	LOG_FUNC_RETURN(card->ctx, r);
}
コード例 #18
0
ファイル: card-esteid2018.c プロジェクト: OpenSC/OpenSC
static int esteid_finish(sc_card_t *card) {
	if (card != NULL)
		free(DRVDATA(card));
	return 0;
}
コード例 #19
0
/* Load the rule and keyd file into our private data.
   Return 0 on success */
static int load_special_files(sc_card_t * card)
{
	sc_context_t *ctx = card->ctx;
	struct mcrd_priv_data *priv = DRVDATA(card);
	int r, recno;
	struct df_info_s *dfi;
	struct rule_record_s *rule;
	struct keyd_record_s *keyd;

	assert(!priv->is_ef);

	/* First check whether we already cached it. */
	dfi = get_df_info(card);
	if (dfi && dfi->rule_file)
		return 0;	/* yes. */
	clear_special_files(dfi);

	/* Read rule file. Note that we bypass our cache here. */
	r = select_part(card, MCRD_SEL_EF, EF_Rule, NULL);
	SC_TEST_RET(ctx, r, "selecting EF_Rule failed");

	for (recno = 1;; recno++) {
		u8 recbuf[256];
		r = sc_read_record(card, recno, recbuf, sizeof(recbuf),
				   SC_RECORD_BY_REC_NR);

		if (r == SC_ERROR_RECORD_NOT_FOUND)
			break;
		else if (r < 0) {
			SC_FUNC_RETURN(ctx, 2, r);
		} else {
			rule = (struct rule_record_s *)malloc(sizeof *rule + r);
			if (!rule)
				SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
			rule->recno = recno;
			rule->datalen = r;
			memcpy(rule->data, recbuf, r);
			rule->next = dfi->rule_file;
			dfi->rule_file = rule;
		}
	}

	sc_debug(ctx, "new EF_Rule file loaded (%d records)\n", recno - 1);

	/* Read the KeyD file. Note that we bypass our cache here. */
	r = select_part(card, MCRD_SEL_EF, EF_KeyD, NULL);
	if (r == SC_ERROR_FILE_NOT_FOUND) {
		sc_debug(ctx, "no EF_KeyD file available\n");
		return 0;	/* That is okay. */
	}
	SC_TEST_RET(ctx, r, "selecting EF_KeyD failed");

	for (recno = 1;; recno++) {
		u8 recbuf[256];
		r = sc_read_record(card, recno, recbuf, sizeof(recbuf),
				   SC_RECORD_BY_REC_NR);

		if (r == SC_ERROR_RECORD_NOT_FOUND)
			break;
		else if (r < 0) {
			SC_FUNC_RETURN(ctx, 2, r);
		} else {
			keyd = (struct keyd_record_s *)malloc(sizeof *keyd + r);
			if (!keyd)
				SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY);
			keyd->recno = recno;
			keyd->datalen = r;
			memcpy(keyd->data, recbuf, r);
			keyd->next = dfi->keyd_file;
			dfi->keyd_file = keyd;
		}
	}

	sc_debug(ctx, "new EF_KeyD file loaded (%d records)\n", recno - 1);
	/* FIXME: Do we need to restore the current DF?  I guess it is
	   not required, but we could try to do so by selecting 3fff?  */
	return 0;
}
コード例 #20
0
int card_sync_card_to_virtual_fs_filter_data_object( 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_data_info *data = NULL;
  unsigned char *card_data = NULL;
  virtual_file_t  *data_virtual_file = NULL;
  virtual_file_t  *data_virtual_file_weak_link = NULL; 
  sc_path_t abs_data_path, data_card_path, def_path;

  SC_FUNC_CALLED(card->ctx, 1);

  /* we need to correct certificate length in path */
  data = (struct sc_pkcs15_data_info *) obj->data;
  if(data) {    
    if(data->path.len > 0) {
      data_virtual_file = virtual_file_new();
      if(!data_virtual_file) {
	r = SC_ERROR_OUT_OF_MEMORY;
	goto end;
      }

      memset(&abs_data_path, 0, sizeof(struct sc_path));
      memset(&data_card_path, 0, sizeof(struct sc_path));      	
      memset(&def_path, 0, sizeof(struct sc_path));

      
      if(data->path.len == 4) {
        sc_format_path("3F00", &def_path);
   	r = sc_append_path(&def_path, &data->path);

	if(r!=SC_SUCCESS)
	  goto end;

        memcpy(data->path.value, def_path.value, def_path.len);
        data->path.len = 6;

      } else {
        memcpy(&def_path, &data->path, sizeof(data->path));
      }

      r = sc_append_path(&abs_data_path, &def_path);
      if(r!=SC_SUCCESS)
	goto end;

      if(abs_data_path.len==6) {
	r = sc_append_path(&data_card_path, &def_path);
	if(r!=SC_SUCCESS)
	  goto end;
      }      

      memcpy(&data_virtual_file->path, &abs_data_path, sizeof(data_virtual_file->path));
      r = map_path_to_path_set_item(DRVDATA(card)->virtual_fs_to_card_path_map, &data_virtual_file->path, &data_card_path);
      if(r != SC_SUCCESS)
	goto end;
      data_virtual_file->is_ef = 1;

      data_virtual_file->card_to_virtual_fs.sync_state = virtual_file_sync_state_sync_pending;
      data_virtual_file->card_to_virtual_fs.sync_callback = card_sync_card_to_virtual_fs_data_file_callback;
      data_virtual_file->virtual_fs_to_card.sync_state = virtual_file_sync_state_unknown;
      data_virtual_file->virtual_fs_to_card.sync_callback = NULL;
      
      /* append file to virtual_fs */
      r = virtual_fs_append(virtual_fs, data_virtual_file);
      if(r != SC_SUCCESS)
	goto end;

      /* we don't have ownership of virtual_file now,
	 so we don't need to free it */
      data_virtual_file_weak_link = data_virtual_file;
      data_virtual_file = NULL;
        
      /* we now synchronize file because this gets a correct size for it */
      r = virtual_file_data_synchronize(data_virtual_file_weak_link, card, virtual_file_sync_type_card_to_virtual_fs, DRVDATA(card)->virtual_fs);
      if (r != SC_SUCCESS) {
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Synchronization failed\n");
	goto end;
      }
      
      /* correct length in PKCS#15 */
      data->path.count = data_virtual_file_weak_link->data_size;
      obj->auth_id.value[0]=0x01;
      obj->auth_id.len=0x01;
    } else {
      sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Path length is 0");
    }
  } else {
    sc_debug(card->ctx,SC_LOG_DEBUG_VERBOSE, "Pointer to data info was empty");
  }

 end:
  if(card_data) {
    free(card_data);
    card_data = NULL;
  }

  if(data_virtual_file) {
    virtual_file_free(data_virtual_file);
    data_virtual_file = NULL;
  }

  SC_FUNC_RETURN(card->ctx, 1, r);
}
コード例 #21
0
int card_sync_card_to_virtual_fs_filter_cert( 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_cert_info *cert = NULL;
  unsigned char *card_data = NULL;
  virtual_file_t  *certificate_virtual_file = NULL;
  virtual_file_t  *certificate_virtual_file_weak_link = NULL; 
  sc_path_t abs_cert_path, cert_card_path;

  SC_FUNC_CALLED(card->ctx, 1);

  /* we need to correct certificate length in path */
  cert = (struct sc_pkcs15_cert_info *) obj->data;
  if(cert) {
    /* set asn1 to map */
    r = map_id_to_der_set_item(DRVDATA(card)->cdf_card_ckaid_to_card_der_map, &cert->id, &obj->content);
    if(r != SC_SUCCESS)
      goto end;
    
    if(cert->path.len > 0) {
      certificate_virtual_file = virtual_file_new();
      if(!certificate_virtual_file) {
	r = SC_ERROR_OUT_OF_MEMORY;
	goto end;
      }
      
      memset(&abs_cert_path, 0, sizeof(struct sc_path));
      memset(&cert_card_path, 0, sizeof(struct sc_path));

      if(cert->path.len==2) {
	sc_format_path("3F005015", &abs_cert_path);
	r = sc_append_path(&abs_cert_path, &cert->path);
	if(r!=SC_SUCCESS)
	  goto end;
	sc_format_path("3F006061", &cert_card_path);
	r = sc_append_path(&cert_card_path, &cert->path);
	if(r!=SC_SUCCESS)
	  goto end;
      } else if(cert->path.len==4) {
	sc_format_path("3F00", &abs_cert_path);
	r = sc_append_path(&abs_cert_path, &cert->path);
	if(r!=SC_SUCCESS)
	  goto end;
	sc_format_path("3F00", &cert_card_path);
	r = sc_append_path(&cert_card_path, &cert->path);
	if(r!=SC_SUCCESS)
	  goto end;
        memcpy(cert->path.value, cert_card_path.value, cert_card_path.len);
        cert->path.len = 6;
      } else { 
	r = sc_append_path(&abs_cert_path, &cert->path);
	if(r!=SC_SUCCESS)
	  goto end;
	if(abs_cert_path.len==6) {
	  r = sc_append_path(&cert_card_path, &cert->path);
	  if(r!=SC_SUCCESS)
	    goto end;
	}
      }

      memcpy(&certificate_virtual_file->path, &abs_cert_path, sizeof(certificate_virtual_file->path));
      r = map_path_to_path_set_item(DRVDATA(card)->virtual_fs_to_card_path_map, &certificate_virtual_file->path, &cert_card_path);
      if(r != SC_SUCCESS)
	goto end;
      certificate_virtual_file->is_ef = 1;

      certificate_virtual_file->card_to_virtual_fs.sync_state = virtual_file_sync_state_sync_pending;
      certificate_virtual_file->card_to_virtual_fs.sync_callback = card_sync_card_to_virtual_fs_certificate_file_callback;
      certificate_virtual_file->virtual_fs_to_card.sync_state = virtual_file_sync_state_unknown;
      certificate_virtual_file->virtual_fs_to_card.sync_callback = NULL;
      
      /* append file to virtual_fs */
      r = virtual_fs_append(virtual_fs, certificate_virtual_file);
      if(r != SC_SUCCESS)
	goto end;

      /* we don't have ownership of virtual_file now,
	 so we don't need to free it */
      certificate_virtual_file_weak_link = certificate_virtual_file;
      certificate_virtual_file = NULL;
        
      /* we now synchronize file because this gets a correct size for it */
      r = virtual_file_data_synchronize(certificate_virtual_file_weak_link, card, virtual_file_sync_type_card_to_virtual_fs, DRVDATA(card)->virtual_fs);
      if (r != SC_SUCCESS) {
	sc_debug(card->ctx,SC_LOG_DEBUG_NORMAL,  "Synchronization failed\n");
	goto end;
      }
      
      /* correct length in PKCS#15 */
      cert->path.count = certificate_virtual_file_weak_link->data_size;
    } else {
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"Path length is 0");
    }
  } else {
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"Pointer to cert info was empty");
  }

 end:
  if(card_data) {
    free(card_data);
    card_data = NULL;
  }

  if(certificate_virtual_file) {
    virtual_file_free(certificate_virtual_file);
    certificate_virtual_file = NULL;
  }

  SC_FUNC_RETURN(card->ctx, 1, r);
}
コード例 #22
0
ファイル: card_helper.c プロジェクト: securez/opendnie
int card_helper_create_cert_file(sc_card_t *card, struct _virtual_file_t *virtual_file, 
				 size_t fcert_len, struct _virtual_file_t **certificate_virtual_file)
{
  int r = SC_SUCCESS;
  sc_path_t fcert_path;
  sc_pkcs15_unusedspace_t *unused_space=NULL;
  sc_pkcs15_card_t *temp_p15card = NULL;
  int old_use_virtual_fs; /*!< backup of use_virtual_fs */

  assert(card!=NULL && virtual_file!=NULL && certificate_virtual_file!=NULL);

  SC_FUNC_CALLED(card->ctx, 1);
  
  /* we backup use_virtual_fs */
  old_use_virtual_fs = card_is_virtual_fs_active(card);

  /* we want to use card without virtual fs */
  card_set_virtual_fs_state(card, 0);

  if(*certificate_virtual_file) {
    virtual_file_free(*certificate_virtual_file);
    *certificate_virtual_file = NULL;
  }

  memset(&fcert_path, 0, sizeof(struct sc_path));

  /* 2. Look for a suitable file on UnusedSpace struct
     which fits the final certificate file size.
     2.1 If found, take file's path to reuse it.
     2.2 If not, create a file on Certificate Directory
     with final certificate len as its size
  */
    
  /* we create a fake p15card structure */
  temp_p15card = sc_pkcs15_card_new();
  temp_p15card->card = card;
    
  r = sc_find_free_unusedspace( temp_p15card, fcert_len, &unused_space );
  if (r!=SC_SUCCESS)
    goto chccf_end;

  if(unused_space) {
    /* we got a path */
    r = sc_path_set_dnie ( &fcert_path, 
		      unused_space->path.type, 
		      unused_space->path.value,
		      unused_space->path.len,
		      unused_space->path.index,
		      unused_space->path.count );
    if (r!=SC_SUCCESS)
      goto chccf_end;
  } else {            
    sc_path_t temp_path;
    /* move to certificate DF */
    sc_format_path("3F006061", &temp_path);
    r = card_select_file(card, &temp_path, NULL);
    if(r != SC_SUCCESS)
      goto chccf_end;

    /* we start at 0x7001 file ID */
    sc_format_path("7001", &fcert_path);

    do {
      r = card_create_cert_file( card, &fcert_path, fcert_len );
      if (r == SC_ERROR_OBJECT_ALREADY_EXISTS) {
	fcert_path.value[1]++;	
      }
      if(r!=SC_SUCCESS && r!=SC_ERROR_OBJECT_ALREADY_EXISTS)
	goto chccf_end;
    } while (r!=SC_SUCCESS);
    r = SC_SUCCESS;
  }    

  /* create certificate file into vfs */
  r = virtual_fs_append_new_virtual_file( DRVDATA(card)->virtual_fs, 
					  &fcert_path, 
					  virtual_file->data, 
					  virtual_file->data_size, 
					  virtual_file->data_size, 
					  1, 
					  virtual_file_sync_state_synced, 
					  card_sync_card_to_virtual_fs_certificate_file_callback, 
					  virtual_file_sync_state_sync_pending, 
					  card_sync_virtual_fs_to_card_certificate_file_callback );
  if(r != SC_SUCCESS)
    goto chccf_end;

  /* retrieve just created virtual file */
  *certificate_virtual_file = virtual_fs_find_by_path( DRVDATA(card)->virtual_fs, &fcert_path );

 chccf_end:
/* we restore use_virtual_fs */
  card_set_virtual_fs_state(card, old_use_virtual_fs);

  if (unused_space) {
    /* Delete UnusedSpace object if reused 
       and also frees reserved memory
    */
    sc_pkcs15_remove_unusedspace(temp_p15card, unused_space);
  }
  if (temp_p15card) { 
    /* set to NULL without freeing because we reused structure */
    temp_p15card->card = NULL;
    
    /* now free temp structure */
    sc_pkcs15_card_free(temp_p15card);
    temp_p15card = NULL;
  }
  SC_FUNC_RETURN(card->ctx, 1, r); 
}