static int iso7816_update_binary(sc_card_t *card,
				 unsigned int idx, const u8 *buf,
				size_t count, unsigned long flags)
{
	sc_apdu_t apdu;
	int r;

	assert(count <= card->max_send_size);

	if (idx > 0x7fff) {
		sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
		return SC_ERROR_OFFSET_TOO_LARGE;
	}

	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6,
		       (idx >> 8) & 0x7F, idx & 0xFF);
	apdu.lc = count;
	apdu.datalen = count;
	apdu.data = buf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");
	SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
		    "Card returned error");
	SC_FUNC_RETURN(card->ctx, 3, count);
}
Example #2
0
static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len)
{
	int	r;
	u8	buf[SC_MAX_APDU_BUFFER_SIZE];
	struct sc_context *ctx = card->ctx;
	struct sc_apdu    apdu;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00);
	apdu.lc      = aid_len;
	apdu.data    = aid;
	apdu.datalen = aid_len;
	apdu.resp    = buf;
	apdu.le      = 256;
	apdu.resplen = sizeof(buf);

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");
	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	if (r)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);

	return SC_SUCCESS;
}
static int iso7816_update_record(sc_card_t *card, unsigned int rec_nr,
				 const u8 *buf, size_t count,
				 unsigned long flags)
{
	sc_apdu_t apdu;
	int r;

	if (count > 256) {
		sc_error(card->ctx, "Trying to send too many bytes\n");
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0);
	apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;
	if (flags & SC_RECORD_BY_REC_NR)
		apdu.p2 |= 0x04;
	
	apdu.lc = count;
	apdu.datalen = count;
	apdu.data = buf;

	r = sc_transmit_apdu(card, &apdu);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");
	SC_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
		    "Card returned error");
	SC_FUNC_RETURN(card->ctx, 3, count);
}
static int myeid_encode_private_key(sc_profile_t *profile, sc_card_t *card,
		struct sc_pkcs15_prkey_rsa *rsa, u8 *key, 
		size_t *keysize, int key_ref)
{
	SC_FUNC_CALLED(card->ctx, 1);
	SC_FUNC_RETURN(card->ctx, 1, 0);
}
Example #5
0
/*
 * Store a private key
 */
