예제 #1
0
CK_RV
pkcs11h_token_freeTokenIdList (
	IN const pkcs11h_token_id_list_t token_id_list
) {
	pkcs11h_token_id_list_t _id = token_id_list;

	_PKCS11H_ASSERT (_g_pkcs11h_data!=NULL);
	_PKCS11H_ASSERT (_g_pkcs11h_data->initialized);
	/*_PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_freeTokenIdList entry token_id_list=%p",
		(void *)token_id_list
	);

	while (_id != NULL) {
		pkcs11h_token_id_list_t x = _id;
		_id = _id->next;
		if (x->token_id != NULL) {
			pkcs11h_token_freeTokenId (x->token_id);
		}
		x->next = NULL;
		_pkcs11h_mem_free ((void *)&x);
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_freeTokenIdList return"
	);

	return CKR_OK;
}
예제 #2
0
CK_RV
_pkcs11h_slotevent_terminate (void) {
	
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_slotevent_terminate entry"
	);

	if (_g_pkcs11h_data->slotevent.initialized) {
		_g_pkcs11h_data->slotevent.should_terminate = TRUE;

		_pkcs11h_slotevent_notify ();

		if (_g_pkcs11h_data->slotevent.thread != PKCS11H_THREAD_NULL) {
			_pkcs11h_threading_threadJoin (&_g_pkcs11h_data->slotevent.thread);
		}

		_pkcs11h_slotevent_terminate_force ();
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_slotevent_terminate return"
	);

	return CKR_OK;
}
예제 #3
0
CK_RV
_pkcs11h_session_freeObjectAttributes (
	IN OUT const CK_ATTRIBUTE_PTR attrs,
	IN const unsigned count
) {
	unsigned i;

	_PKCS11H_ASSERT (attrs!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_freeObjectAttributes entry attrs=%p, count=%u",
		(void *)attrs,
		count
	);

	for (i=0;i<count;i++) {
		if (attrs[i].pValue != NULL) {
			_pkcs11h_mem_free ((void *)&attrs[i].pValue);
			attrs[i].pValue = NULL;
		}
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_freeObjectAttributes return"
	);

	return CKR_OK;
}
예제 #4
0
void
pkcs11h_openssl_freeSession (
	IN const pkcs11h_openssl_session_t openssl_session
) {
	CK_RV rv;

	_PKCS11H_ASSERT (openssl_session!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
		(void *)openssl_session,
		openssl_session->reference_count
	);

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot lock mutex %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}
#endif
	openssl_session->reference_count--;
#if defined(ENABLE_PKCS11H_THREADING)
	_pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock);
#endif

	_PKCS11H_ASSERT (openssl_session->reference_count>=0);

	if (openssl_session->reference_count == 0) {
#if defined(ENABLE_PKCS11H_THREADING)
		_pkcs11h_threading_mutexFree(&openssl_session->reference_count_lock);
#endif

		if (openssl_session->cleanup_hook != NULL) {
			openssl_session->cleanup_hook (openssl_session->certificate);
		}

		if (openssl_session->x509 != NULL) {
			X509_free (openssl_session->x509);
			openssl_session->x509 = NULL;
		}
		if (openssl_session->certificate != NULL) {
			pkcs11h_certificate_freeCertificate (openssl_session->certificate);
			openssl_session->certificate = NULL;
		}

		_pkcs11h_mem_free ((void *)&openssl_session);
	}

cleanup:

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_freeSession - return"
	);
}
예제 #5
0
static
PKCS11H_BOOL
__pkcs11h_openssl_session_setRSA(
	IN const pkcs11h_openssl_session_t openssl_session,
	IN EVP_PKEY * evp
) {
	PKCS11H_BOOL ret = FALSE;
	RSA *rsa = NULL;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setRSA - entered openssl_session=%p, evp=%p",
		(void *)openssl_session,
		(void *)evp
	);

	if (
		(rsa = EVP_PKEY_get1_RSA (evp)) == NULL
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
		goto cleanup;
	}

	RSA_set_method (rsa, __openssl_methods.rsa);
	RSA_set_ex_data (rsa, __openssl_methods.rsa_index, openssl_session);
#if OPENSSL_VERSION_NUMBER < 0x10100001L
	rsa->flags |= RSA_FLAG_SIGN_VER;
#endif

#ifdef BROKEN_OPENSSL_ENGINE
	if (!rsa->engine) {
		rsa->engine = ENGINE_get_default_RSA ();
	}

	ENGINE_set_RSA(ENGINE_get_default_RSA (), &openssl_session->rsa);
	_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
#endif

	ret = TRUE;

cleanup:

	if (rsa != NULL) {
		RSA_free (rsa);
		rsa = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setRSA - return ret=%d",
		ret
	);

	return ret;
}
예제 #6
0
CK_RV
_pkcs11h_session_release (
	IN const _pkcs11h_session_t session
) {
#if defined(ENABLE_PKCS11H_THREADING)
	PKCS11H_BOOL mutex_locked = TRUE;
#endif
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_ASSERT (session!=NULL);
	_PKCS11H_ASSERT (session->reference_count>=0);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_release entry session=%p",
		(void *)session
	);

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexLock (&session->mutex)) != CKR_OK) {
		goto cleanup;
	}
	mutex_locked = TRUE;
#endif

	/*
	 * Never logout for now
	 */
	if (session->reference_count > 0) {
		session->reference_count--;
	}

	rv = CKR_OK;

#if defined(ENABLE_PKCS11H_THREADING)
cleanup:

	if (mutex_locked) {
		_pkcs11h_threading_mutexRelease (&session->mutex);
		mutex_locked = FALSE;
	}
#endif

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_release return rv=%lu-'%s'",
		rv,
		pkcs11h_getMessage (rv)
	);

	return rv;
}
예제 #7
0
pkcs11h_openssl_session_t
pkcs11h_openssl_createSession (
	IN const pkcs11h_certificate_t certificate
) {
	pkcs11h_openssl_session_t openssl_session = NULL;
	CK_RV rv;
	PKCS11H_BOOL ok = FALSE;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_createSession - entry"
	);

	OpenSSL_add_all_digests ();

	if (
		_pkcs11h_mem_malloc (
			(void*)&openssl_session,
			sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
		goto cleanup;
	}

	openssl_session->certificate = certificate;
	openssl_session->reference_count = 1;

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexInit(&openssl_session->reference_count_lock)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_ERROR, "PKCS#11: Cannot initialize mutex %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}
#endif

	ok = TRUE;

cleanup:

	if (!ok) {
		_pkcs11h_mem_free ((void *)&openssl_session);
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
		(void *)openssl_session
	);

	return openssl_session;
}
예제 #8
0
PKCS11H_BOOL
_pkcs11h_openssl_terminate (void) {
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_openssl_terminate"
	);
