Example #1
0
int sc_update_binary(sc_card_t *card, unsigned int idx,
		     const u8 *buf, size_t count, unsigned long flags)
{
	size_t max_lc = sc_get_max_send_size(card);
	int r;

	if (card == NULL || card->ops == NULL || buf == NULL) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}
	sc_log(card->ctx, "called; %"SC_FORMAT_LEN_SIZE_T"u bytes at index %d",
	       count, idx);
	if (count == 0)
		return 0;

#ifdef ENABLE_SM
	if (card->sm_ctx.ops.update_binary)   {
		r = card->sm_ctx.ops.update_binary(card, idx, buf, count);
		if (r)
			LOG_FUNC_RETURN(card->ctx, r);
	}
#endif

	if (card->ops->update_binary == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	if (count > max_lc) {
		int bytes_written = 0;
		const u8 *p = buf;

		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_lc? max_lc : count;
			r = sc_update_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				LOG_TEST_RET(card->ctx, r, "sc_update_binary() failed");
			}
			p += r;
			idx += r;
			bytes_written += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				LOG_FUNC_RETURN(card->ctx, bytes_written);
			}
		}
		sc_unlock(card);
		LOG_FUNC_RETURN(card->ctx, bytes_written);
	}

	r = card->ops->update_binary(card, idx, buf, count, flags);
	LOG_FUNC_RETURN(card->ctx, r);
}
Example #2
0
int main(int argc, char **argv)
{
	sc_context_t *ctx = NULL;
	sc_context_param_t ctx_param;
	sc_card_t *card = NULL;
	int r;

	/* get options */
	decode_options(argc, argv);

	/* connect to the card */
	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r) {
	fprintf(stderr, "Failed to establish context: %s\n",
		sc_strerror(r));
		return 1;
	}
	r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0);
	if (r) {
		fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r));
		return 1;
	}

	/* Check card type */
	if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V10 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V11 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V30)
		do_esteid(card);
	else if (card->type == SC_CARD_TYPE_BELPIC_EID)
		do_belpic(card);
	else {
		fprintf(stderr, "Not an EstEID or Belpic card!\n");
		goto out;
	}
	
	if (exec_program) {
		char *const largv[] = {exec_program, NULL};
		sc_unlock(card);
		sc_disconnect_card(card);
		sc_release_context(ctx);
		execv(exec_program, largv);
		/* we should not get here */
		perror("execv()");
		exit(1);
	}
	
out:
	sc_unlock(card);
	sc_disconnect_card(card);
	sc_release_context(ctx);
	exit(exit_status);
}
Example #3
0
int sc_update_binary(sc_card_t *card, unsigned int idx,
		     const u8 *buf, size_t count, unsigned long flags)
{
	size_t max_lc = card->max_send_size;
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_log(card->ctx, "called; %d bytes at index %d", count, idx);
	if (count == 0)
		return 0;

#ifdef ENABLE_SM
	if (card->sm_ctx.ops.update_binary)   {
		r = card->sm_ctx.ops.update_binary(card, idx, buf, count);
		if (r)
			LOG_FUNC_RETURN(card->ctx, r);
	}
#endif

	if (card->ops->update_binary == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	if (count > max_lc) {
		int bytes_written = 0;
		const u8 *p = buf;

		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_lc? max_lc : count;
			r = sc_update_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				LOG_TEST_RET(card->ctx, r, "sc_update_binary() failed");
			}
			p += r;
			idx += r;
			bytes_written += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				LOG_FUNC_RETURN(card->ctx, bytes_written);
			}
		}
		sc_unlock(card);
		LOG_FUNC_RETURN(card->ctx, bytes_written);
	}

	r = card->ops->update_binary(card, idx, buf, count, flags);
	LOG_FUNC_RETURN(card->ctx, r);
}
Example #4
0
File: card.c Project: DDvO/OpenSC
int sc_read_binary(sc_card_t *card, unsigned int idx,
		   unsigned char *buf, size_t count, unsigned long flags)
{
	size_t max_le = sc_get_max_recv_size(card);
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_log(card->ctx, "called; %d bytes at index %d", count, idx);
	if (count == 0)
		return 0;

#ifdef ENABLE_SM
	if (card->sm_ctx.ops.read_binary)   {
		r = card->sm_ctx.ops.read_binary(card, idx, buf, count);
		if (r)
			LOG_FUNC_RETURN(card->ctx, r);
	}
#endif
	if (card->ops->read_binary == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	if (count > max_le) {
		int bytes_read = 0;
		unsigned char *p = buf;

		r = sc_lock(card);
		LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_le ? max_le : count;
			r = sc_read_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				LOG_TEST_RET(card->ctx, r, "sc_read_binary() failed");
			}
			p += r;
			idx += r;
			bytes_read += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				LOG_FUNC_RETURN(card->ctx, bytes_read);
			}
		}
		sc_unlock(card);
		LOG_FUNC_RETURN(card->ctx, bytes_read);
	}
	r = card->ops->read_binary(card, idx, buf, count, flags);
	LOG_FUNC_RETURN(card->ctx, r);
}
static int ask_and_verify_pin(struct sc_pkcs15_object *obj)
{
	struct sc_pkcs15_pin_info *pin;
	int i = 0;
	char prompt[80];
	u8 *pass;

	pin = (struct sc_pkcs15_pin_info *) obj->data;
	if (pin->flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) {
		printf("Skipping unblocking pin [%s]\n", obj->label);
		return 0;
	}

	sprintf(prompt, "Please enter PIN code [%s]: ", obj->label);
	pass = (u8 *) getpass(prompt);

	sc_lock(card);
	i = sc_pkcs15_verify_pin(p15card, pin, pass, strlen((char *) pass));
	sc_unlock(card);
	if (i) {
		if (i == SC_ERROR_PIN_CODE_INCORRECT)
			fprintf(stderr,
				"Incorrect PIN code (%d tries left)\n",
				pin->tries_left);
		else
			fprintf(stderr,
				"PIN verifying failed: %s\n",
				sc_strerror(i));
		return 1;
	} else
		printf("PIN code correct.\n");

	return 0;
}
Example #6
0
/* Close a card and release all resources */
void
card_close (CARD card)
{
  if (card)
    {
#ifdef HAVE_OPENSC
      if (card->p15card)
        {
          sc_pkcs15_unbind (card->p15card);
          card->p15card = NULL;
        }
      if (card->p15priv)
        p15_release_private_data (card);
      if (card->scard)
        {
          sc_unlock (card->scard);
          sc_disconnect_card (card->scard, 0);
          card->scard = NULL;
	}
      if (card->ctx)
        {
          sc_release_context (card->ctx);
          card->ctx = NULL;
        }
#endif
      xfree (card);
    }
}
int main(int argc, char *argv[])
{
	int i;

	i = sc_test_init(&argc, argv);
	if (i < 0)
		return 1;
	printf("Looking for a PKCS#15 compatible Smart Card... ");
	fflush(stdout);
	sc_lock(card);
	i = sc_pkcs15_bind(card, &p15card);
	/* Keep card locked to prevent useless calls to sc_logout */
	if (i) {
		fprintf(stderr, "failed: %s\n", sc_strerror(i));
		return 1;
	}
	printf("found.\n");
	sc_test_print_card(p15card);

	dump_objects("PIN codes", SC_PKCS15_TYPE_AUTH_PIN);
	dump_objects("Private keys", SC_PKCS15_TYPE_PRKEY);
	dump_objects("Public keys", SC_PKCS15_TYPE_PUBKEY);
	dump_objects("X.509 certificates", SC_PKCS15_TYPE_CERT_X509);
	dump_objects("data objects", SC_PKCS15_TYPE_DATA_OBJECT);
	dump_unusedspace();

	sc_pkcs15_unbind(p15card);
	sc_unlock(card);
	sc_test_cleanup();
	return 0;
}
Example #8
0
void *thread_pop(void * camera){
	 camera_t *cam=(camera_t *)camera;
	 sc_frame_t *f;
	 int count=0;
	 zbfp=fopen("zbzb.yuv","wb");


	 slogi("pop ");
	 while(!cam->stopflag){
	 	if(count==0){
	 		sc_lock(&cam->q->mutex);
			slogi("wait for signal");
			pthread_cond_wait(&cam->q->cond,&cam->q->mutex);/*等待*/
			slogi("wake up");
			sc_unlock(&cam->q->mutex);
	 	}
	 	count++;
	 	int ret=queue_popfront(cam->q,&f);
		 if(ret==0 && f!=NULL){
		 	// slogi("pop ok delete it");
			  if(zbfp)
			  {
			  	 yuv_write(f->data, f->len, zbfp);
                // sc_write_onebyone(f->data, f->len, count);

			  }else{
				slogi("#####zbzb.yuv open fail#####");
			  }
			 delete_frame(f);}
		 if(ret==QEMPTY_POPFAIL || ret==QGNEL_FAIL ){//宁愿popfail,也不能让push数据放不进去而丢帧
				usleep(300);
		 }
	 }

}
Example #9
0
static void die(int ret)
{
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card, 0);
	}
	if (ctx)
		sc_release_context(ctx);
	exit(ret);
}
Example #10
0
static void die(int ret)
{
	sc_file_free(current_file);
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);
	exit(ret);
}
Example #11
0
int sc_update_binary(sc_card_t *card, unsigned int idx,
		     const u8 *buf, size_t count, unsigned long flags)
{
	size_t max_lc = card->max_send_size > 0 ? card->max_send_size : 255;
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
		"called; %d bytes at index %d\n", count, idx);
	if (count == 0)
		return 0;
	if (card->ops->update_binary == NULL)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
	if (count > max_lc) {
		int bytes_written = 0;
		const u8 *p = buf;

		r = sc_lock(card);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_lc? max_lc : count;
			r = sc_update_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_update_binary() failed");
			}
			p += r;
			idx += r;
			bytes_written += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_written);
			}
		}
		sc_unlock(card);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_written);
	}
	r = card->ops->update_binary(card, idx, buf, count, flags);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
