Esempio n. 1
0
/*
 * Find all keys of a given type (public or private)
 */
static int pkcs11_find_keys(PKCS11_TOKEN *token, unsigned int type)
{
	PKCS11_SLOT *slot = TOKEN2SLOT(token);
	PKCS11_CTX *ctx = TOKEN2CTX(token);
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
	CK_OBJECT_CLASS key_search_class;
	CK_ATTRIBUTE key_search_attrs[1] = {
		{CKA_CLASS, &key_search_class, sizeof(key_search_class)},
	};
	int rv, res = -1;

	/* Tell the PKCS11 lib to enumerate all matching objects */
	key_search_class = type;
	rv = CRYPTOKI_call(ctx,
		C_FindObjectsInit(spriv->session, key_search_attrs, 1));
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_KEYS, rv);

	keys->num = 0;
	do {
		res = pkcs11_next_key(ctx, token, spriv->session, type);
	} while (res == 0);

	CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));

	return (res < 0) ? -1 : 0;
}
Esempio n. 2
0
/*
 * Return keys of a given type (public or private)
 * Use the cached values if available
 */
int pkcs11_enumerate_keys(PKCS11_TOKEN *token, unsigned int type,
		PKCS11_KEY ** keyp, unsigned int *countp)
{
	PKCS11_SLOT *slot = TOKEN2SLOT(token);
	PKCS11_CTX *ctx = TOKEN2CTX(token);
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
	int rv;

	if (keys->num < 0) { /* No cache was built for the specified type */
		/* Make sure we have a session */
		if (!spriv->haveSession && PKCS11_open_session(slot, 0))
			return -1;
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
		rv = pkcs11_find_keys(token, type);
		CRYPTO_THREAD_unlock(cpriv->rwlock);
		if (rv < 0) {
			pkcs11_destroy_keys(token, type);
			return -1;
		}
	}
	if (keyp)
		*keyp = keys->keys;
	if (countp)
		*countp = keys->num;
	return 0;
}
Esempio n. 3
0
/*
 * Find all certs of a given type (public or private)
 */
static int pkcs11_find_certs(PKCS11_TOKEN *token)
{
	PKCS11_SLOT *slot = TOKEN2SLOT(token);
	PKCS11_CTX *ctx = SLOT2CTX(slot);
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	CK_OBJECT_CLASS cert_search_class;
	CK_ATTRIBUTE cert_search_attrs[] = {
		{CKA_CLASS, &cert_search_class, sizeof(cert_search_class)},
	};
	int rv, res = -1;

	/* Tell the PKCS11 lib to enumerate all matching objects */
	cert_search_class = CKO_CERTIFICATE;
	rv = CRYPTOKI_call(ctx, C_FindObjectsInit(spriv->session, cert_search_attrs, 1));
	CRYPTOKI_checkerr(PKCS11_F_PKCS11_ENUM_CERTS, rv);

	tpriv->ncerts = 0;
	do {
		res = pkcs11_next_cert(ctx, token, spriv->session);
	} while (res == 0);

	CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));

	return (res < 0) ? -1 : 0;
}
Esempio n. 4
0
/*
 * Enumerate all certs on the card
 */
