⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framework-pkcs15.c

📁 读写Smart卡加解密接口的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (pool_is_present(&slot->object_pool, obj))		return;	pool_insert(&slot->object_pool, obj, pHandle);	obj->base.flags |= SC_PKCS11_OBJECT_SEEN;	obj->refcount++;	/* Add related objects	 * XXX prevent infinite recursion when a card specifies two certificates	 * referring to each other.	 */	obj->base.flags |= SC_PKCS11_OBJECT_RECURS;	switch (__p15_type(obj)) {	case SC_PKCS15_TYPE_PRKEY_RSA:		if (obj->related_cert == NULL)			pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);		pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL);		break;	case SC_PKCS15_TYPE_CERT_X509:		pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL);		pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL);		break;	}	obj->base.flags &= ~SC_PKCS11_OBJECT_RECURS;}static void pkcs15_init_slot(struct sc_pkcs15_card *card,		struct sc_pkcs11_slot *slot,		struct sc_pkcs15_object *auth){	struct pkcs15_slot_data *fw_data;	struct sc_pkcs15_pin_info *pin_info = NULL;	char tmp[64];	pkcs15_init_token_info(card, &slot->token_info);	slot->token_info.flags |= CKF_USER_PIN_INITIALIZED				| CKF_TOKEN_INITIALIZED;	if (card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) {		slot->token_info.flags |= CKF_PROTECTED_AUTHENTICATION_PATH;		sc_pkcs11_conf.cache_pins = 0;	}	if (card->card->caps & SC_CARD_CAP_RNG)		slot->token_info.flags |= CKF_RNG;	slot->fw_data = fw_data = (struct pkcs15_slot_data *) calloc(1, sizeof(*fw_data));	fw_data->auth_obj = auth;	if (auth != NULL) {		pin_info = (struct sc_pkcs15_pin_info*) auth->data;		if (auth->label[0]) {			snprintf(tmp, sizeof(tmp), "%s (%s)",				card->label, auth->label);		} else {			snprintf(tmp, sizeof(tmp), "%s", card->label);		}		slot->token_info.flags |= CKF_LOGIN_REQUIRED;	} else		sprintf(tmp, card->label);	strcpy_bp(slot->token_info.label, tmp, 32);	if (pin_info && pin_info->magic == SC_PKCS15_PIN_MAGIC) {		slot->token_info.ulMaxPinLen = pin_info->max_length;		slot->token_info.ulMinPinLen = pin_info->min_length;	} else {		/* choose reasonable defaults */		slot->token_info.ulMaxPinLen = 8;		slot->token_info.ulMinPinLen = 4;	}	sc_debug(context, "Initialized token '%s'\n", tmp);}static CK_RV pkcs15_create_slot(struct sc_pkcs11_card *p11card,		struct sc_pkcs15_object *auth,		struct sc_pkcs11_slot **out){        struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	struct sc_pkcs11_slot *slot;	int rv;	rv = slot_allocate(&slot, p11card);	if (rv != CKR_OK)		return rv;	/* There's a token in this slot */	slot->slot_info.flags |= CKF_TOKEN_PRESENT;	/* Fill in the slot/token info from pkcs15 data */	pkcs15_init_slot(fw_data->p15_card, slot, auth);	*out = slot;	return CKR_OK;}static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card){	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	struct sc_pkcs15_object *auths[MAX_OBJECTS];	struct sc_pkcs11_slot *slot;	int i, rv, reader = p11card->reader;        int auth_count;	unsigned int j;        rv = sc_pkcs15_get_objects(fw_data->p15_card,					SC_PKCS15_TYPE_AUTH_PIN,					auths,					SC_PKCS15_MAX_PINS);	if (rv < 0)                return sc_to_cryptoki_error(rv, reader);	sc_debug(context, "Found %d authentication objects\n", rv);	auth_count = rv;        rv = pkcs15_create_pkcs11_objects(fw_data,				SC_PKCS15_TYPE_PRKEY_RSA,				"private key",				__pkcs15_create_prkey_object); 	if (rv < 0)                return sc_to_cryptoki_error(rv, reader);        rv = pkcs15_create_pkcs11_objects(fw_data,				SC_PKCS15_TYPE_PUBKEY_RSA,				"public key",				__pkcs15_create_pubkey_object); 	if (rv < 0)                return sc_to_cryptoki_error(rv, reader);	rv = pkcs15_create_pkcs11_objects(fw_data,				SC_PKCS15_TYPE_CERT_X509,				"certificate",				__pkcs15_create_cert_object);	if (rv < 0)                return sc_to_cryptoki_error(rv, reader);	/* Match up related keys and certificates */	pkcs15_bind_related_objects(fw_data);	for (i = 0; i < auth_count; i++) {		struct sc_pkcs15_pin_info *pin_info = NULL;		pin_info = (struct sc_pkcs15_pin_info*) auths[i]->data;		/* Ignore any non-authentication PINs */		if ((pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN)		 || (pin_info->flags & SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN))			continue;		/* Add all the private keys related to this pin */		rv = pkcs15_create_slot(p11card, auths[i], &slot);		if (rv != CKR_OK)			return rv;		for (j=0; j < fw_data->num_objects; j++) {			struct pkcs15_any_object *obj = fw_data->objects[j];			if (!is_privkey(obj)			 || !sc_pkcs15_compare_id(&pin_info->auth_id,						  &obj->p15_object->auth_id))				continue;			sc_debug(context, "Adding private key %d to PIN %d\n", j, i);			pkcs15_add_object(slot, obj, NULL);		}	}	/* Add all public objects to a virtual slot without pin protection */	slot = NULL;	/* Add all the remaining objects */	for (j = 0; j < fw_data->num_objects; j++) {		struct pkcs15_any_object *obj = fw_data->objects[j];		if (!(obj->base.flags & SC_PKCS11_OBJECT_SEEN)) {                        sc_debug(context, "Object %d was not seen previously\n", j);			if (!slot) {				rv = pkcs15_create_slot(p11card, NULL, &slot);				if (rv != CKR_OK)					return rv;			}			pkcs15_add_object(slot, obj, NULL);		}	}	/* Create read/write slots */	while (slot_allocate(&slot, p11card) == CKR_OK) {		if (!sc_pkcs11_conf.hide_empty_tokens) {			slot->slot_info.flags |= CKF_TOKEN_PRESENT;			pkcs15_init_token_info(fw_data->p15_card, &slot->token_info);			strcpy_bp(slot->token_info.label, fw_data->p15_card->label, 32);			slot->token_info.flags |= CKF_TOKEN_INITIALIZED;		}	}	sc_debug(context, "All tokens created\n");	return CKR_OK;}static CK_RV pkcs15_release_token(struct sc_pkcs11_card *p11card, void *fw_token){	unlock_card((struct pkcs15_fw_data *) p11card->fw_data);        return CKR_OK;}static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card,			  void *fw_token,			  CK_USER_TYPE userType,			  CK_CHAR_PTR pPin,			  CK_ULONG ulPinLen){	int rc;	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	struct sc_pkcs15_card *card = fw_data->p15_card;        struct sc_pkcs15_object *auth_object;	struct sc_pkcs15_pin_info *pin;	switch (userType) {	case CKU_USER:		auth_object = slot_data_auth(fw_token);		if (auth_object == NULL)			return CKR_USER_PIN_NOT_INITIALIZED;		break;	case CKU_SO:		/* A card with no SO PIN is treated as if no SO login		 * is required */		rc = sc_pkcs15_find_so_pin(card, &auth_object);		/* If there's no SO PIN on the card, silently		 * accept any PIN, and lock the card if required */		if (rc == SC_ERROR_OBJECT_NOT_FOUND		 && sc_pkcs11_conf.lock_login)			rc = lock_card(fw_data);		if (rc < 0)			return sc_to_cryptoki_error(rc, p11card->reader);		break;	default:		return CKR_USER_TYPE_INVALID;	}	pin = (struct sc_pkcs15_pin_info *) auth_object->data;	if (p11card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) {		/* pPin should be NULL in case of a pin pad reader, but		 * some apps (e.g. older Netscapes) don't know about it.		 * So we don't require that pPin == NULL, but set it to		 * NULL ourselves. This way, you can supply an empty (if		 * possible) or fake PIN if an application asks a PIN).		 */		pPin = NULL;		ulPinLen = 0;	} else	if (ulPinLen < pin->min_length ||	    ulPinLen > pin->max_length)		return CKR_ARGUMENTS_BAD;	/* By default, we make the pcsc daemon keep other processes	 * from accessing the card while we're logged in. Otherwise	 * an attacker could perform some crypto operation after	 * we've authenticated with the card */	if (sc_pkcs11_conf.lock_login && (rc = lock_card(fw_data)) < 0)		return sc_to_cryptoki_error(rc, p11card->reader);	rc = sc_pkcs15_verify_pin(card, pin, pPin, ulPinLen);        sc_debug(context, "PIN verification returned %d\n", rc);		if (rc >= 0)		cache_pin(fw_token, userType, pPin, ulPinLen);	return sc_to_cryptoki_error(rc, p11card->reader);}static CK_RV pkcs15_logout(struct sc_pkcs11_card *p11card, void *fw_token){	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	int rc = 0;	cache_pin(fw_token, CKU_SO, NULL, 0);	cache_pin(fw_token, CKU_USER, NULL, 0);	sc_logout(fw_data->p15_card->card);	if (sc_pkcs11_conf.lock_login)		rc = unlock_card(fw_data);	return sc_to_cryptoki_error(rc, p11card->reader);}static CK_RV pkcs15_change_pin(struct sc_pkcs11_card *p11card,			  void *fw_token,			  CK_CHAR_PTR pOldPin, CK_ULONG ulOldLen,			  CK_CHAR_PTR pNewPin, CK_ULONG ulNewLen){	int rc;	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	struct sc_pkcs15_pin_info *pin;	if (!(pin = slot_data_pin_info(fw_token)))		return CKR_USER_PIN_NOT_INITIALIZED;	if (p11card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) {		/* pPin should be NULL in case of a pin pad reader, but		 * some apps (e.g. older Netscapes) don't know about it.		 * So we don't require that pPin == NULL, but set it to		 * NULL ourselves. This way, you can supply an empty (if		 * possible) or fake PIN if an application asks a PIN).		 */		pOldPin = pNewPin = NULL;		ulOldLen = ulNewLen = 0;	} else	if (ulNewLen < pin->min_length ||	    ulNewLen > pin->max_length)		return CKR_PIN_LEN_RANGE;	rc = sc_pkcs15_change_pin(fw_data->p15_card, pin, pOldPin, ulOldLen,				pNewPin, ulNewLen);        sc_debug(context, "PIN verification returned %d\n", rc);	if (rc >= 0)		cache_pin(fw_token, CKU_USER, pNewPin, ulNewLen);	return sc_to_cryptoki_error(rc, p11card->reader);}#ifdef USE_PKCS15_INITstatic CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,			struct sc_pkcs11_slot *slot,			CK_CHAR_PTR pPin, CK_ULONG ulPinLen){	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	struct sc_pkcs15init_pinargs args;	struct sc_profile	*profile;	struct sc_pkcs15_object	*auth_obj;	int			rc;	rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile);	if (rc < 0)		return sc_to_cryptoki_error(rc, p11card->reader);	memset(&args, 0, sizeof(args));	args.label = "User PIN";	args.pin = pPin;	args.pin_len = ulPinLen;	rc = sc_pkcs15init_store_pin(fw_data->p15_card, profile, &args);	sc_pkcs15init_unbind(profile);	if (rc < 0)		return sc_to_cryptoki_error(rc, p11card->reader);	rc = sc_pkcs15_find_pin_by_auth_id(fw_data->p15_card, &args.auth_id, &auth_obj);	if (rc < 0)		return sc_to_cryptoki_error(rc, p11card->reader);	/* Re-initialize the slot */	free(slot->fw_data);	pkcs15_init_slot(fw_data->p15_card, slot, auth_obj);	cache_pin(slot->fw_data, CKU_USER, pPin, ulPinLen);	return CKR_OK;}static CK_RV pkcs15_create_private_key(struct sc_pkcs11_card *p11card,		struct sc_pkcs11_slot *slot,		struct sc_profile *profile,		CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,		CK_OBJECT_HANDLE_PTR phObject){	struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;	struct sc_pkcs15init_prkeyargs args;	struct pkcs15_any_object *key_any_obj;	struct sc_pkcs15_object	*key_obj;	struct sc_pkcs15_pin_info *pin;	CK_KEY_TYPE		key_type;	struct sc_pkcs15_prkey_rsa *rsa;	int			rc, rv;	memset(&args, 0, sizeof(args));	/* See if the "slot" is pin protected. If so, get the	 * PIN id */	if ((pin = slot_data_pin_info(slot->fw_data)) != NULL)		args.auth_id = pin->auth_id;	/* Get the key type */	rv = attr_find(pTemplate, ulCount, CKA_KEY_TYPE, &key_type, NULL);	if (rv != CKR_OK)		return rv;	if (key_type != CKK_RSA)		return CKR_ATTRIBUTE_VALUE_INVALID;	args.key.algorithm = SC_ALGORITHM_RSA;	rsa = &args.key.u.rsa;	rv = CKR_OK;	while (ulCount--) {		CK_ATTRIBUTE_PTR attr = pTemplate++;		sc_pkcs15_bignum_t *bn = NULL;		switch (attr->type) {		/* Skip attrs we already know or don't care for */		case CKA_CLASS:		case CKA_KEY_TYPE:		case CKA_MODULUS_BITS:		case CKA_PRIVATE:		       	break;		case CKA_LABEL:			args.label = (char *) attr->pValue;			break;		case CKA_ID:			args.id.len = sizeof(args.id.value);			rv = attr_extract(attr, args.id.value, &args.id.len);			if (rv != CKR_OK)				goto out;			break;		case CKA_MODULUS:			bn = &rsa->modulus; break;		case CKA_PUBLIC_EXPONENT:			bn = &rsa->exponent; break;		case CKA_PRIVATE_EXPONENT:			bn = &rsa->d; break;		case CKA_PRIME_1:			bn = &rsa->p; break;		case CKA_PRIME_2:			bn = &rsa->q; break;		default:			/* ignore unknown attrs, or flag error? */			continue;		}		if (bn) {			if (attr->ulValueLen > 1024)				return CKR_ATTRIBUTE_VALUE_INVALID;			bn->len = attr->ulValueLen;			bn->data = (u8 *) attr->pValue;		}	}	if (!rsa->modulus.len || !rsa->exponent.len || !rsa->d.len	 || !rsa->p.len || !rsa->q.len) {		rv = CKR_TEMPLATE_INCOMPLETE;		goto out;	}	rc = sc_pkcs15init_store_private_key(fw_data->p15_card, profile, &args, &key_obj);	if (rc < 0) {		rv = sc_to_cryptoki_error(rc, p11card->reader);		goto out;	}	/* Create a new pkcs11 object for it */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -