gnome-keyring r1519 - in trunk: . pkcs11/gck pkcs11/roots-store



Author: nnielsen
Date: Sat Feb  7 23:23:52 2009
New Revision: 1519
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1519&view=rev

Log:
Implement netscape trust in roots-store.

so that we can have Root CA certificates trusted by NSS programs.

Added:
   trunk/pkcs11/gck/gck-certificate-trust.c
   trunk/pkcs11/gck/gck-certificate-trust.h
Modified:
   trunk/ChangeLog
   trunk/pkcs11/gck/Makefile.am
   trunk/pkcs11/gck/gck-certificate.c
   trunk/pkcs11/gck/gck-certificate.h
   trunk/pkcs11/gck/gck-types.h
   trunk/pkcs11/roots-store/gck-roots-certificate.c
   trunk/pkcs11/roots-store/gck-roots-certificate.h
   trunk/pkcs11/roots-store/gck-roots-module.c

Modified: trunk/pkcs11/gck/Makefile.am
==============================================================================
--- trunk/pkcs11/gck/Makefile.am	(original)
+++ trunk/pkcs11/gck/Makefile.am	Sat Feb  7 23:23:52 2009
@@ -20,6 +20,7 @@
 	gck-attributes.c gck-attributes.h \
 	gck-certificate.c gck-certificate.h \
 	gck-certificate-key.c gck-certificate-key.h \
+	gck-certificate-trust.c gck-certificate-trust.h \
 	gck-crypto.c gck-crypto.h \
 	gck-data-asn1.c gck-data-asn1.h \
 	gck-data-der.c gck-data-der.h \

