gnome-keyring r1640 - in trunk: . daemon/pkcs11 pkcs11 pkcs11/ssh-store pkcs11/user-store



Author: nnielsen
Date: Sat Feb 28 22:46:34 2009
New Revision: 1640
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1640&view=rev

Log:
Add compatibility support for loading SSH key unlock passwords from previous versions of
gnome-keyring.

Modified:
   trunk/ChangeLog
   trunk/daemon/pkcs11/gkr-pkcs11-auth-ep.c
   trunk/daemon/pkcs11/gkr-pkcs11-auth.c
   trunk/daemon/pkcs11/gkr-pkcs11-auth.h
   trunk/pkcs11/pkcs11i.h
   trunk/pkcs11/ssh-store/gck-ssh-openssh.c
   trunk/pkcs11/ssh-store/gck-ssh-openssh.h
   trunk/pkcs11/ssh-store/gck-ssh-private-key.c
   trunk/pkcs11/user-store/gck-user-storage.c

Modified: trunk/daemon/pkcs11/gkr-pkcs11-auth-ep.c
==============================================================================
--- trunk/daemon/pkcs11/gkr-pkcs11-auth-ep.c	(original)
+++ trunk/daemon/pkcs11/gkr-pkcs11-auth-ep.c	Sat Feb 28 22:46:34 2009
@@ -27,6 +27,7 @@
 
 #include "pkcs11/pkcs11.h"
 #include "pkcs11/pkcs11g.h"
+#include "pkcs11/pkcs11i.h"
 
 #include <glib.h>
 
@@ -60,10 +61,11 @@
 {
 	GkrPkcs11AuthObject *info = NULL;
 	CK_SESSION_INFO session_info;
-	CK_ATTRIBUTE attrs[5];
+	CK_ATTRIBUTE attrs[6];
 	CK_OBJECT_CLASS klass;
 	gchar *label = NULL;
 	gchar *unique = NULL;
+	gchar *digest = NULL;
 	CK_BBOOL token, always;
 	CK_ULONG n_attrs;
 	CK_RV rv;
@@ -77,21 +79,26 @@
 	attrs[1].pValue = unique = NULL;
 	attrs[1].ulValueLen = 0;
 
-	attrs[2].type = CKA_CLASS;
-	attrs[2].pValue = &klass;
-	attrs[2].ulValueLen = sizeof (klass);
+	/* COMPAT: Loaded for compatibility with old gnome-keyrings */
+	attrs[2].type = CKA_GNOME_INTERNAL_SHA1;
+	attrs[2].pValue = digest = NULL;
+	attrs[2].ulValueLen = 0;
+
+	attrs[3].type = CKA_CLASS;
+	attrs[3].pValue = &klass;
+	attrs[3].ulValueLen = sizeof (klass);
 
 	always = CK_FALSE;
-	attrs[3].type = CKA_ALWAYS_AUTHENTICATE;
-	attrs[3].pValue = &always;
-	attrs[3].ulValueLen = sizeof (always);
+	attrs[4].type = CKA_ALWAYS_AUTHENTICATE;
+	attrs[4].pValue = &always;
+	attrs[4].ulValueLen = sizeof (always);
 	
 	token = CK_FALSE;
-	attrs[4].type = CKA_TOKEN;
-	attrs[4].pValue = &token;
-	attrs[4].ulValueLen = sizeof (token);
+	attrs[5].type = CKA_TOKEN;
+	attrs[5].pValue = &token;
+	attrs[5].ulValueLen = sizeof (token);
 	
-	n_attrs = 5;
+	n_attrs = 6;
 	
 	/* Get attribute sizes */
 	rv = (pkcs11_lower->C_GetAttributeValue) (handle, object, attrs, n_attrs);
@@ -112,12 +119,15 @@
 		attrs[0].pValue = label = g_malloc0 (attrs[0].ulValueLen + 1);
 	if (attrs[1].ulValueLen != (CK_ULONG)-1)
 		attrs[1].pValue = unique = g_malloc0 (attrs[1].ulValueLen + 1);
+	if (attrs[2].ulValueLen != (CK_ULONG)-1)
+		attrs[2].pValue = digest = g_malloc0 (attrs[2].ulValueLen + 1);
 	
 	/* Get actual attributes */
 	rv = (pkcs11_lower->C_GetAttributeValue) (handle, object, attrs, n_attrs);
 	if (rv != CKR_OK && rv != CKR_ATTRIBUTE_TYPE_INVALID) {
 		g_free (label);
 		g_free (unique);
+		g_free (digest);
 		return NULL;
 	}
 	
@@ -132,6 +142,11 @@
 		info->unique = unique;
 		unique = NULL;
 	}
+	
+	if (attrs[2].ulValueLen != (CK_ULONG)-1) {
+		info->digest = digest;
+		digest = NULL;
+	}
 
 	info->token = token;
 	info->klass = klass;