Example #12
0
int main(int argc, char *argv[])
{
	struct sc_pkcs15_object **objs = NULL;
	int i, count;

	i = sc_test_init(&argc, argv);
	if (i < 0)
		return 1;
	if (card->reader->capabilities & SC_READER_CAP_PIN_PAD)
		printf("Slot is capable of doing pinpad operations!\n");
	printf("Looking for a PKCS#15 compatible Smart Card... ");
	fflush(stdout);
	if (SC_SUCCESS != sc_lock(card))
		return 1;
	i = sc_pkcs15_bind(card, NULL, &p15card);
	if (SC_SUCCESS != sc_unlock(card))
		return 1;
	if (i) {
		fprintf(stderr, "failed: %s\n", sc_strerror(i));
		sc_test_cleanup();
		return 1;
	}
	printf("found.\n");
	printf("Enumerating PIN codes...\n");
	if (SC_SUCCESS != sc_lock(card))
		return 1;
	count = enum_pins(&objs);
	if (SC_SUCCESS != sc_unlock(card))
		return 1;
	if (count < 0) {
		sc_pkcs15_unbind(p15card);
		sc_test_cleanup();
		return 1;
	}
	for (i = 0; i < count; i++) {
		ask_and_verify_pin(objs[i]);
	}
	sc_pkcs15_unbind(p15card);
	sc_test_cleanup();
	return 0;
}
Example #13
0
int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
{
	int r;
	size_t retry = 10;

	if (len == 0)
		return SC_SUCCESS;

	if (card == NULL || rnd == NULL) {
		return SC_ERROR_INVALID_ARGUMENTS;
	}

	LOG_FUNC_CALLED(card->ctx);

	if (card->ops == NULL || card->ops->get_challenge == NULL)
		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);

	r = sc_lock(card);
	if (r != SC_SUCCESS)
		LOG_FUNC_RETURN(card->ctx, r);

	while (len > 0 && retry > 0) {
		r = card->ops->get_challenge(card, rnd, len);
		if (r < 0) {
			sc_unlock(card);
			LOG_FUNC_RETURN(card->ctx, r);
		}

		if (r > 0) {
			rnd += (size_t) r;
			len -= (size_t) r;
		} else {
			retry--;
		}
	}

	sc_unlock(card);

	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
Example #14
0
int sc_read_binary(sc_card_t *card, unsigned int idx,
		   unsigned char *buf, size_t count, unsigned long flags)
{
	size_t max_le = card->max_recv_size > 0 ? card->max_recv_size : 256;
	int r;

	assert(card != NULL && card->ops != NULL && buf != NULL);
	sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "called; %d bytes at index %d", count, idx);
	if (count == 0)
		return 0;
	if (card->ops->read_binary == NULL)
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
	if (count > max_le) {
		int bytes_read = 0;
		unsigned char *p = buf;

		r = sc_lock(card);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
		while (count > 0) {
			size_t n = count > max_le ? max_le : count;
			r = sc_read_binary(card, idx, p, n, flags);
			if (r < 0) {
				sc_unlock(card);
				SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_read_binary() failed");
			}
			p += r;
			idx += r;
			bytes_read += r;
			count -= r;
			if (r == 0) {
				sc_unlock(card);
				SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_read);
			}
		}
		sc_unlock(card);
		SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, bytes_read);
	}
	r = card->ops->read_binary(card, idx, buf, count, flags);
	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
}
static int dump_objects(const char *what, int type)
{
	struct sc_pkcs15_object **objs;
	int count, i;

	printf("\nEnumerating %s... ", what);
	fflush(stdout);

	sc_lock(card);
	count = sc_pkcs15_get_objects(p15card, type, NULL, 0);
	if (count < 0) {
		printf("failed.\n");
		fprintf(stderr, "Error enumerating %s: %s\n",
			what, sc_strerror(count));
		sc_unlock(card);
		return 1;
	}
	if (count == 0) {
		printf("none found.\n");
		sc_unlock(card);
		return 0;
	}
	printf("%u found.\n", count);

	objs = (struct sc_pkcs15_object **) calloc(count, sizeof(*objs));
	if ((count = sc_pkcs15_get_objects(p15card, type, objs, count)) < 0) {
		fprintf(stderr, "Error enumerating %s: %s\n",
			what, sc_strerror(count));
	} else {
		for (i = 0; i < count; i++)
			sc_test_print_object(objs[i]);
	}
	free(objs);
	sc_unlock(card);
	return (count < 0) ? 1 : 0;
}
Example #16
0
 void sc_process_image(const void *buf, int size,int cmd,camera_t *camera)
{
	switch(cmd){
		case CMD_OUT_FILE:
			{
       			 frame_number++;
				 sc_write_onebyone(buf,size,frame_number);

			}
		break;
		case CMD_OUT_BUF:
		{	sc_frame_t *f=new_frame(size);
			/* The memcpy() function returns a pointer to dest.*/
			memcpy(f->data,buf,size);
			f->len=size;
			sc_queue_t *q=camera->q;
			int ret=queue_pushback(q, f);
			if(ret==QGNEL_FAIL || ret==QFULL_PUSHFAIL){
				sleep(1);slogi("sleep for full");
				// usleep(500);
			}
			#if 1
			if(count==0){
				sc_lock(&q->mutex);
				count=count+1;
				slogi("signal");
			    pthread_cond_signal(&q->cond);/*条件改变,发送信号,通知t_b进程*/
				sc_unlock(&q->mutex);

			}
			#endif
			break;
		}
		default:
			printf("process image");
	}
}
static int
sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
    int padding)
{
	struct sc_pkcs15_object *key_obj;
	int r;

	if (padding != RSA_PKCS1_PADDING)
		return -1;
	r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_DECRYPT);
	if (r)
		return -1;
	r = sc_pkcs15_decipher(p15card, key_obj, SC_ALGORITHM_RSA_PAD_PKCS1,
	    from, flen, to, flen);
	sc_unlock(card);
	if (r < 0) {
		error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
		goto err;
	}
	return r;
