Esempio n. 1
0
static void
DSA_meth_free (DSA_METHOD *meth)
{
	if (meth != NULL) {
		if (meth->name != NULL) {
			_pkcs11h_mem_free ((void *)&meth->name);
		}
		_pkcs11h_mem_free ((void *)&meth);
	}
}
Esempio n. 2
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;
}
Esempio n. 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;
}
Esempio n. 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"
	);
}
Esempio n. 5
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;
}
Esempio n. 6
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;
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
0
CK_RV
_pkcs11h_session_getSessionByTokenId (
	IN const pkcs11h_token_id_t token_id,
	OUT _pkcs11h_session_t * const p_session
) {
#if defined(ENABLE_PKCS11H_THREADING)
	PKCS11H_BOOL mutex_locked = FALSE;
	PKCS11H_BOOL have_session_mutex = FALSE;
#endif
	_pkcs11h_session_t session = NULL;
	_pkcs11h_session_t current_session;

	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_ASSERT (token_id!=NULL);
	_PKCS11H_ASSERT (p_session!=NULL);

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

	*p_session = NULL;

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

	for (
		current_session = _g_pkcs11h_data->sessions;
		current_session != NULL && session == NULL;
		current_session = current_session->next
	) {
		if (
			pkcs11h_token_sameTokenId (
				current_session->token_id,
				token_id
			)
		) {
			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Using cached session"
			);
			session = current_session;
			session->reference_count++;
		}
	}

	if (session == NULL) {
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Creating a new session"
		);

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

		session->reference_count = 1;
		session->session_handle = _PKCS11H_INVALID_SESSION_HANDLE;

		session->pin_cache_period = _g_pkcs11h_data->pin_cache_period;

		if (
			(rv = pkcs11h_token_duplicateTokenId (
				&session->token_id,
				token_id
			)) != CKR_OK
		) {
			goto cleanup;
		}

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

		session->valid = TRUE;
		session->next = _g_pkcs11h_data->sessions;
		_g_pkcs11h_data->sessions = session;
	}

	*p_session = session;
	session = NULL;
	rv = CKR_OK;

cleanup:
	if (session != NULL) {
#if defined(ENABLE_PKCS11H_THREADING)
		if (have_session_mutex) {
			_pkcs11h_threading_mutexFree (&session->mutex);
		}
#endif
		_pkcs11h_mem_free ((void *)&session);
	}

#if defined(ENABLE_PKCS11H_THREADING)
	if (mutex_locked) {
		_pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.session);
		mutex_locked = FALSE;
	}
#endif

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

	return rv;
}
Esempio n. 11
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;
}
Esempio n. 12
0
CK_RV
_pkcs11h_session_getSlotList (
	IN const _pkcs11h_provider_t provider,
	IN const CK_BBOOL token_present,
	OUT CK_SLOT_ID_PTR * const pSlotList,
	OUT CK_ULONG_PTR pulCount
) {
	CK_SLOT_ID_PTR _slots = NULL;
	CK_ULONG _slotnum = 0;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_ASSERT (provider!=NULL);
	_PKCS11H_ASSERT (pSlotList!=NULL);
	_PKCS11H_ASSERT (pulCount!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_getSlotList entry provider=%p, token_present=%d, pSlotList=%p, pulCount=%p",
		(void *)provider,
		token_present ? 1 : 0,
		(void *)pSlotList,
		(void *)pulCount
	);

	*pSlotList = NULL;
	*pulCount = 0;

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

	if (
		(rv = provider->f->C_GetSlotList (
			token_present,
			NULL_PTR,
			&_slotnum
		)) != CKR_OK
	) {
		goto cleanup;
	}

	if (_slotnum > 0) {
		if ((rv = _pkcs11h_mem_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID))) != CKR_OK) {
			goto cleanup;
		}
	}

	if (_slotnum > 0) {
		if (
			(rv = provider->f->C_GetSlotList (
				token_present,
				_slots,
				&_slotnum
			)) != CKR_OK
		) {
			goto cleanup;
		}
	}

	*pSlotList = _slots;
	_slots = NULL;
	*pulCount = _slotnum;
	rv = CKR_OK;