#ifndef OPENSSL_NO_RSA
	if (__openssl_methods.rsa != NULL) {
		RSA_meth_free (__openssl_methods.rsa);
		__openssl_methods.rsa = NULL;
	}
#endif
#ifndef OPENSSL_NO_DSA
	if (__openssl_methods.dsa != NULL) {
		DSA_meth_free (__openssl_methods.dsa);
		__openssl_methods.dsa = NULL;
	}
#endif
#ifdef __ENABLE_EC
	if (__openssl_methods.ecdsa != NULL) {
		ECDSA_METHOD_free(__openssl_methods.ecdsa);
		__openssl_methods.ecdsa = NULL;
	}
#endif
	return TRUE;
}
예제 #9
0
static
PKCS11H_BOOL
__pkcs11h_hooks_default_pin_prompt (
	IN void * const global_data,
	IN void * const user_data,
	IN const pkcs11h_token_id_t token,
	IN const unsigned retry,
	OUT char * const pin,
	IN const size_t pin_max
) {
	/*_PKCS11H_ASSERT (global_data) NOT NEEDED */
	/*_PKCS11H_ASSERT (user_data) NOT NEEDED */
	_PKCS11H_ASSERT (token!=NULL);

	(void)global_data;
	(void)user_data;
	(void)retry;
	(void)pin;
	(void)pin_max;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_hooks_default_pin_prompt global_data=%p, user_data=%p, display='%s'",
		global_data,
		user_data,
		token->display
	);
	
	return FALSE;
}
예제 #10
0
static
void
__pkcs11h_openssl_ex_data_free (
	void *parent,
	void *ptr,
	CRYPTO_EX_DATA *ad,
	int idx,
	long argl,
	void *argp
) {
	pkcs11h_openssl_session_t openssl_session = (pkcs11h_openssl_session_t)ptr;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_ex_data_free entered - parent=%p, ptr=%p, ad=%p, idx=%d, argl=%ld, argp=%p",
		parent,
		ptr,
		(void *)ad,
		idx,
		argl,
		argp
	);

	if (openssl_session != NULL) {
		pkcs11h_openssl_freeSession (openssl_session);
	}
}
예제 #11
0
static
int
__pkcs11h_openssl_ex_data_dup (
	CRYPTO_EX_DATA *to,
	CRYPTO_EX_DATA *from,
	void *from_d,
	int idx,
	long argl,
	void *argp
) {
#else
int
__pkcs11h_openssl_ex_data_dup (
	CRYPTO_EX_DATA *to,
	const CRYPTO_EX_DATA *from,
	void *from_d,
	int idx,
	long argl,
	void *argp
) {
#endif
	pkcs11h_openssl_session_t openssl_session;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_ex_data_dup entered - to=%p, from=%p, from_d=%p, idx=%d, argl=%ld, argp=%p",
		(void *)to,
		(void *)from,
		from_d,
		idx,
		argl,
		argp
	);

	_PKCS11H_ASSERT (from_d!=NULL);

	if ((openssl_session = *(pkcs11h_openssl_session_t *)from_d) != NULL) {
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG2,
			"PKCS#11: __pkcs11h_openssl_ex_data_dup session refcount=%d",
			openssl_session->reference_count
		);
		openssl_session->reference_count++;
	}

	return 1;
}
예제 #12
0
X509 *
pkcs11h_openssl_session_getX509 (
	IN const pkcs11h_openssl_session_t openssl_session
) {
	X509 *x509 = NULL;
	PKCS11H_BOOL ok = FALSE;

	_PKCS11H_ASSERT (openssl_session!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getX509 - entry openssl_session=%p",
		(void *)openssl_session
	);

	if (
		openssl_session->x509 == NULL &&
		(openssl_session->x509 = pkcs11h_openssl_getX509 (openssl_session->certificate)) == NULL
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
		goto cleanup;
	}

	if ((x509 = X509_dup (openssl_session->x509)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot duplicate certificate object");
		goto cleanup;
	}

	ok = TRUE;

cleanup:

	if (!ok) {
		if (x509 != NULL) {
			X509_free (x509);
			x509 = NULL;
		}
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getX509 - return x509=%p",
		(void *)x509
	);

	return x509;
}
예제 #13
0
CK_RV
pkcs11h_token_duplicateTokenId (
	OUT pkcs11h_token_id_t * const to,
	IN const pkcs11h_token_id_t from
) {
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_ASSERT (_g_pkcs11h_data!=NULL);
	_PKCS11H_ASSERT (_g_pkcs11h_data->initialized);
	_PKCS11H_ASSERT (to!=NULL);
	_PKCS11H_ASSERT (from!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_duplicateTokenId entry to=%p form=%p",
		(void *)to,
		(void *)from
	);

	*to = NULL;

	if (
		(rv = _pkcs11h_mem_duplicate (
			(void*)to,
			NULL,
			from,
			sizeof (struct pkcs11h_token_id_s)
		)) != CKR_OK
	) {
		goto cleanup;
	}

	rv = CKR_OK;

cleanup:

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_duplicateTokenId return rv=%lu-'%s', *to=%p",
		rv,
		pkcs11h_getMessage (rv),
		(void *)*to
	);
	
	return rv;
}
예제 #14
0
CK_RV
_pkcs11h_token_newTokenId (
	OUT pkcs11h_token_id_t * const p_token_id
) {
	CK_RV rv = CKR_FUNCTION_FAILED;

	pkcs11h_token_id_t token_id = NULL;

	_PKCS11H_ASSERT (_g_pkcs11h_data!=NULL);
	_PKCS11H_ASSERT (_g_pkcs11h_data->initialized);
	_PKCS11H_ASSERT (p_token_id!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_token_newTokenId entry p_token_id=%p",
		(void *)p_token_id
	);

	*p_token_id = NULL;

	if ((rv = _pkcs11h_mem_malloc ((void *)&token_id, sizeof (struct pkcs11h_token_id_s))) != CKR_OK) {
		goto cleanup;
	}

	*p_token_id = token_id;
	token_id = NULL;

	rv = CKR_OK;

cleanup:

	if (token_id != NULL) {
		_pkcs11h_mem_free ((void *)&token_id);
		token_id = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_token_newTokenId return rv=%lu-'%s', *p_token_id=%p",
		rv,
		pkcs11h_getMessage (rv),
		(void *)*p_token_id
	);

	return rv;
}
예제 #15
0
static
PKCS11H_BOOL
__pkcs11h_openssl_session_setDSA(
	IN const pkcs11h_openssl_session_t openssl_session,
	IN EVP_PKEY * evp
) {
	PKCS11H_BOOL ret = FALSE;
	DSA *dsa = NULL;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setDSA - entered openssl_session=%p, evp=%p",
		(void *)openssl_session,
		(void *)evp
	);

	if (
		(dsa = EVP_PKEY_get1_DSA (evp)) == NULL
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get DSA key");
		goto cleanup;
	}

	DSA_set_method (dsa, __openssl_methods.dsa);
	DSA_set_ex_data (dsa, __openssl_methods.dsa_index, openssl_session);

	ret = TRUE;

