예제 #1
0
CK_RV
C_DestroyObject(CK_SESSION_HANDLE hSession,	/* the session's handle */
		CK_OBJECT_HANDLE hObject)	/* the object's handle */
{
	CK_RV rv;
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;
	CK_BBOOL is_token = FALSE;
	CK_ATTRIBUTE token_attribure = {CKA_TOKEN, &is_token, sizeof(is_token)};

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	sc_log(context, "C_DestroyObject(hSession=0x%lx, hObject=0x%lx)", hSession, hObject);
	rv = get_object_from_session(hSession, hObject, &session, &object);
	if (rv != CKR_OK)
		goto out;

	object->ops->get_attribute(session, object, &token_attribure);
	if (is_token == TRUE && !(session->flags & CKF_RW_SESSION)) {
		rv = CKR_SESSION_READ_ONLY;
		goto out;
	}

	if (object->ops->destroy_object == NULL)
		rv = CKR_FUNCTION_NOT_SUPPORTED;
	else
		rv = object->ops->destroy_object(session, object);

out:
	sc_pkcs11_unlock();
	return rv;
}
예제 #2
0
CK_RV
C_SignRecoverInit(CK_SESSION_HANDLE hSession,	/* the session's handle */
		CK_MECHANISM_PTR pMechanism,	/* the signature mechanism */
		CK_OBJECT_HANDLE hKey)		/* handle of the signature key */
{
	CK_RV rv;
	CK_BBOOL can_sign;
	CK_KEY_TYPE key_type;
	CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) };
	CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;

	/* FIXME #47: C_SignRecover is not implemented */
	return CKR_FUNCTION_NOT_SUPPORTED;

	if (pMechanism == NULL_PTR)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	rv = get_object_from_session(hSession, hKey, &session, &object);
	if (rv != CKR_OK) {
		if (rv == CKR_OBJECT_HANDLE_INVALID)
			rv = CKR_KEY_HANDLE_INVALID;
		goto out;
	}

	if (object->ops->sign == NULL_PTR) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = object->ops->get_attribute(session, object, &sign_attribute);
	if (rv != CKR_OK || !can_sign) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}
	rv = object->ops->get_attribute(session, object, &key_type_attr);
	if (rv != CKR_OK) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	/* XXX: need to tell the signature algorithm that we want
	 * to recover the signature */
	sc_log(context, "SignRecover operation initialized\n");

	rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type);

out:
	sc_log(context, "C_SignRecoverInit() = %sn", lookup_enum ( RV_T, rv ));
	sc_pkcs11_unlock();
	return rv;
}
예제 #3
0
파일: pkcs11-object.c 프로젝트: jpki/OpenSC
CK_RV C_DecryptInit(CK_SESSION_HANDLE hSession,	/* the session's handle */
		    CK_MECHANISM_PTR pMechanism,	/* the decryption mechanism */
		    CK_OBJECT_HANDLE hKey)
{				/* handle of the decryption key */
	CK_BBOOL can_decrypt, can_unwrap;
	CK_KEY_TYPE key_type;
	CK_ATTRIBUTE decrypt_attribute = { CKA_DECRYPT,	&can_decrypt,	sizeof(can_decrypt) };
	CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE,	&key_type,	sizeof(key_type) };
	CK_ATTRIBUTE unwrap_attribute = { CKA_UNWRAP,	&can_unwrap,	sizeof(can_unwrap) };
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;
	CK_RV rv;

	if (pMechanism == NULL_PTR)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	rv = get_object_from_session(hSession, hKey, &session, &object);
	if (rv != CKR_OK) {
		if (rv == CKR_OBJECT_HANDLE_INVALID)
			rv = CKR_KEY_HANDLE_INVALID;
		goto out;
	}

	if (object->ops->decrypt == NULL_PTR) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = object->ops->get_attribute(session, object, &decrypt_attribute);
	if (rv != CKR_OK || !can_decrypt) {
		/* Also accept UNWRAP - apps call Decrypt when they mean Unwrap */
		rv = object->ops->get_attribute(session, object, &unwrap_attribute);
		if (rv != CKR_OK || !can_unwrap) {
			rv = CKR_KEY_TYPE_INCONSISTENT;
			goto out;
		}
	}
	rv = object->ops->get_attribute(session, object, &key_type_attr);
	if (rv != CKR_OK) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = sc_pkcs11_decr_init(session, pMechanism, object, key_type);