cleanup:

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

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

	return rv;
}
Esempio n. 13
0
CK_RV
_pkcs11h_session_reset (
	IN const _pkcs11h_session_t session,
	IN void * const user_data,
	IN const unsigned mask_prompt,
	OUT CK_SLOT_ID * const p_slot
) {
	PKCS11H_BOOL found = FALSE;

	CK_RV rv = CKR_FUNCTION_FAILED;

	unsigned nRetry = 0;

	_PKCS11H_ASSERT (session!=NULL);
	/*_PKCS11H_ASSERT (user_data) NOT NEEDED */
	_PKCS11H_ASSERT (p_slot!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_reset entry session=%p, user_data=%p, mask_prompt=%08x, p_slot=%p",
		(void *)session,
		user_data,
		mask_prompt,
		(void *)p_slot
	);

	*p_slot = _PKCS11H_INVALID_SLOT_ID;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_reset Expected token manufacturerID='%s' model='%s', serialNumber='%s', label='%s'",
		session->token_id->manufacturerID,
		session->token_id->model,
		session->token_id->serialNumber,
		session->token_id->label
	);

	while (!found) {
		_pkcs11h_provider_t current_provider = NULL;

		for (
			current_provider = _g_pkcs11h_data->providers;
			(
				current_provider != NULL &&
				!found
			);
			current_provider = current_provider->next
		) {
			CK_SLOT_ID_PTR slots = NULL;
			CK_ULONG slotnum;
			CK_SLOT_ID slot_index;

			/*
			 * Skip all other providers,
			 * if one was set in the past
			 */
			if (
				session->provider != NULL &&
				session->provider != current_provider
			) {
				continue;
			}

			if (
				(rv = _pkcs11h_session_getSlotList (
					current_provider,
					CK_TRUE,
					&slots,
					&slotnum
				)) != CKR_OK
			) {
				_PKCS11H_DEBUG (
					PKCS11H_LOG_DEBUG1,
					"PKCS#11: Cannot get slot list for provider '%s' rv=%lu-'%s'",
					current_provider->manufacturerID,
					rv,
					pkcs11h_getMessage (rv)
				);
				goto retry1;
			}

			for (
				slot_index=0;
				(
					slot_index < slotnum &&
					!found
				);
				slot_index++
			) {
				pkcs11h_token_id_t token_id = NULL;
				CK_TOKEN_INFO info;

				if (
					(rv = current_provider->f->C_GetTokenInfo (
						slots[slot_index],
						&info
					)) != CKR_OK ||
					(rv = _pkcs11h_token_getTokenId (
						&info,
						&token_id
					)) != CKR_OK
				) {
					goto retry11;
				}

				_PKCS11H_DEBUG (
					PKCS11H_LOG_DEBUG2,
					"PKCS#11: _pkcs11h_session_reset Found token manufacturerID='%s' model='%s', serialNumber='%s', label='%s'",
					token_id->manufacturerID,
					token_id->model,
					token_id->serialNumber,
					token_id->label
				);

				if (
					pkcs11h_token_sameTokenId (
						session->token_id,
						token_id
					)
				) {
					found = TRUE;
					*p_slot = slots[slot_index];
					if (session->provider == NULL) {
						session->provider = current_provider;
						session->allow_protected_auth_supported = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) != 0;
					}
				}

				rv = CKR_OK;

			retry11:

				if (rv != CKR_OK) {
					_PKCS11H_DEBUG (
						PKCS11H_LOG_DEBUG1,
						"PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%lu-'%s'",
						current_provider->manufacturerID,
						slots[slot_index],
						rv,
						pkcs11h_getMessage (rv)
					);
				}

				if (token_id != NULL) {
					pkcs11h_token_freeTokenId (token_id);
				}
			}

		retry1:
			if (slots != NULL) {
				_pkcs11h_mem_free ((void *)&slots);
				slots = NULL;
			}
		}

		if (!found && (mask_prompt & PKCS11H_PROMPT_MASK_ALLOW_TOKEN_PROMPT) == 0) {
			rv = CKR_TOKEN_NOT_PRESENT;
			goto cleanup;
		}

		if (!found) {
			PKCS11H_BOOL canceled;

			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Calling token_prompt hook for '%s'",
				session->token_id->display
			);

			canceled = !_g_pkcs11h_data->hooks.token_prompt (
				_g_pkcs11h_data->hooks.token_prompt_data,
				user_data,
				session->token_id,
				nRetry++
			);

			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: token_prompt returned %d",
				canceled ? 0 : 1
			);

			if (canceled) {
				rv = CKR_CANCEL;
				goto cleanup;
			}
		}
	}

	rv = CKR_OK;