cleanup:

	if (dsa != NULL) {
		DSA_free (dsa);
		dsa = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setDSA - return ret=%d",
		ret
	);

	return ret;
}
예제 #16
0
static
PKCS11H_BOOL
__pkcs11h_openssl_session_setECDSA(
	IN const pkcs11h_openssl_session_t openssl_session,
	IN EVP_PKEY * evp
) {
	PKCS11H_BOOL ret = FALSE;
	EC_KEY *ec = NULL;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setECDSA - entered openssl_session=%p, evp=%p",
		(void *)openssl_session,
		(void *)evp
	);

	if (
		(ec = EVP_PKEY_get1_EC_KEY (evp)) == NULL
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get EC key");
		goto cleanup;
	}

	ECDSA_set_method (ec, __openssl_methods.ecdsa);
	ECDSA_set_ex_data (ec, __openssl_methods.ecdsa_index, openssl_session);

	ret = TRUE;

cleanup:

	if (ec != NULL) {
		EC_KEY_free (ec);
		ec = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_session_setECDSA - return ret=%d",
		ret
	);

	return ret;
}
예제 #17
0
CK_RV
_pkcs11h_slotevent_notify (void) {
	
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_slotevent_notify entry"
	);

	if (_g_pkcs11h_data->slotevent.initialized) {
		_g_pkcs11h_data->slotevent.skip_event = TRUE;
		_pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event);
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_slotevent_notify return"
	);

	return CKR_OK;
}
예제 #18
0
CK_RV
_pkcs11h_slotevent_init (void) {
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_slotevent_init entry"
	);

	if (!_g_pkcs11h_data->slotevent.initialized) {
		if ((rv = _pkcs11h_threading_condInit (&_g_pkcs11h_data->slotevent.cond_event)) != CKR_OK) {
			goto cleanup;
		}
		
		if (
			(rv = _pkcs11h_threading_threadStart (
				&_g_pkcs11h_data->slotevent.thread,
				__pkcs11h_slotevent_manager,
				NULL
			)) != CKR_OK
		) {
			goto cleanup;
		}
		
		_g_pkcs11h_data->slotevent.initialized = TRUE;
	}

	rv = CKR_OK;

