--- /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 = ¶ms;
++ 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(¶m, 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(¶m, key, 128, DECRYPT)) {
+ return FALSE;
+ }
+ for (pos = 0; pos < buffer->len; pos += 16) {
+- if (aesDecrypt (¶m, (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 (¶m, (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 ==========================================================================
+