cleanup:

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

	return rv;
}
Esempio n. 14
0
CK_RV
pkcs11h_addProvider (
	IN const char * const reference,
	IN const char * const provider_location,
	IN const PKCS11H_BOOL allow_protected_auth,
	IN const unsigned mask_private_mode,
	IN const unsigned slot_event_method,
	IN const unsigned slot_poll_interval,
	IN const PKCS11H_BOOL cert_is_private
) {
#if defined(ENABLE_PKCS11H_THREADING)
	PKCS11H_BOOL mutex_locked = FALSE;
#endif
#if defined(ENABLE_PKCS11H_DEBUG)
#if defined(_WIN32)
	int mypid = 0;
#else
	pid_t mypid = getpid ();
#endif
#endif
#if !defined(_WIN32)
	void *p;
#endif

	_pkcs11h_provider_t provider = NULL;
	CK_C_GetFunctionList gfl = NULL;
	CK_C_INITIALIZE_ARGS initargs;
	CK_C_INITIALIZE_ARGS_PTR pinitargs = NULL;
	CK_INFO info;
	CK_RV rv = CKR_FUNCTION_FAILED;

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

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_addProvider entry version='%s', pid=%d, reference='%s', provider_location='%s', allow_protected_auth=%d, mask_private_mode=%08x, cert_is_private=%d",
		PACKAGE_VERSION,
		mypid,
		reference,
		provider_location,
		allow_protected_auth ? 1 : 0,
		mask_private_mode,
		cert_is_private ? 1 : 0
	);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Adding provider '%s'-'%s'",
		reference,
		provider_location
	);

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global)) != CKR_OK) {
		goto cleanup;
	}
	mutex_locked = TRUE;
#endif

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

	strncpy (
		provider->reference,
		reference,
		sizeof (provider->reference)-1
	);
	provider->reference[sizeof (provider->reference)-1] = '\x0';
	strncpy (
		provider->manufacturerID,
		(
			strlen (provider_location) < sizeof (provider->manufacturerID) ?
			provider_location :
			provider_location+strlen (provider_location)-sizeof (provider->manufacturerID)+1
		),
		sizeof (provider->manufacturerID)-1
	);
	provider->manufacturerID[sizeof (provider->manufacturerID)-1] = '\x0';
	provider->allow_protected_auth = allow_protected_auth;
	provider->mask_private_mode = mask_private_mode;
	provider->slot_event_method = slot_event_method;
	provider->slot_poll_interval = slot_poll_interval;
	provider->cert_is_private = cert_is_private;
		
#if defined(_WIN32)
	provider->handle = LoadLibraryA (provider_location);
#else
	provider->handle = dlopen (provider_location, RTLD_NOW);
#endif

	if (provider->handle == NULL) {
		rv = CKR_FUNCTION_FAILED;
		goto cleanup;
	}

#if defined(_WIN32)
	gfl = (CK_C_GetFunctionList)GetProcAddress (
		provider->handle,
		"C_GetFunctionList"
	);
#else
	/*
	 * Make compiler happy!
	 */
	p = dlsym (
		provider->handle,
		"C_GetFunctionList"
	);
	memmove (
		&gfl, 
		&p,
		sizeof (void *)
	);
#endif
	if (gfl == NULL) {
		rv = CKR_FUNCTION_FAILED;
		goto cleanup;
	}

	if ((rv = gfl (&provider->f)) != CKR_OK) {
		goto cleanup;
	}

	memset(&initargs, 0, sizeof(initargs));
	if ((initargs.pReserved = getenv("PKCS11H_INIT_ARGS_RESERVED")) != NULL) {
		pinitargs = &initargs;
	}

	if ((rv = provider->f->C_Initialize (pinitargs)) != CKR_OK) {
		if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
			rv = CKR_OK;
		}
		else {
			goto cleanup;
		}
	}
	else {
		provider->should_finalize = TRUE;
	}

	if ((rv = provider->f->C_GetInfo (&info)) != CKR_OK) {
		goto cleanup;
	}

	_pkcs11h_util_fixupFixedString (
		provider->manufacturerID,
		(char *)info.manufacturerID,
		sizeof (info.manufacturerID)
	);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_addProvider Provider '%s' manufacturerID '%s'",
		reference,
		provider->manufacturerID
	);

	provider->enabled = TRUE;

	if (_g_pkcs11h_data->providers == NULL) {
		_g_pkcs11h_data->providers = provider;
	}
	else {
		_pkcs11h_provider_t last = NULL;

		for (
			last = _g_pkcs11h_data->providers;
			last->next != NULL;
			last = last->next
		);
		last->next = provider;
	}

	provider = NULL;
	rv = CKR_OK;