cleanup:

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_slotevent_init return rv=%lu-'%s'",
		rv,
		pkcs11h_getMessage (rv)
	);

	return rv;
}
예제 #19
0
CK_RV
pkcs11h_token_freeTokenId (
	IN pkcs11h_token_id_t token_id
) {
	_PKCS11H_ASSERT (_g_pkcs11h_data!=NULL);
	_PKCS11H_ASSERT (_g_pkcs11h_data->initialized);
	_PKCS11H_ASSERT (token_id!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_freeTokenId entry certificate_id=%p",
		(void *)token_id
	);

	_pkcs11h_mem_free ((void *)&token_id);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_freeTokenId return"
	);

	return CKR_OK;
}
예제 #20
0
EVP_PKEY *
pkcs11h_openssl_session_getEVP (
	IN const pkcs11h_openssl_session_t openssl_session
) {
	X509 *x509 = NULL;
	EVP_PKEY *evp = NULL;
	EVP_PKEY *ret = NULL;

	_PKCS11H_ASSERT (openssl_session!=NULL);
	_PKCS11H_ASSERT (!openssl_session->initialized);
	_PKCS11H_ASSERT (openssl_session!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getEVP - entry openssl_session=%p",
		(void *)openssl_session
	);

	/*
	 * Dup x509 so RSA will not hold session x509
	 */
	if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object");
		goto cleanup;
	}

	if ((evp = X509_get_pubkey (x509)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
		goto cleanup;
	}

	if (0) {
	}
#ifndef OPENSSL_NO_RSA
	else if (EVP_PKEY_id (evp) == EVP_PKEY_RSA) {
		if (!__pkcs11h_openssl_session_setRSA(openssl_session, evp)) {
			goto cleanup;
		}
	}
#endif
#ifndef OPENSSL_NO_RSA
	else if (EVP_PKEY_id (evp) == EVP_PKEY_DSA) {
		if (!__pkcs11h_openssl_session_setDSA(openssl_session, evp)) {
			goto cleanup;
		}
	}
#endif
#ifdef __ENABLE_EC
	else if (evp->type == EVP_PKEY_EC) {
		if (!__pkcs11h_openssl_session_setECDSA(openssl_session, evp)) {
			goto cleanup;
		}
	}
#endif
	else {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm %d", EVP_PKEY_id (evp));
		goto cleanup;
	}

#if defined(ENABLE_PKCS11H_THREADING)
	_pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock);
#endif
	openssl_session->reference_count++;
#if defined(ENABLE_PKCS11H_THREADING)
	_pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock);
#endif

	openssl_session->initialized = TRUE;

	ret = evp;
	evp = NULL;

cleanup:

	/*
	 * openssl objects have reference
	 * count, so release them
	 */
	if (evp != NULL) {
		EVP_PKEY_free (evp);
		evp = NULL;
	}

	if (x509 != NULL) {
		X509_free (x509);
		x509 = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getEVP - return ret=%p",
		(void *)ret
	);

	return ret;
}
예제 #21
0
static
DSA_SIG *
__pkcs11h_openssl_dsa_do_sign(
	IN const unsigned char *dgst,
	IN int dlen,
	OUT DSA *dsa
) {
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_dsa_get_pkcs11h_certificate (dsa);
	unsigned char *sigbuf = NULL;
	size_t siglen;
	DSA_SIG *sig = NULL;
	DSA_SIG *ret = NULL;
	BIGNUM *r = NULL;
	BIGNUM *s = NULL;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_dsa_do_sign - entered dgst=%p, dlen=%d, dsa=%p",
		(void *)dgst,
		dlen,
		(void *)dsa
	);

	_PKCS11H_ASSERT (dgst!=NULL);
	_PKCS11H_ASSERT (dsa!=NULL);
	_PKCS11H_ASSERT (certificate!=NULL);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_DSA,
			dgst,
			(size_t)dlen,
			NULL,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer");
		goto cleanup;
	}

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_DSA,
			dgst,
			(size_t)dlen,
			sigbuf,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((sig = DSA_SIG_new ()) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate DSA_SIG");
		goto cleanup;
	}

	if ((r = BN_bin2bn (&sigbuf[0], siglen/2, NULL)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa r");
		goto cleanup;
	}

	if ((s = BN_bin2bn (&sigbuf[siglen/2], siglen/2, NULL)) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert dsa s");
		goto cleanup;
	}

	DSA_SIG_set0 (sig, r, s);
	ret = sig;
	sig = NULL;
	r = NULL;
	s = NULL;

cleanup:

	if (sigbuf != NULL) {
		_pkcs11h_mem_free ((void *)&sigbuf);
	}

	if (sig != NULL) {
		DSA_SIG_free (sig);
		sig = NULL;
	}

	if (r != NULL) {
		BN_clear_free (r);
	}

	if (s != NULL) {
		BN_clear_free (s);
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_dsa_do_sign - return sig=%p",
		(void *)sig
	);

	return ret;
}
예제 #22
0
PKCS11H_BOOL
_pkcs11h_openssl_initialize (void) {

	PKCS11H_BOOL ret = FALSE;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_openssl_initialize - entered"
	);