int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
		PKCS11_CERT **certp, unsigned int *countp)
{
	PKCS11_SLOT *slot = TOKEN2SLOT(token);
	PKCS11_CTX *ctx = SLOT2CTX(slot);
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
	PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
	int rv;

	if (tpriv->ncerts < 0) {
		/* Make sure we have a session */
		if (!spriv->haveSession && PKCS11_open_session(slot, 0))
			return -1;
		CRYPTO_THREAD_write_lock(cpriv->rwlock);
		rv = pkcs11_find_certs(token);
		CRYPTO_THREAD_unlock(cpriv->rwlock);
		if (rv < 0) {
			pkcs11_destroy_certs(token);
			return -1;
		}
	}
	if (certp)
		*certp = tpriv->certs;
	if (countp)
		*countp = tpriv->ncerts;
	return 0;
}
Esempio n. 5
0
static int pkcs11_init_cert(PKCS11_CTX * ctx, PKCS11_TOKEN * token,
	 CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
{
	PKCS11_TOKEN_private *tpriv;
	PKCS11_CERT_private *kpriv;
	PKCS11_CERT *cert, *tmp;
	char label[256], data[2048];
	unsigned char id[256];
	CK_CERTIFICATE_TYPE cert_type;
	size_t size;

	size = sizeof(cert_type);
	if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, &cert_type, &size))
		return -1;

	/* Ignore any certs we don't understand */
	if (cert_type != CKC_X_509)
		return 0;

	tpriv = PRIVTOKEN(token);
	tmp = (PKCS11_CERT *) OPENSSL_realloc(tpriv->certs,
				(tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
	if (!tmp) {
		free(tpriv->certs);
		tpriv->certs = NULL;
		return -1;
	}
	tpriv->certs = tmp;

	cert = tpriv->certs + tpriv->ncerts++;
	memset(cert, 0, sizeof(*cert));
	cert->_private = kpriv = PKCS11_NEW(PKCS11_CERT_private);
	kpriv->object = obj;
	kpriv->parent = token;

	if (!pkcs11_getattr_s(token, obj, CKA_LABEL, label, sizeof(label)))
		cert->label = BUF_strdup(label);
	size = sizeof(data);
	if (!pkcs11_getattr_var(token, obj, CKA_VALUE, data, &size)) {
		const unsigned char *p = (unsigned char *) data;

		cert->x509 = d2i_X509(NULL, &p, size);
	}
	cert->id_len = sizeof(id);
	if (!pkcs11_getattr_var(token, obj, CKA_ID, id, &cert->id_len)) {
		cert->id = (unsigned char *) malloc(cert->id_len);
		memcpy(cert->id, id, cert->id_len);
	}

	/* Initialize internal information */
	kpriv->id_len = sizeof(kpriv->id);
	if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
		kpriv->id_len = 0;

	if (ret)
		*ret = cert;

	return 0;
}
Esempio n. 6
0
/*
 * Enumerate all certs on the card
 */
int
PKCS11_enumerate_certs(PKCS11_TOKEN * token,
		       PKCS11_CERT ** certp, unsigned int *countp)
{
	PKCS11_TOKEN_private *priv = PRIVTOKEN(token);

	if (priv->ncerts < 0) {
		priv->ncerts = 0;
		if (pkcs11_find_certs(token)) {
			pkcs11_destroy_certs(token);
			return -1;
		}
	}
	*certp = priv->certs;
	*countp = priv->ncerts;
	return 0;
}
Esempio n. 7
0
/*
 * Destroy all certs
 */
void pkcs11_destroy_certs(PKCS11_TOKEN * token)
{
	PKCS11_TOKEN_private *priv = PRIVTOKEN(token);

	while (priv->ncerts > 0) {
		PKCS11_CERT *cert = &priv->certs[--(priv->ncerts)];

		if (cert->x509)
			X509_free(cert->x509);
		OPENSSL_free(cert->label);
		if (cert->id)
			free(cert->id);
		if (cert->_private != NULL)
			OPENSSL_free(cert->_private);
	}
	if (priv->certs)
		OPENSSL_free(priv->certs);
	priv->ncerts = -1;
	priv->certs = NULL;
}
Esempio n. 8
0
/*
 * Destroy all keys of a given type (public or private)
 */
void pkcs11_destroy_keys(PKCS11_TOKEN *token, unsigned int type)
{
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;

	while (keys->num > 0) {
		PKCS11_KEY *key = &keys->keys[--(keys->num)];

		if (key->evp_key)
			EVP_PKEY_free(key->evp_key);
		OPENSSL_free(key->label);
		if (key->id)
			OPENSSL_free(key->id);
		if (key->_private != NULL)
			OPENSSL_free(key->_private);
	}
	if (keys->keys)
		OPENSSL_free(keys->keys);
	keys->keys = NULL;
	keys->num = -1;
}
Esempio n. 9
0
static int pkcs11_init_key(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
		CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj,
		CK_OBJECT_CLASS type, PKCS11_KEY ** ret)
{
	PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
	PKCS11_keys *keys = (type == CKO_PRIVATE_KEY) ? &tpriv->prv : &tpriv->pub;
	PKCS11_KEY_private *kpriv;
	PKCS11_KEY *key, *tmp;
	CK_KEY_TYPE key_type;
	PKCS11_KEY_ops *ops;
	size_t size;

	(void)ctx;
	(void)session;

	size = sizeof(key_type);
	if (pkcs11_getattr_var(token, obj, CKA_KEY_TYPE, (CK_BYTE *)&key_type, &size))
		return -1;

	switch (key_type) {
	case CKK_RSA:
		ops = &pkcs11_rsa_ops;
		break;
	case CKK_EC:
		ops = pkcs11_ec_ops;
		if (ops == NULL)
			return 0; /* not supported */
		break;
	default:
		/* Ignore any keys we don't understand */
		return 0;
	}

	tmp = OPENSSL_realloc(keys->keys, (keys->num + 1) * sizeof(PKCS11_KEY));
	if (tmp == NULL) {
		OPENSSL_free(keys->keys);
		keys->keys = NULL;
		return -1;
	}
	keys->keys = tmp;

	key = keys->keys + keys->num++;
	memset(key, 0, sizeof(PKCS11_KEY));
	kpriv = OPENSSL_malloc(sizeof(PKCS11_KEY_private));
	if (kpriv)
		memset(kpriv, 0, sizeof(PKCS11_KEY_private));
	key->_private = kpriv;
	kpriv->object = obj;
	kpriv->parent = token;

	pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&key->label, NULL);
	key->id_len = 0;
	pkcs11_getattr_alloc(token, obj, CKA_ID, &key->id, &key->id_len);
	key->isPrivate = (type == CKO_PRIVATE_KEY);

	/* Initialize internal information */
	kpriv->id_len = sizeof(kpriv->id);
	if (pkcs11_getattr_var(token, obj, CKA_ID, kpriv->id, &kpriv->id_len))
		kpriv->id_len = 0;
	kpriv->ops = ops;
	kpriv->forkid = _P11_get_forkid();

	if (ret)
		*ret = key;
	return 0;
}
Esempio n. 10
0
static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
		CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
{
	PKCS11_TOKEN_private *tpriv;
	PKCS11_CERT_private *cpriv;
	PKCS11_CERT *cert, *tmp;
	unsigned char *data;
	CK_CERTIFICATE_TYPE cert_type;
	size_t size;

	(void)ctx;
	(void)session;

	size = sizeof(cert_type);
	if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, (CK_BYTE *)&cert_type, &size))
		return -1;

	/* Ignore any certs we don't understand */
	if (cert_type != CKC_X_509)
		return 0;

	tpriv = PRIVTOKEN(token);
	tmp = OPENSSL_realloc(tpriv->certs,
		(tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
	if (tmp == NULL) {
		OPENSSL_free(tpriv->certs);
		tpriv->certs = NULL;
		return -1;
	}
	tpriv->certs = tmp;

	cert = tpriv->certs + tpriv->ncerts++;
	memset(cert, 0, sizeof(*cert));
	cpriv = OPENSSL_malloc(sizeof(PKCS11_CERT_private));
	if (cpriv == NULL)
		return -1;
	memset(cpriv, 0, sizeof(PKCS11_CERT_private));
	cert->_private = cpriv;
	cpriv->object = obj;
	cpriv->parent = token;

	pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&cert->label, NULL);
	size = 0;
	if (!pkcs11_getattr_alloc(token, obj, CKA_VALUE, &data, &size)) {
		const unsigned char *p = data;

		cert->x509 = d2i_X509(NULL, &p, (long)size);
		OPENSSL_free(data);
	}
	cert->id_len = 0;
	pkcs11_getattr_alloc(token, obj, CKA_ID, &cert->id, &cert->id_len);

	/* Initialize internal information */
	cpriv->id_len = sizeof(cpriv->id);
	if (pkcs11_getattr_var(token, obj, CKA_ID, cpriv->id, &cpriv->id_len))
		cpriv->id_len = 0;

	if (ret)
		*ret = cert;
	return 0;
}