static int
miocos_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object,
		struct sc_pkcs15_prkey *key)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_pkcs15_prkey_rsa *rsa;
	struct sc_file *file = NULL;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA
			|| key->algorithm != SC_ALGORITHM_RSA)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys.");

	rsa = &key->u.rsa;
	if (rsa->modulus.len != 128)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys.");

        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store key with ID:%s and path:%s\n", sc_pkcs15_print_id(&key_info->id),
			sc_print_path(&key_info->path));

	r = sc_select_file(p15card->card, &key_info->path, &file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store key: select key file failed");

	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store private key");

	r = miocos_update_private_key(profile, p15card->card, rsa);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
/*
 * Select the PIN reference
 */
static int myeid_select_pin_reference(sc_profile_t *profile, sc_card_t *card,
		sc_pkcs15_pin_info_t *pin_info)
{
	sc_pkcs15_pin_info_t pin_info_prof;
	int type;

	SC_FUNC_CALLED(card->ctx, 1);
	if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
	{
	  type = SC_PKCS15INIT_SO_PIN;
	  sc_debug(card->ctx, "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)\n",
                            pin_info->reference,pin_info->tries_left);	
	}
	else	
	{
	  type = SC_PKCS15INIT_USER_PIN;
	  sc_debug(card->ctx, "PIN_FLAG_PIN, ref (%d), tries_left (%d)\n",
                            pin_info->reference, pin_info->tries_left);

	}

	if (pin_info->reference <= 0 || pin_info->reference > MYEID_MAX_PINS)
		pin_info->reference = 1;
		
	SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int entersafe_init(sc_card_t *card)
{
	unsigned int flags;

	SC_FUNC_CALLED(card->ctx, 1);

	card->name = "entersafe";
	card->cla  = 0x00;
	/*card->drv_data = NULL;*/

	flags =SC_ALGORITHM_ONBOARD_KEY_GEN
		 | SC_ALGORITHM_RSA_RAW
		 | SC_ALGORITHM_RSA_HASH_NONE;

	

	_sc_card_add_rsa_alg(card, 512, flags, 0x10001);
	_sc_card_add_rsa_alg(card, 768, flags, 0x10001);
	_sc_card_add_rsa_alg(card,1024, flags, 0x10001);
	_sc_card_add_rsa_alg(card,2048, flags, 0x10001);

	/*card->caps = SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT; */
	card->caps = SC_CARD_CAP_RNG; 

	card->drv_data = 0;

	/* we need read_binary&friends with max 224 bytes per read */
	if (card->max_send_size > 0xE0)
		card->max_send_size = 0xE0;
	if (card->max_recv_size > 0xE0)
		card->max_recv_size = 0xE0;
	SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS);
}
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);
}
Example #9
0
static int entersafe_init(sc_card_t *card)
{
	unsigned int flags;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	card->name = "entersafe";
	card->cla  = 0x00;
	card->drv_data = NULL;

	flags =SC_ALGORITHM_ONBOARD_KEY_GEN
		 | SC_ALGORITHM_RSA_RAW
		 | SC_ALGORITHM_RSA_HASH_NONE;

	_sc_card_add_rsa_alg(card, 512, flags, 0);
	_sc_card_add_rsa_alg(card, 768, flags, 0);
	_sc_card_add_rsa_alg(card,1024, flags, 0);
	_sc_card_add_rsa_alg(card,2048, flags, 0);

	card->caps = SC_CARD_CAP_RNG; 

	/* we need read_binary&friends with max 224 bytes per read */
	card->max_send_size = 224;
	card->max_recv_size = 224;
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_SUCCESS);
}
Example #10
0
/*
 * Select a PIN reference
 */
static int
gpk_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_pkcs15_auth_info_t *auth_info)
{
	int	preferred, current;

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

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

	if ((current = auth_info->attrs.pin.reference) < 0)
		current = 0;

	if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
		preferred = GPK_PIN_SCOPE | 0;
	} else {
		preferred = current | GPK_PIN_SCOPE;

		if (preferred & 1)
			preferred++;
		if (preferred < (GPK_PIN_SCOPE | 2))
			preferred = GPK_PIN_SCOPE | 2;
		if (preferred > 15)
			return SC_ERROR_TOO_MANY_OBJECTS;
	}

	if (current > preferred)
		return SC_ERROR_TOO_MANY_OBJECTS;
	auth_info->attrs.pin.reference = preferred;
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 0);
}
Example #11
0
/*
 * Lock the pin file
 */