cleanup:

	if (provider != NULL) {
		if (provider->handle != NULL) {
#if defined(_WIN32)
			FreeLibrary (provider->handle);
#else
			dlclose (provider->handle);
#endif
			provider->handle = NULL;
		}

		_pkcs11h_mem_free ((void *)&provider);
		provider = NULL;
	}

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

#if defined(ENABLE_PKCS11H_SLOTEVENT)
	_pkcs11h_slotevent_notify ();
#endif

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG1,
		"PKCS#11: Provider '%s' added rv=%lu-'%s'",
		reference,
		rv,
		pkcs11h_getMessage (rv)
	);

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

	return rv;
}
Esempio n. 15
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;
}
Esempio n. 16
0
CK_RV
pkcs11h_initialize (void) {
#if defined(ENABLE_PKCS11H_THREADING)
	PKCS11H_BOOL has_mutex_global = FALSE;
	PKCS11H_BOOL has_mutex_cache = FALSE;
	PKCS11H_BOOL has_mutex_session = FALSE;
#endif

	CK_RV rv = CKR_FUNCTION_FAILED;

	_pkcs11h_data_t data = NULL;
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_initialize entry"
	);

	pkcs11h_terminate ();

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

	if (_g_pkcs11h_crypto_engine.initialize == NULL) {
		if ((rv = pkcs11h_engine_setCrypto (PKCS11H_ENGINE_CRYPTO_AUTO)) != CKR_OK) {
			goto cleanup;
		}
	}

	if (!_g_pkcs11h_crypto_engine.initialize (_g_pkcs11h_crypto_engine.global_data)) {
		_PKCS11H_DEBUG (
			PKCS11H_LOG_ERROR,
			"PKCS#11: Cannot initialize crypto engine"
		);

		rv = CKR_FUNCTION_FAILED;
		goto cleanup;
	}

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexInit (&data->mutexes.global)) != CKR_OK) {
		goto cleanup;
	}
	has_mutex_global = TRUE;
	if ((rv = _pkcs11h_threading_mutexInit (&data->mutexes.cache)) != CKR_OK) {
		goto cleanup;
	}
	has_mutex_cache = TRUE;
	if ((rv = _pkcs11h_threading_mutexInit (&data->mutexes.session)) != CKR_OK) {
		goto cleanup;
	}
	has_mutex_session = TRUE;
#if !defined(_WIN32)
	if (
		pthread_atfork (
			__pkcs11h_threading_atfork_prepare,
			__pkcs11h_threading_atfork_parent,
			__pkcs11h_threading_atfork_child
		)
	) {
		rv = CKR_FUNCTION_FAILED;
		goto cleanup;
	}
#endif
#endif

	data->max_retries = _PKCS11H_DEFAULT_MAX_LOGIN_RETRY;
	data->allow_protected_auth = TRUE;
	data->pin_cache_period = _PKCS11H_DEFAULT_PIN_CACHE_PERIOD;
	data->initialized = TRUE;

	_g_pkcs11h_data = data;
	data = NULL;

	pkcs11h_setLogHook (__pkcs11h_hooks_default_log, NULL);
	pkcs11h_setTokenPromptHook (__pkcs11h_hooks_default_token_prompt, NULL);
	pkcs11h_setPINPromptHook (__pkcs11h_hooks_default_pin_prompt, NULL);

	rv = CKR_OK;

cleanup:

	if (data != NULL) {
#if defined(ENABLE_PKCS11H_THREADING)
		if (has_mutex_global) {
			_pkcs11h_threading_mutexFree (&data->mutexes.global);
			has_mutex_global = FALSE;
		}
		if (has_mutex_cache) {
			_pkcs11h_threading_mutexFree (&data->mutexes.cache);
			has_mutex_cache = FALSE;
		}
		if (has_mutex_session) {
			_pkcs11h_threading_mutexFree (&data->mutexes.session); 
			has_mutex_session = FALSE;
		}
#endif
		_pkcs11h_mem_free ((void *)&data);
		data = NULL;
	}

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

	return rv;
}
Esempio n. 17
0
CK_RV
pkcs11h_terminate (void) {

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

	if (_g_pkcs11h_data != NULL) {
		_pkcs11h_provider_t current_provider = NULL;

		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Removing providers"
		);

		for (
			current_provider = _g_pkcs11h_data->providers;
			current_provider != NULL;
			current_provider = current_provider->next
		) {
			pkcs11h_removeProvider (current_provider->reference);
		}

#if defined(ENABLE_PKCS11H_THREADING)
		_pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.cache);
		_pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.session);
		_pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global);