Added: trunk/pkcs11/gck/gck-certificate-trust.c
==============================================================================
--- (empty file)
+++ trunk/pkcs11/gck/gck-certificate-trust.c	Sat Feb  7 23:23:52 2009
@@ -0,0 +1,374 @@
+/* 
+ * gnome-trustring
+ * 
+ * Copyright (C) 2008 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 "gck-attributes.h"
+#include "gck-certificate.h"
+#include "gck-certificate-trust.h"
+#include "gck-data-der.h"
+
+#include "gck-object.h"
+#include "gck-util.h"
+
+#include "pkcs11/pkcs11g.h"
+#include "pkcs11/pkcs11n.h"
+
+#include <glib/gi18n.h>
+
+enum {
+	PROP_0,
+	PROP_CERTIFICATE
+};
+
+struct _GckCertificateTrustPrivate {
+	GckCertificate *certificate;
+};
+
+G_DEFINE_TYPE (GckCertificateTrust, gck_certificate_trust, GCK_TYPE_OBJECT);
+
+#define PKIX_KEY_USAGE_DIGITAL_SIGNATURE 0x80
+#define PKIX_KEY_USAGE_NON_REPUDIATION 0x40
+#define PKIX_KEY_USAGE_KEY_ENCIPHERMENT 0x20
+#define PKIX_KEY_USAGE_DATA_ENCIPHERMENT 0x10
+#define PKIX_KEY_USAGE_KEY_AGREEMENT 0x08
+#define PKIX_KEY_USAGE_KEY_CERT_SIGN 0x04
+#define PKIX_KEY_USAGE_CRL_SIGN 0x02
+#define PKIX_KEY_USAGE_ENCIPHER_ONLY 0x01
+
+static GQuark OID_KEY_USAGE;
+
+/* -----------------------------------------------------------------------------
+ * 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_KEY_USAGE, "2.5.29.15");
+
+		#undef QUARK
+		
+		g_once_init_leave (&quarks_inited, 1);
+	}
+}
+
+static CK_RV
+has_key_usage (GckCertificateTrust *self, guint check, CK_ULONG *val)
+{
+	GckDataResult res;
+	const guchar *extension;
+	gsize n_extension;
+	guint usage;
+
+	g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
+	*val = CKT_NETSCAPE_TRUST_UNKNOWN;
+	
+	/* Find out the key usage */
+	extension = gck_certificate_get_extension (self->pv->certificate, OID_KEY_USAGE, 
+	                                           &n_extension, NULL);
+	if (!extension)
+		return CKR_OK;
+	
+	res = gck_data_der_read_key_usage (extension, n_extension, &usage);
+	
+	if (res != GCK_DATA_SUCCESS) {
+		g_warning ("invalid key usage in certificate");
+		return CKR_GENERAL_ERROR;
+	}
+			
+	if ((usage & check) == check)
+		*val = CKT_NETSCAPE_TRUSTED;
+	else
+		*val = CKT_NETSCAPE_UNTRUSTED;
+
+	return CKR_OK;
+}
+
+static CK_RV
+read_key_usage (GckCertificateTrust *self, guint check, CK_ATTRIBUTE_PTR attr)
+{
+	CK_ULONG value;
+	CK_RV rv;
+	
+	g_assert (GCK_IS_CERTIFICATE_TRUST (self));
+	
+	rv = has_key_usage (self, check, &value);
+	if (rv == CKR_OK)
+		rv = gck_attribute_set_ulong (attr, value);
+	return rv;
+}
+
+static CK_RV
+has_enhanced_usage (GckCertificateTrust *self, CK_ATTRIBUTE_TYPE type, CK_ULONG *val)
+{
+	gboolean bval;
+	CK_ULONG nval;
+
+	g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
+
+	/* Check if we have the purpose setup */
+	if (!gck_object_get_attribute_boolean (GCK_OBJECT (self->pv->certificate), type, &bval))
+		bval = FALSE;
+	
+	/* Don't have the purpose */
+	if (bval != TRUE) {
+		*val = CKT_NETSCAPE_UNTRUSTED;
+		return CKR_OK;
+	}
+	
+	/* Ascertain the trust in this certificate */
+	if (!gck_object_get_attribute_boolean (GCK_OBJECT (self->pv->certificate), CKA_TRUSTED, &bval))
+		bval = FALSE;
+	
+	if (bval != TRUE) {
+		*val = CKT_NETSCAPE_TRUST_UNKNOWN;
+		return CKR_OK;
+	}
+	
+	/* See if we can delegate the purpase (ie: CA) */
+	if (!gck_object_get_attribute_ulong (GCK_OBJECT (self->pv->certificate),
+	                                     CKA_CERTIFICATE_CATEGORY, &nval))
+		nval = 0;
+
+	/* 2 is a certificate authority in PKCS#11 */
+	*val = (nval == 2) ? CKT_NETSCAPE_TRUSTED_DELEGATOR : CKT_NETSCAPE_TRUSTED;
+	return CKR_OK;
+}
+
+static CK_RV
+read_enhanced_usage (GckCertificateTrust *self, CK_ATTRIBUTE_TYPE type, 
+                     CK_ATTRIBUTE_PTR attr)
+{
+	CK_ULONG value;
+	CK_RV rv;
+
+	g_assert (GCK_IS_CERTIFICATE_TRUST (self));
+
+	rv = has_enhanced_usage (self, type, &value);
+	if (rv == CKR_OK)
+		rv = gck_attribute_set_ulong (attr, value);
+	return rv;
+}
+
+static CK_RV
+hash_certificate (GckCertificateTrust *self, int algo, CK_ATTRIBUTE_PTR result)
+{
+	guchar *hash;
+	gsize n_hash;
+	CK_RV rv;
+
+	g_assert (GCK_IS_CERTIFICATE_TRUST (self));
+
+	g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
+
+	hash = gck_certificate_hash (self->pv->certificate, algo, &n_hash);
+	g_return_val_if_fail (hash, CKR_GENERAL_ERROR);
+	
+	rv = gck_attribute_set_data (result, hash, n_hash);
+	g_free (hash);
+	
+	return rv;
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
+static CK_RV
+gck_certificate_trust_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
+{
+	GckCertificateTrust *self = GCK_CERTIFICATE_TRUST (base);
+	
+	switch (attr->type)
+	{
+	case CKA_PRIVATE:
+		return gck_attribute_set_bool (attr, CK_FALSE);
+		
+	case CKA_TRUST_STEP_UP_APPROVED:
+		return gck_attribute_set_bool (attr, CK_FALSE);
+
+	case CKA_CLASS:
+		return gck_attribute_set_ulong (attr, CKO_NETSCAPE_TRUST);
+		
+	/* Key restrictions */
+	case CKA_TRUST_DIGITAL_SIGNATURE:
+		return read_key_usage (self, PKIX_KEY_USAGE_DIGITAL_SIGNATURE, attr);
+
+	case CKA_TRUST_NON_REPUDIATION:
+		return read_key_usage (self, PKIX_KEY_USAGE_NON_REPUDIATION, attr);
+
+	case CKA_TRUST_KEY_ENCIPHERMENT:
+		return read_key_usage (self, PKIX_KEY_USAGE_KEY_ENCIPHERMENT, attr);
+
+	case CKA_TRUST_DATA_ENCIPHERMENT:
+		return read_key_usage (self, PKIX_KEY_USAGE_DATA_ENCIPHERMENT, attr);
+
+	case CKA_TRUST_KEY_AGREEMENT:
+		return read_key_usage (self, PKIX_KEY_USAGE_KEY_AGREEMENT, attr);
+
+	case CKA_TRUST_KEY_CERT_SIGN:
+		return read_key_usage (self, PKIX_KEY_USAGE_KEY_CERT_SIGN, attr);
+
+	case CKA_TRUST_CRL_SIGN:
+		return read_key_usage (self, PKIX_KEY_USAGE_CRL_SIGN, attr);
+
+	/* Various trust flags */
+	case CKA_TRUST_SERVER_AUTH:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_SERVER_AUTH, attr);
+
+	case CKA_TRUST_CLIENT_AUTH:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_CLIENT_AUTH, attr);
+
+	case CKA_TRUST_CODE_SIGNING:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_CODE_SIGNING, attr);
+
+	case CKA_TRUST_EMAIL_PROTECTION:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_EMAIL_PROTECTION, attr);
+
+	case CKA_TRUST_IPSEC_END_SYSTEM:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_IPSEC_END_SYSTEM, attr);
+
+	case CKA_TRUST_IPSEC_TUNNEL:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_IPSEC_TUNNEL, attr);
+
+	case CKA_TRUST_IPSEC_USER:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_IPSEC_USER, attr);
+
+	case CKA_TRUST_TIME_STAMPING:
+		return read_enhanced_usage (self, CKA_GNOME_PURPOSE_TIME_STAMPING, attr);
+
+	case CKA_ID:
+	case CKA_SUBJECT:
+	case CKA_SERIAL_NUMBER:
+	case CKA_ISSUER:
+		g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
+		return gck_object_get_attribute (GCK_OBJECT (self->pv->certificate), 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 GCK_OBJECT_CLASS (gck_certificate_trust_parent_class)->get_attribute (base, attr);
+}
+
+static void
+gck_certificate_trust_init (GckCertificateTrust *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_CERTIFICATE_TRUST, GckCertificateTrustPrivate);
+}
+
+static void
+gck_certificate_trust_finalize (GObject *obj)
+{
+	GckCertificateTrust *self = GCK_CERTIFICATE_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_OBJECT_CLASS (gck_certificate_trust_parent_class)->finalize (obj);
+}
+
+static void
+gck_certificate_trust_set_property (GObject *obj, guint prop_id, const GValue *value, 
+                           GParamSpec *pspec)
+{
+	GckCertificateTrust *self = GCK_CERTIFICATE_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
+gck_certificate_trust_get_property (GObject *obj, guint prop_id, GValue *value, 
+                           GParamSpec *pspec)
+{
+	GckCertificateTrust *self = GCK_CERTIFICATE_TRUST (obj);
+
+	switch (prop_id) {
+	case PROP_CERTIFICATE:
+		g_value_set_object (value, gck_certificate_trust_get_certificate (self));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gck_certificate_trust_class_init (GckCertificateTrustClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
+    
+	gobject_class->finalize = gck_certificate_trust_finalize;
+	gobject_class->set_property = gck_certificate_trust_set_property;
+	gobject_class->get_property = gck_certificate_trust_get_property;
+	
+	gck_class->get_attribute = gck_certificate_trust_get_attribute;
+	
+	g_type_class_add_private (klass, sizeof (GckCertificateTrustPrivate));
+	
+	g_object_class_install_property (gobject_class, PROP_CERTIFICATE,
+	           g_param_spec_object ("certificate", "Certificate", "Certificate this trust belongs to", 
+	                                GCK_TYPE_CERTIFICATE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	
+	init_quarks ();
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC 
+ */
+
+GckCertificateTrust*
+gck_certificate_trust_new (GckCertificate *cert)
+{
+	return g_object_new (GCK_TYPE_CERTIFICATE_TRUST, "certificate", cert, NULL);
+}
+
+GckCertificate*
+gck_certificate_trust_get_certificate (GckCertificateTrust *self)
+{
+	g_return_val_if_fail (GCK_IS_CERTIFICATE_TRUST (self), NULL);
+	g_return_val_if_fail (self->pv->certificate, NULL);
+	return self->pv->certificate;
+}

Added: trunk/pkcs11/gck/gck-certificate-trust.h
==============================================================================
--- (empty file)
+++ trunk/pkcs11/gck/gck-certificate-trust.h	Sat Feb  7 23:23:52 2009
@@ -0,0 +1,55 @@
+/* 
+ * gnome-trustring
+ * 
+ * Copyright (C) 2008 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 __GCK_CERTIFICATE_TRUST_H__
+#define __GCK_CERTIFICATE_TRUST_H__
+
+#include <glib-object.h>
+
+#include "gck-object.h"
+#include "gck-types.h"
+
+#define GCK_TYPE_CERTIFICATE_TRUST               (gck_certificate_trust_get_type ())
+#define GCK_CERTIFICATE_TRUST(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_CERTIFICATE_TRUST, GckCertificateTrust))
+#define GCK_CERTIFICATE_TRUST_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCK_TYPE_CERTIFICATE_TRUST, GckCertificateTrustClass))
+#define GCK_IS_CERTIFICATE_TRUST(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCK_TYPE_CERTIFICATE_TRUST))
+#define GCK_IS_CERTIFICATE_TRUST_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCK_TYPE_CERTIFICATE_TRUST))
+#define GCK_CERTIFICATE_TRUST_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCK_TYPE_CERTIFICATE_TRUST, GckCertificateTrustClass))
+
+typedef struct _GckCertificateTrustClass GckCertificateTrustClass;
+typedef struct _GckCertificateTrustPrivate GckCertificateTrustPrivate;
+    
+struct _GckCertificateTrust {
+	GckObject parent;
+	GckCertificateTrustPrivate *pv;
+};
+
+struct _GckCertificateTrustClass {
+	GckObjectClass parent_class;
+};
+
+GType                 gck_certificate_trust_get_type               (void);
+
+GckCertificateTrust*  gck_certificate_trust_new                    (GckCertificate *cert);
+
+GckCertificate*       gck_certificate_trust_get_certificate        (GckCertificateTrust *self);
+
+#endif /* __GCK_CERTIFICATE_TRUST_H__ */

Modified: trunk/pkcs11/gck/gck-certificate.c
==============================================================================
--- trunk/pkcs11/gck/gck-certificate.c	(original)
+++ trunk/pkcs11/gck/gck-certificate.c	Sat Feb  7 23:23:52 2009
@@ -21,8 +21,6 @@
 
 #include "config.h"
 
-#include "pkcs11/pkcs11.h"
-
 #include "gck-attributes.h"
 #include "gck-certificate.h"
 #include "gck-certificate-key.h"
@@ -31,10 +29,13 @@
 #include "gck-data-der.h"
 #include "gck-key.h"
 #include "gck-manager.h"
-#include "gck-serializable.h"
 #include "gck-sexp.h"
+#include "gck-serializable.h"
 #include "gck-util.h"
 
+#include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11g.h"
+
 #include <glib/gi18n.h>
 
 #include <libtasn1.h>
@@ -54,6 +55,18 @@
 };
 
 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 gck_certificate_serializable (GckSerializableIface *iface);
 
@@ -74,6 +87,18 @@
 			name = g_quark_from_static_string(value)
  
 		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
 		
@@ -81,6 +106,106 @@
 	}
 }
 
+static gboolean 
+has_certificate_purposes (GckCertificate *self)
+{
+	const guchar *extension;
+	gsize n_extension;
+	
+	/* TODO: Storage of certificate purposes in the store */
+	
+	extension = gck_certificate_get_extension (self, OID_ENHANCED_USAGE, &n_extension, NULL);
+	return extension != NULL;
+}
+
+static CK_RV
+lookup_certificate_purposes (GckCertificate *self, GQuark **oids)
+{
+	GckDataResult res;
+	const guchar *extension;
+	gsize n_extension;
+
+	*oids = NULL;
+	
+	/* TODO: Storage of certificate purposes in the store */
+        
+	extension = gck_certificate_get_extension (self, OID_ENHANCED_USAGE, &n_extension, NULL);
+	
+	/* No enhanced usage noted, any are allowed */
+	if (!extension)
+		return CKR_OK;
+
+	res = gck_data_der_read_enhanced_usage (extension, n_extension, oids);
+	
+	if (res != GCK_DATA_SUCCESS)
+		return CKR_GENERAL_ERROR;
+	
+	return CKR_OK;
+}
+
+
+static gboolean
+check_certificate_purpose (GckCertificate *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 (GckCertificate *self, GQuark oid, CK_ATTRIBUTE_PTR attr)
+{
+	gboolean value = check_certificate_purpose (self, oid);
+	gck_attribute_set_bool (attr, value);
+	return CKR_OK;
+}
+
+
+static CK_RV
+read_certificate_purposes (GckCertificate *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);
+	
+	gck_attribute_set_string (attr, result->str);
+	g_string_free (result, TRUE);
+
+	return CKR_OK;
+}
+
+
 static gint
 find_certificate_extension (GckCertificate *self, GQuark oid)
 {
@@ -211,6 +336,40 @@
 	/* What in the world is this doing in the spec? */
 	case CKA_JAVA_MIDP_SECURITY_DOMAIN:
 		return gck_attribute_set_ulong (attr, 0); /* 0 = unspecified */
+		
+	case CKA_GNOME_PURPOSE_RESTRICTED:
+		gck_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 GCK_OBJECT_CLASS (gck_certificate_parent_class)->get_attribute (base, attr);
@@ -530,3 +689,21 @@
 	self->pv->label = g_strdup (label);
 	g_object_notify (G_OBJECT (self), "label");
 }
+
+guchar*
+gck_certificate_hash (GckCertificate *self, int hash_algo, gsize *n_hash)
+{
+	guchar *hash;
+	
+	g_return_val_if_fail (GCK_IS_CERTIFICATE (self), NULL);
+	g_return_val_if_fail (self->pv->data, NULL);
+	g_return_val_if_fail (n_hash, NULL);
+	
+	*n_hash = gcry_md_get_algo_dlen (hash_algo);
+	g_return_val_if_fail (*n_hash > 0, NULL);
+	
+	hash = g_malloc0 (*n_hash);
+	gcry_md_hash_buffer (hash_algo, hash, self->pv->data, self->pv->n_data);
+	
+	return hash;
+}

Modified: trunk/pkcs11/gck/gck-certificate.h
==============================================================================
--- trunk/pkcs11/gck/gck-certificate.h	(original)
+++ trunk/pkcs11/gck/gck-certificate.h	Sat Feb  7 23:23:52 2009
@@ -63,4 +63,8 @@
 void                       gck_certificate_set_label              (GckCertificate *self, 
                                                                    const gchar *label);
 
+guchar*                    gck_certificate_hash                   (GckCertificate *self,
+                                                                   int hash_algo,
+                                                                   gsize *n_hash);
+
 #endif /* __GCK_CERTIFICATE_H__ */

Modified: trunk/pkcs11/gck/gck-types.h
==============================================================================
--- trunk/pkcs11/gck/gck-types.h	(original)
+++ trunk/pkcs11/gck/gck-types.h	Sat Feb  7 23:23:52 2009
@@ -24,6 +24,7 @@
 
 typedef struct _GckCertificate GckCertificate;
 typedef struct _GckCertificateKey GckCertificateKey;
+typedef struct _GckCertificateTrust GckCertificateTrust;
 typedef struct _GckKey GckKey;
 typedef struct _GckFactoryInfo GckFactoryInfo;
 typedef struct _GckLogin GckLogin;

Modified: trunk/pkcs11/roots-store/gck-roots-certificate.c
==============================================================================
--- trunk/pkcs11/roots-store/gck-roots-certificate.c	(original)
+++ trunk/pkcs11/roots-store/gck-roots-certificate.c	Sat Feb  7 23:23:52 2009
@@ -24,6 +24,7 @@
 #include "gck-roots-certificate.h"
 
 #include "gck/gck-attributes.h"
+#include "gck/gck-certificate-trust.h"
 #include "gck/gck-manager.h"
 #include "gck/gck-object.h"
 #include "gck/gck-sexp.h"
@@ -34,10 +35,12 @@
 enum {
 	PROP_0,
 	PROP_PATH,
+	PROP_NETSCAPE_TRUST,
 };
 
 struct _GckRootsCertificate {
 	GckCertificate parent;
+	GckCertificateTrust *trust;
 	gchar *path;
 };
 
@@ -77,7 +80,7 @@
 static void
 gck_roots_certificate_init (GckRootsCertificate *self)
 {
-
+	self->trust = gck_certificate_trust_new (GCK_CERTIFICATE (self));
 }
 
 static void
@@ -107,6 +110,9 @@
 	case PROP_PATH:
 		g_value_set_string (value, gck_roots_certificate_get_path (self));
 		break;
+	case PROP_NETSCAPE_TRUST:
+		g_value_set_object (value, gck_roots_certificate_get_netscape_trust (self));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
 		break;
@@ -114,11 +120,24 @@
 }
 
 static void
+gck_roots_certificate_dispose (GObject *obj)
+{
+	GckRootsCertificate *self = GCK_ROOTS_CERTIFICATE (obj);
+	
+	if (self->trust)
+		g_object_unref (self->trust);
+	self->trust = NULL;
+
+	G_OBJECT_CLASS (gck_roots_certificate_parent_class)->finalize (obj);
+}
+
+static void
 gck_roots_certificate_finalize (GObject *obj)
 {
 	GckRootsCertificate *self = GCK_ROOTS_CERTIFICATE (obj);
 	
 	g_free (self->path);
+	g_assert (!self->trust);
 
 	G_OBJECT_CLASS (gck_roots_certificate_parent_class)->finalize (obj);
 }
@@ -129,6 +148,7 @@
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
 	
+	gobject_class->dispose = gck_roots_certificate_dispose;
 	gobject_class->finalize = gck_roots_certificate_finalize;
 	gobject_class->set_property = gck_roots_certificate_set_property;
 	gobject_class->get_property = gck_roots_certificate_get_property;
@@ -138,6 +158,10 @@
 	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", 
+	                                GCK_TYPE_CERTIFICATE_TRUST, G_PARAM_READABLE));
 }
 
 /* -----------------------------------------------------------------------------
@@ -156,3 +180,11 @@
 	g_return_val_if_fail (GCK_IS_ROOTS_CERTIFICATE (self), "");
 	return self->path;
 }
+
+GckCertificateTrust*
+gck_roots_certificate_get_netscape_trust (GckRootsCertificate *self)
+{
+	g_return_val_if_fail (GCK_IS_ROOTS_CERTIFICATE (self), NULL);
+	g_return_val_if_fail (GCK_IS_CERTIFICATE_TRUST (self->trust), NULL);
+	return self->trust;
+}

Modified: trunk/pkcs11/roots-store/gck-roots-certificate.h
==============================================================================
--- trunk/pkcs11/roots-store/gck-roots-certificate.h	(original)
+++ trunk/pkcs11/roots-store/gck-roots-certificate.h	Sat Feb  7 23:23:52 2009
@@ -49,4 +49,6 @@
 
 const gchar*          gck_roots_certificate_get_path               (GckRootsCertificate *self);
 
+GckCertificateTrust*  gck_roots_certificate_get_netscape_trust     (GckRootsCertificate *self);
+
 #endif /* __GCK_ROOTS_CERTIFICATE_H__ */

Modified: trunk/pkcs11/roots-store/gck-roots-module.c
==============================================================================
--- trunk/pkcs11/roots-store/gck-roots-module.c	(original)
+++ trunk/pkcs11/roots-store/gck-roots-module.c	Sat Feb  7 23:23:52 2009
@@ -128,6 +128,7 @@
 	/* Setup the right manager on the certificates */
 	gck_manager_register_object (manager, GCK_OBJECT (cert));
 	gck_manager_register_object (manager, GCK_OBJECT (gck_certificate_get_public_key (cert)));
+	gck_manager_register_object (manager, GCK_OBJECT (gck_roots_certificate_get_netscape_trust (GCK_ROOTS_CERTIFICATE (cert))));
 	
 	/* And add to our wonderful table */
 	g_hash_table_insert (self->certificates, cert, cert);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]