out:
	sc_log(context, "C_DecryptInit() = %s", lookup_enum ( RV_T, rv ));
	sc_pkcs11_unlock();
	return rv;
}
예제 #4
0
CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,	/* the session's handle */
		   CK_MECHANISM_PTR pMechanism,	/* the verification mechanism */
		   CK_OBJECT_HANDLE hKey)
{				/* handle of the verification key */
#ifndef ENABLE_OPENSSL
	return CKR_FUNCTION_NOT_SUPPORTED;
#else
#if 0
	CK_BBOOL can_verify;
	CK_ATTRIBUTE verify_attribute = { CKA_VERIFY, &can_verify, sizeof(can_verify) };
#endif
	CK_KEY_TYPE key_type;
	CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
	CK_RV rv;
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;

	if (pMechanism == NULL_PTR)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;


	rv = get_object_from_session(hSession, hKey, &session, &object);
	if (rv != CKR_OK) {
		if (rv == CKR_OBJECT_HANDLE_INVALID)
			rv = CKR_KEY_HANDLE_INVALID;
		goto out;
	}
#if 0
	rv = object->ops->get_attribute(session, object, &verify_attribute);
	if (rv != CKR_OK || !can_verify) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}
#endif
	rv = object->ops->get_attribute(session, object, &key_type_attr);
	if (rv != CKR_OK) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = sc_pkcs11_verif_init(session, pMechanism, object, key_type);

out:	sc_log(context, "C_VerifyInit() = %s", lookup_enum ( RV_T, rv ));
	sc_pkcs11_unlock();
	return rv;
#endif
}
예제 #5
0
CK_RV
C_SignInit(CK_SESSION_HANDLE hSession,		/* the session's handle */
		CK_MECHANISM_PTR pMechanism,	/* the signature mechanism */
		CK_OBJECT_HANDLE hKey)		/* handle of the signature key */
{
	CK_BBOOL can_sign;
	CK_KEY_TYPE key_type;
	CK_ATTRIBUTE sign_attribute = { CKA_SIGN, &can_sign, sizeof(can_sign) };
	CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;
	CK_RV rv;

	if (pMechanism == NULL_PTR)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	rv = get_object_from_session(hSession, hKey, &session, &object);
	if (rv != CKR_OK) {
		if (rv == CKR_OBJECT_HANDLE_INVALID)
			rv = CKR_KEY_HANDLE_INVALID;
		goto out;
	}

	if (object->ops->sign == NULL_PTR) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = object->ops->get_attribute(session, object, &sign_attribute);
	if (rv != CKR_OK || !can_sign) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}
	rv = object->ops->get_attribute(session, object, &key_type_attr);
	if (rv != CKR_OK) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = sc_pkcs11_sign_init(session, pMechanism, object, key_type);

