diff options
author | Stef Walter <stef@memberwebs.com> | 2010-09-18 17:17:41 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2010-09-18 17:26:03 +0000 |
commit | 95cd2d8d183b2d16a5875c1b8b43b2ab26f1e1ed (patch) | |
tree | f8fedc6d7420683f9a9c6ff7f859487e924dcc3d /pkcs11/xdg-store | |
parent | a92fbf55ebb629c173f6fb1958c3f0de275542f8 (diff) |
[xdg-store] Initial xdg-store with trust storage.
Initial xdg-store implementation. Only trust storage is implemented.
xdg-store stores objects in the .local directory.
Diffstat (limited to 'pkcs11/xdg-store')
-rw-r--r-- | pkcs11/xdg-store/Makefile.am | 61 | ||||
-rw-r--r-- | pkcs11/xdg-store/asn1-def-xdg.c | 37 | ||||
-rw-r--r-- | pkcs11/xdg-store/gkm-xdg-module.c | 305 | ||||
-rw-r--r-- | pkcs11/xdg-store/gkm-xdg-module.h | 45 | ||||
-rw-r--r-- | pkcs11/xdg-store/gkm-xdg-standalone.c | 51 | ||||
-rw-r--r-- | pkcs11/xdg-store/gkm-xdg-store.h | 29 | ||||
-rw-r--r-- | pkcs11/xdg-store/gkm-xdg-trust.c | 740 | ||||
-rw-r--r-- | pkcs11/xdg-store/gkm-xdg-trust.h | 54 | ||||
-rw-r--r-- | pkcs11/xdg-store/tests/Makefile.am | 2 | ||||
-rw-r--r-- | pkcs11/xdg-store/tests/p11-tests.conf | 2 | ||||
-rw-r--r-- | pkcs11/xdg-store/xdg.asn | 47 |
11 files changed, 1373 insertions, 0 deletions
diff --git a/pkcs11/xdg-store/Makefile.am b/pkcs11/xdg-store/Makefile.am new file mode 100644 index 00000000..dfa5f3c0 --- /dev/null +++ b/pkcs11/xdg-store/Makefile.am @@ -0,0 +1,61 @@ + +INCLUDES = \ + -I$(top_builddir) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/pkcs11 \ + $(GOBJECT_CFLAGS) \ + $(LIBGCRYPT_CFLAGS) \ + $(GLIB_CFLAGS) + + +# ------------------------------------------------------------------------------ +# The xdg-store component code + +noinst_LTLIBRARIES = \ + libgkm-xdg-store.la + +BUILT_SOURCES = \ + asn1-def-xdg.c + +libgkm_xdg_store_la_SOURCES = \ + gkm-xdg-store.h \ + gkm-xdg-module.c gkm-xdg-module.h \ + gkm-xdg-trust.c gkm-xdg-trust.h \ + $(BUILT_SOURCES) + +asn1-def-xdg.c: xdg.asn + $(ASN1PARSER) -o asn1-def-xdg.c $(srcdir)/xdg.asn + +# ------------------------------------------------------------------------------ +# The standalone module + +moduledir = $(libdir)/gnome-keyring/devel/ + +module_LTLIBRARIES = \ + gkm-xdg-store-standalone.la + +gkm_xdg_store_standalone_la_LDFLAGS = \ + -module -avoid-version \ + -no-undefined -export-symbols-regex 'C_GetFunctionList' + +gkm_xdg_store_standalone_la_SOURCES = \ + gkm-xdg-standalone.c + +gkm_xdg_store_standalone_la_LIBADD = \ + libgkm-xdg-store.la \ + $(top_builddir)/pkcs11/gkm/libgkm.la \ + $(GOBJECT_LIBS) \ + $(GTHREAD_LIBS) \ + $(GLIB_LIBS) \ + $(LIBGCRYPT_LIBS) + + +# ------------------------------------------------------------------------------- + +if WITH_TESTS +TESTS_DIR = tests +else +TESTS_DIR = +endif + +SUBDIRS = . $(TESTS_DIR) diff --git a/pkcs11/xdg-store/asn1-def-xdg.c b/pkcs11/xdg-store/asn1-def-xdg.c new file mode 100644 index 00000000..1d608be6 --- /dev/null +++ b/pkcs11/xdg-store/asn1-def-xdg.c @@ -0,0 +1,37 @@ +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <libtasn1.h> + +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"}, + { "untrustedUsage", 1073741825, "1"}, + { "mustVerify", 1073741825, "2"}, + { "trustedUsage", 1073741825, "3"}, + { "trustedDelegator", 1, "4"}, + { "TrustPair", 1610612741, NULL }, + { "purpose", 1073741836, NULL }, + { "level", 2, "TrustLevel"}, + { "TrustPairs", 1610612747, NULL }, + { NULL, 2, "TrustPair"}, + { "CertReference", 1610612741, NULL }, + { "serialNumber", 1073741827, NULL }, + { "issuer", 1073741837, NULL }, + { "subject", 1073758221, NULL }, + { "digests", 2, "TrustDigests"}, + { "TrustReference", 1610612754, NULL }, + { "certReference", 2, "CertReference"}, + { "trust-1", 536870917, NULL }, + { "reference", 1073741826, "TrustReference"}, + { "trusts", 2, "TrustPairs"}, + { NULL, 0, NULL } +}; diff --git a/pkcs11/xdg-store/gkm-xdg-module.c b/pkcs11/xdg-store/gkm-xdg-module.c new file mode 100644 index 00000000..1e7d81dc --- /dev/null +++ b/pkcs11/xdg-store/gkm-xdg-module.c @@ -0,0 +1,305 @@ +/* + * 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-module.h" +#include "gkm-xdg-store.h" +#include "gkm-xdg-trust.h" + +#include "egg/egg-error.h" + +#include "gkm/gkm-file-tracker.h" +#include "gkm/gkm-serializable.h" +#include "gkm/gkm-util.h" + +#include <string.h> + +struct _GkmXdgModule { + GkmModule parent; + gchar *directory; + GHashTable *objects_by_path; + GkmFileTracker *tracker; + CK_TOKEN_INFO token_info; +}; + +static const CK_SLOT_INFO user_module_slot_info = { + "User Key Storage", + "Gnome Keyring", + CKF_TOKEN_PRESENT, + { 0, 0 }, + { 0, 0 } +}; + +static const CK_TOKEN_INFO user_module_token_info = { + "User Key Storage", + "Gnome Keyring", + "1.0", + "1:XDG:DEFAULT", /* Unique serial number for manufacturer */ + CKF_TOKEN_INITIALIZED, + CK_EFFECTIVELY_INFINITE, + CK_EFFECTIVELY_INFINITE, + CK_EFFECTIVELY_INFINITE, + CK_EFFECTIVELY_INFINITE, + 1024, + 1, + CK_UNAVAILABLE_INFORMATION, + CK_UNAVAILABLE_INFORMATION, + CK_UNAVAILABLE_INFORMATION, + CK_UNAVAILABLE_INFORMATION, + { 0, 0 }, + { 0, 0 }, + "" +}; + +#define UNUSED_VALUE (GUINT_TO_POINTER (1)) + +G_DEFINE_TYPE (GkmXdgModule, gkm_xdg_module, GKM_TYPE_MODULE); + +/* ----------------------------------------------------------------------------- + * ACTUAL PKCS#11 Module Implementation + */ + +/* Include all the module entry points */ +#include "gkm/gkm-module-ep.h" +GKM_DEFINE_MODULE (gkm_xdg_module, GKM_TYPE_XDG_MODULE); + +/* ----------------------------------------------------------------------------- + * INTERNAL + */ + +static GType +type_from_path (const gchar *path) +{ + const gchar *ext; + + ext = strrchr (path, '.'); + if (ext == NULL) + return 0; + + if (g_str_equal (ext, ".trust")) + return GKM_XDG_TYPE_TRUST; + +#if 0 + else if (strcmp (extension, ".pkcs8") == 0) + return GKM_TYPE_GNOME2_PRIVATE_KEY; + else if (strcmp (extension, ".pub") == 0) + return GKM_TYPE_GNOME2_PUBLIC_KEY; + else if (strcmp (extension, ".cer") == 0) + return GKM_TYPE_CERTIFICATE; +#endif + + return 0; +} + +static void +file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self) +{ + GkmObject *object; + GkmManager *manager; + gboolean added = FALSE; + GError *error = NULL; + GType type; + guchar *data; + gsize n_data; + + g_return_if_fail (path); + g_return_if_fail (GKM_IS_XDG_MODULE (self)); + + manager = gkm_module_get_manager (GKM_MODULE (self)); + + /* Already have this object? */ + object = g_hash_table_lookup (self->objects_by_path, path); + if (object == NULL) { + + /* Figure out what type of object we're dealing with */ + type = type_from_path (path); + if (type == 0) { + g_warning ("don't know how to load file in key store: %s", path); + return; + } + + /* Create a new object for this identifier */ + object = g_object_new (type, + "module", GKM_MODULE (self), + "manager", manager, NULL); + g_return_if_fail (GKM_IS_SERIALIZABLE (object)); + g_return_if_fail (GKM_SERIALIZABLE_GET_INTERFACE (object)->extension); + + added = TRUE; + + } else { + g_object_ref (object); + } + + /* Read the file in */ + if (!g_file_get_contents (path, (gchar**)&data, &n_data, &error)) { + g_warning ("couldn't read file in key store: %s: %s", path, + egg_error_message (error)); + g_object_unref (object); + g_clear_error (&error); + return; + + /* And load the data into it */ + } else if (gkm_serializable_load (GKM_SERIALIZABLE (object), NULL, data, n_data)) { + if (added) + g_hash_table_insert (self->objects_by_path, g_strdup (path), g_object_ref (object)); + gkm_object_expose (object, TRUE); + + } else { + g_message ("failed to load file in user store: %s", path); + if (!added) + gkm_object_expose (object, FALSE); + } + + g_object_unref (object); +} + +static void +file_remove (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self) +{ + g_return_if_fail (path); + g_return_if_fail (GKM_IS_XDG_MODULE (self)); + g_hash_table_remove (self->objects_by_path, path); +} + +/* ----------------------------------------------------------------------------- + * OBJECT + */ + +static const CK_SLOT_INFO* +gkm_xdg_module_real_get_slot_info (GkmModule *base) +{ + return &user_module_slot_info; +} + +static const CK_TOKEN_INFO* +gkm_xdg_module_real_get_token_info (GkmModule *base) +{ + GkmXdgModule *self = GKM_XDG_MODULE (base); + + /* TODO: Update the info with current info */ + return &self->token_info; +} + +static void +gkm_xdg_module_real_parse_argument (GkmModule *base, const gchar *name, const gchar *value) +{ + GkmXdgModule *self = GKM_XDG_MODULE (base); + if (g_str_equal (name, "directory")) { + g_free (self->directory); + self->directory = g_strdup (value); + } +} + +static CK_RV +gkm_xdg_module_real_refresh_token (GkmModule *base) +{ + GkmXdgModule *self = GKM_XDG_MODULE (base); + gkm_file_tracker_refresh (self->tracker, FALSE); + return CKR_OK; +} + +static GObject* +gkm_xdg_module_constructor (GType type, guint n_props, GObjectConstructParam *props) +{ + GkmXdgModule *self = GKM_XDG_MODULE (G_OBJECT_CLASS (gkm_xdg_module_parent_class)->constructor(type, n_props, props)); + g_return_val_if_fail (self, NULL); + + if (!self->directory) + self->directory = g_build_filename (g_get_user_data_dir (), "keystore", NULL); + + self->tracker = gkm_file_tracker_new (self->directory, "*.*", NULL); + g_signal_connect (self->tracker, "file-added", G_CALLBACK (file_load), self); + g_signal_connect (self->tracker, "file-changed", G_CALLBACK (file_load), self); + g_signal_connect (self->tracker, "file-removed", G_CALLBACK (file_remove), self); + + return G_OBJECT (self); +} + +static void +gkm_xdg_module_init (GkmXdgModule *self) +{ + self->objects_by_path = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + /* 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); +} + +static void +gkm_xdg_module_dispose (GObject *obj) +{ + GkmXdgModule *self = GKM_XDG_MODULE (obj); + + if (self->tracker) + g_object_unref (self->tracker); + self->tracker = NULL; + + g_hash_table_remove_all (self->objects_by_path); + + G_OBJECT_CLASS (gkm_xdg_module_parent_class)->dispose (obj); +} + +static void +gkm_xdg_module_finalize (GObject *obj) +{ + GkmXdgModule *self = GKM_XDG_MODULE (obj); + + g_assert (self->tracker == NULL); + + g_hash_table_destroy (self->objects_by_path); + self->objects_by_path = NULL; + + g_free (self->directory); + self->directory = NULL; + + G_OBJECT_CLASS (gkm_xdg_module_parent_class)->finalize (obj); +} + +static void +gkm_xdg_module_class_init (GkmXdgModuleClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GkmModuleClass *module_class = GKM_MODULE_CLASS (klass); + + gobject_class->constructor = gkm_xdg_module_constructor; + gobject_class->dispose = gkm_xdg_module_dispose; + gobject_class->finalize = gkm_xdg_module_finalize; + + module_class->get_slot_info = gkm_xdg_module_real_get_slot_info; + module_class->get_token_info = gkm_xdg_module_real_get_token_info; + module_class->parse_argument = gkm_xdg_module_real_parse_argument; + module_class->refresh_token = gkm_xdg_module_real_refresh_token; +} + +/* ---------------------------------------------------------------------------- + * PUBLIC + */ + +CK_FUNCTION_LIST_PTR +gkm_xdg_store_get_functions (void) +{ + gkm_crypto_initialize (); + return gkm_xdg_module_function_list; +} diff --git a/pkcs11/xdg-store/gkm-xdg-module.h b/pkcs11/xdg-store/gkm-xdg-module.h new file mode 100644 index 00000000..755fa6f2 --- /dev/null +++ b/pkcs11/xdg-store/gkm-xdg-module.h @@ -0,0 +1,45 @@ +/* + * 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_MODULE_H__ +#define __GKM_XDG_MODULE_H__ + +#include <glib-object.h> + +#include "gkm/gkm-module.h" + +#define GKM_TYPE_XDG_MODULE (gkm_xdg_module_get_type ()) +#define GKM_XDG_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_TYPE_XDG_MODULE, GkmXdgModule)) +#define GKM_XDG_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_TYPE_XDG_MODULE, GkmXdgModuleClass)) +#define GKM_IS_XDG_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_TYPE_XDG_MODULE)) +#define GKM_IS_XDG_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_TYPE_XDG_MODULE)) +#define GKM_XDG_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_TYPE_XDG_MODULE, GkmXdgModuleClass)) + +typedef struct _GkmXdgModule GkmXdgModule; +typedef struct _GkmXdgModuleClass GkmXdgModuleClass; + +struct _GkmXdgModuleClass { + GkmModuleClass parent_class; +}; + +GType gkm_xdg_module_get_type (void); + +#endif /* __GKM_XDG_MODULE_H__ */ diff --git a/pkcs11/xdg-store/gkm-xdg-standalone.c b/pkcs11/xdg-store/gkm-xdg-standalone.c new file mode 100644 index 00000000..a539938c --- /dev/null +++ b/pkcs11/xdg-store/gkm-xdg-standalone.c @@ -0,0 +1,51 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* gkm-gnome2-standalone.h - The user-store PKCS#11 code as a standalone module + + Copyright (C) 2008, Stef Walter + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Stef Walter <stef@memberwebs.com> +*/ + +#include "config.h" + +#include "gkm-xdg-store.h" + +#include "gkm/gkm-crypto.h" + +#include "egg/egg-secure-memory.h" + +#include "pkcs11/pkcs11.h" + +#include <glib-object.h> + +/* Module callbacks for secure memory */ +EGG_SECURE_GLIB_DEFINITIONS (); + +CK_RV +C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) +{ + if (!list) + return CKR_ARGUMENTS_BAD; + + g_type_init (); + if (!g_thread_supported ()) + g_thread_init (NULL); + + *list = gkm_xdg_store_get_functions (); + return CKR_OK; +} diff --git a/pkcs11/xdg-store/gkm-xdg-store.h b/pkcs11/xdg-store/gkm-xdg-store.h new file mode 100644 index 00000000..7943a9c2 --- /dev/null +++ b/pkcs11/xdg-store/gkm-xdg-store.h @@ -0,0 +1,29 @@ +/* + * 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_STORE_H__ +#define __GKM_XDG_STORE_H__ + +#include "pkcs11/pkcs11.h" + +CK_FUNCTION_LIST_PTR gkm_xdg_store_get_functions (void); + +#endif /* __GKM_XDG_STORE_H__ */ diff --git a/pkcs11/xdg-store/gkm-xdg-trust.c b/pkcs11/xdg-store/gkm-xdg-trust.c new file mode 100644 index 00000000..89235d1c --- /dev/null +++ b/pkcs11/xdg-store/gkm-xdg-trust.c @@ -0,0 +1,740 @@ +/* + * 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.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 _GkmXdgTrustPrivate { + GNode *asn; + GHashTable *pairs; + gpointer data; + gsize n_data; +}; + +/* From asn1-def-xdg.c */ +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_XDG_TYPE_TRUST, 0, + G_IMPLEMENT_INTERFACE (GKM_TYPE_SERIALIZABLE, gkm_xdg_trust_serializable)); + +enum { + TRUST_UNKNOWN = 0, + TRUST_UNTRUSTED = 1, + TRUST_MUST_VERIFY = 2, + TRUST_TRUSTED = 3, + TRUST_TRUSTED_DELEGATOR = 4 +}; + +/* ----------------------------------------------------------------------------- + * 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 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_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"); + + #undef QUARK + + g_once_init_leave (&quarks_inited, 1); + } +} + +/* ----------------------------------------------------------------------------- + * 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) +{ + GNode *node; + gconstpointer element; + gsize n_element; + + 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, part, NULL); + if (node == NULL) + return CKR_ATTRIBUTE_TYPE_INVALID; + + element = egg_asn1x_get_raw_element (node, &n_element); + return gkm_attribute_set_data (attr, element, n_element); +} + +static CK_RV +trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr) +{ + GNode *node; + gpointer integer; + gsize n_integer; + CK_RV rv; + + g_assert (GKM_XDG_IS_TRUST (self)); + + node = egg_asn1x_node (self->pv->asn, "reference", "certReference", NULL); + g_return_val_if_fail (node, CKR_GENERAL_ERROR); + + node = egg_asn1x_node (self->pv->asn, part, NULL); + if (node == NULL) + return CKR_ATTRIBUTE_TYPE_INVALID; + + integer = egg_asn1x_get_integer_as_raw (node, NULL, &n_integer); + rv = gkm_attribute_set_data (attr, integer, n_integer); + g_free (integer); + + return rv; +} + +static CK_RV +trust_get_hash (GkmXdgTrust *self, GQuark oid, CK_ATTRIBUTE_PTR attr) +{ + CK_RV rv = CKR_ATTRIBUTE_VALUE_INVALID; + GNode *digests, *digest; + gpointer hash; + gsize n_hash; + guint count, i; + GQuark check; + + digests = egg_asn1x_node (self->pv->asn, "reference", "certReference", "digests", NULL); + g_return_val_if_fail (digests, CKR_GENERAL_ERROR); + + 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; + } + } + + return rv; +} + +static gboolean +validate_der (CK_ATTRIBUTE_PTR attr) +{ + return attr->pValue != NULL && + attr->ulValueLen != (CK_ULONG)-1 && + egg_asn1x_element_length (attr->pValue, attr->ulValueLen) >= 0; +} + +static gboolean +validate_integer (CK_ATTRIBUTE_PTR attr) +{ + return attr->pValue != NULL && + attr->ulValueLen > 0 && + 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 gint +trust_ulong_to_level_enum (CK_ULONG trust) +{ + switch (trust) { + case CKT_NETSCAPE_TRUST_UNKNOWN: + return TRUST_UNKNOWN; + case CKT_NETSCAPE_UNTRUSTED: + return TRUST_UNTRUSTED; + case CKT_NETSCAPE_TRUSTED_DELEGATOR: + return TRUST_TRUSTED_DELEGATOR; + case CKT_NETSCAPE_TRUSTED: + return TRUST_TRUSTED; + case CKT_NETSCAPE_MUST_VERIFY: + return TRUST_MUST_VERIFY; + default: + return -1; + }; +} + +static CK_ULONG +level_enum_to_trust_ulong (guint level) +{ + switch (level) { + case TRUST_UNKNOWN: + return CKT_NETSCAPE_TRUST_UNKNOWN; + case TRUST_UNTRUSTED: + return CKT_NETSCAPE_UNTRUSTED; + case TRUST_TRUSTED_DELEGATOR: + return CKT_NETSCAPE_TRUSTED_DELEGATOR; + case TRUST_TRUSTED: + return CKT_NETSCAPE_TRUSTED; + case TRUST_MUST_VERIFY: + return CKT_NETSCAPE_MUST_VERIFY; + default: + return (CK_ULONG)-1; + }; +} + +static GkmObject* +factory_create_trust (GkmSession *session, GkmTransaction *transaction, + CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs) +{ + GkmXdgTrust *trust; + CK_ATTRIBUTE_PTR serial, issuer, subject; + CK_ATTRIBUTE_PTR md5, sha1; + GNode *asn; + + g_return_val_if_fail (attrs || !n_attrs, NULL); + + 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 (serial == NULL || issuer == NULL) { + gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE); + return NULL; + } + + if (!validate_der (issuer) || (subject && !validate_der (subject))) { + gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID); + return NULL; + } + + if (!validate_integer (serial)) { + gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID); + return NULL; + } + + md5 = gkm_attributes_find (attrs, n_attrs, CKA_CERT_MD5_HASH); + sha1 = gkm_attributes_find (attrs, n_attrs, CKA_CERT_SHA1_HASH); + + if ((md5 && !validate_hash (md5, G_CHECKSUM_MD5)) || + (sha1 && !validate_hash (sha1, G_CHECKSUM_SHA1))) { + gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID); + return NULL; + } + + 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", "serial", 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", "issuer", NULL), + g_memdup (subject->pValue, issuer->ulValueLen), + issuer->ulValueLen, g_free); + + if (md5) + append_reference_hash (asn, OID_HASH_MD5, md5); + if (sha1) + append_reference_hash (asn, OID_HASH_SHA1, sha1); + + 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; + + gkm_attributes_consume (attrs, n_attrs, CKA_CERT_MD5_HASH, CKA_CERT_SHA1_HASH, + CKA_SUBJECT, CKA_ISSUER, CKA_SERIAL_NUMBER, G_MAXULONG); + + gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (trust), + TRUE, attrs, n_attrs); + return GKM_OBJECT (trust); +} + +static gboolean +load_trust_pairs (GHashTable *pairs, GNode *asn) +{ + GNode *pair; + guint count, i; + gulong level; + gulong trust; + GQuark oid; + + g_assert (pairs); + g_assert (asn); + + g_hash_table_remove_all (pairs); + + count = egg_asn1x_count (egg_asn1x_node (asn, "trusts", NULL)); + + for (i = 0; i < count; ++i) { + pair = egg_asn1x_node (asn, "trusts", i + 1, NULL); + g_return_val_if_fail (pair, FALSE); + + /* Get the usage */ + if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (pair, "level", NULL), &level)) + g_return_val_if_reached (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; + } + + /* A key usage */ + oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (pair, "purpose", NULL)); + g_return_val_if_fail (oid, FALSE); + + g_hash_table_replace (pairs, GUINT_TO_POINTER (oid), + gkm_util_ulong_alloc (trust)); + } + + return TRUE; +} + +static gboolean +save_trust_pairs (GHashTable *pairs, GNode *asn) +{ + GHashTableIter iter; + GNode *pair, *node; + gpointer key, value; + gulong level; + GQuark oid; + + g_assert (pairs); + 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)); + + 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_integer_as_ulong (egg_asn1x_node (pair, "level", NULL), level); + } + + return TRUE; +} +/* ----------------------------------------------------------------------------- + * OBJECT + */ + +static CK_RV +gkm_xdg_trust_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr) +{ + GkmXdgTrust *self = GKM_XDG_TRUST (base); + + 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); + + /* 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); + + /* Various trust flags */ + case CKA_TRUST_SERVER_AUTH: + return trust_get_usage (self, OID_PURPOSE_SERVER_AUTH, attr); + case CKA_TRUST_CLIENT_AUTH: + return trust_get_usage (self, OID_PURPOSE_CLIENT_AUTH, attr); + case CKA_TRUST_CODE_SIGNING: + return trust_get_usage (self, OID_PURPOSE_CODE_SIGNING, attr); + case CKA_TRUST_EMAIL_PROTECTION: + return trust_get_usage (self, OID_PURPOSE_EMAIL, attr); + case CKA_TRUST_IPSEC_END_SYSTEM: + return trust_get_usage (self, OID_PURPOSE_IPSEC_ENDPOINT, attr); + case CKA_TRUST_IPSEC_TUNNEL: + return trust_get_usage (self, OID_PURPOSE_IPSEC_TUNNEL, attr); + case CKA_TRUST_IPSEC_USER: + return trust_get_usage (self, OID_PURPOSE_IPSEC_USER, attr); + case CKA_TRUST_TIME_STAMPING: + return trust_get_usage (self, OID_PURPOSE_TIME_STAMPING, attr); + + /* Certificate reference values */ + case CKA_SUBJECT: + return trust_get_der (self, "subject", attr); + case CKA_SERIAL_NUMBER: + return trust_get_der (self, "serialNumber", attr); + case CKA_ISSUER: + return trust_get_integer (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); + + default: + break; + }; + + return GKM_OBJECT_CLASS (gkm_xdg_trust_parent_class)->get_attribute (base, session, attr); +} + +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); +} + +static void +gkm_xdg_trust_finalize (GObject *obj) +{ + GkmXdgTrust *self = GKM_XDG_TRUST (obj); + + if (self->pv->asn) + 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; + + 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; + gkm_class->set_attribute = gkm_xdg_trust_set_attribute; + + g_type_class_add_private (klass, sizeof (GkmXdgTrustPrivate)); + + init_quarks (); +} + +static gboolean +gkm_xdg_trust_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data) +{ + GkmXdgTrust *self = GKM_XDG_TRUST (base); + GNode *asn = NULL; + gpointer copy; + + g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE); + g_return_val_if_fail (data, FALSE); + g_return_val_if_fail (n_data, FALSE); + + copy = g_memdup (data, n_data); + + asn = egg_asn1x_create_and_decode (xdg_asn1_tab, "trust-1", copy, n_data); + if (asn == NULL) { + g_warning ("couldn't parse trust data"); + g_free (copy); + return FALSE; + } + + /* Next parse out all the pairs */ + if (!load_trust_pairs (self->pv->pairs, asn)) { + egg_asn1x_destroy (asn); + g_free (copy); + return FALSE; + } + + /* Take ownership of this new data */ + g_free (self->pv->data); + self->pv->data = copy; + self->pv->n_data = n_data; + egg_asn1x_destroy (self->pv->asn); + self->pv->asn = asn; + + return TRUE; +} + +static gboolean +gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data) +{ + GkmXdgTrust *self = GKM_XDG_TRUST (base); + + g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE); + g_return_val_if_fail (data, FALSE); + g_return_val_if_fail (n_data, FALSE); + g_return_val_if_fail (self->pv->asn, FALSE); + + if (!save_trust_pairs (self->pv->pairs, self->pv->asn)) + return FALSE; + + *data = egg_asn1x_encode (self->pv->asn, NULL, n_data); + if (*data == NULL) { + g_warning ("encoding trust failed: %s", egg_asn1x_message (self->pv->asn)); + return FALSE; + } + + /* ASN.1 now refers to this data, take ownership */ + g_free (self->pv->data); + self->pv->data = *data; + self->pv->n_data = *n_data; + + /* Return a duplicate, since we own encoded */ + *data = g_memdup (*data, *n_data); + return TRUE; +} + +static void +gkm_xdg_trust_serializable (GkmSerializableIface *iface) +{ + iface->extension = ".trust"; + iface->load = gkm_xdg_trust_real_load; + iface->save = gkm_xdg_trust_real_save; +} + +/* ----------------------------------------------------------------------------- + * PUBLIC + */ + + +GkmFactory* +gkm_xdg_trust_get_factory (void) +{ + static CK_OBJECT_CLASS klass = CKO_NETSCAPE_TRUST; + + static CK_ATTRIBUTE attributes[] = { + { CKA_CLASS, &klass, sizeof (klass) }, + }; + + static GkmFactory factory = { + attributes, + G_N_ELEMENTS (attributes), + factory_create_trust + }; + + return &factory; +} diff --git a/pkcs11/xdg-store/gkm-xdg-trust.h b/pkcs11/xdg-store/gkm-xdg-trust.h new file mode 100644 index 00000000..2780d2e7 --- /dev/null +++ b/pkcs11/xdg-store/gkm-xdg-trust.h @@ -0,0 +1,54 @@ +/* + * 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_H__ +#define __GKM_XDG_TRUST_H__ + +#include <glib-object.h> + +#include "gkm/gkm-object.h" + +#define GKM_XDG_FACTORY_TRUST (gkm_xdg_trust_get_factory ()) +#define GKM_XDG_TYPE_TRUST (gkm_xdg_trust_get_type ()) +#define GKM_XDG_TRUST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKM_XDG_TYPE_TRUST, GkmXdgTrust)) +#define GKM_XDG_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GKM_XDG_TYPE_TRUST, GkmXdgTrustClass)) +#define GKM_XDG_IS_TRUST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GKM_XDG_TYPE_TRUST)) +#define GKM_XDG_IS_TRUST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GKM_XDG_TYPE_TRUST)) +#define GKM_XDG_TRUST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GKM_XDG_TYPE_TRUST, GkmXdgTrustClass)) + +typedef struct _GkmXdgTrust GkmXdgTrust; +typedef struct _GkmXdgTrustClass GkmXdgTrustClass; +typedef struct _GkmXdgTrustPrivate GkmXdgTrustPrivate; + +struct _GkmXdgTrust { + GkmObject parent; + GkmXdgTrustPrivate *pv; +}; + +struct _GkmXdgTrustClass { + GkmObjectClass parent_class; +}; + +GType gkm_xdg_trust_get_type (void); + +GkmFactory* gkm_xdg_trust_get_factory (void); + +#endif /* __GKM_XDG_TRUST_H__ */ diff --git a/pkcs11/xdg-store/tests/Makefile.am b/pkcs11/xdg-store/tests/Makefile.am new file mode 100644 index 00000000..7bf4e783 --- /dev/null +++ b/pkcs11/xdg-store/tests/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = \ + p11-tests.conf diff --git a/pkcs11/xdg-store/tests/p11-tests.conf b/pkcs11/xdg-store/tests/p11-tests.conf new file mode 100644 index 00000000..fda5f0dd --- /dev/null +++ b/pkcs11/xdg-store/tests/p11-tests.conf @@ -0,0 +1,2 @@ +# Configuration for running p11-tests on this module +init-string = directory='test-data' diff --git a/pkcs11/xdg-store/xdg.asn b/pkcs11/xdg-store/xdg.asn new file mode 100644 index 00000000..941a8e95 --- /dev/null +++ b/pkcs11/xdg-store/xdg.asn @@ -0,0 +1,47 @@ +XDG { } + +DEFINITIONS EXPLICIT TAGS ::= + +BEGIN + +-- This file contains definitions for keyring + +TrustDigest ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + digest OCTET STRING +} + +TrustDigests ::= SEQUENCE OF TrustDigest + +TrustLevel ::= ENUMERATED { + trustUnknown (0), + untrustedUsage (1), + mustVerify (2), + trustedUsage (3), + trustedDelegator (4) +} + +TrustPair ::= SEQUENCE { + purpose OBJECT IDENTIFIER, + level TrustLevel +} + +TrustPairs ::= SEQUENCE OF TrustPair + +CertReference ::= SEQUENCE { + serialNumber INTEGER, + issuer ANY, + subject ANY OPTIONAL, + digests TrustDigests +} + +TrustReference ::= CHOICE { + certReference CertReference +} + +trust-1 ::= SEQUENCE { + reference TrustReference, + trusts TrustPairs +} + +END |