err:
	sc_close();
	return -1;
}
static int
sc_sign(int type, u_char *m, unsigned int m_len,
	unsigned char *sigret, unsigned int *siglen, RSA *rsa)
{
	struct sc_pkcs15_object *key_obj;
	int r;
	unsigned long flags = 0;

	/* XXX: sc_prkey_op_init will search for a pkcs15 private
	 * key object with the sign or signrecover usage flag set.
	 * If the signing key has only the non-repudiation flag set
	 * the key will be rejected as using a non-repudiation key
	 * for authentication is not recommended. Note: This does not
	 * prevent the use of a non-repudiation key for authentication
	 * if the sign or signrecover flag is set as well.
	 */
	r = sc_prkey_op_init(rsa, &key_obj, SC_USAGE_SIGN);
	if (r)
		return -1;
	/* FIXME: length of sigret correct? */
	/* FIXME: check 'type' and modify flags accordingly */
	flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_SHA1;
	r = sc_pkcs15_compute_signature(p15card, key_obj, flags,
					m, m_len, sigret, RSA_size(rsa));
	sc_unlock(card);
	if (r < 0) {
		error("sc_pkcs15_compute_signature() failed: %s",
		      sc_strerror(r));
		goto err;
	}
	*siglen = r;
	return 1;
err:
	sc_close();
	return 0;
}
Example #19
0
static int ask_and_verify_pin(struct sc_pkcs15_object *pin_obj)
{
	struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *) pin_obj->data;
	int i = 0;
	char prompt[(sizeof pin_obj->label) + 30];
	u8 *pass;

	if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN) {
		printf("Skipping unblocking pin [%.*s]\n", (int) sizeof pin_obj->label, pin_obj->label);
		return 0;
	}

	snprintf(prompt, sizeof(prompt), "Please enter PIN code [%.*s]: ",
		(int) sizeof pin_obj->label, pin_obj->label);
	pass = (u8 *) getpass(prompt);

	if (SC_SUCCESS != sc_lock(card))
		return 1;
	i = sc_pkcs15_verify_pin(p15card, pin_obj, pass, strlen((char *) pass));
	if (SC_SUCCESS != sc_unlock(card))
		return 1;
	if (i) {
		if (i == SC_ERROR_PIN_CODE_INCORRECT)
			fprintf(stderr,
				"Incorrect PIN code (%d tries left)\n",
				pin_info->tries_left);
		else
			fprintf(stderr,
				"PIN verifying failed: %s\n",
				sc_strerror(i));
		return 1;
	} else
		printf("PIN code correct.\n");

	return 0;
}
Example #20
0
/*
 * Change a PIN.
 */
int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
			 struct sc_pkcs15_object *pin_obj,
			 const u8 *oldpin, size_t oldpinlen,
			 const u8 *newpin, size_t newpinlen)
{
	int r;
	sc_card_t *card;
	struct sc_pin_cmd_data data;
	struct sc_pkcs15_pin_info *pin_info = (struct sc_pkcs15_pin_info *)pin_obj->data;
	
	/* make sure the pins are in valid range */
	if ((r = _validate_pin(p15card, pin_info, oldpinlen)) != SC_SUCCESS)
		return r;
	if ((r = _validate_pin(p15card, pin_info, newpinlen)) != SC_SUCCESS)
		return r;

	card = p15card->card;
	r = sc_lock(card);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
	/* the path in the pin object is optional */
	if (pin_info->path.len > 0) {
		r = sc_select_file(card, &pin_info->path, NULL);
		if (r)
			goto out;
	}

	/* set pin_cmd data */
	memset(&data, 0, sizeof(data));
	data.cmd             = SC_PIN_CMD_CHANGE;
	data.pin_type        = SC_AC_CHV;
	data.pin_reference   = pin_info->reference;
	data.pin1.data       = oldpin;
	data.pin1.len        = oldpinlen;
	data.pin1.pad_char   = pin_info->pad_char;
	data.pin1.min_length = pin_info->min_length;
	data.pin1.max_length = pin_info->max_length;
	data.pin1.pad_length = pin_info->stored_length;
	data.pin2.data       = newpin;
	data.pin2.len        = newpinlen;
	data.pin2.pad_char   = pin_info->pad_char;
	data.pin2.min_length = pin_info->min_length;
	data.pin2.max_length = pin_info->max_length;
	data.pin2.pad_length = pin_info->stored_length;

	if (pin_info->flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDING)
		data.flags |= SC_PIN_CMD_NEED_PADDING;

	switch (pin_info->type) {
	case SC_PKCS15_PIN_TYPE_BCD:
		data.pin1.encoding = SC_PIN_ENCODING_BCD;
		data.pin2.encoding = SC_PIN_ENCODING_BCD;
		break;
	case SC_PKCS15_PIN_TYPE_ASCII_NUMERIC:
		data.pin1.encoding = SC_PIN_ENCODING_ASCII;
		data.pin2.encoding = SC_PIN_ENCODING_ASCII;
		break;
	}
	
	if((!oldpin || !newpin) 
			&& p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
		data.flags |= SC_PIN_CMD_USE_PINPAD;
		if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
			data.pin1.prompt = "Please enter SO PIN";
			data.pin2.prompt = "Please enter new SO PIN";
		} else {
			data.pin1.prompt = "Please enter PIN";
			data.pin2.prompt = "Please enter new PIN";
		}
	}

	r = sc_pin_cmd(card, &data, &pin_info->tries_left);
	if (r == SC_SUCCESS)
		sc_pkcs15_pincache_add(p15card, pin_obj, newpin, newpinlen);