static int
gpk_lock_pinfile(struct sc_profile *profile, sc_pkcs15_card_t *p15card,
		sc_file_t *pinfile)
{
	struct sc_path	path;
	struct sc_file	*parent = NULL;
	int		r;

	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
	/* Select the parent DF */
	path = pinfile->path;
	if (path.len >= 2)
		path.len -= 2;
	if (path.len == 0)
		sc_format_path("3F00", &path);
	if ((r = sc_select_file(p15card->card, &path, &parent)) < 0)
		return r;

	/* Present PINs etc as necessary */
	r = sc_pkcs15init_authenticate(profile, p15card, parent, SC_AC_OP_LOCK);
	if (r >= 0)
		r = gpk_lock(p15card->card, pinfile, SC_AC_OP_WRITE);

	sc_file_free(parent);
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #12
0
int file_uncompress_data(struct sc_card *card, u8 * data, size_t length, u8 **uncompressed_data, size_t *uncompressed_data_length )
{
  size_t compressed_data_length;
  int r = SC_SUCCESS, pos=0;

  SC_FUNC_CALLED(card->ctx, 1);

  /* zlib header; uncompressed length + compressed length: always will be 8 bytes */
  pos = 8;	
  *uncompressed_data_length = lebytes2ulong(data);
  compressed_data_length = lebytes2ulong(data+4);

  *uncompressed_data = (u8 *) calloc(*uncompressed_data_length, sizeof(u8));		
  if (!*uncompressed_data)		
    return SC_ERROR_OUT_OF_MEMORY;

  if(compressed_data_length < *uncompressed_data_length) {
    r = uncompress(*uncompressed_data, (unsigned long *)uncompressed_data_length, data+pos, length-pos);			
    if(r!=Z_OK) {
      free(*uncompressed_data);		
      return r;
    }
    r = SC_SUCCESS;
  }  else {
    memcpy(*uncompressed_data, data+pos, *uncompressed_data_length);
    r = SC_SUCCESS;
  }

  SC_FUNC_RETURN(card->ctx, 1, r);
}
Example #13
0
static int entersafe_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
							   sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
{
	sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
	sc_card_t *card = p15card->card;
	sc_entersafe_wkey_data data;
	sc_file_t              *tfile;
	const sc_acl_entry_t   *acl_entry;
	int r;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

	if (key->algorithm != SC_ALGORITHM_RSA)
		 /* ignore DSA keys */
		 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,SC_ERROR_INVALID_ARGUMENTS);

	r = sc_profile_get_file(profile, "PKCS15-AODF", &tfile);
	if (r < 0)
		 return r;
	acl_entry = sc_file_get_acl_entry(tfile, SC_AC_OP_UPDATE);
	if (acl_entry->method  != SC_AC_NONE) {
		 r = sc_pkcs15init_authenticate(profile, p15card, tfile, SC_AC_OP_UPDATE);
		 if(r<0)
			  r = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}
	sc_file_free(tfile);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "cant verify pin");

	data.key_id = (u8) kinfo->key_reference;
	data.usage=0x22;
	data.key_data.rsa=&key->u.rsa;
	return sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
}
static int entersafe_select_fid(sc_card_t *card,
								unsigned int id_hi, unsigned int id_lo,
								sc_file_t **file_out)
{
	int r;
	sc_file_t *file=0;
	sc_path_t path;

	path.type=SC_PATH_TYPE_FILE_ID;
	path.value[0]=id_hi;
	path.value[1]=id_lo;
	path.len=2;

	r = iso_ops->select_file(card,&path,&file);
	SC_TEST_RET(card->ctx, r, "APDU transmit failed");

	/* update cache */
	if (file->type == SC_FILE_TYPE_DF) {
		 card->cache.current_path.type = SC_PATH_TYPE_PATH;
		 card->cache.current_path.value[0] = 0x3f;
		 card->cache.current_path.value[1] = 0x00;
		 if (id_hi == 0x3f && id_lo == 0x00){
			  card->cache.current_path.len = 2;
		 }else{
			  card->cache.current_path.len = 4;
			  card->cache.current_path.value[2] = id_hi;
			  card->cache.current_path.value[3] = id_lo;
		 }
	}
	
	if (file_out)
		 *file_out = file;

	SC_FUNC_RETURN(card->ctx, 2, SC_SUCCESS);
}
Example #15
0
/*
 * Select the PIN reference
 */
