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; }
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; }
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); }
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); }
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; }