#endif

		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Releasing sessions"
		);

		while (_g_pkcs11h_data->sessions != NULL) {
			_pkcs11h_session_t current = _g_pkcs11h_data->sessions;
			_g_pkcs11h_data->sessions = _g_pkcs11h_data->sessions->next;

#if defined(ENABLE_PKCS11H_THREADING)
			_pkcs11h_threading_mutexLock (&current->mutex);
#endif

			current->valid = FALSE;

			if (current->reference_count != 0) {
				_PKCS11H_DEBUG (
					PKCS11H_LOG_DEBUG1,
					"PKCS#11: Warning: Found session with references"
				);
			}

			if (current->token_id != NULL) {
				pkcs11h_token_freeTokenId (current->token_id);
				current->token_id = NULL;
			}

#if defined(ENABLE_PKCS11H_CERTIFICATE)
			pkcs11h_certificate_freeCertificateIdList (current->cached_certs);
#endif

			current->provider = NULL;

#if defined(ENABLE_PKCS11H_THREADING)
			_pkcs11h_threading_mutexFree (&current->mutex);
#endif

			_pkcs11h_mem_free ((void *)&current);
		}

#if defined(ENABLE_PKCS11H_SLOTEVENT)
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Terminating slotevent"
		);

		_pkcs11h_slotevent_terminate ();
#endif
		_PKCS11H_DEBUG (
			PKCS11H_LOG_DEBUG1,
			"PKCS#11: Marking as uninitialized"
		);
		
		_g_pkcs11h_data->initialized = FALSE;

		while (_g_pkcs11h_data->providers != NULL) {
			_pkcs11h_provider_t current = _g_pkcs11h_data->providers;
			_g_pkcs11h_data->providers = _g_pkcs11h_data->providers->next;

			_pkcs11h_mem_free ((void *)&current);
		}

#if defined(ENABLE_PKCS11H_THREADING)
		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.global); 
		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.cache);
		_pkcs11h_threading_mutexFree (&_g_pkcs11h_data->mutexes.session); 
#endif

		_g_pkcs11h_crypto_engine.uninitialize (_g_pkcs11h_crypto_engine.global_data);

		_pkcs11h_mem_free ((void *)&_g_pkcs11h_data);
	}

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

	return CKR_OK;
}
Esempio n. 18
0
CK_RV
_pkcs11h_session_findObjects (
	IN const _pkcs11h_session_t session,
	IN const CK_ATTRIBUTE * const filter,
	IN const CK_ULONG filter_attrs,
	OUT CK_OBJECT_HANDLE **const p_objects,
	OUT CK_ULONG *p_objects_found
) {
	/*
	 * THREADING:
	 * session->mutex must be locked
	 */
	PKCS11H_BOOL should_FindObjectsFinal = FALSE;

	CK_OBJECT_HANDLE *objects = NULL;
	CK_ULONG objects_size = 0;
	CK_OBJECT_HANDLE objects_buffer[100];
	CK_ULONG objects_found;
	CK_OBJECT_HANDLE oLast = _PKCS11H_INVALID_OBJECT_HANDLE;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_ASSERT (session!=NULL);
	_PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL);
	_PKCS11H_ASSERT (p_objects!=NULL);
	_PKCS11H_ASSERT (p_objects_found!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_session_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p",
		(void *)session,
		(void *)filter,
		filter_attrs,
		(void *)p_objects,
		(void *)p_objects_found
	);

	*p_objects = NULL;
	*p_objects_found = 0;

	if (
		(rv = session->provider->f->C_FindObjectsInit (
			session->session_handle,
			(CK_ATTRIBUTE *)filter,
			filter_attrs
		)) != CKR_OK
	) {
		goto cleanup;
	}
	should_FindObjectsFinal = TRUE;

	while (
		(rv = session->provider->f->C_FindObjects (
			session->session_handle,
			objects_buffer,
			sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE),
			&objects_found
		)) == CKR_OK &&
		objects_found > 0
	) {
		CK_OBJECT_HANDLE *temp = NULL;

		/*
		 * Begin workaround
		 *
		 * Workaround iKey bug
		 * It returns the same objects over and over
		 */
		if (oLast == objects_buffer[0]) {
			_PKCS11H_LOG (
				PKCS11H_LOG_WARN,
				"PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
			);
			break;
		}
		oLast = objects_buffer[0];
		/* End workaround */

		if (
			(rv = _pkcs11h_mem_malloc (
				(void *)&temp,
				(objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE)
			)) != CKR_OK
		) {
			goto cleanup;
		}

		if (objects != NULL) {
			memmove (
				temp,
				objects,
				objects_size * sizeof (CK_OBJECT_HANDLE)
			);
		}
		memmove (
			temp + objects_size,
			objects_buffer,
			objects_found * sizeof (CK_OBJECT_HANDLE)
		);

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

		objects = temp;
		objects_size += objects_found;
		temp = NULL;
	}

	if (should_FindObjectsFinal) {
		session->provider->f->C_FindObjectsFinal (
			session->session_handle
		);
		should_FindObjectsFinal = FALSE;
	}

	*p_objects = objects;
	*p_objects_found = objects_size;
	objects = NULL;
	objects_size = 0;
	rv = CKR_OK;