out:
	sc_unlock(card);
	return r;
}
Example #21
0
int main(int argc, char * const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int action_count = 0;
	int do_initialize = 0;
	int do_import_dkek_share = 0;
	int do_create_dkek_share = 0;
	int do_wrap_key = 0;
	int do_unwrap_key = 0;
	sc_path_t path;
	sc_file_t *file = NULL;
	const char *opt_so_pin = NULL;
	const char *opt_pin = NULL;
	const char *opt_filename = NULL;
	char *opt_password = NULL;
	int opt_retry_counter = 3;
	int opt_dkek_shares = -1;
	int opt_key_reference = -1;
	int opt_password_shares_threshold = -1;
	int opt_password_shares_total = -1;
	int opt_force = 0;
	int opt_iter = 10000000;
	sc_context_param_t ctx_param;

	setbuf(stderr, NULL);
	setbuf(stdout, NULL);

	while (1) {
		c = getopt_long(argc, argv, "XC:I:W:U:s:i:fr:wv", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			util_print_usage_and_die(app_name, options, option_help, NULL);
		switch (c) {
		case 'X':
			do_initialize = 1;
			action_count++;
			break;
		case 'C':
			do_create_dkek_share = 1;
			opt_filename = optarg;
			action_count++;
			break;
		case 'I':
			do_import_dkek_share = 1;
			opt_filename = optarg;
			action_count++;
			break;
		case 'W':
			do_wrap_key = 1;
			opt_filename = optarg;
			action_count++;
			break;
		case 'U':
			do_unwrap_key = 1;
			opt_filename = optarg;
			action_count++;
			break;
		case OPT_PASSWORD:
			opt_password = optarg;
			break;
		case OPT_SO_PIN:
			opt_so_pin = optarg;
			break;
		case OPT_PIN:
			opt_pin = optarg;
			break;
		case OPT_RETRY:
			opt_retry_counter = atol(optarg);
			break;
		case OPT_PASSWORD_SHARES_THRESHOLD:
			opt_password_shares_threshold = atol(optarg);
			break;
		case OPT_PASSWORD_SHARES_TOTAL:
			opt_password_shares_total = atol(optarg);
			break;
		case 's':
			opt_dkek_shares = atol(optarg);
			break;
		case 'f':
			opt_force = 1;
			break;
		case 'i':
			opt_key_reference = atol(optarg);
			break;
		case 'r':
			opt_reader = optarg;
			break;
		case 'v':
			verbose++;
			break;
		case 'w':
			opt_wait = 1;
			break;
		}
	}

	CRYPTO_malloc_init();
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	memset(&ctx_param, 0, sizeof(sc_context_param_t));
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r != SC_SUCCESS) {
		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}

	/* Only change if not in opensc.conf */
	if (verbose > 1 && ctx->debug == 0) {
		ctx->debug = verbose;
		sc_ctx_log_to_file(ctx, "stderr");
	}

	err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
	if (r != SC_SUCCESS) {
		fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r));
		goto end;
	}

	sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
	r = sc_select_file(card, &path, &file);

	if (r != SC_SUCCESS) {
		fprintf(stderr, "Failed to select application: %s\n", sc_strerror(r));
		goto end;
	}

	if (do_initialize) {
		initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares);
	}

	if (do_create_dkek_share) {
		create_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_threshold, opt_password_shares_total);
	}

	if (do_import_dkek_share) {
		import_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_total);
	}

	if (do_wrap_key) {
		wrap_key(card, opt_key_reference, opt_filename, opt_pin);
	}

	if (do_unwrap_key) {
		unwrap_key(card, opt_key_reference, opt_filename, opt_pin, opt_force);
	}

	if (action_count == 0) {
		print_info(card, file);
	}

