gnome-keyring r1463 - in trunk: . egg egg/tests gcr gcr/template gcr/tests gcr/tests/test-data gp11 pkcs11/gck pkcs11/gck/tests pkcs11/roots-store pkcs11/ssh-store pkcs11/user-store
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-keyring r1463 - in trunk: . egg egg/tests gcr gcr/template gcr/tests gcr/tests/test-data gp11 pkcs11/gck pkcs11/gck/tests pkcs11/roots-store pkcs11/ssh-store pkcs11/user-store
- Date: Sun, 18 Jan 2009 22:24:09 +0000 (UTC)
Author: nnielsen
Date: Sun Jan 18 22:24:09 2009
New Revision: 1463
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1463&view=rev
Log:
* egg/egg-asn1.c:
* egg/egg-hex.c: (split from pkcs11/gck/gck-util.c)
* egg/egg-hex.h: (split from pkcs11/gck/gck-util.h)
* egg/egg-openssl.c: (moved from pkcs11/gck/gck-data-openssl.c)
* egg/egg-openssl.h: (moved from pkcs11/gck/gck-data-openssl.h)
* egg/egg-symkey.c: (split from pkcs11/gck/gck-crypto.c)
* egg/egg-symkey.h: (split from pkcs11/gck/gck-crypto.h)
* egg/Makefile.am:
* egg/tests/Makefile.am:
* egg/tests/unit-test-asn1.c:
* egg/tests/unit-test-hex.c: (moved from pkcs11/gck/tests/unit-test-util.c)
* egg/tests/unit-test-openssl.c: (moved from pkcs11/gck/tests/unit-test-data-openssl.c)
* egg/tests/unit-test-symkey.c: (split from pkcs11/gck/tests/unit-test-crypto.c)
* gcr/gcr.pc.in: (added)
* gcr/gcr-internal.c: (added)
* gcr/gcr-internal.h: (added)
* gcr/gcr-marshal.list: (added)
* gcr/gcr-parser.c: (added)
* gcr/gcr-parser.h: (added)
* gcr/gcr-types.h: (added)
* gcr/Makefile.am: (added)
* gcr/template/*: (added)
* gcr/tests/Makefile.am: (added)
* gcr/tests/unit-test-parser.c: (added)
* gcr/tests/test-data: (copied from daemon/pkix/test/test-data)
* gp11/gp11.h:
* pkcs11/gck/gck-crypto.c:
* pkcs11/gck/gck-crypto.h:
* pkcs11/gck/gck-data-der.c:
* pkcs11/gck/gck-data-der.h:
* pkcs11/gck/gck-data-file.c:
* pkcs11/gck/gck-data-openssl.c: (moved)
* pkcs11/gck/gck-data-openssl.h: (moved)
* pkcs11/gck/gck-data-pem.c: (combined into egg/egg-openssl.c)
* pkcs11/gck/gck-data-pem.c: (combined into egg/egg-openssl.h)
* pkcs11/gck/gck-util.c:
* pkcs11/gck/gck-util.h:
* pkcs11/gck/Makefile.am:
* pkcs11/gck/tests/unit-test-crypto.c:
* pkcs11/gck/tests/unit-test-data-openssl.c: (moved)
* pkcs11/gck/tests/unit-test-util.c: (moved)
* pkcs11/roots-store/gck-roots-module.c:
* pkcs11/ssh-store/gck-ssh-openssh.c:
* pkcs11/user-store/gck-user-storage.c:
* configure.in:
* Makefile.am: Add new gcr library for crypto UI and related tasks. Implement
GckParser class.
Added:
trunk/egg/egg-hex.c (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/gck-util.c
trunk/egg/egg-hex.h (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/gck-util.h
trunk/egg/egg-openssl.c (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/gck-data-openssl.c
trunk/egg/egg-openssl.h (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/gck-data-openssl.h
trunk/egg/egg-symkey.c (contents, props changed)
- copied, changed from r1461, /trunk/pkcs11/gck/gck-crypto.c
trunk/egg/egg-symkey.h (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/gck-crypto.h
trunk/egg/tests/unit-test-hex.c (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/tests/unit-test-util.c
trunk/egg/tests/unit-test-openssl.c (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/tests/unit-test-data-openssl.c
trunk/egg/tests/unit-test-symkey.c (contents, props changed)
- copied, changed from r1460, /trunk/pkcs11/gck/tests/unit-test-crypto.c
trunk/gcr/ (props changed)
trunk/gcr/Makefile.am
trunk/gcr/gcr-import-dialog.glade
trunk/gcr/gcr-importer.c
trunk/gcr/gcr-importer.h
trunk/gcr/gcr-internal.c
trunk/gcr/gcr-internal.h
trunk/gcr/gcr-marshal.list
trunk/gcr/gcr-parser.c
trunk/gcr/gcr-parser.h
trunk/gcr/gcr-types.h
trunk/gcr/gcr.pc.in
trunk/gcr/template/
trunk/gcr/template/gcr-xxx.c
trunk/gcr/template/gcr-xxx.h
trunk/gcr/tests/ (props changed)
trunk/gcr/tests/Makefile.am
trunk/gcr/tests/test-data/ (props changed)
- copied from r1460, /trunk/daemon/pkix/tests/test-data/
trunk/gcr/tests/unit-test-parser.c (contents, props changed)
- copied, changed from r1461, /trunk/daemon/pkix/tests/unit-test-pkix-parser.c
Removed:
trunk/pkcs11/gck/gck-data-openssl.c
trunk/pkcs11/gck/gck-data-openssl.h
trunk/pkcs11/gck/gck-data-pem.c
trunk/pkcs11/gck/gck-data-pem.h
trunk/pkcs11/gck/tests/unit-test-data-openssl.c
trunk/pkcs11/gck/tests/unit-test-util.c
Modified:
trunk/ChangeLog
trunk/Makefile.am
trunk/configure.in
trunk/egg/Makefile.am
trunk/egg/egg-asn1.c
trunk/egg/tests/Makefile.am
trunk/egg/tests/unit-test-asn1.c
trunk/gp11/gp11.h
trunk/pkcs11/gck/Makefile.am
trunk/pkcs11/gck/gck-crypto.c
trunk/pkcs11/gck/gck-crypto.h
trunk/pkcs11/gck/gck-data-der.c
trunk/pkcs11/gck/gck-data-der.h
trunk/pkcs11/gck/gck-data-file.c
trunk/pkcs11/gck/gck-util.c
trunk/pkcs11/gck/gck-util.h
trunk/pkcs11/gck/tests/Makefile.am
trunk/pkcs11/gck/tests/unit-test-crypto.c
trunk/pkcs11/roots-store/gck-roots-module.c
trunk/pkcs11/ssh-store/gck-ssh-openssh.c
trunk/pkcs11/user-store/gck-user-storage.c
Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am (original)
+++ trunk/Makefile.am Sun Jan 18 22:24:09 2009
@@ -14,6 +14,7 @@
. \
gp11 \
egg \
+ gcr \
common \
library \
pkcs11 \
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Sun Jan 18 22:24:09 2009
@@ -4,12 +4,16 @@
AM_CONFIG_HEADER(config.h)
dnl ****************************************************************************
-dnl GP11 library libtool versioning
+dnl Library libtool versioning
GP11_MAJOR=0 # Increment for major version number, breaks old apps.
GP11_REVISION=0 # Increment for internal changes, nothing affected.
GP11_AGE=0 # Increment for interface that doesn't break anything
+GCR_MAJOR=0 # Increment for major version number, breaks old apps.
+GCR_REVISION=0 # Increment for internal changes, nothing affected.
+GCR_AGE=0 # Increment for interface that doesn't break anything
+
dnl ****************************************************************************
AM_SANITY_CHECK
@@ -469,6 +473,10 @@
AC_SUBST(GP11_LT_RELEASE)
AC_SUBST(GP11_MAJOR)
+GCR_LT_RELEASE=$GCR_MAJOR:$GCR_REVISION:$GCR_AGE
+AC_SUBST(GCR_LT_RELEASE)
+AC_SUBST(GCR_MAJOR)
+
AC_SUBST(DAEMON_CFLAGS)
AC_SUBST(DAEMON_LIBS)
@@ -497,6 +505,9 @@
daemon/ui/Makefile
egg/Makefile
egg/tests/Makefile
+gcr/gcr.pc
+gcr/Makefile
+gcr/tests/Makefile
gp11/gp11.pc
gp11/Makefile
gp11/reference/Makefile
Modified: trunk/egg/Makefile.am
==============================================================================
--- trunk/egg/Makefile.am (original)
+++ trunk/egg/Makefile.am Sun Jan 18 22:24:09 2009
@@ -19,8 +19,11 @@
libegg_la_SOURCES = \
egg-asn1.c egg-asn1.h \
egg-buffer.c egg-buffer.h \
+ egg-hex.c egg-hex.h \
+ egg-openssl.c egg-openssl.h \
egg-unix-credentials.c egg-unix-credentials.h \
- egg-secure-memory.c egg-secure-memory.h
+ egg-secure-memory.c egg-secure-memory.h \
+ egg-symkey.c egg-symkey.h
asn1-def-pk.h: pk.asn
asn1Parser -o asn1-def-pk.h pk.asn
Modified: trunk/egg/egg-asn1.c
==============================================================================
--- trunk/egg/egg-asn1.c (original)
+++ trunk/egg/egg-asn1.c Sun Jan 18 22:24:09 2009
@@ -335,12 +335,9 @@
if (!buf)
return 0;
- quark = g_quark_try_string ((gchar*)buf);
+ quark = g_quark_from_string ((gchar*)buf);
g_free (buf);
- if (quark == 0)
- quark = g_quark_from_static_string ("0.UNKNOWN.OID");
-
return quark;
}
Copied: trunk/egg/egg-hex.c (from r1460, /trunk/pkcs11/gck/gck-util.c)
==============================================================================
--- /trunk/pkcs11/gck/gck-util.c (original)
+++ trunk/egg/egg-hex.c Sun Jan 18 22:24:09 2009
@@ -21,77 +21,14 @@
#include "config.h"
-#include "gck-util.h"
+#include "egg-hex.h"
-#include <stdio.h>
#include <string.h>
-/* Only access using atomic operations */
-static gint next_handle = 0x00000010;
-
static const char HEXC[] = "0123456789ABCDEF";
-gulong*
-gck_util_ulong_alloc (gulong value)
-{
- return g_slice_dup (gulong, &value);
-}
-
-void
-gck_util_ulong_free (gpointer ptr_to_ulong)
-{
- g_slice_free (gulong, ptr_to_ulong);
-}
-
-guint
-gck_util_ulong_hash (gconstpointer v)
-{
- const signed char *p = v;
- guint32 i, h = *p;
- for(i = 0; i < sizeof (gulong); ++i)
- h = (h << 5) - h + *(p++);
- return h;
-}
-
-gboolean
-gck_util_ulong_equal (gconstpointer v1, gconstpointer v2)
-{
- return *((const gulong*)v1) == *((const gulong*)v2);
-}
-
-CK_RV
-gck_util_return_data (CK_VOID_PTR output, CK_ULONG_PTR n_output,
- gconstpointer input, gsize n_input)
-{
- g_return_val_if_fail (n_output, CKR_GENERAL_ERROR);
- g_return_val_if_fail (input || !n_input, CKR_GENERAL_ERROR);
-
- /* Just asking for the length */
- if (!output) {
- *n_output = n_input;
- return CKR_OK;
- }
-
- /* Buffer is too short */
- if (n_input > *n_output) {
- *n_output = n_input;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- *n_output = n_input;
- if (n_input)
- memcpy (output, input, n_input);
- return CKR_OK;
-}
-
-CK_ULONG
-gck_util_next_handle (void)
-{
- return (CK_ULONG)g_atomic_int_exchange_and_add (&next_handle, 1);
-}
-
guchar*
-gck_util_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
+egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
{
guchar *result;
guchar *decoded;
@@ -142,7 +79,7 @@
}
gchar*
-gck_util_hex_encode (const guchar *data, gsize n_data)
+egg_hex_encode (const guchar *data, gsize n_data)
{
gchar *result, *encoded;
guchar j;
Copied: trunk/egg/egg-hex.h (from r1460, /trunk/pkcs11/gck/gck-util.h)
==============================================================================
--- /trunk/pkcs11/gck/gck-util.h (original)
+++ trunk/egg/egg-hex.h Sun Jan 18 22:24:09 2009
@@ -19,39 +19,16 @@
* 02111-1307, USA.
*/
-#ifndef GCKUTIL_H_
-#define GCKUTIL_H_
+#ifndef EGG_HEX_H_
+#define EGG_HEX_H_
#include <glib.h>
-#include <gcrypt.h>
-
-#include "pkcs11/pkcs11.h"
-
-guint gck_util_ulong_hash (gconstpointer ptr_to_ulong);
-
-gboolean gck_util_ulong_equal (gconstpointer ptr_to_ulong_1,
- gconstpointer ptr_to_ulong_2);
-
-gulong* gck_util_ulong_alloc (gulong value);
-
-void gck_util_ulong_free (gpointer ptr_to_ulong);
-
-CK_RV gck_util_return_data (CK_VOID_PTR output,
- CK_ULONG_PTR n_output,
- gconstpointer input,
- gsize n_input);
-
-CK_RV gck_attribute_set_mpi (CK_ATTRIBUTE_PTR attr,
- gcry_mpi_t mpi);
-
-CK_ULONG gck_util_next_handle (void);
-
-guchar* gck_util_hex_decode (const gchar *data,
+guchar* egg_hex_decode (const gchar *data,
gssize n_data,
gsize *n_decoded);
-gchar* gck_util_hex_encode (const guchar *data,
+gchar* egg_hex_encode (const guchar *data,
gsize n_data);
-#endif /* GCKUTIL_H_ */
+#endif /* EGG_HEX_H_ */
Copied: trunk/egg/egg-openssl.c (from r1460, /trunk/pkcs11/gck/gck-data-openssl.c)
==============================================================================
--- /trunk/pkcs11/gck/gck-data-openssl.c (original)
+++ trunk/egg/egg-openssl.c Sun Jan 18 22:24:09 2009
@@ -1,5 +1,5 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gck-data-openssl.c - OpenSSL compatibility functionality
+/* egg-openssl.c - OpenSSL compatibility functionality
Copyright (C) 2007 Stefan Walter
@@ -23,15 +23,331 @@
#include "config.h"
-#include "gck-crypto.h"
-#include "gck-data-openssl.h"
-#include "gck-util.h"
+#include "egg-hex.h"
+#include "egg-openssl.h"
+#include "egg-secure-memory.h"
+#include "egg-symkey.h"
#include <gcrypt.h>
#include <libtasn1.h>
#include <glib.h>
+#include <ctype.h>
+#include <string.h>
+
+/*
+ * PEM looks like:
+ *
+ * -----BEGIN RSA PRIVATE KEY-----
+ * Proc-Type: 4,ENCRYPTED
+ * DEK-Info: DES-EDE3-CBC,704CFFD62FBA03E9
+ *
+ * 4AV/g0BiTeb07hzo4/Ct47HGhHEshMhBPGJ843QzuAinpZBbg3OxwPsQsLgoPhJL
+ * Bg6Oxyz9M4UN1Xlx6Lyo2lRT908mBP6dl/OItLsVArqAzM+e29KHQVNjV1h7xN9F
+ * u84tOgZftKun+ZkQUOoRvMLLu4yV4CUraks9tgyXquugGba/tbeyj2MYsC8wwSJX
+ * ....
+ * -----END RSA PRIVATE KEY-----
+ */
+
+#define PEM_SUFF "-----"
+#define PEM_SUFF_L 5
+#define PEM_PREF_BEGIN "-----BEGIN "
+#define PEM_PREF_BEGIN_L 11
+#define PEM_PREF_END "-----END "
+#define PEM_PREF_END_L 9
+
+static void
+parse_header_lines (const gchar *hbeg, const gchar *hend, GHashTable **result)
+{
+ gchar **lines, **l;
+ gchar *line, *name, *value;
+ gchar *copy;
+
+ copy = g_strndup (hbeg, hend - hbeg);
+ lines = g_strsplit (copy, "\n", 0);
+ g_free (copy);
+
+ for (l = lines; l && *l; ++l) {
+ line = *l;
+ g_strstrip (line);
+
+ /* Look for the break between name: value */
+ value = strchr (line, ':');
+ if (value == NULL)
+ continue;
+
+ *value = 0;
+ value = g_strdup (value + 1);
+ g_strstrip (value);
+
+ name = g_strdup (line);
+ g_strstrip (name);
+
+ if (!*result)
+ *result = egg_openssl_headers_new ();
+ g_hash_table_replace (*result, name, value);
+ }
+
+ g_strfreev (lines);
+}
+
+static const gchar*
+pem_find_begin (const gchar *data, gsize n_data, GQuark *type)
+{
+ const gchar *pref, *suff;
+ gchar *stype;
+
+ /* Look for a prefix */
+ pref = g_strstr_len ((gchar*)data, n_data, PEM_PREF_BEGIN);
+ if (!pref)
+ return NULL;
+
+ n_data -= (pref - data) + PEM_PREF_BEGIN_L;
+ data = pref + PEM_PREF_BEGIN_L;
+
+ /* Look for the end of that begin */
+ suff = g_strstr_len ((gchar*)data, n_data, PEM_SUFF);
+ if (!suff)
+ return NULL;
+
+ /* Make sure on the same line */
+ if (memchr (pref, '\n', suff - pref))
+ return NULL;
+
+ if (type) {
+ *type = 0;
+ pref += PEM_PREF_BEGIN_L;
+ g_assert (suff > pref);
+ stype = g_alloca (suff - pref + 1);
+ memcpy (stype, pref, suff - pref);
+ stype[suff - pref] = 0;
+ *type = g_quark_from_string (stype);
+ }
+
+ /* The byte after this ---BEGIN--- */
+ return suff + PEM_SUFF_L;
+}
+
+static const gchar*
+pem_find_end (const gchar *data, gsize n_data, GQuark type)
+{
+ const gchar *stype;
+ const gchar *pref;
+ gsize n_type;
+
+ /* Look for a prefix */
+ pref = g_strstr_len (data, n_data, PEM_PREF_END);
+ if (!pref)
+ return NULL;
+
+ n_data -= (pref - data) + PEM_PREF_END_L;
+ data = pref + PEM_PREF_END_L;
+
+ /* Next comes the type string */
+ stype = g_quark_to_string (type);
+ n_type = strlen (stype);
+ if (strncmp ((gchar*)data, stype, n_type) != 0)
+ return NULL;
+
+ n_data -= n_type;
+ data += n_type;
+
+ /* Next comes the suffix */
+ if (strncmp ((gchar*)data, PEM_SUFF, PEM_SUFF_L) != 0)
+ return NULL;
+
+ /* The beginning of this ---END--- */
+ return pref;
+}
+
+static gboolean
+pem_parse_block (const gchar *data, gsize n_data, guchar **decoded, gsize *n_decoded,
+ GHashTable **headers)
+{
+ const gchar *x, *hbeg, *hend;
+ const gchar *p, *end;
+ gint state = 0;
+ guint save = 0;
+
+ g_assert (data);
+ g_assert (n_data);
+
+ g_assert (decoded);
+ g_assert (n_decoded);
+
+ p = data;
+ end = p + n_data;
+
+ hbeg = hend = NULL;
+
+ /* Try and find a pair of blank lines with only white space between */
+ while (hend == NULL) {
+ x = memchr (p, '\n', end - p);
+ if (!x)
+ break;
+ ++x;
+ while (isspace (*x)) {
+ /* Found a second line, with only spaces between */
+ if (*x == '\n') {
+ hbeg = data;
+ hend = x;
+ break;
+ /* Found a space between two lines */
+ } else {
+ ++x;
+ }
+ }
+
+ /* Try next line */
+ p = x;
+ }
+
+ /* Headers found? */
+ if (hbeg && hend) {
+ data = hend;
+ n_data = end - data;
+ }
+
+ *n_decoded = (n_data * 3) / 4 + 1;
+ if (egg_secure_check (data))
+ *decoded = egg_secure_alloc (*n_decoded);
+ else
+ *decoded = g_malloc0 (*n_decoded);
+ g_return_val_if_fail (*decoded, FALSE);
+
+ *n_decoded = g_base64_decode_step (data, n_data, *decoded, &state, &save);
+ if (!*n_decoded) {
+ egg_secure_free (*decoded);
+ return FALSE;
+ }
+
+ if (headers && hbeg && hend)
+ parse_header_lines (hbeg, hend, headers);
+
+ return TRUE;
+}
+
+GHashTable*
+egg_openssl_headers_new (void)
+{
+ return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+guint
+egg_openssl_pem_parse (const guchar *data, gsize n_data,
+ EggOpensslPemCallback callback, gpointer user_data)
+{
+ const gchar *beg, *end;
+ guint nfound = 0;
+ guchar *decoded = NULL;
+ gsize n_decoded = 0;
+ GHashTable *headers = NULL;
+ GQuark type;
+
+ g_return_val_if_fail (data, 0);
+ g_return_val_if_fail (n_data, 0);
+ g_return_val_if_fail (callback, 0);
+
+ while (n_data > 0) {
+
+ /* This returns the first character after the PEM BEGIN header */
+ beg = pem_find_begin ((const gchar*)data, n_data, &type);
+ if (!beg)
+ break;
+
+ g_assert (type);
+
+ /* This returns the character position before the PEM END header */
+ end = pem_find_end ((const gchar*)beg, n_data - ((const guchar*)beg - data), type);
+ if (!end)
+ break;
+
+ if (beg != end) {
+ if (pem_parse_block (beg, end - beg, &decoded, &n_decoded, &headers)) {
+ (callback) (type, decoded, n_decoded, headers, user_data);
+ ++nfound;
+ egg_secure_free (decoded);
+ if (headers)
+ g_hash_table_remove_all (headers);
+ }
+ }
+
+ /* Try for another block */
+ end += PEM_SUFF_L;
+ n_data -= (const guchar*)end - data;
+ data = (const guchar*)end;
+ }
+
+ if (headers)
+ g_hash_table_destroy (headers);
+
+ return nfound;
+}
+
+#ifdef UNTESTED_CODE
+
+static void
+append_each_header (gpointer key, gpointer value, gpointer user_data)
+{
+ GString *string = (GString*)user_data;
+
+ g_string_append (string, (gchar*)key);
+ g_string_append (string, ": ");
+ g_string_append (string, (gchar*)value);
+ g_string_append_c (string, '\n');
+}
+
+guchar*
+egg_openssl_pem_write (const guchar *data, gsize n_data, GQuark type,
+ GHashTable *headers, gsize *n_result)
+{
+ GString *string;
+ gint state, save;
+ gsize length, n_prefix;
+
+ g_return_val_if_fail (data || !n_data, NULL);
+ g_return_val_if_fail (type, NULL);
+ g_return_val_if_fail (n_result, NULL);
+
+ string = g_string_sized_new (4096);
+
+ /* The prefix */
+ g_string_append_len (string, PEM_PREF_BEGIN, PEM_PREF_BEGIN_L);
+ g_string_append (string, g_quark_to_string (type));
+ g_string_append_len (string, PEM_SUFF, PEM_SUFF_L);
+ g_string_append_c (string, '\n');
+
+ /* The headers */
+ if (headers && g_hash_table_size (headers) > 0) {
+ g_hash_table_foreach (headers, append_each_header, string);
+ g_string_append_c (string, '\n');
+ }
+
+ /* Resize string to fit the base64 data. Algorithm from Glib reference */
+ length = n_data * 4 / 3 + n_data * 4 / (3 * 72) + 7;
+ n_prefix = string->len;
+ g_string_set_size (string, n_prefix + length);
+
+ /* The actual base64 data */
+ state = save = 0;
+ length = g_base64_encode_step (data, n_data, TRUE,
+ string->str + string->len, &state, &save);
+ g_string_set_size (string, n_prefix + length);
+
+ /* The suffix */
+ g_string_append_c (string, '\n');
+ g_string_append_len (string, PEM_PREF_END, PEM_PREF_END_L);
+ g_string_append (string, g_quark_to_string (type));
+ g_string_append_len (string, PEM_SUFF, PEM_SUFF_L);
+ g_string_append_c (string, '\n');
+
+ *n_result = string->len;
+ return (guchar*)g_string_free (string, FALSE);
+}
+
+#endif /* UNTESTED_CODE */
+
/* ----------------------------------------------------------------------------
* DEFINITIONS
*/
@@ -137,7 +453,7 @@
/* ------------------------------------------------------------------------- */
int
-gck_data_openssl_parse_algo (const char *name, int *mode)
+egg_openssl_parse_algo (const char *name, int *mode)
{
static GQuark openssl_quarks[G_N_ELEMENTS(openssl_algos)] = { 0, };
static gsize openssl_quarks_inited = 0;
@@ -176,7 +492,7 @@
goto done;
/* Parse the algorithm name */
- *algo = gck_data_openssl_parse_algo (parts[0], mode);
+ *algo = egg_openssl_parse_algo (parts[0], mode);
if (!*algo)
goto done;
@@ -188,7 +504,7 @@
/* Parse the IV */
ivlen = gcry_cipher_get_algo_blklen (*algo);
- *iv = gck_util_hex_decode (parts[1], strlen(parts[1]), &len);
+ *iv = egg_hex_decode (parts[1], strlen(parts[1]), &len);
if (!*iv || ivlen != len) {
g_free (*iv);
goto done;
@@ -201,10 +517,10 @@
return success;
}
-GckDataResult
-gck_data_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **decrypted, gsize *n_decrypted)
+gboolean
+egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
+ gssize n_password, const guchar *data, gsize n_data,
+ guchar **decrypted, gsize *n_decrypted)
{
gcry_cipher_hd_t ch;
guchar *key = NULL;
@@ -214,7 +530,7 @@
int mode = 0;
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
- return GCK_DATA_UNRECOGNIZED;
+ return FALSE;
ivlen = gcry_cipher_get_algo_blklen (algo);
@@ -222,42 +538,42 @@
g_return_val_if_fail (ivlen >= 8, FALSE);
/* IV is already set from the DEK info */
- if (!gck_crypto_symkey_generate_simple (algo, GCRY_MD_MD5, password,
+ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
n_password, iv, 8, 1, &key, NULL)) {
g_free (iv);
- return GCK_DATA_FAILURE;
+ return FALSE;
}
/* TODO: Use secure memory */
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, GCK_DATA_FAILURE);
+ g_return_val_if_fail (!gcry, FALSE);
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, GCK_DATA_UNRECOGNIZED);
- gcry_free (key);
+ g_return_val_if_fail (!gcry, FALSE);
+ egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, GCK_DATA_UNRECOGNIZED);
+ g_return_val_if_fail (!gcry, FALSE);
g_free (iv);
/* Allocate output area */
*n_decrypted = n_data;
- *decrypted = gcry_calloc_secure (n_data, 1);
+ *decrypted = egg_secure_alloc (n_data);
gcry = gcry_cipher_decrypt (ch, *decrypted, *n_decrypted, (void*)data, n_data);
if (gcry) {
- gcry_free (*decrypted);
- g_return_val_if_reached (GCK_DATA_FAILURE);
+ egg_secure_free (*decrypted);
+ g_return_val_if_reached (FALSE);
}
gcry_cipher_close (ch);
- return GCK_DATA_SUCCESS;
+ return TRUE;
}
gboolean
-gck_data_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
+egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
gssize n_password, const guchar *data, gsize n_data,
guchar **encrypted, gsize *n_encrypted)
{
@@ -279,7 +595,7 @@
g_return_val_if_fail (ivlen >= 8, FALSE);
/* IV is already set from the DEK info */
- if (!gck_crypto_symkey_generate_simple (algo, GCRY_MD_MD5, password,
+ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
n_password, iv, 8, 1, &key, NULL))
g_return_val_if_reached (FALSE);
@@ -288,7 +604,7 @@
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
g_return_val_if_fail (!gcry, FALSE);
- gcry_free (key);
+ egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
@@ -315,11 +631,11 @@
/* Encrypt the padded block */
if (n_overflow) {
- padded = gcry_calloc_secure (ivlen, 1);
+ padded = egg_secure_alloc (ivlen);
memset (padded, 0, ivlen);
memcpy (padded, data + n_batch, n_overflow);
gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen);
- gcry_free (padded);
+ egg_secure_free (padded);
if (gcry) {
g_free (*encrypted);
g_return_val_if_reached (FALSE);
@@ -331,7 +647,7 @@
}
const gchar*
-gck_data_openssl_get_dekinfo (GHashTable *headers)
+egg_openssl_get_dekinfo (GHashTable *headers)
{
const gchar *val;
if (!headers)
@@ -345,7 +661,7 @@
}
const gchar*
-gck_data_openssl_prep_dekinfo (GHashTable *headers)
+egg_openssl_prep_dekinfo (GHashTable *headers)
{
gchar *dekinfo, *hex;
gsize ivlen;
@@ -358,7 +674,7 @@
gcry_create_nonce (iv, ivlen);
/* And encode it into the string */
- hex = gck_util_hex_encode (iv, ivlen);
+ hex = egg_hex_encode (iv, ivlen);
g_return_val_if_fail (hex, NULL);
dekinfo = g_strdup_printf ("DES-EDE3-CBC,%s", hex);
g_free (hex);
Copied: trunk/egg/egg-openssl.h (from r1460, /trunk/pkcs11/gck/gck-data-openssl.h)
==============================================================================
--- /trunk/pkcs11/gck/gck-data-openssl.h (original)
+++ trunk/egg/egg-openssl.h Sun Jan 18 22:24:09 2009
@@ -1,5 +1,5 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gck-data-openssl.h - OpenSSL compatibility functionality
+/* egg-openssl.h - OpenSSL compatibility functionality
Copyright (C) 2007 Stefan Walter
@@ -21,23 +21,36 @@
Author: Stef Walter <stef memberwebs com>
*/
-#ifndef GCKDATAOPENSSL_H_
-#define GCKDATAOPENSSL_H_
+#ifndef EGG_OPENSSL_H_
+#define EGG_OPENSSL_H_
-#include "gck-data-types.h"
+#include <glib.h>
-int gck_data_openssl_parse_algo (const gchar *name, int *mode);
+typedef void (*EggOpensslPemCallback) (GQuark type, const guchar *data, gsize n_data,
+ GHashTable *headers, gpointer user_data);
-gboolean gck_data_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **encrypted, gsize *n_encrypted);
+GHashTable* egg_openssl_headers_new (void);
-GckDataResult gck_data_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **decrypted, gsize *n_decrypted);
+guint egg_openssl_pem_parse (const guchar *data, gsize n_data,
+ EggOpensslPemCallback callback,
+ gpointer user_data);
-const gchar* gck_data_openssl_get_dekinfo (GHashTable *headers);
+guchar* egg_openssl_pem_write (const guchar *data, gsize n_data,
+ GQuark type, GHashTable *headers,
+ gsize *n_result);
-const gchar* gck_data_openssl_prep_dekinfo (GHashTable *headers);
+int egg_openssl_parse_algo (const gchar *name, int *mode);
-#endif /* GCKDATAOPENSSL_H_ */
+gboolean egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
+ gssize n_password, const guchar *data, gsize n_data,
+ guchar **encrypted, gsize *n_encrypted);
+
+gboolean egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
+ gssize n_password, const guchar *data, gsize n_data,
+ guchar **decrypted, gsize *n_decrypted);
+
+const gchar* egg_openssl_get_dekinfo (GHashTable *headers);
+
+const gchar* egg_openssl_prep_dekinfo (GHashTable *headers);
+
+#endif /* EGG_OPENSSL_H_ */
Copied: trunk/egg/egg-symkey.c (from r1461, /trunk/pkcs11/gck/gck-crypto.c)
==============================================================================
--- /trunk/pkcs11/gck/gck-crypto.c (original)
+++ trunk/egg/egg-symkey.c Sun Jan 18 22:24:09 2009
@@ -21,960 +21,72 @@
#include "config.h"
-#include "gck-crypto.h"
+#include "egg-asn1.h"
+#include "egg-secure-memory.h"
+#include "egg-symkey.h"
-#include "egg/egg-secure-memory.h"
-
-/* ----------------------------------------------------------------------------
- * INTERNAL
+/* -----------------------------------------------------------------------------
+ * QUARKS
*/
-static gcry_sexp_t
-sexp_get_childv (gcry_sexp_t sexp, va_list va)
-{
- gcry_sexp_t at = NULL;
- gcry_sexp_t child;
- const char *name;
-
- for(;;) {
- name = va_arg (va, const char*);
- if (!name)
- break;
-
- child = gcry_sexp_find_token (at ? at : sexp, name, 0);
- gcry_sexp_release (at);
- at = child;
- if (at == NULL)
- break;
- }
-
- va_end (va);
-
- return at;
-}
-
-static CK_RV
-data_to_sexp (const gchar *format, guint nbits, GckCryptoPadding padding,
- CK_BYTE_PTR data, CK_ULONG n_data, gcry_sexp_t *sexp)
-{
- guchar *padded = NULL;
- gcry_error_t gcry;
- gcry_mpi_t mpi;
- gsize n_padded;
-
- g_assert (format);
- g_assert (sexp);
-
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (padding) {
- padded = (padding) (nbits, data, n_data, &n_padded);
- if (!padded)
- return CKR_DATA_LEN_RANGE;
- }
-
- /* Prepare the input s expression */
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG,
- padded ? padded : data,
- padded ? n_padded : n_data, NULL);
- g_free (padded);
-
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- gcry = gcry_sexp_build (sexp, NULL, format, mpi);
- gcry_mpi_release (mpi);
-
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- g_assert (*sexp);
- return CKR_OK;
-}
-
-/* For the sake of checking arguments */
-static CK_RV
-sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
- CK_ULONG *n_data, GckCryptoPadding padding,
- ...) G_GNUC_NULL_TERMINATED;
-
-static CK_RV
-sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
- CK_ULONG *n_data, GckCryptoPadding padding, ...)
-{
- gcry_sexp_t at = NULL;
- gsize n_block, offset, len;
- gcry_mpi_t mpi = NULL;
- guchar *block;
- va_list va;
- gcry_error_t gcry;
-
- g_assert (sexp);
- g_assert (data);
- g_assert (n_data);
- g_assert (bits);
-
- /* First try and dig out sexp child based on arguments */
- va_start (va, padding);
- at = sexp_get_childv (sexp, va);
- va_end (va);
-
- /* It's expected we would find it */
- g_return_val_if_fail (at != NULL, CKR_GENERAL_ERROR);
-
- /* Parse out the MPI */
- mpi = gcry_sexp_nth_mpi (at, 1, GCRYMPI_FMT_USG);
- g_return_val_if_fail (at != NULL, CKR_GENERAL_ERROR);
- gcry_sexp_release (at);
-
- /* Print out the MPI into the end of a temporary buffer */
- n_block = (bits + 7) / 8;
- gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &len, mpi);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- g_return_val_if_fail (len <= n_block, CKR_GENERAL_ERROR);
- offset = n_block - len;
- block = g_malloc0 (n_block);
- memset (block, 0, offset);
- gcry = gcry_mpi_print (GCRYMPI_FMT_USG, block + offset, len, &len, mpi);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- g_return_val_if_fail (len == n_block - offset, CKR_GENERAL_ERROR);
- gcry_mpi_release (mpi);
-
- /* Pad it properly if necessary */
- if (padding != NULL) {
- guchar *padded = (padding) (bits, block, n_block, &n_block);
- g_free (block);
- if (!padded)
- return CKR_DATA_LEN_RANGE;
- block = padded;
- }
-
- /* Now stuff it into the output buffer */
- if (n_block > *n_data)
- return CKR_BUFFER_TOO_SMALL;
-
- memcpy (data, block, n_block);
- *n_data = n_block;
- g_free (block);
-
- return CKR_OK;
-}
+static GQuark OID_PBE_MD2_DES_CBC;
+static GQuark OID_PBE_MD5_DES_CBC;
+static GQuark OID_PBE_MD2_RC2_CBC;
+static GQuark OID_PBE_MD5_RC2_CBC;
+static GQuark OID_PBE_SHA1_DES_CBC;
+static GQuark OID_PBE_SHA1_RC2_CBC;
+static GQuark OID_PBES2;
+static GQuark OID_PBKDF2;
+
+static GQuark OID_DES_CBC;
+static GQuark OID_DES_RC2_CBC;
+static GQuark OID_DES_EDE3_CBC;
+static GQuark OID_DES_RC5_CBC;
+
+static GQuark OID_PKCS12_PBE_ARCFOUR_SHA1;
+static GQuark OID_PKCS12_PBE_RC4_40_SHA1;
+static GQuark OID_PKCS12_PBE_3DES_SHA1;
+static GQuark OID_PKCS12_PBE_2DES_SHA1;
+static GQuark OID_PKCS12_PBE_RC2_128_SHA1;
+static GQuark OID_PKCS12_PBE_RC2_40_SHA1;
static void
-fill_random_nonzero (guchar *data, gsize n_data)
-{
- guchar *rnd;
- guint n_zero, i, j;
-
- gcry_randomize (data, n_data, GCRY_STRONG_RANDOM);
-
- /* Find any zeros in random data */
- n_zero = 0;
- for (i = 0; i < n_data; ++i) {
- if (data[i] == 0x00)
- ++n_zero;
- }
-
- while (n_zero > 0) {
- rnd = gcry_random_bytes (n_zero, GCRY_STRONG_RANDOM);
- n_zero = 0;
- for (i = 0, j = 0; i < n_data; ++i) {
- if (data[i] != 0x00)
- continue;
-
- /* Use some of the replacement data */
- data[i] = rnd[j];
- ++j;
-
- /* It's zero again :( */
- if (data[i] == 0x00)
- n_zero++;
- }
-
- gcry_free (rnd);
- }
-}
-
-static guchar*
-unpad_rsa_pkcs1 (guchar bt, guint n_modulus, const guchar* padded,
- gsize n_padded, gsize *n_raw)
-{
- const guchar *at;
- guchar *raw;
-
- /* The absolute minimum size including padding */
- g_return_val_if_fail (n_modulus / 8 >= 3 + 8, NULL);
-
- if (n_padded != n_modulus / 8)
- return NULL;
-
- /* Check the header */
- if (padded[0] != 0x00 || padded[1] != bt)
- return NULL;
-
- /* The first zero byte after the header */
- at = memchr (padded + 2, 0x00, n_padded - 2);
- if (!at)
- return NULL;
-
- ++at;
- *n_raw = n_padded - (at - padded);
- raw = g_new0 (guchar, *n_raw);
- memcpy (raw, at, *n_raw);
- return raw;
-}
-
-
-/* ----------------------------------------------------------------------------
- * PUBLIC
- */
-
-CK_RV
-gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
-{
- int algorithm;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
- g_return_val_if_reached (CKR_GENERAL_ERROR);
-
- /*
- * The algorithm checks below are merely sanity checks.
- * Other code should have checed this at an earlier stage
- * and return the right error codes if invalid.
- */
-
- switch (mech) {
- case CKM_RSA_PKCS:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_encrypt_rsa (sexp, gck_crypto_rsa_pad_two, data, n_data, encrypted, n_encrypted);
- break;
- case CKM_RSA_X_509:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_encrypt_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, encrypted, n_encrypted);
- break;
- default:
- /* Again shouldn't be reached */
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- };
-
- return rv;
-}
-
-CK_RV
-gck_crypto_encrypt_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
-{
- gcry_sexp_t splain, sdata;
- gcry_error_t gcry;
- guint nbits;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- /* Just want to know the length */
- if (!encrypted) {
- *n_encrypted = (nbits + 7) / 8;
- return CKR_OK;
- }
-
- /* Prepare the input s expression */
- rv = data_to_sexp ("(data (flags raw) (value %m))",
- nbits, padding, data, n_data, &splain);
- if (rv != CKR_OK)
- return rv;
-
- /* Do the magic */
- gcry = gcry_pk_encrypt (&sdata, splain, sexp);
- gcry_sexp_release (splain);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("encrypting of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- /* Now extract and send it back out */
- rv = sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL, "enc-val", "rsa", "a", NULL);
- gcry_sexp_release (sdata);
-
- return rv;
-}
-
-CK_RV
-gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
-{
- int algorithm;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
-
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
- g_return_val_if_reached (CKR_GENERAL_ERROR);
-
- /*
- * The algorithm checks below are merely sanity checks.
- * Other code should have checed this at an earlier stage
- * and return the right error codes if invalid.
- */
-
- switch (mech) {
- case CKM_RSA_PKCS:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_decrypt_rsa (sexp, gck_crypto_rsa_unpad_two, encrypted, n_encrypted, data, n_data);
- break;
- case CKM_RSA_X_509:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_decrypt_rsa (sexp, NULL, encrypted, n_encrypted, data, n_data);
- break;
- default:
- /* Again shouldn't be reached */
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- };
-
- return rv;
-}
-
-CK_RV
-gck_crypto_decrypt_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
-{
- gcry_sexp_t splain, sdata;
- gcry_error_t gcry;
- guint nbits;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
-
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- /* Just want to know the length */
- if (!data) {
- *n_data = (nbits + 7) / 8;
- return CKR_OK;
- }
-
- if (n_encrypted != (nbits + 7) / 8)
- return CKR_DATA_LEN_RANGE;
-
- /* Prepare the input s expression */
- rv = data_to_sexp ("(enc-val (flags) (rsa (a %m)))",
- nbits, NULL, encrypted, n_encrypted, &sdata);
- if (rv != CKR_OK)
- return rv;
-
- /* Do the magic */
- gcry = gcry_pk_decrypt (&splain, sdata, sexp);
- gcry_sexp_release (sdata);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("decrypting of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- /* Now extract and send it back out */
- rv = sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
- gcry_sexp_release (splain);
-
- return rv;
-}
-
-CK_RV
-gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
- int algorithm;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
- g_return_val_if_reached (CKR_GENERAL_ERROR);
-
- /*
- * The algorithm checks below are merely sanity checks.
- * Other code should have checed this at an earlier stage
- * and return the right error codes if invalid.
- */
-
- switch (mech) {
- case CKM_RSA_PKCS:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_sign_rsa (sexp, gck_crypto_rsa_pad_one, data, n_data, signature, n_signature);
- break;
- case CKM_RSA_X_509:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_sign_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, signature, n_signature);
- break;
- case CKM_DSA:
- g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_sign_dsa (sexp, data, n_data, signature, n_signature);
- break;
- default:
- /* Again shouldn't be reached */
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- };
-
- return rv;
-}
-
-CK_RV
-gck_crypto_sign_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
- gcry_sexp_t ssig, sdata;
- guint nbits;
- gcry_error_t gcry;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- /* Just want to know the length */
- if (!signature) {
- *n_signature = (nbits + 7) / 8;
- return CKR_OK;
- }
-
- /* Prepare the input sexp */
- rv = data_to_sexp ("(data (flags raw) (value %m))",
- nbits, padding, data, n_data, &sdata);
- if (rv != CKR_OK)
- return rv;
-
- /* Do the magic */
- gcry = gcry_pk_sign (&ssig, sdata, sexp);
- gcry_sexp_release (sdata);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- /* Now extract and send it back out */
- rv = sexp_to_data (ssig, nbits, signature, n_signature, NULL, "rsa", "s", NULL);
- gcry_sexp_release (ssig);
-
- return rv;
-}
-
-CK_RV
-gck_crypto_sign_dsa (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
- CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
- gcry_sexp_t ssig, splain;
- gcry_error_t gcry;
- gcry_mpi_t mpi;
- CK_ULONG size;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (n_data != 20)
- return CKR_DATA_LEN_RANGE;
-
- /* If no output, then don't process */
- if (!signature) {
- *n_signature = 40;
- return CKR_OK;
- } else if (*n_signature < 40) {
- *n_signature = 40;
- return CKR_BUFFER_TOO_SMALL;
- }
-
- /* Prepare the input s-expression */
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
- gcry_mpi_release (mpi);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- /* Do the magic */
- gcry = gcry_pk_sign (&ssig, splain, sexp);
- gcry_sexp_release (splain);
-
- /* TODO: Certain codes should be returned (data too big etc... ) */
- if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- g_assert (*n_signature >= 40);
-
- size = 20;
- rv = sexp_to_data (ssig, 20 * 8, signature, &size, NULL, "dsa", "r", NULL);
- if (rv == CKR_OK) {
- g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
- rv = sexp_to_data (ssig, 20 * 8, signature + 20, &size, NULL, "dsa", "s", NULL);
- if (rv == CKR_OK) {
- g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
- *n_signature = 40;
- }
- }
-
- gcry_sexp_release (ssig);
- return CKR_OK;
-}
-
-CK_RV
-gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
-{
- int algorithm;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
- g_return_val_if_reached (CKR_GENERAL_ERROR);
-
- /*
- * The algorithm checks below are merely sanity checks.
- * Other code should have checed this at an earlier stage
- * and return the right error codes if invalid.
- */
-
- switch (mech) {
- case CKM_RSA_PKCS:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_verify_rsa (sexp, gck_crypto_rsa_pad_one, data, n_data, signature, n_signature);
- break;
- case CKM_RSA_X_509:
- g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_verify_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, signature, n_signature);
- break;
- case CKM_DSA:
- g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
- rv = gck_crypto_verify_dsa (sexp, data, n_data, signature, n_signature);
- break;
- default:
- /* Again shouldn't be reached */
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- };
-
- return rv;
-}
-
-CK_RV
-gck_crypto_verify_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data,
- CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
-{
- gcry_sexp_t ssig, sdata;
- gcry_error_t gcry;
- guint nbits;
- CK_RV rv;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- /* The key size */
- nbits = gcry_pk_get_nbits (sexp);
- g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
- if (n_signature != (nbits + 7) / 8)
- return CKR_SIGNATURE_LEN_RANGE;
-
- /* Prepare the input s expressions */
- rv = data_to_sexp ("(data (flags raw) (value %m))",
- nbits, padding, data, n_data, &sdata);
- if (rv != CKR_OK)
- return rv;
-
- rv = data_to_sexp ("(sig-val (rsa (s %m)))",
- nbits, NULL, signature, n_signature, &ssig);
- if (rv != CKR_OK) {
- gcry_sexp_release (sdata);
- return rv;
- }
-
- /* Do the magic */
- gcry = gcry_pk_verify (ssig, sdata, sexp);
- gcry_sexp_release (sdata);
- gcry_sexp_release (ssig);
-
- /* TODO: See if any other codes should be mapped */
- if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
- return CKR_SIGNATURE_INVALID;
- } else if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- return CKR_OK;
-}
-
-CK_RV
-gck_crypto_verify_dsa (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
- CK_BYTE_PTR signature, CK_ULONG n_signature)
+init_quarks (void)
{
- gcry_sexp_t ssig, splain;
- gcry_error_t gcry;
- gcry_mpi_t mpi, mpi2;
-
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
- g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
- if (n_data != 20)
- return CKR_DATA_LEN_RANGE;
- if (n_signature != 40)
- return CKR_SIGNATURE_LEN_RANGE;
-
- /* Prepare the input s-expressions */
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
- gcry_mpi_release (mpi);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, signature, 20, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_mpi_scan (&mpi2, GCRYMPI_FMT_USG, signature + 20, 20, NULL);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
- gcry = gcry_sexp_build (&ssig, NULL, "(sig-val (dsa (r %m) (s %m)))", mpi, mpi2);
- gcry_mpi_release (mpi);
- gcry_mpi_release (mpi2);
- g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
- /* Do the magic */
- gcry = gcry_pk_verify (ssig, splain, sexp);
- gcry_sexp_release (splain);
- gcry_sexp_release (ssig);
-
- /* TODO: See if any other codes should be mapped */
- if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
- return CKR_SIGNATURE_INVALID;
- } else if (gcry) {
- g_message ("signing of the data failed: %s", gcry_strerror (gcry));
- return CKR_FUNCTION_FAILED;
- }
-
- return CKR_OK;
-}
+ static volatile gsize quarks_inited = 0;
-CK_RV
-gck_crypto_perform (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE method,
- CK_BYTE_PTR bufone, CK_ULONG n_bufone, CK_BYTE_PTR buftwo, CK_ULONG_PTR n_buftwo)
-{
- g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
- g_return_val_if_fail (method, CKR_GENERAL_ERROR);
- g_return_val_if_fail (n_buftwo, CKR_GENERAL_ERROR);
-
- switch (method) {
- case CKA_ENCRYPT:
- return gck_crypto_encrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
- case CKA_DECRYPT:
- return gck_crypto_decrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
- case CKA_SIGN:
- return gck_crypto_sign (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
- case CKA_VERIFY:
- return gck_crypto_verify (sexp, mech, bufone, n_bufone, buftwo, *n_buftwo);
- default:
- g_return_val_if_reached (CKR_GENERAL_ERROR);
- }
-}
+ if (g_once_init_enter (&quarks_inited)) {
-/* ----------------------------------------------------------------------------
- * SEXP FUNCTIONS
- */
+ #define QUARK(name, value) \
+ name = g_quark_from_static_string(value)
-#define PUBLIC_KEY "public-key"
-#define PUBLIC_KEY_L 10
-#define PRIVATE_KEY "private-key"
-#define PRIVATE_KEY_L 11
-
-gboolean
-gck_crypto_sexp_parse_key (gcry_sexp_t s_key, int *algorithm, gboolean *is_private,
- gcry_sexp_t *numbers)
-{
- gboolean ret = FALSE;
- gcry_sexp_t child = NULL;
- gchar *str = NULL;
- const gchar *data;
- gsize n_data;
- gboolean priv;
- int algo;
-
- data = gcry_sexp_nth_data (s_key, 0, &n_data);
- if (!data)
- goto done;
-
- if (n_data == PUBLIC_KEY_L && strncmp (data, PUBLIC_KEY, PUBLIC_KEY_L) == 0)
- priv = FALSE;
- else if (n_data == PRIVATE_KEY_L && strncmp (data, PRIVATE_KEY, PRIVATE_KEY_L) == 0)
- priv = TRUE;
- else
- goto done;
-
- child = gcry_sexp_nth (s_key, 1);
- if (!child)
- goto done;
+ QUARK (OID_PBE_MD2_DES_CBC, "1.2.840.113549.1.5.1");
+ QUARK (OID_PBE_MD5_DES_CBC, "1.2.840.113549.1.5.3");
+ QUARK (OID_PBE_MD2_RC2_CBC, "1.2.840.113549.1.5.4");
+ QUARK (OID_PBE_MD5_RC2_CBC, "1.2.840.113549.1.5.6");
+ QUARK (OID_PBE_SHA1_DES_CBC, "1.2.840.113549.1.5.10");
+ QUARK (OID_PBE_SHA1_RC2_CBC, "1.2.840.113549.1.5.11");
- data = gcry_sexp_nth_data (child, 0, &n_data);
- if (!data)
- goto done;
+ QUARK (OID_PBES2, "1.2.840.113549.1.5.13");
- str = g_alloca (n_data + 1);
- memcpy (str, data, n_data);
- str[n_data] = 0;
-
- algo = gcry_pk_map_name (str);
- if (!algo)
- goto done;
-
- /* Yay all done */
- if (algorithm)
- *algorithm = algo;
- if (numbers) {
- *numbers = child;
- child = NULL;
- }
- if (is_private)
- *is_private = priv;
-
- ret = TRUE;
-
-done:
- gcry_sexp_release (child);
- return ret;
-}
-
-static gcry_sexp_t
-rsa_numbers_to_public (gcry_sexp_t rsa)
-{
- gcry_sexp_t pubkey = NULL;
- gcry_mpi_t n, e;
- gcry_error_t gcry;
-
- n = e = NULL;
-
- if (!gck_crypto_sexp_extract_mpi (rsa, &n, "n", NULL) ||
- !gck_crypto_sexp_extract_mpi (rsa, &e, "e", NULL))
- goto done;
-
- gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
- n, e);
- if (gcry)
- goto done;
- g_assert (pubkey);
-
-done:
- gcry_mpi_release (n);
- gcry_mpi_release (e);
-
- return pubkey;
-}
-
-static gcry_sexp_t
-dsa_numbers_to_public (gcry_sexp_t dsa)
-{
- gcry_mpi_t p, q, g, y;
- gcry_sexp_t pubkey = NULL;
- gcry_error_t gcry;
-
- p = q = g = y = NULL;
-
- if (!gck_crypto_sexp_extract_mpi (dsa, &p, "p", NULL) ||
- !gck_crypto_sexp_extract_mpi (dsa, &q, "q", NULL) ||
- !gck_crypto_sexp_extract_mpi (dsa, &g, "g", NULL) ||
- !gck_crypto_sexp_extract_mpi (dsa, &y, "y", NULL))
- goto done;
-
- gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
- p, q, g, y);
- if (gcry)
- goto done;
- g_assert (pubkey);
-
-done:
- gcry_mpi_release (p);
- gcry_mpi_release (q);
- gcry_mpi_release (g);
- gcry_mpi_release (y);
-
- return pubkey;
-}
-
-gboolean
-gck_crypto_sexp_key_to_public (gcry_sexp_t privkey, gcry_sexp_t *pubkey)
-{
- gcry_sexp_t numbers;
- int algorithm;
-
- if (!gck_crypto_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
- g_return_val_if_reached (FALSE);
+ QUARK (OID_PBKDF2, "1.2.840.113549.1.5.12");
- switch (algorithm) {
- case GCRY_PK_RSA:
- *pubkey = rsa_numbers_to_public (numbers);
- break;
- case GCRY_PK_DSA:
- *pubkey = dsa_numbers_to_public (numbers);
- break;
- default:
- g_return_val_if_reached (FALSE);
- }
-
- gcry_sexp_release (numbers);
- return *pubkey ? TRUE : FALSE;
-}
-
-gboolean
-gck_crypto_sexp_extract_mpi (gcry_sexp_t sexp, gcry_mpi_t *mpi, ...)
-{
- gcry_sexp_t at = NULL;
- va_list va;
-
- g_assert (sexp);
- g_assert (mpi);
-
- va_start (va, mpi);
- at = sexp_get_childv (sexp, va);
- va_end (va);
-
- *mpi = NULL;
- if (at)
- *mpi = gcry_sexp_nth_mpi (at ? at : sexp, 1, GCRYMPI_FMT_USG);
- if (at)
- gcry_sexp_release (at);
-
- return (*mpi) ? TRUE : FALSE;
-}
-
-void
-gck_crypto_sexp_dump (gcry_sexp_t sexp)
-{
- gsize len;
- gchar *buf;
-
- len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
- buf = g_malloc (len);
- gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, len);
- g_printerr ("%s", buf);
- g_free (buf);
-}
-
-/* ----------------------------------------------------------------------------
- * PADDING FUNCTIONS
- */
-
-
-guchar*
-gck_crypto_rsa_pad_raw (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded)
-{
- gint total, n_pad;
- guchar *padded;
-
- /*
- * 0x00 0x00 0x00 ... 0x?? 0x?? 0x?? ...
- * padding data
- */
-
- total = n_modulus / 8;
- n_pad = total - n_raw;
- if (n_pad < 0) /* minumum padding */
- return NULL;
-
- padded = g_new0 (guchar, total);
- memset (padded, 0x00, n_pad);
- memcpy (padded + n_pad, raw, n_raw);
-
- *n_padded = total;
- return padded;
-}
-
-guchar*
-gck_crypto_rsa_pad_one (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded)
-{
- gint total, n_pad;
- guchar *padded;
-
- /*
- * 0x00 0x01 0xFF 0xFF ... 0x00 0x?? 0x?? 0x?? ...
- * type padding data
- */
-
- total = n_modulus / 8;
- n_pad = total - 3 - n_raw;
- if (n_pad < 8) /* minumum padding */
- return NULL;
-
- padded = g_new0 (guchar, total);
- padded[1] = 1; /* Block type */
- memset (padded + 2, 0xff, n_pad);
- memcpy (padded + 3 + n_pad, raw, n_raw);
-
- *n_padded = total;
- return padded;
-}
-
-guchar*
-gck_crypto_rsa_pad_two (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded)
-{
- gint total, n_pad;
- guchar *padded;
-
- /*
- * 0x00 0x01 0x?? 0x?? ... 0x00 0x?? 0x?? 0x?? ...
- * type padding data
- */
-
- total = n_modulus / 8;
- n_pad = total - 3 - n_raw;
- if (n_pad < 8) /* minumum padding */
- return NULL;
-
- padded = g_new0 (guchar, total);
- padded[1] = 2; /* Block type */
- fill_random_nonzero (padded + 2, n_pad);
- memcpy (padded + 3 + n_pad, raw, n_raw);
-
- *n_padded = total;
- return padded;
-}
-
-guchar*
-gck_crypto_rsa_unpad_one (guint bits, const guchar *padded,
- gsize n_padded, gsize *n_raw)
-{
- return unpad_rsa_pkcs1 (0x01, bits, padded, n_padded, n_raw);
-}
-
-guchar*
-gck_crypto_rsa_unpad_two (guint bits, const guchar *padded,
- gsize n_padded, gsize *n_raw)
-{
- return unpad_rsa_pkcs1 (0x02, bits, padded, n_padded, n_raw);
+ QUARK (OID_DES_CBC, "1.3.14.3.2.7");
+ QUARK (OID_DES_RC2_CBC, "1.2.840.113549.3.2");
+ QUARK (OID_DES_EDE3_CBC, "1.2.840.113549.3.7");
+ QUARK (OID_DES_RC5_CBC, "1.2.840.113549.3.9");
+
+ QUARK (OID_PKCS12_PBE_ARCFOUR_SHA1, "1.2.840.113549.1.12.1.1");
+ QUARK (OID_PKCS12_PBE_RC4_40_SHA1, "1.2.840.113549.1.12.1.2");
+ QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
+ QUARK (OID_PKCS12_PBE_2DES_SHA1, "1.2.840.113549.1.12.1.4");
+ QUARK (OID_PKCS12_PBE_RC2_128_SHA1, "1.2.840.113549.1.12.1.5");
+ QUARK (OID_PKCS12_PBE_RC2_40_SHA1, "1.2.840.113549.1.12.1.6");
+
+ #undef QUARK
+
+ g_once_init_leave (&quarks_inited, 1);
+ }
}
/* -----------------------------------------------------------------------------
@@ -982,10 +94,10 @@
*/
gboolean
-gck_crypto_symkey_generate_simple (int cipher_algo, int hash_algo,
- const gchar *password, gssize n_password,
- const guchar *salt, gsize n_salt, int iterations,
- guchar **key, guchar **iv)
+egg_symkey_generate_simple (int cipher_algo, int hash_algo,
+ const gchar *password, gssize n_password,
+ const guchar *salt, gsize n_salt, int iterations,
+ guchar **key, guchar **iv)
{
gcry_md_hd_t mdh;
gcry_error_t gcry;
@@ -1025,10 +137,10 @@
n_digest = gcry_md_get_algo_dlen (hash_algo);
g_return_val_if_fail (n_digest > 0, FALSE);
- digest = gcry_calloc_secure (n_digest, 1);
+ digest = egg_secure_alloc (n_digest);
g_return_val_if_fail (digest, FALSE);
if (key) {
- *key = gcry_calloc_secure (needed_key, 1);
+ *key = egg_secure_alloc (needed_key);
g_return_val_if_fail (*key, FALSE);
}
if (iv)
@@ -1081,16 +193,16 @@
break;
}
- gcry_free (digest);
+ egg_secure_free (digest);
gcry_md_close (mdh);
return TRUE;
}
gboolean
-gck_crypto_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
- gssize n_password, const guchar *salt, gsize n_salt, int iterations,
- guchar **key, guchar **iv)
+egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
+ gssize n_password, const guchar *salt, gsize n_salt, int iterations,
+ guchar **key, guchar **iv)
{
gcry_md_hd_t mdh;
gcry_error_t gcry;
@@ -1139,10 +251,10 @@
return FALSE;
}
- digest = gcry_calloc_secure (n_digest, 1);
+ digest = egg_secure_alloc (n_digest);
g_return_val_if_fail (digest, FALSE);
if (key) {
- *key = gcry_calloc_secure (needed_key, 1);
+ *key = egg_secure_alloc (needed_key);
g_return_val_if_fail (*key, FALSE);
}
if (iv)
@@ -1172,7 +284,7 @@
memcpy (*iv, digest + (16 - needed_iv), needed_iv);
}
- gcry_free (digest);
+ egg_secure_free (digest);
gcry_md_close (mdh);
return TRUE;
@@ -1213,9 +325,9 @@
}
/* Reqisition me a buffer */
- hash = gcry_calloc_secure (n_hash, 1);
- buf_i = gcry_calloc_secure (1, 128);
- buf_b = gcry_calloc_secure (1, 64);
+ hash = egg_secure_alloc (n_hash);
+ buf_i = egg_secure_alloc (128);
+ buf_b = egg_secure_alloc (64);
g_return_val_if_fail (hash && buf_i && buf_b, FALSE);
/* Bring in the salt */
@@ -1298,9 +410,9 @@
}
}
- gcry_free (buf_i);
- gcry_free (buf_b);
- gcry_free (hash);
+ egg_secure_free (buf_i);
+ egg_secure_free (buf_b);
+ egg_secure_free (hash);
gcry_mpi_release (num_b1);
gcry_md_close (mdh);
@@ -1308,9 +420,9 @@
}
gboolean
-gck_crypto_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password,
- gssize n_password, const guchar *salt, gsize n_salt,
- int iterations, guchar **key, guchar **iv)
+egg_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password,
+ gssize n_password, const guchar *salt, gsize n_salt,
+ int iterations, guchar **key, guchar **iv)
{
gsize n_block, n_key;
gboolean ret = TRUE;
@@ -1334,7 +446,7 @@
/* Generate us an key */
if (key) {
- *key = gcry_calloc_secure (n_key, 1);
+ *key = egg_secure_alloc (n_key);
g_return_val_if_fail (*key != NULL, FALSE);
ret = generate_pkcs12 (hash_algo, 1, password, n_password, salt, n_salt,
iterations, *key, n_key);
@@ -1354,7 +466,7 @@
/* Cleanup in case of failure */
if (!ret) {
g_free (iv ? *iv : NULL);
- gcry_free (key ? *key : NULL);
+ egg_secure_free (key ? *key : NULL);
}
return ret;
@@ -1387,10 +499,10 @@
}
/* Get us a temporary buffers */
- T = gcry_calloc_secure (n_hash, 1);
- U = gcry_calloc_secure (n_hash, 1);
+ T = egg_secure_alloc (n_hash);
+ U = egg_secure_alloc (n_hash);
n_buf = n_salt + 4;
- buf = gcry_calloc_secure (n_buf, 1);
+ buf = egg_secure_alloc (n_buf);
g_return_val_if_fail (buf && T && U, FALSE);
/* n_hash blocks in output, rounding up */
@@ -1431,18 +543,18 @@
memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
}
- gcry_free (T);
- gcry_free (U);
- gcry_free (buf);
+ egg_secure_free (T);
+ egg_secure_free (U);
+ egg_secure_free (buf);
gcry_md_close (mdh);
return TRUE;
}
gboolean
-gck_crypto_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
- const gchar *password, gssize n_password,
- const guchar *salt, gsize n_salt, int iterations,
- guchar **key, guchar **iv)
+egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
+ const gchar *password, gssize n_password,
+ const guchar *salt, gsize n_salt, int iterations,
+ guchar **key, guchar **iv)
{
gsize n_key, n_block;
gboolean ret = TRUE;
@@ -1466,7 +578,7 @@
/* Generate us an key */
if (key) {
- *key = gcry_calloc_secure (n_key, 1);
+ *key = egg_secure_alloc (n_key);
g_return_val_if_fail (*key != NULL, FALSE);
ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt,
iterations, *key, n_key);
@@ -1485,100 +597,431 @@
/* Cleanup in case of failure */
if (!ret) {
g_free (iv ? *iv : NULL);
- gcry_free (key ? *key : NULL);
+ egg_secure_free (key ? *key : NULL);
}
return ret;
}
-/* --------------------------------------------------------------------------
- * INITIALIZATION
+/* ----------------------------------------------------------------------------
+ * DER encoded cipher params
*/
-static void
-log_handler (gpointer unused, int unknown, const gchar *msg, va_list va)
-{
- /* TODO: Figure out additional arguments */
- g_logv ("gcrypt", G_LOG_LEVEL_MESSAGE, msg, va);
-}
-static int
-no_mem_handler (gpointer unused, size_t sz, unsigned int unknown)
+static gboolean
+read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
+ const gchar *password, gsize n_password, const guchar *data,
+ gsize n_data, gcry_cipher_hd_t *cih)
{
- /* TODO: Figure out additional arguments */
- g_error ("couldn't allocate %lu bytes of memory",
- (unsigned long int)sz);
- return 0;
-}
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gcry_error_t gcry;
+ const guchar *salt;
+ gsize n_salt;
+ gsize n_block, n_key;
+ guint iterations;
+ guchar *key = NULL;
+ guchar *iv = NULL;
+ gboolean ret;
+
+ g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
+ g_return_val_if_fail (cih != NULL, FALSE);
+ g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+
+ *cih = NULL;
+ ret = FALSE;
+
+ /* Check if we can use this algorithm */
+ if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
+ gcry_md_test_algo (hash_algo) != 0)
+ goto done;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-5-PBE-params", data, n_data);
+ if (!asn)
+ goto done;
+
+ salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
+ if (!salt)
+ goto done;
+ if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
+ iterations = 1;
+
+ n_key = gcry_cipher_get_algo_keylen (cipher_algo);
+ g_return_val_if_fail (n_key > 0, FALSE);
+ n_block = gcry_cipher_get_algo_blklen (cipher_algo);
+
+ if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password, salt,
+ n_salt, iterations, &key, n_block > 1 ? &iv : NULL))
+ goto done;
+
+ gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
+ if (gcry != 0) {
+ g_warning ("couldn't create cipher: %s", gcry_strerror (gcry));
+ goto done;
+ }
+
+ if (iv)
+ gcry_cipher_setiv (*cih, iv, n_block);
+ gcry_cipher_setkey (*cih, key, n_key);
+
+ ret = TRUE;
-static void
-fatal_handler (gpointer unused, int unknown, const gchar *msg)
-{
- /* TODO: Figure out additional arguments */
- g_log ("gcrypt", G_LOG_LEVEL_ERROR, "%s", msg);
+done:
+ g_free (iv);
+ egg_secure_free (key);
+
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
}
-static int
-glib_thread_mutex_init (void **lock)
+static gboolean
+setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
{
- *lock = g_mutex_new ();
- return 0;
-}
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gcry_error_t gcry;
+ const guchar *iv;
+ gsize n_iv;
+ guint version;
+
+ g_assert (data);
-static int
-glib_thread_mutex_destroy (void **lock)
-{
- g_mutex_free (*lock);
- return 0;
+ asn = egg_asn1_decode ("PKIX1.pkcs-5-rc2-CBC-params", data, n_data);
+ if (!asn)
+ return FALSE;
+
+ if (!egg_asn1_read_uint (asn, "rc2ParameterVersion", &version))
+ return FALSE;
+
+ iv = egg_asn1_read_content (asn, data, n_data, "iv", &n_iv);
+ asn1_delete_structure (&asn);
+
+ if (!iv)
+ return FALSE;
+
+ gcry = gcry_cipher_setiv (cih, iv, n_iv);
+
+ if (gcry != 0) {
+ g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
+ return FALSE;
+ }
+
+ return TRUE;
}
-static int
-glib_thread_mutex_lock (void **lock)
+static gboolean
+setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
{
- g_mutex_lock (*lock);
- return 0;
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gcry_error_t gcry;
+ const guchar *iv;
+ gsize n_iv;
+
+ g_assert (data);
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-5-des-EDE3-CBC-params", data, n_data);
+ if (!asn)
+ asn = egg_asn1_decode ("PKIX1.pkcs-5-des-CBC-params", data, n_data);
+ if (!asn)
+ return FALSE;
+
+ iv = egg_asn1_read_content (asn, data, n_data, "", &n_iv);
+ asn1_delete_structure (&asn);
+
+ if (!iv)
+ return FALSE;
+
+ gcry = gcry_cipher_setiv (cih, iv, n_iv);
+
+ if (gcry != 0) {
+ g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
+ return FALSE;
+ }
+
+ return TRUE;
}
-static int
-glib_thread_mutex_unlock (void **lock)
+static gboolean
+setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar *data,
+ gsize n_data, int cipher_algo, gcry_cipher_hd_t cih)
{
- g_mutex_unlock (*lock);
- return 0;
-}
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gboolean ret;
+ gcry_error_t gcry;
+ guchar *key = NULL;
+ const guchar *salt;
+ gsize n_salt, n_key;
+ guint iterations;
+
+ g_assert (cipher_algo);
+ g_assert (data);
+
+ ret = FALSE;
-static struct gcry_thread_cbs glib_thread_cbs = {
- GCRY_THREAD_OPTION_USER, NULL,
- glib_thread_mutex_init, glib_thread_mutex_destroy,
- glib_thread_mutex_lock, glib_thread_mutex_unlock,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
+ asn = egg_asn1_decode ("PKIX1.pkcs-5-PBKDF2-params", data, n_data);
+ if (!asn)
+ goto done;
+
+ if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
+ iterations = 1;
+ salt = egg_asn1_read_content (asn, data, n_data, "salt.specified", &n_salt);
+ if (!salt)
+ goto done;
+
+ if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
+ salt, n_salt, iterations, &key, NULL))
+ goto done;
+
+ n_key = gcry_cipher_get_algo_keylen (cipher_algo);
+ g_return_val_if_fail (n_key > 0, FALSE);
+
+ gcry = gcry_cipher_setkey (cih, key, n_key);
+ if (gcry != 0) {
+ g_message ("couldn't set %lu byte key on cipher", (gulong)n_key);
+ goto done;
+ }
+
+ ret = TRUE;
+
+done:
+ egg_secure_free (key);
+ if (asn)
+ asn1_delete_structure (&asn);
+ return ret;
+}
-void
-gck_crypto_initialize (void)
+static gboolean
+read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data,
+ gsize n_data, gcry_cipher_hd_t *cih)
{
- static gsize gcrypt_initialized = FALSE;
- unsigned seed;
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gboolean r, ret;
+ GQuark key_deriv_algo, enc_oid;
+ gcry_error_t gcry;
+ int algo, mode;
+ int beg, end;
- if (g_once_init_enter (&gcrypt_initialized)) {
+ g_return_val_if_fail (cih != NULL, FALSE);
+ g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+
+ init_quarks ();
+
+ *cih = NULL;
+ ret = FALSE;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-5-PBES2-params", data, n_data);
+ if (!asn)
+ goto done;
- /* Only initialize libgcrypt if it hasn't already been initialized */
- if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
- gcry_control (GCRYCTL_SET_THREAD_CBS, &glib_thread_cbs);
- gcry_check_version (LIBGCRYPT_VERSION);
- gcry_set_log_handler (log_handler, NULL);
- gcry_set_outofcore_handler (no_mem_handler, NULL);
- gcry_set_fatalerror_handler (fatal_handler, NULL);
- gcry_set_allocation_handler ((gcry_handler_alloc_t)g_malloc,
- (gcry_handler_alloc_t)egg_secure_alloc,
- egg_secure_check,
- (gcry_handler_realloc_t)egg_secure_realloc,
- egg_secure_free);
- gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
- }
+ algo = mode = 0;
+
+ /* Read in all the encryption type */
+ enc_oid = egg_asn1_read_oid (asn, "encryptionScheme.algorithm");
+ if (!enc_oid)
+ goto done;
+ if (enc_oid == OID_DES_EDE3_CBC)
+ algo = GCRY_CIPHER_3DES;
+ else if (enc_oid == OID_DES_CBC)
+ algo = GCRY_CIPHER_DES;
+ else if (enc_oid == OID_DES_RC2_CBC)
+ algo = GCRY_CIPHER_RFC2268_128;
+ else if (enc_oid == OID_DES_RC5_CBC)
+ /* RC5 doesn't exist in libgcrypt */;
+
+ /* Unsupported? */
+ if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
+ goto done;
+
+ /* Instantiate our cipher */
+ gcry = gcry_cipher_open (cih, algo, GCRY_CIPHER_MODE_CBC, 0);
+ if (gcry != 0) {
+ g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo));
+ goto done;
+ }
- gcry_create_nonce (&seed, sizeof (seed));
- srand (seed);
+ /* Read out the parameters */
+ if (asn1_der_decoding_startEnd (asn, data, n_data, "encryptionScheme.parameters",
+ &beg, &end) != ASN1_SUCCESS)
+ goto done;
+
+ switch (algo) {
+ case GCRY_CIPHER_3DES:
+ case GCRY_CIPHER_DES:
+ r = setup_pkcs5_des_params (data + beg, end - beg + 1, *cih);
+ break;
+ case GCRY_CIPHER_RFC2268_128:
+ r = setup_pkcs5_rc2_params (data + beg, end - beg + 1, *cih);
+ break;
+ default:
+ /* Should have been caught on the oid check above */
+ g_assert_not_reached ();
+ r = FALSE;
+ break;
+ };
+
+ if (r != TRUE)
+ goto done;
+
+ /* Read out the key creation paramaters */
+ key_deriv_algo = egg_asn1_read_oid (asn, "keyDerivationFunc.algorithm");
+ if (!key_deriv_algo)
+ goto done;
+ if (key_deriv_algo != OID_PBKDF2) {
+ g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
+ goto done;
+ }
+
+ if (asn1_der_decoding_startEnd (asn, data, n_data, "keyDerivationFunc.parameters",
+ &beg, &end) != ASN1_SUCCESS)
+ goto done;
+
+ ret = setup_pkcs5_pbkdf2_params (password, n_password, data + beg, end - beg + 1, algo, *cih);
+
+done:
+ if (ret != TRUE && *cih) {
+ gcry_cipher_close (*cih);
+ *cih = NULL;
+ }
+
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
+}
+
+static gboolean
+read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
+ gsize n_password, const guchar *data, gsize n_data,
+ gcry_cipher_hd_t *cih)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gcry_error_t gcry;
+ gboolean ret;
+ const guchar *salt;
+ gsize n_salt;
+ gsize n_block, n_key;
+ guint iterations;
+ guchar *key = NULL;
+ guchar *iv = NULL;
+
+ g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
+ g_return_val_if_fail (cih != NULL, FALSE);
+ g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+
+ *cih = NULL;
+ ret = FALSE;
+
+ /* Check if we can use this algorithm */
+ if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
+ goto done;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-12-PbeParams", data, n_data);
+ if (!asn)
+ goto done;
+
+ salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
+ if (!salt)
+ goto done;
+ if (!egg_asn1_read_uint (asn, "iterations", &iterations))
+ goto done;
+
+ n_block = gcry_cipher_get_algo_blklen (cipher_algo);
+ n_key = gcry_cipher_get_algo_keylen (cipher_algo);
+
+ /* Generate IV and key using salt read above */
+ if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password,
+ n_password, salt, n_salt, iterations, &key,
+ n_block > 1 ? &iv : NULL))
+ goto done;
- g_once_init_leave (&gcrypt_initialized, 1);
+ gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
+ if (gcry != 0) {
+ g_warning ("couldn't create encryption cipher: %s", gcry_strerror (gcry));
+ goto done;
}
+
+ if (iv)
+ gcry_cipher_setiv (*cih, iv, n_block);
+ gcry_cipher_setkey (*cih, key, n_key);
+
+ ret = TRUE;
+
+done:
+ if (ret != TRUE && *cih) {
+ gcry_cipher_close (*cih);
+ *cih = NULL;
+ }
+
+ g_free (iv);
+ egg_secure_free (key);
+
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
+}
+
+gboolean
+egg_symkey_read_cipher (GQuark oid_scheme, const gchar *password, gsize n_password,
+ const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
+{
+ gboolean ret = FALSE;
+
+ g_return_val_if_fail (oid_scheme != 0, FALSE);
+ g_return_val_if_fail (cih != NULL, FALSE);
+ g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+
+ init_quarks ();
+
+ /* PKCS#5 PBE */
+ if (oid_scheme == OID_PBE_MD2_DES_CBC)
+ ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+ GCRY_MD_MD2, password, n_password, data, n_data, cih);
+
+ else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
+ /* RC2-64 has no implementation in libgcrypt */;
+
+ else if (oid_scheme == OID_PBE_MD5_DES_CBC)
+ ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+ GCRY_MD_MD5, password, n_password, data, n_data, cih);
+ else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
+ /* RC2-64 has no implementation in libgcrypt */;
+
+ else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
+ ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+ GCRY_MD_SHA1, password, n_password, data, n_data, cih);
+ else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
+ /* RC2-64 has no implementation in libgcrypt */;
+
+
+ /* PKCS#5 PBES2 */
+ else if (oid_scheme == OID_PBES2)
+ ret = read_cipher_pkcs5_pbes2 (password, n_password, data, n_data, cih);
+
+
+ /* PKCS#12 PBE */
+ else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM,
+ password, n_password, data, n_data, cih);
+ else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
+ /* RC4-40 has no implementation in libgcrypt */;
+
+ else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC,
+ password, n_password, data, n_data, cih);
+ else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1)
+ /* 2DES has no implementation in libgcrypt */;
+
+ else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC,
+ password, n_password, data, n_data, cih);
+
+ else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC,
+ password, n_password, data, n_data, cih);
+
+ if (ret == FALSE)
+ g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
+
+ return ret;
}
Copied: trunk/egg/egg-symkey.h (from r1460, /trunk/pkcs11/gck/gck-crypto.h)
==============================================================================
--- /trunk/pkcs11/gck/gck-crypto.h (original)
+++ trunk/egg/egg-symkey.h Sun Jan 18 22:24:09 2009
@@ -19,184 +19,58 @@
* 02111-1307, USA.
*/
-#ifndef GCKCRYPTO_H_
-#define GCKCRYPTO_H_
+#ifndef EGG_SYMKEY_H_
+#define EGG_SYMKEY_H_
#include <glib.h>
#include <gcrypt.h>
-#include "pkcs11/pkcs11.h"
+gboolean egg_symkey_generate_simple (int cipher_algo,
+ int hash_algo,
+ const gchar *password,
+ gssize n_password,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
+ guchar **iv);
+
+gboolean egg_symkey_generate_pbe (int cipher_algo,
+ int hash_algo,
+ const gchar *password,
+ gssize n_password,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
+ guchar **iv);
+
+gboolean egg_symkey_generate_pkcs12 (int cipher_algo,
+ int hash_algo,
+ const gchar *password,
+ gssize n_password,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
+ guchar **iv);
+
+gboolean egg_symkey_generate_pbkdf2 (int cipher_algo,
+ int hash_algo,
+ const gchar *password,
+ gssize n_password,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
+ guchar **iv);
+
+gboolean egg_symkey_read_cipher (GQuark oid_scheme,
+ const gchar *password,
+ gsize n_password,
+ const guchar *data,
+ gsize n_data,
+ gcry_cipher_hd_t *cih);
-typedef guchar* (*GckCryptoPadding) (guint n_modulus, const guchar* raw,
- gsize n_raw, gsize *n_padded);
-
-static const CK_MECHANISM_TYPE GCK_CRYPTO_RSA_MECHANISMS[] = {
- CKM_RSA_PKCS,
- CKM_RSA_X_509
-};
-
-static const CK_MECHANISM_TYPE GCK_CRYPTO_DSA_MECHANISMS[] = {
- CKM_DSA
-};
-
-void gck_crypto_initialize (void);
-
-CK_RV gck_crypto_perform (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_ATTRIBUTE_TYPE method,
- CK_BYTE_PTR bufone,
- CK_ULONG n_bufone,
- CK_BYTE_PTR buftwo,
- CK_ULONG_PTR n_buftwo);
-
-CK_RV gck_crypto_encrypt (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR encrypted,
- CK_ULONG_PTR n_encrypted);
-
-CK_RV gck_crypto_encrypt_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR encrypted,
- CK_ULONG_PTR n_encrypted);
-
-
-CK_RV gck_crypto_decrypt (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted,
- CK_BYTE_PTR data,
- CK_ULONG_PTR n_data);
-
-CK_RV gck_crypto_decrypt_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR encrypted,
- CK_ULONG n_encrypted,
- CK_BYTE_PTR data,
- CK_ULONG_PTR n_data);
-
-CK_RV gck_crypto_sign (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG_PTR n_signature);
-
-CK_RV gck_crypto_sign_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG_PTR n_signature);
-
-CK_RV gck_crypto_sign_dsa (gcry_sexp_t sexp,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG_PTR n_signature);
-
-CK_RV gck_crypto_verify (gcry_sexp_t sexp,
- CK_MECHANISM_TYPE mech,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG n_signature);
-
-CK_RV gck_crypto_verify_rsa (gcry_sexp_t sexp,
- GckCryptoPadding padding,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG n_signature);
-
-
-CK_RV gck_crypto_verify_dsa (gcry_sexp_t sexp,
- CK_BYTE_PTR data,
- CK_ULONG n_data,
- CK_BYTE_PTR signature,
- CK_ULONG n_signature);
-
-gboolean gck_crypto_sexp_parse_key (gcry_sexp_t sexp,
- int *algorithm,
- gboolean *is_private,
- gcry_sexp_t *numbers);
-
-gboolean gck_crypto_sexp_key_to_public (gcry_sexp_t sexp,
- gcry_sexp_t *pub);
-
-gboolean gck_crypto_sexp_extract_mpi (gcry_sexp_t sexp,
- gcry_mpi_t *mpi,
- ...) G_GNUC_NULL_TERMINATED;
-
-void gck_crypto_sexp_dump (gcry_sexp_t sexp);
-
-guchar* gck_crypto_rsa_pad_raw (guint bits,
- const guchar* raw,
- gsize n_raw,
- gsize *n_padded);
-
-guchar* gck_crypto_rsa_pad_one (guint bits,
- const guchar* raw,
- gsize n_raw,
- gsize *n_padded);
-
-guchar* gck_crypto_rsa_pad_two (guint bits,
- const guchar* raw,
- gsize n_raw,
- gsize *n_padded);
-
-guchar* gck_crypto_rsa_unpad_one (guint bits,
- const guchar *padded,
- gsize n_padded,
- gsize *n_raw);
-
-guchar* gck_crypto_rsa_unpad_two (guint bits,
- const guchar* padded,
- gsize n_padded,
- gsize *n_raw);
-
-gboolean gck_crypto_symkey_generate_simple (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-gboolean gck_crypto_symkey_generate_pbe (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-gboolean gck_crypto_symkey_generate_pkcs12 (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-gboolean gck_crypto_symkey_generate_pbkdf2 (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-#endif /* GCKCRYPTO_H_ */
+#endif /* EGG_SYMKEY_H_ */
Modified: trunk/egg/tests/Makefile.am
==============================================================================
--- trunk/egg/tests/Makefile.am (original)
+++ trunk/egg/tests/Makefile.am Sun Jan 18 22:24:09 2009
@@ -8,7 +8,10 @@
# Test files should be listed in order they need to run
UNIT_AUTO = \
unit-test-asn1.c \
+ unit-test-hex.c \
unit-test-secmem.c \
+ unit-test-symkey.c \
+ unit-test-openssl.c \
$(BUILT_SOURCES)
UNIT_PROMPT =
Modified: trunk/egg/tests/unit-test-asn1.c
==============================================================================
--- trunk/egg/tests/unit-test-asn1.c (original)
+++ trunk/egg/tests/unit-test-asn1.c Sun Jan 18 22:24:09 2009
@@ -274,11 +274,6 @@
oid = egg_asn1_read_oid (asn, "nonExistant");
g_assert (oid == 0);
- /* No quark of this has been defined, so should return an invalid OID */
- oid = egg_asn1_read_oid (asn, "data");
- g_assert (oid != 0);
- g_assert_cmpstr (g_quark_to_string (oid), !=, "SOME DATA");
-
/* Now a quark has been defined */
check = g_quark_from_static_string ("SOME DATA");
oid = egg_asn1_read_oid (asn, "data");
Copied: trunk/egg/tests/unit-test-hex.c (from r1460, /trunk/pkcs11/gck/tests/unit-test-util.c)
==============================================================================
--- /trunk/pkcs11/gck/tests/unit-test-util.c (original)
+++ trunk/egg/tests/unit-test-hex.c Sun Jan 18 22:24:09 2009
@@ -27,7 +27,7 @@
#include "run-auto-test.h"
-#include "gck/gck-util.h"
+#include "egg-hex.h"
static const guchar TEST_DATA[] = { 0x05, 0xD6, 0x95, 0x96, 0x10, 0x12, 0xAE, 0x35 };
static const gchar *TEST_HEX = "05D695961012AE35";
@@ -37,7 +37,7 @@
{
gchar *hex;
- hex = gck_util_hex_encode (TEST_DATA, sizeof (TEST_DATA));
+ hex = egg_hex_encode (TEST_DATA, sizeof (TEST_DATA));
g_assert (hex);
g_assert_cmpstr (hex, ==, TEST_HEX);
}
@@ -47,23 +47,23 @@
guchar *data;
gsize n_data;
- data = gck_util_hex_decode (TEST_HEX, -1, &n_data);
+ data = egg_hex_decode (TEST_HEX, -1, &n_data);
g_assert (data);
g_assert (n_data == sizeof (TEST_DATA));
g_assert (memcmp (data, TEST_DATA, n_data) == 0);
/* Spaces should be ignored */
- data = gck_util_hex_decode (TEST_HEX_SPACE, -1, &n_data);
+ data = egg_hex_decode (TEST_HEX_SPACE, -1, &n_data);
g_assert (data);
g_assert (n_data == sizeof (TEST_DATA));
g_assert (memcmp (data, TEST_DATA, n_data) == 0);
/* Invalid input, null out */
- data = gck_util_hex_decode ("AB", 1, &n_data);
+ data = egg_hex_decode ("AB", 1, &n_data);
g_assert (!data);
/* Nothing in, empty out */
- data = gck_util_hex_decode ("AB", 0, &n_data);
+ data = egg_hex_decode ("AB", 0, &n_data);
g_assert (data);
g_assert (n_data == 0);
}
Copied: trunk/egg/tests/unit-test-openssl.c (from r1460, /trunk/pkcs11/gck/tests/unit-test-data-openssl.c)
==============================================================================
--- /trunk/pkcs11/gck/tests/unit-test-data-openssl.c (original)
+++ trunk/egg/tests/unit-test-openssl.c Sun Jan 18 22:24:09 2009
@@ -25,9 +25,8 @@
#include "run-auto-test.h"
-#include "gck/gck-crypto.h"
-#include "gck/gck-data-pem.h"
-#include "gck/gck-data-openssl.h"
+#include "egg-symkey.h"
+#include "egg-openssl.h"
#include <glib.h>
@@ -51,7 +50,7 @@
parse_reference (GQuark type, const guchar *data, gsize n_data,
GHashTable *headers, gpointer user_data)
{
- GckDataResult res;
+ gboolean res;
const gchar *dekinfo;
g_assert ("no data in PEM callback" && data != NULL);
@@ -60,13 +59,13 @@
n_refenc = n_data;
g_assert ("no headers present in file" && headers != NULL);
- refheaders = gck_data_pem_headers_new ();
+ refheaders = egg_openssl_headers_new ();
g_hash_table_foreach (headers, copy_each_key_value, refheaders);
- dekinfo = gck_data_openssl_get_dekinfo (headers);
+ dekinfo = egg_openssl_get_dekinfo (headers);
g_assert ("no dekinfo in headers" && dekinfo != NULL);
- res = gck_data_openssl_decrypt_block (dekinfo, "booo", 4, data, n_data, &refdata, &n_refdata);
- g_assert ("couldn't openssl decrypt block" && res == GCK_DATA_SUCCESS);
+ res = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, n_data, &refdata, &n_refdata);
+ g_assert ("couldn't openssl decrypt block" && res == TRUE);
g_assert ("no data returned from openssl decrypt" && refdata != NULL);
g_assert ("invalid amount of data returned from openssl decrypt" && n_refdata == n_data);
}
@@ -79,7 +78,7 @@
input = test_read_testdata ("pem-rsa-enc.key", &n_input);
- num = gck_data_pem_parse (input, n_input, parse_reference, NULL);
+ num = egg_openssl_pem_parse (input, n_input, parse_reference, NULL);
g_assert ("couldn't PEM block in reference data" && num == 1);
g_assert ("parse_reference() wasn't called" && refdata != NULL);
@@ -92,10 +91,10 @@
gsize n_encrypted;
gboolean ret;
- dekinfo = gck_data_openssl_get_dekinfo (refheaders);
+ dekinfo = egg_openssl_get_dekinfo (refheaders);
g_assert ("no dekinfo in headers" && dekinfo != NULL);
- ret = gck_data_openssl_encrypt_block (dekinfo, "booo", 4, refdata, n_refdata, &encrypted, &n_encrypted);
+ ret = egg_openssl_encrypt_block (dekinfo, "booo", 4, refdata, n_refdata, &encrypted, &n_encrypted);
g_assert ("couldn't openssl encrypt block" && ret == TRUE);
g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
g_assert ("invalid amount of data returned from openssl encrypt" && n_refdata <= n_encrypted);
@@ -111,21 +110,21 @@
DEFINE_TEST(openssl_roundtrip)
{
const gchar *dekinfo;
- GckDataResult res;
+ gboolean res;
gboolean ret;
guchar *encrypted, *decrypted;
gsize n_encrypted, n_decrypted;
int i;
- dekinfo = gck_data_openssl_prep_dekinfo (refheaders);
+ dekinfo = egg_openssl_prep_dekinfo (refheaders);
- ret = gck_data_openssl_encrypt_block (dekinfo, "password", -1, TEST_DATA, TEST_DATA_L, &encrypted, &n_encrypted);
+ ret = egg_openssl_encrypt_block (dekinfo, "password", -1, TEST_DATA, TEST_DATA_L, &encrypted, &n_encrypted);
g_assert ("couldn't openssl encrypt block" && ret == TRUE);
g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
g_assert ("invalid amount of data returned from openssl encrypt" && TEST_DATA_L <= n_encrypted);
- res = gck_data_openssl_decrypt_block (dekinfo, "password", 8, encrypted, n_encrypted, &decrypted, &n_decrypted);
- g_assert ("couldn't openssl decrypt block" && res == GCK_DATA_SUCCESS);
+ res = egg_openssl_decrypt_block (dekinfo, "password", 8, encrypted, n_encrypted, &decrypted, &n_decrypted);
+ g_assert ("couldn't openssl decrypt block" && res == TRUE);
g_assert ("no data returned from openssl decrypt" && decrypted != NULL);
/* Check that the data was decrypted properly */
Copied: trunk/egg/tests/unit-test-symkey.c (from r1460, /trunk/pkcs11/gck/tests/unit-test-crypto.c)
==============================================================================
--- /trunk/pkcs11/gck/tests/unit-test-crypto.c (original)
+++ trunk/egg/tests/unit-test-symkey.c Sun Jan 18 22:24:09 2009
@@ -27,49 +27,18 @@
#include "run-auto-test.h"
-#include "gck/gck-crypto.h"
+#include "egg-symkey.h"
#include <gcrypt.h>
-#define TEST_RSA \
-"(private-key (rsa " \
-"(n #00B78758D55EBFFAB61D07D0DC49B5309A6F1DA2AE51C275DFC2370959BB81AC0C39093B1C618E396161A0DECEB8768D0FFB14F197B96C3DA14190EE0F20D51315#)" \
-"(e #010001#)" \
-"(d #108BCAC5FDD35812981E6EC5957D98E2AB76E4064C47B861D27C2CC322C50792313C852B4164A035B42D261F1A09F9FFE8F477F9F78FF2EABBDA6BA875C671D7#)" \
-"(p #00C357F11B19A18C66573D25D1E466D9AB8BCDDCDFE0B2E80BD46712C4BEC18EB7#)" \
-"(q #00F0843B90A60EF7034CA4BE80414ED9497CABCC685143B388013FF989CBB0E093#)" \
-"(u #12F2555F52EB56329A991CF0404B51C68AC921AD370A797860F550415FF987BD#)" \
-"))"
-
-#define TEST_DSA \
-"(private-key (dsa " \
-" (p #0090EC0B60735839C754EAF8F64BB03FC35398D69772BFAE540079DEA2D3A61FAFFB27630A038A01A3D0CD62A10745A574A27ECB462F4F0885B79C61BBE954A60A29668AD54BBA5C07A72FD8B1105249670B339DF2C59E64A47064EFCF0B7236C5C72CD55CEB32917430BEC9A003D4E484FBAA84D79571B38D6B5AC95BB73E3F7B#)" \
-" (q #00FA214A1385C21BFEBAADAB240A2430C607D56271#)" \
-" (g #2DE05751F5DAEE97F3D43C54595A3E94A080728F0C66C98AEBED5762F6AB155802D8359EAD1DE1EC36A459FBEEEA48E59B9E6A8CB4F5295936B3CC881A5D957C7339175E2CFFE0F30D3711E430DB6648C2EB474AA10A4A3297450531FF2C7C6951220C9D446B6B6B0F00262E1EBEB3CC861476AA518CC555C9ABF9E5F39023FC#)" \
-" (y #54734451DB79D4EEDF0BBCEBD43BB6CBB7B8584603B957080075DD318EB5B0266D4B20DC5EFF376BDFC4EA2983B1F7F02A39ED4C619ED68712729FFF3B7C696ADD1B6D748F56A4B4BEC5C4385E528423A3B88AE65E6D5500F97839E7A486255982189C3B4FA8D94338C76F0E5CAFC9A30A1ED728BB9F2091D594E3250A09EA00#)" \
-" (x #00876F84F709D51108DFB0CBFA1F1C569C09C413EC#)))"
-
-gcry_sexp_t rsakey = NULL;
-gcry_sexp_t dsakey = NULL;
-
DEFINE_SETUP(crypto_setup)
{
- gcry_error_t gcry;
-
- gck_crypto_initialize ();
-
- gcry = gcry_sexp_new (&rsakey, TEST_RSA, strlen (TEST_RSA), 1);
- g_return_if_fail (gcry == 0);
- gcry = gcry_sexp_new (&dsakey, TEST_DSA, strlen (TEST_DSA), 1);
- g_return_if_fail (gcry == 0);
+ gcry_check_version (LIBGCRYPT_VERSION);
}
DEFINE_TEARDOWN(crypto_setup)
{
- gcry_sexp_release (rsakey);
- rsakey = NULL;
- gcry_sexp_release (dsakey);
- dsakey = NULL;
+
}
const static struct {
@@ -162,7 +131,7 @@
if (!all_generation_tests[i].result_simple)
continue;
- ret = gck_crypto_symkey_generate_simple (all_generation_tests[i].cipher_algo,
+ ret = egg_symkey_generate_simple (all_generation_tests[i].cipher_algo,
all_generation_tests[i].hash_algo,
all_generation_tests[i].password, -1,
(guchar*)all_generation_tests[i].salt, 8,
@@ -188,7 +157,7 @@
if (!all_generation_tests[i].result_pkcs12)
continue;
- ret = gck_crypto_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo,
+ ret = egg_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo,
all_generation_tests[i].hash_algo,
all_generation_tests[i].password, -1,
(guchar*)all_generation_tests[i].salt, 8,
@@ -214,7 +183,7 @@
if (!all_generation_tests[i].result_pbkdf2)
continue;
- ret = gck_crypto_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo,
+ ret = egg_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo,
all_generation_tests[i].hash_algo,
all_generation_tests[i].password, -1,
(guchar*)all_generation_tests[i].salt, 8,
@@ -240,7 +209,7 @@
if (!all_generation_tests[i].result_pbe)
continue;
- ret = gck_crypto_symkey_generate_pbe (all_generation_tests[i].cipher_algo,
+ ret = egg_symkey_generate_pbe (all_generation_tests[i].cipher_algo,
all_generation_tests[i].hash_algo,
all_generation_tests[i].password, -1,
(guchar*)all_generation_tests[i].salt, 8,
@@ -255,61 +224,3 @@
}
}
-
-DEFINE_TEST(parse_key)
-{
- gcry_sexp_t sexp = NULL;
- gcry_mpi_t mpi = NULL;
- gboolean ret;
- gboolean is_priv = FALSE;
- int algorithm = 0;
-
- /* Get the private key out */
- ret = gck_crypto_sexp_parse_key (rsakey, &algorithm, &is_priv, &sexp);
- g_assert (ret);
- g_assert (algorithm == GCRY_PK_RSA);
- g_assert (is_priv == TRUE);
- g_assert (sexp != NULL);
-
- ret = gck_crypto_sexp_extract_mpi (rsakey, &mpi, "p", NULL);
- g_assert (ret);
- g_assert (mpi != NULL);
-}
-
-DEFINE_TEST(sexp_key_to_public)
-{
- gcry_sexp_t pubkey = NULL;
- guchar id1[20], id2[20];
- gboolean ret;
- guchar *p;
-
- /* RSA */
- ret = gck_crypto_sexp_key_to_public (rsakey, &pubkey);
- g_assert (ret);
- g_assert (pubkey != NULL);
-
- p = gcry_pk_get_keygrip (rsakey, id1);
- g_return_if_fail (p == id1);
- p = gcry_pk_get_keygrip (pubkey, id2);
- g_return_if_fail (p == id2);
-
- g_assert (memcmp (id1, id2, sizeof (id1)) == 0);
-
- gcry_sexp_release (pubkey);
-
-
- /* DSA */
- ret = gck_crypto_sexp_key_to_public (dsakey, &pubkey);
- g_assert (ret);
- g_assert (pubkey != NULL);
-
- p = gcry_pk_get_keygrip (dsakey, id1);
- g_return_if_fail (p == id1);
- p = gcry_pk_get_keygrip (pubkey, id2);
- g_return_if_fail (p == id2);
-
- g_assert (memcmp (id1, id2, sizeof (id1)) == 0);
-
- gcry_sexp_release (pubkey);
-
-}
Added: trunk/gcr/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/gcr/Makefile.am Sun Jan 18 22:24:09 2009
@@ -0,0 +1,62 @@
+incdir = $(includedir)/gcr
+
+inc_HEADERS = \
+ gcr-parser.h \
+ gcr-types.h
+
+INCLUDES = \
+ -I$(top_builddir) \
+ -I$(top_srcdir) \
+ $(GOBJECT_CFLAGS) \
+ $(GLIB_CFLAGS)
+
+BUILT_SOURCES = \
+ gcr-marshal.c gcr-marshal.h
+
+lib_LTLIBRARIES = libgcr.la
+
+libgcr_la_SOURCES = \
+ gcr-internal.c gcr-internal.h \
+ gcr-parser.c gcr-parser.h \
+ gcr-types.h \
+ $(BUILT_SOURCES)
+
+libgcr_la_LDFLAGS = \
+ -version-info $(GCR_LT_RELEASE) \
+ -no-undefined -export-symbols-regex 'gcr_*'
+
+libgcr_la_LIBADD = \
+ $(top_builddir)/egg/libegg.la \
+ $(top_builddir)/gp11/libgp11.la \
+ $(GOBJECT_LIBS) \
+ $(GLIB_LIBS)
+
+gcr-marshal.h: gcr-marshal.list $(GLIB_GENMARSHAL)
+ $(GLIB_GENMARSHAL) $< --header --prefix=_gcr_marshal > $@
+
+gcr-marshal.c: gcr-marshal.list $(GLIB_GENMARSHAL)
+ echo "#include \"gcr-marshal.h\"" > $@ && \
+ $(GLIB_GENMARSHAL) $< --body --prefix=_gcr_marshal >> $@
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gcr-$(GCR_MAJOR).pc
+
+EXTRA_DIST = \
+ gcr.pc.in \
+ gcr-marshal.list
+
+DISTCLEANFILES = \
+ gcr-$(GCR_MAJOR).pc
+
+gcr-$(GCR_MAJOR).pc: gcr.pc
+ cp gcr.pc gcr-$(GCR_MAJOR).pc
+
+if WITH_TESTS
+TESTS_DIR = tests
+else
+TESTS_DIR =
+endif
+
+SUBDIRS = . \
+ $(TESTS_DIR)
+
\ No newline at end of file
Added: trunk/gcr/gcr-import-dialog.glade
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-import-dialog.glade Sun Jan 18 22:24:09 2009
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Sat Jan 17 14:53:28 2009 -->
+<glade-interface>
+ <widget class="GtkDialog" id="dialog1">
+ <property name="border_width">5</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">2</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">1</property>
+ <property name="stock">gtk-dialog-authentication</property>
+ <property name="icon_size">6</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <widget class="GtkLabel" id="primary-text">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes"><span size='large' weight='bold'>Import Certificates and Keys</span></property>
+ <property name="use_markup">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="secondary-text">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Secondary prompt text</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">2</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <widget class="GtkEntry" id="password-entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkComboBox" id="location-combo">
+ <property name="visible">True</property>
+ <property name="button_sensitivity">GTK_SENSITIVITY_ON</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Password:</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Import Into:</property>
+ </widget>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+ <child>
+ <widget class="GtkButton" id="button1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="button2">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="label" translatable="yes">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
Added: trunk/gcr/gcr-importer.c
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-importer.c Sun Jan 18 22:24:09 2009
@@ -0,0 +1,213 @@
+/*
+ * gnome-keyring
+ *
+ * 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 "gcr-importer.h"
+
+enum {
+ PROP_0,
+ PROP_IMPORTER
+};
+
+enum {
+ SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GcrImporter, gcr_importer, G_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+
+static GObject*
+gcr_importer_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GcrImporter *self = GCR_IMPORTER (G_OBJECT_CLASS (gcr_importer_parent_class)->constructor(type, n_props, props));
+ g_return_val_if_fail (self, NULL);
+
+
+
+ return G_OBJECT (self);
+}
+
+static void
+gcr_importer_init (GcrImporter *self)
+{
+
+}
+
+static void
+gcr_importer_dispose (GObject *obj)
+{
+ GcrImporter *self = GCR_IMPORTER (obj);
+
+ G_OBJECT_CLASS (gcr_importer_parent_class)->dispose (obj);
+}
+
+static void
+gcr_importer_finalize (GObject *obj)
+{
+ GcrImporter *self = GCR_IMPORTER (obj);
+
+ G_OBJECT_CLASS (gcr_importer_parent_class)->finalize (obj);
+}
+
+static void
+gcr_importer_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrImporter *self = GCR_IMPORTER (obj);
+
+ switch (prop_id) {
+ case PROP_IMPORTER:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_importer_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrImporter *self = GCR_IMPORTER (obj);
+
+ switch (prop_id) {
+ case PROP_IMPORTER:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_importer_class_init (GcrImporterClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructor = gcr_importer_constructor;
+ gobject_class->dispose = gcr_importer_dispose;
+ gobject_class->finalize = gcr_importer_finalize;
+ gobject_class->set_property = gcr_importer_set_property;
+ gobject_class->get_property = gcr_importer_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_IMPORTER,
+ g_param_spec_pointer ("importer", "Importer", "Importer.", G_PARAM_READWRITE));
+
+ signals[SIGNAL] = g_signal_new ("signal", GCR_TYPE_IMPORTER,
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrImporterClass, signal),
+ NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 0);
+
+ _gcr_initialize ();
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrImporter*
+gcr_importer_new (void)
+{
+ return g_object_new (GCR_TYPE_IMPORTER, NULL);
+}
+
+gboolean
+gcr_importer_import_data (GcrImporter *self, const guchar *data, gsize n_data,
+ GError *err)
+{
+ GckParser *parser;
+ gulong parsed_conn;
+ gulong auth_conn;
+ gboolean ret;
+
+ g_return_val_if_fail (GCR_IS_IMPORTER (self), FALSE);
+ g_return_val_if_fail (data || !n_data, FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+
+
+ xxxx;
+
+
+ /*
+ * Parse to see if it's something that needs a password
+ * if we can't prompt,
+ * return an error
+ * Possibly prompt, if password needed, with all information necessary
+ *
+ */
+
+
+ g_object_ref (self);
+
+ parser = gcr_importer_get_parser (self);
+
+ /* Listen in to the parser */
+ g_object_ref (parser);
+ parsed_conn = g_signal_connect (parser, "parsed-item", G_CALLBACK (parser_parsed_item), self);
+ auth_conn = g_signal_connect (parser, "authenticate", G_CALLBACK (parser_authenticate), self);
+
+ /* Feed the parser the data */
+ ret = gcr_parser_parse_data (parser, data, n_data, err);
+
+ /* Now we should have all the data ready, check if we should prompt... */
+ /* Import data one by one into module */
+
+ g_signal_handler_disconnect (parser, parsed_conn);
+ g_signal_handler_disconnect (parser, auth_conn);
+ g_object_unref (parser);
+
+ g_object_unref (self);
+
+ return ret;
+}
+
+gboolean
+gcr_importer_import_file (GcrImporter *self, const gchar *filename,
+ GError *err)
+{
+ gboolean ret;
+ gchar *data;
+ gsize n_data;
+
+ g_return_val_if_fail (GCR_IS_IMPORTER (self), FALSE);
+ g_return_val_if_fail (filename, FALSE);
+ g_return_val_if_fail (!error || !*error, FALSE);
+
+ if (!g_file_get_contents (filename, &data, &n_data, err))
+ return FALSE;
+
+ ret = gcr_importer_import_data (self, (const guchar*)data, n_data, error);
+ g_free (data);
+
+ return ret;
+}
Added: trunk/gcr/gcr-importer.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-importer.h Sun Jan 18 22:24:09 2009
@@ -0,0 +1,81 @@
+/*
+ * gnome-keyring
+ *
+ * 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 __GCR_IMPORTER_H__
+#define __GCR_IMPORTER_H__
+
+#include <glib-object.h>
+
+#define GCR_TYPE_IMPORTER (gcr_importer_get_type ())
+#define GCR_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_IMPORTER, GcrImporter))
+#define GCR_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_IMPORTER, GcrImporterClass))
+#define GCR_IS_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_IMPORTER))
+#define GCR_IS_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_IMPORTER))
+#define GCR_IMPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_IMPORTER, GcrImporterClass))
+
+typedef struct _GcrImporter GcrImporter;
+typedef struct _GcrImporterClass GcrImporterClass;
+
+struct _GcrImporter {
+ GObject parent;
+};
+
+struct _GcrImporterClass {
+ GObjectClass parent_class;
+
+ /* signals --------------------------------------------------------- */
+
+ void (*signal) (GcrImporter *self, GkrImportedItem *item);
+};
+
+GType gcr_importer_get_type (void);
+
+GcrImporter* gcr_importer_new (void);
+
+GcrImporter* gcr_importer_new_for_module (GP11Module *module);
+
+GcrImporter* gcr_importer_new_for_module_funcs (gpointer pkcs11_funcs);
+
+void gcr_importer_set_slot (GcrImporter *self,
+ GP11Slot *slot);
+
+void gcr_importer_set_slot_id (GcrImporter *self,
+ gulong slot_id);
+
+void gcr_importer_set_parser (GcrImporter *self,
+ GcrParser *parser);
+
+void gcr_importer_set_window (GcrImporter *self,
+ GtkWindow *window);
+
+void gcr_importer_set_prompt_behavior (GcrImporter *self,
+ GcrImporterPromptBehavior behavior);
+
+gboolean gcr_importer_import_data (GcrImporter *self,
+ const guchar *data,
+ gsize n_data,
+ GError *error);
+
+gboolean gcr_importer_import_file (GcrImporter *self,
+ const gchar *filename,
+ GError *error);
+
+#endif /* __GCR_IMPORTER_H__ */
Added: trunk/gcr/gcr-internal.c
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-internal.c Sun Jan 18 22:24:09 2009
@@ -0,0 +1,116 @@
+/*
+ * gnome-keyring
+ *
+ * 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 "gcr-internal.h"
+
+#include "egg/egg-secure-memory.h"
+
+#include <gcrypt.h>
+
+static void
+log_handler (gpointer unused, int unknown, const gchar *msg, va_list va)
+{
+ /* TODO: Figure out additional arguments */
+ g_logv ("gcrypt", G_LOG_LEVEL_MESSAGE, msg, va);
+}
+
+static int
+no_mem_handler (gpointer unused, size_t sz, unsigned int unknown)
+{
+ /* TODO: Figure out additional arguments */
+ g_error ("couldn't allocate %lu bytes of memory",
+ (unsigned long int)sz);
+ return 0;
+}
+
+static void
+fatal_handler (gpointer unused, int unknown, const gchar *msg)
+{
+ /* TODO: Figure out additional arguments */
+ g_log ("gcrypt", G_LOG_LEVEL_ERROR, "%s", msg);
+}
+
+static int
+glib_thread_mutex_init (void **lock)
+{
+ *lock = g_mutex_new ();
+ return 0;
+}
+
+static int
+glib_thread_mutex_destroy (void **lock)
+{
+ g_mutex_free (*lock);
+ return 0;
+}
+
+static int
+glib_thread_mutex_lock (void **lock)
+{
+ g_mutex_lock (*lock);
+ return 0;
+}
+
+static int
+glib_thread_mutex_unlock (void **lock)
+{
+ g_mutex_unlock (*lock);
+ return 0;
+}
+
+static struct gcry_thread_cbs glib_thread_cbs = {
+ GCRY_THREAD_OPTION_USER, NULL,
+ glib_thread_mutex_init, glib_thread_mutex_destroy,
+ glib_thread_mutex_lock, glib_thread_mutex_unlock,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+void
+_gcr_initialize (void)
+{
+ static gsize gcrypt_initialized = FALSE;
+ unsigned seed;
+
+ if (g_once_init_enter (&gcrypt_initialized)) {
+
+ /* Only initialize libgcrypt if it hasn't already been initialized */
+ if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
+ gcry_control (GCRYCTL_SET_THREAD_CBS, &glib_thread_cbs);
+ gcry_check_version (LIBGCRYPT_VERSION);
+ gcry_set_log_handler (log_handler, NULL);
+ gcry_set_outofcore_handler (no_mem_handler, NULL);
+ gcry_set_fatalerror_handler (fatal_handler, NULL);
+ gcry_set_allocation_handler ((gcry_handler_alloc_t)g_malloc,
+ (gcry_handler_alloc_t)egg_secure_alloc,
+ egg_secure_check,
+ (gcry_handler_realloc_t)egg_secure_realloc,
+ egg_secure_free);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+ }
+
+ gcry_create_nonce (&seed, sizeof (seed));
+ srand (seed);
+
+ g_once_init_leave (&gcrypt_initialized, 1);
+ }
+}
Added: trunk/gcr/gcr-internal.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-internal.h Sun Jan 18 22:24:09 2009
@@ -0,0 +1,8 @@
+#ifndef GCR_INTERNAL_H_
+#define GCR_INTERNAL_H_
+
+#include <glib.h>
+
+void _gcr_initialize (void);
+
+#endif /* GCR_INTERNAL_H_ */
Added: trunk/gcr/gcr-marshal.list
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-marshal.list Sun Jan 18 22:24:09 2009
@@ -0,0 +1 @@
+BOOLEAN:INT
Added: trunk/gcr/gcr-parser.c
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-parser.c Sun Jan 18 22:24:09 2009
@@ -0,0 +1,1710 @@
+/*
+ * gnome-keyring
+ *
+ * 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 "gp11/gp11.h"
+
+#include "gcr-internal.h"
+#include "gcr-marshal.h"
+#include "gcr-parser.h"
+#include "gcr-types.h"
+
+#include "egg/egg-asn1.h"
+#include "egg/egg-openssl.h"
+#include "egg/egg-secure-memory.h"
+#include "egg/egg-symkey.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <stdlib.h>
+#include <gcrypt.h>
+#include <libtasn1.h>
+
+enum {
+ PROP_0,
+ PROP_PARSED_LABEL,
+ PROP_PARSED_ATTRIBUTES,
+ PROP_PARSED_DESCRIPTION
+};
+
+enum {
+ AUTHENTICATE,
+ PARSED,
+ LAST_SIGNAL
+};
+
+#define SUCCESS 0
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+struct _GcrParserPrivate {
+ GTree *specific_formats;
+ gboolean normal_formats;
+ GPtrArray *passwords;
+
+ GP11Attributes *parsed_attrs;
+ const gchar *parsed_desc;
+ gchar *parsed_label;
+};
+
+G_DEFINE_TYPE (GcrParser, gcr_parser, G_TYPE_OBJECT);
+
+typedef struct {
+ gint ask_state;
+ gint seen;
+} PasswordState;
+
+#define PASSWORD_STATE_INIT { 0, 0 }
+
+typedef struct _ParserFormat {
+ gint format_id;
+ gint (*function) (GcrParser *self, const guchar *data, gsize n_data);
+} ParserFormat;
+
+/* Forward declarations */
+static const ParserFormat parser_normal[];
+static const ParserFormat parser_formats[];
+static ParserFormat* parser_format_lookup (gint format_id);
+
+/* -----------------------------------------------------------------------------
+ * QUARK DEFINITIONS
+ */
+
+/*
+ * PEM STRINGS
+ * The xxxxx in: ----- BEGIN xxxxx ------
+ */
+
+static GQuark PEM_CERTIFICATE;
+static GQuark PEM_RSA_PRIVATE_KEY;
+static GQuark PEM_DSA_PRIVATE_KEY;
+static GQuark PEM_ANY_PRIVATE_KEY;
+static GQuark PEM_ENCRYPTED_PRIVATE_KEY;
+static GQuark PEM_PRIVATE_KEY;
+static GQuark PEM_PKCS7;
+static GQuark PEM_PKCS12;
+
+/*
+ * OIDS
+ */
+
+static GQuark OID_PKIX1_RSA;
+static GQuark OID_PKIX1_DSA;
+static GQuark OID_PKCS7_DATA;
+static GQuark OID_PKCS7_SIGNED_DATA;
+static GQuark OID_PKCS7_ENCRYPTED_DATA;
+static GQuark OID_PKCS12_BAG_PKCS8_KEY;
+static GQuark OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY;
+static GQuark OID_PKCS12_BAG_CERTIFICATE;
+static GQuark OID_PKCS12_BAG_CRL;
+
+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_PKIX1_RSA, "1.2.840.113549.1.1.1");
+ QUARK (OID_PKIX1_DSA, "1.2.840.10040.4.1");
+ QUARK (OID_PKCS7_DATA, "1.2.840.113549.1.7.1");
+ QUARK (OID_PKCS7_SIGNED_DATA, "1.2.840.113549.1.7.2");
+ QUARK (OID_PKCS7_ENCRYPTED_DATA, "1.2.840.113549.1.7.6");
+ QUARK (OID_PKCS12_BAG_PKCS8_KEY, "1.2.840.113549.1.12.10.1.1");
+ QUARK (OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY, "1.2.840.113549.1.12.10.1.2");
+ QUARK (OID_PKCS12_BAG_CERTIFICATE, "1.2.840.113549.1.12.10.1.3");
+ QUARK (OID_PKCS12_BAG_CRL, "1.2.840.113549.1.12.10.1.4");
+
+ QUARK (PEM_CERTIFICATE, "CERTIFICATE");
+ QUARK (PEM_PRIVATE_KEY, "PRIVATE KEY");
+ QUARK (PEM_RSA_PRIVATE_KEY, "RSA PRIVATE KEY");
+ QUARK (PEM_DSA_PRIVATE_KEY, "DSA PRIVATE KEY");
+ QUARK (PEM_ANY_PRIVATE_KEY, "ANY PRIVATE KEY");
+ QUARK (PEM_ENCRYPTED_PRIVATE_KEY, "ENCRYPTED PRIVATE KEY");
+ QUARK (PEM_PKCS7, "PKCS7");
+ QUARK (PEM_PKCS12, "PKCS12");
+
+ #undef QUARK
+
+ g_once_init_leave (&quarks_inited, 1);
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gboolean
+parsed_asn1_attribute (GcrParser *self, ASN1_TYPE asn, const guchar *data, gsize n_data,
+ const gchar *part, CK_ATTRIBUTE_TYPE type)
+{
+ const guchar *value;
+ gsize n_value;
+
+ g_assert (GCR_IS_PARSER (self));
+ g_assert (asn);
+ g_assert (data);
+ g_assert (part);
+ g_assert (self->pv->parsed_attrs);
+
+ value = egg_asn1_read_content (asn, data, n_data, part, &n_value);
+ if (value == NULL)
+ return FALSE;
+
+ gp11_attributes_add_data (self->pv->parsed_attrs, type, value, n_value);
+ return TRUE;
+}
+
+static void
+parsed_clear (GcrParser *self, CK_OBJECT_CLASS klass)
+{
+ if (self->pv->parsed_attrs)
+ gp11_attributes_unref (self->pv->parsed_attrs);
+ if (klass == CKO_PRIVATE_KEY)
+ self->pv->parsed_attrs = gp11_attributes_new_full ((GP11Allocator)egg_secure_realloc);
+ else
+ self->pv->parsed_attrs = gp11_attributes_new ();
+ gp11_attributes_add_ulong (self->pv->parsed_attrs, CKA_CLASS, klass);
+
+ g_free (self->pv->parsed_label);
+ self->pv->parsed_label = NULL;
+
+ switch (klass) {
+ case CKO_PRIVATE_KEY:
+ self->pv->parsed_desc = _("Private Key");
+ break;
+ case CKO_CERTIFICATE:
+ self->pv->parsed_desc = _("Certificate");
+ break;
+ case CKO_PUBLIC_KEY:
+ self->pv->parsed_desc = _("Public Key");
+ break;
+ default:
+ self->pv->parsed_desc = NULL;
+ break;
+ }
+}
+
+static void
+parsed_label (GcrParser *self, const gchar *label)
+{
+ g_free (self->pv->parsed_label);
+ self->pv->parsed_label = g_strdup (label);
+}
+
+static void
+parsed_attribute (GcrParser *self, CK_ATTRIBUTE_TYPE type, gconstpointer data, gsize n_data)
+{
+ g_assert (GCR_IS_PARSER (self));
+ g_assert (self->pv->parsed_attrs);
+ gp11_attributes_add_data (self->pv->parsed_attrs, type, data, n_data);
+}
+
+static void
+parsed_ulong (GcrParser *self, CK_ATTRIBUTE_TYPE type, gulong value)
+{
+ g_assert (GCR_IS_PARSER (self));
+ g_assert (self->pv->parsed_attrs);
+ gp11_attributes_add_ulong (self->pv->parsed_attrs, type, value);
+}
+
+static gint
+enum_next_password (GcrParser *self, PasswordState *state, const gchar **password)
+{
+ gboolean result;
+
+ /*
+ * Next passes we look through all the passwords that the parser
+ * has seen so far. This is because different parts of a encrypted
+ * container (such as PKCS#12) often use the same password even
+ * if with different algorithms.
+ *
+ * If we didn't do this and the user chooses enters a password,
+ * but doesn't save it, they would get prompted for the same thing
+ * over and over, dumb.
+ */
+
+ /* Look in our list of passwords */
+ if (state->seen < self->pv->passwords->len) {
+ g_assert (state->seen >= 0);
+ *password = g_ptr_array_index (self->pv->passwords, state->seen);
+ ++state->seen;
+ return SUCCESS;
+ }
+
+ /* Fire off all the parsed property signals so anyone watching can update their state */
+ g_object_notify (G_OBJECT (self), "parsed-description");
+ g_object_notify (G_OBJECT (self), "parsed-attributes");
+ g_object_notify (G_OBJECT (self), "parsed-label");
+
+ g_signal_emit (self, signals[AUTHENTICATE], 0, state->ask_state, &result);
+ ++state->ask_state;
+
+ if (!result)
+ return GCR_PARSE_CANCELLED;
+
+ /* Return any passwords added */
+ if (state->seen < self->pv->passwords->len) {
+ g_assert (state->seen >= 0);
+ *password = g_ptr_array_index (self->pv->passwords, state->seen);
+ ++state->seen;
+ return SUCCESS;
+ }
+
+ return GCR_PARSE_LOCKED;
+}
+
+static void
+parsed_fire (GcrParser *self)
+{
+ g_object_notify (G_OBJECT (self), "parsed-description");
+ g_object_notify (G_OBJECT (self), "parsed-attributes");
+ g_object_notify (G_OBJECT (self), "parsed-label");
+
+ g_signal_emit (self, signals[PARSED], 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * RSA PRIVATE KEY
+ */
+
+static gint
+parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+ gint res = GCR_PARSE_UNRECOGNIZED;
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ guint version;
+
+ asn = egg_asn1_decode ("PK.RSAPrivateKey", data, n_data);
+ if (!asn)
+ goto done;
+
+ parsed_clear (self, CKO_PRIVATE_KEY);
+ parsed_ulong (self, CKA_KEY_TYPE, CKK_RSA);
+ res = GCR_PARSE_FAILURE;
+
+ if (!egg_asn1_read_uint (asn, "version", &version))
+ goto done;
+
+ /* We only support simple version */
+ if (version != 0) {
+ res = GCR_PARSE_UNRECOGNIZED;
+ g_message ("unsupported version of RSA key: %u", version);
+ goto done;
+ }
+
+ if (!parsed_asn1_attribute (self, asn, data, n_data, "modulus", CKA_MODULUS) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "publicExponent", CKA_PUBLIC_EXPONENT) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "privateExponent", CKA_PRIVATE_EXPONENT) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "prime1", CKA_PRIME_1) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "prime2", CKA_PRIME_2) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "coefficient", CKA_COEFFICIENT))
+ goto done;
+
+ parsed_fire (self);
+ res = SUCCESS;
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ if (res == GCR_PARSE_FAILURE)
+ g_message ("invalid RSA key");
+
+ return res;
+}
+
+/* -----------------------------------------------------------------------------
+ * DSA PRIVATE KEY
+ */
+
+static gint
+parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+ gint ret = GCR_PARSE_UNRECOGNIZED;
+ int res;
+ ASN1_TYPE asn;
+
+ asn = egg_asn1_decode ("PK.DSAPrivateKey", data, n_data);
+ if (!asn)
+ goto done;
+
+ parsed_clear (self, CKO_PRIVATE_KEY);
+ parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
+ res = GCR_PARSE_FAILURE;
+
+ if (!parsed_asn1_attribute (self, asn, data, n_data, "p", CKA_PRIME) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "q", CKA_SUBPRIME) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "g", CKA_BASE) ||
+ !parsed_asn1_attribute (self, asn, data, n_data, "priv", CKA_VALUE))
+ goto done;
+
+ parsed_fire (self);
+ ret = SUCCESS;
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ if (ret == GCR_PARSE_FAILURE)
+ g_message ("invalid DSA key");
+
+ return ret;
+}
+
+static gint
+parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n_keydata,
+ const guchar *params, gsize n_params)
+{
+ gint ret = GCR_PARSE_UNRECOGNIZED;
+ int res;
+ ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
+ ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
+
+ asn_params = egg_asn1_decode ("PK.DSAParameters", params, n_params);
+ asn_key = egg_asn1_decode ("PK.DSAPrivatePart", keydata, n_keydata);
+ if (!asn_params || !asn_key)
+ goto done;
+
+ parsed_clear (self, CKO_PRIVATE_KEY);
+ parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
+ res = GCR_PARSE_FAILURE;
+
+ if (!parsed_asn1_attribute (self, asn_params, params, n_params, "p", CKA_PRIME) ||
+ !parsed_asn1_attribute (self, asn_params, params, n_params, "q", CKA_SUBPRIME) ||
+ !parsed_asn1_attribute (self, asn_params, params, n_params, "g", CKA_BASE) ||
+ !parsed_asn1_attribute (self, asn_key, keydata, n_keydata, "", CKA_VALUE))
+ goto done;
+
+ parsed_fire (self);
+ ret = SUCCESS;
+
+done:
+ if (asn_key)
+ asn1_delete_structure (&asn_key);
+ if (asn_params)
+ asn1_delete_structure (&asn_params);
+
+ if (ret == GCR_PARSE_FAILURE)
+ g_message ("invalid DSA key");
+
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * PRIVATE KEY
+ */
+
+static gint
+parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
+{
+ gint res;
+
+ res = parse_der_private_key_rsa (self, data, n_data);
+ if (res == GCR_PARSE_UNRECOGNIZED)
+ res = parse_der_private_key_dsa (self, data, n_data);
+
+ return res;
+}
+
+/* -----------------------------------------------------------------------------
+ * PKCS8
+ */
+
+static gint
+parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gint ret;
+ CK_KEY_TYPE key_type;
+ GQuark key_algo;
+ const guchar *keydata;
+ gsize n_keydata;
+ const guchar *params;
+ gsize n_params;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-8-PrivateKeyInfo", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+ key_type = GP11_INVALID;
+
+ key_algo = egg_asn1_read_oid (asn, "privateKeyAlgorithm.algorithm");
+ if (!key_algo)
+ goto done;
+ else if (key_algo == OID_PKIX1_RSA)
+ key_type = CKK_RSA;
+ else if (key_algo == OID_PKIX1_DSA)
+ key_type = CKK_DSA;
+
+ if (key_type == GP11_INVALID) {
+ ret = GCR_PARSE_UNRECOGNIZED;
+ goto done;
+ }
+
+ keydata = egg_asn1_read_content (asn, data, n_data, "privateKey", &n_keydata);
+ if (!keydata)
+ goto done;
+
+ params = egg_asn1_read_element (asn, data, n_data, "privateKeyAlgorithm.parameters",
+ &n_params);
+
+ ret = SUCCESS;
+
+done:
+ if (ret == SUCCESS) {
+ switch (key_type) {
+ case CKK_RSA:
+ ret = parse_der_private_key_rsa (self, keydata, n_keydata);
+ break;
+ case CKK_DSA:
+ /* Try the normal sane format */
+ ret = parse_der_private_key_dsa (self, keydata, n_keydata);
+
+ /* Otherwise try the two part format that everyone seems to like */
+ if (ret == GCR_PARSE_UNRECOGNIZED && params && n_params)
+ ret = parse_der_private_key_dsa_parts (self, keydata, n_keydata,
+ params, n_params);
+ break;
+ default:
+ g_message ("invalid or unsupported key type in PKCS#8 key");
+ ret = GCR_PARSE_UNRECOGNIZED;
+ break;
+ };
+
+ } else if (ret == GCR_PARSE_FAILURE) {
+ g_message ("invalid PKCS#8 key");
+ }
+
+ if (asn)
+ asn1_delete_structure (&asn);
+ return ret;
+}
+
+static gint
+parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
+{
+ PasswordState pstate = PASSWORD_STATE_INIT;
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gcry_cipher_hd_t cih = NULL;
+ gcry_error_t gcry;
+ gint ret, r;
+ GQuark scheme;
+ guchar *crypted = NULL;
+ const guchar *params;
+ gsize n_crypted, n_params;
+ const gchar *password;
+ gint l;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ /* Figure out the type of encryption */
+ scheme = egg_asn1_read_oid (asn, "encryptionAlgorithm.algorithm");
+ if (!scheme)
+ goto done;
+
+ params = egg_asn1_read_element (asn, data, n_data, "encryptionAlgorithm.parameters", &n_params);
+
+ parsed_clear (self, CKO_PRIVATE_KEY);
+
+ /* Loop to try different passwords */
+ for (;;) {
+
+ g_assert (cih == NULL);
+
+ r = enum_next_password (self, &pstate, &password);
+ if (r != SUCCESS) {
+ ret = r;
+ break;
+ }
+
+ /* Parse the encryption stuff into a cipher. */
+ if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih))
+ break;
+
+ crypted = egg_asn1_read_value (asn, "encryptedData", &n_crypted, egg_secure_realloc);
+ if (!crypted)
+ break;
+
+ gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
+ gcry_cipher_close (cih);
+ cih = NULL;
+
+ if (gcry != 0) {
+ g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
+ break;
+ }
+
+ /* Unpad the DER data */
+ l = egg_asn1_element_length (crypted, n_crypted);
+ if (l > 0)
+ n_crypted = l;
+
+ /* Try to parse the resulting key */
+ r = parse_der_pkcs8_plain (self, crypted, n_crypted);
+ egg_secure_free (crypted);
+ crypted = NULL;
+
+ if (r != GCR_PARSE_UNRECOGNIZED) {
+ ret = r;
+ break;
+ }
+
+ /* We assume unrecognized data, is a bad encryption key */
+ }
+
+done:
+ if (cih)
+ gcry_cipher_close (cih);
+ if (asn)
+ asn1_delete_structure (&asn);
+ egg_secure_free (crypted);
+
+ return ret;
+}
+
+static gint
+parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
+{
+ gint ret;
+
+ ret = parse_der_pkcs8_plain (self, data, n_data);
+ if (ret == GCR_PARSE_UNRECOGNIZED)
+ ret = parse_der_pkcs8_encrypted (self, data, n_data);
+
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * CERTIFICATE
+ */
+
+static gint
+parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn;
+ gchar *name;
+
+ asn = egg_asn1_decode ("PKIX1.Certificate", data, n_data);
+ if (asn == NULL)
+ return GCR_PARSE_UNRECOGNIZED;
+
+ parsed_clear (self, CKO_CERTIFICATE);
+ parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
+
+ name = egg_asn1_read_dn_part (asn, "tbsCertificate.subject.rdnSequence", "CN");
+ asn1_delete_structure (&asn);
+
+ if (name != NULL) {
+ parsed_label (self, name);
+ g_free (name);
+ }
+
+ parsed_attribute (self, CKA_VALUE, data, n_data);
+ parsed_fire (self);
+
+ return SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------
+ * PKCS7
+ */
+
+static gint
+handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gint ret;
+ gchar *part;
+ const guchar *certificate;
+ gsize n_certificate;
+ int i;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-7-SignedData", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ for (i = 0; TRUE; ++i) {
+
+ part = g_strdup_printf ("certificates.?%u", i + 1);
+ certificate = egg_asn1_read_element (asn, data, n_data, part, &n_certificate);
+ g_free (part);
+
+ /* No more certificates? */
+ if (!certificate)
+ break;
+
+ ret = parse_der_certificate (self, certificate, n_certificate);
+ if (ret != SUCCESS)
+ goto done;
+ }
+
+ /* TODO: Parse out all the CRLs */
+
+ ret = SUCCESS;
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
+}
+
+static gint
+parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gint ret;
+ const guchar* content = NULL;
+ gsize n_content;
+ GQuark oid;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-7-ContentInfo", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ oid = egg_asn1_read_oid (asn, "contentType");
+ if (!oid)
+ goto done;
+
+ /* Outer most one must just be plain data */
+ if (oid != OID_PKCS7_SIGNED_DATA) {
+ g_message ("unsupported outer content type in pkcs7: %s", g_quark_to_string (oid));
+ goto done;
+ }
+
+ content = egg_asn1_read_content (asn, data, n_data, "content", &n_content);
+ if (!content)
+ goto done;
+
+ ret = handle_pkcs7_signed_data (self, content, n_content);
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * PKCS12
+ */
+
+static gint
+handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ const guchar *certificate;
+ gsize n_certificate;
+ gint ret;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-12-CertBag", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ certificate = egg_asn1_read_content (asn, data, n_data, "certValue", &n_certificate);
+ if (!certificate)
+ goto done;
+
+ /*
+ * Wrapped in an OCTET STRING, so unwrap here, rather than allocating
+ * a whole bunch more memory for a full ASN.1 parsing context.
+ */
+ certificate = egg_asn1_element_content (certificate, n_certificate, &n_certificate);
+ if (!certificate)
+ goto done;
+
+ ret = parse_der_certificate (self, certificate, n_certificate);
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
+}
+
+static gint
+handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gint ret, r;
+ int res, count = 0;
+ GQuark oid;
+ const guchar *element;
+ gsize n_element;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-12-SafeContents", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ /* Get the number of elements in this bag */
+ res = asn1_number_of_elements (asn, "", &count);
+ if (res != ASN1_SUCCESS)
+ goto done;
+
+ /*
+ * Now inside each bag are multiple elements. Who comes up
+ * with this stuff?
+ *
+ * But this is where we draw the line. We only support one
+ * element per bag, not multiple elements, not strange
+ * nested bags, not fairy queens with magical wands in bags...
+ *
+ * Just one element per bag.
+ */
+ if (count >= 1) {
+
+ oid = egg_asn1_read_oid (asn, "?1.bagId");
+ if (!oid)
+ goto done;
+
+ element = egg_asn1_read_content (asn, data, n_data, "?1.bagValue", &n_element);
+ if (!element)
+ goto done;
+
+ /* A normal unencrypted key */
+ if (oid == OID_PKCS12_BAG_PKCS8_KEY) {
+ r = parse_der_pkcs8_plain (self, element, n_element);
+
+ /* A properly encrypted key */
+ } else if (oid == OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
+ r = parse_der_pkcs8_encrypted (self, element, n_element);
+
+ /* A certificate */
+ } else if (oid == OID_PKCS12_BAG_CERTIFICATE) {
+ r = handle_pkcs12_cert_bag (self, element, n_element);
+
+ /* TODO: OID_PKCS12_BAG_CRL */
+ } else {
+ r = GCR_PARSE_UNRECOGNIZED;
+ }
+
+ if (r == GCR_PARSE_FAILURE || r == GCR_PARSE_CANCELLED) {
+ ret = r;
+ goto done;
+ }
+ }
+
+ ret = SUCCESS;
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
+}
+
+static gint
+handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
+{
+ PasswordState pstate = PASSWORD_STATE_INIT;
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gcry_cipher_hd_t cih = NULL;
+ gcry_error_t gcry;
+ guchar *crypted = NULL;
+ const guchar *params;
+ gsize n_params, n_crypted;
+ const gchar *password;
+ GQuark scheme;
+ gint ret, r;
+ gint l;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-7-EncryptedData", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ /* Check the encryption schema OID */
+ scheme = egg_asn1_read_oid (asn, "encryptedContentInfo.contentEncryptionAlgorithm.algorithm");
+ if (!scheme)
+ goto done;
+
+ params = egg_asn1_read_element (asn, data, n_data, "encryptedContentInfo.contentEncryptionAlgorithm.parameters", &n_params);
+ if (!params)
+ goto done;
+
+ parsed_clear (self, 0);
+
+ /* Loop to try different passwords */
+ for (;;) {
+
+ g_assert (cih == NULL);
+
+ r = enum_next_password (self, &pstate, &password);
+ if (r != SUCCESS) {
+ ret = r;
+ goto done;
+ }
+
+ /* Parse the encryption stuff into a cipher. */
+ if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih)) {
+ ret = GCR_PARSE_FAILURE;
+ goto done;
+ }
+
+ crypted = egg_asn1_read_value (asn, "encryptedContentInfo.encryptedContent",
+ &n_crypted, egg_secure_realloc);
+ if (!crypted)
+ goto done;
+
+ gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
+ gcry_cipher_close (cih);
+ cih = NULL;
+
+ if (gcry != 0) {
+ g_warning ("couldn't decrypt pkcs7 data: %s", gcry_strerror (gcry));
+ goto done;
+ }
+
+ /* Unpad the DER data */
+ l = egg_asn1_element_length (crypted, n_crypted);
+ if (l > 0)
+ n_crypted = l;
+
+ /* Try to parse the resulting key */
+ r = handle_pkcs12_bag (self, crypted, n_crypted);
+ egg_secure_free (crypted);
+ crypted = NULL;
+
+ if (r != GCR_PARSE_UNRECOGNIZED) {
+ ret = r;
+ break;
+ }
+
+ /* We assume unrecognized data is a bad encryption key */
+ }
+
+done:
+ if (cih)
+ gcry_cipher_close (cih);
+ if (asn)
+ asn1_delete_structure (&asn);
+ egg_secure_free (crypted);
+
+ return ret;
+}
+
+static gint
+handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gint ret, r;
+ const guchar *bag;
+ gsize n_bag;
+ gchar *part;
+ GQuark oid;
+ guint i;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-12-AuthenticatedSafe", data, n_data);
+ if (!asn)
+ goto done;
+
+ ret = GCR_PARSE_FAILURE;
+
+ /*
+ * Inside each PKCS12 safe there are multiple bags.
+ */
+ for (i = 0; TRUE; ++i) {
+
+ part = g_strdup_printf ("?%u.contentType", i + 1);
+ oid = egg_asn1_read_oid (asn, part);
+ g_free (part);
+
+ /* All done? no more bags */
+ if (!oid)
+ break;
+
+ part = g_strdup_printf ("?%u.content", i + 1);
+ bag = egg_asn1_read_content (asn, data, n_data, part, &n_bag);
+ g_free (part);
+
+ if (!bag) /* A parse error */
+ goto done;
+
+ /* A non encrypted bag, just parse */
+ if (oid == OID_PKCS7_DATA) {
+
+ /*
+ * Wrapped in an OCTET STRING, so unwrap here, rather than allocating
+ * a whole bunch more memory for a full ASN.1 parsing context.
+ */
+ bag = egg_asn1_element_content (bag, n_bag, &n_bag);
+ if (!bag)
+ goto done;
+
+ r = handle_pkcs12_bag (self, bag, n_bag);
+
+ /* Encrypted data first needs decryption */
+ } else if (oid == OID_PKCS7_ENCRYPTED_DATA) {
+ r = handle_pkcs12_encrypted_bag (self, bag, n_bag);
+
+ /* Hmmmm, not sure what this is */
+ } else {
+ g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
+ r = GCR_PARSE_UNRECOGNIZED;
+ }
+
+ if (r == GCR_PARSE_FAILURE || r == GCR_PARSE_CANCELLED) {
+ ret = r;
+ goto done;
+ }
+ }
+
+ ret = SUCCESS;
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+
+ return ret;
+}
+
+static gint
+parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
+{
+ ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ gint ret;
+ const guchar* content = NULL;
+ gsize n_content;
+ GQuark oid;
+
+ ret = GCR_PARSE_UNRECOGNIZED;
+
+ asn = egg_asn1_decode ("PKIX1.pkcs-12-PFX", data, n_data);
+ if (!asn)
+ goto done;
+
+ oid = egg_asn1_read_oid (asn, "authSafe.contentType");
+ if (!oid)
+ goto done;
+
+ /* Outer most one must just be plain data */
+ if (oid != OID_PKCS7_DATA) {
+ g_message ("unsupported safe content type in pkcs12: %s", g_quark_to_string (oid));
+ goto done;
+ }
+
+ content = egg_asn1_read_content (asn, data, n_data, "authSafe.content", &n_content);
+ if (!content)
+ goto done;
+
+ /*
+ * Wrapped in an OCTET STRING, so unwrap here, rather than allocating
+ * a whole bunch more memory for a full ASN.1 parsing context.
+ */
+ content = egg_asn1_element_content (content, n_content, &n_content);
+ if (!content)
+ goto done;
+
+ ret = handle_pkcs12_safe (self, content, n_content);
+
+done:
+ if (asn)
+ asn1_delete_structure (&asn);
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * PEM PARSING
+ */
+
+static gint
+handle_plain_pem (GcrParser *self, GQuark type, gint subformat,
+ const guchar *data, gsize n_data)
+{
+ ParserFormat *format;
+ gint format_id;
+
+ if (type == PEM_RSA_PRIVATE_KEY)
+ format_id = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
+
+ else if (type == PEM_DSA_PRIVATE_KEY)
+ format_id = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
+
+ else if (type == PEM_ANY_PRIVATE_KEY)
+ format_id = GCR_FORMAT_DER_PRIVATE_KEY;
+
+ else if (type == PEM_PRIVATE_KEY)
+ format_id = GCR_FORMAT_DER_PKCS8_PLAIN;
+
+ else if (type == PEM_ENCRYPTED_PRIVATE_KEY)
+ format_id = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
+
+ else if (type == PEM_CERTIFICATE)
+ format_id = GCR_FORMAT_DER_CERTIFICATE_X509;
+
+ else if (type == PEM_PKCS7)
+ format_id = GCR_FORMAT_DER_PKCS7;
+
+ else if (type == PEM_PKCS12)
+ format_id = GCR_FORMAT_DER_PKCS12;
+
+ else
+ return GCR_PARSE_UNRECOGNIZED;
+
+ if (subformat != 0 && subformat != format_id)
+ return GCR_PARSE_UNRECOGNIZED;
+
+ format = parser_format_lookup (format_id);
+ if (format == NULL)
+ return GCR_PARSE_UNRECOGNIZED;
+
+ return (format->function) (self, data, n_data);
+}
+
+static CK_OBJECT_CLASS
+pem_type_to_class (gint type)
+{
+ if (type == PEM_RSA_PRIVATE_KEY ||
+ type == PEM_DSA_PRIVATE_KEY ||
+ type == PEM_ANY_PRIVATE_KEY ||
+ type == PEM_PRIVATE_KEY ||
+ type == PEM_ENCRYPTED_PRIVATE_KEY)
+ return CKO_PRIVATE_KEY;
+
+ else if (type == PEM_CERTIFICATE)
+ return CKO_CERTIFICATE;
+
+ else if (type == PEM_PKCS7 ||
+ type == PEM_PKCS12)
+ return 0;
+
+ return 0;
+}
+
+static gint
+handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
+ GHashTable *headers, const guchar *data, gsize n_data)
+{
+ PasswordState pstate = PASSWORD_STATE_INIT;
+ const gchar *password;
+ guchar *decrypted;
+ gsize n_decrypted;
+ const gchar *val;
+ gboolean ret;
+ gint res;
+ gint l;
+
+ g_assert (GCR_IS_PARSER (self));
+ g_assert (headers);
+ g_assert (type);
+
+ val = g_hash_table_lookup (headers, "DEK-Info");
+ if (!val) {
+ g_message ("missing encryption header");
+ return GCR_PARSE_FAILURE;
+ }
+
+ /* Fill in information necessary for prompting */
+ parsed_clear (self, pem_type_to_class (type));
+
+ for (;;) {
+
+ res = enum_next_password (self, &pstate, &password);
+ if (res != SUCCESS)
+ return res;
+
+ decrypted = NULL;
+ n_decrypted = 0;
+
+ /* Decrypt, this will result in garble if invalid password */
+ ret = egg_openssl_decrypt_block (val, password, -1, data, n_data,
+ &decrypted, &n_decrypted);
+ if (!ret)
+ return GCR_PARSE_FAILURE;
+
+ g_assert (decrypted);
+
+ /* Unpad the DER data */
+ l = egg_asn1_element_length (decrypted, n_decrypted);
+ if (l > 0)
+ n_decrypted = l;
+
+ /* Try to parse */
+ res = handle_plain_pem (self, type, subformat, decrypted, n_decrypted);
+ egg_secure_free (decrypted);
+
+ /* Unrecognized is a bad password */
+ if (res != GCR_PARSE_UNRECOGNIZED)
+ return res;
+ }
+
+ return GCR_PARSE_FAILURE;
+}
+
+typedef struct {
+ GcrParser *parser;
+ gint result;
+ gint subformat;
+} HandlePemArgs;
+
+static void
+handle_pem_data (GQuark type, const guchar *data, gsize n_data,
+ GHashTable *headers, gpointer user_data)
+{
+ HandlePemArgs *args = (HandlePemArgs*)user_data;
+ gint res = GCR_PARSE_FAILURE;
+ gboolean encrypted = FALSE;
+ const gchar *val;
+
+ /* Something already failed to parse */
+ if (args->result == GCR_PARSE_FAILURE)
+ return;
+
+ /* See if it's encrypted PEM all openssl like*/
+ if (headers) {
+ val = g_hash_table_lookup (headers, "Proc-Type");
+ if (val && strcmp (val, "4,ENCRYPTED") == 0)
+ encrypted = TRUE;
+ }
+
+ if (encrypted)
+ res = handle_encrypted_pem (args->parser, type, args->subformat,
+ headers, data, n_data);
+ else
+ res = handle_plain_pem (args->parser, type, args->subformat,
+ data, n_data);
+
+ if (res != GCR_PARSE_UNRECOGNIZED) {
+ if (args->result == GCR_PARSE_UNRECOGNIZED)
+ args->result = res;
+ else if (res > args->result)
+ args->result = res;
+ }
+}
+
+static gint
+handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_data)
+{
+ HandlePemArgs ctx = { self, GCR_PARSE_UNRECOGNIZED, subformat };
+ guint found;
+
+ if (n_data == 0)
+ return GCR_PARSE_UNRECOGNIZED;
+
+ found = egg_openssl_pem_parse (data, n_data, handle_pem_data, &ctx);
+
+ if (found == 0)
+ return GCR_PARSE_UNRECOGNIZED;
+
+ return ctx.result;
+}
+
+
+static gint
+parse_pem (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, 0, data, n_data);
+}
+
+static gint
+parse_pem_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
+}
+
+static gint
+parse_pem_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
+}
+
+static gint
+parse_pem_certificate (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_PEM_CERTIFICATE_X509, data, n_data);
+}
+
+static gint
+parse_pem_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_PLAIN, data, n_data);
+}
+
+static gint
+parse_pem_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_ENCRYPTED, data, n_data);
+}
+
+static gint
+parse_pem_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_PEM_PKCS7, data, n_data);
+}
+
+static gint
+parse_pem_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
+{
+ return handle_pem_format (self, GCR_FORMAT_PEM_PKCS12, data, n_data);
+}
+
+/* -----------------------------------------------------------------------------
+ * FORMATS
+ */
+
+/* In order of parsing when no formats specified */
+static const ParserFormat parser_normal[] = {
+ { GCR_FORMAT_PEM, parse_pem },
+ { GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
+ { GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
+ { GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
+ { GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
+ { GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
+ { GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
+ { GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 }
+};
+
+/* Must be in format_id numeric order */
+static const ParserFormat parser_formats[] = {
+ { GCR_FORMAT_DER_PRIVATE_KEY, parse_der_private_key },
+ { GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
+ { GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
+ { GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
+ { GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
+ { GCR_FORMAT_DER_PKCS8, parse_der_pkcs8 },
+ { GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
+ { GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
+ { GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
+ { GCR_FORMAT_PEM, parse_pem },
+ { GCR_FORMAT_PEM_PRIVATE_KEY_RSA, parse_pem_private_key_rsa },
+ { GCR_FORMAT_PEM_PRIVATE_KEY_DSA, parse_pem_private_key_dsa },
+ { GCR_FORMAT_PEM_CERTIFICATE_X509, parse_pem_certificate },
+ { GCR_FORMAT_PEM_PKCS7, parse_pem_pkcs7 },
+ { GCR_FORMAT_PEM_PKCS8_PLAIN, parse_pem_pkcs8_plain },
+ { GCR_FORMAT_PEM_PKCS8_ENCRYPTED, parse_pem_pkcs8_encrypted },
+ { GCR_FORMAT_PEM_PKCS12, parse_pem_pkcs12 },
+};
+
+static int
+compar_id_to_parser_format (const void *a, const void *b)
+{
+ const gint *format_id = a;
+ const ParserFormat *format = b;
+
+ g_assert (format_id);
+ g_assert (format);
+
+ if (format->format_id == *format_id)
+ return 0;
+ return (*format_id < format->format_id) ? -1 : 1;
+}
+
+static ParserFormat*
+parser_format_lookup (gint format_id)
+{
+ return bsearch (&format_id, parser_formats, G_N_ELEMENTS (parser_formats),
+ sizeof (parser_formats[0]), compar_id_to_parser_format);
+}
+
+static gint
+compare_pointers (gconstpointer a, gconstpointer b)
+{
+ if (a == b)
+ return 0;
+ return a < b ? -1 : 1;
+}
+
+typedef struct _ForeachArgs {
+ GcrParser *parser;
+ const guchar *data;
+ gsize n_data;
+ gint result;
+} ForeachArgs;
+
+static gboolean
+parser_format_foreach (gpointer key, gpointer value, gpointer data)
+{
+ ForeachArgs *args = data;
+ ParserFormat *format = key;
+ gint result;
+
+ g_assert (format);
+ g_assert (format->function);
+ g_assert (GCR_IS_PARSER (args->parser));
+
+ result = (format->function) (args->parser, args->data, args->n_data);
+ if (result != GCR_PARSE_UNRECOGNIZED) {
+ args->result = result;
+ return TRUE;
+ }
+
+ /* Keep going */
+ return FALSE;
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+
+static GObject*
+gcr_parser_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GcrParser *self = GCR_PARSER (G_OBJECT_CLASS (gcr_parser_parent_class)->constructor(type, n_props, props));
+ g_return_val_if_fail (self, NULL);
+
+ /* Always try to parse with NULL and empty passwords first */
+ gcr_parser_add_password (self, NULL);
+ gcr_parser_add_password (self, "");
+
+ return G_OBJECT (self);
+}
+
+static void
+gcr_parser_init (GcrParser *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PARSER, GcrParserPrivate);
+ self->pv->passwords = g_ptr_array_new ();
+ self->pv->normal_formats = TRUE;
+}
+
+static void
+gcr_parser_dispose (GObject *obj)
+{
+ GcrParser *self = GCR_PARSER (obj);
+ gsize i;
+
+ if (self->pv->parsed_attrs)
+ gp11_attributes_unref (self->pv->parsed_attrs);
+ self->pv->parsed_attrs = NULL;
+
+ g_free (self->pv->parsed_label);
+ self->pv->parsed_label = NULL;
+
+ for (i = 0; i < self->pv->passwords->len; ++i)
+ egg_secure_strfree (g_ptr_array_index (self->pv->passwords, i));
+ g_ptr_array_set_size (self->pv->passwords, 0);
+
+ G_OBJECT_CLASS (gcr_parser_parent_class)->dispose (obj);
+}
+
+static void
+gcr_parser_finalize (GObject *obj)
+{
+ GcrParser *self = GCR_PARSER (obj);
+
+ g_assert (!self->pv->parsed_attrs);
+ g_assert (!self->pv->parsed_label);
+
+ g_ptr_array_free (self->pv->passwords, TRUE);
+ self->pv->passwords = NULL;
+
+ G_OBJECT_CLASS (gcr_parser_parent_class)->finalize (obj);
+}
+
+static void
+gcr_parser_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+#if 0
+ GcrParser *self = GCR_PARSER (obj);
+#endif
+ switch (prop_id) {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_parser_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrParser *self = GCR_PARSER (obj);
+
+ switch (prop_id) {
+ case PROP_PARSED_ATTRIBUTES:
+ g_value_set_boxed (value, gcr_parser_get_parsed_attributes (self));
+ break;
+ case PROP_PARSED_LABEL:
+ g_value_set_string (value, gcr_parser_get_parsed_label (self));
+ break;
+ case PROP_PARSED_DESCRIPTION:
+ g_value_set_string (value, gcr_parser_get_parsed_description (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_parser_class_init (GcrParserClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gint i;
+
+ gobject_class->constructor = gcr_parser_constructor;
+ gobject_class->dispose = gcr_parser_dispose;
+ gobject_class->finalize = gcr_parser_finalize;
+ gobject_class->set_property = gcr_parser_set_property;
+ gobject_class->get_property = gcr_parser_get_property;
+
+ g_type_class_add_private (gobject_class, sizeof (GcrParserPrivate));
+
+ g_object_class_install_property (gobject_class, PROP_PARSED_ATTRIBUTES,
+ g_param_spec_boxed ("parsed-attributes", "Parsed Attributes", "Parsed PKCS#11 attributes",
+ GP11_TYPE_ATTRIBUTES, G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class, PROP_PARSED_LABEL,
+ g_param_spec_string ("parsed-label", "Parsed Label", "Parsed item label",
+ "", G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class, PROP_PARSED_DESCRIPTION,
+ g_param_spec_string ("parsed-description", "Parsed Description", "Parsed item description",
+ "", G_PARAM_READABLE));
+
+ signals[AUTHENTICATE] = g_signal_new ("authenticate", GCR_TYPE_PARSER,
+ G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrParserClass, authenticate),
+ g_signal_accumulator_true_handled, NULL, _gcr_marshal_BOOLEAN__INT,
+ G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
+
+ signals[PARSED] = g_signal_new ("parsed", GCR_TYPE_PARSER,
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrParserClass, parsed),
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ init_quarks ();
+ _gcr_initialize ();
+
+ /* Check that the format tables are in order */
+ for (i = 1; i < G_N_ELEMENTS (parser_formats); ++i)
+ g_assert (parser_formats[i].format_id >= parser_formats[i - 1].format_id);
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrParser*
+gcr_parser_new (void)
+{
+ return g_object_new (GCR_TYPE_PARSER, NULL);
+}
+
+GQuark
+gcr_parser_get_error_domain (void)
+{
+ static GQuark domain = 0;
+ if (domain == 0)
+ domain = g_quark_from_static_string ("gcr-parser-error");
+ return domain;
+}
+
+void
+gcr_parser_add_password (GcrParser *self, const gchar *password)
+{
+ g_return_if_fail (GCR_IS_PARSER (self));
+ g_ptr_array_add (self->pv->passwords, egg_secure_strdup (password));
+}
+
+gboolean
+gcr_parser_parse_data (GcrParser *self, const guchar *data,
+ gsize n_data, GError **err)
+{
+ ForeachArgs args = { self, data, n_data, GCR_PARSE_UNRECOGNIZED };
+ const gchar *message;
+ gint i;
+
+ g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+ g_return_val_if_fail (data || !n_data, FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
+
+ /* Just the specific formats requested */
+ if (self->pv->specific_formats) {
+ g_tree_foreach (self->pv->specific_formats, parser_format_foreach, &args);
+
+ /* All the 'normal' formats */
+ } else if (self->pv->normal_formats) {
+ for (i = 0; i < G_N_ELEMENTS (parser_normal); ++i) {
+ if (parser_format_foreach ((gpointer)(parser_normal + i),
+ (gpointer)(parser_normal + i), &args))
+ break;
+ }
+ }
+
+ switch (args.result) {
+ case SUCCESS:
+ return TRUE;
+ case GCR_PARSE_CANCELLED:
+ message = _("The operation was cancelled");
+ break;
+ case GCR_PARSE_UNRECOGNIZED:
+ message = _("Unrecognized or unsupported data.");
+ break;
+ case GCR_PARSE_FAILURE:
+ message = _("Could not parse invalid or corrupted data.");
+ break;
+ case GCR_PARSE_LOCKED:
+ message = _("The data is locked");
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ };
+
+ g_set_error_literal (err, GCR_PARSER_ERROR, args.result, message);
+ return FALSE;
+}
+
+gboolean
+gcr_parser_parse_file (GcrParser *self, const gchar *filename, GError **err)
+{
+ GMappedFile *mapped;
+ gboolean ret;
+ const guchar *data;
+ gsize n_data;
+
+ g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+ g_return_val_if_fail (filename, FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
+
+ mapped = g_mapped_file_new (filename, FALSE, err);
+ if (mapped == NULL)
+ return FALSE;
+
+ data = (const guchar*)g_mapped_file_get_contents (mapped);
+ n_data = g_mapped_file_get_length (mapped);
+
+ ret = gcr_parser_parse_data (self, data, n_data, err);
+
+ g_mapped_file_free (mapped);
+
+ return ret;
+}
+
+gboolean
+gcr_parser_format_enable (GcrParser *self, gint format_id)
+{
+ ParserFormat *format;
+
+ g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+
+ if (format_id == -1) {
+ if (self->pv->specific_formats)
+ g_tree_destroy (self->pv->specific_formats);
+ self->pv->specific_formats = NULL;
+ self->pv->normal_formats = TRUE;
+ return TRUE;
+ }
+
+ format = parser_format_lookup (format_id);
+ if (format == NULL)
+ return FALSE;
+
+ if (!self->pv->specific_formats) {
+ if (self->pv->normal_formats)
+ return TRUE;
+ self->pv->specific_formats = g_tree_new (compare_pointers);
+ }
+
+ g_tree_insert (self->pv->specific_formats, format, format);
+ return TRUE;
+}
+
+gboolean
+gcr_parser_format_disable (GcrParser *self, gint format_id)
+{
+ ParserFormat *format;
+
+ g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+
+ if (format_id == -1) {
+ if (self->pv->specific_formats)
+ g_tree_destroy (self->pv->specific_formats);
+ self->pv->specific_formats = NULL;
+ self->pv->normal_formats = FALSE;
+ return TRUE;
+ }
+
+ if (!self->pv->specific_formats)
+ return TRUE;
+
+ format = parser_format_lookup (format_id);
+ if (format == NULL)
+ return FALSE;
+
+ g_tree_remove (self->pv->specific_formats, format);
+ return TRUE;
+}
+
+gboolean
+gcr_parser_format_supported (GcrParser *self, gint format_id)
+{
+ g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+ g_return_val_if_fail (format_id != -1, FALSE);
+ return parser_format_lookup (format_id) ? TRUE : FALSE;
+}
+
+const gchar*
+gcr_parser_get_parsed_description (GcrParser *self)
+{
+ g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
+ return self->pv->parsed_desc;
+}
+
+GP11Attributes*
+gcr_parser_get_parsed_attributes (GcrParser *self)
+{
+ g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
+ return self->pv->parsed_attrs;
+}
+
+const gchar*
+gcr_parser_get_parsed_label (GcrParser *self)
+{
+ g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
+ return self->pv->parsed_label;
+}
Added: trunk/gcr/gcr-parser.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-parser.h Sun Jan 18 22:24:09 2009
@@ -0,0 +1,92 @@
+/*
+ * gnome-keyring
+ *
+ * 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 __GCR_PARSER_H__
+#define __GCR_PARSER_H__
+
+#include <glib-object.h>
+
+#include "gcr-types.h"
+
+#define GCR_PARSER_ERROR (gcr_parser_get_error_domain ())
+
+#define GCR_TYPE_PARSER (gcr_parser_get_type ())
+#define GCR_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PARSER, GcrParser))
+#define GCR_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PARSER, GcrParserClass))
+#define GCR_IS_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PARSER))
+#define GCR_IS_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PARSER))
+#define GCR_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PARSER, GcrParserClass))
+
+typedef struct _GcrParser GcrParser;
+typedef struct _GcrParsedItem GcrParsedItem;
+typedef struct _GcrParserClass GcrParserClass;
+typedef struct _GcrParserPrivate GcrParserPrivate;
+
+struct _GcrParser {
+ GObject parent;
+ GcrParserPrivate *pv;
+};
+
+struct _GcrParserClass {
+ GObjectClass parent_class;
+
+ /* signals --------------------------------------------------------- */
+
+ /* A callback for each password needed */
+ gboolean (*authenticate) (GcrParser *self, gint count);
+
+ void (*parsed) (GcrParser *self);
+};
+
+GType gcr_parser_get_type (void);
+
+GQuark gcr_parser_get_error_domain (void) G_GNUC_CONST;
+
+GcrParser* gcr_parser_new (void);
+
+gboolean gcr_parser_format_enable (GcrParser *self,
+ gint format);
+
+gboolean gcr_parser_format_disable (GcrParser *self,
+ gint format);
+
+gboolean gcr_parser_format_supported (GcrParser *self,
+ gint format);
+
+gboolean gcr_parser_parse_data (GcrParser *self,
+ const guchar *data,
+ gsize n_data,
+ GError **err);
+
+gboolean gcr_parser_parse_file (GcrParser *self,
+ const gchar *filename,
+ GError **err);
+
+void gcr_parser_add_password (GcrParser *self,
+ const gchar *password);
+
+const gchar* gcr_parser_get_parsed_label (GcrParser *self);
+
+const gchar* gcr_parser_get_parsed_description (GcrParser *self);
+
+GP11Attributes* gcr_parser_get_parsed_attributes (GcrParser *self);
+
+#endif /* __GCR_PARSER_H__ */
Added: trunk/gcr/gcr-types.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-types.h Sun Jan 18 22:24:09 2009
@@ -0,0 +1,45 @@
+#ifndef GCRTYPES_H_
+#define GCRTYPES_H_
+
+enum {
+ GCR_PARSE_FAILURE = -1,
+ GCR_PARSE_UNRECOGNIZED = 1,
+ GCR_PARSE_CANCELLED = 2,
+ GCR_PARSE_LOCKED = 3
+};
+
+enum {
+ GCR_FORMAT_INVALID = 0,
+
+ GCR_FORMAT_DER_PRIVATE_KEY = 100,
+ GCR_FORMAT_DER_PRIVATE_KEY_RSA,
+ GCR_FORMAT_DER_PRIVATE_KEY_DSA,
+
+ GCR_FORMAT_DER_CERTIFICATE_X509 = 200,
+
+ GCR_FORMAT_DER_PKCS7 = 300,
+
+ GCR_FORMAT_DER_PKCS8 = 400,
+ GCR_FORMAT_DER_PKCS8_PLAIN,
+ GCR_FORMAT_DER_PKCS8_ENCRYPTED,
+
+ GCR_FORMAT_DER_PKCS12 = 500,
+
+ GCR_FORMAT_PEM = 1000,
+ GCR_FORMAT_PEM_PRIVATE_KEY_RSA,
+ GCR_FORMAT_PEM_PRIVATE_KEY_DSA,
+ GCR_FORMAT_PEM_CERTIFICATE_X509,
+ GCR_FORMAT_PEM_PKCS7,
+ GCR_FORMAT_PEM_PKCS8_PLAIN,
+ GCR_FORMAT_PEM_PKCS8_ENCRYPTED,
+ GCR_FORMAT_PEM_PKCS12
+};
+
+#ifndef GP11_H
+
+/* Forward declare some of the GP11 objects */
+typedef struct _GP11Attributes GP11Attributes;
+
+#endif /* GP11_H */
+
+#endif /* GCRTYPES_H_ */
Added: trunk/gcr/gcr.pc.in
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr.pc.in Sun Jan 18 22:24:09 2009
@@ -0,0 +1,14 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+datarootdir= datarootdir@
+datadir= datadir@
+sysconfdir= sysconfdir@
+
+Name: gp11
+Description: GObject bindings for PKCS#11
+Version: @VERSION@
+Requires: glib-2.0
+Libs: -L${libdir} -lgp11
+Cflags: -I${includedir}/gp11
Added: trunk/gcr/template/gcr-xxx.c
==============================================================================
--- (empty file)
+++ trunk/gcr/template/gcr-xxx.c Sun Jan 18 22:24:09 2009
@@ -0,0 +1,146 @@
+/*
+ * gnome-keyring
+ *
+ * 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 "gcr-xxx.h"
+
+enum {
+ PROP_0,
+ PROP_XXX
+};
+
+enum {
+ SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+
+struct _GcrXxxPrivate {
+};
+
+G_DEFINE_TYPE (GcrXxx, gcr_xxx, G_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+/* -----------------------------------------------------------------------------
+ * OBJECT
+ */
+
+
+static GObject*
+gcr_xxx_constructor (GType type, guint n_props, GObjectConstructParam *props)
+{
+ GcrXxx *self = GCR_XXX (G_OBJECT_CLASS (gcr_xxx_parent_class)->constructor(type, n_props, props));
+ g_return_val_if_fail (self, NULL);
+
+
+
+ return G_OBJECT (self);
+}
+
+static void
+gcr_xxx_init (GcrXxx *self)
+{
+ self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_XXX, GcrXxxPrivate);
+}
+
+static void
+gcr_xxx_dispose (GObject *obj)
+{
+ GcrXxx *self = GCR_XXX (obj);
+
+ G_OBJECT_CLASS (gcr_xxx_parent_class)->dispose (obj);
+}
+
+static void
+gcr_xxx_finalize (GObject *obj)
+{
+ GcrXxx *self = GCR_XXX (obj);
+
+ G_OBJECT_CLASS (gcr_xxx_parent_class)->finalize (obj);
+}
+
+static void
+gcr_xxx_set_property (GObject *obj, guint prop_id, const GValue *value,
+ GParamSpec *pspec)
+{
+ GcrXxx *self = GCR_XXX (obj);
+
+ switch (prop_id) {
+ case PROP_XXX:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_xxx_get_property (GObject *obj, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ GcrXxx *self = GCR_XXX (obj);
+
+ switch (prop_id) {
+ case PROP_XXX:
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gcr_xxx_class_init (GcrXxxClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->constructor = gcr_xxx_constructor;
+ gobject_class->dispose = gcr_xxx_dispose;
+ gobject_class->finalize = gcr_xxx_finalize;
+ gobject_class->set_property = gcr_xxx_set_property;
+ gobject_class->get_property = gcr_xxx_get_property;
+
+ g_type_class_add_private (gobject_class, sizeof (GcrXxxPrivate));
+
+ g_object_class_install_property (gobject_class, PROP_XXX,
+ g_param_spec_pointer ("xxx", "Xxx", "Xxx.", G_PARAM_READWRITE));
+
+ signals[SIGNAL] = g_signal_new ("signal", GCR_TYPE_XXX,
+ G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrXxxClass, signal),
+ NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+GcrXxx*
+gcr_xxx_new (void)
+{
+ return g_object_new (GCR_TYPE_XXX, NULL);
+}
Added: trunk/gcr/template/gcr-xxx.h
==============================================================================
--- (empty file)
+++ trunk/gcr/template/gcr-xxx.h Sun Jan 18 22:24:09 2009
@@ -0,0 +1,55 @@
+/*
+ * gnome-keyring
+ *
+ * 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 __GCR_XXX_H__
+#define __GCR_XXX_H__
+
+#include <glib-object.h>
+
+#define GCR_TYPE_XXX (gcr_xxx_get_type ())
+#define GCR_XXX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_XXX, GcrXxx))
+#define GCR_XXX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_XXX, GcrXxxClass))
+#define GCR_IS_XXX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_XXX))
+#define GCR_IS_XXX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_XXX))
+#define GCR_XXX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_XXX, GcrXxxClass))
+
+typedef struct _GcrXxx GcrXxx;
+typedef struct _GcrXxxClass GcrXxxClass;
+typedef struct _GcrXxxPrivate GcrXxxPrivate;
+
+struct _GcrXxx {
+ GObject parent;
+ GcrXxxPrivate *pv;
+};
+
+struct _GcrXxxClass {
+ GObjectClass parent_class;
+
+ /* signals --------------------------------------------------------- */
+
+ void (*signal) (GcrXxx *self);
+};
+
+GType gcr_xxx_get_type (void);
+
+GcrXxx* gcr_xxx_new (void);
+
+#endif /* __GCR_XXX_H__ */
Added: trunk/gcr/tests/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/gcr/tests/Makefile.am Sun Jan 18 22:24:09 2009
@@ -0,0 +1,13 @@
+
+# Test files should be listed in order they need to run
+UNIT_AUTO = \
+ unit-test-parser.c
+
+UNIT_PROMPT =
+
+UNIT_LIBS = \
+ $(top_builddir)/gcr/libgcr.la \
+ $(top_builddir)/egg/libegg.la \
+ $(top_builddir)/gp11/libgp11.la
+
+include $(top_srcdir)/tests/gtest.make
Copied: trunk/gcr/tests/unit-test-parser.c (from r1461, /trunk/daemon/pkix/tests/unit-test-pkix-parser.c)
==============================================================================
--- /trunk/daemon/pkix/tests/unit-test-pkix-parser.c (original)
+++ trunk/gcr/tests/unit-test-parser.c Sun Jan 18 22:24:09 2009
@@ -25,11 +25,9 @@
#include "run-auto-test.h"
-#include "common/gkr-location.h"
-#include "common/gkr-crypto.h"
#include "egg/egg-secure-memory.h"
-#include "pkix/gkr-pkix-parser.h"
+#include "gcr/gcr-parser.h"
#include <glib.h>
#include <gcrypt.h>
@@ -52,263 +50,87 @@
* Tests be run in the order specified here.
*/
-static GkrPkixParser *parser = NULL;
+static GcrParser *parser = NULL;
+static const gchar* filedesc = NULL;
-static GQuark last_type_parsed = 0;
-static gcry_sexp_t last_sexp_parsed = NULL;
-static ASN1_TYPE last_asn1_parsed = NULL;
-static guint n_parsed = 0;
-
-static CuTest *the_cu = NULL;
-
-static gboolean
-parsed_partial (GkrPkixParser *parser, GQuark location, gkrconstid digest,
- GQuark type, gpointer user_data)
+static void
+parsed_item (GcrParser *par, gpointer user_data)
{
- CuTest *cu = the_cu;
- g_assert (cu);
-
- CuAssert (cu, "location is empty", location != 0);
- CuAssert (cu, "location is invalid", gkr_location_to_path (location) != NULL);
- CuAssert (cu, "digest is empty", digest != NULL);
- CuAssert (cu, "type is invalid", type != 0);
+ GP11Attributes *attrs;
+ const gchar *description;
+ const gchar *label;
- g_print ("parsed partial at: %s\n", g_quark_to_string (location));
- last_sexp_parsed = NULL;
- last_type_parsed = type;
- ++n_parsed;
+ g_assert (GCR_IS_PARSER (par));
+ g_assert (par == parser);
+ g_assert (par == user_data);
- return TRUE;
-}
-
-static gboolean
-parsed_sexp (GkrPkixParser *parser, GQuark location, gkrconstid digest,
- GQuark type, gcry_sexp_t sexp, gpointer user_data)
-{
- CuTest *cu = the_cu;
- g_assert (cu);
-
- CuAssert (cu, "location is empty", location != 0);
- CuAssert (cu, "location is invalid", gkr_location_to_path (location) != NULL);
- CuAssert (cu, "digest is empty", digest != NULL);
- CuAssert (cu, "type is invalid", type != 0);
- CuAssert (cu, "sexp is invalid", sexp != NULL);
-
- g_print ("parsed sexp at: %s\n", g_quark_to_string (location));
-
- last_sexp_parsed = sexp;
- last_type_parsed = type;
- ++n_parsed;
-
- return TRUE;
-}
-
-static gboolean
-parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstid digest,
- GQuark type, ASN1_TYPE asn1, gpointer user_data)
-{
- CuTest *cu = the_cu;
- g_assert (cu);
-
- CuAssert (cu, "location is empty", location != 0);
- CuAssert (cu, "location is invalid", gkr_location_to_path (location) != NULL);
- CuAssert (cu, "digest is empty", digest != NULL);
- CuAssert (cu, "type is invalid", type != 0);
- CuAssert (cu, "asn1 is invalid", asn1 != NULL);
-
- g_print ("parsed asn1 at: %s\n", g_quark_to_string (location));
-
- last_asn1_parsed = asn1;
- last_type_parsed = type;
- ++n_parsed;
+ attrs = gcr_parser_get_parsed_attributes (parser);
+ description = gcr_parser_get_parsed_description (parser);
+ label = gcr_parser_get_parsed_label (parser);
- return TRUE;
+ g_print ("parsed %s '%s' at: %s\n", description, label, filedesc);
}
static gboolean
-ask_password (GkrPkixParser *parser, GQuark loc, gkrconstid digest,
- GQuark type, const gchar *details, gint *state,
- gchar **password, gpointer user_data)
+authenticate (GcrParser *par, gint state, gpointer user_data)
{
- CuTest *cu = the_cu;
- gchar *msg;
- gint st;
-
- g_assert (cu);
- CuAssert (cu, "state is null", state != NULL);
- CuAssert (cu, "state is bad", *state >= 0 && *state < 3);
-
- st = *state;
- (*state)++;
+ g_assert (GCR_IS_PARSER (par));
+ g_assert (par == parser);
+ g_assert (par == user_data);
- CuAssert (cu, "location is empty", loc != 0);
- CuAssert (cu, "details is null", details != NULL);
-
- /* Return "", null, and "booo" in that order */
- switch (st) {
+ switch (state) {
case 0:
- *password = egg_secure_strdup ("");
- return TRUE;
- case 1:
- *password = NULL;
- return TRUE;
- case 2:
- /* Most of our test encrypted stuff use this password */
- g_print ("getting password 'booo' for: %s\n", details);
- *password = egg_secure_strdup ("booo");
+ gcr_parser_add_password (parser, "booo");
return TRUE;
default:
- msg = g_strdup_printf ("decryption didn't work for: %s", g_quark_to_string (loc));
- CuAssert (cu, msg, FALSE);
- return FALSE;
+ g_printerr ("decryption didn't work for: %s", filedesc);
+ g_assert (FALSE);
};
-}
+}
-static void
-read_file (CuTest *cu, const gchar *filename, GQuark *location, guchar **contents, gsize *len)
+DEFINE_SETUP(parser)
{
- gchar *path;
- gboolean ret;
-
- the_cu = cu;
-
- path = g_build_filename (g_get_current_dir (), "test-data", filename, NULL);
- *location = gkr_location_from_path (path);
- CuAssert (cu, "location is empty", *location != 0);
-
- ret = g_file_get_contents (path, (gchar**)contents, len, NULL);
- CuAssert (cu, "couldn't read in file", ret);
-
- g_free (path);
+ parser = gcr_parser_new ();
+ g_signal_connect (parser, "parsed", G_CALLBACK (parsed_item), parser);
+ g_signal_connect (parser, "authenticate", G_CALLBACK (authenticate), parser);
}
-
-void unit_test_start_parser (CuTest *cu)
+DEFINE_TEARDOWN(parser)
{
- parser = gkr_pkix_parser_new (FALSE);
- g_signal_connect (parser, "parsed-partial", G_CALLBACK (parsed_partial), NULL);
- g_signal_connect (parser, "parsed-sexp", G_CALLBACK (parsed_sexp), NULL);
- g_signal_connect (parser, "parsed-asn1", G_CALLBACK (parsed_asn1), NULL);
- g_signal_connect (parser, "ask-password", G_CALLBACK (ask_password), NULL);
+ g_object_unref (parser);
+ parser = NULL;
}
-void unit_test_pkix_parse_der_keys (CuTest* cu)
+DEFINE_TEST(parse_all)
{
guchar *contents;
- GkrPkixResult result;
- GQuark location;
- gsize len;
-
- the_cu = cu;
-
- /* First an RSA key */
- read_file (cu, "der-rsa-1024.key", &location, &contents, &len);
-
- last_sexp_parsed = NULL;
- result = gkr_pkix_parser_der_private_key (parser, location, contents, len);
- CuAssert (cu, "couldn't parse RSA key", result == GKR_PKIX_SUCCESS);
- CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-
- gkr_crypto_sexp_dump (last_sexp_parsed);
-
- /* Now a DSA key */
- read_file (cu, "der-dsa-1024.key", &location, &contents, &len);
-
- last_sexp_parsed = NULL;
- result = gkr_pkix_parser_der_private_key (parser, location, contents, len);
- CuAssert (cu, "couldn't parse DSA key", result == GKR_PKIX_SUCCESS);
- CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-
- gkr_crypto_sexp_dump (last_sexp_parsed);
-}
-
-void unit_test_pkix_parse_der_pkcs8 (CuTest* cu)
-{
- guchar *contents;
- GkrPkixResult result;
- GQuark location;
- gsize len;
-
- the_cu = cu;
-
- /* First an DSA key */
- read_file (cu, "der-pkcs8-dsa.key", &location, &contents, &len);
-
- last_sexp_parsed = NULL;
- result = gkr_pkix_parser_der_pkcs8_plain (parser, location, contents, len);
- CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PKIX_SUCCESS);
- CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-
- gkr_crypto_sexp_dump (last_sexp_parsed);
-
- /* Now an encrypted key */
- read_file (cu, "der-pkcs8-encrypted-pkcs5.key", &location, &contents, &len);
-
- last_sexp_parsed = NULL;
- result = gkr_pkix_parser_der_pkcs8_encrypted (parser, location, contents, len);
- CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PKIX_SUCCESS);
- CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-
- gkr_crypto_sexp_dump (last_sexp_parsed);
-}
-
-void unit_test_pkix_parse_pem (CuTest *cu)
-{
- guchar *contents;
- GkrPkixResult result;
- GQuark location;
- gsize len;
-
- the_cu = cu;
-
- /* First an RSA key */
- read_file (cu, "pem-dsa-1024.key", &location, &contents, &len);
-
- n_parsed = 0;
- result = gkr_pkix_parser_pem (parser, location, contents, len);
- CuAssert (cu, "couldn't parse PEM data", result == GKR_PKIX_SUCCESS);
-
- CuAssert (cu, "invalid number of items parsed", n_parsed == 1);
- CuAssert (cu, "invalid type of data parsed", last_sexp_parsed != NULL);
-
- gkr_crypto_sexp_dump (last_sexp_parsed);
-}
-
-void unit_test_pkix_parse_all (CuTest *cu)
-{
- gchar *path, *filepath, *msg;
- guchar *contents;
GError *err = NULL;
gboolean result;
const gchar *filename;
- GQuark location;
gsize len;
GDir *dir;
- the_cu = cu;
- path = g_build_filename (g_get_current_dir (), "test-data", NULL);
-
- dir = g_dir_open (path, 0, NULL);
- CuAssert (cu, "couldn't open directory", dir != NULL);
+ dir = g_dir_open ("test-data", 0, NULL);
+ g_assert (dir);
- while (dir) {
+ for (;;) {
filename = g_dir_read_name (dir);
if (!filename)
break;
-
- filepath = g_build_filename (path, filename, NULL);
- if (!g_file_test (filepath, G_FILE_TEST_IS_REGULAR))
+ if (filename[0] == '.')
continue;
- read_file (cu, filename, &location, &contents, &len);
+ filedesc = filename;
+ contents = test_read_testdata (filename, &len);
- result = gkr_pkix_parser_parse (parser, location, contents, len, &err);
+ result = gcr_parser_parse_data (parser, contents, len, &err);
if (!result) {
- msg = g_strdup_printf ("couldn't parse file data: %s: %s",
- filename, err && err->message ? err->message : "");
+ g_warning ("couldn't parse file data: %s: %s",
+ filename, err && err->message ? err->message : "");
g_error_free (err);
- err = NULL;
- CuAssert (cu, msg, FALSE);
+ g_assert (FALSE);
}
}
+
+ g_dir_close (dir);
}
Modified: trunk/gp11/gp11.h
==============================================================================
--- trunk/gp11/gp11.h (original)
+++ trunk/gp11/gp11.h Sun Jan 18 22:24:09 2009
@@ -21,8 +21,8 @@
Author: Stef Walter <nielsen memberwebs com>
*/
-#ifndef GP11_H_
-#define GP11_H_
+#ifndef GP11_H
+#define GP11_H
#include <glib.h>
#include <glib-object.h>
@@ -1431,4 +1431,4 @@
G_END_DECLS
-#endif /*GP11_H_*/
+#endif /*GP11_H*/
Modified: trunk/pkcs11/gck/Makefile.am
==============================================================================
--- trunk/pkcs11/gck/Makefile.am (original)
+++ trunk/pkcs11/gck/Makefile.am Sun Jan 18 22:24:09 2009
@@ -24,8 +24,6 @@
gck-data-asn1.c gck-data-asn1.h \
gck-data-der.c gck-data-der.h \
gck-data-file.c gck-data-file.h \
- gck-data-openssl.c gck-data-openssl.h \
- gck-data-pem.c gck-data-pem.h \
gck-data-types.h \
gck-factory.c gck-factory.h \
gck-file-tracker.c gck-file-tracker.h \
Modified: trunk/pkcs11/gck/gck-crypto.c
==============================================================================
--- trunk/pkcs11/gck/gck-crypto.c (original)
+++ trunk/pkcs11/gck/gck-crypto.c Sun Jan 18 22:24:09 2009
@@ -977,520 +977,6 @@
return unpad_rsa_pkcs1 (0x02, bits, padded, n_padded, n_raw);
}
-/* -----------------------------------------------------------------------------
- * PASSWORD TO KEY/IV
- */
-
-gboolean
-gck_crypto_symkey_generate_simple (int cipher_algo, int hash_algo,
- const gchar *password, gssize n_password,
- const guchar *salt, gsize n_salt, int iterations,
- guchar **key, guchar **iv)
-{
- gcry_md_hd_t mdh;
- gcry_error_t gcry;
- guchar *digest;
- guchar *digested;
- guint n_digest;
- gint pass, i;
- gint needed_iv, needed_key;
- guchar *at_iv, *at_key;
-
- g_assert (cipher_algo);
- g_assert (hash_algo);
-
- g_return_val_if_fail (iterations >= 1, FALSE);
-
- if (!password)
- n_password = 0;
- if (n_password == -1)
- n_password = strlen (password);
-
- /*
- * If cipher algo needs more bytes than hash algo has available
- * then the entire hashing process is done again (with the previous
- * hash bytes as extra input), and so on until satisfied.
- */
-
- needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
- needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
-
- gcry = gcry_md_open (&mdh, hash_algo, 0);
- if (gcry) {
- g_warning ("couldn't create '%s' hash context: %s",
- gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
- return FALSE;
- }
-
- n_digest = gcry_md_get_algo_dlen (hash_algo);
- g_return_val_if_fail (n_digest > 0, FALSE);
-
- digest = gcry_calloc_secure (n_digest, 1);
- g_return_val_if_fail (digest, FALSE);
- if (key) {
- *key = gcry_calloc_secure (needed_key, 1);
- g_return_val_if_fail (*key, FALSE);
- }
- if (iv)
- *iv = g_new0 (guchar, needed_iv);
-
- at_key = key ? *key : NULL;
- at_iv = iv ? *iv : NULL;
-
- for (pass = 0; TRUE; ++pass) {
- gcry_md_reset (mdh);
-
- /* Hash in the previous buffer on later passes */
- if (pass > 0)
- gcry_md_write (mdh, digest, n_digest);
-
- if (password)
- gcry_md_write (mdh, password, n_password);
- if (salt && n_salt)
- gcry_md_write (mdh, salt, n_salt);
- gcry_md_final (mdh);
- digested = gcry_md_read (mdh, 0);
- g_return_val_if_fail (digested, FALSE);
- memcpy (digest, digested, n_digest);
-
- for (i = 1; i < iterations; ++i) {
- gcry_md_reset (mdh);
- gcry_md_write (mdh, digest, n_digest);
- gcry_md_final (mdh);
- digested = gcry_md_read (mdh, 0);
- g_return_val_if_fail (digested, FALSE);
- memcpy (digest, digested, n_digest);
- }
-
- /* Copy as much as possible into the destinations */
- i = 0;
- while (needed_key && i < n_digest) {
- if (at_key)
- *(at_key++) = digest[i];
- needed_key--;
- i++;
- }
- while (needed_iv && i < n_digest) {
- if (at_iv)
- *(at_iv++) = digest[i];
- needed_iv--;
- i++;
- }
-
- if (needed_key == 0 && needed_iv == 0)
- break;
- }
-
- gcry_free (digest);
- gcry_md_close (mdh);
-
- return TRUE;
-}
-
-gboolean
-gck_crypto_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
- gssize n_password, const guchar *salt, gsize n_salt, int iterations,
- guchar **key, guchar **iv)
-{
- gcry_md_hd_t mdh;
- gcry_error_t gcry;
- guchar *digest;
- guchar *digested;
- guint i, n_digest;
- gint needed_iv, needed_key;
-
- g_assert (cipher_algo);
- g_assert (hash_algo);
-
- g_return_val_if_fail (iterations >= 1, FALSE);
-
- if (!password)
- n_password = 0;
- if (n_password == -1)
- n_password = strlen (password);
-
- /*
- * We only do one pass here.
- *
- * The key ends up as the first needed_key bytes of the hash buffer.
- * The iv ends up as the last needed_iv bytes of the hash buffer.
- *
- * The IV may overlap the key (which is stupid) if the wrong pair of
- * hash/cipher algorithms are chosen.
- */
-
- n_digest = gcry_md_get_algo_dlen (hash_algo);
- g_return_val_if_fail (n_digest > 0, FALSE);
-
- needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
- needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
- if (needed_iv + needed_key > 16 || needed_iv + needed_key > n_digest) {
- g_warning ("using PBE symkey generation with %s using an algorithm that needs "
- "too many bytes of key and/or IV: %s",
- gcry_cipher_algo_name (hash_algo),
- gcry_cipher_algo_name (cipher_algo));
- return FALSE;
- }
-
- gcry = gcry_md_open (&mdh, hash_algo, 0);
- if (gcry) {
- g_warning ("couldn't create '%s' hash context: %s",
- gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
- return FALSE;
- }
-
- digest = gcry_calloc_secure (n_digest, 1);
- g_return_val_if_fail (digest, FALSE);
- if (key) {
- *key = gcry_calloc_secure (needed_key, 1);
- g_return_val_if_fail (*key, FALSE);
- }
- if (iv)
- *iv = g_new0 (guchar, needed_iv);
-
- if (password)
- gcry_md_write (mdh, password, n_password);
- if (salt && n_salt)
- gcry_md_write (mdh, salt, n_salt);
- gcry_md_final (mdh);
- digested = gcry_md_read (mdh, 0);
- g_return_val_if_fail (digested, FALSE);
- memcpy (digest, digested, n_digest);
-
- for (i = 1; i < iterations; ++i)
- gcry_md_hash_buffer (hash_algo, digest, digest, n_digest);
-
- /* The first x bytes are the key */
- if (key) {
- g_assert (needed_key <= n_digest);
- memcpy (*key, digest, needed_key);
- }
-
- /* The last 16 - x bytes are the iv */
- if (iv) {
- g_assert (needed_iv <= n_digest && n_digest >= 16);
- memcpy (*iv, digest + (16 - needed_iv), needed_iv);
- }
-
- gcry_free (digest);
- gcry_md_close (mdh);
-
- return TRUE;
-}
-
-static gboolean
-generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
- gssize n_password, const guchar *salt, gsize n_salt,
- int iterations, guchar *output, gsize n_output)
-{
- gcry_mpi_t num_b1, num_ij;
- guchar *hash, *buf_i, *buf_b;
- const gchar *end_password;
- gcry_md_hd_t mdh;
- const gchar *p2;
- guchar *p;
- gsize n_hash, i;
- gunichar unich;
- gcry_error_t gcry;
-
- num_b1 = num_ij = NULL;
-
- n_hash = gcry_md_get_algo_dlen (hash_algo);
- g_return_val_if_fail (n_hash > 0, FALSE);
-
- if (!utf8_password)
- n_password = 0;
- if (n_password == -1)
- end_password = utf8_password + strlen (utf8_password);
- else
- end_password = utf8_password + n_password;
-
- gcry = gcry_md_open (&mdh, hash_algo, 0);
- if (gcry) {
- g_warning ("couldn't create '%s' hash context: %s",
- gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
- return FALSE;
- }
-
- /* Reqisition me a buffer */
- hash = gcry_calloc_secure (n_hash, 1);
- buf_i = gcry_calloc_secure (1, 128);
- buf_b = gcry_calloc_secure (1, 64);
- g_return_val_if_fail (hash && buf_i && buf_b, FALSE);
-
- /* Bring in the salt */
- p = buf_i;
- if (salt) {
- for (i = 0; i < 64; ++i)
- *(p++) = salt[i % n_salt];
- } else {
- memset (p, 0, 64);
- p += 64;
- }
-
- /* Bring in the password, as 16bits per character BMP string, ie: UCS2 */
- if (utf8_password) {
- p2 = utf8_password;
- for (i = 0; i < 64; i += 2) {
-
- /* Get a character from the string */
- if (p2 < end_password) {
- unich = g_utf8_get_char (p2);
- p2 = g_utf8_next_char (p2);
-
- /* Get zero null terminator, and loop back to beginning */
- } else {
- unich = 0;
- p2 = utf8_password;
- }
-
- /* Encode the bytes received */
- *(p++) = (unich & 0xFF00) >> 8;
- *(p++) = (unich & 0xFF);
- }
- } else {
- memset (p, 0, 64);
- p += 64;
- }
-
- /* Hash and bash */
- for (;;) {
- gcry_md_reset (mdh);
-
- /* Put in the PKCS#12 type of key */
- for (i = 0; i < 64; ++i)
- gcry_md_putc (mdh, type);
-
- /* Bring in the password */
- gcry_md_write (mdh, buf_i, utf8_password ? 128 : 64);
-
- /* First iteration done */
- memcpy (hash, gcry_md_read (mdh, hash_algo), n_hash);
-
- /* All the other iterations */
- for (i = 1; i < iterations; i++)
- gcry_md_hash_buffer (hash_algo, hash, hash, n_hash);
-
- /* Take out as much as we need */
- for (i = 0; i < n_hash && n_output; ++i) {
- *(output++) = hash[i];
- --n_output;
- }
-
- /* Is that enough generated keying material? */
- if (!n_output)
- break;
-
- /* Need more bytes, do some voodoo */
- for (i = 0; i < 64; ++i)
- buf_b[i] = hash[i % n_hash];
- gcry = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
- gcry_mpi_add_ui (num_b1, num_b1, 1);
- for (i = 0; i < 128; i += 64) {
- gcry = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, NULL);
- g_return_val_if_fail (gcry == 0, FALSE);
- gcry_mpi_add (num_ij, num_ij, num_b1);
- gcry_mpi_clear_highbit (num_ij, 64 * 8);
- gcry = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, NULL, num_ij);
- g_return_val_if_fail (gcry == 0, FALSE);
- gcry_mpi_release (num_ij);
- }
- }
-
- gcry_free (buf_i);
- gcry_free (buf_b);
- gcry_free (hash);
- gcry_mpi_release (num_b1);
- gcry_md_close (mdh);
-
- return TRUE;
-}
-
-gboolean
-gck_crypto_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password,
- gssize n_password, const guchar *salt, gsize n_salt,
- int iterations, guchar **key, guchar **iv)
-{
- gsize n_block, n_key;
- gboolean ret = TRUE;
-
- g_return_val_if_fail (cipher_algo, FALSE);
- g_return_val_if_fail (hash_algo, FALSE);
- g_return_val_if_fail (iterations > 0, FALSE);
-
- n_key = gcry_cipher_get_algo_keylen (cipher_algo);
- n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-
- if (password && !g_utf8_validate (password, n_password, NULL)) {
- g_warning ("invalid non-UTF8 password");
- g_return_val_if_reached (FALSE);
- }
-
- if (key)
- *key = NULL;
- if (iv)
- *iv = NULL;
-
- /* Generate us an key */
- if (key) {
- *key = gcry_calloc_secure (n_key, 1);
- g_return_val_if_fail (*key != NULL, FALSE);
- ret = generate_pkcs12 (hash_algo, 1, password, n_password, salt, n_salt,
- iterations, *key, n_key);
- }
-
- /* Generate us an iv */
- if (ret && iv) {
- if (n_block > 1) {
- *iv = g_malloc (n_block);
- ret = generate_pkcs12 (hash_algo, 2, password, n_password, salt, n_salt,
- iterations, *iv, n_block);
- } else {
- *iv = NULL;
- }
- }
-
- /* Cleanup in case of failure */
- if (!ret) {
- g_free (iv ? *iv : NULL);
- gcry_free (key ? *key : NULL);
- }
-
- return ret;
-}
-
-static gboolean
-generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
- const guchar *salt, gsize n_salt, guint iterations,
- guchar *output, gsize n_output)
-{
- gcry_md_hd_t mdh;
- guint u, l, r, i, k;
- gcry_error_t gcry;
- guchar *U, *T, *buf;
- gsize n_buf, n_hash;
-
- g_return_val_if_fail (hash_algo > 0, FALSE);
- g_return_val_if_fail (iterations > 0, FALSE);
- g_return_val_if_fail (n_output > 0, FALSE);
- g_return_val_if_fail (n_output < G_MAXUINT32, FALSE);
-
- n_hash = gcry_md_get_algo_dlen (hash_algo);
- g_return_val_if_fail (n_hash > 0, FALSE);
-
- gcry = gcry_md_open (&mdh, hash_algo, GCRY_MD_FLAG_HMAC);
- if (gcry != 0) {
- g_warning ("couldn't create '%s' hash context: %s",
- gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
- return FALSE;
- }
-
- /* Get us a temporary buffers */
- T = gcry_calloc_secure (n_hash, 1);
- U = gcry_calloc_secure (n_hash, 1);
- n_buf = n_salt + 4;
- buf = gcry_calloc_secure (n_buf, 1);
- g_return_val_if_fail (buf && T && U, FALSE);
-
- /* n_hash blocks in output, rounding up */
- l = ((n_output - 1) / n_hash) + 1;
-
- /* number of bytes in last, rounded up, n_hash block */
- r = n_output - (l - 1) * n_hash;
-
- memcpy (buf, salt, n_salt);
- for (i = 1; i <= l; i++) {
- memset (T, 0, n_hash);
- for (u = 1; u <= iterations; u++) {
- gcry_md_reset (mdh);
-
- gcry = gcry_md_setkey (mdh, password, n_password);
- g_return_val_if_fail (gcry == 0, FALSE);
-
- /* For first iteration on each block add 4 extra bytes */
- if (u == 1) {
- buf[n_salt + 0] = (i & 0xff000000) >> 24;
- buf[n_salt + 1] = (i & 0x00ff0000) >> 16;
- buf[n_salt + 2] = (i & 0x0000ff00) >> 8;
- buf[n_salt + 3] = (i & 0x000000ff) >> 0;
-
- gcry_md_write (mdh, buf, n_buf);
-
- /* Other iterations, any block */
- } else {
- gcry_md_write (mdh, U, n_hash);
- }
-
- memcpy (U, gcry_md_read (mdh, hash_algo), n_hash);
-
- for (k = 0; k < n_hash; k++)
- T[k] ^= U[k];
- }
-
- memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
- }
-
- gcry_free (T);
- gcry_free (U);
- gcry_free (buf);
- gcry_md_close (mdh);
- return TRUE;
-}
-
-gboolean
-gck_crypto_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
- const gchar *password, gssize n_password,
- const guchar *salt, gsize n_salt, int iterations,
- guchar **key, guchar **iv)
-{
- gsize n_key, n_block;
- gboolean ret = TRUE;
-
- g_return_val_if_fail (hash_algo, FALSE);
- g_return_val_if_fail (cipher_algo, FALSE);
- g_return_val_if_fail (iterations > 0, FALSE);
-
- n_key = gcry_cipher_get_algo_keylen (cipher_algo);
- n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-
- if (key)
- *key = NULL;
- if (iv)
- *iv = NULL;
-
- if (!password)
- n_password = 0;
- if (n_password == -1)
- n_password = strlen (password);
-
- /* Generate us an key */
- if (key) {
- *key = gcry_calloc_secure (n_key, 1);
- g_return_val_if_fail (*key != NULL, FALSE);
- ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt,
- iterations, *key, n_key);
- }
-
- /* Generate us an iv */
- if (ret && iv) {
- if (n_block > 1) {
- *iv = g_malloc (n_block);
- gcry_create_nonce (*iv, n_block);
- } else {
- *iv = NULL;
- }
- }
-
- /* Cleanup in case of failure */
- if (!ret) {
- g_free (iv ? *iv : NULL);
- gcry_free (key ? *key : NULL);
- }
-
- return ret;
-}
-
/* --------------------------------------------------------------------------
* INITIALIZATION
*/
Modified: trunk/pkcs11/gck/gck-crypto.h
==============================================================================
--- trunk/pkcs11/gck/gck-crypto.h (original)
+++ trunk/pkcs11/gck/gck-crypto.h Sun Jan 18 22:24:09 2009
@@ -159,44 +159,4 @@
gsize n_padded,
gsize *n_raw);
-gboolean gck_crypto_symkey_generate_simple (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-gboolean gck_crypto_symkey_generate_pbe (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-gboolean gck_crypto_symkey_generate_pkcs12 (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
-gboolean gck_crypto_symkey_generate_pbkdf2 (int cipher_algo,
- int hash_algo,
- const gchar *password,
- gssize n_password,
- const guchar *salt,
- gsize n_salt,
- int iterations,
- guchar **key,
- guchar **iv);
-
#endif /* GCKCRYPTO_H_ */
Modified: trunk/pkcs11/gck/gck-data-der.c
==============================================================================
--- trunk/pkcs11/gck/gck-data-der.c (original)
+++ trunk/pkcs11/gck/gck-data-der.c Sun Jan 18 22:24:09 2009
@@ -29,6 +29,7 @@
#include "gck-data-types.h"
#include "egg/egg-secure-memory.h"
+#include "egg/egg-symkey.h"
#include <glib.h>
#include <gcrypt.h>
@@ -40,27 +41,7 @@
static GQuark OID_PKIX1_RSA;
static GQuark OID_PKIX1_DSA;
-
-static GQuark OID_PBE_MD2_DES_CBC;
-static GQuark OID_PBE_MD5_DES_CBC;
-static GQuark OID_PBE_MD2_RC2_CBC;
-static GQuark OID_PBE_MD5_RC2_CBC;
-static GQuark OID_PBE_SHA1_DES_CBC;
-static GQuark OID_PBE_SHA1_RC2_CBC;
-static GQuark OID_PBES2;
-static GQuark OID_PBKDF2;
-
-static GQuark OID_DES_CBC;
-static GQuark OID_DES_RC2_CBC;
-static GQuark OID_DES_EDE3_CBC;
-static GQuark OID_DES_RC5_CBC;
-
-static GQuark OID_PKCS12_PBE_ARCFOUR_SHA1;
-static GQuark OID_PKCS12_PBE_RC4_40_SHA1;
static GQuark OID_PKCS12_PBE_3DES_SHA1;
-static GQuark OID_PKCS12_PBE_2DES_SHA1;
-static GQuark OID_PKCS12_PBE_RC2_128_SHA1;
-static GQuark OID_PKCS12_PBE_RC2_40_SHA1;
static void
init_quarks (void)
@@ -74,29 +55,7 @@
QUARK (OID_PKIX1_RSA, "1.2.840.113549.1.1.1");
QUARK (OID_PKIX1_DSA, "1.2.840.10040.4.1");
-
- QUARK (OID_PBE_MD2_DES_CBC, "1.2.840.113549.1.5.1");
- QUARK (OID_PBE_MD5_DES_CBC, "1.2.840.113549.1.5.3");
- QUARK (OID_PBE_MD2_RC2_CBC, "1.2.840.113549.1.5.4");
- QUARK (OID_PBE_MD5_RC2_CBC, "1.2.840.113549.1.5.6");
- QUARK (OID_PBE_SHA1_DES_CBC, "1.2.840.113549.1.5.10");
- QUARK (OID_PBE_SHA1_RC2_CBC, "1.2.840.113549.1.5.11");
-
- QUARK (OID_PBES2, "1.2.840.113549.1.5.13");
-
- QUARK (OID_PBKDF2, "1.2.840.113549.1.5.12");
-
- QUARK (OID_DES_CBC, "1.3.14.3.2.7");
- QUARK (OID_DES_RC2_CBC, "1.2.840.113549.3.2");
- QUARK (OID_DES_EDE3_CBC, "1.2.840.113549.3.7");
- QUARK (OID_DES_RC5_CBC, "1.2.840.113549.3.9");
-
- QUARK (OID_PKCS12_PBE_ARCFOUR_SHA1, "1.2.840.113549.1.12.1.1");
- QUARK (OID_PKCS12_PBE_RC4_40_SHA1, "1.2.840.113549.1.12.1.2");
QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
- QUARK (OID_PKCS12_PBE_2DES_SHA1, "1.2.840.113549.1.12.1.4");
- QUARK (OID_PKCS12_PBE_RC2_128_SHA1, "1.2.840.113549.1.12.1.5");
- QUARK (OID_PKCS12_PBE_RC2_40_SHA1, "1.2.840.113549.1.12.1.6");
#undef QUARK
@@ -638,7 +597,7 @@
/*
* Parse the encryption stuff into a cipher.
*/
- r = gck_data_der_read_cipher (scheme, password, n_password, params, n_params, &cih);
+ r = egg_symkey_read_cipher (scheme, password, n_password, params, n_params, &cih);
if (r == GCK_DATA_UNRECOGNIZED) {
ret = GCK_DATA_FAILURE;
goto done;
@@ -1031,7 +990,7 @@
*n_block = gcry_cipher_get_algo_blklen (GCRY_MD_SHA1);
g_return_val_if_fail (n_key && *n_block, NULL);
- if (!gck_crypto_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1,
+ if (!egg_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1,
password, n_password, salt,
sizeof (salt), iterations, &key, &iv))
g_return_val_if_reached (NULL);
@@ -1322,437 +1281,3 @@
return egg_asn1_encode (asn1, "", n_data, NULL);
}
-
-/* -----------------------------------------------------------------------------
- * CIPHER/KEY DESCRIPTIONS
- */
-
-GckDataResult
-gck_data_der_read_cipher (GQuark oid_scheme, const gchar *password, gsize n_password,
- const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
-{
- GckDataResult ret = GCK_DATA_UNRECOGNIZED;
-
- g_return_val_if_fail (oid_scheme != 0, GCK_DATA_FAILURE);
- g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
- g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-
- init_quarks ();
-
- /* PKCS#5 PBE */
- if (oid_scheme == OID_PBE_MD2_DES_CBC)
- ret = gck_data_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
- GCRY_MD_MD2, password, n_password, data, n_data, cih);
-
- else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
- /* RC2-64 has no implementation in libgcrypt */
- ret = GCK_DATA_UNRECOGNIZED;
- else if (oid_scheme == OID_PBE_MD5_DES_CBC)
- ret = gck_data_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
- GCRY_MD_MD5, password, n_password, data, n_data, cih);
- else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
- /* RC2-64 has no implementation in libgcrypt */
- ret = GCK_DATA_UNRECOGNIZED;
- else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
- ret = gck_data_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
- GCRY_MD_SHA1, password, n_password, data, n_data, cih);
- else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
- /* RC2-64 has no implementation in libgcrypt */
- ret = GCK_DATA_UNRECOGNIZED;
-
-
- /* PKCS#5 PBES2 */
- else if (oid_scheme == OID_PBES2)
- ret = gck_data_der_read_cipher_pkcs5_pbes2 (password, n_password, data, n_data, cih);
-
-
- /* PKCS#12 PBE */
- else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
- ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM,
- password, n_password, data, n_data, cih);
- else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
- /* RC4-40 has no implementation in libgcrypt */;
-
- else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
- ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC,
- password, n_password, data, n_data, cih);
- else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1)
- /* 2DES has no implementation in libgcrypt */;
-
- else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
- ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC,
- password, n_password, data, n_data, cih);
-
- else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
- ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC,
- password, n_password, data, n_data, cih);
-
- if (ret == GCK_DATA_UNRECOGNIZED)
- g_message ("unsupported or unrecognized cipher oid: %s", g_quark_to_string (oid_scheme));
- return ret;
-}
-
-GckDataResult
-gck_data_der_read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
- const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih)
-{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- gcry_error_t gcry;
- GckDataResult ret;
- const guchar *salt;
- gsize n_salt;
- gsize n_block, n_key;
- guint iterations;
- guchar *key = NULL;
- guchar *iv = NULL;
-
- g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GCK_DATA_FAILURE);
- g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
- g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-
- *cih = NULL;
- ret = GCK_DATA_UNRECOGNIZED;
-
- /* Check if we can use this algorithm */
- if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
- gcry_md_test_algo (hash_algo) != 0)
- goto done;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-PBE-params", data, n_data);
- if (!asn)
- goto done;
-
- ret = GCK_DATA_FAILURE;
-
- salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
- if (!salt)
- goto done;
- if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
- iterations = 1;
-
- n_key = gcry_cipher_get_algo_keylen (cipher_algo);
- g_return_val_if_fail (n_key > 0, GCK_DATA_FAILURE);
- n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-
- if (!gck_crypto_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password, salt,
- n_salt, iterations, &key, n_block > 1 ? &iv : NULL))
- goto done;
-
- gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
- if (gcry != 0) {
- g_warning ("couldn't create cipher: %s", gcry_strerror (gcry));
- goto done;
- }
-
- if (iv)
- gcry_cipher_setiv (*cih, iv, n_block);
- gcry_cipher_setkey (*cih, key, n_key);
-
- ret = GCK_DATA_SUCCESS;
-
-done:
- gcry_free (iv);
- gcry_free (key);
-
- if (asn)
- asn1_delete_structure (&asn);
-
- return ret;
-}
-
-static gboolean
-setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
-{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- gcry_error_t gcry;
- const guchar *iv;
- gsize n_iv;
- guint version;
-
- g_assert (data);
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-rc2-CBC-params", data, n_data);
- if (!asn)
- return GCK_DATA_UNRECOGNIZED;
-
- if (!egg_asn1_read_uint (asn, "rc2ParameterVersion", &version))
- return GCK_DATA_FAILURE;
-
- iv = egg_asn1_read_content (asn, data, n_data, "iv", &n_iv);
- asn1_delete_structure (&asn);
-
- if (!iv)
- return GCK_DATA_FAILURE;
-
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
-
- if (gcry != 0) {
- g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
- return GCK_DATA_FAILURE;
- }
-
- return GCK_DATA_SUCCESS;
-}
-
-static gboolean
-setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
-{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- gcry_error_t gcry;
- const guchar *iv;
- gsize n_iv;
-
- g_assert (data);
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-des-EDE3-CBC-params", data, n_data);
- if (!asn)
- asn = egg_asn1_decode ("PKIX1.pkcs-5-des-CBC-params", data, n_data);
- if (!asn)
- return GCK_DATA_UNRECOGNIZED;
-
- iv = egg_asn1_read_content (asn, data, n_data, "", &n_iv);
- asn1_delete_structure (&asn);
-
- if (!iv)
- return GCK_DATA_FAILURE;
-
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
-
- if (gcry != 0) {
- g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
- return GCK_DATA_FAILURE;
- }
-
- return GCK_DATA_SUCCESS;
-}
-
-static GckDataResult
-setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, int cipher_algo, gcry_cipher_hd_t cih)
-{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- GckDataResult ret;
- gcry_error_t gcry;
- guchar *key = NULL;
- const guchar *salt;
- gsize n_salt, n_key;
- guint iterations;
-
- g_assert (cipher_algo);
- g_assert (data);
-
- ret = GCK_DATA_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-PBKDF2-params", data, n_data);
- if (!asn)
- goto done;
-
- ret = GCK_DATA_FAILURE;
-
- if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
- iterations = 1;
- salt = egg_asn1_read_content (asn, data, n_data, "salt.specified", &n_salt);
- if (!salt)
- goto done;
-
- if (!gck_crypto_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
- salt, n_salt, iterations, &key, NULL))
- goto done;
-
- n_key = gcry_cipher_get_algo_keylen (cipher_algo);
- g_return_val_if_fail (n_key > 0, GCK_DATA_FAILURE);
-
- gcry = gcry_cipher_setkey (cih, key, n_key);
- if (gcry != 0) {
- g_message ("couldn't set %lu byte key on cipher", (gulong)n_key);
- goto done;
- }
-
- ret = GCK_DATA_SUCCESS;
-
-done:
- gcry_free (key);
- if (asn)
- asn1_delete_structure (&asn);
- return ret;
-}
-
-GckDataResult
-gck_data_der_read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih)
-{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- GckDataResult r, ret;
- GQuark key_deriv_algo, enc_oid;
- gcry_error_t gcry;
- int algo, mode;
- int beg, end, res;
-
- g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
- g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-
- init_quarks ();
-
- *cih = NULL;
- ret = GCK_DATA_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-PBES2-params", data, n_data);
- if (!asn)
- goto done;
-
- res = GCK_DATA_FAILURE;
- algo = mode = 0;
-
- /* Read in all the encryption type */
- enc_oid = egg_asn1_read_oid (asn, "encryptionScheme.algorithm");
- if (!enc_oid)
- goto done;
- if (enc_oid == OID_DES_EDE3_CBC)
- algo = GCRY_CIPHER_3DES;
- else if (enc_oid == OID_DES_CBC)
- algo = GCRY_CIPHER_DES;
- else if (enc_oid == OID_DES_RC2_CBC)
- algo = GCRY_CIPHER_RFC2268_128;
- else if (enc_oid == OID_DES_RC5_CBC)
- /* RC5 doesn't exist in libgcrypt */;
-
- /* Unsupported? */
- if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0) {
- ret = GCK_DATA_UNRECOGNIZED;
- goto done;
- }
-
- /* Instantiate our cipher */
- gcry = gcry_cipher_open (cih, algo, GCRY_CIPHER_MODE_CBC, 0);
- if (gcry != 0) {
- g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo));
- goto done;
- }
-
- /* Read out the parameters */
- if (asn1_der_decoding_startEnd (asn, data, n_data, "encryptionScheme.parameters",
- &beg, &end) != ASN1_SUCCESS)
- goto done;
-
- switch (algo) {
- case GCRY_CIPHER_3DES:
- case GCRY_CIPHER_DES:
- r = setup_pkcs5_des_params (data + beg, end - beg + 1, *cih);
- break;
- case GCRY_CIPHER_RFC2268_128:
- r = setup_pkcs5_rc2_params (data + beg, end - beg + 1, *cih);
- break;
- default:
- /* Should have been caught on the oid check above */
- g_assert_not_reached ();
- r = GCK_DATA_UNRECOGNIZED;
- break;
- };
-
- if (r != GCK_DATA_SUCCESS) {
- ret = r;
- goto done;
- }
-
- /* Read out the key creation paramaters */
- key_deriv_algo = egg_asn1_read_oid (asn, "keyDerivationFunc.algorithm");
- if (!key_deriv_algo)
- goto done;
- if (key_deriv_algo != OID_PBKDF2) {
- g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
- ret = GCK_DATA_UNRECOGNIZED;
- goto done;
- }
-
- if (asn1_der_decoding_startEnd (asn, data, n_data, "keyDerivationFunc.parameters",
- &beg, &end) != ASN1_SUCCESS)
- goto done;
-
- ret = setup_pkcs5_pbkdf2_params (password, n_password, data + beg, end - beg + 1, algo, *cih);
-
-done:
- if (ret != GCK_DATA_SUCCESS && *cih) {
- gcry_cipher_close (*cih);
- *cih = NULL;
- }
-
- if (asn)
- asn1_delete_structure (&asn);
-
- return ret;
-}
-
-GckDataResult
-gck_data_der_read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
- gsize n_password, const guchar *data, gsize n_data,
- gcry_cipher_hd_t *cih)
-{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- gcry_error_t gcry;
- GckDataResult ret;
- const guchar *salt;
- gsize n_salt;
- gsize n_block, n_key;
- guint iterations;
- guchar *key = NULL;
- guchar *iv = NULL;
-
- g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GCK_DATA_FAILURE);
- g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
- g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-
- *cih = NULL;
- ret = GCK_DATA_UNRECOGNIZED;
-
- /* Check if we can use this algorithm */
- if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
- goto done;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-12-PbeParams", data, n_data);
- if (!asn)
- goto done;
-
- ret = GCK_DATA_FAILURE;
-
- salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
- if (!salt)
- goto done;
- if (!egg_asn1_read_uint (asn, "iterations", &iterations))
- goto done;
-
- n_block = gcry_cipher_get_algo_blklen (cipher_algo);
- n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-
- /* Generate IV and key using salt read above */
- if (!gck_crypto_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password,
- n_password, salt, n_salt, iterations, &key,
- n_block > 1 ? &iv : NULL))
- goto done;
-
- gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
- if (gcry != 0) {
- g_warning ("couldn't create encryption cipher: %s", gcry_strerror (gcry));
- goto done;
- }
-
- if (iv)
- gcry_cipher_setiv (*cih, iv, n_block);
- gcry_cipher_setkey (*cih, key, n_key);
-
- ret = GCK_DATA_SUCCESS;
-
-done:
- if (ret != GCK_DATA_SUCCESS && *cih) {
- gcry_cipher_close (*cih);
- *cih = NULL;
- }
-
- gcry_free (iv);
- gcry_free (key);
-
- if (asn)
- asn1_delete_structure (&asn);
-
- return ret;
-}
Modified: trunk/pkcs11/gck/gck-data-der.h
==============================================================================
--- trunk/pkcs11/gck/gck-data-der.h (original)
+++ trunk/pkcs11/gck/gck-data-der.h Sun Jan 18 22:24:09 2009
@@ -118,24 +118,4 @@
guchar* gck_data_der_write_certificate (ASN1_TYPE asn1, gsize *n_data);
-/* -----------------------------------------------------------------------------
- * CIPHERS
- */
-
-GckDataResult gck_data_der_read_cipher (GQuark oid_scheme, const gchar *password,
- gsize n_password, const guchar *data, gsize n_data,
- gcry_cipher_hd_t *cih);
-
-GckDataResult gck_data_der_read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode,
- int hash_algo, const gchar *password, gsize n_password,
- const guchar *data, gsize n_data,
- gcry_cipher_hd_t *cih);
-
-GckDataResult gck_data_der_read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih);
-
-GckDataResult gck_data_der_read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode,
- const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih);
-
#endif /*GKRPKIXDER_H_*/
Modified: trunk/pkcs11/gck/gck-data-file.c
==============================================================================
--- trunk/pkcs11/gck/gck-data-file.c (original)
+++ trunk/pkcs11/gck/gck-data-file.c Sun Jan 18 22:24:09 2009
@@ -30,6 +30,7 @@
#include "egg/egg-buffer.h"
#include "egg/egg-secure-memory.h"
+#include "egg/egg-symkey.h"
#include <glib/gstdio.h>
@@ -361,7 +362,7 @@
password = gck_login_get_password (login, &n_password);
- if (!gck_crypto_symkey_generate_simple (calgo, halgo, password, n_password,
+ if (!egg_symkey_generate_simple (calgo, halgo, password, n_password,
salt, n_salt, iterations, &key, &iv)) {
gcry_free (key);
g_free (iv);
Modified: trunk/pkcs11/gck/gck-util.c
==============================================================================
--- trunk/pkcs11/gck/gck-util.c (original)
+++ trunk/pkcs11/gck/gck-util.c Sun Jan 18 22:24:09 2009
@@ -29,8 +29,6 @@
/* Only access using atomic operations */
static gint next_handle = 0x00000010;
-static const char HEXC[] = "0123456789ABCDEF";
-
gulong*
gck_util_ulong_alloc (gulong value)
{
@@ -89,79 +87,3 @@
{
return (CK_ULONG)g_atomic_int_exchange_and_add (&next_handle, 1);
}
-
-guchar*
-gck_util_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
-{
- guchar *result;
- guchar *decoded;
- gushort j;
- gint state = 0;
- const gchar* pos;
-
- g_return_val_if_fail (data || !n_data, NULL);
- g_return_val_if_fail (n_decoded, NULL);
-
- if (n_data == -1)
- n_data = strlen (data);
-
- decoded = result = g_malloc0 ((n_data / 2) + 1);
- *n_decoded = 0;
-
- while (n_data > 0) {
- if (!g_ascii_isspace (*data)) {
-
- /* Find the position */
- pos = strchr (HEXC, g_ascii_toupper (*data));
- if (pos == 0)
- break;
-
- j = pos - HEXC;
- if(!state) {
- *decoded = (j & 0xf) << 4;
- state = 1;
- } else {
- *decoded |= (j & 0xf);
- (*n_decoded)++;
- decoded++;
- state = 0;
- }
- }
-
- ++data;
- --n_data;
- }
-
- /* Parsing error */
- if (state != 0) {
- g_free (result);
- result = NULL;
- }
-
- return result;
-}
-
-gchar*
-gck_util_hex_encode (const guchar *data, gsize n_data)
-{
- gchar *result, *encoded;
- guchar j;
-
- g_return_val_if_fail (data || !n_data, NULL);
-
- encoded = result = g_malloc0 (n_data * 2 + 1);
-
- while(n_data > 0) {
- j = *(data) >> 4 & 0xf;
- *(encoded++) = HEXC[j];
-
- j = *(data++) & 0xf;
- *(encoded++) = HEXC[j];
-
- n_data--;
- }
-
- /* Make sure still null terminated */
- g_assert (encoded[n_data * 2] == 0);
- return result;
-}
Modified: trunk/pkcs11/gck/gck-util.h
==============================================================================
--- trunk/pkcs11/gck/gck-util.h (original)
+++ trunk/pkcs11/gck/gck-util.h Sun Jan 18 22:24:09 2009
@@ -47,11 +47,4 @@
CK_ULONG gck_util_next_handle (void);
-guchar* gck_util_hex_decode (const gchar *data,
- gssize n_data,
- gsize *n_decoded);
-
-gchar* gck_util_hex_encode (const guchar *data,
- gsize n_data);
-
#endif /* GCKUTIL_H_ */
Modified: trunk/pkcs11/gck/tests/Makefile.am
==============================================================================
--- trunk/pkcs11/gck/tests/Makefile.am (original)
+++ trunk/pkcs11/gck/tests/Makefile.am Sun Jan 18 22:24:09 2009
@@ -7,11 +7,9 @@
# Test files should be listed in order they need to run
UNIT_AUTO = \
- unit-test-util.c \
unit-test-crypto.c \
unit-test-data-asn1.c \
unit-test-data-der.c \
- unit-test-data-openssl.c \
unit-test-transaction.c \
unit-test-store.c \
unit-test-memory-store.c \
Modified: trunk/pkcs11/gck/tests/unit-test-crypto.c
==============================================================================
--- trunk/pkcs11/gck/tests/unit-test-crypto.c (original)
+++ trunk/pkcs11/gck/tests/unit-test-crypto.c Sun Jan 18 22:24:09 2009
@@ -72,190 +72,6 @@
dsakey = NULL;
}
-const static struct {
- const gchar *password;
- int cipher_algo;
- int hash_algo;
- int iterations;
- const gchar *salt;
-
- const gchar *result_simple;
- const gchar *result_pkcs12;
- const gchar *result_pbkdf2;
- const gchar *result_pbe;
-} all_generation_tests[] = {
-
- { /* 24 byte output */
- "booo", GCRY_CIPHER_3DES, GCRY_MD_MD5, 1,
- "\x70\x4C\xFF\xD6\x2F\xBA\x03\xE9",
- "\x84\x12\xBB\x34\x94\x8C\x40\xAD\x97\x57\x96\x74\x5B\x6A\xFB\xF8\xD6\x61\x33\x51\xEA\x8C\xCF\xD8",
- NULL,
- NULL,
- NULL
- },
-
- { /* 5 byte output */
- "booo", GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2048,
- "\x8A\x58\xC2\xE8\x7C\x1D\x80\x11",
- NULL,
- "\xD6\xA6\xF0\x76\x66",
- NULL,
- NULL
- },
-
- { /* Null Password, 5 byte output */
- NULL, GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2000,
- "\x04\xE0\x1C\x3E\xF8\xF2\xE9\xFD",
- NULL,
- "\x98\x7F\x20\x97\x1E",
- NULL,
- NULL
- },
-
- { /* 24 byte output */
- "booo", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
- "\xBD\xEE\x0B\xC6\xCF\x43\xAC\x25",
- NULL,
- "\x3F\x38\x1B\x0E\x87\xEB\x19\xBE\xD1\x39\xDC\x5B\xC2\xD2\xB3\x3C\x35\xA8\xB8\xF9\xEE\x66\x48\x94",
- "\x20\x25\x90\xD8\xD6\x98\x3E\x71\x10\x17\x1F\x51\x49\x87\x27\xCA\x97\x27\xD1\xC9\x72\xF8\x11\xBB",
- NULL
- },
-
- { /* Empty password, 24 byte output */
- "", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
- "\xF7\xCF\xD9\xCF\x1F\xF3\xAD\xF6",
- NULL,
- NULL,
- "\x53\xE3\x35\x9E\x5D\xC1\x85\x1A\x71\x3A\x67\x4E\x80\x56\x13\xD6\x4E\x3E\x89\x43\xB7\x1D\x5F\x7F",
- NULL
- },
-
- { /* Empty password, 24 byte output */
- "", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
- "\xD9\xB3\x2E\xC7\xBA\x1A\x8E\x15",
- NULL,
- "\x39\x70\x75\x7C\xF5\xE2\x13\x0B\x5D\xC2\x9D\x96\x8B\x71\xC7\xFC\x5B\x97\x1F\x79\x9F\x06\xFC\xA2",
- NULL,
- NULL
- },
-
- { /* 8 byte output */
- "booo", GCRY_CIPHER_DES, GCRY_MD_MD5, 2048,
- "\x93\x4C\x3D\x29\xA2\x42\xB0\xF5",
- NULL,
- NULL,
- NULL,
- "\x8C\x67\x19\x7F\xB9\x23\xE2\x8D"
- }
-};
-
-#define N_GENERATION_TESTS (sizeof (all_generation_tests) / sizeof (all_generation_tests[0]))
-
-DEFINE_TEST(generate_key_simple)
-{
- int i;
- gboolean ret;
- guchar *key;
-
- for (i = 0; i < N_GENERATION_TESTS; ++i) {
-
- if (!all_generation_tests[i].result_simple)
- continue;
-
- ret = gck_crypto_symkey_generate_simple (all_generation_tests[i].cipher_algo,
- all_generation_tests[i].hash_algo,
- all_generation_tests[i].password, -1,
- (guchar*)all_generation_tests[i].salt, 8,
- all_generation_tests[i].iterations,
- &key, NULL);
- g_assert (ret && "key generation failed");
-
- ret = (memcmp (key, all_generation_tests[i].result_simple,
- gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-
- g_assert (ret && "invalid simple key generated");
- }
-}
-
-DEFINE_TEST(generate_key_pkcs12)
-{
- int i;
- gboolean ret;
- guchar *key;
-
- for (i = 0; i < N_GENERATION_TESTS; ++i) {
-
- if (!all_generation_tests[i].result_pkcs12)
- continue;
-
- ret = gck_crypto_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo,
- all_generation_tests[i].hash_algo,
- all_generation_tests[i].password, -1,
- (guchar*)all_generation_tests[i].salt, 8,
- all_generation_tests[i].iterations,
- &key, NULL);
- g_assert ("failed to generate pkcs12 key" && ret);
-
- ret = (memcmp (key, all_generation_tests[i].result_pkcs12,
- gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-
- g_assert ("invalid pkcs12 key generated" && ret);
- }
-}
-
-DEFINE_TEST(generate_key_pbkdf2)
-{
- int i;
- gboolean ret;
- guchar *key;
-
- for (i = 0; i < N_GENERATION_TESTS; ++i) {
-
- if (!all_generation_tests[i].result_pbkdf2)
- continue;
-
- ret = gck_crypto_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo,
- all_generation_tests[i].hash_algo,
- all_generation_tests[i].password, -1,
- (guchar*)all_generation_tests[i].salt, 8,
- all_generation_tests[i].iterations,
- &key, NULL);
- g_assert ("failed to generate pbkdf2 key" && ret);
-
- ret = (memcmp (key, all_generation_tests[i].result_pbkdf2,
- gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-
- g_assert ("invalid pbkdf2 key generated" && ret);
- }
-}
-
-DEFINE_TEST(generate_key_pbe)
-{
- int i;
- gboolean ret;
- guchar *key;
-
- for (i = 0; i < N_GENERATION_TESTS; ++i) {
-
- if (!all_generation_tests[i].result_pbe)
- continue;
-
- ret = gck_crypto_symkey_generate_pbe (all_generation_tests[i].cipher_algo,
- all_generation_tests[i].hash_algo,
- all_generation_tests[i].password, -1,
- (guchar*)all_generation_tests[i].salt, 8,
- all_generation_tests[i].iterations,
- &key, NULL);
- g_assert ("failed to generate pbe key" && ret);
-
- ret = (memcmp (key, all_generation_tests[i].result_pbe,
- gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-
- g_assert ("invalid pbe key generated" && ret);
-
- }
-}
-
DEFINE_TEST(parse_key)
{
gcry_sexp_t sexp = NULL;
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 Sun Jan 18 22:24:09 2009
@@ -25,10 +25,11 @@
#include "gck-roots-module.h"
#include "gck-roots-certificate.h"
-#include "gck/gck-data-pem.h"
#include "gck/gck-file-tracker.h"
#include "gck/gck-serializable.h"
+#include "egg/egg-openssl.h"
+
#include <string.h>
struct _GckRootsModule {
@@ -204,7 +205,7 @@
g_list_free (objects);
/* Try and parse the PEM */
- num = gck_data_pem_parse (data, n_data, parsed_pem_block, &ctx);
+ num = egg_openssl_pem_parse (data, n_data, parsed_pem_block, &ctx);
/* If no PEM data, try to parse directly as DER */
if (ctx.count == 0) {
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 Sun Jan 18 22:24:09 2009
@@ -3,11 +3,10 @@
#include "gck/gck-data-asn1.h"
#include "gck/gck-data-der.h"
-#include "gck/gck-data-openssl.h"
-#include "gck/gck-data-pem.h"
#include "gck/gck-data-types.h"
#include "egg/egg-buffer.h"
+#include "egg/egg-openssl.h"
typedef struct _ParsePrivate {
gcry_sexp_t sexp;
@@ -163,7 +162,7 @@
gint length;
/* Decrypt, this will result in garble if invalid password */
- res = gck_data_openssl_decrypt_block (dekinfo, password, n_password,
+ res = egg_openssl_decrypt_block (dekinfo, password, n_password,
data, n_data, &decrypted, &n_decrypted);
if (!res)
return FALSE;
@@ -214,7 +213,7 @@
return;
/* If it's encrypted ... */
- dekinfo = gck_data_openssl_get_dekinfo (headers);
+ dekinfo = egg_openssl_get_dekinfo (headers);
if (dekinfo) {
ctx->result = load_encrypted_key (data, n_data, dekinfo, ctx->password,
ctx->n_password, &ctx->sexp);
@@ -346,7 +345,7 @@
ctx.password = password;
ctx.n_password = n_password;
- num = gck_data_pem_parse (data, n_data, parsed_pem_block, &ctx);
+ num = egg_openssl_pem_parse (data, n_data, parsed_pem_block, &ctx);
/* Didn't find any private key there */
if (num == 0 || !ctx.seen) {
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 Sun Jan 18 22:24:09 2009
@@ -33,6 +33,8 @@
#include "gck/gck-serializable.h"
#include "gck/gck-util.h"
+#include "egg/egg-hex.h"
+
#include <glib/gstdio.h>
#include <libtasn1.h>
@@ -175,7 +177,7 @@
if (name == NULL) {
data = gck_object_get_attribute_data (object, CKA_ID, &n_data);
if (data && n_data)
- name = gck_util_hex_encode (data, n_data);
+ name = egg_hex_encode (data, n_data);
g_free (data);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]