cleanup:

	if (objects != NULL) {
		_pkcs11h_mem_free ((void *)&objects);
		objects = NULL;
		objects_size = 0;
	}

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

	return rv;
}
Esempio n. 19
0
CK_RV
pkcs11h_token_enumTokenIds (
	IN const unsigned method,
	OUT pkcs11h_token_id_list_t * const p_token_id_list
) {
#if defined(ENABLE_PKCS11H_THREADING)
	PKCS11H_BOOL mutex_locked = FALSE;
#endif

	pkcs11h_token_id_list_t token_id_list = NULL;
	_pkcs11h_provider_t current_provider;
	CK_RV rv = CKR_FUNCTION_FAILED;

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

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_enumTokenIds entry method=%u, p_token_id_list=%p",
		method,
		(void *)p_token_id_list
	);

	*p_token_id_list = NULL;

#if defined(ENABLE_PKCS11H_THREADING)
	if ((rv = _pkcs11h_threading_mutexLock (&_g_pkcs11h_data->mutexes.global)) != CKR_OK) {
		goto cleanup;
	}
	mutex_locked = TRUE;
#endif

	for (
		current_provider = _g_pkcs11h_data->providers;
		current_provider != NULL;
		current_provider = current_provider->next
	) {
		CK_SLOT_ID_PTR slots = NULL;
		CK_ULONG slotnum;
		CK_SLOT_ID slot_index;

		/*
		 * Skip disabled providers
		 */
		if (!current_provider->enabled) {
			continue;
		}

		if (
			(rv = _pkcs11h_session_getSlotList (
				current_provider,
				CK_TRUE,
				&slots,
				&slotnum
			)) != CKR_OK
		) {
			_PKCS11H_DEBUG (
				PKCS11H_LOG_DEBUG1,
				"PKCS#11: Cannot get slot list for provider '%s' rv=%lu-'%s'",
				current_provider->manufacturerID,
				rv,
				pkcs11h_getMessage (rv)
			);
			goto retry1;
		}

		for (
			slot_index=0;
			slot_index < slotnum;
			slot_index++
		) {
			pkcs11h_token_id_list_t entry = NULL;
			CK_TOKEN_INFO info;

			if (
				(rv = _pkcs11h_mem_malloc (
					(void *)&entry,
					sizeof (struct pkcs11h_token_id_list_s)
				)) != CKR_OK ||
				(rv = current_provider->f->C_GetTokenInfo (
					slots[slot_index],
					&info
				)) != CKR_OK ||
				(rv = _pkcs11h_token_getTokenId (
					&info,
					&entry->token_id
				))
			) {
				goto retry11;
			}

			entry->next = token_id_list;
			token_id_list = entry;
			entry = NULL;
			rv = CKR_OK;

		retry11:

			if (entry != NULL) {
				pkcs11h_token_freeTokenIdList (entry);
				entry = NULL;
			}
		}

	retry1:

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

	if (method == PKCS11H_ENUM_METHOD_CACHE) {
		_pkcs11h_session_t session = NULL;

		for (
			session = _g_pkcs11h_data->sessions;
			session != NULL;
			session = session->next
		) {
			pkcs11h_token_id_list_t entry = NULL;
			PKCS11H_BOOL found = FALSE;

			for (
				entry = token_id_list;
				entry != NULL && !found;
				entry = entry->next
			) {
				if (
					pkcs11h_token_sameTokenId (
						session->token_id,
						entry->token_id
					)
				) {
					found = TRUE;
				}
			}

			if (!found) {
				entry = NULL;

				if (
					(rv = _pkcs11h_mem_malloc (
						(void *)&entry,
						sizeof (struct pkcs11h_token_id_list_s)
					)) != CKR_OK ||
					(rv = pkcs11h_token_duplicateTokenId (
						&entry->token_id,
						session->token_id
					)) != CKR_OK 
				) {
					goto retry12;
				}

				entry->next = token_id_list;
				token_id_list = entry;
				entry = NULL;

			retry12:

				if (entry != NULL) {
					if (entry->token_id != NULL) {
						pkcs11h_token_freeTokenId (entry->token_id);
					}
					_pkcs11h_mem_free ((void *)&entry);
				}
			}
		}
	}

	*p_token_id_list = token_id_list;
	token_id_list = NULL;
	rv = CKR_OK;

cleanup:

	if (token_id_list != NULL) {
		pkcs11h_token_freeTokenIdList (token_id_list);
		token_id_list = NULL;
	}

#if defined(ENABLE_PKCS11H_THREADING)
	if (mutex_locked) {
		rv = _pkcs11h_threading_mutexRelease (&_g_pkcs11h_data->mutexes.global);
		mutex_locked = FALSE;
	}
#endif

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_enumTokenIds return rv=%lu-'%s', *p_token_id_list=%p",
		rv,
		pkcs11h_getMessage (rv),
		(void *)p_token_id_list
	);
	
	return rv;
}
CK_RV
pkcs11h_token_deserializeTokenId (
	OUT pkcs11h_token_id_t *p_token_id,
	IN const char * const sz
) {
#define __PKCS11H_TARGETS_NUMBER 4
	struct {
		char *p;
		size_t s;
	} targets[__PKCS11H_TARGETS_NUMBER];

	pkcs11h_token_id_t token_id = NULL;
	char *p1 = NULL;
	char *_sz = NULL;
	int e;
	CK_RV rv = CKR_FUNCTION_FAILED;

	_PKCS11H_ASSERT (p_token_id!=NULL);
	_PKCS11H_ASSERT (sz!=NULL);

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_token_deserializeTokenId entry p_token_id=%p, sz='%s'",
		(void *)p_token_id,
		sz
	);

	*p_token_id = NULL;

	if (
		(rv = _pkcs11h_mem_strdup (
			(void *)&_sz,
			sz
		)) != CKR_OK
	) {
		goto cleanup;
	}

	p1 = _sz;

	if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) {
		goto cleanup;
	}

	targets[0].p = token_id->manufacturerID;
	targets[0].s = sizeof (token_id->manufacturerID);
	targets[1].p = token_id->model;
	targets[1].s = sizeof (token_id->model);
	targets[2].p = token_id->serialNumber;
	targets[2].s = sizeof (token_id->serialNumber);
	targets[3].p = token_id->label;
	targets[3].s = sizeof (token_id->label);

	for (e=0;e < __PKCS11H_TARGETS_NUMBER;e++) {
		size_t l;
		char *p2 = NULL;

		/*
		 * Don't search for last
		 * separator
		 */
		if (e != __PKCS11H_TARGETS_NUMBER-1) {
			p2 = strchr (p1, '/');
			if (p2 == NULL) {
				rv = CKR_ATTRIBUTE_VALUE_INVALID;
				goto cleanup;
			}
			else {
				*p2 = '\x0';
			}
		}

		if (
			(rv = _pkcs11h_util_unescapeString (
				NULL,
				p1,
				&l
			)) != CKR_OK
		) {
			goto cleanup;
		}

		if (l > targets[e].s) {
			rv = CKR_ATTRIBUTE_VALUE_INVALID;
			goto cleanup;
		}

		l = targets[e].s;

		if (
			(rv = _pkcs11h_util_unescapeString (
				targets[e].p,
				p1,
				&l
			)) != CKR_OK
		) {
			goto cleanup;
		}

		p1 = p2+1;
	}

	strncpy (
		token_id->display,
		token_id->label,
		sizeof (token_id->display)
	);

	*p_token_id = token_id;
	token_id = NULL;

	rv = CKR_OK;