end:
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);

	ERR_print_errors_fp(stderr);
	return err;
}
int main(int argc, char * const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int do_list_readers = 0;
	int do_list_drivers = 0;
	int do_list_rdrivers = 0;
	int do_list_files = 0;
	int do_send_apdu = 0;
	int do_print_atr = 0;
	int do_print_serial = 0;
	int do_print_name = 0;
	int action_count = 0;
	const char *opt_driver = NULL;
	sc_context_param_t ctx_param;
		
	setbuf(stderr, NULL);
	setbuf(stdout, NULL);

	while (1) {
		c = getopt_long(argc, argv, "nlfr:vs:DRc:aw", options, &long_optind);
		if (c == -1)
			break;
		if (c == '?')
			print_usage_and_die(app_name, options, option_help);
		switch (c) {
		case 'l':
			do_list_readers = 1;
			action_count++;
			break;
		case 'D':
			do_list_drivers = 1;
			action_count++;
			break;
		case 'R':
			do_list_rdrivers = 1;
			action_count++;
			break;
		case 'f':
			do_list_files = 1;
			action_count++;
			break;
		case 's':
			opt_apdus = (char **) realloc(opt_apdus,
					(opt_apdu_count + 1) * sizeof(char *));
			opt_apdus[opt_apdu_count] = optarg;
			do_send_apdu++;
			if (opt_apdu_count == 0)
				action_count++;
			opt_apdu_count++;
			break;
		case 'a':
			do_print_atr = 1;
			action_count++;
			break;
		case 'n':
			do_print_name = 1;
			action_count++;
			break;
		case 'r':
			opt_reader = atoi(optarg);
			break;
		case 'v':
			verbose++;
			break;
		case 'c':
			opt_driver = optarg;
			break;
		case 'w':
			opt_wait = 1;
			break;
		case OPT_SERIAL:
			do_print_serial = 1;
			action_count++;
			break;
		}
	}
	if (action_count == 0)
		print_usage_and_die(app_name, options, option_help);

	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = app_name;

	r = sc_context_create(&ctx, &ctx_param);
	if (r) {
		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
		return 1;
	}
	if (verbose > 1)
		ctx->debug = verbose-1;
	if (do_list_rdrivers) {
		if ((err = list_reader_drivers()))
			goto end;
		action_count--;
	}
	if (do_list_readers) {
		if ((err = list_readers()))
			goto end;
		action_count--;
	}
	if (do_list_drivers) {
		if ((err = list_drivers()))
			goto end;
		action_count--;
	}
	if (action_count <= 0)
		goto end;

	if (opt_driver != NULL) {
		err = sc_set_card_driver(ctx, opt_driver);
		if (err) {
			fprintf(stderr, "Driver '%s' not found!\n", opt_driver);
			err = 1;
			goto end;
		}
	}

	err = connect_card(ctx, &card, opt_reader, 0, opt_wait, verbose);
	if (err)
		goto end;

	if (do_print_atr) {
		if (verbose) {
			printf("Card ATR:\n");
			hex_dump_asc(stdout, card->atr, card->atr_len, -1);		
		} else {
			char tmp[SC_MAX_ATR_SIZE*3];
			sc_bin_to_hex(card->atr, card->atr_len, tmp, sizeof(tmp) - 1, ':');
			fprintf(stdout,"%s\n",tmp);
		}
		action_count--;
	}
	if (do_print_serial) {
		if (verbose)
			printf("Card serial number:");
		print_serial(card);
		action_count--;
	}
	if (do_print_name) {
		if (verbose)
			printf("Card name: ");
		printf("%s\n", card->name);
		action_count--;
	}
	if (do_send_apdu) {
		if ((err = send_apdu()))
			goto end;
		action_count--;
	}
	
	if (do_list_files) {
		if ((err = list_files()))
			goto end;
		action_count--;
	}
end:
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card, 0);
	}
	if (ctx)
		sc_release_context(ctx);
	return err;
}
int main(int argc, char *argv[])
{
	int i, c, r, cnt = 3, freq[39];
	struct timeval tv1, tv2;
	u8 buf[14];

	i = sc_test_init(&argc, argv);
	for (i = 0; i < 39; i++)
		freq[i] = 0;
	c = 0;
	while (cnt) {
		u8 nbuf[39];

		for (i = 0; i < 39; i++) {
			nbuf[i] = i + 1;
		}
		if (c == 0)
			gettimeofday(&tv1, NULL);
		sc_lock(card);
		r = sc_get_challenge(card, buf, 14);
		sc_unlock(card);
		if (r == 0) {
			int left = 39;

			printf("Lottery: ");
			for (i = 0; i < 7; i++) {
				unsigned short s = buf[2 * i] + (buf[2 * i + 1] << 8);
				int lot = s % (left + 1);
				int num = nbuf[lot];

				nbuf[lot] = nbuf[left - 1];
				left--;
				freq[num - 1]++;
				printf("%3d ", num);
			}
			printf("\n");
		} else {
			fprintf(stderr, "sc_get_challenge() failed: %s\n", sc_strerror(r));
			sc_test_cleanup();
			return 1;
		}
		c++;
		if (c == 50) {
			unsigned long long foo, foo2;

			gettimeofday(&tv2, NULL);
			foo = tv2.tv_sec * 1000 + tv2.tv_usec / 1000;
			foo2 = tv1.tv_sec * 1000 + tv1.tv_usec / 1000;
			printf("Time per one: %lld ms\n", (foo - foo2) / 50);
			printf("Frequencies:\n");
			for (i = 0; i < 39; i++) {
				printf("%3d: %-5d", i + 1, freq[i]);
				if (((i + 1) % 10) == 0)
					printf("\n");
			}
			printf("\n");
			c = 0;
			cnt--;
		}
	}
	sc_test_cleanup();
	return 0;
}
Example #24
0
LIBOPENSC_API int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
		       const struct sc_pkcs15_object *obj,
		       unsigned long flags,
		       const u8 * in, size_t inlen, u8 *out, size_t outlen)
{
	sc_context_t *ctx = p15card->card->ctx;
	int r;
	sc_algorithm_info_t *alg_info;
	sc_security_env_t senv;
	const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
	unsigned long pad_flags = 0, sec_flags = 0;

	LOG_FUNC_CALLED(ctx);

	memset(&senv, 0, sizeof(senv));

	/* Card driver should have the access to supported algorithms from 'tokenInfo'. So that
	 * it can get value of card specific 'AlgorithmInfo::algRef'. */
	memcpy(&senv.supported_algos, &p15card->tokeninfo->supported_algos, sizeof(senv.supported_algos));

	/* If the key is not native, we can't operate with it. */
	if (!prkey->native)
		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "This key is not native, cannot operate with it");

	if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP)))
		LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for decryption");

	switch (obj->type) {
		case SC_PKCS15_TYPE_PRKEY_RSA:
			alg_info = sc_card_find_rsa_alg(p15card->card, prkey->modulus_length);
			if (alg_info == NULL) {
				sc_log(ctx, "Card does not support RSA with key length %d", prkey->modulus_length);
				LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
			}
			senv.algorithm = SC_ALGORITHM_RSA;
			break;

		case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
			alg_info = sc_card_find_gostr3410_alg(p15card->card, prkey->modulus_length);
			if (alg_info == NULL) {
				sc_log(ctx, "Card does not support GOSTR3410 with key length %d", prkey->modulus_length);
				LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
			}
			senv.algorithm = SC_ALGORITHM_GOSTR3410;
			break;

		default:
			LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,"Key type not supported");
	}

	r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
	LOG_TEST_RET(ctx, r, "cannot encode security operation flags");

	senv.algorithm_flags = sec_flags;
	senv.operation       = SC_SEC_OPERATION_DECIPHER;
	senv.flags           = 0;
	/* optional keyReference attribute (the default value is -1) */
	if (prkey->key_reference >= 0) {
		senv.key_ref_len = 1;
		senv.key_ref[0] = prkey->key_reference & 0xFF;
		senv.flags |= SC_SEC_ENV_KEY_REF_PRESENT;
	}
	senv.flags |= SC_SEC_ENV_ALG_PRESENT;

	r = sc_lock(p15card->card);
	LOG_TEST_RET(ctx, r, "sc_lock() failed");

	if (prkey->path.len != 0 || prkey->path.aid.len != 0) {
		r = select_key_file(p15card, prkey, &senv);
		if (r < 0) {
			sc_unlock(p15card->card);
			LOG_TEST_RET(ctx, r,"Unable to select private key file");
		}
	}

	r = sc_set_security_env(p15card->card, &senv, 0);
	if (r < 0) {
		sc_unlock(p15card->card);
		LOG_TEST_RET(ctx, r, "sc_set_security_env() failed");
	}
	r = sc_decipher(p15card->card, in, inlen, out, outlen);
	if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
		if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
			r = sc_decipher(p15card->card, in, inlen, out, outlen);
	}
	sc_unlock(p15card->card);
	LOG_TEST_RET(ctx, r, "sc_decipher() failed");

	/* Strip any padding */
	if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
		size_t s = r;
		r = sc_pkcs1_strip_02_padding(out, s, out, &s);
		LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
	}

	LOG_FUNC_RETURN(ctx, r);
}
Example #25
0
LIBOPENSC_API int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
				const struct sc_pkcs15_object *obj,
				unsigned long flags, const u8 *in, size_t inlen,
				u8 *out, size_t outlen)
{
	sc_context_t *ctx = p15card->card->ctx;
	int r;
	sc_security_env_t senv;
	sc_algorithm_info_t *alg_info;
	const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
	u8 buf[1024], *tmp;
	size_t modlen;
	unsigned long pad_flags = 0, sec_flags = 0;

	LOG_FUNC_CALLED(ctx);
	sc_log(ctx, "security operation flags 0x%X", flags);

	memset(&senv, 0, sizeof(senv));

	/* Card driver should have the access to supported algorithms from 'tokenInfo'. So that
	 * it can get value of card specific 'AlgorithmInfo::algRef'. */
	memcpy(&senv.supported_algos, &p15card->tokeninfo->supported_algos, sizeof(senv.supported_algos));

	if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
		LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This is not a private key");

	/* If the key is not native, we can't operate with it. */
	if (!prkey->native)
		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "This key is not native, cannot operate with it");

	if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|
	                      SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)))
		LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for signing");

	switch (obj->type) {
		case SC_PKCS15_TYPE_PRKEY_RSA:
			modlen = prkey->modulus_length / 8;
			alg_info = sc_card_find_rsa_alg(p15card->card, prkey->modulus_length);
			if (alg_info == NULL) {
				sc_log(ctx, "Card does not support RSA with key length %d", prkey->modulus_length);
				LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
			}
			senv.flags |= SC_SEC_ENV_ALG_PRESENT;
			senv.algorithm = SC_ALGORITHM_RSA;
			break;

		case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
			modlen = (prkey->modulus_length + 7) / 8 * 2;
			alg_info = sc_card_find_gostr3410_alg(p15card->card, prkey->modulus_length);
			if (alg_info == NULL) {
				sc_log(ctx, "Card does not support GOSTR3410 with key length %d", prkey->modulus_length);
				LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
			}
			senv.flags |= SC_SEC_ENV_ALG_PRESENT;
			senv.algorithm = SC_ALGORITHM_GOSTR3410;
			break;

		case SC_PKCS15_TYPE_PRKEY_EC:
			modlen = ((prkey->field_length +7) / 8) * 2;  /* 2*nLen */ 
			alg_info = sc_card_find_ec_alg(p15card->card, prkey->field_length);
			if (alg_info == NULL) {
				sc_log(ctx, "Card does not support EC with field_size %d", prkey->field_length);
				LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
			}
			senv.algorithm = SC_ALGORITHM_EC;
			senv.flags |= SC_SEC_ENV_ALG_PRESENT;

			senv.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
			senv.algorithm_ref = prkey->field_length;
			break;
			/* add other crypto types here */
		default:
			LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Key type not supported");
	}

	/* Probably never happens, but better make sure */
	if (inlen > sizeof(buf) || outlen < modlen)
		LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL);

	memcpy(buf, in, inlen);

	/* revert data to sign when signing with the GOST key.
	 * TODO: can it be confirmed by the GOST standard?
	 * TODO: tested with RuTokenECP, has to be validated for RuToken. */
	if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410)
		sc_mem_reverse(buf, inlen);

	tmp = buf;

	/* flags: the requested algo
	 * algo_info->flags: what is supported by the card
	 * senv.algorithm_flags: what the card will have to do */

	/* if the card has SC_ALGORITHM_NEED_USAGE set, and the
	   key is for signing and decryption, we need to emulate signing */
	/* TODO: -DEE assume only RSA keys will ever use _NEED_USAGE */

	sc_log(ctx, "supported algorithm flags 0x%X, private key usage 0x%X", alg_info->flags, prkey->usage);
	if ((alg_info->flags & SC_ALGORITHM_NEED_USAGE) &&
		((prkey->usage & USAGE_ANY_SIGN) &&
		(prkey->usage & USAGE_ANY_DECIPHER)) ) {
		size_t tmplen = sizeof(buf);
		if (flags & SC_ALGORITHM_RSA_RAW) {
			r = sc_pkcs15_decipher(p15card, obj,flags, in, inlen, out, outlen);
			LOG_FUNC_RETURN(ctx, r);
		}
		if (modlen > tmplen)
			LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "Buffer too small, needs recompile!");

		r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen);

		/* no padding needed - already done */
		flags &= ~SC_ALGORITHM_RSA_PADS;
		/* instead use raw rsa */
		flags |= SC_ALGORITHM_RSA_RAW;

		LOG_TEST_RET(ctx, r, "Unable to add padding");

		r = sc_pkcs15_decipher(p15card, obj,flags, buf, modlen, out, outlen);
		LOG_FUNC_RETURN(ctx, r);
	}


	/* If the card doesn't support the requested algorithm, see if we
	 * can strip the input so a more restrictive algo can be used */
	if ((flags == (SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE)) &&
	    !(alg_info->flags & (SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE))) {
		unsigned int algo;
		size_t tmplen = sizeof(buf);

		r = sc_pkcs1_strip_digest_info_prefix(&algo, tmp, inlen, tmp, &tmplen);
		if (r != SC_SUCCESS || algo == SC_ALGORITHM_RSA_HASH_NONE) {
			sc_mem_clear(buf, sizeof(buf));
			LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
		}
		flags &= ~SC_ALGORITHM_RSA_HASH_NONE;
		flags |= algo;
		inlen = tmplen;
	}

	r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
	if (r != SC_SUCCESS) {
		sc_mem_clear(buf, sizeof(buf));
		LOG_FUNC_RETURN(ctx, r);
	}
	senv.algorithm_flags = sec_flags;

	sc_log(ctx, "DEE flags:0x%8.8x alg_info->flags:0x%8.8x pad:0x%8.8x sec:0x%8.8x",
		flags, alg_info->flags, pad_flags, sec_flags);

	/* add the padding bytes (if necessary) */
	if (pad_flags != 0) {
		size_t tmplen = sizeof(buf);

		r = sc_pkcs1_encode(ctx, pad_flags, tmp, inlen, tmp, &tmplen, modlen);
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "Unable to add padding");

		inlen = tmplen;
	}
	else if ( senv.algorithm == SC_ALGORITHM_RSA &&
			(flags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) {
		/* Add zero-padding if input is shorter than the modulus */
		if (inlen < modlen) {
			if (modlen > sizeof(buf))
				return SC_ERROR_BUFFER_TOO_SMALL;
			memmove(tmp+modlen-inlen, tmp, inlen);
			memset(tmp, 0, modlen-inlen);
		}
		inlen = modlen;
	}

	senv.operation = SC_SEC_OPERATION_SIGN;

	/* optional keyReference attribute (the default value is -1) */
	if (prkey->key_reference >= 0) {
		senv.key_ref_len = 1;
		senv.key_ref[0] = prkey->key_reference & 0xFF;
		senv.flags |= SC_SEC_ENV_KEY_REF_PRESENT;
	}

	r = sc_lock(p15card->card);
	LOG_TEST_RET(ctx, r, "sc_lock() failed");

	sc_log(ctx, "Private key path '%s'", sc_print_path(&prkey->path));
	if (prkey->path.len != 0 || prkey->path.aid.len != 0) {
		r = select_key_file(p15card, prkey, &senv);
		if (r < 0) {
			sc_unlock(p15card->card);
			LOG_TEST_RET(ctx, r,"Unable to select private key file");
		}
	}

	r = sc_set_security_env(p15card->card, &senv, 0);
	if (r < 0) {
		sc_unlock(p15card->card);
		LOG_TEST_RET(ctx, r, "sc_set_security_env() failed");
	}

	r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
	if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
		if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
			r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);

	sc_mem_clear(buf, sizeof(buf));
	sc_unlock(p15card->card);
	LOG_TEST_RET(ctx, r, "sc_compute_signature() failed");

	LOG_FUNC_RETURN(ctx, r);
}
Example #26
0
/* derive one key from another. RSA can use decipher, so this is for only ECDH
 * Since the value may be returned, and the call is expected to provide
 * the buffer, we used the PKCS#11 convention of outlen == 0 and out == NULL
 * to indicate that this is a request for the size.
 * In that case r = 0, and *poutlen = expected size
 */
