예제 #1
0
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;
}
예제 #2
0
파일: pkcs15-pin.c 프로젝트: BradPID/OpenSC
/* Validate the PIN code associated with an object */
int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_object_t *pin_obj;
	int r;

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

	/*  Apps that do not support CK_ALWAYS_AUTHENTICATE
	 *  may need pin_cache_ignore_user_consent = 1 */
	if (!p15card->opts.pin_cache_ignore_user_consent) {
	    if (obj->user_consent)
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}

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

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

	if (pin_obj->usage_counter >= p15card->opts.pin_cache_counter) {
		sc_pkcs15_free_object_content(pin_obj);
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
	}

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

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

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

	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
예제 #3
0
/* Validate the PIN code associated with an object */
int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj)
{
	struct sc_context *ctx = p15card->card->ctx;
	sc_pkcs15_object_t *pin_obj;
	int r;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);

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

	if (obj->user_consent)
		return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;

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

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

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

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

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

	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
}
예제 #4
0
파일: pintest.c 프로젝트: AktivCo/OpenSC
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;
}
예제 #5
0
int ask_and_verify_pin_code(struct sc_pkcs15_card *p15card,
			    struct sc_pkcs15_object *pin)
{
	int r;
	size_t len;
	const char *argv[3];
	const char *pgmname = PIN_ENTRY;
	ASSUAN_CONTEXT ctx;
	char buf[500];
	char errtext[100];
	struct entry_parm_s parm;
	struct sc_pkcs15_pin_info *pinfo = (struct sc_pkcs15_pin_info *) pin->data;
	
	argv[0] = pgmname;
	argv[1] = NULL;
	