static int 
myeid_select_pin_reference(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
		sc_pkcs15_auth_info_t *auth_info)
{
	SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);

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

	if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
	{
	  sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
			  "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)",
			  auth_info->attrs.pin.reference, auth_info->tries_left);	
	}
	else	
	{
	  sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 
			  "PIN_FLAG_PIN, ref (%d), tries_left (%d)",
			  auth_info->attrs.pin.reference, auth_info->tries_left);

	}

	if (auth_info->attrs.pin.reference <= 0 || auth_info->attrs.pin.reference > MYEID_MAX_PINS)
		auth_info->attrs.pin.reference = 1;
		
	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 0);
}
Example #16
0
static int ctapi_connect(sc_reader_t *reader)
{
	struct ctapi_private_data *priv = GET_PRIV_DATA(reader);
	char rv;
	u8 cmd[9], rbuf[256], sad, dad;
	unsigned short lr;
	int r;

	cmd[0] = CTBCS_CLA;
	cmd[1] = CTBCS_INS_REQUEST;
	cmd[2] = CTBCS_P1_INTERFACE1;
	cmd[3] = CTBCS_P2_REQUEST_GET_ATR;
	cmd[4] = 0x00;
	dad = 1;
	sad = 2;
	lr = 256;

	rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
	if (rv || rbuf[lr-2] != 0x90) {
		sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error activating card: %d\n", rv);
		return SC_ERROR_TRANSMIT_FAILED;
	}
	if (lr < 2)
		SC_FUNC_RETURN(reader->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
	lr -= 2;
	if (lr > SC_MAX_ATR_SIZE)
		return SC_ERROR_INTERNAL;
	reader->atr.len = lr;
	memcpy(reader->atr.value, rbuf, lr);
	r = _sc_parse_atr(reader);

	return 0;
}
Example #17
0
/*
 * Erase the card.
 */
static int 
myeid_erase_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_cardctl_myeid_data_obj data_obj;
	struct sc_file *mf = NULL;
	unsigned char data[8];
	int r;
	
	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);

	r = myeid_get_init_applet_data(profile, p15card, data, sizeof(data));
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Get init applet date error");

	/* Select parent DF and verify PINs/key as necessary */
	r = sc_select_file(p15card->card, sc_get_mf_path(), &mf);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot select MF");

	/* ACLs are not actives if file is not in the operational state */
	if (mf->status == SC_FILE_STATUS_ACTIVATED)
		r = sc_pkcs15init_authenticate(profile, p15card, mf, SC_AC_OP_DELETE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "'DELETE' authentication failed on MF");
	
	data_obj.P1      = 0x01;
	data_obj.P2      = 0xE0;
	data_obj.Data    = data;
	data_obj.DataLen = sizeof(data);

	r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);

	SC_FUNC_RETURN(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
static int 
sc_oberthur_parse_tokeninfo (struct sc_pkcs15_card *p15card, 
		unsigned char *buff, size_t len, int postpone_allowed)
{
	struct sc_context *ctx = p15card->card->ctx;
	char label[0x21];
	unsigned flags;
	int ii;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (!buff || len < 0x24)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Cannot parse token info");

	memset(label, 0, sizeof(label));

	memcpy(label, buff, 0x20);
	ii = 0x20;
	while (*(label + --ii)==' ' && ii)
		;
	*(label + ii + 1) = '\0';

	flags = *(buff + 0x22) * 0x100 + *(buff + 0x23);
	
	p15card->tokeninfo->label = strdup(label);
	p15card->tokeninfo->manufacturer_id = strdup("Oberthur/OpenSC");

	if (flags & 0x01)
		p15card->tokeninfo->flags |= SC_PKCS15_TOKEN_PRN_GENERATION;

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "label %s", p15card->tokeninfo->label);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "manufacturer_id %s", p15card->tokeninfo->manufacturer_id);
	
	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_SUCCESS);
}
Example #19
0
/*
 * Create private key file
 */
static int
miocos_create_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_file *file;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
        	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys.");

	if (key_info->modulus_length != 1024)
        	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "MioCOS supports only 1024-bit RSA keys.");

        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "create private key ID:%s\n",  sc_pkcs15_print_id(&key_info->id));
	r = miocos_new_file(profile, p15card->card, SC_PKCS15_TYPE_PRKEY_RSA, key_info->key_reference, &file);
        SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot create key: failed to allocate new key object");

        memcpy(&file->path, &key_info->path, sizeof(file->path));
        file->id = file->path.value[file->path.len - 2] * 0x100
			+ file->path.value[file->path.len - 1];

        sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Path of private key file to create %s\n", sc_print_path(&file->path));

	r = sc_pkcs15init_create_file(profile, p15card, file);
	sc_file_free(file);

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #20
0
/*
 * Store a private key
 */
