static CK_RV
trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
	GNode *node;
	GBytes *integer;
	CK_RV rv;

	g_assert (GKM_XDG_IS_TRUST (self));

	node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL);
	g_return_val_if_fail (node, CKR_GENERAL_ERROR);

	/* If the assertion doesn't contain this info ... */
	if (!egg_asn1x_have (node)) {
		gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: %s wants %s which is not part of assertion",
		           gkm_log_attr_type (attr->type), part);
		return CKR_ATTRIBUTE_TYPE_INVALID;
	}

	integer = egg_asn1x_get_integer_as_raw (node);
	g_return_val_if_fail (integer, CKR_GENERAL_ERROR);

	rv = gkm_attribute_set_bytes (attr, integer);
	g_bytes_unref (integer);

	return rv;
}
Beispiel #2
0
static gboolean
gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data)
{
	GkmXdgTrust *self = GKM_XDG_TRUST (base);

	g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
	g_return_val_if_fail (data, FALSE);
	g_return_val_if_fail (n_data, FALSE);
	g_return_val_if_fail (self->pv->asn, FALSE);

	if (!save_assertions (self, self->pv->asn))
		return FALSE;

	*data = egg_asn1x_encode (self->pv->asn, NULL, n_data);
	if (*data == NULL) {
		g_warning ("encoding trust failed: %s", egg_asn1x_message (self->pv->asn));
		return FALSE;
	}

	/* ASN.1 now refers to this data, take ownership */
	g_free (self->pv->data);
	self->pv->data = *data;
	self->pv->n_data = *n_data;

	/* Return a duplicate, since we own encoded */
	*data = g_memdup (*data, *n_data);
	return TRUE;
}
Beispiel #3
0
static CK_RV
trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
	GNode *node;
	gpointer integer;
	gsize n_integer;
	CK_RV rv;

	g_assert (GKM_XDG_IS_TRUST (self));

	node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL);
	g_return_val_if_fail (node, CKR_GENERAL_ERROR);

	/* If the assertion doesn't contain this info ... */
	if (!egg_asn1x_have (node))
		return CKR_ATTRIBUTE_TYPE_INVALID;

	integer = egg_asn1x_get_integer_as_raw (node, NULL, &n_integer);
	g_return_val_if_fail (integer, CKR_GENERAL_ERROR);

	rv = gkm_attribute_set_data (attr, integer, n_integer);
	g_free (integer);

	return rv;
}
void
gkm_xdg_trust_remove_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
                                GkmTransaction *transaction)
{
	GBytes *key;

	g_return_if_fail (GKM_XDG_IS_TRUST (self));
	g_return_if_fail (GKM_IS_ASSERTION (assertion));
	g_return_if_fail (!transaction || GKM_IS_TRANSACTION (transaction));

	key = lookup_assertion_key (assertion);
	g_return_if_fail (key);

	/* Assertion needs to be from this trust object */
	g_return_if_fail (g_hash_table_lookup (self->pv->assertions, key) == assertion);
	remove_assertion_from_trust (self, assertion, transaction);
}
Beispiel #5
0
static CK_RV
trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
	GNode *node;
	gconstpointer element;
	gsize n_element;

	g_assert (GKM_XDG_IS_TRUST (self));

	node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL);
	g_return_val_if_fail (node, CKR_GENERAL_ERROR);

	/* If the assertion doesn't contain this info ... */
	if (!egg_asn1x_have (node))
		return CKR_ATTRIBUTE_TYPE_INVALID;

	element = egg_asn1x_get_raw_element (node, &n_element);
	return gkm_attribute_set_data (attr, element, n_element);
}
Beispiel #6
0
static gboolean
gkm_xdg_trust_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
{
	GkmXdgTrust *self = GKM_XDG_TRUST (base);
	GNode *asn = NULL;
	gpointer copy;

	g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
	g_return_val_if_fail (data, FALSE);

	if (n_data == 0)
		return FALSE;

	copy = g_memdup (data, n_data);

	asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
	g_return_val_if_fail (asn, FALSE);

	if (!egg_asn1x_decode (asn, copy, n_data)) {
		g_warning ("couldn't parse trust data: %s", egg_asn1x_message (asn));
		egg_asn1x_destroy (asn);
		g_free (copy);
		return FALSE;
	}

	/* Next parse out all the pairs */
	if (!load_assertions (self, asn)) {
		egg_asn1x_destroy (asn);
		g_free (copy);
		return FALSE;
	}

	/* Take ownership of this new data */
	g_free (self->pv->data);
	self->pv->data = copy;
	self->pv->n_data = n_data;
	egg_asn1x_destroy (self->pv->asn);
	self->pv->asn = asn;

	return TRUE;
}
void
gkm_xdg_trust_replace_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
                             GkmTransaction *transaction)
{
	GkmAssertion *previous;
	GBytes *key;

	g_return_if_fail (GKM_XDG_IS_TRUST (self));
	g_return_if_fail (GKM_IS_ASSERTION (assertion));
	g_return_if_fail (!transaction || GKM_IS_TRANSACTION (transaction));

	/* Build up a key if we don't have one */
	key = lookup_or_create_assertion_key (assertion);

	/* Remove any previous assertion with this key */
	previous = g_hash_table_lookup (self->pv->assertions, key);
	if (previous != NULL)
		remove_assertion_from_trust (self, previous, transaction);
	add_assertion_to_trust (self, assertion, transaction);

}
static gboolean
save_assertions (GkmXdgTrust *self, GNode *asn)
{
	GHashTableIter iter;
	GNode *pair, *node;
	gpointer value;

	g_assert (GKM_XDG_IS_TRUST (self));
	g_assert (asn);

	node = egg_asn1x_node (asn, "assertions", NULL);
	egg_asn1x_clear (node);

	g_hash_table_iter_init (&iter, self->pv->assertions);
	while (g_hash_table_iter_next (&iter, NULL, &value)) {
		pair = egg_asn1x_append (node);
		g_return_val_if_fail (pair, FALSE);
		save_assertion (pair, GKM_ASSERTION (value));
	}

	return TRUE;
}
static GBytes *
gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login)
{
	GkmXdgTrust *self = GKM_XDG_TRUST (base);
	GBytes *bytes;

	g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
	g_return_val_if_fail (self->pv->asn, FALSE);

	if (!save_assertions (self, self->pv->asn))
		return FALSE;

	bytes = egg_asn1x_encode (self->pv->asn, NULL);
	if (bytes == NULL) {
		g_warning ("encoding trust failed: %s", egg_asn1x_message (self->pv->asn));
		return FALSE;
	}

	if (self->pv->bytes)
		g_bytes_unref (self->pv->bytes);
	self->pv->bytes = bytes;

	return g_bytes_ref (bytes);
}
gboolean
gkm_xdg_trust_have_assertion (GkmXdgTrust *self)
{
	g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
	return g_hash_table_size (self->pv->assertions);
}
static GkmXdgTrust*
lookup_or_create_trust_object (GkmSession *session, GkmManager *manager,
                               GkmTransaction *transaction, CK_X_ASSERTION_TYPE type,
                               CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, gboolean *created)
{
	CK_ATTRIBUTE_PTR serial, issuer, value;
	CK_ATTRIBUTE lookups[3];
	CK_OBJECT_CLASS klass;
	CK_ULONG n_lookups;
	GList *objects;
	GkmXdgTrust *trust;
	GkmModule *module;

	klass = CKO_NETSCAPE_TRUST;
	lookups[0].type = CKA_CLASS;
	lookups[0].pValue = &klass;
	lookups[0].ulValueLen = sizeof (klass);

	switch (type) {
	case CKT_X_ANCHORED_CERTIFICATE:
	case CKT_X_PINNED_CERTIFICATE:
		value = gkm_attributes_find (attrs, n_attrs, CKA_X_CERTIFICATE_VALUE);
		if (!value) {
			gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
			return NULL;
		}

		/* Attributes used for looking up trust object */
		memcpy (&lookups[1], value, sizeof (CK_ATTRIBUTE));
		n_lookups = 2;
		break;

	case CKT_X_DISTRUSTED_CERTIFICATE:
		serial = gkm_attributes_find (attrs, n_attrs, CKA_SERIAL_NUMBER);
		issuer = gkm_attributes_find (attrs, n_attrs, CKA_ISSUER);
		if (!serial || !issuer) {
			gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
			return NULL;
		}

		/* Attributes used for looking up trust object */
		memcpy (&lookups[1], issuer, sizeof (CK_ATTRIBUTE));
		memcpy (&lookups[2], serial, sizeof (CK_ATTRIBUTE));
		n_lookups = 3;
		break;

	default:
		gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
		return NULL;
	};

	objects = gkm_manager_find_by_attributes (manager, session, lookups, n_lookups);
	module = gkm_session_get_module (session);

	/* Found a matching trust object for this assertion */
	if (objects) {
		g_return_val_if_fail (GKM_XDG_IS_TRUST (objects->data), NULL);
		trust = g_object_ref (objects->data);
		g_list_free (objects);

	/* Create a trust object for this assertion */
	} else {
		trust = gkm_xdg_trust_create_for_assertion (module, manager, transaction,
		                                            lookups, n_lookups);

		gkm_attributes_consume (attrs, n_attrs, CKA_X_CERTIFICATE_VALUE,
		                        CKA_ISSUER, CKA_SERIAL_NUMBER, G_MAXULONG);
		gkm_attributes_consume (lookups, n_lookups, CKA_X_CERTIFICATE_VALUE,
		                        CKA_ISSUER, CKA_SERIAL_NUMBER, G_MAXULONG);

		if (!gkm_transaction_get_failed (transaction))
			gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (trust),
			                                      TRUE, lookups, n_lookups);
	}

	return trust;
}