#ifndef OPENSSL_NO_RSA
	if (__openssl_methods.rsa != NULL) {
		RSA_meth_free (__openssl_methods.rsa);
	}
	if ((__openssl_methods.rsa = RSA_meth_dup (RSA_get_default_method ())) == NULL) {
		goto cleanup;
	}
	RSA_meth_set1_name (__openssl_methods.rsa, "pkcs11h");
	RSA_meth_set_priv_dec (__openssl_methods.rsa, __pkcs11h_openssl_rsa_dec);
	RSA_meth_set_priv_enc (__openssl_methods.rsa, __pkcs11h_openssl_rsa_enc);
	RSA_meth_set_flags (__openssl_methods.rsa, RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY);
	__openssl_methods.rsa_index = RSA_get_ex_new_index (
		0,
		"pkcs11h",
		NULL,
		__pkcs11h_openssl_ex_data_dup,
		__pkcs11h_openssl_ex_data_free
	);
#endif
#ifndef OPENSSL_NO_DSA
	if (__openssl_methods.dsa != NULL) {
		DSA_meth_free (__openssl_methods.dsa);
	}
	__openssl_methods.dsa = DSA_meth_dup (DSA_get_default_method ());
	DSA_meth_set1_name (__openssl_methods.dsa, "pkcs11h");
	DSA_meth_set_sign (__openssl_methods.dsa, __pkcs11h_openssl_dsa_do_sign);
	__openssl_methods.dsa_index = DSA_get_ex_new_index (
		0,
		"pkcs11h",
		NULL,
		__pkcs11h_openssl_ex_data_dup,
		__pkcs11h_openssl_ex_data_free
	);
#endif
#ifdef __ENABLE_EC
	if (__openssl_methods.ecdsa != NULL) {
		ECDSA_METHOD_free(__openssl_methods.ecdsa);
	}
	__openssl_methods.ecdsa = ECDSA_METHOD_new ((ECDSA_METHOD *)ECDSA_get_default_method ());
	ECDSA_METHOD_set_name(__openssl_methods.ecdsa, "pkcs11h");
	ECDSA_METHOD_set_sign(__openssl_methods.ecdsa, __pkcs11h_openssl_ecdsa_do_sign);
	__openssl_methods.ecdsa_index = ECDSA_get_ex_new_index (
		0,
		"pkcs11h",
		NULL,
		__pkcs11h_openssl_ex_data_dup,
		__pkcs11h_openssl_ex_data_free
	);
#endif
	ret = TRUE;

cleanup:
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_openssl_initialize - return %d",
		ret
	);
	return ret;
}
예제 #23
0
static
void *
__pkcs11h_slotevent_manager (
	IN void *p
) {
	PKCS11H_BOOL first_time = TRUE;

	(void)p;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_slotevent_manager entry"
	);

	/*
	 * Trigger hook, so application may
	 * depend on initial slot change
	 */
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Calling slotevent hook"
	);
	_g_pkcs11h_data->hooks.slotevent (_g_pkcs11h_data->hooks.slotevent_data);

	while (
		first_time ||	/* Must enter wait or mutex will never be free */
		!_g_pkcs11h_data->slotevent.should_terminate
	) {
		_pkcs11h_provider_t current_provider;

		first_time = FALSE;

		/*
		 * Start each provider thread
		 * if not already started.
		 * This is required in order to allow
		 * adding new providers.
		 */
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG2,
			"PKCS#11: __pkcs11h_slotevent_manager examine provider list"
		);
		for (
			current_provider = _g_pkcs11h_data->providers;
			current_provider != NULL;
			current_provider = current_provider->next
		) {
			if (current_provider->enabled) {
				if (current_provider->slotevent_thread == PKCS11H_THREAD_NULL) {
					_PKCS11H_DEBUG (
						PKCS11H_LOG_DEBUG2,
						"PKCS#11: __pkcs11h_slotevent_manager found enabled provider without thread"
					);
					_pkcs11h_threading_threadStart (
						&current_provider->slotevent_thread,
						__pkcs11h_slotevent_provider,
						current_provider
					);
				}
			}
			else {
				if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
					_PKCS11H_DEBUG (
						PKCS11H_LOG_DEBUG2,
						"PKCS#11: __pkcs11h_slotevent_manager found disabled provider with thread"
					);
					_pkcs11h_threading_threadJoin (&current_provider->slotevent_thread);
				}
			}
		}

		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG2,
			"PKCS#11: __pkcs11h_slotevent_manager waiting for slotevent"
		);
		_pkcs11h_threading_condWait (&_g_pkcs11h_data->slotevent.cond_event, PKCS11H_COND_INFINITE);

		if (_g_pkcs11h_data->slotevent.skip_event) {
			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Slotevent skipping event"
			);
			_g_pkcs11h_data->slotevent.skip_event = FALSE;
		}
		else {
			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Calling slotevent hook"
			);
			_g_pkcs11h_data->hooks.slotevent (_g_pkcs11h_data->hooks.slotevent_data);
		}
	}

	{
		_pkcs11h_provider_t current_provider;

		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG2,
			"PKCS#11: __pkcs11h_slotevent_manager joining threads"
		);


		for (
			current_provider = _g_pkcs11h_data->providers;
			current_provider != NULL;
			current_provider = current_provider->next
		) {
			if (current_provider->slotevent_thread != PKCS11H_THREAD_NULL) {
				_pkcs11h_threading_threadJoin (&current_provider->slotevent_thread);
			}
		}
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_slotevent_manager return"
	);

	return NULL;
}
예제 #24
0
CK_RV
pkcs11h_plugAndPlay (void) {
#if defined(ENABLE_PKCS11H_DEBUG)
#if defined(_WIN32)
	int mypid = 0;
#else
	pid_t mypid = getpid ();
#endif
#endif

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_plugAndPlay entry pid=%d",
		mypid
	);

	if (_g_pkcs11h_data != NULL && _g_pkcs11h_data->initialized) {
		_pkcs11h_provider_t current;
#if defined(ENABLE_PKCS11H_SLOTEVENT)
		PKCS11H_BOOL slot_event_active = FALSE;
#endif

#if defined(ENABLE_PKCS11H_THREADING)
		_pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global);
