Esempio n. 1
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;

	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);
}
Esempio n. 2
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);
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}