[gnome-keyring/trust-store: 98/105] Implement trust assertions in pkcs11 modules.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring/trust-store: 98/105] Implement trust assertions in pkcs11 modules.
- Date: Tue, 23 Nov 2010 03:09:03 +0000 (UTC)
commit e973a2bd20367d2a88a70e6f7f0643abdb56b646
Author: Stef Walter <stefw collabora co uk>
Date: Fri Nov 19 19:33:39 2010 +0000
Implement trust assertions in pkcs11 modules.
* Change the format of trust stored in XDG store.
* Introduce new assertion object.
* Trust objects own multiple assertion objects.
* Netscape style trust is implemented on assertion objects.
pkcs11/gkm/Makefile.am | 3 +-
pkcs11/gkm/gkm-assertion.c | 232 ++++++++++
pkcs11/gkm/gkm-assertion.h | 66 +++
pkcs11/gkm/gkm-attributes.c | 36 ++
pkcs11/gkm/gkm-attributes.h | 5 +
pkcs11/gkm/gkm-certificate-trust.c | 377 ---------------
pkcs11/gkm/gkm-certificate-trust.h | 57 ---
pkcs11/gkm/gkm-certificate.c | 156 -------
pkcs11/gkm/gkm-oids.h | 34 ++
pkcs11/gkm/gkm-trust.c | 174 +++++++
pkcs11/gkm/gkm-trust.h | 62 +++
pkcs11/gkm/gkm-types.h | 3 +-
pkcs11/gkm/gkm-util.c | 97 ++++
pkcs11/gkm/gkm-util.h | 15 +
pkcs11/pkcs11g.h | 50 --
pkcs11/pkcs11i.h | 22 +
pkcs11/roots-store/Makefile.am | 3 +-
pkcs11/roots-store/gkm-roots-certificate.c | 28 +-
pkcs11/roots-store/gkm-roots-certificate.h | 3 +-
pkcs11/roots-store/gkm-roots-trust.c | 411 +++++++++++++++++
pkcs11/roots-store/gkm-roots-trust.h | 60 +++
pkcs11/xdg-store/Makefile.am | 1 +
pkcs11/xdg-store/asn1-def-xdg.c | 35 +-
pkcs11/xdg-store/gkm-xdg-assertion.c | 252 ++++++++++
pkcs11/xdg-store/gkm-xdg-assertion.h | 55 +++
pkcs11/xdg-store/gkm-xdg-module.c | 26 +-
pkcs11/xdg-store/gkm-xdg-trust-netscape.c | 314 +++++++++++++
pkcs11/xdg-store/gkm-xdg-trust-netscape.h | 59 +++
pkcs11/xdg-store/gkm-xdg-trust.c | 691 +++++++++++++---------------
pkcs11/xdg-store/gkm-xdg-trust.h | 15 +-
pkcs11/xdg-store/xdg.asn | 33 +-
31 files changed, 2297 insertions(+), 1078 deletions(-)
---
diff --git a/pkcs11/gkm/Makefile.am b/pkcs11/gkm/Makefile.am
index 47ee90b..c618480 100644
--- a/pkcs11/gkm/Makefile.am
+++ b/pkcs11/gkm/Makefile.am
@@ -19,10 +19,10 @@ BUILT_SOURCES = \
libgkm_la_SOURCES = \
gkm-aes-key.c gkm-aes-key.h \
gkm-aes-mechanism.c gkm-aes-mechanism.h \
+ gkm-assertion.c gkm-assertion.h \
gkm-attributes.c gkm-attributes.h \
gkm-certificate.c gkm-certificate.h \
gkm-certificate-key.c gkm-certificate-key.h \
- gkm-certificate-trust.c gkm-certificate-trust.h \
gkm-credential.c gkm-credential.h \
gkm-crypto.c gkm-crypto.h \
gkm-data-asn1.c gkm-data-asn1.h \
@@ -55,6 +55,7 @@ libgkm_la_SOURCES = \
gkm-test.c gkm-test.h \
gkm-timer.c gkm-timer.h \
gkm-transaction.c gkm-transaction.h \
+ gkm-trust.c gkm-trust.h \
gkm-types.h \
gkm-util.c gkm-util.h \
$(BUILT_SOURCES)
diff --git a/pkcs11/gkm/gkm-assertion.c b/pkcs11/gkm/gkm-assertion.c
new file mode 100644
index 0000000..2754c99
--- /dev/null
+++ b/pkcs11/gkm/gkm-assertion.c
@@ -0,0 +1,232 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkm-assertion.h"
+#include "gkm-attributes.h"
+#include "gkm-object.h"
+#include "gkm-trust.h"
+#include "gkm-util.h"
+
+#include "pkcs11/pkcs11g.h"
+#include "pkcs11/pkcs11i.h"
+
+#include <glib/gi18n.h>
+
+enum {
+ PROP_0,
+ PROP_TRUST,
+ PROP_TYPE,
+ PROP_PURPOSE,
+ PROP_REMOTE
+};
+
+struct _GkmAssertionPrivate {
+ GkmTrust *trust;
+ gulong type;
+ gchar *purpose;
+ gchar *remote;
+};
+
+G_DEFINE_TYPE (GkmAssertion, gkm_assertion, GKM_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static CK_RV
+gkm_assertion_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr)
+{
+ GkmAssertion *self = GKM_ASSERTION (base);
+
+ switch (attr->type)
+ {
+ case CKA_PRIVATE:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+ case CKA_CLASS:
+ return gkm_attribute_set_ulong (attr, CKO_G_TRUST_ASSERTION);
+ case CKA_MODIFIABLE:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+
+ /* Various trust flags */
+ case CKA_G_ASSERTION_TYPE:
+ return gkm_attribute_set_ulong (attr, self->pv->type);
+ case CKA_G_PURPOSE:
+ return gkm_attribute_set_string (attr, self->pv->purpose);
+ case CKA_G_REMOTE:
+ if (!self->pv->remote)
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+ return gkm_attribute_set_string (attr, self->pv->remote);
+
+ /* Certificate reference values */
+ case CKA_SERIAL_NUMBER:
+ case CKA_ISSUER:
+ case CKA_G_CERTIFICATE_VALUE:
+ return gkm_object_get_attribute (GKM_OBJECT (self->pv->trust), session, attr);
+
+ default:
+ break;
+ };
+
+ return GKM_OBJECT_CLASS (gkm_assertion_parent_class)->get_attribute (base, session, attr);
+}
+
+static void
+gkm_assertion_init (GkmAssertion *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKM_TYPE_ASSERTION, GkmAssertionPrivate);
+}
+
+static void
+gkm_assertion_finalize (GObject *obj)
+{
+ GkmAssertion *self = GKM_ASSERTION (obj);
+
+ if (self->pv->trust)
+ g_object_remove_weak_pointer (G_OBJECT (self->pv->trust), (gpointer*)&(self->pv->trust));
+ self->pv->trust = NULL;
+
+ g_free (self->pv->purpose);
+ self->pv->purpose = NULL;
+
+ g_free (self->pv->remote);
+ self->pv->remote = NULL;
+
+ G_OBJECT_CLASS (gkm_assertion_parent_class)->finalize (obj);
+}
+
+
+static void
+gkm_assertion_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GkmAssertion *self = GKM_ASSERTION (obj);
+
+ switch (prop_id) {
+ case PROP_TRUST:
+ g_return_if_fail (!self->pv->trust);
+ self->pv->trust = g_value_get_object (value);
+ g_return_if_fail (self->pv->trust);
+ g_object_add_weak_pointer (G_OBJECT (self->pv->trust), (gpointer*)&(self->pv->trust));
+ break;
+ case PROP_TYPE:
+ self->pv->type = g_value_get_ulong (value);
+ break;
+ case PROP_PURPOSE:
+ self->pv->purpose = g_value_dup_string (value);
+ break;
+ case PROP_REMOTE:
+ self->pv->remote = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gkm_assertion_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GkmAssertion *self = GKM_ASSERTION (obj);
+
+ switch (prop_id) {
+ case PROP_TRUST:
+ g_value_set_object (value, gkm_assertion_get_trust_object (self));
+ break;
+ case PROP_TYPE:
+ g_value_set_ulong (value, gkm_assertion_get_trust_type (self));
+ break;
+ case PROP_PURPOSE:
+ g_value_set_string (value, gkm_assertion_get_purpose (self));
+ break;
+ case PROP_REMOTE:
+ g_value_set_string (value, gkm_assertion_get_remote (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gkm_assertion_class_init (GkmAssertionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gkm_assertion_finalize;
+ gobject_class->set_property = gkm_assertion_set_property;
+ gobject_class->get_property = gkm_assertion_get_property;
+
+ gkm_class->get_attribute = gkm_assertion_get_attribute;
+
+ g_type_class_add_private (klass, sizeof (GkmAssertionPrivate));
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GkmAssertion*
+gkm_assertion_new (GkmTrust *trust, gulong type, const gchar *purpose, const gchar *remote)
+{
+ return g_object_new (GKM_TYPE_ASSERTION,
+ "trust", trust,
+ "type", type,
+ "purpose", purpose,
+ "remote", remote,
+ NULL);
+}
+
+const gchar*
+gkm_assertion_get_purpose (GkmAssertion *self)
+{
+ g_return_val_if_fail (GKM_IS_ASSERTION (self), NULL);
+ return self->pv->purpose;
+}
+
+const gchar*
+gkm_assertion_get_remote (GkmAssertion *self)
+{
+ g_return_val_if_fail (GKM_IS_ASSERTION (self), NULL);
+ return self->pv->remote;
+}
+
+gulong
+gkm_assertion_get_trust_type (GkmAssertion *self)
+{
+ g_return_val_if_fail (GKM_IS_ASSERTION (self), 0UL);
+ return self->pv->type;
+}
+
+GkmTrust*
+gkm_assertion_get_trust_object (GkmAssertion *self)
+{
+ g_return_val_if_fail (GKM_IS_ASSERTION (self), NULL);
+ return self->pv->trust;
+}
diff --git a/pkcs11/gkm/gkm-assertion.h b/pkcs11/gkm/gkm-assertion.h
new file mode 100644
index 0000000..d9cfe7e
--- /dev/null
+++ b/pkcs11/gkm/gkm-assertion.h
@@ -0,0 +1,66 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ * Copyright (C) 2010 Collabora Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKM_ASSERTION_H__
+#define __GKM_ASSERTION_H__
+
+#include <glib-object.h>
+
+#include "gkm-object.h"
+#include "gkm-types.h"
+
+#define GKM_FACTORY_ASSERTION (gkm_assertion_get_factory ())
+#define GKM_TYPE_ASSERTION (gkm_assertion_get_type ())
+#define GKM_ASSERTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_TYPE_ASSERTION, GkmAssertion))
+#define GKM_ASSERTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_TYPE_ASSERTION, GkmAssertionClass))
+#define GKM_IS_ASSERTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_TYPE_ASSERTION))
+#define GKM_IS_ASSERTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_TYPE_ASSERTION))
+#define GKM_ASSERTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_TYPE_ASSERTION, GkmAssertionClass))
+
+typedef struct _GkmAssertionClass GkmAssertionClass;
+typedef struct _GkmAssertionPrivate GkmAssertionPrivate;
+
+struct _GkmAssertion {
+ GkmObject parent;
+ GkmAssertionPrivate *pv;
+};
+
+struct _GkmAssertionClass {
+ GkmObjectClass parent_class;
+};
+
+GType gkm_assertion_get_type (void);
+
+GkmAssertion* gkm_assertion_new (GkmTrust *trust,
+ gulong trust_type,
+ const gchar *purpose,
+ const gchar *remote);
+
+const gchar* gkm_assertion_get_purpose (GkmAssertion *self);
+
+const gchar* gkm_assertion_get_remote (GkmAssertion *self);
+
+gulong gkm_assertion_get_trust_type (GkmAssertion *self);
+
+GkmTrust* gkm_assertion_get_trust_object (GkmAssertion *self);
+
+#endif /* __GKM_ASSERTION_H__ */
diff --git a/pkcs11/gkm/gkm-attributes.c b/pkcs11/gkm/gkm-attributes.c
index e4d571a..8aff557 100644
--- a/pkcs11/gkm/gkm-attributes.c
+++ b/pkcs11/gkm/gkm-attributes.c
@@ -349,6 +349,42 @@ gkm_attribute_set_template (CK_ATTRIBUTE_PTR attr, GArray *template)
return rv;
}
+CK_RV
+gkm_attribute_set_checksum (CK_ATTRIBUTE_PTR attr, GChecksumType ctype,
+ gconstpointer data, gsize n_data)
+{
+ GChecksum *checksum;
+ gssize length;
+ gsize result;
+
+ g_assert (attr);
+
+ g_return_val_if_fail (data, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (n_data, CKR_GENERAL_ERROR);
+
+ length = g_checksum_type_get_length (ctype);
+ g_return_val_if_fail (length < 0, CKR_GENERAL_ERROR);
+
+ /* Just asking for the length */
+ if (!attr->pValue) {
+ attr->ulValueLen = length;
+ return CKR_OK;
+ }
+
+ /* Buffer is too short */
+ if (length > attr->ulValueLen) {
+ attr->ulValueLen = length;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ checksum = g_checksum_new (ctype);
+ g_checksum_update (checksum, data, n_data);
+ result = attr->ulValueLen;
+ g_checksum_get_digest (checksum, attr->pValue, &result);
+ attr->ulValueLen = result;
+ return CKR_OK;
+}
+
gboolean
gkm_attribute_equal (gconstpointer v1, gconstpointer v2)
{
diff --git a/pkcs11/gkm/gkm-attributes.h b/pkcs11/gkm/gkm-attributes.h
index 97088d4..4315940 100644
--- a/pkcs11/gkm/gkm-attributes.h
+++ b/pkcs11/gkm/gkm-attributes.h
@@ -73,6 +73,11 @@ CK_RV gkm_attribute_set_mpi (CK_ATTRI
CK_RV gkm_attribute_set_template (CK_ATTRIBUTE_PTR attr,
GArray *template);
+CK_RV gkm_attribute_set_checksum (CK_ATTRIBUTE_PTR attr,
+ GChecksumType ctype,
+ gconstpointer data,
+ gsize n_data);
+
guint gkm_attribute_hash (gconstpointer v);
gboolean gkm_attribute_equal (gconstpointer a,
diff --git a/pkcs11/gkm/gkm-certificate.c b/pkcs11/gkm/gkm-certificate.c
index 910c365..4c45340 100644
--- a/pkcs11/gkm/gkm-certificate.c
+++ b/pkcs11/gkm/gkm-certificate.c
@@ -61,17 +61,6 @@ struct _GkmCertificatePrivate {
static GQuark OID_BASIC_CONSTRAINTS;
static GQuark OID_ENHANCED_USAGE;
-static GQuark OID_USAGE_SSH_AUTH;
-static GQuark OID_USAGE_SERVER_AUTH;
-static GQuark OID_USAGE_CLIENT_AUTH;
-static GQuark OID_USAGE_CODE_SIGNING;
-static GQuark OID_USAGE_EMAIL;
-static GQuark OID_USAGE_TIME_STAMPING;
-static GQuark OID_USAGE_IPSEC_ENDPOINT;
-static GQuark OID_USAGE_IPSEC_TUNNEL;
-static GQuark OID_USAGE_IPSEC_USER;
-static GQuark OID_USAGE_IKE_INTERMEDIATE;
-
static void gkm_certificate_serializable (GkmSerializableIface *iface);
G_DEFINE_TYPE_EXTENDED (GkmCertificate, gkm_certificate, GKM_TYPE_OBJECT, 0,
@@ -93,123 +82,12 @@ init_quarks (void)
QUARK (OID_BASIC_CONSTRAINTS, "2.5.29.19");
QUARK (OID_ENHANCED_USAGE, "2.5.29.37");
- QUARK (OID_USAGE_SSH_AUTH, "ssh-authentication");
- QUARK (OID_USAGE_SERVER_AUTH, "1.3.6.1.5.5.7.3.1");
- QUARK (OID_USAGE_CLIENT_AUTH, "1.3.6.1.5.5.7.3.2");
- QUARK (OID_USAGE_CODE_SIGNING, "1.3.6.1.5.5.7.3.3");
- QUARK (OID_USAGE_EMAIL, "1.3.6.1.5.5.7.3.4");
- QUARK (OID_USAGE_TIME_STAMPING, "1.3.6.1.5.5.7.3.8");
- QUARK (OID_USAGE_IPSEC_ENDPOINT, "1.3.6.1.5.5.7.3.5");
- QUARK (OID_USAGE_IPSEC_TUNNEL, "1.3.6.1.5.5.7.3.6");
- QUARK (OID_USAGE_IPSEC_USER, "1.3.6.1.5.5.7.3.7");
- QUARK (OID_USAGE_IKE_INTERMEDIATE, "1.3.6.1.5.5.8.2.2");
-
#undef QUARK
g_once_init_leave (&quarks_inited, 1);
}
}
-static gboolean
-has_certificate_purposes (GkmCertificate *self)
-{
- const guchar *extension;
- gsize n_extension;
-
- /* TODO: Storage of certificate purposes in the store */
-
- extension = gkm_certificate_get_extension (self, OID_ENHANCED_USAGE, &n_extension, NULL);
- return extension != NULL;
-}
-
-static CK_RV
-lookup_certificate_purposes (GkmCertificate *self, GQuark **oids)
-{
- GkmDataResult res;
- const guchar *extension;
- gsize n_extension;
-
- *oids = NULL;
-
- /* TODO: Storage of certificate purposes in the store */
-
- extension = gkm_certificate_get_extension (self, OID_ENHANCED_USAGE, &n_extension, NULL);
-
- /* No enhanced usage noted, any are allowed */
- if (!extension)
- return CKR_OK;
-
- res = gkm_data_der_read_enhanced_usage (extension, n_extension, oids);
-
- if (res != GKM_DATA_SUCCESS)
- return CKR_GENERAL_ERROR;
-
- return CKR_OK;
-}
-
-
-static gboolean
-check_certificate_purpose (GkmCertificate *self, GQuark oid)
-{
- GQuark *usages, *usage;
- gboolean ret;
-
- if (lookup_certificate_purposes (self, &usages) != CKR_OK)
- return FALSE;
-
- /* No usages noted, any are allowed */
- if (!usages)
- return TRUE;
-
- ret = FALSE;
- for (usage = usages; *usage; ++usage) {
- if (*usage == oid) {
- ret = TRUE;
- break;
- }
- }
-
- g_free (usages);
-
- return ret;
-}
-
-static CK_RV
-read_certificate_purpose (GkmCertificate *self, GQuark oid, CK_ATTRIBUTE_PTR attr)
-{
- gboolean value = check_certificate_purpose (self, oid);
- gkm_attribute_set_bool (attr, value);
- return CKR_OK;
-}
-
-
-static CK_RV
-read_certificate_purposes (GkmCertificate *self, CK_ATTRIBUTE_PTR attr)
-{
- GQuark *purposes, *purpose;
- GString *result;
- CK_RV ret;
-
- ret = lookup_certificate_purposes (self, &purposes);
- if (ret != CKR_OK)
- return ret;
-
- /* Convert into a space delimited string */
- result = g_string_sized_new (128);
- for (purpose = purposes; purpose && *purpose; ++purpose) {
- g_string_append (result, g_quark_to_string (*purpose));
- g_string_append_c (result, ' ');
- }
-
- g_free (purposes);
-
- gkm_attribute_set_string (attr, result->str);
- g_string_free (result, TRUE);
-
- return CKR_OK;
-}
-
-
static gint
find_certificate_extension (GkmCertificate *self, GQuark oid)
{
@@ -369,40 +247,6 @@ gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
/* What in the world is this doing in the spec? */
case CKA_JAVA_MIDP_SECURITY_DOMAIN:
return gkm_attribute_set_ulong (attr, 0); /* 0 = unspecified */
-
- case CKA_GNOME_PURPOSE_RESTRICTED:
- gkm_attribute_set_bool (attr, has_certificate_purposes (self));
- return CKR_OK;
-
- case CKA_GNOME_PURPOSE_OIDS:
- return read_certificate_purposes (self, attr);
-
- case CKA_GNOME_PURPOSE_SSH_AUTH:
- return read_certificate_purpose (self, OID_USAGE_SSH_AUTH, attr);
-
- case CKA_GNOME_PURPOSE_SERVER_AUTH:
- return read_certificate_purpose (self, OID_USAGE_SERVER_AUTH, attr);
-
- case CKA_GNOME_PURPOSE_CLIENT_AUTH:
- return read_certificate_purpose (self, OID_USAGE_CLIENT_AUTH, attr);
-
- case CKA_GNOME_PURPOSE_CODE_SIGNING:
- return read_certificate_purpose (self, OID_USAGE_CODE_SIGNING, attr);
-
- case CKA_GNOME_PURPOSE_EMAIL_PROTECTION:
- return read_certificate_purpose (self, OID_USAGE_EMAIL, attr);
-
- case CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM:
- return read_certificate_purpose (self, OID_USAGE_IPSEC_ENDPOINT, attr);
-
- case CKA_GNOME_PURPOSE_IPSEC_TUNNEL:
- return read_certificate_purpose (self, OID_USAGE_IPSEC_TUNNEL, attr);
-
- case CKA_GNOME_PURPOSE_IPSEC_USER:
- return read_certificate_purpose (self, OID_USAGE_IPSEC_USER, attr);
-
- case CKA_GNOME_PURPOSE_TIME_STAMPING:
- return read_certificate_purpose (self, OID_USAGE_TIME_STAMPING, attr);
};
return GKM_OBJECT_CLASS (gkm_certificate_parent_class)->get_attribute (base, session, attr);
diff --git a/pkcs11/gkm/gkm-oids.h b/pkcs11/gkm/gkm-oids.h
new file mode 100644
index 0000000..011d748
--- /dev/null
+++ b/pkcs11/gkm/gkm-oids.h
@@ -0,0 +1,34 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKM_OIDS_H__
+#define __GKM_OIDS_H__
+
+#define GKM_OID_EXTUSAGE_SERVER_AUTH "1.3.6.1.5.5.7.3.1"
+#define GKM_OID_EXTUSAGE_CLIENT_AUTH "1.3.6.1.5.5.7.3.2"
+#define GKM_OID_EXTUSAGE_CODE_SIGNING "1.3.6.1.5.5.7.3.3"
+#define GKM_OID_EXTUSAGE_EMAIL "1.3.6.1.5.5.7.3.4"
+#define GKM_OID_EXTUSAGE_IPSEC_ENDPOINT "1.3.6.1.5.5.7.3.5"
+#define GKM_OID_EXTUSAGE_IPSEC_TUNNEL "1.3.6.1.5.5.7.3.6"
+#define GKM_OID_EXTUSAGE_IPSEC_USER "1.3.6.1.5.5.7.3.7"
+#define GKM_OID_EXTUSAGE_TIME_STAMPING "1.3.6.1.5.5.7.3.8"
+
+#endif /* __GKM_OIDS_H__ */
diff --git a/pkcs11/gkm/gkm-trust.c b/pkcs11/gkm/gkm-trust.c
new file mode 100644
index 0000000..5389429
--- /dev/null
+++ b/pkcs11/gkm/gkm-trust.c
@@ -0,0 +1,174 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkm-trust.h"
+
+#include "gkm-attributes.h"
+#include "gkm-object.h"
+#include "gkm-oids.h"
+
+#include "pkcs11/pkcs11n.h"
+#include "pkcs11/pkcs11i.h"
+
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (GkmTrust, gkm_trust, GKM_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static CK_RV
+trust_get_usage (GkmTrust *self, const gchar *purpose, CK_ATTRIBUTE_PTR attr)
+{
+ GkmTrustLevel level;
+ CK_ULONG trust;
+
+ level = gkm_trust_get_level_for_purpose (self, purpose);
+
+ switch (level) {
+ case GKM_TRUST_UNKNOWN:
+ trust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ break;
+ case GKM_TRUST_UNTRUSTED:
+ trust = CKT_NETSCAPE_UNTRUSTED;
+ break;
+ case GKM_TRUST_TRUSTED:
+ trust = CKT_NETSCAPE_TRUSTED;
+ break;
+ case GKM_TRUST_ANCHOR:
+ trust = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ break;
+ default:
+ g_return_val_if_reached (CKR_GENERAL_ERROR);
+ };
+
+ return gkm_attribute_set_ulong (attr, trust);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static CK_RV
+gkm_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr)
+{
+ GkmTrust *self = GKM_TRUST (base);
+
+ /*
+ * This object exposes a netscape compatible trust object. However the
+ * primary interface for dealing with trust is through GkmAssertion objects.
+ */
+
+ switch (attr->type)
+ {
+ case CKA_PRIVATE:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+ case CKA_TRUST_STEP_UP_APPROVED:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+ case CKA_CLASS:
+ return gkm_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST);
+ case CKA_MODIFIABLE:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+
+ /*
+ * TODO: Is it even useful to support overriding from certificate
+ * defaults? For now we just return unknown for all of them, and
+ * the caller should use whatever's in the certificate.
+ */
+ case CKA_TRUST_DIGITAL_SIGNATURE:
+ case CKA_TRUST_NON_REPUDIATION:
+ case CKA_TRUST_KEY_ENCIPHERMENT:
+ case CKA_TRUST_DATA_ENCIPHERMENT:
+ case CKA_TRUST_KEY_AGREEMENT:
+ case CKA_TRUST_KEY_CERT_SIGN:
+ case CKA_TRUST_CRL_SIGN:
+ return gkm_attribute_set_ulong (attr, CKT_NETSCAPE_TRUST_UNKNOWN);
+
+ /* Various trust flags */
+ case CKA_TRUST_SERVER_AUTH:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_SERVER_AUTH, attr);
+ case CKA_TRUST_CLIENT_AUTH:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_CLIENT_AUTH, attr);
+ case CKA_TRUST_CODE_SIGNING:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_CODE_SIGNING, attr);
+ case CKA_TRUST_EMAIL_PROTECTION:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_EMAIL, attr);
+ case CKA_TRUST_IPSEC_END_SYSTEM:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_IPSEC_ENDPOINT, attr);
+ case CKA_TRUST_IPSEC_TUNNEL:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_IPSEC_TUNNEL, attr);
+ case CKA_TRUST_IPSEC_USER:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_IPSEC_USER, attr);
+ case CKA_TRUST_TIME_STAMPING:
+ return trust_get_usage (self, GKM_OID_EXTUSAGE_TIME_STAMPING, attr);
+
+ /* Certificate reference values */
+ case CKA_SUBJECT:
+ case CKA_SERIAL_NUMBER:
+ case CKA_ISSUER:
+ case CKA_CERT_MD5_HASH:
+ case CKA_CERT_SHA1_HASH:
+ g_warning ("derived class should have provided these attributes");
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+
+ default:
+ break;
+ };
+
+ return GKM_OBJECT_CLASS (gkm_trust_parent_class)->get_attribute (base, session, attr);
+}
+
+static GkmTrustLevel
+gkm_trust_real_get_trust_level (GkmTrust *self, const gchar *purpose)
+{
+ return GKM_TRUST_UNKNOWN;
+}
+
+static void
+gkm_trust_init (GkmTrust *self)
+{
+ /* For future expansion */
+ self->pv = NULL;
+}
+
+static void
+gkm_trust_class_init (GkmTrustClass *klass)
+{
+ GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
+ gkm_class->get_attribute = gkm_trust_get_attribute;
+ klass->get_trust_level = gkm_trust_real_get_trust_level;
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GkmTrustLevel
+gkm_trust_get_level_for_purpose (GkmTrust *self, const gchar *purpose)
+{
+ g_return_val_if_fail (GKM_IS_TRUST (self), GKM_TRUST_UNKNOWN);
+ g_return_val_if_fail (purpose, GKM_TRUST_UNKNOWN);
+ g_assert (GKM_TRUST_GET_CLASS (self)->get_trust_level);
+ return GKM_TRUST_GET_CLASS (self)->get_trust_level (self, purpose);
+}
diff --git a/pkcs11/gkm/gkm-trust.h b/pkcs11/gkm/gkm-trust.h
new file mode 100644
index 0000000..7bb1f15
--- /dev/null
+++ b/pkcs11/gkm/gkm-trust.h
@@ -0,0 +1,62 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKM_TRUST_H__
+#define __GKM_TRUST_H__
+
+#include <glib-object.h>
+
+#include "gkm-object.h"
+
+typedef enum _GkmTrustLevel {
+ GKM_TRUST_UNKNOWN = 0,
+ GKM_TRUST_UNTRUSTED = 1,
+ GKM_TRUST_TRUSTED = 2,
+ GKM_TRUST_ANCHOR = 3,
+} GkmTrustLevel;
+
+#define GKM_FACTORY_TRUST (gkm_trust_get_factory ())
+#define GKM_TYPE_TRUST (gkm_trust_get_type ())
+#define GKM_TRUST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_TYPE_TRUST, GkmTrust))
+#define GKM_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_TYPE_TRUST, GkmTrustClass))
+#define GKM_IS_TRUST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_TYPE_TRUST))
+#define GKM_IS_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_TYPE_TRUST))
+#define GKM_TRUST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_TYPE_TRUST, GkmTrustClass))
+
+typedef struct _GkmTrustClass GkmTrustClass;
+typedef struct _GkmTrustPrivate GkmTrustPrivate;
+
+struct _GkmTrust {
+ GkmObject parent;
+ GkmTrustPrivate *pv;
+};
+
+struct _GkmTrustClass {
+ GkmObjectClass parent_class;
+
+ GkmTrustLevel (*get_trust_level) (GkmTrust *self, const gchar *purpose);
+};
+
+GType gkm_trust_get_type (void);
+
+GkmTrustLevel gkm_trust_get_level_for_purpose (GkmTrust *self, const gchar *purpose);
+
+#endif /* __GKM_TRUST_H__ */
diff --git a/pkcs11/gkm/gkm-types.h b/pkcs11/gkm/gkm-types.h
index 386fd4c..4ed1c4c 100644
--- a/pkcs11/gkm/gkm-types.h
+++ b/pkcs11/gkm/gkm-types.h
@@ -23,9 +23,9 @@
#define __GKM_TYPES_H__
typedef struct _GkmAesKey GkmAesKey;
+typedef struct _GkmAssertion GkmAssertion;
typedef struct _GkmCertificate GkmCertificate;
typedef struct _GkmCertificateKey GkmCertificateKey;
-typedef struct _GkmCertificateTrust GkmCertificateTrust;
typedef struct _GkmCredential GkmCredential;
typedef struct _GkmDhKey GkmDhKey;
typedef struct _GkmDhPrivateKey GkmDhPrivateKey;
@@ -47,5 +47,6 @@ typedef struct _GkmSexpKey GkmSexpKey;
typedef struct _GkmStore GkmStore;
typedef struct _GkmTimer GkmTimer;
typedef struct _GkmTransaction GkmTransaction;
+typedef struct _GkmTrust GkmTrust;
#endif /* __GKM_TYPES_H__ */
diff --git a/pkcs11/gkm/gkm-util.c b/pkcs11/gkm/gkm-util.c
index 26fca33..6e1f29c 100644
--- a/pkcs11/gkm/gkm-util.c
+++ b/pkcs11/gkm/gkm-util.c
@@ -19,6 +19,41 @@
* 02111-1307, USA.
*/
+/*
+ * PORTIONS FROM: ----------------------------------------------------------
+ *
+ * GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * --------------------------------------------------------------------------
+ */
+
+/*
+ * PORTIONS FROM: ----------------------------------------------------------
+ *
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ *
+ * --------------------------------------------------------------------------
+ */
+
#include "config.h"
#include "gkm-util.h"
@@ -32,6 +67,68 @@
/* Only access using atomic operations */
static gint next_handle = 0x00000010;
+GkmMemory*
+gkm_util_memory_new (gconstpointer data, gsize n_data)
+{
+ GkmMemory *memory;
+
+ memory = g_malloc (n_data + sizeof (GkmMemory));
+ memory->n_data = n_data;
+ memory->data = memory + 1;
+
+ if (n_data) {
+ g_assert (data);
+ memcpy (memory + 1, data, n_data);
+ }
+
+ return memory;
+}
+
+guint
+gkm_util_memory_hash (gconstpointer v)
+{
+ const GkmMemory *memory = v;
+ const signed char *p;
+ guint32 h = 0;
+ gsize i;
+
+ g_assert (memory);
+ g_assert (memory->data);
+ p = memory->data;
+
+ /* 31 bit hash function */
+ for (i = 0; i < memory->n_data; ++i, ++p)
+ h = (h << 5) - h + *p;
+
+ return h;
+}
+
+gboolean
+gkm_util_memory_equal (gconstpointer v1, gconstpointer v2)
+{
+ const GkmMemory *memory_1 = v1;
+ const GkmMemory *memory_2 = v2;
+
+ if (memory_1 == memory_2)
+ return TRUE;
+ if (!memory_1 || !memory_2)
+ return FALSE;
+
+ if (memory_1->n_data != memory_2->n_data)
+ return FALSE;
+
+ g_assert (memory_1->data);
+ g_assert (memory_2->data);
+
+ return (memcmp (memory_1->data, memory_2->data, memory_1->n_data) == 0);
+}
+
+void
+gkm_util_memory_free (gpointer memory)
+{
+ g_free (memory);
+}
+
gulong*
gkm_util_ulong_alloc (gulong value)
{
diff --git a/pkcs11/gkm/gkm-util.h b/pkcs11/gkm/gkm-util.h
index b44a978..2a645b6 100644
--- a/pkcs11/gkm/gkm-util.h
+++ b/pkcs11/gkm/gkm-util.h
@@ -28,6 +28,21 @@
#include "pkcs11/pkcs11.h"
+typedef struct _GkmMemory {
+ gconstpointer data;
+ gsize n_data;
+} GkmMemory;
+
+GkmMemory* gkm_util_memory_new (gconstpointer data,
+ gsize n_data);
+
+guint gkm_util_memory_hash (gconstpointer memory);
+
+gboolean gkm_util_memory_equal (gconstpointer memory_1,
+ gconstpointer memory_2);
+
+void gkm_util_memory_free (gpointer memory);
+
guint gkm_util_ulong_hash (gconstpointer ptr_to_ulong);
gboolean gkm_util_ulong_equal (gconstpointer ptr_to_ulong_1,
diff --git a/pkcs11/pkcs11g.h b/pkcs11/pkcs11g.h
index c01a3c9..48be2e3 100644
--- a/pkcs11/pkcs11g.h
+++ b/pkcs11/pkcs11g.h
@@ -40,56 +40,6 @@
#define CKA_GNOME_UNIQUE (CKA_GNOME + 350)
/* -------------------------------------------------------------------
- * PURPOSES
- */
-
-/*
- * Whether the key or certificate is restricted to a set of
- * purposes (ie: enhanced usages).
- *
- * CK_BBOOL
- *
- * - When CK_TRUE see CKA_PURPOSE_OIDS for the set of purposes.
- * - When CK_FALSE then is not restricted to any specific purpose.
- */
-#define CKA_GNOME_PURPOSE_RESTRICTED (CKA_GNOME + 12)
-
-/*
- * The available purposes that a certificate or key can be
- * used for.
- *
- * CK_STRING
- *
- * - This is only relevant if CKA_PURPOSE_RESTRICTED is CK_TRUE.
- * - Use CKA_TRUSTED and CKA_CERTIFICATE_CATEGORY to validate whether
- * usage of the certificate for these purposes is directly or
- * indirectly trusted by the user.
- * - The returned string is a space delemited set of OIDs.
- * - When an empty string is returned then no purposes are valid.
- */
-#define CKA_GNOME_PURPOSE_OIDS (CKA_GNOME + 11)
-
-/*
- * The key or certificate can be used for the purpose
- * indicated
- *
- * CK_BBOOL
- *
- * - These are shortcuts to using CKA_PURPOSE_OIDS
- * - Use CKA_TRUSTED and CKA_CERTIFICATE_CATEGORY to validate whether
- * the certificate is directly or indirectly trusted by the user.
- */
-#define CKA_GNOME_PURPOSE_SSH_AUTH (CKA_GNOME + 101)
-#define CKA_GNOME_PURPOSE_SERVER_AUTH (CKA_GNOME + 102)
-#define CKA_GNOME_PURPOSE_CLIENT_AUTH (CKA_GNOME + 103)
-#define CKA_GNOME_PURPOSE_CODE_SIGNING (CKA_GNOME + 104)
-#define CKA_GNOME_PURPOSE_EMAIL_PROTECTION (CKA_GNOME + 105)
-#define CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM (CKA_GNOME + 106)
-#define CKA_GNOME_PURPOSE_IPSEC_TUNNEL (CKA_GNOME + 107)
-#define CKA_GNOME_PURPOSE_IPSEC_USER (CKA_GNOME + 108)
-#define CKA_GNOME_PURPOSE_TIME_STAMPING (CKA_GNOME + 109)
-
-/* -------------------------------------------------------------------
*/
#define CKA_GNOME_TRANSIENT (CKA_GNOME + 201)
diff --git a/pkcs11/pkcs11i.h b/pkcs11/pkcs11i.h
index 44f285a..9e23ef5 100644
--- a/pkcs11/pkcs11i.h
+++ b/pkcs11/pkcs11i.h
@@ -119,4 +119,26 @@ typedef CK_G_APPLICATION* CK_G_APPLICATION_PTR;
#define CKA_G_CREDENTIAL_TEMPLATE (CKA_GNOME + 205)
+/* -------------------------------------------------------------------
+ * TRUST ASSERTIONS
+ */
+
+#define CKO_G_TRUST_ASSERTION (CKO_GNOME + 400)
+
+#define CKA_G_ASSERTION_TYPE (CKO_GNOME + 401)
+
+#define CKA_G_CERTIFICATE_VALUE (CKO_GNOME + 402)
+
+#define CKA_G_PURPOSE (CKO_GNOME + 403)
+
+#define CKA_G_REMOTE (CKO_GNOME + 404)
+
+typedef CK_ULONG CK_ASSERTION_TYPE;
+
+#define CKT_G_CERTIFICATE_UNTRUSTED 1UL
+
+#define CKT_G_CERTIFICATE_TRUST_EXCEPTION 2UL
+
+#define CKT_G_CERTIFICATE_TRUST_ANCHOR 3UL
+
#endif /* PKCS11I_H */
diff --git a/pkcs11/roots-store/Makefile.am b/pkcs11/roots-store/Makefile.am
index 5d6108b..759cff8 100644
--- a/pkcs11/roots-store/Makefile.am
+++ b/pkcs11/roots-store/Makefile.am
@@ -17,7 +17,8 @@ noinst_LTLIBRARIES = \
libgkm_roots_store_la_SOURCES = \
gkm-roots-store.h \
gkm-roots-module.c gkm-roots-module.h \
- gkm-roots-certificate.c gkm-roots-certificate.h
+ gkm-roots-certificate.c gkm-roots-certificate.h \
+ gkm-roots-trust.c gkm-roots-trust.h
# ------------------------------------------------------------------------------
# The standalone module
diff --git a/pkcs11/roots-store/gkm-roots-certificate.c b/pkcs11/roots-store/gkm-roots-certificate.c
index 8499ec4..e2febaf 100644
--- a/pkcs11/roots-store/gkm-roots-certificate.c
+++ b/pkcs11/roots-store/gkm-roots-certificate.c
@@ -22,9 +22,9 @@
#include "config.h"
#include "gkm-roots-certificate.h"
+#include "gkm-roots-trust.h"
#include "gkm/gkm-attributes.h"
-#include "gkm/gkm-certificate-trust.h"
#include "gkm/gkm-manager.h"
#include "gkm/gkm-module.h"
#include "gkm/gkm-object.h"
@@ -35,13 +35,12 @@
enum {
PROP_0,
- PROP_PATH,
- PROP_NETSCAPE_TRUST,
+ PROP_PATH
};
struct _GkmRootsCertificate {
GkmCertificate parent;
- GkmCertificateTrust *trust;
+ GkmRootsTrust *trust;
gchar *path;
};
@@ -97,9 +96,9 @@ gkm_roots_certificate_constructor (GType type, guint n_props, GObjectConstructPa
GkmRootsCertificate *self = GKM_ROOTS_CERTIFICATE (G_OBJECT_CLASS (gkm_roots_certificate_parent_class)->constructor(type, n_props, props));
g_return_val_if_fail (self, NULL);
- self->trust = gkm_certificate_trust_new (gkm_object_get_module (GKM_OBJECT (self)),
- gkm_object_get_manager (GKM_OBJECT (self)),
- GKM_CERTIFICATE (self));
+ self->trust = gkm_roots_trust_new (gkm_object_get_module (GKM_OBJECT (self)),
+ gkm_object_get_manager (GKM_OBJECT (self)),
+ GKM_CERTIFICATE (self));
return G_OBJECT (self);
}
@@ -131,9 +130,6 @@ gkm_roots_certificate_get_property (GObject *obj, guint prop_id, GValue *value,
case PROP_PATH:
g_value_set_string (value, gkm_roots_certificate_get_path (self));
break;
- case PROP_NETSCAPE_TRUST:
- g_value_set_object (value, gkm_roots_certificate_get_netscape_trust (self));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -183,10 +179,6 @@ gkm_roots_certificate_class_init (GkmRootsCertificateClass *klass)
g_object_class_install_property (gobject_class, PROP_PATH,
g_param_spec_string ("path", "Path", "Certificate origin path",
"", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (gobject_class, PROP_NETSCAPE_TRUST,
- g_param_spec_object ("netscape-trust", "Netscape Trust", "Netscape trust object",
- GKM_TYPE_CERTIFICATE_TRUST, G_PARAM_READABLE));
}
/* -----------------------------------------------------------------------------
@@ -206,11 +198,3 @@ gkm_roots_certificate_get_path (GkmRootsCertificate *self)
g_return_val_if_fail (GKM_IS_ROOTS_CERTIFICATE (self), "");
return self->path;
}
-
-GkmCertificateTrust*
-gkm_roots_certificate_get_netscape_trust (GkmRootsCertificate *self)
-{
- g_return_val_if_fail (GKM_IS_ROOTS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (GKM_IS_CERTIFICATE_TRUST (self->trust), NULL);
- return self->trust;
-}
diff --git a/pkcs11/roots-store/gkm-roots-certificate.h b/pkcs11/roots-store/gkm-roots-certificate.h
index 8938425..9d61caf 100644
--- a/pkcs11/roots-store/gkm-roots-certificate.h
+++ b/pkcs11/roots-store/gkm-roots-certificate.h
@@ -25,6 +25,7 @@
#include <glib-object.h>
#include "gkm/gkm-certificate.h"
+#include "gkm-roots-trust.h"
#define GKM_TYPE_ROOTS_CERTIFICATE (gkm_roots_certificate_get_type ())
#define GKM_ROOTS_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_TYPE_ROOTS_CERTIFICATE, GkmRootsCertificate))
@@ -50,6 +51,4 @@ const gchar* gkm_roots_certificate_get_unique (GkmRootsCert
const gchar* gkm_roots_certificate_get_path (GkmRootsCertificate *self);
-GkmCertificateTrust* gkm_roots_certificate_get_netscape_trust (GkmRootsCertificate *self);
-
#endif /* __GKM_ROOTS_CERTIFICATE_H__ */
diff --git a/pkcs11/roots-store/gkm-roots-trust.c b/pkcs11/roots-store/gkm-roots-trust.c
new file mode 100644
index 0000000..eb52124
--- /dev/null
+++ b/pkcs11/roots-store/gkm-roots-trust.c
@@ -0,0 +1,411 @@
+/*
+ * gnome-trustring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ * Copyright (C) 2010 Collabora Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkm-roots-trust.h"
+
+#include "gkm/gkm-assertion.h"
+#include "gkm/gkm-attributes.h"
+#include "gkm/gkm-certificate.h"
+#include "gkm/gkm-data-der.h"
+#include "gkm/gkm-object.h"
+#include "gkm/gkm-oids.h"
+#include "gkm/gkm-util.h"
+
+#include "pkcs11/pkcs11i.h"
+#include "pkcs11/pkcs11n.h"
+
+#include <glib/gi18n.h>
+
+enum {
+ PROP_0,
+ PROP_CERTIFICATE
+};
+
+struct _GkmRootsTrustPrivate {
+ GkmCertificate *certificate;
+ GList *assertions;
+};
+
+G_DEFINE_TYPE (GkmRootsTrust, gkm_roots_trust, GKM_TYPE_TRUST);
+
+static GQuark OID_KEY_USAGE;
+static GQuark OID_ENHANCED_USAGE;
+
+/*
+ * When a certificate doesn't explicitly supply the purposes it's allowed
+ * to use, and gives carte blanche then we use the following list.
+ */
+
+const char *OID_KNOWN_PURPOSES[] = {
+ GKM_OID_EXTUSAGE_SERVER_AUTH,
+ GKM_OID_EXTUSAGE_CLIENT_AUTH,
+ GKM_OID_EXTUSAGE_CODE_SIGNING,
+ GKM_OID_EXTUSAGE_EMAIL,
+ GKM_OID_EXTUSAGE_IPSEC_ENDPOINT,
+ GKM_OID_EXTUSAGE_IPSEC_TUNNEL,
+ GKM_OID_EXTUSAGE_IPSEC_USER,
+ GKM_OID_EXTUSAGE_TIME_STAMPING,
+ NULL
+};
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static void
+init_quarks (void)
+{
+ static volatile gsize quarks_inited = 0;
+
+ if (g_once_init_enter (&quarks_inited)) {
+ #define QUARK(name, value) \
+ name = g_quark_from_static_string(value)
+
+ QUARK (OID_ENHANCED_USAGE, "2.5.29.37");
+ QUARK (OID_KEY_USAGE, "2.5.29.15");
+
+ #undef QUARK
+
+ g_once_init_leave (&quarks_inited, 1);
+ }
+}
+
+static CK_RV
+hash_certificate (GkmRootsTrust *self, int algo, CK_ATTRIBUTE_PTR result)
+{
+ guchar *hash;
+ gsize n_hash;
+ CK_RV rv;
+
+ g_assert (GKM_ROOTS_IS_TRUST (self));
+
+ g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
+
+ hash = gkm_certificate_hash (self->pv->certificate, algo, &n_hash);
+ g_return_val_if_fail (hash, CKR_GENERAL_ERROR);
+
+ rv = gkm_attribute_set_data (result, hash, n_hash);
+ g_free (hash);
+
+ return rv;
+}
+
+static GQuark*
+lookup_extended_usages (GkmRootsTrust *self)
+{
+ gconstpointer extension;
+ gsize n_extension;
+ GQuark *usages = NULL;
+ GkmDataResult res;
+
+ extension = gkm_certificate_get_extension (self->pv->certificate,
+ OID_ENHANCED_USAGE,
+ &n_extension, NULL);
+
+ if (!extension)
+ return NULL;
+
+ /* Returns null terminated set of OID quarks */
+ res = gkm_data_der_read_enhanced_usage (extension, n_extension, &usages);
+
+ /* Failure: An empty set means nothing is trusted */
+ if (res != GKM_DATA_SUCCESS) {
+ g_message ("couldn't parse extended usage info in certificate");
+ usages = g_new0 (GQuark, 1);
+ }
+
+ return usages;
+}
+
+static gboolean
+is_certificate_authority (GkmCertificate *cert)
+{
+ gulong nval;
+
+ if (!gkm_object_get_attribute_ulong (GKM_OBJECT (cert),
+ NULL, CKA_CERTIFICATE_CATEGORY, &nval))
+ nval = 0;
+
+ /* 2 is a certificate authority in PKCS#11 */
+ return (nval == 2) ? TRUE : FALSE;
+}
+
+static void
+build_linked_assertion (GkmRootsTrust *self, GkmTrustLevel level, const gchar *purpose)
+{
+ GkmAssertion *assertion;
+ gulong type = 0;
+
+ /* For now only have logic to create assertions early */
+ g_return_if_fail (!gkm_object_is_exposed (GKM_OBJECT (self)));
+
+ switch (level) {
+ case GKM_TRUST_UNKNOWN:
+ return;
+ case GKM_TRUST_TRUSTED:
+ type = CKT_G_CERTIFICATE_TRUST_EXCEPTION;
+ break;
+ case GKM_TRUST_UNTRUSTED:
+ type = CKT_G_CERTIFICATE_UNTRUSTED;
+ break;
+ case GKM_TRUST_ANCHOR:
+ type = CKT_G_CERTIFICATE_TRUST_ANCHOR;
+ break;
+ default:
+ g_assert_not_reached ();
+ return;
+ };
+
+ assertion = gkm_assertion_new (GKM_TRUST (self), type, purpose, NULL);
+ self->pv->assertions = g_list_prepend (self->pv->assertions, assertion);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static CK_RV
+gkm_roots_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr)
+{
+ GkmRootsTrust *self = GKM_ROOTS_TRUST (base);
+
+ switch (attr->type)
+ {
+ case CKA_SUBJECT:
+ case CKA_SERIAL_NUMBER:
+ case CKA_ISSUER:
+ case CKA_VALUE:
+ g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
+ return gkm_object_get_attribute (GKM_OBJECT (self->pv->certificate), session, attr);
+
+ case CKA_CERT_MD5_HASH:
+ return hash_certificate (self, GCRY_MD_MD5, attr);
+ case CKA_CERT_SHA1_HASH:
+ return hash_certificate (self, GCRY_MD_SHA1, attr);
+
+ default:
+ break;
+ };
+
+ return GKM_OBJECT_CLASS (gkm_roots_trust_parent_class)->get_attribute (base, session, attr);
+}
+
+static void
+gkm_roots_trust_expose_object (GkmObject *base, gboolean expose)
+{
+ GList *l;
+ GKM_OBJECT_CLASS (gkm_roots_trust_parent_class)->expose_object (base, expose);
+ for (l = GKM_ROOTS_TRUST (base)->pv->assertions; l; l = g_list_next (l))
+ gkm_object_expose (l->data, expose);
+}
+
+static GkmTrustLevel
+gkm_roots_trust_get_trust_level (GkmTrust *base, const gchar *purpose)
+{
+ GkmRootsTrust *self;
+ GkmTrustLevel result;
+ GQuark *usage, *usages;
+ GQuark oid;
+
+ self = GKM_ROOTS_TRUST (base);
+
+ /*
+ * For root certificates we just believe whatever is in the
+ * certificate enhanced usage extension.
+ */
+
+ usages = lookup_extended_usages (self);
+
+ /* No enhanced usage noted, any are allowed */
+ if (!usages) {
+ result = GKM_TRUST_TRUSTED;
+
+ } else {
+ result = GKM_TRUST_UNTRUSTED;
+ oid = g_quark_try_string (purpose);
+ for (usage = usages; *usage; ++usage) {
+ if (*usage == oid) {
+ result = GKM_TRUST_TRUSTED;
+ break;
+ }
+ }
+ }
+
+ g_free (usages);
+
+ /* See if we can delegate the trust (ie: CA) */
+ if (result == GKM_TRUST_TRUSTED && is_certificate_authority (self->pv->certificate))
+ result = GKM_TRUST_ANCHOR;
+
+ return result;
+}
+
+static void
+gkm_roots_trust_init (GkmRootsTrust *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKM_ROOTS_TYPE_TRUST, GkmRootsTrustPrivate);
+}
+
+static GObject*
+gkm_roots_trust_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GkmRootsTrust *self;
+ GQuark *usages, *u;
+ const gchar **p;
+ GkmTrustLevel level;
+
+ self = GKM_ROOTS_TRUST (G_OBJECT_CLASS (gkm_roots_trust_parent_class)->constructor (type, n_props, props));
+ g_return_val_if_fail (self->pv->certificate, NULL);
+
+ usages = lookup_extended_usages (self);
+
+ if (is_certificate_authority (self->pv->certificate))
+ level = GKM_TRUST_TRUSTED;
+ else
+ level = GKM_TRUST_ANCHOR;
+
+ /* Build assertions for all the listed usages */
+ if (usages) {
+ for (u = usages; *u; ++u)
+ build_linked_assertion (self, level, g_quark_to_string (*u));
+
+ /* Build assertions for all the known default purposes */
+ } else {
+ for (p = OID_KNOWN_PURPOSES; *p; ++p)
+ build_linked_assertion (self, level, *p);
+ }
+
+ return G_OBJECT (self);
+}
+
+static void
+gkm_roots_trust_dispose (GObject *obj)
+{
+ GkmRootsTrust *self = GKM_ROOTS_TRUST (obj);
+ GList *l;
+
+ for (l = self->pv->assertions; l; l = g_list_next (l)) {
+ g_object_run_dispose (G_OBJECT (l->data));
+ g_object_unref (l->data);
+ }
+
+ g_list_free (self->pv->assertions);
+ self->pv->assertions = NULL;
+
+ G_OBJECT_CLASS (gkm_roots_trust_parent_class)->dispose (obj);
+}
+
+static void
+gkm_roots_trust_finalize (GObject *obj)
+{
+ GkmRootsTrust *self = GKM_ROOTS_TRUST (obj);
+
+ if (self->pv->certificate)
+ g_object_remove_weak_pointer (G_OBJECT (self->pv->certificate), (gpointer*)&(self->pv->certificate));
+ self->pv->certificate = NULL;
+
+ g_assert (!self->pv->assertions);
+
+ G_OBJECT_CLASS (gkm_roots_trust_parent_class)->finalize (obj);
+}
+
+static void
+gkm_roots_trust_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GkmRootsTrust *self = GKM_ROOTS_TRUST (obj);
+
+ switch (prop_id) {
+ case PROP_CERTIFICATE:
+ g_return_if_fail (!self->pv->certificate);
+ self->pv->certificate = g_value_get_object (value);
+ g_return_if_fail (self->pv->certificate);
+ g_object_add_weak_pointer (G_OBJECT (self->pv->certificate), (gpointer*)&(self->pv->certificate));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gkm_roots_trust_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GkmRootsTrust *self = GKM_ROOTS_TRUST (obj);
+
+ switch (prop_id) {
+ case PROP_CERTIFICATE:
+ g_value_set_object (value, gkm_roots_trust_get_certificate (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gkm_roots_trust_class_init (GkmRootsTrustClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
+ GkmTrustClass *trust_class = GKM_TRUST_CLASS (klass);
+
+ gobject_class->constructor = gkm_roots_trust_constructor;
+ gobject_class->dispose = gkm_roots_trust_dispose;
+ gobject_class->finalize = gkm_roots_trust_finalize;
+ gobject_class->set_property = gkm_roots_trust_set_property;
+ gobject_class->get_property = gkm_roots_trust_get_property;
+
+ gkm_class->get_attribute = gkm_roots_trust_get_attribute;
+ gkm_class->expose_object = gkm_roots_trust_expose_object;
+
+ trust_class->get_trust_level = gkm_roots_trust_get_trust_level;
+
+ g_type_class_add_private (klass, sizeof (GkmRootsTrustPrivate));
+
+ g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
+ g_param_spec_object ("certificate", "Certificate", "Certificate this trust belongs to",
+ GKM_TYPE_CERTIFICATE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ init_quarks ();
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GkmRootsTrust*
+gkm_roots_trust_new (GkmModule *module, GkmManager *manager, GkmCertificate *cert)
+{
+ return g_object_new (GKM_ROOTS_TYPE_TRUST, "module", module,
+ "manager", manager, "certificate", cert, NULL);
+}
+
+GkmCertificate*
+gkm_roots_trust_get_certificate (GkmRootsTrust *self)
+{
+ g_return_val_if_fail (GKM_ROOTS_IS_TRUST (self), NULL);
+ g_return_val_if_fail (self->pv->certificate, NULL);
+ return self->pv->certificate;
+}
diff --git a/pkcs11/roots-store/gkm-roots-trust.h b/pkcs11/roots-store/gkm-roots-trust.h
new file mode 100644
index 0000000..def17aa
--- /dev/null
+++ b/pkcs11/roots-store/gkm-roots-trust.h
@@ -0,0 +1,60 @@
+/*
+ * gnome-trustring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ * Copyright (C) 2010 Collabora Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKM_ROOTS_TRUST_H__
+#define __GKM_ROOTS_TRUST_H__
+
+#include <glib-object.h>
+
+#include "gkm/gkm-trust.h"
+#include "gkm/gkm-object.h"
+#include "gkm/gkm-types.h"
+
+#define GKM_ROOTS_TYPE_TRUST (gkm_roots_trust_get_type ())
+#define GKM_ROOTS_TRUST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_ROOTS_TYPE_TRUST, GkmRootsTrust))
+#define GKM_ROOTS_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_ROOTS_TYPE_TRUST, GkmRootsTrustClass))
+#define GKM_ROOTS_IS_TRUST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_ROOTS_TYPE_TRUST))
+#define GKM_ROOTS_IS_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_ROOTS_TYPE_TRUST))
+#define GKM_ROOTS_TRUST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_ROOTS_TYPE_TRUST, GkmRootsTrustClass))
+
+typedef struct _GkmRootsTrust GkmRootsTrust;
+typedef struct _GkmRootsTrustClass GkmRootsTrustClass;
+typedef struct _GkmRootsTrustPrivate GkmRootsTrustPrivate;
+
+struct _GkmRootsTrust {
+ GkmTrust parent;
+ GkmRootsTrustPrivate *pv;
+};
+
+struct _GkmRootsTrustClass {
+ GkmTrustClass parent_class;
+};
+
+GType gkm_roots_trust_get_type (void);
+
+GkmRootsTrust* gkm_roots_trust_new (GkmModule *module,
+ GkmManager *manager,
+ GkmCertificate *cert);
+
+GkmCertificate* gkm_roots_trust_get_certificate (GkmRootsTrust *self);
+
+#endif /* __GKM_ROOTS_TRUST_H__ */
diff --git a/pkcs11/xdg-store/Makefile.am b/pkcs11/xdg-store/Makefile.am
index a0bc901..931613a 100644
--- a/pkcs11/xdg-store/Makefile.am
+++ b/pkcs11/xdg-store/Makefile.am
@@ -18,6 +18,7 @@ BUILT_SOURCES = \
libgkm_xdg_store_la_SOURCES = \
gkm-xdg-store.h \
+ gkm-xdg-assertion.c gkm-xdg-assertion.h \
gkm-xdg-module.c gkm-xdg-module.h \
gkm-xdg-trust.c gkm-xdg-trust.h \
$(BUILT_SOURCES)
diff --git a/pkcs11/xdg-store/asn1-def-xdg.c b/pkcs11/xdg-store/asn1-def-xdg.c
index 0d1edd9..9e9dfee 100644
--- a/pkcs11/xdg-store/asn1-def-xdg.c
+++ b/pkcs11/xdg-store/asn1-def-xdg.c
@@ -7,31 +7,36 @@
const ASN1_ARRAY_TYPE xdg_asn1_tab[] = {
{ "XDG", 536872976, NULL },
{ NULL, 1073741836, NULL },
- { "TrustDigest", 1610612741, NULL },
- { "algorithm", 1073741836, NULL },
- { "digest", 7, NULL },
- { "TrustDigests", 1610612747, NULL },
- { NULL, 2, "TrustDigest"},
{ "TrustLevel", 1610874901, NULL },
- { "trustUnknown", 1073741825, "0"},
+ { "unknown", 1073741825, "0"},
{ "untrusted", 1073741825, "1"},
- { "mustVerify", 1073741825, "2"},
{ "trusted", 1073741825, "3"},
- { "trustedDelegator", 1, "4"},
- { "TrustPair", 1610612741, NULL },
+ { "trustedAnchor", 1, "4"},
+ { "TrustAssertion", 1610612741, NULL },
{ "purpose", 1073741836, NULL },
- { "level", 2, "TrustLevel"},
- { "TrustPairs", 1610612747, NULL },
- { NULL, 2, "TrustPair"},
+ { "level", 1073741826, "TrustLevel"},
+ { "with", 1073741831, NULL },
+ { "additions", 536870923, NULL },
+ { NULL, 13, NULL },
+ { "TrustAssertions", 1610612747, NULL },
+ { NULL, 2, "TrustAssertion"},
{ "CertReference", 1610612741, NULL },
{ "serialNumber", 1073741827, NULL },
{ "issuer", 1073741837, NULL },
{ "subject", 1073758221, NULL },
- { "digests", 16386, "TrustDigests"},
+ { "additions", 536870923, NULL },
+ { NULL, 13, NULL },
{ "TrustReference", 1610612754, NULL },
- { "certReference", 2, "CertReference"},
+ { "certReference", 1610620930, "CertReference"},
+ { NULL, 2056, "0"},
+ { "certComplete", 1610620941, NULL },
+ { NULL, 2056, "1"},
+ { "additions", 536879117, NULL },
+ { NULL, 2056, "2"},
{ "trust-1", 536870917, NULL },
{ "reference", 1073741826, "TrustReference"},
- { "trusts", 2, "TrustPairs"},
+ { "assertions", 1073741826, "TrustAssertions"},
+ { "additions", 536870923, NULL },
+ { NULL, 13, NULL },
{ NULL, 0, NULL }
};
diff --git a/pkcs11/xdg-store/gkm-xdg-assertion.c b/pkcs11/xdg-store/gkm-xdg-assertion.c
new file mode 100644
index 0000000..0c88613
--- /dev/null
+++ b/pkcs11/xdg-store/gkm-xdg-assertion.c
@@ -0,0 +1,252 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkm-xdg-assertion.h"
+#include "gkm-xdg-trust.h"
+
+#include "gkm/gkm-attributes.h"
+#include "gkm/gkm-object.h"
+#include "gkm/gkm-session.h"
+#include "gkm/gkm-transaction.h"
+#include "gkm/gkm-trust.h"
+#include "gkm/gkm-util.h"
+
+#include "pkcs11/pkcs11i.h"
+#include "pkcs11/pkcs11n.h"
+
+#include <glib/gi18n.h>
+
+struct _GkmXdgAssertionPrivate {
+
+};
+
+G_DEFINE_TYPE (GkmXdgAssertion, gkm_xdg_assertion, GKM_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * QUARKS
+ */
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static GkmTrust*
+lookup_or_create_trust_object (GkmSession *session, GkmManager *manager,
+ GkmTransaction *transaction, CK_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;
+ GkmTrust *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_G_CERTIFICATE_TRUST_ANCHOR:
+ case CKT_G_CERTIFICATE_TRUST_EXCEPTION:
+ value = gkm_attributes_find (attrs, n_attrs, CKA_G_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 (value));
+ n_lookups = 2;
+ break;
+
+ case CKT_G_CERTIFICATE_UNTRUSTED:
+ 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 (issuer));
+ memcpy (lookups + 2, issuer, sizeof (serial));
+ n_lookups = 2;
+ 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_IS_TRUST (objects->data), NULL);
+ trust = GKM_TRUST (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_G_CERTIFICATE_VALUE,
+ CKA_ISSUER, CKA_SERIAL_NUMBER, G_MAXULONG);
+ gkm_attributes_consume (lookups, n_lookups, CKA_G_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;
+}
+
+static GkmObject*
+factory_create_assertion (GkmSession *session, GkmTransaction *transaction,
+ CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
+{
+ GkmAssertion *assertion;
+ CK_ASSERTION_TYPE type;
+ GkmManager *manager;
+ gboolean created = FALSE;
+ GkmTrust *trust;
+ gchar *purpose;
+
+ g_return_val_if_fail (attrs || !n_attrs, NULL);
+
+ if (!gkm_attributes_find_ulong (attrs, n_attrs, CKA_G_ASSERTION_TYPE, &type)) {
+ gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
+ return NULL;
+ }
+
+ if (!gkm_attributes_find_string (attrs, n_attrs, CKA_G_PURPOSE, &purpose)) {
+ gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
+ return NULL;
+ }
+
+ /* Try to find or create an appropriate trust object for this assertion */
+ manager = gkm_manager_for_template (attrs, n_attrs, session);
+ trust = lookup_or_create_trust_object (session, manager, transaction,
+ type, attrs, n_attrs, &created);
+
+ /* Creating the trust object failed */
+ if (trust == NULL) {
+ g_return_val_if_fail (gkm_transaction_get_failed (transaction), NULL);
+ g_free (purpose);
+ return NULL;
+ }
+
+ assertion = g_object_new (GKM_XDG_TYPE_ASSERTION, "trust", trust,
+ "type", type, "purpose", purpose, NULL);
+
+ gkm_attributes_consume (attrs, n_attrs, CKA_G_ASSERTION_TYPE, CKA_G_PURPOSE, G_MAXULONG);
+ gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (assertion),
+ TRUE, attrs, n_attrs);
+
+ return GKM_OBJECT (trust);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static CK_RV
+gkm_xdg_assertion_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr)
+{
+#if 0
+ GkmXdgAssertion *self = GKM_XDG_ASSERTION (base);
+
+ switch (attr->type)
+ {
+ case CKA_G
+ /* Various trust flags */
+ case CKA_G_TRUST_LEVEL:
+ xxxx;
+ case CKA_G_TRUST_PURPOSE:
+ xxxx;
+
+ default:
+ break;
+ };
+
+#endif
+ return GKM_OBJECT_CLASS (gkm_xdg_assertion_parent_class)->get_attribute (base, session, attr);
+}
+
+static void
+gkm_xdg_assertion_init (GkmXdgAssertion *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKM_XDG_TYPE_ASSERTION, GkmXdgAssertionPrivate);
+}
+
+static void
+gkm_xdg_assertion_finalize (GObject *obj)
+{
+#if 0
+ GkmXdgAssertion *self = GKM_XDG_ASSERTION (obj);
+#endif
+ G_OBJECT_CLASS (gkm_xdg_assertion_parent_class)->finalize (obj);
+}
+
+static void
+gkm_xdg_assertion_class_init (GkmXdgAssertionClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gkm_xdg_assertion_finalize;
+ gkm_class->get_attribute = gkm_xdg_assertion_get_attribute;
+
+ g_type_class_add_private (klass, sizeof (GkmXdgAssertionPrivate));
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+
+GkmFactory*
+gkm_xdg_assertion_get_factory (void)
+{
+ static CK_OBJECT_CLASS klass = CKO_G_TRUST_ASSERTION;
+
+ static CK_ATTRIBUTE attributes[] = {
+ { CKA_CLASS, &klass, sizeof (klass) },
+ };
+
+ static GkmFactory factory = {
+ attributes,
+ G_N_ELEMENTS (attributes),
+ factory_create_assertion
+ };
+
+ return &factory;
+}
diff --git a/pkcs11/xdg-store/gkm-xdg-assertion.h b/pkcs11/xdg-store/gkm-xdg-assertion.h
new file mode 100644
index 0000000..75bc073
--- /dev/null
+++ b/pkcs11/xdg-store/gkm-xdg-assertion.h
@@ -0,0 +1,55 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ * Copyright (C) 2010 Collabora Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKM_XDG_ASSERTION_H__
+#define __GKM_XDG_ASSERTION_H__
+
+#include <glib-object.h>
+
+#include "gkm/gkm-object.h"
+
+#define GKM_XDG_FACTORY_ASSERTION (gkm_xdg_assertion_get_factory ())
+#define GKM_XDG_TYPE_ASSERTION (gkm_xdg_assertion_get_type ())
+#define GKM_XDG_ASSERTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_XDG_TYPE_ASSERTION, GkmXdgAssertion))
+#define GKM_XDG_ASSERTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_XDG_TYPE_ASSERTION, GkmXdgAssertionClass))
+#define GKM_XDG_IS_ASSERTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_XDG_TYPE_ASSERTION))
+#define GKM_XDG_IS_ASSERTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_XDG_TYPE_ASSERTION))
+#define GKM_XDG_ASSERTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_XDG_TYPE_ASSERTION, GkmXdgAssertionClass))
+
+typedef struct _GkmXdgAssertion GkmXdgAssertion;
+typedef struct _GkmXdgAssertionClass GkmXdgAssertionClass;
+typedef struct _GkmXdgAssertionPrivate GkmXdgAssertionPrivate;
+
+struct _GkmXdgAssertion {
+ GkmObject parent;
+ GkmXdgAssertionPrivate *pv;
+};
+
+struct _GkmXdgAssertionClass {
+ GkmObjectClass parent_class;
+};
+
+GType gkm_xdg_assertion_get_type (void);
+
+GkmFactory* gkm_xdg_assertion_get_factory (void);
+
+#endif /* __GKM_XDG_ASSERTION_H__ */
diff --git a/pkcs11/xdg-store/gkm-xdg-module.c b/pkcs11/xdg-store/gkm-xdg-module.c
index 64bdcf7..92f9fbc 100644
--- a/pkcs11/xdg-store/gkm-xdg-module.c
+++ b/pkcs11/xdg-store/gkm-xdg-module.c
@@ -23,7 +23,7 @@
#include "gkm-xdg-module.h"
#include "gkm-xdg-store.h"
-#include "gkm-xdg-trust.h"
+#include "gkm-xdg-assertion.h"
#include "egg/egg-asn1x.h"
#include "egg/egg-asn1-defs.h"
@@ -31,6 +31,7 @@
#include "egg/egg-error.h"
#include "egg/egg-hex.h"
+#include "gkm/gkm-assertion.h"
#include "gkm/gkm-file-tracker.h"
#include "gkm/gkm-serializable.h"
#include "gkm/gkm-transaction.h"
@@ -105,7 +106,7 @@ type_from_path (const gchar *path)
return 0;
if (g_str_equal (ext, ".trust"))
- return GKM_XDG_TYPE_TRUST;
+ return GKM_XDG_TYPE_ASSERTION;
#if 0
else if (strcmp (extension, ".pkcs8") == 0)
@@ -310,12 +311,19 @@ gkm_xdg_module_real_add_token_object (GkmModule *module, GkmTransaction *transac
GkmObject *object)
{
GkmXdgModule *self;
+ GkmTrust *trust;
gchar *basename;
gchar *actual;
gchar *filename;
self = GKM_XDG_MODULE (module);
+ /* Always serialize the trust object for each assertion */
+ if (GKM_XDG_IS_ASSERTION (object)) {
+ trust = gkm_assertion_get_trust_object (GKM_ASSERTION (object));
+ object = GKM_OBJECT (trust);
+ }
+
/* Double check that the object is in fact serializable */
if (!GKM_IS_SERIALIZABLE (object)) {
g_message ("can't store object of type '%s' on token", G_OBJECT_TYPE_NAME (object));
@@ -344,10 +352,17 @@ gkm_xdg_module_real_store_token_object (GkmModule *module, GkmTransaction *trans
GkmObject *object)
{
GkmXdgModule *self = GKM_XDG_MODULE (module);
+ GkmTrust *trust;
const gchar *filename;
gpointer data;
gsize n_data;
+ /* Always serialize the trust object for each assertion */
+ if (GKM_XDG_IS_ASSERTION (object)) {
+ trust = gkm_assertion_get_trust_object (GKM_ASSERTION (object));
+ object = GKM_OBJECT (trust);
+ }
+
/* Double check that the object is in fact serializable */
if (!GKM_IS_SERIALIZABLE (object)) {
g_message ("can't store object of type '%s' on token", G_OBJECT_TYPE_NAME (object));
@@ -376,6 +391,9 @@ gkm_xdg_module_real_remove_token_object (GkmModule *module, GkmTransaction *tran
GkmXdgModule *self = GKM_XDG_MODULE (module);
const gchar *filename;
+ /* XXXX; need to implement for assertions */
+ g_assert_not_reached ();
+
filename = lookup_filename_for_object (object);
g_return_if_fail (filename != NULL);
g_return_if_fail (g_hash_table_lookup (self->objects_by_path, filename) == object);
@@ -409,8 +427,8 @@ gkm_xdg_module_init (GkmXdgModule *self)
/* Our default token info, updated as module runs */
memcpy (&self->token_info, &user_module_token_info, sizeof (CK_TOKEN_INFO));
- /* For creating stored keys */
- gkm_module_register_factory (GKM_MODULE (self), GKM_XDG_FACTORY_TRUST);
+ /* For creating stored objects */
+ gkm_module_register_factory (GKM_MODULE (self), GKM_XDG_FACTORY_ASSERTION);
}
static void
diff --git a/pkcs11/xdg-store/gkm-xdg-trust-netscape.c b/pkcs11/xdg-store/gkm-xdg-trust-netscape.c
new file mode 100644
index 0000000..0a41a09
--- /dev/null
+++ b/pkcs11/xdg-store/gkm-xdg-trust-netscape.c
@@ -0,0 +1,314 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkm-xdg-trust-netscape.h"
+
+#include "egg/egg-asn1x.h"
+
+#include "gkm/gkm-attributes.h"
+#include "gkm/gkm-object.h"
+#include "gkm/gkm-serializable.h"
+#include "gkm/gkm-session.h"
+#include "gkm/gkm-transaction.h"
+#include "gkm/gkm-util.h"
+
+#include "pkcs11/pkcs11g.h"
+#include "pkcs11/pkcs11n.h"
+
+#include <libtasn1.h>
+
+#include <glib/gi18n.h>
+
+struct _GkmXdgTrustNetscapePrivate {
+ GHashTable *assertions;
+};
+
+G_DEFINE_TYPE (GkmXdgTrustNetscape, gkm_xdg_trust_netscape, GKM_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static GkmXdgTrustNetscape*
+lookup_or_create_matching_netscape_trust (GkmXdgTrust *assertion)
+{
+ CK_OBJECT_CLASS klass = CKO_NETSCAPE_TRUST;
+ GkmXdgTrustNetscape *netscape;
+ GkmManager *manager;
+ GkmModule *module;
+ CK_ATTRIBUTE attrs[5];
+ GList *objects;
+
+ attrs[0].type = CKA_CLASS;
+ attrs[0].pValue = &klass;
+ attrs[0].ulValueLen = sizeof (klass);
+
+ switch (gkm_xdg_trust_get_assertion_type (assertion)) {
+ case GKM_XDG_TRUST_ROOT:
+ data = gkm_xdg_trust_get_hash (assertion, G_CHECKSUM_SHA1, &n_data);
+ g_return_val_if_fail (data, NULL);
+ attrs[1].type = CKA_CERT_SHA1_HASH;
+ attrs[1].pValue = data;
+ attrs[1].ulValueLen = n_data;
+ n_attrs = 2;
+ break;
+ case GKM_XDG_TRUST_EXCEPTION:
+ data = gkm_xdg_trust_get_serial (assertion, &n_data);
+ g_return_val_if_fail (data, NULL);
+ attrs[1].type = CKA_SERIAL_NUMBER;
+ attrs[1].pValue = data;
+ attrs[1].ulValueLen = n_data;
+ data = gkm_xdg_trust_get_issuer (assertion, &n_data);
+ g_return_val_if_fail (data, NULL);
+ attrs[2].type = CKA_ISSUER;
+ attrs[2].pValue = data;
+ attrs[2].ulValueLen = n_data;
+ n_attrs = 3;
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ };
+
+ manager = gkm_object_get_manager (GKM_OBJECT (assertion));
+ objects = gkm_manager_find_by_attributes (manager, NULL, attrs, n_attrs);
+
+ if (objects) {
+ g_assert (objects->data);
+ netscape = GKM_XDG_TRUST_NETSCAPE (objects->data);
+ g_list_free (objects->data);
+ } else {
+ trust = g_object_new (GKM_XDG_TYPE_TRUST_NETSCAPE,
+ "module", gkm_object_get_module (assertion),
+ "manager", manager,
+ NULL);
+ gkm_object_expose (GKM_OBJECT (trust), TRUE);
+
+#if XXXX
+ /* Certificate reference values */
+ case CKA_SUBJECT:
+ return trust_get_der (self, "subject", attr);
+ case CKA_SERIAL_NUMBER:
+ return trust_get_integer (self, "serialNumber", attr);
+ case CKA_ISSUER:
+ return trust_get_der (self, "issuer", attr);
+
+ /* Certificate hash values */
+ case CKA_CERT_MD5_HASH:
+ return trust_get_hash (self, OID_HASH_MD5, attr);
+ case CKA_CERT_SHA1_HASH:
+ return trust_get_hash (self, OID_HASH_SHA1, attr);
+#endif
+
+ }
+
+ xxxx ownership xxxx;
+
+ return trust;
+}
+
+static CK_RV
+lookup_certificate_hash (GkmXdgTrustNetscape *self, CK_ATTRIBUTE_PTR attr, GChecksumType type)
+{
+ GkmXdgAssertion *assertion;
+ GChecksum *checksum;
+ gpointer value, hash;
+ gconstpointer data;
+ gsize n_data, n_hash;
+ CK_RV rv;
+
+ if (self->pv->assertion_type != CKT_G_CERTIFICATE_ROOT)
+ return CKR_ATTRIBUTE_TYPE_INVALID;
+
+ /* Find the first assertion */
+ g_hash_table_iter_init (&iter, self->pv->assertions);
+ if (!g_hash_table_iter_next (&iter, NULL, &value))
+ g_assert_not_reached ();
+ assertion = GKM_XDG_ASSERTION (value);
+
+ g_assert (gkm_xdg_assertion_get_assertion_type (assertion) == CKT_G_CERTIFICATE_ROOT);
+ data = gkm_xdg_assertion_get_certificate_value (assertion, &n_data);
+ g_return_val_if_fail (data, CKR_GENERAL_ERROR);
+
+ checksum = g_checksum_new (type);
+ g_checksum_update (checksum, data, n_data);
+ n_hash = g_checksum_type_get_length (type);
+ hash = g_malloc (n_hash);
+ g_checksum_get_digest (checksum, hash, &n_hash);
+ g_checksum_free (checksum);
+
+ rv = gkm_attribute_set_data (attr, hash, n_hash);
+ g_free (hash);
+
+ return rv;
+}
+
+static CK_RV
+lookup_assertion_attr (GkmXdgTrustNetscape *self, GkmSession *session, CK_ATTRIBUTE_PTR attr)
+{
+ GHashTableIter iter;
+ gpointer value;
+
+ /* Find the first assertion, any will do */
+ g_hash_table_iter_init (&iter, self->pv->assertions);
+ if (!g_hash_table_iter_next (&iter, NULL, &value))
+ g_assert_not_reached ();
+
+ return gkm_object_get_attribute (GKM_OBJECT (value), session, attr);
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+static CK_RV
+gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr)
+{
+ GkmXdgTrustNetscape *self = GKM_XDG_TRUST (base);
+ GkmXdgAssertion *assertion;
+ CK_ULONG value;
+
+ /* Attributes like subject, issuer, cert hashes */
+ for (i = 0; i < self->pv->n_attrs; ++i) {
+ if (self->pv->attrs[i].type == attr->type) {
+ gkm_attribute_set_data (attr, self->pv->attrs[i].pValue,
+ self->pv->attrs[i].ulValueLen);
+ return;
+ }
+ }
+
+ /* Look for overrides of the default flags and restrictions below */
+ assertion = g_hash_table_lookup (self->pv->assertions, &(attr->type));
+ if (assertion) {
+ level = gkm_xdg_assertion_get_level (assertion);
+ return gkm_attribute_set_ulong (attr, level_to_netscape_trust (level));
+ }
+
+ switch (attr->type)
+ {
+ case CKA_PRIVATE:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+ case CKA_TRUST_STEP_UP_APPROVED:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+ case CKA_CLASS:
+ return gkm_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST);
+ case CKA_MODIFIABLE:
+ return gkm_attribute_set_bool (attr, CK_FALSE);
+
+ /* Key restrictions */
+ case CKA_TRUST_DIGITAL_SIGNATURE:
+ case CKA_TRUST_NON_REPUDIATION:
+ case CKA_TRUST_KEY_ENCIPHERMENT:
+ case CKA_TRUST_DATA_ENCIPHERMENT:
+ case CKA_TRUST_KEY_AGREEMENT:
+ case CKA_TRUST_KEY_CERT_SIGN:
+ case CKA_TRUST_CRL_SIGN:
+ return gkm_attribute_set_ulong (attr, CKT_NETSCAPE_TRUST_UNKNOWN);
+
+ /* Various trust flags */
+ case CKA_TRUST_SERVER_AUTH:
+ case CKA_TRUST_CLIENT_AUTH:
+ case CKA_TRUST_CODE_SIGNING:
+ case CKA_TRUST_EMAIL_PROTECTION:
+ case CKA_TRUST_IPSEC_END_SYSTEM:
+ case CKA_TRUST_IPSEC_TUNNEL:
+ case CKA_TRUST_IPSEC_USER:
+ case CKA_TRUST_TIME_STAMPING:
+ return gkm_attribute_set_ulong (attr, CKT_NETSCAPE_TRUST_UNKNOWN);
+
+ case CKA_CERT_MD5_HASH:
+ return lookup_certificate_hash (self, attr, G_CHECKSUM_MD5);
+ case CKA_CERT_SHA1_HASH:
+ return lookup_certificate_hash (self, attr, G_CHECKSUM_SHA1);
+
+ case CKA_LABEL:
+ case CKA_SUBJECT:
+ case CKA_ISSUER:
+ case CKA_SERIAL_NUMBER:
+ return lookup_assertion_value (self, session, attr);
+
+ default:
+ break;
+ };
+
+ return GKM_OBJECT_CLASS (gkm_xdg_trust_parent_class)->get_attribute (base, session, attr);
+}
+
+static void
+gkm_xdg_trust_init (GkmXdgTrust *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKM_XDG_TYPE_TRUST, GkmXdgTrustPrivate);
+ self->pv->assertions = g_hash_table_new (gkm_util_ulong_hash, gkm_util_ulong_equal);
+}
+
+static void
+gkm_xdg_trust_finalize (GObject *obj)
+{
+ GkmXdgTrust *self = GKM_XDG_TRUST (obj);
+
+ g_assert (self->pv->assertions);
+ g_hash_table_destroy (self->pv->assertions);
+ self->pv->assertions = NULL;
+
+ g_free (self->pv->attrs);
+ self->pv->attrs = NULL;
+ self->pv->n_attrs = 0;
+
+ G_OBJECT_CLASS (gkm_xdg_trust_parent_class)->finalize (obj);
+}
+
+static void
+gkm_xdg_trust_class_init (GkmXdgTrustClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = gkm_xdg_trust_finalize;
+ gkm_class->get_attribute = gkm_xdg_trust_get_attribute;
+
+ g_type_class_add_private (klass, sizeof (GkmXdgTrustPrivate));
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+void
+gkm_xdg_trust_netscape_register_assertion (GkmXdgTrustAssertion *assertion)
+{
+ GHashTable *netscape_trusts;
+ GkmXdgTrustLevel level;
+ const gchar *purpose;
+
+ g_return_if_fail (GKM_IS_MODULE (module));
+ g_return_if_fail (GKM_XDG_IS_TRUST_ASSERTION (assertion));
+
+ trust = lookup_or_create_matching_netscape_trust (assertion);
+
+ level = gkm_xdg_trust_get_level (assertion);
+ purpose = gkm_xdg_trust_get_purpose (assertion);
+ g_return_if_fail (purpose);
+
+ type = netscape_type_for_purpose (purpose);
+ value = netscape_trust_for_level (level);
+
+}
diff --git a/pkcs11/xdg-store/gkm-xdg-trust-netscape.h b/pkcs11/xdg-store/gkm-xdg-trust-netscape.h
new file mode 100644
index 0000000..c8060d2
--- /dev/null
+++ b/pkcs11/xdg-store/gkm-xdg-trust-netscape.h
@@ -0,0 +1,59 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKM_XDG_TRUST_NETSCAPE_H__
+#define __GKM_XDG_TRUST_NETSCAPE_H__
+
+#include <glib-object.h>
+
+#include "gkm/gkm-object.h"
+
+#define GKM_XDG_TYPE_TRUST_NETSCAPE (gkm_xdg_trust_netscape_get_type ())
+#define GKM_XDG_TRUST_NETSCAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_XDG_TYPE_TRUST_NETSCAPE, GkmXdgTrustNetscape))
+#define GKM_XDG_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_XDG_TYPE_TRUST_NETSCAPE, GkmXdgTrustNetscapeClass))
+#define GKM_XDG_IS_TRUST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_XDG_TYPE_TRUST_NETSCAPE))
+#define GKM_XDG_IS_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_XDG_TYPE_TRUST_NETSCAPE))
+#define GKM_XDG_TRUST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_XDG_TYPE_TRUST_NETSCAPE, GkmXdgTrustClass))
+
+typedef struct _GkmXdgTrustNetscape GkmXdgTrustNetscape;
+typedef struct _GkmXdgTrustNetscapeClass GkmXdgTrustNetscapeClass;
+typedef struct _GkmXdgTrustNetscapePrivate GkmXdgTrustNetscapePrivate;
+
+struct _GkmXdgTrustNetscape {
+ GkmObject parent;
+ GkmXdgTrustNetscapePrivate *pv;
+};
+
+struct _GkmXdgTrustNetscapeClass {
+ GkmObjectClass parent_class;
+};
+
+GType gkm_xdg_trust_netscape_get_type (void);
+
+void gkm_xdg_trust_netscape_add_assertion_for_sha1 (GModule *module,
+ gpointer sha1_hash,
+ gsize n_sha1_hash);
+
+void gkm_xdg_trust_netscape_add_assertion_for_issuer (GModule *module,
+ gpointer sha1_hash,
+ gsize n_sha1_hash);
+
+#endif /* __GKM_XDG_TRUST_NETSCAPE_H__ */
diff --git a/pkcs11/xdg-store/gkm-xdg-trust.c b/pkcs11/xdg-store/gkm-xdg-trust.c
index d32cb59..ff976e8 100644
--- a/pkcs11/xdg-store/gkm-xdg-trust.c
+++ b/pkcs11/xdg-store/gkm-xdg-trust.c
@@ -24,26 +24,42 @@
#include "gkm-xdg-trust.h"
#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
+#include "gkm/gkm-assertion.h"
#include "gkm/gkm-attributes.h"
#include "gkm/gkm-object.h"
+#include "gkm/gkm-oids.h"
#include "gkm/gkm-serializable.h"
#include "gkm/gkm-session.h"
#include "gkm/gkm-transaction.h"
#include "gkm/gkm-util.h"
-#include "pkcs11/pkcs11g.h"
+#include "pkcs11/pkcs11i.h"
#include "pkcs11/pkcs11n.h"
#include <libtasn1.h>
#include <glib/gi18n.h>
+/* COMPAT: netscape's usages */
+typedef struct _NetscapeFlags {
+ CK_ULONG server_auth;
+ CK_ULONG client_auth;
+ CK_ULONG code_signing;
+ CK_ULONG email_protection;
+ CK_ULONG ipsec_end_system;
+ CK_ULONG ipsec_tunnel;
+ CK_ULONG ipsec_user;
+ CK_ULONG time_stamping;
+} NetscapeFlags;
+
struct _GkmXdgTrustPrivate {
GNode *asn;
- GHashTable *pairs;
+ GHashTable *assertions;
gpointer data;
gsize n_data;
+ NetscapeFlags netscape;
};
/* From asn1-def-xdg.c */
@@ -51,41 +67,17 @@ extern const ASN1_ARRAY_TYPE xdg_asn1_tab[];
static void gkm_xdg_trust_serializable (GkmSerializableIface *iface);
-G_DEFINE_TYPE_EXTENDED (GkmXdgTrust, gkm_xdg_trust, GKM_TYPE_OBJECT, 0,
+G_DEFINE_TYPE_EXTENDED (GkmXdgTrust, gkm_xdg_trust, GKM_TYPE_TRUST, 0,
G_IMPLEMENT_INTERFACE (GKM_TYPE_SERIALIZABLE, gkm_xdg_trust_serializable));
/* -----------------------------------------------------------------------------
* QUARKS
*/
-static GQuark OID_HASH_SHA1;
-static GQuark OID_HASH_MD5;
-
-static GQuark OID_USAGE_DIGITAL_SIGNATURE;
-static GQuark OID_USAGE_NON_REPUDIATION;
-static GQuark OID_USAGE_KEY_ENCIPHERMENT;
-static GQuark OID_USAGE_DATA_ENCIPHERMENT;
-static GQuark OID_USAGE_KEY_AGREEMENT;
-static GQuark OID_USAGE_KEY_CERT_SIGN;
-static GQuark OID_USAGE_CRL_SIGN;
-static GQuark OID_USAGE_ENCIPHER_ONLY;
-
-/* OID's for these purposes */
-static GQuark OID_PURPOSE_SERVER_AUTH;
-static GQuark OID_PURPOSE_CLIENT_AUTH;
-static GQuark OID_PURPOSE_CODE_SIGNING;
-static GQuark OID_PURPOSE_EMAIL;
-static GQuark OID_PURPOSE_TIME_STAMPING;
-static GQuark OID_PURPOSE_IPSEC_ENDPOINT;
-static GQuark OID_PURPOSE_IPSEC_TUNNEL;
-static GQuark OID_PURPOSE_IPSEC_USER;
-static GQuark OID_PURPOSE_IKE_INTERMEDIATE;
-
static GQuark TRUST_UNKNOWN;
static GQuark TRUST_UNTRUSTED;
-static GQuark TRUST_MUST_VERIFY;
static GQuark TRUST_TRUSTED;
-static GQuark TRUST_TRUSTED_DELEGATOR;
+static GQuark TRUST_TRUSTED_ANCHOR;
static void
init_quarks (void)
@@ -97,34 +89,10 @@ init_quarks (void)
#define QUARK(name, value) \
name = g_quark_from_static_string(value)
- QUARK (OID_HASH_SHA1, "1.3.14.3.2.26");
- QUARK (OID_HASH_MD5, "1.2.840.113549.2.5");
-
- /* These OIDs are in GNOME's space */
- QUARK (OID_USAGE_DIGITAL_SIGNATURE, "1.3.6.1.4.1.3319.1.6.3.128");
- QUARK (OID_USAGE_NON_REPUDIATION, "1.3.6.1.4.1.3319.1.6.3.64");
- QUARK (OID_USAGE_KEY_ENCIPHERMENT, "1.3.6.1.4.1.3319.1.6.3.32");
- QUARK (OID_USAGE_DATA_ENCIPHERMENT, "1.3.6.1.4.1.3319.1.6.3.16");
- QUARK (OID_USAGE_KEY_AGREEMENT, "1.3.6.1.4.1.3319.1.6.3.8");
- QUARK (OID_USAGE_KEY_CERT_SIGN, "1.3.6.1.4.1.3319.1.6.3.4");
- QUARK (OID_USAGE_CRL_SIGN, "1.3.6.1.4.1.3319.1.6.3.2");
- QUARK (OID_USAGE_ENCIPHER_ONLY, "1.3.6.1.4.1.3319.1.6.3.1");
-
- QUARK (OID_PURPOSE_SERVER_AUTH, "1.3.6.1.5.5.7.3.1");
- QUARK (OID_PURPOSE_CLIENT_AUTH, "1.3.6.1.5.5.7.3.2");
- QUARK (OID_PURPOSE_CODE_SIGNING, "1.3.6.1.5.5.7.3.3");
- QUARK (OID_PURPOSE_EMAIL, "1.3.6.1.5.5.7.3.4");
- QUARK (OID_PURPOSE_TIME_STAMPING, "1.3.6.1.5.5.7.3.8");
- QUARK (OID_PURPOSE_IPSEC_ENDPOINT, "1.3.6.1.5.5.7.3.5");
- QUARK (OID_PURPOSE_IPSEC_TUNNEL, "1.3.6.1.5.5.7.3.6");
- QUARK (OID_PURPOSE_IPSEC_USER, "1.3.6.1.5.5.7.3.7");
- QUARK (OID_PURPOSE_IKE_INTERMEDIATE, "1.3.6.1.5.5.8.2.2");
-
QUARK (TRUST_UNKNOWN, "trustUnknown");
QUARK (TRUST_UNTRUSTED, "untrusted");
- QUARK (TRUST_MUST_VERIFY, "mustVerify");
QUARK (TRUST_TRUSTED, "trusted");
- QUARK (TRUST_TRUSTED_DELEGATOR, "trustedDelegator");
+ QUARK (TRUST_TRUSTED_ANCHOR, "trustedAnchor");
#undef QUARK
@@ -136,25 +104,6 @@ init_quarks (void)
* INTERNAL
*/
-static CK_ULONG
-lookup_usage (GkmXdgTrust *self, GQuark purpose)
-{
- CK_ULONG *trust;
-
- trust = g_hash_table_lookup (self->pv->pairs, GUINT_TO_POINTER (purpose));
- if (!trust)
- return CKT_NETSCAPE_TRUST_UNKNOWN;
- else
- return *trust;
-}
-
-static CK_RV
-trust_get_usage (GkmXdgTrust *self, GQuark purpose, CK_ATTRIBUTE_PTR attr)
-{
- g_assert (GKM_XDG_IS_TRUST (self));
- return gkm_attribute_set_ulong (attr, lookup_usage (self, purpose));
-}
-
static CK_RV
trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
@@ -164,10 +113,9 @@ trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
g_assert (GKM_XDG_IS_TRUST (self));
- node = egg_asn1x_node (self->pv->asn, "reference", "certReference", NULL);
- g_return_val_if_fail (node, CKR_GENERAL_ERROR);
+ node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL);
- node = egg_asn1x_node (node, part, NULL);
+ /* If the assertion doesn't contain this info ... */
if (node == NULL)
return CKR_ATTRIBUTE_TYPE_INVALID;
@@ -188,10 +136,9 @@ trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
g_assert (GKM_XDG_IS_TRUST (self));
- node = egg_asn1x_node (self->pv->asn, "reference", "certReference", NULL);
- g_return_val_if_fail (node, CKR_GENERAL_ERROR);
+ node = egg_asn1x_node (self->pv->asn, "reference", "certReference", part, NULL);
- node = egg_asn1x_node (node, part, NULL);
+ /* If the assertion doesn't contain this info ... */
if (node == NULL)
return CKR_ATTRIBUTE_TYPE_INVALID;
@@ -203,44 +150,39 @@ trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
}
static CK_RV
-trust_get_hash (GkmXdgTrust *self, GQuark oid, CK_ATTRIBUTE_PTR attr)
+trust_get_hash (GkmXdgTrust *self, GChecksumType ctype, CK_ATTRIBUTE_PTR attr)
{
- CK_RV rv = CKR_ATTRIBUTE_VALUE_INVALID;
- GNode *digests, *digest;
- gpointer hash;
- gsize n_hash;
- guint count, i;
- GQuark check;
+ GNode *cert;
+ gconstpointer element;
+ gsize n_element;
- digests = egg_asn1x_node (self->pv->asn, "reference", "certReference", "digests", NULL);
- g_return_val_if_fail (digests, CKR_GENERAL_ERROR);
+ cert = egg_asn1x_node (self->pv->asn, "reference", "certComplete", NULL);
- count = egg_asn1x_count (digests);
- for (i = 0; i < count; ++i) {
- digest = egg_asn1x_node (digests, i + 1, NULL);
- g_return_val_if_fail (digest, CKR_GENERAL_ERROR);
-
- check = egg_asn1x_get_oid_as_quark (egg_asn1x_node (digest, "algorithm", NULL));
- if (oid == check) {
- hash = egg_asn1x_get_string_as_raw (egg_asn1x_node (digest, "digest", NULL),
- NULL, &n_hash);
- g_return_val_if_fail (hash, CKR_GENERAL_ERROR);
-
- rv = gkm_attribute_set_data (attr, hash, n_hash);
- g_free (hash);
- break;
- }
- }
+ /* If it's not stored, then this attribute is not present */
+ if (cert == NULL)
+ return CKR_ATTRIBUTE_TYPE_INVALID;
- return rv;
+ element = egg_asn1x_get_raw_element (cert, &n_element);
+ g_return_val_if_fail (element, CKR_GENERAL_ERROR);
+
+ return gkm_attribute_set_checksum (attr, ctype, element, n_element);
}
static gboolean
-validate_der (CK_ATTRIBUTE_PTR attr)
+validate_der (CK_ATTRIBUTE_PTR attr, const gchar *asn_type)
{
- return attr->pValue != NULL &&
- attr->ulValueLen != (CK_ULONG)-1 &&
- egg_asn1x_element_length (attr->pValue, attr->ulValueLen) >= 0;
+ GNode *asn;
+
+ if (!attr->pValue || attr->ulValueLen == (CK_ULONG)-1)
+ return FALSE;
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, asn_type, attr->pValue, attr->ulValueLen);
+ if (!asn)
+ return FALSE;
+
+ /* Yes, this is an expensive check, but worthwhile */
+ egg_asn1x_destroy (asn);
+ return TRUE;
}
static gboolean
@@ -251,212 +193,277 @@ validate_integer (CK_ATTRIBUTE_PTR attr)
attr->ulValueLen != (CK_ULONG)-1;
}
-static gboolean
-validate_hash (CK_ATTRIBUTE_PTR attr, GChecksumType type)
-{
- return attr->pValue != NULL &&
- attr->ulValueLen == g_checksum_type_get_length (type);
-}
-
-static void
-append_reference_hash (GNode *asn, GQuark oid, CK_ATTRIBUTE_PTR attr)
-{
- GNode *node;
-
- node = egg_asn1x_node (asn, "reference", "certReference", "digests", NULL);
- g_return_if_fail (node);
-
- /* Add another digest */
- node = egg_asn1x_append (node);
- g_return_if_fail (node);
-
- egg_asn1x_set_oid_as_quark (egg_asn1x_node (node, "algorithm", NULL), oid);
- egg_asn1x_set_string_as_raw (egg_asn1x_node (node, "digest", NULL),
- g_memdup (attr->pValue, attr->ulValueLen),
- attr->ulValueLen, g_free);
-}
-
static GQuark
-trust_ulong_to_level_enum (CK_ULONG trust)
+assertion_type_to_level_enum (CK_ASSERTION_TYPE type)
{
- switch (trust) {
- case CKT_NETSCAPE_TRUST_UNKNOWN:
- return TRUST_UNKNOWN;
- case CKT_NETSCAPE_UNTRUSTED:
+ switch (type) {
+ case CKT_G_CERTIFICATE_UNTRUSTED:
return TRUST_UNTRUSTED;
- case CKT_NETSCAPE_TRUSTED_DELEGATOR:
- return TRUST_TRUSTED_DELEGATOR;
+ case CKT_G_CERTIFICATE_TRUST_ANCHOR:
+ return TRUST_TRUSTED_ANCHOR;
case CKT_NETSCAPE_TRUSTED:
return TRUST_TRUSTED;
- case CKT_NETSCAPE_MUST_VERIFY:
- return TRUST_MUST_VERIFY;
default:
- return -1;
+ return 0;
};
}
-static CK_ULONG
-level_enum_to_trust_ulong (GQuark level)
+static gboolean
+level_enum_to_assertion_type (GQuark level, CK_ASSERTION_TYPE *type)
{
- if (level == TRUST_UNKNOWN)
- return CKT_NETSCAPE_TRUST_UNKNOWN;
- else if (level == TRUST_UNTRUSTED)
- return CKT_NETSCAPE_UNTRUSTED;
- else if (level == TRUST_TRUSTED_DELEGATOR)
- return CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ if (level == TRUST_UNTRUSTED)
+ *type = CKT_G_CERTIFICATE_UNTRUSTED;
+ else if (level == TRUST_TRUSTED_ANCHOR)
+ *type = CKT_G_CERTIFICATE_TRUST_ANCHOR;
else if (level == TRUST_TRUSTED)
- return CKT_NETSCAPE_TRUSTED;
- else if (level == TRUST_MUST_VERIFY)
- return CKT_NETSCAPE_MUST_VERIFY;
+ *type = CKT_G_CERTIFICATE_TRUST_EXCEPTION;
+ else if (level == TRUST_UNKNOWN)
+ *type = 0;
else
- return (CK_ULONG)-1;
+ return FALSE;
+ return TRUE;
}
-static GkmObject*
-factory_create_trust (GkmSession *session, GkmTransaction *transaction,
- CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
+static void
+init_netscape_trust (NetscapeFlags *netscape)
{
- GkmXdgTrust *trust;
- CK_ATTRIBUTE_PTR serial, issuer, subject;
- CK_ATTRIBUTE_PTR md5, sha1;
- GNode *asn;
+ netscape->server_auth = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->client_auth = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->code_signing = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->email_protection = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->ipsec_end_system = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->ipsec_tunnel = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->ipsec_user = CKT_NETSCAPE_TRUST_UNKNOWN;
+ netscape->time_stamping = CKT_NETSCAPE_TRUST_UNKNOWN;
+}
- g_return_val_if_fail (attrs || !n_attrs, NULL);
+static void
+parse_netscape_trust (NetscapeFlags *netscape, GQuark level, const gchar *purpose)
+{
+ CK_TRUST trust;
- subject = gkm_attributes_find (attrs, n_attrs, CKA_SUBJECT);
- serial = gkm_attributes_find (attrs, n_attrs, CKA_SERIAL_NUMBER);
- issuer = gkm_attributes_find (attrs, n_attrs, CKA_ISSUER);
+ if (level == TRUST_UNTRUSTED)
+ trust = CKT_NETSCAPE_TRUSTED;
+ else if (level == TRUST_TRUSTED_ANCHOR)
+ trust = CKT_NETSCAPE_TRUSTED_DELEGATOR;
+ else if (level == TRUST_TRUSTED)
+ trust = CKT_NETSCAPE_TRUSTED;
+ else if (level == TRUST_UNKNOWN)
+ trust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ else
+ return;
- if (serial == NULL || issuer == NULL) {
- gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
- return NULL;
- }
+ if (g_str_equal (purpose, GKM_OID_EXTUSAGE_SERVER_AUTH))
+ netscape->server_auth = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_CLIENT_AUTH))
+ netscape->client_auth = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_CODE_SIGNING))
+ netscape->code_signing = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_EMAIL))
+ netscape->email_protection = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_IPSEC_ENDPOINT))
+ netscape->ipsec_end_system = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_IPSEC_TUNNEL))
+ netscape->ipsec_tunnel = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_IPSEC_USER))
+ netscape->ipsec_user = trust;
+ else if (g_str_equal (purpose, GKM_OID_EXTUSAGE_TIME_STAMPING))
+ netscape->time_stamping = trust;
+}
- if (!validate_der (issuer) || (subject && !validate_der (subject))) {
- gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
- return NULL;
- }
+static void
+dispose_each_assertion (gpointer key, gpointer value, gpointer user_data)
+{
+ g_assert (GKM_IS_ASSERTION (value));
+ g_object_run_dispose (G_OBJECT (value));
+}
- if (!validate_integer (serial)) {
- gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
- return NULL;
- }
+static GHashTable*
+create_assertions (void)
+{
+ return g_hash_table_new_full (gkm_util_memory_hash, gkm_util_memory_equal,
+ gkm_util_memory_free, gkm_util_dispose_unref);
+}
- md5 = gkm_attributes_find (attrs, n_attrs, CKA_CERT_MD5_HASH);
- sha1 = gkm_attributes_find (attrs, n_attrs, CKA_CERT_SHA1_HASH);
+static GkmAssertion*
+create_assertion (GkmXdgTrust *self, GNode *asn, NetscapeFlags *netscape)
+{
+ CK_ASSERTION_TYPE type;
+ GkmAssertion *assertion;
+ GQuark level;
+ gchar *purpose;
+ gchar *remote;
+ GNode *node;
- if ((md5 && !validate_hash (md5, G_CHECKSUM_MD5)) ||
- (sha1 && !validate_hash (sha1, G_CHECKSUM_SHA1))) {
- gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
+ /* Get the trust level */
+ level = egg_asn1x_get_enumerated (egg_asn1x_node (asn, "level", NULL));
+ if (level == 0)
+ g_return_val_if_reached (NULL);
+ if (!level_enum_to_assertion_type (level, &type))
+ g_message ("unsupported trust level %s in trust object", g_quark_to_string (level));
+ else if (type == 0)
return NULL;
- }
- asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
- g_return_val_if_fail (asn, NULL);
+ /* A purpose */
+ purpose = egg_asn1x_get_oid_as_string (egg_asn1x_node (asn, "purpose", NULL));
+ g_return_val_if_fail (purpose, NULL);
- egg_asn1x_set_integer_as_raw (egg_asn1x_node (asn, "reference", "certReference", "serialNumber", NULL),
- g_memdup (serial->pValue, serial->ulValueLen),
- serial->ulValueLen, g_free);
-
- egg_asn1x_set_raw_element (egg_asn1x_node (asn, "reference", "certReference", "issuer", NULL),
- g_memdup (issuer->pValue, issuer->ulValueLen),
- issuer->ulValueLen, g_free);
-
- if (subject)
- egg_asn1x_set_raw_element (egg_asn1x_node (asn, "reference", "certReference", "subject", NULL),
- g_memdup (subject->pValue, issuer->ulValueLen),
- issuer->ulValueLen, g_free);
+ /* A remote name */
+ node = egg_asn1x_node (asn, "remote", NULL);
+ if (egg_asn1x_have (node))
+ remote = egg_asn1x_get_string_as_utf8 (node, NULL);
+ else
+ remote = NULL;
- if (md5)
- append_reference_hash (asn, OID_HASH_MD5, md5);
- if (sha1)
- append_reference_hash (asn, OID_HASH_SHA1, sha1);
+ assertion = gkm_assertion_new (GKM_TRUST (self), type, purpose, remote);
- trust = g_object_new (GKM_XDG_TYPE_TRUST,
- "module", gkm_session_get_module (session),
- "manager", gkm_manager_for_template (attrs, n_attrs, session),
- NULL);
- trust->pv->asn = asn;
+ /* Parse netscape trust flags */
+ if (remote == NULL)
+ parse_netscape_trust (netscape, level, purpose);
- gkm_attributes_consume (attrs, n_attrs, CKA_CERT_MD5_HASH, CKA_CERT_SHA1_HASH,
- CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER, G_MAXULONG);
+ g_free (purpose);
+ g_free (remote);
- gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (trust),
- TRUE, attrs, n_attrs);
- return GKM_OBJECT (trust);
+ return assertion;
}
static gboolean
-load_trust_pairs (GHashTable *pairs, GNode *asn)
+load_assertions (GkmXdgTrust *self, GNode *asn)
{
- GNode *pair;
+ gconstpointer element;
+ GHashTable *assertions;
+ GkmAssertion *assertion;
+ NetscapeFlags netscape;
+ gsize n_element;
+ GNode *node;
guint count, i;
- gulong trust;
- GQuark oid;
- GQuark level;
- g_assert (pairs);
+ g_assert (self);
g_assert (asn);
- g_hash_table_remove_all (pairs);
+ assertions = create_assertions ();
+ init_netscape_trust (&netscape);
- count = egg_asn1x_count (egg_asn1x_node (asn, "trusts", NULL));
+ count = egg_asn1x_count (egg_asn1x_node (asn, "assertions", NULL));
for (i = 0; i < count; ++i) {
- pair = egg_asn1x_node (asn, "trusts", i + 1, NULL);
- g_return_val_if_fail (pair, FALSE);
+ node = egg_asn1x_node (asn, "assertions", i + 1, NULL);
+ g_return_val_if_fail (node, FALSE);
- /* Get the usage */
- level = egg_asn1x_get_enumerated (egg_asn1x_node (pair, "level", NULL));
- if (level == 0)
- g_return_val_if_reached (FALSE);
+ /* We use the raw DER encoding as an assertion */
+ element = egg_asn1x_get_raw_element (node, &n_element);
+ g_return_val_if_fail (node, FALSE);
- trust = level_enum_to_trust_ulong (level);
- if (trust == (CK_ULONG)-1) {
- g_message ("unsupported trust level %u in trust object", (guint)level);
- continue;
- }
+ /* Double check that this is valid, because it's how we hash */
+ g_assert (egg_asn1x_element_length (element, n_element) == n_element);
+
+ /* Already have this assertion? */
+ assertion = g_hash_table_lookup (self->pv->assertions, element);
+ if (assertion) {
+ g_object_ref (assertion);
+ g_hash_table_remove (self->pv->assertions, element);
- /* A key usage */
- oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (pair, "purpose", NULL));
- g_return_val_if_fail (oid, FALSE);
+ /* Create a new assertion */
+ } else {
+ assertion = create_assertion (self, node, &netscape);
+ }
- g_hash_table_replace (pairs, GUINT_TO_POINTER (oid),
- gkm_util_ulong_alloc (trust));
+ if (assertion)
+ g_hash_table_insert (assertions, g_memdup (element, n_element), assertion);
}
+ /* Override the stored assertions and netscape trust */
+ g_hash_table_foreach (self->pv->assertions, dispose_each_assertion, NULL);
+ g_hash_table_unref (self->pv->assertions);
+ self->pv->assertions = assertions;
+ memcpy (&self->pv->netscape, &netscape, sizeof (netscape));
+
return TRUE;
}
static gboolean
-save_trust_pairs (GHashTable *pairs, GNode *asn)
+save_assertions (GkmXdgTrust *self, GNode *asn)
{
+ GkmAssertion *assertion;
GHashTableIter iter;
GNode *pair, *node;
- gpointer key, value;
+ const gchar *purpose;
+ const gchar *remote;
+ gpointer value;
GQuark level;
- GQuark oid;
- g_assert (pairs);
+ g_assert (GKM_XDG_IS_TRUST (self));
g_assert (asn);
node = egg_asn1x_node (asn, "trusts", NULL);
egg_asn1x_clear (node);
- g_hash_table_iter_init (&iter, pairs);
- while (g_hash_table_iter_next (&iter, &key, &value)) {
- oid = GPOINTER_TO_UINT (key);
- level = trust_ulong_to_level_enum (*((CK_ULONG_PTR)value));
+ g_hash_table_iter_init (&iter, self->pv->assertions);
+ while (g_hash_table_iter_next (&iter, NULL, &value)) {
+ assertion = GKM_ASSERTION (value);
+ level = assertion_type_to_level_enum (gkm_assertion_get_trust_type (assertion));
+ purpose = gkm_assertion_get_purpose (assertion);
+ remote = gkm_assertion_get_remote (assertion);
pair = egg_asn1x_append (node);
g_return_val_if_fail (pair, FALSE);
- egg_asn1x_set_oid_as_quark (egg_asn1x_node (pair, "purpose", NULL), oid);
+ egg_asn1x_set_oid_as_string (egg_asn1x_node (pair, "purpose", NULL), purpose);
egg_asn1x_set_enumerated (egg_asn1x_node (pair, "level", NULL), level);
+
+ if (remote) {
+ egg_asn1x_set_string_as_utf8 (egg_asn1x_node (pair, "remote", NULL),
+ g_strdup (remote), g_free);
+ }
}
return TRUE;
}
+
+static GkmXdgTrust*
+create_trust_for_reference (GkmModule *module, GkmManager *manager,
+ CK_ATTRIBUTE_PTR serial, CK_ATTRIBUTE_PTR issuer)
+{
+ GkmXdgTrust *trust;
+ GNode *asn;
+
+ asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
+ g_return_val_if_fail (asn, NULL);
+
+ egg_asn1x_set_integer_as_raw (egg_asn1x_node (asn, "reference", "certReference", "serialNumber", NULL),
+ g_memdup (serial->pValue, serial->ulValueLen),
+ serial->ulValueLen, g_free);
+
+ egg_asn1x_set_raw_element (egg_asn1x_node (asn, "reference", "certReference", "issuer", NULL),
+ g_memdup (issuer->pValue, issuer->ulValueLen),
+ issuer->ulValueLen, g_free);
+
+ trust = g_object_new (GKM_XDG_TYPE_TRUST, "module", module, "manager", manager, NULL);
+ trust->pv->asn = asn;
+
+ return trust;
+}
+
+static GkmXdgTrust*
+create_trust_for_certificate (GkmModule *module, GkmManager *manager,
+ CK_ATTRIBUTE_PTR cert)
+{
+ GkmXdgTrust *trust;
+ GNode *asn;
+
+ asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
+ g_return_val_if_fail (asn, NULL);
+
+ egg_asn1x_set_raw_element (egg_asn1x_node (asn, "reference", "certComplete", NULL),
+ g_memdup (cert->pValue, cert->ulValueLen),
+ cert->ulValueLen, g_free);
+
+ trust = g_object_new (GKM_XDG_TYPE_TRUST, "module", module, "manager", manager, NULL);
+ trust->pv->asn = asn;
+
+ return trust;
+}
+
/* -----------------------------------------------------------------------------
* OBJECT
*/
@@ -475,41 +482,25 @@ gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_
case CKA_CLASS:
return gkm_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST);
case CKA_MODIFIABLE:
- return gkm_attribute_set_bool (attr, CK_TRUE);
-
- /* Key restrictions */
- case CKA_TRUST_DIGITAL_SIGNATURE:
- return trust_get_usage (self, OID_USAGE_DIGITAL_SIGNATURE, attr);
- case CKA_TRUST_NON_REPUDIATION:
- return trust_get_usage (self, OID_USAGE_NON_REPUDIATION, attr);
- case CKA_TRUST_KEY_ENCIPHERMENT:
- return trust_get_usage (self, OID_USAGE_KEY_ENCIPHERMENT, attr);
- case CKA_TRUST_DATA_ENCIPHERMENT:
- return trust_get_usage (self, OID_USAGE_DATA_ENCIPHERMENT, attr);
- case CKA_TRUST_KEY_AGREEMENT:
- return trust_get_usage (self, OID_USAGE_KEY_AGREEMENT, attr);
- case CKA_TRUST_KEY_CERT_SIGN:
- return trust_get_usage (self, OID_USAGE_KEY_CERT_SIGN, attr);
- case CKA_TRUST_CRL_SIGN:
- return trust_get_usage (self, OID_USAGE_CRL_SIGN, attr);
+ return gkm_attribute_set_bool (attr, CK_FALSE);
/* Various trust flags */
case CKA_TRUST_SERVER_AUTH:
- return trust_get_usage (self, OID_PURPOSE_SERVER_AUTH, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.server_auth);
case CKA_TRUST_CLIENT_AUTH:
- return trust_get_usage (self, OID_PURPOSE_CLIENT_AUTH, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.client_auth);
case CKA_TRUST_CODE_SIGNING:
- return trust_get_usage (self, OID_PURPOSE_CODE_SIGNING, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.code_signing);
case CKA_TRUST_EMAIL_PROTECTION:
- return trust_get_usage (self, OID_PURPOSE_EMAIL, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.email_protection);
case CKA_TRUST_IPSEC_END_SYSTEM:
- return trust_get_usage (self, OID_PURPOSE_IPSEC_ENDPOINT, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.ipsec_end_system);
case CKA_TRUST_IPSEC_TUNNEL:
- return trust_get_usage (self, OID_PURPOSE_IPSEC_TUNNEL, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.ipsec_tunnel);
case CKA_TRUST_IPSEC_USER:
- return trust_get_usage (self, OID_PURPOSE_IPSEC_USER, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.ipsec_user);
case CKA_TRUST_TIME_STAMPING:
- return trust_get_usage (self, OID_PURPOSE_TIME_STAMPING, attr);
+ return gkm_attribute_set_ulong (attr, self->pv->netscape.time_stamping);
/* Certificate reference values */
case CKA_SUBJECT:
@@ -521,9 +512,9 @@ gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_
/* Certificate hash values */
case CKA_CERT_MD5_HASH:
- return trust_get_hash (self, OID_HASH_MD5, attr);
+ return trust_get_hash (self, G_CHECKSUM_MD5, attr);
case CKA_CERT_SHA1_HASH:
- return trust_get_hash (self, OID_HASH_SHA1, attr);
+ return trust_get_hash (self, G_CHECKSUM_SHA1, attr);
default:
break;
@@ -533,90 +524,10 @@ gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_
}
static void
-gkm_xdg_trust_set_attribute (GkmObject *base, GkmSession *session,
- GkmTransaction* transaction, CK_ATTRIBUTE* attr)
-{
- GkmXdgTrust *self = GKM_XDG_TRUST (base);
- CK_ULONG value;
- GQuark oid = 0;
- CK_RV rv;
-
- switch (attr->type)
- {
-
- /* Key restrictions */
- case CKA_TRUST_DIGITAL_SIGNATURE:
- oid = OID_USAGE_DIGITAL_SIGNATURE;
- break;
- case CKA_TRUST_NON_REPUDIATION:
- oid = OID_USAGE_NON_REPUDIATION;
- break;
- case CKA_TRUST_KEY_ENCIPHERMENT:
- oid = OID_USAGE_KEY_ENCIPHERMENT;
- break;
- case CKA_TRUST_DATA_ENCIPHERMENT:
- oid = OID_USAGE_DATA_ENCIPHERMENT;
- break;
- case CKA_TRUST_KEY_AGREEMENT:
- oid = OID_USAGE_KEY_AGREEMENT;
- break;
- case CKA_TRUST_KEY_CERT_SIGN:
- oid = OID_USAGE_KEY_CERT_SIGN;
- break;
- case CKA_TRUST_CRL_SIGN:
- oid = OID_USAGE_CRL_SIGN;
- break;
-
- /* Various trust flags */
- case CKA_TRUST_SERVER_AUTH:
- oid = OID_PURPOSE_SERVER_AUTH;
- break;
- case CKA_TRUST_CLIENT_AUTH:
- oid = OID_PURPOSE_CLIENT_AUTH;
- break;
- case CKA_TRUST_CODE_SIGNING:
- oid = OID_PURPOSE_CODE_SIGNING;
- break;
- case CKA_TRUST_EMAIL_PROTECTION:
- oid = OID_PURPOSE_EMAIL;
- break;
- case CKA_TRUST_IPSEC_END_SYSTEM:
- oid = OID_PURPOSE_IPSEC_ENDPOINT;
- break;
- case CKA_TRUST_IPSEC_TUNNEL:
- oid = OID_PURPOSE_IPSEC_TUNNEL;
- break;
- case CKA_TRUST_IPSEC_USER:
- oid = OID_PURPOSE_IPSEC_USER;
- break;
- case CKA_TRUST_TIME_STAMPING:
- oid = OID_PURPOSE_TIME_STAMPING;
- break;
-
- default:
- break;
- };
-
- if (oid != 0) {
- rv = gkm_attribute_get_ulong (attr, &value);
- if (rv != CKR_OK)
- gkm_transaction_fail (transaction, rv);
- else if (trust_ulong_to_level_enum (value) < 0)
- gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
- else
- g_hash_table_replace (self->pv->pairs, GUINT_TO_POINTER (oid),
- gkm_util_ulong_alloc (value));
- return;
- }
-
- GKM_OBJECT_CLASS (gkm_xdg_trust_parent_class)->set_attribute (base, session, transaction, attr);
-}
-
-static void
gkm_xdg_trust_init (GkmXdgTrust *self)
{
self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GKM_XDG_TYPE_TRUST, GkmXdgTrustPrivate);
- self->pv->pairs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, gkm_util_ulong_free);
+ self->pv->assertions = create_assertions ();
}
static void
@@ -628,9 +539,9 @@ gkm_xdg_trust_finalize (GObject *obj)
egg_asn1x_destroy (self->pv->asn);
self->pv->asn = NULL;
- if (self->pv->pairs)
- g_hash_table_destroy (self->pv->pairs);
- self->pv->pairs = NULL;
+ if (self->pv->assertions)
+ g_hash_table_destroy (self->pv->assertions);
+ self->pv->assertions = NULL;
G_OBJECT_CLASS (gkm_xdg_trust_parent_class)->finalize (obj);
}
@@ -643,7 +554,6 @@ gkm_xdg_trust_class_init (GkmXdgTrustClass *klass)
gobject_class->finalize = gkm_xdg_trust_finalize;
gkm_class->get_attribute = gkm_xdg_trust_get_attribute;
- gkm_class->set_attribute = gkm_xdg_trust_set_attribute;
g_type_class_add_private (klass, sizeof (GkmXdgTrustPrivate));
@@ -673,7 +583,7 @@ gkm_xdg_trust_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer
}
/* Next parse out all the pairs */
- if (!load_trust_pairs (self->pv->pairs, asn)) {
+ if (!load_assertions (self, asn)) {
egg_asn1x_destroy (asn);
g_free (copy);
return FALSE;
@@ -699,7 +609,7 @@ gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data
g_return_val_if_fail (n_data, FALSE);
g_return_val_if_fail (self->pv->asn, FALSE);
- if (!save_trust_pairs (self->pv->pairs, self->pv->asn))
+ if (!save_assertions (self, self->pv->asn))
return FALSE;
*data = egg_asn1x_encode (self->pv->asn, NULL, n_data);
@@ -730,22 +640,57 @@ gkm_xdg_trust_serializable (GkmSerializableIface *iface)
* PUBLIC
*/
-
-GkmFactory*
-gkm_xdg_trust_get_factory (void)
+GkmTrust*
+gkm_xdg_trust_create_for_assertion (GkmModule *module, GkmManager *manager,
+ GkmTransaction *transaction,
+ CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
{
- static CK_OBJECT_CLASS klass = CKO_NETSCAPE_TRUST;
- static CK_ATTRIBUTE attributes[] = {
- { CKA_CLASS, &klass, sizeof (klass) },
- };
+ CK_ATTRIBUTE_PTR serial, issuer, cert;
+ GkmXdgTrust *trust;
- static GkmFactory factory = {
- attributes,
- G_N_ELEMENTS (attributes),
- factory_create_trust
- };
+ g_return_val_if_fail (GKM_IS_MODULE (module), NULL);
+ g_return_val_if_fail (GKM_IS_MANAGER (manager), NULL);
+ g_return_val_if_fail (attrs || !n_attrs, NULL);
- init_quarks ();
- return &factory;
+ serial = gkm_attributes_find (attrs, n_attrs, CKA_SERIAL_NUMBER);
+ issuer = gkm_attributes_find (attrs, n_attrs, CKA_ISSUER);
+ cert = gkm_attributes_find (attrs, n_attrs, CKA_G_CERTIFICATE_VALUE);
+
+ /* A trust object with just serial + issuer */
+ if (serial != NULL && issuer != NULL) {
+ if (cert != NULL) {
+ gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
+ return NULL;
+ }
+ if (!validate_der (issuer, "Name") || !validate_integer (serial)) {
+ gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
+ return NULL;
+ }
+
+ trust = create_trust_for_reference (module, manager, serial, issuer);
+
+ /* A trust object with a full certificate */
+ } else if (cert != NULL) {
+ if (serial != NULL || issuer != NULL) {
+ gkm_transaction_fail (transaction, CKR_TEMPLATE_INCONSISTENT);
+ return NULL;
+ }
+ if (!validate_der (cert, "TBSCertificate")) {
+ gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
+ return NULL;
+ }
+
+ trust = create_trust_for_certificate (module, manager, cert);
+
+ /* Not sure what this is */
+ } else {
+ gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
+ return NULL;
+ }
+
+ gkm_attributes_consume (attrs, n_attrs, CKA_G_CERTIFICATE_VALUE, CKA_ISSUER,
+ CKA_SERIAL_NUMBER, G_MAXULONG);
+
+ return GKM_TRUST (trust);
}
diff --git a/pkcs11/xdg-store/gkm-xdg-trust.h b/pkcs11/xdg-store/gkm-xdg-trust.h
index 2780d2e..2e22218 100644
--- a/pkcs11/xdg-store/gkm-xdg-trust.h
+++ b/pkcs11/xdg-store/gkm-xdg-trust.h
@@ -25,6 +25,7 @@
#include <glib-object.h>
#include "gkm/gkm-object.h"
+#include "gkm/gkm-trust.h"
#define GKM_XDG_FACTORY_TRUST (gkm_xdg_trust_get_factory ())
#define GKM_XDG_TYPE_TRUST (gkm_xdg_trust_get_type ())
@@ -39,16 +40,24 @@ typedef struct _GkmXdgTrustClass GkmXdgTrustClass;
typedef struct _GkmXdgTrustPrivate GkmXdgTrustPrivate;
struct _GkmXdgTrust {
- GkmObject parent;
+ GkmTrust parent;
GkmXdgTrustPrivate *pv;
};
struct _GkmXdgTrustClass {
- GkmObjectClass parent_class;
+ GkmTrustClass parent_class;
};
GType gkm_xdg_trust_get_type (void);
-GkmFactory* gkm_xdg_trust_get_factory (void);
+GkmTrust* gkm_xdg_trust_create_for_assertion (GkmModule *module,
+ GkmManager *manager,
+ GkmTransaction *transaction,
+ CK_ATTRIBUTE_PTR attrs,
+ CK_ULONG n_attrs);
+
+GkmAssertion* gkm_xdg_trust_add_assertion (GkmTrust *trust,
+ GkmTrustLevel level,
+ const char *purpose);
#endif /* __GKM_XDG_TRUST_H__ */
diff --git a/pkcs11/xdg-store/xdg.asn b/pkcs11/xdg-store/xdg.asn
index 8358a25..bb7ccf8 100644
--- a/pkcs11/xdg-store/xdg.asn
+++ b/pkcs11/xdg-store/xdg.asn
@@ -6,42 +6,43 @@ BEGIN
-- This file contains definitions for keyring
-TrustDigest ::= SEQUENCE {
- algorithm OBJECT IDENTIFIER,
- digest OCTET STRING
-}
-
-TrustDigests ::= SEQUENCE OF TrustDigest
-
TrustLevel ::= ENUMERATED {
- trustUnknown (0),
+ unknown (0),
untrusted (1),
- mustVerify (2),
trusted (3),
- trustedDelegator (4)
+ trustedAnchor (4)
}
-TrustPair ::= SEQUENCE {
+TrustAssertion ::= SEQUENCE {
purpose OBJECT IDENTIFIER,
- level TrustLevel
+ level TrustLevel,
+ with OCTET STRING,
+
+ additions SEQUENCE OF ANY
}
-TrustPairs ::= SEQUENCE OF TrustPair
+TrustAssertions ::= SEQUENCE OF TrustAssertion
CertReference ::= SEQUENCE {
serialNumber INTEGER,
issuer ANY,
subject ANY OPTIONAL,
- digests TrustDigests OPTIONAL
+
+ additions SEQUENCE OF ANY
}
TrustReference ::= CHOICE {
- certReference CertReference
+ certReference [0] CertReference,
+ certComplete [1] ANY,
+
+ additions [2] ANY
}
trust-1 ::= SEQUENCE {
reference TrustReference,
- trusts TrustPairs
+ assertions TrustAssertions,
+
+ additions SEQUENCE OF ANY
}
END
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]