static int
myeid_store_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_pkcs15_object *object, 
		struct sc_pkcs15_prkey *prkey)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
	struct sc_cardctl_myeid_gen_store_key_info args;
	struct sc_file *file = NULL;
	int r, keybits = key_info->modulus_length;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (object->type != SC_PKCS15_TYPE_PRKEY_RSA)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED, "Store key failed: RSA only supported");

	/* Check that the card supports the requested modulus length */
	if (sc_card_find_rsa_alg(p15card->card, keybits) == NULL)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size");

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "store MyEID key with ID:%s and path:%s", 
			sc_pkcs15_print_id(&key_info->id), sc_print_path(&key_info->path));

	r = sc_select_file(card, &key_info->path, &file);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Cannot store MyEID key: select key file failed");
	
	r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "No authorisation to store MyEID private key");

	if (file) 
		sc_file_free(file);

	/* Fill in data structure */
	memset(&args, 0, sizeof(args));
	args.mod_len = keybits;
	args.op_type    = OP_TYPE_STORE;
	args.pubexp_len = prkey->u.rsa.exponent.len;
	args.pubexp     = prkey->u.rsa.exponent.data;
	args.primep_len = prkey->u.rsa.p.len;
	args.primep     = prkey->u.rsa.p.data;
	args.primeq_len = prkey->u.rsa.q.len;
	args.primeq     = prkey->u.rsa.q.data;

	args.dp1_len    = prkey->u.rsa.dmp1.len;
	args.dp1        = prkey->u.rsa.dmp1.data;
	args.dq1_len    = prkey->u.rsa.dmq1.len;
	args.dq1        = prkey->u.rsa.dmq1.data;
	args.invq_len   = prkey->u.rsa.iqmp.len;
	args.invq       = prkey->u.rsa.iqmp.data;

	args.mod_len    = prkey->u.rsa.modulus.len;
	args.mod        = prkey->u.rsa.modulus.data;		

	/* Store RSA key  */
	r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_STORE_KEY, &args);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Card control 'MYEID_GENERATE_STORE_KEY' failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #21
0
/*
 * Create a new PIN
 */
