[gnome-keyring] Bring over new egg'd components from gcr
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] Bring over new egg'd components from gcr
- Date: Sat, 7 Apr 2012 14:46:12 +0000 (UTC)
commit 5c4a86255897206875d72fee0c41e657dce3e39f
Author: Stef Walter <stefw gnome org>
Date: Sat Mar 10 07:57:41 2012 +0100
Bring over new egg'd components from gcr
* Updated ASN.1, armor, bytes, openssl, etc.
.gitignore | 1 +
Makefile.decl | 26 +-
daemon/control/tests/frob-control-change.c | 2 +-
daemon/control/tests/frob-control-init.c | 2 +-
daemon/control/tests/frob-control-quit.c | 2 +-
daemon/control/tests/frob-control-unlock.c | 2 +-
daemon/gkd-main.c | 8 +-
daemon/gpg-agent/gkd-gpg-agent-standalone.c | 2 +-
daemon/ssh-agent/gkd-ssh-agent-standalone.c | 2 +-
egg/Makefile.am | 22 +-
egg/egg-armor.c | 44 +-
egg/egg-armor.h | 11 +-
egg/egg-asn1-defs.c | 33 +
egg/egg-asn1-defs.h | 12 +-
egg/egg-asn1x.c | 1162 ++++++++++++-------
egg/egg-asn1x.h | 122 ++-
egg/egg-bytes.c | 454 ++++++++
egg/egg-bytes.h | 102 ++
egg/egg-dn.c | 167 +++-
egg/egg-dn.h | 12 +-
egg/egg-openssl.c | 147 ++--
egg/egg-openssl.h | 20 +-
egg/egg-secure-memory.c | 184 ++--
egg/egg-secure-memory.h | 38 +-
egg/egg-symkey.c | 489 ++++----
egg/egg-symkey.h | 62 +-
egg/egg-testing.h | 7 +
egg/tests/Makefile.am | 16 +-
egg/tests/test-asn1.c | 566 ++++++----
egg/tests/test-asn1x.c | 21 +-
egg/tests/test-dh.c | 2 +-
egg/tests/test-dn.c | 66 +-
egg/tests/test-hkdf.c | 2 +-
egg/tests/test-openssl.c | 71 +-
egg/tests/test-secmem.c | 2 +-
egg/tests/test-symkey.c | 9 +-
egg/tests/test.asn | 2 +
pam/gkr-pam-stubs.c | 8 +-
pkcs11/gkm/Makefile.am | 14 +-
pkcs11/gkm/gkm-attributes.c | 7 +
pkcs11/gkm/gkm-attributes.h | 5 +
pkcs11/gkm/gkm-certificate.c | 110 +-
pkcs11/gkm/gkm-certificate.h | 5 +-
pkcs11/gkm/gkm-data-asn1.c | 14 +-
pkcs11/gkm/gkm-data-der.c | 328 +++---
pkcs11/gkm/gkm-data-der.h | 69 +-
pkcs11/gkm/gkm-serializable.c | 11 +-
pkcs11/gkm/gkm-serializable.h | 18 +-
pkcs11/gkm/pk.asn | 103 --
pkcs11/gkm/pkix.asn | 1230 --------------------
pkcs11/gkm/tests/Makefile.am | 17 +-
pkcs11/gkm/tests/mock-module.c | 2 +-
pkcs11/gkm/tests/test-certificate.c | 19 +-
pkcs11/gkm/tests/test-data-asn1.c | 27 +-
pkcs11/gkm/tests/test-data-der.c | 206 ++--
pkcs11/gkm/tests/test-secret.c | 2 +-
pkcs11/gkm/tests/test-sexp.c | 2 +-
pkcs11/gnome2-store/gkm-gnome2-private-key.c | 52 +-
pkcs11/gnome2-store/gkm-gnome2-public-key.c | 19 +-
pkcs11/gnome2-store/gkm-gnome2-standalone.c | 2 +-
pkcs11/gnome2-store/gkm-gnome2-storage.c | 52 +-
pkcs11/gnome2-store/tests/check-gnome2-module.c | 2 +-
pkcs11/gnome2-store/tests/frob-gnome2-file.c | 2 +-
pkcs11/gnome2-store/tests/mock-gnome2-module.c | 2 +-
pkcs11/gnome2-store/tests/test-gnome2-file.c | 2 +-
.../gnome2-store/tests/test-gnome2-private-key.c | 32 +-
pkcs11/gnome2-store/tests/test-gnome2-storage.c | 8 +-
pkcs11/roots-store/gkm-roots-module.c | 28 +-
pkcs11/roots-store/gkm-roots-standalone.c | 2 +-
pkcs11/roots-store/gkm-roots-trust.c | 9 +-
pkcs11/roots-store/tests/check-roots-module.c | 2 +-
pkcs11/secret-store/gkm-secret-standalone.c | 2 +-
pkcs11/secret-store/tests/dump-keyring0-format.c | 2 +-
pkcs11/secret-store/tests/mock-secret-module.c | 2 +-
pkcs11/secret-store/tests/test-secret-data.c | 2 +-
pkcs11/ssh-store/gkm-ssh-openssh.c | 56 +-
pkcs11/ssh-store/gkm-ssh-openssh.h | 8 +-
pkcs11/ssh-store/gkm-ssh-private-key.c | 30 +-
pkcs11/ssh-store/gkm-ssh-standalone.c | 2 +-
pkcs11/ssh-store/tests/check-ssh-module.c | 2 +-
pkcs11/ssh-store/tests/mock-ssh-module.c | 2 +-
pkcs11/ssh-store/tests/test-ssh-openssh.c | 9 +-
pkcs11/wrap-layer/tests/mock-secret-store.c | 2 +-
pkcs11/xdg-store/Makefile.am | 18 +-
pkcs11/xdg-store/gkm-xdg-asn1-defs.c | 32 +
pkcs11/xdg-store/gkm-xdg-asn1-defs.h | 31 +
pkcs11/xdg-store/gkm-xdg-module.c | 35 +-
pkcs11/xdg-store/gkm-xdg-standalone.c | 2 +-
pkcs11/xdg-store/gkm-xdg-trust.c | 200 ++--
pkcs11/xdg-store/tests/check-xdg-module.c | 2 +-
pkcs11/xdg-store/tests/dump-trust-file.c | 43 +-
pkcs11/xdg-store/tests/frob-trust-file.c | 74 +-
pkcs11/xdg-store/tests/mock-xdg-module.c | 2 +-
93 files changed, 3534 insertions(+), 3327 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 0a6df42..eecb8d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@
*.la
*.lo
*.a
+*.asn.h
*.bak
*.Po
*.Plo
diff --git a/Makefile.decl b/Makefile.decl
index 96900ec..cfbf716 100644
--- a/Makefile.decl
+++ b/Makefile.decl
@@ -1,5 +1,30 @@
NULL =
+TEST_ARGS =
+
+TEST_SUPPRESSIONS = $(top_builddir)/build/valgrind-suppressions
+
+perform-memcheck: $(TEST_PROGS)
+ make -C $(top_builddir)/build all
+ @for test in $(TEST_PROGS); do \
+ G_SLICE=always-malloc libtool --mode=execute \
+ valgrind --trace-children=no --gen-suppressions=all \
+ --suppressions=$(TEST_SUPPRESSIONS) \
+ --leak-check=full --show-reachable=yes --num-callers=16 \
+ --quiet --error-exitcode=3 \
+ $(builddir)/$$test $(TEST_ARGS) || exit 3; \
+ done
+
+coverage:
+ mkdir -p $(top_builddir)/build/coverage
+ $(LCOV) --directory . --capture --output-file $(top_builddir)/build/coverage.info
+ $(GENHTML) --output-directory $(top_builddir)/build/coverage $(top_builddir)/build/coverage.info
+ $(LCOV) --directory . --zerocounters
+ @echo "file://$(abs_top_builddir)/build/coverage/index.html"
+
+clear-coverage:
+ $(LCOV) --directory . --zerocounters
+
V_ASN1 = $(V_ASN1_$(V))
V_ASN1_ = $(V_ASN1_$(AM_DEFAULT_VERBOSITY))
V_ASN1_0 = @echo " ASN1 " $@;
@@ -40,4 +65,3 @@ SED_SUBST = sed \
$(V_SED) $(SED_SUBST) $< > $@
SUFFIXES = .asn .asn.h .conf .conf.in .desktop.in .desktop.in.in .service .service.in
-
diff --git a/daemon/control/tests/frob-control-change.c b/daemon/control/tests/frob-control-change.c
index 9b9c9ba..2fa6b4c 100644
--- a/daemon/control/tests/frob-control-change.c
+++ b/daemon/control/tests/frob-control-change.c
@@ -6,7 +6,7 @@
#include <pwd.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
int
main (int argc, char *argv[])
diff --git a/daemon/control/tests/frob-control-init.c b/daemon/control/tests/frob-control-init.c
index 3e83d03..88149be 100644
--- a/daemon/control/tests/frob-control-init.c
+++ b/daemon/control/tests/frob-control-init.c
@@ -7,7 +7,7 @@
#include <stdlib.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
int
main (int argc, char *argv[])
diff --git a/daemon/control/tests/frob-control-quit.c b/daemon/control/tests/frob-control-quit.c
index bf73a4e..66261d7 100644
--- a/daemon/control/tests/frob-control-quit.c
+++ b/daemon/control/tests/frob-control-quit.c
@@ -7,7 +7,7 @@
#include <stdlib.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
int
main (int argc, char *argv[])
diff --git a/daemon/control/tests/frob-control-unlock.c b/daemon/control/tests/frob-control-unlock.c
index b361066..6a44801 100644
--- a/daemon/control/tests/frob-control-unlock.c
+++ b/daemon/control/tests/frob-control-unlock.c
@@ -6,7 +6,7 @@
#include <pwd.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
int
main (int argc, char *argv[])
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index e9f4392..9ff675f 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -206,19 +206,19 @@ static gboolean do_warning = TRUE;
G_LOCK_DEFINE_STATIC (memory_mutex);
-void
+static void
egg_memory_lock (void)
{
G_LOCK (memory_mutex);
}
-void
+static void
egg_memory_unlock (void)
{
G_UNLOCK (memory_mutex);
}
-void*
+static void *
egg_memory_fallback (void *p, size_t sz)
{
const gchar *env;
@@ -254,6 +254,8 @@ egg_memory_fallback (void *p, size_t sz)
return g_realloc (p, sz);
}
+EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, egg_memory_fallback);
+
/* -----------------------------------------------------------------------------
* LOGS
*/
diff --git a/daemon/gpg-agent/gkd-gpg-agent-standalone.c b/daemon/gpg-agent/gkd-gpg-agent-standalone.c
index a9a1c99..48220b1 100644
--- a/daemon/gpg-agent/gkd-gpg-agent-standalone.c
+++ b/daemon/gpg-agent/gkd-gpg-agent-standalone.c
@@ -36,7 +36,7 @@
#include <string.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static gboolean
accept_client (GIOChannel *channel, GIOCondition cond, gpointer unused)
diff --git a/daemon/ssh-agent/gkd-ssh-agent-standalone.c b/daemon/ssh-agent/gkd-ssh-agent-standalone.c
index a496a36..f5f3dc0 100644
--- a/daemon/ssh-agent/gkd-ssh-agent-standalone.c
+++ b/daemon/ssh-agent/gkd-ssh-agent-standalone.c
@@ -37,7 +37,7 @@
#include <string.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static gboolean
accept_client (GIOChannel *channel, GIOCondition cond, gpointer unused)
diff --git a/egg/Makefile.am b/egg/Makefile.am
index f067d05..f024ae0 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -1,3 +1,4 @@
+include $(top_srcdir)/Makefile.decl
noinst_LTLIBRARIES = \
libegg.la \
@@ -11,8 +12,14 @@ noinst_LTLIBRARIES = \
libegg-hex.la \
libegg-test.la
+ASN_FILES = \
+ pk.asn \
+ pkix.asn
+
+ASN_SRCS = $(ASN_FILES:.asn=.asn.h)
+
BUILT_SOURCES = \
- asn1-def-pk.c asn1-def-pkix.c
+ $(ASN_SRCS)
INCLUDES = \
-I$(top_srcdir) \
@@ -26,8 +33,10 @@ libegg_la_SOURCES = \
dotlock.c dotlock.h \
egg-armor.c egg-armor.h \
egg-asn1x.c egg-asn1x.h \
+ egg-asn1-defs.c egg-asn1-defs.h \
egg-buffer.c egg-buffer.h \
egg-byte-array.c egg-byte-array.h \
+ egg-bytes.c egg-bytes.h \
egg-cleanup.c egg-cleanup.h \
egg-dh.c egg-dh.h \
egg-dn.c egg-dn.h \
@@ -48,15 +57,8 @@ libegg_la_SOURCES = \
egg-asn1-defs.h \
$(BUILT_SOURCES)
-asn1-def-pk.c: pk.asn
- $(ASN1PARSER) -o asn1-def-pk.c $(srcdir)/pk.asn
-
-asn1-def-pkix.c: pkix.asn
- $(ASN1PARSER) -o asn1-def-pkix.c $(srcdir)/pkix.asn
-
EXTRA_DIST = \
- pkix.asn \
- pk.asn
+ $(ASN_FILES)
DISTCLEANFILES = \
$(BUILT_SOURCES)
@@ -66,6 +68,8 @@ DISTCLEANFILES = \
libegg_asn1x_la_SOURCES = \
egg-asn1x.c egg-asn1x.h \
+ egg-asn1-defs.c egg-asn1-defs.h \
+ egg-bytes.c egg-bytes.h \
$(BUILT_SOURCES)
libegg_asn1x_la_CFLAGS = \
diff --git a/egg/egg-armor.c b/egg/egg-armor.c
index 5a4b047..473e42e 100644
--- a/egg/egg-armor.c
+++ b/egg/egg-armor.c
@@ -162,14 +162,14 @@ armor_find_end (const gchar *data,
/* Next comes the type string */
stype = g_quark_to_string (type);
n_type = strlen (stype);
- if (strncmp ((gchar*)data, stype, n_type) != 0)
+ if (n_type > n_data || strncmp ((gchar*)data, stype, n_type) != 0)
return NULL;
n_data -= n_type;
data += n_type;
/* Next comes the suffix */
- if (strncmp ((gchar*)data, ARMOR_SUFF, ARMOR_SUFF_L) != 0)
+ if (ARMOR_SUFF_L > n_data && strncmp ((gchar*)data, ARMOR_SUFF, ARMOR_SUFF_L) != 0)
return NULL;
/*
@@ -269,48 +269,52 @@ egg_armor_headers_new (void)
}
guint
-egg_armor_parse (gconstpointer data,
- gsize n_data,
+egg_armor_parse (EggBytes *data,
EggArmorCallback callback,
gpointer user_data)
{
- const gchar *beg, *end;
+ const gchar *beg, *end, *at;
const gchar *outer_beg, *outer_end;
guint nfound = 0;
guchar *decoded = NULL;
gsize n_decoded = 0;
GHashTable *headers = NULL;
+ EggBytes *dec;
+ EggBytes *outer;
GQuark type;
+ gsize n_at;
- g_return_val_if_fail (data, 0);
- g_return_val_if_fail (n_data, 0);
+ g_return_val_if_fail (data != NULL, 0);
+ at = egg_bytes_get_data (data);
+ n_at = egg_bytes_get_size (data);
- while (n_data > 0) {
+ while (n_at > 0) {
/* This returns the first character after the PEM BEGIN header */
- beg = armor_find_begin ((const gchar*)data, n_data, &type, &outer_beg);
+ beg = armor_find_begin (at, n_at, &type, &outer_beg);
if (beg == NULL)
break;
g_assert (type);
/* This returns the character position before the PEM END header */
- end = armor_find_end ((const gchar*)beg,
- n_data - ((const gchar*)beg - (const gchar *)data),
- type, &outer_end);
+ end = armor_find_end (beg, n_at - (beg - at), type, &outer_end);
if (end == NULL)
break;
if (beg != end) {
if (armor_parse_block (beg, end - beg, &decoded, &n_decoded, &headers)) {
g_assert (outer_end > outer_beg);
- if (callback != NULL)
- (callback) (type,
- decoded, n_decoded,
- outer_beg, outer_end - outer_beg,
- headers, user_data);
+ dec = egg_bytes_new_with_free_func (decoded, n_decoded,
+ egg_secure_free, decoded);
+ if (callback != NULL) {
+ outer = egg_bytes_new_with_free_func (outer_beg, outer_end - outer_beg,
+ egg_bytes_unref, egg_bytes_ref (data));
+ (callback) (type, dec, outer, headers, user_data);
+ egg_bytes_unref (outer);
+ }
+ egg_bytes_unref (dec);
++nfound;
- egg_secure_free (decoded);
if (headers)
g_hash_table_remove_all (headers);
}
@@ -318,8 +322,8 @@ egg_armor_parse (gconstpointer data,
/* Try for another block */
end += ARMOR_SUFF_L;
- n_data -= (const gchar*)end - (const gchar*)data;
- data = end;
+ n_at -= (const gchar*)end - (const gchar*)at;
+ at = end;
}
if (headers)
diff --git a/egg/egg-armor.h b/egg/egg-armor.h
index e0f13d3..586a0d2 100644
--- a/egg/egg-armor.h
+++ b/egg/egg-armor.h
@@ -26,18 +26,17 @@
#include <glib.h>
+#include <egg/egg-bytes.h>
+
typedef void (*EggArmorCallback) (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data);
GHashTable* egg_armor_headers_new (void);
-guint egg_armor_parse (gconstpointer data,
- gsize n_data,
+guint egg_armor_parse (EggBytes *data,
EggArmorCallback callback,
gpointer user_data);
diff --git a/egg/egg-asn1-defs.c b/egg/egg-asn1-defs.c
new file mode 100644
index 0000000..8295ec0
--- /dev/null
+++ b/egg/egg-asn1-defs.c
@@ -0,0 +1,33 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-asn1-defs.c - ASN.1 definitions
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw collabora co uk>
+*/
+
+#include "config.h"
+
+#include "egg-asn1-defs.h"
+
+#include <stdlib.h>
+
+typedef struct _EggAsn1xDef ASN1_ARRAY_TYPE;
+
+#include "pk.asn.h"
+#include "pkix.asn.h"
diff --git a/egg/egg-asn1-defs.h b/egg/egg-asn1-defs.h
index 02fe427..ec47287 100644
--- a/egg/egg-asn1-defs.h
+++ b/egg/egg-asn1-defs.h
@@ -24,9 +24,13 @@
#ifndef EGG_ASN1_DEFS_H_
#define EGG_ASN1_DEFS_H_
-#include <libtasn1.h>
+struct _EggAsn1xDef {
+ const char *name;
+ unsigned int type;
+ const void *value;
+};
-extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
-extern const ASN1_ARRAY_TYPE pk_asn1_tab[];
+extern const struct _EggAsn1xDef pkix_asn1_tab[];
+extern const struct _EggAsn1xDef pk_asn1_tab[];
-#endif /*EGG_ASN1_DEFS_H_*/
+#endif /* EGG_ASN1_DEFS_H_ */
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index f2d4b42..c940a54 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -48,38 +48,35 @@
#include "config.h"
#include "egg-asn1x.h"
+#include "egg-asn1-defs.h"
#include "egg-timegm.h"
-#include <libtasn1.h>
-
#include <stdlib.h>
#include <string.h>
+/* From libtasn1's libtasn.h */
+
+#define ASN1_CLASS_UNIVERSAL 0x00
+#define ASN1_CLASS_APPLICATION 0x40
+#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80
+#define ASN1_CLASS_PRIVATE 0xC0
+#define ASN1_CLASS_STRUCTURED 0x20
+
+#define ASN1_TAG_BOOLEAN 0x01
+#define ASN1_TAG_INTEGER 0x02
+#define ASN1_TAG_SEQUENCE 0x10
+#define ASN1_TAG_SET 0x11
+#define ASN1_TAG_OCTET_STRING 0x04
+#define ASN1_TAG_BIT_STRING 0x03
+#define ASN1_TAG_UTCTime 0x17
+#define ASN1_TAG_GENERALIZEDTime 0x18
+#define ASN1_TAG_OBJECT_ID 0x06
+#define ASN1_TAG_ENUMERATED 0x0A
+#define ASN1_TAG_NULL 0x05
+#define ASN1_TAG_GENERALSTRING 0x1B
+
+
/* From libtasn1's int.h */
-enum {
- TYPE_CONSTANT = 1,
- TYPE_IDENTIFIER = 2,
- TYPE_INTEGER = 3,
- TYPE_BOOLEAN = 4,
- TYPE_SEQUENCE = 5,
- TYPE_BIT_STRING = 6,
- TYPE_OCTET_STRING = 7,
- TYPE_TAG = 8,
- TYPE_DEFAULT = 9,
- TYPE_SIZE = 10,
- TYPE_SEQUENCE_OF = 11,
- TYPE_OBJECT_ID = 12,
- TYPE_ANY = 13,
- TYPE_SET = 14,
- TYPE_SET_OF = 15,
- TYPE_DEFINITIONS = 16,
- TYPE_TIME = 17,
- TYPE_CHOICE = 18,
- TYPE_IMPORTS = 19,
- TYPE_NULL = 20,
- TYPE_ENUMERATED = 21,
- TYPE_GENERALSTRING = 27
-};
enum {
FLAG_UNIVERSAL = (1<<8),
@@ -107,6 +104,11 @@ enum {
FLAG_RIGHT = (1<<30),
};
+typedef gboolean (*Aencoder) (gpointer data,
+ GNode *node,
+ guchar *buf,
+ gsize n_buf);
+
typedef struct _Aenc Aenc;
typedef struct _Atlv Atlv;
typedef struct _Anode Anode;
@@ -114,8 +116,9 @@ typedef struct _Abuf Abuf;
typedef struct _Abits Abits;
struct _Aenc {
- EggAsn1xEncoder encoder;
+ Aencoder encoder;
gpointer data;
+ GDestroyNotify destroy;
};
struct _Atlv {
@@ -129,16 +132,14 @@ struct _Atlv {
};
struct _Anode {
- const ASN1_ARRAY_TYPE *def;
- const ASN1_ARRAY_TYPE *join;
+ const EggAsn1xDef *def;
+ const EggAsn1xDef *join;
GList *opts;
Atlv *tlv;
Aenc *enc;
- gpointer user_data;
- GDestroyNotify destroy;
-
+ EggBytes *backing;
gchar* failure;
gint chosen : 1;
@@ -152,13 +153,12 @@ struct _Abuf {
struct _Abits {
guint n_bits;
- guchar *bits;
- GDestroyNotify destroy;
+ EggBytes *bits;
};
/* Forward Declarations */
-static gboolean anode_decode_anything (GNode*, Atlv*);
-static gboolean anode_decode_anything_for_flags (GNode *, Atlv*, gint);
+static gboolean anode_decode_anything (GNode*, EggBytes*, Atlv*);
+static gboolean anode_decode_anything_for_flags (GNode *, EggBytes*, Atlv*, gint);
static gboolean anode_validate_anything (GNode*, gboolean);
static gboolean anode_encode_prepare (GNode*, gboolean want);
@@ -176,7 +176,7 @@ atoin (const char *p, gint digits)
}
static GNode*
-anode_new (const ASN1_ARRAY_TYPE *def)
+anode_new (const EggAsn1xDef *def)
{
Anode *an = g_slice_new0 (Anode);
an->def = def;
@@ -212,30 +212,30 @@ static gboolean
anode_def_type_is_real (GNode *node)
{
switch (anode_def_type (node)) {
- case TYPE_INTEGER:
- case TYPE_BOOLEAN:
- case TYPE_BIT_STRING:
- case TYPE_OCTET_STRING:
- case TYPE_OBJECT_ID:
- case TYPE_TIME:
- case TYPE_NULL:
- case TYPE_ENUMERATED:
- case TYPE_GENERALSTRING:
+ case EGG_ASN1X_INTEGER:
+ case EGG_ASN1X_BOOLEAN:
+ case EGG_ASN1X_BIT_STRING:
+ case EGG_ASN1X_OCTET_STRING:
+ case EGG_ASN1X_OBJECT_ID:
+ case EGG_ASN1X_TIME:
+ case EGG_ASN1X_NULL:
+ case EGG_ASN1X_ENUMERATED:
+ case EGG_ASN1X_GENERALSTRING:
return TRUE;
- case TYPE_SEQUENCE:
- case TYPE_SEQUENCE_OF:
- case TYPE_ANY:
- case TYPE_SET:
- case TYPE_SET_OF:
- case TYPE_CHOICE:
+ case EGG_ASN1X_SEQUENCE:
+ case EGG_ASN1X_SEQUENCE_OF:
+ case EGG_ASN1X_ANY:
+ case EGG_ASN1X_SET:
+ case EGG_ASN1X_SET_OF:
+ case EGG_ASN1X_CHOICE:
return TRUE;
- case TYPE_CONSTANT:
- case TYPE_IDENTIFIER:
- case TYPE_TAG:
- case TYPE_DEFAULT:
- case TYPE_SIZE:
- case TYPE_DEFINITIONS:
- case TYPE_IMPORTS:
+ case EGG_ASN1X_CONSTANT:
+ case EGG_ASN1X_IDENTIFIER:
+ case EGG_ASN1X_TAG:
+ case EGG_ASN1X_DEFAULT:
+ case EGG_ASN1X_SIZE:
+ case EGG_ASN1X_DEFINITIONS:
+ case EGG_ASN1X_IMPORTS:
return FALSE;
default:
g_return_val_if_reached (FALSE);
@@ -267,7 +267,7 @@ anode_def_value (GNode *node)
}
static gulong
-anode_def_value_as_ulong (const ASN1_ARRAY_TYPE *def)
+anode_def_value_as_ulong (const EggAsn1xDef *def)
{
gchar *end = NULL;
gulong lval;
@@ -292,17 +292,20 @@ anode_child_with_name (GNode *node, const gchar *name)
}
static void
-anode_opt_add (GNode *node, const ASN1_ARRAY_TYPE *def)
+anode_opt_add (GNode *node,
+ const EggAsn1xDef *def)
{
Anode *an = node->data;
an->opts = g_list_append (an->opts, (gpointer)def);
}
-static ASN1_ARRAY_TYPE*
-anode_opt_lookup (GNode *node, gint type, const gchar *name)
+static EggAsn1xDef *
+anode_opt_lookup (GNode *node,
+ gint type,
+ const gchar *name)
{
Anode *an = node->data;
- ASN1_ARRAY_TYPE* def;
+ EggAsn1xDef *def;
GList *l;
for (l = an->opts; l; l = g_list_next (l)) {
@@ -316,11 +319,13 @@ anode_opt_lookup (GNode *node, gint type, const gchar *name)
return NULL;
}
-static ASN1_ARRAY_TYPE*
-anode_opt_lookup_value (GNode *node, gint type, const gchar *value)
+static EggAsn1xDef *
+anode_opt_lookup_value (GNode *node,
+ gint type,
+ const gchar *value)
{
Anode *an = node->data;
- ASN1_ARRAY_TYPE* def;
+ EggAsn1xDef *def;
GList *l;
for (l = an->opts; l; l = g_list_next (l)) {
@@ -338,7 +343,7 @@ static GList*
anode_opts_lookup (GNode *node, gint type, const gchar *name)
{
Anode *an = node->data;
- ASN1_ARRAY_TYPE* def;
+ EggAsn1xDef *def;
GList *l, *res = NULL;
for (l = an->opts; l; l = g_list_next (l)) {
@@ -367,17 +372,48 @@ compare_tlvs (Atlv *tlva, Atlv *tlvb)
return la < lb ? -1 : 1;
}
+static inline EggBytes *
+anode_get_backing (GNode *node)
+{
+ Anode *an = node->data;
+ return an->backing;
+}
+
+static inline void
+anode_clr_backing (GNode *node)
+{
+ Anode *an = node->data;
+ if (an->backing)
+ egg_bytes_unref (an->backing);
+ an->backing = NULL;
+}
+
+static inline void
+anode_set_backing (GNode *node,
+ EggBytes *backing)
+{
+ Anode *an = node->data;
+ if (backing)
+ egg_bytes_ref (backing);
+ if (an->backing)
+ egg_bytes_unref (an->backing);
+ an->backing = backing;
+}
+
static void
-anode_set_tlv_data (GNode *node, Atlv *tlv)
+anode_set_tlv_data (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv)
{
Anode *an = node->data;
- g_assert (!an->tlv);
+ g_assert (an->tlv == NULL);
g_assert (tlv->len >= 0);
+ anode_set_backing (node, backing);
an->tlv = g_slice_new0 (Atlv);
memcpy (an->tlv, tlv, sizeof (Atlv));
}
-static Atlv*
+static inline Atlv *
anode_get_tlv_data (GNode *node)
{
Anode *an = node->data;
@@ -398,31 +434,26 @@ anode_clr_enc_data (GNode *node)
{
Anode *an = node->data;
if (an->enc) {
+ if (an->enc->destroy)
+ (an->enc->destroy) (an->enc->data);
g_slice_free (Aenc, an->enc);
an->enc = NULL;
}
}
static void
-anode_set_enc_data (GNode *node, EggAsn1xEncoder encoder, gpointer enc_data)
+anode_set_enc_data (GNode *node,
+ Aencoder encoder,
+ gpointer data,
+ GDestroyNotify destroy)
{
Anode *an = node->data;
g_assert (!an->enc);
an->enc = g_slice_new0 (Aenc);
an->enc->encoder = encoder;
- an->enc->data = enc_data;
-}
-
-static void
-anode_set_user_data (GNode *node, gpointer user_data, GDestroyNotify destroy)
-{
- Anode *an;
- g_assert (node && node->data);
- an = node->data;
- if (an->destroy)
- (an->destroy) (an->user_data);
- an->user_data = user_data;
- an->destroy = destroy;
+ an->enc->data = data;
+ an->enc->destroy = destroy;
+ anode_clr_backing (node);
}
static Aenc*
@@ -462,9 +493,9 @@ static void
anode_clear (GNode *node)
{
Anode *an = node->data;
+ anode_clr_backing (node);
anode_clr_tlv_data (node);
anode_clr_enc_data (node);
- anode_set_user_data (node, NULL, NULL);
g_free (an->failure);
an->failure = NULL;
}
@@ -483,9 +514,9 @@ static void
abits_destroy (gpointer data)
{
Abits *ab = data;
- g_assert (ab);
- if (ab->destroy)
- (ab->destroy) (ab->bits);
+ g_assert (ab != NULL);
+ if (ab->bits)
+ egg_bytes_unref (ab->bits);
g_slice_free (Abits, ab);
}
@@ -501,60 +532,60 @@ anode_destroy (GNode *node)
static gulong
anode_calc_tag_for_flags (GNode *node, gint flags)
{
- ASN1_ARRAY_TYPE *def;
+ EggAsn1xDef *def;
/* A context specific tag */
if (flags & FLAG_TAG) {
- def = anode_opt_lookup (node, TYPE_TAG, NULL);
+ def = anode_opt_lookup (node, EGG_ASN1X_TAG, NULL);
g_return_val_if_fail (def, G_MAXULONG);
return anode_def_value_as_ulong (def);
}
/* A tag from the universal set */
switch (anode_def_type (node)) {
- case TYPE_INTEGER:
+ case EGG_ASN1X_INTEGER:
return ASN1_TAG_INTEGER;
- case TYPE_ENUMERATED:
+ case EGG_ASN1X_ENUMERATED:
return ASN1_TAG_ENUMERATED;
- case TYPE_BOOLEAN:
+ case EGG_ASN1X_BOOLEAN:
return ASN1_TAG_BOOLEAN;
- case TYPE_BIT_STRING:
+ case EGG_ASN1X_BIT_STRING:
return ASN1_TAG_BIT_STRING;
- case TYPE_OCTET_STRING:
+ case EGG_ASN1X_OCTET_STRING:
return ASN1_TAG_OCTET_STRING;
- case TYPE_OBJECT_ID:
+ case EGG_ASN1X_OBJECT_ID:
return ASN1_TAG_OBJECT_ID;
- case TYPE_NULL:
+ case EGG_ASN1X_NULL:
return ASN1_TAG_NULL;
- case TYPE_GENERALSTRING:
+ case EGG_ASN1X_GENERALSTRING:
return ASN1_TAG_GENERALSTRING;
- case TYPE_TIME:
+ case EGG_ASN1X_TIME:
if (flags & FLAG_GENERALIZED)
return ASN1_TAG_GENERALIZEDTime;
else if (flags & FLAG_UTC)
return ASN1_TAG_UTCTime;
else
g_return_val_if_reached (G_MAXULONG);
- case TYPE_SEQUENCE:
- case TYPE_SEQUENCE_OF:
+ case EGG_ASN1X_SEQUENCE:
+ case EGG_ASN1X_SEQUENCE_OF:
return ASN1_TAG_SEQUENCE;
- case TYPE_SET:
- case TYPE_SET_OF:
+ case EGG_ASN1X_SET:
+ case EGG_ASN1X_SET_OF:
return ASN1_TAG_SET;
/* These should be handled specially */
- case TYPE_ANY:
- case TYPE_CHOICE:
+ case EGG_ASN1X_ANY:
+ case EGG_ASN1X_CHOICE:
return G_MAXULONG;
/* These are not real nodes */
- case TYPE_CONSTANT:
- case TYPE_IDENTIFIER:
- case TYPE_TAG:
- case TYPE_DEFAULT:
- case TYPE_SIZE:
- case TYPE_DEFINITIONS:
- case TYPE_IMPORTS:
+ case EGG_ASN1X_CONSTANT:
+ case EGG_ASN1X_IDENTIFIER:
+ case EGG_ASN1X_TAG:
+ case EGG_ASN1X_DEFAULT:
+ case EGG_ASN1X_SIZE:
+ case EGG_ASN1X_DEFINITIONS:
+ case EGG_ASN1X_IMPORTS:
g_return_val_if_reached (G_MAXULONG);
/* Unknown value */
@@ -570,22 +601,35 @@ anode_calc_tag (GNode *node)
}
static gboolean
-anode_calc_explicit_for_flags (GNode *node, gint flags)
+anode_calc_explicit_for_flags (GNode *node,
+ gint flags,
+ guchar *cls_type)
{
- const ASN1_ARRAY_TYPE *opt;
+ const EggAsn1xDef *opt;
if ((flags & FLAG_TAG) != FLAG_TAG)
return FALSE;
- opt = anode_opt_lookup (node, TYPE_TAG, NULL);
+ opt = anode_opt_lookup (node, EGG_ASN1X_TAG, NULL);
g_return_val_if_fail (opt, FALSE);
+ if (cls_type) {
+ if (opt->type & FLAG_UNIVERSAL)
+ *cls_type = ASN1_CLASS_UNIVERSAL;
+ else if (opt->type & FLAG_APPLICATION)
+ *cls_type = ASN1_CLASS_APPLICATION;
+ else if (opt->type & FLAG_PRIVATE)
+ *cls_type = ASN1_CLASS_PRIVATE;
+ else
+ *cls_type = ASN1_CLASS_CONTEXT_SPECIFIC;
+ }
if ((opt->type & FLAG_IMPLICIT) == FLAG_IMPLICIT)
return FALSE;
return TRUE;
}
static gboolean
-anode_calc_explicit (GNode *node)
+anode_calc_explicit (GNode *node,
+ guchar *cls_type)
{
- return anode_calc_explicit_for_flags (node, anode_def_flags (node));
+ return anode_calc_explicit_for_flags (node, anode_def_flags (node), cls_type);
}
/* -------------------------------------------------------------------------
@@ -826,7 +870,9 @@ anode_decode_tlv_for_contents (Atlv *outer, gboolean first, Atlv *tlv)
}
static gboolean
-anode_decode_choice (GNode *node, Atlv *tlv)
+anode_decode_choice (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv)
{
gboolean have = FALSE;
GNode *child;
@@ -834,7 +880,7 @@ anode_decode_choice (GNode *node, Atlv *tlv)
for (child = node->children; child; child = child->next) {
an = (Anode*)child->data;
- if (!have && anode_decode_anything (child, tlv)) {
+ if (!have && anode_decode_anything (child, backing, tlv)) {
an->chosen = 1;
have = TRUE;
} else {
@@ -882,7 +928,9 @@ anode_decode_struct_any (GNode *node, Atlv *tlv)
}
static gboolean
-anode_decode_sequence_or_set (GNode *node, Atlv *outer)
+anode_decode_sequence_or_set (GNode *node,
+ EggBytes *backing,
+ Atlv *outer)
{
GNode *child;
Atlv tlv;
@@ -902,7 +950,7 @@ anode_decode_sequence_or_set (GNode *node, Atlv *outer)
if (!anode_decode_tlv_for_contents (outer, i == 0, &tlv))
return anode_failure (node, "invalid encoding of child");
- if (!anode_decode_anything (child, &tlv))
+ if (!anode_decode_anything (child, backing, &tlv))
return FALSE;
outer->len = (tlv.end - outer->buf) - outer->off;
@@ -913,7 +961,9 @@ anode_decode_sequence_or_set (GNode *node, Atlv *outer)
}
static gboolean
-anode_decode_sequence_or_set_of (GNode *node, Atlv *outer)
+anode_decode_sequence_or_set_of (GNode *node,
+ EggBytes *backing,
+ Atlv *outer)
{
GNode *child, *other;
Atlv tlv;
@@ -946,7 +996,7 @@ anode_decode_sequence_or_set_of (GNode *node, Atlv *outer)
g_node_append (node, other);
}
- if (!anode_decode_anything (other, &tlv))
+ if (!anode_decode_anything (other, backing, &tlv))
return FALSE;
outer->len = (tlv.end - outer->buf) - outer->off;
@@ -957,7 +1007,10 @@ anode_decode_sequence_or_set_of (GNode *node, Atlv *outer)
}
static gboolean
-anode_decode_primitive (GNode *node, Atlv *tlv, gint flags)
+anode_decode_primitive (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv,
+ gint flags)
{
gint type;
@@ -969,27 +1022,27 @@ anode_decode_primitive (GNode *node, Atlv *tlv, gint flags)
switch (type) {
/* The primitive value types */
- case TYPE_INTEGER:
- case TYPE_ENUMERATED:
- case TYPE_BOOLEAN:
- case TYPE_BIT_STRING:
- case TYPE_OCTET_STRING:
- case TYPE_OBJECT_ID:
- case TYPE_NULL:
- case TYPE_GENERALSTRING:
- case TYPE_TIME:
- anode_set_tlv_data (node, tlv);
+ case EGG_ASN1X_INTEGER:
+ case EGG_ASN1X_ENUMERATED:
+ case EGG_ASN1X_BOOLEAN:
+ case EGG_ASN1X_BIT_STRING:
+ case EGG_ASN1X_OCTET_STRING:
+ case EGG_ASN1X_OBJECT_ID:
+ case EGG_ASN1X_NULL:
+ case EGG_ASN1X_GENERALSTRING:
+ case EGG_ASN1X_TIME:
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
/* Transparent types */
- case TYPE_ANY:
- anode_set_tlv_data (node, tlv);
+ case EGG_ASN1X_ANY:
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
- case TYPE_CHOICE:
- if (!anode_decode_choice (node, tlv))
+ case EGG_ASN1X_CHOICE:
+ if (!anode_decode_choice (node, backing, tlv))
return FALSE;
- anode_set_tlv_data (node, tlv);
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
default:
@@ -1000,7 +1053,10 @@ anode_decode_primitive (GNode *node, Atlv *tlv, gint flags)
}
static gboolean
-anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
+anode_decode_structured (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv,
+ gint flags)
{
gboolean definite;
const guchar *end;
@@ -1014,13 +1070,13 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
end = tlv->end;
/* An explicit, wrapped tag */
- if (anode_calc_explicit_for_flags (node, flags)) {
+ if (anode_calc_explicit_for_flags (node, flags, NULL)) {
if ((tlv->cls & ASN1_CLASS_CONTEXT_SPECIFIC) == 0)
return anode_failure (node, "missing context specific tag");
if (!anode_decode_tlv_for_contents (tlv, TRUE, &ctlv))
return anode_failure (node, "invalid encoding of child");
flags &= ~FLAG_TAG;
- if (!anode_decode_anything_for_flags (node, &ctlv, flags))
+ if (!anode_decode_anything_for_flags (node, backing, &ctlv, flags))
return FALSE;
/* Use most of the child's tlv */
@@ -1034,27 +1090,27 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
/* Other structured types */
} else {
switch (anode_def_type (node)) {
- case TYPE_ANY:
+ case EGG_ASN1X_ANY:
if (!anode_decode_struct_any (node, tlv))
return FALSE;
break;
- case TYPE_CHOICE:
- if (!anode_decode_choice (node, tlv))
+ case EGG_ASN1X_CHOICE:
+ if (!anode_decode_choice (node, backing, tlv))
return FALSE;
break;
- case TYPE_GENERALSTRING:
- case TYPE_OCTET_STRING:
+ case EGG_ASN1X_GENERALSTRING:
+ case EGG_ASN1X_OCTET_STRING:
if (!anode_decode_struct_string (node, tlv))
return FALSE;
break;
- case TYPE_SEQUENCE:
- case TYPE_SET:
- if (!anode_decode_sequence_or_set (node, tlv))
+ case EGG_ASN1X_SEQUENCE:
+ case EGG_ASN1X_SET:
+ if (!anode_decode_sequence_or_set (node, backing, tlv))
return FALSE;
break;
- case TYPE_SEQUENCE_OF:
- case TYPE_SET_OF:
- if (!anode_decode_sequence_or_set_of (node, tlv))
+ case EGG_ASN1X_SEQUENCE_OF:
+ case EGG_ASN1X_SET_OF:
+ if (!anode_decode_sequence_or_set_of (node, backing, tlv))
return FALSE;
break;
default:
@@ -1080,7 +1136,7 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
g_return_val_if_fail (tlv->buf + tlv->off + tlv->len + off == end, FALSE);
tlv->end = end;
- anode_set_tlv_data (node, tlv);
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
}
@@ -1099,7 +1155,10 @@ anode_decode_option_or_default (GNode *node, Atlv *tlv, gint flags)
}
static gboolean
-anode_decode_anything_for_flags (GNode *node, Atlv *tlv, gint flags)
+anode_decode_anything_for_flags (GNode *node,
+ EggBytes *bytes,
+ Atlv *tlv,
+ gint flags)
{
gboolean ret;
gulong tag;
@@ -1119,21 +1178,23 @@ anode_decode_anything_for_flags (GNode *node, Atlv *tlv, gint flags)
/* Structured value */
if (tlv->cls & ASN1_CLASS_STRUCTURED)
- ret = anode_decode_structured (node, tlv, flags);
+ ret = anode_decode_structured (node, bytes, tlv, flags);
/* A primitive simple value */
else
- ret = anode_decode_primitive (node, tlv, flags);
+ ret = anode_decode_primitive (node, bytes, tlv, flags);
return ret;
}
static gboolean
-anode_decode_anything (GNode *node, Atlv *tlv)
+anode_decode_anything (GNode *node,
+ EggBytes *bytes,
+ Atlv *tlv)
{
gint flags = anode_def_flags (node);
- if (!anode_decode_anything_for_flags (node, tlv, flags))
+ if (!anode_decode_anything_for_flags (node, bytes, tlv, flags))
return anode_decode_option_or_default (node, tlv, flags);
return TRUE;
@@ -1141,20 +1202,28 @@ anode_decode_anything (GNode *node, Atlv *tlv)
gboolean
egg_asn1x_decode_no_validate (GNode *asn,
- gconstpointer data,
- gsize n_data)
+ EggBytes *data)
{
+ const guchar *dat;
+ gsize size;
Atlv tlv;
+ g_return_val_if_fail (asn != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+
egg_asn1x_clear (asn);
- if (!anode_decode_tlv_for_data (data, (const guchar*)data + n_data, &tlv))
+ dat = egg_bytes_get_data (data);
+ g_return_val_if_fail (dat != NULL, FALSE);
+
+ size = egg_bytes_get_size (data);
+ if (!anode_decode_tlv_for_data (dat, dat + size, &tlv))
return anode_failure (asn, "content is not encoded properly");
- if (!anode_decode_anything (asn, &tlv))
+ if (!anode_decode_anything (asn, data, &tlv))
return FALSE;
- if (tlv.end - tlv.buf != n_data)
+ if (tlv.end - tlv.buf != size)
return FALSE;
return TRUE;
@@ -1162,16 +1231,14 @@ egg_asn1x_decode_no_validate (GNode *asn,
gboolean
egg_asn1x_decode (GNode *asn,
- gconstpointer data,
- gsize n_data)
+ EggBytes *data)
{
gboolean ret;
- g_return_val_if_fail (asn, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
+ g_return_val_if_fail (asn != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
- ret = egg_asn1x_decode_no_validate (asn, data, n_data);
+ ret = egg_asn1x_decode_no_validate (asn, data);
if (!ret)
return ret;
@@ -1255,10 +1322,14 @@ anode_encode_cls_tag_len (guchar *data, gsize n_data, guchar cls,
}
static void
-anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
- gpointer user_data, GDestroyNotify destroy)
+anode_encode_tlv_and_enc (GNode *node,
+ gsize n_data,
+ Aencoder encoder,
+ gpointer user_data,
+ GDestroyNotify destroy)
{
gboolean explicit = FALSE;
+ guchar cls_type;
gulong tag;
gint flags;
Atlv tlv;
@@ -1272,28 +1343,28 @@ anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
/* Figure out the basis if the class */
switch (anode_def_type (node)) {
- case TYPE_INTEGER:
- case TYPE_BOOLEAN:
- case TYPE_BIT_STRING:
- case TYPE_OCTET_STRING:
- case TYPE_OBJECT_ID:
- case TYPE_TIME:
- case TYPE_ENUMERATED:
- case TYPE_GENERALSTRING:
- case TYPE_NULL:
+ case EGG_ASN1X_INTEGER:
+ case EGG_ASN1X_BOOLEAN:
+ case EGG_ASN1X_BIT_STRING:
+ case EGG_ASN1X_OCTET_STRING:
+ case EGG_ASN1X_OBJECT_ID:
+ case EGG_ASN1X_TIME:
+ case EGG_ASN1X_ENUMERATED:
+ case EGG_ASN1X_GENERALSTRING:
+ case EGG_ASN1X_NULL:
tlv.cls = ASN1_CLASS_UNIVERSAL;
break;
/* Container types */
- case TYPE_SEQUENCE:
- case TYPE_SET:
- case TYPE_SEQUENCE_OF:
- case TYPE_SET_OF:
+ case EGG_ASN1X_SEQUENCE:
+ case EGG_ASN1X_SET:
+ case EGG_ASN1X_SEQUENCE_OF:
+ case EGG_ASN1X_SET_OF:
tlv.cls = (ASN1_CLASS_STRUCTURED | ASN1_CLASS_UNIVERSAL);
break;
/* Transparent types shouldn't get here */
- case TYPE_ANY:
- case TYPE_CHOICE:
+ case EGG_ASN1X_ANY:
+ case EGG_ASN1X_CHOICE:
g_return_if_reached ();
default:
@@ -1303,11 +1374,11 @@ anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
/* Build up the class */
flags = anode_def_flags (node);
if (flags & FLAG_TAG) {
- explicit = anode_calc_explicit_for_flags (node, flags);
+ explicit = anode_calc_explicit_for_flags (node, flags, &cls_type);
if (explicit)
flags &= ~FLAG_TAG;
else
- tlv.cls |= ASN1_CLASS_CONTEXT_SPECIFIC;
+ tlv.cls |= cls_type;
}
/* And now the tag */
@@ -1328,14 +1399,17 @@ anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
tlv.buf = tlv.end = NULL;
anode_clear (node);
- anode_set_tlv_data (node, &tlv);
- anode_set_enc_data (node, encoder, user_data);
- anode_set_user_data (node, user_data, destroy);
+ anode_set_tlv_data (node, NULL, &tlv);
+ anode_set_enc_data (node, encoder, user_data, destroy);
}
static gboolean
-anode_encode_build (GNode *node, guchar *data, gsize n_data)
+anode_encode_build (GNode *node,
+ EggBytes *backing,
+ guchar *data,
+ gsize n_data)
{
+ guchar cls_type;
gint type;
guchar cls;
gulong tag;
@@ -1352,16 +1426,16 @@ anode_encode_build (GNode *node, guchar *data, gsize n_data)
g_return_val_if_fail (enc, FALSE);
/* If it's a choice node, use the choice for calculations */
- if (type == TYPE_CHOICE) {
+ if (type == EGG_ASN1X_CHOICE) {
node = egg_asn1x_get_choice (node);
g_return_val_if_fail (node, FALSE);
}
/* Encode any explicit tag */
- if (anode_calc_explicit (node)) {
+ if (anode_calc_explicit (node, &cls_type)) {
tag = anode_calc_tag (node);
g_return_val_if_fail (tag != G_MAXULONG, FALSE);
- cls = (ASN1_CLASS_STRUCTURED | ASN1_CLASS_CONTEXT_SPECIFIC);
+ cls = (ASN1_CLASS_STRUCTURED | cls_type);
g_assert (tlv->oft > 0 && tlv->oft < tlv->off);
off = anode_encode_cls_tag_len (data, n_data, cls, tag, (tlv->off - tlv->oft) + tlv->len);
g_assert (off == tlv->oft);
@@ -1375,9 +1449,10 @@ anode_encode_build (GNode *node, guchar *data, gsize n_data)
g_assert (tlv->len + tlv->off == n_data);
tlv->buf = data;
tlv->end = data + n_data;
+ anode_set_backing (node, backing);
/* Encode in the data */
- if (!(enc->encoder) (enc->data, data + tlv->off, tlv->len))
+ if (!(enc->encoder) (enc->data, node, data + tlv->off, tlv->len))
return FALSE;
return TRUE;
@@ -1437,10 +1512,11 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
GNode *child;
GNode *next;
- g_assert (allocator);
+ if (!allocator)
+ allocator = g_realloc;
/* We have to sort any SET OF :( */
- if (anode_def_type (node) != TYPE_SET_OF)
+ if (anode_def_type (node) != EGG_ASN1X_SET_OF)
return FALSE;
bufs = NULL;
@@ -1457,7 +1533,7 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
if (!data)
break;
- if (!anode_encode_build (child, data, n_data)) {
+ if (!anode_encode_build (child, NULL, data, n_data)) {
(allocator) (data, 0);
continue;
}
@@ -1485,7 +1561,22 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
}
static gboolean
-anode_encoder_simple (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_bytes (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
+{
+ EggBytes *bytes = user_data;
+ g_assert (egg_bytes_get_size (bytes) >= n_data);
+ memcpy (data, egg_bytes_get_data (bytes), n_data);
+ return TRUE;
+}
+
+static gboolean
+anode_encoder_data (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
{
memcpy (data, user_data, n_data);
return TRUE;
@@ -1493,11 +1584,13 @@ anode_encoder_simple (gpointer user_data, guchar *data, gsize n_data)
static gboolean
anode_encoder_unsigned (gpointer user_data,
+ GNode *node,
guchar *data,
gsize n_data)
{
+ EggBytes *value = user_data;
gboolean sign;
- gchar *p;
+ const gchar *p;
/*
* If top bit is set, the result would be negative in two's complement
@@ -1505,7 +1598,9 @@ anode_encoder_unsigned (gpointer user_data,
* byte is already calculated into n_data, see egg_asn1x_set_integer_as_usg
*/
- p = user_data;
+ p = egg_bytes_get_data (value);
+ g_return_val_if_fail (p != NULL, FALSE);
+
sign = !!(p[0] & 0x80);
if (sign) {
g_assert (n_data > 1);
@@ -1519,7 +1614,10 @@ anode_encoder_unsigned (gpointer user_data,
}
static gboolean
-anode_encoder_structured (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_structured (gpointer user_data,
+ GNode *unused,
+ guchar *data,
+ gsize n_data)
{
GNode *node = user_data;
GNode *child;
@@ -1531,7 +1629,8 @@ anode_encoder_structured (gpointer user_data, guchar *data, gsize n_data)
if (tlv) {
length = tlv->off + tlv->len;
g_assert (length <= n_data);
- if (!anode_encode_build (child, data, length))
+ if (!anode_encode_build (child, anode_get_backing (node),
+ data, length))
return FALSE;
data += length;
n_data -= length;
@@ -1542,7 +1641,10 @@ anode_encoder_structured (gpointer user_data, guchar *data, gsize n_data)
}
static gboolean
-anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_choice (gpointer user_data,
+ GNode *unused,
+ guchar *data,
+ gsize n_data)
{
GNode *node = user_data;
Aenc *enc = NULL;
@@ -1560,7 +1662,7 @@ anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
enc = anode_get_enc_data (child);
g_return_val_if_fail (enc, FALSE);
- if (!(enc->encoder) (enc->data, data, n_data))
+ if (!(enc->encoder) (enc->data, child, data, n_data))
return FALSE;
/* Child's buffer matches ours */
@@ -1571,7 +1673,10 @@ anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
}
static gboolean
-anode_encoder_bit_string (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_bit_string (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
{
Abits *ab = user_data;
guchar empty, mask;
@@ -1588,7 +1693,7 @@ anode_encoder_bit_string (gpointer user_data, guchar *data, gsize n_data)
data += 1;
/* Fill in the actual data */
- memcpy (data, ab->bits, len);
+ memcpy (data, egg_bytes_get_data (ab->bits), len);
/* Set the extra bits to zero */
if (len && empty) {
@@ -1602,6 +1707,8 @@ anode_encoder_bit_string (gpointer user_data, guchar *data, gsize n_data)
static gboolean
anode_encode_prepare_simple (GNode *node, gboolean want)
{
+ EggBytes *backing;
+ EggBytes *bytes;
Aenc *enc;
Atlv *tlv;
@@ -1611,8 +1718,15 @@ anode_encode_prepare_simple (GNode *node, gboolean want)
/* Transfer the tlv data over to enc */
enc = anode_get_enc_data (node);
- if (enc == NULL)
- anode_set_enc_data (node, anode_encoder_simple, (guchar*)tlv->buf + tlv->off);
+ if (enc == NULL) {
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return FALSE;
+
+ bytes = egg_bytes_new_with_free_func ((guchar *)tlv->buf + tlv->off, tlv->len,
+ egg_bytes_unref, egg_bytes_ref (backing));
+ anode_set_enc_data (node, anode_encoder_bytes, bytes, egg_bytes_unref);
+ }
tlv->buf = tlv->end = NULL;
return TRUE;
@@ -1624,7 +1738,7 @@ anode_encode_prepare_choice (GNode *node, gboolean want)
Atlv *tlv;
GNode *child;
- g_assert (anode_def_type (node) == TYPE_CHOICE);
+ g_assert (anode_def_type (node) == EGG_ASN1X_CHOICE);
child = egg_asn1x_get_choice (node);
if (!child)
@@ -1636,8 +1750,8 @@ anode_encode_prepare_choice (GNode *node, gboolean want)
tlv = anode_get_tlv_data (child);
g_return_val_if_fail (tlv, FALSE);
anode_clr_tlv_data (node);
- anode_set_tlv_data (node, tlv);
- anode_set_enc_data (node, anode_encoder_choice, node);
+ anode_set_tlv_data (node, NULL, tlv);
+ anode_set_enc_data (node, anode_encoder_choice, node, NULL);
return TRUE;
@@ -1658,7 +1772,7 @@ anode_encode_prepare_structured (GNode *node, gboolean want)
had = FALSE;
length = 0;
- if (type == TYPE_SEQUENCE_OF || type == TYPE_SET_OF)
+ if (type == EGG_ASN1X_SEQUENCE_OF || type == EGG_ASN1X_SET_OF)
child_want = FALSE;
if (anode_def_flags (node) & FLAG_OPTION)
want = FALSE;
@@ -1674,7 +1788,7 @@ anode_encode_prepare_structured (GNode *node, gboolean want)
if (had == FALSE) {
/* See if we should encode an empty set or seq of */
- if (type == TYPE_SEQUENCE_OF || type == TYPE_SET_OF) {
+ if (type == EGG_ASN1X_SEQUENCE_OF || type == EGG_ASN1X_SET_OF) {
if (!want)
return FALSE;
} else {
@@ -1690,25 +1804,25 @@ static gboolean
anode_encode_prepare (GNode *node, gboolean want)
{
switch (anode_def_type (node)) {
- case TYPE_INTEGER:
- case TYPE_BOOLEAN:
- case TYPE_BIT_STRING:
- case TYPE_OCTET_STRING:
- case TYPE_OBJECT_ID:
- case TYPE_TIME:
- case TYPE_ENUMERATED:
- case TYPE_GENERALSTRING:
- case TYPE_ANY:
- case TYPE_NULL:
+ case EGG_ASN1X_INTEGER:
+ case EGG_ASN1X_BOOLEAN:
+ case EGG_ASN1X_BIT_STRING:
+ case EGG_ASN1X_OCTET_STRING:
+ case EGG_ASN1X_OBJECT_ID:
+ case EGG_ASN1X_TIME:
+ case EGG_ASN1X_ENUMERATED:
+ case EGG_ASN1X_GENERALSTRING:
+ case EGG_ASN1X_ANY:
+ case EGG_ASN1X_NULL:
return anode_encode_prepare_simple (node, want);
break;
- case TYPE_SEQUENCE:
- case TYPE_SEQUENCE_OF:
- case TYPE_SET:
- case TYPE_SET_OF:
+ case EGG_ASN1X_SEQUENCE:
+ case EGG_ASN1X_SEQUENCE_OF:
+ case EGG_ASN1X_SET:
+ case EGG_ASN1X_SET_OF:
return anode_encode_prepare_structured (node, want);
break;
- case TYPE_CHOICE:
+ case EGG_ASN1X_CHOICE:
return anode_encode_prepare_choice (node, want);
break;
default:
@@ -1716,20 +1830,55 @@ anode_encode_prepare (GNode *node, gboolean want)
};
}
-gpointer
-egg_asn1x_encode (GNode *asn, EggAllocator allocator, gsize *n_data)
+typedef struct {
+ EggAllocator allocator;
+ gpointer allocated;
+} AllocatorClosure;
+
+static void
+destroy_with_allocator (gpointer data)
+{
+ AllocatorClosure *closure = data;
+ g_assert (closure->allocator);
+ (closure->allocator) (closure->allocated, 0);
+ g_slice_free (AllocatorClosure, closure);
+}
+
+static EggBytes *
+new_bytes_with_allocator (EggAllocator allocator,
+ guchar **data,
+ gsize length)
+{
+ AllocatorClosure *closure;
+
+ if (allocator) {
+ *data = (allocator) (NULL, length + 1);
+ if (allocator == NULL)
+ return NULL;
+ closure = g_slice_new (AllocatorClosure);
+ closure->allocated = *data;
+ closure->allocator = allocator;
+ return egg_bytes_new_with_free_func (*data, length,
+ destroy_with_allocator,
+ closure);
+ } else {
+ *data = g_malloc (length);
+ return egg_bytes_new_take (*data, length);
+ }
+}
+
+EggBytes *
+egg_asn1x_encode (GNode *asn,
+ EggAllocator allocator)
{
+ EggBytes *bytes;
guchar *data;
gsize length;
Atlv *tlv;
- g_return_val_if_fail (asn, NULL);
- g_return_val_if_fail (n_data, NULL);
+ g_return_val_if_fail (asn != NULL, NULL);
g_return_val_if_fail (anode_def_type_is_real (asn), NULL);
- if (!allocator)
- allocator = g_realloc;
-
if (!anode_encode_prepare (asn, TRUE)) {
anode_failure (asn, "missing value(s)");
return NULL;
@@ -1744,18 +1893,17 @@ egg_asn1x_encode (GNode *asn, EggAllocator allocator, gsize *n_data)
/* Allocate enough memory for entire thingy */
length = tlv->off + tlv->len;
- data = (allocator) (NULL, length + 1);
+ bytes = new_bytes_with_allocator (allocator, &data, length);
if (data == NULL)
return NULL;
- if (anode_encode_build (asn, data, length) &&
+ if (anode_encode_build (asn, bytes, data, length) &&
anode_validate_anything (asn, TRUE)) {
anode_encode_commit (asn);
- *n_data = length;
- return data;
+ return bytes;
}
- (allocator) (data, 0);
+ egg_bytes_unref (bytes);
anode_encode_rollback (asn);
return NULL;
}
@@ -2256,7 +2404,6 @@ anode_write_oid (const gchar *oid, guchar *data, gsize *n_data)
gboolean had;
gint i, k, at;
- p = oid;
at = 0;
num1 = 0;
@@ -2320,7 +2467,7 @@ egg_asn1x_node (GNode *asn, ...)
type = anode_def_type (node);
/* Use integer indexes for these */
- if (type == TYPE_SEQUENCE_OF || type == TYPE_SET_OF) {
+ if (type == EGG_ASN1X_SEQUENCE_OF || type == EGG_ASN1X_SET_OF) {
index = va_arg (va, gint);
if (index == 0)
return node;
@@ -2363,6 +2510,13 @@ egg_asn1x_name (GNode *node)
return anode_def_name (node);
}
+EggAsn1xType
+egg_asn1x_type (GNode *node)
+{
+ g_return_val_if_fail (node, 0);
+ return anode_def_type (node);
+}
+
guint
egg_asn1x_count (GNode *node)
{
@@ -2373,7 +2527,7 @@ egg_asn1x_count (GNode *node)
g_return_val_if_fail (node, 0);
type = anode_def_type (node);
- if (type != TYPE_SEQUENCE_OF && type != TYPE_SET_OF) {
+ if (type != EGG_ASN1X_SEQUENCE_OF && type != EGG_ASN1X_SET_OF) {
g_warning ("node passed to egg_asn1x_count was not a sequence of or set of");
return 0;
}
@@ -2395,7 +2549,7 @@ egg_asn1x_append (GNode *node)
g_return_val_if_fail (node, NULL);
type = anode_def_type (node);
- if (type != TYPE_SEQUENCE_OF && type != TYPE_SET_OF) {
+ if (type != EGG_ASN1X_SEQUENCE_OF && type != EGG_ASN1X_SET_OF) {
g_warning ("node passed to egg_asn1x_append was not a sequence of or set of");
return NULL;
}
@@ -2427,12 +2581,12 @@ egg_asn1x_have (GNode *node)
gboolean
egg_asn1x_get_boolean (GNode *node, gboolean *value)
{
- ASN1_ARRAY_TYPE *opt;
+ EggAsn1xDef *opt;
Atlv *tlv;
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (value, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_BOOLEAN, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_BOOLEAN, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL) {
@@ -2441,7 +2595,7 @@ egg_asn1x_get_boolean (GNode *node, gboolean *value)
return FALSE;
/* Try to get a default */
- opt = anode_opt_lookup (node, TYPE_DEFAULT, NULL);
+ opt = anode_opt_lookup (node, EGG_ASN1X_DEFAULT, NULL);
g_return_val_if_fail (opt, FALSE);
/* Parse out the default value */
@@ -2464,7 +2618,7 @@ egg_asn1x_set_boolean (GNode *node, gboolean value)
gsize n_data;
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_BOOLEAN, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_BOOLEAN, FALSE);
/* TODO: Handle default values */
@@ -2472,7 +2626,7 @@ egg_asn1x_set_boolean (GNode *node, gboolean value)
data = g_malloc0 (1);
if (!anode_write_boolean (value, data, &n_data))
return FALSE;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
@@ -2480,10 +2634,10 @@ gboolean
egg_asn1x_set_null (GNode *node)
{
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_NULL, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_NULL, FALSE);
/* Encode zero characters */
- anode_encode_tlv_and_enc (node, 0, anode_encoder_simple, "", NULL);
+ anode_encode_tlv_and_enc (node, 0, anode_encoder_data, "", NULL);
return TRUE;
}
@@ -2491,12 +2645,12 @@ GQuark
egg_asn1x_get_enumerated (GNode *node)
{
gchar buf[sizeof (gulong) * 3];
- ASN1_ARRAY_TYPE *opt;
+ EggAsn1xDef *opt;
gulong val;
Atlv *tlv;
g_return_val_if_fail (node, 0);
- g_return_val_if_fail (anode_def_type (node) == TYPE_ENUMERATED, 0);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_ENUMERATED, 0);
tlv = anode_get_tlv_data (node);
@@ -2515,7 +2669,7 @@ egg_asn1x_get_enumerated (GNode *node)
g_return_val_if_reached (0);
/* Lookup that value in our table */
- opt = anode_opt_lookup_value (node, TYPE_CONSTANT, buf);
+ opt = anode_opt_lookup_value (node, EGG_ASN1X_CONSTANT, buf);
if (opt == NULL || opt->name == NULL)
return 0;
@@ -2525,7 +2679,7 @@ egg_asn1x_get_enumerated (GNode *node)
gboolean
egg_asn1x_set_enumerated (GNode *node, GQuark value)
{
- ASN1_ARRAY_TYPE *opt;
+ EggAsn1xDef *opt;
const gchar *name;
gpointer data;
gsize n_data;
@@ -2533,14 +2687,14 @@ egg_asn1x_set_enumerated (GNode *node, GQuark value)
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (value, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_ENUMERATED, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_ENUMERATED, FALSE);
/* TODO: Handle default values */
name = g_quark_to_string (value);
g_return_val_if_fail (name, FALSE);
- opt = anode_opt_lookup (node, TYPE_CONSTANT, name);
+ opt = anode_opt_lookup (node, EGG_ASN1X_CONSTANT, name);
g_return_val_if_fail (opt && opt->value, FALSE);
/* TODO: Signed values */
@@ -2553,21 +2707,21 @@ egg_asn1x_set_enumerated (GNode *node, GQuark value)
if (!anode_write_integer_ulong (val, data, &n_data))
return FALSE;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
gboolean
egg_asn1x_get_integer_as_ulong (GNode *node, gulong *value)
{
- const ASN1_ARRAY_TYPE *opt;
+ const EggAsn1xDef *opt;
const gchar *defval;
Atlv *tlv;
gchar *end;
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (value, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_INTEGER, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL) {
@@ -2576,12 +2730,12 @@ egg_asn1x_get_integer_as_ulong (GNode *node, gulong *value)
return FALSE;
/* Try to get a default */
- opt = anode_opt_lookup (node, TYPE_DEFAULT, NULL);
+ opt = anode_opt_lookup (node, EGG_ASN1X_DEFAULT, NULL);
g_return_val_if_fail (opt, FALSE);
g_return_val_if_fail (opt->value, FALSE);
defval = opt->value;
- opt = anode_opt_lookup (node, TYPE_CONSTANT, defval);
+ opt = anode_opt_lookup (node, EGG_ASN1X_CONSTANT, defval);
if (opt != NULL) {
g_return_val_if_fail (opt->value, FALSE);
defval = opt->value;
@@ -2603,7 +2757,7 @@ egg_asn1x_set_integer_as_ulong (GNode *node, gulong value)
gsize n_data;
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_INTEGER, FALSE);
/* TODO: Handle default values */
@@ -2611,100 +2765,136 @@ egg_asn1x_set_integer_as_ulong (GNode *node, gulong value)
data = g_malloc0 (n_data);
if (!anode_write_integer_ulong (value, data, &n_data))
return FALSE;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
-gconstpointer
-egg_asn1x_get_integer_as_raw (GNode *node, gsize *n_data)
+EggBytes *
+egg_asn1x_get_integer_as_raw (GNode *node)
{
+ EggBytes *backing;
Atlv *tlv;
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (n_data, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_INTEGER, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
- *n_data = tlv->len;
- return tlv->buf + tlv->off;
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
+ return egg_bytes_new_with_free_func (tlv->buf + tlv->off, tlv->len,
+ egg_bytes_unref, egg_bytes_ref (backing));
}
-gconstpointer
-egg_asn1x_get_integer_as_usg (GNode *node,
- gsize *n_data)
+EggBytes *
+egg_asn1x_get_integer_as_usg (GNode *node)
{
+ EggBytes *backing;
const guchar *p;
gboolean sign;
+ Atlv *tlv;
+ gsize n_data;
gsize len;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (n_data, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_val_if_fail (node != NULL, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_INTEGER, FALSE);
+
+ tlv = anode_get_tlv_data (node);
+ if (tlv == NULL || tlv->buf == NULL)
+ return NULL;
+
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
+ p = tlv->buf + tlv->off;
+ len = tlv->len;
- p = egg_asn1x_get_integer_as_raw (node, &len);
sign = !!(p[0] & 0x80);
if (sign) {
g_warning ("invalid two's complement integer is negative, but expected unsigned");
return NULL;
}
- *n_data = len;
+ n_data = len;
/* Strip off the extra zero byte that was preventing it from being negative */
if (p[0] == 0 && len > 1) {
sign = !!(p[1] & 0x80);
if (sign) {
p++;
- *n_data = len - 1;
+ n_data = len - 1;
}
}
- return p;
+ return egg_bytes_new_with_free_func (p, n_data,
+ egg_bytes_unref,
+ egg_bytes_ref (backing));
}
-gboolean
-egg_asn1x_set_integer_as_raw (GNode *node, gconstpointer data, gsize n_data, GDestroyNotify destroy)
+void
+egg_asn1x_set_integer_as_raw (GNode *node,
+ EggBytes *value)
+{
+ g_return_if_fail (value != NULL);
+ egg_asn1x_take_integer_as_raw (node, egg_bytes_ref (value));
+}
+
+void
+egg_asn1x_take_integer_as_raw (GNode *node,
+ EggBytes *value)
{
gboolean sign;
- guchar *p;
+ const guchar *p;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data > 0, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (anode_def_type (node) == EGG_ASN1X_INTEGER);
/* Make sure the integer is properly encoded in twos complement*/
- p = (guchar*)data;
+ p = egg_bytes_get_data (value);
+ g_return_if_fail (p != NULL);
+
sign = !!(p[0] & 0x80);
if (sign) {
g_warning ("integer in egg_asn1x_set_integer_as_raw is not two's complement");
- return FALSE;
+ return;
}
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, (gpointer)data, destroy);
- return TRUE;
+ anode_encode_tlv_and_enc (node, egg_bytes_get_size (value), anode_encoder_bytes,
+ value, egg_bytes_unref);
}
-gboolean
+void
egg_asn1x_set_integer_as_usg (GNode *node,
- gconstpointer data,
- gsize n_data,
- GDestroyNotify destroy)
+ EggBytes *value)
+{
+ g_return_if_fail (value != NULL);
+ egg_asn1x_take_integer_as_usg (node, egg_bytes_ref (value));
+}
+
+void
+egg_asn1x_take_integer_as_usg (GNode *node,
+ EggBytes *value)
{
gboolean sign;
- guchar *p;
+ const guchar *p;
+ gsize len;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data > 0, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (anode_def_type (node) == EGG_ASN1X_INTEGER);
/* Make sure the integer is properly encoded in twos complement*/
- p = (guchar*)data;
+ p = egg_bytes_get_data (value);
+ g_return_if_fail (p != NULL);
+
sign = !!(p[0] & 0x80);
+ len = egg_bytes_get_size (value);
/*
* If in two's complement this would be negative, add a zero byte so
@@ -2712,50 +2902,66 @@ egg_asn1x_set_integer_as_usg (GNode *node,
* longer. In anode_encoder_unsigned we actually add the zero byte.
*/
if (sign)
- n_data += 1;
+ len += 1;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_unsigned,
- (gpointer)data, destroy);
- return TRUE;
+ anode_encode_tlv_and_enc (node, len, anode_encoder_unsigned,
+ value, egg_bytes_unref);
}
-gconstpointer
-egg_asn1x_get_raw_element (GNode *node, gsize *n_element)
+EggBytes *
+egg_asn1x_get_element_raw (GNode *node)
{
+ EggBytes *backing;
+ const guchar *p;
+ gsize len;
Atlv *tlv;
- g_return_val_if_fail (node, NULL);
- g_return_val_if_fail (n_element, NULL);
+ g_return_val_if_fail (node != NULL, NULL);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
- if (anode_calc_explicit (node)) {
- *n_element = (tlv->len + tlv->off) - tlv->oft;
- return tlv->buf + tlv->oft;
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
+ if (anode_calc_explicit (node, NULL)) {
+ len = (tlv->len + tlv->off) - tlv->oft;
+ p = tlv->buf + tlv->oft;
} else {
- *n_element = tlv->len + tlv->off;
- return tlv->buf;
+ len = tlv->len + tlv->off;
+ p = tlv->buf;
}
+
+ return egg_bytes_new_with_free_func (p, len, egg_bytes_unref,
+ egg_bytes_ref (backing));
}
gboolean
-egg_asn1x_set_raw_element (GNode *node, gpointer data,
- gsize n_data, GDestroyNotify destroy)
+egg_asn1x_set_element_raw (GNode *node,
+ EggBytes *element)
{
Atlv dtlv, *tlv;
gint oft, flags;
+ const guchar *data;
+ guchar cls_type;
+ EggBytes *sub;
+ gsize size;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
+ g_return_val_if_fail (node != NULL, FALSE);
+ g_return_val_if_fail (element != NULL, FALSE);
anode_clear (node);
memset (&dtlv, 0, sizeof (dtlv));
+ data = egg_bytes_get_data (element);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ size = egg_bytes_get_size (element);
+
/* Decode the beginning TLV */
- if (!anode_decode_tlv_for_data (data, (const guchar*)data + n_data, &dtlv))
+ if (!anode_decode_tlv_for_data (data, data + size, &dtlv))
return FALSE;
/*
@@ -2767,11 +2973,11 @@ egg_asn1x_set_raw_element (GNode *node, gpointer data,
*/
flags = anode_def_flags (node);
flags &= ~(FLAG_TAG | FLAG_DEFAULT | FLAG_OPTION);
- if (!anode_decode_anything_for_flags (node, &dtlv, flags))
+ if (!anode_decode_anything_for_flags (node, element, &dtlv, flags))
return FALSE;
/* There was extra data */
- if (dtlv.end - dtlv.buf != n_data)
+ if (dtlv.end - dtlv.buf != size)
return FALSE;
/* Clear buffer from TLV so it gets encoded */
@@ -2780,46 +2986,41 @@ egg_asn1x_set_raw_element (GNode *node, gpointer data,
tlv->buf = tlv->end = NULL;
/* Explicit tagging: leave space for the outer tag */
- if (anode_calc_explicit (node)) {
- oft = anode_encode_cls_tag_len (NULL, 0, (ASN1_CLASS_STRUCTURED | ASN1_CLASS_CONTEXT_SPECIFIC),
- anode_calc_tag (node), n_data);
+ if (anode_calc_explicit (node, &cls_type)) {
+ oft = anode_encode_cls_tag_len (NULL, 0, (ASN1_CLASS_STRUCTURED | cls_type),
+ anode_calc_tag (node), size);
tlv->off += oft;
tlv->oft = oft;
}
+ sub = egg_bytes_new_with_free_func (dtlv.buf + dtlv.off, dtlv.len,
+ egg_bytes_unref, egg_bytes_ref (element));
+
/* Setup encoding of the contents */
- anode_set_enc_data (node, anode_encoder_simple, (gpointer)(dtlv.buf + dtlv.off));
- anode_set_user_data (node, data, destroy);
+ anode_set_enc_data (node, anode_encoder_bytes, sub, egg_bytes_unref);
return TRUE;
}
-gconstpointer
-egg_asn1x_get_raw_value (GNode *node, gsize *n_content)
+EggBytes *
+egg_asn1x_get_raw_value (GNode *node)
{
+ EggBytes *backing;
Atlv *tlv;
g_return_val_if_fail (node, NULL);
- g_return_val_if_fail (n_content, NULL);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
g_return_val_if_fail (!(tlv->cls & ASN1_CLASS_STRUCTURED), NULL);
- *n_content = tlv->len;
- return tlv->buf + tlv->off;
-}
-
-gboolean
-egg_asn1x_set_raw_value (GNode *node, gsize length, EggAsn1xEncoder encoder,
- gpointer user_data, GDestroyNotify destroy)
-{
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (encoder, FALSE);
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
- anode_encode_tlv_and_enc (node, length, encoder, user_data, destroy);
- return TRUE;
+ return egg_bytes_new_with_free_func (tlv->buf + tlv->off, tlv->len,
+ egg_bytes_unref, egg_bytes_ref (backing));
}
guchar*
@@ -2837,7 +3038,7 @@ egg_asn1x_get_string_as_raw (GNode *node, EggAllocator allocator, gsize *n_strin
allocator = g_realloc;
type = anode_def_type (node);
- g_return_val_if_fail (type == TYPE_OCTET_STRING || type == TYPE_GENERALSTRING, NULL);
+ g_return_val_if_fail (type == EGG_ASN1X_OCTET_STRING || type == EGG_ASN1X_GENERALSTRING, NULL);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
@@ -2870,9 +3071,41 @@ egg_asn1x_set_string_as_raw (GNode *node, guchar *data, gsize n_data, GDestroyNo
g_return_val_if_fail (data, FALSE);
type = anode_def_type (node);
- g_return_val_if_fail (type == TYPE_OCTET_STRING || type == TYPE_GENERALSTRING, FALSE);
+ g_return_val_if_fail (type == EGG_ASN1X_OCTET_STRING || type == EGG_ASN1X_GENERALSTRING, FALSE);
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, destroy);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, destroy);
+ return TRUE;
+}
+
+EggBytes *
+egg_asn1x_get_string_as_bytes (GNode *node)
+{
+ gpointer raw;
+ gsize length;
+
+ g_return_val_if_fail (node != NULL, NULL);
+
+ raw = egg_asn1x_get_string_as_raw (node, NULL, &length);
+ if (raw == NULL)
+ return NULL;
+
+ return egg_bytes_new_take (raw, length);
+}
+
+gboolean
+egg_asn1x_set_string_as_bytes (GNode *node,
+ EggBytes *data)
+{
+ gint type;
+
+ g_return_val_if_fail (node != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ type = anode_def_type (node);
+ g_return_val_if_fail (type == EGG_ASN1X_OCTET_STRING || type == EGG_ASN1X_GENERALSTRING, FALSE);
+
+ anode_encode_tlv_and_enc (node, egg_bytes_get_size (data), anode_encoder_bytes,
+ egg_bytes_ref (data), egg_bytes_unref);
return TRUE;
}
@@ -2933,61 +3166,67 @@ egg_asn1x_set_string_as_utf8 (GNode *node, gchar *data, GDestroyNotify destroy)
return egg_asn1x_set_string_as_raw (node, (guchar*)data, n_data, destroy);
}
-guchar*
-egg_asn1x_get_bits_as_raw (GNode *node, EggAllocator allocator, guint *n_bits)
+EggBytes *
+egg_asn1x_get_bits_as_raw (GNode *node, guint *n_bits)
{
- Atlv *tlv;
- gpointer bits;
+ EggBytes *backing;
guchar padded;
+ Atlv *tlv;
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (n_bits, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_BIT_STRING, FALSE);
-
- if (!allocator)
- allocator = g_realloc;
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_BIT_STRING, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
padded = *(tlv->buf + tlv->off);
g_return_val_if_fail (padded < 8, NULL);
g_return_val_if_fail (tlv->len > 1, NULL);
- bits = (allocator) (NULL, tlv->len);
- if (bits == NULL)
- return NULL;
-
- memcpy (bits, tlv->buf + tlv->off + 1, tlv->len - 1);
*n_bits = ((tlv->len - 1) * 8) - padded;
- return bits;
+ return egg_bytes_new_with_free_func (tlv->buf + tlv->off + 1, tlv->len - 1,
+ egg_bytes_unref, egg_bytes_ref (backing));
}
-gboolean
-egg_asn1x_set_bits_as_raw (GNode *node, guchar *bits, guint n_bits, GDestroyNotify destroy)
+void
+egg_asn1x_set_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits)
+{
+ g_return_if_fail (value != NULL);
+ egg_asn1x_take_bits_as_raw (node, egg_bytes_ref (value), n_bits);
+}
+
+void
+egg_asn1x_take_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits)
{
gint type;
gsize length;
Abits *ab;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (bits, FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (value != NULL);
type = anode_def_type (node);
- g_return_val_if_fail (type == TYPE_BIT_STRING, FALSE);
+ g_return_if_fail (type == EGG_ASN1X_BIT_STRING);
length = (n_bits / 8);
if (n_bits % 8)
length += 1;
ab = g_slice_new0 (Abits);
- ab->bits = bits;
+ ab->bits = value;
ab->n_bits = n_bits;
- ab->destroy = destroy;
anode_encode_tlv_and_enc (node, length + 1, anode_encoder_bit_string, ab, abits_destroy);
- return TRUE;
}
gboolean
@@ -3002,7 +3241,7 @@ egg_asn1x_get_bits_as_ulong (GNode *node, gulong *bits, guint *n_bits)
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (bits, FALSE);
g_return_val_if_fail (n_bits, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_BIT_STRING, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_BIT_STRING, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
@@ -3042,7 +3281,7 @@ egg_asn1x_set_bits_as_ulong (GNode *node, gulong bits, guint n_bits)
g_return_val_if_fail (n_bits <= sizeof (gulong) * 8, FALSE);
type = anode_def_type (node);
- g_return_val_if_fail (type == TYPE_BIT_STRING, FALSE);
+ g_return_val_if_fail (type == EGG_ASN1X_BIT_STRING, FALSE);
empty = n_bits % 8;
if (empty > 0)
@@ -3056,9 +3295,8 @@ egg_asn1x_set_bits_as_ulong (GNode *node, gulong bits, guint n_bits)
data[(length - i) - 1] = (value >> i * 8) & 0xFF;
ab = g_slice_new0 (Abits);
- ab->bits = data;
+ ab->bits = egg_bytes_new_take (data, sizeof (gulong));
ab->n_bits = n_bits;
- ab->destroy = g_free;
anode_encode_tlv_and_enc (node, length + 1, anode_encoder_bit_string, ab, abits_destroy);
return TRUE;
@@ -3076,15 +3314,15 @@ egg_asn1x_get_time_as_long (GNode *node)
type = anode_def_type (node);
/* Time is often represented as a choice, so work than in here */
- if (type == TYPE_CHOICE) {
+ if (type == EGG_ASN1X_CHOICE) {
node = egg_asn1x_get_choice (node);
if (node == NULL)
return -1;
- g_return_val_if_fail (anode_def_type (node) == TYPE_TIME, -1);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_TIME, -1);
return egg_asn1x_get_time_as_long (node);
}
- g_return_val_if_fail (type == TYPE_TIME, -1);
+ g_return_val_if_fail (type == EGG_ASN1X_TIME, -1);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
@@ -3107,15 +3345,15 @@ egg_asn1x_get_time_as_date (GNode *node, GDate *date)
type = anode_def_type (node);
/* Time is often represented as a choice, so work than in here */
- if (type == TYPE_CHOICE) {
+ if (type == EGG_ASN1X_CHOICE) {
node = egg_asn1x_get_choice (node);
if (node == NULL)
return FALSE;
- g_return_val_if_fail (anode_def_type (node) == TYPE_TIME, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_TIME, FALSE);
return egg_asn1x_get_time_as_date (node, date);
}
- g_return_val_if_fail (type == TYPE_TIME, FALSE);
+ g_return_val_if_fail (type == EGG_ASN1X_TIME, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
@@ -3135,7 +3373,7 @@ egg_asn1x_get_oid_as_string (GNode *node)
Atlv *tlv;
g_return_val_if_fail (node, NULL);
- g_return_val_if_fail (anode_def_type (node) == TYPE_OBJECT_ID, NULL);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_OBJECT_ID, NULL);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
@@ -3155,7 +3393,7 @@ egg_asn1x_set_oid_as_string (GNode *node, const gchar *oid)
g_return_val_if_fail (oid, FALSE);
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_OBJECT_ID, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_OBJECT_ID, FALSE);
/* Encoding will always be shorter than string */
n_data = strlen (oid);
@@ -3166,7 +3404,7 @@ egg_asn1x_set_oid_as_string (GNode *node, const gchar *oid)
return FALSE;
}
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
@@ -3221,7 +3459,7 @@ egg_asn1x_set_choice (GNode *node, GNode *choice)
Anode *an;
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_CHOICE, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == EGG_ASN1X_CHOICE, FALSE);
/* One and only one of the children must be set */
for (child = node->children; child; child = child->next) {
@@ -3247,7 +3485,7 @@ egg_asn1x_set_choice (GNode *node, GNode *choice)
static gboolean
anode_parse_size (GNode *node, const gchar *text, gulong *value)
{
- ASN1_ARRAY_TYPE *def;
+ EggAsn1xDef *def;
gchar *end = NULL;
if (text == NULL) {
@@ -3257,7 +3495,7 @@ anode_parse_size (GNode *node, const gchar *text, gulong *value)
*value = G_MAXULONG;
return TRUE;
} else if (g_ascii_isalpha (text[0])) {
- def = anode_opt_lookup (node, TYPE_INTEGER, text);
+ def = anode_opt_lookup (node, EGG_ASN1X_INTEGER, text);
g_return_val_if_fail (def, FALSE);
return anode_parse_size (node, def->value, value);
}
@@ -3271,12 +3509,12 @@ anode_parse_size (GNode *node, const gchar *text, gulong *value)
static gboolean
anode_validate_size (GNode *node, gulong length)
{
- ASN1_ARRAY_TYPE *size;
+ EggAsn1xDef *size;
gulong value1 = 0;
gulong value2 = G_MAXULONG;
if (anode_def_flags (node) & FLAG_SIZE) {
- size = anode_opt_lookup (node, TYPE_SIZE, NULL);
+ size = anode_opt_lookup (node, EGG_ASN1X_SIZE, NULL);
g_return_val_if_fail (size, FALSE);
if (!anode_parse_size (node, size->value, &value1))
g_return_val_if_reached (FALSE);
@@ -3316,7 +3554,7 @@ anode_validate_integer (GNode *node, Atlv *tlv)
/* Look through the list of constants */
found = FALSE;
- constants = anode_opts_lookup (node, TYPE_CONSTANT, NULL);
+ constants = anode_opts_lookup (node, EGG_ASN1X_CONSTANT, NULL);
for (l = constants; l; l = g_list_next (l)) {
check = anode_def_value_as_ulong (l->data);
g_return_val_if_fail (check != G_MAXULONG, FALSE);
@@ -3458,7 +3696,7 @@ anode_validate_sequence_or_set (GNode *node,
/* Tags must be in ascending order */
tlv = anode_get_tlv_data (child);
- if (tlv && type == TYPE_SET) {
+ if (tlv && type == EGG_ASN1X_SET) {
if (count > 0 && tag > tlv->tag)
return anode_failure (node, "content must be in ascending order");
tag = tlv->tag;
@@ -3481,7 +3719,7 @@ anode_validate_sequence_or_set_of (GNode *node,
tag = 0;
count = 0;
- tlv = ptlv = NULL;
+ ptlv = NULL;
type = anode_def_type (node);
@@ -3499,7 +3737,7 @@ anode_validate_sequence_or_set_of (GNode *node,
return anode_failure (node, "invalid mismatched content");
/* Set of must be in ascending order */
- if (strict && type == TYPE_SET_OF &&
+ if (strict && type == EGG_ASN1X_SET_OF &&
ptlv != NULL && compare_tlvs (ptlv, tlv) > 0)
return anode_failure (node, "content must be in ascending order");
ptlv = tlv;
@@ -3533,38 +3771,38 @@ anode_validate_anything (GNode *node,
switch (type) {
/* The primitive value types */
- case TYPE_INTEGER:
+ case EGG_ASN1X_INTEGER:
return anode_validate_integer (node, tlv);
- case TYPE_ENUMERATED:
+ case EGG_ASN1X_ENUMERATED:
return anode_validate_enumerated (node, tlv);
- case TYPE_BOOLEAN:
+ case EGG_ASN1X_BOOLEAN:
return anode_validate_boolean (node, tlv);
- case TYPE_BIT_STRING:
+ case EGG_ASN1X_BIT_STRING:
return anode_validate_bit_string (node, tlv);
- case TYPE_OCTET_STRING:
+ case EGG_ASN1X_OCTET_STRING:
return anode_validate_string (node, tlv);
- case TYPE_OBJECT_ID:
+ case EGG_ASN1X_OBJECT_ID:
return anode_validate_object_id (node, tlv);
- case TYPE_NULL:
+ case EGG_ASN1X_NULL:
return anode_validate_null (node, tlv);
- case TYPE_GENERALSTRING:
+ case EGG_ASN1X_GENERALSTRING:
return anode_validate_string (node, tlv);
- case TYPE_TIME:
+ case EGG_ASN1X_TIME:
return anode_validate_time (node, tlv);
/* Transparent types */
- case TYPE_ANY:
+ case EGG_ASN1X_ANY:
return TRUE;
- case TYPE_CHOICE:
+ case EGG_ASN1X_CHOICE:
return anode_validate_choice (node, strict);
/* Structured types */
- case TYPE_SEQUENCE:
- case TYPE_SET:
+ case EGG_ASN1X_SEQUENCE:
+ case EGG_ASN1X_SET:
return anode_validate_sequence_or_set (node, strict);
- case TYPE_SEQUENCE_OF:
- case TYPE_SET_OF:
+ case EGG_ASN1X_SEQUENCE_OF:
+ case EGG_ASN1X_SET_OF:
return anode_validate_sequence_or_set_of (node, strict);
default:
@@ -3605,8 +3843,8 @@ compare_nodes_by_tag (gconstpointer a, gconstpointer b)
return (taga < tagb) ? -1 : 1;
}
-static const ASN1_ARRAY_TYPE*
-adef_next_sibling (const ASN1_ARRAY_TYPE *def)
+static const EggAsn1xDef *
+adef_next_sibling (const EggAsn1xDef *def)
{
int depth = 0;
@@ -3633,8 +3871,8 @@ adef_next_sibling (const ASN1_ARRAY_TYPE *def)
return def;
}
-static const ASN1_ARRAY_TYPE*
-adef_first_child (const ASN1_ARRAY_TYPE *def)
+static const EggAsn1xDef *
+adef_first_child (const EggAsn1xDef *def)
{
g_assert (def);
g_assert (def->value || def->type || def->name);
@@ -3647,10 +3885,12 @@ adef_first_child (const ASN1_ARRAY_TYPE *def)
return def;
}
-static const ASN1_ARRAY_TYPE*
-lookup_def_of_type (const ASN1_ARRAY_TYPE *defs, const gchar *name, gint type)
+static const EggAsn1xDef *
+lookup_def_of_type (const EggAsn1xDef *defs,
+ const gchar *name,
+ gint type)
{
- const ASN1_ARRAY_TYPE *def;
+ const EggAsn1xDef *def;
g_assert (defs);
g_assert (defs->value || defs->type || defs->name);
@@ -3666,8 +3906,8 @@ lookup_def_of_type (const ASN1_ARRAY_TYPE *defs, const gchar *name, gint type)
static gboolean
traverse_and_prepare (GNode *node, gpointer data)
{
- const ASN1_ARRAY_TYPE *defs = data;
- const ASN1_ARRAY_TYPE *def;
+ const EggAsn1xDef *defs = data;
+ const EggAsn1xDef *def;
const gchar *identifier;
Anode *an, *anj;
GNode *join = NULL;
@@ -3675,7 +3915,7 @@ traverse_and_prepare (GNode *node, gpointer data)
GList *list = NULL, *l;
/* A while, because the stuff we join, could also be an identifier */
- while (anode_def_type (node) == TYPE_IDENTIFIER) {
+ while (anode_def_type (node) == EGG_ASN1X_IDENTIFIER) {
an = node->data;
identifier = an->join ? an->join->value : an->def->value;
g_return_val_if_fail (identifier, TRUE);
@@ -3702,11 +3942,11 @@ traverse_and_prepare (GNode *node, gpointer data)
}
/* Lookup the max set size */
- if (anode_def_type (node) == TYPE_SIZE) {
+ if (anode_def_type (node) == EGG_ASN1X_SIZE) {
identifier = anode_def_name (node);
if (identifier && !g_str_equal (identifier, "MAX") &&
g_ascii_isalpha (identifier[0])) {
- def = lookup_def_of_type (defs, identifier, TYPE_INTEGER);
+ def = lookup_def_of_type (defs, identifier, EGG_ASN1X_INTEGER);
g_return_val_if_fail (def, TRUE);
anode_opt_add (node, def);
}
@@ -3737,7 +3977,7 @@ traverse_and_prepare (GNode *node, gpointer data)
}
/* Sort the children of any sets */
- if (anode_def_type (node) == TYPE_SET) {
+ if (anode_def_type (node) == EGG_ASN1X_SET) {
for (child = node->children; child; child = child->next)
list = g_list_prepend (list, child);
list = g_list_sort (list, compare_nodes_by_tag);
@@ -3753,12 +3993,14 @@ traverse_and_prepare (GNode *node, gpointer data)
return FALSE;
}
-static const ASN1_ARRAY_TYPE*
-match_oid_in_definition (const ASN1_ARRAY_TYPE *def, GHashTable *names,
- const gchar *match, const gchar **problem)
+static const EggAsn1xDef *
+match_oid_in_definition (const EggAsn1xDef *def,
+ GHashTable *names,
+ const gchar *match,
+ const gchar **problem)
{
- const ASN1_ARRAY_TYPE *result = NULL;
- const ASN1_ARRAY_TYPE *odef;
+ const EggAsn1xDef *result = NULL;
+ const EggAsn1xDef *odef;
const gchar *value;
GString *oid = NULL;
@@ -3767,7 +4009,7 @@ match_oid_in_definition (const ASN1_ARRAY_TYPE *def, GHashTable *names,
g_assert (names);
for (odef = adef_first_child (def); odef; odef = adef_next_sibling (odef)) {
- if ((odef->type & 0xFF) != TYPE_CONSTANT)
+ if ((odef->type & 0xFF) != EGG_ASN1X_CONSTANT)
continue;
g_return_val_if_fail (odef->value, NULL);
@@ -3804,11 +4046,12 @@ match_oid_in_definition (const ASN1_ARRAY_TYPE *def, GHashTable *names,
return result;
}
-static const ASN1_ARRAY_TYPE*
-match_oid_in_definitions (const ASN1_ARRAY_TYPE *defs, const gchar *match)
+static const EggAsn1xDef *
+match_oid_in_definitions (const EggAsn1xDef *defs,
+ const gchar *match)
{
- const ASN1_ARRAY_TYPE *def;
- const ASN1_ARRAY_TYPE *result;
+ const EggAsn1xDef *def;
+ const EggAsn1xDef *result;
GHashTable *names;
gboolean progress;
const gchar *problem;
@@ -3823,7 +4066,7 @@ match_oid_in_definitions (const ASN1_ARRAY_TYPE *defs, const gchar *match)
for (def = adef_first_child (defs); def; def = adef_next_sibling (def)) {
/* Only work with object ids, and ones with names */
- if ((def->type & 0xFF) != TYPE_OBJECT_ID || !def->name)
+ if ((def->type & 0xFF) != EGG_ASN1X_OBJECT_ID || !def->name)
continue;
/* If we've already seen this one, skip */
@@ -3848,10 +4091,32 @@ match_oid_in_definitions (const ASN1_ARRAY_TYPE *defs, const gchar *match)
return result;
}
+static gboolean
+is_oid_number (const gchar *p)
+{
+ gboolean must = TRUE;
+ gint i;
+
+ for (i = 0; p[i] != '\0'; i++) {
+ if (g_ascii_isdigit (p[i])) {
+ must = FALSE;
+ } else if (must) {
+ return FALSE;
+ } else {
+ if (p[i] != '.')
+ return FALSE;
+ must = TRUE;
+ }
+ }
+
+ return !must;
+}
+
GNode*
-egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *type)
+egg_asn1x_create (const EggAsn1xDef *defs,
+ const gchar *type)
{
- const ASN1_ARRAY_TYPE *def;
+ const EggAsn1xDef *def;
GNode *root, *parent, *node;
int flags;
@@ -3859,7 +4124,7 @@ egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *type)
g_return_val_if_fail (type, NULL);
/* An OID */
- if (strspn (type, "0123456789.") == strlen (type)) {
+ if (is_oid_number (type)) {
def = match_oid_in_definitions (defs, type);
/* An Identifier */
@@ -3912,15 +4177,17 @@ egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *type)
}
GNode*
-egg_asn1x_create_quark (const ASN1_ARRAY_TYPE *defs, GQuark type)
+egg_asn1x_create_quark (const EggAsn1xDef *defs,
+ GQuark type)
{
g_return_val_if_fail (type, NULL);
return egg_asn1x_create (defs, g_quark_to_string (type));
}
GNode*
-egg_asn1x_create_and_decode (const ASN1_ARRAY_TYPE *defs, const gchar *identifier,
- gconstpointer data, gsize n_data)
+egg_asn1x_create_and_decode (const EggAsn1xDef *defs,
+ const gchar *identifier,
+ EggBytes *data)
{
GNode *asn;
@@ -3930,7 +4197,7 @@ egg_asn1x_create_and_decode (const ASN1_ARRAY_TYPE *defs, const gchar *identifie
asn = egg_asn1x_create (defs, identifier);
g_return_val_if_fail (asn, NULL);
- if (!egg_asn1x_decode (asn, data, n_data)) {
+ if (!egg_asn1x_decode (asn, data)) {
egg_asn1x_destroy (asn);
return NULL;
}
@@ -3945,7 +4212,7 @@ egg_asn1x_create_and_decode (const ASN1_ARRAY_TYPE *defs, const gchar *identifie
static void
dump_append_type (GString *output, gint type)
{
- #define XX(x) if (type == TYPE_##x) g_string_append (output, #x " ")
+ #define XX(x) if (type == EGG_ASN1X_##x) g_string_append (output, #x " ")
XX(CONSTANT); XX(IDENTIFIER); XX(INTEGER); XX(BOOLEAN); XX(SEQUENCE); XX(BIT_STRING);
XX(OCTET_STRING); XX(TAG); XX(DEFAULT); XX(SIZE); XX(SEQUENCE_OF); XX(OBJECT_ID); XX(ANY);
XX(SET); XX(SET_OF); XX(DEFINITIONS); XX(TIME); XX(CHOICE); XX(IMPORTS); XX(NULL);
@@ -3969,7 +4236,7 @@ dump_append_flags (GString *output, gint flags)
static gboolean
traverse_and_dump (GNode *node, gpointer unused)
{
- ASN1_ARRAY_TYPE *def;
+ EggAsn1xDef *def;
guint i, depth;
GString *output;
gchar *string;
@@ -4048,7 +4315,7 @@ traverse_and_clear (GNode *node, gpointer unused)
anode_clear (node);
type = anode_def_type (node);
- if (type == TYPE_SET_OF || type == TYPE_SEQUENCE_OF) {
+ if (type == EGG_ASN1X_SET_OF || type == EGG_ASN1X_SEQUENCE_OF) {
/* The first 'real' child is the template */
child = node->children;
@@ -4156,16 +4423,17 @@ egg_asn1x_parse_time_utc (const gchar *time, gssize n_time)
*/
gssize
-egg_asn1x_element_length (gconstpointer data, gsize n_data)
+egg_asn1x_element_length (const guchar *data,
+ gsize n_data)
{
guchar cls;
int counter = 0;
int cb, len;
gulong tag;
- if (anode_decode_cls_tag (data, (const guchar*)data + n_data, &cls, &tag, &cb)) {
+ if (anode_decode_cls_tag (data, data + n_data, &cls, &tag, &cb)) {
counter += cb;
- len = anode_decode_length ((const guchar*)data + cb, (const guchar*)data + n_data, &cb);
+ len = anode_decode_length (data + cb, data + n_data, &cb);
counter += cb;
if (len >= 0) {
len += counter;
@@ -4178,7 +4446,9 @@ egg_asn1x_element_length (gconstpointer data, gsize n_data)
}
gconstpointer
-egg_asn1x_element_content (gconstpointer data, gsize n_data, gsize *n_content)
+egg_asn1x_element_content (const guchar *data,
+ gsize n_data,
+ gsize *n_content)
{
int counter = 0;
guchar cls;
diff --git a/egg/egg-asn1x.h b/egg/egg-asn1x.h
index 3f74655..50cdfe5 100644
--- a/egg/egg-asn1x.h
+++ b/egg/egg-asn1x.h
@@ -26,44 +26,65 @@
#include <glib.h>
+#include "egg-bytes.h"
+
#ifndef HAVE_EGG_ALLOCATOR
typedef void* (*EggAllocator) (void* p, gsize);
#define HAVE_EGG_ALLOCATOR
#endif
-typedef gboolean (*EggAsn1xEncoder) (gpointer data, guchar *buf, gsize n_buf);
-
-struct static_struct_asn;
-
-GNode* egg_asn1x_create (const struct static_struct_asn *defs,
+typedef struct _EggAsn1xDef EggAsn1xDef;
+
+typedef enum {
+ EGG_ASN1X_CONSTANT = 1,
+ EGG_ASN1X_IDENTIFIER = 2,
+ EGG_ASN1X_INTEGER = 3,
+ EGG_ASN1X_BOOLEAN = 4,
+ EGG_ASN1X_SEQUENCE = 5,
+ EGG_ASN1X_BIT_STRING = 6,
+ EGG_ASN1X_OCTET_STRING = 7,
+ EGG_ASN1X_TAG = 8,
+ EGG_ASN1X_DEFAULT = 9,
+ EGG_ASN1X_SIZE = 10,
+ EGG_ASN1X_SEQUENCE_OF = 11,
+ EGG_ASN1X_OBJECT_ID = 12,
+ EGG_ASN1X_ANY = 13,
+ EGG_ASN1X_SET = 14,
+ EGG_ASN1X_SET_OF = 15,
+ EGG_ASN1X_DEFINITIONS = 16,
+ EGG_ASN1X_TIME = 17,
+ EGG_ASN1X_CHOICE = 18,
+ EGG_ASN1X_IMPORTS = 19,
+ EGG_ASN1X_NULL = 20,
+ EGG_ASN1X_ENUMERATED = 21,
+ EGG_ASN1X_GENERALSTRING = 27
+} EggAsn1xType;
+
+GNode* egg_asn1x_create (const EggAsn1xDef *defs,
const gchar *type);
-GNode* egg_asn1x_create_quark (const struct static_struct_asn *defs,
+GNode* egg_asn1x_create_quark (const EggAsn1xDef *defs,
GQuark type);
-GNode* egg_asn1x_create_and_decode (const struct static_struct_asn *defs,
+GNode* egg_asn1x_create_and_decode (const EggAsn1xDef *defs,
const gchar *type,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
void egg_asn1x_dump (GNode *asn);
void egg_asn1x_clear (GNode *asn);
gboolean egg_asn1x_decode (GNode *asn,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
gboolean egg_asn1x_decode_no_validate (GNode *asn,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
gboolean egg_asn1x_validate (GNode *asn,
gboolean strict);
-gpointer egg_asn1x_encode (GNode *asn,
- EggAllocator allocator,
- gsize *n_data);
+EggBytes * egg_asn1x_encode (GNode *asn,
+ EggAllocator allocator);
const gchar* egg_asn1x_message (GNode *asn);
@@ -72,6 +93,8 @@ GNode* egg_asn1x_node (GNode *asn,
const gchar* egg_asn1x_name (GNode *asn);
+EggAsn1xType egg_asn1x_type (GNode *asn);
+
guint egg_asn1x_count (GNode *node);
GNode* egg_asn1x_append (GNode *node);
@@ -102,38 +125,28 @@ gboolean egg_asn1x_get_integer_as_ulong (GNode *node,
gboolean egg_asn1x_set_integer_as_ulong (GNode *node,
gulong value);
-gconstpointer egg_asn1x_get_integer_as_raw (GNode *node,
- gsize *n_data);
+EggBytes * egg_asn1x_get_integer_as_raw (GNode *node);
-gboolean egg_asn1x_set_integer_as_raw (GNode *node,
- gconstpointer data,
- gsize n_data,
- GDestroyNotify destroy);
+void egg_asn1x_set_integer_as_raw (GNode *node,
+ EggBytes *value);
-gconstpointer egg_asn1x_get_integer_as_usg (GNode *node,
- gsize *n_data);
+void egg_asn1x_take_integer_as_raw (GNode *node,
+ EggBytes *value);
-gboolean egg_asn1x_set_integer_as_usg (GNode *node,
- gconstpointer data,
- gsize n_data,
- GDestroyNotify destroy);
+EggBytes * egg_asn1x_get_integer_as_usg (GNode *node);
-gconstpointer egg_asn1x_get_raw_value (GNode *node,
- gsize *n_content);
+void egg_asn1x_set_integer_as_usg (GNode *node,
+ EggBytes *value);
-gboolean egg_asn1x_set_raw_value (GNode *node,
- gsize length,
- EggAsn1xEncoder encoder,
- gpointer user_data,
- GDestroyNotify destroy);
+void egg_asn1x_take_integer_as_usg (GNode *node,
+ EggBytes *value);
-gconstpointer egg_asn1x_get_raw_element (GNode *node,
- gsize *n_data);
+EggBytes * egg_asn1x_get_raw_value (GNode *node);
-gboolean egg_asn1x_set_raw_element (GNode *node,
- gpointer user_data,
- gsize n_data,
- GDestroyNotify destroy);
+EggBytes * egg_asn1x_get_element_raw (GNode *node);
+
+gboolean egg_asn1x_set_element_raw (GNode *node,
+ EggBytes *value);
guchar* egg_asn1x_get_string_as_raw (GNode *node,
EggAllocator allocator,
@@ -144,14 +157,21 @@ gboolean egg_asn1x_set_string_as_raw (GNode *node,
gsize n_data,
GDestroyNotify destroy);
-guchar* egg_asn1x_get_bits_as_raw (GNode *node,
- EggAllocator allocator,
+EggBytes * egg_asn1x_get_string_as_bytes (GNode *node);
+
+gboolean egg_asn1x_set_string_as_bytes (GNode *node,
+ EggBytes *data);
+
+EggBytes * egg_asn1x_get_bits_as_raw (GNode *node,
guint *n_bits);
-gboolean egg_asn1x_set_bits_as_raw (GNode *node,
- guchar *data,
- guint n_bits,
- GDestroyNotify destroy);
+void egg_asn1x_set_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits);
+
+void egg_asn1x_take_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits);
gboolean egg_asn1x_get_bits_as_ulong (GNode *node,
gulong *value,
@@ -161,7 +181,7 @@ gboolean egg_asn1x_set_bits_as_ulong (GNode *node,
gulong value,
guint n_bits);
-gchar* egg_asn1x_get_string_as_utf8 (GNode *node,
+gchar * egg_asn1x_get_string_as_utf8 (GNode *node,
EggAllocator allocator);
gboolean egg_asn1x_set_string_as_utf8 (GNode *node,
@@ -186,7 +206,7 @@ GQuark egg_asn1x_get_oid_as_quark (GNode *node);
gboolean egg_asn1x_set_oid_as_quark (GNode *node,
GQuark oid);
-gchar* egg_asn1x_get_oid_as_string (GNode *node);
+gchar * egg_asn1x_get_oid_as_string (GNode *node);
gboolean egg_asn1x_set_oid_as_string (GNode *node,
const gchar *oid);
@@ -199,10 +219,10 @@ glong egg_asn1x_parse_time_general (const gchar *time,
glong egg_asn1x_parse_time_utc (const gchar *time,
gssize n_time);
-gssize egg_asn1x_element_length (gconstpointer data,
+gssize egg_asn1x_element_length (const guchar *data,
gsize n_data);
-gconstpointer egg_asn1x_element_content (gconstpointer data,
+gconstpointer egg_asn1x_element_content (const guchar *data,
gsize n_data,
gsize *n_content);
diff --git a/egg/egg-bytes.c b/egg/egg-bytes.c
new file mode 100644
index 0000000..8f58da2
--- /dev/null
+++ b/egg/egg-bytes.c
@@ -0,0 +1,454 @@
+/*
+ * Copyright  2009, 2010 Codethink Limited
+ *
+ * This library 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 of the licence, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "config.h"
+
+#include "egg-bytes.h"
+
+#include <glib.h>
+
+#include <string.h>
+
+struct _EggBytes
+{
+ gconstpointer data;
+ gsize size;
+ gint ref_count;
+ GDestroyNotify free_func;
+ gpointer user_data;
+};
+
+/**
+ * egg_bytes_new:
+ * @data: (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ *
+ * Creates a new #EggBytes from @data.
+ *
+ * @data is copied.
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new (gconstpointer data,
+ gsize size)
+{
+ return egg_bytes_new_take (g_memdup (data, size), size);
+}
+
+/**
+ * egg_bytes_new_take:
+ * @data: (transfer full) (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ *
+ * Creates a new #EggBytes from @data.
+ *
+ * After this call, @data belongs to the bytes and may no longer be
+ * modified by the caller. g_free() will be called on @data when the
+ * bytes is no longer in use. Because of this @data must have been created by
+ * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many
+ * functions that wrap these calls (such as g_new(), g_strdup(), etc).
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_take (gpointer data,
+ gsize size)
+{
+ return egg_bytes_new_with_free_func (data, size, g_free, data);
+}
+
+
+/**
+ * egg_bytes_new_static:
+ * @data: (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ *
+ * Creates a new #EggBytes from static data.
+ *
+ * @data must be static (ie: never modified or freed).
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_static (gconstpointer data,
+ gsize size)
+{
+ return egg_bytes_new_with_free_func (data, size, NULL, NULL);
+}
+
+/**
+ * egg_bytes_new_with_free_func:
+ * @data: (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ * @free_func: the function to call to release the data
+ * @user_data: data to pass to @free_func
+ *
+ * Creates a #EggBytes from @data.
+ *
+ * When the last reference is dropped, @free_func will be called with the
+ * @user_data argument.
+ *
+ * @data must not be modified after this call is made until @free_func has
+ * been called to indicate that the bytes is no longer in use.
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_with_free_func (gconstpointer data,
+ gsize size,
+ GDestroyNotify free_func,
+ gpointer user_data)
+{
+ EggBytes *bytes;
+
+ bytes = g_slice_new (EggBytes);
+ bytes->data = data;
+ bytes->size = size;
+ bytes->free_func = free_func;
+ bytes->user_data = user_data;
+ bytes->ref_count = 1;
+
+ return (EggBytes *)bytes;
+}
+
+/**
+ * egg_bytes_new_from_bytes:
+ * @bytes: a #EggBytes
+ * @offset: offset which subsection starts at
+ * @length: length of subsucsection
+ *
+ * Creates a #EggBytes which is a subsection of another #EggBytes.
+ *
+ * A reference to @bytes will be held by the newly created #EggBytes until
+ * the byte data is no longer needed.
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_from_bytes (EggBytes *bytes,
+ goffset offset,
+ gsize length)
+{
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (offset <= bytes->size, NULL);
+ g_return_val_if_fail (offset + length <= bytes->size, NULL);
+
+ return egg_bytes_new_with_free_func ((gchar *)bytes->data + offset, length,
+ egg_bytes_unref, egg_bytes_ref (bytes));
+}
+
+/**
+ * egg_bytes_get_data:
+ * @bytes: a #EggBytes
+ *
+ * Get the byte data in the #EggBytes. This data should not be modified.
+ *
+ * This function will always return the same pointer for a given #EggBytes.
+ *
+ * Returns: a pointer to the byte data
+ *
+ * Since: 2.32
+ */
+gconstpointer
+egg_bytes_get_data (EggBytes *bytes)
+{
+ g_return_val_if_fail (bytes != NULL, NULL);
+ return bytes->data;
+}
+
+/**
+ * egg_bytes_get_size:
+ * @bytes: a #EggBytes
+ *
+ * Get the size of the byte data in the #EggBytes.
+ *
+ * This function will always return the same value for a given #EggBytes.
+ *
+ * Returns: the size
+ *
+ * Since: 2.32
+ */
+gsize
+egg_bytes_get_size (EggBytes *bytes)
+{
+ g_return_val_if_fail (bytes != NULL, 0);
+ return bytes->size;
+}
+
+
+/**
+ * egg_bytes_ref:
+ * @bytes: a #EggBytes
+ *
+ * Increase the reference count on @bytes.
+ *
+ * Returns: (transfer full): the #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_ref (EggBytes *bytes)
+{
+ g_return_val_if_fail (bytes != NULL, NULL);
+
+ g_atomic_int_inc (&bytes->ref_count);
+
+ return bytes;
+}
+
+/**
+ * egg_bytes_unref:
+ * @bytes: (transfer full) (type GLib.Bytes): a #EggBytes
+ *
+ * Releases a reference on @bytes. This may result in the bytes being
+ * freed.
+ *
+ * Since: 2.32
+ */
+void
+egg_bytes_unref (gpointer bytes)
+{
+ EggBytes *bytes_ = bytes;
+
+ g_return_if_fail (bytes_ != NULL);
+
+ if (g_atomic_int_dec_and_test (&bytes_->ref_count))
+ {
+ if (bytes_->free_func != NULL)
+ bytes_->free_func (bytes_->user_data);
+ g_slice_free (EggBytes, bytes);
+ }
+}
+
+/**
+ * egg_bytes_equal:
+ * @bytes1: (type GLib.Bytes): a pointer to a #EggBytes
+ * @bytes2: (type GLib.Bytes): a pointer to a #EggBytes to compare with @bytes1
+ *
+ * Compares the two #EggBytes values being pointed to and returns
+ * %TRUE if they are equal.
+ *
+ * This function can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using non-%NULL #EggBytes pointers as keys in a #GHashTable.
+ *
+ * Returns: %TRUE if the two keys match.
+ *
+ * Since: 2.32
+ */
+gboolean
+egg_bytes_equal (gconstpointer bytes1,
+ gconstpointer bytes2)
+{
+ const EggBytes *b1 = bytes1;
+ const EggBytes *b2 = bytes2;
+
+ g_return_val_if_fail (bytes1 != NULL, FALSE);
+ g_return_val_if_fail (bytes2 != NULL, FALSE);
+
+ return b1->size == b2->size &&
+ memcmp (b1->data, b2->data, b1->size) == 0;
+}
+
+/**
+ * egg_bytes_hash:
+ * @bytes: (type GLib.Bytes): a pointer to a #EggBytes key
+ *
+ * Creates an integer hash code for the byte data in the #EggBytes.
+ *
+ * This function can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using non-%NULL #EggBytes pointers as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key.
+ *
+ * Since: 2.32
+ */
+guint
+egg_bytes_hash (gconstpointer bytes)
+{
+ const EggBytes *a = bytes;
+ const signed char *p, *e;
+ guint32 h = 5381;
+
+ g_return_val_if_fail (bytes != NULL, 0);
+
+ for (p = (signed char *)a->data, e = (signed char *)a->data + a->size; p != e; p++)
+ h = (h << 5) + h + *p;
+
+ return h;
+}
+
+/**
+ * egg_bytes_compare:
+ * @bytes1: (type GLib.Bytes): a pointer to a #EggBytes
+ * @bytes2: (type GLib.Bytes): a pointer to a #EggBytes to compare with @bytes1
+ *
+ * Compares the two #EggBytes values.
+ *
+ * This function can be passed to g_tree_new() when using non-%NULL #EggBytes
+ * pointers as keys in a #GTree.
+ *
+ * Returns: a negative value if bytes2 is lesser, a positive value if bytes2 is
+ * greater, and zero if bytes2 is equal to bytes1
+ *
+ * Since: 2.32
+ */
+gint
+egg_bytes_compare (gconstpointer bytes1,
+ gconstpointer bytes2)
+{
+ const EggBytes *b1 = bytes1;
+ const EggBytes *b2 = bytes2;
+ gint ret;
+
+ g_return_val_if_fail (bytes1 != NULL, 0);
+ g_return_val_if_fail (bytes2 != NULL, 0);
+
+ ret = memcmp (b1->data, b2->data, MIN (b1->size, b2->size));
+ if (ret == 0 && b1->size != b2->size)
+ ret = b1->size < b2->size ? -1 : 1;
+ return ret;
+}
+
+/**
+ * egg_bytes_unref_to_array:
+ * @bytes: (transfer full): a #EggBytes
+ *
+ * Unreferences the bytes, and returns a new mutable #GByteArray containing
+ * the same byte data.
+ *
+ * As an optimization, the byte data is transferred to the array without copying
+ * if: this was the last reference to bytes and bytes was created with
+ * egg_bytes_new(), egg_bytes_new_take() or g_byte_array_free_to_bytes(). In all
+ * other cases the data is copied.
+ *
+ * Returns: (transfer full): a new mutable #GByteArray containing the same byte data
+ *
+ * Since: 2.32
+ */
+GByteArray *
+egg_bytes_unref_to_array (EggBytes *bytes)
+{
+ GByteArray *result = NULL;
+#if 0
+ gpointer data;
+ gsize size;
+#endif
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+
+#if 0
+ data = egg_bytes_try_steal_and_unref (bytes, NULL, &size);
+ if (data != NULL)
+ {
+ /*
+ * Optimal path: if this is was the last reference, then we can have
+ * the GByteArray assume the data from this EggBytes without copying.
+ */
+ result = g_byte_array_new_take (data, size);
+ }
+ else
+#endif
+ {
+ /*
+ * Copy: Non g_malloc (or compatible) allocator, or static memory,
+ * so we have to copy, and then unref.
+ */
+ result = g_byte_array_append (g_byte_array_new (), bytes->data, bytes->size);
+ egg_bytes_unref (bytes);
+ }
+
+ return result;
+}
+
+/*
+ * The behavior of this function with regards to references cannot be easily
+ * modeled by most gobject-introspection consumers, so we use (skip).
+ */
+
+/**
+ * egg_bytes_try_steal_and_unref: (skip)
+ * @bytes: a #EggBytes
+ * @free_func: the function data is freed with, or %NULL for default
+ * @size: location to return the length of the data
+ *
+ * This is an advanced function, and seldom used.
+ *
+ * Try to take ownership of the data in the byte array. This is only successful
+ * if this is the last reference and @free_func matches the function that would
+ * have been used to free the data. This is to demonstrate that the caller
+ * is aware of the how the data in the #EggBytes was allocated. If %NULL is passed
+ * for @free_func this represents the standard Glib allocation routines.
+ *
+ * You should use %NULL instead of passing g_free() for @free_func. This is
+ * because the actual address of g_free() varies depending on how the calling
+ * application and library was linked.
+ *
+ * If the attempt to take ownership of the byte data is successful according to
+ * the above criteria, then the data is returned and @size is set to the length
+ * of the data. The #EggBytes is unreferenced and is no longer valid.
+ *
+ * If the attempt to take ownership of the byte data is unsuccessful, %NULL is
+ * returned. The #EggBytes is not unreferenced, and the caller must unreference
+ * the #EggBytes elsewhere.
+ *
+ * It is always incorrect to ignore the return value from this function.
+ *
+ * Returns: the stolen data, or %NULL if attempt failed
+ *
+ * Since: 2.32
+ */
+gpointer
+egg_bytes_try_steal_and_unref (EggBytes *bytes,
+ GDestroyNotify free_func,
+ gsize *size)
+{
+ gpointer result;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (size != NULL, NULL);
+
+ if (free_func == NULL)
+ free_func = g_free;
+ if (bytes->free_func != free_func)
+ return NULL;
+
+ /* Are we the only reference? */
+ if (g_atomic_int_get (&bytes->ref_count) == 1)
+ {
+ *size = bytes->size;
+ result = (gpointer)bytes->data;
+ g_slice_free (EggBytes, bytes);
+ return result;
+ }
+
+ return NULL;
+}
diff --git a/egg/egg-bytes.h b/egg/egg-bytes.h
new file mode 100644
index 0000000..d25432f
--- /dev/null
+++ b/egg/egg-bytes.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright  2009, 2010 Codethink Limited
+ * Copyright  2011 Collabora Ltd.
+ *
+ * This library 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 of the licence, or (at your option) any later version.
+ *
+ * This library 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 library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ * Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __EGG_BYTES_H__
+#define __EGG_BYTES_H__
+
+#include <glib.h>
+
+/**
+ * EggBytes:
+ *
+ * A simple refcounted data type representing an immutable byte sequence
+ * from an unspecified origin.
+ *
+ * The purpose of a #EggBytes is to keep the memory region that it holds
+ * alive for as long as anyone holds a reference to the bytes. When
+ * the last reference count is dropped, the memory is released. Multiple
+ * unrelated callers can use byte data in the #EggBytes without coordinating
+ * their activities, resting assured that the byte data will not change or
+ * move while they hold a reference.
+ *
+ * A #EggBytes can come from many different origins that may have
+ * different procedures for freeing the memory region. Examples are
+ * memory from g_malloc(), from memory slices, from a #GMappedFile or
+ * memory from other allocators.
+ *
+ * #EggBytes work well as keys in #GHashTable. Use egg_bytes_equal() and
+ * egg_bytes_hash() as parameters to g_hash_table_new() or g_hash_table_new_full().
+ * #EggBytes can also be used as keys in a #GTree by passing the egg_bytes_compare()
+ * function to g_tree_new().
+ *
+ * The data pointed to by this bytes must not be modified. For a mutable
+ * array of bytes see #GByteArray. Use egg_bytes_unref_to_array() to create a
+ * mutable array for a #EggBytes sequence. To create an immutable #EggBytes from
+ * a mutable #GByteArray, use the g_byte_array_free_to_bytes() function.
+ *
+ * Since: 2.32
+ **/
+
+typedef struct _EggBytes EggBytes;
+
+EggBytes * egg_bytes_new (gconstpointer data,
+ gsize size);
+
+EggBytes * egg_bytes_new_take (gpointer data,
+ gsize size);
+
+EggBytes * egg_bytes_new_static (gconstpointer data,
+ gsize size);
+
+EggBytes * egg_bytes_new_with_free_func (gconstpointer data,
+ gsize size,
+ GDestroyNotify free_func,
+ gpointer user_data);
+
+EggBytes * egg_bytes_new_from_bytes (EggBytes *bytes,
+ goffset offset,
+ gsize length);
+
+gconstpointer egg_bytes_get_data (EggBytes *bytes);
+
+gsize egg_bytes_get_size (EggBytes *bytes);
+
+EggBytes * egg_bytes_ref (EggBytes *bytes);
+
+void egg_bytes_unref (gpointer bytes);
+
+GByteArray * egg_bytes_unref_to_array (EggBytes *bytes);
+
+gpointer egg_bytes_try_steal_and_unref (EggBytes *bytes,
+ GDestroyNotify free_func,
+ gsize *size);
+
+guint egg_bytes_hash (gconstpointer bytes);
+
+gboolean egg_bytes_equal (gconstpointer bytes1,
+ gconstpointer bytes2);
+
+gint egg_bytes_compare (gconstpointer bytes1,
+ gconstpointer bytes2);
+
+#endif /* __EGG_BYTES_H__ */
diff --git a/egg/egg-dn.c b/egg/egg-dn.c
index b41844e..2ec5751 100644
--- a/egg/egg-dn.c
+++ b/egg/egg-dn.c
@@ -33,13 +33,15 @@
static const char HEXC[] = "0123456789ABCDEF";
static gchar*
-dn_print_hex_value (const guchar *data, gsize len)
+dn_print_hex_value (EggBytes *val)
{
- GString *result = g_string_sized_new (len * 2 + 1);
+ const gchar *data = egg_bytes_get_data (val);
+ gsize size = egg_bytes_get_size (val);
+ GString *result = g_string_sized_new (size * 2 + 1);
gsize i;
g_string_append_c (result, '#');
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < size; ++i) {
g_string_append_c (result, HEXC[data[i] >> 4 & 0xf]);
g_string_append_c (result, HEXC[data[i] & 0xf]);
}
@@ -48,20 +50,22 @@ dn_print_hex_value (const guchar *data, gsize len)
}
static gchar*
-dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize len)
+dn_print_oid_value_parsed (GQuark oid,
+ guint flags,
+ EggBytes *val)
{
GNode *asn1, *node;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
+ const gchar *data;
+ gsize size;
gchar *result;
- g_assert (data);
- g_assert (len);
+ g_assert (val != NULL);
asn1 = egg_asn1x_create_quark (pkix_asn1_tab, oid);
g_return_val_if_fail (asn1, NULL);
- if (!egg_asn1x_decode (asn1, data, len)) {
+ if (!egg_asn1x_decode (asn1, val)) {
g_message ("couldn't decode value for OID: %s: %s",
g_quark_to_string (oid), egg_asn1x_message (asn1));
egg_asn1x_destroy (asn1);
@@ -77,7 +81,9 @@ dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize le
else
node = asn1;
- value = egg_asn1x_get_raw_value (node, &n_value);
+ value = egg_asn1x_get_raw_value (node);
+ data = egg_bytes_get_data (value);
+ size = egg_bytes_get_size (value);
/*
* Now we make sure it's UTF-8.
@@ -87,33 +93,35 @@ dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize le
g_message ("couldn't read value for OID: %s", g_quark_to_string (oid));
result = NULL;
- } else if (!g_utf8_validate (value, n_value, NULL)) {
- result = dn_print_hex_value ((guchar*)value, n_value);
+ } else if (!g_utf8_validate (data, size, NULL)) {
+ result = dn_print_hex_value (value);
} else {
- result = g_strndup (value, n_value);
+ result = g_strndup (data, size);
}
+ egg_bytes_unref (value);
egg_asn1x_destroy (asn1);
return result;
}
static gchar*
-dn_print_oid_value (GQuark oid, guint flags, const guchar *data, gsize len)
+dn_print_oid_value (GQuark oid,
+ guint flags,
+ EggBytes *val)
{
gchar *value;
- g_assert (data);
- g_assert (len);
+ g_assert (val != NULL);
if (flags & EGG_OID_PRINTABLE) {
- value = dn_print_oid_value_parsed (oid, flags, data, len);
+ value = dn_print_oid_value_parsed (oid, flags, val);
if (value != NULL)
return value;
}
- return dn_print_hex_value (data, len);
+ return dn_print_hex_value (val);
}
static gchar*
@@ -122,8 +130,7 @@ dn_parse_rdn (GNode *asn)
const gchar *name;
guint flags;
GQuark oid;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
gchar *display;
gchar *result;
@@ -135,14 +142,15 @@ dn_parse_rdn (GNode *asn)
flags = egg_oid_get_flags (oid);
name = egg_oid_get_name (oid);
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "value", NULL), &n_value);
+ value = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "value", NULL));
g_return_val_if_fail (value, NULL);
- display = dn_print_oid_value (oid, flags, value, n_value);
+ display = dn_print_oid_value (oid, flags, value);
result = g_strconcat ((flags & EGG_OID_PRINTABLE) ? name : g_quark_to_string (oid),
"=", display, NULL);
g_free (display);
+ egg_bytes_unref (value);
return result;
}
@@ -193,11 +201,11 @@ egg_dn_read_part (GNode *asn, const gchar *match)
{
gboolean done = FALSE;
const gchar *name;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
GNode *node;
GQuark oid;
gint i, j;
+ gchar *result;
g_return_val_if_fail (asn, NULL);
g_return_val_if_fail (match, NULL);
@@ -226,10 +234,12 @@ egg_dn_read_part (GNode *asn, const gchar *match)
node = egg_asn1x_node (asn, i, j, "value", NULL);
g_return_val_if_fail (node, NULL);
- value = egg_asn1x_get_raw_element (node, &n_value);
+ value = egg_asn1x_get_element_raw (node);
g_return_val_if_fail (value, NULL);
- return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
+ result = dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
+ egg_bytes_unref (value);
+ return result;
}
}
@@ -241,8 +251,7 @@ egg_dn_parse (GNode *asn, EggDnCallback callback, gpointer user_data)
{
gboolean done = FALSE;
GNode *node;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
GQuark oid;
guint i, j;
@@ -271,21 +280,109 @@ egg_dn_parse (GNode *asn, EggDnCallback callback, gpointer user_data)
break;
}
- value = egg_asn1x_get_raw_element (node, &n_value);
+ value = egg_asn1x_get_element_raw (node);
if (callback)
- (callback) (i, oid, value, n_value, user_data);
+ (callback) (i, oid, value, user_data);
+
+ egg_bytes_unref (value);
}
}
return i > 1;
}
-gchar*
-egg_dn_print_value (GQuark oid, const guchar *value, gsize n_value)
+gchar *
+egg_dn_print_value (GQuark oid,
+ EggBytes *value)
{
- g_return_val_if_fail (oid, NULL);
- g_return_val_if_fail (value || !n_value, NULL);
+ g_return_val_if_fail (oid != 0, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
+
+ return dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
+}
+
+static gboolean
+is_ascii_string (const gchar *string)
+{
+ const gchar *p = string;
+
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ for (p = string; *p != '\0'; p++) {
+ if (!g_ascii_isspace (*p) && *p < ' ')
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+is_printable_string (const gchar *string)
+{
+ const gchar *p = string;
+
+ g_return_val_if_fail (string != NULL, FALSE);
+
+ for (p = string; *p != '\0'; p++) {
+ if (!g_ascii_isalnum (*p) && !strchr (" '()+,-./:=?", *p))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void
+egg_dn_add_string_part (GNode *asn,
+ GQuark oid,
+ const gchar *string)
+{
+ EggBytes *bytes;
+ GNode *node;
+ GNode *value;
+ GNode *val;
+ guint flags;
+
+ g_return_if_fail (asn != NULL);
+ g_return_if_fail (oid != 0);
+ g_return_if_fail (string != NULL);
+
+ flags = egg_oid_get_flags (oid);
+ g_return_if_fail (flags & EGG_OID_PRINTABLE);
+
+ /* Add the RelativeDistinguishedName */
+ node = egg_asn1x_append (asn);
+
+ /* Add the AttributeTypeAndValue */
+ node = egg_asn1x_append (node);
+
+ egg_asn1x_set_oid_as_quark (egg_asn1x_node (node, "type", NULL), oid);
+
+ value = egg_asn1x_create_quark (pkix_asn1_tab, oid);
+
+ if (egg_asn1x_type (value) == EGG_ASN1X_CHOICE) {
+ if (is_printable_string (string))
+ val = egg_asn1x_node (value, "printableString", NULL);
+ else if (is_ascii_string (string))
+ val = egg_asn1x_node (value, "ia5String", NULL);
+ else
+ val = egg_asn1x_node (value, "utf8String", NULL);
+ egg_asn1x_set_choice (value, val);
+ } else {
+ val = value;
+ }
+
+ egg_asn1x_set_string_as_utf8 (val, g_strdup (string), g_free);
+
+ bytes = egg_asn1x_encode (value, NULL);
+ if (bytes == NULL) {
+ g_warning ("couldn't build dn string value: %s", egg_asn1x_message (value));
+ return;
+ }
+
+ if (!egg_asn1x_set_element_raw (egg_asn1x_node (node, "value", NULL), bytes))
+ g_return_if_reached ();
- return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
+ egg_asn1x_destroy (value);
+ egg_bytes_unref (bytes);
}
diff --git a/egg/egg-dn.h b/egg/egg-dn.h
index 96fe5ff..08251ec 100644
--- a/egg/egg-dn.h
+++ b/egg/egg-dn.h
@@ -26,6 +26,8 @@
#include <glib.h>
+#include "egg/egg-bytes.h"
+
gchar* egg_dn_read (GNode *node);
gchar* egg_dn_read_part (GNode *node,
@@ -33,8 +35,7 @@ gchar* egg_dn_read_part (GNode *node,
typedef void (*EggDnCallback) (guint index,
GQuark oid,
- const guchar *value,
- gsize n_value,
+ EggBytes *value,
gpointer user_data);
gboolean egg_dn_parse (GNode *node,
@@ -42,7 +43,10 @@ gboolean egg_dn_parse (GNode *node,
gpointer user_data);
gchar* egg_dn_print_value (GQuark oid,
- const guchar *value,
- gsize n_value);
+ EggBytes *value);
+
+void egg_dn_add_string_part (GNode *node,
+ GQuark oid,
+ const gchar *string);
#endif /* EGG_DN_H_ */
diff --git a/egg/egg-openssl.c b/egg/egg-openssl.c
index 352451f..2433f07 100644
--- a/egg/egg-openssl.c
+++ b/egg/egg-openssl.c
@@ -55,8 +55,8 @@ static const struct {
/* DES-EDE-CFB1 */
/* DES-EDE-CFB8 */
/* DES-EDE-OFB */
- /* DES-EDE3 */
- { "DES-EDE3-ECB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
+ /* DES-EDE3 */
+ { "DES-EDE3-ECB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
{ "DES-EDE3-CFB64", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
{ "DES-EDE3-CFB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
/* DES-EDE3-CFB1 */
@@ -87,7 +87,7 @@ static const struct {
{ "CAST5-CFB64", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
{ "CAST5-CFB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
{ "CAST5-OFB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
- /* RC5-32-12-16-CBC */
+ /* RC5-32-12-16-CBC */
/* RC5-32-12-16-ECB */
/* RC5-32-12-16-CFB64 RC5-32-12-16-CFB */
/* RC5-32-12-16-OFB */
@@ -150,7 +150,7 @@ egg_openssl_parse_algo (const char *name, int *mode)
openssl_quarks[i] = g_quark_from_static_string (openssl_algos[i].desc);
g_once_init_leave (&openssl_quarks_inited, 1);
}
-
+
q = g_quark_try_string (name);
if (q) {
for (i = 0; i < G_N_ELEMENTS(openssl_algos); ++i) {
@@ -160,7 +160,7 @@ egg_openssl_parse_algo (const char *name, int *mode)
}
}
}
-
+
return 0;
}
@@ -171,16 +171,16 @@ parse_dekinfo (const gchar *dek, int *algo, int *mode, guchar **iv)
gchar **parts = NULL;
gcry_error_t gcry;
gsize ivlen, len;
-
+
parts = g_strsplit (dek, ",", 2);
- if (!parts || !parts[0] || !parts[1])
+ if (!parts || !parts[0] || !parts[1])
goto done;
-
+
/* Parse the algorithm name */
*algo = egg_openssl_parse_algo (parts[0], mode);
if (!*algo)
goto done;
-
+
/* Make sure this is usable */
gcry = gcry_cipher_test_algo (*algo);
if (gcry)
@@ -188,13 +188,13 @@ parse_dekinfo (const gchar *dek, int *algo, int *mode, guchar **iv)
/* Parse the IV */
ivlen = gcry_cipher_get_algo_blklen (*algo);
-
+
*iv = egg_hex_decode (parts[1], strlen(parts[1]), &len);
if (!*iv || ivlen != len) {
g_free (*iv);
goto done;
}
-
+
success = TRUE;
done:
@@ -202,10 +202,12 @@ done:
return success;
}
-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)
+guchar *
+egg_openssl_decrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_decrypted)
{
gcry_cipher_hd_t ch;
guchar *key = NULL;
@@ -213,54 +215,58 @@ egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
int gcry, ivlen;
int algo = 0;
int mode = 0;
-
+ guchar *decrypted;
+
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
return FALSE;
-
+
ivlen = gcry_cipher_get_algo_blklen (algo);
/* We assume the iv is at least as long as at 8 byte salt */
g_return_val_if_fail (ivlen >= 8, FALSE);
-
+
/* IV is already set from the DEK info */
- if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
- n_password, iv, 8, 1, &key, NULL)) {
+ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
+ n_password, iv, 8, 1, &key, NULL)) {
g_free (iv);
- return FALSE;
+ return NULL;
}
-
- /* TODO: Use secure memory */
+
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, FALSE);
-
+ g_return_val_if_fail (!gcry, NULL);
+
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
g_free (iv);
-
+
/* Allocate output area */
- *n_decrypted = n_data;
- *decrypted = egg_secure_alloc (n_data);
+ *n_decrypted = egg_bytes_get_size (data);
+ decrypted = egg_secure_alloc (*n_decrypted);
- gcry = gcry_cipher_decrypt (ch, *decrypted, *n_decrypted, (void*)data, n_data);
+ gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
if (gcry) {
- egg_secure_free (*decrypted);
- g_return_val_if_reached (FALSE);
+ egg_secure_free (decrypted);
+ g_return_val_if_reached (NULL);
}
-
+
gcry_cipher_close (ch);
-
- return TRUE;
+
+ return decrypted;
}
-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)
+guchar *
+egg_openssl_encrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_encrypted)
{
gsize n_overflow, n_batch, n_padding;
gcry_cipher_hd_t ch;
@@ -270,65 +276,71 @@ egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
int gcry, ivlen;
int algo = 0;
int mode = 0;
-
+ gsize n_data;
+ guchar *encrypted;
+ const guchar *dat;
+
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
- g_return_val_if_reached (FALSE);
-
+ g_return_val_if_reached (NULL);
+
ivlen = gcry_cipher_get_algo_blklen (algo);
/* We assume the iv is at least as long as at 8 byte salt */
- g_return_val_if_fail (ivlen >= 8, FALSE);
-
+ g_return_val_if_fail (ivlen >= 8, NULL);
+
/* IV is already set from the DEK info */
- if (!egg_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);
-
+ g_return_val_if_reached (NULL);
+
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, FALSE);
-
+ g_return_val_if_fail (!gcry, NULL);
+
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
g_free (iv);
-
+
+ dat = egg_bytes_get_data (data);
+ n_data = egg_bytes_get_size (data);
+
/* Allocate output area */
n_overflow = (n_data % ivlen);
n_padding = n_overflow ? (ivlen - n_overflow) : 0;
n_batch = n_data - n_overflow;
*n_encrypted = n_data + n_padding;
- *encrypted = g_malloc0 (*n_encrypted);
-
+ encrypted = g_malloc0 (*n_encrypted);
+
g_assert (*n_encrypted % ivlen == 0);
g_assert (*n_encrypted >= n_data);
g_assert (*n_encrypted == n_batch + n_overflow + n_padding);
/* Encrypt everything but the last bit */
- gcry = gcry_cipher_encrypt (ch, *encrypted, n_batch, (void*)data, n_batch);
+ gcry = gcry_cipher_encrypt (ch, encrypted, n_batch, dat, n_batch);
if (gcry) {
- g_free (*encrypted);
- g_return_val_if_reached (FALSE);
+ g_free (encrypted);
+ g_return_val_if_reached (NULL);
}
-
+
/* Encrypt the padded block */
if (n_overflow) {
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);
+ memcpy (padded, dat + n_batch, n_overflow);
+ gcry = gcry_cipher_encrypt (ch, encrypted + n_batch, ivlen, padded, ivlen);
egg_secure_free (padded);
if (gcry) {
- g_free (*encrypted);
- g_return_val_if_reached (FALSE);
+ g_free (encrypted);
+ g_return_val_if_reached (NULL);
}
}
gcry_cipher_close (ch);
- return TRUE;
+ return encrypted;
}
const gchar*
@@ -351,21 +363,22 @@ egg_openssl_prep_dekinfo (GHashTable *headers)
gchar *dekinfo, *hex;
gsize ivlen;
guchar *iv;
-
+
/* Create the iv */
ivlen = gcry_cipher_get_algo_blklen (GCRY_CIPHER_3DES);
g_return_val_if_fail (ivlen, NULL);
iv = g_malloc (ivlen);
gcry_create_nonce (iv, ivlen);
-
+
/* And encode it into the string */
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);
+ g_free (iv);
g_hash_table_insert (headers, g_strdup ("DEK-Info"), (void*)dekinfo);
g_hash_table_insert (headers, g_strdup ("Proc-Type"), g_strdup ("4,ENCRYPTED"));
-
+
return dekinfo;
}
diff --git a/egg/egg-openssl.h b/egg/egg-openssl.h
index 7d4e4f0..642d906 100644
--- a/egg/egg-openssl.h
+++ b/egg/egg-openssl.h
@@ -26,15 +26,21 @@
#include <glib.h>
-int egg_openssl_parse_algo (const gchar *name, int *mode);
+#include <egg/egg-bytes.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);
+int egg_openssl_parse_algo (const gchar *name, int *mode);
-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);
+guchar * egg_openssl_encrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_encrypted);
+
+guchar * egg_openssl_decrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_decrypted);
const gchar* egg_openssl_get_dekinfo (GHashTable *headers);
diff --git a/egg/egg-secure-memory.c b/egg/egg-secure-memory.c
index 7af4ac9..ca5e38d 100644
--- a/egg/egg-secure-memory.c
+++ b/egg/egg-secure-memory.c
@@ -46,12 +46,6 @@
#include <valgrind/memcheck.h>
#endif
-/*
- * Use this to force all memory through malloc
- * for use with valgrind and the like
- */
-#define FORCE_FALLBACK_MEMORY 0
-
#define DEBUG_SECURE_MEMORY 0
#if DEBUG_SECURE_MEMORY
@@ -72,12 +66,12 @@
#endif
#define DO_LOCK() \
- egg_memory_lock ();
-
+ EGG_SECURE_GLOBALS.lock ();
+
#define DO_UNLOCK() \
- egg_memory_unlock ();
+ EGG_SECURE_GLOBALS.unlock ();
-static int lock_warning = 1;
+static int show_warning = 1;
int egg_secure_warnings = 1;
/*
@@ -169,17 +163,25 @@ typedef struct _Pool {
Item items[1]; /* Actual items hang off here */
} Pool;
-static Pool *all_pools = NULL;
-
-static void*
+static void *
pool_alloc (void)
{
Pool *pool;
void *pages, *item;
size_t len, i;
-
+
+ if (!EGG_SECURE_GLOBALS.pool_version ||
+ strcmp (EGG_SECURE_GLOBALS.pool_version, EGG_SECURE_POOL_VER_STR) != 0) {
+ if (show_warning && egg_secure_warnings)
+ fprintf (stderr, "the secure memory pool version does not match the code '%s' != '%s'\n",
+ EGG_SECURE_GLOBALS.pool_version ? EGG_SECURE_GLOBALS.pool_version : "(null)",
+ EGG_SECURE_POOL_VER_STR);
+ show_warning = 0;
+ return NULL;
+ }
+
/* A pool with an available item */
- for (pool = all_pools; pool; pool = pool->next) {
+ for (pool = EGG_SECURE_GLOBALS.pool_data; pool; pool = pool->next) {
if (unused_peek (&pool->unused))
break;
}
@@ -193,8 +195,8 @@ pool_alloc (void)
/* Fill in the block header, and inlude in block list */
pool = pages;
- pool->next = all_pools;
- all_pools = pool;
+ pool->next = EGG_SECURE_GLOBALS.pool_data;
+ EGG_SECURE_GLOBALS.pool_data = pool;
pool->length = len;
pool->used = 0;
pool->unused = NULL;
@@ -212,11 +214,11 @@ pool_alloc (void)
++pool->used;
ASSERT (unused_peek (&pool->unused));
item = unused_pop (&pool->unused);
-
+
#ifdef WITH_VALGRIND
VALGRIND_MEMPOOL_ALLOC (pool, item, sizeof (Item));
#endif
-
+
return memset (item, 0, sizeof (Item));
}
@@ -229,7 +231,8 @@ pool_free (void* item)
ptr = item;
/* Find which block this one belongs to */
- for (at = &all_pools, pool = *at; pool; at = &pool->next, pool = *at) {
+ for (at = (Pool **)&EGG_SECURE_GLOBALS.pool_data, pool = *at;
+ pool != NULL; at = &pool->next, pool = *at) {
beg = (char*)pool->items;
end = (char*)pool + pool->length - sizeof (Item);
if (ptr >= beg && ptr <= end) {
@@ -246,20 +249,20 @@ pool_free (void* item)
/* No more meta cells used in this block, remove from list, destroy */
if (pool->used == 1) {
*at = pool->next;
-
+
#ifdef WITH_VALGRIND
VALGRIND_DESTROY_MEMPOOL (pool);
#endif
-
+
munmap (pool, pool->length);
return;
}
-
+
#ifdef WITH_VALGRIND
VALGRIND_MEMPOOL_FREE (pool, item);
VALGRIND_MAKE_MEM_UNDEFINED (item, sizeof (Item));
#endif
-
+
--pool->used;
memset (item, 0xCD, sizeof (Item));
unused_push (&pool->unused, item);
@@ -276,7 +279,7 @@ pool_valid (void* item)
ptr = item;
/* Find which block this one belongs to */
- for (pool = all_pools; pool; pool = pool->next) {
+ for (pool = EGG_SECURE_GLOBALS.pool_data; pool; pool = pool->next) {
beg = (char*)pool->items;
end = (char*)pool + pool->length - sizeof (Item);
if (ptr >= beg && ptr <= end)
@@ -404,12 +407,33 @@ sec_is_valid_word (Block *block, word_t *word)
return (word >= block->words && word < block->words + block->n_words);
}
-static inline void*
-sec_clear_memory (void *memory, size_t from, size_t to)
+static inline void
+sec_clear_undefined (void *memory,
+ size_t from,
+ size_t to)
{
+ char *ptr = memory;
ASSERT (from <= to);
- memset ((char*)memory + from, 0, to - from);
- return memory;
+#ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_UNDEFINED (ptr + from, to - from);
+#endif
+ memset (ptr + from, 0, to - from);
+#ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_UNDEFINED (ptr + from, to - from);
+#endif
+}
+static inline void
+sec_clear_noaccess (void *memory, size_t from, size_t to)
+{
+ char *ptr = memory;
+ ASSERT (from <= to);
+#ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_UNDEFINED (ptr + from, to - from);
+#endif
+ memset (ptr + from, 0, to - from);
+#ifdef WITH_VALGRIND
+ VALGRIND_MAKE_MEM_NOACCESS (ptr + from, to - from);
+#endif
}
static Cell*
@@ -567,7 +591,7 @@ sec_free (Block *block, void *memory)
#endif
sec_check_guards (cell);
- sec_clear_memory (memory, 0, cell->requested);
+ sec_clear_noaccess (memory, 0, cell->requested);
sec_check_guards (cell);
ASSERT (cell->requested > 0);
@@ -611,6 +635,34 @@ sec_free (Block *block, void *memory)
return NULL;
}
+static void
+memcpy_with_vbits (void *dest,
+ void *src,
+ size_t length)
+{
+#ifdef WITH_VALGRIND
+ int vbits_setup = 0;
+ void *vbits = NULL;
+
+ if (RUNNING_ON_VALGRIND) {
+ vbits = malloc (length);
+ if (vbits != NULL)
+ vbits_setup = VALGRIND_GET_VBITS (src, vbits, length);
+ VALGRIND_MAKE_MEM_DEFINED (src, length);
+ }
+#endif
+
+ memcpy (dest, src, length);
+
+#ifdef WITH_VALGRIND
+ if (vbits_setup == 1) {
+ VALGRIND_SET_VBITS (dest, vbits, length);
+ VALGRIND_SET_VBITS (src, vbits, length);
+ }
+ free (vbits);
+#endif
+}
+
static void*
sec_realloc (Block *block,
const char *tag,
@@ -658,19 +710,15 @@ sec_realloc (Block *block,
cell->requested = length;
alloc = sec_cell_to_memory (cell);
-#ifdef WITH_VALGRIND
- VALGRIND_MAKE_MEM_DEFINED (alloc, length);
-#endif
-
/*
* Even though we may be reusing the same cell, that doesn't
* mean that the allocation is shrinking. It could have shrunk
* and is now expanding back some.
*/
if (length < valid)
- return sec_clear_memory (alloc, length, valid);
- else
- return alloc;
+ sec_clear_undefined (alloc, length, valid);
+
+ return alloc;
}
/* Need braaaaaiiiiiinsss... */
@@ -702,18 +750,14 @@ sec_realloc (Block *block,
cell->requested = length;
cell->tag = tag;
alloc = sec_cell_to_memory (cell);
-
-#ifdef WITH_VALGRIND
- VALGRIND_MAKE_MEM_DEFINED (alloc, length);
-#endif
-
- return sec_clear_memory (alloc, valid, length);
+ sec_clear_undefined (alloc, valid, length);
+ return alloc;
}
/* That didn't work, try alloc/free */
alloc = sec_alloc (block, tag, length);
if (alloc) {
- memcpy (alloc, memory, valid);
+ memcpy_with_vbits (alloc, memory, valid);
sec_free (block, memory);
}
@@ -758,7 +802,12 @@ sec_validate (Block *block)
{
Cell *cell;
word_t *word, *last;
-
+
+#ifdef WITH_VALGRIND
+ if (RUNNING_ON_VALGRIND)
+ return;
+#endif
+
word = block->words;
last = word + block->n_words;
@@ -781,7 +830,7 @@ sec_validate (Block *block)
ASSERT (cell->prev->next == cell);
ASSERT (cell->requested <= (cell->n_words - 2) * sizeof (word_t));
- /* An unused block */
+ /* An unused block */
} else {
ASSERT (cell->tag == NULL);
ASSERT (cell->next != NULL);
@@ -818,18 +867,18 @@ sec_acquire_pages (size_t *sz,
#if defined(HAVE_MLOCK)
pages = mmap (0, *sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
if (pages == MAP_FAILED) {
- if (lock_warning && egg_secure_warnings)
+ if (show_warning && egg_secure_warnings)
fprintf (stderr, "couldn't map %lu bytes of memory (%s): %s\n",
(unsigned long)*sz, during_tag, strerror (errno));
- lock_warning = 0;
+ show_warning = 0;
return NULL;
}
if (mlock (pages, *sz) < 0) {
- if (lock_warning && egg_secure_warnings && errno != EPERM) {
+ if (show_warning && egg_secure_warnings && errno != EPERM) {
fprintf (stderr, "couldn't lock %lu bytes of memory (%s): %s\n",
(unsigned long)*sz, during_tag, strerror (errno));
- lock_warning = 0;
+ show_warning = 0;
}
munmap (pages, *sz);
return NULL;
@@ -837,13 +886,13 @@ sec_acquire_pages (size_t *sz,
DEBUG_ALLOC ("gkr-secure-memory: new block ", *sz);
- lock_warning = 1;
+ show_warning = 1;
return pages;
#else
- if (lock_warning && egg_secure_warnings)
+ if (show_warning && egg_secure_warnings)
fprintf (stderr, "your system does not support private memory");
- lock_warning = 0;
+ show_warning = 0;
return NULL;
#endif
@@ -884,11 +933,10 @@ sec_block_create (size_t size,
ASSERT (during_tag);
-#if FORCE_FALLBACK_MEMORY
/* We can force all all memory to be malloced */
- return NULL;
-#endif
-
+ if (getenv ("SECMEM_FORCE_FALLBACK"))
+ return NULL;
+
block = pool_alloc ();
if (!block)
return NULL;
@@ -1011,8 +1059,8 @@ egg_secure_alloc_full (const char *tag,
DO_UNLOCK ();
- if (!memory && (flags & EGG_SECURE_USE_FALLBACK)) {
- memory = egg_memory_fallback (NULL, length);
+ if (!memory && (flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback != NULL) {
+ memory = EGG_SECURE_GLOBALS.fallback (NULL, length);
if (memory) /* Our returned memory is always zeroed */
memset (memory, 0, length);
}
@@ -1085,17 +1133,17 @@ egg_secure_realloc_full (const char *tag,
DO_UNLOCK ();
if (!block) {
- if ((flags & EGG_SECURE_USE_FALLBACK)) {
+ if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) {
/*
* In this case we can't zero the returned memory,
* because we don't know what the block size was.
*/
- return egg_memory_fallback (memory, length);
+ return EGG_SECURE_GLOBALS.fallback (memory, length);
} else {
if (egg_secure_warnings)
- fprintf (stderr, "memory does not belong to gnome-keyring: 0x%08lx\n",
+ fprintf (stderr, "memory does not belong to secure memory pool: 0x%08lx\n",
(unsigned long)memory);
- ASSERT (0 && "memory does does not belong to gnome-keyring");
+ ASSERT (0 && "memory does does not belong to secure memory pool");
return NULL;
}
}
@@ -1103,7 +1151,7 @@ egg_secure_realloc_full (const char *tag,
if (donew) {
alloc = egg_secure_alloc_full (tag, length, flags);
if (alloc) {
- memcpy (alloc, memory, previous);
+ memcpy_with_vbits (alloc, memory, previous);
egg_secure_free_full (memory, flags);
}
}
@@ -1151,13 +1199,13 @@ egg_secure_free_full (void *memory, int flags)
DO_UNLOCK ();
if (!block) {
- if ((flags & EGG_SECURE_USE_FALLBACK)) {
- egg_memory_fallback (memory, 0);
+ if ((flags & EGG_SECURE_USE_FALLBACK) && EGG_SECURE_GLOBALS.fallback) {
+ EGG_SECURE_GLOBALS.fallback (memory, 0);
} else {
if (egg_secure_warnings)
- fprintf (stderr, "memory does not belong to gnome-keyring: 0x%08lx\n",
+ fprintf (stderr, "memory does not belong to secure memory pool: 0x%08lx\n",
(unsigned long)memory);
- ASSERT (0 && "memory does does not belong to gnome-keyring");
+ ASSERT (0 && "memory does does not belong to secure memory pool");
}
}
}
diff --git a/egg/egg-secure-memory.h b/egg/egg-secure-memory.h
index 682811d..3ef0ab5 100644
--- a/egg/egg-secure-memory.h
+++ b/egg/egg-secure-memory.h
@@ -39,30 +39,32 @@
* must be defined somewhere, and provide appropriate locking for
* secure memory between threads:
*/
-
-extern void egg_memory_lock (void);
-
-extern void egg_memory_unlock (void);
-
-/*
- * Allocation Fallbacks
- *
- * If we cannot allocate secure memory, then this function
- * (defined elsewhere) will be called which has a chance to
- * allocate other memory abort or do whatever.
- *
- * Same call semantics as realloc with regard to NULL and zeros
- */
-extern void* egg_memory_fallback (void *p, size_t length);
-#define EGG_SECURE_GLIB_DEFINITIONS() \
+typedef struct {
+ void (* lock) (void);
+ void (* unlock) (void);
+ void * (* fallback) (void *pointer,
+ size_t length);
+ void * pool_data;
+ const char * pool_version;
+} egg_secure_glob;
+
+#define EGG_SECURE_POOL_VER_STR "1.0"
+#define EGG_SECURE_GLOBALS SECMEM_pool_data_v1_0
+
+#define EGG_SECURE_DEFINE_GLOBALS(lock, unlock, fallback) \
+ egg_secure_glob EGG_SECURE_GLOBALS = { \
+ lock, unlock, fallback, NULL, EGG_SECURE_POOL_VER_STR };
+
+#define EGG_SECURE_DEFINE_GLIB_GLOBALS() \
static GStaticMutex memory_mutex = G_STATIC_MUTEX_INIT; \
- void egg_memory_lock (void) \
+ static void egg_memory_lock (void) \
{ g_static_mutex_lock (&memory_mutex); } \
- void egg_memory_unlock (void) \
+ static void egg_memory_unlock (void) \
{ g_static_mutex_unlock (&memory_mutex); } \
- void* egg_memory_fallback (void *p, size_t sz) \
- { return g_realloc (p, sz); } \
+ EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, g_realloc);
+
+extern egg_secure_glob EGG_SECURE_GLOBALS;
/*
* Main functionality
diff --git a/egg/egg-symkey.c b/egg/egg-symkey.c
index 630f922..6af1751 100644
--- a/egg/egg-symkey.c
+++ b/egg/egg-symkey.c
@@ -1,13 +1,13 @@
-/*
+/*
* 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
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#include "config.h"
@@ -71,16 +71,16 @@ init_quarks (void)
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");
@@ -91,7 +91,7 @@ init_quarks (void)
QUARK (OID_SHA1, "1.3.14.3.2.26");
#undef QUARK
-
+
g_once_init_leave (&quarks_inited, 1);
}
}
@@ -101,9 +101,9 @@ init_quarks (void)
*/
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,
+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;
@@ -119,38 +119,38 @@ egg_symkey_generate_simple (int cipher_algo, int hash_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",
+ 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 = egg_secure_alloc (n_digest);
g_return_val_if_fail (digest, FALSE);
if (key) {
*key = egg_secure_alloc (needed_key);
g_return_val_if_fail (*key, FALSE);
}
- if (iv)
+ if (iv)
*iv = g_new0 (guchar, needed_iv);
at_key = key ? *key : NULL;
@@ -158,7 +158,7 @@ egg_symkey_generate_simple (int cipher_algo, int hash_algo,
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);
@@ -171,7 +171,7 @@ egg_symkey_generate_simple (int cipher_algo, int hash_algo,
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);
@@ -180,9 +180,9 @@ egg_symkey_generate_simple (int cipher_algo, int hash_algo,
g_return_val_if_fail (digested, FALSE);
memcpy (digest, digested, n_digest);
}
-
+
/* Copy as much as possible into the destinations */
- i = 0;
+ i = 0;
while (needed_key && i < n_digest) {
if (at_key)
*(at_key++) = digest[i];
@@ -190,25 +190,25 @@ egg_symkey_generate_simple (int cipher_algo, int hash_algo,
i++;
}
while (needed_iv && i < n_digest) {
- if (at_iv)
+ if (at_iv)
*(at_iv++) = digest[i];
needed_iv--;
i++;
}
-
+
if (needed_key == 0 && needed_iv == 0)
break;
}
egg_secure_free (digest);
gcry_md_close (mdh);
-
+
return TRUE;
}
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,
+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;
@@ -222,38 +222,38 @@ egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
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
+ * 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 "
+ 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 (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",
+ g_warning ("couldn't create '%s' hash context: %s",
gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
return FALSE;
}
@@ -264,7 +264,7 @@ egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
*key = egg_secure_alloc (needed_key);
g_return_val_if_fail (*key, FALSE);
}
- if (iv)
+ if (iv)
*iv = g_new0 (guchar, needed_iv);
if (password)
@@ -275,31 +275,31 @@ egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password,
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);
}
-
+
egg_secure_free (digest);
gcry_md_close (mdh);
-
- return TRUE;
+
+ return TRUE;
}
static gboolean
-generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
- gssize n_password, const guchar *salt, gsize n_salt,
+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;
@@ -314,20 +314,20 @@ generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
gsize length;
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)
+ 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",
+ g_warning ("couldn't create '%s' hash context: %s",
gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
return FALSE;
}
@@ -337,7 +337,7 @@ generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
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 */
p = buf_i;
if (salt) {
@@ -347,12 +347,12 @@ generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
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);
@@ -370,9 +370,8 @@ generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
}
} else {
memset (p, 0, 64);
- p += 64;
}
-
+
/* Hash and bash */
for (;;) {
gcry_md_reset (mdh);
@@ -380,27 +379,27 @@ generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
/* 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];
@@ -420,67 +419,67 @@ generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password,
g_return_val_if_fail (gcry == 0, FALSE);
gcry_mpi_release (num_ij);
}
- }
-
+ }
+
egg_secure_free (buf_i);
egg_secure_free (buf_b);
egg_secure_free (hash);
gcry_mpi_release (num_b1);
gcry_md_close (mdh);
-
+
return TRUE;
}
gboolean
-egg_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password,
+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;
-
+
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 = 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,
+ 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,
+ 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);
egg_secure_free (key ? *key : NULL);
}
-
+
return ret;
}
@@ -531,7 +530,7 @@ generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
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);
@@ -539,10 +538,10 @@ generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
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",
+ g_warning ("couldn't create '%s' hash context: %s",
gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
return FALSE;
}
@@ -556,10 +555,10 @@ generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
/* 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);
@@ -568,21 +567,21 @@ generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
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++)
@@ -591,7 +590,7 @@ generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
}
-
+
egg_secure_free (T);
egg_secure_free (U);
egg_secure_free (buf);
@@ -600,39 +599,39 @@ generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
}
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,
+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;
-
+
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 = egg_secure_alloc (n_key);
g_return_val_if_fail (*key != NULL, FALSE);
- ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt,
+ 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) {
@@ -642,13 +641,13 @@ egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
*iv = NULL;
}
}
-
+
/* Cleanup in case of failure */
if (!ret) {
g_free (iv ? *iv : NULL);
egg_secure_free (key ? *key : NULL);
}
-
+
return ret;
}
@@ -658,14 +657,17 @@ egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
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)
+read_cipher_pkcs5_pbe (int cipher_algo,
+ int cipher_mode,
+ int hash_algo,
+ const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ gcry_cipher_hd_t *cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
- gconstpointer salt;
- gsize n_salt;
+ EggBytes *salt = NULL;
gsize n_block, n_key;
gulong iterations;
guchar *key = NULL;
@@ -674,11 +676,11 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
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);
+ g_return_val_if_fail (data != NULL, 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)
@@ -687,10 +689,10 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-PBE-params");
g_return_val_if_fail (asn, FALSE);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
goto done;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL));
if (!salt)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
@@ -699,25 +701,28 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
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))
+
+ if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password,
+ egg_bytes_get_data (salt), egg_bytes_get_size (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)
+
+ if (iv)
gcry_cipher_setiv (*cih, iv, n_block);
gcry_cipher_setkey (*cih, key, n_key);
-
+
ret = TRUE;
done:
g_free (iv);
+ if (salt != NULL)
+ egg_bytes_unref (salt);
egg_secure_free (key);
egg_asn1x_destroy (asn);
@@ -725,12 +730,12 @@ done:
}
static gboolean
-setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
+setup_pkcs5_rc2_params (EggBytes *data,
+ gcry_cipher_hd_t cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
- const guchar *iv;
- gsize n_iv;
+ EggBytes *iv = NULL;
gulong version;
gboolean ret = FALSE;
@@ -739,135 +744,147 @@ setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-rc2-CBC-params");
g_return_val_if_fail (asn, FALSE);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "rc2ParameterVersion", NULL), &version))
goto done;
- iv = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "iv", NULL), &n_iv);
+ iv = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "iv", NULL));
if (!iv)
goto done;
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
+ gcry = gcry_cipher_setiv (cih, egg_bytes_get_data (iv), egg_bytes_get_size (iv));
if (gcry != 0) {
- g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
+ g_message ("couldn't set %lu byte iv on cipher", (gulong)egg_bytes_get_size (iv));
goto done;
}
ret = TRUE;
done:
+ if (iv != NULL)
+ egg_bytes_unref (iv);
egg_asn1x_destroy (asn);
return ret;
}
static gboolean
-setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
+setup_pkcs5_des_params (EggBytes *data,
+ gcry_cipher_hd_t cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
- gconstpointer iv;
- gsize n_iv;
+ EggBytes *iv;
+ gboolean ret;
g_assert (data);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params", data);
+ if (!asn)
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-CBC-params", data);
if (!asn)
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-CBC-params", data, n_data);
- if (!asn)
return FALSE;
- iv = egg_asn1x_get_raw_value (asn, &n_iv);
+ iv = egg_asn1x_get_raw_value (asn);
egg_asn1x_destroy (asn);
if (!iv)
return FALSE;
-
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
-
+
+ gcry = gcry_cipher_setiv (cih, egg_bytes_get_data (iv), egg_bytes_get_size (iv));
if (gcry != 0) {
- g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
- return FALSE;
+ g_message ("couldn't set %lu byte iv on cipher", (gulong)egg_bytes_get_size (iv));
+ ret = FALSE;
+ } else {
+ ret = TRUE;
}
-
- return TRUE;
+
+ egg_bytes_unref (iv);
+ return ret;
}
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)
+setup_pkcs5_pbkdf2_params (const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ int cipher_algo,
+ gcry_cipher_hd_t cih)
{
GNode *asn = NULL;
gboolean ret;
gcry_error_t gcry;
- guchar *key = NULL;
- const guchar *salt;
- gsize n_salt, n_key;
+ guchar *key = NULL;
+ EggBytes *salt = NULL;
+ gsize n_key;
gulong iterations;
g_assert (cipher_algo);
- g_assert (data);
-
+ g_assert (data != NULL);
+
ret = FALSE;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBKDF2-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBKDF2-params", data);
if (!asn)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
iterations = 1;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", "specified", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", "specified", NULL));
if (!salt)
goto done;
- if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
- salt, n_salt, iterations, &key, NULL))
+ if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
+ egg_bytes_get_data (salt), egg_bytes_get_size (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:
+ if (salt != NULL)
+ egg_bytes_unref (salt);
egg_secure_free (key);
egg_asn1x_destroy (asn);
return ret;
}
static gboolean
-read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih)
+read_cipher_pkcs5_pbes2 (const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ gcry_cipher_hd_t *cih)
{
GNode *asn = NULL;
gboolean r, ret;
GQuark key_deriv_algo, enc_oid;
+ EggBytes *params = NULL;
gcry_error_t gcry;
int algo, mode;
- gconstpointer params;
- gsize n_params;
g_return_val_if_fail (cih != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
-
+ g_return_val_if_fail (data != NULL, FALSE);
+
init_quarks ();
-
+
*cih = NULL;
ret = FALSE;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBES2-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBES2-params", data);
if (!asn)
goto done;
algo = mode = 0;
-
+
/* Read in all the encryption type */
enc_oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionScheme", "algorithm", NULL));
if (!enc_oid)
@@ -880,7 +897,7 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
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;
@@ -891,19 +908,19 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo));
goto done;
}
-
+
/* Read out the parameters */
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL));
if (!params)
goto done;
switch (algo) {
case GCRY_CIPHER_3DES:
case GCRY_CIPHER_DES:
- r = setup_pkcs5_des_params (params, n_params, *cih);
+ r = setup_pkcs5_des_params (params, *cih);
break;
case GCRY_CIPHER_RFC2268_128:
- r = setup_pkcs5_rc2_params (params, n_params, *cih);
+ r = setup_pkcs5_rc2_params (params, *cih);
break;
default:
/* Should have been caught on the oid check above */
@@ -912,7 +929,7 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
break;
};
- if (r != TRUE)
+ if (r != TRUE)
goto done;
/* Read out the key creation paramaters */
@@ -924,11 +941,12 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
goto done;
}
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL), &n_params);
+ egg_bytes_unref (params);
+ params = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL));
if (!params)
goto done;
- ret = setup_pkcs5_pbkdf2_params (password, n_password, params, n_params, algo, *cih);
+ ret = setup_pkcs5_pbkdf2_params (password, n_password, params, algo, *cih);
done:
if (ret != TRUE && *cih) {
@@ -936,20 +954,24 @@ done:
*cih = NULL;
}
+ if (params != NULL)
+ egg_bytes_unref (params);
egg_asn1x_destroy (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,
+read_cipher_pkcs12_pbe (int cipher_algo,
+ int cipher_mode,
+ const gchar *password,
+ gsize n_password,
+ EggBytes *data,
gcry_cipher_hd_t *cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
gboolean ret;
- const guchar *salt;
- gsize n_salt;
+ EggBytes *salt = NULL;
gsize n_block, n_key;
gulong iterations;
guchar *key = NULL;
@@ -957,52 +979,54 @@ read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
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);
-
+ g_return_val_if_fail (data != NULL, 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_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-PbeParams", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-PbeParams", data);
if (!asn)
goto done;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL));
if (!salt)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterations", NULL), &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))
+ if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password, n_password,
+ egg_bytes_get_data (salt), egg_bytes_get_size (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)
+
+ 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;
}
-
+
+ if (salt != NULL)
+ egg_bytes_unref (salt);
g_free (iv);
egg_secure_free (key);
egg_asn1x_destroy (asn);
@@ -1013,8 +1037,7 @@ static gboolean
read_mac_pkcs12_pbe (int hash_algo,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_md_hd_t *mdh,
gsize *digest_len)
{
@@ -1022,14 +1045,13 @@ read_mac_pkcs12_pbe (int hash_algo,
gcry_error_t gcry;
gboolean ret;
gsize n_key;
- const guchar *salt;
- gsize n_salt;
+ EggBytes *salt = NULL;
gulong iterations;
guchar *key = NULL;
g_return_val_if_fail (hash_algo != 0, FALSE);
g_return_val_if_fail (mdh != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
*mdh = NULL;
ret = FALSE;
@@ -1038,11 +1060,11 @@ read_mac_pkcs12_pbe (int hash_algo,
if (gcry_md_algo_info (hash_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
goto done;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-MacData", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-MacData", data);
if (!asn)
goto done;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "macSalt", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "macSalt", NULL));
if (!salt)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterations", NULL), &iterations))
@@ -1052,7 +1074,8 @@ read_mac_pkcs12_pbe (int hash_algo,
/* Generate IV and key using salt read above */
if (!egg_symkey_generate_pkcs12_mac (hash_algo, password, n_password,
- salt, n_salt, iterations, &key))
+ egg_bytes_get_data (salt), egg_bytes_get_size (salt),
+ iterations, &key))
goto done;
gcry = gcry_md_open (mdh, hash_algo, GCRY_MD_FLAG_HMAC);
@@ -1073,82 +1096,86 @@ done:
*mdh = NULL;
}
+ if (salt != NULL)
+ egg_bytes_unref (salt);
egg_secure_free (key);
egg_asn1x_destroy (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)
+egg_symkey_read_cipher (GQuark oid_scheme,
+ const gchar *password,
+ gsize n_password,
+ EggBytes *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);
-
+ g_return_val_if_fail (data != NULL, 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);
+ GCRY_MD_MD2, password, n_password, 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);
+ GCRY_MD_MD5, password, n_password, 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);
+ GCRY_MD_SHA1, password, n_password, 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);
+ ret = read_cipher_pkcs5_pbes2 (password, n_password, 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);
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM,
+ password, n_password, 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)
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC,
+ password, n_password, 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);
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC,
+ password, n_password, 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);
+ ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC,
+ password, n_password, data, cih);
if (ret == FALSE)
- g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
-
- return ret;
+ g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
+
+ return ret;
}
gboolean
egg_symkey_read_mac (GQuark oid_scheme,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_md_hd_t *mdh,
gsize *digest_len)
{
@@ -1156,14 +1183,14 @@ egg_symkey_read_mac (GQuark oid_scheme,
g_return_val_if_fail (oid_scheme != 0, FALSE);
g_return_val_if_fail (mdh != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
init_quarks ();
/* PKCS#12 MAC with SHA-1 */
if (oid_scheme == OID_SHA1)
ret = read_mac_pkcs12_pbe (GCRY_MD_SHA1, password, n_password,
- data, n_data, mdh, digest_len);
+ data, mdh, digest_len);
if (ret == FALSE)
g_message ("unsupported or invalid mac: %s", g_quark_to_string (oid_scheme));
diff --git a/egg/egg-symkey.h b/egg/egg-symkey.h
index 21feab6..de9eb8b 100644
--- a/egg/egg-symkey.h
+++ b/egg/egg-symkey.h
@@ -1,13 +1,13 @@
-/*
+/*
* 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
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU Lesser General
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * 02111-1307, USA.
*/
#ifndef EGG_SYMKEY_H_
@@ -26,34 +26,36 @@
#include <gcrypt.h>
-gboolean egg_symkey_generate_simple (int cipher_algo,
- int hash_algo,
- const gchar *password,
+#include <egg/egg-bytes.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,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
guchar **iv);
-gboolean egg_symkey_generate_pbe (int cipher_algo,
- int hash_algo,
+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,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
guchar **iv);
-gboolean egg_symkey_generate_pkcs12 (int cipher_algo,
+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 **key,
guchar **iv);
gboolean egg_symkey_generate_pkcs12_mac (int hash_algo,
@@ -64,28 +66,26 @@ gboolean egg_symkey_generate_pkcs12_mac (int hash_algo,
int iterations,
guchar **key);
-gboolean egg_symkey_generate_pbkdf2 (int cipher_algo,
- int hash_algo,
+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,
+ const guchar *salt,
+ gsize n_salt,
+ int iterations,
+ guchar **key,
guchar **iv);
-gboolean egg_symkey_read_cipher (GQuark oid_scheme,
+gboolean egg_symkey_read_cipher (GQuark oid_scheme,
const gchar *password,
- gsize n_password,
- const guchar *data,
- gsize n_data,
+ gsize n_password,
+ EggBytes *data,
gcry_cipher_hd_t *cih);
gboolean egg_symkey_read_mac (GQuark oid_scheme,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_md_hd_t *mdh,
gsize *digest_len);
diff --git a/egg/egg-testing.h b/egg/egg-testing.h
index 8dca086..5b4c911 100644
--- a/egg/egg-testing.h
+++ b/egg/egg-testing.h
@@ -37,6 +37,13 @@
G_STRFUNC, #a "[" #na"] " #cmp " " #b "[" #nb "]", \
__p1, __n1, #cmp, __p2, __n2); } while (0)
+#define egg_assert_cmpbytes(a, cmp, b, nb) \
+ do { gpointer __p1 = (gpointer)(a); gconstpointer __p2 = (b); gsize __n2 = (nb); \
+ if (egg_bytes_get_size (__p1) cmp __n2 && memcmp (egg_bytes_get_data (__p1), __p2, __n2) cmp 0) ; else \
+ egg_assertion_message_cmpmem (G_LOG_DOMAIN, __FILE__, __LINE__, \
+ G_STRFUNC, #a " " #cmp " " #b, \
+ egg_bytes_get_data (__p1), egg_bytes_get_size(__p1), #cmp, __p2, __n2); } while (0)
+
void egg_assertion_message_cmpmem (const char *domain, const char *file,
int line, const char *func,
const char *expr, gconstpointer arg1,
diff --git a/egg/tests/Makefile.am b/egg/tests/Makefile.am
index aa5fac7..a6d51e1 100644
--- a/egg/tests/Makefile.am
+++ b/egg/tests/Makefile.am
@@ -1,6 +1,12 @@
+include $(top_srcdir)/Makefile.decl
-asn1-def-test.c: test.asn
- $(ASN1PARSER) -o asn1-def-test.c $(srcdir)/test.asn
+ASN_FILES = \
+ test.asn
+
+ASN_SRCS = $(ASN_FILES:.asn=.asn.h)
+
+BUILT_SOURCES = \
+ $(ASN_SRCS)
INCLUDES = \
-I$(top_builddir) \
@@ -30,7 +36,7 @@ TEST_PROGS = \
test_asn1_SOURCES = \
test-asn1.c \
- asn1-def-test.c
+ $(ASN_SRCS)
check_PROGRAMS = $(TEST_PROGS)
@@ -42,11 +48,11 @@ check-local: test
all-local: $(check_PROGRAMS)
EXTRA_DIST = \
- test.asn \
+ $(ASN_FILES) \
files
DISTCLEANFILES = \
- asn1-def-test.c
+ $(ASN_SRCS)
# ------------------------------------------------------------------------------
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index 9403ebb..7844c92 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -28,13 +28,13 @@
#include "egg/egg-testing.h"
#include <glib.h>
-#include <libtasn1.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-extern const ASN1_ARRAY_TYPE test_asn1_tab[];
+typedef struct _EggAsn1xDef ASN1_ARRAY_TYPE;
+#include "test.asn.h"
const gchar I33[] = "\x02\x01\x2A";
const gchar I253[] = "\x02\x02\x00\xFD";
@@ -42,7 +42,8 @@ const gchar BFALSE[] = "\x01\x01\x00";
const gchar BTRUE[] = "\x01\x01\xFF";
const gchar SFARNSWORTH[] = "\x04\x0A""farnsworth";
const gchar SIMPLICIT[] = "\x85\x08""implicit";
-const gchar SEXPLICIT[] = "\xE5\x0A\x04\x08""explicit";
+const gchar SEXPLICIT[] = "\xA5\x0A\x04\x08""explicit";
+const gchar SUNIVERSAL[] = "\x05\x09""universal";
const gchar TGENERALIZED[] = "\x18\x0F""20070725130528Z";
const gchar BITS_TEST[] = "\x03\x04\x06\x6e\x5d\xc0";
const gchar BITS_BAD[] = "\x03\x04\x06\x6e\x5d\xc1";
@@ -60,31 +61,38 @@ const gchar ENUM_THREE[] = "\x0A\x01\x03";
static void
test_boolean (void)
{
+ EggBytes *bytes;
GNode *asn;
gboolean value;
asn = egg_asn1x_create (test_asn1_tab, "TestBoolean");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_BOOLEAN, ==, egg_asn1x_type (asn));
+
/* Shouldn't succeed */
if (egg_asn1x_get_boolean (asn, &value))
g_assert_not_reached ();
/* Decode a false */
- if (!egg_asn1x_decode (asn, BFALSE, XL (BFALSE)))
+ bytes = egg_bytes_new_static (BFALSE, XL (BFALSE));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
value = TRUE;
if (!egg_asn1x_get_boolean (asn, &value))
g_assert_not_reached ();
g_assert (value == FALSE);
+ egg_bytes_unref (bytes);
/* Decode a true */
- if (!egg_asn1x_decode (asn, BTRUE, XL (BTRUE)))
+ bytes = egg_bytes_new_static (BTRUE, XL (BTRUE));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
value = FALSE;
if (!egg_asn1x_get_boolean (asn, &value))
g_assert_not_reached ();
g_assert (value == TRUE);
+ egg_bytes_unref (bytes);
egg_asn1x_clear (asn);
@@ -99,23 +107,24 @@ static void
test_null (void)
{
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
asn = egg_asn1x_create (test_asn1_tab, "TestNull");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_NULL, ==, egg_asn1x_type (asn));
+
if (!egg_asn1x_set_null (asn))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, g_realloc, &n_data);
- egg_assert_cmpmem (NULL_TEST, XL (NULL_TEST), ==, data, n_data);
+ data = egg_asn1x_encode (asn, g_realloc);
+ egg_assert_cmpmem (NULL_TEST, XL (NULL_TEST), ==, egg_bytes_get_data (data), egg_bytes_get_size (data));
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
g_assert_not_reached ();
egg_asn1x_destroy (asn);
- g_free (data);
+ egg_bytes_unref (data);
}
static void
@@ -123,20 +132,25 @@ test_integer (void)
{
GNode *asn;
gulong value;
+ EggBytes *bytes;
asn = egg_asn1x_create (test_asn1_tab, "TestInteger");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_INTEGER, ==, egg_asn1x_type (asn));
+
/* Shouldn't succeed */
if (egg_asn1x_get_integer_as_ulong (asn, &value))
g_assert_not_reached ();
/* Should suceed now */
- if (!egg_asn1x_decode (asn, I33, XL (I33)))
+ bytes = egg_bytes_new_static (I33, XL (I33));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
if (!egg_asn1x_get_integer_as_ulong (asn, &value))
g_assert_not_reached ();
g_assert (value == 42);
+ egg_bytes_unref (bytes);
egg_asn1x_clear (asn);
@@ -152,50 +166,55 @@ test_unsigned (void)
{
GNode *asn;
gulong value;
- guchar *check;
- gsize n_check;
+ EggBytes *check;
guchar val;
- gconstpointer usg;
- gsize n_usg;
+ EggBytes *bytes;
+ EggBytes *usg;
asn = egg_asn1x_create (test_asn1_tab, "TestInteger");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_INTEGER, ==, egg_asn1x_type (asn));
+
/* Check with ulong */
- if (!egg_asn1x_decode (asn, I253, XL (I253)))
+ bytes = egg_bytes_new_static (I253, XL (I253));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
if (!egg_asn1x_get_integer_as_ulong (asn, &value))
g_assert_not_reached ();
g_assert (value == 253);
+ egg_bytes_unref (bytes);
egg_asn1x_clear (asn);
if (!egg_asn1x_set_integer_as_ulong (asn, 253))
g_assert_not_reached ();
- check = egg_asn1x_encode (asn, NULL, &n_check);
- egg_assert_cmpmem (check, n_check, ==, I253, XL (I253));
+ check = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpmem (I253, XL (I253), ==, egg_bytes_get_data (check), egg_bytes_get_size (check));
+ egg_bytes_unref (check);
/* Now check with usg */
- if (!egg_asn1x_decode (asn, I253, XL (I253)))
+ bytes = egg_bytes_new_static (I253, XL (I253));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
- g_free (check);
+ egg_bytes_unref (bytes);
val = 0xFD; /* == 253 */
- usg = egg_asn1x_get_integer_as_usg (asn, &n_usg);
- egg_assert_cmpmem (&val, 1, ==, usg, n_usg);
+ usg = egg_asn1x_get_integer_as_usg (asn);
+ egg_assert_cmpmem (&val, 1, ==, egg_bytes_get_data (usg), egg_bytes_get_size (usg));
+ egg_bytes_unref (usg);
egg_asn1x_clear (asn);
- if (!egg_asn1x_set_integer_as_usg (asn, &val, 1, NULL))
- g_assert_not_reached ();
+ egg_asn1x_take_integer_as_usg (asn, egg_bytes_new_static (&val, 1));
- check = egg_asn1x_encode (asn, NULL, &n_check);
- egg_assert_cmpsize (n_check, ==, XL (I253));
- egg_assert_cmpmem (check, n_check, ==, I253, XL (I253));
+ check = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpsize (egg_bytes_get_size (check), ==, XL (I253));
+ egg_assert_cmpmem (I253, XL (I253), ==, egg_bytes_get_data (check), egg_bytes_get_size (check));
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
- g_free (check);
}
static void
@@ -203,17 +222,23 @@ test_octet_string (void)
{
GNode *asn;
gchar *value;
+ EggBytes *bytes;
asn = egg_asn1x_create (test_asn1_tab, "TestOctetString");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_OCTET_STRING, ==, egg_asn1x_type (asn));
+
/* Shouldn't succeed */
if (egg_asn1x_get_string_as_utf8 (asn, NULL))
g_assert_not_reached ();
/* Should work */
- if (!egg_asn1x_decode (asn, SFARNSWORTH, XL (SFARNSWORTH)))
+ bytes = egg_bytes_new_static (SFARNSWORTH, XL (SFARNSWORTH));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
+
value = egg_asn1x_get_string_as_utf8 (asn, NULL);
g_assert_cmpstr (value, ==, "farnsworth");
g_free (value);
@@ -230,19 +255,24 @@ test_octet_string (void)
static void
test_generalized_time (void)
{
+ EggBytes *bytes;
GNode *asn;
glong value;
asn = egg_asn1x_create (test_asn1_tab, "TestGeneralized");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_TIME, ==, egg_asn1x_type (asn));
+
/* Shouldn't succeed */
value = egg_asn1x_get_time_as_long (asn);
g_assert (value == -1);
/* Should work */
- if (!egg_asn1x_decode (asn, TGENERALIZED, XL (TGENERALIZED)))
+ bytes = egg_bytes_new_static (TGENERALIZED, XL (TGENERALIZED));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
value = egg_asn1x_get_time_as_long (asn);
g_assert (value == 1185368728);
@@ -256,8 +286,9 @@ test_generalized_time (void)
}
static void
-test_implicit (void)
+test_implicit_encode (void)
{
+ EggBytes *bytes;
GNode *asn;
gchar *value;
@@ -265,8 +296,10 @@ test_implicit (void)
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, SIMPLICIT, XL (SIMPLICIT)))
+ bytes = egg_bytes_new_static (SIMPLICIT, XL (SIMPLICIT));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
value = egg_asn1x_get_string_as_utf8 (asn, NULL);
g_assert_cmpstr (value, ==, "implicit");
g_free (value);
@@ -275,8 +308,28 @@ test_implicit (void)
}
static void
-test_explicit (void)
+test_implicit_decode (void)
{
+ EggBytes *bytes;
+ GNode *asn;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestImplicit");
+ g_assert (asn);
+
+ if (!egg_asn1x_set_string_as_utf8 (asn, g_strdup ("implicit"), g_free))
+ g_assert_not_reached ();
+
+ bytes = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpbytes (bytes, ==, SIMPLICIT, XL (SIMPLICIT));
+
+ egg_asn1x_destroy (asn);
+ egg_bytes_unref (bytes);
+}
+
+static void
+test_explicit_decode (void)
+{
+ EggBytes *bytes;
GNode *asn;
gchar *value;
@@ -284,8 +337,11 @@ test_explicit (void)
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, SEXPLICIT, XL (SEXPLICIT)))
+ bytes = egg_bytes_new_static (SEXPLICIT, XL (SEXPLICIT));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
+
value = egg_asn1x_get_string_as_utf8 (asn, NULL);
g_assert_cmpstr (value, ==, "explicit");
g_free (value);
@@ -294,41 +350,112 @@ test_explicit (void)
}
static void
+test_explicit_encode (void)
+{
+ EggBytes *bytes;
+ GNode *asn;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestExplicit");
+ g_assert (asn);
+
+ if (!egg_asn1x_set_string_as_utf8 (asn, g_strdup ("explicit"), g_free))
+ g_assert_not_reached ();
+
+ bytes = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpbytes (bytes, ==, SEXPLICIT, XL (SEXPLICIT));
+
+ egg_asn1x_destroy (asn);
+ egg_bytes_unref (bytes);
+}
+
+static void
+test_universal_decode (void)
+{
+ EggBytes *bytes;
+ GNode *asn;
+ gchar *value;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestUniversal");
+ g_assert (asn);
+
+ /* Should work */
+ bytes = egg_bytes_new_static (SUNIVERSAL, XL (SUNIVERSAL));
+ if (!egg_asn1x_decode (asn, bytes))
+ g_assert_not_reached ();
+ egg_bytes_unref (bytes);
+
+ value = egg_asn1x_get_string_as_utf8 (asn, NULL);
+ g_assert_cmpstr (value, ==, "universal");
+ g_free (value);
+
+ egg_asn1x_destroy (asn);
+}
+
+static void
+test_universal_encode (void)
+{
+ EggBytes *bytes;
+ GNode *asn;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestUniversal");
+ g_assert (asn);
+
+ if (!egg_asn1x_set_string_as_utf8 (asn, g_strdup ("universal"), g_free))
+ g_assert_not_reached ();
+
+ bytes = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpbytes (bytes, ==, SUNIVERSAL, XL (SUNIVERSAL));
+
+ egg_asn1x_destroy (asn);
+ egg_bytes_unref (bytes);
+}
+
+static void
test_bit_string_decode (void)
{
+ EggBytes *bytes;
GNode *asn;
- guchar *bits;
+ EggBytes *bits;
guint n_bits;
+ const guchar *data;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_BIT_STRING, ==, egg_asn1x_type (asn));
+
/* Should work */
- if (!egg_asn1x_decode (asn, BITS_TEST, XL (BITS_TEST)))
+ bytes = egg_bytes_new_static (BITS_TEST, XL (BITS_TEST));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- bits = egg_asn1x_get_bits_as_raw (asn, NULL, &n_bits);
- g_assert (bits);
+ bits = egg_asn1x_get_bits_as_raw (asn, &n_bits);
+ g_assert (bits != NULL);
g_assert_cmpuint (n_bits, ==, 18);
- g_assert_cmpint (bits[0], ==, 0x6e);
- g_assert_cmpint (bits[1], ==, 0x5d);
- g_assert_cmpint (bits[2], ==, 0xc0);
+ data = egg_bytes_get_data (bits);
+ g_assert_cmpint (data[0], ==, 0x6e);
+ g_assert_cmpint (data[1], ==, 0x5d);
+ g_assert_cmpint (data[2], ==, 0xc0);
- g_free (bits);
+ egg_bytes_unref (bits);
egg_asn1x_destroy (asn);
}
static void
test_bit_string_decode_bad (void)
{
+ EggBytes *bytes;
GNode *asn;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
/* Should not work */
- if (egg_asn1x_decode (asn, BITS_BAD, XL (BITS_BAD)))
+ bytes = egg_bytes_new_static (BITS_BAD, XL (BITS_BAD));
+ if (egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
egg_asn1x_destroy (asn);
}
@@ -336,6 +463,7 @@ test_bit_string_decode_bad (void)
static void
test_bit_string_decode_ulong (void)
{
+ EggBytes *bytes;
GNode *asn;
gulong bits;
guint n_bits;
@@ -344,8 +472,10 @@ test_bit_string_decode_ulong (void)
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, BITS_TEST, XL (BITS_TEST)))
+ bytes = egg_bytes_new_static (BITS_TEST, XL (BITS_TEST));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
if (!egg_asn1x_get_bits_as_ulong (asn, &bits, &n_bits))
g_assert_not_reached ();
@@ -359,46 +489,46 @@ test_bit_string_decode_ulong (void)
static void
test_bit_string_encode_decode (void)
{
+ EggBytes *data;
GNode *asn;
guchar bits[] = { 0x5d, 0x6e, 0x83 };
- guchar *check;
- guint n_check, n_bits = 17;
- gpointer data;
- gsize n_data;
+ EggBytes *check;
+ const guchar *ch;
+ guint n_bits = 17;
+ guint n_check;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
- if (!egg_asn1x_set_bits_as_raw (asn, bits, n_bits, NULL))
- g_assert_not_reached ();
+ egg_asn1x_take_bits_as_raw (asn, egg_bytes_new (bits, 3), n_bits);
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
g_assert_not_reached ();
- check = egg_asn1x_get_bits_as_raw (asn, NULL, &n_check);
- g_assert (check);
- g_assert_cmpuint (n_check, ==, 17);
- g_assert_cmpint (check[0], ==, 0x5d);
- g_assert_cmpint (check[1], ==, 0x6e);
- g_assert_cmpint (check[2], ==, 0x80);
+ egg_bytes_unref (data);
- g_free (check);
+ check = egg_asn1x_get_bits_as_raw (asn, &n_check);
+ g_assert (check != NULL);
+ g_assert_cmpuint (n_check, ==, 17);
+ ch = egg_bytes_get_data (check);
+ g_assert_cmpint (ch[0], ==, 0x5d);
+ g_assert_cmpint (ch[1], ==, 0x6e);
+ g_assert_cmpint (ch[2], ==, 0x80);
- g_free (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
}
static void
test_bit_string_encode_decode_ulong (void)
{
+ EggBytes *data;
GNode *asn;
gulong check, bits = 0x0101b977;
guint n_check, n_bits = 18;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
@@ -406,51 +536,48 @@ test_bit_string_encode_decode_ulong (void)
if (!egg_asn1x_set_bits_as_ulong (asn, bits, n_bits))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
g_assert_not_reached ();
+ egg_bytes_unref (data);
+
if (!egg_asn1x_get_bits_as_ulong (asn, &check, &n_check))
g_assert_not_reached ();
g_assert_cmpuint (n_check, ==, 18);
g_assert_cmphex (check, ==, 0x1b977);
- g_free (data);
egg_asn1x_destroy (asn);
}
static void
test_bit_string_encode_decode_zero (void)
{
+ EggBytes *data;
GNode *asn;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
- if (!egg_asn1x_set_bits_as_raw (asn, (guchar*)"", 0, NULL))
- g_assert_not_reached ();
+ egg_asn1x_take_bits_as_raw (asn, egg_bytes_new_static ("", 0), 0);
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
- egg_assert_cmpsize (n_data, ==, XL (BITS_ZERO));
- g_assert (memcmp (data, BITS_ZERO, n_data) == 0);
+ egg_assert_cmpmem (egg_bytes_get_data (data), egg_bytes_get_size (data), ==, BITS_ZERO, XL (BITS_ZERO));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_have (void)
{
+ EggBytes *data;
GNode *asn;
- guchar *data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBoolean");
g_assert (asn);
@@ -462,12 +589,12 @@ test_have (void)
g_assert (!egg_asn1x_have (asn));
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
g_assert (egg_asn1x_have (asn));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
@@ -483,10 +610,10 @@ test_is_freed (gpointer unused)
static void
test_any_set_raw (void)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- const guchar *check;
- gsize n_data, n_check;
+ EggBytes *data;
+ EggBytes *check;
/* ENCODED SEQUENCE ANY with OCTET STRING */
const gchar SEQ_ENCODING[] = "\x30\x0C\x04\x0A""farnsworth";
@@ -498,22 +625,24 @@ test_any_set_raw (void)
node = egg_asn1x_node (asn, "contents", NULL);
g_assert (node);
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ bytes = egg_bytes_new_with_free_func (SFARNSWORTH, XL (SFARNSWORTH),
+ test_is_freed, NULL);
+ if (!egg_asn1x_set_element_raw (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- egg_assert_cmpsize (n_data, ==, XL (SEQ_ENCODING));
- g_assert (memcmp (data, SEQ_ENCODING, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, SEQ_ENCODING, XL (SEQ_ENCODING));
- check = egg_asn1x_get_raw_element (node, &n_check);
+ check = egg_asn1x_get_element_raw (node);
g_assert (check);
- egg_assert_cmpsize (n_check, ==, XL (SFARNSWORTH));
- g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+ egg_assert_cmpbytes (check, ==, SFARNSWORTH, XL (SFARNSWORTH));
- g_free (data);
+ egg_bytes_unref (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
g_assert (is_freed);
}
@@ -521,10 +650,10 @@ test_any_set_raw (void)
static void
test_any_set_raw_explicit (void)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- const guchar *check;
- gsize n_data, n_check;
+ EggBytes *data;
+ EggBytes *check;
/* ENCODED SEQUENCE [89] ANY with OCTET STRING */
const gchar SEQ_ENCODING[] = "\x30\x0F\xBF\x59\x0C\x04\x0A""farnsworth";
@@ -536,22 +665,23 @@ test_any_set_raw_explicit (void)
node = egg_asn1x_node (asn, "contents", NULL);
g_assert (node);
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ bytes = egg_bytes_new_with_free_func (SFARNSWORTH, XL (SFARNSWORTH), test_is_freed, NULL);
+ if (!egg_asn1x_set_element_raw (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- egg_assert_cmpsize (n_data, ==, XL (SEQ_ENCODING));
- g_assert (memcmp (data, SEQ_ENCODING, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, SEQ_ENCODING, XL (SEQ_ENCODING));
- check = egg_asn1x_get_raw_element (node, &n_check);
+ check = egg_asn1x_get_element_raw (node);
g_assert (check);
- g_assert (n_check == XL (SFARNSWORTH));
- g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+ egg_assert_cmpbytes (check, ==, SFARNSWORTH, XL (SFARNSWORTH));
- g_free (data);
+ egg_bytes_unref (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
g_assert (is_freed);
}
@@ -559,22 +689,26 @@ test_any_set_raw_explicit (void)
static void
test_choice_not_chosen (void)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- gsize n_data;
+ EggBytes *data;
asn = egg_asn1x_create (test_asn1_tab, "TestAnyChoice");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_CHOICE, ==, egg_asn1x_type (asn));
+
node = egg_asn1x_node (asn, "choiceShortTag", NULL);
g_assert (node);
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), NULL))
+ bytes = egg_bytes_new_static (SFARNSWORTH, XL (SFARNSWORTH));
+ if (!egg_asn1x_set_element_raw (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
/* egg_asn1x_set_choice() was not called */
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (!data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data == NULL);
g_assert (egg_asn1x_message (asn));
g_assert (strstr (egg_asn1x_message (asn), "TestAnyChoice") != NULL);
@@ -584,14 +718,16 @@ test_choice_not_chosen (void)
static void
perform_asn1_any_choice_set_raw (const gchar *choice, const gchar *encoding, gsize n_encoding)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- const guchar *check;
- gsize n_data, n_check;
+ EggBytes *data;
+ EggBytes *check;
asn = egg_asn1x_create (test_asn1_tab, "TestAnyChoice");
g_assert (asn);
+ g_assert_cmpint (EGG_ASN1X_CHOICE, ==, egg_asn1x_type (asn));
+
is_freed = FALSE;
node = egg_asn1x_node (asn, choice, NULL);
g_assert (node);
@@ -599,26 +735,27 @@ perform_asn1_any_choice_set_raw (const gchar *choice, const gchar *encoding, gsi
if (!egg_asn1x_set_choice (asn, node))
g_assert_not_reached ();
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ bytes = egg_bytes_new_with_free_func (SFARNSWORTH, XL (SFARNSWORTH), test_is_freed, NULL);
+ if (!egg_asn1x_set_element_raw (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- if (!data) {
+ data = egg_asn1x_encode (asn, NULL);
+ if (data == NULL) {
g_printerr ("%s\n", egg_asn1x_message (asn));
g_assert_not_reached ();
}
- g_assert (data);
+ g_assert (data != NULL);
- egg_assert_cmpsize (n_data, ==, n_encoding);
- g_assert (memcmp (data, encoding, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, encoding, n_encoding);
- check = egg_asn1x_get_raw_element (node, &n_check);
- g_assert (check);
+ check = egg_asn1x_get_element_raw (node);
+ g_assert (check != NULL);
- g_assert (n_check == XL (SFARNSWORTH));
- g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+ egg_assert_cmpbytes (check, ==, SFARNSWORTH, XL (SFARNSWORTH));
- g_free (data);
+ egg_bytes_unref (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
g_assert (is_freed);
}
@@ -640,10 +777,10 @@ test_any_choice_set_raw_long_tag (void)
static void
test_append (void)
{
+ EggBytes *bytes;
GNode *asn;
GNode *child;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
/* SEQUENCE OF with one INTEGER = 1 */
const gchar SEQOF_ONE[] = "\x30\x03\x02\x01\x01";
@@ -651,8 +788,12 @@ test_append (void)
/* SEQUENCE OF with two INTEGER = 1, 2 */
const gchar SEQOF_TWO[] = "\x30\x06\x02\x01\x01\x02\x01\x02";
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSeqOf", SEQOF_ONE, XL (SEQOF_ONE));
+ bytes = egg_bytes_new_static (SEQOF_ONE, XL (SEQOF_ONE));
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSeqOf", bytes);
g_assert (asn);
+ egg_bytes_unref (bytes);
+
+ g_assert_cmpint (EGG_ASN1X_SEQUENCE_OF, ==, egg_asn1x_type (asn));
child = egg_asn1x_append (asn);
g_assert (child);
@@ -661,22 +802,20 @@ test_append (void)
if (!egg_asn1x_set_integer_as_ulong (child, 2))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- g_assert (n_data == XL (SEQOF_TWO));
- g_assert (memcmp (data, SEQOF_TWO, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, SEQOF_TWO, XL (SEQOF_TWO));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_append_and_clear (void)
{
+ EggBytes *data;
GNode *asn;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestSeqOf");
g_assert (asn);
@@ -690,8 +829,8 @@ test_append_and_clear (void)
g_assert_cmpuint (egg_asn1x_count (asn), ==, 0);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
g_assert_cmpuint (egg_asn1x_count (asn), ==, 2);
@@ -699,15 +838,15 @@ test_append_and_clear (void)
g_assert_cmpuint (egg_asn1x_count (asn), ==, 0);
egg_asn1x_destroy (asn);
- g_free (data);
+ egg_bytes_unref (data);
}
static void
test_setof (void)
{
+ EggBytes *bytes;
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
/* SEQUENCE OF with one INTEGER = 3 */
const gchar SETOF_ONE[] = "\x31\x03\x02\x01\x03";
@@ -715,8 +854,12 @@ test_setof (void)
/* SET OF with two INTEGER = 1, 3, 8 */
const gchar SETOF_THREE[] = "\x31\x09\x02\x01\x01\x02\x01\x03\x02\x01\x08";
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSetOf", SETOF_ONE, XL (SETOF_ONE));
- g_assert (asn);
+ bytes = egg_bytes_new_static (SETOF_ONE, XL (SETOF_ONE));
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSetOf", bytes);
+ g_assert (asn != NULL);
+ egg_bytes_unref (bytes);
+
+ g_assert_cmpint (EGG_ASN1X_SET_OF, ==, egg_asn1x_type (asn));
/* Add integer 1, in SET OF DER should sort to front */
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_append (asn), 1))
@@ -726,25 +869,23 @@ test_setof (void)
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_append (asn), 8))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
- if (!data) {
+ data = egg_asn1x_encode (asn, NULL);
+ if (data == NULL) {
g_printerr ("%s\n", egg_asn1x_message (asn));
g_assert_not_reached ();
}
- g_assert (n_data == XL (SETOF_THREE));
- g_assert (memcmp (data, SETOF_THREE, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, SETOF_THREE, XL (SETOF_THREE));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_setof_empty (void)
{
+ EggBytes *data;
GNode *asn;
- gpointer data;
- gsize n_data;
/* SEQUENCE OF with nothing */
const gchar SETOF_NONE[] = "\x31\x00";
@@ -752,29 +893,32 @@ test_setof_empty (void)
asn = egg_asn1x_create (test_asn1_tab, "TestSetOf");
g_assert (asn);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- if (!data) {
+ data = egg_asn1x_encode (asn, NULL);
+ if (data == NULL) {
g_printerr ("%s\n", egg_asn1x_message (asn));
g_assert_not_reached ();
}
- g_assert (n_data == XL (SETOF_NONE));
- g_assert (memcmp (data, SETOF_NONE, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, SETOF_NONE, XL (SETOF_NONE));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_enumerated (void)
{
+ EggBytes *bytes;
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
GQuark value;
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestEnumerated", ENUM_TWO, XL (ENUM_TWO));
- g_assert (asn);
+ bytes = egg_bytes_new_static (ENUM_TWO, XL (ENUM_TWO));
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestEnumerated", bytes);
+ g_assert (asn != NULL);
+ egg_bytes_unref (bytes);
+
+ g_assert_cmpint (EGG_ASN1X_ENUMERATED, ==, egg_asn1x_type (asn));
value = egg_asn1x_get_enumerated (asn);
g_assert (value);
@@ -783,13 +927,12 @@ test_enumerated (void)
if (!egg_asn1x_set_enumerated (asn, g_quark_from_static_string ("valueThree")))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- g_assert (n_data == XL (ENUM_THREE));
- g_assert (memcmp (data, ENUM_THREE, n_data) == 0);
+ egg_assert_cmpbytes (data, ==, ENUM_THREE, XL (ENUM_THREE));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
@@ -802,6 +945,8 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
+ EggBytes *bytes;
+
if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der",
(gchar**)&test->data, &test->n_data, NULL))
g_assert_not_reached ();
@@ -809,8 +954,10 @@ setup (Test *test, gconstpointer unused)
test->asn1 = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_assert (test->asn1 != NULL);
- if (!egg_asn1x_decode (test->asn1, test->data, test->n_data))
+ bytes = egg_bytes_new_static (test->data, test->n_data);
+ if (!egg_asn1x_decode (test->asn1, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
}
static void
@@ -829,9 +976,8 @@ test_node_name (Test* test, gconstpointer unused)
static void
test_asn1_integers (Test* test, gconstpointer unused)
{
+ EggBytes *data;
GNode *asn;
- guchar *data;
- gsize n_data;
gboolean ret;
gulong val;
@@ -848,13 +994,13 @@ test_asn1_integers (Test* test, gconstpointer unused)
g_assert ("couldn't write integer" && ret);
/* Now encode the whole caboodle */
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert ("encoding asn1 didn't work" && data != NULL);
egg_asn1x_destroy (asn);
/* Now decode it all nicely */
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data, n_data);
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data);
g_return_if_fail (asn != NULL);
/* And get out the values */
@@ -870,16 +1016,16 @@ test_asn1_integers (Test* test, gconstpointer unused)
g_assert ("couldn't read integer from asn1" && ret);
g_assert_cmpuint (val, ==, 209384022);
- g_free (data);
+ egg_asn1x_destroy (asn);
+ egg_bytes_unref (data);
}
static void
test_boolean_seq (Test* test, gconstpointer unused)
{
+ EggBytes *data;
GNode *asn = NULL;
gboolean value, ret;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBooleanSeq");
g_assert ("asn test structure is null" && asn != NULL);
@@ -893,8 +1039,8 @@ test_boolean_seq (Test* test, gconstpointer unused)
ret = egg_asn1x_set_boolean (egg_asn1x_node (asn, "boolean", NULL), TRUE);
g_assert (ret == TRUE);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
g_assert (ret);
@@ -903,26 +1049,25 @@ test_boolean_seq (Test* test, gconstpointer unused)
ret = egg_asn1x_set_boolean (egg_asn1x_node (asn, "boolean", NULL), FALSE);
g_assert (ret == TRUE);
- g_free (data);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ egg_bytes_unref (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
g_assert (ret);
g_assert (value == FALSE);
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_write_value (Test* test, gconstpointer unused)
{
+ EggBytes *encoded;
GNode *asn = NULL;
guchar *data;
gsize n_data;
- guchar *encoded;
- gsize n_encoded;
asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
@@ -930,7 +1075,7 @@ test_write_value (Test* test, gconstpointer unused)
if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- encoded = egg_asn1x_encode (asn, NULL, &n_encoded);
+ encoded = egg_asn1x_encode (asn, NULL);
g_assert (encoded);
data = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "data", NULL), NULL, &n_data);
@@ -939,18 +1084,17 @@ test_write_value (Test* test, gconstpointer unused)
g_assert (memcmp (data, "SOME DATA", 9) == 0);
g_free (data);
- g_free (encoded);
+ egg_bytes_unref (encoded);
egg_asn1x_destroy (asn);
}
static void
test_element_length_content (Test* test, gconstpointer unused)
{
+ EggBytes *buffer;
GNode *asn = NULL;
- gchar *buffer;
const guchar *content;
gsize n_content;
- gsize n_buffer;
gssize length;
asn = egg_asn1x_create (test_asn1_tab, "TestData");
@@ -959,15 +1103,17 @@ test_element_length_content (Test* test, gconstpointer unused)
if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
/* Now the real test */
- length = egg_asn1x_element_length (buffer, n_buffer + 1024);
+ length = egg_asn1x_element_length (egg_bytes_get_data (buffer),
+ egg_bytes_get_size (buffer) + 1024);
g_assert_cmpint (length, ==, 13);
- content = egg_asn1x_element_content (buffer, length, &n_content);
- g_assert (content);
+ content = egg_asn1x_element_content (egg_bytes_get_data (buffer),
+ length, &n_content);
+ g_assert (content != NULL);
g_assert_cmpuint (n_content, ==, 11);
content = egg_asn1x_element_content (content, n_content, &n_content);
@@ -975,26 +1121,24 @@ test_element_length_content (Test* test, gconstpointer unused)
g_assert_cmpuint (n_content, ==, 9);
g_assert (memcmp (content, "SOME DATA", 9) == 0);
- const char *BAD_ASN_TAG = "\x00";
+ const guchar *BAD_ASN_TAG = (guchar *)"\x00";
content = egg_asn1x_element_content (BAD_ASN_TAG, 1, &n_content);
g_assert (content == NULL);
- const char *BAD_ASN_LENGTH = "\x30\x80";
+ const guchar *BAD_ASN_LENGTH = (guchar *)"\x30\x80";
content = egg_asn1x_element_content (BAD_ASN_LENGTH, 2, &n_content);
g_assert (content == NULL);
egg_asn1x_destroy (asn);
- g_free (buffer);
+ egg_bytes_unref (buffer);
}
static void
test_read_element (Test* test, gconstpointer unused)
{
+ EggBytes *buffer;
GNode *asn = NULL;
- guchar *buffer;
- gconstpointer data;
- gsize n_data;
- gsize n_buffer;
+ EggBytes *data;
asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
@@ -1002,38 +1146,42 @@ test_read_element (Test* test, gconstpointer unused)
if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
/* Now the real test */
- data = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "data", NULL), &n_data);
+ data = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "data", NULL));
g_assert (data != NULL);
- g_assert_cmpint (n_data, ==, 11);
+ g_assert_cmpint (egg_bytes_get_size (data), ==, 11);
+ egg_bytes_unref (data);
- data = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "data", NULL), &n_data);
- g_assert (data);
- g_assert_cmpuint (n_data, ==, 9);
- g_assert (memcmp (data, "SOME DATA", 9) == 0);
+ data = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "data", NULL));
+ g_assert (data != NULL);
+ egg_assert_cmpbytes (data, ==, "SOME DATA", 9);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
- g_free (buffer);
+ egg_bytes_unref (buffer);
}
static void
test_oid (Test* test, gconstpointer unused)
{
+ EggBytes *buffer;
GNode *asn = NULL;
+ GNode *node;
GQuark oid, check;
- guchar *buffer;
- gsize n_buffer;
asn = egg_asn1x_create (test_asn1_tab, "TestOid");
g_assert ("asn test structure is null" && asn != NULL);
- if (!egg_asn1x_set_oid_as_string (egg_asn1x_node (asn, "oid", NULL), "1.2.34567.89"))
+ node = egg_asn1x_node (asn, "oid", NULL);
+ g_assert_cmpint (EGG_ASN1X_OBJECT_ID, ==, egg_asn1x_type (node));
+
+ if (!egg_asn1x_set_oid_as_string (node, "1.2.34567.89"))
g_assert_not_reached ();
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
/* Now a quark has been defined */
@@ -1047,15 +1195,15 @@ test_oid (Test* test, gconstpointer unused)
if (!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "oid", NULL), g_quark_from_static_string ("5.4.3.2.1678")))
g_assert_not_reached ();
- g_free (buffer);
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ egg_bytes_unref (buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "oid", NULL));
g_assert (oid);
g_assert_cmpstr (g_quark_to_string (oid), ==, "5.4.3.2.1678");
- g_free (buffer);
+ egg_bytes_unref (buffer);
egg_asn1x_destroy (asn);
}
@@ -1211,8 +1359,12 @@ main (int argc, char **argv)
g_test_add_func ("/asn1/unsigned", test_unsigned);
g_test_add_func ("/asn1/octet_string", test_octet_string);
g_test_add_func ("/asn1/generalized_time", test_generalized_time);
- g_test_add_func ("/asn1/implicit", test_implicit);
- g_test_add_func ("/asn1/explicit", test_explicit);
+ g_test_add_func ("/asn1/implicit/decode", test_implicit_decode);
+ g_test_add_func ("/asn1/implicit/encode", test_implicit_encode);
+ g_test_add_func ("/asn1/explicit/decode", test_explicit_decode);
+ g_test_add_func ("/asn1/explicit/encode", test_explicit_encode);
+ g_test_add_func ("/asn1/universal/decode", test_universal_decode);
+ g_test_add_func ("/asn1/universal/encode", test_universal_encode);
g_test_add_func ("/asn1/bit_string_decode", test_bit_string_decode);
g_test_add_func ("/asn1/bit_string_decode_bad", test_bit_string_decode_bad);
g_test_add_func ("/asn1/bit_string_decode_ulong", test_bit_string_decode_ulong);
diff --git a/egg/tests/test-asn1x.c b/egg/tests/test-asn1x.c
index baeba55..720d62a 100644
--- a/egg/tests/test-asn1x.c
+++ b/egg/tests/test-asn1x.c
@@ -64,32 +64,37 @@ build_personal_name (void)
#endif
static void
-test_some_asn1_stuff (const ASN1_ARRAY_TYPE *defs, const gchar *file, const gchar *identifier)
+test_some_asn1_stuff (const EggAsn1xDef *defs,
+ const gchar *file,
+ const gchar *identifier)
{
GNode *asn;
- gpointer data, encoded;
- gsize n_data, n_encoded;
+ EggBytes *encoded;
+ gpointer data;
+ gsize n_data;
+ EggBytes *bytes;
if (!g_file_get_contents (file, (gchar**)&data, &n_data, NULL))
g_assert_not_reached ();
+ bytes = egg_bytes_new_take (data, n_data);
asn = egg_asn1x_create (defs, identifier);
egg_asn1x_dump (asn);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, bytes))
g_warning ("decode of %s failed: %s", identifier, egg_asn1x_message (asn));
- encoded = egg_asn1x_encode (asn, NULL, &n_encoded);
+ encoded = egg_asn1x_encode (asn, NULL);
if (encoded == NULL)
g_warning ("encode of %s failed: %s", identifier, egg_asn1x_message (asn));
/* Decode the encoding */
- if (!egg_asn1x_decode (asn, encoded, n_encoded))
+ if (!egg_asn1x_decode (asn, encoded))
g_warning ("decode of encoded %s failed: %s", identifier, egg_asn1x_message (asn));
egg_asn1x_clear (asn);
egg_asn1x_destroy (asn);
- g_free (encoded);
- g_free (data);
+ egg_bytes_unref (bytes);
+ egg_bytes_unref (encoded);
}
int
diff --git a/egg/tests/test-dh.c b/egg/tests/test-dh.c
index ba9fcfc..a676f93 100644
--- a/egg/tests/test-dh.c
+++ b/egg/tests/test-dh.c
@@ -34,7 +34,7 @@
#include <glib.h>
#include <gcrypt.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
test_perform (void)
diff --git a/egg/tests/test-dn.c b/egg/tests/test-dn.c
index 98f5a43..929cec2 100644
--- a/egg/tests/test-dn.c
+++ b/egg/tests/test-dn.c
@@ -27,10 +27,10 @@
#include "egg/egg-asn1x.h"
#include "egg/egg-dn.h"
#include "egg/egg-oid.h"
+#include "egg/egg-testing.h"
#include <glib.h>
#include <gcrypt.h>
-#include <libtasn1.h>
#include <stdlib.h>
#include <stdio.h>
@@ -45,6 +45,8 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
+ EggBytes *bytes;
+
if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der",
(gchar**)&test->data, &test->n_data, NULL))
g_assert_not_reached ();
@@ -52,8 +54,10 @@ setup (Test *test, gconstpointer unused)
test->asn1 = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_assert (test->asn1 != NULL);
- if (!egg_asn1x_decode (test->asn1, test->data, test->n_data))
+ bytes = egg_bytes_new_static (test->data, test->n_data);
+ if (!egg_asn1x_decode (test->asn1, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
}
static void
@@ -80,18 +84,23 @@ test_dn_value (Test* test, gconstpointer unused)
{
const guchar value[] = { 0x13, 0x1a, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x41 };
gsize n_value = 28;
+ EggBytes *bytes;
GQuark oid;
gchar *text;
/* Some printable strings */
oid = g_quark_from_static_string ("2.5.4.3");
- text = egg_dn_print_value (oid, value, n_value);
+ bytes = egg_bytes_new_static (value, n_value);
+ text = egg_dn_print_value (oid, bytes);
+ egg_bytes_unref (bytes);
g_assert_cmpstr (text, ==, "Thawte Personal Premium CA");
g_free (text);
/* Unknown oid */
oid = g_quark_from_static_string ("1.1.1.1.1.1");
- text = egg_dn_print_value (oid, value, n_value);
+ bytes = egg_bytes_new_static (value, n_value);
+ text = egg_dn_print_value (oid, bytes);
+ egg_bytes_unref (bytes);
g_assert_cmpstr (text, ==, "#131A54686177746520506572736F6E616C205072656D69756D204341");
g_free (text);
}
@@ -99,14 +108,17 @@ test_dn_value (Test* test, gconstpointer unused)
static int last_index = 0;
static void
-concatenate_dn (guint index, GQuark oid, const guchar *value, gsize n_value, gpointer user_data)
+concatenate_dn (guint index,
+ GQuark oid,
+ EggBytes *value,
+ gpointer user_data)
{
GString *dn = user_data;
gchar *text;
g_assert (oid);
- g_assert (value);
- g_assert (n_value);
+ g_assert (value != NULL);
+ g_assert (egg_bytes_get_size (value) != 0);
g_assert (index == last_index);
++last_index;
@@ -118,7 +130,7 @@ concatenate_dn (guint index, GQuark oid, const guchar *value, gsize n_value, gpo
g_string_append (dn, egg_oid_get_name (oid));
g_string_append_c (dn, '=');
- text = egg_dn_print_value (oid, value, n_value);
+ text = egg_dn_print_value (oid, value);
g_string_append (dn, text);
g_free (text);
}
@@ -164,6 +176,43 @@ test_read_dn_part (Test* test, gconstpointer unused)
g_assert (value == NULL);
}
+static void
+test_add_dn_part (Test *test,
+ gconstpointer unused)
+{
+ EggBytes *check;
+ EggBytes *dn;
+ GNode *check_dn;
+ GNode *asn;
+ GNode *node;
+
+ asn = egg_asn1x_create (pkix_asn1_tab, "Name");
+ node = egg_asn1x_node (asn, "rdnSequence", NULL);
+ egg_asn1x_set_choice (asn, node);
+ egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.6"), "ZA");
+ egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.8"), "Western Cape");
+ egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.7"), "Cape Town");
+ egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.10"), "Thawte Consulting");
+ egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.11"), "Certification Services Division");
+ egg_dn_add_string_part (node, g_quark_from_static_string ("2.5.4.3"), "Thawte Personal Premium CA");
+ egg_dn_add_string_part (node, g_quark_from_static_string ("1.2.840.113549.1.9.1"), "personal-premium thawte com");
+
+ dn = egg_asn1x_encode (asn, NULL);
+ if (dn == NULL) {
+ g_warning ("couldn't encode dn: %s", egg_asn1x_message (asn));
+ g_assert_not_reached ();
+ }
+
+ check_dn = egg_asn1x_node (test->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL);
+ check = egg_asn1x_encode (check_dn, NULL);
+ egg_asn1x_destroy (asn);
+
+ egg_assert_cmpbytes (dn, ==, egg_bytes_get_data (check), egg_bytes_get_size (check));
+
+ egg_bytes_unref (dn);
+ egg_bytes_unref (check);
+}
+
int
main (int argc, char **argv)
{
@@ -173,6 +222,7 @@ main (int argc, char **argv)
g_test_add ("/dn/dn_value", Test, NULL, setup, test_dn_value, teardown);
g_test_add ("/dn/parse_dn", Test, NULL, setup, test_parse_dn, teardown);
g_test_add ("/dn/read_dn_part", Test, NULL, setup, test_read_dn_part, teardown);
+ g_test_add ("/dn/add_dn_part", Test, NULL, setup, test_add_dn_part, teardown);
return g_test_run ();
}
diff --git a/egg/tests/test-hkdf.c b/egg/tests/test-hkdf.c
index 93f16df..de1d196 100644
--- a/egg/tests/test-hkdf.c
+++ b/egg/tests/test-hkdf.c
@@ -33,7 +33,7 @@
#include <gcrypt.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
test_hkdf_test_case_1 (void)
diff --git a/egg/tests/test-openssl.c b/egg/tests/test-openssl.c
index da5e457..87596fd 100644
--- a/egg/tests/test-openssl.c
+++ b/egg/tests/test-openssl.c
@@ -36,11 +36,12 @@
#include <string.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+#include <egg/egg-bytes.h>
+
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
typedef struct {
- guchar *input;
- gsize n_input;
+ EggBytes *input;
GQuark reftype;
guchar *refenc;
guchar *refdata;
@@ -52,14 +53,19 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
- if (!g_file_get_contents (SRCDIR "/files/pem-rsa-enc.key", (gchar**)&test->input, &test->n_input, NULL))
+ gchar *contents;
+ gsize length;
+
+ if (!g_file_get_contents (SRCDIR "/files/pem-rsa-enc.key", &contents, &length, NULL))
g_assert_not_reached ();
+
+ test->input = egg_bytes_new_take (contents, length);
}
static void
teardown (Test *test, gconstpointer unused)
{
- g_free (test->input);
+ egg_bytes_unref (test->input);
g_free (test->refenc);
egg_secure_free (test->refdata);
g_hash_table_destroy (test->refheaders);
@@ -73,24 +79,21 @@ copy_each_key_value (gpointer key, gpointer value, gpointer user_data)
static void
parse_reference (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
Test *test = user_data;
- gboolean res;
const gchar *dekinfo;
g_assert (type);
test->reftype = type;
g_assert ("no data in PEM callback" && data != NULL);
- g_assert ("no data in PEM callback" && n_data > 0);
- test->refenc = g_memdup (data, n_data);
- test->n_refenc = n_data;
+ g_assert ("no data in PEM callback" && egg_bytes_get_size (data) > 0);
+ test->refenc = g_memdup (egg_bytes_get_data (data), egg_bytes_get_size (data));
+ test->n_refenc = egg_bytes_get_size (data);
g_assert ("no headers present in file" && headers != NULL);
g_assert (!test->refheaders);
@@ -99,10 +102,9 @@ parse_reference (GQuark type,
dekinfo = egg_openssl_get_dekinfo (headers);
g_assert ("no dekinfo in headers" && dekinfo != NULL);
- res = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, n_data, &test->refdata, &test->n_refdata);
- g_assert ("couldn't openssl decrypt block" && res == TRUE);
+ test->refdata = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, &test->n_refdata);
g_assert ("no data returned from openssl decrypt" && test->refdata != NULL);
- g_assert ("invalid amount of data returned from openssl decrypt" && test->n_refdata == n_data);
+ g_assert ("invalid amount of data returned from openssl decrypt" && test->n_refdata == egg_bytes_get_size (data));
}
static void
@@ -110,7 +112,7 @@ test_parse_reference (Test *test, gconstpointer unused)
{
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
g_assert ("parse_reference() wasn't called" && test->refdata != NULL);
@@ -122,22 +124,26 @@ test_write_reference (Test *test, gconstpointer unused)
const gchar *dekinfo;
guchar *encrypted;
gsize n_encrypted;
- gboolean ret;
+ EggBytes *data;
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
dekinfo = egg_openssl_get_dekinfo (test->refheaders);
g_assert ("no dekinfo in headers" && dekinfo != NULL);
- ret = egg_openssl_encrypt_block (dekinfo, "booo", 4, test->refdata, test->n_refdata, &encrypted, &n_encrypted);
- g_assert ("couldn't openssl encrypt block" && ret == TRUE);
+ data = egg_bytes_new_static (test->refdata, test->n_refdata);
+ encrypted = egg_openssl_encrypt_block (dekinfo, "booo", 4, data, &n_encrypted);
+ egg_bytes_unref (data);
+
g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
g_assert ("invalid amount of data returned from openssl encrypt" && test->n_refdata <= n_encrypted);
g_assert ("data length doesn't match input length" && n_encrypted == test->n_refenc);
g_assert ("data doesn't match input" && memcmp (encrypted, test->refenc, n_encrypted) == 0);
+
+ g_free (encrypted);
}
static void
@@ -147,7 +153,7 @@ test_write_exactly_same (Test *test, gconstpointer unused)
gsize n_result;
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
result = egg_armor_write (test->refenc, test->n_refenc, test->reftype,
@@ -159,7 +165,7 @@ test_write_exactly_same (Test *test, gconstpointer unused)
* and line endings.
*/
- egg_assert_cmpmem (test->input, test->n_input, ==, result, n_result);
+ egg_assert_cmpbytes (test->input, ==, result, n_result);
g_free (result);
}
@@ -171,25 +177,28 @@ static void
test_openssl_roundtrip (Test *test, gconstpointer unused)
{
const gchar *dekinfo;
- gboolean res;
- gboolean ret;
guchar *encrypted, *decrypted;
gsize n_encrypted, n_decrypted;
+ EggBytes *data;
int i;
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
dekinfo = egg_openssl_prep_dekinfo (test->refheaders);
- 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);
+ data = egg_bytes_new_static (TEST_DATA, TEST_DATA_L);
+ encrypted = egg_openssl_encrypt_block (dekinfo, "password", -1, data, &n_encrypted);
+ egg_bytes_unref (data);
+
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 = egg_openssl_decrypt_block (dekinfo, "password", 8, encrypted, n_encrypted, &decrypted, &n_decrypted);
- g_assert ("couldn't openssl decrypt block" && res == TRUE);
+ data = egg_bytes_new_with_free_func (encrypted, n_encrypted, egg_secure_free, encrypted);
+ decrypted = egg_openssl_decrypt_block (dekinfo, "password", 8, data, &n_decrypted);
+ egg_bytes_unref (data);
+
g_assert ("no data returned from openssl decrypt" && decrypted != NULL);
/* Check that the data was decrypted properly */
@@ -199,6 +208,8 @@ test_openssl_roundtrip (Test *test, gconstpointer unused)
/* Check that the remainder is all zeros */
for (i = TEST_DATA_L; i < n_decrypted; ++i)
g_assert ("non null byte in padding" && decrypted[i] == 0);
+
+ egg_secure_free (decrypted);
}
int
diff --git a/egg/tests/test-secmem.c b/egg/tests/test-secmem.c
index 20beec9..6ac5e96 100644
--- a/egg/tests/test-secmem.c
+++ b/egg/tests/test-secmem.c
@@ -32,7 +32,7 @@
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
/* Declared in egg-secure-memory.c */
extern int egg_secure_warnings;
diff --git a/egg/tests/test-symkey.c b/egg/tests/test-symkey.c
index b65ee30..b4c1e2d 100644
--- a/egg/tests/test-symkey.c
+++ b/egg/tests/test-symkey.c
@@ -33,7 +33,7 @@
#include <stdio.h>
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static const struct {
const gchar *password;
@@ -138,6 +138,8 @@ test_generate_key_simple (void)
gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
g_assert (ret && "invalid simple key generated");
+
+ egg_secure_free (key);
}
}
@@ -165,6 +167,8 @@ test_generate_key_pkcs12 (void)
gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
g_assert ("invalid pkcs12 key generated" && ret);
+
+ egg_secure_free (key);
}
}
@@ -192,6 +196,8 @@ test_generate_key_pbkdf2 (void)
gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
g_assert ("invalid pbkdf2 key generated" && ret);
+
+ egg_secure_free (key);
}
}
@@ -220,6 +226,7 @@ test_generate_key_pbe (void)
g_assert ("invalid pbe key generated" && ret);
+ egg_secure_free (key);
}
}
diff --git a/egg/tests/test.asn b/egg/tests/test.asn
index 28cb176..5412a63 100644
--- a/egg/tests/test.asn
+++ b/egg/tests/test.asn
@@ -18,6 +18,8 @@ TestImplicit ::= [5] IMPLICIT OCTET STRING
TestExplicit ::= [5] EXPLICIT OCTET STRING
+TestUniversal ::= [UNIVERSAL 5] IMPLICIT OCTET STRING
+
TestBitString ::= BIT STRING
TestIntegers ::= SEQUENCE {
diff --git a/pam/gkr-pam-stubs.c b/pam/gkr-pam-stubs.c
index 13c4436..cccec13 100644
--- a/pam/gkr-pam-stubs.c
+++ b/pam/gkr-pam-stubs.c
@@ -30,21 +30,23 @@
* locking for memory between threads
*/
-void
+static void
egg_memory_lock (void)
{
/* No threads in PAM, no locking */
}
-void
+static void
egg_memory_unlock (void)
{
/* No threads in PAM, no locking */
}
-void*
+static void *
egg_memory_fallback (void *p, size_t sz)
{
/* Handles allocation, reallocation and freeing */
return realloc (p, sz);
}
+
+EGG_SECURE_DEFINE_GLOBALS (egg_memory_lock, egg_memory_unlock, egg_memory_fallback);
diff --git a/pkcs11/gkm/Makefile.am b/pkcs11/gkm/Makefile.am
index 54f867c..f0e902c 100644
--- a/pkcs11/gkm/Makefile.am
+++ b/pkcs11/gkm/Makefile.am
@@ -1,4 +1,3 @@
-
INCLUDES = \
-I$(top_builddir) \
-I$(top_srcdir) \
@@ -13,8 +12,7 @@ noinst_LTLIBRARIES = \
libgkm.la
BUILT_SOURCES = \
- gkm-marshal.c gkm-marshal.h \
- asn1-def-pk.h asn1-def-pkix.h
+ gkm-marshal.c gkm-marshal.h
libgkm_la_SOURCES = \
gkm-aes-key.c gkm-aes-key.h \
@@ -83,16 +81,8 @@ gkm-marshal.c: gkm-marshal.list $(GLIB_GENMARSHAL)
echo "#include \"gkm-marshal.h\"" > $@ && \
$(GLIB_GENMARSHAL) $< --body --prefix=gkm_marshal >> $@
-asn1-def-pk.h: pk.asn
- $(ASN1PARSER) -o asn1-def-pk.h $<
-
-asn1-def-pkix.h: pkix.asn
- $(ASN1PARSER) -o asn1-def-pkix.h $<
-
EXTRA_DIST = \
- gkm-marshal.list \
- pkix.asn \
- pk.asn
+ gkm-marshal.list
# -------------------------------------------------------------------------------
diff --git a/pkcs11/gkm/gkm-attributes.c b/pkcs11/gkm/gkm-attributes.c
index 52f5894..71f6af9 100644
--- a/pkcs11/gkm/gkm-attributes.c
+++ b/pkcs11/gkm/gkm-attributes.c
@@ -247,6 +247,13 @@ gkm_attribute_set_data (CK_ATTRIBUTE_PTR attr, gconstpointer value, gsize n_valu
}
CK_RV
+gkm_attribute_set_bytes (CK_ATTRIBUTE_PTR attr,
+ EggBytes *value)
+{
+ return gkm_attribute_set_data (attr, egg_bytes_get_data (value), egg_bytes_get_size (value));
+}
+
+CK_RV
gkm_attribute_set_mpi (CK_ATTRIBUTE_PTR attr, gcry_mpi_t mpi)
{
gsize len;
diff --git a/pkcs11/gkm/gkm-attributes.h b/pkcs11/gkm/gkm-attributes.h
index 7f09fac..3c300af 100644
--- a/pkcs11/gkm/gkm-attributes.h
+++ b/pkcs11/gkm/gkm-attributes.h
@@ -28,6 +28,8 @@
#include "pkcs11/pkcs11.h"
+#include "egg/egg-bytes.h"
+
CK_RV gkm_attribute_get_bool (CK_ATTRIBUTE_PTR attr,
gboolean *value);
@@ -67,6 +69,9 @@ CK_RV gkm_attribute_set_data (CK_ATTRI
gconstpointer value,
gsize n_value);
+CK_RV gkm_attribute_set_bytes (CK_ATTRIBUTE_PTR attr,
+ EggBytes *value);
+
CK_RV gkm_attribute_set_mpi (CK_ATTRIBUTE_PTR attr,
gcry_mpi_t mpi);
diff --git a/pkcs11/gkm/gkm-certificate.c b/pkcs11/gkm/gkm-certificate.c
index 1e3e2f2..ca5a2e0 100644
--- a/pkcs11/gkm/gkm-certificate.c
+++ b/pkcs11/gkm/gkm-certificate.c
@@ -53,8 +53,7 @@ enum {
struct _GkmCertificatePrivate {
GkmCertificateKey *key;
GNode *asn1;
- guchar *data;
- gsize n_data;
+ EggBytes *der;
gchar *label;
};
@@ -122,6 +121,8 @@ factory_create_certificate (GkmSession *session, GkmTransaction *transaction,
{
CK_ATTRIBUTE_PTR attr;
GkmCertificate *cert;
+ EggBytes *bytes;
+ gboolean ret;
g_return_val_if_fail (GKM_IS_TRANSACTION (transaction), NULL);
g_return_val_if_fail (attrs || !n_attrs, NULL);
@@ -139,7 +140,11 @@ factory_create_certificate (GkmSession *session, GkmTransaction *transaction,
NULL);
/* Load the certificate from the data specified */
- if (!gkm_serializable_load (GKM_SERIALIZABLE (cert), NULL, attr->pValue, attr->ulValueLen)) {
+ bytes = egg_bytes_new (attr->pValue, attr->ulValueLen);
+ ret = gkm_serializable_load (GKM_SERIALIZABLE (cert), NULL, bytes);
+ egg_bytes_unref (bytes);
+
+ if(!ret) {
gkm_transaction_fail (transaction, CKR_ATTRIBUTE_VALUE_INVALID);
g_object_unref (cert);
return NULL;
@@ -162,7 +167,7 @@ gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
{
GkmCertificate *self = GKM_CERTIFICATE (base);
CK_ULONG category;
- const guchar *cdata;
+ EggBytes *cdata;
guchar *data;
gsize n_data;
time_t when;
@@ -191,11 +196,13 @@ gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
return gkm_attribute_set_ulong (attr, category);
case CKA_CHECK_VALUE:
- g_return_val_if_fail (self->pv->data, CKR_GENERAL_ERROR);
+ g_return_val_if_fail (self->pv->der != NULL, CKR_GENERAL_ERROR);
n_data = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
g_return_val_if_fail (n_data && n_data > 3, CKR_GENERAL_ERROR);
data = g_new0 (guchar, n_data);
- gcry_md_hash_buffer (GCRY_MD_SHA1, data, self->pv->data, self->pv->n_data);
+ gcry_md_hash_buffer (GCRY_MD_SHA1, data,
+ egg_bytes_get_data (self->pv->der),
+ egg_bytes_get_size (self->pv->der));
rv = gkm_attribute_set_data (attr, data, 3);
g_free (data);
return rv;
@@ -213,9 +220,11 @@ gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
case CKA_SUBJECT:
g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
- cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", NULL), &n_data);
+ cdata = egg_asn1x_get_element_raw (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", NULL));
g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
- return gkm_attribute_set_data (attr, cdata, n_data);
+ rv = gkm_attribute_set_bytes (attr, cdata);
+ egg_bytes_unref (cdata);
+ return rv;
case CKA_ID:
if (!self->pv->key)
@@ -224,19 +233,23 @@ gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
case CKA_ISSUER:
g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
- cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "issuer", NULL), &n_data);
+ cdata = egg_asn1x_get_element_raw (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "issuer", NULL));
g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
- return gkm_attribute_set_data (attr, cdata, n_data);
+ rv = gkm_attribute_set_bytes (attr, cdata);
+ egg_bytes_unref (cdata);
+ return rv;
case CKA_SERIAL_NUMBER:
g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
- cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "serialNumber", NULL), &n_data);
+ cdata = egg_asn1x_get_element_raw (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "serialNumber", NULL));
g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
- return gkm_attribute_set_data (attr, cdata, n_data);
+ rv = gkm_attribute_set_bytes (attr, cdata);
+ egg_bytes_unref (cdata);
+ return rv;
case CKA_VALUE:
- g_return_val_if_fail (self->pv->data, CKR_GENERAL_ERROR);
- return gkm_attribute_set_data (attr, self->pv->data, self->pv->n_data);
+ g_return_val_if_fail (self->pv->der != NULL, CKR_GENERAL_ERROR);
+ return gkm_attribute_set_bytes (attr, self->pv->der);
/* These are only used for strange online certificates which we don't support */
case CKA_URL:
@@ -287,7 +300,8 @@ gkm_certificate_finalize (GObject *obj)
GkmCertificate *self = GKM_CERTIFICATE (obj);
g_assert (!self->pv->key);
- g_free (self->pv->data);
+ if (self->pv->der)
+ egg_bytes_unref (self->pv->der);
g_free (self->pv->label);
egg_asn1x_destroy (self->pv->asn1);
@@ -358,40 +372,36 @@ gkm_certificate_class_init (GkmCertificateClass *klass)
}
static gboolean
-gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
+gkm_certificate_real_load (GkmSerializable *base,
+ GkmSecret *login,
+ EggBytes *data)
{
GkmCertificate *self = GKM_CERTIFICATE (base);
GNode *asn1 = NULL;
GkmDataResult res;
- guchar *copy, *keydata;
- gsize n_keydata;
+ EggBytes *keydata;
gcry_sexp_t sexp;
GkmSexp *wrapper;
- g_return_val_if_fail (GKM_IS_CERTIFICATE (self), FALSE);
-
- if (!data || !n_data) {
+ if (egg_bytes_get_size (data) == 0) {
g_message ("cannot load empty certificate file");
return FALSE;
}
- copy = g_memdup (data, n_data);
-
/* Parse the ASN1 data */
- res = gkm_data_der_read_certificate (copy, n_data, &asn1);
+ res = gkm_data_der_read_certificate (data, &asn1);
if (res != GKM_DATA_SUCCESS) {
g_message ("couldn't parse certificate data");
- g_free (copy);
return FALSE;
}
/* Generate a raw public key from our certificate */
- keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL, &n_keydata);
+ keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL);
g_return_val_if_fail (keydata, FALSE);
/* Now create us a nice public key with that identifier */
- res = gkm_data_der_read_public_key_info (keydata, n_keydata, &sexp);
- g_free (keydata);
+ res = gkm_data_der_read_public_key_info (keydata, &sexp);
+ egg_bytes_unref (keydata);
switch (res) {
@@ -417,7 +427,6 @@ gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, gconstpointe
case GKM_DATA_FAILURE:
case GKM_DATA_LOCKED:
g_warning ("couldn't parse certificate key data");
- g_free (copy);
egg_asn1x_destroy (asn1);
return FALSE;
@@ -426,9 +435,10 @@ gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, gconstpointe
break;
}
- g_free (self->pv->data);
- self->pv->data = copy;
- self->pv->n_data = n_data;
+ egg_bytes_ref (data);
+ if (self->pv->der)
+ egg_bytes_unref (self->pv->der);
+ self->pv->der = data;
egg_asn1x_destroy (self->pv->asn1);
self->pv->asn1 = asn1;
@@ -436,18 +446,15 @@ gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, gconstpointe
return TRUE;
}
-static gboolean
-gkm_certificate_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data)
+static EggBytes *
+gkm_certificate_real_save (GkmSerializable *base,
+ GkmSecret *login)
{
GkmCertificate *self = GKM_CERTIFICATE (base);
g_return_val_if_fail (GKM_IS_CERTIFICATE (self), FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
- *n_data = self->pv->n_data;
- *data = g_memdup (self->pv->data, self->pv->n_data);
- return TRUE;
+ return egg_bytes_ref (self->pv->der);
}
static void
@@ -465,9 +472,8 @@ gkm_certificate_serializable (GkmSerializableIface *iface)
gboolean
gkm_certificate_calc_category (GkmCertificate *self, GkmSession *session, CK_ULONG* category)
{
- const guchar *extension;
+ EggBytes *extension;
GkmManager *manager;
- gsize n_extension;
GkmDataResult res;
gboolean is_ca;
GkmObject *object;
@@ -486,9 +492,9 @@ gkm_certificate_calc_category (GkmCertificate *self, GkmSession *session, CK_ULO
}
/* Read in the Basic Constraints section */
- extension = gkm_certificate_get_extension (self, OID_BASIC_CONSTRAINTS, &n_extension, NULL);
+ extension = gkm_certificate_get_extension (self, OID_BASIC_CONSTRAINTS, NULL);
if (extension != NULL) {
- res = gkm_data_der_read_basic_constraints (extension, n_extension, &is_ca, NULL);
+ res = gkm_data_der_read_basic_constraints (extension, &is_ca, NULL);
if (res != GKM_DATA_SUCCESS)
return FALSE;
@@ -512,9 +518,9 @@ gkm_certificate_get_public_key (GkmCertificate *self)
return self->pv->key;
}
-const guchar*
+EggBytes *
gkm_certificate_get_extension (GkmCertificate *self, GQuark oid,
- gsize *n_extension, gboolean *critical)
+ gboolean *critical)
{
guchar *val;
gsize n_val;
@@ -523,7 +529,6 @@ gkm_certificate_get_extension (GkmCertificate *self, GQuark oid,
g_return_val_if_fail (GKM_IS_CERTIFICATE (self), NULL);
g_return_val_if_fail (self->pv->asn1, NULL);
g_return_val_if_fail (oid, NULL);
- g_return_val_if_fail (n_extension, NULL);
index = find_certificate_extension (self, oid);
if (index <= 0)
@@ -548,7 +553,7 @@ gkm_certificate_get_extension (GkmCertificate *self, GQuark oid,
/* And the extension value */
return egg_asn1x_get_raw_value (egg_asn1x_node (self->pv->asn1, "tbsCertificate",
- "extensions", index, "extnValue", NULL), n_extension);
+ "extensions", index, "extnValue", NULL));
}
const gchar*
@@ -593,14 +598,15 @@ gkm_certificate_hash (GkmCertificate *self, int hash_algo, gsize *n_hash)
guchar *hash;
g_return_val_if_fail (GKM_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (self->pv->data, NULL);
+ g_return_val_if_fail (self->pv->der != NULL, NULL);
g_return_val_if_fail (n_hash, NULL);
*n_hash = gcry_md_get_algo_dlen (hash_algo);
g_return_val_if_fail (*n_hash > 0, NULL);
hash = g_malloc0 (*n_hash);
- gcry_md_hash_buffer (hash_algo, hash, self->pv->data, self->pv->n_data);
+ gcry_md_hash_buffer (hash_algo, hash, egg_bytes_get_data (self->pv->der),
+ egg_bytes_get_size (self->pv->der));
return hash;
}
@@ -609,11 +615,11 @@ gconstpointer
gkm_certificate_der_data (GkmCertificate *self, gsize *n_data)
{
g_return_val_if_fail (GKM_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (self->pv->data, NULL);
+ g_return_val_if_fail (self->pv->der != NULL, NULL);
g_return_val_if_fail (n_data, NULL);
- *n_data = self->pv->n_data;
- return self->pv->data;
+ *n_data = egg_bytes_get_size (self->pv->der);
+ return egg_bytes_get_data (self->pv->der);
}
GkmFactory*
diff --git a/pkcs11/gkm/gkm-certificate.h b/pkcs11/gkm/gkm-certificate.h
index ac630b3..506a17f 100644
--- a/pkcs11/gkm/gkm-certificate.h
+++ b/pkcs11/gkm/gkm-certificate.h
@@ -27,6 +27,8 @@
#include "gkm-object.h"
#include "gkm-types.h"
+#include "egg/egg-bytes.h"
+
#define GKM_FACTORY_CERTIFICATE (gkm_certificate_get_factory ())
#define GKM_TYPE_CERTIFICATE (gkm_certificate_get_type ())
@@ -58,9 +60,8 @@ gboolean gkm_certificate_calc_category (GkmCertificat
GkmCertificateKey* gkm_certificate_get_public_key (GkmCertificate *self);
-const guchar* gkm_certificate_get_extension (GkmCertificate *self,
+EggBytes * gkm_certificate_get_extension (GkmCertificate *self,
GQuark oid,
- gsize *n_extension,
gboolean *critical);
const gchar* gkm_certificate_get_label (GkmCertificate *self);
diff --git a/pkcs11/gkm/gkm-data-asn1.c b/pkcs11/gkm/gkm-data-asn1.c
index 6641395..5765862 100644
--- a/pkcs11/gkm/gkm-data-asn1.c
+++ b/pkcs11/gkm/gkm-data-asn1.c
@@ -31,18 +31,19 @@ gboolean
gkm_data_asn1_read_mpi (GNode *asn, gcry_mpi_t *mpi)
{
gcry_error_t gcry;
+ EggBytes *buf;
gsize sz;
- const guchar *buf;
g_return_val_if_fail (asn, FALSE);
g_return_val_if_fail (mpi, FALSE);
- buf = egg_asn1x_get_raw_value (asn, &sz);
+ buf = egg_asn1x_get_raw_value (asn);
if (!buf)
return FALSE;
/* Automatically stores in secure memory if DER data is secure */
- gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_STD, buf, sz, &sz);
+ sz = egg_bytes_get_size (buf);
+ gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_STD, egg_bytes_get_data (buf), sz, &sz);
if (gcry != 0)
return FALSE;
@@ -53,6 +54,7 @@ gboolean
gkm_data_asn1_write_mpi (GNode *asn, gcry_mpi_t mpi)
{
gcry_error_t gcry;
+ EggBytes *bytes;
gsize len;
guchar *buf;
@@ -69,5 +71,9 @@ gkm_data_asn1_write_mpi (GNode *asn, gcry_mpi_t mpi)
gcry = gcry_mpi_print (GCRYMPI_FMT_STD, buf, len, &len, mpi);
g_return_val_if_fail (gcry == 0, FALSE);
- return egg_asn1x_set_integer_as_raw (asn, buf, len, gcry_free);
+ bytes = egg_bytes_new_with_free_func (buf, len, gcry_free, buf);
+ egg_asn1x_set_integer_as_raw (asn, bytes);
+ egg_bytes_unref (bytes);
+
+ return TRUE;
}
diff --git a/pkcs11/gkm/gkm-data-der.c b/pkcs11/gkm/gkm-data-der.c
index d9a5001..0dfc76d 100644
--- a/pkcs11/gkm/gkm-data-der.c
+++ b/pkcs11/gkm/gkm-data-der.c
@@ -77,7 +77,8 @@ init_quarks (void)
" (e %m)))"
GkmDataResult
-gkm_data_der_read_public_key_rsa (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_public_key_rsa (EggBytes *data,
+ gcry_sexp_t *s_key)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GNode *asn = NULL;
@@ -86,7 +87,7 @@ gkm_data_der_read_public_key_rsa (gconstpointer data, gsize n_data, gcry_sexp_t
n = e = NULL;
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data);
if (!asn)
goto done;
@@ -125,7 +126,8 @@ done:
" (u %m)))"
GkmDataResult
-gkm_data_der_read_private_key_rsa (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_private_key_rsa (EggBytes *data,
+ gcry_sexp_t *s_key)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
gcry_mpi_t n, e, d, p, q, u;
@@ -136,7 +138,7 @@ gkm_data_der_read_private_key_rsa (gconstpointer data, gsize n_data, gcry_sexp_t
n = e = d = p = q = u = NULL;
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data);
if (!asn)
goto done;
@@ -202,7 +204,8 @@ done:
" (y %m)))"
GkmDataResult
-gkm_data_der_read_public_key_dsa (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_public_key_dsa (EggBytes *data,
+ gcry_sexp_t *s_key)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GNode *asn = NULL;
@@ -211,7 +214,7 @@ gkm_data_der_read_public_key_dsa (gconstpointer data, gsize n_data, gcry_sexp_t
p = q = g = y = NULL;
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPublicKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPublicKey", data);
if (!asn)
goto done;
@@ -244,8 +247,8 @@ done:
}
GkmDataResult
-gkm_data_der_read_public_key_dsa_parts (gconstpointer keydata, gsize n_keydata,
- gconstpointer params, gsize n_params,
+gkm_data_der_read_public_key_dsa_parts (EggBytes *keydata,
+ EggBytes *params,
gcry_sexp_t *s_key)
{
gcry_mpi_t p, q, g, y;
@@ -256,8 +259,8 @@ gkm_data_der_read_public_key_dsa_parts (gconstpointer keydata, gsize n_keydata,
p = q = g = y = NULL;
- asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
- asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPublicPart", keydata, n_keydata);
+ asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params);
+ asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPublicPart", keydata);
if (!asn_params || !asn_key)
goto done;
@@ -302,7 +305,8 @@ done:
" (x %m)))"
GkmDataResult
-gkm_data_der_read_private_key_dsa (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_private_key_dsa (EggBytes *data,
+ gcry_sexp_t *s_key)
{
gcry_mpi_t p, q, g, y, x;
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
@@ -311,7 +315,7 @@ gkm_data_der_read_private_key_dsa (gconstpointer data, gsize n_data, gcry_sexp_t
p = q = g = y = x = NULL;
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data);
if (!asn)
goto done;
@@ -346,8 +350,8 @@ done:
}
GkmDataResult
-gkm_data_der_read_private_key_dsa_parts (gconstpointer keydata, gsize n_keydata,
- gconstpointer params, gsize n_params,
+gkm_data_der_read_private_key_dsa_parts (EggBytes *keydata,
+ EggBytes *params,
gcry_sexp_t *s_key)
{
gcry_mpi_t p, q, g, y, x;
@@ -358,8 +362,8 @@ gkm_data_der_read_private_key_dsa_parts (gconstpointer keydata, gsize n_keydata,
p = q = g = y = x = NULL;
- asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
- asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata, n_keydata);
+ asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params);
+ asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata);
if (!asn_params || !asn_key)
goto done;
@@ -400,31 +404,31 @@ done:
}
GkmDataResult
-gkm_data_der_read_public_key (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_public_key (EggBytes *data, gcry_sexp_t *s_key)
{
GkmDataResult res;
- res = gkm_data_der_read_public_key_rsa (data, n_data, s_key);
+ res = gkm_data_der_read_public_key_rsa (data, s_key);
if (res == GKM_DATA_UNRECOGNIZED)
- res = gkm_data_der_read_public_key_dsa (data, n_data, s_key);
+ res = gkm_data_der_read_public_key_dsa (data, s_key);
return res;
}
GkmDataResult
-gkm_data_der_read_public_key_info (gconstpointer data, gsize n_data, gcry_sexp_t* s_key)
+gkm_data_der_read_public_key_info (EggBytes *data,
+ gcry_sexp_t* s_key)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GQuark oid;
GNode *asn = NULL;
- gsize n_params;
+ EggBytes *params;
+ EggBytes *key = NULL;
guint n_bits;
- const guchar *params;
- guchar *key = NULL;
init_quarks ();
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data);
if (!asn)
goto done;
@@ -436,20 +440,25 @@ gkm_data_der_read_public_key_info (gconstpointer data, gsize n_data, gcry_sexp_t
goto done;
/* A bit string so we cannot process in place */
- key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
+ key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), &n_bits);
if (!key)
goto done;
+ if (n_bits % 8 != 0) {
+ g_message ("invalid bit length for public key: %u", n_bits);
+ goto done;
+ }
/* An RSA key is simple */
if (oid == OID_PKIX1_RSA) {
- ret = gkm_data_der_read_public_key_rsa (key, n_bits / 8, s_key);
+ ret = gkm_data_der_read_public_key_rsa (key, s_key);
/* A DSA key paramaters are stored separately */
} else if (oid == OID_PKIX1_DSA) {
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "algorithm", "parameters", NULL));
if (!params)
goto done;
- ret = gkm_data_der_read_public_key_dsa_parts (key, n_bits / 8, params, n_params, s_key);
+ ret = gkm_data_der_read_public_key_dsa_parts (key, params, s_key);
+ egg_bytes_unref (params);
} else {
g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
@@ -459,7 +468,8 @@ gkm_data_der_read_public_key_info (gconstpointer data, gsize n_data, gcry_sexp_t
done:
egg_asn1x_destroy (asn);
- g_free (key);
+ if (key)
+ egg_bytes_unref (key);
if (ret == GKM_DATA_FAILURE)
g_message ("invalid subject public-key info");
@@ -468,34 +478,34 @@ done:
}
GkmDataResult
-gkm_data_der_read_private_key (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_private_key (EggBytes *data,
+ gcry_sexp_t *s_key)
{
GkmDataResult res;
- res = gkm_data_der_read_private_key_rsa (data, n_data, s_key);
+ res = gkm_data_der_read_private_key_rsa (data, s_key);
if (res == GKM_DATA_UNRECOGNIZED)
- res = gkm_data_der_read_private_key_dsa (data, n_data, s_key);
+ res = gkm_data_der_read_private_key_dsa (data, s_key);
return res;
}
GkmDataResult
-gkm_data_der_read_private_pkcs8_plain (gconstpointer data, gsize n_data, gcry_sexp_t *s_key)
+gkm_data_der_read_private_pkcs8_plain (EggBytes *data,
+ gcry_sexp_t *s_key)
{
GNode *asn = NULL;
GkmDataResult ret;
int algorithm;
GQuark key_algo;
- const guchar *keydata;
- gsize n_keydata;
- const guchar *params;
- gsize n_params;
+ EggBytes *keydata = NULL;
+ EggBytes *params = NULL;
ret = GKM_DATA_UNRECOGNIZED;
init_quarks ();
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data);
if (!asn)
goto done;
@@ -515,12 +525,11 @@ gkm_data_der_read_private_pkcs8_plain (gconstpointer data, gsize n_data, gcry_se
goto done;
}
- keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
+ keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL));
if (!keydata)
goto done;
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
- &n_params);
+ params = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL));
ret = GKM_DATA_SUCCESS;
@@ -528,16 +537,15 @@ done:
if (ret == GKM_DATA_SUCCESS) {
switch (algorithm) {
case GCRY_PK_RSA:
- ret = gkm_data_der_read_private_key_rsa (keydata, n_keydata, s_key);
+ ret = gkm_data_der_read_private_key_rsa (keydata, s_key);
break;
case GCRY_PK_DSA:
/* Try the normal one block format */
- ret = gkm_data_der_read_private_key_dsa (keydata, n_keydata, s_key);
+ ret = gkm_data_der_read_private_key_dsa (keydata, s_key);
/* Otherwise try the two part format that everyone seems to like */
- if (ret == GKM_DATA_UNRECOGNIZED && params && n_params)
- ret = gkm_data_der_read_private_key_dsa_parts (keydata, n_keydata,
- params, n_params, s_key);
+ if (ret == GKM_DATA_UNRECOGNIZED && params)
+ ret = gkm_data_der_read_private_key_dsa_parts (keydata, params, s_key);
break;
default:
g_message ("invalid or unsupported key type in PKCS#8 key");
@@ -549,13 +557,19 @@ done:
g_message ("invalid PKCS#8 key");
}
+ if (params)
+ egg_bytes_unref (params);
+ if (keydata)
+ egg_bytes_unref (keydata);
egg_asn1x_destroy (asn);
return ret;
}
GkmDataResult
-gkm_data_der_read_private_pkcs8_crypted (gconstpointer data, gsize n_data, const gchar *password,
- gsize n_password, gcry_sexp_t *s_key)
+gkm_data_der_read_private_pkcs8_crypted (EggBytes *data,
+ const gchar *password,
+ gsize n_password,
+ gcry_sexp_t *s_key)
{
GNode *asn = NULL;
gcry_cipher_hd_t cih = NULL;
@@ -563,15 +577,16 @@ gkm_data_der_read_private_pkcs8_crypted (gconstpointer data, gsize n_data, const
GkmDataResult ret, r;
GQuark scheme;
guchar *crypted = NULL;
- const guchar *params;
- gsize n_crypted, n_params;
+ EggBytes *params;
+ EggBytes *bytes;
+ gsize n_crypted;
gint l;
init_quarks ();
ret = GKM_DATA_UNRECOGNIZED;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data);
if (!asn)
goto done;
@@ -582,14 +597,16 @@ gkm_data_der_read_private_pkcs8_crypted (gconstpointer data, gsize n_data, const
if (!scheme)
goto done;
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL));
if (!params)
goto done;
/*
* Parse the encryption stuff into a cipher.
*/
- r = egg_symkey_read_cipher (scheme, password, n_password, params, n_params, &cih);
+ r = egg_symkey_read_cipher (scheme, password, n_password, params, &cih);
+ egg_bytes_unref (params);
+
if (r == GKM_DATA_UNRECOGNIZED) {
ret = GKM_DATA_FAILURE;
goto done;
@@ -620,11 +637,13 @@ gkm_data_der_read_private_pkcs8_crypted (gconstpointer data, gsize n_data, const
}
n_crypted = l;
- /* Try to parse the resulting key */
- ret = gkm_data_der_read_private_pkcs8_plain (crypted, n_crypted, s_key);
- egg_secure_free (crypted);
+ bytes = egg_bytes_new_with_free_func (crypted, n_crypted, egg_secure_free, crypted);
crypted = NULL;
+ /* Try to parse the resulting key */
+ ret = gkm_data_der_read_private_pkcs8_plain (bytes, s_key);
+ egg_bytes_unref (bytes);
+
/* If unrecognized we assume bad password */
if (ret == GKM_DATA_UNRECOGNIZED)
ret = GKM_DATA_LOCKED;
@@ -639,24 +658,26 @@ done:
}
GkmDataResult
-gkm_data_der_read_private_pkcs8 (gconstpointer data, gsize n_data, const gchar *password,
- gsize n_password, gcry_sexp_t *s_key)
+gkm_data_der_read_private_pkcs8 (EggBytes *data,
+ const gchar *password,
+ gsize n_password,
+ gcry_sexp_t *s_key)
{
GkmDataResult res;
- res = gkm_data_der_read_private_pkcs8_crypted (data, n_data, password, n_password, s_key);
+ res = gkm_data_der_read_private_pkcs8_crypted (data, password, n_password, s_key);
if (res == GKM_DATA_UNRECOGNIZED)
- res = gkm_data_der_read_private_pkcs8_plain (data, n_data, s_key);
+ res = gkm_data_der_read_private_pkcs8_plain (data, s_key);
return res;
}
-gpointer
-gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len)
+EggBytes *
+gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key)
{
GNode *asn = NULL;
gcry_mpi_t n, e;
- guchar *result = NULL;
+ EggBytes *result = NULL;
n = e = NULL;
@@ -671,7 +692,7 @@ gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len)
!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e))
goto done;
- result = egg_asn1x_encode (asn, NULL, len);
+ result = egg_asn1x_encode (asn, NULL);
if (result == NULL)
g_warning ("couldn't encode public rsa key: %s", egg_asn1x_message (asn));
@@ -683,12 +704,12 @@ done:
return result;
}
-gpointer
-gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
+EggBytes *
+gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key)
{
GNode *asn = NULL;
gcry_mpi_t n, e, d, p, q, u, e1, e2, tmp;
- guchar *result = NULL;
+ EggBytes *result = NULL;
n = e = d = p = q = u = e1 = e2 = tmp = NULL;
@@ -729,7 +750,7 @@ gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
goto done;
- result = egg_asn1x_encode (asn, egg_secure_realloc, n_key);
+ result = egg_asn1x_encode (asn, egg_secure_realloc);
if (result == NULL)
g_warning ("couldn't encode private rsa key: %s", egg_asn1x_message (asn));
@@ -749,12 +770,12 @@ done:
return result;
}
-gpointer
-gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
+EggBytes *
+gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key)
{
GNode *asn = NULL;
gcry_mpi_t p, q, g, y;
- guchar *result = NULL;
+ EggBytes *result = NULL;
p = q = g = y = NULL;
@@ -776,7 +797,7 @@ gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
goto done;
- result = egg_asn1x_encode (asn, NULL, len);
+ result = egg_asn1x_encode (asn, NULL);
if (result == NULL)
g_warning ("couldn't encode public dsa key: %s", egg_asn1x_message (asn));
@@ -790,12 +811,12 @@ done:
return result;
}
-gpointer
-gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key)
+EggBytes *
+gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey)
{
GNode *asn = NULL;
gcry_mpi_t x;
- guchar *result = NULL;
+ EggBytes *result = NULL;
x = NULL;
@@ -808,7 +829,7 @@ gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key)
if (!gkm_data_asn1_write_mpi (asn, x))
goto done;
- result = egg_asn1x_encode (asn, egg_secure_realloc, n_key);
+ result = egg_asn1x_encode (asn, egg_secure_realloc);
if (result == NULL)
g_warning ("couldn't encode private dsa key: %s", egg_asn1x_message (asn));
@@ -819,12 +840,12 @@ done:
return result;
}
-gpointer
-gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params)
+EggBytes *
+gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey)
{
GNode *asn = NULL;
gcry_mpi_t p, q, g;
- guchar *result = NULL;
+ EggBytes *result = NULL;
p = q = g = NULL;
@@ -841,7 +862,7 @@ gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params)
!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g))
goto done;
- result = egg_asn1x_encode (asn, egg_secure_realloc, n_params);
+ result = egg_asn1x_encode (asn, egg_secure_realloc);
if (result == NULL)
g_warning ("couldn't encode private dsa params: %s", egg_asn1x_message (asn));
@@ -854,12 +875,12 @@ done:
return result;
}
-gpointer
-gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
+EggBytes *
+gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key)
{
GNode *asn = NULL;
gcry_mpi_t p, q, g, y, x;
- guchar *result = NULL;
+ EggBytes *result = NULL;
p = q = g = y = x = NULL;
@@ -883,7 +904,7 @@ gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
goto done;
- result = egg_asn1x_encode (asn, egg_secure_realloc, len);
+ result = egg_asn1x_encode (asn, egg_secure_realloc);
if (result == NULL)
g_warning ("couldn't encode private dsa key: %s", egg_asn1x_message (asn));
@@ -898,8 +919,8 @@ done:
return result;
}
-gpointer
-gkm_data_der_write_public_key (gcry_sexp_t s_key, gsize *len)
+EggBytes *
+gkm_data_der_write_public_key (gcry_sexp_t s_key)
{
gboolean is_priv;
int algorithm;
@@ -913,16 +934,16 @@ gkm_data_der_write_public_key (gcry_sexp_t s_key, gsize *len)
switch (algorithm) {
case GCRY_PK_RSA:
- return gkm_data_der_write_public_key_rsa (s_key, len);
+ return gkm_data_der_write_public_key_rsa (s_key);
case GCRY_PK_DSA:
- return gkm_data_der_write_public_key_dsa (s_key, len);
+ return gkm_data_der_write_public_key_dsa (s_key);
default:
g_return_val_if_reached (NULL);
}
}
-gpointer
-gkm_data_der_write_private_key (gcry_sexp_t s_key, gsize *len)
+EggBytes *
+gkm_data_der_write_private_key (gcry_sexp_t s_key)
{
gboolean is_priv;
int algorithm;
@@ -936,9 +957,9 @@ gkm_data_der_write_private_key (gcry_sexp_t s_key, gsize *len)
switch (algorithm) {
case GCRY_PK_RSA:
- return gkm_data_der_write_private_key_rsa (s_key, len);
+ return gkm_data_der_write_private_key_rsa (s_key);
case GCRY_PK_DSA:
- return gkm_data_der_write_private_key_dsa (s_key, len);
+ return gkm_data_der_write_private_key_dsa (s_key);
default:
g_return_val_if_reached (NULL);
}
@@ -952,8 +973,9 @@ prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password,
gcry_cipher_hd_t cih;
guchar salt[8];
gcry_error_t gcry;
- guchar *key, *iv, *portion;
- gsize n_key, n_portion;
+ guchar *key, *iv;
+ EggBytes *portion;
+ gsize n_key;
int iterations;
init_quarks ();
@@ -988,15 +1010,16 @@ prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password,
g_return_val_if_reached (NULL);
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn1_params, "iterations", NULL), iterations))
g_return_val_if_reached (NULL);
- portion = egg_asn1x_encode (asn1_params, NULL, &n_portion);
+ portion = egg_asn1x_encode (asn1_params, NULL);
if (portion == NULL) {
g_warning ("couldn't encode pkcs8 params key: %s", egg_asn1x_message (asn1_params));
g_return_val_if_reached (NULL);
}
- if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL),
- portion, n_portion, g_free))
+ if (!egg_asn1x_set_element_raw (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL),
+ portion))
g_return_val_if_reached (NULL);
+ egg_bytes_unref (portion);
/* Now make a cipher that matches what we wrote out */
gcry = gcry_cipher_open (&cih, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
@@ -1013,15 +1036,16 @@ prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password,
return cih;
}
-gpointer
-gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
+EggBytes *
+gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey)
{
GNode *asn = NULL;
int algorithm;
gboolean is_priv;
GQuark oid;
- guchar *params, *key, *data;
- gsize n_params, n_key;
+ EggBytes *params;
+ EggBytes *key;
+ EggBytes *data;
init_quarks ();
@@ -1044,15 +1068,14 @@ gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
case GCRY_PK_RSA:
oid = OID_PKIX1_RSA;
params = NULL;
- n_params = 0;
- key = gkm_data_der_write_private_key_rsa (skey, &n_key);
+ key = gkm_data_der_write_private_key_rsa (skey);
break;
/* DSA gets incoded with the params seperate */
case GCRY_PK_DSA:
oid = OID_PKIX1_DSA;
- key = gkm_data_der_write_private_key_dsa_part (skey, &n_key);
- params = gkm_data_der_write_private_key_dsa_params (skey, &n_params);
+ key = gkm_data_der_write_private_key_dsa_part (skey);
+ params = gkm_data_der_write_private_key_dsa_params (skey);
break;
default:
@@ -1066,17 +1089,19 @@ gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
/* Write out the parameters */
if (params) {
- if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
- params, n_params, egg_secure_free))
+ if (!egg_asn1x_set_element_raw (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
+ params))
g_return_val_if_reached (NULL);
+ egg_bytes_unref (params);
}
/* Write out the key portion */
- if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "privateKey", NULL),
- key, n_key, egg_secure_free))
+ if (!egg_asn1x_set_string_as_bytes (egg_asn1x_node (asn, "privateKey", NULL), key))
g_return_val_if_reached (NULL);
- data = egg_asn1x_encode (asn, egg_secure_realloc, n_data);
+ egg_bytes_unref (key);
+
+ data = egg_asn1x_encode (asn, egg_secure_realloc);
if (data == NULL)
g_warning ("couldn't encode private pkcs8 key: %s", egg_asn1x_message (asn));
@@ -1084,18 +1109,21 @@ gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
return data;
}
-gpointer
-gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password,
- gsize n_password, gsize *n_data)
+EggBytes *
+gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey,
+ const gchar *password,
+ gsize n_password)
{
gcry_error_t gcry;
gcry_cipher_hd_t cih;
GNode *asn = NULL;
- guchar *key, *data;
- gsize n_key, block = 0;
+ EggBytes *key, *data;
+ guchar *raw;
+ gsize n_raw, n_key;
+ gsize block = 0;
/* Encode the key in normal pkcs8 fashion */
- key = gkm_data_der_write_private_pkcs8_plain (skey, &n_key);
+ key = gkm_data_der_write_private_pkcs8_plain (skey);
if (key == NULL)
return NULL;
@@ -1106,30 +1134,39 @@ gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *passwor
cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block);
g_return_val_if_fail (cih, NULL);
+ n_key = egg_bytes_get_size (key);
+
/* Pad the block of data */
if(block > 1) {
- gsize pad;
- guchar *padded;
-
- pad = block - (n_key % block);
- if (pad == 0)
- pad = block;
- padded = egg_secure_realloc (key, n_key + pad);
- memset (padded + n_key, pad, pad);
- key = padded;
- n_key += pad;
+ gsize n_pad = block - (n_key % block);
+ if (n_pad == 0)
+ n_pad = block;
+ raw = egg_secure_alloc (n_key + n_pad);
+ memcpy (raw, egg_bytes_get_data (key), n_key);
+ memset (raw + n_key, (int)n_pad, n_pad);
+ n_raw = n_key + n_pad;
+
+ /* No padding, probably stream cipher */
+ } else {
+ raw = egg_secure_alloc (n_key);
+ memcpy (raw, egg_bytes_get_data (key), n_key);
+ n_raw = n_key;
}
- gcry = gcry_cipher_encrypt (cih, key, n_key, NULL, 0);
+ egg_bytes_unref (key);
+
+ gcry = gcry_cipher_encrypt (cih, raw, n_raw, NULL, 0);
g_return_val_if_fail (gcry == 0, NULL);
gcry_cipher_close (cih);
+ key = egg_bytes_new_with_free_func (raw, n_raw, egg_secure_free, raw);
- if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL),
- key, n_key, egg_secure_free))
+ if (!egg_asn1x_set_string_as_bytes (egg_asn1x_node (asn, "encryptedData", NULL), key))
g_return_val_if_reached (NULL);
- data = egg_asn1x_encode (asn, NULL, n_data);
+ egg_bytes_unref (key);
+
+ data = egg_asn1x_encode (asn, NULL);
if (data == NULL)
g_warning ("couldn't encode encrypted pkcs8 key: %s", egg_asn1x_message (asn));
@@ -1142,9 +1179,10 @@ gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *passwor
*/
GkmDataResult
-gkm_data_der_read_certificate (gconstpointer data, gsize n_data, GNode **asn1)
+gkm_data_der_read_certificate (EggBytes *data,
+ GNode **asn1)
{
- *asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
+ *asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
if (!*asn1)
return GKM_DATA_UNRECOGNIZED;
@@ -1152,15 +1190,16 @@ gkm_data_der_read_certificate (gconstpointer data, gsize n_data, GNode **asn1)
}
GkmDataResult
-gkm_data_der_read_basic_constraints (gconstpointer data, gsize n_data,
- gboolean *is_ca, gint *path_len)
+gkm_data_der_read_basic_constraints (EggBytes *data,
+ gboolean *is_ca,
+ gint *path_len)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GNode *asn = NULL;
GNode *node;
gulong value;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data);
if (!asn)
goto done;
@@ -1195,13 +1234,14 @@ done:
}
GkmDataResult
-gkm_data_der_read_key_usage (gconstpointer data, gsize n_data, gulong *key_usage)
+gkm_data_der_read_key_usage (EggBytes *data,
+ gulong *key_usage)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GNode *asn = NULL;
guint n_bits;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "KeyUsage", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "KeyUsage", data);
if (!asn)
goto done;
@@ -1218,7 +1258,8 @@ done:
}
GkmDataResult
-gkm_data_der_read_enhanced_usage (gconstpointer data, gsize n_data, GQuark **usage_oids)
+gkm_data_der_read_enhanced_usage (EggBytes *data,
+ GQuark **usage_oids)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GNode *asn = NULL;
@@ -1227,7 +1268,7 @@ gkm_data_der_read_enhanced_usage (gconstpointer data, gsize n_data, GQuark **usa
GQuark oid;
int i;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data);
if (!asn)
goto done;
@@ -1252,15 +1293,14 @@ done:
}
-gpointer
-gkm_data_der_write_certificate (GNode *asn1, gsize *n_data)
+EggBytes *
+gkm_data_der_write_certificate (GNode *asn1)
{
- gpointer result;
+ EggBytes *result;
g_return_val_if_fail (asn1, NULL);
- g_return_val_if_fail (n_data, NULL);
- result = egg_asn1x_encode (asn1, NULL, n_data);
+ result = egg_asn1x_encode (asn1, NULL);
if (result == NULL)
g_warning ("couldn't encode certificate: %s", egg_asn1x_message (asn1));
diff --git a/pkcs11/gkm/gkm-data-der.h b/pkcs11/gkm/gkm-data-der.h
index 664259a..f98ec6b 100644
--- a/pkcs11/gkm/gkm-data-der.h
+++ b/pkcs11/gkm/gkm-data-der.h
@@ -30,94 +30,97 @@
#include "gkm-data-types.h"
#include "egg/egg-asn1x.h"
+#include "egg/egg-bytes.h"
/* -----------------------------------------------------------------------------
* PRIVATE KEYS
*/
-GkmDataResult gkm_data_der_read_private_key_rsa (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_private_key_rsa (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_private_key_dsa (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_private_key_dsa (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_private_key_dsa_parts (gconstpointer keydata, gsize n_keydata,
- gconstpointer params, gsize n_params,
+GkmDataResult gkm_data_der_read_private_key_dsa_parts (EggBytes *keydata,
+ EggBytes *params,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_private_key (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_private_key (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_private_pkcs8 (gconstpointer data, gsize n_data,
- const gchar *password, gsize n_password,
+GkmDataResult gkm_data_der_read_private_pkcs8 (EggBytes *data,
+ const gchar *password,
+ gsize n_password,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_private_pkcs8_plain (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_private_pkcs8_plain (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_private_pkcs8_crypted (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_private_pkcs8_crypted (EggBytes *data,
const gchar *password, gsize n_password,
gcry_sexp_t *s_key);
-gpointer gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_data);
+EggBytes * gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key);
-gpointer gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len);
+EggBytes * gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key);
-gpointer gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key);
+EggBytes * gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey);
-gpointer gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params);
+EggBytes * gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey);
-gpointer gkm_data_der_write_private_key (gcry_sexp_t s_key, gsize *n_data);
+EggBytes * gkm_data_der_write_private_key (gcry_sexp_t s_key);
-gpointer gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data);
+EggBytes * gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey);
-gpointer gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password,
- gsize n_password, gsize *n_data);
+EggBytes * gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey,
+ const gchar *password,
+ gsize n_password);
/* -----------------------------------------------------------------------------
* PUBLIC KEYS
*/
-GkmDataResult gkm_data_der_read_public_key_rsa (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_public_key_rsa (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_public_key_dsa (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_public_key_dsa (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_public_key_dsa_parts (gconstpointer keydata, gsize n_keydata,
- gconstpointer params, gsize n_params,
+GkmDataResult gkm_data_der_read_public_key_dsa_parts (EggBytes *keydata,
+ EggBytes *params,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_public_key (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_public_key (EggBytes *data,
gcry_sexp_t *s_key);
-GkmDataResult gkm_data_der_read_public_key_info (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_public_key_info (EggBytes *data,
gcry_sexp_t *s_key);
-gpointer gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len);
+EggBytes * gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key);
-gpointer gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len);
+EggBytes * gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key);
-gpointer gkm_data_der_write_public_key (gcry_sexp_t s_key, gsize *len);
+EggBytes * gkm_data_der_write_public_key (gcry_sexp_t s_key);
/* -----------------------------------------------------------------------------
* CERTIFICATES
*/
-GkmDataResult gkm_data_der_read_certificate (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_certificate (EggBytes *data,
GNode **asn1);
-GkmDataResult gkm_data_der_read_basic_constraints (gconstpointer data, gsize n_data,
- gboolean *is_ca, gint *path_len);
+GkmDataResult gkm_data_der_read_basic_constraints (EggBytes *data,
+ gboolean *is_ca,
+ gint *path_len);
-GkmDataResult gkm_data_der_read_key_usage (gconstpointer data,
- gsize n_data,
+GkmDataResult gkm_data_der_read_key_usage (EggBytes *data,
gulong *key_usage);
-GkmDataResult gkm_data_der_read_enhanced_usage (gconstpointer data, gsize n_data,
+GkmDataResult gkm_data_der_read_enhanced_usage (EggBytes *data,
GQuark **oids);
-gpointer gkm_data_der_write_certificate (GNode *asn1, gsize *n_data);
+EggBytes * gkm_data_der_write_certificate (GNode *asn1);
#endif /*GKRPKIXDER_H_*/
diff --git a/pkcs11/gkm/gkm-serializable.c b/pkcs11/gkm/gkm-serializable.c
index c0ff12d..4fab9e5 100644
--- a/pkcs11/gkm/gkm-serializable.c
+++ b/pkcs11/gkm/gkm-serializable.c
@@ -63,17 +63,18 @@ gkm_serializable_get_type (void)
}
gboolean
-gkm_serializable_load (GkmSerializable *self, GkmSecret *login, gconstpointer data, gsize n_data)
+gkm_serializable_load (GkmSerializable *self, GkmSecret *login, EggBytes *data)
{
g_return_val_if_fail (GKM_IS_SERIALIZABLE (self), FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (GKM_SERIALIZABLE_GET_INTERFACE (self)->load, FALSE);
- return GKM_SERIALIZABLE_GET_INTERFACE (self)->load (self, login, data, n_data);
+ return GKM_SERIALIZABLE_GET_INTERFACE (self)->load (self, login, data);
}
-gboolean
-gkm_serializable_save (GkmSerializable *self, GkmSecret *login, gpointer *data, gsize *n_data)
+EggBytes *
+gkm_serializable_save (GkmSerializable *self, GkmSecret *login)
{
g_return_val_if_fail (GKM_IS_SERIALIZABLE (self), FALSE);
g_return_val_if_fail (GKM_SERIALIZABLE_GET_INTERFACE (self)->save, FALSE);
- return GKM_SERIALIZABLE_GET_INTERFACE (self)->save (self, login, data, n_data);
+ return GKM_SERIALIZABLE_GET_INTERFACE (self)->save (self, login);
}
diff --git a/pkcs11/gkm/gkm-serializable.h b/pkcs11/gkm/gkm-serializable.h
index 385793c..8e773ec 100644
--- a/pkcs11/gkm/gkm-serializable.h
+++ b/pkcs11/gkm/gkm-serializable.h
@@ -26,6 +26,8 @@
#include "gkm-types.h"
+#include "egg/egg-bytes.h"
+
G_BEGIN_DECLS
#define GKM_TYPE_SERIALIZABLE (gkm_serializable_get_type())
@@ -41,22 +43,22 @@ struct _GkmSerializableIface {
const gchar *extension;
- gboolean (*load) (GkmSerializable *self, GkmSecret *login, gconstpointer data, gsize n_data);
+ gboolean (*load) (GkmSerializable *self,
+ GkmSecret *login,
+ EggBytes *data);
- gboolean (*save) (GkmSerializable *self, GkmSecret *login, gpointer *data, gsize *n_data);
+ EggBytes * (*save) (GkmSerializable *self,
+ GkmSecret *login);
};
GType gkm_serializable_get_type (void) G_GNUC_CONST;
gboolean gkm_serializable_load (GkmSerializable *self,
GkmSecret *login,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
-gboolean gkm_serializable_save (GkmSerializable *self,
- GkmSecret *login,
- gpointer *data,
- gsize *n_data);
+EggBytes * gkm_serializable_save (GkmSerializable *self,
+ GkmSecret *login);
G_END_DECLS
diff --git a/pkcs11/gkm/tests/Makefile.am b/pkcs11/gkm/tests/Makefile.am
index 034e147..9dcd70b 100644
--- a/pkcs11/gkm/tests/Makefile.am
+++ b/pkcs11/gkm/tests/Makefile.am
@@ -1,3 +1,12 @@
+include $(top_srcdir)/Makefile.decl
+
+ASN_FILES = \
+ test.asn
+
+ASN_SRCS = $(ASN_FILES:.asn=.asn.h)
+
+BUILT_SOURCES = \
+ $(ASN_SRCS)
INCLUDES = \
-I$(top_builddir) \
@@ -16,9 +25,6 @@ LDADD = \
noinst_LIBRARIES = libgkm-mock.a
-BUILT_SOURCES = \
- asn1-def-test.h
-
libgkm_mock_a_SOURCES = \
mock-module.c mock-module.h \
mock-locked-object.c mock-locked-object.h \
@@ -72,11 +78,8 @@ check-local: test
all-local: $(check_PROGRAMS)
-asn1-def-test.h: test.asn
- $(ASN1PARSER) -o asn1-def-test.h $(srcdir)/test.asn
-
EXTRA_DIST = \
- test.asn \
+ $(ASN_FILES) \
files
DISTCLEANFILES = \
diff --git a/pkcs11/gkm/tests/mock-module.c b/pkcs11/gkm/tests/mock-module.c
index 3abe116..58d8664 100644
--- a/pkcs11/gkm/tests/mock-module.c
+++ b/pkcs11/gkm/tests/mock-module.c
@@ -33,7 +33,7 @@ GKM_DEFINE_MODULE (test_module, GKM_TYPE_MODULE);
#include "gkm/gkm-certificate.h"
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
GkmModule*
mock_module_initialize_and_enter (void)
diff --git a/pkcs11/gkm/tests/test-certificate.c b/pkcs11/gkm/tests/test-certificate.c
index 7ad9a6d..1927926 100644
--- a/pkcs11/gkm/tests/test-certificate.c
+++ b/pkcs11/gkm/tests/test-certificate.c
@@ -40,8 +40,7 @@
typedef struct {
GkmModule *module;
GkmSession *session;
- gpointer certificate_data;
- gsize n_certificate_data;
+ EggBytes *certificate_data;
GkmCertificate *certificate;
} Test;
@@ -58,21 +57,20 @@ setup_basic (Test* test,
if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der", &data, &length, NULL))
g_assert_not_reached ();
- test->certificate_data = data;
- test->n_certificate_data = length;
+ test->certificate_data = egg_bytes_new_take (data, length);
}
static void
teardown_basic (Test* test,
gconstpointer unused)
{
- g_free (test->certificate_data);
+ egg_bytes_unref (test->certificate_data);
mock_module_leave_and_finalize ();
}
static GkmCertificate *
create_certificate_object (GkmSession *session,
- gpointer data, gsize length)
+ EggBytes *data)
{
GkmCertificate *certificate;
@@ -82,7 +80,7 @@ create_certificate_object (GkmSession *session,
"manager", gkm_session_get_manager (session),
NULL);
- if (!gkm_serializable_load (GKM_SERIALIZABLE (certificate), NULL, data, length))
+ if (!gkm_serializable_load (GKM_SERIALIZABLE (certificate), NULL, data))
g_assert_not_reached ();
return certificate;
@@ -93,7 +91,7 @@ setup (Test *test,
gconstpointer unused)
{
setup_basic (test, unused);
- test->certificate = create_certificate_object (test->session, test->certificate_data, test->n_certificate_data);
+ test->certificate = create_certificate_object (test->session, test->certificate_data);
}
static void
@@ -171,9 +169,8 @@ test_attribute_value (Test* test,
data = gkm_object_get_attribute_data (GKM_OBJECT (test->certificate),
test->session, CKA_VALUE, &n_data);
- raw = test->certificate_data;
- n_raw = test->n_certificate_data
- ;
+ raw = egg_bytes_get_data (test->certificate_data);
+ n_raw = egg_bytes_get_size (test->certificate_data);
egg_assert_cmpmem (data, n_data, ==, raw, n_raw);
g_free (data);
}
diff --git a/pkcs11/gkm/tests/test-data-asn1.c b/pkcs11/gkm/tests/test-data-asn1.c
index b29ea0b..e9d98d6 100644
--- a/pkcs11/gkm/tests/test-data-asn1.c
+++ b/pkcs11/gkm/tests/test-data-asn1.c
@@ -36,29 +36,33 @@
#include "egg/egg-asn1x.h"
#include "egg/egg-asn1-defs.h"
-#include "asn1-def-test.h"
+typedef struct _EggAsn1xDef ASN1_ARRAY_TYPE;
+#include "test.asn.h"
typedef struct {
GNode *asn1_cert;
- gchar *data_cert;
- gsize n_data_cert;
} Test;
static void
setup (Test *test, gconstpointer unused)
{
- if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der", &test->data_cert, &test->n_data_cert, NULL))
+ EggBytes *data;
+ gchar *contents;
+ gsize length;
+
+ if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der", &contents, &length, NULL))
g_assert_not_reached ();
- test->asn1_cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", test->data_cert, test->n_data_cert);
+ data = egg_bytes_new_take (contents, length);
+ test->asn1_cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
g_assert (test->asn1_cert);
+ egg_bytes_unref (data);
}
static void
teardown (Test *test, gconstpointer unused)
{
egg_asn1x_destroy (test->asn1_cert);
- g_free (test->data_cert);
}
static void
@@ -66,8 +70,7 @@ test_asn1_integers (Test *test, gconstpointer unused)
{
GNode *asn;
gcry_mpi_t mpi, mpt;
- guchar *data;
- gsize n_data;
+ EggBytes *data;
gboolean ret;
asn = egg_asn1x_create (test_asn1_tab, "TestIntegers");
@@ -82,21 +85,21 @@ test_asn1_integers (Test *test, gconstpointer unused)
ret = gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "mpi", NULL), mpi);
/* Now encode the whole caboodle */
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert ("encoding asn1 didn't work" && data != NULL);
egg_asn1x_destroy (asn);
/* Now decode it all nicely */
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data, n_data);
- g_assert (asn);
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data);
+ g_assert (asn != NULL);
ret = gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "mpi", NULL), &mpt);
g_assert ("couldn't read mpi from asn1" && ret);
g_assert ("mpi returned is null" && mpt != NULL);
g_assert ("mpi is wrong number" && gcry_mpi_cmp (mpi, mpt) == 0);
- g_free (data);
+ egg_bytes_unref (data);
}
int
diff --git a/pkcs11/gkm/tests/test-data-der.c b/pkcs11/gkm/tests/test-data-der.c
index 2bc90df..dc751d3 100644
--- a/pkcs11/gkm/tests/test-data-der.c
+++ b/pkcs11/gkm/tests/test-data-der.c
@@ -41,7 +41,7 @@
#include <stdio.h>
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
typedef struct {
GNode *certificate;
@@ -95,36 +95,45 @@ compare_keys (gcry_sexp_t key, gcry_sexp_t sexp)
static void
test_der_public (gcry_sexp_t key)
{
- guchar *data;
- gsize n_data;
+ EggBytes *data;
GkmDataResult ret;
gcry_sexp_t sexp;
/* Encode it */
- data = gkm_data_der_write_public_key (key, &n_data);
+ data = gkm_data_der_write_public_key (key);
g_assert ("couldn't encode public key" && data != NULL);
- g_assert ("encoding is empty" && n_data > 0);
+ g_assert ("encoding is empty" && egg_bytes_get_size (data) > 0);
/* Now parse it */
- ret = gkm_data_der_read_public_key (data, n_data, &sexp);
+ ret = gkm_data_der_read_public_key (data, &sexp);
g_assert ("couldn't decode public key" && ret == GKM_DATA_SUCCESS);
g_assert ("parsed key is empty" && sexp != NULL);
/* Now compare them */
g_assert ("key parsed differently" && compare_keys (key, sexp));
+
+ egg_bytes_unref (data);
}
static void
setup (Test *test, gconstpointer unused)
{
+ EggBytes *data;
+
if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der", &test->certificate_data, &test->n_certificate_data, NULL))
g_assert_not_reached ();
- test->certificate = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", test->certificate_data, test->n_certificate_data);
- g_assert (test->certificate);
+
+ data = egg_bytes_new (test->certificate_data, test->n_certificate_data);
+ test->certificate = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
+ g_assert (test->certificate != NULL);
+ egg_bytes_unref (data);
+
if (!g_file_get_contents (SRCDIR "/files/test-certificate-2.der", &test->certificate2_data, &test->n_certificate2_data, NULL))
g_assert_not_reached ();
- test->certificate2 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", test->certificate2_data, test->n_certificate2_data);
- g_assert (test->certificate2);
+ data = egg_bytes_new (test->certificate2_data, test->n_certificate2_data);
+ test->certificate2 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
+ g_assert (test->certificate2 != NULL);
+ egg_bytes_unref (data);
}
static void
@@ -163,25 +172,24 @@ test_der_dsa_public (Test *test, gconstpointer unused)
static void
test_der_private (gcry_sexp_t key)
{
- guchar *data;
- gsize n_data;
+ EggBytes *data;
GkmDataResult ret;
gcry_sexp_t sexp;
/* Encode it */
- data = gkm_data_der_write_private_key (key, &n_data);
+ data = gkm_data_der_write_private_key (key);
g_assert ("couldn't encode private key" && data != NULL);
- g_assert ("encoding is empty" && n_data > 0);
+ g_assert ("encoding is empty" && egg_bytes_get_size (data) > 0);
/* Now parse it */
- ret = gkm_data_der_read_private_key (data, n_data, &sexp);
+ ret = gkm_data_der_read_private_key (data, &sexp);
g_assert ("couldn't decode private key" && ret == GKM_DATA_SUCCESS);
g_assert ("parsed key is empty" && sexp != NULL);
/* Now compare them */
g_assert ("key parsed differently" && compare_keys (key, sexp));
- egg_secure_free (data);
+ egg_bytes_unref (data);
}
static void
@@ -211,8 +219,7 @@ test_der_dsa_private (Test *test, gconstpointer unused)
static void
test_der_dsa_private_parts (Test *test, gconstpointer unused)
{
- guchar *params, *key;
- gsize n_params, n_key;
+ EggBytes *params, *key;
gcry_sexp_t skey, pkey;
gcry_error_t gcry;
GkmDataResult result;
@@ -221,21 +228,21 @@ test_der_dsa_private_parts (Test *test, gconstpointer unused)
g_return_if_fail (gcry == 0);
/* Encode the the dsa key by parts */
- params = gkm_data_der_write_private_key_dsa_params (skey, &n_params);
+ params = gkm_data_der_write_private_key_dsa_params (skey);
g_assert ("didn't encode dsa params" && params != NULL);
- key = gkm_data_der_write_private_key_dsa_part (skey, &n_key);
+ key = gkm_data_der_write_private_key_dsa_part (skey);
g_assert ("didn't encode dsa key" && key != NULL);
/* Parse the dsa key by parts */
- result = gkm_data_der_read_private_key_dsa_parts (key, n_key, params, n_params, &pkey);
+ result = gkm_data_der_read_private_key_dsa_parts (key, params, &pkey);
g_assert ("couldn't parse dsa parts" && result == GKM_DATA_SUCCESS);
g_assert ("parsing dsa parts resulted in null key" && pkey != NULL);
/* Now compare them */
g_assert ("key parsed differently" && compare_keys (skey, pkey));
- egg_secure_free (params);
- egg_secure_free (key);
+ egg_bytes_unref (params);
+ egg_bytes_unref (key);
}
const gchar *certpub = "(public-key (rsa " \
@@ -245,17 +252,16 @@ const gchar *certpub = "(public-key (rsa " \
static void
test_read_public_key_info (Test *test, gconstpointer unused)
{
- const guchar *data;
+ EggBytes *data;
guchar hash[20];
- gsize n_data;
GkmDataResult res;
gcry_sexp_t sexp, match;
gcry_error_t gcry;
- data = egg_asn1x_get_raw_element (egg_asn1x_node (test->certificate, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_data);
- g_assert (data);
+ data = egg_asn1x_get_element_raw (egg_asn1x_node (test->certificate, "tbsCertificate", "subjectPublicKeyInfo", NULL));
+ g_assert (data != NULL);
- res = gkm_data_der_read_public_key_info (data, n_data, &sexp);
+ res = gkm_data_der_read_public_key_info (data, &sexp);
g_assert (res == GKM_DATA_SUCCESS);
g_assert (sexp != NULL);
@@ -269,6 +275,7 @@ test_read_public_key_info (Test *test, gconstpointer unused)
gcry_sexp_release (sexp);
gcry_sexp_release (match);
+ egg_bytes_unref (data);
}
static void
@@ -276,77 +283,79 @@ test_read_certificate (Test *test, gconstpointer unused)
{
GNode *asn = NULL;
GkmDataResult res;
+ EggBytes *data;
- res = gkm_data_der_read_certificate (test->certificate_data, test->n_certificate_data, &asn);
+ data = egg_bytes_new (test->certificate_data, test->n_certificate_data);
+ res = gkm_data_der_read_certificate (data, &asn);
g_assert (res == GKM_DATA_SUCCESS);
g_assert (asn != NULL);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_write_certificate (Test *test, gconstpointer unused)
{
- guchar *data;
- gsize n_data;
+ EggBytes *data;
- data = gkm_data_der_write_certificate (test->certificate, &n_data);
- g_assert (data);
- g_assert (n_data == test->n_certificate_data);
- g_assert (memcmp (data, test->certificate_data, n_data) == 0);
- g_free (data);
+ data = gkm_data_der_write_certificate (test->certificate);
+ g_assert (egg_bytes_get_size (data) == test->n_certificate_data);
+ g_assert (memcmp (egg_bytes_get_data (data), test->certificate_data, egg_bytes_get_size (data)) == 0);
+ egg_bytes_unref (data);
}
static void
on_ca_certificate_public_key_info (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
GNode *asn1 = NULL;
GkmDataResult res;
- gpointer keydata;
- gsize n_keydata;
+ EggBytes *keydata;
gcry_sexp_t sexp;
g_assert (g_quark_try_string ("CERTIFICATE") == type);
/* Parse the ASN1 data */
- res = gkm_data_der_read_certificate (data, n_data, &asn1);
+ res = gkm_data_der_read_certificate (data, &asn1);
g_assert (res == GKM_DATA_SUCCESS);
/* Generate a raw public key from our test->certificate */
- keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL, &n_keydata);
- g_assert (keydata);
+ keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL);
+ g_assert (keydata != NULL);
/* Now create us a nice public key with that identifier */
- res = gkm_data_der_read_public_key_info (keydata, n_keydata, &sexp);
+ res = gkm_data_der_read_public_key_info (keydata, &sexp);
g_assert (res == GKM_DATA_SUCCESS || res == GKM_DATA_UNRECOGNIZED);
if (res == GKM_DATA_SUCCESS)
gcry_sexp_release (sexp);
- g_free (keydata);
+ egg_bytes_unref (keydata);
}
static void
test_read_ca_certificates_public_key_info (Test *test, gconstpointer unused)
{
+ EggBytes *bytes;
gchar *data;
gsize n_data;
if (!g_file_get_contents (SRCDIR "/files/ca-certificates.crt", &data, &n_data, NULL))
g_assert_not_reached ();
- egg_armor_parse (data, n_data, on_ca_certificate_public_key_info, NULL);
- g_free (data);
+
+ bytes = egg_bytes_new_take (data, n_data);
+ egg_armor_parse (bytes, on_ca_certificate_public_key_info, NULL);
+ egg_bytes_unref (bytes);
}
-static const guchar*
-find_extension (GNode *asn, gconstpointer data, gsize n_data, const gchar *oid, gsize *n_extension)
+static EggBytes *
+find_extension (GNode *asn,
+ const gchar *oid)
{
- const guchar *value;
+ EggBytes *value;
GNode *node = NULL;
gchar *exoid;
guint index;
@@ -364,7 +373,7 @@ find_extension (GNode *asn, gconstpointer data, gsize n_data, const gchar *oid,
if (strcmp (exoid, oid) == 0) {
g_free (exoid);
node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, "extnValue", NULL);
- value = egg_asn1x_get_raw_value (node, n_extension);
+ value = egg_asn1x_get_raw_value (node);
g_assert (value);
return value;
}
@@ -378,58 +387,60 @@ find_extension (GNode *asn, gconstpointer data, gsize n_data, const gchar *oid,
static void
test_read_basic_constraints (Test *test, gconstpointer unused)
{
- const guchar *extension;
- gsize n_extension;
+ EggBytes *extension;
gboolean is_ca;
gint path_len;
GkmDataResult res;
- extension = egg_asn1x_get_raw_value (egg_asn1x_node (test->certificate, "tbsCertificate", "extensions", 1, "extnValue", NULL),
- &n_extension);
- g_assert (extension);
+ extension = egg_asn1x_get_raw_value (egg_asn1x_node (test->certificate, "tbsCertificate", "extensions", 1, "extnValue", NULL));
+ g_assert (extension != NULL);
- res = gkm_data_der_read_basic_constraints (extension, n_extension, &is_ca, &path_len);
+ res = gkm_data_der_read_basic_constraints (extension, &is_ca, &path_len);
g_assert (res == GKM_DATA_SUCCESS);
g_assert (is_ca == TRUE);
g_assert (path_len == -1);
+
+ egg_bytes_unref (extension);
}
static void
test_read_key_usage (Test *test, gconstpointer unused)
{
- const guchar *extension;
- gsize n_extension;
+ EggBytes *extension;
gulong key_usage;
GkmDataResult res;
- extension = find_extension (test->certificate2, test->certificate2_data, test->n_certificate2_data, "2.5.29.15", &n_extension);
+ extension = find_extension (test->certificate2, "2.5.29.15");
g_assert (extension);
- res = gkm_data_der_read_key_usage (extension, n_extension, &key_usage);
+ res = gkm_data_der_read_key_usage (extension, &key_usage);
g_assert (res == GKM_DATA_SUCCESS);
g_assert_cmpuint (key_usage, ==, 0x01);
+
+ egg_bytes_unref (extension);
}
static void
test_read_enhanced_usage (Test *test, gconstpointer unused)
{
- const guchar *extension;
- gsize n_extension;
+ EggBytes *extension;
GQuark *usages;
GkmDataResult res;
- extension = find_extension (test->certificate2, test->certificate2_data, test->n_certificate2_data, "2.5.29.37", &n_extension);
+ extension = find_extension (test->certificate2, "2.5.29.37");
g_assert (extension);
- res = gkm_data_der_read_enhanced_usage (extension, n_extension, &usages);
+ res = gkm_data_der_read_enhanced_usage (extension, &usages);
g_assert (res == GKM_DATA_SUCCESS);
+ egg_bytes_unref (extension);
g_free (usages);
}
static void
test_read_all_pkcs8 (Test *test, gconstpointer unused)
{
+ EggBytes *bytes;
gcry_sexp_t sexp;
GkmDataResult res;
GDir *dir;
@@ -454,12 +465,13 @@ test_read_all_pkcs8 (Test *test, gconstpointer unused)
g_assert_not_reached ();
g_free (path);
- res = gkm_data_der_read_private_pkcs8 (data, n_data, "booo", 4, &sexp);
+ bytes = egg_bytes_new_take (data, n_data);
+ res = gkm_data_der_read_private_pkcs8 (bytes, "booo", 4, &sexp);
g_assert (res == GKM_DATA_SUCCESS);
+ egg_bytes_unref (bytes);
g_assert (gkm_sexp_parse_key (sexp, NULL, NULL, NULL));
gcry_sexp_release (sexp);
- g_free (data);
}
g_dir_close (dir);
@@ -470,16 +482,18 @@ test_read_pkcs8_bad_password (Test *test, gconstpointer unused)
{
gcry_sexp_t sexp;
GkmDataResult res;
+ EggBytes *bytes;
gchar *data;
gsize n_data;
if (!g_file_get_contents (SRCDIR "/files/der-key-encrypted-pkcs5.p8", &data, &n_data, NULL))
g_assert_not_reached ();
- res = gkm_data_der_read_private_pkcs8 (data, n_data, "wrong password", 4, &sexp);
+ bytes = egg_bytes_new_take (data, n_data);
+ res = gkm_data_der_read_private_pkcs8 (bytes, "wrong password", 4, &sexp);
g_assert (res == GKM_DATA_LOCKED);
- g_free (data);
+ egg_bytes_unref (bytes);
}
static void
@@ -488,22 +502,20 @@ test_write_pkcs8_plain (Test *test, gconstpointer unused)
gcry_sexp_t sexp, check;
gcry_error_t gcry;
GkmDataResult res;
- guchar *data;
- gsize n_data;
+ EggBytes *data;
/* RSA */
gcry = gcry_sexp_sscan (&sexp, NULL, rsaprv, strlen (rsaprv));
g_return_if_fail (gcry == 0);
- data = gkm_data_der_write_private_pkcs8_plain (sexp, &n_data);
- g_assert (data);
- g_assert (n_data);
+ data = gkm_data_der_write_private_pkcs8_plain (sexp);
+ g_assert (data != NULL);
- res = gkm_data_der_read_private_pkcs8_plain (data, n_data, &check);
- egg_secure_free (data);
+ res = gkm_data_der_read_private_pkcs8_plain (data, &check);
+ egg_bytes_unref (data);
g_assert (res == GKM_DATA_SUCCESS);
- g_assert (check);
+ g_assert (check != NULL);
g_assert (compare_keys (sexp, check));
gcry_sexp_release (sexp);
@@ -515,14 +527,13 @@ test_write_pkcs8_plain (Test *test, gconstpointer unused)
gcry = gcry_sexp_sscan (&sexp, NULL, dsaprv, strlen (dsaprv));
g_return_if_fail (gcry == 0);
- data = gkm_data_der_write_private_pkcs8_plain (sexp, &n_data);
- g_assert (data);
- g_assert (n_data);
+ data = gkm_data_der_write_private_pkcs8_plain (sexp);
+ g_assert (data != NULL);
- res = gkm_data_der_read_private_pkcs8_plain (data, n_data, &check);
- egg_secure_free (data);
+ res = gkm_data_der_read_private_pkcs8_plain (data, &check);
+ egg_bytes_unref (data);
g_assert (res == GKM_DATA_SUCCESS);
- g_assert (check);
+ g_assert (check != NULL);
g_assert (compare_keys (sexp, check));
gcry_sexp_release (sexp);
@@ -536,22 +547,20 @@ test_write_pkcs8_encrypted (Test *test, gconstpointer unused)
gcry_sexp_t sexp, check;
gcry_error_t gcry;
GkmDataResult res;
- guchar *data;
- gsize n_data;
+ EggBytes *data;
/* RSA */
gcry = gcry_sexp_sscan (&sexp, NULL, rsaprv, strlen (rsaprv));
g_return_if_fail (gcry == 0);
- data = gkm_data_der_write_private_pkcs8_crypted (sexp, "testo", 5, &n_data);
- g_assert (data);
- g_assert (n_data);
+ data = gkm_data_der_write_private_pkcs8_crypted (sexp, "testo", 5);
+ g_assert (data != NULL);
- res = gkm_data_der_read_private_pkcs8_crypted (data, n_data, "testo", 5, &check);
- g_free (data);
+ res = gkm_data_der_read_private_pkcs8_crypted (data, "testo", 5, &check);
+ egg_bytes_unref (data);
g_assert (res == GKM_DATA_SUCCESS);
- g_assert (check);
+ g_assert (check != NULL);
g_assert (compare_keys (sexp, check));
gcry_sexp_release (sexp);
@@ -563,14 +572,13 @@ test_write_pkcs8_encrypted (Test *test, gconstpointer unused)
gcry = gcry_sexp_sscan (&sexp, NULL, dsaprv, strlen (dsaprv));
g_return_if_fail (gcry == 0);
- data = gkm_data_der_write_private_pkcs8_crypted (sexp, "testo", 5, &n_data);
- g_assert (data);
- g_assert (n_data);
+ data = gkm_data_der_write_private_pkcs8_crypted (sexp, "testo", 5);
+ g_assert (data != NULL);
- res = gkm_data_der_read_private_pkcs8_crypted (data, n_data, "testo", 5, &check);
- g_free (data);
+ res = gkm_data_der_read_private_pkcs8_crypted (data, "testo", 5, &check);
+ egg_bytes_unref (data);
g_assert (res == GKM_DATA_SUCCESS);
- g_assert (check);
+ g_assert (check != NULL);
g_assert (compare_keys (sexp, check));
gcry_sexp_release (sexp);
diff --git a/pkcs11/gkm/tests/test-secret.c b/pkcs11/gkm/tests/test-secret.c
index 67e7a62..e8fc58d 100644
--- a/pkcs11/gkm/tests/test-secret.c
+++ b/pkcs11/gkm/tests/test-secret.c
@@ -31,7 +31,7 @@
#include "egg/egg-secure-memory.h"
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
test_secret (void)
diff --git a/pkcs11/gkm/tests/test-sexp.c b/pkcs11/gkm/tests/test-sexp.c
index 5f3e062..3d9e039 100644
--- a/pkcs11/gkm/tests/test-sexp.c
+++ b/pkcs11/gkm/tests/test-sexp.c
@@ -34,7 +34,7 @@
#include <gcrypt.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
#define TEST_RSA \
"(private-key (rsa " \
diff --git a/pkcs11/gnome2-store/gkm-gnome2-private-key.c b/pkcs11/gnome2-store/gkm-gnome2-private-key.c
index a2bc738..a9c5c4e 100644
--- a/pkcs11/gnome2-store/gkm-gnome2-private-key.c
+++ b/pkcs11/gnome2-store/gkm-gnome2-private-key.c
@@ -46,9 +46,7 @@ enum {
struct _GkmGnome2PrivateKey {
GkmPrivateXsaKey parent;
- guchar *private_data;
- gsize n_private_data;
-
+ EggBytes *private_bytes;
GkmSexp *private_sexp;
gboolean is_encrypted;
GkmSecret *login;
@@ -122,8 +120,7 @@ gkm_gnome2_private_key_real_acquire_crypto_sexp (GkmSexpKey *base, GkmSession *u
g_return_val_if_fail (self->is_encrypted, NULL);
password = gkm_secret_get_password (self->login, &n_password);
- res = gkm_data_der_read_private_pkcs8 (self->private_data, self->n_private_data,
- password, n_password, &sexp);
+ res = gkm_data_der_read_private_pkcs8 (self->private_bytes, password, n_password, &sexp);
g_return_val_if_fail (res == GKM_DATA_SUCCESS, NULL);
return gkm_sexp_new (sexp);
@@ -154,8 +151,8 @@ gkm_gnome2_private_key_finalize (GObject *obj)
g_assert (self->login == NULL);
- g_free (self->private_data);
- self->private_data = NULL;
+ if (self->private_bytes)
+ egg_bytes_unref (self->private_bytes);
if (self->private_sexp)
gkm_sexp_unref (self->private_sexp);
@@ -204,7 +201,9 @@ gkm_gnome2_private_key_class_init (GkmGnome2PrivateKeyClass *klass)
}
static gboolean
-gkm_gnome2_private_key_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
+gkm_gnome2_private_key_real_load (GkmSerializable *base,
+ GkmSecret *login,
+ EggBytes *data)
{
GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (base);
GkmDataResult res;
@@ -213,10 +212,10 @@ gkm_gnome2_private_key_real_load (GkmSerializable *base, GkmSecret *login, gcons
const gchar *password;
gsize n_password;
- g_return_val_if_fail (GKM_IS_GNOME2_PRIVATE_KEY (self), FALSE);
- g_return_val_if_fail (data, FALSE);
+ if (egg_bytes_get_size (data) == 0)
+ return FALSE;
- res = gkm_data_der_read_private_pkcs8 (data, n_data, NULL, 0, &sexp);
+ res = gkm_data_der_read_private_pkcs8 (data, NULL, 0, &sexp);
/* An unencrypted pkcs8 file */
if (res == GKM_DATA_SUCCESS) {
@@ -232,7 +231,7 @@ gkm_gnome2_private_key_real_load (GkmSerializable *base, GkmSecret *login, gcons
}
password = gkm_secret_get_password (login, &n_password);
- res = gkm_data_der_read_private_pkcs8 (data, n_data, password, n_password, &sexp);
+ res = gkm_data_der_read_private_pkcs8 (data, password, n_password, &sexp);
}
switch (res) {
@@ -262,9 +261,9 @@ gkm_gnome2_private_key_real_load (GkmSerializable *base, GkmSecret *login, gcons
/* Encrypted private key, keep login and data */
if (self->is_encrypted) {
- g_free (self->private_data);
- self->n_private_data = n_data;
- self->private_data = g_memdup (data, n_data);
+ if (self->private_bytes)
+ egg_bytes_unref (self->private_bytes);
+ self->private_bytes = egg_bytes_ref (data);
g_object_ref (login);
if (self->login)
@@ -289,18 +288,16 @@ gkm_gnome2_private_key_real_load (GkmSerializable *base, GkmSecret *login, gcons
return TRUE;
}
-static gboolean
-gkm_gnome2_private_key_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data)
+static EggBytes *
+gkm_gnome2_private_key_real_save (GkmSerializable *base, GkmSecret *login)
{
GkmGnome2PrivateKey *self = GKM_GNOME2_PRIVATE_KEY (base);
const gchar *password = NULL;
gsize n_password;
GkmSexp *sexp;
- guchar *key;
+ EggBytes *result;
g_return_val_if_fail (GKM_IS_GNOME2_PRIVATE_KEY (self), FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
sexp = gkm_gnome2_private_key_real_acquire_crypto_sexp (GKM_SEXP_KEY (self), NULL);
g_return_val_if_fail (sexp, FALSE);
@@ -308,21 +305,14 @@ gkm_gnome2_private_key_real_save (GkmSerializable *base, GkmSecret *login, gpoin
if (login != NULL)
password = gkm_secret_get_password (login, &n_password);
if (password == NULL) {
- key = gkm_data_der_write_private_pkcs8_plain (gkm_sexp_get (sexp), n_data);
-
- /*
- * Caller is expecting normal memory buffer, which makes sense since
- * this is being written to disk, and won't be 'secure' anyway.
- */
- *data = g_memdup (key, *n_data);
- egg_secure_free (key);
+ result = gkm_data_der_write_private_pkcs8_plain (gkm_sexp_get (sexp));
} else {
- *data = gkm_data_der_write_private_pkcs8_crypted (gkm_sexp_get (sexp), password,
- n_password, n_data);
+ result = gkm_data_der_write_private_pkcs8_crypted (gkm_sexp_get (sexp), password,
+ n_password);
}
gkm_sexp_unref (sexp);
- return *data != NULL;
+ return result;
}
static void
diff --git a/pkcs11/gnome2-store/gkm-gnome2-public-key.c b/pkcs11/gnome2-store/gkm-gnome2-public-key.c
index e5c16be..e40d18b 100644
--- a/pkcs11/gnome2-store/gkm-gnome2-public-key.c
+++ b/pkcs11/gnome2-store/gkm-gnome2-public-key.c
@@ -120,17 +120,19 @@ gkm_gnome2_public_key_class_init (GkmGnome2PublicKeyClass *klass)
static gboolean
-gkm_gnome2_public_key_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
+gkm_gnome2_public_key_real_load (GkmSerializable *base,
+ GkmSecret *login,
+ EggBytes *data)
{
GkmGnome2PublicKey *self = GKM_GNOME2_PUBLIC_KEY (base);
GkmDataResult res;
GkmSexp *wrapper;
gcry_sexp_t sexp;
- g_return_val_if_fail (GKM_IS_GNOME2_PUBLIC_KEY (self), FALSE);
- g_return_val_if_fail (data, FALSE);
+ if (egg_bytes_get_size (data) == 0)
+ return FALSE;
- res = gkm_data_der_read_public_key (data, n_data, &sexp);
+ res = gkm_data_der_read_public_key (data, &sexp);
switch (res) {
case GKM_DATA_LOCKED:
@@ -155,21 +157,18 @@ gkm_gnome2_public_key_real_load (GkmSerializable *base, GkmSecret *login, gconst
return TRUE;
}
-static gboolean
-gkm_gnome2_public_key_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data)
+static EggBytes *
+gkm_gnome2_public_key_real_save (GkmSerializable *base, GkmSecret *login)
{
GkmGnome2PublicKey *self = GKM_GNOME2_PUBLIC_KEY (base);
GkmSexp *wrapper;
g_return_val_if_fail (GKM_IS_GNOME2_PUBLIC_KEY (self), FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
wrapper = gkm_sexp_key_get_base (GKM_SEXP_KEY (self));
g_return_val_if_fail (wrapper, FALSE);
- *data = gkm_data_der_write_public_key (gkm_sexp_get (wrapper), n_data);
- return *data != NULL;
+ return gkm_data_der_write_public_key (gkm_sexp_get (wrapper));
}
static void
diff --git a/pkcs11/gnome2-store/gkm-gnome2-standalone.c b/pkcs11/gnome2-store/gkm-gnome2-standalone.c
index 631499c..102a46a 100644
--- a/pkcs11/gnome2-store/gkm-gnome2-standalone.c
+++ b/pkcs11/gnome2-store/gkm-gnome2-standalone.c
@@ -34,7 +34,7 @@
#include <glib-object.h>
/* Module callbacks for secure memory */
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
CK_RV
C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
diff --git a/pkcs11/gnome2-store/gkm-gnome2-storage.c b/pkcs11/gnome2-store/gkm-gnome2-storage.c
index ac52ccf..e654c5b 100644
--- a/pkcs11/gnome2-store/gkm-gnome2-storage.c
+++ b/pkcs11/gnome2-store/gkm-gnome2-storage.c
@@ -92,16 +92,20 @@ G_DEFINE_TYPE (GkmGnome2Storage, gkm_gnome2_storage, GKM_TYPE_STORE);
#define UNWANTED_IDENTIFIER_CHARS ":/\\<>|\t\n\r\v "
static gchar*
-name_for_subject (const guchar *subject, gsize n_subject)
+name_for_subject (const guchar *subject,
+ gsize n_subject)
{
GNode *asn;
gchar *name;
+ EggBytes *bytes;
g_assert (subject);
g_assert (n_subject);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Name", subject, n_subject);
- g_return_val_if_fail (asn, NULL);
+ bytes = egg_bytes_new (subject, n_subject);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Name", bytes);
+ g_return_val_if_fail (asn != NULL, NULL);
+ egg_bytes_unref (bytes);
name = egg_dn_read_part (egg_asn1x_node (asn, "rdnSequence", NULL), "CN");
egg_asn1x_destroy (asn);
@@ -495,6 +499,7 @@ data_file_entry_added (GkmGnome2File *store, const gchar *identifier, GkmGnome2S
{
GError *error = NULL;
GkmObject *object;
+ EggBytes *bytes;
gboolean ret;
guchar *data;
gsize n_data;
@@ -531,6 +536,7 @@ data_file_entry_added (GkmGnome2File *store, const gchar *identifier, GkmGnome2S
/* Make sure that the object wasn't tampered with */
if (!check_object_hash (self, identifier, data, n_data)) {
g_message ("file in user store doesn't match hash: %s", identifier);
+ g_free (data);
return;
}
@@ -540,13 +546,15 @@ data_file_entry_added (GkmGnome2File *store, const gchar *identifier, GkmGnome2S
g_return_if_fail (GKM_IS_SERIALIZABLE (object));
g_return_if_fail (GKM_SERIALIZABLE_GET_INTERFACE (object)->extension);
+ bytes = egg_bytes_new_take (data, n_data);
+
/* And load the data into it */
- if (gkm_serializable_load (GKM_SERIALIZABLE (object), self->login, data, n_data))
+ if (gkm_serializable_load (GKM_SERIALIZABLE (object), self->login, bytes))
take_object_ownership (self, identifier, object);
else
g_message ("failed to load file in user store: %s", identifier);
- g_free (data);
+ egg_bytes_unref (bytes);
g_object_unref (object);
}
@@ -587,6 +595,7 @@ relock_object (GkmGnome2Storage *self, GkmTransaction *transaction, const gchar
{
GError *error = NULL;
GkmObject *object;
+ EggBytes *bytes;
gpointer data;
gsize n_data;
GType type;
@@ -628,23 +637,26 @@ relock_object (GkmGnome2Storage *self, GkmTransaction *transaction, const gchar
if (!check_object_hash (self, identifier, data, n_data)) {
g_message ("file in data store doesn't match hash: %s", identifier);
gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
+ g_free (data);
return;
}
+ bytes = egg_bytes_new_take (data, n_data);
+
/* Load it into our temporary object */
- if (!gkm_serializable_load (GKM_SERIALIZABLE (object), old_login, data, n_data)) {
+ if (!gkm_serializable_load (GKM_SERIALIZABLE (object), old_login, bytes)) {
g_message ("unrecognized or invalid user store file: %s", identifier);
gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
- g_free (data);
+ egg_bytes_unref (bytes);
g_object_unref (object);
return;
}
- g_free (data);
- data = NULL;
+ egg_bytes_unref (bytes);
/* Read it out of our temporary object */
- if (!gkm_serializable_save (GKM_SERIALIZABLE (object), new_login, &data, &n_data)) {
+ bytes = gkm_serializable_save (GKM_SERIALIZABLE (object), new_login);
+ if (bytes == NULL) {
g_warning ("unable to serialize data with new login: %s", identifier);
gkm_transaction_fail (transaction, CKR_GENERAL_ERROR);
g_object_unref (object);
@@ -661,8 +673,7 @@ relock_object (GkmGnome2Storage *self, GkmTransaction *transaction, const gchar
if (!gkm_transaction_get_failed (transaction))
store_object_hash (self, transaction, identifier, data, n_data);
- g_free (data);
-
+ egg_bytes_unref (bytes);
}
typedef struct _RelockArgs {
@@ -1045,8 +1056,7 @@ gkm_gnome2_storage_create (GkmGnome2Storage *self, GkmTransaction *transaction,
gboolean is_private;
GkmDataResult res;
gchar *identifier;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
gchar *path;
g_return_if_fail (GKM_IS_GNOME2_STORAGE (self));
@@ -1113,17 +1123,23 @@ gkm_gnome2_storage_create (GkmGnome2Storage *self, GkmTransaction *transaction,
}
/* Serialize the object in question */
- if (!gkm_serializable_save (GKM_SERIALIZABLE (object), is_private ? self->login : NULL, &data, &n_data)) {
+ data = gkm_serializable_save (GKM_SERIALIZABLE (object), is_private ? self->login : NULL);
+
+ if (data == NULL) {
gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
g_return_if_reached ();
}
path = g_build_filename (self->directory, identifier, NULL);
- gkm_transaction_write_file (transaction, path, data, n_data);
+ gkm_transaction_write_file (transaction, path,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
/* Make sure we write in the object hash */
if (!gkm_transaction_get_failed (transaction))
- store_object_hash (self, transaction, identifier, data, n_data);
+ store_object_hash (self, transaction, identifier,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
/* Now we decide to own the object */
if (!gkm_transaction_get_failed (transaction))
@@ -1131,7 +1147,7 @@ gkm_gnome2_storage_create (GkmGnome2Storage *self, GkmTransaction *transaction,
g_free (identifier);
g_free (path);
- g_free (data);
+ egg_bytes_unref (data);
}
void
diff --git a/pkcs11/gnome2-store/tests/check-gnome2-module.c b/pkcs11/gnome2-store/tests/check-gnome2-module.c
index 5385778..d5f4600 100644
--- a/pkcs11/gnome2-store/tests/check-gnome2-module.c
+++ b/pkcs11/gnome2-store/tests/check-gnome2-module.c
@@ -34,7 +34,7 @@
static int failures = 0;
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
on_p11_tests_log (int level, const char *section, const char *message)
diff --git a/pkcs11/gnome2-store/tests/frob-gnome2-file.c b/pkcs11/gnome2-store/tests/frob-gnome2-file.c
index e3515ef..4667a90 100644
--- a/pkcs11/gnome2-store/tests/frob-gnome2-file.c
+++ b/pkcs11/gnome2-store/tests/frob-gnome2-file.c
@@ -39,7 +39,7 @@
#include <string.h>
#include <unistd.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void G_GNUC_NORETURN
failure (const gchar* message, ...)
diff --git a/pkcs11/gnome2-store/tests/mock-gnome2-module.c b/pkcs11/gnome2-store/tests/mock-gnome2-module.c
index f652fd0..2441af2 100644
--- a/pkcs11/gnome2-store/tests/mock-gnome2-module.c
+++ b/pkcs11/gnome2-store/tests/mock-gnome2-module.c
@@ -31,7 +31,7 @@
#include "gnome2-store/gkm-gnome2-store.h"
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static GMutex *mutex = NULL;
diff --git a/pkcs11/gnome2-store/tests/test-gnome2-file.c b/pkcs11/gnome2-store/tests/test-gnome2-file.c
index 7b9d9f8..3ab97a2 100644
--- a/pkcs11/gnome2-store/tests/test-gnome2-file.c
+++ b/pkcs11/gnome2-store/tests/test-gnome2-file.c
@@ -48,7 +48,7 @@ typedef struct {
GkmSecret *login;
} Test;
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
setup (Test *test, gconstpointer unused)
diff --git a/pkcs11/gnome2-store/tests/test-gnome2-private-key.c b/pkcs11/gnome2-store/tests/test-gnome2-private-key.c
index f7ca8c7..10580cf 100644
--- a/pkcs11/gnome2-store/tests/test-gnome2-private-key.c
+++ b/pkcs11/gnome2-store/tests/test-gnome2-private-key.c
@@ -38,6 +38,7 @@
#include "gkm/gkm-session.h"
#include "gkm/gkm-test.h"
+#include "egg/egg-bytes.h"
#include "egg/egg-testing.h"
#include "pkcs11i.h"
@@ -45,8 +46,7 @@
typedef struct {
GkmModule *module;
GkmSession *session;
- gpointer key_data;
- gsize n_key_data;
+ EggBytes *key_data;
GkmGnome2PrivateKey *key;
} Test;
@@ -63,15 +63,14 @@ setup_basic (Test* test,
if (!g_file_get_contents (SRCDIR "/files/der-key-v2-des3.p8", &data, &length, NULL))
g_assert_not_reached ();
- test->key_data = data;
- test->n_key_data = length;
+ test->key_data = egg_bytes_new_take (data, length);
}
static void
teardown_basic (Test* test,
gconstpointer unused)
{
- g_free (test->key_data);
+ egg_bytes_unref (test->key_data);
mock_gnome2_module_leave_and_finalize ();
}
@@ -90,7 +89,7 @@ setup (Test *test,
NULL);
login = gkm_secret_new_from_password ("booo");
- if (!gkm_serializable_load (GKM_SERIALIZABLE (test->key), login, test->key_data, test->n_key_data))
+ if (!gkm_serializable_load (GKM_SERIALIZABLE (test->key), login, test->key_data))
g_assert_not_reached ();
g_object_unref (login);
}
@@ -117,11 +116,11 @@ test_load_private_key (Test *test,
NULL);
/* It's encrypted, this should fail */
- if (gkm_serializable_load (GKM_SERIALIZABLE (key), NULL, test->key_data, test->n_key_data))
+ if (gkm_serializable_load (GKM_SERIALIZABLE (key), NULL, test->key_data))
g_assert_not_reached ();
login = gkm_secret_new_from_password ("booo");
- if (!gkm_serializable_load (GKM_SERIALIZABLE (key), login, test->key_data, test->n_key_data))
+ if (!gkm_serializable_load (GKM_SERIALIZABLE (key), login, test->key_data))
g_assert_not_reached ();
g_object_unref (login);
@@ -133,25 +132,22 @@ test_save_private_key (Test *test,
gconstpointer unused)
{
GkmSecret *login;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
gcry_sexp_t sexp;
/* Save unencrypted */
- if (!gkm_serializable_save (GKM_SERIALIZABLE (test->key), NULL, &data, &n_data))
- g_assert_not_reached ();
+ data = gkm_serializable_save (GKM_SERIALIZABLE (test->key), NULL);
g_assert (data != NULL);
- g_assert (gkm_data_der_read_private_pkcs8_plain (data, n_data, &sexp) == GKM_DATA_SUCCESS);
- g_free (data);
+ g_assert (gkm_data_der_read_private_pkcs8_plain (data, &sexp) == GKM_DATA_SUCCESS);
+ egg_bytes_unref (data);
gcry_sexp_release (sexp);
/* Save encrypted */
login = gkm_secret_new_from_password ("booo");
- if (!gkm_serializable_save (GKM_SERIALIZABLE (test->key), login, &data, &n_data))
- g_assert_not_reached ();
+ data = gkm_serializable_save (GKM_SERIALIZABLE (test->key), login);
g_assert (data != NULL);
- g_assert (gkm_data_der_read_private_pkcs8_crypted (data, n_data, "booo", 4, &sexp) == GKM_DATA_SUCCESS);
- g_free (data);
+ g_assert (gkm_data_der_read_private_pkcs8_crypted (data, "booo", 4, &sexp) == GKM_DATA_SUCCESS);
+ egg_bytes_unref (data);
gcry_sexp_release (sexp);
g_object_unref (login);
}
diff --git a/pkcs11/gnome2-store/tests/test-gnome2-storage.c b/pkcs11/gnome2-store/tests/test-gnome2-storage.c
index ac489c8..862547a 100644
--- a/pkcs11/gnome2-store/tests/test-gnome2-storage.c
+++ b/pkcs11/gnome2-store/tests/test-gnome2-storage.c
@@ -98,6 +98,7 @@ setup_module (Test *test,
CK_ATTRIBUTE url = { CKA_URL, NULL, 0 };
gchar *contents;
gsize length;
+ EggBytes *bytes;
GkmManager *manager;
GError *error = NULL;
GkmSession *session;
@@ -129,9 +130,12 @@ setup_module (Test *test,
NULL);
g_file_get_contents (SRCDIR "/files/test-certificate.cer", &contents, &length, &error);
g_assert_no_error (error);
- if (!gkm_serializable_load (GKM_SERIALIZABLE (test->new_object), NULL, contents, length))
+
+ bytes = egg_bytes_new_take (contents, length);
+ if (!gkm_serializable_load (GKM_SERIALIZABLE (test->new_object), NULL, bytes))
g_assert_not_reached ();
- g_free (contents);
+ egg_bytes_unref (bytes);
+
/* We happen to know this certificate will get named */
test->new_filename = g_build_filename (test->directory, "CA_Cert_Signing_Authority.cer", NULL);
diff --git a/pkcs11/roots-store/gkm-roots-module.c b/pkcs11/roots-store/gkm-roots-module.c
index a36c15b..253b801 100644
--- a/pkcs11/roots-store/gkm-roots-module.c
+++ b/pkcs11/roots-store/gkm-roots-module.c
@@ -93,8 +93,9 @@ GKM_DEFINE_MODULE (gkm_roots_module, GKM_TYPE_ROOTS_MODULE);
*/
static GkmCertificate*
-add_certificate_for_data (GkmRootsModule *self, const guchar *data,
- gsize n_data, const gchar *path)
+add_certificate_for_data (GkmRootsModule *self,
+ EggBytes *data,
+ const gchar *path)
{
GkmCertificate *cert;
GkmManager *manager;
@@ -108,7 +109,9 @@ add_certificate_for_data (GkmRootsModule *self, const guchar *data,
g_return_val_if_fail (manager, NULL);
/* Hash the certificate */
- hash = g_compute_checksum_for_data (G_CHECKSUM_MD5, data, n_data);
+ hash = g_compute_checksum_for_data (G_CHECKSUM_MD5,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
unique = g_strdup_printf ("%s:%s", path, hash);
g_free (hash);
@@ -123,7 +126,7 @@ add_certificate_for_data (GkmRootsModule *self, const guchar *data,
cert = GKM_CERTIFICATE (gkm_roots_certificate_new (GKM_MODULE (self), unique, path));
g_free (unique);
- if (!gkm_serializable_load (GKM_SERIALIZABLE (cert), NULL, data, n_data)) {
+ if (!gkm_serializable_load (GKM_SERIALIZABLE (cert), NULL, data)) {
g_message ("couldn't parse certificate(s): %s", path);
g_object_unref (cert);
return NULL;
@@ -139,10 +142,8 @@ add_certificate_for_data (GkmRootsModule *self, const guchar *data,
static void
parsed_pem_block (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
@@ -161,7 +162,7 @@ parsed_pem_block (GQuark type,
}
if (type == PEM_CERTIFICATE) {
- cert = add_certificate_for_data (ctx->module, data, n_data, ctx->path);
+ cert = add_certificate_for_data (ctx->module, data, ctx->path);
if (cert != NULL) {
g_hash_table_remove (ctx->checks, cert);
++ctx->count;
@@ -184,6 +185,7 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmRootsModule *self)
ParsePrivate ctx;
GkmManager *manager;
GkmCertificate *cert;
+ EggBytes *bytes;
guchar *data;
GList *objects, *l;
GError *error = NULL;
@@ -211,12 +213,14 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmRootsModule *self)
g_hash_table_insert (ctx.checks, l->data, l->data);
g_list_free (objects);
+ bytes = egg_bytes_new_take (data, n_data);
+
/* Try and parse the PEM */
- egg_armor_parse (data, n_data, parsed_pem_block, &ctx);
+ egg_armor_parse (bytes, parsed_pem_block, &ctx);
/* If no PEM data, try to parse directly as DER */
if (ctx.count == 0) {
- cert = add_certificate_for_data (self, data, n_data, path);
+ cert = add_certificate_for_data (self, bytes, path);
if (cert != NULL)
g_hash_table_remove (ctx.checks, cert);
}
@@ -224,7 +228,7 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmRootsModule *self)
g_hash_table_foreach (ctx.checks, remove_each_certificate, self);
g_hash_table_destroy (ctx.checks);
- g_free (data);
+ egg_bytes_unref (data);
}
static void
diff --git a/pkcs11/roots-store/gkm-roots-standalone.c b/pkcs11/roots-store/gkm-roots-standalone.c
index fb0f642..bceb232 100644
--- a/pkcs11/roots-store/gkm-roots-standalone.c
+++ b/pkcs11/roots-store/gkm-roots-standalone.c
@@ -35,7 +35,7 @@
#include "pkcs11/pkcs11.h"
/* Module callbacks for secure memory */
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
const gchar* g_module_check_init (GModule *module);
diff --git a/pkcs11/roots-store/gkm-roots-trust.c b/pkcs11/roots-store/gkm-roots-trust.c
index 93da42b..3810cdb 100644
--- a/pkcs11/roots-store/gkm-roots-trust.c
+++ b/pkcs11/roots-store/gkm-roots-trust.c
@@ -126,20 +126,18 @@ full_certificate (GkmRootsTrust *self, CK_ATTRIBUTE_PTR result)
static GQuark*
lookup_extended_usages (GkmRootsTrust *self)
{
- gconstpointer extension;
- gsize n_extension;
+ EggBytes *extension;
GQuark *usages = NULL;
GkmDataResult res;
extension = gkm_certificate_get_extension (self->pv->certificate,
- OID_ENHANCED_USAGE,
- &n_extension, NULL);
+ OID_ENHANCED_USAGE, NULL);
if (!extension)
return NULL;
/* Returns null terminated set of OID quarks */
- res = gkm_data_der_read_enhanced_usage (extension, n_extension, &usages);
+ res = gkm_data_der_read_enhanced_usage (extension, &usages);
/* Failure: An empty set means nothing is trusted */
if (res != GKM_DATA_SUCCESS) {
@@ -147,6 +145,7 @@ lookup_extended_usages (GkmRootsTrust *self)
usages = g_new0 (GQuark, 1);
}
+ egg_bytes_unref (extension);
return usages;
}
diff --git a/pkcs11/roots-store/tests/check-roots-module.c b/pkcs11/roots-store/tests/check-roots-module.c
index 1bc9e16..c73a188 100644
--- a/pkcs11/roots-store/tests/check-roots-module.c
+++ b/pkcs11/roots-store/tests/check-roots-module.c
@@ -34,7 +34,7 @@
static int failures = 0;
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS();
static void
on_p11_tests_log (int level, const char *section, const char *message)
diff --git a/pkcs11/secret-store/gkm-secret-standalone.c b/pkcs11/secret-store/gkm-secret-standalone.c
index 70924b9..cfc3956 100644
--- a/pkcs11/secret-store/gkm-secret-standalone.c
+++ b/pkcs11/secret-store/gkm-secret-standalone.c
@@ -35,7 +35,7 @@
#include "pkcs11/pkcs11.h"
/* Module callbacks for secure memory */
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
const gchar* g_module_check_init (GModule *module);
diff --git a/pkcs11/secret-store/tests/dump-keyring0-format.c b/pkcs11/secret-store/tests/dump-keyring0-format.c
index 9b42d9f..0da05ed 100644
--- a/pkcs11/secret-store/tests/dump-keyring0-format.c
+++ b/pkcs11/secret-store/tests/dump-keyring0-format.c
@@ -55,7 +55,7 @@ enum {
ACCESS_REMOVE = 1 << 2
};
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
#define KEYRING_FILE_HEADER "GnomeKeyring\n\r\0\n"
#define KEYRING_FILE_HEADER_LEN 16
diff --git a/pkcs11/secret-store/tests/mock-secret-module.c b/pkcs11/secret-store/tests/mock-secret-module.c
index 6cb698c..7022e69 100644
--- a/pkcs11/secret-store/tests/mock-secret-module.c
+++ b/pkcs11/secret-store/tests/mock-secret-module.c
@@ -42,7 +42,7 @@
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static GMutex *mutex = NULL;
static gchar *directory = NULL;
diff --git a/pkcs11/secret-store/tests/test-secret-data.c b/pkcs11/secret-store/tests/test-secret-data.c
index a71e301..c1bf54b 100644
--- a/pkcs11/secret-store/tests/test-secret-data.c
+++ b/pkcs11/secret-store/tests/test-secret-data.c
@@ -36,7 +36,7 @@
#include <stdio.h>
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
test_new (void)
diff --git a/pkcs11/ssh-store/gkm-ssh-openssh.c b/pkcs11/ssh-store/gkm-ssh-openssh.c
index 5003471..831e555 100644
--- a/pkcs11/ssh-store/gkm-ssh-openssh.c
+++ b/pkcs11/ssh-store/gkm-ssh-openssh.c
@@ -155,31 +155,34 @@ read_public (EggBuffer *req, gsize *offset, gcry_sexp_t *key, int *algo)
}
static GkmDataResult
-load_encrypted_key (const guchar *data, gsize n_data, const gchar *dekinfo,
- const gchar *password, gssize n_password, gcry_sexp_t *skey)
+load_encrypted_key (EggBytes *data,
+ const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ gcry_sexp_t *skey)
{
guchar *decrypted = NULL;
gsize n_decrypted = 0;
+ EggBytes *bytes;
GkmDataResult ret;
- gboolean res;
gint length;
/* Decrypt, this will result in garble if invalid password */
- res = egg_openssl_decrypt_block (dekinfo, password, n_password,
- data, n_data, &decrypted, &n_decrypted);
- if (!res)
+ decrypted = egg_openssl_decrypt_block (dekinfo, password, n_password,
+ data, &n_decrypted);
+ if (!decrypted)
return FALSE;
- g_assert (decrypted);
-
/* Unpad the DER data */
length = egg_asn1x_element_length (decrypted, n_decrypted);
if (length > 0)
n_decrypted = length;
+ bytes = egg_bytes_new_with_free_func (decrypted, n_decrypted, egg_secure_free, decrypted);
+
/* Try to parse */
- ret = gkm_data_der_read_private_key (decrypted, n_decrypted, skey);
- egg_secure_free (decrypted);
+ ret = gkm_data_der_read_private_key (bytes, skey);
+ egg_bytes_unref (bytes);
if (ret != GKM_DATA_UNRECOGNIZED)
return ret;
@@ -207,10 +210,8 @@ is_private_key_type (GQuark type)
static void
parsed_pem_block (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
@@ -229,21 +230,19 @@ parsed_pem_block (GQuark type,
/* If it's encrypted ... */
dekinfo = egg_openssl_get_dekinfo (headers);
if (dekinfo) {
- ctx->result = load_encrypted_key (data, n_data, dekinfo, ctx->password,
+ ctx->result = load_encrypted_key (data, dekinfo, ctx->password,
ctx->n_password, &ctx->sexp);
/* not encryted, just load the data */
} else {
- ctx->result = gkm_data_der_read_private_key (data, n_data, &ctx->sexp);
+ ctx->result = gkm_data_der_read_private_key (data, &ctx->sexp);
}
}
static void
digest_pem_block (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
@@ -258,7 +257,9 @@ digest_pem_block (GQuark type,
if (*result != NULL)
return;
- *result = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, n_data);
+ *result = g_compute_checksum_for_data (G_CHECKSUM_SHA1,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
}
/* ------------------------------------------------------------------------------
@@ -372,8 +373,9 @@ gkm_ssh_openssh_parse_public_key (gconstpointer input, gsize n_data,
}
GkmDataResult
-gkm_ssh_openssh_parse_private_key (gconstpointer data, gsize n_data,
- const gchar *password, gssize n_password,
+gkm_ssh_openssh_parse_private_key (EggBytes *data,
+ const gchar *password,
+ gssize n_password,
gcry_sexp_t *sexp)
{
ParsePrivate ctx;
@@ -386,7 +388,7 @@ gkm_ssh_openssh_parse_private_key (gconstpointer data, gsize n_data,
ctx.password = password;
ctx.n_password = n_password;
- num = egg_armor_parse (data, n_data, parsed_pem_block, &ctx);
+ num = egg_armor_parse (data, parsed_pem_block, &ctx);
/* Didn't find any private key there */
if (num == 0 || !ctx.seen) {
@@ -398,10 +400,10 @@ gkm_ssh_openssh_parse_private_key (gconstpointer data, gsize n_data,
return ctx.result;
}
-gchar*
-gkm_ssh_openssh_digest_private_key (const guchar *data, gsize n_data)
+gchar *
+gkm_ssh_openssh_digest_private_key (EggBytes *data)
{
gchar *result = NULL;
- egg_armor_parse (data, n_data, digest_pem_block, &result);
+ egg_armor_parse (data, digest_pem_block, &result);
return result;
}
diff --git a/pkcs11/ssh-store/gkm-ssh-openssh.h b/pkcs11/ssh-store/gkm-ssh-openssh.h
index fe8db8e..62cdd2e 100644
--- a/pkcs11/ssh-store/gkm-ssh-openssh.h
+++ b/pkcs11/ssh-store/gkm-ssh-openssh.h
@@ -7,18 +7,18 @@
#include "gkm/gkm-data-types.h"
+#include <egg/egg-bytes.h>
+
GkmDataResult gkm_ssh_openssh_parse_public_key (gconstpointer data,
gsize n_data,
gcry_sexp_t *sexp,
gchar **comment);
-GkmDataResult gkm_ssh_openssh_parse_private_key (gconstpointer data,
- gsize n_data,
+GkmDataResult gkm_ssh_openssh_parse_private_key (EggBytes *data,
const gchar *password,
gssize n_password,
gcry_sexp_t *sexp);
-gchar* gkm_ssh_openssh_digest_private_key (const guchar *data,
- gsize n_data);
+gchar* gkm_ssh_openssh_digest_private_key (EggBytes *data);
#endif /* GKM_SSHOPENSSH_H_ */
diff --git a/pkcs11/ssh-store/gkm-ssh-private-key.c b/pkcs11/ssh-store/gkm-ssh-private-key.c
index b633a56..4141078 100644
--- a/pkcs11/ssh-store/gkm-ssh-private-key.c
+++ b/pkcs11/ssh-store/gkm-ssh-private-key.c
@@ -46,9 +46,8 @@ struct _GkmSshPrivateKey {
GkmPrivateXsaKey parent;
GkmSshPublicKey *pubkey;
+ EggBytes *private_bytes;
gchar *label;
- guchar *private_data;
- gsize n_private_data;
gboolean is_encrypted;
};
@@ -69,8 +68,7 @@ unlock_private_key (GkmSshPrivateKey *self, const gchar *password,
g_assert (GKM_IS_SSH_PRIVATE_KEY (self));
- res = gkm_ssh_openssh_parse_private_key (self->private_data,
- self->n_private_data,
+ res = gkm_ssh_openssh_parse_private_key (self->private_bytes,
password, n_password, &sexp);
switch (res) {
@@ -99,8 +97,10 @@ unlock_private_key (GkmSshPrivateKey *self, const gchar *password,
}
static void
-realize_and_take_data (GkmSshPrivateKey *self, gcry_sexp_t sexp, gchar *comment,
- guchar *private_data, gsize n_private_data)
+realize_and_take_data (GkmSshPrivateKey *self,
+ gcry_sexp_t sexp,
+ gchar *comment,
+ EggBytes *private_data)
{
GkmSexp *wrapper;
@@ -118,9 +118,9 @@ realize_and_take_data (GkmSshPrivateKey *self, gcry_sexp_t sexp, gchar *comment,
g_free (comment);
/* Own the data */
- g_free (self->private_data);
- self->private_data = private_data;
- self->n_private_data = n_private_data;
+ if (self->private_bytes)
+ egg_bytes_unref (self->private_bytes);
+ self->private_bytes = private_data;
/* Try to parse the private data, and note if it's not actually encrypted */
self->is_encrypted = TRUE;
@@ -148,9 +148,9 @@ gkm_ssh_private_key_get_attribute (GkmObject *base, GkmSession *session, CK_ATTR
/* COMPAT: Previous versions of gnome-keyring used this to save unlock passwords */
case CKA_GNOME_INTERNAL_SHA1:
- if (!self->private_data)
+ if (!self->private_bytes)
return CKR_ATTRIBUTE_TYPE_INVALID;
- digest = gkm_ssh_openssh_digest_private_key (self->private_data, self->n_private_data);
+ digest = gkm_ssh_openssh_digest_private_key (self->private_bytes);
rv = gkm_attribute_set_string (attr, digest);
g_free (digest);
return rv;
@@ -231,11 +231,9 @@ gkm_ssh_private_key_finalize (GObject *obj)
g_assert (self->pubkey == NULL);
- g_free (self->private_data);
- self->private_data = NULL;
-
+ if (self->private_bytes)
+ egg_bytes_unref (self->private_bytes);
g_free (self->label);
- self->label = NULL;
G_OBJECT_CLASS (gkm_ssh_private_key_parent_class)->finalize (obj);
}
@@ -350,7 +348,7 @@ gkm_ssh_private_key_parse (GkmSshPrivateKey *self, const gchar *public_path,
if (comment == NULL)
comment = g_path_get_basename (private_path);
- realize_and_take_data (self, sexp, comment, private_data, n_private_data);
+ realize_and_take_data (self, sexp, comment, egg_bytes_new_take (private_data, n_private_data));
return TRUE;
}
diff --git a/pkcs11/ssh-store/gkm-ssh-standalone.c b/pkcs11/ssh-store/gkm-ssh-standalone.c
index 0d7c10d..3b53f48 100644
--- a/pkcs11/ssh-store/gkm-ssh-standalone.c
+++ b/pkcs11/ssh-store/gkm-ssh-standalone.c
@@ -35,7 +35,7 @@
#include <gmodule.h>
/* Module callbacks for secure memory */
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
const gchar* g_module_check_init (GModule *module);
diff --git a/pkcs11/ssh-store/tests/check-ssh-module.c b/pkcs11/ssh-store/tests/check-ssh-module.c
index eeeb2de..a52dd2e 100644
--- a/pkcs11/ssh-store/tests/check-ssh-module.c
+++ b/pkcs11/ssh-store/tests/check-ssh-module.c
@@ -34,7 +34,7 @@
static int failures = 0;
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
on_p11_tests_log (int level, const char *section, const char *message)
diff --git a/pkcs11/ssh-store/tests/mock-ssh-module.c b/pkcs11/ssh-store/tests/mock-ssh-module.c
index 2cec728..aad0bc3 100644
--- a/pkcs11/ssh-store/tests/mock-ssh-module.c
+++ b/pkcs11/ssh-store/tests/mock-ssh-module.c
@@ -31,7 +31,7 @@
#include "ssh-store/gkm-ssh-store.h"
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static GMutex *mutex = NULL;
diff --git a/pkcs11/ssh-store/tests/test-ssh-openssh.c b/pkcs11/ssh-store/tests/test-ssh-openssh.c
index 12fc0cc..2cc8136 100644
--- a/pkcs11/ssh-store/tests/test-ssh-openssh.c
+++ b/pkcs11/ssh-store/tests/test-ssh-openssh.c
@@ -34,7 +34,7 @@
#include <stdio.h>
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static const gchar *PRIVATE_FILES[] = {
SRCDIR "/files/id_rsa_encrypted",
@@ -95,6 +95,7 @@ test_parse_private (void)
gsize n_data;
int algorithm;
gboolean is_private;
+ EggBytes *bytes;
guint i;
GkmDataResult res;
@@ -104,7 +105,10 @@ test_parse_private (void)
if (!g_file_get_contents (PRIVATE_FILES[i], &data, &n_data, NULL))
g_assert_not_reached ();
- res = gkm_ssh_openssh_parse_private_key (data, n_data, "password", 8, &sexp);
+ bytes = egg_bytes_new_take (data, n_data);
+ res = gkm_ssh_openssh_parse_private_key (bytes, "password", 8, &sexp);
+ egg_bytes_unref (bytes);
+
if (res != GKM_DATA_SUCCESS) {
g_warning ("couldn't parse private key: %s", PRIVATE_FILES[i]);
g_assert_cmpint (res, ==, GKM_DATA_SUCCESS);
@@ -116,7 +120,6 @@ test_parse_private (void)
g_assert_cmpint (algorithm, !=, 0);
g_assert (is_private);
- g_free (data);
gcry_sexp_release (sexp);
}
}
diff --git a/pkcs11/wrap-layer/tests/mock-secret-store.c b/pkcs11/wrap-layer/tests/mock-secret-store.c
index 7e8e08e..5f6a9b5 100644
--- a/pkcs11/wrap-layer/tests/mock-secret-store.c
+++ b/pkcs11/wrap-layer/tests/mock-secret-store.c
@@ -31,7 +31,7 @@
static guint secret_identifier = 8800;
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static CK_RV
mock_secret_C_Initialize (CK_VOID_PTR pInitArgs)
diff --git a/pkcs11/xdg-store/Makefile.am b/pkcs11/xdg-store/Makefile.am
index 569ae65..bbe0e56 100644
--- a/pkcs11/xdg-store/Makefile.am
+++ b/pkcs11/xdg-store/Makefile.am
@@ -1,3 +1,12 @@
+include $(top_srcdir)/Makefile.decl
+
+ASN_FILES = \
+ xdg.asn
+
+ASN_SRCS = $(ASN_FILES:.asn=.asn.h)
+
+BUILT_SOURCES = \
+ $(ASN_SRCS)
INCLUDES = \
-I$(top_builddir) \
@@ -14,21 +23,16 @@ INCLUDES = \
noinst_LTLIBRARIES = \
libgkm-xdg-store.la
-BUILT_SOURCES = \
- asn1-def-xdg.c
-
libgkm_xdg_store_la_SOURCES = \
gkm-xdg-store.h \
+ gkm-xdg-asn1-defs.c gkm-xdg-asn1-defs.h \
gkm-xdg-assertion.c gkm-xdg-assertion.h \
gkm-xdg-module.c gkm-xdg-module.h \
gkm-xdg-trust.c gkm-xdg-trust.h \
$(BUILT_SOURCES)
-asn1-def-xdg.c: xdg.asn
- $(ASN1PARSER) -o asn1-def-xdg.c $(srcdir)/xdg.asn
-
EXTRA_DIST = \
- xdg.asn
+ $(ASN_FILES)
# ------------------------------------------------------------------------------
# The standalone module
diff --git a/pkcs11/xdg-store/gkm-xdg-asn1-defs.c b/pkcs11/xdg-store/gkm-xdg-asn1-defs.c
new file mode 100644
index 0000000..403f620
--- /dev/null
+++ b/pkcs11/xdg-store/gkm-xdg-asn1-defs.c
@@ -0,0 +1,32 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-asn1-defs.c - ASN.1 definitions
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw collabora co uk>
+*/
+
+#include "config.h"
+
+#include "gkm-xdg-asn1-defs.h"
+
+#include <stdlib.h>
+
+typedef struct _EggAsn1xDef ASN1_ARRAY_TYPE;
+
+#include "xdg.asn.h"
diff --git a/pkcs11/xdg-store/gkm-xdg-asn1-defs.h b/pkcs11/xdg-store/gkm-xdg-asn1-defs.h
new file mode 100644
index 0000000..9eebd08
--- /dev/null
+++ b/pkcs11/xdg-store/gkm-xdg-asn1-defs.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-asn1-defs.h - ASN.1 definitions
+
+ Copyright (C) 2010 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef memberwebs com>
+*/
+
+#ifndef GKM_XDG_ASN1_DEFS_H_
+#define GKM_XDG_ASN1_DEFS_H_
+
+#include "egg/egg-asn1-defs.h"
+
+extern const struct _EggAsn1xDef xdg_asn1_tab[];
+
+#endif /* GKM_XDG_ASN1_DEFS_H_ */
diff --git a/pkcs11/xdg-store/gkm-xdg-module.c b/pkcs11/xdg-store/gkm-xdg-module.c
index 708d4ee..fd3da09 100644
--- a/pkcs11/xdg-store/gkm-xdg-module.c
+++ b/pkcs11/xdg-store/gkm-xdg-module.c
@@ -203,6 +203,7 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
GkmManager *manager;
gboolean added = FALSE;
GError *error = NULL;
+ EggBytes *bytes;
GType type;
guchar *data;
gsize n_data;
@@ -243,9 +244,12 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
g_object_unref (object);
g_clear_error (&error);
return;
+ }
+
+ bytes = egg_bytes_new_take (data, n_data);
/* And load the data into it */
- } else if (gkm_serializable_load (GKM_SERIALIZABLE (object), NULL, data, n_data)) {
+ if (gkm_serializable_load (GKM_SERIALIZABLE (object), NULL, bytes)) {
if (added)
add_object_to_module (self, object, path, NULL);
gkm_object_expose (object, TRUE);
@@ -258,6 +262,7 @@ file_load (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
}
}
+ egg_bytes_unref (bytes);
g_object_unref (object);
}
@@ -275,16 +280,19 @@ file_remove (GkmFileTracker *tracker, const gchar *path, GkmXdgModule *self)
}
static gchar*
-name_for_subject (gconstpointer subject, gsize n_subject)
+name_for_subject (gconstpointer data,
+ gsize n_data)
{
+ EggBytes *subject;
GNode *asn;
gchar *name;
- g_assert (subject);
- g_assert (n_subject);
+ g_assert (data != NULL);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Name", subject, n_subject);
- g_return_val_if_fail (asn, NULL);
+ subject = egg_bytes_new (data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Name", subject);
+ g_return_val_if_fail (asn != NULL, NULL);
+ egg_bytes_unref (subject);
name = egg_dn_read_part (egg_asn1x_node (asn, "rdnSequence", NULL), "CN");
egg_asn1x_destroy (asn);
@@ -430,10 +438,9 @@ gkm_xdg_module_real_store_token_object (GkmModule *module, GkmTransaction *trans
GkmObject *object)
{
GkmXdgModule *self = GKM_XDG_MODULE (module);
- GkmTrust *trust;
const gchar *filename;
- gpointer data;
- gsize n_data;
+ EggBytes *bytes;
+ GkmTrust *trust;
/* Always serialize the trust object for each assertion */
if (GKM_XDG_IS_ASSERTION (object)) {
@@ -449,7 +456,9 @@ gkm_xdg_module_real_store_token_object (GkmModule *module, GkmTransaction *trans
}
/* Serialize the object in question */
- if (!gkm_serializable_save (GKM_SERIALIZABLE (object), NULL, &data, &n_data)) {
+ bytes = gkm_serializable_save (GKM_SERIALIZABLE (object), NULL);
+
+ if (bytes == NULL) {
gkm_transaction_fail (transaction, CKR_FUNCTION_FAILED);
g_return_if_reached ();
}
@@ -458,8 +467,10 @@ gkm_xdg_module_real_store_token_object (GkmModule *module, GkmTransaction *trans
g_return_if_fail (filename != NULL);
g_return_if_fail (g_hash_table_lookup (self->objects_by_path, filename) == object);
- gkm_transaction_write_file (transaction, filename, data, n_data);
- g_free (data);
+ gkm_transaction_write_file (transaction, filename,
+ egg_bytes_get_data (bytes),
+ egg_bytes_get_size (bytes));
+ egg_bytes_unref (bytes);
}
static void
diff --git a/pkcs11/xdg-store/gkm-xdg-standalone.c b/pkcs11/xdg-store/gkm-xdg-standalone.c
index dd1d328..8dbfa13 100644
--- a/pkcs11/xdg-store/gkm-xdg-standalone.c
+++ b/pkcs11/xdg-store/gkm-xdg-standalone.c
@@ -35,7 +35,7 @@
#include <gmodule.h>
/* Module callbacks for secure memory */
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
const gchar* g_module_check_init (GModule *module);
diff --git a/pkcs11/xdg-store/gkm-xdg-trust.c b/pkcs11/xdg-store/gkm-xdg-trust.c
index f9a4f59..75f66d4 100644
--- a/pkcs11/xdg-store/gkm-xdg-trust.c
+++ b/pkcs11/xdg-store/gkm-xdg-trust.c
@@ -26,7 +26,6 @@
#include "egg/egg-asn1x.h"
#include "egg/egg-asn1-defs.h"
-#include "egg/egg-byte-array.h"
#include "gkm/gkm-assertion.h"
#include "gkm/gkm-attributes.h"
@@ -45,16 +44,14 @@
#include <glib/gi18n.h>
+extern const struct _EggAsn1xDef xdg_asn1_tab[];
+
struct _GkmXdgTrustPrivate {
GHashTable *assertions;
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *bytes;
};
-/* From asn1-def-xdg.c */
-extern const ASN1_ARRAY_TYPE xdg_asn1_tab[];
-
static void gkm_xdg_trust_serializable (GkmSerializableIface *iface);
G_DEFINE_TYPE_EXTENDED (GkmXdgTrust, gkm_xdg_trust, GKM_TYPE_TRUST, 0,
@@ -107,8 +104,8 @@ static CK_RV
trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
GNode *node;
- gconstpointer element;
- gsize n_element;
+ EggBytes *element;
+ CK_RV rv;
g_assert (GKM_XDG_IS_TRUST (self));
@@ -119,16 +116,18 @@ trust_get_der (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
if (!egg_asn1x_have (node))
return CKR_ATTRIBUTE_TYPE_INVALID;
- element = egg_asn1x_get_raw_element (node, &n_element);
- return gkm_attribute_set_data (attr, element, n_element);
+ element = egg_asn1x_get_element_raw (node);
+ rv = gkm_attribute_set_bytes (attr, element);
+ egg_bytes_unref (element);
+
+ return rv;
}
static CK_RV
trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
{
GNode *node;
- gconstpointer integer;
- gsize n_integer;
+ EggBytes *integer;
CK_RV rv;
g_assert (GKM_XDG_IS_TRUST (self));
@@ -140,10 +139,11 @@ trust_get_integer (GkmXdgTrust *self, const gchar *part, CK_ATTRIBUTE_PTR attr)
if (!egg_asn1x_have (node))
return CKR_ATTRIBUTE_TYPE_INVALID;
- integer = egg_asn1x_get_integer_as_raw (node, &n_integer);
+ integer = egg_asn1x_get_integer_as_raw (node);
g_return_val_if_fail (integer, CKR_GENERAL_ERROR);
- rv = gkm_attribute_set_data (attr, integer, n_integer);
+ rv = gkm_attribute_set_bytes (attr, integer);
+ egg_bytes_unref (integer);
return rv;
}
@@ -152,8 +152,8 @@ static CK_RV
trust_get_hash (GkmXdgTrust *self, GChecksumType ctype, CK_ATTRIBUTE_PTR attr)
{
GNode *cert;
- gconstpointer element;
- gsize n_element;
+ EggBytes *element;
+ CK_RV rv;
cert = egg_asn1x_node (self->pv->asn, "reference", "certComplete", NULL);
g_return_val_if_fail (cert, CKR_GENERAL_ERROR);
@@ -162,18 +162,23 @@ trust_get_hash (GkmXdgTrust *self, GChecksumType ctype, CK_ATTRIBUTE_PTR attr)
if (!egg_asn1x_have (cert))
return CKR_ATTRIBUTE_TYPE_INVALID;
- element = egg_asn1x_get_raw_element (cert, &n_element);
- g_return_val_if_fail (element, CKR_GENERAL_ERROR);
+ element = egg_asn1x_get_element_raw (cert);
+ g_return_val_if_fail (element != NULL, CKR_GENERAL_ERROR);
+
+ rv = gkm_attribute_set_checksum (attr, ctype,
+ egg_bytes_get_data (element),
+ egg_bytes_get_size (element));
- return gkm_attribute_set_checksum (attr, ctype, element, n_element);
+ egg_bytes_unref (element);
+ return rv;
}
static CK_RV
trust_get_complete (GkmXdgTrust *self, CK_ATTRIBUTE_PTR attr)
{
GNode *cert;
- gconstpointer element;
- gsize n_element;
+ EggBytes *element;
+ CK_RV rv;
cert = egg_asn1x_node (self->pv->asn, "reference", "certComplete", NULL);
g_return_val_if_fail (cert, CKR_GENERAL_ERROR);
@@ -182,10 +187,13 @@ trust_get_complete (GkmXdgTrust *self, CK_ATTRIBUTE_PTR attr)
if (!egg_asn1x_have (cert))
return CKR_ATTRIBUTE_TYPE_INVALID;
- element = egg_asn1x_get_raw_element (cert, &n_element);
- g_return_val_if_fail (element, CKR_GENERAL_ERROR);
+ element = egg_asn1x_get_element_raw (cert);
+ g_return_val_if_fail (element != NULL, CKR_GENERAL_ERROR);
+
+ rv = gkm_attribute_set_bytes (attr, element);
+ egg_bytes_unref (element);
- return gkm_attribute_set_data (attr, element, n_element);
+ return rv;
}
@@ -194,6 +202,7 @@ validate_der (CK_ATTRIBUTE_PTR attr, const gchar *asn_type)
{
GNode *asn;
gboolean valid = TRUE;
+ EggBytes *data;
if (!attr->pValue || attr->ulValueLen == (CK_ULONG)-1)
return FALSE;
@@ -201,7 +210,10 @@ validate_der (CK_ATTRIBUTE_PTR attr, const gchar *asn_type)
asn = egg_asn1x_create (pkix_asn1_tab, asn_type);
g_return_val_if_fail (asn, FALSE);
- valid = egg_asn1x_decode (asn, attr->pValue, attr->ulValueLen);
+ data = egg_bytes_new_static (attr->pValue, attr->ulValueLen);
+ valid = egg_asn1x_decode (asn, data);
+ egg_bytes_unref (data);
+
if (!valid)
g_message ("failed to parse certificate passed to trust assertion: %s",
egg_asn1x_message (asn));
@@ -262,8 +274,8 @@ check_and_unref_assertion (gpointer data)
static GHashTable*
create_assertions (void)
{
- return g_hash_table_new_full (egg_byte_array_hash, egg_byte_array_equal,
- (GDestroyNotify)g_byte_array_unref,
+ return g_hash_table_new_full (egg_bytes_hash, egg_bytes_equal,
+ (GDestroyNotify)egg_bytes_unref,
check_and_unref_assertion);
}
@@ -311,41 +323,44 @@ create_assertion (GkmXdgTrust *self, GNode *asn)
return assertion;
}
-static GByteArray*
-create_assertion_key (const gchar *purpose, const gchar *peer)
+static EggBytes *
+create_assertion_key (const gchar *purpose,
+ const gchar *peer)
{
- GByteArray *key;
+ GString *string;
+ gsize len;
g_return_val_if_fail (purpose, NULL);
- key = g_byte_array_new ();
- g_byte_array_append (key, (void*)purpose, strlen (purpose));
+ string = g_string_sized_new (32);
+ g_string_append (string, purpose);
if (peer != NULL) {
- g_byte_array_append (key, (void*)"\0", 1);
- g_byte_array_append (key, (void*)peer, strlen (peer));
+ g_string_append_len (string, "\0", 1);
+ g_string_append (string, peer);
}
- return key;
+ len = string->len;
+ return egg_bytes_new_take (g_string_free (string, FALSE), len);
}
-static GByteArray*
+static EggBytes *
lookup_assertion_key (GkmAssertion *assertion)
{
return g_object_get_qdata (G_OBJECT (assertion), QDATA_ASSERTION_KEY);
}
-static GByteArray*
+static EggBytes *
lookup_or_create_assertion_key (GkmAssertion *assertion)
{
- GByteArray *key;
+ EggBytes *key;
key = lookup_assertion_key (assertion);
if (key == NULL) {
key = create_assertion_key (gkm_assertion_get_purpose (assertion),
gkm_assertion_get_peer (assertion));
g_object_set_qdata_full (G_OBJECT (assertion), QDATA_ASSERTION_KEY,
- g_byte_array_ref (key), (GDestroyNotify)g_byte_array_unref);
+ egg_bytes_ref (key), (GDestroyNotify)egg_bytes_unref);
}
return key;
@@ -368,12 +383,12 @@ static void
add_assertion_to_trust (GkmXdgTrust *self, GkmAssertion *assertion,
GkmTransaction *transaction)
{
- GByteArray *key;
+ EggBytes *key;
key = lookup_or_create_assertion_key (assertion);
- g_assert (key);
+ g_assert (key != NULL);
- g_hash_table_insert (self->pv->assertions, g_byte_array_ref (key), g_object_ref (assertion));
+ g_hash_table_insert (self->pv->assertions, egg_bytes_ref (key), g_object_ref (assertion));
gkm_object_expose (GKM_OBJECT (assertion), gkm_object_is_exposed (GKM_OBJECT (self)));
if (transaction != NULL)
@@ -399,10 +414,10 @@ static void
remove_assertion_from_trust (GkmXdgTrust *self, GkmAssertion *assertion,
GkmTransaction *transaction)
{
- GByteArray *key;
+ EggBytes *key;
key = lookup_assertion_key (assertion);
- g_assert (key);
+ g_assert (key != NULL);
gkm_object_expose (GKM_OBJECT (assertion), FALSE);
@@ -419,11 +434,9 @@ remove_assertion_from_trust (GkmXdgTrust *self, GkmAssertion *assertion,
static gboolean
load_assertions (GkmXdgTrust *self, GNode *asn)
{
- gconstpointer element;
GHashTable *assertions;
GkmAssertion *assertion;
- gsize n_element;
- GByteArray *key;
+ EggBytes *key;
GNode *node;
guint count, i;
@@ -437,15 +450,11 @@ load_assertions (GkmXdgTrust *self, GNode *asn)
for (i = 0; i < count; ++i) {
node = egg_asn1x_node (asn, "assertions", i + 1, NULL);
- g_return_val_if_fail (node, FALSE);
+ g_return_val_if_fail (node != NULL, FALSE);
/* We use the raw DER encoding as an assertion */
- element = egg_asn1x_get_raw_element (node, &n_element);
- g_return_val_if_fail (node, FALSE);
-
- /* Double check that this is valid, because it's how we hash */
- key = g_byte_array_new ();
- g_byte_array_append (key, element, n_element);
+ key = egg_asn1x_get_element_raw (node);
+ g_return_val_if_fail (key != NULL, FALSE);
/* Already have this assertion? */
assertion = g_hash_table_lookup (assertions, key);
@@ -459,7 +468,7 @@ load_assertions (GkmXdgTrust *self, GNode *asn)
}
add_assertion_to_trust (self, assertion, NULL);
- g_byte_array_unref (key);
+ egg_bytes_unref (key);
g_object_unref (assertion);
}
@@ -522,6 +531,7 @@ create_trust_for_reference (GkmModule *module, GkmManager *manager,
{
GkmXdgTrust *trust;
GNode *asn, *ref, *node;
+ EggBytes *bytes;
asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
g_return_val_if_fail (asn, NULL);
@@ -530,20 +540,20 @@ create_trust_for_reference (GkmModule *module, GkmManager *manager,
node = egg_asn1x_node (ref, "certReference", NULL);
egg_asn1x_set_choice (ref, node);
- egg_asn1x_set_integer_as_raw (egg_asn1x_node (node, "serialNumber", NULL),
- g_memdup (serial->pValue, serial->ulValueLen),
- serial->ulValueLen, g_free);
+ bytes = egg_bytes_new (serial->pValue, serial->ulValueLen);
+ egg_asn1x_set_integer_as_raw (egg_asn1x_node (node, "serialNumber", NULL), bytes);
+ egg_bytes_unref (bytes);
- egg_asn1x_set_raw_element (egg_asn1x_node (node, "issuer", NULL),
- g_memdup (issuer->pValue, issuer->ulValueLen),
- issuer->ulValueLen, g_free);
+ bytes = egg_bytes_new (issuer->pValue, issuer->ulValueLen);
+ egg_asn1x_set_element_raw (egg_asn1x_node (node, "issuer", NULL), bytes);
+ egg_bytes_unref (bytes);
trust = g_object_new (GKM_XDG_TYPE_TRUST, "module", module, "manager", manager, NULL);
trust->pv->asn = asn;
/* Encode it, so we have read access to all the data */
- trust->pv->data = egg_asn1x_encode (asn, NULL, &trust->pv->n_data);
- if (!trust->pv->data) {
+ trust->pv->bytes = egg_asn1x_encode (asn, NULL);
+ if (!trust->pv->bytes) {
g_warning ("created invalid trust object: %s", egg_asn1x_message (asn));
return NULL;
}
@@ -557,6 +567,7 @@ create_trust_for_complete (GkmModule *module, GkmManager *manager,
{
GkmXdgTrust *trust;
GNode *asn, *ref, *node;
+ EggBytes *bytes;
asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
g_return_val_if_fail (asn, NULL);
@@ -565,15 +576,16 @@ create_trust_for_complete (GkmModule *module, GkmManager *manager,
node = egg_asn1x_node (ref, "certComplete", NULL);
egg_asn1x_set_choice (ref, node);
- egg_asn1x_set_raw_element (node, g_memdup (cert->pValue, cert->ulValueLen),
- cert->ulValueLen, g_free);
+ bytes = egg_bytes_new (cert->pValue, cert->ulValueLen);
+ egg_asn1x_set_element_raw (node, bytes);
+ egg_bytes_unref (bytes);
trust = g_object_new (GKM_XDG_TYPE_TRUST, "module", module, "manager", manager, NULL);
trust->pv->asn = asn;
/* Encode it, which validates, and so we have read access to all the data */
- trust->pv->data = egg_asn1x_encode (asn, NULL, &trust->pv->n_data);
- if (!trust->pv->data) {
+ trust->pv->bytes = egg_asn1x_encode (asn, NULL);
+ if (!trust->pv->bytes) {
g_warning ("created invalid trust object: %s", egg_asn1x_message (asn));
return NULL;
}
@@ -642,12 +654,12 @@ gkm_xdg_trust_get_level (GkmTrust *base, const gchar *purpose)
{
GkmXdgTrust *self = GKM_XDG_TRUST (base);
GkmAssertion *assertion;
- GByteArray *key;
+ EggBytes *key;
gulong type;
key = create_assertion_key (purpose, NULL);
assertion = g_hash_table_lookup (self->pv->assertions, key);
- g_byte_array_unref (key);
+ egg_bytes_unref (key);
if (!assertion)
return GKM_TRUST_UNKNOWN;
@@ -705,74 +717,64 @@ gkm_xdg_trust_class_init (GkmXdgTrustClass *klass)
}
static gboolean
-gkm_xdg_trust_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data)
+gkm_xdg_trust_real_load (GkmSerializable *base,
+ GkmSecret *login,
+ EggBytes *data)
{
GkmXdgTrust *self = GKM_XDG_TRUST (base);
GNode *asn = NULL;
- gpointer copy;
- g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
- g_return_val_if_fail (data, FALSE);
-
- if (n_data == 0)
+ if (egg_bytes_get_size (data) == 0)
return FALSE;
- copy = g_memdup (data, n_data);
-
asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
g_return_val_if_fail (asn, FALSE);
- if (!egg_asn1x_decode (asn, copy, n_data)) {
+ if (!egg_asn1x_decode (asn, data)) {
g_warning ("couldn't parse trust data: %s", egg_asn1x_message (asn));
egg_asn1x_destroy (asn);
- g_free (copy);
return FALSE;
}
/* Next parse out all the pairs */
if (!load_assertions (self, asn)) {
egg_asn1x_destroy (asn);
- g_free (copy);
return FALSE;
}
/* Take ownership of this new data */
- g_free (self->pv->data);
- self->pv->data = copy;
- self->pv->n_data = n_data;
+ if (self->pv->bytes)
+ egg_bytes_unref (self->pv->bytes);
+ self->pv->bytes = egg_bytes_ref (data);
egg_asn1x_destroy (self->pv->asn);
self->pv->asn = asn;
return TRUE;
}
-static gboolean
-gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data)
+static EggBytes *
+gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login)
{
GkmXdgTrust *self = GKM_XDG_TRUST (base);
+ EggBytes *bytes;
g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
g_return_val_if_fail (self->pv->asn, FALSE);
if (!save_assertions (self, self->pv->asn))
return FALSE;
- *data = egg_asn1x_encode (self->pv->asn, NULL, n_data);
- if (*data == NULL) {
+ bytes = egg_asn1x_encode (self->pv->asn, NULL);
+ if (bytes == NULL) {
g_warning ("encoding trust failed: %s", egg_asn1x_message (self->pv->asn));
return FALSE;
}
- /* ASN.1 now refers to this data, take ownership */
- g_free (self->pv->data);
- self->pv->data = *data;
- self->pv->n_data = *n_data;
+ if (self->pv->bytes)
+ egg_bytes_unref (self->pv->bytes);
+ self->pv->bytes = bytes;
- /* Return a duplicate, since we own encoded */
- *data = g_memdup (*data, *n_data);
- return TRUE;
+ return egg_bytes_ref (bytes);
}
static void
@@ -847,7 +849,7 @@ gkm_xdg_trust_replace_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
GkmTransaction *transaction)
{
GkmAssertion *previous;
- GByteArray *key;
+ EggBytes *key;
g_return_if_fail (GKM_XDG_IS_TRUST (self));
g_return_if_fail (GKM_IS_ASSERTION (assertion));
@@ -862,14 +864,14 @@ gkm_xdg_trust_replace_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
remove_assertion_from_trust (self, previous, transaction);
add_assertion_to_trust (self, assertion, transaction);
- g_byte_array_unref (key);
+ egg_bytes_unref (key);
}
void
gkm_xdg_trust_remove_assertion (GkmXdgTrust *self, GkmAssertion *assertion,
GkmTransaction *transaction)
{
- GByteArray *key;
+ EggBytes *key;
g_return_if_fail (GKM_XDG_IS_TRUST (self));
g_return_if_fail (GKM_IS_ASSERTION (assertion));
diff --git a/pkcs11/xdg-store/tests/check-xdg-module.c b/pkcs11/xdg-store/tests/check-xdg-module.c
index 64ea387..4ed03a0 100644
--- a/pkcs11/xdg-store/tests/check-xdg-module.c
+++ b/pkcs11/xdg-store/tests/check-xdg-module.c
@@ -34,7 +34,7 @@
static int failures = 0;
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static void
on_p11_tests_log (int level, const char *section, const char *message)
diff --git a/pkcs11/xdg-store/tests/dump-trust-file.c b/pkcs11/xdg-store/tests/dump-trust-file.c
index a0a1ca3..14c31a3 100644
--- a/pkcs11/xdg-store/tests/dump-trust-file.c
+++ b/pkcs11/xdg-store/tests/dump-trust-file.c
@@ -33,8 +33,7 @@
#include <stdlib.h>
/* Bring in the relevant definitions */
-#include "../asn1-def-xdg.c"
-
+#include "xdg-store/gkm-xdg-asn1-defs.h"
static void
barf_and_die (const char *msg, const char *detail)
@@ -50,26 +49,25 @@ static void
dump_certificate_reference (GNode *asn)
{
gchar *issuer, *serial;
- gconstpointer data;
- gsize n_data;
+ EggBytes *data;
GNode *name;
- gconstpointer element;
- gsize n_element;
+ EggBytes *element;
/* Parse the name out */
name = egg_asn1x_create (pkix_asn1_tab, "Name");
g_return_if_fail (name);
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "issuer", NULL), &n_element);
+ element = egg_asn1x_get_element_raw (egg_asn1x_node (asn, "issuer", NULL));
g_return_if_fail (element);
- if (!egg_asn1x_decode (name, element, n_element))
+ if (!egg_asn1x_decode (name, element))
barf_and_die ("couldn't parse certificate", egg_asn1x_message (name));
+ egg_bytes_unref (element);
issuer = egg_dn_read (name);
g_return_if_fail (issuer);
- data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL), &n_data);
- g_return_if_fail (data && n_data);
- serial = egg_hex_encode (data, n_data);
+ data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL));
+ g_return_if_fail (data != NULL);
+ serial = egg_hex_encode (egg_bytes_get_data (data), egg_bytes_get_size (data));
g_print ("Reference\n");
g_print (" issuer: %s\n", issuer);
@@ -86,17 +84,18 @@ dump_certificate_complete (GNode *asn)
{
GNode *cert;
gchar *issuer, *serial, *subject;
- gconstpointer element;
- gconstpointer data;
- gsize n_data, n_element;
+ EggBytes *element;
+ EggBytes *data;
/* Parse the certificate out */
cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_return_if_fail (cert);
- element = egg_asn1x_get_raw_element (asn, &n_element);
+
+ element = egg_asn1x_get_element_raw (asn);
g_return_if_fail (element);
- if (!egg_asn1x_decode (cert, element, n_element))
+ if (!egg_asn1x_decode (cert, element))
barf_and_die ("couldn't parse certificate", egg_asn1x_message (cert));
+ egg_bytes_unref (element);
issuer = egg_dn_read (egg_asn1x_node (asn, "issuer", NULL));
g_return_if_fail (issuer);
@@ -104,9 +103,10 @@ dump_certificate_complete (GNode *asn)
subject = egg_dn_read (egg_asn1x_node (asn, "subject", NULL));
g_return_if_fail (subject);
- data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL), &n_data);
- g_return_if_fail (data && n_data);
- serial = egg_hex_encode (data, n_data);
+ data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL));
+ g_return_if_fail (data != NULL);
+ serial = egg_hex_encode (egg_bytes_get_data (data), egg_bytes_get_size (data));
+ egg_bytes_unref (data);
g_print ("Complete\n");
g_print (" issuer: %s\n", issuer);
@@ -155,6 +155,7 @@ main(int argc, char* argv[])
gchar *contents;
gsize n_contents;
GNode *asn, *node;
+ EggBytes *bytes;
gint i, count;
if (argc != 2) {
@@ -168,8 +169,10 @@ main(int argc, char* argv[])
asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
g_return_val_if_fail (asn, 1);
- if (!egg_asn1x_decode (asn, contents, n_contents))
+ bytes = egg_bytes_new_take (contents, n_contents);
+ if (!egg_asn1x_decode (asn, bytes))
barf_and_die ("couldn't parse file", egg_asn1x_message (asn));
+ egg_bytes_unref (bytes);
/* Print out the certificate we refer to first */
node = egg_asn1x_node (asn, "reference", "certReference", NULL);
diff --git a/pkcs11/xdg-store/tests/frob-trust-file.c b/pkcs11/xdg-store/tests/frob-trust-file.c
index 129e609..a576377 100644
--- a/pkcs11/xdg-store/tests/frob-trust-file.c
+++ b/pkcs11/xdg-store/tests/frob-trust-file.c
@@ -31,8 +31,7 @@
#include <libtasn1.h>
#include <stdlib.h>
-/* Bring in the relevant definitions */
-#include "../asn1-def-xdg.c"
+#include "xdg-store/gkm-xdg-asn1-defs.h"
static void
barf_and_die (const gchar *msg, const gchar *detail)
@@ -49,8 +48,9 @@ create_trust_file_for_certificate (const gchar *filename, const gchar *certifica
{
GError *err = NULL;
GNode *asn, *cert, *choice, *ref;
- gchar *data, *result;
- gsize n_data, n_result;
+ EggBytes *bytes, *result;
+ gchar *data;
+ gsize n_data;
if (!g_file_get_contents (certificate, &data, &n_data, &err))
barf_and_die ("couldn't read certificate file", egg_error_message (err));
@@ -58,7 +58,9 @@ create_trust_file_for_certificate (const gchar *filename, const gchar *certifica
/* Make sure the certificate is */
cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_return_if_fail (cert);
- if (!egg_asn1x_decode (cert, data, n_data))
+
+ bytes = egg_bytes_new_take (data, n_data);
+ if (!egg_asn1x_decode (cert, bytes))
barf_and_die ("couldn't parse der certificate file", egg_asn1x_message (cert));
asn = egg_asn1x_create (xdg_asn1_tab, "trust-1");
@@ -67,19 +69,23 @@ create_trust_file_for_certificate (const gchar *filename, const gchar *certifica
ref = egg_asn1x_node (asn, "reference", NULL);
choice = egg_asn1x_node (ref, "certComplete", NULL);
- if (!egg_asn1x_set_choice (ref, choice) ||
- !egg_asn1x_set_raw_element (choice, data, n_data, g_free))
+ if (!egg_asn1x_set_choice (ref, choice) || !egg_asn1x_set_element_raw (choice, bytes))
g_return_if_reached ();
- result = egg_asn1x_encode (asn, NULL, &n_result);
+ egg_bytes_unref (bytes);
+
+ result = egg_asn1x_encode (asn, NULL);
if (result == NULL)
barf_and_die ("couldn't encode the trust file", egg_asn1x_message (asn));
egg_asn1x_destroy (asn);
egg_asn1x_destroy (cert);
- if (!g_file_set_contents (filename, result, n_result, &err))
+ if (!g_file_set_contents (filename, egg_bytes_get_data (result),
+ egg_bytes_get_size (result), &err))
barf_and_die ("couldn't write trust file", egg_error_message (err));
+
+ egg_bytes_unref (result);
}
static void
@@ -88,10 +94,12 @@ create_trust_file_for_issuer_and_serial (const gchar *filename, const gchar *cer
GError *err = NULL;
GNode *asn, *cert, *choice, *ref;
GNode *issuer, *serial;
- gchar *data, *result;
- gconstpointer value;
- gconstpointer element;
- gsize n_data, n_result, n_element, n_value;
+ gchar *data;
+ EggBytes *result;
+ EggBytes *value;
+ EggBytes *element;
+ gsize n_data;
+ EggBytes *bytes;
if (!g_file_get_contents (certificate, &data, &n_data, &err))
barf_and_die ("couldn't read certificate file", egg_error_message (err));
@@ -99,8 +107,11 @@ create_trust_file_for_issuer_and_serial (const gchar *filename, const gchar *cer
/* Make sure the certificate is */
cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_return_if_fail (cert);
- if (!egg_asn1x_decode (cert, data, n_data))
+
+ bytes = egg_bytes_new_take (data, n_data);
+ if (!egg_asn1x_decode (cert, bytes))
barf_and_die ("couldn't parse der certificate file", egg_asn1x_message (cert));
+ egg_bytes_unref (bytes);
/* Dig out the issuer and serial */
issuer = egg_asn1x_node (cert, "tbsCertificate", "issuer", NULL);
@@ -118,15 +129,16 @@ create_trust_file_for_issuer_and_serial (const gchar *filename, const gchar *cer
g_return_if_reached ();
/* Copy over the serial and issuer */
- element = egg_asn1x_get_raw_element (issuer, &n_element);
- if (!egg_asn1x_set_raw_element (egg_asn1x_node (choice, "issuer", NULL),
- g_memdup (element, n_element), n_element, g_free))
- g_return_if_reached ();
- value = egg_asn1x_get_integer_as_raw (serial, &n_value);
- if (!egg_asn1x_set_integer_as_raw (egg_asn1x_node (choice, "serialNumber", NULL), value, n_value, NULL))
+ element = egg_asn1x_get_element_raw (issuer);
+ if (!egg_asn1x_set_element_raw (egg_asn1x_node (choice, "issuer", NULL), element))
g_return_if_reached ();
+ egg_bytes_unref (element);
+
+ value = egg_asn1x_get_integer_as_raw (serial);
+ egg_asn1x_set_integer_as_raw (egg_asn1x_node (choice, "serialNumber", NULL), value);
+ egg_bytes_unref (value);
- result = egg_asn1x_encode (asn, NULL, &n_result);
+ result = egg_asn1x_encode (asn, NULL);
if (result == NULL)
barf_and_die ("couldn't encode the trust file", egg_asn1x_message (asn));
@@ -134,19 +146,22 @@ create_trust_file_for_issuer_and_serial (const gchar *filename, const gchar *cer
egg_asn1x_destroy (cert);
egg_asn1x_destroy (asn);
- if (!g_file_set_contents (filename, result, n_result, &err))
+ if (!g_file_set_contents (filename, egg_bytes_get_data (result),
+ egg_bytes_get_size (result), &err))
barf_and_die ("couldn't write trust file", egg_error_message (err));
- g_free (result);
+ egg_bytes_unref (result);
}
static void
add_trust_purpose_to_file (const gchar *filename, const gchar *purpose)
{
GError *err = NULL;
- gchar *data, *result;
- gsize n_data, n_result;
+ gchar *data;
+ EggBytes *result;
+ gsize n_data;
GNode *asn, *assertion;
+ EggBytes *bytes;
if (!g_file_get_contents (filename, &data, &n_data, &err))
barf_and_die ("couldn't read trust file", egg_error_message (err));
@@ -156,8 +171,10 @@ add_trust_purpose_to_file (const gchar *filename, const gchar *purpose)
g_return_if_fail (asn);
/* And parse it */
- if (!egg_asn1x_decode (asn, data, n_data))
+ bytes = egg_bytes_new_take (data, n_data);
+ if (!egg_asn1x_decode (asn, bytes))
barf_and_die ("couldn't parse trust file", egg_asn1x_message (asn));
+ egg_bytes_unref (bytes);
assertion = egg_asn1x_append (egg_asn1x_node (asn, "assertions", NULL));
g_return_if_fail (assertion);
@@ -166,14 +183,15 @@ add_trust_purpose_to_file (const gchar *filename, const gchar *purpose)
!egg_asn1x_set_enumerated (egg_asn1x_node (assertion, "level", NULL), g_quark_from_string ("trusted")))
g_return_if_reached ();
- result = egg_asn1x_encode (asn, NULL, &n_result);
+ result = egg_asn1x_encode (asn, NULL);
if (result == NULL)
barf_and_die ("couldn't encode trust file", egg_asn1x_message (asn));
g_free (data);
egg_asn1x_destroy (asn);
- if (!g_file_set_contents (filename, result, n_result, &err))
+ if (!g_file_set_contents (filename, egg_bytes_get_data (result),
+ egg_bytes_get_size (result), &err))
barf_and_die ("couldn't write trust file", egg_error_message (err));
g_free (result);
diff --git a/pkcs11/xdg-store/tests/mock-xdg-module.c b/pkcs11/xdg-store/tests/mock-xdg-module.c
index f8271c2..a3b8cb9 100644
--- a/pkcs11/xdg-store/tests/mock-xdg-module.c
+++ b/pkcs11/xdg-store/tests/mock-xdg-module.c
@@ -41,7 +41,7 @@
#include <string.h>
-EGG_SECURE_GLIB_DEFINITIONS ();
+EGG_SECURE_DEFINE_GLIB_GLOBALS ();
static GMutex *mutex = NULL;
static gchar *directory = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]