LIBOPENSC_API int sc_pkcs15_derive(struct sc_pkcs15_card *p15card,
		       const struct sc_pkcs15_object *obj,
		       unsigned long flags,
		       const u8 * in, size_t inlen, u8 *out,
		       unsigned long *poutlen)
{
	sc_context_t *ctx = p15card->card->ctx;
	int r;
	sc_algorithm_info_t *alg_info;
	sc_security_env_t senv;
	const struct sc_pkcs15_prkey_info *prkey = (const struct sc_pkcs15_prkey_info *) obj->data;
	unsigned long pad_flags = 0, sec_flags = 0;

	LOG_FUNC_CALLED(ctx);

	memset(&senv, 0, sizeof(senv));

	/* Card driver should have the access to supported algorithms from 'tokenInfo'. So that
	 * it can get value of card specific 'AlgorithmInfo::algRef'. */
	memcpy(&senv.supported_algos, &p15card->tokeninfo->supported_algos, sizeof(senv.supported_algos));

	/* If the key is not native, we can't operate with it. */
	if (!prkey->native)
		LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "This key is not native, cannot operate with it");

	if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_DERIVE)))
		LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "This key cannot be used for derivation");

	switch (obj->type) {
		case SC_PKCS15_TYPE_PRKEY_EC:
			alg_info = sc_card_find_ec_alg(p15card->card, prkey->field_length);
			if (alg_info == NULL) {
				sc_log(ctx, "Card does not support EC with field_size %d", prkey->field_length);
				LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
			}

			if (out == NULL || *poutlen < (prkey->field_length +7) / 8) {
			    *poutlen = (prkey->field_length +7) / 8;
			    r = 0; /* say no data to return */
			    goto out;
			}

			senv.algorithm = SC_ALGORITHM_EC;
			senv.flags |= SC_SEC_ENV_ALG_PRESENT;

			senv.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
			senv.algorithm_ref = prkey->field_length;
			break;
		default:
			LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED,"Key type not supported");
	}

	r = sc_get_encoding_flags(ctx, flags, alg_info->flags, &pad_flags, &sec_flags);
	LOG_TEST_RET(ctx, r, "cannot encode security operation flags");

	senv.algorithm_flags = sec_flags;
	senv.operation       = SC_SEC_OPERATION_DERIVE;
	/* optional keyReference attribute (the default value is -1) */
	if (prkey->key_reference >= 0) {
		senv.key_ref_len = 1;
		senv.key_ref[0] = prkey->key_reference & 0xFF;
		senv.flags |= SC_SEC_ENV_KEY_REF_PRESENT;
	}

	r = sc_lock(p15card->card);
	LOG_TEST_RET(ctx, r, "sc_lock() failed");

	if (prkey->path.len != 0 || prkey->path.aid.len != 0)   {
		r = select_key_file(p15card, prkey, &senv);
		if (r < 0) {
			sc_unlock(p15card->card);
			LOG_TEST_RET(ctx, r,"Unable to select private key file");
		}
	}

	r = sc_set_security_env(p15card->card, &senv, 0);
	if (r < 0) {
		sc_unlock(p15card->card);
		LOG_TEST_RET(ctx, r, "sc_set_security_env() failed");
	}