@@ -140,6 +155,7 @@
 	
 	g_free (label);
 	g_free (unique);
+	g_free (digest);
 	
 	return info;
 }

Modified: trunk/daemon/pkcs11/gkr-pkcs11-auth.c
==============================================================================
--- trunk/daemon/pkcs11/gkr-pkcs11-auth.c	(original)
+++ trunk/daemon/pkcs11/gkr-pkcs11-auth.c	Sat Feb 28 22:46:34 2009
@@ -177,6 +177,13 @@
 	g_hash_table_replace (slot->session_to_specific, ulong_alloc (handle), object);
 }
 
+static void
+convert_upper_case (gchar *str)
+{
+	for (; *str; ++str)
+		*str = g_ascii_toupper (*str);
+}
+
 gboolean 
 gkr_pkcs11_auth_login_specific_prompt (CK_SESSION_HANDLE handle, CK_SESSION_INFO *info,
                                        CK_UTF8CHAR_PTR *pin, CK_ULONG *pin_len)
@@ -216,7 +223,7 @@
 	}
 	
 	/* See if we can just use the login keyring password for this */
-	if (object->unique && object->token && gkr_keyring_login_is_usable ()) {
+	if (object->unique && object->token) {
 		password = gkr_keyring_login_lookup_secret (GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD,
 		                                            "unique", object->unique, NULL);
 		if (password != NULL) { 
@@ -224,6 +231,21 @@
 			return TRUE;
 		}
 	}
+	
+	/* COMPAT: Check old method of storing secrets for objects in login keyring */
+	if (object->digest) {
+		convert_upper_case (object->digest);
+		password = gkr_keyring_login_lookup_secret (GNOME_KEYRING_ITEM_PK_STORAGE,
+		                                            "object-digest", object->digest, NULL);
+		if (password != NULL) {
+			if (object->unique)
+				gkr_keyring_login_attach_secret (GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD, 
+				                                 object->label, password, 
+		                                                 "unique", object->unique, NULL);
+			password_to_pin (password, pin, pin_len);
+			return TRUE;
+		}
+	}
 
 	/* Build up the prompt */
 	flags = GKR_ASK_REQUEST_PASSWORD | GKR_ASK_REQUEST_OK_DENY_BUTTONS;

Modified: trunk/daemon/pkcs11/gkr-pkcs11-auth.h
==============================================================================
--- trunk/daemon/pkcs11/gkr-pkcs11-auth.h	(original)
+++ trunk/daemon/pkcs11/gkr-pkcs11-auth.h	Sat Feb 28 22:46:34 2009
@@ -33,6 +33,7 @@
 	CK_BBOOL token;
 	gchar *label;
 	gchar *unique;
+	gchar *digest;
 } GkrPkcs11AuthObject;
 
 void                            gkr_pkcs11_auth_chain_functions          (CK_FUNCTION_LIST_PTR funcs); 

Modified: trunk/pkcs11/pkcs11i.h
==============================================================================
--- trunk/pkcs11/pkcs11i.h	(original)
+++ trunk/pkcs11/pkcs11i.h	Sat Feb 28 22:46:34 2009
@@ -73,7 +73,7 @@
  * OBJECT HASH
  */
 
-#define CK_GNOME_INTERNAL_SHA1                      (CKA_GNOME + 1000)
+#define CKA_GNOME_INTERNAL_SHA1                      (CKA_GNOME + 1000)
 
 
 #endif /* PKCS11I_H */

Modified: trunk/pkcs11/ssh-store/gck-ssh-openssh.c
==============================================================================
--- trunk/pkcs11/ssh-store/gck-ssh-openssh.c	(original)
+++ trunk/pkcs11/ssh-store/gck-ssh-openssh.c	Sat Feb 28 22:46:34 2009
@@ -184,17 +184,13 @@
 	return GCK_DATA_LOCKED;
 }
 
-static void
-parsed_pem_block (GQuark type, const guchar *data, gsize n_data,
-                  GHashTable *headers, gpointer user_data)
+static gboolean
+is_private_key_type (GQuark type)
 {
 	static GQuark PEM_RSA_PRIVATE_KEY;
 	static GQuark PEM_DSA_PRIVATE_KEY;
 	static gsize quarks_inited = 0;
-	
-	ParsePrivate *ctx = (ParsePrivate*)user_data;
-	const gchar *dekinfo;
-	
+
 	/* Initialize the first time through */
 	if (g_once_init_enter (&quarks_inited)) {
 		PEM_RSA_PRIVATE_KEY = g_quark_from_static_string ("RSA PRIVATE KEY");
@@ -203,7 +199,17 @@
 	}
 	
 	/* Only handle SSHv2 private keys */
-	if (type != PEM_RSA_PRIVATE_KEY && type != PEM_DSA_PRIVATE_KEY)
+	return (type == PEM_RSA_PRIVATE_KEY || type == PEM_DSA_PRIVATE_KEY);
+}
+
+static void
+parsed_pem_block (GQuark type, const guchar *data, gsize n_data,
+                  GHashTable *headers, gpointer user_data)
+{
+	ParsePrivate *ctx = (ParsePrivate*)user_data;
+	const gchar *dekinfo;
+	
+	if (!is_private_key_type (type))
 		return;
 
 	ctx->seen = TRUE;
@@ -224,6 +230,24 @@
 	}
 }
 