#endif
		for (
			current = _g_pkcs11h_data->providers;
			current != NULL;
			current = current->next
		) {
			if (current->enabled) {
				current->f->C_Finalize (NULL);
			}
		}

#if defined(ENABLE_PKCS11H_SLOTEVENT)
		if (_g_pkcs11h_data->slotevent.initialized) {
			slot_event_active = TRUE;
			_pkcs11h_slotevent_terminate ();
		}
#endif

		for (
			current = _g_pkcs11h_data->providers;
			current != NULL;
			current = current->next
		) {
			if (current->enabled) {
				current->f->C_Initialize (NULL);
			}
		}

#if defined(ENABLE_PKCS11H_SLOTEVENT)
		if (slot_event_active) {
			_pkcs11h_slotevent_init ();
		}
#endif

#if defined(ENABLE_PKCS11H_THREADING)
		_pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.global);
#endif
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_plugAndPlay return"
	);

	return CKR_OK;
}
예제 #25
0
static
ECDSA_SIG *
__pkcs11h_openssl_ecdsa_do_sign(
	IN const unsigned char *dgst,
	IN int dlen,
	IN const BIGNUM *inv,
	IN const BIGNUM *r,
	OUT EC_KEY *ec
) {
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_ecdsa_get_pkcs11h_certificate (ec);
	unsigned char *sigbuf = NULL;
	size_t siglen;
	ECDSA_SIG *sig = NULL;
	ECDSA_SIG *ret = NULL;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - entered dgst=%p, dlen=%d, inv=%p, r=%p, ec=%p",
		(void *)dgst,
		dlen,
		(void *)inv,
		(void *)r,
		(void *)ec
	);

	_PKCS11H_ASSERT (dgst!=NULL);
	_PKCS11H_ASSERT (inv==NULL);
	_PKCS11H_ASSERT (r==NULL);
	_PKCS11H_ASSERT (ec!=NULL);
	_PKCS11H_ASSERT (certificate!=NULL);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_ECDSA,
			dgst,
			(size_t)dlen,
			NULL,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((rv = _pkcs11h_mem_malloc ((void *)&sigbuf, siglen)) != CKR_OK) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot cannot allocate signature buffer");
		goto cleanup;
	}

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_ECDSA,
			dgst,
			(size_t)dlen,
			sigbuf,
			&siglen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	if ((sig = ECDSA_SIG_new ()) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate ECDSA_SIG");
		goto cleanup;
	}

	if (BN_bin2bn (&sigbuf[0], siglen/2, sig->r) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa r");
		goto cleanup;
	}

	if (BN_bin2bn (&sigbuf[siglen/2], siglen/2, sig->s) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot convert ecdsa s");
		goto cleanup;
	}

	ret = sig;
	sig = NULL;