out:
	sc_log(context, "C_SignInit() = %s", lookup_enum ( RV_T, rv ));
	sc_pkcs11_unlock();
	return rv;
}
예제 #6
0
CK_RV
C_SetAttributeValue(CK_SESSION_HANDLE hSession,	/* the session's handle */
		CK_OBJECT_HANDLE hObject,	/* the object's handle */
		CK_ATTRIBUTE_PTR pTemplate,	/* specifies attributes and values */
		CK_ULONG ulCount)		/* attributes in template */
{
	CK_RV rv;
	unsigned int i;
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;

	if (pTemplate == NULL_PTR || ulCount == 0)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	dump_template(SC_LOG_DEBUG_NORMAL, "C_SetAttributeValue", pTemplate, ulCount);

	rv = get_object_from_session(hSession, hObject, &session, &object);
	if (rv != CKR_OK)
		goto out;

	if (!(session->flags & CKF_RW_SESSION)) {
		rv = CKR_SESSION_READ_ONLY;
		goto out;
	}

	if (object->ops->set_attribute == NULL)
		rv = CKR_FUNCTION_NOT_SUPPORTED;
	else {
		for (i = 0; i < ulCount; i++) {
			rv = object->ops->set_attribute(session, object, &pTemplate[i]);
			if (rv != CKR_OK)
				break;
		}
	}

out:
	sc_pkcs11_unlock();
	return rv;
}
예제 #7
0
CK_RV
C_GetAttributeValue(CK_SESSION_HANDLE hSession,	/* the session's handle */
		CK_OBJECT_HANDLE hObject,	/* the object's handle */
		CK_ATTRIBUTE_PTR pTemplate,	/* specifies attributes, gets values */
		CK_ULONG ulCount)		/* attributes in template */
{
	static int precedence[] = {
		CKR_OK,
		CKR_BUFFER_TOO_SMALL,
		CKR_ATTRIBUTE_TYPE_INVALID,
		CKR_ATTRIBUTE_SENSITIVE,
		-1
	};
	char object_name[64];
	int j;
	CK_RV rv;
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;
	int res, res_type;
	unsigned int i;

	if (pTemplate == NULL_PTR || ulCount == 0)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	rv = get_object_from_session(hSession, hObject, &session, &object);
	if (rv != CKR_OK)
		goto out;

	/* Debug printf */
	snprintf(object_name, sizeof(object_name), "Object %lu", (unsigned long)hObject);

	res_type = 0;
	for (i = 0; i < ulCount; i++) {
		res = object->ops->get_attribute(session, object, &pTemplate[i]);
		if (res != CKR_OK)
			pTemplate[i].ulValueLen = (CK_ULONG) - 1;

		dump_template(SC_LOG_DEBUG_NORMAL, object_name, &pTemplate[i], 1);

		/* the pkcs11 spec has complicated rules on
		 * what errors take precedence:
		 *      CKR_ATTRIBUTE_SENSITIVE
		 *      CKR_ATTRIBUTE_INVALID
		 *      CKR_BUFFER_TOO_SMALL
		 * It does not exactly specify how other errors
		 * should be handled - we give them highest
		 * precedence
		 */
		for (j = 0; precedence[j] != -1; j++) {
			if (precedence[j] == res)
				break;
		}
		if (j > res_type) {
			res_type = j;
			rv = res;
		}
	}

out:	sc_log(context, "C_GetAttributeValue(hSession=0x%lx, hObject=0x%lx) = %s",
			hSession, hObject, lookup_enum ( RV_T, rv ));
	sc_pkcs11_unlock();
	return rv;
}
예제 #8
0
CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession,	/* the session's handle */
		  CK_MECHANISM_PTR pMechanism,	/* the key derivation mechanism */
		  CK_OBJECT_HANDLE hBaseKey,	/* handle of the base key */
		  CK_ATTRIBUTE_PTR pTemplate,	/* template for the new key */
		  CK_ULONG ulAttributeCount,	/* # of attributes in template */
		  CK_OBJECT_HANDLE_PTR phKey)	/* gets handle of derived key */
{
/* TODO: -DEE ECDH with Cofactor  on PIV is an example */
/* TODO: need to do a lot of checking, will only support ECDH for now.*/
	CK_RV rv;
	CK_BBOOL can_derive;
	CK_KEY_TYPE key_type;
	CK_ATTRIBUTE derive_attribute = { CKA_DERIVE, &can_derive, sizeof(can_derive) };
	CK_ATTRIBUTE key_type_attr = { CKA_KEY_TYPE, &key_type, sizeof(key_type) };
	struct sc_pkcs11_session *session;
	struct sc_pkcs11_object *object;
	struct sc_pkcs11_object *key_object;

	if (pMechanism == NULL_PTR)
		return CKR_ARGUMENTS_BAD;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	rv = get_object_from_session(hSession, hBaseKey, &session, &object);
	if (rv != CKR_OK) {
		if (rv == CKR_OBJECT_HANDLE_INVALID)
			rv = CKR_KEY_HANDLE_INVALID;
		goto out;
	}

	if (object->ops->derive == NULL_PTR) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}

	rv = object->ops->get_attribute(session, object, &derive_attribute);
	if (rv != CKR_OK || !can_derive) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}
	rv = object->ops->get_attribute(session, object, &key_type_attr);
	if (rv != CKR_OK) {
		rv = CKR_KEY_TYPE_INCONSISTENT;
		goto out;
	}
	/* TODO DEE Should also check SENSITIVE, ALWAYS_SENSITIVE, EXTRACTABLE,
	   NEVER_EXTRACTABLE of the BaseKey against the template for the newkey.
	*/

	switch(key_type) {
	    case CKK_EC:

		rv = sc_create_object_int(hSession, pTemplate, ulAttributeCount, phKey, 0);
		if (rv != CKR_OK)
		    goto out;

		rv = get_object_from_session(hSession, *phKey, &session, &key_object);
		if (rv != CKR_OK) {
			if (rv == CKR_OBJECT_HANDLE_INVALID)
				rv = CKR_KEY_HANDLE_INVALID;
			goto out;
		}

		rv = sc_pkcs11_deri(session, pMechanism, object, key_type,
			hSession, *phKey, key_object);
		/* TODO if (rv != CK_OK) need to destroy the object */

		break;
	    default:
		rv = CKR_KEY_TYPE_INCONSISTENT;
	}

out:
	sc_pkcs11_unlock();
	return rv;
}