+static void
+digest_pem_block (GQuark type, const guchar *data, gsize n_data,
+                  GHashTable *headers, gpointer user_data)
+{
+	gchar **result = (gchar**)user_data;
+	
+	g_assert (result);
+	
+	if (!is_private_key_type (type))
+		return;
+	
+	/* Only digest the first key in the file */
+	if (*result != NULL)
+		return;
+
+	*result = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, n_data);
+}
+
 /* ------------------------------------------------------------------------------
  * PUBLIC
  */
@@ -356,3 +380,11 @@
 	*sexp = ctx.sexp;
 	return ctx.result;
 }
+
+gchar*
+gck_ssh_openssh_digest_private_key (const guchar *data, gsize n_data)
+{
+	gchar *result = NULL;
+	egg_openssl_pem_parse (data, n_data, digest_pem_block, &result);
+	return result;
+}

Modified: trunk/pkcs11/ssh-store/gck-ssh-openssh.h
==============================================================================
--- trunk/pkcs11/ssh-store/gck-ssh-openssh.h	(original)
+++ trunk/pkcs11/ssh-store/gck-ssh-openssh.h	Sat Feb 28 22:46:34 2009
@@ -18,4 +18,7 @@
                                                                           gssize n_password,
                                                                           gcry_sexp_t *sexp);
 
+gchar*                gck_ssh_openssh_digest_private_key                 (const guchar *data,
+                                                                          gsize n_data);
+
 #endif /* GCKSSHOPENSSH_H_ */

Modified: trunk/pkcs11/ssh-store/gck-ssh-private-key.c
==============================================================================
--- trunk/pkcs11/ssh-store/gck-ssh-private-key.c	(original)
+++ trunk/pkcs11/ssh-store/gck-ssh-private-key.c	Sat Feb 28 22:46:34 2009
@@ -30,6 +30,8 @@
 #include "gck/gck-sexp.h"
 #include "gck/gck-util.h"
 
+#include "pkcs11/pkcs11i.h"
+
 #include <glib/gi18n.h>
 
 enum {
@@ -136,10 +138,21 @@
 gck_ssh_private_key_get_attribute (GckObject *base, CK_ATTRIBUTE_PTR attr)
 {
 	GckSshPrivateKey *self = GCK_SSH_PRIVATE_KEY (base);
+	gchar *digest;
+	CK_RV rv;
 	
 	switch (attr->type) {
 	case CKA_LABEL:
 		return gck_attribute_set_string (attr, self->label);
+
+	/* COMPAT: Previous versions of gnome-keyring used this to save unlock passwords */
+	case CKA_GNOME_INTERNAL_SHA1:
+		if (!self->private_data)
+			return CKR_ATTRIBUTE_TYPE_INVALID;
+		digest = gck_ssh_openssh_digest_private_key (self->private_data, self->n_private_data);
+		rv = gck_attribute_set_string (attr, digest);
+		g_free (digest);
+		return rv;
 	}
 	
 	return GCK_OBJECT_CLASS (gck_ssh_private_key_parent_class)->get_attribute (base, attr);

Modified: trunk/pkcs11/user-store/gck-user-storage.c
==============================================================================
--- trunk/pkcs11/user-store/gck-user-storage.c	(original)
+++ trunk/pkcs11/user-store/gck-user-storage.c	Sat Feb 28 22:46:34 2009
@@ -468,7 +468,7 @@
 	digest = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, n_data);
 	g_return_val_if_fail (digest, FALSE);
 	
-	res = gck_data_file_read_value (self->file, identifier, CK_GNOME_INTERNAL_SHA1, &value, &n_value);
+	res = gck_data_file_read_value (self->file, identifier, CKA_GNOME_INTERNAL_SHA1, &value, &n_value);
 	g_return_val_if_fail (res == GCK_DATA_SUCCESS, FALSE);
 	
 	result = (strlen (digest) == n_value && memcmp (digest, value, n_value) == 0);
@@ -495,7 +495,7 @@
 		g_return_if_reached ();
 	}
 	
-	res = gck_data_file_write_value (self->file, identifier, CK_GNOME_INTERNAL_SHA1, digest, strlen (digest));
+	res = gck_data_file_write_value (self->file, identifier, CKA_GNOME_INTERNAL_SHA1, digest, strlen (digest));
 	g_free (digest);
 	
 	if (res != GCK_DATA_SUCCESS)



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