patches/gnome-keyring-01-pkcs.diff
changeset 4395 b38a84a931a5
child 4398 8833d7027509
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-keyring-01-pkcs.diff	Fri Oct 29 22:39:35 2004 +0000
@@ -0,0 +1,889 @@
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/gnome-keyring-daemon-io.c	2004-01-13 08:29:02.000000000 -0500
++++ gnome-keyring-0.2.0/gnome-keyring-daemon-io.c	2004-10-27 19:48:35.980579000 -0400
+@@ -33,6 +33,9 @@
+ #include <sys/un.h>
+ #include <sys/uio.h>
+ #include <unistd.h>
++#if defined(HAVE_GETPEERUCRED)
++#include <ucred.h>
++#endif
+ 
+ #include "gnome-keyring.h"
+ #include "gnome-keyring-private.h"
+@@ -174,6 +177,18 @@
+ 		
+ 		*pid = cred->cmcred_pid;
+ 		*uid = cred->cmcred_euid;
++#elif defined (HAVE_GETPEERUCRED)
++		ucred_t *uc = NULL;
++
++		if (getpeerucred(fd, &uc) == 0) {
++			*pid = ucred_getpid(uc);
++			*uid = ucred_geteuid(uc);
++			ucred_free(uc);
++		} else {
++			g_warning ("getpeerucred() failed: %s", strerror(errno));
++			return FALSE;
++		}
++
+ #else /* !SO_PEERCRED && !HAVE_CMSGCRED */
+ 		g_warning ("Socket credentials not supported on this OS\n");
+ 		return FALSE;
+@@ -371,10 +386,15 @@
+ 				gnome_keyring_client_free (client);
+ 				return;
+ 			}
++			if (str != NULL) {
+ 			debug_print (("got name: %s\n", str));
+ 			client->app_ref->display_name = str;
+ 			client->input_pos = 0;
+ 			client->state = GNOME_CLIENT_STATE_READ_PACKET;
++			} else {
++				gnome_keyring_client_free (client);
++				return;
++			}
+ 		}
+ 		break;
+ 	case GNOME_CLIENT_STATE_READ_PACKET:
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/gnome-keyring-proto.c	2003-12-05 05:21:57.000000000 -0500
++++ gnome-keyring-0.2.0/gnome-keyring-proto.c	2004-10-19 20:43:21.132899000 -0400
+@@ -276,7 +276,6 @@
+ 		return FALSE;
+ 	}
+ 
+-	
+ 	/* Make space for packet size */
+ 	*op_start = buffer->len;
+ 	gnome_keyring_proto_add_uint32 (buffer, 0);
+@@ -340,8 +339,7 @@
+ 	if (!gnome_keyring_proto_start_operation (buffer, op, &op_start)) {
+ 		return FALSE;
+ 	}
+-	if (!gnome_keyring_proto_add_utf8_string (buffer,
+-						  str)) {
++	if (!gnome_keyring_proto_add_utf8_string (buffer, str)) {
+ 		return FALSE;
+ 	}
+ 	if (!gnome_keyring_proto_end_operation (buffer,	op_start)) {
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/test.c	2004-01-12 04:37:31.000000000 -0500
++++ gnome-keyring-0.2.0/test.c	2004-10-19 20:43:51.622573000 -0400
+@@ -301,6 +301,7 @@
+ {
+ 	char arg;
+ 
++	g_set_application_name("test-keyring");
+ 	loop = g_main_loop_new (NULL, FALSE);
+ 	
+ 	arg = 0;
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/gnome-keyring-daemon.c	2004-02-09 07:17:18.000000000 -0500
++++ gnome-keyring-0.2.0/gnome-keyring-daemon.c	2004-10-20 10:16:57.433570000 -0400
+@@ -28,6 +28,7 @@
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <signal.h>
++#include <string.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
+@@ -121,7 +122,7 @@
+ 	int i;
+ 
+ 	got_random = FALSE;
+-#ifdef __linux__
++#ifdef HAVE_DEVRANDOM
+ 	{
+ 		int fd;
+ 
+@@ -295,8 +296,11 @@
+ {
+         guchar digest[16];
+ 	
+-	gnome_keyring_md5_string (str, digest);
+-	return gnome_keyring_md5_digest_to_ascii (digest);
++	(void) memset(digest, 0, sizeof(digest));
++
++	(void) gnome_keyring_md5_digest (str, strlen(str), digest, sizeof(digest));
++
++	return gnome_keyring_md5_digest_to_ascii(digest, sizeof(digest));
+ }
+ 
+ GnomeKeyringAttributeList *
+@@ -1116,7 +1120,8 @@
+ 	
+ 	if (!gnome_keyring_proto_decode_create_item (packet,
+ 						     &keyring_name, NULL,
+-						     &attributes, NULL, &type,
++				     &attributes, NULL,
++				     (GnomeKeyringItemType *)&type,
+ 						     &update_if_exists)) {
+ 		return FALSE;
+ 	}
+@@ -1196,7 +1201,7 @@
+ 						     &display_name,
+ 						     &attributes,
+ 						     &secret,
+-						     &type,
++						     (GnomeKeyringItemType *)&type,
+ 						     &update_if_exists)) {
+ 		return FALSE;
+ 	}
+@@ -1597,7 +1602,7 @@
+ 	if (!gnome_keyring_proto_decode_set_item_info (packet,
+ 						       &keyring_name,
+ 						       &item_id,
+-						       &type,
++						       (GnomeKeyringItemType *)&type,
+ 						       &item_name,
+ 						       &secret)) {
+ 		return FALSE;
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/list-keyrings.c	2003-11-28 06:30:39.000000000 -0500
++++ gnome-keyring-0.2.0/list-keyrings.c	2004-10-20 13:48:42.780015000 -0400
+@@ -171,6 +171,7 @@
+ 	gboolean locked;
+ 	guint32 item_id;
+ 	
++	g_set_application_name("list-keyrings");
+ 	loop = g_main_loop_new (NULL, FALSE);
+ 	
+ 	g_print ("Keyrings:\n");
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/md5.h	2003-12-01 06:10:09.000000000 -0500
++++ gnome-keyring-0.2.0/md5.h	2004-10-20 16:37:21.553000000 -0400
+@@ -2,14 +2,18 @@
+ #define MD5_H
+ 
+ #include <glib.h>
++#include "config.h"
+ 
++char *gnome_keyring_md5_digest_to_ascii (unsigned char *, uint32_t);
++int gnome_keyring_md5_digest(guchar *, uint32_t , guchar *, uint32_t );
++
++#ifndef HAVE_PKCS11
+ struct GnomeKeyringMD5Context {
+ 	guint32 buf[4];
+ 	guint32 bits[2];
+ 	unsigned char in[64];
+ };
+ 
+-char *gnome_keyring_md5_digest_to_ascii (unsigned char                  digest[16]);
+ void  gnome_keyring_md5_string          (const char                    *string,
+ 					 unsigned char                  digest[16]);
+ void  gnome_keyring_md5_init            (struct GnomeKeyringMD5Context *ctx);
+@@ -19,4 +23,6 @@
+ void  gnome_keyring_md5_final           (unsigned char                  digest[16],
+ 					 struct GnomeKeyringMD5Context *ctx);
+ 
++#endif /* HAVE_PKCS11 */
++
+ #endif /* MD5_h */
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/aes.c	2003-11-27 10:45:09.000000000 -0500
++++ gnome-keyring-0.2.0/aes.c	2004-10-20 20:58:25.415883000 -0400
+@@ -31,6 +31,9 @@
+ 
+ #include "config.h"
+ 
++/* Only build this if there is no PKCS11 support available */
++#ifndef HAVE_PKCS11
++
+ #include "aes.h"
+ 
+ #if defined(G_BYTE_ORDER) && defined(G_BIG_ENDIAN) && defined(G_LITTLE_ENDIAN)
+@@ -333,3 +336,5 @@
+ {
+ 	return ap->fdback;
+ }
++
++#endif /* ! HAVE_PKCS11 */
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/md5.c	2003-12-01 06:10:40.000000000 -0500
++++ gnome-keyring-0.2.0/md5.c	2004-10-21 10:11:59.748915000 -0400
+@@ -20,19 +20,76 @@
+ #include "md5.h"
+ #include <string.h>
+ 
+-static void gnome_keyring_md5_transform (guint32                 buf[4],
+-					 guint32 const           in[16]);
++#ifdef HAVE_PKCS11
++#include <security/cryptoki.h>
++int GetCryptoSession(CK_MECHANISM_TYPE, CK_SESSION_HANDLE_PTR);
++#endif
+ 
+-void
+-gnome_keyring_md5_string (const char *string, unsigned char digest[16])
++char *
++gnome_keyring_md5_digest_to_ascii (unsigned char *digest, uint32_t digestlen)
+ {
++  static char hex_digits[] = "0123456789abcdef";
++  unsigned char *res;
++  int i;
++  
++  res = g_malloc (33);
++  
++  for (i = 0; i < digestlen; i++) {
++    res[2*i] = hex_digits[digest[i] >> 4];
++    res[2*i+1] = hex_digits[digest[i] & 0xf];
++  }
++  
++  res[32] = 0;
++  
++  return (char *)res;
++}
++
++int
++gnome_keyring_md5_digest(guchar *buffer, uint32_t len, guchar *digest, uint32_t digestlen)
++{
++	guchar md5digest[16];
++#ifdef HAVE_PKCS11
++	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
++	CK_MECHANISM mech = { CKM_MD5, NULL, 0 };
++	CK_RV rv = CKR_OK;
++
++	if (GetCryptoSession(CKM_MD5, &hSession) == CKR_OK) {
++		if ((rv = C_DigestInit(hSession, &mech)) != CKR_OK) {
++			/* Report an error */
++			g_warning("gnome_keyring_md5_digest: C_DigestInit failed - 0x%0x", rv);
++			goto cleanup;
++		}
++		rv = C_Digest(hSession, (CK_BYTE_PTR)buffer, len, (CK_BYTE_PTR)md5digest, &digestlen);
++		if (rv != CKR_OK) {
++			/* Report an error */
++			g_warning("gnome_keyring_md5_digest: C_Digest failed - 0x%0x", rv);
++			goto cleanup;
++		}
++	}
++cleanup:
++	if (hSession != CK_INVALID_HANDLE)
++		C_CloseSession(hSession);
++
++#else
++	int rv = 0;
+   struct GnomeKeyringMD5Context md5_context;
+   
+   gnome_keyring_md5_init (&md5_context);
+-  gnome_keyring_md5_update (&md5_context, string, strlen (string));
+-  gnome_keyring_md5_final (digest, &md5_context);
++	gnome_keyring_md5_update (&md5_context, buffer, len);
++	gnome_keyring_md5_final (md5digest, &md5_context);
++#endif /* HAVE_PKCS11 */
++
++	(void)memcpy(digest, md5digest, digestlen);
++
++	return (rv);
++
+ }
+ 
++#ifndef HAVE_PKCS11
++
++static void gnome_keyring_md5_transform (guint32                 buf[4],
++					 guint32 const           in[16]);
++
+ #if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ #define byteReverse(buf, len)	/* Nothing */
+ #else
+@@ -54,26 +111,6 @@
+ 
+ #endif
+ 
+-char *
+-gnome_keyring_md5_digest_to_ascii (unsigned char digest[16])
+-{
+-  static char hex_digits[] = "0123456789abcdef";
+-  unsigned char *res;
+-  int i;
+-  
+-  res = g_malloc (33);
+-  
+-  for (i = 0; i < 16; i++) {
+-    res[2*i] = hex_digits[digest[i] >> 4];
+-    res[2*i+1] = hex_digits[digest[i] & 0xf];
+-  }
+-  
+-  res[32] = 0;
+-  
+-  return res;
+-}
+-
+-
+ /*
+  * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+  * initialization constants.
+@@ -289,3 +326,5 @@
+     buf[3] += d;
+ }
+ 
++#endif /* HAVE_PKCS11 */
++
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/gnome-keyring-daemon-file.c	2003-12-05 05:34:09.000000000 -0500
++++ gnome-keyring-0.2.0/gnome-keyring-daemon-file.c	2004-10-27 20:27:21.143089000 -0400
+@@ -26,6 +26,7 @@
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <stdio.h>
++#include <string.h>
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <sys/un.h>
+@@ -34,28 +35,200 @@
+ 
+ #include "gnome-keyring-daemon.h"
+ #include "gnome-keyring-proto.h"
+-#include "md5.h"
+-#include "sha256.h"
++
++#ifdef HAVE_PKCS11
++#include <security/cryptoki.h>
++#else
+ #include "aes.h"
++#endif /* HAVE_PKCS11 */
++
++#include "sha256.h"
++#include "md5.h"
+ 
+ time_t keyring_dir_mtime = 0;
+ 
+-static void
+-generate_key (const char *password,
+-	      guchar salt[8],
+-	      int iterations,
+-	      char key[16],
+-	      char iv[16])
++#ifdef HAVE_PKCS11
++int
++GetCryptoSession(CK_MECHANISM_TYPE mech, CK_SESSION_HANDLE_PTR hSession)
++{
++	CK_RV rv;
++	CK_ULONG slotcount;
++	CK_SLOT_ID_PTR slot_list;
++	CK_SLOT_ID slot_id;
++	CK_MECHANISM_INFO mech_info;
++	CK_ULONG i;
++
++	if (hSession == NULL) {
++		return (CKR_ARGUMENTS_BAD);
++	}
++
++	/* initialize PKCS #11 */
++	rv = C_Initialize(NULL);
++	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
++		return (rv);
++	}
++
++	/* get slot count */
++	rv = C_GetSlotList(0, NULL, &slotcount);
++	if (rv != CKR_OK) {
++		return (rv);
++	}
++
++	if (slotcount == 0) {
++		return (CKR_FUNCTION_FAILED);
++	}
++
++	/* allocate memory for slot list */
++	slot_list = malloc(slotcount * sizeof (CK_SLOT_ID));
++	if (slot_list == NULL) {
++		return (CKR_HOST_MEMORY);
++	}
++
++	if ((rv = C_GetSlotList(0, slot_list, &slotcount)) != CKR_OK) {
++		free(slot_list);
++		return (rv);
++	}
++
++	/* find slot with matching mechanism */
++	for (i = 0; i < slotcount; i++) {
++		slot_id = slot_list[i];
++		if (C_GetMechanismInfo(slot_id, mech, &mech_info) == CKR_OK) {
++			break;
++		}
++	}
++
++	if (i == slotcount) {
++		free(slot_list);
++		return (CKR_MECHANISM_INVALID);
++	}
++
++	rv = C_OpenSession(slot_id, CKF_SERIAL_SESSION, NULL,
++	    NULL, hSession);
++
++	free(slot_list);
++	return (rv);
++
++}
++
++static int
++create_key_object(CK_SESSION_HANDLE  hSession, CK_KEY_TYPE ktype, uchar_t *keydata, uint32_t keylen,
++			CK_OBJECT_HANDLE *hKey)
+ {
++	CK_RV rv = CKR_OK;
++	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
++	CK_BBOOL true = TRUE, false =  FALSE;
++
++	CK_ATTRIBUTE template[] = {
++		{CKA_CLASS, NULL, sizeof (class) },
++		{CKA_KEY_TYPE, NULL, sizeof (CKA_KEY_TYPE) },
++		{CKA_TOKEN, NULL, sizeof (false) },
++		{CKA_ENCRYPT, NULL, sizeof (true) },
++		{CKA_VALUE, NULL, keylen }
++        };
++
++	template[0].pValue = &class;
++	template[1].pValue = &ktype;
++	template[2].pValue = &false;
++	template[3].pValue = &true;
++	template[4].pValue = keydata;
++
++	rv = C_CreateObject(hSession, template, 5, hKey);
++	if (rv != CKR_OK) {
++		g_warning ("create_key_object: C_CreateObject error 0x%0x", rv);
++	}
++
++	return (rv);
++}
++#endif /* HAVE_PKCS11 */
++
++static int
++generate_key (const char *password, guchar *salt, int iterations, char *key, char *iv)
++{
++#ifdef HAVE_PKCS11
++	/*
++	 * If we have PKCS11, use the PKCS#5 PKBDF2 algorithm to derive a key 
++	 * from the given password and salt.
++	 */
++        CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
++	CK_PKCS5_PBKD2_PARAMS params;
++	CK_OBJECT_CLASS class = CKO_SECRET_KEY;
++	CK_ATTRIBUTE tmpl[3];
++	CK_KEY_TYPE keytype = CKK_AES;
++	CK_OBJECT_HANDLE hKey;
++        CK_MECHANISM mech; 
++        CK_RV rv = CKR_OK;
++	CK_BYTE  fullkey[32];
++	CK_ULONG keylen = 32, passlen = strlen(password);
++	int attrs = 0;
++
++	g_assert (iterations >= 1);
++        if (GetCryptoSession(CKM_PKCS5_PBKD2, &hSession) == CKR_OK) {
++		tmpl[attrs].type = CKA_CLASS;
++		tmpl[attrs].pValue = &class;
++		tmpl[attrs].ulValueLen = sizeof (class);
++		attrs++;
++
++		tmpl[attrs].type = CKA_KEY_TYPE;
++		tmpl[attrs].pValue = &keytype;
++		tmpl[attrs].ulValueLen = sizeof (keytype);
++		attrs++;
++
++		tmpl[attrs].type = CKA_VALUE_LEN;
++		tmpl[attrs].pValue = (void *)&keylen;
++		tmpl[attrs].ulValueLen = keylen;
++		attrs++;
++
++		params.saltSource = CKZ_SALT_SPECIFIED;
++		params.pSaltSourceData = (void *)salt;
++		params.ulSaltSourceDataLen = 8;
++		params.iterations = iterations;
++		params.prf = CKP_PKCS5_PBKD2_HMAC_SHA1;
++		params.pPrfData = NULL;
++		params.ulPrfDataLen = 0;
++		params.pPassword = (CK_UTF8CHAR_PTR)password;
++		params.ulPasswordLen = (CK_ULONG *)&passlen;
++
++		mech.mechanism = CKM_PKCS5_PBKD2;
++		mech.pParameter = &params;
++		mech.ulParameterLen = sizeof (params);
++
++		rv = C_GenerateKey(hSession, &mech, tmpl, attrs, &hKey);
++		if (rv != CKR_OK) {
++			g_warning ("generate_key: C_GenerateKey error 0x%0x", rv);
++			goto cleanup;
++		}
++		
++		tmpl[0].type = CKA_VALUE;
++		tmpl[0].pValue = fullkey;
++		tmpl[0].ulValueLen = sizeof(fullkey);
++		rv = C_GetAttributeValue(hSession, hKey, tmpl, 1);
++		if (rv != CKR_OK) {
++			g_warning ("generate_key: C_GenerateKey error 0x%0x", rv);
++			goto cleanup;
++		}
++		/*
++		 * We copied the key data from the object, now destroy it.
++		 */
++		(void) C_DestroyObject(hSession, hKey);
++		memcpy (key, fullkey, 16);
++		memcpy (iv, fullkey+16, 16);
++        }
++cleanup:
++        if (hSession != CK_INVALID_HANDLE)
++                C_CloseSession(hSession);
++
++#else
+ 	sha256Param sha;
++	int rv = 0;
+ 	guchar digest[32];
+ 
+ 	g_assert (iterations >= 1);
+ 
+ 	sha256Reset (&sha);
+-	sha256Update (&sha, password, strlen (password));
++	sha256Update (&sha, (const uchar_t *)password, strlen (password));
+ 	sha256Update (&sha, salt, 8);
+ 	sha256Digest (&sha, digest);
++
+ 	iterations--;
+ 
+ 	while (iterations != 0) {
+@@ -64,9 +237,11 @@
+ 		sha256Digest (&sha, digest);
+ 		iterations--;
+ 	}
+-
+ 	memcpy (key, digest, 16);
+ 	memcpy (iv, digest+16, 16);
++#endif /* HAVE_PKCS11 */
++
++	return (rv);
+ }
+ 
+ static gboolean
+@@ -77,17 +252,62 @@
+ {
+         guchar key[16];
+         guchar iv[16];
+-	aesParam param;
++#ifdef HAVE_PKCS11
++	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
++	CK_MECHANISM mechanism;
++	CK_OBJECT_HANDLE hKey;
++	CK_RV rv;
++	CK_ULONG cipherlen;
++#else
+ 	guchar dst[16];
+ 	guchar src[16];
++	aesParam param;
+ 	size_t pos;
+ 	int i;
++#endif
+ 
+ 	g_assert (buffer->len % 16 == 0);
+ 
+-	generate_key (password, salt, iterations,
+-		      key, iv);
++	if (generate_key (password, salt, iterations, (char *)key, (char *)iv) != 0)
++		return (FALSE);
++#ifdef HAVE_PKCS11
++	rv = GetCryptoSession(CKM_AES_CBC, &hSession);
++	if (rv != CKR_OK) {
++		g_warning ("encrypt_buffer: GetCryptoSession error 0x%0x", rv);
++		return (FALSE);
++	}
++
++	rv = create_key_object(hSession, CKK_AES, key, sizeof(key), &hKey);
++	if (rv != CKR_OK) {
++		(void)C_CloseSession(hSession);
++		return (FALSE);
++	}
++
++	/* Setup to do AES CBC mode with the given IV */
++	mechanism.mechanism = CKM_AES_CBC;
++	mechanism.pParameter = iv;
++	mechanism.ulParameterLen = sizeof (iv);
++
++	rv = C_EncryptInit(hSession, &mechanism, hKey);
++	if (rv != CKR_OK) {
++		g_warning ("encrypt_buffer: C_EncryptInit error 0x%0x", rv);
++		goto cleanup;
++	}
++
++	cipherlen = buffer->len;
++	/* encrypt the whole buffer in-place. */
++	if ((rv = C_Encrypt(hSession, (CK_BYTE_PTR)buffer->str, buffer->len,
++			(CK_BYTE_PTR)buffer->str, &cipherlen)) != CKR_OK)
++		g_warning ("encrypt_buffer: C_Encrypt error 0x%0x", rv);
++
++cleanup:
++	(void)C_DestroyObject(hSession, hKey);
++	(void)C_CloseSession(hSession);
++	if (rv != CKR_OK) {
++		return (FALSE);
++	}
+ 	
++#else
+ 	if (aesSetup(&param, key, 128, ENCRYPT)) {
+ 		return FALSE;
+ 	}
+@@ -102,6 +322,7 @@
+ 		memcpy (iv, dst, 16);
+ 		memcpy (buffer->str + pos, dst, 16);
+ 	}
++#endif /* HAVE_PKCS11 */
+ 
+ 	return TRUE;
+ }
+@@ -114,29 +335,85 @@
+ {
+         guchar key[16];
+         guchar iv[16];
++#ifdef HAVE_PKCS11
++	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
++	CK_MECHANISM mechanism;
++	CK_OBJECT_HANDLE hKey;
++	CK_RV rv;
++	CK_ULONG cipherlen;
++	CK_BYTE dst[16];
++#else
+ 	aesParam param;
+-	guchar dst[16];
++	guchar *dst;
++	guint32 dstint[4];
++	guint32 srcint[4];
+ 	size_t pos;
+ 	int i;
++#endif
+ 
+ 	g_assert (buffer->len % 16 == 0);
+ 
+-	generate_key (password, salt, iterations,
+-		      key, iv);
++	if (generate_key (password, salt, iterations, (char *)key, (char *)iv))
++		return FALSE;
++
++#ifdef HAVE_PKCS11
++	rv = GetCryptoSession(CKM_AES_CBC, &hSession);
++	if (rv != CKR_OK) {
++		g_warning ("decrypt_buffer: GetCryptoSession error 0x%0x", rv);
++		return (FALSE);
++	}
++
++	rv = create_key_object(hSession, CKK_AES, key, sizeof(key), &hKey);
++	if (rv != CKR_OK) {
++		(void)C_CloseSession(hSession);
++		return (FALSE);
++	}
++
++	mechanism.mechanism = CKM_AES_CBC;
++	mechanism.pParameter = iv;
++	mechanism.ulParameterLen = sizeof(iv);
++
++	rv = C_DecryptInit(hSession, &mechanism, hKey);
++	if (rv != CKR_OK) {
++		g_warning ("decrypt_buffer: C_DecryptInit error 0x%0x", rv);
++		goto cleanup;
++	}
++
++	cipherlen = buffer->len;
++	/* decrypt the entire buffer in-place */
++	if ((rv = C_Decrypt(hSession, (CK_BYTE *)buffer->str, buffer->len,
++						(CK_BYTE *)buffer->str, &cipherlen))) {
++		g_warning ("decrypt_buffer: C_Decrypt error 0x%0x", rv);
++	}
++
++cleanup:
++	(void)C_DestroyObject(hSession, hKey);
++	(void)C_CloseSession(hSession);
++
++	if (rv != CKR_OK)
++		return (FALSE);
++
++#else
+ 	
+ 	if (aesSetup(&param, key, 128, DECRYPT)) {
+ 		return FALSE;
+ 	}
+ 	for (pos = 0; pos < buffer->len; pos += 16) {
+-		if (aesDecrypt (&param, (guint32*) dst, (guint32*) (buffer->str + pos))) {
++
++		/* Copy the data to a properly aligned data struct before the AES operation */
++		memcpy((void *)srcint, buffer->str+pos, 16);
++		if (aesDecrypt (&param, (guint32*) dstint, (guint32 *)srcint)) {
+ 			return FALSE;
+ 		}
++		dst = (guchar *)dstint;
++
+ 		for (i = 0; i < 16; i++) {
+ 			dst[i] = iv[i] ^ dst[i];
+ 		}
+ 		memcpy (iv, buffer->str + pos, 16);
+ 		memcpy (buffer->str + pos, dst, 16);
+ 	}
++#endif /* HAVE_PKCS11 */
+ 
+ 	return TRUE;
+ }
+@@ -144,15 +421,11 @@
+ static gboolean
+ verify_decrypted_buffer (GString *buffer)
+ {
+-        struct GnomeKeyringMD5Context md5_context;
+         guchar digest[16];
+-	
+-	gnome_keyring_md5_init (&md5_context);
+-	gnome_keyring_md5_update (&md5_context,
+-				  buffer->str + 16, buffer->len - 16);
+-	gnome_keyring_md5_final (digest, &md5_context);
+-	
+-	return memcmp (buffer->str, digest, 16) == 0;
++	if (gnome_keyring_md5_digest((uchar_t *)(buffer->str + 16), buffer->len - 16, 
++				digest, sizeof (digest)))
++		return (FALSE);
++	return (memcmp (buffer->str, digest, 16) == 0);
+ }
+ 
+ static char *
+@@ -278,7 +551,6 @@
+ 	GnomeKeyringItem *item;
+ 	GnomeKeyringAttributeList *hashed;
+ 	GString *to_encrypt;
+-        struct GnomeKeyringMD5Context md5_context;
+         guchar digest[16];
+ 	int i;
+ 
+@@ -304,7 +576,7 @@
+ 	gnome_keyring_proto_add_uint32 (buffer, flags);
+ 	gnome_keyring_proto_add_uint32 (buffer, keyring->lock_timeout);
+ 	gnome_keyring_proto_add_uint32 (buffer, keyring->hash_iterations);
+-	g_string_append_len (buffer, keyring->salt, 8);
++	g_string_append_len (buffer, (const char *)keyring->salt, 8);
+ 
+ 	/* Reserved: */
+ 	for (i = 0; i < 4; i++) {
+@@ -330,7 +602,7 @@
+ 
+ 	/* Encrypted data: */
+ 	to_encrypt = g_string_new (NULL);
+-	g_string_append_len (to_encrypt, digest, 16); /* Space for hash */
++	g_string_append_len (to_encrypt, (const char *)digest, 16); /* Space for hash */
+ 
+ 	if (!generate_encrypted_data (to_encrypt, keyring)) {
+ 		g_string_free (to_encrypt, TRUE);
+@@ -342,11 +614,9 @@
+ 		g_string_append_c (to_encrypt, 0);
+ 	}
+ 
+-	gnome_keyring_md5_init (&md5_context);
+-	gnome_keyring_md5_update (&md5_context,
+-				  to_encrypt->str + 16, to_encrypt->len - 16);
+-	gnome_keyring_md5_final (digest, &md5_context);
+-	memcpy (to_encrypt->str, digest, 16);
++	if (gnome_keyring_md5_digest((uchar_t *)(to_encrypt->str + 16), to_encrypt->len - 16, 
++			digest, 16) == 0)
++		(void) memcpy (to_encrypt->str, digest, 16);
+ 	
+ 	if (!encrypt_buffer (to_encrypt, keyring->password, keyring->salt, keyring->hash_iterations)) {
+ 		g_string_free (to_encrypt, TRUE);
+@@ -572,7 +842,7 @@
+ 	if (!gnome_keyring_proto_get_uint32 (buffer, offset, &offset, &hash_iterations)) {
+ 		goto bail;
+ 	}
+-	if (!gnome_keyring_proto_get_bytes (buffer, offset, &offset, salt, 8)) {
++	if (!gnome_keyring_proto_get_bytes (buffer, offset, &offset, (char *)salt, 8)) {
+ 		goto bail;
+ 	}
+ 	
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/sha256.c	2003-12-05 04:04:31.000000000 -0500
++++ gnome-keyring-0.2.0/sha256.c	2004-10-27 20:33:52.297403000 -0400
+@@ -30,6 +30,7 @@
+ # include "config.h"
+ #endif
+ 
++#ifndef HAVE_PKCS11
+ #include "sha256.h"
+ 
+ static void
+@@ -381,3 +382,5 @@
+ 
+ /*!\}
+  */
++
++#endif /* !HAVE_PKCS11 */
+--- /export/home/wyllys/C/gnome/gnome-keyring-0.2.0/sha256.h	2003-12-05 04:01:01.000000000 -0500
++++ gnome-keyring-0.2.0/sha256.h	2004-10-27 20:34:22.044870000 -0400
+@@ -26,6 +26,10 @@
+ #ifndef _SHA256_H
+ #define _SHA256_H
+ 
++#include "config.h"
++
++#ifndef HAVE_PKCS11
++
+ #include <glib.h>
+ #include "beecrypt_compat.h"
+ 
+@@ -105,3 +109,5 @@
+ #endif
+ 
+ #endif
++
++#endif /* !HAVE_PKCS11 */
+--- gnome-keyring-0.2.0/Makefile.am-orig	2004-10-28 16:38:46.765489000 -0500
++++ gnome-keyring-0.2.0/Makefile.am	2004-10-28 16:47:12.688860000 -0500
+@@ -68,27 +68,31 @@
+ gnome_keyring_daemon_LDADD = \
+ 	libgnome-keyring-common.la \
+ 	@LIBOBJS@ \
+-	$(GLIB_LIBS)
++	$(GLIB_LIBS) \
++	$(PKCS_LIBS)
+ 
+ gnome_keyring_ask_SOURCES = \
+ 	gnome-keyring-ask.c
+ 
+ gnome_keyring_ask_LDADD = \
+-	$(GTK_LIBS)
++	$(GTK_LIBS) \
++	$(PKCS_LIBS)
+ 
+ list_keyrings_SOURCES = \
+ 	list-keyrings.c
+ 
+ list_keyrings_LDADD = \
+ 	libgnome-keyring.la \
+-	$(GTK_LIBS)
++	$(GTK_LIBS) \
++	$(PKCS_LIBS)
+ 
+ test_keyring_SOURCES = \
+ 	test.c
+ 
+ test_keyring_LDADD = \
+ 	libgnome-keyring.la \
+-	$(GTK_LIBS)
++	$(GTK_LIBS) \
++	$(PKCS_LIBS)
+ 
+ pkgconfigdir = $(libdir)/pkgconfig
+ pkgconfig_DATA = gnome-keyring-1.pc
+--- gnome-keyring-0.2.0/configure.in-orig	2004-10-28 16:38:51.292499000 -0500
++++ gnome-keyring-0.2.0/configure.in	2004-10-28 17:11:18.358127000 -0500
+@@ -98,7 +98,6 @@
+ AC_CHECK_HEADERS(fcntl.h sys/time.h time.h unistd.h)
+ AC_CHECK_FUNCS(gettimeofday)
+ 	
+-
+ AC_CHECK_LIB(socket, socket)
+ 
+ have_socket=no
+@@ -113,6 +112,25 @@
+ 	  break])
+   done
+ fi
++
++# Check for getpeerucred
++#
++AC_CHECK_FUNCS(getpeerucred, AC_DEFINE(HAVE_GETPEERUCRED,1,[Have getpeerucred]))
++
++# Check for pkcs11 library
++#
++AC_CHECK_HEADERS(security/cryptoki.h)
++have_pkcs=no
++AC_CHECK_LIB(pkcs11, C_Initialize, have_pkcs=yes)
++if test $have_pkcs = yes; then
++	AC_DEFINE(HAVE_PKCS11,1,[Have pkcs11 library])
++	PKCS_LIBS=-lpkcs11
++fi
++AC_SUBST(PKCS_LIBS)
++
++# Check for /dev/random
++#
++AC_CHECK_FILE(/dev/random, AC_DEFINE(HAVE_DEVRANDOM,1,[Have /dev/random]))
+ 		
+ dnl ==========================================================================
+