cleanup:

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

	if (token_id != NULL) {
		pkcs11h_token_freeTokenId (token_id);
	}

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

	return rv;
#undef __PKCS11H_TARGETS_NUMBER
}
CK_RV
pkcs11h_certificate_deserializeCertificateId (
	OUT pkcs11h_certificate_id_t * const p_certificate_id,
	IN const char * const sz
) {
	pkcs11h_certificate_id_t certificate_id = NULL;
	CK_RV rv = CKR_FUNCTION_FAILED;
	char *p = NULL;
	char *_sz = NULL;

	_PKCS11H_ASSERT (p_certificate_id!=NULL);
	_PKCS11H_ASSERT (sz!=NULL);

	*p_certificate_id = NULL;

	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: pkcs11h_certificate_deserializeCertificateId entry p_certificate_id=%p, sz='%s'",
		(void *)p_certificate_id,
		sz
	);

	if (
		(rv = _pkcs11h_mem_strdup (
			(void *)&_sz,
			sz
		)) != CKR_OK
	) {
		goto cleanup;
	}

	p = _sz;

	if ((rv = _pkcs11h_certificate_newCertificateId (&certificate_id)) != CKR_OK) {
		goto cleanup;
	}

	if ((p = strrchr (_sz, '/')) == NULL) {
		rv = CKR_ATTRIBUTE_VALUE_INVALID;
		goto cleanup;
	}

	*p = '\x0';
	p++;

	if (
		(rv = pkcs11h_token_deserializeTokenId (
			&certificate_id->token_id,
			_sz
		)) != CKR_OK
	) {
		goto cleanup;
	}

	certificate_id->attrCKA_ID_size = strlen (p)/2;

	if (
		(rv = _pkcs11h_mem_malloc (
			(void *)&certificate_id->attrCKA_ID,
			certificate_id->attrCKA_ID_size)
		) != CKR_OK ||
		(rv = _pkcs11h_util_hexToBinary (
			certificate_id->attrCKA_ID,
			p,
			&certificate_id->attrCKA_ID_size
		)) != CKR_OK
	) {
		goto cleanup;
	}

	*p_certificate_id = certificate_id;
	certificate_id = NULL;
	rv = CKR_OK;