cleanup:

	if (sigbuf != NULL) {
		_pkcs11h_mem_free ((void *)&sigbuf);
	}

	if (sig != NULL) {
		ECDSA_SIG_free (sig);
		sig = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_ecdsa_do_sign - return sig=%p",
		(void *)sig
	);

	return ret;
}
예제 #26
0
static
int
__pkcs11h_openssl_rsa_dec (
	IN int flen,
	IN unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#else
static
int
__pkcs11h_openssl_rsa_dec (
	IN int flen,
	IN const unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#endif
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa);
	PKCS11H_BOOL session_locked = FALSE;
	CK_MECHANISM_TYPE mech = CKM_RSA_PKCS;
	CK_RV rv = CKR_FUNCTION_FAILED;
	size_t tlen = (size_t)flen;

	_PKCS11H_ASSERT (from!=NULL);
	_PKCS11H_ASSERT (to!=NULL);
	_PKCS11H_ASSERT (rsa!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
		flen,
		from,
		to,
		(void *)rsa,
		padding
	);

	switch (padding) {
		case RSA_PKCS1_PADDING:
			mech = CKM_RSA_PKCS;
		break;
		case RSA_PKCS1_OAEP_PADDING:
			mech = CKM_RSA_PKCS_OAEP;
		break;
		case RSA_SSLV23_PADDING:
			rv = CKR_MECHANISM_INVALID;
		break;
		case RSA_NO_PADDING:
			rv = CKR_MECHANISM_INVALID;
		break;
	}
	if (rv == CKR_MECHANISM_INVALID)
		goto cleanup;

	if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) {
		goto cleanup;
	}
	session_locked = TRUE;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Performing decryption"
	);

	if (
		(rv = pkcs11h_certificate_decryptAny (
			certificate,
			mech,
			from,
			flen,
			to,
			&tlen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform decryption %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	rv = CKR_OK;

cleanup:

	if (session_locked) {
		pkcs11h_certificate_releaseSession (certificate);
		session_locked = FALSE;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_dec - return rv=%lu-'%s'",
		rv,
		pkcs11h_getMessage (rv)
	);

	return rv == CKR_OK ? (int)tlen : -1;
}
예제 #27
0
RSA *
pkcs11h_openssl_session_getRSA (
	IN const pkcs11h_openssl_session_t openssl_session
) {
#ifndef OPENSSL_NO_RSA
	RSA *rsa = NULL;
	RSA *ret = NULL;
	EVP_PKEY *evp = NULL;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getRSA - entry openssl_session=%p",
		(void *)openssl_session
	);

	if ((evp = pkcs11h_openssl_session_getEVP(openssl_session)) == NULL) {
		goto cleanup;
	}

	if (EVP_PKEY_id (evp) != EVP_PKEY_RSA) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
		goto cleanup;
	}

	if (
		(rsa = EVP_PKEY_get1_RSA (evp)) == NULL
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
		goto cleanup;
	}

	ret = rsa;
	rsa = NULL;

cleanup:

	/*
	 * openssl objects have reference
	 * count, so release them
	 */
	if (rsa != NULL) {
		RSA_free (rsa);
		rsa = NULL;
	}

	if (evp != NULL) {
		EVP_PKEY_free (evp);
		evp = NULL;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_session_getRSA - return ret=%p",
		(void *)rsa
	);

	return ret;
#else
	return NULL;
#endif
}
예제 #28
0
static
int
__pkcs11h_openssl_rsa_enc (
	IN int flen,
	IN unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#else
static
int
__pkcs11h_openssl_rsa_enc (
	IN int flen,
	IN const unsigned char *from,
	OUT unsigned char *to,
	IN OUT RSA *rsa,
	IN int padding
) {
#endif
	pkcs11h_certificate_t certificate = __pkcs11h_openssl_rsa_get_pkcs11h_certificate (rsa);
	PKCS11H_BOOL session_locked = FALSE;
	CK_RV rv = CKR_FUNCTION_FAILED;
	size_t tlen;

	_PKCS11H_ASSERT (from!=NULL);
	_PKCS11H_ASSERT (to!=NULL);
	_PKCS11H_ASSERT (rsa!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_enc entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
		flen,
		from,
		to,
		(void *)rsa,
		padding
	);

	if (padding != RSA_PKCS1_PADDING) {
		rv = CKR_MECHANISM_INVALID;
		goto cleanup;
	}

	tlen = (size_t)RSA_size(rsa);

	if ((rv = pkcs11h_certificate_lockSession (certificate)) != CKR_OK) {
		goto cleanup;
	}
	session_locked = TRUE;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Performing signature"
	);

	if (
		(rv = pkcs11h_certificate_signAny (
			certificate,
			CKM_RSA_PKCS,
			from,
			flen,
			to,
			&tlen
		)) != CKR_OK
	) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
		goto cleanup;
	}

	rv = CKR_OK;