static int 
myeid_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
		struct sc_file *df, struct sc_pkcs15_object *pin_obj,
		const unsigned char *pin, size_t pin_len,
		const unsigned char *puk, size_t puk_len)
{
	struct sc_context *ctx = p15card->card->ctx;
	unsigned char  data[20];
	struct sc_cardctl_myeid_data_obj data_obj;
	struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)pin_obj->data;
        struct sc_pkcs15_auth_info puk_ainfo;
	int	r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN('%s',ref:%i,flags:0x%X,pin_len:%d,puk_len:%d)\n",
                            pin_obj->label, auth_info->attrs.pin.reference, auth_info->attrs.pin.flags, pin_len, puk_len);

	if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
		return SC_ERROR_OBJECT_NOT_VALID;
	if (auth_info->attrs.pin.reference >= MYEID_MAX_PINS)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
		return SC_ERROR_INVALID_PIN_LENGTH;

	sc_profile_get_pin_info(profile, (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) 
			? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, 
			&puk_ainfo);

	memset(data, 0, sizeof(data));
	/* Make command to add a pin-record */
	data_obj.P1 = 0x01;
	data_obj.P2 = auth_info->attrs.pin.reference;	/* myeid pin number */
	
	memset(data, auth_info->attrs.pin.pad_char, 8);
	memcpy(&data[0], (u8 *)pin, pin_len);   /* copy pin */

	memset(&data[8], puk_ainfo.attrs.pin.pad_char, 8);
	memcpy(&data[8], (u8 *)puk, puk_len);   /* copy puk */

	if(auth_info->tries_left > 0 && auth_info->tries_left < 15)
		data[16] = auth_info->tries_left;
	else
		data[16] = 5;	/* default value */

	if(puk_ainfo.tries_left > 0 && puk_ainfo.tries_left < 15)
		data[17] = puk_ainfo.tries_left;
	else
		data[17] = 5;	/* default value */

	data[18] = 0x00;

	data_obj.Data    = data;
	data_obj.DataLen = 19;

	r = sc_card_ctl(p15card->card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Initialize PIN failed");

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #22
0
int sc_pkcs15_get_card_objects_cond(struct sc_pkcs15_card *p15card, unsigned int type,
                               int (* func)(struct sc_pkcs15_object *, void *),
                               void *func_arg,
                               struct sc_pkcs15_object **ret, size_t ret_size)
{
  SC_FUNC_RETURN (p15card->card->ctx, 1, __sc_pkcs15_search_card_objects(p15card, 0, type,
					 func, func_arg, ret, ret_size));
}
Example #23
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 #24
0
int sc_delete_file(sc_card_t *card, const sc_path_t *path)
{
	int r;
	char pbuf[SC_MAX_PATH_STRING_SIZE];

	assert(card != NULL);

	r = sc_path_print(pbuf, sizeof(pbuf), path);
	if (r != SC_SUCCESS)
		pbuf[0] = '\0';

	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called; type=%d, path=%s", path->type, pbuf);
	if (card->ops->delete_file == NULL)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_NOT_SUPPORTED);
	r = card->ops->delete_file(card, path);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
}
Example #25
0
static int 
myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card, 
		struct sc_pkcs15_prkey_rsa *rsa, u8 *key, 
		size_t *keysize, int key_ref)
{
	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, 0);
}
Example #26
0
int sc_pkcs15_decode_cdf_entry(struct sc_pkcs15_card *p15card,
			       struct sc_pkcs15_object *obj,
			       const u8 ** buf, size_t *buflen)
{
        sc_context_t *ctx = p15card->card->ctx;
	struct sc_pkcs15_cert_info info;
	struct sc_asn1_entry	asn1_cred_ident[3], asn1_com_cert_attr[4],
				asn1_x509_cert_attr[2], asn1_type_cert_attr[2],
				asn1_cert[2], asn1_x509_cert_value_choice[3];
	struct sc_asn1_pkcs15_object cert_obj = { obj, asn1_com_cert_attr, NULL,
					     asn1_type_cert_attr };
	sc_pkcs15_der_t *der = &info.value;
	u8 id_value[128];
	int id_type;
	size_t id_value_len = sizeof(id_value);
	int r;

	sc_copy_asn1_entry(c_asn1_cred_ident, asn1_cred_ident);
	sc_copy_asn1_entry(c_asn1_com_cert_attr, asn1_com_cert_attr);
	sc_copy_asn1_entry(c_asn1_x509_cert_attr, asn1_x509_cert_attr);
	sc_copy_asn1_entry(c_asn1_x509_cert_value_choice, asn1_x509_cert_value_choice);
	sc_copy_asn1_entry(c_asn1_type_cert_attr, asn1_type_cert_attr);
	sc_copy_asn1_entry(c_asn1_cert, asn1_cert);
	
	sc_format_asn1_entry(asn1_cred_ident + 0, &id_type, NULL, 0);
	sc_format_asn1_entry(asn1_cred_ident + 1, &id_value, &id_value_len, 0);
	sc_format_asn1_entry(asn1_com_cert_attr + 0, &info.id, NULL, 0);
	sc_format_asn1_entry(asn1_com_cert_attr + 1, &info.authority, NULL, 0);
	sc_format_asn1_entry(asn1_com_cert_attr + 2, asn1_cred_ident, NULL, 0);
	sc_format_asn1_entry(asn1_x509_cert_attr + 0, asn1_x509_cert_value_choice, NULL, 0);
	sc_format_asn1_entry(asn1_x509_cert_value_choice + 0, &info.path, NULL, 0);
	sc_format_asn1_entry(asn1_x509_cert_value_choice + 1, &der->value, &der->len, 0);
	sc_format_asn1_entry(asn1_type_cert_attr + 0, asn1_x509_cert_attr, NULL, 0);
	sc_format_asn1_entry(asn1_cert + 0, &cert_obj, NULL, 0);

        /* Fill in defaults */
        memset(&info, 0, sizeof(info));
	info.authority = 0;
	
	r = sc_asn1_decode(ctx, asn1_cert, *buf, *buflen, buf, buflen);
	/* In case of error, trash the cert value (direct coding) */
	if (r < 0 && der->value)
		free(der->value);
	if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
		return r;
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");
	r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
	if (r < 0)
		return r;
	obj->type = SC_PKCS15_TYPE_CERT_X509;
	obj->data = malloc(sizeof(info));
	if (obj->data == NULL)
		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
	memcpy(obj->data, &info, sizeof(info));

	return 0;
}
/*
 * Create a new PIN
 */
