[gnome-keyring] Use new DER decoding and encoding routines.
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] Use new DER decoding and encoding routines.
- Date: Sat, 10 Jul 2010 23:58:35 +0000 (UTC)
commit 8d7e551b8575e4916542f17ba3a5185816400f0e
Author: Stef Walter <stef memberwebs com>
Date: Fri Jul 9 16:57:20 2010 +0000
Use new DER decoding and encoding routines.
* Benefits are less copies of sensitive data in memory.
* More insightful parsing and API.
egg/.gitignore | 2 +-
egg/Makefile.am | 19 +-
egg/egg-asn1-defs.h | 32 +
egg/egg-asn1.c | 817 --------------------------
egg/egg-asn1.h | 80 ---
egg/egg-asn1x.c | 921 +++++++++++++++++++++++++++---
egg/egg-asn1x.h | 79 +++-
egg/egg-dn.c | 179 +++----
egg/egg-dn.h | 29 +-
egg/egg-symkey.c | 166 +++---
egg/tests/Makefile.am | 13 +-
egg/tests/test-asn1.c | 229 +++++++-
egg/tests/test-asn1x.c | 6 +-
egg/tests/test-data/test-pkcs7-2.der | Bin 0 -> 1002 bytes
egg/tests/test-dn.c | 45 +-
egg/tests/test.asn | 29 +-
egg/tests/tests.asn | 19 -
egg/tests/unit-test-asn1.c | 341 ++++++-----
gcr/gcr-certificate-details-widget.c | 122 ++--
gcr/gcr-certificate.c | 107 ++--
gcr/gcr-parser.c | 414 +++++++-------
gcr/gcr-simple-certificate.c | 1 -
pkcs11/gkm/gkm-certificate-trust.c | 2 +-
pkcs11/gkm/gkm-certificate.c | 66 +--
pkcs11/gkm/gkm-data-asn1.c | 48 +--
pkcs11/gkm/gkm-data-asn1.h | 9 +-
pkcs11/gkm/gkm-data-der.c | 449 +++++++--------
pkcs11/gkm/gkm-data-der.h | 11 +-
pkcs11/gkm/tests/unit-test-data-asn1.c | 51 +--
pkcs11/gkm/tests/unit-test-data-der.c | 65 ++-
pkcs11/ssh-store/gkm-ssh-openssh.c | 3 +-
pkcs11/user-store/gkm-user-private-key.c | 17 +-
pkcs11/user-store/gkm-user-storage.c | 10 +-
po/POTFILES.in | 1 -
34 files changed, 2225 insertions(+), 2157 deletions(-)
---
diff --git a/egg/.gitignore b/egg/.gitignore
index 7061f83..2d6c41b 100644
--- a/egg/.gitignore
+++ b/egg/.gitignore
@@ -1,3 +1,3 @@
-asn1-def-*.h
+asn1-def-*.[ch]
/tests/test-asn1x
diff --git a/egg/Makefile.am b/egg/Makefile.am
index e47c560..527d80e 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -10,7 +10,7 @@ noinst_LTLIBRARIES = \
libegg-entry-buffer.la
BUILT_SOURCES = \
- asn1-def-pk.h asn1-def-pkix.h
+ asn1-def-pk.c asn1-def-pkix.c
INCLUDES = \
-I$(top_srcdir)
@@ -21,7 +21,6 @@ libegg_la_CFLAGS = \
$(GLIB_CFLAGS)
libegg_la_SOURCES = \
- egg-asn1.c egg-asn1.h \
egg-asn1x.c egg-asn1x.h \
egg-buffer.c egg-buffer.h \
egg-cleanup.c egg-cleanup.h \
@@ -38,13 +37,14 @@ libegg_la_SOURCES = \
egg-secure-memory.c egg-secure-memory.h \
egg-spawn.c egg-spawn.h \
egg-symkey.c egg-symkey.h \
+ egg-asn1-defs.h \
$(BUILT_SOURCES)
-
-asn1-def-pk.h: pk.asn
- $(ASN1PARSER) -o asn1-def-pk.h $(srcdir)/pk.asn
-
-asn1-def-pkix.h: pkix.asn
- $(ASN1PARSER) -o asn1-def-pkix.h $(srcdir)/pkix.asn
+
+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 \
@@ -57,7 +57,8 @@ DISTCLEANFILES = \
# COMMON STUFF COMPILED INTO SMALLER COMPONENTS
libegg_asn1x_la_SOURCES = \
- egg-asn1x.c egg-asn1x.h
+ egg-asn1x.c egg-asn1x.h \
+ $(BUILT_SOURCES)
libegg_asn1x_la_CFLAGS = \
$(LIBTASN1_CFLAGS) \
diff --git a/egg/egg-asn1-defs.h b/egg/egg-asn1-defs.h
new file mode 100644
index 0000000..02fe427
--- /dev/null
+++ b/egg/egg-asn1-defs.h
@@ -0,0 +1,32 @@
+/* -*- 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 EGG_ASN1_DEFS_H_
+#define EGG_ASN1_DEFS_H_
+
+#include <libtasn1.h>
+
+extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
+extern const ASN1_ARRAY_TYPE pk_asn1_tab[];
+
+#endif /*EGG_ASN1_DEFS_H_*/
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index 1c71e8f..3a46ddf 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -86,11 +86,11 @@ typedef struct _Aenc Aenc;
typedef struct _Atlv Atlv;
typedef struct _Anode Anode;
typedef struct _Abuf Abuf;
+typedef struct _Abits Abits;
struct _Aenc {
EggAsn1xEncoder encoder;
- gpointer user_data;
- GDestroyNotify destroy;
+ gpointer data;
};
struct _Atlv {
@@ -109,6 +109,8 @@ struct _Anode {
GList *opts;
Atlv *tlv;
Aenc *enc;
+ gpointer user_data;
+ GDestroyNotify destroy;
gchar* failure;
};
@@ -118,6 +120,12 @@ struct _Abuf {
gpointer user_data;
};
+struct _Abits {
+ guint n_bits;
+ guchar *bits;
+ GDestroyNotify destroy;
+};
+
/* Forward Declarations */
static gboolean anode_decode_anything (GNode*, Atlv*);
static gboolean anode_decode_anything_for_flags (GNode *, Atlv*, gint);
@@ -229,7 +237,7 @@ anode_def_value (GNode *node)
}
static gulong
-anode_def_value_as_ulong (ASN1_ARRAY_TYPE *def)
+anode_def_value_as_ulong (const ASN1_ARRAY_TYPE *def)
{
gchar *end = NULL;
gulong lval;
@@ -342,23 +350,31 @@ anode_clr_enc_data (GNode *node)
{
Anode *an = node->data;
if (an->enc) {
- if (an->enc->destroy)
- (an->enc->destroy) (an->enc->user_data);
g_slice_free (Aenc, an->enc);
an->enc = NULL;
}
}
static void
-anode_set_enc_data (GNode *node, EggAsn1xEncoder encoder,
- gpointer user_data, GDestroyNotify destroy)
+anode_set_enc_data (GNode *node, EggAsn1xEncoder encoder, gpointer enc_data)
{
Anode *an = node->data;
g_assert (!an->enc);
an->enc = g_slice_new0 (Aenc);
an->enc->encoder = encoder;
- an->enc->user_data = user_data;
- an->enc->destroy = destroy;
+ 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;
}
static Aenc*
@@ -384,7 +400,7 @@ anode_failure (GNode *node, const gchar *failure)
g_free (an->failure);
an->failure = g_strdup_printf ("%s: %s", prefix, failure);
- return FALSE; /* So this can be changed */
+ return FALSE; /* So this can be chained */
}
static const gchar*
@@ -400,6 +416,7 @@ anode_clear (GNode *node)
Anode *an = node->data;
anode_clr_tlv_data (node);
anode_clr_enc_data (node);
+ anode_set_user_data (node, NULL, NULL);
g_free (an->failure);
an->failure = NULL;
}
@@ -415,6 +432,16 @@ anode_free_func (GNode *node, gpointer unused)
}
static void
+abits_destroy (gpointer data)
+{
+ Abits *ab = data;
+ g_assert (ab);
+ if (ab->destroy)
+ (ab->destroy) (ab->bits);
+ g_slice_free (Abits, ab);
+}
+
+static void
anode_destroy (GNode *node)
{
if (!G_NODE_IS_ROOT (node))
@@ -494,6 +521,25 @@ anode_calc_tag (GNode *node)
return anode_calc_tag_for_flags (node, anode_def_flags (node));
}
+static gboolean
+anode_calc_explicit_for_flags (GNode *node, gint flags)
+{
+ const ASN1_ARRAY_TYPE *opt;
+ if ((flags & FLAG_TAG) != FLAG_TAG)
+ return FALSE;
+ opt = anode_opt_lookup (node, TYPE_TAG, NULL);
+ g_return_val_if_fail (opt, FALSE);
+ if ((opt->type & FLAG_IMPLICIT) == FLAG_IMPLICIT)
+ return FALSE;
+ return TRUE;
+}
+
+static gboolean
+anode_calc_explicit (GNode *node)
+{
+ return anode_calc_explicit_for_flags (node, anode_def_flags (node));
+}
+
/* -------------------------------------------------------------------------
* DECODE
*/
@@ -801,7 +847,7 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
end = tlv->end;
/* An explicit, wrapped tag */
- if (flags & FLAG_TAG && !(flags & FLAG_IMPLICIT)) {
+ if (anode_calc_explicit_for_flags (node, flags)) {
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))
@@ -820,8 +866,6 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
/* Other structured types */
} else {
- if ((tlv->cls & ASN1_CLASS_CONTEXT_SPECIFIC) != 0)
- return anode_failure (node, "invalid context specific tag");
switch (anode_def_type (node)) {
case TYPE_ANY:
if (!anode_decode_struct_any (node, tlv))
@@ -886,16 +930,8 @@ anode_decode_anything_for_flags (GNode *node, Atlv *tlv, gint flags)
tag = tlv->tag;
/* Tag does not match, what do we do? */
- if (tlv->off == 0 || tag != tlv->tag) {
- if (flags & FLAG_OPTION || flags & FLAG_DEFAULT) {
- tlv->len = 0;
- tlv->end = tlv->buf;
- tlv->off = 0;
- return TRUE;
- } else {
- return FALSE;
- }
- }
+ if (tlv->off == 0 || tag != tlv->tag)
+ return FALSE;
/* Structured value */
if (tlv->cls & ASN1_CLASS_STRUCTURED)
@@ -911,7 +947,21 @@ anode_decode_anything_for_flags (GNode *node, Atlv *tlv, gint flags)
static gboolean
anode_decode_anything (GNode *node, Atlv *tlv)
{
- return anode_decode_anything_for_flags (node, tlv, anode_def_flags (node));
+ gint flags = anode_def_flags (node);
+
+ if (!anode_decode_anything_for_flags (node, tlv, flags)) {
+ if (flags & FLAG_OPTION || flags & FLAG_DEFAULT) {
+ tlv->len = 0;
+ tlv->end = tlv->buf;
+ tlv->off = 0;
+ anode_clr_tlv_data (node);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ return TRUE;
}
gboolean
@@ -1031,7 +1081,7 @@ 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 = !(flags & FLAG_IMPLICIT);
+ explicit = anode_calc_explicit_for_flags (node, flags);
if (explicit)
flags &= ~FLAG_TAG;
else
@@ -1053,11 +1103,12 @@ anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
}
/* Not completely filled in */
- tlv.buf = tlv.end = 0;
+ tlv.buf = tlv.end = NULL;
anode_clear (node);
anode_set_tlv_data (node, &tlv);
- anode_set_enc_data (node, encoder, user_data, destroy);
+ anode_set_enc_data (node, encoder, user_data);
+ anode_set_user_data (node, user_data, destroy);
}
static gboolean
@@ -1081,7 +1132,7 @@ anode_encode_build (GNode *node, guchar *data, gsize n_data)
/* Encode any explicit tag */
flags = anode_def_flags (node);
- if (flags & FLAG_TAG && !(flags & FLAG_IMPLICIT)) {
+ if (anode_calc_explicit_for_flags (node, flags)) {
tag = anode_calc_tag (node);
g_return_val_if_fail (tag != G_MAXULONG, FALSE);
cls = (ASN1_CLASS_STRUCTURED | ASN1_CLASS_CONTEXT_SPECIFIC);
@@ -1100,7 +1151,7 @@ anode_encode_build (GNode *node, guchar *data, gsize n_data)
tlv->end = data + n_data;
/* Encode in the data */
- if (!(enc->encoder) (enc->user_data, data + tlv->off, tlv->len))
+ if (!(enc->encoder) (enc->data, data + tlv->off, tlv->len))
return FALSE;
return TRUE;
@@ -1159,6 +1210,8 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
Atlv *tlv;
GNode *child;
+ g_assert (allocator);
+
/* We have to sort any SET OF :( */
if (anode_def_type (node) != TYPE_SET_OF)
return FALSE;
@@ -1248,7 +1301,7 @@ anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
if (ctlv) {
enc = anode_get_enc_data (child);
g_return_val_if_fail (enc, FALSE);
- if (!(enc->encoder) (enc->user_data, data, n_data))
+ if (!(enc->encoder) (enc->data, data, n_data))
return FALSE;
/* Child's buffer matches ours */
@@ -1262,19 +1315,49 @@ 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)
+{
+ Abits *ab = user_data;
+ guchar empty, mask;
+ gsize len;
+
+ empty = ab->n_bits % 8;
+ if (empty > 0)
+ empty = 8 - empty;
+ len = (ab->n_bits / 8) + (empty ? 1 : 0);
+ g_assert (n_data == len + 1);
+
+ /* Fill in the amount of empty */
+ data[0] = empty;
+ data += 1;
+
+ /* Fill in the actual data */
+ memcpy (data, ab->bits, len);
+
+ /* Set the extra bits to zero */
+ if (len && empty) {
+ mask = 0xFF >> (8 - empty);
+ data[len - 1] &= ~mask;
+ }
+
+ return TRUE;
+}
+
+static gboolean
anode_encode_prepare_simple (GNode *node)
{
Aenc *enc;
Atlv *tlv;
- enc = anode_get_enc_data (node);
tlv = anode_get_tlv_data (node);
- if (enc != NULL || tlv == NULL)
+ if (tlv == NULL)
return FALSE;
/* Transfer the tlv data over to enc */
- anode_set_enc_data (node, anode_encoder_simple,
- (guchar*)tlv->buf + tlv->off, NULL);
+ enc = anode_get_enc_data (node);
+ if (enc == NULL)
+ anode_set_enc_data (node, anode_encoder_simple, (guchar*)tlv->buf + tlv->off);
+
tlv->buf = tlv->end = NULL;
return TRUE;
}
@@ -1314,7 +1397,7 @@ anode_encode_prepare_structured (GNode *node)
g_return_val_if_fail (tlv, had);
anode_clr_tlv_data (node);
anode_set_tlv_data (node, tlv);
- anode_set_enc_data (node, anode_encoder_choice, node, NULL);
+ anode_set_enc_data (node, anode_encoder_choice, node);
}
/* Other container types */
@@ -1366,7 +1449,8 @@ egg_asn1x_encode (GNode *asn, EggAllocator allocator, gsize *n_data)
if (!allocator)
allocator = g_realloc;
- anode_encode_prepare (asn);
+ if (!anode_encode_prepare (asn))
+ return NULL;
/* We must sort all the nasty SET OF nodes */
g_node_traverse (asn, G_POST_ORDER, G_TRAVERSE_ALL, -1,
@@ -1865,7 +1949,7 @@ anode_read_object_id (GNode *node, Atlv *tlv, gchar **oid)
val = p[0] - pval * 40;
if (result)
- g_string_append_printf (result, "%u.%u.", pval, val);
+ g_string_append_printf (result, "%u.%u", pval, val);
/* TODO: Validate first byte? */
for (k = 1, lead = 1, val = 0, pval = 0; k < tlv->len; ++k) {
@@ -1884,7 +1968,7 @@ anode_read_object_id (GNode *node, Atlv *tlv, gchar **oid)
pval = val;
if (!(p[k] & 0x80)) {
if (result)
- g_string_append_printf (result, "%u.", val);
+ g_string_append_printf (result, ".%u", val);
pval = val = 0;
lead = 1;
}
@@ -1904,7 +1988,7 @@ anode_read_object_id (GNode *node, Atlv *tlv, gchar **oid)
static gboolean
anode_write_oid (const gchar *oid, guchar *data, gsize *n_data)
{
- const gchar *p;
+ const gchar *p, *next;
gint num, num1;
guchar bit7;
gboolean had;
@@ -1913,10 +1997,12 @@ anode_write_oid (const gchar *oid, guchar *data, gsize *n_data)
p = oid;
at = 0;
- for (i = 0; oid[0]; ++i, oid = p) {
+ for (i = 0; oid[0]; ++i, oid = next) {
p = strchr (oid, '.');
if (p == NULL)
- p = oid + strlen (oid);
+ next = p = oid + strlen (oid);
+ else
+ next = p + 1;
if (p == oid)
return FALSE;
num = atoin (oid, p - oid);
@@ -1975,7 +2061,18 @@ egg_asn1x_node (GNode *asn, ...)
index = va_arg (va, gint);
if (index == 0)
return node;
- node = g_node_nth_child (node, index);
+
+ /* Only consider nodes that have data */
+ node = g_node_nth_child (node, 0);
+ while (node) {
+ if (egg_asn1x_have (node)) {
+ --index;
+ if (index == 0)
+ break;
+ }
+ node = g_node_next_sibling (node);
+ }
+
if (node == NULL)
return NULL;
@@ -1996,9 +2093,46 @@ egg_asn1x_node (GNode *asn, ...)
}
}
+const gchar*
+egg_asn1x_name (GNode *node)
+{
+ g_return_val_if_fail (node, NULL);
+ return anode_def_name (node);
+}
+
+guint
+egg_asn1x_count (GNode *node)
+{
+ gint type;
+
+ g_return_val_if_fail (node, 0);
+
+ type = anode_def_type (node);
+ if (type != TYPE_SEQUENCE_OF && type != TYPE_SET_OF) {
+ g_warning ("node passed to egg_asn1x_count was not a sequence of or set of");
+ return 0;
+ }
+
+ return g_node_n_children (node);
+}
+
+gboolean
+egg_asn1x_have (GNode *node)
+{
+ Atlv *tlv;
+
+ g_return_val_if_fail (node, FALSE);
+
+ /* TODO: Handle default values */
+
+ tlv = anode_get_tlv_data (node);
+ return tlv != NULL && tlv->buf != NULL;
+}
+
gboolean
egg_asn1x_get_boolean (GNode *node, gboolean *value)
{
+ ASN1_ARRAY_TYPE *opt;
Atlv *tlv;
g_return_val_if_fail (node, FALSE);
@@ -2006,8 +2140,24 @@ egg_asn1x_get_boolean (GNode *node, gboolean *value)
g_return_val_if_fail (anode_def_type (node) == TYPE_BOOLEAN, FALSE);
tlv = anode_get_tlv_data (node);
- if (tlv == NULL)
- return FALSE;
+ if (tlv == NULL || tlv->buf == NULL) {
+
+ if ((anode_def_flags (node) & FLAG_DEFAULT) == 0)
+ return FALSE;
+
+ /* Try to get a default */
+ opt = anode_opt_lookup (node, TYPE_DEFAULT, NULL);
+ g_return_val_if_fail (opt, FALSE);
+
+ /* Parse out the default value */
+ if ((opt->type & FLAG_TRUE) == FLAG_TRUE)
+ *value = TRUE;
+ else if ((opt->type & FLAG_FALSE) == FLAG_FALSE)
+ *value = FALSE;
+ else
+ g_return_val_if_reached (FALSE);
+ return TRUE;
+ }
return anode_read_boolean (node, tlv, value);
}
@@ -2021,6 +2171,8 @@ egg_asn1x_set_boolean (GNode *node, gboolean value)
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (anode_def_type (node) == TYPE_BOOLEAN, FALSE);
+ /* TODO: Handle default values */
+
n_data = 1;
data = g_malloc0 (1);
if (!anode_write_boolean (value, data, &n_data))
@@ -2032,16 +2184,44 @@ egg_asn1x_set_boolean (GNode *node, gboolean value)
gboolean
egg_asn1x_get_integer_as_ulong (GNode *node, gulong *value)
{
+ const ASN1_ARRAY_TYPE *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);
tlv = anode_get_tlv_data (node);
- if (tlv == NULL)
+ if (tlv == NULL || tlv->buf == NULL) {
+
+ if ((anode_def_flags (node) & FLAG_DEFAULT) == 0)
+ return FALSE;
+
+ /* Try to get a default */
+ opt = anode_opt_lookup (node, TYPE_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);
+ if (opt != NULL) {
+ g_return_val_if_fail (opt->value, FALSE);
+ defval = opt->value;
+ }
+
+ /* Parse out the default value */
+ *value = strtoul (defval, &end, 10);
+ g_return_val_if_fail (end && !end[0], FALSE);
+ return TRUE;
+ }
+
+ if (tlv == NULL || tlv->buf == NULL)
return FALSE;
+ /* TODO: Default integer values */
+
return anode_read_integer_as_ulong(node, tlv, value);
}
@@ -2052,7 +2232,9 @@ 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_BOOLEAN, FALSE);
+ g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+
+ /* TODO: Handle default values */
n_data = 8;
data = g_malloc0 (8);
@@ -2062,6 +2244,115 @@ egg_asn1x_set_integer_as_ulong (GNode *node, gulong value)
return TRUE;
}
+gpointer
+egg_asn1x_get_integer_as_raw (GNode *node, EggAllocator allocator, gsize *n_data)
+{
+ Atlv *tlv;
+ gpointer data;
+
+ 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);
+
+ if (!allocator)
+ allocator = g_realloc;
+
+ tlv = anode_get_tlv_data (node);
+ if (tlv == NULL || tlv->buf == NULL)
+ return NULL;
+
+ data = (allocator) (NULL, tlv->len);
+ if (data == NULL)
+ return NULL;
+
+ memcpy (data, tlv->buf + tlv->off, tlv->len);
+ *n_data = tlv->len;
+ return data;
+}
+
+gboolean
+egg_asn1x_set_integer_as_raw (GNode *node, gpointer data, gsize n_data, GDestroyNotify destroy)
+{
+ gboolean sign;
+ 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);
+
+ /* Make sure the integer is properly encoded in twos complement*/
+ p = (guchar*)data;
+ sign = !!(p[0] & 0x80);
+ if (sign) {
+ g_warning ("integer in egg_asn1x_set_integer_as_raw is not two's complement");
+ return FALSE;
+ }
+
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, destroy);
+ return TRUE;
+}
+
+gconstpointer
+egg_asn1x_get_raw_element (GNode *node, gsize *n_element)
+{
+ Atlv *tlv;
+
+ g_return_val_if_fail (node, NULL);
+ g_return_val_if_fail (n_element, 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;
+ } else {
+ *n_element = tlv->len + tlv->off;
+ return tlv->buf;
+ }
+}
+
+gboolean
+egg_asn1x_set_raw_element (GNode *node, gpointer data,
+ gsize n_data, GDestroyNotify destroy)
+{
+ Atlv tlv;
+
+ g_return_val_if_fail (node, FALSE);
+ g_return_val_if_fail (data, FALSE);
+ g_return_val_if_fail (n_data, FALSE);
+
+ anode_clear (node);
+ memset (&tlv, 0, sizeof (tlv));
+
+ /* TODO: This needs implementation */
+ if (anode_calc_explicit (node)) {
+ g_warning ("egg_asn1x_set_raw_element does not yet work with explicit tagging");
+ return FALSE;
+ }
+
+ /* Decode the beginning TLV */
+ if (!anode_decode_tlv_for_data (data, (const guchar*)data + n_data, &tlv))
+ return FALSE;
+
+ /* Decode the data into place properly */
+ if (!anode_decode_anything (node, &tlv))
+ return FALSE;
+
+ /* There was extra data */
+ if (tlv.end - tlv.buf != n_data)
+ return FALSE;
+
+ /* Should have been set above */
+ g_assert (anode_get_tlv_data (node) != NULL);
+
+ /* We set this so the data is properly destroyed */
+ anode_set_user_data (node, data, destroy);
+ return TRUE;
+}
+
gconstpointer
egg_asn1x_get_raw_value (GNode *node, gsize *n_content)
{
@@ -2071,8 +2362,8 @@ egg_asn1x_get_raw_value (GNode *node, gsize *n_content)
g_return_val_if_fail (n_content, NULL);
tlv = anode_get_tlv_data (node);
- if (tlv == NULL)
- return FALSE;
+ if (tlv == NULL || tlv->buf == NULL)
+ return NULL;
g_return_val_if_fail (!(tlv->cls & ASN1_CLASS_STRUCTURED), NULL);
*n_content = tlv->len;
@@ -2101,11 +2392,14 @@ egg_asn1x_get_string_as_raw (GNode *node, EggAllocator allocator, gsize *n_strin
g_return_val_if_fail (node, NULL);
g_return_val_if_fail (n_string, NULL);
+ if (!allocator)
+ allocator = g_realloc;
+
type = anode_def_type (node);
g_return_val_if_fail (type == TYPE_OCTET_STRING || type == TYPE_GENERALSTRING, NULL);
tlv = anode_get_tlv_data (node);
- if (tlv == NULL)
+ if (tlv == NULL || tlv->buf == NULL)
return NULL;
if (!anode_read_string (node, tlv, NULL, &length))
@@ -2179,17 +2473,160 @@ 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)
+{
+ Atlv *tlv;
+ gpointer bits;
+ guchar padded;
+
+ 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;
+
+ tlv = anode_get_tlv_data (node);
+ if (tlv == NULL || tlv->buf == 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;
+}
+
+gboolean
+egg_asn1x_set_bits_as_raw (GNode *node, guchar *bits, guint n_bits, GDestroyNotify destroy)
+{
+ gint type;
+ gsize length;
+ Abits *ab;
+
+ g_return_val_if_fail (node, FALSE);
+ g_return_val_if_fail (bits, FALSE);
+
+ type = anode_def_type (node);
+ g_return_val_if_fail (type == TYPE_BIT_STRING, FALSE);
+
+ length = (n_bits / 8);
+ if (n_bits % 8)
+ length += 1;
+
+ ab = g_slice_new0 (Abits);
+ ab->bits = bits;
+ 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
+egg_asn1x_get_bits_as_ulong (GNode *node, gulong *bits, guint *n_bits)
+{
+ Atlv *tlv;
+ guint i, length;
+ guchar empty;
+ const guchar *p;
+ gulong value;
+
+ 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);
+
+ tlv = anode_get_tlv_data (node);
+ if (tlv == NULL || tlv->buf == NULL)
+ return FALSE;
+
+ empty = *(tlv->buf + tlv->off);
+ g_return_val_if_fail (empty < 8, FALSE);
+ g_return_val_if_fail (tlv->len > 1, FALSE);
+
+ length = ((tlv->len - 1) * 8) - empty;
+ if (length > sizeof (gulong) * 8)
+ return FALSE;
+
+ value = 0;
+ p = tlv->buf + tlv->off + 1;
+
+ for (i = 0; i < tlv->len - 1; ++i)
+ value = value << 8 | p[i];
+
+ *bits = value >> empty;
+ *n_bits = length;
+ return TRUE;
+}
+
+gboolean
+egg_asn1x_set_bits_as_ulong (GNode *node, gulong bits, guint n_bits)
+{
+ guchar *data;
+ gulong value;
+ gint type;
+ gsize i, length;
+ guchar empty;
+ Abits *ab;
+
+ g_return_val_if_fail (node, FALSE);
+ g_return_val_if_fail (bits, FALSE);
+ 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);
+
+ empty = n_bits % 8;
+ if (empty > 0)
+ empty = 8 - empty;
+ length = (n_bits / 8) + (empty ? 1 : 0);
+
+ data = g_malloc0 (sizeof (gulong));
+ value = bits << empty;
+
+ for (i = 0; i < length; ++i)
+ data[(length - i) - 1] = (value >> i * 8) & 0xFF;
+
+ ab = g_slice_new0 (Abits);
+ ab->bits = data;
+ 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;
+}
+
glong
egg_asn1x_get_time_as_long (GNode *node)
{
Atlv *tlv;
glong time;
+ gint type;
g_return_val_if_fail (node, -1);
- g_return_val_if_fail (anode_def_type (node) == TYPE_TIME, -1);
+ type = anode_def_type (node);
+
+ /* Time is often represented as a choice, so work than in here */
+ if (type == TYPE_CHOICE) {
+ node = egg_asn1x_get_choice (node);
+ if (node == NULL)
+ return -1;
+ g_return_val_if_fail (anode_def_type (node) == TYPE_TIME, -1);
+ return egg_asn1x_get_time_as_long (node);
+ }
+
+ g_return_val_if_fail (type == TYPE_TIME, -1);
tlv = anode_get_tlv_data (node);
- if (tlv == NULL)
+ if (tlv == NULL || tlv->buf == NULL)
return -1;
if (!anode_read_time (node, tlv, &time))
@@ -2197,6 +2634,23 @@ egg_asn1x_get_time_as_long (GNode *node)
return time;
}
+gboolean
+egg_asn1x_get_time_as_date (GNode *node, GDate *date)
+{
+ GTimeVal tv;
+
+ g_return_val_if_fail (node, FALSE);
+ g_return_val_if_fail (date, FALSE);
+
+ tv.tv_sec = egg_asn1x_get_time_as_long (node);
+ if (tv.tv_sec < 0)
+ return FALSE;
+ tv.tv_usec = 0;
+
+ g_date_set_time_val (date, &tv);
+ return TRUE;
+}
+
gchar*
egg_asn1x_get_oid_as_string (GNode *node)
{
@@ -2207,7 +2661,7 @@ egg_asn1x_get_oid_as_string (GNode *node)
g_return_val_if_fail (anode_def_type (node) == TYPE_OBJECT_ID, NULL);
tlv = anode_get_tlv_data (node);
- if (tlv == NULL)
+ if (tlv == NULL || tlv->buf == NULL)
return NULL;
if (!anode_read_object_id (node, tlv, &oid))
@@ -2265,6 +2719,22 @@ egg_asn1x_set_oid_as_quark (GNode *node, GQuark oid)
return egg_asn1x_set_oid_as_string (node, str);
}
+GNode*
+egg_asn1x_get_choice (GNode *node)
+{
+ GNode *child;
+
+ g_return_val_if_fail (node, NULL);
+
+ /* One and only one of the children must be set */
+ for (child = node->children; child; child = child->next) {
+ if (anode_get_tlv_data (child))
+ return child;
+ }
+
+ return NULL;
+}
+
/* -----------------------------------------------------------------------------------
* VALIDATION
*/
@@ -2302,9 +2772,6 @@ anode_validate_size (GNode *node, gulong length)
if (anode_def_flags (node) & FLAG_SIZE) {
size = anode_opt_lookup (node, TYPE_SIZE, NULL);
- if (size == NULL) {
- egg_asn1x_dump (g_node_get_root (node));
- }
g_return_val_if_fail (size, FALSE);
if (!anode_parse_size (node, size->value, &value1))
g_return_val_if_reached (FALSE);
@@ -2396,7 +2863,7 @@ anode_validate_bit_string (GNode *node, Atlv *tlv)
g_assert (tlv);
/* At least two bytes in length */
- if (tlv->len < 2)
+ if (tlv->len < 1)
return anode_failure (node, "invalid length bit string");
/* First byte is the number of free bits at end */
empty = tlv->buf[tlv->off];
@@ -2404,7 +2871,7 @@ anode_validate_bit_string (GNode *node, Atlv *tlv)
return anode_failure (node, "bit string has invalid header");
/* Free bits at end must be zero */
mask = 0xFF >> (8 - empty);
- if (tlv->buf[tlv->off + tlv->len - 1] & mask)
+ if (tlv->len > 1 && tlv->buf[tlv->off + tlv->len - 1] & mask)
return anode_failure (node, "bit string has invalid trailing bits");
return TRUE;
}
@@ -2507,11 +2974,11 @@ anode_validate_sequence_or_set_of (GNode *node)
/* All the children must validate properly */
for (child = node->children; child; child = child->next) {
- if (!anode_validate_anything (child))
- return FALSE;
-
tlv = anode_get_tlv_data (child);
if (tlv) {
+ if (!anode_validate_anything (child))
+ return FALSE;
+
/* Tag must have same tag as top */
if (count == 0)
tag = anode_calc_tag (child);
@@ -2541,6 +3008,8 @@ anode_validate_anything (GNode *node)
if (!tlv) {
if (anode_def_flags (node) & FLAG_OPTION)
return TRUE;
+ if (anode_def_flags (node) & FLAG_DEFAULT)
+ return TRUE;
return anode_failure (node, "missing value");
}
@@ -2629,14 +3098,58 @@ join_each_child (GNode *child, gpointer data)
}
static const ASN1_ARRAY_TYPE*
-lookup_def (const ASN1_ARRAY_TYPE *defs, const gchar *identifier, gint type)
+adef_next_sibling (const ASN1_ARRAY_TYPE *def)
+{
+ int depth = 0;
+
+ g_assert (def);
+ g_assert (def->value || def->type || def->name);
+
+ if ((def->type & FLAG_RIGHT) == 0)
+ return NULL;
+
+ /* Skip past any children */
+ if ((def->type & FLAG_DOWN) == FLAG_DOWN) {
+ depth += 1;
+ while (depth > 0) {
+ ++def;
+ if ((def->type & FLAG_DOWN) == FLAG_DOWN)
+ depth += 1;
+ if ((def->type & FLAG_RIGHT) == 0)
+ depth -= 1;
+ }
+ }
+
+ ++def;
+ g_return_val_if_fail (def->value || def->type || def->name, NULL);
+ return def;
+}
+
+static const ASN1_ARRAY_TYPE*
+adef_first_child (const ASN1_ARRAY_TYPE *def)
{
- /* Find the one we're interested in */
- while (defs && (defs->value || defs->type || defs->name)) {
- if ((defs->type & 0xFF) == type &&
- defs->name && g_str_equal (identifier, defs->name))
- return defs;
- ++defs;
+ g_assert (def);
+ g_assert (def->value || def->type || def->name);
+
+ if ((def->type & FLAG_DOWN) == 0)
+ return NULL;
+
+ ++def;
+ g_return_val_if_fail (def->value || def->type || def->name, NULL);
+ return def;
+}
+
+static const ASN1_ARRAY_TYPE*
+lookup_def_of_type (const ASN1_ARRAY_TYPE *defs, const gchar *name, gint type)
+{
+ const ASN1_ARRAY_TYPE *def;
+
+ g_assert (defs);
+ g_assert (defs->value || defs->type || defs->name);
+
+ for (def = adef_first_child (defs); def; def = adef_next_sibling (def)) {
+ if ((def->type & 0xFF) == type && def->name && g_str_equal (name, def->name))
+ return def;
}
return NULL;
@@ -2673,7 +3186,7 @@ traverse_and_prepare (GNode *node, gpointer data)
identifier = anode_def_name (node);
if (identifier && !g_str_equal (identifier, "MAX") &&
g_ascii_isalpha (identifier[0])) {
- def = lookup_def (defs, identifier, TYPE_INTEGER);
+ def = lookup_def_of_type (defs, identifier, TYPE_INTEGER);
g_return_val_if_fail (def, TRUE);
anode_opt_add (node, def);
}
@@ -2719,26 +3232,123 @@ 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)
+{
+ const ASN1_ARRAY_TYPE *result = NULL;
+ const ASN1_ARRAY_TYPE *odef;
+ const gchar *value;
+ GString *oid = NULL;
+
+ g_assert (match);
+ g_assert (problem);
+ g_assert (names);
+
+ for (odef = adef_first_child (def); odef; odef = adef_next_sibling (odef)) {
+ if ((odef->type & 0xFF) != TYPE_CONSTANT)
+ continue;
+
+ g_return_val_if_fail (odef->value, NULL);
+ if (strspn (odef->value, "01234567890") == strlen (odef->value)) {
+ value = odef->value;
+
+ } else {
+ value = g_hash_table_lookup (names, odef->value);
+
+ /* A name resolution problem */
+ if (!value) {
+ if (oid)
+ g_string_free (oid, TRUE);
+ *problem = odef->value;
+ return NULL;
+ }
+ }
+
+ if (oid) {
+ g_string_append_c (oid, '.');
+ g_string_append (oid, value);
+ } else {
+ oid = g_string_new (value);
+ }
+ }
+
+ if (oid != NULL) {
+ if (g_str_equal (oid->str, match))
+ result = adef_next_sibling (def);
+ g_assert (def->name);
+ g_hash_table_insert (names, (gchar*)def->name, g_string_free (oid, FALSE));
+ }
+
+ return result;
+}
+
+static const ASN1_ARRAY_TYPE*
+match_oid_in_definitions (const ASN1_ARRAY_TYPE *defs, const gchar *match)
+{
+ const ASN1_ARRAY_TYPE *def;
+ const ASN1_ARRAY_TYPE *result;
+ GHashTable *names;
+ gboolean progress;
+ const gchar *problem;
+
+ names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
+
+ for (;;) {
+ progress = FALSE;
+ problem = NULL;
+
+ 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)
+ continue;
+
+ /* If we've already seen this one, skip */
+ if (g_hash_table_lookup (names, def->name))
+ continue;
+
+ progress = TRUE;
+ result = match_oid_in_definition (def, names, match, &problem);
+ if (result != NULL)
+ break;
+ }
+
+ if (!problem || result) {
+ break;
+ } else if (problem && !progress) {
+ g_warning ("couldn't find oid definition in ASN.1 for: %s", problem);
+ g_return_val_if_reached (NULL);
+ }
+ }
+
+ g_hash_table_destroy (names);
+ return result;
+}
+
GNode*
-egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *identifier)
+egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *type)
{
const ASN1_ARRAY_TYPE *def;
GNode *root, *parent, *node;
int flags;
g_return_val_if_fail (defs, NULL);
- g_return_val_if_fail (identifier, NULL);
+ g_return_val_if_fail (type, NULL);
- def = defs;
+ /* An OID */
+ if (strspn (type, "0123456789.") == strlen (type)) {
+ def = match_oid_in_definitions (defs, type);
- /* Find the one we're interested in */
- while (def && (def->value || def->type || def->name)) {
- if (def->name && g_str_equal (identifier, def->name))
- break;
- ++def;
+ /* An Identifier */
+ } else {
+ for (def = adef_first_child (defs); def; def = adef_next_sibling (def)) {
+ if (def->name && g_str_equal (type, def->name))
+ break;
+ }
}
- if (!def->name || !def->type)
+ if (def == NULL || !def->name || !def->type)
return NULL;
/* The node for this item */
@@ -2779,6 +3389,33 @@ egg_asn1x_create (const ASN1_ARRAY_TYPE *defs, const gchar *identifier)
return root;
}
+GNode*
+egg_asn1x_create_quark (const ASN1_ARRAY_TYPE *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)
+{
+ GNode *asn;
+
+ g_return_val_if_fail (defs, NULL);
+ g_return_val_if_fail (identifier, NULL);
+
+ asn = egg_asn1x_create (defs, identifier);
+ g_return_val_if_fail (asn, NULL);
+
+ if (!egg_asn1x_decode (asn, data, n_data)) {
+ egg_asn1x_destroy (asn);
+ return NULL;
+ }
+
+ return asn;
+}
+
/* -----------------------------------------------------------------------------------
* DUMPING and MESSAGES
*/
@@ -2814,6 +3451,7 @@ traverse_and_dump (GNode *node, gpointer unused)
guint i, depth;
GString *output;
gchar *string;
+ Atlv *tlv;
Anode *an;
GList *l;
@@ -2821,12 +3459,14 @@ traverse_and_dump (GNode *node, gpointer unused)
for (i = 0; i < depth - 1; ++i)
g_printerr (" ");
+ tlv = anode_get_tlv_data (node);
output = g_string_new ("");
dump_append_type (output, anode_def_type (node));
dump_append_flags (output, anode_def_flags (node));
string = g_utf8_casefold (output->str, output->len - 1);
g_string_free (output, TRUE);
- g_printerr ("+ %s: %s [%s]\n", anode_def_name (node), anode_def_value (node), string);
+ g_printerr ("+ %s: %s [%s]%s\n", anode_def_name (node), anode_def_value (node),
+ string, tlv && tlv->buf ? " *" : "");
g_free (string);
/* Print out all the options */
@@ -2915,6 +3555,127 @@ egg_asn1x_clear (GNode *asn)
void
egg_asn1x_destroy (gpointer data)
{
- if (data)
- anode_destroy (data);
+ GNode *node = data;
+
+ if (node != NULL) {
+ g_return_if_fail (G_NODE_IS_ROOT (node));
+ anode_destroy (node);
+ }
+}
+
+/* --------------------------------------------------------------------------------
+ * TIME PARSING
+ */
+
+glong
+egg_asn1x_parse_time_general (const gchar *time, gssize n_time)
+{
+ gboolean ret;
+ glong value;
+ struct tm when;
+ gint offset = 0;
+
+ g_return_val_if_fail (time, -1);
+
+ if (n_time < 0)
+ n_time = strlen (time);
+
+ ret = parse_general_time (time, n_time, &when, &offset);
+ if (!ret)
+ return -1;
+
+ /* In order to work with 32 bit time_t. */
+ if (sizeof (time_t) <= 4 && when.tm_year >= 2038) {
+ value = (time_t)2145914603; /* 2037-12-31 23:23:23 */
+
+ /* Convert to seconds since epoch */
+ } else {
+ value = timegm (&when);
+ g_return_val_if_fail (*time >= 0, FALSE);
+ value += offset;
+ }
+
+ return value;
+}
+
+glong
+egg_asn1x_parse_time_utc (const gchar *time, gssize n_time)
+{
+ gboolean ret;
+ glong value;
+ struct tm when;
+ gint offset = 0;
+
+ g_return_val_if_fail (time, -1);
+
+ if (n_time < 0)
+ n_time = strlen (time);
+
+ ret = parse_utc_time (time, n_time, &when, &offset);
+ if (!ret)
+ return -1;
+
+ /* In order to work with 32 bit time_t. */
+ if (sizeof (time_t) <= 4 && when.tm_year >= 2038) {
+ value = (time_t)2145914603; /* 2037-12-31 23:23:23 */
+
+ /* Convert to seconds since epoch */
+ } else {
+ value = timegm (&when);
+ g_return_val_if_fail (*time >= 0, FALSE);
+ value += offset;
+ }
+
+ return value;
+}
+
+/* --------------------------------------------------------------------------------
+ * BASIC RAW ELEMENT INFO
+ */
+
+gssize
+egg_asn1x_element_length (gconstpointer data, gsize n_data)
+{
+ guchar cls;
+ int counter = 0;
+ int cb, len;
+ gulong tag;
+
+ if (asn1_get_tag_der (data, n_data, &cls, &cb, &tag) == ASN1_SUCCESS) {
+ counter += cb;
+ len = asn1_get_length_der ((const guchar*)data + cb, n_data - cb, &cb);
+ counter += cb;
+ if (len >= 0) {
+ len += counter;
+ if (n_data >= len)
+ return len;
+ }
+ }
+
+ return -1;
+}
+
+gconstpointer
+egg_asn1x_element_content (gconstpointer data, gsize n_data, gsize *n_content)
+{
+ int counter = 0;
+ guchar cls;
+ gulong tag;
+ int cb, len;
+
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (n_content != NULL, NULL);
+
+ /* Now get the data out of this element */
+ if (asn1_get_tag_der (data, n_data, &cls, &cb, &tag) != ASN1_SUCCESS)
+ return NULL;
+
+ counter += cb;
+ len = asn1_get_length_der ((const guchar*)data + cb, n_data - cb, &cb);
+ if (len < 0)
+ return NULL;
+ counter += cb;
+
+ *n_content = len;
+ return (const guchar*)data + counter;
}
diff --git a/egg/egg-asn1x.h b/egg/egg-asn1x.h
index 6d69b0a..705e226 100644
--- a/egg/egg-asn1x.h
+++ b/egg/egg-asn1x.h
@@ -26,9 +26,6 @@
#include <glib.h>
-#include <libtasn1.h>
-
-
#ifndef HAVE_EGG_ALLOCATOR
typedef void* (*EggAllocator) (void* p, gsize);
#define HAVE_EGG_ALLOCATOR
@@ -36,9 +33,19 @@ typedef void* (*EggAllocator) (void* p, gsize);
typedef gboolean (*EggAsn1xEncoder) (gpointer data, guchar *buf, gsize n_buf);
-GNode* egg_asn1x_create (const ASN1_ARRAY_TYPE *defs,
+struct static_struct_asn;
+
+GNode* egg_asn1x_create (const struct static_struct_asn *defs,
const gchar *type);
+GNode* egg_asn1x_create_quark (const struct static_struct_asn *defs,
+ GQuark type);
+
+GNode* egg_asn1x_create_and_decode (const struct static_struct_asn *defs,
+ const gchar *type,
+ gconstpointer data,
+ gsize n_data);
+
void egg_asn1x_dump (GNode *asn);
void egg_asn1x_clear (GNode *asn);
@@ -58,6 +65,14 @@ const gchar* egg_asn1x_message (GNode *asn);
GNode* egg_asn1x_node (GNode *asn,
...) G_GNUC_NULL_TERMINATED;
+const gchar* egg_asn1x_name (GNode *asn);
+
+guint egg_asn1x_count (GNode *node);
+
+gboolean egg_asn1x_have (GNode *node);
+
+GNode* egg_asn1x_get_choice (GNode *node);
+
gboolean egg_asn1x_get_boolean (GNode *node,
gboolean *value);
@@ -70,6 +85,15 @@ gboolean egg_asn1x_get_integer_as_ulong (GNode *node,
gboolean egg_asn1x_set_integer_as_ulong (GNode *node,
gulong value);
+gpointer egg_asn1x_get_integer_as_raw (GNode *node,
+ EggAllocator allocator,
+ gsize *n_data);
+
+gboolean egg_asn1x_set_integer_as_raw (GNode *node,
+ gpointer data,
+ gsize n_data,
+ GDestroyNotify destroy);
+
gconstpointer egg_asn1x_get_raw_value (GNode *node,
gsize *n_content);
@@ -79,6 +103,14 @@ gboolean egg_asn1x_set_raw_value (GNode *node,
gpointer user_data,
GDestroyNotify destroy);
+gconstpointer egg_asn1x_get_raw_element (GNode *node,
+ gsize *n_data);
+
+gboolean egg_asn1x_set_raw_element (GNode *node,
+ gpointer user_data,
+ gsize n_data,
+ GDestroyNotify destroy);
+
guchar* egg_asn1x_get_string_as_raw (GNode *node,
EggAllocator allocator,
gsize *n_string);
@@ -88,6 +120,23 @@ 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,
+ guint *n_bits);
+
+gboolean egg_asn1x_set_bits_as_raw (GNode *node,
+ guchar *data,
+ guint n_bits,
+ GDestroyNotify destroy);
+
+gboolean egg_asn1x_get_bits_as_ulong (GNode *node,
+ gulong *value,
+ guint *n_bits);
+
+gboolean egg_asn1x_set_bits_as_ulong (GNode *node,
+ gulong value,
+ guint n_bits);
+
gchar* egg_asn1x_get_string_as_utf8 (GNode *node,
EggAllocator allocator);
@@ -97,7 +146,14 @@ gboolean egg_asn1x_set_string_as_utf8 (GNode *node,
glong egg_asn1x_get_time_as_long (GNode *node);
-glong egg_asn1x_set_time_as_long (GNode *node);
+gboolean egg_asn1x_set_time_as_long (GNode *node,
+ glong time);
+
+gboolean egg_asn1x_get_time_as_date (GNode *node,
+ GDate *date);
+
+gboolean egg_asn1x_set_time_as_date (GNode *node,
+ GDate *date);
GQuark egg_asn1x_get_oid_as_quark (GNode *node);
@@ -111,4 +167,17 @@ gboolean egg_asn1x_set_oid_as_string (GNode *node,
void egg_asn1x_destroy (gpointer asn);
+glong egg_asn1x_parse_time_general (const gchar *time,
+ gssize n_time);
+
+glong egg_asn1x_parse_time_utc (const gchar *time,
+ gssize n_time);
+
+gssize egg_asn1x_element_length (gconstpointer data,
+ gsize n_data);
+
+gconstpointer egg_asn1x_element_content (gconstpointer data,
+ gsize n_data,
+ gsize *n_content);
+
#endif /*EGG_ASN1X_H_*/
diff --git a/egg/egg-dn.c b/egg/egg-dn.c
index 199cb6a..b41844e 100644
--- a/egg/egg-dn.c
+++ b/egg/egg-dn.c
@@ -23,27 +23,15 @@
#include "config.h"
-#include "egg-asn1.h"
+#include "egg-asn1-defs.h"
+#include "egg-asn1x.h"
#include "egg-dn.h"
#include "egg-oid.h"
-#include <libtasn1.h>
-
#include <string.h>
static const char HEXC[] = "0123456789ABCDEF";
-static gboolean
-ascii_length_equals (const gchar *str, gconstpointer data, gsize n_data)
-{
- g_assert (str);
- if (!data)
- return FALSE;
- if (strlen (str) != n_data)
- return FALSE;
- return strncmp (str, data, n_data) == 0;
-}
-
static gchar*
dn_print_hex_value (const guchar *data, gsize len)
{
@@ -62,63 +50,53 @@ 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)
{
- const gchar *asn_name;
- ASN1_TYPE asn1;
- gchar *part;
- gchar *value;
+ GNode *asn1, *node;
+ gconstpointer value;
gsize n_value;
+ gchar *result;
g_assert (data);
g_assert (len);
- asn_name = asn1_find_structure_from_oid (egg_asn1_get_pkix_asn1type (),
- g_quark_to_string (oid));
- g_return_val_if_fail (asn_name, NULL);
-
- part = g_strdup_printf ("PKIX1.%s", asn_name);
- asn1 = egg_asn1_decode (part, data, len);
- g_free (part);
+ asn1 = egg_asn1x_create_quark (pkix_asn1_tab, oid);
+ g_return_val_if_fail (asn1, NULL);
- if (!asn1) {
- g_message ("couldn't decode value for OID: %s", g_quark_to_string (oid));
+ if (!egg_asn1x_decode (asn1, data, len)) {
+ g_message ("couldn't decode value for OID: %s: %s",
+ g_quark_to_string (oid), egg_asn1x_message (asn1));
+ egg_asn1x_destroy (asn1);
return NULL;
}
- value = (gchar*)egg_asn1_read_value (asn1, "", &n_value, NULL);
-
/*
* If it's a choice element, then we have to read depending
* on what's there.
*/
- if (value && (flags & EGG_OID_IS_CHOICE)) {
- if (ascii_length_equals ("printableString", value, n_value - 1) ||
- ascii_length_equals ("ia5String", value, n_value - 1 ) ||
- ascii_length_equals ("utf8String", value, n_value - 1) ||
- ascii_length_equals ("teletexString", value, n_value - 1)) {
- part = value;
- value = (gchar*)egg_asn1_read_value (asn1, part, &n_value, NULL);
- g_free (part);
- } else {
- g_free (value);
- return NULL;
- }
- }
+ if (flags & EGG_OID_IS_CHOICE)
+ node = egg_asn1x_get_choice (asn1);
+ else
+ node = asn1;
- if (!value) {
- g_message ("couldn't read value for OID: %s", g_quark_to_string (oid));
- return NULL;
- }
+ value = egg_asn1x_get_raw_value (node, &n_value);
/*
* Now we make sure it's UTF-8.
*/
- if (!g_utf8_validate (value, n_value, NULL)) {
- gchar *hex = dn_print_hex_value ((guchar*)value, n_value);
- g_free (value);
- value = hex;
+
+ if (!value) {
+ 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 {
+ result = g_strndup (value, n_value);
}
- return value;
+ egg_asn1x_destroy (asn1);
+
+ return result;
}
static gchar*
@@ -139,55 +117,45 @@ dn_print_oid_value (GQuark oid, guint flags, const guchar *data, gsize len)
}
static gchar*
-dn_parse_rdn (ASN1_TYPE asn, const gchar *part)
+dn_parse_rdn (GNode *asn)
{
const gchar *name;
guint flags;
GQuark oid;
- gchar *path;
- guchar *value;
+ gconstpointer value;
gsize n_value;
gchar *display;
gchar *result;
g_assert (asn);
- g_assert (part);
- path = g_strdup_printf ("%s.type", part);
- oid = egg_asn1_read_oid (asn, path);
- g_free (path);
-
- if (!oid)
- return NULL;
-
- path = g_strdup_printf ("%s.value", part);
- value = egg_asn1_read_value (asn, path, &n_value, NULL);
- g_free (path);
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "type", NULL));
+ g_return_val_if_fail (oid, NULL);
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);
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, n_value);
result = g_strconcat ((flags & EGG_OID_PRINTABLE) ? name : g_quark_to_string (oid),
- "=", display, NULL);
+ "=", display, NULL);
g_free (display);
return result;
}
gchar*
-egg_dn_read (ASN1_TYPE asn, const gchar *part)
+egg_dn_read (GNode* asn)
{
gboolean done = FALSE;
GString *result;
- gchar *path;
+ GNode *node;
gchar *rdn;
gint i, j;
g_return_val_if_fail (asn, NULL);
- g_return_val_if_fail (part, NULL);
result = g_string_sized_new (64);
@@ -196,16 +164,15 @@ egg_dn_read (ASN1_TYPE asn, const gchar *part)
/* Each type=value pair of an RDN */
for (j = 1; TRUE; ++j) {
- path = g_strdup_printf ("%s%s?%u.?%u", part ? part : "",
- part ? "." : "", i, j);
- rdn = dn_parse_rdn (asn, path);
- g_free (path);
-
- if (!rdn) {
+ node = egg_asn1x_node (asn, i, j, NULL);
+ if (!node) {
done = j == 1;
break;
}
+ rdn = dn_parse_rdn (node);
+ g_return_val_if_fail (rdn, NULL);
+
/* Account for multi valued RDNs */
if (j > 1)
g_string_append (result, "+");
@@ -222,18 +189,17 @@ egg_dn_read (ASN1_TYPE asn, const gchar *part)
}
gchar*
-egg_dn_read_part (ASN1_TYPE asn, const gchar *part, const gchar *match)
+egg_dn_read_part (GNode *asn, const gchar *match)
{
gboolean done = FALSE;
const gchar *name;
- guchar *value;
+ gconstpointer value;
gsize n_value;
- gchar *path;
+ GNode *node;
GQuark oid;
gint i, j;
g_return_val_if_fail (asn, NULL);
- g_return_val_if_fail (part, NULL);
g_return_val_if_fail (match, NULL);
/* Each (possibly multi valued) RDN */
@@ -241,17 +207,15 @@ egg_dn_read_part (ASN1_TYPE asn, const gchar *part, const gchar *match)
/* Each type=value pair of an RDN */
for (j = 1; TRUE; ++j) {
- path = g_strdup_printf ("%s%s?%u.?%u.type",
- part ? part : "",
- part ? "." : "", i, j);
- oid = egg_asn1_read_oid (asn, path);
- g_free (path);
-
- if (!oid) {
+ node = egg_asn1x_node (asn, i, j, "type", NULL);
+ if (!node) {
done = j == 1;
break;
}
+ oid = egg_asn1x_get_oid_as_quark (node);
+ g_return_val_if_fail (oid, NULL);
+
/* Does it match either the OID or the displayable? */
if (g_ascii_strcasecmp (g_quark_to_string (oid), match) != 0) {
name = egg_oid_get_name (oid);
@@ -259,13 +223,12 @@ egg_dn_read_part (ASN1_TYPE asn, const gchar *part, const gchar *match)
continue;
}
- path = g_strdup_printf ("%s%s?%u.?%u.value",
- part ? part : "",
- part ? "." : "", i, j);
- value = egg_asn1_read_value (asn, path, &n_value, NULL);
- g_free (path);
+ 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);
g_return_val_if_fail (value, NULL);
+
return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
}
}
@@ -274,12 +237,11 @@ egg_dn_read_part (ASN1_TYPE asn, const gchar *part, const gchar *match)
}
gboolean
-egg_dn_parse (ASN1_TYPE asn, const gchar *part,
- EggDnCallback callback, gpointer user_data)
+egg_dn_parse (GNode *asn, EggDnCallback callback, gpointer user_data)
{
gboolean done = FALSE;
- gchar *path;
- guchar *value;
+ GNode *node;
+ gconstpointer value;
gsize n_value;
GQuark oid;
guint i, j;
@@ -293,33 +255,26 @@ egg_dn_parse (ASN1_TYPE asn, const gchar *part,
for (j = 1; TRUE; ++j) {
/* Dig out the type */
- path = g_strdup_printf ("%s%s?%u.?%u.type",
- part ? part : "",
- part ? "." : "", i, j);
- oid = egg_asn1_read_oid (asn, path);
- g_free (path);
-
- if (!oid) {
+ node = egg_asn1x_node (asn, i, j, "type", NULL);
+ if (!node) {
done = j == 1;
break;
}
- /* Print the value as nicely as we can */
- path = g_strdup_printf ("%s%s?%u.?%u.value",
- part ? part : "",
- part ? "." : "", i, j);
- value = egg_asn1_read_value (asn, path, &n_value, NULL);
- g_free (path);
+ oid = egg_asn1x_get_oid_as_quark (node);
+ g_return_val_if_fail (oid, FALSE);
- if (!value) {
+ /* Dig out the value */
+ node = egg_asn1x_node (asn, i, j, "value", NULL);
+ if (!node) {
done = j == 1;
break;
}
+ value = egg_asn1x_get_raw_element (node, &n_value);
+
if (callback)
(callback) (i, oid, value, n_value, user_data);
-
- g_free (value);
}
}
diff --git a/egg/egg-dn.h b/egg/egg-dn.h
index c205ba7..96fe5ff 100644
--- a/egg/egg-dn.h
+++ b/egg/egg-dn.h
@@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* egg-asn1.h - ASN.1 helper routines
+/* egg-dn.h - ASN.1 helper routines
- Copyright (C) 2007 Stefan Walter
+ 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
@@ -26,18 +26,23 @@
#include <glib.h>
-#include <libtasn1.h>
+gchar* egg_dn_read (GNode *node);
-gchar* egg_dn_read (ASN1_TYPE asn, const gchar *part);
+gchar* egg_dn_read_part (GNode *node,
+ const gchar *match);
-gchar* egg_dn_read_part (ASN1_TYPE asn, const gchar *part, const gchar *match);
+typedef void (*EggDnCallback) (guint index,
+ GQuark oid,
+ const guchar *value,
+ gsize n_value,
+ gpointer user_data);
-typedef void (*EggDnCallback) (guint index, GQuark oid, const guchar *value,
- gsize n_value, gpointer user_data);
+gboolean egg_dn_parse (GNode *node,
+ EggDnCallback callback,
+ gpointer user_data);
-gboolean egg_dn_parse (ASN1_TYPE asn, const gchar *part,
- EggDnCallback callback, gpointer user_data);
+gchar* egg_dn_print_value (GQuark oid,
+ const guchar *value,
+ gsize n_value);
-gchar* egg_dn_print_value (GQuark oid, const guchar *value, gsize n_value);
-
-#endif /*EGG_DN_H_*/
+#endif /* EGG_DN_H_ */
diff --git a/egg/egg-symkey.c b/egg/egg-symkey.c
index 426c763..a69100f 100644
--- a/egg/egg-symkey.c
+++ b/egg/egg-symkey.c
@@ -21,7 +21,8 @@
#include "config.h"
-#include "egg-asn1.h"
+#include "egg-asn1-defs.h"
+#include "egg-asn1x.h"
#include "egg-secure-memory.h"
#include "egg-symkey.h"
@@ -613,12 +614,12 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
const gchar *password, gsize n_password, const guchar *data,
gsize n_data, gcry_cipher_hd_t *cih)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_error_t gcry;
- const guchar *salt;
+ gconstpointer salt;
gsize n_salt;
gsize n_block, n_key;
- guint iterations;
+ gulong iterations;
guchar *key = NULL;
guchar *iv = NULL;
gboolean ret;
@@ -634,17 +635,19 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
gcry_md_test_algo (hash_algo) != 0)
goto done;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-PBE-params", data, n_data);
- if (!asn)
+
+ 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))
goto done;
-
- salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
+
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL), &n_salt);
if (!salt)
goto done;
- if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
iterations = 1;
-
+
n_key = gcry_cipher_get_algo_keylen (cipher_algo);
g_return_val_if_fail (n_key > 0, FALSE);
n_block = gcry_cipher_get_algo_blklen (cipher_algo);
@@ -668,65 +671,67 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
done:
g_free (iv);
egg_secure_free (key);
-
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
+
return ret;
}
static gboolean
setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_error_t gcry;
const guchar *iv;
gsize n_iv;
- guint version;
-
+ gulong version;
+ gboolean ret = FALSE;
+
g_assert (data);
- asn = egg_asn1_decode ("PKIX1.pkcs-5-rc2-CBC-params", data, n_data);
- if (!asn)
- return FALSE;
-
- if (!egg_asn1_read_uint (asn, "rc2ParameterVersion", &version))
- return FALSE;
-
- iv = egg_asn1_read_content (asn, data, n_data, "iv", &n_iv);
- asn1_delete_structure (&asn);
+ 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))
+ 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);
if (!iv)
- return FALSE;
-
+ goto done;
+
gcry = gcry_cipher_setiv (cih, iv, n_iv);
-
if (gcry != 0) {
g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
- return FALSE;
+ goto done;
}
-
- return TRUE;
+
+ ret = TRUE;
+
+done:
+ egg_asn1x_destroy (asn);
+ return ret;
}
static gboolean
setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_error_t gcry;
- const guchar *iv;
+ gconstpointer iv;
gsize n_iv;
-
+
g_assert (data);
- asn = egg_asn1_decode ("PKIX1.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, n_data);
if (!asn)
- asn = egg_asn1_decode ("PKIX1.pkcs-5-des-CBC-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-CBC-params", data, n_data);
if (!asn)
return FALSE;
-
- iv = egg_asn1_read_content (asn, data, n_data, "", &n_iv);
- asn1_delete_structure (&asn);
+
+ iv = egg_asn1x_get_raw_value (asn, &n_iv);
+ egg_asn1x_destroy (asn);
if (!iv)
return FALSE;
@@ -745,29 +750,29 @@ 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)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gboolean ret;
gcry_error_t gcry;
guchar *key = NULL;
const guchar *salt;
gsize n_salt, n_key;
- guint iterations;
-
+ gulong iterations;
+
g_assert (cipher_algo);
g_assert (data);
ret = FALSE;
- asn = egg_asn1_decode ("PKIX1.pkcs-5-PBKDF2-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBKDF2-params", data, n_data);
if (!asn)
goto done;
-
- if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
+
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
iterations = 1;
- salt = egg_asn1_read_content (asn, data, n_data, "salt.specified", &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", "specified", NULL), &n_salt);
if (!salt)
goto done;
-
+
if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
salt, n_salt, iterations, &key, NULL))
goto done;
@@ -785,8 +790,7 @@ setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar
done:
egg_secure_free (key);
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -794,12 +798,13 @@ static gboolean
read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data,
gsize n_data, gcry_cipher_hd_t *cih)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gboolean r, ret;
GQuark key_deriv_algo, enc_oid;
gcry_error_t gcry;
int algo, mode;
- int beg, end;
+ gconstpointer params;
+ gsize n_params;
g_return_val_if_fail (cih != NULL, FALSE);
g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
@@ -808,17 +813,17 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
*cih = NULL;
ret = FALSE;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-5-PBES2-params", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBES2-params", data, n_data);
if (!asn)
goto done;
-
+
algo = mode = 0;
/* Read in all the encryption type */
- enc_oid = egg_asn1_read_oid (asn, "encryptionScheme.algorithm");
+ enc_oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionScheme", "algorithm", NULL));
if (!enc_oid)
- goto done;
+ goto done;
if (enc_oid == OID_DES_EDE3_CBC)
algo = GCRY_CIPHER_3DES;
else if (enc_oid == OID_DES_CBC)
@@ -840,17 +845,17 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
}
/* Read out the parameters */
- if (asn1_der_decoding_startEnd (asn, data, n_data, "encryptionScheme.parameters",
- &beg, &end) != ASN1_SUCCESS)
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL), &n_params);
+ if (!params)
goto done;
-
+
switch (algo) {
case GCRY_CIPHER_3DES:
case GCRY_CIPHER_DES:
- r = setup_pkcs5_des_params (data + beg, end - beg + 1, *cih);
+ r = setup_pkcs5_des_params (params, n_params, *cih);
break;
case GCRY_CIPHER_RFC2268_128:
- r = setup_pkcs5_rc2_params (data + beg, end - beg + 1, *cih);
+ r = setup_pkcs5_rc2_params (params, n_params, *cih);
break;
default:
/* Should have been caught on the oid check above */
@@ -863,7 +868,7 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
goto done;
/* Read out the key creation paramaters */
- key_deriv_algo = egg_asn1_read_oid (asn, "keyDerivationFunc.algorithm");
+ key_deriv_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "keyDerivationFunc", "algorithm", NULL));
if (!key_deriv_algo)
goto done;
if (key_deriv_algo != OID_PBKDF2) {
@@ -871,21 +876,19 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
goto done;
}
- if (asn1_der_decoding_startEnd (asn, data, n_data, "keyDerivationFunc.parameters",
- &beg, &end) != ASN1_SUCCESS)
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL), &n_params);
+ if (!params)
goto done;
-
- ret = setup_pkcs5_pbkdf2_params (password, n_password, data + beg, end - beg + 1, algo, *cih);
+
+ ret = setup_pkcs5_pbkdf2_params (password, n_password, params, n_params, algo, *cih);
done:
if (ret != TRUE && *cih) {
gcry_cipher_close (*cih);
*cih = NULL;
}
-
- if (asn)
- asn1_delete_structure (&asn);
-
+
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -894,16 +897,16 @@ read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
gsize n_password, const guchar *data, gsize n_data,
gcry_cipher_hd_t *cih)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_error_t gcry;
gboolean ret;
const guchar *salt;
gsize n_salt;
gsize n_block, n_key;
- guint iterations;
+ gulong iterations;
guchar *key = NULL;
guchar *iv = NULL;
-
+
g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
g_return_val_if_fail (cih != NULL, FALSE);
g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
@@ -914,15 +917,15 @@ read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
/* Check if we can use this algorithm */
if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
goto done;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-12-PbeParams", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-PbeParams", data, n_data);
if (!asn)
goto done;
- salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL), &n_salt);
if (!salt)
goto done;
- if (!egg_asn1_read_uint (asn, "iterations", &iterations))
+ 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);
@@ -954,10 +957,7 @@ done:
g_free (iv);
egg_secure_free (key);
-
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
return ret;
}
diff --git a/egg/tests/Makefile.am b/egg/tests/Makefile.am
index eddb066..2e7e692 100644
--- a/egg/tests/Makefile.am
+++ b/egg/tests/Makefile.am
@@ -1,8 +1,5 @@
-asn1-def-test.h: test.asn
- $(ASN1PARSER) -o asn1-def-test.h $(srcdir)/test.asn
-
-asn1-def-tests.h: tests.asn
- $(ASN1PARSER) -o asn1-def-tests.h $(srcdir)/tests.asn
+asn1-def-test.c: test.asn
+ $(ASN1PARSER) -o asn1-def-test.c $(srcdir)/test.asn
# Test files should be listed in order they need to run
TESTING_FILES = \
@@ -18,8 +15,7 @@ TESTING_FILES = \
unit-test-openssl.c \
unit-test-dh.c \
unit-test-spawn.c \
- asn1-def-test.h \
- asn1-def-tests.h
+ asn1-def-test.c
UNIT_PROMPT =
@@ -28,13 +24,12 @@ TESTING_LIBS = \
EXTRA_DIST = \
test.asn \
- tests.asn \
test-data
include $(top_srcdir)/testing/testing.make
BUILT_SOURCES += \
- asn1-def-test.h
+ asn1-def-test.c
# ------------------------------------------------------------------------------
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index d550984..57d4aac 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -28,12 +28,13 @@
#include "egg/egg-asn1x.h"
#include <glib.h>
+#include <libtasn1.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "asn1-def-tests.h"
+extern const ASN1_ARRAY_TYPE test_asn1_tab[];
const gchar I33[] = "\x02\x01\x2A";
const gchar BFALSE[] = "\x01\x01\x00";
@@ -42,6 +43,9 @@ const gchar SFARNSWORTH[] = "\x04\x0A""farnsworth";
const gchar SIMPLICIT[] = "\x85\x08""implicit";
const gchar SEXPLICIT[] = "\xE5\x0A\x04\x08""explicit";
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";
+const gchar BITS_ZERO[] = "\x03\x01\x00";
#define XL(x) G_N_ELEMENTS (x) - 1
@@ -50,7 +54,7 @@ DEFINE_TEST(asn1_boolean)
GNode *asn;
gboolean value;
- asn = egg_asn1x_create (tests_asn1_tab, "TestBoolean");
+ asn = egg_asn1x_create (test_asn1_tab, "TestBoolean");
g_assert (asn);
/* Shouldn't succeed */
@@ -87,7 +91,7 @@ DEFINE_TEST(asn1_integer)
GNode *asn;
gulong value;
- asn = egg_asn1x_create (tests_asn1_tab, "TestInteger");
+ asn = egg_asn1x_create (test_asn1_tab, "TestInteger");
g_assert (asn);
/* Shouldn't succeed */
@@ -115,7 +119,7 @@ DEFINE_TEST(asn1_octet_string)
GNode *asn;
gchar *value;
- asn = egg_asn1x_create (tests_asn1_tab, "TestOctetString");
+ asn = egg_asn1x_create (test_asn1_tab, "TestOctetString");
g_assert (asn);
/* Shouldn't succeed */
@@ -143,7 +147,7 @@ DEFINE_TEST(asn1_generalized_time)
GNode *asn;
glong value;
- asn = egg_asn1x_create (tests_asn1_tab, "TestGeneralized");
+ asn = egg_asn1x_create (test_asn1_tab, "TestGeneralized");
g_assert (asn);
/* Shouldn't succeed */
@@ -170,7 +174,7 @@ DEFINE_TEST(asn1_implicit)
GNode *asn;
gchar *value;
- asn = egg_asn1x_create (tests_asn1_tab, "TestImplicit");
+ asn = egg_asn1x_create (test_asn1_tab, "TestImplicit");
g_assert (asn);
/* Should work */
@@ -188,7 +192,7 @@ DEFINE_TEST(asn1_explicit)
GNode *asn;
gchar *value;
- asn = egg_asn1x_create (tests_asn1_tab, "TestExplicit");
+ asn = egg_asn1x_create (test_asn1_tab, "TestExplicit");
g_assert (asn);
/* Should work */
@@ -200,3 +204,214 @@ DEFINE_TEST(asn1_explicit)
egg_asn1x_destroy (asn);
}
+
+DEFINE_TEST(asn1_bit_string_decode)
+{
+ GNode *asn;
+ guchar *bits;
+ guint n_bits;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
+ g_assert (asn);
+
+ /* Should work */
+ if (!egg_asn1x_decode (asn, BITS_TEST, XL (BITS_TEST)))
+ g_assert_not_reached ();
+
+ bits = egg_asn1x_get_bits_as_raw (asn, NULL, &n_bits);
+ g_assert (bits);
+ g_assert_cmpuint (n_bits, ==, 18);
+ g_assert_cmpint (bits[0], ==, 0x6e);
+ g_assert_cmpint (bits[1], ==, 0x5d);
+ g_assert_cmpint (bits[2], ==, 0xc0);
+
+ g_free (bits);
+ egg_asn1x_destroy (asn);
+}
+
+DEFINE_TEST(asn1_bit_string_decode_bad)
+{
+ 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)))
+ g_assert_not_reached ();
+
+ egg_asn1x_destroy (asn);
+}
+
+DEFINE_TEST(asn1_bit_string_decode_ulong)
+{
+ GNode *asn;
+ gulong bits;
+ guint n_bits;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
+ g_assert (asn);
+
+ /* Should work */
+ if (!egg_asn1x_decode (asn, BITS_TEST, XL (BITS_TEST)))
+ g_assert_not_reached ();
+
+ if (!egg_asn1x_get_bits_as_ulong (asn, &bits, &n_bits))
+ g_assert_not_reached ();
+
+ g_assert_cmpuint (n_bits, ==, 18);
+ g_assert_cmphex (bits, ==, 0x1b977);
+
+ egg_asn1x_destroy (asn);
+}
+
+DEFINE_TEST(asn1_bit_string_encode_decode)
+{
+ GNode *asn;
+ guchar bits[] = { 0x5d, 0x6e, 0x83 };
+ guchar *check;
+ guint n_check, n_bits = 17;
+ gpointer data;
+ gsize n_data;
+
+ 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 ();
+
+ data = egg_asn1x_encode (asn, NULL, &n_data);
+ g_assert (data);
+
+ if (!egg_asn1x_decode (asn, data, n_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);
+
+ g_free (check);
+
+ g_free (data);
+ egg_asn1x_destroy (asn);
+}
+
+DEFINE_TEST(asn1_bit_string_encode_decode_ulong)
+{
+ 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);
+
+ if (!egg_asn1x_set_bits_as_ulong (asn, bits, n_bits))
+ g_assert_not_reached ();
+
+ data = egg_asn1x_encode (asn, NULL, &n_data);
+ g_assert (data);
+
+ if (!egg_asn1x_decode (asn, data, n_data))
+ g_assert_not_reached ();
+
+ 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);
+}
+
+DEFINE_TEST(asn1_bit_string_encode_decode_zero)
+{
+ 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 ();
+
+ data = egg_asn1x_encode (asn, NULL, &n_data);
+ g_assert (data);
+
+ g_assert_cmpsize (n_data, ==, XL (BITS_ZERO));
+ g_assert (memcmp (data, BITS_ZERO, n_data) == 0);
+
+ g_free (data);
+ egg_asn1x_destroy (asn);
+}
+
+DEFINE_TEST(asn1_have)
+{
+ GNode *asn;
+ guchar *data;
+ gsize n_data;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestBoolean");
+ g_assert (asn);
+
+ g_assert (!egg_asn1x_have (asn));
+
+ if (!egg_asn1x_set_boolean (asn, TRUE))
+ g_assert_not_reached ();
+
+ g_assert (!egg_asn1x_have (asn));
+
+ data = egg_asn1x_encode (asn, NULL, &n_data);
+ g_assert (data);
+
+ g_assert (egg_asn1x_have (asn));
+
+ g_free (data);
+ egg_asn1x_destroy (asn);
+}
+
+static gboolean is_freed = FALSE;
+
+static void
+test_is_freed (gpointer unused)
+{
+ g_assert (!is_freed);
+ is_freed = TRUE;
+}
+
+DEFINE_TEST(asn1_any_set_raw)
+{
+ GNode *asn, *node;
+ guchar *data;
+ const guchar *check;
+ gsize n_data, n_check;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestAnySeq");
+ g_assert (asn);
+
+ is_freed = FALSE;
+ node = egg_asn1x_node (asn, "contents", NULL);
+ g_assert (node);
+
+ if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ g_assert_not_reached ();
+
+ data = egg_asn1x_encode (asn, NULL, &n_data);
+ g_assert (data);
+
+ check = egg_asn1x_get_raw_element (node, &n_check);
+ g_assert (check);
+
+ g_assert (n_check == XL (SFARNSWORTH));
+ g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+
+ g_free (data);
+ egg_asn1x_destroy (asn);
+ g_assert (is_freed);
+}
diff --git a/egg/tests/test-asn1x.c b/egg/tests/test-asn1x.c
index c71a29f..b397754 100644
--- a/egg/tests/test-asn1x.c
+++ b/egg/tests/test-asn1x.c
@@ -6,10 +6,7 @@
#include <stdlib.h>
#include <unistd.h>
-#define extern
-#include "egg/asn1-def-pkix.h"
-#include "egg/asn1-def-pk.h"
-#undef extern
+#include "egg/egg-asn1-defs.h"
#if 0
static void
@@ -86,6 +83,7 @@ run (void)
test_some_asn1_stuff (pk_asn1_tab, "test-rsakey-1.der", "RSAPrivateKey");
test_some_asn1_stuff (pkix_asn1_tab, "test-personalname-1.der", "PersonalName");
test_some_asn1_stuff (pkix_asn1_tab, "test-pkcs7-1.der", "pkcs-7-ContentInfo");
+ test_some_asn1_stuff (pkix_asn1_tab, "test-pkcs7-2.der", "pkcs-7-ContentInfo");
test_some_asn1_stuff (pkix_asn1_tab, "test-pkcs12-1.der", "pkcs-12-PFX");
return 0;
diff --git a/egg/tests/test-data/test-pkcs7-2.der b/egg/tests/test-data/test-pkcs7-2.der
new file mode 100755
index 0000000..d45b9e0
Binary files /dev/null and b/egg/tests/test-data/test-pkcs7-2.der differ
diff --git a/egg/tests/test-dn.c b/egg/tests/test-dn.c
index 6ad3811..aa0a61c 100644
--- a/egg/tests/test-dn.c
+++ b/egg/tests/test-dn.c
@@ -25,7 +25,8 @@
#include "test-suite.h"
-#include "egg/egg-asn1.h"
+#include "egg/egg-asn1-defs.h"
+#include "egg/egg-asn1x.h"
#include "egg/egg-dn.h"
#include "egg/egg-oid.h"
@@ -37,31 +38,24 @@
#include <stdio.h>
#include <string.h>
-static ASN1_TYPE asn1_cert = NULL;
+static GNode* asn1_cert = NULL;
static guchar *data_cert = NULL;
static gsize n_data_cert = 0;
DEFINE_SETUP(dn_cert)
{
- ASN1_TYPE pkix;
- int res;
-
data_cert = testing_data_read ("test-certificate-1.der", &n_data_cert);
- /* We'll be catching this error later */
- pkix = egg_asn1_get_pkix_asn1type ();
- if (!pkix) return;
-
- res = asn1_create_element (pkix, "PKIX1.Certificate", &asn1_cert);
- g_assert (res == ASN1_SUCCESS);
+ asn1_cert = egg_asn1x_create (pkix_asn1_tab, "Certificate");
+ g_assert (asn1_cert != NULL);
- res = asn1_der_decoding (&asn1_cert, data_cert, n_data_cert, NULL);
- g_assert (res == ASN1_SUCCESS);
+ if (!egg_asn1x_decode (asn1_cert, data_cert, n_data_cert))
+ g_assert_not_reached ();
}
DEFINE_TEARDOWN(dn_cert)
{
- asn1_delete_structure (&asn1_cert);
+ egg_asn1x_destroy (asn1_cert);
g_free (data_cert);
data_cert = NULL;
}
@@ -70,14 +64,11 @@ DEFINE_TEST(read_dn)
{
gchar *dn;
- dn = egg_dn_read (asn1_cert, "tbsCertificate.issuer.rdnSequence");
+ dn = egg_dn_read (egg_asn1x_node (asn1_cert, "tbsCertificate", "issuer", "rdnSequence", NULL));
g_assert (dn != NULL);
g_assert_cmpstr (dn, ==, "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA, EMAIL=personal-premium thawte com");
g_free (dn);
-
- dn = egg_dn_read (asn1_cert, "tbsCertificate.nonExistant");
- g_assert (dn == NULL);
}
DEFINE_TEST(dn_value)
@@ -132,7 +123,7 @@ DEFINE_TEST(parse_dn)
GString *dn = g_string_new ("");
last_index = 1;
- if (!egg_dn_parse (asn1_cert, "tbsCertificate.issuer.rdnSequence", concatenate_dn, dn))
+ if (!egg_dn_parse (egg_asn1x_node (asn1_cert, "tbsCertificate", "issuer", "rdnSequence", NULL), concatenate_dn, dn))
g_assert_not_reached ();
g_assert_cmpstr (dn->str, ==, "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting, OU=Certification Services Division, CN=Thawte Personal Premium CA, EMAIL=personal-premium thawte com");
@@ -141,27 +132,27 @@ DEFINE_TEST(parse_dn)
DEFINE_TEST(read_dn_part)
{
+ GNode *node;
gchar *value;
- value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "CN");
+ node = egg_asn1x_node (asn1_cert, "tbsCertificate", "issuer", "rdnSequence", NULL);
+
+ value = egg_dn_read_part (node, "CN");
g_assert (value != NULL);
g_assert_cmpstr (value, ==, "Thawte Personal Premium CA");
g_free (value);
- value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "2.5.4.8");
+ value = egg_dn_read_part (node, "2.5.4.8");
g_assert (value != NULL);
g_assert_cmpstr (value, ==, "Western Cape");
g_free (value);
- value = egg_dn_read_part (asn1_cert, "tbsCertificate.nonExistant", "CN");
- g_assert (value == NULL);
-
- value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "DC");
+ value = egg_dn_read_part (node, "DC");
g_assert (value == NULL);
- value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "0.0.0.0");
+ value = egg_dn_read_part (node, "0.0.0.0");
g_assert (value == NULL);
- value = egg_dn_read_part (asn1_cert, "tbsCertificate.issuer.rdnSequence", "2.5.4.9");
+ value = egg_dn_read_part (node, "2.5.4.9");
g_assert (value == NULL);
}
diff --git a/egg/tests/test.asn b/egg/tests/test.asn
index 0a9c7d1..f5f3053 100644
--- a/egg/tests/test.asn
+++ b/egg/tests/test.asn
@@ -1,9 +1,23 @@
-TEST { }
+TESTS { }
DEFINITIONS EXPLICIT TAGS ::=
BEGIN
+TestInteger ::= INTEGER
+
+TestBoolean ::= BOOLEAN
+
+TestOctetString ::= OCTET STRING
+
+TestGeneralized ::= GeneralizedTime
+
+TestImplicit ::= [5] IMPLICIT OCTET STRING
+
+TestExplicit ::= [5] EXPLICIT OCTET STRING
+
+TestBitString ::= BIT STRING
+
TestIntegers ::= SEQUENCE {
uint1 INTEGER,
uint2 INTEGER,
@@ -11,8 +25,19 @@ TestIntegers ::= SEQUENCE {
}
TestData ::= SEQUENCE {
- data OCTET STRING,
+ data OCTET STRING
+}
+
+TestBooleanSeq ::= SEQUENCE {
boolean BOOLEAN DEFAULT FALSE
}
+TestOid ::= SEQUENCE {
+ oid OBJECT IDENTIFIER
+}
+
+TestAnySeq ::= SEQUENCE {
+ contents ANY
+}
+
END
diff --git a/egg/tests/unit-test-asn1.c b/egg/tests/unit-test-asn1.c
index 61fd605..63c835d 100644
--- a/egg/tests/unit-test-asn1.c
+++ b/egg/tests/unit-test-asn1.c
@@ -25,7 +25,8 @@
#include "test-suite.h"
-#include "egg/egg-asn1.h"
+#include "egg/egg-asn1-defs.h"
+#include "egg/egg-asn1x.h"
#include "egg/egg-oid.h"
#include <glib.h>
@@ -36,260 +37,249 @@
#include <stdio.h>
#include <string.h>
-#define extern
-#include "asn1-def-test.h"
-#undef extern
+extern const ASN1_ARRAY_TYPE test_asn1_tab[];
-static ASN1_TYPE asn1_test = NULL;
-
-static ASN1_TYPE asn1_cert = NULL;
+static GNode *asn1_cert = NULL;
static guchar *data_cert = NULL;
static gsize n_data_cert = 0;
DEFINE_SETUP(asn1_tree)
{
- ASN1_TYPE pkix;
-
- int res = asn1_array2tree (test_asn1_tab, &asn1_test, NULL);
- g_assert (res == ASN1_SUCCESS);
-
- /* -------- */
-
data_cert = testing_data_read ("test-certificate-1.der", &n_data_cert);
- /* We'll be catching this error later */
- pkix = egg_asn1_get_pkix_asn1type ();
- if (!pkix) return;
-
- res = asn1_create_element (pkix, "PKIX1.Certificate", &asn1_cert);
- g_assert (res == ASN1_SUCCESS);
-
- res = asn1_der_decoding (&asn1_cert, data_cert, n_data_cert, NULL);
- g_assert (res == ASN1_SUCCESS);
+ asn1_cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data_cert, n_data_cert);
+ g_assert (asn1_cert != NULL);
}
DEFINE_TEARDOWN(asn1_tree)
{
- asn1_delete_structure (&asn1_test);
- asn1_delete_structure (&asn1_cert);
+ egg_asn1x_destroy (asn1_cert);
g_free (data_cert);
data_cert = NULL;
}
-DEFINE_TEST(asn1_types)
+DEFINE_TEST(node_name)
{
- ASN1_TYPE asn;
-
- asn = egg_asn1_get_pk_asn1type ();
- g_assert ("pk asn type is null" && asn != NULL);
-
- asn = egg_asn1_get_pkix_asn1type ();
- g_assert ("pkix asn type is null" && asn != NULL);
+ g_assert_cmpstr (egg_asn1x_name (asn1_cert), ==, "Certificate");
}
DEFINE_TEST(asn1_integers)
{
- ASN1_TYPE asn;
+ GNode *asn;
guchar *data;
gsize n_data;
gboolean ret;
- guint val;
- int res;
-
- res = asn1_create_element (asn1_test, "TEST.TestIntegers", &asn);
+ gulong val;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestIntegers");
g_assert ("asn test structure is null" && asn != NULL);
- ret = egg_asn1_write_uint (asn, "uint1", 35);
+ ret = egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "uint1", NULL), 35);
g_assert ("couldn't write integer" && ret);
-
- ret = egg_asn1_write_uint (asn, "uint2", 23456);
+
+ ret = egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "uint2", NULL), 23456);
g_assert ("couldn't write integer" && ret);
-
- ret = egg_asn1_write_uint (asn, "uint3", 209384022);
+
+ ret = egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "uint3", NULL), 209384022);
g_assert ("couldn't write integer" && ret);
/* Now encode the whole caboodle */
- data = egg_asn1_encode (asn, "", &n_data, NULL);
+ data = egg_asn1x_encode (asn, NULL, &n_data);
g_assert ("encoding asn1 didn't work" && data != NULL);
-
- asn1_delete_structure (&asn);
-
+
+ egg_asn1x_destroy (asn);
+
/* Now decode it all nicely */
- res = asn1_create_element (asn1_test, "TEST.TestIntegers", &asn);
- g_return_if_fail (res == ASN1_SUCCESS);
-
- res = asn1_der_decoding (&asn, data, n_data, NULL);
- g_assert ("decoding asn didn't work" && res == ASN1_SUCCESS);
-
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data, n_data);
+ g_return_if_fail (asn != NULL);
+
/* And get out the values */
- ret = egg_asn1_read_uint (asn, "uint1", &val);
+ ret = egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "uint1", NULL), &val);
g_assert ("couldn't read integer from asn1" && ret);
g_assert_cmpuint (val, ==, 35);
-
- ret = egg_asn1_read_uint (asn, "uint2", &val);
+
+ ret = egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "uint2", NULL), &val);
g_assert ("couldn't read integer from asn1" && ret);
g_assert_cmpuint (val, ==, 23456);
- ret = egg_asn1_read_uint (asn, "uint3", &val);
+ ret = egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "uint3", NULL), &val);
g_assert ("couldn't read integer from asn1" && ret);
g_assert_cmpuint (val, ==, 209384022);
+
+ g_free (data);
}
DEFINE_TEST(boolean)
{
- ASN1_TYPE asn = NULL;
+ GNode *asn = NULL;
gboolean value, ret;
- int res;
-
- res = asn1_create_element (asn1_test, "TEST.TestData", &asn);
+ gpointer data;
+ gsize n_data;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestBooleanSeq");
g_assert ("asn test structure is null" && asn != NULL);
-
- res = asn1_write_value (asn, "boolean", "TRUE", 4);
- g_assert (res == ASN1_SUCCESS);
-
- ret = egg_asn1_read_boolean (asn, "boolean", &value);
+
+ /* Get the default value */
+ value = TRUE;
+ ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
+ g_assert (ret == TRUE);
+ g_assert (value == FALSE);
+
+ 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);
+
+ ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
g_assert (ret);
g_assert (value == TRUE);
-
- res = asn1_write_value (asn, "boolean", "FALSE", 5);
- g_assert (res == ASN1_SUCCESS);
- ret = egg_asn1_read_boolean (asn, "boolean", &value);
+ 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);
+
+ ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
g_assert (ret);
g_assert (value == FALSE);
-
- ret = egg_asn1_read_boolean (asn, "nonExistant", &value);
- g_assert (!ret);
-
- asn1_delete_structure (&asn);
+
+ g_free (data);
+ egg_asn1x_destroy (asn);
}
DEFINE_TEST(write_value)
{
- ASN1_TYPE asn = NULL;
+ GNode *asn = NULL;
guchar *data;
gsize n_data;
- int res;
-
- res = asn1_create_element (asn1_test, "TEST.TestData", &asn);
+ guchar *encoded;
+ gsize n_encoded;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
-
- if (!egg_asn1_write_value (asn, "data", (const guchar*)"SOME DATA", 9))
+
+ if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- data = egg_asn1_read_value (asn, "data", &n_data, NULL);
+ encoded = egg_asn1x_encode (asn, NULL, &n_encoded);
+ g_assert (encoded);
+
+ data = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "data", NULL), NULL, &n_data);
g_assert (data != NULL);
g_assert_cmpuint (n_data, ==, 9);
g_assert (memcmp (data, "SOME DATA", 9) == 0);
g_free (data);
-
- asn1_delete_structure (&asn);
+
+ g_free (encoded);
+ egg_asn1x_destroy (asn);
}
DEFINE_TEST(element_length_content)
{
- ASN1_TYPE asn = NULL;
- guchar buffer[1024];
+ GNode *asn = NULL;
+ gchar *buffer;
const guchar *content;
gsize n_content;
- gint length;
- int res;
-
- res = asn1_create_element (asn1_test, "TEST.TestData", &asn);
+ gsize n_buffer;
+ gssize length;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
-
- res = asn1_write_value (asn, "data", "SOME DATA", 9);
- g_assert (res == ASN1_SUCCESS);
-
- length = 1024;
- res = asn1_der_coding (asn, "", buffer, &length, NULL);
- g_assert (res == ASN1_SUCCESS);
-
+
+ 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);
+ g_assert (buffer != NULL);
+
/* Now the real test */
- length = egg_asn1_element_length (buffer, 1024);
+ length = egg_asn1x_element_length (buffer, n_buffer + 1024);
g_assert_cmpint (length, ==, 13);
-
- content = egg_asn1_element_content (buffer, length, &n_content);
+
+ content = egg_asn1x_element_content (buffer, length, &n_content);
g_assert (content);
g_assert_cmpuint (n_content, ==, 11);
- content = egg_asn1_element_content (content, n_content, &n_content);
+ content = egg_asn1x_element_content (content, n_content, &n_content);
g_assert (content);
g_assert_cmpuint (n_content, ==, 9);
g_assert (memcmp (content, "SOME DATA", 9) == 0);
-
- asn1_delete_structure (&asn);
+
+ egg_asn1x_destroy (asn);
+ g_free (buffer);
}
DEFINE_TEST(read_element)
{
- ASN1_TYPE asn = NULL;
- guchar buffer[1024];
- const guchar *data;
+ GNode *asn = NULL;
+ guchar *buffer;
+ gconstpointer data;
gsize n_data;
- gint length;
- int res;
-
- res = asn1_create_element (asn1_test, "TEST.TestData", &asn);
+ gsize n_buffer;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
-
- res = asn1_write_value (asn, "data", "SOME DATA", 9);
- g_assert (res == ASN1_SUCCESS);
-
- length = 1024;
- res = asn1_der_coding (asn, "", buffer, &length, NULL);
- g_assert (res == ASN1_SUCCESS);
-
+
+ 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);
+ g_assert (buffer != NULL);
+
/* Now the real test */
- data = egg_asn1_read_element (asn, buffer, length, "data", &n_data);
+ data = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "data", NULL), &n_data);
g_assert (data != NULL);
g_assert_cmpint (n_data, ==, 11);
- data = egg_asn1_read_content (asn, buffer, length, "data", &n_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_cmpuint (n_data, ==, 9);
g_assert (memcmp (data, "SOME DATA", 9) == 0);
-
- /* Invalid should return null for both those */
- data = egg_asn1_read_element (asn, buffer, length, "nonExistant", &n_data);
- g_assert (data == NULL);
- data = egg_asn1_read_content (asn, buffer, length, "nonExistant", &n_data);
- g_assert (data == NULL);
-
- asn1_delete_structure (&asn);
+
+ egg_asn1x_destroy (asn);
+ g_free (buffer);
}
DEFINE_TEST(oid)
{
- ASN1_TYPE asn = NULL;
+ GNode *asn = NULL;
GQuark oid, check;
- int res;
-
- res = asn1_create_element (asn1_test, "TEST.TestData", &asn);
+ guchar *buffer;
+ gsize n_buffer;
+
+ asn = egg_asn1x_create (test_asn1_tab, "TestOid");
g_assert ("asn test structure is null" && asn != NULL);
-
- res = asn1_write_value (asn, "data", "SOME DATA", 9);
- g_assert (res == ASN1_SUCCESS);
- /* No such element, should return 0 */
- oid = egg_asn1_read_oid (asn, "nonExistant");
- g_assert (oid == 0);
+ if (!egg_asn1x_set_oid_as_string (egg_asn1x_node (asn, "oid", NULL), "1.2.34567.89"))
+ g_assert_not_reached ();
+
+ buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ g_assert (buffer != NULL);
/* Now a quark has been defined */
- check = g_quark_from_static_string ("SOME DATA");
- oid = egg_asn1_read_oid (asn, "data");
+ check = g_quark_from_static_string ("1.2.34567.89");
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "oid", NULL));
+ g_assert (oid);
g_assert (check == oid);
- g_assert_cmpstr (g_quark_to_string (oid), ==, "SOME DATA");
-
+ g_assert_cmpstr (g_quark_to_string (oid), ==, "1.2.34567.89");
+
/* Write a different OID */
- if (!egg_asn1_write_oid (asn, "data", g_quark_from_static_string ("ANOTHER")))
+ 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 ();
-
- oid = egg_asn1_read_oid (asn, "data");
+
+ g_free (buffer);
+ buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ 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), ==, "ANOTHER");
-
- asn1_delete_structure (&asn);
+ g_assert_cmpstr (g_quark_to_string (oid), ==, "5.4.3.2.1678");
+
+ g_free (buffer);
+ egg_asn1x_destroy (asn);
}
typedef struct _TimeTestData {
@@ -332,7 +322,7 @@ DEFINE_TEST(general_time)
const TimeTestData *data;
for (data = generalized_time_test_data; data->value; ++data) {
- when = egg_asn1_time_parse_general (data->value, -1);
+ when = egg_asn1x_parse_time_general (data->value, -1);
if (data->ref != when) {
printf ("%s", data->value);
printf ("%s != ", ctime (&when));
@@ -350,7 +340,7 @@ DEFINE_TEST(utc_time)
const TimeTestData *data;
for (data = utc_time_test_data; data->value; ++data) {
- when = egg_asn1_time_parse_utc (data->value, -1);
+ when = egg_asn1x_parse_time_utc (data->value, -1);
if (data->ref != when) {
printf ("%s", data->value);
printf ("%s != ", ctime (&when));
@@ -364,19 +354,56 @@ DEFINE_TEST(utc_time)
DEFINE_TEST(read_time)
{
- time_t time;
-
- if (!egg_asn1_read_time (asn1_cert, "tbsCertificate.validity.notBefore", &time))
- g_assert_not_reached ();
+ glong time;
+
+ time = egg_asn1x_get_time_as_long (egg_asn1x_node (asn1_cert, "tbsCertificate", "validity", "notBefore", NULL));
g_assert_cmpint (time, ==, 820454400);
}
DEFINE_TEST(read_date)
{
GDate date;
- if (!egg_asn1_read_date (asn1_cert, "tbsCertificate.validity.notAfter", &date))
+ if (!egg_asn1x_get_time_as_date (egg_asn1x_node (asn1_cert, "tbsCertificate", "validity", "notAfter", NULL), &date))
g_assert_not_reached ();
g_assert_cmpint (date.day, ==, 31);
g_assert_cmpint (date.month, ==, 12);
g_assert_cmpint (date.year, ==, 2020);
}
+
+DEFINE_TEST(create_by_oid)
+{
+ /* id-at-initials = X520initials */
+ GNode *node = egg_asn1x_create (pkix_asn1_tab, "2.5.4.43");
+ g_assert (node != NULL);
+ g_assert_cmpstr (egg_asn1x_name (node), ==, "X520initials");
+ egg_asn1x_destroy (node);
+}
+
+DEFINE_TEST(create_by_oid_invalid)
+{
+ GNode *node = egg_asn1x_create (pkix_asn1_tab, "23.23.23.23");
+ g_assert (node == NULL);
+}
+
+DEFINE_TEST(create_by_bad_order)
+{
+ /*
+ * In pkix.asn the definition for parts of this oid
+ * come in the wrong order. However this should still work.
+ */
+
+ /* id-pe-authorityInfoAccess = AuthorityInfoAccessSyntax */
+ GNode *node = egg_asn1x_create (pkix_asn1_tab, "1.3.6.1.5.5.7.1.1");
+ g_assert (node != NULL);
+ g_assert_cmpstr (egg_asn1x_name (node), ==, "AuthorityInfoAccessSyntax");
+ egg_asn1x_destroy (node);
+}
+
+DEFINE_TEST(count)
+{
+ GNode *node;
+
+ node = egg_asn1x_node (asn1_cert, "tbsCertificate", "issuer", "rdnSequence", NULL);
+ g_assert (node);
+ g_assert_cmpuint (egg_asn1x_count (node), ==, 7);
+}
diff --git a/gcr/gcr-certificate-details-widget.c b/gcr/gcr-certificate-details-widget.c
index 48e6fba..4178e30 100644
--- a/gcr/gcr-certificate-details-widget.c
+++ b/gcr/gcr-certificate-details-widget.c
@@ -22,7 +22,8 @@
#include "gcr-certificate.h"
#include "gcr-certificate-details-widget.h"
-#include "egg/egg-asn1.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
#include "egg/egg-dn.h"
#include "egg/egg-oid.h"
#include "egg/egg-hex.h"
@@ -178,58 +179,51 @@ append_fingerprint (GcrCertificateDetailsWidget *self, const guchar *data,
}
static gboolean
-append_extension (GcrCertificateDetailsWidget *self, ASN1_TYPE asn,
+append_extension (GcrCertificateDetailsWidget *self, GNode *asn,
const guchar *data, gsize n_data, gint index)
{
GQuark oid;
- gchar *name, *display;
+ gchar *display;
gsize n_value;
const guchar *value;
const gchar *text;
gboolean critical;
- int len, res;
-
+ GNode *node;
+
/* Make sure it is present */
- len = 0;
- name = g_strdup_printf ("tbsCertificate.extensions.?%u", index);
- res = asn1_read_value (asn, name, NULL, &len);
- g_free (name);
-
- if (res == ASN1_ELEMENT_NOT_FOUND)
+ asn = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, NULL);
+ if (asn == NULL)
return FALSE;
/* Dig out the OID */
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnID", index);
- oid = egg_asn1_read_oid (asn, name);
- g_free (name);
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "extnID", NULL));
g_return_val_if_fail (oid, FALSE);
-
-
+
+
append_heading (self, _("Extension"));
-
-
+
+
/* Extension type */
text = egg_oid_get_description (oid);
append_field_and_value (self, _("Identifier"), text, FALSE);
-
-
+
+
/* Extension value */
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnValue", index);
- value = egg_asn1_read_content (asn, data, n_data, name, &n_value);
- g_free (name);
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "extnValue", NULL), &n_value);
/* TODO: Parsing of extensions that we understand */
display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
append_field_and_value (self, _("Value"), display, TRUE);
g_free (display);
-
+
/* Critical */
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.critical", index);
- if (egg_asn1_read_boolean (asn, name, &critical))
- append_field_and_value (self, _("Critical"), critical ? _("Yes") : _("No"), FALSE);
- g_free (name);
-
+ node = egg_asn1x_node (asn, "critical", NULL);
+ if (node != NULL) {
+ if (egg_asn1x_get_boolean (node, &critical))
+ append_field_and_value (self, _("Critical"), critical ? _("Yes") : _("No"), FALSE);
+ }
+
return TRUE;
}
@@ -280,13 +274,14 @@ refresh_display (GcrCertificateDetailsWidget *self)
const guchar *data, *value;
gsize n_data, n_value;
const gchar *text;
- guint version, size;
- guint index;
+ gulong version;
+ guint index, size, n_bits;
gchar *display;
- ASN1_TYPE asn;
+ guchar *bits;
+ GNode *asn;
GQuark oid;
GDate date;
-
+
gtk_text_buffer_get_start_iter (self->pv->buffer, &start);
gtk_text_buffer_get_end_iter (self->pv->buffer, &iter);
gtk_text_buffer_delete (self->pv->buffer, &start, &iter);
@@ -296,40 +291,40 @@ refresh_display (GcrCertificateDetailsWidget *self)
data = gcr_certificate_get_der_data (self->pv->certificate, &n_data);
g_return_if_fail (data);
-
- asn = egg_asn1_decode ("PKIX1.Certificate", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
g_return_if_fail (asn);
-
+
/* The subject */
append_heading (self, _("Subject Name"));
- egg_dn_parse (asn, "tbsCertificate.subject.rdnSequence", on_parsed_dn_part, self);
-
+ egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), on_parsed_dn_part, self);
+
/* The Issuer */
append_heading (self, _("Issuer Name"));
- egg_dn_parse (asn, "tbsCertificate.issuer.rdnSequence", on_parsed_dn_part, self);
-
+ egg_dn_parse (egg_asn1x_node (asn, "tbsCertificate", "issuer", "rdnSequence", NULL), on_parsed_dn_part, self);
+
/* The Issued Parameters */
append_heading (self, _("Issued Certificate"));
-
- if (!egg_asn1_read_uint (asn, "tbsCertificate.version", &version))
+
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "tbsCertificate", "version", NULL), &version))
g_return_if_reached ();
- display = g_strdup_printf ("%u", version + 1);
+ display = g_strdup_printf ("%lu", version + 1);
append_field_and_value (self, _("Version"), display, FALSE);
g_free (display);
-
- value = egg_asn1_read_content (asn, data, n_data, "tbsCertificate.serialNumber", &n_value);
+
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), &n_value);
g_return_if_fail (value);
display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
append_field_and_value (self, _("Serial Number"), display, TRUE);
g_free (display);
display = g_malloc0 (128);
- if (egg_asn1_read_date (asn, "tbsCertificate.validity.notBefore", &date)) {
+ if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
g_return_if_reached ();
append_field_and_value (self, _("Not Valid Before"), display, FALSE);
}
- if (egg_asn1_read_date (asn, "tbsCertificate.validity.notAfter", &date)) {
+ if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notAfter", NULL), &date)) {
if (!g_date_strftime (display, 128, "%Y-%m-%d", &date))
g_return_if_reached ();
append_field_and_value (self, _("Not Valid After"), display, FALSE);
@@ -338,19 +333,19 @@ refresh_display (GcrCertificateDetailsWidget *self)
/* Signature */
append_heading (self, _("Signature"));
-
- oid = egg_asn1_read_oid (asn, "signatureAlgorithm.algorithm");
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "signatureAlgorithm", "algorithm", NULL));
text = egg_oid_get_description (oid);
append_field_and_value (self, _("Signature Algorithm"), text, FALSE);
-
- value = egg_asn1_read_content (asn, data, n_data, "signatureAlgorithm.parameters", &n_value);
+
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
if (value && n_value) {
display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
append_field_and_value (self, _("Signature Parameters"), display, TRUE);
g_free (display);
}
- value = egg_asn1_read_content (asn, data, n_data, "signature", &n_value);
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "signature", NULL), &n_value);
g_return_if_fail (value);
display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
append_field_and_value (self, _("Signature"), display, TRUE);
@@ -358,12 +353,12 @@ refresh_display (GcrCertificateDetailsWidget *self)
/* Public Key Info */
append_heading (self, _("Public Key Info"));
-
- oid = egg_asn1_read_oid (asn, "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm");
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "algorithm", "algorithm", NULL));
text = egg_oid_get_description (oid);
append_field_and_value (self, _("Key Algorithm"), text, FALSE);
-
- value = egg_asn1_read_content (asn, data, n_data, "tbsCertificate.subjectPublicKeyInfo.algorithm.parameters", &n_value);
+
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "algorithm", "parameters", NULL), &n_value);
if (value && n_value) {
display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
append_field_and_value (self, _("Key Parameters"), display, TRUE);
@@ -376,13 +371,14 @@ refresh_display (GcrCertificateDetailsWidget *self)
append_field_and_value (self, _("Key Size"), display, FALSE);
g_free (display);
}
-
- value = egg_asn1_read_content (asn, data, n_data, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", &n_value);
- g_return_if_fail (value);
- display = egg_hex_encode_full (value, n_value, TRUE, ' ', 1);
+
+ bits = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", "subjectPublicKey", NULL), NULL, &n_bits);
+ g_return_if_fail (bits);
+ display = egg_hex_encode_full (bits, n_bits / 8, TRUE, ' ', 1);
append_field_and_value (self, _("Public Key"), display, TRUE);
g_free (display);
-
+ g_free (bits);
+
/* Fingerprints */
append_heading (self, _("Fingerprints"));
@@ -394,8 +390,8 @@ refresh_display (GcrCertificateDetailsWidget *self)
if (!append_extension (self, asn, data, n_data, index))
break;
}
-
- asn1_delete_structure (&asn);
+
+ egg_asn1x_destroy (asn);
}
/* -----------------------------------------------------------------------------
diff --git a/gcr/gcr-certificate.c b/gcr/gcr-certificate.c
index 5d8d6c8..8a8abd7 100644
--- a/gcr/gcr-certificate.c
+++ b/gcr/gcr-certificate.c
@@ -24,7 +24,8 @@
#include "gcr-internal.h"
#include "gcr-certificate.h"
-#include "egg/egg-asn1.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
#include "egg/egg-dn.h"
#include "egg/egg-hex.h"
@@ -56,7 +57,7 @@
typedef struct _GcrCertificateInfo {
const guchar *der;
gsize n_der;
- ASN1_TYPE asn1;
+ GNode *asn1;
guint key_size;
} GcrCertificateInfo;
@@ -74,7 +75,7 @@ certificate_info_free (gpointer data)
GcrCertificateInfo *info = data;
if (info) {
g_assert (info->asn1);
- asn1_delete_structure (&info->asn1);
+ egg_asn1x_destroy (info->asn1);
g_free (info);
}
}
@@ -83,7 +84,7 @@ static GcrCertificateInfo*
certificate_info_load (GcrCertificate *cert)
{
GcrCertificateInfo *info;
- ASN1_TYPE asn1;
+ GNode *asn1;
const guchar *der;
gsize n_der;
@@ -99,7 +100,7 @@ certificate_info_load (GcrCertificate *cert)
}
/* Cache is invalid or non existent */
- asn1 = egg_asn1_decode ("PKIX1.Certificate", der, n_der);
+ asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", der, n_der);
if (asn1 == NULL) {
g_warning ("a derived class provided an invalid or unparseable X509 DER certificate data.");
return NULL;
@@ -109,7 +110,7 @@ certificate_info_load (GcrCertificate *cert)
info->der = der;
info->n_der = n_der;
info->asn1 = asn1;
-
+
g_object_set_qdata_full (G_OBJECT (cert), CERTIFICATE_INFO, info, certificate_info_free);
return info;
}
@@ -117,17 +118,17 @@ certificate_info_load (GcrCertificate *cert)
static guint
calculate_rsa_key_size (const guchar *data, gsize n_data)
{
- ASN1_TYPE asn;
+ GNode *asn;
gsize n_content;
-
- asn = egg_asn1_decode ("PK.RSAPublicKey", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data, n_data);
g_return_val_if_fail (asn, 0);
-
- if (!egg_asn1_read_content (asn, data, n_data, "modulus", &n_content))
+
+ if (!egg_asn1x_get_raw_value (egg_asn1x_node (asn, "modulus", NULL), &n_content))
g_return_val_if_reached (0);
-
- asn1_delete_structure (&asn);
-
+
+ egg_asn1x_destroy (asn);
+
/* Removes the complement */
return (n_content / 2) * 2 * 8;
}
@@ -135,17 +136,17 @@ calculate_rsa_key_size (const guchar *data, gsize n_data)
static guint
calculate_dsa_params_size (const guchar *data, gsize n_data)
{
- ASN1_TYPE asn;
+ GNode *asn;
gsize n_content;
-
- asn = egg_asn1_decode ("PK.DSAParameters", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", data, n_data);
g_return_val_if_fail (asn, 0);
- if (!egg_asn1_read_content (asn, data, n_data, "p", &n_content))
+ if (!egg_asn1x_get_raw_value (egg_asn1x_node (asn, "p", NULL), &n_content))
g_return_val_if_reached (0);
-
- asn1_delete_structure (&asn);
-
+
+ egg_asn1x_destroy (asn);
+
/* Removes the complement */
return (n_content / 2) * 2 * 8;
}
@@ -153,43 +154,43 @@ calculate_dsa_params_size (const guchar *data, gsize n_data)
static guint
calculate_key_size (GcrCertificateInfo *info)
{
- ASN1_TYPE asn;
+ GNode *asn;
const guchar *data, *params;
- gsize n_data, n_params, n_key;
- guint key_size = 0;
+ gsize n_data, n_params;
+ guint key_size = 0, n_bits;
guchar *key;
GQuark oid;
-
- data = egg_asn1_read_element (info->asn1, info->der, info->n_der, "tbsCertificate.subjectPublicKeyInfo", &n_data);
+
+ data = egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_data);
g_return_val_if_fail (data != NULL, 0);
-
- asn = egg_asn1_decode ("PKIX1.SubjectPublicKeyInfo", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
g_return_val_if_fail (asn, 0);
-
+
/* Figure out the algorithm */
- oid = egg_asn1_read_oid (asn, "algorithm.algorithm");
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
g_return_val_if_fail (oid, 0);
-
+
/* RSA keys are stored in the main subjectPublicKey field */
if (oid == OID_RSA_KEY) {
-
+
/* A bit string so we cannot process in place */
- key = egg_asn1_read_value (asn, "subjectPublicKey", &n_key, NULL);
+ key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
g_return_val_if_fail (key, 0);
- key_size = calculate_rsa_key_size (key, n_key / 8);
+ key_size = calculate_rsa_key_size (key, n_bits / 8);
/* The DSA key size is discovered by the prime in params */
} else if (oid == OID_DSA_KEY) {
- params = egg_asn1_read_element (asn, data, n_data, "algorithm.parameters", &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
key_size = calculate_dsa_params_size (params, n_params);
-
+
} else {
g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
}
-
- asn1_delete_structure (&asn);
+
+ egg_asn1x_destroy (asn);
g_free (key);
-
+
return key_size;
}
@@ -319,8 +320,8 @@ gcr_certificate_get_issuer_part (GcrCertificate *self, const char *part)
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
-
- return egg_dn_read_part (info->asn1, "tbsCertificate.issuer.rdnSequence", part);
+
+ return egg_dn_read_part (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL), part);
}
/**
@@ -344,8 +345,8 @@ gcr_certificate_get_issuer_dn (GcrCertificate *self)
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
-
- return egg_dn_read (info->asn1, "tbsCertificate.issuer.rdnSequence");
+
+ return egg_dn_read (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL));
}
/**
@@ -390,8 +391,8 @@ gcr_certificate_get_subject_part (GcrCertificate *self, const char *part)
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
-
- return egg_dn_read_part (info->asn1, "tbsCertificate.subject.rdnSequence", part);
+
+ return egg_dn_read_part (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", "rdnSequence", NULL), part);
}
/**
@@ -415,8 +416,8 @@ gcr_certificate_get_subject_dn (GcrCertificate *self)
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
-
- return egg_dn_read (info->asn1, "tbsCertificate.issuer.rdnSequence");
+
+ return egg_dn_read (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL));
}
/**
@@ -442,7 +443,7 @@ gcr_certificate_get_issued_date (GcrCertificate *self)
g_return_val_if_fail (info, NULL);
date = g_date_new ();
- if (!egg_asn1_read_date (info->asn1, "tbsCertificate.validity.notBefore", date)) {
+ if (!egg_asn1x_get_time_as_date (egg_asn1x_node (info->asn1, "tbsCertificate", "validity", "notBefore", NULL), date)) {
g_date_free (date);
return NULL;
}
@@ -473,7 +474,7 @@ gcr_certificate_get_expiry_date (GcrCertificate *self)
g_return_val_if_fail (info, NULL);
date = g_date_new ();
- if (!egg_asn1_read_date (info->asn1, "tbsCertificate.validity.notAfter", date)) {
+ if (!egg_asn1x_get_time_as_date (egg_asn1x_node (info->asn1, "tbsCertificate", "validity", "notAfter", NULL), date)) {
g_date_free (date);
return NULL;
}
@@ -600,14 +601,16 @@ guchar*
gcr_certificate_get_serial_number (GcrCertificate *self, gsize *n_length)
{
GcrCertificateInfo *info;
-
+ gconstpointer serial;
+
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
g_return_val_if_fail (n_length, NULL);
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
-
- return egg_asn1_read_value (info->asn1, "tbsCertificate.serialNumber", n_length, g_realloc);
+
+ serial = egg_asn1x_get_raw_value (egg_asn1x_node (info->asn1, "tbsCertificate", "serialNumber", NULL), n_length);
+ return g_memdup (serial, *n_length);
}
/**
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index f3b597c..2a052e7 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -28,7 +28,8 @@
#include "gcr-parser.h"
#include "gcr-types.h"
-#include "egg/egg-asn1.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
#include "egg/egg-dn.h"
#include "egg/egg-openssl.h"
#include "egg/egg-secure-memory.h"
@@ -158,7 +159,7 @@ init_quarks (void)
*/
static gboolean
-parsed_asn1_attribute (GcrParser *self, ASN1_TYPE asn, const guchar *data, gsize n_data,
+parsed_asn1_attribute (GcrParser *self, GNode *asn, const guchar *data, gsize n_data,
const gchar *part, CK_ATTRIBUTE_TYPE type)
{
const guchar *value;
@@ -167,13 +168,13 @@ parsed_asn1_attribute (GcrParser *self, ASN1_TYPE asn, const guchar *data, gsize
g_assert (GCR_IS_PARSER (self));
g_assert (asn);
g_assert (data);
- g_assert (part);
g_assert (self->pv->parsed_attrs);
-
- value = egg_asn1_read_content (asn, data, n_data, part, &n_value);
+
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, part, NULL), &n_value);
if (value == NULL)
return FALSE;
-
+
+ /* TODO: Convert to USG FROM STD */
gp11_attributes_add_data (self->pv->parsed_attrs, type, value, n_value);
return TRUE;
}
@@ -295,27 +296,27 @@ static gint
parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
{
gint res = GCR_ERROR_UNRECOGNIZED;
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- guint version;
-
- asn = egg_asn1_decode ("PK.RSAPrivateKey", data, n_data);
+ GNode *asn = NULL;
+ gulong version;
+
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
if (!asn)
goto done;
-
+
parsed_clear (self, CKO_PRIVATE_KEY);
parsed_ulong (self, CKA_KEY_TYPE, CKK_RSA);
res = GCR_ERROR_FAILURE;
- if (!egg_asn1_read_uint (asn, "version", &version))
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
goto done;
-
+
/* We only support simple version */
if (version != 0) {
res = GCR_ERROR_UNRECOGNIZED;
- g_message ("unsupported version of RSA key: %u", version);
+ g_message ("unsupported version of RSA key: %lu", version);
goto done;
}
-
+
if (!parsed_asn1_attribute (self, asn, data, n_data, "modulus", CKA_MODULUS) ||
!parsed_asn1_attribute (self, asn, data, n_data, "publicExponent", CKA_PUBLIC_EXPONENT) ||
!parsed_asn1_attribute (self, asn, data, n_data, "privateExponent", CKA_PRIVATE_EXPONENT) ||
@@ -328,9 +329,7 @@ parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
res = SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
if (res == GCR_ERROR_FAILURE)
g_message ("invalid RSA key");
@@ -345,16 +344,15 @@ static gint
parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
{
gint ret = GCR_ERROR_UNRECOGNIZED;
- int res;
- ASN1_TYPE asn;
+ GNode *asn = NULL;
- asn = egg_asn1_decode ("PK.DSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
if (!asn)
goto done;
-
+
parsed_clear (self, CKO_PRIVATE_KEY);
parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
- res = GCR_ERROR_FAILURE;
+ ret = GCR_ERROR_FAILURE;
if (!parsed_asn1_attribute (self, asn, data, n_data, "p", CKA_PRIME) ||
!parsed_asn1_attribute (self, asn, data, n_data, "q", CKA_SUBPRIME) ||
@@ -366,9 +364,7 @@ parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
ret = SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
if (ret == GCR_ERROR_FAILURE)
g_message ("invalid DSA key");
@@ -380,34 +376,30 @@ parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n
const guchar *params, gsize n_params)
{
gint ret = GCR_ERROR_UNRECOGNIZED;
- int res;
- ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
- ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
+ GNode *asn_params = NULL;
+ GNode *asn_key = NULL;
- asn_params = egg_asn1_decode ("PK.DSAParameters", params, n_params);
- asn_key = egg_asn1_decode ("PK.DSAPrivatePart", keydata, n_keydata);
+ 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);
if (!asn_params || !asn_key)
goto done;
-
+
parsed_clear (self, CKO_PRIVATE_KEY);
parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
- res = GCR_ERROR_FAILURE;
-
+ ret = GCR_ERROR_FAILURE;
+
if (!parsed_asn1_attribute (self, asn_params, params, n_params, "p", CKA_PRIME) ||
!parsed_asn1_attribute (self, asn_params, params, n_params, "q", CKA_SUBPRIME) ||
!parsed_asn1_attribute (self, asn_params, params, n_params, "g", CKA_BASE) ||
- !parsed_asn1_attribute (self, asn_key, keydata, n_keydata, "", CKA_VALUE))
+ !parsed_asn1_attribute (self, asn_key, keydata, n_keydata, NULL, CKA_VALUE))
goto done;
parsed_fire (self);
ret = SUCCESS;
done:
- if (asn_key)
- asn1_delete_structure (&asn_key);
- if (asn_params)
- asn1_delete_structure (&asn_params);
-
+ egg_asn1x_destroy (asn_key);
+ egg_asn1x_destroy (asn_params);
if (ret == GCR_ERROR_FAILURE)
g_message ("invalid DSA key");
@@ -437,7 +429,6 @@ parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
static gint
parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
gint ret;
CK_KEY_TYPE key_type;
GQuark key_algo;
@@ -445,17 +436,18 @@ parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
gsize n_keydata;
const guchar *params;
gsize n_params;
-
+ GNode *asn = NULL;
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-8-PrivateKeyInfo", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
if (!asn)
goto done;
ret = GCR_ERROR_FAILURE;
key_type = GP11_INVALID;
-
- key_algo = egg_asn1_read_oid (asn, "privateKeyAlgorithm.algorithm");
+
+ key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
if (!key_algo)
goto done;
else if (key_algo == OID_PKIX1_RSA)
@@ -468,13 +460,12 @@ parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
goto done;
}
- keydata = egg_asn1_read_content (asn, data, n_data, "privateKey", &n_keydata);
+ keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
if (!keydata)
goto done;
-
- params = egg_asn1_read_element (asn, data, n_data, "privateKeyAlgorithm.parameters",
- &n_params);
-
+
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL), &n_params);
+
ret = SUCCESS;
done:
@@ -501,9 +492,8 @@ done:
} else if (ret == GCR_ERROR_FAILURE) {
g_message ("invalid PKCS#8 key");
}
-
- if (asn)
- asn1_delete_structure (&asn);
+
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -511,7 +501,7 @@ static gint
parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
{
PasswordState pstate = PASSWORD_STATE_INIT;
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_cipher_hd_t cih = NULL;
gcry_error_t gcry;
gint ret, r;
@@ -523,20 +513,20 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
gint l;
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
if (!asn)
goto done;
ret = GCR_ERROR_FAILURE;
/* Figure out the type of encryption */
- scheme = egg_asn1_read_oid (asn, "encryptionAlgorithm.algorithm");
+ scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
if (!scheme)
goto done;
-
- params = egg_asn1_read_element (asn, data, n_data, "encryptionAlgorithm.parameters", &n_params);
-
+
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
+
parsed_clear (self, CKO_PRIVATE_KEY);
/* Loop to try different passwords */
@@ -553,11 +543,11 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
/* Parse the encryption stuff into a cipher. */
if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih))
break;
-
- crypted = egg_asn1_read_value (asn, "encryptedData", &n_crypted, (EggAllocator)egg_secure_realloc);
+
+ crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted);
if (!crypted)
break;
-
+
gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
gcry_cipher_close (cih);
cih = NULL;
@@ -568,13 +558,12 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
}
/* Unpad the DER data */
- l = egg_asn1_element_length (crypted, n_crypted);
+ l = egg_asn1x_element_length (crypted, n_crypted);
if (l > 0)
n_crypted = l;
/* Try to parse the resulting key */
r = parse_der_pkcs8_plain (self, crypted, n_crypted);
- egg_secure_free (crypted);
crypted = NULL;
if (r != GCR_ERROR_UNRECOGNIZED) {
@@ -588,10 +577,9 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
done:
if (cih)
gcry_cipher_close (cih);
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
egg_secure_free (crypted);
-
+
return ret;
}
@@ -614,19 +602,19 @@ parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
static gint
parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn;
+ GNode *asn;
gchar *name;
-
- asn = egg_asn1_decode ("PKIX1.Certificate", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
if (asn == NULL)
return GCR_ERROR_UNRECOGNIZED;
parsed_clear (self, CKO_CERTIFICATE);
parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
- name = egg_dn_read_part (asn, "tbsCertificate.subject.rdnSequence", "CN");
- asn1_delete_structure (&asn);
-
+ name = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
+ egg_asn1x_destroy (asn);
+
if (name != NULL) {
parsed_label (self, name);
g_free (name);
@@ -645,30 +633,30 @@ parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
static gint
handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
+ GNode *node;
gint ret;
- gchar *part;
const guchar *certificate;
gsize n_certificate;
int i;
-
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-7-SignedData", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-SignedData", data, n_data);
if (!asn)
goto done;
ret = GCR_ERROR_FAILURE;
for (i = 0; TRUE; ++i) {
-
- part = g_strdup_printf ("certificates.?%u", i + 1);
- certificate = egg_asn1_read_element (asn, data, n_data, part, &n_certificate);
- g_free (part);
-
+
+ node = egg_asn1x_node (asn, "certificates", i + 1, NULL);
+
/* No more certificates? */
- if (!certificate)
+ if (node == NULL)
break;
+
+ certificate = egg_asn1x_get_raw_element (node, &n_certificate);
ret = parse_der_certificate (self, certificate, n_certificate);
if (ret != SUCCESS)
@@ -678,50 +666,51 @@ handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
/* TODO: Parse out all the CRLs */
ret = SUCCESS;
-
+
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
return ret;
}
static gint
parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
+ GNode *node;
gint ret;
const guchar* content = NULL;
gsize n_content;
GQuark oid;
-
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-7-ContentInfo", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data, n_data);
if (!asn)
goto done;
ret = GCR_ERROR_FAILURE;
- oid = egg_asn1_read_oid (asn, "contentType");
- if (!oid)
+ node = egg_asn1x_node (asn, "contentType", NULL);
+ if (!node)
goto done;
+ oid = egg_asn1x_get_oid_as_quark (node);
+ g_return_val_if_fail (oid, GCR_ERROR_FAILURE);
+
/* Outer most one must just be plain data */
if (oid != OID_PKCS7_SIGNED_DATA) {
g_message ("unsupported outer content type in pkcs7: %s", g_quark_to_string (oid));
goto done;
}
-
- content = egg_asn1_read_content (asn, data, n_data, "content", &n_content);
+
+ content = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "content", NULL), &n_content);
if (!content)
goto done;
-
+
ret = handle_pkcs7_signed_data (self, content, n_content);
-
+
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -732,63 +721,62 @@ done:
static gint
handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
- const guchar *certificate;
- gsize n_certificate;
+ GNode *asn = NULL;
+ GNode *asn_content = NULL;
+ guchar *certificate;
+ const guchar *element;
+ gsize n_certificate, n_element;
gint ret;
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-12-CertBag", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-CertBag", data, n_data);
if (!asn)
goto done;
-
+
ret = GCR_ERROR_FAILURE;
-
- certificate = egg_asn1_read_content (asn, data, n_data, "certValue", &n_certificate);
- if (!certificate)
+
+ element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "certValue", NULL), &n_element);
+ if (!element)
goto done;
- /*
- * Wrapped in an OCTET STRING, so unwrap here, rather than allocating
- * a whole bunch more memory for a full ASN.1 parsing context.
- */
- certificate = egg_asn1_element_content (certificate, n_certificate, &n_certificate);
+ asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element, n_element);
+ if (!asn_content)
+ goto done;
+
+ certificate = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_certificate);
if (!certificate)
goto done;
-
+
ret = parse_der_certificate (self, certificate, n_certificate);
-
+
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn_content);
+ egg_asn1x_destroy (asn);
+ g_free (certificate);
return ret;
}
static gint
handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gint ret, r;
- int res, count = 0;
+ guint count = 0;
GQuark oid;
const guchar *element;
gsize n_element;
-
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-12-SafeContents", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-SafeContents", data, n_data);
if (!asn)
goto done;
-
+
ret = GCR_ERROR_FAILURE;
-
+
/* Get the number of elements in this bag */
- res = asn1_number_of_elements (asn, "", &count);
- if (res != ASN1_SUCCESS)
- goto done;
-
+ count = egg_asn1x_count (asn);
+
/*
* Now inside each bag are multiple elements. Who comes up
* with this stuff?
@@ -801,11 +789,11 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
*/
if (count >= 1) {
- oid = egg_asn1_read_oid (asn, "?1.bagId");
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, 1, "bagId", NULL));
if (!oid)
goto done;
-
- element = egg_asn1_read_content (asn, data, n_data, "?1.bagValue", &n_element);
+
+ element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, 1, "bagValue", NULL), &n_element);
if (!element)
goto done;
@@ -835,9 +823,7 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
ret = SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -845,7 +831,7 @@ static gint
handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
{
PasswordState pstate = PASSWORD_STATE_INIT;
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_cipher_hd_t cih = NULL;
gcry_error_t gcry;
guchar *crypted = NULL;
@@ -855,24 +841,24 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
GQuark scheme;
gint ret, r;
gint l;
-
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-7-EncryptedData", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-EncryptedData", data, n_data);
if (!asn)
goto done;
-
+
ret = GCR_ERROR_FAILURE;
-
+
/* Check the encryption schema OID */
- scheme = egg_asn1_read_oid (asn, "encryptedContentInfo.contentEncryptionAlgorithm.algorithm");
+ scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "algorithm", NULL));
if (!scheme)
- goto done;
+ goto done;
- params = egg_asn1_read_element (asn, data, n_data, "encryptedContentInfo.contentEncryptionAlgorithm.parameters", &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL), &n_params);
if (!params)
goto done;
-
+
parsed_clear (self, 0);
/* Loop to try different passwords */
@@ -891,9 +877,9 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
ret = GCR_ERROR_FAILURE;
goto done;
}
-
- crypted = egg_asn1_read_value (asn, "encryptedContentInfo.encryptedContent",
- &n_crypted, (EggAllocator)egg_secure_realloc);
+
+ crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedContentInfo", "encryptedContent", NULL),
+ egg_secure_realloc, &n_crypted);
if (!crypted)
goto done;
@@ -905,9 +891,9 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
g_warning ("couldn't decrypt pkcs7 data: %s", gcry_strerror (gcry));
goto done;
}
-
+
/* Unpad the DER data */
- l = egg_asn1_element_length (crypted, n_crypted);
+ l = egg_asn1x_element_length (crypted, n_crypted);
if (l > 0)
n_crypted = l;
@@ -927,64 +913,65 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
done:
if (cih)
gcry_cipher_close (cih);
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
egg_secure_free (crypted);
-
return ret;
}
static gint
handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
+ GNode *asn_content = NULL;
gint ret, r;
const guchar *bag;
- gsize n_bag;
- gchar *part;
+ guchar *content = NULL;
+ gsize n_bag, n_content;
GQuark oid;
guint i;
-
+ GNode *node;
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-12-AuthenticatedSafe", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-AuthenticatedSafe", data, n_data);
if (!asn)
goto done;
-
+
ret = GCR_ERROR_FAILURE;
/*
* Inside each PKCS12 safe there are multiple bags.
*/
for (i = 0; TRUE; ++i) {
-
- part = g_strdup_printf ("?%u.contentType", i + 1);
- oid = egg_asn1_read_oid (asn, part);
- g_free (part);
-
+ node = egg_asn1x_node (asn, i + 1, "contentType", NULL);
+
/* All done? no more bags */
- if (!oid)
+ if (!node)
break;
-
- part = g_strdup_printf ("?%u.content", i + 1);
- bag = egg_asn1_read_content (asn, data, n_data, part, &n_bag);
- g_free (part);
-
- if (!bag) /* A parse error */
+
+ oid = egg_asn1x_get_oid_as_quark (node);
+
+ node = egg_asn1x_node (asn, i + 1, "content", NULL);
+ if (!node)
goto done;
-
+
+ bag = egg_asn1x_get_raw_element (node, &n_bag);
+ g_return_val_if_fail (bag, ret);
+
/* A non encrypted bag, just parse */
if (oid == OID_PKCS7_DATA) {
-
- /*
- * Wrapped in an OCTET STRING, so unwrap here, rather than allocating
- * a whole bunch more memory for a full ASN.1 parsing context.
- */
- bag = egg_asn1_element_content (bag, n_bag, &n_bag);
- if (!bag)
- goto done;
-
- r = handle_pkcs12_bag (self, bag, n_bag);
+
+ egg_asn1x_destroy (asn_content);
+ asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", bag, n_bag);
+ if (!asn_content)
+ goto done;
+
+ g_free (content);
+ content = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_content);
+ if (!content)
+ goto done;
+
+ r = handle_pkcs12_bag (self, content, n_content);
/* Encrypted data first needs decryption */
} else if (oid == OID_PKCS7_ENCRYPTED_DATA) {
@@ -1005,54 +992,59 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
ret = SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
+ egg_asn1x_destroy (asn_content);
+ g_free (content);
return ret;
}
static gint
parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
+ GNode *asn_content = NULL;
gint ret;
- const guchar* content = NULL;
- gsize n_content;
+ const guchar* element = NULL;
+ guchar *content = NULL;
+ gsize n_element, n_content;
GQuark oid;
-
+
ret = GCR_ERROR_UNRECOGNIZED;
-
- asn = egg_asn1_decode ("PKIX1.pkcs-12-PFX", data, n_data);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-PFX", data, n_data);
if (!asn)
goto done;
- oid = egg_asn1_read_oid (asn, "authSafe.contentType");
+ ret = GCR_ERROR_FAILURE;
+
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
if (!oid)
goto done;
-
+
/* Outer most one must just be plain data */
if (oid != OID_PKCS7_DATA) {
g_message ("unsupported safe content type in pkcs12: %s", g_quark_to_string (oid));
goto done;
}
-
- content = egg_asn1_read_content (asn, data, n_data, "authSafe.content", &n_content);
- if (!content)
+
+ element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "authSafe", "content", NULL), &n_element);
+ if (!element)
goto done;
-
- /*
- * Wrapped in an OCTET STRING, so unwrap here, rather than allocating
- * a whole bunch more memory for a full ASN.1 parsing context.
- */
- content = egg_asn1_element_content (content, n_content, &n_content);
+
+ asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element, n_element);
+ if (!asn_content)
+ goto done;
+
+ content = egg_asn1x_get_string_as_raw (asn_content, g_realloc, &n_content);
if (!content)
goto done;
-
+
ret = handle_pkcs12_safe (self, content, n_content);
-
+
done:
- if (asn)
- asn1_delete_structure (&asn);
+ g_free (content);
+ egg_asn1x_destroy (asn_content);
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -1168,7 +1160,7 @@ handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
g_assert (decrypted);
/* Unpad the DER data */
- l = egg_asn1_element_length (decrypted, n_decrypted);
+ l = egg_asn1x_element_length (decrypted, n_decrypted);
if (l > 0)
n_decrypted = l;
diff --git a/gcr/gcr-simple-certificate.c b/gcr/gcr-simple-certificate.c
index 0bac622..d9bf516 100644
--- a/gcr/gcr-simple-certificate.c
+++ b/gcr/gcr-simple-certificate.c
@@ -25,7 +25,6 @@
#include "gcr-internal.h"
#include "gcr-simple-certificate.h"
-#include "egg/egg-asn1.h"
#include "egg/egg-hex.h"
#include <string.h>
diff --git a/pkcs11/gkm/gkm-certificate-trust.c b/pkcs11/gkm/gkm-certificate-trust.c
index cbcd7c2..97df501 100644
--- a/pkcs11/gkm/gkm-certificate-trust.c
+++ b/pkcs11/gkm/gkm-certificate-trust.c
@@ -83,7 +83,7 @@ has_key_usage (GkmCertificateTrust *self, guint check, CK_ULONG *val)
GkmDataResult res;
const guchar *extension;
gsize n_extension;
- guint usage;
+ gulong usage;
g_return_val_if_fail (self->pv->certificate, CKR_GENERAL_ERROR);
*val = CKT_NETSCAPE_TRUST_UNKNOWN;
diff --git a/pkcs11/gkm/gkm-certificate.c b/pkcs11/gkm/gkm-certificate.c
index 0db7327..7f3dfd9 100644
--- a/pkcs11/gkm/gkm-certificate.c
+++ b/pkcs11/gkm/gkm-certificate.c
@@ -37,6 +37,7 @@
#include "gkm-util.h"
#include "egg/egg-dn.h"
+#include "egg/egg-asn1x.h"
#include "pkcs11/pkcs11.h"
#include "pkcs11/pkcs11g.h"
@@ -53,7 +54,7 @@ enum {
struct _GkmCertificatePrivate {
GkmCertificateKey *key;
- ASN1_TYPE asn1;
+ GNode *asn1;
guchar *data;
gsize n_data;
gchar *label;
@@ -215,9 +216,8 @@ static gint
find_certificate_extension (GkmCertificate *self, GQuark oid)
{
GQuark exoid;
- gchar *name;
+ GNode *node;
guint index;
- int res, len;
g_assert (oid);
g_assert (GKM_IS_CERTIFICATE (self));
@@ -226,17 +226,12 @@ find_certificate_extension (GkmCertificate *self, GQuark oid)
for (index = 1; TRUE; ++index) {
/* Make sure it is present */
- len = 0;
- name = g_strdup_printf ("tbsCertificate.extensions.?%u", index);
- res = asn1_read_value (self->pv->asn1, name, NULL, &len);
- g_free (name);
- if (res == ASN1_ELEMENT_NOT_FOUND)
+ node = egg_asn1x_node (self->pv->asn1, "tbsCertificate", "extensions", index, NULL);
+ if (node == NULL)
break;
/* See if it's the same */
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnID", index);
- exoid = egg_asn1_read_oid (self->pv->asn1, name);
- g_free (name);
+ exoid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (self->pv->asn1, "extnID", NULL));
if(exoid == oid)
return index;
@@ -332,18 +327,18 @@ gkm_certificate_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
case CKA_START_DATE:
case CKA_END_DATE:
g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
- if (!egg_asn1_read_time (self->pv->asn1,
- attr->type == CKA_START_DATE ?
- "tbsCertificate.validity.notBefore" :
- "tbsCertificate.validity.notAfter",
- &when))
+ when = egg_asn1x_get_time_as_long (egg_asn1x_node (self->pv->asn1,
+ attr->type == CKA_START_DATE ?
+ "tbsCertificate.validity.notBefore" :
+ "tbsCertificate.validity.notAfter",
+ NULL));
+ if (when < 0)
return CKR_FUNCTION_FAILED;
return gkm_attribute_set_date (attr, when);
case CKA_SUBJECT:
g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
- cdata = egg_asn1_read_element (self->pv->asn1, self->pv->data, self->pv->n_data,
- "tbsCertificate.subject", &n_data);
+ cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", NULL), &n_data);
g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
return gkm_attribute_set_data (attr, cdata, n_data);
@@ -354,15 +349,13 @@ 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_asn1_read_element (self->pv->asn1, self->pv->data, self->pv->n_data,
- "tbsCertificate.issuer", &n_data);
+ cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "issuer", NULL), &n_data);
g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
return gkm_attribute_set_data (attr, cdata, n_data);
case CKA_SERIAL_NUMBER:
g_return_val_if_fail (self->pv->asn1, CKR_GENERAL_ERROR);
- cdata = egg_asn1_read_element (self->pv->asn1, self->pv->data, self->pv->n_data,
- "tbsCertificate.serialNumber", &n_data);
+ cdata = egg_asn1x_get_raw_element (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "serialNumber", NULL), &n_data);
g_return_val_if_fail (cdata, CKR_GENERAL_ERROR);
return gkm_attribute_set_data (attr, cdata, n_data);
@@ -455,7 +448,7 @@ gkm_certificate_finalize (GObject *obj)
g_assert (!self->pv->key);
g_free (self->pv->data);
g_free (self->pv->label);
- asn1_delete_structure (&self->pv->asn1);
+ egg_asn1x_destroy (self->pv->asn1);
G_OBJECT_CLASS (gkm_certificate_parent_class)->finalize (obj);
}
@@ -527,7 +520,7 @@ static gboolean
gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, const guchar *data, gsize n_data)
{
GkmCertificate *self = GKM_CERTIFICATE (base);
- ASN1_TYPE asn1 = ASN1_TYPE_EMPTY;
+ GNode *asn1 = NULL;
GkmDataResult res;
guchar *copy, *keydata;
gsize n_keydata;
@@ -549,7 +542,7 @@ gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, const guchar
}
/* Generate a raw public key from our certificate */
- keydata = egg_asn1_encode (asn1, "tbsCertificate.subjectPublicKeyInfo", &n_keydata, NULL);
+ keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL, &n_keydata);
g_return_val_if_fail (keydata, FALSE);
/* Now create us a nice public key with that identifier */
@@ -581,7 +574,7 @@ gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, const guchar
case GKM_DATA_LOCKED:
g_warning ("couldn't parse certificate key data");
g_free (copy);
- asn1_delete_structure (&asn1);
+ egg_asn1x_destroy (asn1);
return FALSE;
default:
@@ -593,7 +586,7 @@ gkm_certificate_real_load (GkmSerializable *base, GkmSecret *login, const guchar
self->pv->data = copy;
self->pv->n_data = n_data;
- asn1_delete_structure (&self->pv->asn1);
+ egg_asn1x_destroy (self->pv->asn1);
self->pv->asn1 = asn1;
return TRUE;
@@ -679,8 +672,6 @@ const guchar*
gkm_certificate_get_extension (GkmCertificate *self, GQuark oid,
gsize *n_extension, gboolean *critical)
{
- const guchar *result;
- gchar *name;
guchar *val;
gsize n_val;
gint index;
@@ -696,9 +687,8 @@ gkm_certificate_get_extension (GkmCertificate *self, GQuark oid,
/* Read the critical status */
if (critical) {
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.critical", index);
- val = egg_asn1_read_value (self->pv->asn1, name, &n_val, NULL);
- g_free (name);
+ val = egg_asn1x_get_string_as_raw (egg_asn1x_node (self->pv->asn1, "tbsCertificate",
+ "extensions", index, "critical", NULL), NULL, &n_val);
/*
* We're pretty liberal in what we accept as critical. The goal
@@ -713,12 +703,8 @@ gkm_certificate_get_extension (GkmCertificate *self, GQuark oid,
}
/* And the extension value */
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnValue", index);
- result = egg_asn1_read_content (self->pv->asn1, self->pv->data, self->pv->n_data,
- name, n_extension);
- g_free (name);
-
- return result;
+ return egg_asn1x_get_raw_value (egg_asn1x_node (self->pv->asn1, "tbsCertificate",
+ "extensions", index, "extnValue", NULL), n_extension);
}
const gchar*
@@ -732,11 +718,11 @@ gkm_certificate_get_label (GkmCertificate *self)
g_return_val_if_fail (self->pv->asn1, "");
/* Look for the CN in the certificate */
- label = egg_dn_read_part (self->pv->asn1, "tbsCertificate.subject.rdnSequence", "cn");
+ label = egg_dn_read_part (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", "rdnSequence", NULL), "cn");
/* Otherwise use the full DN */
if (!label)
- label = egg_dn_read (self->pv->asn1, "tbsCertificate.subject.rdnSequence");
+ label = egg_dn_read (egg_asn1x_node (self->pv->asn1, "tbsCertificate", "subject", "rdnSequence", NULL));
if (!label)
label = g_strdup (_("Unnamed Certificate"));
diff --git a/pkcs11/gkm/gkm-data-asn1.c b/pkcs11/gkm/gkm-data-asn1.c
index 4a6bd7b..6641395 100644
--- a/pkcs11/gkm/gkm-data-asn1.c
+++ b/pkcs11/gkm/gkm-data-asn1.c
@@ -25,40 +25,24 @@
#include "gkm-data-asn1.h"
-gboolean
-gkm_data_asn1_read_mpi (ASN1_TYPE asn, const gchar *part, gcry_mpi_t *mpi)
-{
- gcry_error_t gcry;
- gsize sz;
- guchar *buf;
-
- buf = egg_asn1_read_value (asn, part, &sz, (EggAllocator)g_realloc);
- if (!buf)
- return FALSE;
-
- gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_STD, buf, sz, &sz);
- g_free (buf);
-
- if (gcry != 0)
- return FALSE;
-
- return TRUE;
-}
+#include "egg/egg-asn1x.h"
gboolean
-gkm_data_asn1_read_secure_mpi (ASN1_TYPE asn, const gchar *part, gcry_mpi_t *mpi)
+gkm_data_asn1_read_mpi (GNode *asn, gcry_mpi_t *mpi)
{
gcry_error_t gcry;
gsize sz;
- guchar *buf;
+ const guchar *buf;
+
+ g_return_val_if_fail (asn, FALSE);
+ g_return_val_if_fail (mpi, FALSE);
- buf = egg_asn1_read_value (asn, part, &sz, (EggAllocator)gcry_realloc);
+ buf = egg_asn1x_get_raw_value (asn, &sz);
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);
- gcry_free (buf);
-
if (gcry != 0)
return FALSE;
@@ -66,16 +50,14 @@ gkm_data_asn1_read_secure_mpi (ASN1_TYPE asn, const gchar *part, gcry_mpi_t *mpi
}
gboolean
-gkm_data_asn1_write_mpi (ASN1_TYPE asn, const gchar *part, gcry_mpi_t mpi)
+gkm_data_asn1_write_mpi (GNode *asn, gcry_mpi_t mpi)
{
gcry_error_t gcry;
gsize len;
guchar *buf;
- int res;
- g_assert (asn);
- g_assert (part);
- g_assert (mpi);
+ g_return_val_if_fail (asn, FALSE);
+ g_return_val_if_fail (mpi, FALSE);
/* Get the size */
gcry = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &len, mpi);
@@ -87,11 +69,5 @@ gkm_data_asn1_write_mpi (ASN1_TYPE asn, const gchar *part, gcry_mpi_t mpi)
gcry = gcry_mpi_print (GCRYMPI_FMT_STD, buf, len, &len, mpi);
g_return_val_if_fail (gcry == 0, FALSE);
- res = asn1_write_value (asn, part, buf, len);
- gcry_free (buf);
-
- if (res != ASN1_SUCCESS)
- return FALSE;
-
- return TRUE;
+ return egg_asn1x_set_integer_as_raw (asn, buf, len, gcry_free);
}
diff --git a/pkcs11/gkm/gkm-data-asn1.h b/pkcs11/gkm/gkm-data-asn1.h
index 77886d2..3fe9d6b 100644
--- a/pkcs11/gkm/gkm-data-asn1.h
+++ b/pkcs11/gkm/gkm-data-asn1.h
@@ -24,16 +24,13 @@
#ifndef GKM_DATA_ASN_H_
#define GKM_DATA_ASN_H_
-#include "egg/egg-asn1.h"
+#include <glib.h>
#include <gcrypt.h>
-gboolean gkm_data_asn1_read_mpi (ASN1_TYPE asn, const gchar *part,
+gboolean gkm_data_asn1_read_mpi (GNode *asn,
gcry_mpi_t *mpi);
-gboolean gkm_data_asn1_read_secure_mpi (ASN1_TYPE asn, const gchar *part,
- gcry_mpi_t *mpi);
-
-gboolean gkm_data_asn1_write_mpi (ASN1_TYPE asn, const gchar *part,
+gboolean gkm_data_asn1_write_mpi (GNode *asn,
gcry_mpi_t mpi);
#endif /*GKM_DATA_ASN_H_*/
diff --git a/pkcs11/gkm/gkm-data-der.c b/pkcs11/gkm/gkm-data-der.c
index e2a5403..dbfef24 100644
--- a/pkcs11/gkm/gkm-data-der.c
+++ b/pkcs11/gkm/gkm-data-der.c
@@ -28,6 +28,8 @@
#include "gkm-data-types.h"
#include "gkm-sexp.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
#include "egg/egg-secure-memory.h"
#include "egg/egg-symkey.h"
@@ -77,20 +79,20 @@ GkmDataResult
gkm_data_der_read_public_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t n, e;
int res;
n = e = NULL;
- asn = egg_asn1_decode ("PK.RSAPublicKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
- if (!gkm_data_asn1_read_mpi (asn, "modulus", &n) ||
- !gkm_data_asn1_read_mpi (asn, "publicExponent", &e))
+ if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "modulus", NULL), &n) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "publicExponent", NULL), &e))
goto done;
res = gcry_sexp_build (s_key, NULL, SEXP_PUBLIC_RSA, n, e);
@@ -101,8 +103,7 @@ gkm_data_der_read_public_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (n);
gcry_mpi_release (e);
@@ -128,34 +129,34 @@ gkm_data_der_read_private_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
gcry_mpi_t n, e, d, p, q, u;
gcry_mpi_t tmp;
- guint version;
+ gulong version;
+ GNode *asn = NULL;
int res;
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
n = e = d = p = q = u = NULL;
- asn = egg_asn1_decode ("PK.RSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
- if (!egg_asn1_read_uint (asn, "version", &version))
+ if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
goto done;
/* We only support simple version */
if (version != 0) {
ret = GKM_DATA_UNRECOGNIZED;
- g_message ("unsupported version of RSA key: %u", version);
+ g_message ("unsupported version of RSA key: %lu", version);
goto done;
}
- if (!gkm_data_asn1_read_secure_mpi (asn, "modulus", &n) ||
- !gkm_data_asn1_read_secure_mpi (asn, "publicExponent", &e) ||
- !gkm_data_asn1_read_secure_mpi (asn, "privateExponent", &d) ||
- !gkm_data_asn1_read_secure_mpi (asn, "prime1", &p) ||
- !gkm_data_asn1_read_secure_mpi (asn, "prime2", &q) ||
- !gkm_data_asn1_read_secure_mpi (asn, "coefficient", &u))
+ if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "modulus", NULL), &n) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "publicExponent", NULL), &e) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "privateExponent", NULL), &d) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "prime1", NULL), &p) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "prime2", NULL), &q) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "coefficient", NULL), &u))
goto done;
/* Fix up the incoming key so gcrypt likes it */
@@ -177,8 +178,7 @@ gkm_data_der_read_private_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (n);
gcry_mpi_release (e);
gcry_mpi_release (d);
@@ -204,22 +204,22 @@ GkmDataResult
gkm_data_der_read_public_key_dsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t p, q, g, y;
int res;
p = q = g = y = NULL;
- asn = egg_asn1_decode ("PK.DSAPublicKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPublicKey", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
- if (!gkm_data_asn1_read_mpi (asn, "p", &p) ||
- !gkm_data_asn1_read_mpi (asn, "q", &q) ||
- !gkm_data_asn1_read_mpi (asn, "g", &g) ||
- !gkm_data_asn1_read_mpi (asn, "Y", &y))
+ if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "p", NULL), &p) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "q", NULL), &q) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "g", NULL), &g) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "Y", NULL), &y))
goto done;
res = gcry_sexp_build (s_key, NULL, SEXP_PUBLIC_DSA, p, q, g, y);
@@ -230,8 +230,7 @@ gkm_data_der_read_public_key_dsa (const guchar *data, gsize n_data, gcry_sexp_t
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -250,25 +249,25 @@ gkm_data_der_read_public_key_dsa_parts (const guchar *keydata, gsize n_keydata,
{
gcry_mpi_t p, q, g, y;
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
- ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
- ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
+ GNode *asn_params = NULL;
+ GNode *asn_key = NULL;
int res;
p = q = g = y = NULL;
- asn_params = egg_asn1_decode ("PK.DSAParameters", params, n_params);
- asn_key = egg_asn1_decode ("PK.DSAPublicPart", keydata, n_keydata);
+ 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);
if (!asn_params || !asn_key)
goto done;
ret = GKM_DATA_FAILURE;
- if (!gkm_data_asn1_read_mpi (asn_params, "p", &p) ||
- !gkm_data_asn1_read_mpi (asn_params, "q", &q) ||
- !gkm_data_asn1_read_mpi (asn_params, "g", &g))
+ if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "p", NULL), &p) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "q", NULL), &q) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "g", NULL), &g))
goto done;
- if (!gkm_data_asn1_read_mpi (asn_key, "", &y))
+ if (!gkm_data_asn1_read_mpi (asn_key, &y))
goto done;
res = gcry_sexp_build (s_key, NULL, SEXP_PUBLIC_DSA, p, q, g, y);
@@ -279,10 +278,8 @@ gkm_data_der_read_public_key_dsa_parts (const guchar *keydata, gsize n_keydata,
ret = GKM_DATA_SUCCESS;
done:
- if (asn_key)
- asn1_delete_structure (&asn_key);
- if (asn_params)
- asn1_delete_structure (&asn_params);
+ egg_asn1x_destroy (asn_key);
+ egg_asn1x_destroy (asn_params);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -309,21 +306,21 @@ gkm_data_der_read_private_key_dsa (const guchar *data, gsize n_data, gcry_sexp_t
gcry_mpi_t p, q, g, y, x;
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
int res;
- ASN1_TYPE asn;
+ GNode *asn = NULL;
p = q = g = y = x = NULL;
- asn = egg_asn1_decode ("PK.DSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
- if (!gkm_data_asn1_read_secure_mpi (asn, "p", &p) ||
- !gkm_data_asn1_read_secure_mpi (asn, "q", &q) ||
- !gkm_data_asn1_read_secure_mpi (asn, "g", &g) ||
- !gkm_data_asn1_read_secure_mpi (asn, "Y", &y) ||
- !gkm_data_asn1_read_secure_mpi (asn, "priv", &x))
+ if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "p", NULL), &p) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "q", NULL), &q) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "g", NULL), &g) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "Y", NULL), &y) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn, "priv", NULL), &x))
goto done;
res = gcry_sexp_build (s_key, NULL, SEXP_PRIVATE_DSA, p, q, g, y, x);
@@ -334,8 +331,7 @@ gkm_data_der_read_private_key_dsa (const guchar *data, gsize n_data, gcry_sexp_t
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -356,24 +352,24 @@ gkm_data_der_read_private_key_dsa_parts (const guchar *keydata, gsize n_keydata,
gcry_mpi_t p, q, g, y, x;
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
int res;
- ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
- ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
+ GNode *asn_params = NULL;
+ GNode *asn_key = NULL;
p = q = g = y = x = NULL;
- asn_params = egg_asn1_decode ("PK.DSAParameters", params, n_params);
- asn_key = egg_asn1_decode ("PK.DSAPrivatePart", keydata, n_keydata);
+ 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);
if (!asn_params || !asn_key)
goto done;
ret = GKM_DATA_FAILURE;
- if (!gkm_data_asn1_read_secure_mpi (asn_params, "p", &p) ||
- !gkm_data_asn1_read_secure_mpi (asn_params, "q", &q) ||
- !gkm_data_asn1_read_secure_mpi (asn_params, "g", &g))
+ if (!gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "p", NULL), &p) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "q", NULL), &q) ||
+ !gkm_data_asn1_read_mpi (egg_asn1x_node (asn_params, "g", NULL), &g))
goto done;
- if (!gkm_data_asn1_read_secure_mpi (asn_key, "", &x))
+ if (!gkm_data_asn1_read_mpi (asn_key, &x))
goto done;
/* Now we calculate y */
@@ -388,10 +384,8 @@ gkm_data_der_read_private_key_dsa_parts (const guchar *keydata, gsize n_keydata,
ret = GKM_DATA_SUCCESS;
done:
- if (asn_key)
- asn1_delete_structure (&asn_key);
- if (asn_params)
- asn1_delete_structure (&asn_params);
+ egg_asn1x_destroy (asn_key);
+ egg_asn1x_destroy (asn_params);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -421,40 +415,40 @@ gkm_data_der_read_public_key_info (const guchar* data, gsize n_data, gcry_sexp_t
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
GQuark oid;
- ASN1_TYPE asn;
- gsize n_key, n_params;
+ GNode *asn = NULL;
+ gsize n_params;
+ guint n_bits;
const guchar *params;
guchar *key = NULL;
init_quarks ();
- asn = egg_asn1_decode ("PKIX1.SubjectPublicKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
/* Figure out the algorithm */
- oid = egg_asn1_read_oid (asn, "algorithm.algorithm");
+ oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
if (!oid)
goto done;
/* A bit string so we cannot process in place */
- key = egg_asn1_read_value (asn, "subjectPublicKey", &n_key, NULL);
+ key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
if (!key)
goto done;
- n_key /= 8;
/* An RSA key is simple */
if (oid == OID_PKIX1_RSA) {
- ret = gkm_data_der_read_public_key_rsa (key, n_key, s_key);
+ ret = gkm_data_der_read_public_key_rsa (key, n_bits / 8, s_key);
/* A DSA key paramaters are stored separately */
} else if (oid == OID_PKIX1_DSA) {
- params = egg_asn1_read_element (asn, data, n_data, "algorithm.parameters", &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
if (!params)
goto done;
- ret = gkm_data_der_read_public_key_dsa_parts (key, n_key, params, n_params, s_key);
+ ret = gkm_data_der_read_public_key_dsa_parts (key, n_bits / 8, params, n_params, s_key);
} else {
g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
@@ -463,9 +457,7 @@ gkm_data_der_read_public_key_info (const guchar* data, gsize n_data, gcry_sexp_t
}
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
g_free (key);
if (ret == GKM_DATA_FAILURE)
@@ -489,7 +481,7 @@ gkm_data_der_read_private_key (const guchar *data, gsize n_data, gcry_sexp_t *s_
GkmDataResult
gkm_data_der_read_private_pkcs8_plain (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
GkmDataResult ret;
int algorithm;
GQuark key_algo;
@@ -502,14 +494,14 @@ gkm_data_der_read_private_pkcs8_plain (const guchar *data, gsize n_data, gcry_se
init_quarks ();
- asn = egg_asn1_decode ("PKIX1.pkcs-8-PrivateKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
algorithm = 0;
- key_algo = egg_asn1_read_oid (asn, "privateKeyAlgorithm.algorithm");
+ key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
if (!key_algo)
goto done;
else if (key_algo == OID_PKIX1_RSA)
@@ -522,12 +514,12 @@ gkm_data_der_read_private_pkcs8_plain (const guchar *data, gsize n_data, gcry_se
goto done;
}
- keydata = egg_asn1_read_content (asn, data, n_data, "privateKey", &n_keydata);
+ keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
if (!keydata)
goto done;
- params = egg_asn1_read_element (asn, data, n_data, "privateKeyAlgorithm.parameters",
- &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
+ &n_params);
ret = GKM_DATA_SUCCESS;
@@ -556,9 +548,7 @@ done:
g_message ("invalid PKCS#8 key");
}
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -566,7 +556,7 @@ GkmDataResult
gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const gchar *password,
gsize n_password, gcry_sexp_t *s_key)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_cipher_hd_t cih = NULL;
gcry_error_t gcry;
GkmDataResult ret, r;
@@ -580,18 +570,18 @@ gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const
ret = GKM_DATA_UNRECOGNIZED;
- asn = egg_asn1_decode ("PKIX1.pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
/* Figure out the type of encryption */
- scheme = egg_asn1_read_oid (asn, "encryptionAlgorithm.algorithm");
+ scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
if (!scheme)
goto done;
- params = egg_asn1_read_element (asn, data, n_data, "encryptionAlgorithm.parameters", &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
if (!params)
goto done;
@@ -607,7 +597,8 @@ gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const
goto done;
}
- crypted = egg_asn1_read_value (asn, "encryptedData", &n_crypted, (EggAllocator)egg_secure_realloc);
+ crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL),
+ egg_secure_realloc, &n_crypted);
if (!crypted)
goto done;
@@ -621,7 +612,7 @@ gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const
}
/* Unpad the DER data */
- l = egg_asn1_element_length (crypted, n_crypted);
+ l = egg_asn1x_element_length (crypted, n_crypted);
if (l <= 0 || l > n_crypted) {
ret = GKM_DATA_LOCKED;
goto done;
@@ -640,8 +631,7 @@ gkm_data_der_read_private_pkcs8_crypted (const guchar *data, gsize n_data, const
done:
if (cih)
gcry_cipher_close (cih);
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
egg_secure_free (crypted);
return ret;
@@ -663,30 +653,27 @@ gkm_data_der_read_private_pkcs8 (const guchar *data, gsize n_data, const gchar *
guchar*
gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t n, e;
guchar *result = NULL;
- int res;
n = e = NULL;
- res = asn1_create_element (egg_asn1_get_pk_asn1type (),
- "PK.RSAPublicKey", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pk_asn1_tab, "RSAPublicKey");
+ g_return_val_if_fail (asn, NULL);
if (!gkm_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
!gkm_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL))
goto done;
- if (!gkm_data_asn1_write_mpi (asn, "modulus", n) ||
- !gkm_data_asn1_write_mpi (asn, "publicExponent", e))
+ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "modulus", NULL), n) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e))
goto done;
- result = egg_asn1_encode (asn, "", len, NULL);
+ result = egg_asn1x_encode (asn, NULL, len);
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (n);
gcry_mpi_release (e);
@@ -696,16 +683,14 @@ done:
guchar*
gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t n, e, d, p, q, u, e1, e2, tmp;
guchar *result = NULL;
- int res;
n = e = d = p = q = u = e1 = e2 = tmp = NULL;
- res = asn1_create_element (egg_asn1_get_pk_asn1type (),
- "PK.RSAPrivateKey", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pk_asn1_tab, "RSAPrivateKey");
+ g_return_val_if_fail (asn, NULL);
if (!gkm_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
!gkm_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
@@ -715,16 +700,12 @@ gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
!gkm_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
goto done;
- if (!gkm_data_asn1_write_mpi (asn, "modulus", n) ||
- !gkm_data_asn1_write_mpi (asn, "publicExponent", e) ||
- !gkm_data_asn1_write_mpi (asn, "privateExponent", d) ||
- !gkm_data_asn1_write_mpi (asn, "prime1", p) ||
- !gkm_data_asn1_write_mpi (asn, "prime2", q) ||
- !gkm_data_asn1_write_mpi (asn, "coefficient", u))
- goto done;
-
- /* Have to write out a null to delete OPTIONAL */
- if (!egg_asn1_write_value (asn, "otherPrimeInfos", NULL, 0))
+ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "modulus", NULL), n) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "privateExponent", NULL), d) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime1", NULL), p) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime2", NULL), q) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "coefficient", NULL), u))
goto done;
/* Calculate e1 and e2 */
@@ -737,19 +718,18 @@ gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
gcry_mpi_mod (e2, d, tmp);
/* Write out calculated */
- if (!gkm_data_asn1_write_mpi (asn, "exponent1", e1) ||
- !gkm_data_asn1_write_mpi (asn, "exponent2", e2))
+ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent1", NULL), e1) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent2", NULL), e2))
goto done;
/* Write out the version */
- if (!egg_asn1_write_uint (asn, "version", 0))
+ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
goto done;
- result = egg_asn1_encode (asn, "", n_key, NULL);
+ result = egg_asn1x_encode (asn, egg_secure_realloc, n_key);
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (n);
gcry_mpi_release (e);
gcry_mpi_release (d);
@@ -767,16 +747,14 @@ done:
guchar*
gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t p, q, g, y;
guchar *result = NULL;
- int res;
p = q = g = y = NULL;
- res = asn1_create_element (egg_asn1_get_pk_asn1type (),
- "PK.DSAPublicKey", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicKey");
+ g_return_val_if_fail (asn, NULL);
if (!gkm_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
!gkm_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
@@ -784,20 +762,19 @@ gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
!gkm_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL))
goto done;
- if (!gkm_data_asn1_write_mpi (asn, "p", p) ||
- !gkm_data_asn1_write_mpi (asn, "q", q) ||
- !gkm_data_asn1_write_mpi (asn, "g", g) ||
- !gkm_data_asn1_write_mpi (asn, "Y", y))
+ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "p", NULL), p) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "q", NULL), q) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "Y", NULL), y))
goto done;
- if (!egg_asn1_write_uint (asn, "version", 0))
+ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
goto done;
- result = egg_asn1_encode (asn, "", len, NULL);
+ result = egg_asn1x_encode (asn, NULL, len);
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -809,28 +786,25 @@ done:
guchar*
gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t x;
guchar *result = NULL;
- int res;
x = NULL;
- res = asn1_create_element (egg_asn1_get_pk_asn1type (),
- "PK.DSAPrivatePart", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pk_asn1_tab, "DSAPrivatePart");
+ g_return_val_if_fail (asn, NULL);
if (!gkm_sexp_extract_mpi (skey, &x, "dsa", "x", NULL))
goto done;
- if (!gkm_data_asn1_write_mpi (asn, "", x))
+ if (!gkm_data_asn1_write_mpi (asn, x))
goto done;
- result = egg_asn1_encode (asn, "", n_key, NULL);
+ result = egg_asn1x_encode (asn, egg_secure_realloc, n_key);
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (x);
return result;
@@ -839,32 +813,29 @@ done:
guchar*
gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t p, q, g;
guchar *result = NULL;
- int res;
p = q = g = NULL;
- res = asn1_create_element (egg_asn1_get_pk_asn1type (),
- "PK.DSAParameters", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters");
+ g_return_val_if_fail (asn, NULL);
if (!gkm_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) ||
!gkm_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) ||
!gkm_sexp_extract_mpi (skey, &g, "dsa", "g", NULL))
goto done;
- if (!gkm_data_asn1_write_mpi (asn, "p", p) ||
- !gkm_data_asn1_write_mpi (asn, "q", q) ||
- !gkm_data_asn1_write_mpi (asn, "g", g))
+ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "p", NULL), p) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "q", NULL), q) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g))
goto done;
- result = egg_asn1_encode (asn, "", n_params, NULL);
+ result = egg_asn1x_encode (asn, egg_secure_realloc, n_params);
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -875,16 +846,14 @@ done:
guchar*
gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
{
- ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+ GNode *asn = NULL;
gcry_mpi_t p, q, g, y, x;
guchar *result = NULL;
- int res;
p = q = g = y = x = NULL;
- res = asn1_create_element (egg_asn1_get_pk_asn1type (),
- "PK.DSAPrivateKey", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pk_asn1_tab, "DSAPrivateKey");
+ g_return_val_if_fail (asn, NULL);
if (!gkm_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
!gkm_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
@@ -893,21 +862,20 @@ gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
!gkm_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL))
goto done;
- if (!gkm_data_asn1_write_mpi (asn, "p", p) ||
- !gkm_data_asn1_write_mpi (asn, "q", q) ||
- !gkm_data_asn1_write_mpi (asn, "g", g) ||
- !gkm_data_asn1_write_mpi (asn, "Y", y) ||
- !gkm_data_asn1_write_mpi (asn, "priv", x))
+ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "p", NULL), p) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "q", NULL), q) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "Y", NULL), y) ||
+ !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "priv", NULL), x))
goto done;
- if (!egg_asn1_write_uint (asn, "version", 0))
+ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
goto done;
- result = egg_asn1_encode (asn, "", len, NULL);
+ result = egg_asn1x_encode (asn, egg_secure_realloc, len);
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
gcry_mpi_release (p);
gcry_mpi_release (q);
gcry_mpi_release (g);
@@ -964,16 +932,16 @@ gkm_data_der_write_private_key (gcry_sexp_t s_key, gsize *len)
}
static gcry_cipher_hd_t
-prepare_and_encode_pkcs8_cipher (ASN1_TYPE asn, const gchar *password,
+prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password,
gsize n_password, gsize *n_block)
{
- ASN1_TYPE asn1_params;
+ GNode *asn1_params = NULL;
gcry_cipher_hd_t cih;
guchar salt[8];
gcry_error_t gcry;
guchar *key, *iv, *portion;
gsize n_key, n_portion;
- int iterations, res;
+ int iterations;
init_quarks ();
@@ -982,8 +950,8 @@ prepare_and_encode_pkcs8_cipher (ASN1_TYPE asn, const gchar *password,
GCRYCTL_TEST_ALGO, NULL, 0), NULL);
/* The encryption algorithm */
- if(!egg_asn1_write_oid (asn, "encryptionAlgorithm.algorithm",
- OID_PKCS12_PBE_3DES_SHA1))
+ if(!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL),
+ OID_PKCS12_PBE_3DES_SHA1))
g_return_val_if_reached (NULL);
/* Randomize some input for the password based secret */
@@ -1001,19 +969,18 @@ prepare_and_encode_pkcs8_cipher (ASN1_TYPE asn, const gchar *password,
g_return_val_if_reached (NULL);
/* Now write out the parameters */
- res = asn1_create_element (egg_asn1_get_pkix_asn1type (),
- "PKIX1.pkcs-12-PbeParams", &asn1_params);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
- if (!egg_asn1_write_value (asn1_params, "salt", salt, sizeof (salt)))
+ asn1_params = egg_asn1x_create (pkix_asn1_tab, "pkcs-12-PbeParams");
+ g_return_val_if_fail (asn1_params, NULL);
+ if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn1_params, "salt", NULL), salt, sizeof (salt), NULL))
g_return_val_if_reached (NULL);
- if (!egg_asn1_write_uint (asn1_params, "iterations", iterations))
+ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn1_params, "iterations", NULL), iterations))
g_return_val_if_reached (NULL);
- portion = egg_asn1_encode (asn1_params, "", &n_portion, NULL);
+ portion = egg_asn1x_encode (asn1_params, NULL, &n_portion);
g_return_val_if_fail (portion, NULL);
- if (!egg_asn1_write_value (asn, "encryptionAlgorithm.parameters", portion, n_portion))
+ if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL),
+ portion, n_portion, g_free))
g_return_val_if_reached (NULL);
- g_free (portion);
/* Now make a cipher that matches what we wrote out */
gcry = gcry_cipher_open (&cih, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
@@ -1025,7 +992,7 @@ prepare_and_encode_pkcs8_cipher (ASN1_TYPE asn, const gchar *password,
g_free (iv);
egg_secure_free (key);
- asn1_delete_structure (&asn1_params);
+ egg_asn1x_destroy (asn1_params);
return cih;
}
@@ -1033,8 +1000,8 @@ prepare_and_encode_pkcs8_cipher (ASN1_TYPE asn, const gchar *password,
guchar*
gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
{
- ASN1_TYPE asn;
- int res, algorithm;
+ GNode *asn = NULL;
+ int algorithm;
gboolean is_priv;
GQuark oid;
guchar *params, *key, *data;
@@ -1047,12 +1014,11 @@ gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
g_return_val_if_reached (NULL);
g_return_val_if_fail (is_priv == TRUE, NULL);
- res = asn1_create_element (egg_asn1_get_pkix_asn1type (),
- "PKIX1.pkcs-8-PrivateKeyInfo", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo");
+ g_return_val_if_fail (asn, NULL);
/* Write out the version */
- if (!egg_asn1_write_uint (asn, "version", 0))
+ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0))
g_return_val_if_reached (NULL);
/* Per algorithm differences */
@@ -1079,28 +1045,25 @@ gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
};
/* Write out the algorithm */
- if (!egg_asn1_write_oid (asn, "privateKeyAlgorithm.algorithm", oid))
+ if (!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL), oid))
g_return_val_if_reached (NULL);
/* Write out the parameters */
- if (!egg_asn1_write_value (asn, "privateKeyAlgorithm.parameters", params, n_params))
- g_return_val_if_reached (NULL);
- egg_secure_free (params);
+ if (params) {
+ if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL),
+ params, n_params, egg_secure_free))
+ g_return_val_if_reached (NULL);
+ }
/* Write out the key portion */
- if (!egg_asn1_write_value (asn, "privateKey", key, n_key))
- g_return_val_if_reached (NULL);
- egg_secure_free (key);
-
- /* Add an empty attributes field */
- if (!egg_asn1_write_value (asn, "attributes", NULL, 0))
+ if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "privateKey", NULL),
+ key, n_key, egg_secure_free))
g_return_val_if_reached (NULL);
- data = egg_asn1_encode (asn, "", n_data, NULL);
+ data = egg_asn1x_encode (asn, egg_secure_realloc, n_data);
g_return_val_if_fail (data, NULL);
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
return data;
}
@@ -1110,17 +1073,17 @@ gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *passwor
{
gcry_error_t gcry;
gcry_cipher_hd_t cih;
- ASN1_TYPE asn;
- int res;
+ GNode *asn = NULL;
guchar *key, *data;
gsize n_key, block = 0;
/* Encode the key in normal pkcs8 fashion */
key = gkm_data_der_write_private_pkcs8_plain (skey, &n_key);
+ if (key == NULL)
+ return NULL;
- res = asn1_create_element (egg_asn1_get_pkix_asn1type (),
- "PKIX1.pkcs-8-EncryptedPrivateKeyInfo", &asn);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo");
+ g_return_val_if_fail (asn, NULL);
/* Create a and write out a cipher used for encryption */
cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block);
@@ -1134,7 +1097,7 @@ gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *passwor
pad = block - (n_key % block);
if (pad == 0)
pad = block;
- padded = g_realloc (key, n_key + pad);
+ padded = egg_secure_realloc (key, n_key + pad);
memset (padded + n_key, pad, pad);
key = padded;
n_key += pad;
@@ -1145,14 +1108,14 @@ gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *passwor
gcry_cipher_close (cih);
- res = asn1_write_value (asn, "encryptedData", key, n_key);
- g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+ if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL),
+ key, n_key, egg_secure_free))
+ g_return_val_if_reached (NULL);
- data = egg_asn1_encode (asn, "", n_data, NULL);
+ data = egg_asn1x_encode (asn, NULL, n_data);
g_return_val_if_fail (data, NULL);
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
return data;
}
@@ -1161,9 +1124,9 @@ gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *passwor
*/
GkmDataResult
-gkm_data_der_read_certificate (const guchar *data, gsize n_data, ASN1_TYPE *asn1)
+gkm_data_der_read_certificate (const guchar *data, gsize n_data, GNode **asn1)
{
- *asn1 = egg_asn1_decode ("PKIX1.Certificate", data, n_data);
+ *asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
if (!*asn1)
return GKM_DATA_UNRECOGNIZED;
@@ -1175,33 +1138,38 @@ gkm_data_der_read_basic_constraints (const guchar *data, gsize n_data,
gboolean *is_ca, gint *path_len)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
- ASN1_TYPE asn;
- guint value;
+ GNode *asn = NULL;
+ GNode *node;
+ gulong value;
- asn = egg_asn1_decode ("PKIX1.BasicConstraints", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
if (path_len) {
- if (!egg_asn1_read_uint (asn, "pathLenConstraint", &value))
+ node = egg_asn1x_node (asn, "pathLenConstraint", NULL);
+ if (!egg_asn1x_have (node))
*path_len = -1;
+ else if (!egg_asn1x_get_integer_as_ulong (node, &value))
+ goto done;
else
*path_len = value;
}
if (is_ca) {
- if (!egg_asn1_read_boolean (asn, "cA", is_ca))
+ node = egg_asn1x_node (asn, "cA", NULL);
+ if (!egg_asn1x_have (node))
*is_ca = FALSE;
+ else if (!egg_asn1x_get_boolean (node, is_ca))
+ goto done;
}
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
-
+ egg_asn1x_destroy (asn);
if (ret == GKM_DATA_FAILURE)
g_message ("invalid basic constraints");
@@ -1209,31 +1177,25 @@ done:
}
GkmDataResult
-gkm_data_der_read_key_usage (const guchar *data, gsize n_data, guint *key_usage)
+gkm_data_der_read_key_usage (const guchar *data, gsize n_data, gulong *key_usage)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
- ASN1_TYPE asn;
- guchar buf[4];
- int res, len;
+ GNode *asn = NULL;
+ guint n_bits;
- asn = egg_asn1_decode ("PKIX1.KeyUsage", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "KeyUsage", data, n_data);
if (!asn)
goto done;
ret = GKM_DATA_FAILURE;
- memset (buf, 0, sizeof (buf));
- len = sizeof (buf);
- res = asn1_read_value (asn, "", buf, &len);
- if (res != ASN1_SUCCESS || len < 1 || len > 2)
+ if (!egg_asn1x_get_bits_as_ulong (asn, key_usage, &n_bits))
goto done;
- *key_usage = buf[0] | (buf[1] << 8);
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
return ret;
}
@@ -1241,13 +1203,13 @@ GkmDataResult
gkm_data_der_read_enhanced_usage (const guchar *data, gsize n_data, GQuark **usage_oids)
{
GkmDataResult ret = GKM_DATA_UNRECOGNIZED;
- ASN1_TYPE asn;
- gchar *part;
+ GNode *asn = NULL;
+ GNode *node;
GArray *array;
GQuark oid;
int i;
- asn = egg_asn1_decode ("PKIX1.ExtKeyUsageSyntax", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data, n_data);
if (!asn)
goto done;
@@ -1255,13 +1217,11 @@ gkm_data_der_read_enhanced_usage (const guchar *data, gsize n_data, GQuark **usa
array = g_array_new (TRUE, TRUE, sizeof (GQuark));
for (i = 0; TRUE; ++i) {
- part = g_strdup_printf ("?%d", i + 1);
- oid = egg_asn1_read_oid (asn, part);
- g_free (part);
-
- if (!oid)
+ node = egg_asn1x_node (asn, i + 1, NULL);
+ if (node == NULL)
break;
+ oid = egg_asn1x_get_oid_as_quark (node);
g_array_append_val (array, oid);
}
@@ -1269,17 +1229,16 @@ gkm_data_der_read_enhanced_usage (const guchar *data, gsize n_data, GQuark **usa
ret = GKM_DATA_SUCCESS;
done:
- if (asn)
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
return ret;
}
guchar*
-gkm_data_der_write_certificate (ASN1_TYPE asn1, gsize *n_data)
+gkm_data_der_write_certificate (GNode *asn1, gsize *n_data)
{
g_return_val_if_fail (asn1, NULL);
g_return_val_if_fail (n_data, NULL);
- return egg_asn1_encode (asn1, "", n_data, NULL);
+ return egg_asn1x_encode (asn1, NULL, n_data);
}
diff --git a/pkcs11/gkm/gkm-data-der.h b/pkcs11/gkm/gkm-data-der.h
index f178a95..4a69091 100644
--- a/pkcs11/gkm/gkm-data-der.h
+++ b/pkcs11/gkm/gkm-data-der.h
@@ -30,6 +30,8 @@
#include "gkm-data-types.h"
+#include "egg/egg-asn1x.h"
+
/* -----------------------------------------------------------------------------
* PRIVATE KEYS
*/
@@ -105,17 +107,18 @@ guchar* gkm_data_der_write_public_key (gcry_sexp_t s_key, g
*/
GkmDataResult gkm_data_der_read_certificate (const guchar *data, gsize n_data,
- ASN1_TYPE *asn1);
+ GNode **asn1);
GkmDataResult gkm_data_der_read_basic_constraints (const guchar *data, gsize n_data,
gboolean *is_ca, gint *path_len);
-GkmDataResult gkm_data_der_read_key_usage (const guchar *data, gsize n_data,
- guint *key_usage);
+GkmDataResult gkm_data_der_read_key_usage (const guchar *data,
+ gsize n_data,
+ gulong *key_usage);
GkmDataResult gkm_data_der_read_enhanced_usage (const guchar *data, gsize n_data,
GQuark **oids);
-guchar* gkm_data_der_write_certificate (ASN1_TYPE asn1, gsize *n_data);
+guchar* gkm_data_der_write_certificate (GNode *asn1, gsize *n_data);
#endif /*GKRPKIXDER_H_*/
diff --git a/pkcs11/gkm/tests/unit-test-data-asn1.c b/pkcs11/gkm/tests/unit-test-data-asn1.c
index a7b6021..24c74e8 100644
--- a/pkcs11/gkm/tests/unit-test-data-asn1.c
+++ b/pkcs11/gkm/tests/unit-test-data-asn1.c
@@ -35,56 +35,38 @@
#include <stdio.h>
#include <string.h>
-#define extern
-#include "asn1-def-test.h"
-#undef extern
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
-static ASN1_TYPE asn1_test = NULL;
+#include "asn1-def-test.h"
-static ASN1_TYPE asn1_cert = NULL;
+static GNode *asn1_cert = NULL;
static guchar *data_cert = NULL;
static gsize n_data_cert = 0;
DEFINE_SETUP(asn1_tree)
{
- ASN1_TYPE pkix;
-
- int res = asn1_array2tree (test_asn1_tab, &asn1_test, NULL);
- g_assert (res == ASN1_SUCCESS);
-
- /* -------- */
-
data_cert = testing_data_read ("test-certificate-1.der", &n_data_cert);
-
- /* We'll be catching this error later */
- pkix = egg_asn1_get_pkix_asn1type ();
- if (!pkix) return;
-
- res = asn1_create_element (pkix, "PKIX1.Certificate", &asn1_cert);
- g_assert (res == ASN1_SUCCESS);
-
- res = asn1_der_decoding (&asn1_cert, data_cert, n_data_cert, NULL);
- g_assert (res == ASN1_SUCCESS);
+ asn1_cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data_cert, n_data_cert);
+ g_assert (asn1_cert);
}
DEFINE_TEARDOWN(asn1_tree)
{
- asn1_delete_structure (&asn1_test);
- asn1_delete_structure (&asn1_cert);
+ egg_asn1x_destroy (asn1_cert);
g_free (data_cert);
data_cert = NULL;
}
DEFINE_TEST(asn1_integers)
{
- ASN1_TYPE asn;
+ GNode *asn;
gcry_mpi_t mpi, mpt;
guchar *data;
gsize n_data;
gboolean ret;
- int res;
- res = asn1_create_element (asn1_test, "TEST.TestIntegers", &asn);
+ asn = egg_asn1x_create (test_asn1_tab, "TestIntegers");
g_assert ("asn test structure is null" && asn != NULL);
/* Make a random number */
@@ -93,22 +75,19 @@ DEFINE_TEST(asn1_integers)
gcry_mpi_randomize (mpi, 512, GCRY_WEAK_RANDOM);
/* Write the mpi out */
- ret = gkm_data_asn1_write_mpi (asn, "mpi", mpi);
+ ret = gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "mpi", NULL), mpi);
/* Now encode the whole caboodle */
- data = egg_asn1_encode (asn, "", &n_data, NULL);
+ data = egg_asn1x_encode (asn, NULL, &n_data);
g_assert ("encoding asn1 didn't work" && data != NULL);
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
/* Now decode it all nicely */
- res = asn1_create_element (asn1_test, "TEST.TestIntegers", &asn);
- g_return_if_fail (res == ASN1_SUCCESS);
-
- res = asn1_der_decoding (&asn, data, n_data, NULL);
- g_assert ("decoding asn didn't work" && res == ASN1_SUCCESS);
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data, n_data);
+ g_assert (asn);
- ret = gkm_data_asn1_read_mpi (asn, "mpi", &mpt);
+ 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);
diff --git a/pkcs11/gkm/tests/unit-test-data-der.c b/pkcs11/gkm/tests/unit-test-data-der.c
index 405547c..3825f0f 100644
--- a/pkcs11/gkm/tests/unit-test-data-der.c
+++ b/pkcs11/gkm/tests/unit-test-data-der.c
@@ -30,7 +30,10 @@
#include "gkm/gkm-data-der.h"
#include "gkm/gkm-sexp.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
#include "egg/egg-openssl.h"
+#include "egg/egg-secure-memory.h"
#include <glib.h>
#include <gcrypt.h>
@@ -39,11 +42,11 @@
#include <stdio.h>
#include <string.h>
-static ASN1_TYPE certificate = NULL;
+static GNode *certificate = NULL;
static guchar *certificate_data = NULL;
static gsize n_certificate_data = 0;
-static ASN1_TYPE certificate2 = NULL;
+static GNode *certificate2 = NULL;
static guchar *certificate2_data = NULL;
static gsize n_certificate2_data = 0;
@@ -112,21 +115,21 @@ test_der_public (gcry_sexp_t key)
DEFINE_SETUP(preload)
{
certificate_data = testing_data_read ("test-certificate-1.der", &n_certificate_data);
- certificate = egg_asn1_decode ("PKIX1.Certificate", certificate_data, n_certificate_data);
+ certificate = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", certificate_data, n_certificate_data);
g_assert (certificate);
certificate2_data = testing_data_read ("test-certificate-2.der", &n_certificate2_data);
- certificate2 = egg_asn1_decode ("PKIX1.Certificate", certificate2_data, n_certificate2_data);
+ certificate2 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", certificate2_data, n_certificate2_data);
g_assert (certificate2);
}
DEFINE_TEARDOWN(preload)
{
- asn1_delete_structure (&certificate);
+ egg_asn1x_destroy (certificate);
g_free (certificate_data);
certificate_data = NULL;
- asn1_delete_structure (&certificate2);
+ egg_asn1x_destroy (certificate2);
g_free (certificate2_data);
certificate2_data = NULL;
}
@@ -173,6 +176,8 @@ test_der_private (gcry_sexp_t key)
/* Now compare them */
g_assert ("key parsed differently" && compare_keys (key, sexp));
+
+ egg_secure_free (data);
}
DEFINE_TEST(der_rsa_private)
@@ -221,6 +226,9 @@ DEFINE_TEST(der_dsa_private_parts)
/* Now compare them */
g_assert ("key parsed differently" && compare_keys (skey, pkey));
+
+ egg_secure_free (params);
+ egg_secure_free (key);
}
const gchar *certpub = "(public-key (rsa " \
@@ -236,7 +244,7 @@ DEFINE_TEST(read_public_key_info)
gcry_sexp_t sexp, match;
gcry_error_t gcry;
- data = egg_asn1_read_element (certificate, certificate_data, n_certificate_data, "tbsCertificate.subjectPublicKeyInfo", &n_data);
+ data = egg_asn1x_get_raw_element (egg_asn1x_node (certificate, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_data);
g_assert (data);
res = gkm_data_der_read_public_key_info (data, n_data, &sexp);
@@ -257,14 +265,14 @@ DEFINE_TEST(read_public_key_info)
DEFINE_TEST(read_certificate)
{
- ASN1_TYPE asn = NULL;
+ GNode *asn = NULL;
GkmDataResult res;
res = gkm_data_der_read_certificate (certificate_data, n_certificate_data, &asn);
g_assert (res == GKM_DATA_SUCCESS);
g_assert (asn != NULL);
- asn1_delete_structure (&asn);
+ egg_asn1x_destroy (asn);
}
DEFINE_TEST(write_certificate)
@@ -283,7 +291,7 @@ static void
on_ca_certificate_public_key_info (GQuark type, const guchar *data, gsize n_data,
GHashTable *headers, gpointer user_data)
{
- ASN1_TYPE asn1 = ASN1_TYPE_EMPTY;
+ GNode *asn1 = NULL;
GkmDataResult res;
gpointer keydata;
gsize n_keydata;
@@ -296,7 +304,7 @@ on_ca_certificate_public_key_info (GQuark type, const guchar *data, gsize n_data
g_assert (res == GKM_DATA_SUCCESS);
/* Generate a raw public key from our certificate */
- keydata = egg_asn1_encode (asn1, "tbsCertificate.subjectPublicKeyInfo", &n_keydata, NULL);
+ keydata = egg_asn1x_encode (egg_asn1x_node (asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), NULL, &n_keydata);
g_assert (keydata);
/* Now create us a nice public key with that identifier */
@@ -319,12 +327,11 @@ DEFINE_TEST(read_ca_certificates_public_key_info)
}
static const guchar*
-find_extension (ASN1_TYPE asn, const guchar *data, gsize n_data, const gchar *oid, gsize *n_extension)
+find_extension (GNode *asn, const guchar *data, gsize n_data, const gchar *oid, gsize *n_extension)
{
const guchar *value;
- gsize n_exoid;
- guchar *exoid;
- gchar *name;
+ GNode *node = NULL;
+ gchar *exoid;
guint index;
int len;
@@ -333,19 +340,18 @@ find_extension (ASN1_TYPE asn, const guchar *data, gsize n_data, const gchar *oi
for (index = 1; TRUE; ++index) {
/* Make sure it is present */
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnID", index);
- exoid = egg_asn1_read_value (asn, name, &n_exoid, NULL);
- g_free (name);
-
- if (!exoid)
+ node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, "extnID", NULL);
+ if (node == NULL)
return NULL;
- if (n_exoid - 1 == strlen (oid) && strcmp ((gchar*)exoid, oid) == 0) {
+ exoid = egg_asn1x_get_oid_as_string (node);
+ g_assert (exoid);
+
+ if (strcmp (exoid, oid) == 0) {
g_free (exoid);
- name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnValue", index);
- value = egg_asn1_read_content (asn, data, n_data, name, n_extension);
+ node = egg_asn1x_node (asn, "tbsCertificate", "extensions", index, "extnValue", NULL);
+ value = egg_asn1x_get_raw_value (node, n_extension);
g_assert (value);
- g_free (name);
return value;
}
@@ -363,7 +369,8 @@ DEFINE_TEST(read_basic_constraints)
gint path_len;
GkmDataResult res;
- extension = egg_asn1_read_content (certificate, certificate_data, n_certificate_data, "tbsCertificate.extensions.?1.extnValue", &n_extension);
+ extension = egg_asn1x_get_raw_value (egg_asn1x_node (certificate, "tbsCertificate", "extensions", 1, "extnValue", NULL),
+ &n_extension);
g_assert (extension);
res = gkm_data_der_read_basic_constraints (extension, n_extension, &is_ca, &path_len);
@@ -376,7 +383,7 @@ DEFINE_TEST(read_key_usage)
{
const guchar *extension;
gsize n_extension;
- guint key_usage;
+ gulong key_usage;
GkmDataResult res;
extension = find_extension (certificate2, certificate2_data, n_certificate2_data, "2.5.29.15", &n_extension);
@@ -384,7 +391,7 @@ DEFINE_TEST(read_key_usage)
res = gkm_data_der_read_key_usage (extension, n_extension, &key_usage);
g_assert (res == GKM_DATA_SUCCESS);
- g_assert_cmpuint (key_usage, ==, 0x80);
+ g_assert_cmpuint (key_usage, ==, 0x01);
}
DEFINE_TEST(read_enhanced_usage)
@@ -467,7 +474,7 @@ DEFINE_TEST(write_pkcs8_plain)
g_assert (n_data);
res = gkm_data_der_read_private_pkcs8_plain (data, n_data, &check);
- g_free (data);
+ egg_secure_free (data);
g_assert (res == GKM_DATA_SUCCESS);
g_assert (check);
@@ -486,7 +493,7 @@ DEFINE_TEST(write_pkcs8_plain)
g_assert (n_data);
res = gkm_data_der_read_private_pkcs8_plain (data, n_data, &check);
- g_free (data);
+ egg_secure_free (data);
g_assert (res == GKM_DATA_SUCCESS);
g_assert (check);
diff --git a/pkcs11/ssh-store/gkm-ssh-openssh.c b/pkcs11/ssh-store/gkm-ssh-openssh.c
index 44953ea..c165cd2 100644
--- a/pkcs11/ssh-store/gkm-ssh-openssh.c
+++ b/pkcs11/ssh-store/gkm-ssh-openssh.c
@@ -5,6 +5,7 @@
#include "gkm/gkm-data-der.h"
#include "gkm/gkm-data-types.h"
+#include "egg/egg-asn1x.h"
#include "egg/egg-buffer.h"
#include "egg/egg-openssl.h"
#include "egg/egg-secure-memory.h"
@@ -171,7 +172,7 @@ load_encrypted_key (const guchar *data, gsize n_data, const gchar *dekinfo,
g_assert (decrypted);
/* Unpad the DER data */
- length = egg_asn1_element_length (decrypted, n_decrypted);
+ length = egg_asn1x_element_length (decrypted, n_decrypted);
if (length > 0)
n_decrypted = length;
diff --git a/pkcs11/user-store/gkm-user-private-key.c b/pkcs11/user-store/gkm-user-private-key.c
index 68f8705..eb7d156 100644
--- a/pkcs11/user-store/gkm-user-private-key.c
+++ b/pkcs11/user-store/gkm-user-private-key.c
@@ -35,6 +35,8 @@
#include "gkm/gkm-sexp.h"
#include "gkm/gkm-util.h"
+#include "egg/egg-secure-memory.h"
+
#include <glib/gi18n.h>
enum {
@@ -294,6 +296,7 @@ gkm_user_private_key_real_save (GkmSerializable *base, GkmSecret *login, guchar
const gchar *password;
gsize n_password;
GkmSexp *sexp;
+ guchar *key;
g_return_val_if_fail (GKM_IS_USER_PRIVATE_KEY (self), FALSE);
g_return_val_if_fail (data, FALSE);
@@ -303,11 +306,19 @@ gkm_user_private_key_real_save (GkmSerializable *base, GkmSecret *login, guchar
g_return_val_if_fail (sexp, FALSE);
password = gkm_secret_get_password (login, &n_password);
- if (password == NULL)
- *data = gkm_data_der_write_private_pkcs8_plain (gkm_sexp_get (sexp), n_data);
- else
+ 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);
+ } else {
*data = gkm_data_der_write_private_pkcs8_crypted (gkm_sexp_get (sexp), password,
n_password, n_data);
+ }
gkm_sexp_unref (sexp);
return *data != NULL;
diff --git a/pkcs11/user-store/gkm-user-storage.c b/pkcs11/user-store/gkm-user-storage.c
index 6cd8399..ea97be3 100644
--- a/pkcs11/user-store/gkm-user-storage.c
+++ b/pkcs11/user-store/gkm-user-storage.c
@@ -34,6 +34,8 @@
#include "gkm/gkm-serializable.h"
#include "gkm/gkm-util.h"
+#include "egg/egg-asn1x.h"
+#include "egg/egg-asn1-defs.h"
#include "egg/egg-dn.h"
#include "egg/egg-error.h"
#include "egg/egg-hex.h"
@@ -133,17 +135,17 @@ static int flock(int fd, int operation)
static gchar*
name_for_subject (const guchar *subject, gsize n_subject)
{
- ASN1_TYPE asn;
+ GNode *asn;
gchar *name;
g_assert (subject);
g_assert (n_subject);
- asn = egg_asn1_decode ("PKIX1.Name", subject, n_subject);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Name", subject, n_subject);
g_return_val_if_fail (asn, NULL);
- name = egg_dn_read_part (asn, "rdnSequence", "CN");
- asn1_delete_structure (&asn);
+ name = egg_dn_read_part (egg_asn1x_node (asn, "rdnSequence", NULL), "CN");
+ egg_asn1x_destroy (asn);
return name;
}
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 971184b..ad4e044 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -11,7 +11,6 @@ daemon/gnome-keyring-gpg.desktop.in.in
daemon/gpg-agent/gkd-gpg-agent-ops.c
daemon/login/gkd-login.c
daemon/org.gnome.keyring.service.in
-egg/egg-asn1.c
egg/egg-oid.c
egg/egg-spawn.c
gcr/gcr-certificate-basics-widget.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]