cleanup:

	if (session_locked) {
		pkcs11h_certificate_releaseSession (certificate);
		session_locked = FALSE;
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_openssl_rsa_enc - return rv=%lu-'%s'",
		rv,
		pkcs11h_getMessage (rv)
	);

	return rv == CKR_OK ? (int)tlen : -1;
}
예제 #29
0
static
void *
__pkcs11h_slotevent_provider (
	IN void *p
) {
	_pkcs11h_provider_t provider = (_pkcs11h_provider_t)p;
	CK_SLOT_ID slot;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_slotevent_provider provider='%s' entry",
		provider->manufacturerID
	);

	if (!provider->enabled) {
		rv = CKR_OPERATION_NOT_INITIALIZED;
		goto cleanup;
	}

	if (provider->slot_poll_interval == 0) {
		provider->slot_poll_interval = _PKCS11H_DEFAULT_SLOTEVENT_POLL;
	}

	/*
	 * If we cannot finalize, we cannot cause
	 * WaitForSlotEvent to terminate
	 */
	if (!provider->should_finalize) {
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Setup slotevent provider='%s' mode hardset to poll",
			provider->manufacturerID
		);
		provider->slot_event_method = PKCS11H_SLOTEVENT_METHOD_POLL;
	}

	if (
		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_TRIGGER
	) { 
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Setup slotevent provider='%s' checking trigger",
			provider->manufacturerID
		);

		while (
			!_g_pkcs11h_data->slotevent.should_terminate &&
			provider->enabled &&
			(rv = provider->f->C_WaitForSlotEvent (
				0,
				&slot,
				NULL_PTR
			)) == CKR_OK
		) {
			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Slotevent provider='%s' event",
				provider->manufacturerID
			);

			_pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event);
		}

		if (rv != CKR_FUNCTION_NOT_SUPPORTED) {
			goto cleanup;
		}
	}

	if (
		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_POLL
	) { 
		PKCS11H_BOOL had_sleep = TRUE;

		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Setup slotevent provider='%s' checking poll",
			provider->manufacturerID
		);

		while (
			!_g_pkcs11h_data->slotevent.should_terminate &&
			provider->enabled &&
			(
				(rv = provider->f->C_WaitForSlotEvent (
					CKF_DONT_BLOCK,
					&slot,
					NULL_PTR
				)) == CKR_OK ||
				rv == CKR_NO_EVENT
			)
		) {
			if (rv == CKR_OK) {
				if (had_sleep) {
					_PKCS11H_DEBUG (
						PKCS11H_LOG_DEBUG1,
						"PKCS#11: Slotevent provider='%s' event",
						provider->manufacturerID
					);

					had_sleep = FALSE; /* Mask out seq events */
					_pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event);
				}
			}
			else {
				_pkcs11h_threading_sleep (provider->slot_poll_interval);
				had_sleep = TRUE;
			}
		}

		if (rv != CKR_FUNCTION_NOT_SUPPORTED) {
			goto cleanup;
		}
	}

	if (
		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_AUTO ||
		provider->slot_event_method == PKCS11H_SLOTEVENT_METHOD_FETCH
	) { 
		unsigned long last_checksum = 0;
		PKCS11H_BOOL is_first_time = TRUE;

		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Setup slotevent provider='%s' checking fetch",
			provider->manufacturerID
		);

		while (
			!_g_pkcs11h_data->slotevent.should_terminate &&
			provider->enabled
		) {
			unsigned long current_checksum = 0;

			CK_ULONG i;
			CK_SLOT_ID_PTR slots = NULL;
			CK_ULONG slotnum;

			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Slotevent provider='%s' poll",
				provider->manufacturerID
			);

			if (
				(rv = _pkcs11h_session_getSlotList (
					provider,
					TRUE,
					&slots,
					&slotnum
				)) != CKR_OK
			) {
				goto cleanup1;
			}

			for (i=0;i<slotnum;i++) {
				CK_TOKEN_INFO info;

				if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) {
					current_checksum += (
						__pkcs11h_slotevent_checksum (
							info.label,
							sizeof (info.label)
						) +
						__pkcs11h_slotevent_checksum (
							info.manufacturerID,
							sizeof (info.manufacturerID)
						) +
						__pkcs11h_slotevent_checksum (
							info.model,
							sizeof (info.model)
						) +
						__pkcs11h_slotevent_checksum (
							info.serialNumber,
							sizeof (info.serialNumber)
						)
					);
				}
			}
			
			if (is_first_time) {
				is_first_time = FALSE;
			}
			else {
				if (last_checksum != current_checksum) {
					_PKCS11H_DEBUG (
						PKCS11H_LOG_DEBUG1,
						"PKCS#11: Slotevent provider='%s' event",
						provider->manufacturerID
					);

					_pkcs11h_threading_condSignal (&_g_pkcs11h_data->slotevent.cond_event);
				}
			}
			last_checksum = current_checksum;

			rv = CKR_OK;

		cleanup1:

			if (slots != NULL) {
				_pkcs11h_mem_free ((void *)&slots);
			}
			
			if (rv != CKR_OK) {
				goto cleanup;
			}

			if (!_g_pkcs11h_data->slotevent.should_terminate) {
				_pkcs11h_threading_sleep (provider->slot_poll_interval);
			}
		}
	}

cleanup:

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: __pkcs11h_slotevent_provider provider='%s' return",
		provider->manufacturerID
	);

	return NULL;
}
예제 #30
0
X509 *
pkcs11h_openssl_getX509 (
	IN const pkcs11h_certificate_t certificate
) {
	unsigned char *certificate_blob = NULL;
	size_t certificate_blob_size = 0;
	X509 *x509 = NULL;
	CK_RV rv = CKR_FUNCTION_FAILED;
	__pkcs11_openssl_d2i_t d2i1 = NULL;

	_PKCS11H_ASSERT (certificate!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_getX509 - entry certificate=%p",
		(void *)certificate
	);

	if ((x509 = X509_new ()) == NULL) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
		rv = CKR_HOST_MEMORY;
		goto cleanup;
	}

	if (
		(rv = pkcs11h_certificate_getCertificateBlob (
			certificate,
			NULL,
			&certificate_blob_size
		)) != CKR_OK
	) {
		goto cleanup;
	}

	if ((rv = _pkcs11h_mem_malloc ((void *)&certificate_blob, certificate_blob_size)) != CKR_OK) {
		goto cleanup;
	}

	if (
		(rv = pkcs11h_certificate_getCertificateBlob (
			certificate,
			certificate_blob,
			&certificate_blob_size
		)) != CKR_OK
	) {
		goto cleanup;
	}

	d2i1 = (__pkcs11_openssl_d2i_t)certificate_blob;
	if (!d2i_X509 (&x509, &d2i1, certificate_blob_size)) {
		_PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
		rv = CKR_FUNCTION_FAILED;
		goto cleanup;
	}

	rv = CKR_OK;

cleanup:

	if (certificate_blob != NULL) {
		_pkcs11h_mem_free((void *)&certificate_blob);
	}

	if (rv != CKR_OK) {
		if (x509 != NULL) {
			X509_free (x509);
			x509 = NULL;
		}
	}

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_openssl_getX509 - return rv=%ld-'%s', x509=%p",
		rv,
		pkcs11h_getMessage (rv),
		(void *)x509
	);

	return x509;
}