static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card,
		int ignore_ac, sc_pkcs15_pin_info_t *pin_info,
		const u8 *pin, size_t pin_len,
		const u8 *puk, size_t puk_len)
{
	u8  data[20];
	int so_pin_ref;
	int	r,type, puk_tries;
	struct sc_cardctl_myeid_data_obj data_obj;
	sc_file_t *pinfile = NULL;

	SC_FUNC_CALLED(card->ctx, 1);
	sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n",
                            pin_info->reference, pin_len, puk_len);

	if (pin_info->reference >= MYEID_MAX_PINS)
		return SC_ERROR_INVALID_ARGUMENTS;
	if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4)
		return SC_ERROR_INVALID_PIN_LENGTH;

	if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
	  type = SC_PKCS15INIT_SO_PIN;
	else
	  type = SC_PKCS15INIT_USER_PIN;

	sc_debug(card->ctx, "pin type (%s)\n",
                             (type == SC_PKCS15INIT_SO_PIN) ? "SO_PIN": "USER_PIN");

	memset(data, 0xFF, sizeof(data));
	/* Make command to add a pin-record */
	data_obj.P1 = 01;
	data_obj.P2 = pin_info->reference;	/* myeid pin number */
	
	memcpy(&data[0], (u8 *)pin, pin_len);   /* copy pin*/
	memcpy(&data[8], (u8 *)puk, puk_len);   /* copy puk */

        data[16] = 0x00;
	data[17] = 0x00;
	data[18] = 0x00;

	data_obj.Data    = data;
	data_obj.DataLen = 16;

	puk_tries = myeid_puk_retries(profile, pin_info);
	if(pin_info->tries_left > 0 && pin_info->tries_left < 15 &&
           puk_tries > 0 && puk_tries < 15)
	{
	    /* Optional PIN locking */
	    data[16] = (pin_info->tries_left & 0x0F);
	    data[17] = (puk_tries & 0x0F);
	    data_obj.DataLen = 19;
	}

	r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj);

	SC_FUNC_RETURN(card->ctx, 1, r);
}
Example #28
0
static int starcos_select_aid(sc_card_t *card,
                              u8 aid[16], size_t len,
                              sc_file_t **file_out)
{
    sc_apdu_t apdu;
    int r;
    size_t i = 0;

    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C);
    apdu.lc = len;
    apdu.data = (u8*)aid;
    apdu.datalen = len;
    apdu.resplen = 0;
    apdu.le = 0;
    r = sc_transmit_apdu(card, &apdu);
    SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

    /* check return value */
    if (!(apdu.sw1 == 0x90 && apdu.sw2 == 0x00) && apdu.sw1 != 0x61 )
        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));

    /* update cache */
    card->cache.current_path.type = SC_PATH_TYPE_DF_NAME;
    card->cache.current_path.len = len;
    memcpy(card->cache.current_path.value, aid, len);

    if (file_out) {
        sc_file_t *file = sc_file_new();
        if (!file)
            SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
        file->type = SC_FILE_TYPE_DF;
        file->ef_structure = SC_FILE_EF_UNKNOWN;
        file->path.len = 0;
        file->size = 0;
        /* AID */
        for (i = 0; i < len; i++)
            file->name[i] = aid[i];
        file->namelen = len;
        file->id = 0x0000;
        file->magic = SC_FILE_MAGIC;
        *file_out = file;
    }
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
}
Example #29
0
static int entersafe_create_pin(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
								sc_file_t *df, sc_pkcs15_object_t *pin_obj,
								const unsigned char *pin, size_t pin_len,
								const unsigned char *puk, size_t puk_len)
{
	struct sc_card *card = p15card->card;
	int	r;
	sc_pkcs15_auth_info_t *auth_info = (sc_pkcs15_auth_info_t *) pin_obj->data;

	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);

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

	{/*pin*/
		 sc_entersafe_wkey_data  data;

		 if (!pin || !pin_len || pin_len > 16)
			  return SC_ERROR_INVALID_ARGUMENTS;

		 data.key_id = auth_info->attrs.pin.reference;
		 data.usage=0x0B;
		 data.key_data.symmetric.EC=0x33;
		 data.key_data.symmetric.ver=0x00;
		 /* pad pin with 0 */
		 memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
		 memcpy(data.key_data.symmetric.key_val, pin, pin_len);
		 data.key_data.symmetric.key_len=16;

		 r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);

		 /* Cache new PIN value. */
		 sc_pkcs15_pincache_add(p15card, pin_obj, pin, pin_len);
	}

	{/*puk*/
		 sc_entersafe_wkey_data  data;

		 if (!puk || !puk_len || puk_len > 16)
			  return SC_ERROR_INVALID_ARGUMENTS;

		 data.key_id = auth_info->attrs.pin.reference+1;
		 data.usage=0x0B;
		 data.key_data.symmetric.EC=0x33;
		 data.key_data.symmetric.ver=0x00;
		 /* pad pin with 0 */
		 memset(data.key_data.symmetric.key_val, 0, sizeof(data.key_data.symmetric.key_val));
		 memcpy(data.key_data.symmetric.key_val, puk, puk_len);
		 data.key_data.symmetric.key_len=16;

		 r = sc_card_ctl(card, SC_CARDCTL_ENTERSAFE_WRITE_KEY, &data);
	}


	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,r);
}
Example #30
0
static int entersafe_select_aid(sc_card_t *card,
								const sc_path_t *in_path,
								sc_file_t **file_out)
{
	int r = 0;

	if (card->cache.valid 
		&& card->cache.current_path.type == SC_PATH_TYPE_DF_NAME
		&& card->cache.current_path.len == in_path->len
		&& memcmp(card->cache.current_path.value, in_path->value, in_path->len)==0 )
	{
		 if(file_out)
		 {
			  *file_out = sc_file_new();
			  if(!file_out)
				   SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
		 }
	}
	else
	{
		 r = iso_ops->select_file(card,in_path,file_out);
		 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

		 /* update cache */
		 card->cache.current_path.type = SC_PATH_TYPE_DF_NAME;
		 card->cache.current_path.len = in_path->len;
		 memcpy(card->cache.current_path.value,in_path->value,in_path->len);
	}
	if (file_out) {
		 sc_file_t *file = *file_out;
		 assert(file);

		 file->type = SC_FILE_TYPE_DF;
		 file->ef_structure = SC_FILE_EF_UNKNOWN;
		 file->path.len = 0;
		 file->size = 0;
		 /* AID */
		 memcpy(file->name,in_path->value,in_path->len);
		 file->namelen = in_path->len;
		 file->id = 0x0000;
	}
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}