cleanup:

	if (certificate_id != NULL) {
		pkcs11h_certificate_freeCertificateId (certificate_id);
		certificate_id = NULL;
	}

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

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

	return rv;

}
Esempio n. 22
0
CK_RV
_pkcs11h_token_getTokenId (
	IN const CK_TOKEN_INFO_PTR info,
	OUT pkcs11h_token_id_t * const p_token_id
) {
	pkcs11h_token_id_t token_id;
	CK_RV rv = CKR_FUNCTION_FAILED;
	
	_PKCS11H_ASSERT (info!=NULL);
	_PKCS11H_ASSERT (p_token_id!=NULL);
	
	_PKCS11H_DEBUG (
		PKCS11H_LOG_DEBUG2,
		"PKCS#11: _pkcs11h_token_getTokenId entry p_token_id=%p",
		(void *)p_token_id
	);

	*p_token_id = NULL;

	if ((rv = _pkcs11h_token_newTokenId (&token_id)) != CKR_OK) {
		goto cleanup;
	}

	_pkcs11h_util_fixupFixedString (
		token_id->label,
		(char *)info->label,
		sizeof (info->label)
	);
	_pkcs11h_util_fixupFixedString (
		token_id->manufacturerID,
		(char *)info->manufacturerID,
		sizeof (info->manufacturerID)
	);
	_pkcs11h_util_fixupFixedString (
		token_id->model,
		(char *)info->model,
		sizeof (info->model)
	);
	_pkcs11h_util_fixupFixedString (
		token_id->serialNumber,
		(char *)info->serialNumber,
		sizeof (info->serialNumber)
	);
	strncpy (
		token_id->display,
		token_id->label,
		sizeof (token_id->display)
	);

	*p_token_id = token_id;
	token_id = NULL;
	rv = CKR_OK;

cleanup:

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

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

	return rv;
}