	r = assuan_pipe_connect(&ctx, pgmname, (char **) argv, NULL);
	if (r) {
		printf("Can't connect to the PIN entry module: %s\n",
		       assuan_strerror((AssuanError) r));
		goto err;
	}
	sprintf(buf, "SETDESC Enter PIN [%s] for digital signing  ", pin->label);
	r = assuan_transact(ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
	if (r) {
		printf("SETDESC: %s\n", assuan_strerror((AssuanError) r));
		goto err;
	}
	errtext[0] = 0;
	while (1) {
		if (errtext[0]) {
			sprintf(buf, "SETERROR %s", errtext);
			r = assuan_transact(ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL);
			errtext[0] = 0;
		}
		parm.lines = 0;
		parm.size = sizeof(buf);
		parm.buffer = buf;
		r = assuan_transact(ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL);
		if (r == ASSUAN_Canceled) {
			assuan_disconnect(ctx);
			return -2;
		}
		if (r) {
			printf("GETPIN: %s\n", assuan_strerror((AssuanError) r));
			goto err;
		}
		len = strlen(buf);
		if (len < pinfo->min_length) {
			sprintf(errtext, "PIN code too short, min. %lu digits", (unsigned long) pinfo->min_length);
			continue;
		}
		if (len > pinfo->max_length) {
			sprintf(errtext, "PIN code too long, max. %lu digits", (unsigned long) pinfo->max_length);
			continue;
		}
		r = sc_pkcs15_verify_pin(p15card, pinfo, (const u8 *) buf, strlen(buf));
		switch (r) {
		case SC_ERROR_PIN_CODE_INCORRECT:
			sprintf(errtext, "PIN code incorrect (%d %s left)",
			       pinfo->tries_left, pinfo->tries_left == 1 ?
			       "try" : "tries");
			break;
		case 0:
			break;
		default:
			goto err;
		}
		if (r == 0)
			break;
	}

	assuan_disconnect(ctx);	
	return 0;
err:	
	assuan_disconnect(ctx);
	return -1;
}
예제 #6
0
static int 
sc_oberthur_read_file(struct sc_pkcs15_card *p15card, const char *in_path, 
		unsigned char **out, size_t *out_len,
		int verify_pin)
{
	struct sc_context *ctx = p15card->card->ctx;
	struct sc_card *card = p15card->card;
	struct sc_file *file = NULL;
	struct sc_path path;
	size_t sz;
	int rv;

	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
	if (!in_path || !out || !out_len)
		SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ARGUMENTS, "Cannot read oberthur file");
		
	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "read file '%s'; verify_pin:%i", in_path, verify_pin);
	
	*out = NULL;
	*out_len = 0;
	
	sc_format_path(in_path, &path);
	rv = sc_select_file(card, &path, &file);
	SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot select oberthur file to read");

	if (file->ef_structure == SC_FILE_EF_TRANSPARENT)
		sz = file->size;
	else
		sz = (file->record_length + 2) * file->record_count;
	
	*out = calloc(sz, 1);
	if (*out == NULL)
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_MEMORY_FAILURE, "Cannot read oberthur file");

	if (file->ef_structure == SC_FILE_EF_TRANSPARENT)   {
		rv = sc_read_binary(card, 0, *out, sz, 0);
	}
	else	{
		int rec;
		int offs = 0;
		int rec_len = file->record_length;
		
		for (rec = 1; ; rec++)   {
			rv = sc_read_record(card, rec, *out + offs + 2, rec_len, SC_RECORD_BY_REC_NR);
			if (rv == SC_ERROR_RECORD_NOT_FOUND)   {
				rv = 0;
				break;
			}
			else if (rv < 0)   {
				break;
			}

			rec_len = rv; 
				
			*(*out + offs) = 'R';
			*(*out + offs + 1) = rv;
			
			offs += rv + 2;
		}

		sz = offs;
	}

	sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "read oberthur file result %i", rv);
	if (verify_pin && rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)   {
		struct sc_pkcs15_object *objs[0x10], *pin_obj = NULL;
		const struct sc_acl_entry *acl = sc_file_get_acl_entry(file, SC_AC_OP_READ);
		int ii;

		rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 0x10);
		SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, rv, "Cannot read oberthur file: get AUTH objects error");

		for (ii=0; ii<rv; ii++)   {
			struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *) objs[ii]->data;
			sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "compare PIN/ACL refs:%i/%i, method:%i/%i", 
					auth_info->attrs.pin.reference, acl->key_ref, auth_info->auth_method, acl->method);
			if (auth_info->attrs.pin.reference == (int)acl->key_ref && auth_info->auth_method == (unsigned)acl->method)   {
				pin_obj = objs[ii];
				break;
			}
		}

		if (!pin_obj || !pin_obj->content.value)    {
			rv = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
		}
		else    {
			rv = sc_pkcs15_verify_pin(p15card, pin_obj, pin_obj->content.value, pin_obj->content.len);
			if (!rv)
				rv = sc_oberthur_read_file(p15card, in_path, out, out_len, 0);
		}
	};
			
	sc_file_free(file);

	if (rv < 0)   {
		free(*out);
		*out = NULL;
		*out_len = 0;
	}

	*out_len = sz;

	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, rv);
}
예제 #7
0
static int get_key(unsigned int usage, sc_pkcs15_object_t **result)
{
	sc_pkcs15_object_t *key, *pin;
	const char	*usage_name;
	sc_pkcs15_id_t	id;
	int		r;

	usage_name = (usage & SC_PKCS15_PRKEY_USAGE_SIGN)? "signature" : "decryption";

	if (opt_key_id != NULL) {
		sc_pkcs15_hex_string_to_id(opt_key_id, &id);
		r = sc_pkcs15_find_prkey_by_id_usage(p15card, &id, usage, &key);
		if (r < 0) {
			fprintf(stderr, "Unable to find private %s key '%s': %s\n",
				usage_name, opt_key_id, sc_strerror(r));
			return 2;
		}
	} else {
		r = sc_pkcs15_find_prkey_by_id_usage(p15card, NULL, usage, &key);
		if (r < 0) {
			fprintf(stderr, "Unable to find any private %s key: %s\n",
				usage_name, sc_strerror(r));
			return 2;
		}
	}

	*result = key;

	if (key->auth_id.len) {
		static sc_pkcs15_object_t *prev_pin = NULL;
		char	*pincode;

		r = sc_pkcs15_find_pin_by_auth_id(p15card, &key->auth_id, &pin);
		if (r) {
			fprintf(stderr, "Unable to find PIN code for private key: %s\n",
				sc_strerror(r));
			return 1;
		}

		/* Pin already verified previously */
		if (pin == prev_pin)
			return 0;

		pincode = get_pin(pin);
		if (((pincode == NULL || *pincode == '\0')) &&
		    !(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD))
				return 5;

		r = sc_pkcs15_verify_pin(p15card, pin, (const u8 *)pincode, pincode ? strlen(pincode) : 0);
		if (r) {
			fprintf(stderr, "PIN code verification failed: %s\n", sc_strerror(r));
			return 5;
		}
		free(pincode);
		if (verbose)
			fprintf(stderr, "PIN code correct.\n");
		prev_pin = pin;
	}

	return 0;
}
예제 #8
0
static int
sc_prkey_op_init(RSA *rsa, struct sc_pkcs15_object **key_obj_out,
	unsigned int usage)
{
	int r;
	struct sc_priv_data *priv;
	struct sc_pkcs15_object *key_obj;
	struct sc_pkcs15_prkey_info *key;
	struct sc_pkcs15_object *pin_obj;
	struct sc_pkcs15_pin_info *pin;

	priv = (struct sc_priv_data *) RSA_get_app_data(rsa);
	if (priv == NULL)
		return -1;
	if (p15card == NULL) {
		sc_close();
		r = sc_init();
		if (r) {
			error("SmartCard init failed: %s", sc_strerror(r));
			goto err;
		}
	}
	r = sc_pkcs15_find_prkey_by_id_usage(p15card, &priv->cert_id,
		usage, &key_obj);
	if (r) {
		error("Unable to find private key from SmartCard: %s",
		      sc_strerror(r));
		goto err;
	}
	key = key_obj->data;
	r = sc_pkcs15_find_pin_by_auth_id(p15card, &key_obj->auth_id,
					  &pin_obj);
	if (r == SC_ERROR_OBJECT_NOT_FOUND) {
		/* no pin required */
		r = sc_lock(card);
		if (r) {
			error("Unable to lock smartcard: %s", sc_strerror(r));
			goto err;
		}
		*key_obj_out = key_obj;
		return 0;
	} else if (r) {
		error("Unable to find PIN object from SmartCard: %s",
		      sc_strerror(r));
		goto err;
	}
	pin = pin_obj->data;
	r = sc_lock(card);
	if (r) {
		error("Unable to lock smartcard: %s", sc_strerror(r));
		goto err;
	}
	if (sc_pin != NULL) {
		r = sc_pkcs15_verify_pin(p15card, pin, sc_pin,
					 strlen(sc_pin));
		if (r) {
			sc_unlock(card);
			error("PIN code verification failed: %s",
			      sc_strerror(r));
			goto err;
		}
	}
	*key_obj_out = key_obj;
	return 0;
err:
	sc_close();
	return -1;
}