/* TODO Do we need a sc_derive? PIV at least can use the decipher,
 * senv.operation       = SC_SEC_OPERATION_DERIVE;
 */
	r = sc_decipher(p15card->card, in, inlen, out, *poutlen);
	if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
		if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
			r = sc_decipher(p15card->card, in, inlen, out, *poutlen);
	}
	sc_unlock(p15card->card);
	LOG_TEST_RET(ctx, r, "sc_decipher/derive() failed");

	/* Strip any padding */
	if (pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
		size_t s = r;
		r = sc_pkcs1_strip_02_padding(out, s, out, &s);
		LOG_TEST_RET(ctx, r, "Invalid PKCS#1 padding");
	}

	/* If card stores derived key on card, then no data is returned
         * and the key must be used on the card. */
	*poutlen = r;
out:
	LOG_FUNC_RETURN(ctx, r);
}
Example #27
0
int main(int argc, char *const argv[])
{
	int err = 0, r, c, long_optind = 0;
	int do_info = 0;
	int do_format = 0;
	int do_change_startkey = 0;
	int action_count = 0;
	const char *opt_driver = NULL;
	const char *opt_startkey = NULL;
	const char *opt_change_startkey = NULL;
	sc_context_param_t ctx_param;

	while (1) {
		c = getopt_long(argc, argv, "hifs:r:vdc:wS:", options,
				&long_optind);
		if (c == -1)
			break;
		switch (c) {
		case 'h':
			printf("NB! This tool is only for Siemens CardOS based cards!\n\n");
			util_print_usage_and_die(app_name, options, option_help);
		case 'i':
			do_info = 1;
			action_count++;
			break;
		case 'f':
			do_format = 1;
			action_count++;
			break;
		case 's':
			opt_startkey = optarg;
			break;
		case 'S':
			do_change_startkey = 1;
			opt_change_startkey = optarg;
			action_count++;
			break;
		case 'r':
			opt_reader = optarg;
			break;
		case 'v':
			verbose++;
			break;
		case 'c':
			opt_driver = optarg;
			break;
		case 'w':
			opt_wait = 1;
			break;
		}
	}

	/* create sc_context_t object */
	memset(&ctx_param, 0, sizeof(ctx_param));
	ctx_param.ver      = 0;
	ctx_param.app_name = app_name;
	r = sc_context_create(&ctx, &ctx_param);
	if (r) {
		fprintf(stderr, "Failed to establish context: %s\n",
			sc_strerror(r));
		return 1;
	}

	if (verbose > 1) {
		ctx->debug = verbose;
		ctx->debug_file = stderr;
	}

	if (opt_driver != NULL) {
		err = sc_set_card_driver(ctx, opt_driver);
		if (err) {
			fprintf(stderr, "Driver '%s' not found!\n",
				opt_driver);
			err = 1;
			goto end;
		}
	}

	err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose);
	if (err)
		goto end;

	if (do_info) {
		if ((err = cardos_info())) {
			goto end;
		}
		action_count--;
	}
	if (do_change_startkey) {
		if ((err = cardos_change_startkey(opt_change_startkey))) {
			goto end;
		}
		action_count--;
	}
	if (do_format) {
		if ((err = cardos_format(opt_startkey))) {
			goto end;
		}
		action_count--;
	}
      end:
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card);
	}
	if (ctx)
		sc_release_context(ctx);
	return err;
}
Example #28
0
/*
 * Verify a PIN.
 *
 * If the code given to us has zero length, this means we
 * should ask the card reader to obtain the PIN from the
 * reader's PIN pad
 */
int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
			 struct sc_pkcs15_object *pin_obj,
			 const unsigned char *pincode, size_t pinlen)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_pkcs15_pin_info *pin_info = (struct sc_pkcs15_pin_info *)pin_obj->data;
	int r;
	sc_card_t *card;
	struct sc_pin_cmd_data data;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "PIN(%p;len:%i)", pincode, pinlen);

	r = _validate_pin(p15card, pin_info, pinlen);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "PIN value do not conforms the PIN policy");

	card = p15card->card;

	r = sc_lock(card);
	SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
	/* the path in the pin object is optional */
	if (pin_info->path.len > 0) {
		r = sc_select_file(card, &pin_info->path, NULL);
		if (r)
			goto out;
	}

	/* Initialize arguments */
	memset(&data, 0, sizeof(data));
	data.cmd = SC_PIN_CMD_VERIFY;
	data.pin_type = pin_info->auth_method;
	data.pin_reference = pin_info->reference;
	data.pin1.min_length = pin_info->min_length;
	data.pin1.max_length = pin_info->max_length;
	data.pin1.pad_length = pin_info->stored_length;
	data.pin1.pad_char = pin_info->pad_char;
	data.pin1.data = pincode;
	data.pin1.len = pinlen;

	if (pin_info->flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDING)
		data.flags |= SC_PIN_CMD_NEED_PADDING;

	switch (pin_info->type) {
	case SC_PKCS15_PIN_TYPE_BCD:
		data.pin1.encoding = SC_PIN_ENCODING_BCD;
		break;
	case SC_PKCS15_PIN_TYPE_ASCII_NUMERIC:
		data.pin1.encoding = SC_PIN_ENCODING_ASCII;
		break;
	default:
		/* assume/hope the card driver knows how to encode the pin */
		data.pin1.encoding = 0;
	}

	if(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
		if (!pincode && !pinlen)
			data.flags |= SC_PIN_CMD_USE_PINPAD;
		if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)
			data.pin1.prompt = "Please enter SO PIN";
		else
			data.pin1.prompt = "Please enter PIN";
	}

	r = sc_pin_cmd(card, &data, &pin_info->tries_left);
	if (r == SC_SUCCESS)
		sc_pkcs15_pincache_add(p15card, pin_obj, pincode, pinlen);
out:
	sc_unlock(card);
	return r;
}
Example #29
0
int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
{
	int r = SC_SUCCESS;

	if (card == NULL || apdu == NULL)
		return SC_ERROR_INVALID_ARGUMENTS;

	LOG_FUNC_CALLED(card->ctx);

	/* determine the APDU type if necessary, i.e. to use
	 * short or extended APDUs  */
	sc_detect_apdu_cse(card, apdu);
	/* basic APDU consistency check */
	r = sc_check_apdu(card, apdu);
	if (r != SC_SUCCESS)
		return SC_ERROR_INVALID_ARGUMENTS;

	r = sc_lock(card);	/* acquire card lock*/
	if (r != SC_SUCCESS) {
		sc_log(card->ctx, "unable to acquire lock");
		return r;
	}

	if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) {
		/* divide et impera: transmit APDU in chunks with Lc <= max_send_size
		 * bytes using command chaining */
		size_t    len  = apdu->datalen;
		const u8  *buf = apdu->data;
		size_t    max_send_size = card->max_send_size;

		while (len != 0) {
			size_t    plen;
			sc_apdu_t tapdu;
			int       last = 0;

			tapdu = *apdu;
			/* clear chaining flag */
			tapdu.flags &= ~SC_APDU_FLAGS_CHAINING;
			if (len > max_send_size) {
				/* adjust APDU case: in case of CASE 4 APDU
				 * the intermediate APDU are of CASE 3 */
				if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT)
					tapdu.cse--;
				/* XXX: the chunk size must be adjusted when
				 *      secure messaging is used */
				plen          = max_send_size;
				tapdu.cla    |= 0x10;
				tapdu.le      = 0;
				/* the intermediate APDU don't expect data */
				tapdu.lc      = 0;
				tapdu.resplen = 0;
				tapdu.resp    = NULL;
			} else {
				plen = len;
				last = 1;
			}
			tapdu.data    = buf;
			tapdu.datalen = tapdu.lc = plen;

			r = sc_check_apdu(card, &tapdu);
			if (r != SC_SUCCESS) {
				sc_log(card->ctx, "inconsistent APDU while chaining");
				break;
			}

			r = sc_transmit(card, &tapdu);
			if (r != SC_SUCCESS)
				break;
			if (last != 0) {
				/* in case of the last APDU set the SW1
				 * and SW2 bytes in the original APDU */
				apdu->sw1 = tapdu.sw1;
				apdu->sw2 = tapdu.sw2;
				apdu->resplen = tapdu.resplen;
			} else {
				/* otherwise check the status bytes */
				r = sc_check_sw(card, tapdu.sw1, tapdu.sw2);
				if (r != SC_SUCCESS)
					break;
			}
			len -= plen;
			buf += plen;
		}
	} else
		/* transmit single APDU */
		r = sc_transmit(card, apdu);
	/* all done => release lock */
	if (sc_unlock(card) != SC_SUCCESS)
		sc_log(card->ctx, "sc_unlock failed");

	return r;
}
Example #30
0
/*
 * Unblock a PIN.
 */
int sc_pkcs15_unblock_pin(struct sc_pkcs15_card *p15card,
			 struct sc_pkcs15_object *pin_obj,
			 const u8 *puk, size_t puklen,
			 const u8 *newpin, size_t newpinlen)
{
	int r;
	sc_card_t *card;
	struct sc_pin_cmd_data data;
	struct sc_pkcs15_object *puk_obj;
	struct sc_pkcs15_pin_info *puk_info = NULL;
	struct sc_pkcs15_pin_info *pin_info = (struct sc_pkcs15_pin_info *)pin_obj->data;

	/* make sure the pins are in valid range */
	if ((r = _validate_pin(p15card, pin_info, newpinlen)) != SC_SUCCESS)
		return r;

	card = p15card->card;
	/* get pin_info object of the puk (this is a little bit complicated
	 * as we don't have the id of the puk (at least now))
	 * note: for compatibility reasons we give no error if no puk object
	 * is found */
	/* first step: try to get the pkcs15 object of the puk */
	r = sc_pkcs15_find_pin_by_auth_id(p15card, &pin_obj->auth_id, &puk_obj);
	if (r >= 0 && puk_obj) {
		/* second step:  get the pkcs15 info object of the puk */
		puk_info = (struct sc_pkcs15_pin_info *)puk_obj->data;
	}
	if (!puk_info) {
		sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unable to get puk object, using pin object instead!");
		puk_info = pin_info;
	}
	
	/* make sure the puk is in valid range */
	if ((r = _validate_pin(p15card, puk_info, puklen)) != SC_SUCCESS)
		return r;

	r = sc_lock(card);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "sc_lock() failed");
	/* the path in the pin object is optional */
	if (pin_info->path.len > 0) {
		r = sc_select_file(card, &pin_info->path, NULL);
		if (r)
			goto out;
	}

	/* set pin_cmd data */
	memset(&data, 0, sizeof(data));
	data.cmd             = SC_PIN_CMD_UNBLOCK;
	data.pin_type        = SC_AC_CHV;
	data.pin_reference   = pin_info->reference;
	data.pin1.data       = puk;
	data.pin1.len        = puklen;
	data.pin1.pad_char   = pin_info->pad_char;
	data.pin1.min_length = pin_info->min_length;
	data.pin1.max_length = pin_info->max_length;
	data.pin1.pad_length = pin_info->stored_length;
	data.pin2.data       = newpin;
	data.pin2.len        = newpinlen;
	data.pin2.pad_char   = puk_info->pad_char;
	data.pin2.min_length = puk_info->min_length;
	data.pin2.max_length = puk_info->max_length;
	data.pin2.pad_length = puk_info->stored_length;

	if (pin_info->flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDING)
		data.flags |= SC_PIN_CMD_NEED_PADDING;

	switch (pin_info->type) {
	case SC_PKCS15_PIN_TYPE_BCD:
		data.pin1.encoding = SC_PIN_ENCODING_BCD;
		break;
	case SC_PKCS15_PIN_TYPE_ASCII_NUMERIC:
		data.pin1.encoding = SC_PIN_ENCODING_ASCII;
		break;
	}

	switch (puk_info->type) {
	case SC_PKCS15_PIN_TYPE_BCD:
		data.pin2.encoding = SC_PIN_ENCODING_BCD;
		break;
	case SC_PKCS15_PIN_TYPE_ASCII_NUMERIC:
		data.pin2.encoding = SC_PIN_ENCODING_ASCII;
		break;
	}
	
	if(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
		data.flags |= SC_PIN_CMD_USE_PINPAD;
		if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
			data.pin1.prompt = "Please enter PUK";
			data.pin2.prompt = "Please enter new SO PIN";
		} else {
			data.pin1.prompt = "Please enter PUK";
			data.pin2.prompt = "Please enter new PIN";
		}
	}

	r = sc_pin_cmd(card, &data, &pin_info->tries_left);
	if (r == SC_SUCCESS)
		sc_pkcs15_pincache_add(p15card, pin_obj, newpin, newpinlen);

out:
	sc_unlock(card);
	return r;
}