[gcr] gcr: Use GBytes immutable ref counted byte buffers
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcr] gcr: Use GBytes immutable ref counted byte buffers
- Date: Mon, 21 Nov 2011 10:17:58 +0000 (UTC)
commit 97cd79171dfbba24394f070f3946b20c2d518d2d
Author: Stef Walter <stefw collabora co uk>
Date: Wed Nov 16 08:38:44 2011 +0100
gcr: Use GBytes immutable ref counted byte buffers
* Copy from glib patch to EggBytes
* This allows us to reliably build up ASN.1 structures from different
sources, and is needed for the certificate request work.
https://bugzilla.gnome.org/show_bug.cgi?id=663291
egg/Makefile.am | 2 +-
egg/egg-armor.c | 40 ++-
egg/egg-armor.h | 11 +-
egg/egg-asn1x.c | 595 +++++++++++++++++++++++------------
egg/egg-asn1x.h | 80 ++---
egg/egg-byte-array.c | 65 ----
egg/egg-byte-array.h | 33 --
egg/egg-bytes.c | 453 ++++++++++++++++++++++++++
egg/egg-bytes.h | 106 +++++++
egg/egg-dn.c | 79 +++--
egg/egg-dn.h | 8 +-
egg/egg-openssl.c | 82 +++--
egg/egg-openssl.h | 20 +-
egg/egg-symkey.c | 193 +++++++-----
egg/egg-symkey.h | 8 +-
egg/tests/test-asn1.c | 435 ++++++++++++++------------
egg/tests/test-asn1x.c | 17 +-
egg/tests/test-dn.c | 26 ++-
egg/tests/test-openssl.c | 65 +++--
gcr/gcr-certificate-extensions.c | 54 ++--
gcr/gcr-certificate-extensions.h | 20 +-
gcr/gcr-certificate-renderer.c | 141 +++++----
gcr/gcr-certificate.c | 148 ++++++---
gcr/gcr-fingerprint.c | 115 +++++---
gcr/gcr-openpgp.c | 16 +-
gcr/gcr-openpgp.h | 8 +-
gcr/gcr-openssh.c | 35 ++-
gcr/gcr-openssh.h | 8 +-
gcr/gcr-parser.c | 470 +++++++++++++++-------------
gcr/tests/frob-openpgp.c | 29 +-
gcr/tests/test-fingerprint.c | 95 +++---
gcr/tests/test-openpgp.c | 26 +-
gcr/tests/test-openssh.c | 39 ++-
gcr/tests/test-pkcs11-certificate.c | 16 +-
34 files changed, 2233 insertions(+), 1305 deletions(-)
---
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 5eaff47..259d522 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -20,7 +20,7 @@ libegg_la_SOURCES = \
egg-armor.c egg-armor.h \
egg-asn1x.c egg-asn1x.h \
egg-buffer.c egg-buffer.h \
- egg-byte-array.c egg-byte-array.h \
+ egg-bytes.c egg-bytes.h \
egg-dh.c egg-dh.h \
egg-dn.c egg-dn.h \
egg-error.h \
diff --git a/egg/egg-armor.c b/egg/egg-armor.c
index 5a4b047..b82730b 100644
--- a/egg/egg-armor.c
+++ b/egg/egg-armor.c
@@ -269,48 +269,52 @@ egg_armor_headers_new (void)
}
guint
-egg_armor_parse (gconstpointer data,
- gsize n_data,
+egg_armor_parse (EggBytes *data,
EggArmorCallback callback,
gpointer user_data)
{
- const gchar *beg, *end;
+ const gchar *beg, *end, *at;
const gchar *outer_beg, *outer_end;
guint nfound = 0;
guchar *decoded = NULL;
gsize n_decoded = 0;
GHashTable *headers = NULL;
+ EggBytes *dec;
+ EggBytes *outer;
GQuark type;
+ gsize n_at;
- g_return_val_if_fail (data, 0);
- g_return_val_if_fail (n_data, 0);
+ g_return_val_if_fail (data != NULL, 0);
+ at = egg_bytes_get_data (data);
+ n_at = egg_bytes_get_size (data);
- while (n_data > 0) {
+ while (n_at > 0) {
/* This returns the first character after the PEM BEGIN header */
- beg = armor_find_begin ((const gchar*)data, n_data, &type, &outer_beg);
+ beg = armor_find_begin (at, n_at, &type, &outer_beg);
if (beg == NULL)
break;
g_assert (type);
/* This returns the character position before the PEM END header */
- end = armor_find_end ((const gchar*)beg,
- n_data - ((const gchar*)beg - (const gchar *)data),
- type, &outer_end);
+ end = armor_find_end (beg, n_at - (beg - at), type, &outer_end);
if (end == NULL)
break;
if (beg != end) {
if (armor_parse_block (beg, end - beg, &decoded, &n_decoded, &headers)) {
g_assert (outer_end > outer_beg);
- if (callback != NULL)
- (callback) (type,
- decoded, n_decoded,
- outer_beg, outer_end - outer_beg,
- headers, user_data);
+ dec = egg_bytes_new_with_free_func (decoded, n_decoded,
+ egg_secure_free, decoded);
+ if (callback != NULL) {
+ outer = egg_bytes_new_with_free_func (outer_beg, outer_end - outer_beg,
+ egg_bytes_unref, egg_bytes_ref (data));
+ (callback) (type, dec, outer, headers, user_data);
+ egg_bytes_unref (outer);
+ }
+ egg_bytes_unref (dec);
++nfound;
- egg_secure_free (decoded);
if (headers)
g_hash_table_remove_all (headers);
}
@@ -318,8 +322,8 @@ egg_armor_parse (gconstpointer data,
/* Try for another block */
end += ARMOR_SUFF_L;
- n_data -= (const gchar*)end - (const gchar*)data;
- data = end;
+ n_at -= (const gchar*)end - (const gchar*)at;
+ at = end;
}
if (headers)
diff --git a/egg/egg-armor.h b/egg/egg-armor.h
index e0f13d3..586a0d2 100644
--- a/egg/egg-armor.h
+++ b/egg/egg-armor.h
@@ -26,18 +26,17 @@
#include <glib.h>
+#include <egg/egg-bytes.h>
+
typedef void (*EggArmorCallback) (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data);
GHashTable* egg_armor_headers_new (void);
-guint egg_armor_parse (gconstpointer data,
- gsize n_data,
+guint egg_armor_parse (EggBytes *data,
EggArmorCallback callback,
gpointer user_data);
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index f2d4b42..ab862e0 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -107,6 +107,11 @@ enum {
FLAG_RIGHT = (1<<30),
};
+typedef gboolean (*Aencoder) (gpointer data,
+ GNode *node,
+ guchar *buf,
+ gsize n_buf);
+
typedef struct _Aenc Aenc;
typedef struct _Atlv Atlv;
typedef struct _Anode Anode;
@@ -114,8 +119,9 @@ typedef struct _Abuf Abuf;
typedef struct _Abits Abits;
struct _Aenc {
- EggAsn1xEncoder encoder;
+ Aencoder encoder;
gpointer data;
+ GDestroyNotify destroy;
};
struct _Atlv {
@@ -136,9 +142,7 @@ struct _Anode {
Atlv *tlv;
Aenc *enc;
- gpointer user_data;
- GDestroyNotify destroy;
-
+ EggBytes *backing;
gchar* failure;
gint chosen : 1;
@@ -152,13 +156,12 @@ struct _Abuf {
struct _Abits {
guint n_bits;
- guchar *bits;
- GDestroyNotify destroy;
+ EggBytes *bits;
};
/* Forward Declarations */
-static gboolean anode_decode_anything (GNode*, Atlv*);
-static gboolean anode_decode_anything_for_flags (GNode *, Atlv*, gint);
+static gboolean anode_decode_anything (GNode*, EggBytes*, Atlv*);
+static gboolean anode_decode_anything_for_flags (GNode *, EggBytes*, Atlv*, gint);
static gboolean anode_validate_anything (GNode*, gboolean);
static gboolean anode_encode_prepare (GNode*, gboolean want);
@@ -367,17 +370,48 @@ compare_tlvs (Atlv *tlva, Atlv *tlvb)
return la < lb ? -1 : 1;
}
+static inline EggBytes *
+anode_get_backing (GNode *node)
+{
+ Anode *an = node->data;
+ return an->backing;
+}
+
+static inline void
+anode_clr_backing (GNode *node)
+{
+ Anode *an = node->data;
+ if (an->backing)
+ egg_bytes_unref (an->backing);
+ an->backing = NULL;
+}
+
+static inline void
+anode_set_backing (GNode *node,
+ EggBytes *backing)
+{
+ Anode *an = node->data;
+ if (backing)
+ egg_bytes_ref (backing);
+ if (an->backing)
+ egg_bytes_unref (an->backing);
+ an->backing = backing;
+}
+
static void
-anode_set_tlv_data (GNode *node, Atlv *tlv)
+anode_set_tlv_data (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv)
{
Anode *an = node->data;
- g_assert (!an->tlv);
+ g_assert (an->tlv == NULL);
g_assert (tlv->len >= 0);
+ anode_set_backing (node, backing);
an->tlv = g_slice_new0 (Atlv);
memcpy (an->tlv, tlv, sizeof (Atlv));
}
-static Atlv*
+static inline Atlv *
anode_get_tlv_data (GNode *node)
{
Anode *an = node->data;
@@ -398,31 +432,26 @@ anode_clr_enc_data (GNode *node)
{
Anode *an = node->data;
if (an->enc) {
+ if (an->enc->destroy)
+ (an->enc->destroy) (an->enc->data);
g_slice_free (Aenc, an->enc);
an->enc = NULL;
}
}
static void
-anode_set_enc_data (GNode *node, EggAsn1xEncoder encoder, gpointer enc_data)
+anode_set_enc_data (GNode *node,
+ Aencoder encoder,
+ gpointer data,
+ GDestroyNotify destroy)
{
Anode *an = node->data;
g_assert (!an->enc);
an->enc = g_slice_new0 (Aenc);
an->enc->encoder = encoder;
- an->enc->data = enc_data;
-}
-
-static void
-anode_set_user_data (GNode *node, gpointer user_data, GDestroyNotify destroy)
-{
- Anode *an;
- g_assert (node && node->data);
- an = node->data;
- if (an->destroy)
- (an->destroy) (an->user_data);
- an->user_data = user_data;
- an->destroy = destroy;
+ an->enc->data = data;
+ an->enc->destroy = destroy;
+ anode_clr_backing (node);
}
static Aenc*
@@ -462,9 +491,9 @@ static void
anode_clear (GNode *node)
{
Anode *an = node->data;
+ anode_clr_backing (node);
anode_clr_tlv_data (node);
anode_clr_enc_data (node);
- anode_set_user_data (node, NULL, NULL);
g_free (an->failure);
an->failure = NULL;
}
@@ -483,9 +512,9 @@ static void
abits_destroy (gpointer data)
{
Abits *ab = data;
- g_assert (ab);
- if (ab->destroy)
- (ab->destroy) (ab->bits);
+ g_assert (ab != NULL);
+ if (ab->bits)
+ egg_bytes_unref (ab->bits);
g_slice_free (Abits, ab);
}
@@ -826,7 +855,9 @@ anode_decode_tlv_for_contents (Atlv *outer, gboolean first, Atlv *tlv)
}
static gboolean
-anode_decode_choice (GNode *node, Atlv *tlv)
+anode_decode_choice (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv)
{
gboolean have = FALSE;
GNode *child;
@@ -834,7 +865,7 @@ anode_decode_choice (GNode *node, Atlv *tlv)
for (child = node->children; child; child = child->next) {
an = (Anode*)child->data;
- if (!have && anode_decode_anything (child, tlv)) {
+ if (!have && anode_decode_anything (child, backing, tlv)) {
an->chosen = 1;
have = TRUE;
} else {
@@ -882,7 +913,9 @@ anode_decode_struct_any (GNode *node, Atlv *tlv)
}
static gboolean
-anode_decode_sequence_or_set (GNode *node, Atlv *outer)
+anode_decode_sequence_or_set (GNode *node,
+ EggBytes *backing,
+ Atlv *outer)
{
GNode *child;
Atlv tlv;
@@ -902,7 +935,7 @@ anode_decode_sequence_or_set (GNode *node, Atlv *outer)
if (!anode_decode_tlv_for_contents (outer, i == 0, &tlv))
return anode_failure (node, "invalid encoding of child");
- if (!anode_decode_anything (child, &tlv))
+ if (!anode_decode_anything (child, backing, &tlv))
return FALSE;
outer->len = (tlv.end - outer->buf) - outer->off;
@@ -913,7 +946,9 @@ anode_decode_sequence_or_set (GNode *node, Atlv *outer)
}
static gboolean
-anode_decode_sequence_or_set_of (GNode *node, Atlv *outer)
+anode_decode_sequence_or_set_of (GNode *node,
+ EggBytes *backing,
+ Atlv *outer)
{
GNode *child, *other;
Atlv tlv;
@@ -946,7 +981,7 @@ anode_decode_sequence_or_set_of (GNode *node, Atlv *outer)
g_node_append (node, other);
}
- if (!anode_decode_anything (other, &tlv))
+ if (!anode_decode_anything (other, backing, &tlv))
return FALSE;
outer->len = (tlv.end - outer->buf) - outer->off;
@@ -957,7 +992,10 @@ anode_decode_sequence_or_set_of (GNode *node, Atlv *outer)
}
static gboolean
-anode_decode_primitive (GNode *node, Atlv *tlv, gint flags)
+anode_decode_primitive (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv,
+ gint flags)
{
gint type;
@@ -978,18 +1016,18 @@ anode_decode_primitive (GNode *node, Atlv *tlv, gint flags)
case TYPE_NULL:
case TYPE_GENERALSTRING:
case TYPE_TIME:
- anode_set_tlv_data (node, tlv);
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
/* Transparent types */
case TYPE_ANY:
- anode_set_tlv_data (node, tlv);
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
case TYPE_CHOICE:
- if (!anode_decode_choice (node, tlv))
+ if (!anode_decode_choice (node, backing, tlv))
return FALSE;
- anode_set_tlv_data (node, tlv);
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
default:
@@ -1000,7 +1038,10 @@ anode_decode_primitive (GNode *node, Atlv *tlv, gint flags)
}
static gboolean
-anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
+anode_decode_structured (GNode *node,
+ EggBytes *backing,
+ Atlv *tlv,
+ gint flags)
{
gboolean definite;
const guchar *end;
@@ -1020,7 +1061,7 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
if (!anode_decode_tlv_for_contents (tlv, TRUE, &ctlv))
return anode_failure (node, "invalid encoding of child");
flags &= ~FLAG_TAG;
- if (!anode_decode_anything_for_flags (node, &ctlv, flags))
+ if (!anode_decode_anything_for_flags (node, backing, &ctlv, flags))
return FALSE;
/* Use most of the child's tlv */
@@ -1039,7 +1080,7 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
return FALSE;
break;
case TYPE_CHOICE:
- if (!anode_decode_choice (node, tlv))
+ if (!anode_decode_choice (node, backing, tlv))
return FALSE;
break;
case TYPE_GENERALSTRING:
@@ -1049,12 +1090,12 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
break;
case TYPE_SEQUENCE:
case TYPE_SET:
- if (!anode_decode_sequence_or_set (node, tlv))
+ if (!anode_decode_sequence_or_set (node, backing, tlv))
return FALSE;
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
- if (!anode_decode_sequence_or_set_of (node, tlv))
+ if (!anode_decode_sequence_or_set_of (node, backing, tlv))
return FALSE;
break;
default:
@@ -1080,7 +1121,7 @@ anode_decode_structured (GNode *node, Atlv *tlv, gint flags)
g_return_val_if_fail (tlv->buf + tlv->off + tlv->len + off == end, FALSE);
tlv->end = end;
- anode_set_tlv_data (node, tlv);
+ anode_set_tlv_data (node, backing, tlv);
return TRUE;
}
@@ -1099,7 +1140,10 @@ anode_decode_option_or_default (GNode *node, Atlv *tlv, gint flags)
}
static gboolean
-anode_decode_anything_for_flags (GNode *node, Atlv *tlv, gint flags)
+anode_decode_anything_for_flags (GNode *node,
+ EggBytes *bytes,
+ Atlv *tlv,
+ gint flags)
{
gboolean ret;
gulong tag;
@@ -1119,21 +1163,23 @@ anode_decode_anything_for_flags (GNode *node, Atlv *tlv, gint flags)
/* Structured value */
if (tlv->cls & ASN1_CLASS_STRUCTURED)
- ret = anode_decode_structured (node, tlv, flags);
+ ret = anode_decode_structured (node, bytes, tlv, flags);
/* A primitive simple value */
else
- ret = anode_decode_primitive (node, tlv, flags);
+ ret = anode_decode_primitive (node, bytes, tlv, flags);
return ret;
}
static gboolean
-anode_decode_anything (GNode *node, Atlv *tlv)
+anode_decode_anything (GNode *node,
+ EggBytes *bytes,
+ Atlv *tlv)
{
gint flags = anode_def_flags (node);
- if (!anode_decode_anything_for_flags (node, tlv, flags))
+ if (!anode_decode_anything_for_flags (node, bytes, tlv, flags))
return anode_decode_option_or_default (node, tlv, flags);
return TRUE;
@@ -1141,20 +1187,26 @@ anode_decode_anything (GNode *node, Atlv *tlv)
gboolean
egg_asn1x_decode_no_validate (GNode *asn,
- gconstpointer data,
- gsize n_data)
+ EggBytes *data)
{
+ const guchar *dat;
+ gsize size;
Atlv tlv;
+ g_return_val_if_fail (asn != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
+
egg_asn1x_clear (asn);
- if (!anode_decode_tlv_for_data (data, (const guchar*)data + n_data, &tlv))
+ dat = egg_bytes_get_data (data);
+ size = egg_bytes_get_size (data);
+ if (!anode_decode_tlv_for_data (dat, dat + size, &tlv))
return anode_failure (asn, "content is not encoded properly");
- if (!anode_decode_anything (asn, &tlv))
+ if (!anode_decode_anything (asn, data, &tlv))
return FALSE;
- if (tlv.end - tlv.buf != n_data)
+ if (tlv.end - tlv.buf != size)
return FALSE;
return TRUE;
@@ -1162,16 +1214,14 @@ egg_asn1x_decode_no_validate (GNode *asn,
gboolean
egg_asn1x_decode (GNode *asn,
- gconstpointer data,
- gsize n_data)
+ EggBytes *data)
{
gboolean ret;
- g_return_val_if_fail (asn, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
+ g_return_val_if_fail (asn != NULL, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
- ret = egg_asn1x_decode_no_validate (asn, data, n_data);
+ ret = egg_asn1x_decode_no_validate (asn, data);
if (!ret)
return ret;
@@ -1255,8 +1305,11 @@ anode_encode_cls_tag_len (guchar *data, gsize n_data, guchar cls,
}
static void
-anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
- gpointer user_data, GDestroyNotify destroy)
+anode_encode_tlv_and_enc (GNode *node,
+ gsize n_data,
+ Aencoder encoder,
+ gpointer user_data,
+ GDestroyNotify destroy)
{
gboolean explicit = FALSE;
gulong tag;
@@ -1328,13 +1381,15 @@ anode_encode_tlv_and_enc (GNode *node, gsize n_data, EggAsn1xEncoder encoder,
tlv.buf = tlv.end = NULL;
anode_clear (node);
- anode_set_tlv_data (node, &tlv);
- anode_set_enc_data (node, encoder, user_data);
- anode_set_user_data (node, user_data, destroy);
+ anode_set_tlv_data (node, NULL, &tlv);
+ anode_set_enc_data (node, encoder, user_data, destroy);
}
static gboolean
-anode_encode_build (GNode *node, guchar *data, gsize n_data)
+anode_encode_build (GNode *node,
+ EggBytes *backing,
+ guchar *data,
+ gsize n_data)
{
gint type;
guchar cls;
@@ -1375,9 +1430,10 @@ anode_encode_build (GNode *node, guchar *data, gsize n_data)
g_assert (tlv->len + tlv->off == n_data);
tlv->buf = data;
tlv->end = data + n_data;
+ anode_set_backing (node, backing);
/* Encode in the data */
- if (!(enc->encoder) (enc->data, data + tlv->off, tlv->len))
+ if (!(enc->encoder) (enc->data, node, data + tlv->off, tlv->len))
return FALSE;
return TRUE;
@@ -1437,7 +1493,8 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
GNode *child;
GNode *next;
- g_assert (allocator);
+ if (!allocator)
+ allocator = g_realloc;
/* We have to sort any SET OF :( */
if (anode_def_type (node) != TYPE_SET_OF)
@@ -1457,7 +1514,7 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
if (!data)
break;
- if (!anode_encode_build (child, data, n_data)) {
+ if (!anode_encode_build (child, NULL, data, n_data)) {
(allocator) (data, 0);
continue;
}
@@ -1485,7 +1542,22 @@ traverse_and_sort_set_of (GNode *node, gpointer user_data)
}
static gboolean
-anode_encoder_simple (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_bytes (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
+{
+ EggBytes *bytes = user_data;
+ g_assert (egg_bytes_get_size (bytes) >= n_data);
+ memcpy (data, egg_bytes_get_data (bytes), n_data);
+ return TRUE;
+}
+
+static gboolean
+anode_encoder_data (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
{
memcpy (data, user_data, n_data);
return TRUE;
@@ -1493,11 +1565,13 @@ anode_encoder_simple (gpointer user_data, guchar *data, gsize n_data)
static gboolean
anode_encoder_unsigned (gpointer user_data,
+ GNode *node,
guchar *data,
gsize n_data)
{
+ EggBytes *value = user_data;
gboolean sign;
- gchar *p;
+ const gchar *p;
/*
* If top bit is set, the result would be negative in two's complement
@@ -1505,7 +1579,7 @@ anode_encoder_unsigned (gpointer user_data,
* byte is already calculated into n_data, see egg_asn1x_set_integer_as_usg
*/
- p = user_data;
+ p = egg_bytes_get_data (value);
sign = !!(p[0] & 0x80);
if (sign) {
g_assert (n_data > 1);
@@ -1519,9 +1593,11 @@ anode_encoder_unsigned (gpointer user_data,
}
static gboolean
-anode_encoder_structured (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_structured (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
{
- GNode *node = user_data;
GNode *child;
gsize length;
Atlv *tlv;
@@ -1531,7 +1607,8 @@ anode_encoder_structured (gpointer user_data, guchar *data, gsize n_data)
if (tlv) {
length = tlv->off + tlv->len;
g_assert (length <= n_data);
- if (!anode_encode_build (child, data, length))
+ if (!anode_encode_build (child, anode_get_backing (node),
+ data, length))
return FALSE;
data += length;
n_data -= length;
@@ -1542,7 +1619,10 @@ anode_encoder_structured (gpointer user_data, guchar *data, gsize n_data)
}
static gboolean
-anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_choice (gpointer user_data,
+ GNode *unused,
+ guchar *data,
+ gsize n_data)
{
GNode *node = user_data;
Aenc *enc = NULL;
@@ -1560,7 +1640,7 @@ anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
enc = anode_get_enc_data (child);
g_return_val_if_fail (enc, FALSE);
- if (!(enc->encoder) (enc->data, data, n_data))
+ if (!(enc->encoder) (enc->data, node, data, n_data))
return FALSE;
/* Child's buffer matches ours */
@@ -1571,7 +1651,10 @@ anode_encoder_choice (gpointer user_data, guchar *data, gsize n_data)
}
static gboolean
-anode_encoder_bit_string (gpointer user_data, guchar *data, gsize n_data)
+anode_encoder_bit_string (gpointer user_data,
+ GNode *node,
+ guchar *data,
+ gsize n_data)
{
Abits *ab = user_data;
guchar empty, mask;
@@ -1588,7 +1671,7 @@ anode_encoder_bit_string (gpointer user_data, guchar *data, gsize n_data)
data += 1;
/* Fill in the actual data */
- memcpy (data, ab->bits, len);
+ memcpy (data, egg_bytes_get_data (ab->bits), len);
/* Set the extra bits to zero */
if (len && empty) {
@@ -1611,8 +1694,10 @@ anode_encode_prepare_simple (GNode *node, gboolean want)
/* Transfer the tlv data over to enc */
enc = anode_get_enc_data (node);
- if (enc == NULL)
- anode_set_enc_data (node, anode_encoder_simple, (guchar*)tlv->buf + tlv->off);
+ if (enc == NULL) {
+ anode_set_enc_data (node, anode_encoder_data,
+ (guchar *)tlv->buf + tlv->off, NULL);
+ }
tlv->buf = tlv->end = NULL;
return TRUE;
@@ -1636,8 +1721,8 @@ anode_encode_prepare_choice (GNode *node, gboolean want)
tlv = anode_get_tlv_data (child);
g_return_val_if_fail (tlv, FALSE);
anode_clr_tlv_data (node);
- anode_set_tlv_data (node, tlv);
- anode_set_enc_data (node, anode_encoder_choice, node);
+ anode_set_tlv_data (node, NULL, tlv);
+ anode_set_enc_data (node, anode_encoder_choice, node, NULL);
return TRUE;
@@ -1716,20 +1801,55 @@ anode_encode_prepare (GNode *node, gboolean want)
};
}
-gpointer
-egg_asn1x_encode (GNode *asn, EggAllocator allocator, gsize *n_data)
+typedef struct {
+ EggAllocator allocator;
+ gpointer allocated;
+} AllocatorClosure;
+
+static void
+destroy_with_allocator (gpointer data)
+{
+ AllocatorClosure *closure = data;
+ g_assert (closure->allocator);
+ (closure->allocator) (closure->allocated, 0);
+ g_slice_free (AllocatorClosure, closure);
+}
+
+static EggBytes *
+new_bytes_with_allocator (EggAllocator allocator,
+ guchar **data,
+ gsize length)
+{
+ AllocatorClosure *closure;
+
+ if (allocator) {
+ *data = (allocator) (NULL, length + 1);
+ if (allocator == NULL)
+ return NULL;
+ closure = g_slice_new (AllocatorClosure);
+ closure->allocated = *data;
+ closure->allocator = allocator;
+ return egg_bytes_new_with_free_func (*data, length,
+ destroy_with_allocator,
+ closure);
+ } else {
+ *data = g_malloc (length);
+ return egg_bytes_new_take (*data, length);
+ }
+}
+
+EggBytes *
+egg_asn1x_encode (GNode *asn,
+ EggAllocator allocator)
{
+ EggBytes *bytes;
guchar *data;
gsize length;
Atlv *tlv;
- g_return_val_if_fail (asn, NULL);
- g_return_val_if_fail (n_data, NULL);
+ g_return_val_if_fail (asn != NULL, NULL);
g_return_val_if_fail (anode_def_type_is_real (asn), NULL);
- if (!allocator)
- allocator = g_realloc;
-
if (!anode_encode_prepare (asn, TRUE)) {
anode_failure (asn, "missing value(s)");
return NULL;
@@ -1744,18 +1864,17 @@ egg_asn1x_encode (GNode *asn, EggAllocator allocator, gsize *n_data)
/* Allocate enough memory for entire thingy */
length = tlv->off + tlv->len;
- data = (allocator) (NULL, length + 1);
+ bytes = new_bytes_with_allocator (allocator, &data, length);
if (data == NULL)
return NULL;
- if (anode_encode_build (asn, data, length) &&
+ if (anode_encode_build (asn, bytes, data, length) &&
anode_validate_anything (asn, TRUE)) {
anode_encode_commit (asn);
- *n_data = length;
- return data;
+ return bytes;
}
- (allocator) (data, 0);
+ egg_bytes_unref (bytes);
anode_encode_rollback (asn);
return NULL;
}
@@ -2472,7 +2591,7 @@ egg_asn1x_set_boolean (GNode *node, gboolean value)
data = g_malloc0 (1);
if (!anode_write_boolean (value, data, &n_data))
return FALSE;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
@@ -2483,7 +2602,7 @@ egg_asn1x_set_null (GNode *node)
g_return_val_if_fail (anode_def_type (node) == TYPE_NULL, FALSE);
/* Encode zero characters */
- anode_encode_tlv_and_enc (node, 0, anode_encoder_simple, "", NULL);
+ anode_encode_tlv_and_enc (node, 0, anode_encoder_data, "", NULL);
return TRUE;
}
@@ -2553,7 +2672,7 @@ egg_asn1x_set_enumerated (GNode *node, GQuark value)
if (!anode_write_integer_ulong (val, data, &n_data))
return FALSE;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
@@ -2611,100 +2730,132 @@ egg_asn1x_set_integer_as_ulong (GNode *node, gulong value)
data = g_malloc0 (n_data);
if (!anode_write_integer_ulong (value, data, &n_data))
return FALSE;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
-gconstpointer
-egg_asn1x_get_integer_as_raw (GNode *node, gsize *n_data)
+EggBytes *
+egg_asn1x_get_integer_as_raw (GNode *node)
{
+ EggBytes *backing;
Atlv *tlv;
g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (n_data, FALSE);
g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
- *n_data = tlv->len;
- return tlv->buf + tlv->off;
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
+ return egg_bytes_new_with_free_func (tlv->buf + tlv->off, tlv->len,
+ egg_bytes_unref, egg_bytes_ref (backing));
}
-gconstpointer
-egg_asn1x_get_integer_as_usg (GNode *node,
- gsize *n_data)
+EggBytes *
+egg_asn1x_get_integer_as_usg (GNode *node)
{
+ EggBytes *backing;
const guchar *p;
gboolean sign;
+ Atlv *tlv;
+ gsize n_data;
gsize len;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (n_data, FALSE);
+ g_return_val_if_fail (node != NULL, FALSE);
g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
- p = egg_asn1x_get_integer_as_raw (node, &len);
+ tlv = anode_get_tlv_data (node);
+ if (tlv == NULL || tlv->buf == NULL)
+ return NULL;
+
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
+ p = tlv->buf + tlv->off;
+ len = tlv->len;
+
sign = !!(p[0] & 0x80);
if (sign) {
g_warning ("invalid two's complement integer is negative, but expected unsigned");
return NULL;
}
- *n_data = len;
+ n_data = len;
/* Strip off the extra zero byte that was preventing it from being negative */
if (p[0] == 0 && len > 1) {
sign = !!(p[1] & 0x80);
if (sign) {
p++;
- *n_data = len - 1;
+ n_data = len - 1;
}
}
- return p;
+ return egg_bytes_new_with_free_func (p, n_data,
+ egg_bytes_unref,
+ egg_bytes_ref (backing));
}
-gboolean
-egg_asn1x_set_integer_as_raw (GNode *node, gconstpointer data, gsize n_data, GDestroyNotify destroy)
+void
+egg_asn1x_set_integer_as_raw (GNode *node,
+ EggBytes *value)
+{
+ g_return_if_fail (value != NULL);
+ egg_asn1x_take_integer_as_raw (node, egg_bytes_ref (value));
+}
+
+void
+egg_asn1x_take_integer_as_raw (GNode *node,
+ EggBytes *value)
{
gboolean sign;
- guchar *p;
+ const guchar *p;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data > 0, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (anode_def_type (node) == TYPE_INTEGER);
/* Make sure the integer is properly encoded in twos complement*/
- p = (guchar*)data;
+ p = egg_bytes_get_data (value);
sign = !!(p[0] & 0x80);
if (sign) {
g_warning ("integer in egg_asn1x_set_integer_as_raw is not two's complement");
- return FALSE;
+ return;
}
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, (gpointer)data, destroy);
- return TRUE;
+ anode_encode_tlv_and_enc (node, egg_bytes_get_size (value), anode_encoder_bytes,
+ value, egg_bytes_unref);
}
-gboolean
+void
egg_asn1x_set_integer_as_usg (GNode *node,
- gconstpointer data,
- gsize n_data,
- GDestroyNotify destroy)
+ EggBytes *value)
+{
+ g_return_if_fail (value != NULL);
+ egg_asn1x_take_integer_as_usg (node, egg_bytes_ref (value));
+}
+
+void
+egg_asn1x_take_integer_as_usg (GNode *node,
+ EggBytes *value)
{
gboolean sign;
- guchar *p;
+ const guchar *p;
+ gsize len;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data > 0, FALSE);
- g_return_val_if_fail (anode_def_type (node) == TYPE_INTEGER, FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (value != NULL);
+ g_return_if_fail (anode_def_type (node) == TYPE_INTEGER);
/* Make sure the integer is properly encoded in twos complement*/
- p = (guchar*)data;
+ p = egg_bytes_get_data (value);
sign = !!(p[0] & 0x80);
+ len = egg_bytes_get_size (value);
/*
* If in two's complement this would be negative, add a zero byte so
@@ -2712,50 +2863,63 @@ egg_asn1x_set_integer_as_usg (GNode *node,
* longer. In anode_encoder_unsigned we actually add the zero byte.
*/
if (sign)
- n_data += 1;
+ len += 1;
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_unsigned,
- (gpointer)data, destroy);
- return TRUE;
+ anode_encode_tlv_and_enc (node, len, anode_encoder_unsigned,
+ value, egg_bytes_unref);
}
-gconstpointer
-egg_asn1x_get_raw_element (GNode *node, gsize *n_element)
+EggBytes *
+egg_asn1x_get_raw_element (GNode *node)
{
+ EggBytes *backing;
+ const guchar *p;
+ gsize len;
Atlv *tlv;
- g_return_val_if_fail (node, NULL);
- g_return_val_if_fail (n_element, NULL);
+ g_return_val_if_fail (node != NULL, NULL);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
if (anode_calc_explicit (node)) {
- *n_element = (tlv->len + tlv->off) - tlv->oft;
- return tlv->buf + tlv->oft;
+ len = (tlv->len + tlv->off) - tlv->oft;
+ p = tlv->buf + tlv->oft;
} else {
- *n_element = tlv->len + tlv->off;
- return tlv->buf;
+ len = tlv->len + tlv->off;
+ p = tlv->buf;
}
+
+ return egg_bytes_new_with_free_func (p, len, egg_bytes_unref,
+ egg_bytes_ref (backing));
}
gboolean
-egg_asn1x_set_raw_element (GNode *node, gpointer data,
- gsize n_data, GDestroyNotify destroy)
+egg_asn1x_set_raw_element (GNode *node,
+ EggBytes *element)
{
Atlv dtlv, *tlv;
gint oft, flags;
+ const guchar *data;
+ EggBytes *sub;
+ gsize size;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
+ g_return_val_if_fail (node != NULL, FALSE);
+ g_return_val_if_fail (element != NULL, FALSE);
anode_clear (node);
memset (&dtlv, 0, sizeof (dtlv));
+ data = egg_bytes_get_data (element);
+ size = egg_bytes_get_size (element);
+
/* Decode the beginning TLV */
- if (!anode_decode_tlv_for_data (data, (const guchar*)data + n_data, &dtlv))
+ if (!anode_decode_tlv_for_data (data, data + size, &dtlv))
return FALSE;
/*
@@ -2767,11 +2931,11 @@ egg_asn1x_set_raw_element (GNode *node, gpointer data,
*/
flags = anode_def_flags (node);
flags &= ~(FLAG_TAG | FLAG_DEFAULT | FLAG_OPTION);
- if (!anode_decode_anything_for_flags (node, &dtlv, flags))
+ if (!anode_decode_anything_for_flags (node, element, &dtlv, flags))
return FALSE;
/* There was extra data */
- if (dtlv.end - dtlv.buf != n_data)
+ if (dtlv.end - dtlv.buf != size)
return FALSE;
/* Clear buffer from TLV so it gets encoded */
@@ -2782,44 +2946,39 @@ egg_asn1x_set_raw_element (GNode *node, gpointer data,
/* Explicit tagging: leave space for the outer tag */
if (anode_calc_explicit (node)) {
oft = anode_encode_cls_tag_len (NULL, 0, (ASN1_CLASS_STRUCTURED | ASN1_CLASS_CONTEXT_SPECIFIC),
- anode_calc_tag (node), n_data);
+ anode_calc_tag (node), size);
tlv->off += oft;
tlv->oft = oft;
}
+ sub = egg_bytes_new_with_free_func (dtlv.buf + dtlv.off, dtlv.len,
+ egg_bytes_unref, egg_bytes_ref (element));
+
/* Setup encoding of the contents */
- anode_set_enc_data (node, anode_encoder_simple, (gpointer)(dtlv.buf + dtlv.off));
- anode_set_user_data (node, data, destroy);
+ anode_set_enc_data (node, anode_encoder_bytes, sub, egg_bytes_unref);
return TRUE;
}
-gconstpointer
-egg_asn1x_get_raw_value (GNode *node, gsize *n_content)
+EggBytes *
+egg_asn1x_get_raw_value (GNode *node)
{
+ EggBytes *backing;
Atlv *tlv;
g_return_val_if_fail (node, NULL);
- g_return_val_if_fail (n_content, NULL);
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
g_return_val_if_fail (!(tlv->cls & ASN1_CLASS_STRUCTURED), NULL);
- *n_content = tlv->len;
- return tlv->buf + tlv->off;
-}
-
-gboolean
-egg_asn1x_set_raw_value (GNode *node, gsize length, EggAsn1xEncoder encoder,
- gpointer user_data, GDestroyNotify destroy)
-{
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (encoder, FALSE);
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
- anode_encode_tlv_and_enc (node, length, encoder, user_data, destroy);
- return TRUE;
+ return egg_bytes_new_with_free_func (tlv->buf + tlv->off, tlv->len,
+ egg_bytes_unref, egg_bytes_ref (backing));
}
guchar*
@@ -2872,10 +3031,25 @@ egg_asn1x_set_string_as_raw (GNode *node, guchar *data, gsize n_data, GDestroyNo
type = anode_def_type (node);
g_return_val_if_fail (type == TYPE_OCTET_STRING || type == TYPE_GENERALSTRING, FALSE);
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, destroy);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, destroy);
return TRUE;
}
+EggBytes *
+egg_asn1x_get_string_as_bytes (GNode *node)
+{
+ gpointer raw;
+ gsize length;
+
+ g_return_val_if_fail (node != NULL, NULL);
+
+ raw = egg_asn1x_get_string_as_raw (node, NULL, &length);
+ if (raw == NULL)
+ return NULL;
+
+ return egg_bytes_new_take (raw, length);
+}
+
gchar *
egg_asn1x_get_bmpstring_as_utf8 (GNode *node)
{
@@ -2933,61 +3107,67 @@ egg_asn1x_set_string_as_utf8 (GNode *node, gchar *data, GDestroyNotify destroy)
return egg_asn1x_set_string_as_raw (node, (guchar*)data, n_data, destroy);
}
-guchar*
-egg_asn1x_get_bits_as_raw (GNode *node, EggAllocator allocator, guint *n_bits)
+EggBytes *
+egg_asn1x_get_bits_as_raw (GNode *node, guint *n_bits)
{
- Atlv *tlv;
- gpointer bits;
+ EggBytes *backing;
guchar padded;
+ Atlv *tlv;
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (n_bits, FALSE);
g_return_val_if_fail (anode_def_type (node) == TYPE_BIT_STRING, FALSE);
- if (!allocator)
- allocator = g_realloc;
-
tlv = anode_get_tlv_data (node);
if (tlv == NULL || tlv->buf == NULL)
return NULL;
+ backing = anode_get_backing (node);
+ if (backing == NULL)
+ return NULL;
+
padded = *(tlv->buf + tlv->off);
g_return_val_if_fail (padded < 8, NULL);
g_return_val_if_fail (tlv->len > 1, NULL);
- bits = (allocator) (NULL, tlv->len);
- if (bits == NULL)
- return NULL;
-
- memcpy (bits, tlv->buf + tlv->off + 1, tlv->len - 1);
*n_bits = ((tlv->len - 1) * 8) - padded;
- return bits;
+ return egg_bytes_new_with_free_func (tlv->buf + tlv->off + 1, tlv->len - 1,
+ egg_bytes_unref, egg_bytes_ref (backing));
}
-gboolean
-egg_asn1x_set_bits_as_raw (GNode *node, guchar *bits, guint n_bits, GDestroyNotify destroy)
+void
+egg_asn1x_set_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits)
+{
+ g_return_if_fail (value != NULL);
+ egg_asn1x_take_bits_as_raw (node, egg_bytes_ref (value), n_bits);
+}
+
+void
+egg_asn1x_take_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits)
{
gint type;
gsize length;
Abits *ab;
- g_return_val_if_fail (node, FALSE);
- g_return_val_if_fail (bits, FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (value != NULL);
type = anode_def_type (node);
- g_return_val_if_fail (type == TYPE_BIT_STRING, FALSE);
+ g_return_if_fail (type == TYPE_BIT_STRING);
length = (n_bits / 8);
if (n_bits % 8)
length += 1;
ab = g_slice_new0 (Abits);
- ab->bits = bits;
+ ab->bits = egg_bytes_ref (value);
ab->n_bits = n_bits;
- ab->destroy = destroy;
anode_encode_tlv_and_enc (node, length + 1, anode_encoder_bit_string, ab, abits_destroy);
- return TRUE;
}
gboolean
@@ -3056,9 +3236,8 @@ egg_asn1x_set_bits_as_ulong (GNode *node, gulong bits, guint n_bits)
data[(length - i) - 1] = (value >> i * 8) & 0xFF;
ab = g_slice_new0 (Abits);
- ab->bits = data;
+ ab->bits = egg_bytes_new_take (data, sizeof (gulong));
ab->n_bits = n_bits;
- ab->destroy = g_free;
anode_encode_tlv_and_enc (node, length + 1, anode_encoder_bit_string, ab, abits_destroy);
return TRUE;
@@ -3166,7 +3345,7 @@ egg_asn1x_set_oid_as_string (GNode *node, const gchar *oid)
return FALSE;
}
- anode_encode_tlv_and_enc (node, n_data, anode_encoder_simple, data, g_free);
+ anode_encode_tlv_and_enc (node, n_data, anode_encoder_data, data, g_free);
return TRUE;
}
@@ -3919,8 +4098,9 @@ egg_asn1x_create_quark (const ASN1_ARRAY_TYPE *defs, GQuark type)
}
GNode*
-egg_asn1x_create_and_decode (const ASN1_ARRAY_TYPE *defs, const gchar *identifier,
- gconstpointer data, gsize n_data)
+egg_asn1x_create_and_decode (const ASN1_ARRAY_TYPE *defs,
+ const gchar *identifier,
+ EggBytes *data)
{
GNode *asn;
@@ -3930,7 +4110,7 @@ egg_asn1x_create_and_decode (const ASN1_ARRAY_TYPE *defs, const gchar *identifie
asn = egg_asn1x_create (defs, identifier);
g_return_val_if_fail (asn, NULL);
- if (!egg_asn1x_decode (asn, data, n_data)) {
+ if (!egg_asn1x_decode (asn, data)) {
egg_asn1x_destroy (asn);
return NULL;
}
@@ -4156,16 +4336,17 @@ egg_asn1x_parse_time_utc (const gchar *time, gssize n_time)
*/
gssize
-egg_asn1x_element_length (gconstpointer data, gsize n_data)
+egg_asn1x_element_length (const guchar *data,
+ gsize n_data)
{
guchar cls;
int counter = 0;
int cb, len;
gulong tag;
- if (anode_decode_cls_tag (data, (const guchar*)data + n_data, &cls, &tag, &cb)) {
+ if (anode_decode_cls_tag (data, data + n_data, &cls, &tag, &cb)) {
counter += cb;
- len = anode_decode_length ((const guchar*)data + cb, (const guchar*)data + n_data, &cb);
+ len = anode_decode_length (data + cb, data + n_data, &cb);
counter += cb;
if (len >= 0) {
len += counter;
@@ -4178,7 +4359,9 @@ egg_asn1x_element_length (gconstpointer data, gsize n_data)
}
gconstpointer
-egg_asn1x_element_content (gconstpointer data, gsize n_data, gsize *n_content)
+egg_asn1x_element_content (const guchar *data,
+ gsize n_data,
+ gsize *n_content)
{
int counter = 0;
guchar cls;
diff --git a/egg/egg-asn1x.h b/egg/egg-asn1x.h
index 3f74655..e211b6d 100644
--- a/egg/egg-asn1x.h
+++ b/egg/egg-asn1x.h
@@ -26,13 +26,13 @@
#include <glib.h>
+#include "egg-bytes.h"
+
#ifndef HAVE_EGG_ALLOCATOR
typedef void* (*EggAllocator) (void* p, gsize);
#define HAVE_EGG_ALLOCATOR
#endif
-typedef gboolean (*EggAsn1xEncoder) (gpointer data, guchar *buf, gsize n_buf);
-
struct static_struct_asn;
GNode* egg_asn1x_create (const struct static_struct_asn *defs,
@@ -43,27 +43,23 @@ GNode* egg_asn1x_create_quark (const struct static_struct
GNode* egg_asn1x_create_and_decode (const struct static_struct_asn *defs,
const gchar *type,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
void egg_asn1x_dump (GNode *asn);
void egg_asn1x_clear (GNode *asn);
gboolean egg_asn1x_decode (GNode *asn,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
gboolean egg_asn1x_decode_no_validate (GNode *asn,
- gconstpointer data,
- gsize n_data);
+ EggBytes *data);
gboolean egg_asn1x_validate (GNode *asn,
gboolean strict);
-gpointer egg_asn1x_encode (GNode *asn,
- EggAllocator allocator,
- gsize *n_data);
+EggBytes * egg_asn1x_encode (GNode *asn,
+ EggAllocator allocator);
const gchar* egg_asn1x_message (GNode *asn);
@@ -102,38 +98,28 @@ gboolean egg_asn1x_get_integer_as_ulong (GNode *node,
gboolean egg_asn1x_set_integer_as_ulong (GNode *node,
gulong value);
-gconstpointer egg_asn1x_get_integer_as_raw (GNode *node,
- gsize *n_data);
+EggBytes * egg_asn1x_get_integer_as_raw (GNode *node);
-gboolean egg_asn1x_set_integer_as_raw (GNode *node,
- gconstpointer data,
- gsize n_data,
- GDestroyNotify destroy);
+void egg_asn1x_set_integer_as_raw (GNode *node,
+ EggBytes *value);
-gconstpointer egg_asn1x_get_integer_as_usg (GNode *node,
- gsize *n_data);
+void egg_asn1x_take_integer_as_raw (GNode *node,
+ EggBytes *value);
-gboolean egg_asn1x_set_integer_as_usg (GNode *node,
- gconstpointer data,
- gsize n_data,
- GDestroyNotify destroy);
+EggBytes * egg_asn1x_get_integer_as_usg (GNode *node);
-gconstpointer egg_asn1x_get_raw_value (GNode *node,
- gsize *n_content);
+void egg_asn1x_set_integer_as_usg (GNode *node,
+ EggBytes *value);
-gboolean egg_asn1x_set_raw_value (GNode *node,
- gsize length,
- EggAsn1xEncoder encoder,
- gpointer user_data,
- GDestroyNotify destroy);
+void egg_asn1x_take_integer_as_usg (GNode *node,
+ EggBytes *value);
+
+EggBytes * egg_asn1x_get_raw_value (GNode *node);
-gconstpointer egg_asn1x_get_raw_element (GNode *node,
- gsize *n_data);
+EggBytes * egg_asn1x_get_raw_element (GNode *node);
gboolean egg_asn1x_set_raw_element (GNode *node,
- gpointer user_data,
- gsize n_data,
- GDestroyNotify destroy);
+ EggBytes *value);
guchar* egg_asn1x_get_string_as_raw (GNode *node,
EggAllocator allocator,
@@ -144,14 +130,18 @@ gboolean egg_asn1x_set_string_as_raw (GNode *node,
gsize n_data,
GDestroyNotify destroy);
-guchar* egg_asn1x_get_bits_as_raw (GNode *node,
- EggAllocator allocator,
+EggBytes * egg_asn1x_get_string_as_bytes (GNode *node);
+
+EggBytes * egg_asn1x_get_bits_as_raw (GNode *node,
guint *n_bits);
-gboolean egg_asn1x_set_bits_as_raw (GNode *node,
- guchar *data,
- guint n_bits,
- GDestroyNotify destroy);
+void egg_asn1x_set_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits);
+
+void egg_asn1x_take_bits_as_raw (GNode *node,
+ EggBytes *value,
+ guint n_bits);
gboolean egg_asn1x_get_bits_as_ulong (GNode *node,
gulong *value,
@@ -161,7 +151,7 @@ gboolean egg_asn1x_set_bits_as_ulong (GNode *node,
gulong value,
guint n_bits);
-gchar* egg_asn1x_get_string_as_utf8 (GNode *node,
+gchar * egg_asn1x_get_string_as_utf8 (GNode *node,
EggAllocator allocator);
gboolean egg_asn1x_set_string_as_utf8 (GNode *node,
@@ -186,7 +176,7 @@ GQuark egg_asn1x_get_oid_as_quark (GNode *node);
gboolean egg_asn1x_set_oid_as_quark (GNode *node,
GQuark oid);
-gchar* egg_asn1x_get_oid_as_string (GNode *node);
+gchar * egg_asn1x_get_oid_as_string (GNode *node);
gboolean egg_asn1x_set_oid_as_string (GNode *node,
const gchar *oid);
@@ -199,10 +189,10 @@ glong egg_asn1x_parse_time_general (const gchar *time,
glong egg_asn1x_parse_time_utc (const gchar *time,
gssize n_time);
-gssize egg_asn1x_element_length (gconstpointer data,
+gssize egg_asn1x_element_length (const guchar *data,
gsize n_data);
-gconstpointer egg_asn1x_element_content (gconstpointer data,
+gconstpointer egg_asn1x_element_content (const guchar *data,
gsize n_data,
gsize *n_content);
diff --git a/egg/egg-bytes.c b/egg/egg-bytes.c
new file mode 100644
index 0000000..22bac5e
--- /dev/null
+++ b/egg/egg-bytes.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright  2009, 2010 Codethink Limited
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ */
+
+#include "config.h"
+
+#include "egg-bytes.h"
+
+#include <glib.h>
+
+#include <string.h>
+
+struct _EggBytes
+{
+ gconstpointer data;
+ gsize size;
+ gint ref_count;
+ GDestroyNotify free_func;
+ gpointer user_data;
+};
+
+/**
+ * egg_bytes_new:
+ * @data: (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ *
+ * Creates a new #EggBytes from @data.
+ *
+ * @data is copied.
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new (gconstpointer data,
+ gsize size)
+{
+ return egg_bytes_new_take (g_memdup (data, size), size);
+}
+
+/**
+ * egg_bytes_new_take:
+ * @data: (transfer full) (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ *
+ * Creates a new #EggBytes from @data.
+ *
+ * After this call, @data belongs to the bytes and may no longer be
+ * modified by the caller. g_free() will be called on @data when the
+ * bytes is no longer in use. Because of this @data must have been created by
+ * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many
+ * functions that wrap these calls (such as g_new(), g_strdup(), etc).
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_take (gpointer data,
+ gsize size)
+{
+ return egg_bytes_new_with_free_func (data, size, g_free, data);
+}
+
+
+/**
+ * egg_bytes_new_static:
+ * @data: (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ *
+ * Creates a new #EggBytes from static data.
+ *
+ * @data must be static (ie: never modified or freed).
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_static (gconstpointer data,
+ gsize size)
+{
+ return egg_bytes_new_with_free_func (data, size, NULL, NULL);
+}
+
+/**
+ * egg_bytes_new_with_free_func:
+ * @data: (array length=size): the data to be used for the bytes
+ * @size: the size of @data
+ * @free_func: the function to call to release the data
+ * @user_data: data to pass to @free_func
+ *
+ * Creates a #EggBytes from @data.
+ *
+ * When the last reference is dropped, @free_func will be called with the
+ * @user_data argument.
+ *
+ * @data must not be modified after this call is made until @free_func has
+ * been called to indicate that the bytes is no longer in use.
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_with_free_func (gconstpointer data,
+ gsize size,
+ GDestroyNotify free_func,
+ gpointer user_data)
+{
+ EggBytes *bytes;
+
+ bytes = g_slice_new (EggBytes);
+ bytes->data = data;
+ bytes->size = size;
+ bytes->free_func = free_func;
+ bytes->user_data = user_data;
+ bytes->ref_count = 1;
+
+ return (EggBytes *)bytes;
+}
+
+/**
+ * egg_bytes_new_from_bytes:
+ * @bytes: a #EggBytes
+ * @offset: offset which subsection starts at
+ * @length: length of subsucsection
+ *
+ * Creates a #EggBytes which is a subsection of another #EggBytes.
+ *
+ * A reference to @bytes will be held by the newly created #EggBytes until
+ * the byte data is no longer needed.
+ *
+ * Returns: (transfer full): a new #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_new_from_bytes (EggBytes *bytes,
+ goffset offset,
+ gsize length)
+{
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (offset <= bytes->size, NULL);
+ g_return_val_if_fail (offset + length <= bytes->size, NULL);
+
+ return egg_bytes_new_with_free_func ((gchar *)bytes->data + offset, length,
+ egg_bytes_unref, egg_bytes_ref (bytes));
+}
+
+/**
+ * egg_bytes_get_data:
+ * @bytes: a #EggBytes
+ *
+ * Get the byte data in the #EggBytes. This data should not be modified.
+ *
+ * This function will always return the same pointer for a given #EggBytes.
+ *
+ * Returns: a pointer to the byte data
+ *
+ * Since: 2.32
+ */
+gconstpointer
+egg_bytes_get_data (EggBytes *bytes)
+{
+ g_return_val_if_fail (bytes != NULL, NULL);
+ return bytes->data;
+}
+
+/**
+ * egg_bytes_get_size:
+ * @bytes: a #EggBytes
+ *
+ * Get the size of the byte data in the #EggBytes.
+ *
+ * This function will always return the same value for a given #EggBytes.
+ *
+ * Returns: the size
+ *
+ * Since: 2.32
+ */
+gsize
+egg_bytes_get_size (EggBytes *bytes)
+{
+ g_return_val_if_fail (bytes != NULL, 0);
+ return bytes->size;
+}
+
+
+/**
+ * egg_bytes_ref:
+ * @bytes: a #EggBytes
+ *
+ * Increase the reference count on @bytes.
+ *
+ * Returns: (transfer full): the #EggBytes
+ *
+ * Since: 2.32
+ */
+EggBytes *
+egg_bytes_ref (EggBytes *bytes)
+{
+ g_return_val_if_fail (bytes != NULL, NULL);
+
+ g_atomic_int_inc (&bytes->ref_count);
+
+ return bytes;
+}
+
+/**
+ * egg_bytes_unref:
+ * @bytes: (transfer full) (type GLib.Bytes): a #EggBytes
+ *
+ * Releases a reference on @bytes. This may result in the bytes being
+ * freed.
+ *
+ * Since: 2.32
+ */
+void
+egg_bytes_unref (gpointer bytes)
+{
+ EggBytes *bytes_ = bytes;
+
+ g_return_if_fail (bytes_ != NULL);
+
+ if (g_atomic_int_dec_and_test (&bytes_->ref_count))
+ {
+ if (bytes_->free_func != NULL)
+ bytes_->free_func (bytes_->user_data);
+ }
+}
+
+/**
+ * egg_bytes_equal:
+ * @bytes1: (type GLib.Bytes): a pointer to a #EggBytes
+ * @bytes2: (type GLib.Bytes): a pointer to a #EggBytes to compare with @bytes1
+ *
+ * Compares the two #EggBytes values being pointed to and returns
+ * %TRUE if they are equal.
+ *
+ * This function can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using non-%NULL #EggBytes pointers as keys in a #GHashTable.
+ *
+ * Returns: %TRUE if the two keys match.
+ *
+ * Since: 2.32
+ */
+gboolean
+egg_bytes_equal (gconstpointer bytes1,
+ gconstpointer bytes2)
+{
+ const EggBytes *b1 = bytes1;
+ const EggBytes *b2 = bytes2;
+
+ g_return_val_if_fail (bytes1 != NULL, FALSE);
+ g_return_val_if_fail (bytes2 != NULL, FALSE);
+
+ return b1->size == b2->size &&
+ memcmp (b1->data, b2->data, b1->size) == 0;
+}
+
+/**
+ * egg_bytes_hash:
+ * @bytes: (type GLib.Bytes): a pointer to a #EggBytes key
+ *
+ * Creates an integer hash code for the byte data in the #EggBytes.
+ *
+ * This function can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using non-%NULL #EggBytes pointers as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key.
+ *
+ * Since: 2.32
+ */
+guint
+egg_bytes_hash (gconstpointer bytes)
+{
+ const EggBytes *a = bytes;
+ const signed char *p, *e;
+ guint32 h = 5381;
+
+ g_return_val_if_fail (bytes != NULL, 0);
+
+ for (p = (signed char *)a->data, e = (signed char *)a->data + a->size; p != e; p++)
+ h = (h << 5) + h + *p;
+
+ return h;
+}
+
+/**
+ * egg_bytes_compare:
+ * @bytes1: (type GLib.Bytes): a pointer to a #EggBytes
+ * @bytes2: (type GLib.Bytes): a pointer to a #EggBytes to compare with @bytes1
+ *
+ * Compares the two #EggBytes values.
+ *
+ * This function can be passed to g_tree_new() when using non-%NULL #EggBytes
+ * pointers as keys in a #GTree.
+ *
+ * Returns: a negative value if bytes2 is lesser, a positive value if bytes2 is
+ * greater, and zero if bytes2 is equal to bytes1
+ *
+ * Since: 2.32
+ */
+gint
+egg_bytes_compare (gconstpointer bytes1,
+ gconstpointer bytes2)
+{
+ const EggBytes *b1 = bytes1;
+ const EggBytes *b2 = bytes2;
+ gint ret;
+
+ g_return_val_if_fail (bytes1 != NULL, 0);
+ g_return_val_if_fail (bytes2 != NULL, 0);
+
+ ret = memcmp (b1->data, b2->data, MIN (b1->size, b2->size));
+ if (ret == 0 && b1->size != b2->size)
+ ret = b1->size < b2->size ? -1 : 1;
+ return ret;
+}
+
+/**
+ * egg_bytes_unref_to_array:
+ * @bytes: (transfer full): a #EggBytes
+ *
+ * Unreferences the bytes, and returns a new mutable #GByteArray containing
+ * the same byte data.
+ *
+ * As an optimization, the byte data is transferred to the array without copying
+ * if: this was the last reference to bytes and bytes was created with
+ * egg_bytes_new(), egg_bytes_new_take() or g_byte_array_free_to_bytes(). In all
+ * other cases the data is copied.
+ *
+ * Returns: (transfer full): a new mutable #GByteArray containing the same byte data
+ *
+ * Since: 2.32
+ */
+GByteArray *
+egg_bytes_unref_to_array (EggBytes *bytes)
+{
+ GByteArray *result = NULL;
+#if 0
+ gpointer data;
+ gsize size;
+#endif
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+
+#if 0
+ data = egg_bytes_try_steal_and_unref (bytes, NULL, &size);
+ if (data != NULL)
+ {
+ /*
+ * Optimal path: if this is was the last reference, then we can have
+ * the GByteArray assume the data from this EggBytes without copying.
+ */
+ result = g_byte_array_new_take (data, size);
+ }
+ else
+#endif
+ {
+ /*
+ * Copy: Non g_malloc (or compatible) allocator, or static memory,
+ * so we have to copy, and then unref.
+ */
+ result = g_byte_array_append (g_byte_array_new (), bytes->data, bytes->size);
+ egg_bytes_unref (bytes);
+ }
+
+ return result;
+}
+
+/*
+ * The behavior of this function with regards to references cannot be easily
+ * modeled by most gobject-introspection consumers, so we use (skip).
+ */
+
+/**
+ * egg_bytes_try_steal_and_unref: (skip)
+ * @bytes: a #EggBytes
+ * @free_func: the function data is freed with, or %NULL for default
+ * @size: location to return the length of the data
+ *
+ * This is an advanced function, and seldom used.
+ *
+ * Try to take ownership of the data in the byte array. This is only successful
+ * if this is the last reference and @free_func matches the function that would
+ * have been used to free the data. This is to demonstrate that the caller
+ * is aware of the how the data in the #EggBytes was allocated. If %NULL is passed
+ * for @free_func this represents the standard Glib allocation routines.
+ *
+ * You should use %NULL instead of passing g_free() for @free_func. This is
+ * because the actual address of g_free() varies depending on how the calling
+ * application and library was linked.
+ *
+ * If the attempt to take ownership of the byte data is successful according to
+ * the above criteria, then the data is returned and @size is set to the length
+ * of the data. The #EggBytes is unreferenced and is no longer valid.
+ *
+ * If the attempt to take ownership of the byte data is unsuccessful, %NULL is
+ * returned. The #EggBytes is not unreferenced, and the caller must unreference
+ * the #EggBytes elsewhere.
+ *
+ * It is always incorrect to ignore the return value from this function.
+ *
+ * Returns: the stolen data, or %NULL if attempt failed
+ *
+ * Since: 2.32
+ */
+gpointer
+egg_bytes_try_steal_and_unref (EggBytes *bytes,
+ GDestroyNotify free_func,
+ gsize *size)
+{
+ gpointer result;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (size != NULL, NULL);
+
+ if (free_func == NULL)
+ free_func = g_free;
+ if (bytes->free_func != free_func)
+ return NULL;
+
+ /* Are we the only reference? */
+ if (g_atomic_int_get (&bytes->ref_count) == 1)
+ {
+ *size = bytes->size;
+ result = (gpointer)bytes->data;
+ g_slice_free (EggBytes, bytes);
+ return result;
+ }
+
+ return NULL;
+}
diff --git a/egg/egg-bytes.h b/egg/egg-bytes.h
new file mode 100644
index 0000000..57cba03
--- /dev/null
+++ b/egg/egg-bytes.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright  2009, 2010 Codethink Limited
+ * Copyright  2011 Collabora Ltd.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the licence, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt desrt ca>
+ * Stef Walter <stefw collabora co uk>
+ */
+
+#ifndef __EGG_BYTES_H__
+#define __EGG_BYTES_H__
+
+#include <glib/gtypes.h>
+#include <glib/garray.h>
+
+/**
+ * EggBytes:
+ *
+ * A simple refcounted data type representing an immutable byte sequence
+ * from an unspecified origin.
+ *
+ * The purpose of a #EggBytes is to keep the memory region that it holds
+ * alive for as long as anyone holds a reference to the bytes. When
+ * the last reference count is dropped, the memory is released. Multiple
+ * unrelated callers can use byte data in the #EggBytes without coordinating
+ * their activities, resting assured that the byte data will not change or
+ * move while they hold a reference.
+ *
+ * A #EggBytes can come from many different origins that may have
+ * different procedures for freeing the memory region. Examples are
+ * memory from g_malloc(), from memory slices, from a #GMappedFile or
+ * memory from other allocators.
+ *
+ * #EggBytes work well as keys in #GHashTable. Use egg_bytes_equal() and
+ * egg_bytes_hash() as parameters to g_hash_table_new() or g_hash_table_new_full().
+ * #EggBytes can also be used as keys in a #GTree by passing the egg_bytes_compare()
+ * function to g_tree_new().
+ *
+ * The data pointed to by this bytes must not be modified. For a mutable
+ * array of bytes see #GByteArray. Use egg_bytes_unref_to_array() to create a
+ * mutable array for a #EggBytes sequence. To create an immutable #EggBytes from
+ * a mutable #GByteArray, use the g_byte_array_free_to_bytes() function.
+ *
+ * Since: 2.32
+ **/
+
+typedef struct _EggBytes EggBytes;
+
+EggBytes * egg_bytes_new (gconstpointer data,
+ gsize size);
+
+EggBytes * egg_bytes_new_take (gpointer data,
+ gsize size);
+
+EggBytes * egg_bytes_new_static (gconstpointer data,
+ gsize size);
+
+EggBytes * egg_bytes_new_with_free_func (gconstpointer data,
+ gsize size,
+ GDestroyNotify free_func,
+ gpointer user_data);
+
+EggBytes * egg_bytes_new_from_bytes (EggBytes *bytes,
+ goffset offset,
+ gsize length);
+
+gconstpointer egg_bytes_get_data (EggBytes *bytes);
+
+gsize egg_bytes_get_size (EggBytes *bytes);
+
+EggBytes * egg_bytes_ref (EggBytes *bytes);
+
+void egg_bytes_unref (gpointer bytes);
+
+GByteArray * egg_bytes_unref_to_array (EggBytes *bytes);
+
+gpointer egg_bytes_try_steal_and_unref (EggBytes *bytes,
+ GDestroyNotify free_func,
+ gsize *size);
+
+guint egg_bytes_hash (gconstpointer bytes);
+
+gboolean egg_bytes_equal (gconstpointer bytes1,
+ gconstpointer bytes2);
+
+gint egg_bytes_compare (gconstpointer bytes1,
+ gconstpointer bytes2);
+
+#define egg_assert_equal_bytes(b, p, s) \
+ egg_assert_cmpmem (egg_bytes_get_data (b), egg_bytes_get_size (b), ==, (p), (s))
+
+#endif /* __EGG_BYTES_H__ */
diff --git a/egg/egg-dn.c b/egg/egg-dn.c
index b41844e..1edcd59 100644
--- a/egg/egg-dn.c
+++ b/egg/egg-dn.c
@@ -33,13 +33,15 @@
static const char HEXC[] = "0123456789ABCDEF";
static gchar*
-dn_print_hex_value (const guchar *data, gsize len)
+dn_print_hex_value (EggBytes *val)
{
- GString *result = g_string_sized_new (len * 2 + 1);
+ const gchar *data = egg_bytes_get_data (val);
+ gsize size = egg_bytes_get_size (val);
+ GString *result = g_string_sized_new (size * 2 + 1);
gsize i;
g_string_append_c (result, '#');
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < size; ++i) {
g_string_append_c (result, HEXC[data[i] >> 4 & 0xf]);
g_string_append_c (result, HEXC[data[i] & 0xf]);
}
@@ -48,20 +50,22 @@ dn_print_hex_value (const guchar *data, gsize len)
}
static gchar*
-dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize len)
+dn_print_oid_value_parsed (GQuark oid,
+ guint flags,
+ EggBytes *val)
{
GNode *asn1, *node;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
+ const gchar *data;
+ gsize size;
gchar *result;
- g_assert (data);
- g_assert (len);
+ g_assert (val != NULL);
asn1 = egg_asn1x_create_quark (pkix_asn1_tab, oid);
g_return_val_if_fail (asn1, NULL);
- if (!egg_asn1x_decode (asn1, data, len)) {
+ if (!egg_asn1x_decode (asn1, val)) {
g_message ("couldn't decode value for OID: %s: %s",
g_quark_to_string (oid), egg_asn1x_message (asn1));
egg_asn1x_destroy (asn1);
@@ -77,7 +81,9 @@ dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize le
else
node = asn1;
- value = egg_asn1x_get_raw_value (node, &n_value);
+ value = egg_asn1x_get_raw_value (node);
+ data = egg_bytes_get_data (value);
+ size = egg_bytes_get_size (value);
/*
* Now we make sure it's UTF-8.
@@ -87,33 +93,35 @@ dn_print_oid_value_parsed (GQuark oid, guint flags, const guchar *data, gsize le
g_message ("couldn't read value for OID: %s", g_quark_to_string (oid));
result = NULL;
- } else if (!g_utf8_validate (value, n_value, NULL)) {
- result = dn_print_hex_value ((guchar*)value, n_value);
+ } else if (!g_utf8_validate (data, size, NULL)) {
+ result = dn_print_hex_value (value);
} else {
- result = g_strndup (value, n_value);
+ result = g_strndup (data, size);
}
+ egg_bytes_unref (value);
egg_asn1x_destroy (asn1);
return result;
}
static gchar*
-dn_print_oid_value (GQuark oid, guint flags, const guchar *data, gsize len)
+dn_print_oid_value (GQuark oid,
+ guint flags,
+ EggBytes *val)
{
gchar *value;
- g_assert (data);
- g_assert (len);
+ g_assert (val != NULL);
if (flags & EGG_OID_PRINTABLE) {
- value = dn_print_oid_value_parsed (oid, flags, data, len);
+ value = dn_print_oid_value_parsed (oid, flags, val);
if (value != NULL)
return value;
}
- return dn_print_hex_value (data, len);
+ return dn_print_hex_value (val);
}
static gchar*
@@ -122,8 +130,7 @@ dn_parse_rdn (GNode *asn)
const gchar *name;
guint flags;
GQuark oid;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
gchar *display;
gchar *result;
@@ -135,14 +142,15 @@ dn_parse_rdn (GNode *asn)
flags = egg_oid_get_flags (oid);
name = egg_oid_get_name (oid);
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "value", NULL), &n_value);
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "value", NULL));
g_return_val_if_fail (value, NULL);
- display = dn_print_oid_value (oid, flags, value, n_value);
+ display = dn_print_oid_value (oid, flags, value);
result = g_strconcat ((flags & EGG_OID_PRINTABLE) ? name : g_quark_to_string (oid),
"=", display, NULL);
g_free (display);
+ egg_bytes_unref (value);
return result;
}
@@ -193,8 +201,7 @@ egg_dn_read_part (GNode *asn, const gchar *match)
{
gboolean done = FALSE;
const gchar *name;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
GNode *node;
GQuark oid;
gint i, j;
@@ -226,10 +233,10 @@ egg_dn_read_part (GNode *asn, const gchar *match)
node = egg_asn1x_node (asn, i, j, "value", NULL);
g_return_val_if_fail (node, NULL);
- value = egg_asn1x_get_raw_element (node, &n_value);
+ value = egg_asn1x_get_raw_element (node);
g_return_val_if_fail (value, NULL);
- return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
+ return dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
}
}
@@ -241,8 +248,7 @@ egg_dn_parse (GNode *asn, EggDnCallback callback, gpointer user_data)
{
gboolean done = FALSE;
GNode *node;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
GQuark oid;
guint i, j;
@@ -271,21 +277,24 @@ egg_dn_parse (GNode *asn, EggDnCallback callback, gpointer user_data)
break;
}
- value = egg_asn1x_get_raw_element (node, &n_value);
+ value = egg_asn1x_get_raw_element (node);
if (callback)
- (callback) (i, oid, value, n_value, user_data);
+ (callback) (i, oid, value, user_data);
+
+ egg_bytes_unref (value);
}
}
return i > 1;
}
-gchar*
-egg_dn_print_value (GQuark oid, const guchar *value, gsize n_value)
+gchar *
+egg_dn_print_value (GQuark oid,
+ EggBytes *value)
{
- g_return_val_if_fail (oid, NULL);
- g_return_val_if_fail (value || !n_value, NULL);
+ g_return_val_if_fail (oid != 0, NULL);
+ g_return_val_if_fail (value != NULL, NULL);
- return dn_print_oid_value (oid, egg_oid_get_flags (oid), value, n_value);
+ return dn_print_oid_value (oid, egg_oid_get_flags (oid), value);
}
diff --git a/egg/egg-dn.h b/egg/egg-dn.h
index 96fe5ff..5d36d7e 100644
--- a/egg/egg-dn.h
+++ b/egg/egg-dn.h
@@ -26,6 +26,8 @@
#include <glib.h>
+#include "egg/egg-bytes.h"
+
gchar* egg_dn_read (GNode *node);
gchar* egg_dn_read_part (GNode *node,
@@ -33,8 +35,7 @@ gchar* egg_dn_read_part (GNode *node,
typedef void (*EggDnCallback) (guint index,
GQuark oid,
- const guchar *value,
- gsize n_value,
+ EggBytes *value,
gpointer user_data);
gboolean egg_dn_parse (GNode *node,
@@ -42,7 +43,6 @@ gboolean egg_dn_parse (GNode *node,
gpointer user_data);
gchar* egg_dn_print_value (GQuark oid,
- const guchar *value,
- gsize n_value);
+ EggBytes *value);
#endif /* EGG_DN_H_ */
diff --git a/egg/egg-openssl.c b/egg/egg-openssl.c
index 77318f5..dc38e2b 100644
--- a/egg/egg-openssl.c
+++ b/egg/egg-openssl.c
@@ -202,10 +202,12 @@ done:
return success;
}
-gboolean
-egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **decrypted, gsize *n_decrypted)
+guchar *
+egg_openssl_decrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_decrypted)
{
gcry_cipher_hd_t ch;
guchar *key = NULL;
@@ -213,6 +215,7 @@ egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
int gcry, ivlen;
int algo = 0;
int mode = 0;
+ guchar *decrypted;
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
return FALSE;
@@ -224,43 +227,46 @@ egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
/* IV is already set from the DEK info */
if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
- n_password, iv, 8, 1, &key, NULL)) {
+ n_password, iv, 8, 1, &key, NULL)) {
g_free (iv);
- return FALSE;
+ return NULL;
}
- /* TODO: Use secure memory */
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
g_free (iv);
/* Allocate output area */
- *n_decrypted = n_data;
- *decrypted = egg_secure_alloc (n_data);
+ *n_decrypted = egg_bytes_get_size (data);
+ decrypted = egg_secure_alloc (*n_decrypted);
- gcry = gcry_cipher_decrypt (ch, *decrypted, *n_decrypted, (void*)data, n_data);
+ gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
if (gcry) {
- egg_secure_free (*decrypted);
- g_return_val_if_reached (FALSE);
+ egg_secure_free (decrypted);
+ g_return_val_if_reached (NULL);
}
gcry_cipher_close (ch);
- return TRUE;
+ return decrypted;
}
-gboolean
-egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **encrypted, gsize *n_encrypted)
+guchar *
+egg_openssl_encrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_encrypted)
{
gsize n_overflow, n_batch, n_padding;
gcry_cipher_hd_t ch;
@@ -270,65 +276,71 @@ egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
int gcry, ivlen;
int algo = 0;
int mode = 0;
+ gsize n_data;
+ guchar *encrypted;
+ const guchar *dat;
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
- g_return_val_if_reached (FALSE);
+ g_return_val_if_reached (NULL);
ivlen = gcry_cipher_get_algo_blklen (algo);
/* We assume the iv is at least as long as at 8 byte salt */
- g_return_val_if_fail (ivlen >= 8, FALSE);
+ g_return_val_if_fail (ivlen >= 8, NULL);
/* IV is already set from the DEK info */
if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
n_password, iv, 8, 1, &key, NULL))
- g_return_val_if_reached (FALSE);
+ g_return_val_if_reached (NULL);
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
g_free (iv);
+ dat = egg_bytes_get_data (data);
+ n_data = egg_bytes_get_size (data);
+
/* Allocate output area */
n_overflow = (n_data % ivlen);
n_padding = n_overflow ? (ivlen - n_overflow) : 0;
n_batch = n_data - n_overflow;
*n_encrypted = n_data + n_padding;
- *encrypted = g_malloc0 (*n_encrypted);
+ encrypted = g_malloc0 (*n_encrypted);
g_assert (*n_encrypted % ivlen == 0);
g_assert (*n_encrypted >= n_data);
g_assert (*n_encrypted == n_batch + n_overflow + n_padding);
/* Encrypt everything but the last bit */
- gcry = gcry_cipher_encrypt (ch, *encrypted, n_batch, (void*)data, n_batch);
+ gcry = gcry_cipher_encrypt (ch, encrypted, n_batch, dat, n_batch);
if (gcry) {
- g_free (*encrypted);
- g_return_val_if_reached (FALSE);
+ g_free (encrypted);
+ g_return_val_if_reached (NULL);
}
/* Encrypt the padded block */
if (n_overflow) {
padded = egg_secure_alloc (ivlen);
memset (padded, 0, ivlen);
- memcpy (padded, data + n_batch, n_overflow);
- gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen);
+ memcpy (padded, dat + n_batch, n_overflow);
+ gcry = gcry_cipher_encrypt (ch, encrypted + n_batch, ivlen, padded, ivlen);
egg_secure_free (padded);
if (gcry) {
- g_free (*encrypted);
- g_return_val_if_reached (FALSE);
+ g_free (encrypted);
+ g_return_val_if_reached (NULL);
}
}
gcry_cipher_close (ch);
- return TRUE;
+ return encrypted;
}
const gchar*
diff --git a/egg/egg-openssl.h b/egg/egg-openssl.h
index a998c9e..642d906 100644
--- a/egg/egg-openssl.h
+++ b/egg/egg-openssl.h
@@ -26,15 +26,21 @@
#include <glib.h>
-int egg_openssl_parse_algo (const gchar *name, int *mode);
+#include <egg/egg-bytes.h>
-gboolean egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **encrypted, gsize *n_encrypted);
+int egg_openssl_parse_algo (const gchar *name, int *mode);
-gboolean egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **decrypted, gsize *n_decrypted);
+guchar * egg_openssl_encrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_encrypted);
+
+guchar * egg_openssl_decrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_decrypted);
const gchar* egg_openssl_get_dekinfo (GHashTable *headers);
diff --git a/egg/egg-symkey.c b/egg/egg-symkey.c
index 5f5070b..835d4a3 100644
--- a/egg/egg-symkey.c
+++ b/egg/egg-symkey.c
@@ -658,14 +658,17 @@ egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo,
static gboolean
-read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
- const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih)
+read_cipher_pkcs5_pbe (int cipher_algo,
+ int cipher_mode,
+ int hash_algo,
+ const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ gcry_cipher_hd_t *cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
- gconstpointer salt;
- gsize n_salt;
+ EggBytes *salt = NULL;
gsize n_block, n_key;
gulong iterations;
guchar *key = NULL;
@@ -674,7 +677,7 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
g_return_val_if_fail (cih != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
*cih = NULL;
ret = FALSE;
@@ -687,10 +690,10 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-PBE-params");
g_return_val_if_fail (asn, FALSE);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
goto done;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL));
if (!salt)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
@@ -700,8 +703,9 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
g_return_val_if_fail (n_key > 0, FALSE);
n_block = gcry_cipher_get_algo_blklen (cipher_algo);
- if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password, salt,
- n_salt, iterations, &key, n_block > 1 ? &iv : NULL))
+ if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password,
+ egg_bytes_get_data (salt), egg_bytes_get_size (salt),
+ iterations, &key, n_block > 1 ? &iv : NULL))
goto done;
gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
@@ -718,6 +722,8 @@ read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo,
done:
g_free (iv);
+ if (salt != NULL)
+ egg_bytes_unref (salt);
egg_secure_free (key);
egg_asn1x_destroy (asn);
@@ -725,12 +731,12 @@ done:
}
static gboolean
-setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
+setup_pkcs5_rc2_params (EggBytes *data,
+ gcry_cipher_hd_t cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
- const guchar *iv;
- gsize n_iv;
+ EggBytes *iv = NULL;
gulong version;
gboolean ret = FALSE;
@@ -739,90 +745,99 @@ setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-5-rc2-CBC-params");
g_return_val_if_fail (asn, FALSE);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "rc2ParameterVersion", NULL), &version))
goto done;
- iv = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "iv", NULL), &n_iv);
+ iv = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "iv", NULL));
if (!iv)
goto done;
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
+ gcry = gcry_cipher_setiv (cih, egg_bytes_get_data (iv), egg_bytes_get_size (iv));
if (gcry != 0) {
- g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
+ g_message ("couldn't set %lu byte iv on cipher", (gulong)egg_bytes_get_size (iv));
goto done;
}
ret = TRUE;
done:
+ if (iv != NULL)
+ egg_bytes_unref (iv);
egg_asn1x_destroy (asn);
return ret;
}
static gboolean
-setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
+setup_pkcs5_des_params (EggBytes *data,
+ gcry_cipher_hd_t cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
- gconstpointer iv;
- gsize n_iv;
+ EggBytes *iv;
+ gboolean ret;
g_assert (data);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-EDE3-CBC-params", data);
if (!asn)
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-CBC-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-des-CBC-params", data);
if (!asn)
return FALSE;
- iv = egg_asn1x_get_raw_value (asn, &n_iv);
+ iv = egg_asn1x_get_raw_value (asn);
egg_asn1x_destroy (asn);
if (!iv)
return FALSE;
- gcry = gcry_cipher_setiv (cih, iv, n_iv);
-
+ gcry = gcry_cipher_setiv (cih, egg_bytes_get_data (iv), egg_bytes_get_size (iv));
if (gcry != 0) {
- g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
- return FALSE;
+ g_message ("couldn't set %lu byte iv on cipher", (gulong)egg_bytes_get_size (iv));
+ ret = FALSE;
+ } else {
+ ret = TRUE;
}
- return TRUE;
+ egg_bytes_unref (iv);
+ return ret;
}
static gboolean
-setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, int cipher_algo, gcry_cipher_hd_t cih)
+setup_pkcs5_pbkdf2_params (const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ int cipher_algo,
+ gcry_cipher_hd_t cih)
{
GNode *asn = NULL;
gboolean ret;
gcry_error_t gcry;
guchar *key = NULL;
- const guchar *salt;
- gsize n_salt, n_key;
+ EggBytes *salt = NULL;
+ gsize n_key;
gulong iterations;
g_assert (cipher_algo);
- g_assert (data);
+ g_assert (data != NULL);
ret = FALSE;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBKDF2-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBKDF2-params", data);
if (!asn)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterationCount", NULL), &iterations))
iterations = 1;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", "specified", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", "specified", NULL));
if (!salt)
goto done;
if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password,
- salt, n_salt, iterations, &key, NULL))
+ egg_bytes_get_data (salt), egg_bytes_get_size (salt),
+ iterations, &key, NULL))
goto done;
n_key = gcry_cipher_get_algo_keylen (cipher_algo);
@@ -837,32 +852,35 @@ setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar
ret = TRUE;
done:
+ if (salt != NULL)
+ egg_bytes_unref (salt);
egg_secure_free (key);
egg_asn1x_destroy (asn);
return ret;
}
static gboolean
-read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data,
- gsize n_data, gcry_cipher_hd_t *cih)
+read_cipher_pkcs5_pbes2 (const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ gcry_cipher_hd_t *cih)
{
GNode *asn = NULL;
gboolean r, ret;
GQuark key_deriv_algo, enc_oid;
+ EggBytes *params = NULL;
gcry_error_t gcry;
int algo, mode;
- gconstpointer params;
- gsize n_params;
g_return_val_if_fail (cih != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
init_quarks ();
*cih = NULL;
ret = FALSE;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBES2-params", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-5-PBES2-params", data);
if (!asn)
goto done;
@@ -893,17 +911,17 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
}
/* Read out the parameters */
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionScheme", "parameters", NULL));
if (!params)
goto done;
switch (algo) {
case GCRY_CIPHER_3DES:
case GCRY_CIPHER_DES:
- r = setup_pkcs5_des_params (params, n_params, *cih);
+ r = setup_pkcs5_des_params (params, *cih);
break;
case GCRY_CIPHER_RFC2268_128:
- r = setup_pkcs5_rc2_params (params, n_params, *cih);
+ r = setup_pkcs5_rc2_params (params, *cih);
break;
default:
/* Should have been caught on the oid check above */
@@ -924,11 +942,12 @@ read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *
goto done;
}
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL), &n_params);
+ egg_bytes_unref (params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "keyDerivationFunc", "parameters", NULL));
if (!params)
goto done;
- ret = setup_pkcs5_pbkdf2_params (password, n_password, params, n_params, algo, *cih);
+ ret = setup_pkcs5_pbkdf2_params (password, n_password, params, algo, *cih);
done:
if (ret != TRUE && *cih) {
@@ -936,20 +955,24 @@ done:
*cih = NULL;
}
+ if (params != NULL)
+ egg_bytes_unref (params);
egg_asn1x_destroy (asn);
return ret;
}
static gboolean
-read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
- gsize n_password, const guchar *data, gsize n_data,
+read_cipher_pkcs12_pbe (int cipher_algo,
+ int cipher_mode,
+ const gchar *password,
+ gsize n_password,
+ EggBytes *data,
gcry_cipher_hd_t *cih)
{
GNode *asn = NULL;
gcry_error_t gcry;
gboolean ret;
- const guchar *salt;
- gsize n_salt;
+ EggBytes *salt = NULL;
gsize n_block, n_key;
gulong iterations;
guchar *key = NULL;
@@ -957,7 +980,7 @@ read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
g_return_val_if_fail (cih != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
*cih = NULL;
ret = FALSE;
@@ -966,11 +989,11 @@ read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
goto done;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-PbeParams", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-PbeParams", data);
if (!asn)
goto done;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "salt", NULL));
if (!salt)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterations", NULL), &iterations))
@@ -980,9 +1003,9 @@ read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password,
n_key = gcry_cipher_get_algo_keylen (cipher_algo);
/* Generate IV and key using salt read above */
- if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password,
- n_password, salt, n_salt, iterations, &key,
- n_block > 1 ? &iv : NULL))
+ if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password, n_password,
+ egg_bytes_get_data (salt), egg_bytes_get_size (salt),
+ iterations, &key, n_block > 1 ? &iv : NULL))
goto done;
gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
@@ -1003,6 +1026,8 @@ done:
*cih = NULL;
}
+ if (salt != NULL)
+ egg_bytes_unref (salt);
g_free (iv);
egg_secure_free (key);
egg_asn1x_destroy (asn);
@@ -1013,8 +1038,7 @@ static gboolean
read_mac_pkcs12_pbe (int hash_algo,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_md_hd_t *mdh,
gsize *digest_len)
{
@@ -1022,14 +1046,13 @@ read_mac_pkcs12_pbe (int hash_algo,
gcry_error_t gcry;
gboolean ret;
gsize n_key;
- const guchar *salt;
- gsize n_salt;
+ EggBytes *salt = NULL;
gulong iterations;
guchar *key = NULL;
g_return_val_if_fail (hash_algo != 0, FALSE);
g_return_val_if_fail (mdh != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
*mdh = NULL;
ret = FALSE;
@@ -1038,11 +1061,11 @@ read_mac_pkcs12_pbe (int hash_algo,
if (gcry_md_algo_info (hash_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
goto done;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-MacData", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-12-MacData", data);
if (!asn)
goto done;
- salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "macSalt", NULL), &n_salt);
+ salt = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "macSalt", NULL));
if (!salt)
goto done;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "iterations", NULL), &iterations))
@@ -1052,7 +1075,8 @@ read_mac_pkcs12_pbe (int hash_algo,
/* Generate IV and key using salt read above */
if (!egg_symkey_generate_pkcs12_mac (hash_algo, password, n_password,
- salt, n_salt, iterations, &key))
+ egg_bytes_get_data (salt), egg_bytes_get_size (salt),
+ iterations, &key))
goto done;
gcry = gcry_md_open (mdh, hash_algo, GCRY_MD_FLAG_HMAC);
@@ -1073,82 +1097,86 @@ done:
*mdh = NULL;
}
+ if (salt != NULL)
+ egg_bytes_unref (salt);
egg_secure_free (key);
egg_asn1x_destroy (asn);
return ret;
}
gboolean
-egg_symkey_read_cipher (GQuark oid_scheme, const gchar *password, gsize n_password,
- const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
+egg_symkey_read_cipher (GQuark oid_scheme,
+ const gchar *password,
+ gsize n_password,
+ EggBytes *data,
+ gcry_cipher_hd_t *cih)
{
gboolean ret = FALSE;
g_return_val_if_fail (oid_scheme != 0, FALSE);
g_return_val_if_fail (cih != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
init_quarks ();
/* PKCS#5 PBE */
if (oid_scheme == OID_PBE_MD2_DES_CBC)
ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
- GCRY_MD_MD2, password, n_password, data, n_data, cih);
+ GCRY_MD_MD2, password, n_password, data, cih);
else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
/* RC2-64 has no implementation in libgcrypt */;
else if (oid_scheme == OID_PBE_MD5_DES_CBC)
ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
- GCRY_MD_MD5, password, n_password, data, n_data, cih);
+ GCRY_MD_MD5, password, n_password, data, cih);
else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
/* RC2-64 has no implementation in libgcrypt */;
else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
- GCRY_MD_SHA1, password, n_password, data, n_data, cih);
+ GCRY_MD_SHA1, password, n_password, data, cih);
else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
/* RC2-64 has no implementation in libgcrypt */;
/* PKCS#5 PBES2 */
else if (oid_scheme == OID_PBES2)
- ret = read_cipher_pkcs5_pbes2 (password, n_password, data, n_data, cih);
+ ret = read_cipher_pkcs5_pbes2 (password, n_password, data, cih);
/* PKCS#12 PBE */
else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM,
- password, n_password, data, n_data, cih);
+ password, n_password, data, cih);
else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
/* RC4-40 has no implementation in libgcrypt */;
else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC,
- password, n_password, data, n_data, cih);
+ password, n_password, data, cih);
else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1)
/* 2DES has no implementation in libgcrypt */;
else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC,
- password, n_password, data, n_data, cih);
+ password, n_password, data, cih);
else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC,
- password, n_password, data, n_data, cih);
+ password, n_password, data, cih);
if (ret == FALSE)
- g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
+ g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
- return ret;
+ return ret;
}
gboolean
egg_symkey_read_mac (GQuark oid_scheme,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_md_hd_t *mdh,
gsize *digest_len)
{
@@ -1156,17 +1184,18 @@ egg_symkey_read_mac (GQuark oid_scheme,
g_return_val_if_fail (oid_scheme != 0, FALSE);
g_return_val_if_fail (mdh != NULL, FALSE);
- g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
init_quarks ();
/* PKCS#12 MAC with SHA-1 */
if (oid_scheme == OID_SHA1)
ret = read_mac_pkcs12_pbe (GCRY_MD_SHA1, password, n_password,
- data, n_data, mdh, digest_len);
+ data, mdh, digest_len);
if (ret == FALSE)
g_message ("unsupported or invalid mac: %s", g_quark_to_string (oid_scheme));
+ egg_bytes_unref (data);
return ret;
}
diff --git a/egg/egg-symkey.h b/egg/egg-symkey.h
index feb1a25..b11d1dd 100644
--- a/egg/egg-symkey.h
+++ b/egg/egg-symkey.h
@@ -26,6 +26,8 @@
#include <gcrypt.h>
+#include <egg/egg-bytes.h>
+
gboolean egg_symkey_generate_simple (int cipher_algo,
int hash_algo,
const gchar *password,
@@ -77,15 +79,13 @@ gboolean egg_symkey_generate_pbkdf2 (int cipher_algo
gboolean egg_symkey_read_cipher (GQuark oid_scheme,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_cipher_hd_t *cih);
gboolean egg_symkey_read_mac (GQuark oid_scheme,
const gchar *password,
gsize n_password,
- const guchar *data,
- gsize n_data,
+ EggBytes *data,
gcry_md_hd_t *mdh,
gsize *digest_len);
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index 9403ebb..2ab9f52 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -60,6 +60,7 @@ const gchar ENUM_THREE[] = "\x0A\x01\x03";
static void
test_boolean (void)
{
+ EggBytes *bytes;
GNode *asn;
gboolean value;
@@ -71,20 +72,24 @@ test_boolean (void)
g_assert_not_reached ();
/* Decode a false */
- if (!egg_asn1x_decode (asn, BFALSE, XL (BFALSE)))
+ bytes = egg_bytes_new_static (BFALSE, XL (BFALSE));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
value = TRUE;
if (!egg_asn1x_get_boolean (asn, &value))
g_assert_not_reached ();
g_assert (value == FALSE);
+ egg_bytes_unref (bytes);
/* Decode a true */
- if (!egg_asn1x_decode (asn, BTRUE, XL (BTRUE)))
+ bytes = egg_bytes_new_static (BTRUE, XL (BTRUE));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
value = FALSE;
if (!egg_asn1x_get_boolean (asn, &value))
g_assert_not_reached ();
g_assert (value == TRUE);
+ egg_bytes_unref (bytes);
egg_asn1x_clear (asn);
@@ -99,8 +104,7 @@ static void
test_null (void)
{
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
asn = egg_asn1x_create (test_asn1_tab, "TestNull");
g_assert (asn);
@@ -108,14 +112,14 @@ test_null (void)
if (!egg_asn1x_set_null (asn))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, g_realloc, &n_data);
- egg_assert_cmpmem (NULL_TEST, XL (NULL_TEST), ==, data, n_data);
+ data = egg_asn1x_encode (asn, g_realloc);
+ egg_assert_cmpmem (NULL_TEST, XL (NULL_TEST), ==, egg_bytes_get_data (data), egg_bytes_get_size (data));
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
g_assert_not_reached ();
egg_asn1x_destroy (asn);
- g_free (data);
+ egg_bytes_unref (data);
}
static void
@@ -123,6 +127,7 @@ test_integer (void)
{
GNode *asn;
gulong value;
+ EggBytes *bytes;
asn = egg_asn1x_create (test_asn1_tab, "TestInteger");
g_assert (asn);
@@ -132,11 +137,13 @@ test_integer (void)
g_assert_not_reached ();
/* Should suceed now */
- if (!egg_asn1x_decode (asn, I33, XL (I33)))
+ bytes = egg_bytes_new_static (I33, XL (I33));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
if (!egg_asn1x_get_integer_as_ulong (asn, &value))
g_assert_not_reached ();
g_assert (value == 42);
+ egg_bytes_unref (bytes);
egg_asn1x_clear (asn);
@@ -152,50 +159,53 @@ test_unsigned (void)
{
GNode *asn;
gulong value;
- guchar *check;
- gsize n_check;
+ EggBytes *check;
guchar val;
- gconstpointer usg;
- gsize n_usg;
+ EggBytes *bytes;
+ EggBytes *usg;
asn = egg_asn1x_create (test_asn1_tab, "TestInteger");
g_assert (asn);
/* Check with ulong */
- if (!egg_asn1x_decode (asn, I253, XL (I253)))
+ bytes = egg_bytes_new_static (I253, XL (I253));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
if (!egg_asn1x_get_integer_as_ulong (asn, &value))
g_assert_not_reached ();
g_assert (value == 253);
+ egg_bytes_unref (bytes);
egg_asn1x_clear (asn);
if (!egg_asn1x_set_integer_as_ulong (asn, 253))
g_assert_not_reached ();
- check = egg_asn1x_encode (asn, NULL, &n_check);
- egg_assert_cmpmem (check, n_check, ==, I253, XL (I253));
+ check = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpmem (I253, XL (I253), ==, egg_bytes_get_data (check), egg_bytes_get_size (check));
+ egg_bytes_unref (check);
/* Now check with usg */
- if (!egg_asn1x_decode (asn, I253, XL (I253)))
+ bytes = egg_bytes_new_static (I253, XL (I253));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
- g_free (check);
+ egg_bytes_unref (bytes);
val = 0xFD; /* == 253 */
- usg = egg_asn1x_get_integer_as_usg (asn, &n_usg);
- egg_assert_cmpmem (&val, 1, ==, usg, n_usg);
+ usg = egg_asn1x_get_integer_as_usg (asn);
+ egg_assert_cmpmem (&val, 1, ==, egg_bytes_get_data (usg), egg_bytes_get_size (usg));
+ egg_bytes_unref (usg);
egg_asn1x_clear (asn);
- if (!egg_asn1x_set_integer_as_usg (asn, &val, 1, NULL))
- g_assert_not_reached ();
+ egg_asn1x_take_integer_as_usg (asn, egg_bytes_new_static (&val, 1));
- check = egg_asn1x_encode (asn, NULL, &n_check);
- egg_assert_cmpsize (n_check, ==, XL (I253));
- egg_assert_cmpmem (check, n_check, ==, I253, XL (I253));
+ check = egg_asn1x_encode (asn, NULL);
+ egg_assert_cmpsize (egg_bytes_get_size (check), ==, XL (I253));
+ egg_assert_cmpmem (I253, XL (I253), ==, egg_bytes_get_data (check), egg_bytes_get_size (check));
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
- g_free (check);
}
static void
@@ -203,6 +213,7 @@ test_octet_string (void)
{
GNode *asn;
gchar *value;
+ EggBytes *bytes;
asn = egg_asn1x_create (test_asn1_tab, "TestOctetString");
g_assert (asn);
@@ -212,8 +223,11 @@ test_octet_string (void)
g_assert_not_reached ();
/* Should work */
- if (!egg_asn1x_decode (asn, SFARNSWORTH, XL (SFARNSWORTH)))
+ bytes = egg_bytes_new_static (SFARNSWORTH, XL (SFARNSWORTH));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
+
value = egg_asn1x_get_string_as_utf8 (asn, NULL);
g_assert_cmpstr (value, ==, "farnsworth");
g_free (value);
@@ -230,6 +244,7 @@ test_octet_string (void)
static void
test_generalized_time (void)
{
+ EggBytes *bytes;
GNode *asn;
glong value;
@@ -241,8 +256,10 @@ test_generalized_time (void)
g_assert (value == -1);
/* Should work */
- if (!egg_asn1x_decode (asn, TGENERALIZED, XL (TGENERALIZED)))
+ bytes = egg_bytes_new_static (TGENERALIZED, XL (TGENERALIZED));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
value = egg_asn1x_get_time_as_long (asn);
g_assert (value == 1185368728);
@@ -258,6 +275,7 @@ test_generalized_time (void)
static void
test_implicit (void)
{
+ EggBytes *bytes;
GNode *asn;
gchar *value;
@@ -265,8 +283,10 @@ test_implicit (void)
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, SIMPLICIT, XL (SIMPLICIT)))
+ bytes = egg_bytes_new_static (SIMPLICIT, XL (SIMPLICIT));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
value = egg_asn1x_get_string_as_utf8 (asn, NULL);
g_assert_cmpstr (value, ==, "implicit");
g_free (value);
@@ -277,6 +297,7 @@ test_implicit (void)
static void
test_explicit (void)
{
+ EggBytes *bytes;
GNode *asn;
gchar *value;
@@ -284,8 +305,11 @@ test_explicit (void)
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, SEXPLICIT, XL (SEXPLICIT)))
+ bytes = egg_bytes_new_static (SEXPLICIT, XL (SEXPLICIT));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
+
value = egg_asn1x_get_string_as_utf8 (asn, NULL);
g_assert_cmpstr (value, ==, "explicit");
g_free (value);
@@ -296,39 +320,47 @@ test_explicit (void)
static void
test_bit_string_decode (void)
{
+ EggBytes *bytes;
GNode *asn;
- guchar *bits;
+ EggBytes *bits;
guint n_bits;
+ const guchar *data;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, BITS_TEST, XL (BITS_TEST)))
+ bytes = egg_bytes_new_static (BITS_TEST, XL (BITS_TEST));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- bits = egg_asn1x_get_bits_as_raw (asn, NULL, &n_bits);
- g_assert (bits);
+ bits = egg_asn1x_get_bits_as_raw (asn, &n_bits);
+ g_assert (bits != NULL);
g_assert_cmpuint (n_bits, ==, 18);
- g_assert_cmpint (bits[0], ==, 0x6e);
- g_assert_cmpint (bits[1], ==, 0x5d);
- g_assert_cmpint (bits[2], ==, 0xc0);
+ data = egg_bytes_get_data (bits);
+ g_assert_cmpint (data[0], ==, 0x6e);
+ g_assert_cmpint (data[1], ==, 0x5d);
+ g_assert_cmpint (data[2], ==, 0xc0);
- g_free (bits);
+ egg_bytes_unref (bits);
egg_asn1x_destroy (asn);
}
static void
test_bit_string_decode_bad (void)
{
+ EggBytes *bytes;
GNode *asn;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
/* Should not work */
- if (egg_asn1x_decode (asn, BITS_BAD, XL (BITS_BAD)))
+ bytes = egg_bytes_new_static (BITS_BAD, XL (BITS_BAD));
+ if (egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
egg_asn1x_destroy (asn);
}
@@ -336,6 +368,7 @@ test_bit_string_decode_bad (void)
static void
test_bit_string_decode_ulong (void)
{
+ EggBytes *bytes;
GNode *asn;
gulong bits;
guint n_bits;
@@ -344,8 +377,10 @@ test_bit_string_decode_ulong (void)
g_assert (asn);
/* Should work */
- if (!egg_asn1x_decode (asn, BITS_TEST, XL (BITS_TEST)))
+ bytes = egg_bytes_new_static (BITS_TEST, XL (BITS_TEST));
+ if (!egg_asn1x_decode (asn, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
if (!egg_asn1x_get_bits_as_ulong (asn, &bits, &n_bits))
g_assert_not_reached ();
@@ -359,46 +394,46 @@ test_bit_string_decode_ulong (void)
static void
test_bit_string_encode_decode (void)
{
+ EggBytes *data;
GNode *asn;
guchar bits[] = { 0x5d, 0x6e, 0x83 };
- guchar *check;
- guint n_check, n_bits = 17;
- gpointer data;
- gsize n_data;
+ EggBytes *check;
+ const guchar *ch;
+ guint n_bits = 17;
+ guint n_check;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
- if (!egg_asn1x_set_bits_as_raw (asn, bits, n_bits, NULL))
- g_assert_not_reached ();
+ egg_asn1x_set_bits_as_raw (asn, egg_bytes_new (bits, 3), n_bits);
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
g_assert_not_reached ();
- check = egg_asn1x_get_bits_as_raw (asn, NULL, &n_check);
- g_assert (check);
- g_assert_cmpuint (n_check, ==, 17);
- g_assert_cmpint (check[0], ==, 0x5d);
- g_assert_cmpint (check[1], ==, 0x6e);
- g_assert_cmpint (check[2], ==, 0x80);
+ egg_bytes_unref (data);
- g_free (check);
+ check = egg_asn1x_get_bits_as_raw (asn, &n_check);
+ g_assert (check != NULL);
+ g_assert_cmpuint (n_check, ==, 17);
+ ch = egg_bytes_get_data (check);
+ g_assert_cmpint (ch[0], ==, 0x5d);
+ g_assert_cmpint (ch[1], ==, 0x6e);
+ g_assert_cmpint (ch[2], ==, 0x80);
- g_free (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
}
static void
test_bit_string_encode_decode_ulong (void)
{
+ EggBytes *data;
GNode *asn;
gulong check, bits = 0x0101b977;
guint n_check, n_bits = 18;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
@@ -406,51 +441,48 @@ test_bit_string_encode_decode_ulong (void)
if (!egg_asn1x_set_bits_as_ulong (asn, bits, n_bits))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, data))
g_assert_not_reached ();
+ egg_bytes_unref (data);
+
if (!egg_asn1x_get_bits_as_ulong (asn, &check, &n_check))
g_assert_not_reached ();
g_assert_cmpuint (n_check, ==, 18);
g_assert_cmphex (check, ==, 0x1b977);
- g_free (data);
egg_asn1x_destroy (asn);
}
static void
test_bit_string_encode_decode_zero (void)
{
+ EggBytes *data;
GNode *asn;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBitString");
g_assert (asn);
- if (!egg_asn1x_set_bits_as_raw (asn, (guchar*)"", 0, NULL))
- g_assert_not_reached ();
+ egg_asn1x_set_bits_as_raw (asn, egg_bytes_new_static ("", 0), 0);
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
- egg_assert_cmpsize (n_data, ==, XL (BITS_ZERO));
- g_assert (memcmp (data, BITS_ZERO, n_data) == 0);
+ egg_assert_cmpmem (egg_bytes_get_data (data), egg_bytes_get_size (data), ==, BITS_ZERO, XL (BITS_ZERO));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_have (void)
{
+ EggBytes *data;
GNode *asn;
- guchar *data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBoolean");
g_assert (asn);
@@ -462,12 +494,12 @@ test_have (void)
g_assert (!egg_asn1x_have (asn));
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert (data);
g_assert (egg_asn1x_have (asn));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
@@ -483,10 +515,10 @@ test_is_freed (gpointer unused)
static void
test_any_set_raw (void)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- const guchar *check;
- gsize n_data, n_check;
+ EggBytes *data;
+ EggBytes *check;
/* ENCODED SEQUENCE ANY with OCTET STRING */
const gchar SEQ_ENCODING[] = "\x30\x0C\x04\x0A""farnsworth";
@@ -498,22 +530,24 @@ test_any_set_raw (void)
node = egg_asn1x_node (asn, "contents", NULL);
g_assert (node);
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ bytes = egg_bytes_new_with_free_func (SFARNSWORTH, XL (SFARNSWORTH),
+ test_is_freed, NULL);
+ if (!egg_asn1x_set_raw_element (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- egg_assert_cmpsize (n_data, ==, XL (SEQ_ENCODING));
- g_assert (memcmp (data, SEQ_ENCODING, n_data) == 0);
+ egg_assert_equal_bytes (data, SEQ_ENCODING, XL (SEQ_ENCODING));
- check = egg_asn1x_get_raw_element (node, &n_check);
+ check = egg_asn1x_get_raw_element (node);
g_assert (check);
- egg_assert_cmpsize (n_check, ==, XL (SFARNSWORTH));
- g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+ egg_assert_equal_bytes (check, SFARNSWORTH, XL (SFARNSWORTH));
- g_free (data);
+ egg_bytes_unref (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
g_assert (is_freed);
}
@@ -521,10 +555,10 @@ test_any_set_raw (void)
static void
test_any_set_raw_explicit (void)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- const guchar *check;
- gsize n_data, n_check;
+ EggBytes *data;
+ EggBytes *check;
/* ENCODED SEQUENCE [89] ANY with OCTET STRING */
const gchar SEQ_ENCODING[] = "\x30\x0F\xBF\x59\x0C\x04\x0A""farnsworth";
@@ -536,22 +570,23 @@ test_any_set_raw_explicit (void)
node = egg_asn1x_node (asn, "contents", NULL);
g_assert (node);
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ bytes = egg_bytes_new_with_free_func (SFARNSWORTH, XL (SFARNSWORTH), test_is_freed, NULL);
+ if (!egg_asn1x_set_raw_element (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- egg_assert_cmpsize (n_data, ==, XL (SEQ_ENCODING));
- g_assert (memcmp (data, SEQ_ENCODING, n_data) == 0);
+ egg_assert_equal_bytes (data, SEQ_ENCODING, XL (SEQ_ENCODING));
- check = egg_asn1x_get_raw_element (node, &n_check);
+ check = egg_asn1x_get_raw_element (node);
g_assert (check);
- g_assert (n_check == XL (SFARNSWORTH));
- g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+ egg_assert_equal_bytes (check, SFARNSWORTH, XL (SFARNSWORTH));
- g_free (data);
+ egg_bytes_unref (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
g_assert (is_freed);
}
@@ -559,9 +594,9 @@ test_any_set_raw_explicit (void)
static void
test_choice_not_chosen (void)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- gsize n_data;
+ EggBytes *data;
asn = egg_asn1x_create (test_asn1_tab, "TestAnyChoice");
g_assert (asn);
@@ -569,12 +604,14 @@ test_choice_not_chosen (void)
node = egg_asn1x_node (asn, "choiceShortTag", NULL);
g_assert (node);
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), NULL))
+ bytes = egg_bytes_new_static (SFARNSWORTH, XL (SFARNSWORTH));
+ if (!egg_asn1x_set_raw_element (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
/* egg_asn1x_set_choice() was not called */
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (!data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data == NULL);
g_assert (egg_asn1x_message (asn));
g_assert (strstr (egg_asn1x_message (asn), "TestAnyChoice") != NULL);
@@ -584,10 +621,10 @@ test_choice_not_chosen (void)
static void
perform_asn1_any_choice_set_raw (const gchar *choice, const gchar *encoding, gsize n_encoding)
{
+ EggBytes *bytes;
GNode *asn, *node;
- guchar *data;
- const guchar *check;
- gsize n_data, n_check;
+ EggBytes *data;
+ EggBytes *check;
asn = egg_asn1x_create (test_asn1_tab, "TestAnyChoice");
g_assert (asn);
@@ -599,26 +636,27 @@ perform_asn1_any_choice_set_raw (const gchar *choice, const gchar *encoding, gsi
if (!egg_asn1x_set_choice (asn, node))
g_assert_not_reached ();
- if (!egg_asn1x_set_raw_element (node, (guchar*)SFARNSWORTH, XL (SFARNSWORTH), test_is_freed))
+ bytes = egg_bytes_new_with_free_func (SFARNSWORTH, XL (SFARNSWORTH), test_is_freed, NULL);
+ if (!egg_asn1x_set_raw_element (node, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- if (!data) {
+ data = egg_asn1x_encode (asn, NULL);
+ if (data == NULL) {
g_printerr ("%s\n", egg_asn1x_message (asn));
g_assert_not_reached ();
}
- g_assert (data);
+ g_assert (data != NULL);
- egg_assert_cmpsize (n_data, ==, n_encoding);
- g_assert (memcmp (data, encoding, n_data) == 0);
+ egg_assert_equal_bytes (data, encoding, n_encoding);
- check = egg_asn1x_get_raw_element (node, &n_check);
- g_assert (check);
+ check = egg_asn1x_get_raw_element (node);
+ g_assert (check != NULL);
- g_assert (n_check == XL (SFARNSWORTH));
- g_assert (memcmp (check, SFARNSWORTH, n_check) == 0);
+ egg_assert_equal_bytes (check, SFARNSWORTH, XL (SFARNSWORTH));
- g_free (data);
+ egg_bytes_unref (data);
+ egg_bytes_unref (check);
egg_asn1x_destroy (asn);
g_assert (is_freed);
}
@@ -640,10 +678,10 @@ test_any_choice_set_raw_long_tag (void)
static void
test_append (void)
{
+ EggBytes *bytes;
GNode *asn;
GNode *child;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
/* SEQUENCE OF with one INTEGER = 1 */
const gchar SEQOF_ONE[] = "\x30\x03\x02\x01\x01";
@@ -651,8 +689,10 @@ test_append (void)
/* SEQUENCE OF with two INTEGER = 1, 2 */
const gchar SEQOF_TWO[] = "\x30\x06\x02\x01\x01\x02\x01\x02";
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSeqOf", SEQOF_ONE, XL (SEQOF_ONE));
+ bytes = egg_bytes_new_static (SEQOF_ONE, XL (SEQOF_ONE));
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSeqOf", bytes);
g_assert (asn);
+ egg_bytes_unref (bytes);
child = egg_asn1x_append (asn);
g_assert (child);
@@ -661,22 +701,20 @@ test_append (void)
if (!egg_asn1x_set_integer_as_ulong (child, 2))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- g_assert (n_data == XL (SEQOF_TWO));
- g_assert (memcmp (data, SEQOF_TWO, n_data) == 0);
+ egg_assert_equal_bytes (data, SEQOF_TWO, XL (SEQOF_TWO));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_append_and_clear (void)
{
+ EggBytes *data;
GNode *asn;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestSeqOf");
g_assert (asn);
@@ -690,8 +728,8 @@ test_append_and_clear (void)
g_assert_cmpuint (egg_asn1x_count (asn), ==, 0);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
g_assert_cmpuint (egg_asn1x_count (asn), ==, 2);
@@ -699,15 +737,15 @@ test_append_and_clear (void)
g_assert_cmpuint (egg_asn1x_count (asn), ==, 0);
egg_asn1x_destroy (asn);
- g_free (data);
+ egg_bytes_unref (data);
}
static void
test_setof (void)
{
+ EggBytes *bytes;
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
/* SEQUENCE OF with one INTEGER = 3 */
const gchar SETOF_ONE[] = "\x31\x03\x02\x01\x03";
@@ -715,8 +753,10 @@ test_setof (void)
/* SET OF with two INTEGER = 1, 3, 8 */
const gchar SETOF_THREE[] = "\x31\x09\x02\x01\x01\x02\x01\x03\x02\x01\x08";
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSetOf", SETOF_ONE, XL (SETOF_ONE));
- g_assert (asn);
+ bytes = egg_bytes_new_static (SETOF_ONE, XL (SETOF_ONE));
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestSetOf", bytes);
+ g_assert (asn != NULL);
+ egg_bytes_unref (bytes);
/* Add integer 1, in SET OF DER should sort to front */
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_append (asn), 1))
@@ -726,25 +766,23 @@ test_setof (void)
if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_append (asn), 8))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
- if (!data) {
+ data = egg_asn1x_encode (asn, NULL);
+ if (data == NULL) {
g_printerr ("%s\n", egg_asn1x_message (asn));
g_assert_not_reached ();
}
- g_assert (n_data == XL (SETOF_THREE));
- g_assert (memcmp (data, SETOF_THREE, n_data) == 0);
+ egg_assert_equal_bytes (data, SETOF_THREE, XL (SETOF_THREE));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_setof_empty (void)
{
+ EggBytes *data;
GNode *asn;
- gpointer data;
- gsize n_data;
/* SEQUENCE OF with nothing */
const gchar SETOF_NONE[] = "\x31\x00";
@@ -752,29 +790,30 @@ test_setof_empty (void)
asn = egg_asn1x_create (test_asn1_tab, "TestSetOf");
g_assert (asn);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- if (!data) {
+ data = egg_asn1x_encode (asn, NULL);
+ if (data == NULL) {
g_printerr ("%s\n", egg_asn1x_message (asn));
g_assert_not_reached ();
}
- g_assert (n_data == XL (SETOF_NONE));
- g_assert (memcmp (data, SETOF_NONE, n_data) == 0);
+ egg_assert_equal_bytes (data, SETOF_NONE, XL (SETOF_NONE));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_enumerated (void)
{
+ EggBytes *bytes;
GNode *asn;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
GQuark value;
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestEnumerated", ENUM_TWO, XL (ENUM_TWO));
- g_assert (asn);
+ bytes = egg_bytes_new_static (ENUM_TWO, XL (ENUM_TWO));
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestEnumerated", bytes);
+ g_assert (asn != NULL);
+ egg_bytes_unref (bytes);
value = egg_asn1x_get_enumerated (asn);
g_assert (value);
@@ -783,13 +822,12 @@ test_enumerated (void)
if (!egg_asn1x_set_enumerated (asn, g_quark_from_static_string ("valueThree")))
g_assert_not_reached ();
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
- g_assert (n_data == XL (ENUM_THREE));
- g_assert (memcmp (data, ENUM_THREE, n_data) == 0);
+ egg_assert_equal_bytes (data, ENUM_THREE, XL (ENUM_THREE));
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
@@ -802,6 +840,8 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
+ EggBytes *bytes;
+
if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der",
(gchar**)&test->data, &test->n_data, NULL))
g_assert_not_reached ();
@@ -809,8 +849,10 @@ setup (Test *test, gconstpointer unused)
test->asn1 = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_assert (test->asn1 != NULL);
- if (!egg_asn1x_decode (test->asn1, test->data, test->n_data))
+ bytes = egg_bytes_new_static (test->data, test->n_data);
+ if (!egg_asn1x_decode (test->asn1, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
}
static void
@@ -829,9 +871,8 @@ test_node_name (Test* test, gconstpointer unused)
static void
test_asn1_integers (Test* test, gconstpointer unused)
{
+ EggBytes *data;
GNode *asn;
- guchar *data;
- gsize n_data;
gboolean ret;
gulong val;
@@ -848,13 +889,13 @@ test_asn1_integers (Test* test, gconstpointer unused)
g_assert ("couldn't write integer" && ret);
/* Now encode the whole caboodle */
- data = egg_asn1x_encode (asn, NULL, &n_data);
+ data = egg_asn1x_encode (asn, NULL);
g_assert ("encoding asn1 didn't work" && data != NULL);
egg_asn1x_destroy (asn);
/* Now decode it all nicely */
- asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data, n_data);
+ asn = egg_asn1x_create_and_decode (test_asn1_tab, "TestIntegers", data);
g_return_if_fail (asn != NULL);
/* And get out the values */
@@ -870,16 +911,15 @@ test_asn1_integers (Test* test, gconstpointer unused)
g_assert ("couldn't read integer from asn1" && ret);
g_assert_cmpuint (val, ==, 209384022);
- g_free (data);
+ egg_bytes_unref (data);
}
static void
test_boolean_seq (Test* test, gconstpointer unused)
{
+ EggBytes *data;
GNode *asn = NULL;
gboolean value, ret;
- gpointer data;
- gsize n_data;
asn = egg_asn1x_create (test_asn1_tab, "TestBooleanSeq");
g_assert ("asn test structure is null" && asn != NULL);
@@ -893,8 +933,8 @@ test_boolean_seq (Test* test, gconstpointer unused)
ret = egg_asn1x_set_boolean (egg_asn1x_node (asn, "boolean", NULL), TRUE);
g_assert (ret == TRUE);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
g_assert (ret);
@@ -903,26 +943,25 @@ test_boolean_seq (Test* test, gconstpointer unused)
ret = egg_asn1x_set_boolean (egg_asn1x_node (asn, "boolean", NULL), FALSE);
g_assert (ret == TRUE);
- g_free (data);
- data = egg_asn1x_encode (asn, NULL, &n_data);
- g_assert (data);
+ egg_bytes_unref (data);
+ data = egg_asn1x_encode (asn, NULL);
+ g_assert (data != NULL);
ret = egg_asn1x_get_boolean (egg_asn1x_node (asn, "boolean", NULL), &value);
g_assert (ret);
g_assert (value == FALSE);
- g_free (data);
+ egg_bytes_unref (data);
egg_asn1x_destroy (asn);
}
static void
test_write_value (Test* test, gconstpointer unused)
{
+ EggBytes *encoded;
GNode *asn = NULL;
guchar *data;
gsize n_data;
- guchar *encoded;
- gsize n_encoded;
asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
@@ -930,7 +969,7 @@ test_write_value (Test* test, gconstpointer unused)
if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- encoded = egg_asn1x_encode (asn, NULL, &n_encoded);
+ encoded = egg_asn1x_encode (asn, NULL);
g_assert (encoded);
data = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "data", NULL), NULL, &n_data);
@@ -939,18 +978,17 @@ test_write_value (Test* test, gconstpointer unused)
g_assert (memcmp (data, "SOME DATA", 9) == 0);
g_free (data);
- g_free (encoded);
+ egg_bytes_unref (encoded);
egg_asn1x_destroy (asn);
}
static void
test_element_length_content (Test* test, gconstpointer unused)
{
+ EggBytes *buffer;
GNode *asn = NULL;
- gchar *buffer;
const guchar *content;
gsize n_content;
- gsize n_buffer;
gssize length;
asn = egg_asn1x_create (test_asn1_tab, "TestData");
@@ -959,15 +997,17 @@ test_element_length_content (Test* test, gconstpointer unused)
if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
/* Now the real test */
- length = egg_asn1x_element_length (buffer, n_buffer + 1024);
+ length = egg_asn1x_element_length (egg_bytes_get_data (buffer),
+ egg_bytes_get_size (buffer) + 1024);
g_assert_cmpint (length, ==, 13);
- content = egg_asn1x_element_content (buffer, length, &n_content);
- g_assert (content);
+ content = egg_asn1x_element_content (egg_bytes_get_data (buffer),
+ length, &n_content);
+ g_assert (content != NULL);
g_assert_cmpuint (n_content, ==, 11);
content = egg_asn1x_element_content (content, n_content, &n_content);
@@ -975,26 +1015,24 @@ test_element_length_content (Test* test, gconstpointer unused)
g_assert_cmpuint (n_content, ==, 9);
g_assert (memcmp (content, "SOME DATA", 9) == 0);
- const char *BAD_ASN_TAG = "\x00";
+ const guchar *BAD_ASN_TAG = (guchar *)"\x00";
content = egg_asn1x_element_content (BAD_ASN_TAG, 1, &n_content);
g_assert (content == NULL);
- const char *BAD_ASN_LENGTH = "\x30\x80";
+ const guchar *BAD_ASN_LENGTH = (guchar *)"\x30\x80";
content = egg_asn1x_element_content (BAD_ASN_LENGTH, 2, &n_content);
g_assert (content == NULL);
egg_asn1x_destroy (asn);
- g_free (buffer);
+ egg_bytes_unref (buffer);
}
static void
test_read_element (Test* test, gconstpointer unused)
{
+ EggBytes *buffer;
GNode *asn = NULL;
- guchar *buffer;
- gconstpointer data;
- gsize n_data;
- gsize n_buffer;
+ EggBytes *data;
asn = egg_asn1x_create (test_asn1_tab, "TestData");
g_assert ("asn test structure is null" && asn != NULL);
@@ -1002,30 +1040,29 @@ test_read_element (Test* test, gconstpointer unused)
if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "data", NULL), (guchar*)"SOME DATA", 9, NULL))
g_assert_not_reached ();
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
/* Now the real test */
- data = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "data", NULL), &n_data);
+ data = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "data", NULL));
g_assert (data != NULL);
- g_assert_cmpint (n_data, ==, 11);
+ g_assert_cmpint (egg_bytes_get_size (data), ==, 11);
- data = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "data", NULL), &n_data);
- g_assert (data);
- g_assert_cmpuint (n_data, ==, 9);
- g_assert (memcmp (data, "SOME DATA", 9) == 0);
+ data = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "data", NULL));
+ g_assert (data != NULL);
+
+ egg_assert_equal_bytes (data, "SOME DATA", 9);
egg_asn1x_destroy (asn);
- g_free (buffer);
+ egg_bytes_unref (buffer);
}
static void
test_oid (Test* test, gconstpointer unused)
{
+ EggBytes *buffer;
GNode *asn = NULL;
GQuark oid, check;
- guchar *buffer;
- gsize n_buffer;
asn = egg_asn1x_create (test_asn1_tab, "TestOid");
g_assert ("asn test structure is null" && asn != NULL);
@@ -1033,7 +1070,7 @@ test_oid (Test* test, gconstpointer unused)
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);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
/* Now a quark has been defined */
@@ -1047,15 +1084,15 @@ test_oid (Test* test, gconstpointer unused)
if (!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "oid", NULL), g_quark_from_static_string ("5.4.3.2.1678")))
g_assert_not_reached ();
- g_free (buffer);
- buffer = egg_asn1x_encode (asn, NULL, &n_buffer);
+ egg_bytes_unref (buffer);
+ buffer = egg_asn1x_encode (asn, NULL);
g_assert (buffer != NULL);
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "oid", NULL));
g_assert (oid);
g_assert_cmpstr (g_quark_to_string (oid), ==, "5.4.3.2.1678");
- g_free (buffer);
+ egg_bytes_unref (buffer);
egg_asn1x_destroy (asn);
}
diff --git a/egg/tests/test-asn1x.c b/egg/tests/test-asn1x.c
index baeba55..cc60c7f 100644
--- a/egg/tests/test-asn1x.c
+++ b/egg/tests/test-asn1x.c
@@ -67,29 +67,32 @@ static void
test_some_asn1_stuff (const ASN1_ARRAY_TYPE *defs, const gchar *file, const gchar *identifier)
{
GNode *asn;
- gpointer data, encoded;
- gsize n_data, n_encoded;
+ EggBytes *encoded;
+ gpointer data;
+ gsize n_data;
+ EggBytes *bytes;
if (!g_file_get_contents (file, (gchar**)&data, &n_data, NULL))
g_assert_not_reached ();
+ bytes = egg_bytes_new_take (data, n_data);
asn = egg_asn1x_create (defs, identifier);
egg_asn1x_dump (asn);
- if (!egg_asn1x_decode (asn, data, n_data))
+ if (!egg_asn1x_decode (asn, bytes))
g_warning ("decode of %s failed: %s", identifier, egg_asn1x_message (asn));
- encoded = egg_asn1x_encode (asn, NULL, &n_encoded);
+ encoded = egg_asn1x_encode (asn, NULL);
if (encoded == NULL)
g_warning ("encode of %s failed: %s", identifier, egg_asn1x_message (asn));
/* Decode the encoding */
- if (!egg_asn1x_decode (asn, encoded, n_encoded))
+ if (!egg_asn1x_decode (asn, encoded))
g_warning ("decode of encoded %s failed: %s", identifier, egg_asn1x_message (asn));
egg_asn1x_clear (asn);
egg_asn1x_destroy (asn);
- g_free (encoded);
- g_free (data);
+ egg_bytes_unref (bytes);
+ egg_bytes_unref (encoded);
}
int
diff --git a/egg/tests/test-dn.c b/egg/tests/test-dn.c
index 98f5a43..7f95439 100644
--- a/egg/tests/test-dn.c
+++ b/egg/tests/test-dn.c
@@ -45,6 +45,8 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
+ EggBytes *bytes;
+
if (!g_file_get_contents (SRCDIR "/files/test-certificate-1.der",
(gchar**)&test->data, &test->n_data, NULL))
g_assert_not_reached ();
@@ -52,8 +54,10 @@ setup (Test *test, gconstpointer unused)
test->asn1 = egg_asn1x_create (pkix_asn1_tab, "Certificate");
g_assert (test->asn1 != NULL);
- if (!egg_asn1x_decode (test->asn1, test->data, test->n_data))
+ bytes = egg_bytes_new_static (test->data, test->n_data);
+ if (!egg_asn1x_decode (test->asn1, bytes))
g_assert_not_reached ();
+ egg_bytes_unref (bytes);
}
static void
@@ -80,18 +84,23 @@ test_dn_value (Test* test, gconstpointer unused)
{
const guchar value[] = { 0x13, 0x1a, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x50, 0x72, 0x65, 0x6d, 0x69, 0x75, 0x6d, 0x20, 0x43, 0x41 };
gsize n_value = 28;
+ EggBytes *bytes;
GQuark oid;
gchar *text;
/* Some printable strings */
oid = g_quark_from_static_string ("2.5.4.3");
- text = egg_dn_print_value (oid, value, n_value);
+ bytes = egg_bytes_new_static (value, n_value);
+ text = egg_dn_print_value (oid, bytes);
+ egg_bytes_unref (bytes);
g_assert_cmpstr (text, ==, "Thawte Personal Premium CA");
g_free (text);
/* Unknown oid */
oid = g_quark_from_static_string ("1.1.1.1.1.1");
- text = egg_dn_print_value (oid, value, n_value);
+ bytes = egg_bytes_new_static (value, n_value);
+ text = egg_dn_print_value (oid, bytes);
+ egg_bytes_unref (bytes);
g_assert_cmpstr (text, ==, "#131A54686177746520506572736F6E616C205072656D69756D204341");
g_free (text);
}
@@ -99,14 +108,17 @@ test_dn_value (Test* test, gconstpointer unused)
static int last_index = 0;
static void
-concatenate_dn (guint index, GQuark oid, const guchar *value, gsize n_value, gpointer user_data)
+concatenate_dn (guint index,
+ GQuark oid,
+ EggBytes *value,
+ gpointer user_data)
{
GString *dn = user_data;
gchar *text;
g_assert (oid);
- g_assert (value);
- g_assert (n_value);
+ g_assert (value != NULL);
+ g_assert (egg_bytes_get_size (value) != 0);
g_assert (index == last_index);
++last_index;
@@ -118,7 +130,7 @@ concatenate_dn (guint index, GQuark oid, const guchar *value, gsize n_value, gpo
g_string_append (dn, egg_oid_get_name (oid));
g_string_append_c (dn, '=');
- text = egg_dn_print_value (oid, value, n_value);
+ text = egg_dn_print_value (oid, value);
g_string_append (dn, text);
g_free (text);
}
diff --git a/egg/tests/test-openssl.c b/egg/tests/test-openssl.c
index da5e457..d3d672e 100644
--- a/egg/tests/test-openssl.c
+++ b/egg/tests/test-openssl.c
@@ -36,11 +36,12 @@
#include <string.h>
#include <unistd.h>
+#include <egg/egg-bytes.h>
+
EGG_SECURE_GLIB_DEFINITIONS ();
typedef struct {
- guchar *input;
- gsize n_input;
+ EggBytes *input;
GQuark reftype;
guchar *refenc;
guchar *refdata;
@@ -52,14 +53,19 @@ typedef struct {
static void
setup (Test *test, gconstpointer unused)
{
- if (!g_file_get_contents (SRCDIR "/files/pem-rsa-enc.key", (gchar**)&test->input, &test->n_input, NULL))
+ gchar *contents;
+ gsize length;
+
+ if (!g_file_get_contents (SRCDIR "/files/pem-rsa-enc.key", &contents, &length, NULL))
g_assert_not_reached ();
+
+ test->input = egg_bytes_new_take (contents, length);
}
static void
teardown (Test *test, gconstpointer unused)
{
- g_free (test->input);
+ egg_bytes_unref (test->input);
g_free (test->refenc);
egg_secure_free (test->refdata);
g_hash_table_destroy (test->refheaders);
@@ -73,24 +79,21 @@ copy_each_key_value (gpointer key, gpointer value, gpointer user_data)
static void
parse_reference (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
Test *test = user_data;
- gboolean res;
const gchar *dekinfo;
g_assert (type);
test->reftype = type;
g_assert ("no data in PEM callback" && data != NULL);
- g_assert ("no data in PEM callback" && n_data > 0);
- test->refenc = g_memdup (data, n_data);
- test->n_refenc = n_data;
+ g_assert ("no data in PEM callback" && egg_bytes_get_size (data) > 0);
+ test->refenc = g_memdup (egg_bytes_get_data (data), egg_bytes_get_size (data));
+ test->n_refenc = egg_bytes_get_size (data);
g_assert ("no headers present in file" && headers != NULL);
g_assert (!test->refheaders);
@@ -99,10 +102,9 @@ parse_reference (GQuark type,
dekinfo = egg_openssl_get_dekinfo (headers);
g_assert ("no dekinfo in headers" && dekinfo != NULL);
- res = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, n_data, &test->refdata, &test->n_refdata);
- g_assert ("couldn't openssl decrypt block" && res == TRUE);
+ test->refdata = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, &test->n_refdata);
g_assert ("no data returned from openssl decrypt" && test->refdata != NULL);
- g_assert ("invalid amount of data returned from openssl decrypt" && test->n_refdata == n_data);
+ g_assert ("invalid amount of data returned from openssl decrypt" && test->n_refdata == egg_bytes_get_size (data));
}
static void
@@ -110,7 +112,7 @@ test_parse_reference (Test *test, gconstpointer unused)
{
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
g_assert ("parse_reference() wasn't called" && test->refdata != NULL);
@@ -122,17 +124,19 @@ test_write_reference (Test *test, gconstpointer unused)
const gchar *dekinfo;
guchar *encrypted;
gsize n_encrypted;
- gboolean ret;
+ EggBytes *data;
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
dekinfo = egg_openssl_get_dekinfo (test->refheaders);
g_assert ("no dekinfo in headers" && dekinfo != NULL);
- ret = egg_openssl_encrypt_block (dekinfo, "booo", 4, test->refdata, test->n_refdata, &encrypted, &n_encrypted);
- g_assert ("couldn't openssl encrypt block" && ret == TRUE);
+ data = egg_bytes_new_static (test->refdata, test->n_refdata);
+ encrypted = egg_openssl_encrypt_block (dekinfo, "booo", 4, data, &n_encrypted);
+ egg_bytes_unref (data);
+
g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
g_assert ("invalid amount of data returned from openssl encrypt" && test->n_refdata <= n_encrypted);
@@ -147,7 +151,7 @@ test_write_exactly_same (Test *test, gconstpointer unused)
gsize n_result;
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
result = egg_armor_write (test->refenc, test->n_refenc, test->reftype,
@@ -159,7 +163,7 @@ test_write_exactly_same (Test *test, gconstpointer unused)
* and line endings.
*/
- egg_assert_cmpmem (test->input, test->n_input, ==, result, n_result);
+ egg_assert_equal_bytes (test->input, result, n_result);
g_free (result);
}
@@ -171,25 +175,28 @@ static void
test_openssl_roundtrip (Test *test, gconstpointer unused)
{
const gchar *dekinfo;
- gboolean res;
- gboolean ret;
guchar *encrypted, *decrypted;
gsize n_encrypted, n_decrypted;
+ EggBytes *data;
int i;
guint num;
- num = egg_armor_parse (test->input, test->n_input, parse_reference, test);
+ num = egg_armor_parse (test->input, parse_reference, test);
g_assert ("couldn't PEM block in reference data" && num == 1);
dekinfo = egg_openssl_prep_dekinfo (test->refheaders);
- ret = egg_openssl_encrypt_block (dekinfo, "password", -1, TEST_DATA, TEST_DATA_L, &encrypted, &n_encrypted);
- g_assert ("couldn't openssl encrypt block" && ret == TRUE);
+ data = egg_bytes_new_static (TEST_DATA, TEST_DATA_L);
+ encrypted = egg_openssl_encrypt_block (dekinfo, "password", -1, data, &n_encrypted);
+ egg_bytes_unref (data);
+
g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
g_assert ("invalid amount of data returned from openssl encrypt" && TEST_DATA_L <= n_encrypted);
- res = egg_openssl_decrypt_block (dekinfo, "password", 8, encrypted, n_encrypted, &decrypted, &n_decrypted);
- g_assert ("couldn't openssl decrypt block" && res == TRUE);
+ data = egg_bytes_new_with_free_func (encrypted, n_encrypted, egg_secure_free, encrypted);
+ decrypted = egg_openssl_decrypt_block (dekinfo, "password", 8, data, &n_decrypted);
+ egg_bytes_unref (data);
+
g_assert ("no data returned from openssl decrypt" && decrypted != NULL);
/* Check that the data was decrypted properly */
diff --git a/gcr/gcr-certificate-extensions.c b/gcr/gcr-certificate-extensions.c
index 8256da2..f130225 100644
--- a/gcr/gcr-certificate-extensions.c
+++ b/gcr/gcr-certificate-extensions.c
@@ -32,18 +32,18 @@
#include <glib/gi18n-lib.h>
gboolean
-_gcr_certificate_extension_basic_constraints (gconstpointer data, gsize n_data,
- gboolean *is_ca, gint *path_len)
+_gcr_certificate_extension_basic_constraints (EggBytes *data,
+ gboolean *is_ca,
+ gint *path_len)
{
gboolean ret = TRUE;
GNode *asn = NULL;
GNode *node;
gulong value;
- g_return_val_if_fail (data, FALSE);
- g_return_val_if_fail (n_data, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "BasicConstraints", data);
if (asn == NULL)
return FALSE;
@@ -69,8 +69,8 @@ _gcr_certificate_extension_basic_constraints (gconstpointer data, gsize n_data,
return ret;
}
-GQuark*
-_gcr_certificate_extension_extended_key_usage (gconstpointer data, gsize n_data)
+GQuark *
+_gcr_certificate_extension_extended_key_usage (EggBytes *data)
{
GNode *asn = NULL;
GNode *node;
@@ -78,7 +78,9 @@ _gcr_certificate_extension_extended_key_usage (gconstpointer data, gsize n_data)
GQuark oid;
int i;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data, n_data);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "ExtKeyUsageSyntax", data);
if (asn == NULL)
return NULL;
@@ -96,13 +98,15 @@ _gcr_certificate_extension_extended_key_usage (gconstpointer data, gsize n_data)
}
gpointer
-_gcr_certificate_extension_subject_key_identifier (gconstpointer data, gsize n_data,
+_gcr_certificate_extension_subject_key_identifier (EggBytes *data,
gsize *n_keyid)
{
GNode *asn = NULL;
gpointer result;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectKeyIdentifier", data, n_data);
+ g_return_val_if_fail (data != NULL, NULL);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectKeyIdentifier", data);
if (asn == NULL)
return NULL;
@@ -113,14 +117,16 @@ _gcr_certificate_extension_subject_key_identifier (gconstpointer data, gsize n_d
}
gboolean
-_gcr_certificate_extension_key_usage (gconstpointer data, gsize n_data,
+_gcr_certificate_extension_key_usage (EggBytes *data,
gulong *key_usage)
{
GNode *asn = NULL;
gboolean ret = TRUE;
guint n_bits;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "KeyUsage", data, n_data);
+ g_return_val_if_fail (data != NULL, FALSE);
+
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "KeyUsage", data);
if (asn == NULL)
return FALSE;
@@ -134,28 +140,28 @@ general_name_parse_other (GNode *node, GcrGeneralName *general)
{
GNode *decode = NULL;
GQuark oid;
- gconstpointer value;
- gsize n_value;
+ EggBytes *value;
general->type = GCR_GENERAL_NAME_OTHER;
general->description = _("Other Name");
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (node, "type-id", NULL));
- value = egg_asn1x_get_raw_element (egg_asn1x_node (node, "value", NULL), &n_value);
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (node, "value", NULL));
if (value == NULL)
return;
if (oid == GCR_OID_ALT_NAME_XMPP_ADDR) {
general->description = _("XMPP Addr");
- decode = egg_asn1x_create_and_decode (pkix_asn1_tab, "UTF8String", value, n_value);
+ decode = egg_asn1x_create_and_decode (pkix_asn1_tab, "UTF8String", value);
general->display = egg_asn1x_get_string_as_utf8 (decode, g_realloc);
} else if (oid == GCR_OID_ALT_NAME_DNS_SRV) {
general->description = _("DNS SRV");
- decode = egg_asn1x_create_and_decode (pkix_asn1_tab, "IA5String", value, n_value);
+ decode = egg_asn1x_create_and_decode (pkix_asn1_tab, "IA5String", value);
general->display = egg_asn1x_get_string_as_utf8 (decode, g_realloc);
}
+ egg_bytes_unref (value);
egg_asn1x_destroy (decode);
}
@@ -222,7 +228,7 @@ general_name_parse_registered (GNode *node, GcrGeneralName *general)
}
GArray*
-_gcr_certificate_extension_subject_alt_name (gconstpointer data, gsize n_data)
+_gcr_certificate_extension_subject_alt_name (EggBytes *data)
{
GNode *asn = NULL;
guint count, i;
@@ -233,7 +239,7 @@ _gcr_certificate_extension_subject_alt_name (gconstpointer data, gsize n_data)
_gcr_oids_init ();
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectAltName", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectAltName", data);
if (asn == NULL)
return NULL;
@@ -276,7 +282,7 @@ _gcr_certificate_extension_subject_alt_name (gconstpointer data, gsize n_data)
else if (g_str_equal (node_name, "registeredID"))
general_name_parse_registered (choice, &general);
- general.raw = egg_asn1x_get_raw_element (choice, &general.n_raw);
+ general.raw = egg_asn1x_get_raw_element (choice);
g_array_append_val (names, general);
}
@@ -287,9 +293,13 @@ _gcr_certificate_extension_subject_alt_name (gconstpointer data, gsize n_data)
void
_gcr_general_names_free (GArray *names)
{
+ GcrGeneralName *name;
guint i;
- for (i = 0; names && i < names->len; i++)
- g_free (g_array_index (names, GcrGeneralName, i).display);
+ for (i = 0; names && i < names->len; i++) {
+ name = &g_array_index (names, GcrGeneralName, i);
+ g_free (name->display);
+ egg_bytes_unref (name->raw);
+ }
g_array_free (names, TRUE);
}
diff --git a/gcr/gcr-certificate-extensions.h b/gcr/gcr-certificate-extensions.h
index 9101008..ea5792f 100644
--- a/gcr/gcr-certificate-extensions.h
+++ b/gcr/gcr-certificate-extensions.h
@@ -30,18 +30,17 @@
#include <glib.h>
+#include <egg/egg-bytes.h>
+
G_BEGIN_DECLS
-gboolean _gcr_certificate_extension_basic_constraints (gconstpointer data,
- gsize n_data,
+gboolean _gcr_certificate_extension_basic_constraints (EggBytes *data,
gboolean *is_ca,
gint *path_len);
-GQuark* _gcr_certificate_extension_extended_key_usage (gconstpointer data,
- gsize n_data);
+GQuark * _gcr_certificate_extension_extended_key_usage (EggBytes *data);
-gpointer _gcr_certificate_extension_subject_key_identifier (gconstpointer data,
- gsize n_data,
+gpointer _gcr_certificate_extension_subject_key_identifier (EggBytes *data,
gsize *n_keyid);
typedef enum {
@@ -54,8 +53,7 @@ typedef enum {
GCR_KEY_USAGE_CRL_SIGN = 1 << 6,
} GcrCertificateExtensionKeyUsage;
-gboolean _gcr_certificate_extension_key_usage (gconstpointer data,
- gsize n_data,
+gboolean _gcr_certificate_extension_key_usage (EggBytes *data,
gulong *key_usage);
typedef enum {
@@ -74,12 +72,10 @@ typedef struct {
GcrGeneralNameType type;
const gchar *description;
gchar *display;
- gconstpointer raw;
- gsize n_raw;
+ EggBytes *raw;
} GcrGeneralName;
-GArray * _gcr_certificate_extension_subject_alt_name (gconstpointer data,
- gsize n_data);
+GArray * _gcr_certificate_extension_subject_alt_name (EggBytes *data);
void _gcr_general_names_free (GArray *names);
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
index 7995917..a350d3e 100644
--- a/gcr/gcr-certificate-renderer.c
+++ b/gcr/gcr-certificate-renderer.c
@@ -102,15 +102,16 @@ calculate_label (GcrCertificateRenderer *self)
}
static gboolean
-append_extension_basic_constraints (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
+append_extension_basic_constraints (GcrCertificateRenderer *self,
+ GcrDisplayView *view,
+ EggBytes *data)
{
GcrRenderer *renderer = GCR_RENDERER (self);
gboolean is_ca = FALSE;
gint path_len = -1;
gchar *number;
- if (!_gcr_certificate_extension_basic_constraints (data, n_data, &is_ca, &path_len))
+ if (!_gcr_certificate_extension_basic_constraints (data, &is_ca, &path_len))
return FALSE;
_gcr_display_view_append_heading (view, renderer, _("Basic Constraints"));
@@ -127,15 +128,16 @@ append_extension_basic_constraints (GcrCertificateRenderer *self, GcrDisplayView
}
static gboolean
-append_extension_extended_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
+append_extension_extended_key_usage (GcrCertificateRenderer *self,
+ GcrDisplayView *view,
+ EggBytes *data)
{
GcrRenderer *renderer = GCR_RENDERER (self);
GQuark *oids;
GString *text;
guint i;
- oids = _gcr_certificate_extension_extended_key_usage (data, n_data);
+ oids = _gcr_certificate_extension_extended_key_usage (data);
if (oids == NULL)
return FALSE;
@@ -159,14 +161,15 @@ append_extension_extended_key_usage (GcrCertificateRenderer *self, GcrDisplayVie
}
static gboolean
-append_extension_subject_key_identifier (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
+append_extension_subject_key_identifier (GcrCertificateRenderer *self,
+ GcrDisplayView *view,
+ EggBytes *data)
{
GcrRenderer *renderer = GCR_RENDERER (self);
gpointer keyid;
gsize n_keyid;
- keyid = _gcr_certificate_extension_subject_key_identifier (data, n_data, &n_keyid);
+ keyid = _gcr_certificate_extension_subject_key_identifier (data, &n_keyid);
if (keyid == NULL)
return FALSE;
@@ -191,15 +194,16 @@ static const struct {
};
static gboolean
-append_extension_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
+append_extension_key_usage (GcrCertificateRenderer *self,
+ GcrDisplayView *view,
+ EggBytes *data)
{
GcrRenderer *renderer = GCR_RENDERER (self);
gulong key_usage;
GString *text;
guint i;
- if (!_gcr_certificate_extension_key_usage (data, n_data, &key_usage))
+ if (!_gcr_certificate_extension_key_usage (data, &key_usage))
return FALSE;
text = g_string_new ("");
@@ -221,15 +225,16 @@ append_extension_key_usage (GcrCertificateRenderer *self, GcrDisplayView *view,
}
static gboolean
-append_extension_subject_alt_name (GcrCertificateRenderer *self, GcrDisplayView *view,
- gconstpointer data, gsize n_data)
+append_extension_subject_alt_name (GcrCertificateRenderer *self,
+ GcrDisplayView *view,
+ EggBytes *data)
{
GcrRenderer *renderer = GCR_RENDERER (self);
GArray *general_names;
GcrGeneralName *general;
guint i;
- general_names = _gcr_certificate_extension_subject_alt_name (data, n_data);
+ general_names = _gcr_certificate_extension_subject_alt_name (data);
if (general_names == NULL)
return FALSE;
@@ -239,7 +244,8 @@ append_extension_subject_alt_name (GcrCertificateRenderer *self, GcrDisplayView
general = &g_array_index (general_names, GcrGeneralName, i);
if (general->display == NULL)
_gcr_display_view_append_hex (view, renderer, general->description,
- general->raw, general->n_raw);
+ egg_bytes_get_data (general->raw),
+ egg_bytes_get_size (general->raw));
else
_gcr_display_view_append_value (view, renderer, general->description,
general->display, FALSE);
@@ -269,14 +275,15 @@ append_extension_hex (GcrCertificateRenderer *self, GcrDisplayView *view,
}
static gboolean
-append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
- GNode *asn, const guchar *data, gsize n_data, gint index)
+append_extension (GcrCertificateRenderer *self,
+ GcrDisplayView *view,
+ GNode *asn,
+ gint index)
{
GcrRenderer *renderer = GCR_RENDERER (self);
GNode *node;
GQuark oid;
- gsize n_value;
- const guchar *value;
+ EggBytes *value;
gboolean critical;
gboolean ret = FALSE;
@@ -290,23 +297,25 @@ append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
g_return_val_if_fail (oid, FALSE);
/* Extension value */
- value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL), &n_value);
+ value = egg_asn1x_get_raw_value (egg_asn1x_node (node, "extnValue", NULL));
/* The custom parsers */
if (oid == GCR_OID_BASIC_CONSTRAINTS)
- ret = append_extension_basic_constraints (self, view, value, n_value);
+ ret = append_extension_basic_constraints (self, view, value);
else if (oid == GCR_OID_EXTENDED_KEY_USAGE)
- ret = append_extension_extended_key_usage (self, view, value, n_value);
+ ret = append_extension_extended_key_usage (self, view, value);
else if (oid == GCR_OID_SUBJECT_KEY_IDENTIFIER)
- ret = append_extension_subject_key_identifier (self, view, value, n_value);
+ ret = append_extension_subject_key_identifier (self, view, value);
else if (oid == GCR_OID_KEY_USAGE)
- ret = append_extension_key_usage (self, view, value, n_value);
+ ret = append_extension_key_usage (self, view, value);
else if (oid == GCR_OID_SUBJECT_ALT_NAME)
- ret = append_extension_subject_alt_name (self, view, value, n_value);
+ ret = append_extension_subject_alt_name (self, view, value);
/* Otherwise the default raw display */
if (ret == FALSE)
- ret = append_extension_hex (self, view, oid, value, n_value);
+ ret = append_extension_hex (self, view, oid,
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
/* Critical */
if (ret == TRUE && egg_asn1x_get_boolean (egg_asn1x_node (node, "critical", NULL), &critical)) {
@@ -314,6 +323,7 @@ append_extension (GcrCertificateRenderer *self, GcrDisplayView *view,
critical ? _("Yes") : _("No"), FALSE);
}
+ egg_bytes_unref (value);
return ret;
}
@@ -323,8 +333,10 @@ typedef struct _on_parsed_dn_args {
} on_parsed_dn_args;
static void
-on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
- gsize n_value, gpointer user_data)
+on_parsed_dn_part (guint index,
+ GQuark oid,
+ EggBytes *value,
+ gpointer user_data)
{
GcrCertificateRenderer *self = ((on_parsed_dn_args*)user_data)->renderer;
GcrDisplayView *view = ((on_parsed_dn_args*)user_data)->view;
@@ -354,7 +366,7 @@ on_parsed_dn_part (guint index, GQuark oid, const guchar *value,
g_assert_not_reached ();
}
- display = egg_dn_print_value (oid, value, n_value);
+ display = egg_dn_print_value (oid, value);
if (display == NULL)
display = g_strdup ("");
@@ -562,17 +574,19 @@ static void
gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
{
GcrCertificateRenderer *self;
- gconstpointer data, value;
- gsize n_data, n_value, n_raw;
+ gconstpointer data;
+ gsize n_data, n_raw;
GcrDisplayView *view;
on_parsed_dn_args args;
const gchar *text;
GcrCertificate *cert;
gpointer raw;
- gconstpointer number;
+ EggBytes *number;
gulong version;
guint bits, index;
gchar *display;
+ EggBytes *bytes;
+ EggBytes *value;
GNode *asn;
GQuark oid;
GDate date;
@@ -602,8 +616,10 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_set_icon (view, GCR_RENDERER (self), icon);
g_object_unref (icon);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
- g_return_if_fail (asn);
+ bytes = egg_bytes_new_static (data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes);
+ g_return_if_fail (asn != NULL);
+ egg_bytes_unref (bytes);
display = calculate_label (self);
_gcr_display_view_append_title (view, renderer, display);
@@ -647,9 +663,12 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_append_value (view, renderer, _("Version"), display, FALSE);
g_free (display);
- number = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL), &n_raw);
+ number = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "tbsCertificate", "serialNumber", NULL));
g_return_if_fail (number != NULL);
- _gcr_display_view_append_hex (view, renderer, _("Serial Number"), number, n_raw);
+ _gcr_display_view_append_hex (view, renderer, _("Serial Number"),
+ egg_bytes_get_data (number),
+ egg_bytes_get_size (number));
+ egg_bytes_unref (number);
display = g_malloc0 (128);
if (egg_asn1x_get_time_as_date (egg_asn1x_node (asn, "tbsCertificate", "validity", "notBefore", NULL), &date)) {
@@ -677,14 +696,19 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
text = egg_oid_get_description (oid);
_gcr_display_view_append_value (view, renderer, _("Signature Algorithm"), text, FALSE);
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL), &n_value);
- if (value && n_value)
- _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"), value, n_value);
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "signatureAlgorithm", "parameters", NULL));
+ if (value) {
+ _gcr_display_view_append_hex (view, renderer, _("Signature Parameters"),
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
+ egg_bytes_unref (value);
+ }
- raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), NULL, &bits);
- g_return_if_fail (raw);
- _gcr_display_view_append_hex (view, renderer, _("Signature"), raw, bits / 8);
- g_free (raw);
+ value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "signature", NULL), &bits);
+ g_return_if_fail (value != NULL);
+ _gcr_display_view_append_hex (view, renderer, _("Signature"),
+ egg_bytes_get_data (value), bits / 8);
+ egg_bytes_unref (value);
/* Public Key Info */
_gcr_display_view_append_heading (view, renderer, _("Public Key Info"));
@@ -695,9 +719,13 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
_gcr_display_view_append_value (view, renderer, _("Key Algorithm"), text, FALSE);
value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "algorithm", "parameters", NULL), &n_value);
- if (value && n_value)
- _gcr_display_view_append_hex (view, renderer, _("Key Parameters"), value, n_value);
+ "algorithm", "parameters", NULL));
+ if (value) {
+ _gcr_display_view_append_hex (view, renderer, _("Key Parameters"),
+ egg_bytes_get_data (value),
+ egg_bytes_get_size (value));
+ egg_bytes_unref (value);
+ }
bits = gcr_certificate_get_key_size (cert);
if (bits > 0) {
@@ -707,20 +735,23 @@ gcr_certificate_renderer_render (GcrRenderer *renderer, GcrViewer *viewer)
}
value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate",
- "subjectPublicKeyInfo", NULL), &n_value);
- raw = gcr_fingerprint_from_subject_public_key_info (value, n_value, G_CHECKSUM_SHA1, &n_raw);
+ "subjectPublicKeyInfo", NULL));
+ raw = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (bytes),
+ egg_bytes_get_size (bytes),
+ G_CHECKSUM_SHA1, &n_raw);
_gcr_display_view_append_hex (view, renderer, _("Key SHA1 Fingerprint"), raw, n_raw);
g_free (raw);
- raw = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
- "subjectPublicKey", NULL), NULL, &bits);
- g_return_if_fail (raw);
- _gcr_display_view_append_hex (view, renderer, _("Public Key"), raw, bits / 8);
- g_free (raw);
+ value = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo",
+ "subjectPublicKey", NULL), &bits);
+ g_return_if_fail (value != NULL);
+ _gcr_display_view_append_hex (view, renderer, _("Public Key"),
+ egg_bytes_get_data (value), bits / 8);
+ egg_bytes_unref (value);
/* Extensions */
for (index = 1; TRUE; ++index) {
- if (!append_extension (self, view, asn, data, n_data, index))
+ if (!append_extension (self, view, asn, index))
break;
}
diff --git a/gcr/gcr-certificate.c b/gcr/gcr-certificate.c
index 5dd16ab..889c67a 100644
--- a/gcr/gcr-certificate.c
+++ b/gcr/gcr-certificate.c
@@ -104,8 +104,8 @@ typedef struct _GcrCertificateInfo {
/* Forward declarations */
-static gconstpointer _gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data);
-static gconstpointer _gcr_certificate_get_issuer_const (GcrCertificate *self, gsize *n_data);
+static EggBytes * _gcr_certificate_get_subject_const (GcrCertificate *self);
+static EggBytes * _gcr_certificate_get_issuer_const (GcrCertificate *self);
enum {
PROP_FIRST = 0x0007000,
@@ -139,6 +139,7 @@ static GcrCertificateInfo*
certificate_info_load (GcrCertificate *cert)
{
GcrCertificateInfo *info;
+ EggBytes *bytes;
GNode *asn1;
gconstpointer der;
gsize n_der;
@@ -154,8 +155,14 @@ certificate_info_load (GcrCertificate *cert)
return info;
}
+ /* TODO: Once GBytes is public, add to GcrCertificate interface */
+ bytes = egg_bytes_new_static (der, n_der);
+
/* Cache is invalid or non existent */
- asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", der, n_der);
+ asn1 = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes);
+
+ egg_bytes_unref (bytes);
+
if (asn1 == NULL) {
g_warning ("a derived class provided an invalid or unparseable X.509 DER certificate data.");
return NULL;
@@ -171,56 +178,67 @@ certificate_info_load (GcrCertificate *cert)
}
static guint
-calculate_rsa_key_size (gconstpointer data, gsize n_data)
+calculate_rsa_key_size (EggBytes *data)
{
+ EggBytes *content;
+ guint key_size;
GNode *asn;
- gsize n_content;
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data, n_data);
- g_return_val_if_fail (asn, 0);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPublicKey", data);
+ g_return_val_if_fail (asn != NULL, 0);
- if (!egg_asn1x_get_raw_value (egg_asn1x_node (asn, "modulus", NULL), &n_content))
+ content = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "modulus", NULL));
+ if (!content)
g_return_val_if_reached (0);
egg_asn1x_destroy (asn);
/* Removes the complement */
- return (n_content / 2) * 2 * 8;
+ key_size = (egg_bytes_get_size (content) / 2) * 2 * 8;
+
+ egg_bytes_unref (content);
+ return key_size;
}
static guint
-calculate_dsa_params_size (gconstpointer data, gsize n_data)
+calculate_dsa_params_size (EggBytes *data)
{
+ EggBytes *content;
+ gsize params_size;
GNode *asn;
- gsize n_content;
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", data, n_data);
- g_return_val_if_fail (asn, 0);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", data);
+ g_return_val_if_fail (asn != NULL, 0);
- if (!egg_asn1x_get_raw_value (egg_asn1x_node (asn, "p", NULL), &n_content))
+ content = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "p", NULL));
+ if (!content)
g_return_val_if_reached (0);
egg_asn1x_destroy (asn);
/* Removes the complement */
- return (n_content / 2) * 2 * 8;
+ params_size = (egg_bytes_get_size (content) / 2) * 2 * 8;
+
+ egg_bytes_unref (content);
+ return params_size;
}
static guint
calculate_key_size (GcrCertificateInfo *info)
{
GNode *asn;
- gconstpointer data, params;
- gsize n_data, n_params;
+ EggBytes *data;
guint key_size = 0, n_bits;
- guchar *key = NULL;
+ EggBytes *key;
GQuark oid;
- data = egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_data);
+ data = egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subjectPublicKeyInfo", NULL));
g_return_val_if_fail (data != NULL, 0);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data, n_data);
- g_return_val_if_fail (asn, 0);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "SubjectPublicKeyInfo", data);
+ g_return_val_if_fail (asn != NULL, 0);
+
+ egg_bytes_unref (data);
/* Figure out the algorithm */
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "algorithm", "algorithm", NULL));
@@ -230,15 +248,16 @@ calculate_key_size (GcrCertificateInfo *info)
if (oid == GCR_OID_PKIX1_RSA) {
/* A bit string so we cannot process in place */
- key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), NULL, &n_bits);
- g_return_val_if_fail (key, 0);
- key_size = calculate_rsa_key_size (key, n_bits / 8);
- g_free (key);
+ key = egg_asn1x_get_bits_as_raw (egg_asn1x_node (asn, "subjectPublicKey", NULL), &n_bits);
+ g_return_val_if_fail (key != NULL, 0);
+ key_size = calculate_rsa_key_size (key);
+ egg_bytes_unref (key);
/* The DSA key size is discovered by the prime in params */
} else if (oid == GCR_OID_PKIX1_DSA) {
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL), &n_params);
- key_size = calculate_dsa_params_size (params, n_params);
+ key = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "algorithm", "parameters", NULL));
+ key_size = calculate_dsa_params_size (key);
+ egg_bytes_unref (key);
} else {
g_message ("unsupported key algorithm in certificate: %s", g_quark_to_string (oid));
@@ -495,18 +514,17 @@ gcr_certificate_get_issuer_part (GcrCertificate *self, const char *part)
return egg_dn_read_part (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", "rdnSequence", NULL), part);
}
-static gconstpointer
-_gcr_certificate_get_issuer_const (GcrCertificate *self, gsize *n_data)
+static EggBytes *
+_gcr_certificate_get_issuer_const (GcrCertificate *self)
{
GcrCertificateInfo *info;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
- return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", NULL), n_data);
+ return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "issuer", NULL));
}
/**
@@ -525,13 +543,21 @@ guchar *
gcr_certificate_get_issuer_raw (GcrCertificate *self,
gsize *n_data)
{
- gconstpointer data;
+ EggBytes *bytes;
+ guchar *result;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
g_return_val_if_fail (n_data != NULL, NULL);
- data = _gcr_certificate_get_issuer_const (self, n_data);
- return g_memdup (data, data ? *n_data : 0);
+ bytes = _gcr_certificate_get_issuer_const (self);
+ if (bytes == NULL)
+ return NULL;
+
+ *n_data = egg_bytes_get_size (bytes);
+ result = g_memdup (egg_bytes_get_data (bytes), *n_data);
+ egg_bytes_unref (bytes);
+
+ return result;
}
/**
@@ -549,20 +575,25 @@ gcr_certificate_get_issuer_raw (GcrCertificate *self,
gboolean
gcr_certificate_is_issuer (GcrCertificate *self, GcrCertificate *issuer)
{
- gconstpointer subject_dn, issuer_dn;
- gsize n_subject_dn, n_issuer_dn;
+ EggBytes *subject_dn;
+ EggBytes *issuer_dn;
+ gboolean ret;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), FALSE);
g_return_val_if_fail (GCR_IS_CERTIFICATE (issuer), FALSE);
- subject_dn = _gcr_certificate_get_subject_const (issuer, &n_subject_dn);
+ subject_dn = _gcr_certificate_get_subject_const (issuer);
g_return_val_if_fail (subject_dn, FALSE);
- issuer_dn = _gcr_certificate_get_issuer_const (self, &n_issuer_dn);
+ issuer_dn = _gcr_certificate_get_issuer_const (self);
g_return_val_if_fail (issuer_dn, FALSE);
- return (n_issuer_dn == n_subject_dn &&
- memcmp (issuer_dn, subject_dn, n_issuer_dn) == 0);
+ ret = egg_bytes_equal (subject_dn, issuer_dn);
+
+ egg_bytes_unref (subject_dn);
+ egg_bytes_unref (issuer_dn);
+
+ return ret;
}
/**
@@ -663,18 +694,17 @@ gcr_certificate_get_subject_dn (GcrCertificate *self)
return egg_dn_read (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", "rdnSequence", NULL));
}
-static gconstpointer
-_gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data)
+static EggBytes *
+_gcr_certificate_get_subject_const (GcrCertificate *self)
{
GcrCertificateInfo *info;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
- g_return_val_if_fail (n_data != NULL, NULL);
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
- return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", NULL), n_data);
+ return egg_asn1x_get_raw_element (egg_asn1x_node (info->asn1, "tbsCertificate", "subject", NULL));
}
/**
@@ -692,17 +722,22 @@ _gcr_certificate_get_subject_const (GcrCertificate *self, gsize *n_data)
guchar *
gcr_certificate_get_subject_raw (GcrCertificate *self, gsize *n_data)
{
- GcrCertificateInfo *info;
- gconstpointer data;
+ EggBytes *bytes;
+ guchar *result;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
g_return_val_if_fail (n_data != NULL, NULL);
- info = certificate_info_load (self);
- g_return_val_if_fail (info, NULL);
+ bytes = _gcr_certificate_get_subject_const (self);
+ if (bytes == NULL)
+ return NULL;
+
+ *n_data = egg_bytes_get_size (bytes);
+ result = g_memdup (egg_bytes_get_data (bytes), *n_data);
+
+ egg_bytes_unref (bytes);
- data = _gcr_certificate_get_subject_const (self, n_data);
- return g_memdup (data, data ? *n_data : 0);
+ return result;
}
/**
@@ -886,7 +921,8 @@ guchar *
gcr_certificate_get_serial_number (GcrCertificate *self, gsize *n_length)
{
GcrCertificateInfo *info;
- const guchar *serial;
+ EggBytes *bytes;
+ guchar *result;
g_return_val_if_fail (GCR_IS_CERTIFICATE (self), NULL);
g_return_val_if_fail (n_length != NULL, NULL);
@@ -894,8 +930,14 @@ gcr_certificate_get_serial_number (GcrCertificate *self, gsize *n_length)
info = certificate_info_load (self);
g_return_val_if_fail (info, NULL);
- serial = egg_asn1x_get_integer_as_raw (egg_asn1x_node (info->asn1, "tbsCertificate", "serialNumber", NULL), n_length);
- return g_memdup (serial, *n_length);
+ bytes = egg_asn1x_get_integer_as_raw (egg_asn1x_node (info->asn1, "tbsCertificate", "serialNumber", NULL));
+ g_return_val_if_fail (bytes != NULL, NULL);
+
+ *n_length = egg_bytes_get_size (bytes);
+ result = g_memdup (egg_bytes_get_data (bytes), *n_length);
+
+ egg_bytes_unref (bytes);
+ return result;
}
/**
diff --git a/gcr/gcr-fingerprint.c b/gcr/gcr-fingerprint.c
index 39d9319..c84b977 100644
--- a/gcr/gcr-fingerprint.c
+++ b/gcr/gcr-fingerprint.c
@@ -91,10 +91,11 @@ rsa_subject_public_key_from_attributes (GckAttributes *attrs, GNode *info_asn)
{
GckAttribute *modulus;
GckAttribute *exponent;
+ EggBytes *key;
+ EggBytes *params;
GNode *key_asn;
GNode *params_asn;
- gpointer key, params;
- gsize n_key, n_params;
+ EggBytes *usg;
_gcr_oids_init ();
@@ -109,27 +110,34 @@ rsa_subject_public_key_from_attributes (GckAttributes *attrs, GNode *info_asn)
params_asn = egg_asn1x_create (pk_asn1_tab, "RSAParameters");
g_return_val_if_fail (params_asn, FALSE);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "modulus", NULL),
- modulus->value, modulus->length, NULL);
+ usg = egg_bytes_new_with_free_func (modulus->value, modulus->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs));
+ egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "modulus", NULL), usg);
+ egg_bytes_unref (usg);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "publicExponent", NULL),
- exponent->value, exponent->length, NULL);
+ usg = egg_bytes_new_with_free_func (exponent->value, exponent->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs));
+ egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "publicExponent", NULL), usg);
+ egg_bytes_unref (usg);
- key = egg_asn1x_encode (key_asn, g_realloc, &n_key);
+ key = egg_asn1x_encode (key_asn, NULL);
egg_asn1x_destroy (key_asn);
egg_asn1x_set_null (params_asn);
- params = egg_asn1x_encode (params_asn, g_realloc, &n_params);
+ params = egg_asn1x_encode (params_asn, g_realloc);
egg_asn1x_destroy (params_asn);
egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
- key, n_key * 8, g_free);
+ key, egg_bytes_get_size (key) * 8);
egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_RSA);
- egg_asn1x_set_raw_element (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL),
- params, n_params, g_free);
+ egg_asn1x_set_raw_element (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params);
+ egg_bytes_unref (key);
+ egg_bytes_unref (params);
return TRUE;
}
@@ -161,7 +169,8 @@ dsa_subject_public_key_from_private (GNode *key_asn, GckAttribute *ap,
gcry = gcry_mpi_aprint (GCRYMPI_FMT_STD, &buffer, &n_buffer, my);
g_return_val_if_fail (gcry == 0, FALSE);
- egg_asn1x_set_integer_as_raw (key_asn, buffer, n_buffer, gcry_free);
+ egg_asn1x_take_integer_as_raw (key_asn, egg_bytes_new_with_free_func (buffer, n_buffer,
+ gcry_free, buffer));
gcry_mpi_release (mp);
gcry_mpi_release (mq);
@@ -179,8 +188,8 @@ dsa_subject_public_key_from_attributes (GckAttributes *attrs,
{
GckAttribute *value, *g, *q, *p;
GNode *key_asn, *params_asn;
- gpointer key, params;
- gsize n_key, n_params;
+ EggBytes *key;
+ EggBytes *params;
_gcr_oids_init ();
@@ -198,9 +207,18 @@ dsa_subject_public_key_from_attributes (GckAttributes *attrs,
params_asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters");
g_return_val_if_fail (params_asn, FALSE);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL), p->value, p->length, NULL);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL), q->value, q->length, NULL);
- egg_asn1x_set_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL), g->value, g->length, NULL);
+ egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL),
+ egg_bytes_new_with_free_func (p->value, p->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs)));
+ egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL),
+ egg_bytes_new_with_free_func (q->value, q->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs)));
+ egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL),
+ egg_bytes_new_with_free_func (g->value, g->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs)));
/* Are these attributes for a public or private key? */
if (klass == CKO_PRIVATE_KEY) {
@@ -210,25 +228,29 @@ dsa_subject_public_key_from_attributes (GckAttributes *attrs,
g_return_val_if_reached (FALSE);
} else if (klass == CKO_PUBLIC_KEY) {
- egg_asn1x_set_integer_as_usg (key_asn, value->value, value->length, NULL);
+ egg_asn1x_take_integer_as_usg (key_asn,
+ egg_bytes_new_with_free_func (value->value, value->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs)));
} else {
g_assert_not_reached ();
}
- key = egg_asn1x_encode (key_asn, g_realloc, &n_key);
+ key = egg_asn1x_encode (key_asn, NULL);
egg_asn1x_destroy (key_asn);
- params = egg_asn1x_encode (params_asn, g_realloc, &n_params);
+ params = egg_asn1x_encode (params_asn, NULL);
egg_asn1x_destroy (params_asn);
- egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
- key, n_key * 8, g_free);
- egg_asn1x_set_raw_element (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL),
- params, n_params, g_free);
+ egg_asn1x_take_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL),
+ key, egg_bytes_get_size (key) * 8);
+ egg_asn1x_set_raw_element (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params);
egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_DSA);
+ egg_bytes_unref (key);
+ egg_bytes_unref (params);
return TRUE;
}
@@ -241,9 +263,8 @@ fingerprint_from_key_attributes (GckAttributes *attrs,
gpointer fingerprint = NULL;
gboolean ret = FALSE;
GNode *info_asn;
- gpointer info;
+ EggBytes *info;
gulong key_type;
- gsize n_info;
if (!gck_attributes_find_ulong (attrs, CKA_KEY_TYPE, &key_type))
return NULL;
@@ -261,11 +282,12 @@ fingerprint_from_key_attributes (GckAttributes *attrs,
ret = FALSE;
if (ret) {
- info = egg_asn1x_encode (info_asn, g_realloc, &n_info);
- fingerprint = gcr_fingerprint_from_subject_public_key_info (info, n_info,
+ info = egg_asn1x_encode (info_asn, NULL);
+ fingerprint = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (info),
+ egg_bytes_get_size (info),
checksum_type,
n_fingerprint);
- g_free (info);
+ egg_bytes_unref (info);
}
egg_asn1x_destroy (info_asn);
@@ -273,25 +295,23 @@ fingerprint_from_key_attributes (GckAttributes *attrs,
}
static guchar *
-fingerprint_from_cert_value (const guchar *der_data,
- gsize n_der_data,
+fingerprint_from_cert_value (EggBytes *der_data,
GChecksumType checksum_type,
gsize *n_fingerprint)
{
guchar *fingerprint;
GNode *cert_asn;
- gconstpointer info;
- gsize n_info;
+ EggBytes *info;
- cert_asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate",
- der_data, n_der_data);
+ cert_asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", der_data);
if (cert_asn == NULL)
return NULL;
- info = egg_asn1x_get_raw_element (egg_asn1x_node (cert_asn, "tbsCertificate", "subjectPublicKeyInfo", NULL), &n_info);
+ info = egg_asn1x_get_raw_element (egg_asn1x_node (cert_asn, "tbsCertificate", "subjectPublicKeyInfo", NULL));
g_return_val_if_fail (info != NULL, NULL);
- fingerprint = gcr_fingerprint_from_subject_public_key_info (info, n_info,
+ fingerprint = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (info),
+ egg_bytes_get_size (info),
checksum_type,
n_fingerprint);
@@ -305,13 +325,20 @@ fingerprint_from_cert_attributes (GckAttributes *attrs,
gsize *n_fingerprint)
{
GckAttribute *attr;
+ EggBytes *bytes;
+ guchar *fingerprint;
attr = gck_attributes_find (attrs, CKA_VALUE);
if (attr == NULL)
return NULL;
- return fingerprint_from_cert_value (attr->value, attr->length, checksum_type,
- n_fingerprint);
+ bytes = egg_bytes_new_with_free_func (attr->value, attr->length,
+ gck_attributes_unref,
+ gck_attributes_ref (attrs));
+ fingerprint = fingerprint_from_cert_value (bytes, checksum_type, n_fingerprint);
+
+ egg_bytes_unref (bytes);
+ return fingerprint;
}
/**
@@ -373,12 +400,18 @@ gcr_fingerprint_from_certificate_public_key (GcrCertificate *certificate,
{
const guchar *der_data;
gsize n_der_data;
+ EggBytes *bytes;
+ guchar *fingerprint;
g_return_val_if_fail (GCR_IS_CERTIFICATE (certificate), NULL);
der_data = gcr_certificate_get_der_data (certificate, &n_der_data);
g_return_val_if_fail (der_data != NULL, NULL);
- return fingerprint_from_cert_value (der_data, n_der_data, checksum_type,
- n_fingerprint);
+ bytes = egg_bytes_new_with_free_func (der_data, n_der_data, g_object_unref,
+ g_object_ref (certificate));
+ fingerprint = fingerprint_from_cert_value (bytes, checksum_type, n_fingerprint);
+ egg_bytes_unref (bytes);
+
+ return fingerprint;
}
diff --git a/gcr/gcr-openpgp.c b/gcr/gcr-openpgp.c
index 3bd41bb..b80f560 100644
--- a/gcr/gcr-openpgp.c
+++ b/gcr/gcr-openpgp.c
@@ -1197,6 +1197,7 @@ typedef struct {
GcrOpenpgpCallback callback;
gpointer user_data;
guint count;
+ EggBytes *backing;
GPtrArray *records;
} openpgp_parse_closure;
@@ -1205,6 +1206,7 @@ openpgp_parse_free (gpointer data)
{
openpgp_parse_closure *closure = data;
g_ptr_array_unref (closure->records);
+ egg_bytes_unref (closure->backing);
g_free (closure);
}
@@ -1213,6 +1215,7 @@ maybe_emit_openpgp_block (openpgp_parse_closure *closure,
const guchar *block,
const guchar *end)
{
+ EggBytes *outer;
gsize length;
GPtrArray *records;
@@ -1228,15 +1231,17 @@ maybe_emit_openpgp_block (openpgp_parse_closure *closure,
records = closure->records;
closure->records = g_ptr_array_new_with_free_func (_gcr_record_free);
+ outer = egg_bytes_new_with_free_func (block, length, egg_bytes_unref,
+ egg_bytes_ref (closure->backing));
if (closure->callback)
- (closure->callback) (records, block, length, closure->user_data);
+ (closure->callback) (records, outer, closure->user_data);
+ egg_bytes_unref (outer);
g_ptr_array_unref (records);
}
guint
-_gcr_openpgp_parse (gconstpointer data,
- gsize n_data,
+_gcr_openpgp_parse (EggBytes *data,
GcrOpenpgpParseFlags flags,
GcrOpenpgpCallback callback,
gpointer user_data)
@@ -1257,13 +1262,14 @@ _gcr_openpgp_parse (gconstpointer data,
/* For libgcrypt */
_gcr_initialize_library ();
- at = data;
- end = at + n_data;
+ at = egg_bytes_get_data (data);
+ end = at + egg_bytes_get_size (data);
block = NULL;
closure = g_new0 (openpgp_parse_closure, 1);
closure->callback = callback;
closure->user_data = user_data;
+ closure->backing = egg_bytes_ref (data);
closure->records = g_ptr_array_new_with_free_func (_gcr_record_free);
while (at != NULL && at != end) {
diff --git a/gcr/gcr-openpgp.h b/gcr/gcr-openpgp.h
index 31fd295..aed7d8d 100644
--- a/gcr/gcr-openpgp.h
+++ b/gcr/gcr-openpgp.h
@@ -30,6 +30,8 @@
#include <glib.h>
+#include <egg/egg-bytes.h>
+
#include <gck/gck.h>
typedef enum {
@@ -51,12 +53,10 @@ typedef enum {
G_BEGIN_DECLS
typedef void (*GcrOpenpgpCallback) (GPtrArray *records,
- const guchar *outer,
- gsize n_outer,
+ EggBytes *outer,
gpointer user_data);
-guint _gcr_openpgp_parse (gconstpointer data,
- gsize n_data,
+guint _gcr_openpgp_parse (EggBytes *data,
GcrOpenpgpParseFlags flags,
GcrOpenpgpCallback callback,
gpointer user_data);
diff --git a/gcr/gcr-openssh.c b/gcr/gcr-openssh.c
index 3a35c60..e8eef4a 100644
--- a/gcr/gcr-openssh.c
+++ b/gcr/gcr-openssh.c
@@ -154,6 +154,7 @@ atoin (const char *p, gint digits)
static GcrDataError
parse_v1_public_line (const gchar *line,
gsize length,
+ EggBytes *backing,
GcrOpensshPubCallback callback,
gpointer user_data)
{
@@ -161,6 +162,7 @@ parse_v1_public_line (const gchar *line,
gsize len_bits, len_exponent, len_modulus, len_options, n_outer;
GckAttributes *attrs;
gchar *label, *options;
+ EggBytes *bytes;
gint bits;
g_assert (line);
@@ -224,8 +226,13 @@ parse_v1_public_line (const gchar *line,
if (word_options)
options = g_strndup (word_options, len_options);
- if (callback != NULL)
- (callback) (attrs, label, options, outer, n_outer, user_data);
+ if (callback != NULL) {
+ bytes = egg_bytes_new_with_free_func (outer, n_outer,
+ egg_bytes_unref,
+ egg_bytes_ref (backing));
+ (callback) (attrs, label, options, bytes, user_data);
+ egg_bytes_unref (bytes);
+ }
gck_attributes_unref (attrs);
g_free (options);
@@ -367,6 +374,7 @@ decode_v2_public_key (gulong algo,
static GcrDataError
parse_v2_public_line (const gchar *line,
gsize length,
+ EggBytes *backing,
GcrOpensshPubCallback callback,
gpointer user_data)
{
@@ -377,6 +385,7 @@ parse_v2_public_line (const gchar *line,
gchar *label = NULL;
const gchar *outer = line;
gsize n_outer = length;
+ EggBytes *bytes;
gulong algo;
g_assert (line);
@@ -435,8 +444,13 @@ parse_v2_public_line (const gchar *line,
gck_attributes_add_string (attrs, CKA_LABEL, label);
}
- if (callback != NULL)
- (callback) (attrs, label, options, outer, n_outer, user_data);
+ if (callback != NULL) {
+ bytes = egg_bytes_new_with_free_func (outer, n_outer,
+ egg_bytes_unref,
+ egg_bytes_ref (backing));
+ (callback) (attrs, label, options, bytes, user_data);
+ egg_bytes_unref (bytes);
+ }
gck_attributes_unref (attrs);
g_free (options);
@@ -445,8 +459,7 @@ parse_v2_public_line (const gchar *line,
}
guint
-_gcr_openssh_pub_parse (gconstpointer data,
- gsize n_data,
+_gcr_openssh_pub_parse (EggBytes *data,
GcrOpensshPubCallback callback,
gpointer user_data)
{
@@ -457,10 +470,10 @@ _gcr_openssh_pub_parse (gconstpointer data,
GcrDataError res;
guint num_parsed;
- g_return_val_if_fail (data, FALSE);
+ g_return_val_if_fail (data != NULL, FALSE);
- line = data;
- length = n_data;
+ line = egg_bytes_get_data (data);
+ length = egg_bytes_get_size (data);
last = FALSE;
num_parsed = 0;
@@ -472,9 +485,9 @@ _gcr_openssh_pub_parse (gconstpointer data,
}
if (line != end) {
- res = parse_v2_public_line (line, end - line, callback, user_data);
+ res = parse_v2_public_line (line, end - line, data, callback, user_data);
if (res == GCR_ERROR_UNRECOGNIZED)
- res = parse_v1_public_line (line, end - line, callback, user_data);
+ res = parse_v1_public_line (line, end - line, data, callback, user_data);
if (res == GCR_SUCCESS)
num_parsed++;
}
diff --git a/gcr/gcr-openssh.h b/gcr/gcr-openssh.h
index 2fdac2a..4f4fe9e 100644
--- a/gcr/gcr-openssh.h
+++ b/gcr/gcr-openssh.h
@@ -32,17 +32,17 @@
#include <gck/gck.h>
+#include <egg/egg-bytes.h>
+
G_BEGIN_DECLS
typedef void (*GcrOpensshPubCallback) (GckAttributes *attrs,
const gchar *label,
const gchar *options,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *outer,
gpointer user_data);
-guint _gcr_openssh_pub_parse (gconstpointer data,
- gsize n_data,
+guint _gcr_openssh_pub_parse (EggBytes *data,
GcrOpensshPubCallback callback,
gpointer user_data);
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index 096bbfe..ebdc8a3 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -123,10 +123,8 @@ struct _GcrParsed {
GckAttributes *attrs;
const gchar *description;
gchar *label;
- gpointer data;
- gsize n_data;
+ EggBytes *data;
gboolean sensitive;
- GDestroyNotify destroy_func;
GcrDataFormat format;
struct _GcrParsed *next;
};
@@ -149,7 +147,7 @@ typedef struct {
typedef struct _ParserFormat {
gint format_id;
- gint (*function) (GcrParser *self, const guchar *data, gsize n_data);
+ gint (*function) (GcrParser *self, EggBytes *data);
} ParserFormat;
/* Forward declarations */
@@ -224,23 +222,35 @@ parsed_attribute (GcrParsed *parsed,
gck_attributes_add_data (parsed->attrs, type, data, n_data);
}
+static void
+parsed_attribute_bytes (GcrParsed *parsed,
+ CK_ATTRIBUTE_TYPE type,
+ EggBytes *data)
+{
+ g_assert (parsed != NULL);
+ g_assert (parsed->attrs != NULL);
+ gck_attributes_add_data (parsed->attrs, type,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
+}
+
static gboolean
parsed_asn1_number (GcrParsed *parsed,
GNode *asn,
const gchar *part,
CK_ATTRIBUTE_TYPE type)
{
- const guchar *value;
- gsize n_value;
+ EggBytes *value;
g_assert (asn);
g_assert (parsed);
- value = egg_asn1x_get_integer_as_usg (egg_asn1x_node (asn, part, NULL), &n_value);
+ value = egg_asn1x_get_integer_as_usg (egg_asn1x_node (asn, part, NULL));
if (value == NULL)
return FALSE;
- parsed_attribute (parsed, type, value, n_value);
+ parsed_attribute_bytes (parsed, type, value);
+ egg_bytes_unref (value);
return TRUE;
}
@@ -250,17 +260,17 @@ parsed_asn1_element (GcrParsed *parsed,
const gchar *part,
CK_ATTRIBUTE_TYPE type)
{
- const guchar *value;
- gsize n_value;
+ EggBytes *value;
g_assert (asn);
g_assert (parsed);
- value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, part, NULL), &n_value);
+ value = egg_asn1x_get_raw_element (egg_asn1x_node (asn, part, NULL));
if (value == NULL)
return FALSE;
- parsed_attribute (parsed, type, value, n_value);
+ parsed_attribute_bytes (parsed, type, value);
+ egg_bytes_unref (value);
return TRUE;
}
@@ -288,19 +298,15 @@ parsed_boolean_attribute (GcrParsed *parsed,
static void
parsing_block (GcrParsed *parsed,
gint format,
- gconstpointer data,
- gsize n_data)
+ EggBytes *data)
{
g_assert (parsed != NULL);
g_assert (data != NULL);
- g_assert (n_data != 0);
- g_assert (format);
+ g_assert (format != 0);
g_assert (parsed->data == NULL);
- g_assert (parsed->destroy_func == NULL);
parsed->format = format;
- parsed->data = (gpointer)data;
- parsed->n_data = n_data;
+ parsed->data = egg_bytes_ref (data);
}
static void
@@ -457,7 +463,8 @@ parsed_fire (GcrParser *self,
*/
static gint
-parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_private_key_rsa (GcrParser *self,
+ EggBytes *data)
{
gint res = GCR_ERROR_UNRECOGNIZED;
GNode *asn = NULL;
@@ -466,11 +473,11 @@ parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
parsed = push_parsed (self, TRUE);
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data);
if (!asn)
goto done;
- parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data);
parsing_object (parsed, CKO_PRIVATE_KEY);
parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_RSA);
parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
@@ -511,7 +518,8 @@ done:
*/
static gint
-parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_private_key_dsa (GcrParser *self,
+ EggBytes *data)
{
gint ret = GCR_ERROR_UNRECOGNIZED;
GNode *asn = NULL;
@@ -519,11 +527,11 @@ parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
parsed = push_parsed (self, TRUE);
- asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
+ asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data);
if (!asn)
goto done;
- parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data);
parsing_object (parsed, CKO_PRIVATE_KEY);
parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
@@ -548,8 +556,9 @@ done:
}
static gint
-parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n_keydata,
- const guchar *params, gsize n_params)
+parse_der_private_key_dsa_parts (GcrParser *self,
+ EggBytes *keydata,
+ EggBytes *params)
{
gint ret = GCR_ERROR_UNRECOGNIZED;
GNode *asn_params = NULL;
@@ -558,8 +567,8 @@ parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n
parsed = push_parsed (self, TRUE);
- asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
- asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata, n_keydata);
+ asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params);
+ asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata);
if (!asn_params || !asn_key)
goto done;
@@ -592,13 +601,14 @@ done:
*/
static gint
-parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_private_key (GcrParser *self,
+ EggBytes *data)
{
gint res;
- res = parse_der_private_key_rsa (self, data, n_data);
+ res = parse_der_private_key_rsa (self, data);
if (res == GCR_ERROR_UNRECOGNIZED)
- res = parse_der_private_key_dsa (self, data, n_data);
+ res = parse_der_private_key_dsa (self, data);
return res;
}
@@ -608,26 +618,25 @@ 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)
+parse_der_pkcs8_plain (GcrParser *self,
+ EggBytes *data)
{
gint ret;
CK_KEY_TYPE key_type;
GQuark key_algo;
- const guchar *keydata;
- gsize n_keydata;
- const guchar *params;
- gsize n_params;
+ EggBytes *keydata = NULL;
+ EggBytes *params = NULL;
GNode *asn = NULL;
GcrParsed *parsed;
parsed = push_parsed (self, TRUE);
ret = GCR_ERROR_UNRECOGNIZED;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data);
if (!asn)
goto done;
- parsing_block (parsed, GCR_FORMAT_DER_PKCS8_PLAIN, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS8_PLAIN, data);
ret = GCR_ERROR_FAILURE;
key_type = GCK_INVALID;
@@ -644,11 +653,11 @@ parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
goto done;
}
- keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
+ keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL));
if (!keydata)
goto done;
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL));
ret = SUCCESS;
@@ -656,16 +665,15 @@ done:
if (ret == SUCCESS) {
switch (key_type) {
case CKK_RSA:
- ret = parse_der_private_key_rsa (self, keydata, n_keydata);
+ ret = parse_der_private_key_rsa (self, keydata);
break;
case CKK_DSA:
/* Try the normal sane format */
- ret = parse_der_private_key_dsa (self, keydata, n_keydata);
+ ret = parse_der_private_key_dsa (self, keydata);
/* Otherwise try the two part format that everyone seems to like */
- if (ret == GCR_ERROR_UNRECOGNIZED && params && n_params)
- ret = parse_der_private_key_dsa_parts (self, keydata, n_keydata,
- params, n_params);
+ if (ret == GCR_ERROR_UNRECOGNIZED && params)
+ ret = parse_der_private_key_dsa_parts (self, keydata, params);
break;
default:
g_message ("invalid or unsupported key type in PKCS#8 key");
@@ -677,13 +685,18 @@ done:
g_message ("invalid PKCS#8 key");
}
+ if (keydata)
+ egg_bytes_unref (keydata);
+ if (params)
+ egg_bytes_unref (params);
egg_asn1x_destroy (asn);
pop_parsed (self, parsed);
return ret;
}
static gint
-parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_pkcs8_encrypted (GcrParser *self,
+ EggBytes *data)
{
PasswordState pstate = PASSWORD_STATE_INIT;
GNode *asn = NULL;
@@ -692,8 +705,9 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
gint ret, r;
GQuark scheme;
guchar *crypted = NULL;
- const guchar *params;
- gsize n_crypted, n_params;
+ EggBytes *params = NULL;
+ EggBytes *cbytes;
+ gsize n_crypted;
const gchar *password;
GcrParsed *parsed;
gint l;
@@ -701,11 +715,11 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
parsed = push_parsed (self, FALSE);
ret = GCR_ERROR_UNRECOGNIZED;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data);
if (!asn)
goto done;
- parsing_block (parsed, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data);
ret = GCR_ERROR_FAILURE;
/* Figure out the type of encryption */
@@ -713,7 +727,7 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
if (!scheme)
goto done;
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL));
/* Loop to try different passwords */
for (;;) {
@@ -727,7 +741,7 @@ 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))
+ if (!egg_symkey_read_cipher (scheme, password, -1, params, &cih))
break;
crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted);
@@ -748,11 +762,14 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
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);
+ cbytes = egg_bytes_new_with_free_func (crypted, n_crypted,
+ egg_secure_free, crypted);
crypted = NULL;
+ /* Try to parse the resulting key */
+ r = parse_der_pkcs8_plain (self, cbytes);
+ egg_bytes_unref (cbytes);
+
if (r != GCR_ERROR_UNRECOGNIZED) {
ret = r;
break;
@@ -762,6 +779,8 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
}
done:
+ if (params)
+ egg_bytes_unref (params);
if (cih)
gcry_cipher_close (cih);
egg_asn1x_destroy (asn);
@@ -772,13 +791,14 @@ done:
}
static gint
-parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_pkcs8 (GcrParser *self,
+ EggBytes *data)
{
gint ret;
- ret = parse_der_pkcs8_plain (self, data, n_data);
+ ret = parse_der_pkcs8_plain (self, data);
if (ret == GCR_ERROR_UNRECOGNIZED)
- ret = parse_der_pkcs8_encrypted (self, data, n_data);
+ ret = parse_der_pkcs8_encrypted (self, data);
return ret;
}
@@ -788,20 +808,21 @@ parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
*/
static gint
-parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_certificate (GcrParser *self,
+ EggBytes *data)
{
gchar *name = NULL;
GcrParsed *parsed;
GNode *node;
GNode *asn;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
if (asn == NULL)
return GCR_ERROR_UNRECOGNIZED;
parsed = push_parsed (self, FALSE);
- parsing_block (parsed, GCR_FORMAT_DER_CERTIFICATE_X509, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_CERTIFICATE_X509, data);
parsing_object (parsed, CKO_CERTIFICATE);
parsed_ulong_attribute (parsed, CKA_CERTIFICATE_TYPE, CKC_X_509);
@@ -816,7 +837,7 @@ parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
g_free (name);
}
- parsed_attribute (parsed, CKA_VALUE, data, n_data);
+ parsed_attribute_bytes (parsed, CKA_VALUE, data);
parsed_asn1_element (parsed, node, "subject", CKA_SUBJECT);
parsed_asn1_element (parsed, node, "issuer", CKA_ISSUER);
parsed_asn1_number (parsed, node, "serialNumber", CKA_SERIAL_NUMBER);
@@ -833,18 +854,18 @@ 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)
+handle_pkcs7_signed_data (GcrParser *self,
+ EggBytes *data)
{
GNode *asn = NULL;
GNode *node;
gint ret;
- const guchar *certificate;
- gsize n_certificate;
+ EggBytes *certificate;
int i;
ret = GCR_ERROR_UNRECOGNIZED;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-SignedData", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-SignedData", data);
if (!asn)
goto done;
@@ -858,9 +879,10 @@ handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
if (node == NULL)
break;
- certificate = egg_asn1x_get_raw_element (node, &n_certificate);
+ certificate = egg_asn1x_get_raw_element (node);
+ ret = parse_der_certificate (self, certificate);
+ egg_bytes_unref (certificate);
- ret = parse_der_certificate (self, certificate, n_certificate);
if (ret != SUCCESS)
goto done;
}
@@ -875,24 +897,24 @@ done:
}
static gint
-parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_pkcs7 (GcrParser *self,
+ EggBytes *data)
{
GNode *asn = NULL;
GNode *node;
gint ret;
- const guchar* content = NULL;
- gsize n_content;
+ EggBytes *content = NULL;
GQuark oid;
GcrParsed *parsed;
parsed = push_parsed (self, FALSE);
ret = GCR_ERROR_UNRECOGNIZED;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data, n_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data);
if (!asn)
goto done;
- parsing_block (parsed, GCR_FORMAT_DER_PKCS7, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS7, data);
ret = GCR_ERROR_FAILURE;
node = egg_asn1x_node (asn, "contentType", NULL);
@@ -908,13 +930,15 @@ parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
goto done;
}
- content = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "content", NULL), &n_content);
+ content = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "content", NULL));
if (!content)
goto done;
- ret = handle_pkcs7_signed_data (self, content, n_content);
+ ret = handle_pkcs7_signed_data (self, content);
done:
+ if (content)
+ egg_bytes_unref (content);
egg_asn1x_destroy (asn);
pop_parsed (self, parsed);
return ret;
@@ -927,8 +951,7 @@ done:
static GNode *
decode_pkcs12_asn1_accepting_invalid_crap (const ASN1_ARRAY_TYPE *defs,
const gchar *identifier,
- gconstpointer data,
- gsize n_data)
+ EggBytes *data)
{
GNode *asn;
@@ -947,7 +970,7 @@ decode_pkcs12_asn1_accepting_invalid_crap (const ASN1_ARRAY_TYPE *defs,
g_return_val_if_fail (asn != NULL, NULL);
/* Passing FALSE as the strictness argument */
- if (!egg_asn1x_decode_no_validate (asn, data, n_data) ||
+ if (!egg_asn1x_decode_no_validate (asn, data) ||
!egg_asn1x_validate (asn, FALSE)) {
egg_asn1x_destroy (asn);
asn = NULL;
@@ -957,29 +980,31 @@ decode_pkcs12_asn1_accepting_invalid_crap (const ASN1_ARRAY_TYPE *defs,
}
static gint
-handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
+handle_pkcs12_cert_bag (GcrParser *self,
+ EggBytes *data)
{
GNode *asn = NULL;
GNode *asn_content = NULL;
guchar *certificate = NULL;
- const guchar *element;
- gsize n_certificate, n_element;
+ EggBytes *element = NULL;
+ gsize n_certificate;
+ EggBytes *bytes;
gint ret;
ret = GCR_ERROR_UNRECOGNIZED;
asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
"pkcs-12-CertBag",
- data, n_data);
+ data);
if (!asn)
goto done;
ret = GCR_ERROR_FAILURE;
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "certValue", NULL), &n_element);
+ element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "certValue", NULL));
if (!element)
goto done;
- asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element, n_element);
+ asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element);
if (!asn_content)
goto done;
@@ -987,12 +1012,15 @@ handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
if (!certificate)
goto done;
- ret = parse_der_certificate (self, certificate, n_certificate);
+ bytes = egg_bytes_new_take (certificate, n_certificate);
+ ret = parse_der_certificate (self, bytes);
+ egg_bytes_unref (bytes);
done:
+ if (element)
+ egg_bytes_unref (element);
egg_asn1x_destroy (asn_content);
egg_asn1x_destroy (asn);
- g_free (certificate);
return ret;
}
@@ -1002,8 +1030,7 @@ parse_pkcs12_bag_friendly_name (GNode *asn)
guint count, i;
GQuark oid;
GNode *node;
- gconstpointer element;
- gsize n_element;
+ EggBytes *element;
GNode *asn_str;
gchar *result;
@@ -1016,9 +1043,10 @@ parse_pkcs12_bag_friendly_name (GNode *asn)
if (oid == GCR_OID_PKCS9_ATTRIBUTE_FRIENDLY) {
node = egg_asn1x_node (asn, i, "values", 1, NULL);
if (node != NULL) {
- element = egg_asn1x_get_raw_element (node, &n_element);
+ element = egg_asn1x_get_raw_element (node);
asn_str = egg_asn1x_create_and_decode (pkix_asn1_tab, "BMPString",
- element, n_element);
+ element);
+ egg_bytes_unref (element);
if (asn_str) {
result = egg_asn1x_get_bmpstring_as_utf8 (asn_str);
egg_asn1x_destroy (asn_str);
@@ -1032,15 +1060,15 @@ parse_pkcs12_bag_friendly_name (GNode *asn)
}
static gint
-handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
+handle_pkcs12_bag (GcrParser *self,
+ EggBytes *data)
{
GNode *asn = NULL;
gint ret, r;
guint count = 0;
GQuark oid;
- const guchar *element;
+ EggBytes *element = NULL;
gchar *friendly;
- gsize n_element;
guint i;
GcrParsed *parsed;
@@ -1048,7 +1076,7 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
"pkcs-12-SafeContents",
- data, n_data);
+ data);
if (!asn)
goto done;
@@ -1067,7 +1095,7 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
if (!oid)
goto done;
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, i, "bagValue", NULL), &n_element);
+ element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, i, "bagValue", NULL));
if (!element)
goto done;
@@ -1079,21 +1107,24 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
/* A normal unencrypted key */
if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
- r = parse_der_pkcs8_plain (self, element, n_element);
+ r = parse_der_pkcs8_plain (self, element);
/* A properly encrypted key */
} else if (oid == GCR_OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
- r = parse_der_pkcs8_encrypted (self, element, n_element);
+ r = parse_der_pkcs8_encrypted (self, element);
/* A certificate */
} else if (oid == GCR_OID_PKCS12_BAG_CERTIFICATE) {
- r = handle_pkcs12_cert_bag (self, element, n_element);
+ r = handle_pkcs12_cert_bag (self, element);
/* TODO: GCR_OID_PKCS12_BAG_CRL */
} else {
r = GCR_ERROR_UNRECOGNIZED;
}
+ if (element != NULL)
+ egg_bytes_unref (element);
+
pop_parsed (self, parsed);
if (r == GCR_ERROR_FAILURE ||
@@ -1112,16 +1143,18 @@ done:
}
static gint
-handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
+handle_pkcs12_encrypted_bag (GcrParser *self,
+ EggBytes *data)
{
PasswordState pstate = PASSWORD_STATE_INIT;
GNode *asn = NULL;
gcry_cipher_hd_t cih = NULL;
gcry_error_t gcry;
guchar *crypted = NULL;
- const guchar *params;
- gsize n_params, n_crypted;
+ EggBytes *params = NULL;
+ gsize n_crypted;
const gchar *password;
+ EggBytes *cbytes;
GQuark scheme;
gint ret, r;
gint l;
@@ -1130,7 +1163,7 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
"pkcs-7-EncryptedData",
- data, n_data);
+ data);
if (!asn)
goto done;
@@ -1141,7 +1174,7 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
if (!scheme)
goto done;
- params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL), &n_params);
+ params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL));
if (!params)
goto done;
@@ -1157,7 +1190,7 @@ handle_pkcs12_encrypted_bag (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)) {
+ if (!egg_symkey_read_cipher (scheme, password, -1, params, &cih)) {
ret = GCR_ERROR_FAILURE;
goto done;
}
@@ -1181,11 +1214,13 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
if (l > 0)
n_crypted = l;
- /* Try to parse the resulting key */
- r = handle_pkcs12_bag (self, crypted, n_crypted);
- egg_secure_free (crypted);
+ cbytes = egg_bytes_new_with_free_func (crypted, n_crypted, egg_secure_free, crypted);
crypted = NULL;
+ /* Try to parse the resulting key */
+ r = handle_pkcs12_bag (self, cbytes);
+ egg_bytes_unref (cbytes);
+
if (r != GCR_ERROR_UNRECOGNIZED) {
ret = r;
break;
@@ -1195,6 +1230,8 @@ handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
}
done:
+ if (params)
+ egg_bytes_unref (params);
if (cih)
gcry_cipher_close (cih);
egg_asn1x_destroy (asn);
@@ -1203,14 +1240,14 @@ done:
}
static gint
-handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
+handle_pkcs12_safe (GcrParser *self,
+ EggBytes *data)
{
GNode *asn = NULL;
GNode *asn_content = NULL;
gint ret, r;
- const guchar *bag;
- guchar *content = NULL;
- gsize n_bag, n_content;
+ EggBytes *bag;
+ EggBytes *content;
GQuark oid;
guint i;
GNode *node;
@@ -1219,7 +1256,7 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
"pkcs-12-AuthenticatedSafe",
- data, n_data);
+ data);
if (!asn)
goto done;
@@ -1241,8 +1278,8 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
if (!node)
goto done;
- bag = egg_asn1x_get_raw_element (node, &n_bag);
- g_return_val_if_fail (bag, ret);
+ bag = egg_asn1x_get_raw_element (node);
+ g_return_val_if_fail (bag != NULL, ret);
/* A non encrypted bag, just parse */
if (oid == GCR_OID_PKCS7_DATA) {
@@ -1250,20 +1287,20 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
egg_asn1x_destroy (asn_content);
asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
"pkcs-7-Data",
- bag, n_bag);
+ bag);
if (!asn_content)
goto done;
- g_free (content);
- content = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_content);
+ content = egg_asn1x_get_string_as_bytes (asn_content);
if (!content)
goto done;
- r = handle_pkcs12_bag (self, content, n_content);
+ r = handle_pkcs12_bag (self, content);
+ egg_bytes_unref (content);
/* Encrypted data first needs decryption */
} else if (oid == GCR_OID_PKCS7_ENCRYPTED_DATA) {
- r = handle_pkcs12_encrypted_bag (self, bag, n_bag);
+ r = handle_pkcs12_encrypted_bag (self, bag);
/* Hmmmm, not sure what this is */
} else {
@@ -1271,6 +1308,9 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
r = GCR_ERROR_UNRECOGNIZED;
}
+ egg_bytes_unref (bag);
+ bag = NULL;
+
if (r == GCR_ERROR_FAILURE ||
r == GCR_ERROR_CANCELLED ||
r == GCR_ERROR_LOCKED) {
@@ -1282,17 +1322,17 @@ handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
ret = SUCCESS;
done:
+ if (bag != NULL)
+ egg_bytes_unref (bag);
egg_asn1x_destroy (asn);
egg_asn1x_destroy (asn_content);
- g_free (content);
return ret;
}
static gint
verify_pkcs12_safe (GcrParser *self,
GNode *asn,
- gconstpointer content,
- gsize n_content)
+ EggBytes *content)
{
PasswordState pstate = PASSWORD_STATE_INIT;
const gchar *password;
@@ -1303,8 +1343,7 @@ verify_pkcs12_safe (GcrParser *self,
gsize n_digest;
GQuark algorithm;
GNode *mac_data;
- gconstpointer params;
- gsize n_params;
+ EggBytes *params = NULL;
int ret, r;
ret = GCR_ERROR_FAILURE;
@@ -1323,7 +1362,7 @@ verify_pkcs12_safe (GcrParser *self,
if (!algorithm)
goto done;
- params = egg_asn1x_get_raw_element (mac_data, &n_params);
+ params = egg_asn1x_get_raw_element (mac_data);
if (!params)
goto done;
@@ -1342,8 +1381,7 @@ verify_pkcs12_safe (GcrParser *self,
}
/* Parse the encryption stuff into a cipher. */
- if (!egg_symkey_read_mac (algorithm, password, -1, params, n_params,
- &mdh, &mac_len)) {
+ if (!egg_symkey_read_mac (algorithm, password, -1, params, &mdh, &mac_len)) {
ret = GCR_ERROR_FAILURE;
goto done;
}
@@ -1353,7 +1391,7 @@ verify_pkcs12_safe (GcrParser *self,
r = GCR_ERROR_FAILURE;
} else {
- gcry_md_write (mdh, content, n_content);
+ gcry_md_write (mdh, egg_bytes_get_data (content), egg_bytes_get_size (content));
mac_digest = gcry_md_read (mdh, 0);
g_return_val_if_fail (mac_digest, GCR_ERROR_FAILURE);
r = memcmp (mac_digest, digest, n_digest) == 0 ? SUCCESS : GCR_ERROR_LOCKED;
@@ -1369,6 +1407,8 @@ verify_pkcs12_safe (GcrParser *self,
}
done:
+ if (params)
+ egg_bytes_unref (params);
if (mdh)
gcry_md_close (mdh);
g_free (digest);
@@ -1377,26 +1417,25 @@ done:
}
static gint
-parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
+parse_der_pkcs12 (GcrParser *self,
+ EggBytes *data)
{
GNode *asn = NULL;
GNode *asn_content = NULL;
gint ret;
- const guchar* element = NULL;
- guchar *content = NULL;
- gsize n_element, n_content;
+ EggBytes *element = NULL;
+ EggBytes *content = NULL;
GQuark oid;
GcrParsed *parsed;
parsed = push_parsed (self, FALSE);
ret = GCR_ERROR_UNRECOGNIZED;
- asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-12-PFX",
- data, n_data);
+ asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-12-PFX", data);
if (!asn)
goto done;
- parsing_block (parsed, GCR_FORMAT_DER_PKCS12, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS12, data);
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
if (!oid)
@@ -1408,25 +1447,27 @@ parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
goto done;
}
- element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "authSafe", "content", NULL), &n_element);
+ element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "authSafe", "content", NULL));
if (!element)
goto done;
- asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-7-Data",
- element, n_element);
+ asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-7-Data", element);
if (!asn_content)
goto done;
- content = egg_asn1x_get_string_as_raw (asn_content, g_realloc, &n_content);
+ content = egg_asn1x_get_string_as_bytes (asn_content);
if (!content)
goto done;
- ret = verify_pkcs12_safe (self, asn, content, n_content);
+ ret = verify_pkcs12_safe (self, asn, content);
if (ret == SUCCESS)
- ret = handle_pkcs12_safe (self, content, n_content);
+ ret = handle_pkcs12_safe (self, content);
done:
- g_free (content);
+ if (element)
+ egg_bytes_unref (element);
+ if (content)
+ egg_bytes_unref (content);
egg_asn1x_destroy (asn_content);
egg_asn1x_destroy (asn);
pop_parsed (self, parsed);
@@ -1440,8 +1481,7 @@ done:
static void
on_openpgp_packet (GPtrArray *records,
- const guchar *outer,
- gsize n_outer,
+ EggBytes *outer,
gpointer user_data)
{
GcrParser *self = GCR_PARSER (user_data);
@@ -1458,7 +1498,7 @@ on_openpgp_packet (GPtrArray *records,
parsed = push_parsed (self, FALSE);
/* All we can do is the packet bounds */
- parsing_block (parsed, GCR_FORMAT_OPENPGP_PACKET, outer, n_outer);
+ parsing_block (parsed, GCR_FORMAT_OPENPGP_PACKET, outer);
parsing_object (parsed, CKO_GCR_GNUPG_RECORDS);
string = _gcr_records_format (records);
parsed_attribute (parsed, CKA_VALUE, string, strlen (string));
@@ -1470,12 +1510,11 @@ on_openpgp_packet (GPtrArray *records,
static gint
parse_openpgp_packets (GcrParser *self,
- const guchar *data,
- gsize n_data)
+ EggBytes *data)
{
gint num_parsed;
- num_parsed = _gcr_openpgp_parse (data, n_data,
+ num_parsed = _gcr_openpgp_parse (data,
GCR_OPENPGP_PARSE_KEYS |
GCR_OPENPGP_PARSE_ATTRIBUTES |
GCR_OPENPGP_PARSE_SIGNATURES,
@@ -1542,8 +1581,7 @@ static gint
handle_plain_pem (GcrParser *self,
gint format_id,
gint want_format,
- const guchar *data,
- gsize n_data)
+ EggBytes *data)
{
ParserFormat *format;
@@ -1554,7 +1592,7 @@ handle_plain_pem (GcrParser *self,
if (format == NULL)
return GCR_ERROR_UNRECOGNIZED;
- return (format->function) (self, data, n_data);
+ return (format->function) (self, data);
}
static gint
@@ -1562,15 +1600,14 @@ handle_encrypted_pem (GcrParser *self,
gint format_id,
gint want_format,
GHashTable *headers,
- const guchar *data,
- gsize n_data)
+ EggBytes *data)
{
PasswordState pstate = PASSWORD_STATE_INIT;
const gchar *password;
guchar *decrypted;
gsize n_decrypted;
const gchar *val;
- gboolean ret;
+ EggBytes *dbytes;
gint res;
gint l;
@@ -1590,28 +1627,25 @@ handle_encrypted_pem (GcrParser *self,
if (res != SUCCESS)
break;
- decrypted = NULL;
- n_decrypted = 0;
-
/* Decrypt, this will result in garble if invalid password */
- ret = egg_openssl_decrypt_block (val, password, -1, data, n_data,
- &decrypted, &n_decrypted);
- if (!ret) {
+ decrypted = egg_openssl_decrypt_block (val, password, -1, data, &n_decrypted);
+ if (!decrypted) {
res = GCR_ERROR_FAILURE;
break;
}
- g_assert (decrypted);
-
/* Unpad the DER data */
l = egg_asn1x_element_length (decrypted, n_decrypted);
if (l > 0)
n_decrypted = l;
+ dbytes = egg_bytes_new_with_free_func (decrypted, n_decrypted,
+ egg_secure_free, decrypted);
+ decrypted = NULL;
+
/* Try to parse */
- res = handle_plain_pem (self, format_id, want_format,
- decrypted, n_decrypted);
- egg_secure_free (decrypted);
+ res = handle_plain_pem (self, format_id, want_format, dbytes);
+ egg_bytes_unref (dbytes);
/* Unrecognized is a bad password */
if (res != GCR_ERROR_UNRECOGNIZED)
@@ -1629,10 +1663,8 @@ typedef struct {
static void
handle_pem_data (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
@@ -1654,7 +1686,7 @@ handle_pem_data (GQuark type,
parsed = push_parsed (args->parser, FALSE);
/* Fill in information necessary for prompting */
- parsing_block (parsed, outer_format, outer, n_outer);
+ parsing_block (parsed, outer_format, outer);
/* See if it's encrypted PEM all openssl like*/
if (headers) {
@@ -1666,10 +1698,10 @@ handle_pem_data (GQuark type,
if (encrypted)
res = handle_encrypted_pem (args->parser, inner_format,
args->want_format, headers,
- data, n_data);
+ data);
else
res = handle_plain_pem (args->parser, inner_format,
- args->want_format, data, n_data);
+ args->want_format, data);
pop_parsed (args->parser, parsed);
@@ -1682,15 +1714,17 @@ handle_pem_data (GQuark type,
}
static gint
-handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_data)
+handle_pem_format (GcrParser *self,
+ gint subformat,
+ EggBytes *data)
{
HandlePemArgs ctx = { self, GCR_ERROR_UNRECOGNIZED, subformat };
guint found;
- if (n_data == 0)
+ if (egg_bytes_get_size (data) == 0)
return GCR_ERROR_UNRECOGNIZED;
- found = egg_armor_parse (data, n_data, handle_pem_data, &ctx);
+ found = egg_armor_parse (data, handle_pem_data, &ctx);
if (found == 0)
return GCR_ERROR_UNRECOGNIZED;
@@ -1700,59 +1734,66 @@ handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_
static gint
-parse_pem (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, 0, data, n_data);
+ return handle_pem_format (self, 0, data);
}
static gint
-parse_pem_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_private_key_rsa (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data);
}
static gint
-parse_pem_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_private_key_dsa (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data);
}
static gint
-parse_pem_certificate (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_certificate (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_CERTIFICATE_X509, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_CERTIFICATE_X509, data);
}
static gint
-parse_pem_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_pkcs8_plain (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_PLAIN, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_PLAIN, data);
}
static gint
-parse_pem_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_pkcs8_encrypted (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data);
}
static gint
-parse_pem_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_pkcs7 (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS7, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_PKCS7, data);
}
static gint
-parse_pem_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
+parse_pem_pkcs12 (GcrParser *self,
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_DER_PKCS12, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_DER_PKCS12, data);
}
static gint
parse_openpgp_armor (GcrParser *self,
- const guchar *data,
- gsize n_data)
+ EggBytes *data)
{
- return handle_pem_format (self, GCR_FORMAT_OPENPGP_PACKET, data, n_data);
+ return handle_pem_format (self, GCR_FORMAT_OPENPGP_PACKET, data);
}
/* -----------------------------------------------------------------------------
@@ -1763,15 +1804,14 @@ static void
on_openssh_public_key_parsed (GckAttributes *attrs,
const gchar *label,
const gchar *options,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *outer,
gpointer user_data)
{
GcrParser *self = GCR_PARSER (user_data);
GcrParsed *parsed;
parsed = push_parsed (self, FALSE);
- parsing_block (parsed, GCR_FORMAT_OPENSSH_PUBLIC, outer, n_outer);
+ parsing_block (parsed, GCR_FORMAT_OPENSSH_PUBLIC, outer);
parsed_attributes (parsed, attrs);
parsed_label (parsed, label);
parsed_fire (self, parsed);
@@ -1780,13 +1820,11 @@ on_openssh_public_key_parsed (GckAttributes *attrs,
static gint
parse_openssh_public (GcrParser *self,
- const guchar *data,
- gsize n_data)
+ EggBytes *data)
{
guint num_parsed;
- num_parsed = _gcr_openssh_pub_parse (data, n_data,
- on_openssh_public_key_parsed, self);
+ num_parsed = _gcr_openssh_pub_parse (data, on_openssh_public_key_parsed, self);
if (num_parsed == 0)
return GCR_ERROR_UNRECOGNIZED;
@@ -1896,8 +1934,7 @@ compare_pointers (gconstpointer a, gconstpointer b)
typedef struct _ForeachArgs {
GcrParser *parser;
- const guchar *data;
- gsize n_data;
+ EggBytes *data;
gint result;
} ForeachArgs;
@@ -1912,7 +1949,7 @@ parser_format_foreach (gpointer key, gpointer value, gpointer data)
g_assert (format->function);
g_assert (GCR_IS_PARSER (args->parser));
- result = (format->function) (args->parser, args->data, args->n_data);
+ result = (format->function) (args->parser, args->data);
if (result != GCR_ERROR_UNRECOGNIZED) {
args->result = result;
return TRUE;
@@ -2147,7 +2184,7 @@ gcr_parser_parse_data (GcrParser *self,
gsize n_data,
GError **error)
{
- ForeachArgs args = { self, data, n_data, GCR_ERROR_UNRECOGNIZED };
+ ForeachArgs args = { self, NULL, GCR_ERROR_UNRECOGNIZED };
const gchar *message = NULL;
gint i;
@@ -2156,6 +2193,9 @@ gcr_parser_parse_data (GcrParser *self,
g_return_val_if_fail (!error || !*error, FALSE);
if (data && n_data) {
+ /* TODO: Once GBytes is in the API, copy here */
+ args.data = egg_bytes_new_static (data, n_data);
+
/* Just the specific formats requested */
if (self->pv->specific_formats) {
g_tree_foreach (self->pv->specific_formats, parser_format_foreach, &args);
@@ -2343,15 +2383,7 @@ gcr_parsed_ref (GcrParsed *parsed)
/* Find the block of data to copy */
while (parsed != NULL) {
if (parsed->data != NULL) {
- if (parsed->sensitive) {
- copy->data = egg_secure_alloc (parsed->n_data);
- memcpy (copy->data, parsed->data, parsed->n_data);
- copy->destroy_func = egg_secure_free;
- } else {
- copy->data = g_memdup (parsed->data, parsed->n_data);
- copy->destroy_func = g_free;
- }
- copy->n_data = parsed->n_data;
+ copy->data = egg_bytes_ref (parsed->data);
break;
}
parsed = parsed->next;
@@ -2377,8 +2409,8 @@ gcr_parsed_unref (gpointer parsed)
if (par->attrs)
gck_attributes_unref (par->attrs);
g_free (par->label);
- if (par->destroy_func)
- (par->destroy_func) (par->data);
+ if (par->data)
+ egg_bytes_unref (par->data);
g_free (par);
}
}
@@ -2542,8 +2574,8 @@ gcr_parsed_get_data (GcrParsed *parsed,
while (parsed != NULL) {
if (parsed->data != NULL) {
- *n_data = parsed->n_data;
- return parsed->data;
+ *n_data = egg_bytes_get_size (parsed->data);
+ return egg_bytes_get_data (parsed->data);
}
parsed = parsed->next;
}
diff --git a/gcr/tests/frob-openpgp.c b/gcr/tests/frob-openpgp.c
index b83305a..46748f6 100644
--- a/gcr/tests/frob-openpgp.c
+++ b/gcr/tests/frob-openpgp.c
@@ -31,8 +31,7 @@
static void
on_packet_print_records (GPtrArray *records,
- const guchar *packet,
- gsize n_packet,
+ EggBytes *packet,
gpointer user_data)
{
gchar *string;
@@ -46,12 +45,11 @@ on_packet_print_records (GPtrArray *records,
}
static gboolean
-parse_binary (gconstpointer contents,
- gsize length)
+parse_binary (EggBytes *contents)
{
guint packets;
- packets = _gcr_openpgp_parse (contents, length,
+ packets = _gcr_openpgp_parse (contents,
GCR_OPENPGP_PARSE_KEYS |
GCR_OPENPGP_PARSE_ATTRIBUTES,
on_packet_print_records, NULL);
@@ -61,10 +59,8 @@ parse_binary (gconstpointer contents,
static void
on_armor_parsed (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
@@ -74,19 +70,18 @@ on_armor_parsed (GQuark type,
value = g_hash_table_lookup (headers, "Version");
g_assert_cmpstr (value, ==, "GnuPG v1.4.11 (GNU/Linux)");
- *result = parse_binary (data, n_data);
+ *result = parse_binary (data);
}
static gboolean
-parse_armor_or_binary (gconstpointer contents,
- gsize length)
+parse_armor_or_binary (EggBytes *contents)
{
gboolean result;
guint parts;
- parts = egg_armor_parse (contents, length, on_armor_parsed, &result);
+ parts = egg_armor_parse (contents, on_armor_parsed, &result);
if (parts == 0)
- result = parse_binary (contents, length);
+ result = parse_binary (contents);
return result;
}
@@ -96,6 +91,7 @@ main(int argc, char *argv[])
GError *error = NULL;
gchar *contents;
gsize length;
+ EggBytes *bytes;
int ret;
g_set_prgname ("frob-openpgp");
@@ -111,12 +107,13 @@ main(int argc, char *argv[])
return 1;
}
+ bytes = egg_bytes_new_take (contents, length);
ret = 0;
- if (!parse_armor_or_binary (contents, length)) {
+ if (!parse_armor_or_binary (bytes)) {
g_printerr ("frob-openpgp: no openpgp data found in data");
ret = 1;
}
- g_free (contents);
+ egg_bytes_unref (bytes);
return ret;
}
diff --git a/gcr/tests/test-fingerprint.c b/gcr/tests/test-fingerprint.c
index d17208b..94564f8 100644
--- a/gcr/tests/test-fingerprint.c
+++ b/gcr/tests/test-fingerprint.c
@@ -39,49 +39,43 @@
#include <errno.h>
typedef struct {
- gpointer cert_rsa;
- gsize n_cert_rsa;
- gpointer key_rsa;
- gsize n_key_rsa;
- gpointer cert_dsa;
- gsize n_cert_dsa;
- gpointer key_dsa;
- gsize n_key_dsa;
+ EggBytes *cert_rsa;
+ EggBytes *key_rsa;
+ EggBytes *cert_dsa;
+ EggBytes *key_dsa;
} Test;
static void
setup (Test *test, gconstpointer unused)
{
GError *error = NULL;
+ gchar *contents;
+ gsize length;
- g_file_get_contents (SRCDIR "/files/client.crt", (gchar**)&test->cert_rsa,
- &test->n_cert_rsa, &error);
+ g_file_get_contents (SRCDIR "/files/client.crt", &contents, &length, &error);
g_assert_no_error (error);
- g_assert (test->cert_rsa);
+ test->cert_rsa = egg_bytes_new_take (contents, length);
- g_file_get_contents (SRCDIR "/files/client.key", (gchar**)&test->key_rsa,
- &test->n_key_rsa, &error);
+ g_file_get_contents (SRCDIR "/files/client.key", &contents, &length, &error);
g_assert_no_error (error);
- g_assert (test->key_rsa);
+ test->key_rsa = egg_bytes_new_take (contents, length);
- g_file_get_contents (SRCDIR "/files/generic-dsa.crt", (gchar**)&test->cert_dsa,
- &test->n_cert_dsa, &error);
+ g_file_get_contents (SRCDIR "/files/generic-dsa.crt", &contents, &length, &error);
g_assert_no_error (error);
- g_assert (test->cert_dsa);
+ test->cert_dsa = egg_bytes_new_take (contents, length);
- g_file_get_contents (SRCDIR "/files/generic-dsa.key", (gchar**)&test->key_dsa,
- &test->n_key_dsa, &error);
+ g_file_get_contents (SRCDIR "/files/generic-dsa.key", &contents, &length, &error);
g_assert_no_error (error);
- g_assert (test->key_dsa);
+ test->key_dsa = egg_bytes_new_take (contents, length);
}
static void
teardown (Test *test, gconstpointer unused)
{
- g_free (test->cert_rsa);
- g_free (test->key_rsa);
- g_free (test->cert_dsa);
- g_free (test->key_dsa);
+ egg_bytes_unref (test->cert_rsa);
+ egg_bytes_unref (test->key_rsa);
+ egg_bytes_unref (test->cert_dsa);
+ egg_bytes_unref (test->key_dsa);
}
static void
@@ -96,7 +90,7 @@ on_parser_parsed (GcrParser *parser,
}
static GckAttributes*
-parse_attributes_for_key (gpointer data, gsize n_data)
+parse_attributes_for_key (EggBytes *data)
{
GcrParser *parser;
GckAttributes *attrs = NULL;
@@ -104,7 +98,8 @@ parse_attributes_for_key (gpointer data, gsize n_data)
parser = gcr_parser_new ();
g_signal_connect (parser, "parsed", G_CALLBACK (on_parser_parsed), &attrs);
- gcr_parser_parse_data (parser, data, n_data, &error);
+ gcr_parser_parse_data (parser, egg_bytes_get_data (data),
+ egg_bytes_get_size (data), &error);
g_assert_no_error (error);
g_object_unref (parser);
@@ -113,30 +108,30 @@ parse_attributes_for_key (gpointer data, gsize n_data)
}
static GckAttributes *
-build_attributes_for_cert (guchar *data,
- gsize n_data)
+build_attributes_for_cert (EggBytes *data)
{
GckAttributes *attrs;
attrs = gck_attributes_new ();
- gck_attributes_add_data (attrs, CKA_VALUE, data, n_data);
+ gck_attributes_add_data (attrs, CKA_VALUE, egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
gck_attributes_add_ulong (attrs, CKA_CERTIFICATE_TYPE, CKC_X_509);
return attrs;
}
-static gconstpointer
-parse_subject_public_key_info_for_cert (gpointer data, gsize n_data, gsize *n_info)
+static EggBytes *
+parse_subject_public_key_info_for_cert (EggBytes *data)
{
- gconstpointer info;
+ EggBytes *info;
GNode *asn;
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
- g_assert (asn);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data);
+ g_assert (asn != NULL);
- info = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", NULL), n_info);
- g_assert (info);
+ info = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "tbsCertificate", "subjectPublicKeyInfo", NULL));
+ g_assert (info != NULL);
egg_asn1x_destroy (asn);
return info;
@@ -146,16 +141,17 @@ static void
test_rsa (Test *test, gconstpointer unused)
{
GckAttributes *key, *cert;
- gconstpointer info;
- gsize n_info;
+ EggBytes *info;
guchar *fingerprint1, *fingerprint2, *fingerprint3;
gsize n_fingerprint1, n_fingerprint2, n_fingerprint3;
- key = parse_attributes_for_key (test->key_rsa, test->n_key_rsa);
- info = parse_subject_public_key_info_for_cert (test->cert_rsa, test->n_cert_rsa, &n_info);
- cert = build_attributes_for_cert (test->cert_rsa, test->n_cert_rsa);
+ key = parse_attributes_for_key (test->key_rsa);
+ info = parse_subject_public_key_info_for_cert (test->cert_rsa);
+ cert = build_attributes_for_cert (test->cert_rsa);
- fingerprint1 = gcr_fingerprint_from_subject_public_key_info (info, n_info, G_CHECKSUM_SHA1, &n_fingerprint1);
+ fingerprint1 = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (info),
+ egg_bytes_get_size (info),
+ G_CHECKSUM_SHA1, &n_fingerprint1);
fingerprint2 = gcr_fingerprint_from_attributes (key, G_CHECKSUM_SHA1, &n_fingerprint2);
fingerprint3 = gcr_fingerprint_from_attributes (cert, G_CHECKSUM_SHA1, &n_fingerprint3);
@@ -166,6 +162,7 @@ test_rsa (Test *test, gconstpointer unused)
g_free (fingerprint2);
g_free (fingerprint3);
+ egg_bytes_unref (info);
gck_attributes_unref (key);
gck_attributes_unref (cert);
}
@@ -174,16 +171,17 @@ static void
test_dsa (Test *test, gconstpointer unused)
{
GckAttributes *key, *cert;
- gconstpointer info;
- gsize n_info;
+ EggBytes *info;
guchar *fingerprint1, *fingerprint2, *fingerprint3;
gsize n_fingerprint1, n_fingerprint2, n_fingerprint3;
- key = parse_attributes_for_key (test->key_dsa, test->n_key_dsa);
- info = parse_subject_public_key_info_for_cert (test->cert_dsa, test->n_cert_dsa, &n_info);
- cert = build_attributes_for_cert (test->cert_dsa, test->n_cert_dsa);
+ key = parse_attributes_for_key (test->key_dsa);
+ info = parse_subject_public_key_info_for_cert (test->cert_dsa);
+ cert = build_attributes_for_cert (test->cert_dsa);
- fingerprint1 = gcr_fingerprint_from_subject_public_key_info (info, n_info, G_CHECKSUM_SHA1, &n_fingerprint1);
+ fingerprint1 = gcr_fingerprint_from_subject_public_key_info (egg_bytes_get_data (info),
+ egg_bytes_get_size (info),
+ G_CHECKSUM_SHA1, &n_fingerprint1);
fingerprint2 = gcr_fingerprint_from_attributes (key, G_CHECKSUM_SHA1, &n_fingerprint2);
fingerprint3 = gcr_fingerprint_from_attributes (cert, G_CHECKSUM_SHA1, &n_fingerprint3);
@@ -194,6 +192,7 @@ test_dsa (Test *test, gconstpointer unused)
g_free (fingerprint2);
g_free (fingerprint3);
+ egg_bytes_unref (info);
gck_attributes_unref (key);
gck_attributes_unref (cert);
}
diff --git a/gcr/tests/test-openpgp.c b/gcr/tests/test-openpgp.c
index be41f40..cfc1dad 100644
--- a/gcr/tests/test-openpgp.c
+++ b/gcr/tests/test-openpgp.c
@@ -240,15 +240,14 @@ compare_fixture_with_records (const gchar *fixture,
static void
on_openpgp_packet (GPtrArray *records,
- const guchar *outer,
- gsize n_outer,
+ EggBytes *outer,
gpointer user_data)
{
Test *test = user_data;
guint seen;
/* Should be parseable again */
- seen = _gcr_openpgp_parse (outer, n_outer, test->fixture->flags |
+ seen = _gcr_openpgp_parse (outer, test->fixture->flags |
GCR_OPENPGP_PARSE_NO_RECORDS, NULL, NULL);
g_assert_cmpuint (seen, ==, 1);
@@ -263,10 +262,8 @@ on_openpgp_packet (GPtrArray *records,
static void
on_armor_parsed (GQuark type,
- const guchar *data,
- gsize n_data,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *data,
+ EggBytes *outer,
GHashTable *headers,
gpointer user_data)
{
@@ -279,7 +276,7 @@ on_armor_parsed (GQuark type,
g_assert_cmpstr (value, ==, test->fixture->version);
}
- seen = _gcr_openpgp_parse (data, n_data, test->fixture->flags,
+ seen = _gcr_openpgp_parse (data, test->fixture->flags,
on_openpgp_packet, test);
g_assert_cmpuint (seen, >, 0);
@@ -294,6 +291,7 @@ test_openpgp_armor (Test *test,
gconstpointer data)
{
GError *error = NULL;
+ EggBytes *bytes;
gchar *armor;
gsize length;
guint parts;
@@ -301,10 +299,11 @@ test_openpgp_armor (Test *test,
g_file_get_contents (test->fixture->filename, &armor, &length, &error);
g_assert_no_error (error);
- parts = egg_armor_parse (armor, length, on_armor_parsed, test);
+ bytes = egg_bytes_new_take (armor, length);
+ parts = egg_armor_parse (bytes, on_armor_parsed, test);
g_assert_cmpuint (parts, ==, 1);
- g_free (armor);
+ egg_bytes_unref (bytes);
}
static void
@@ -312,6 +311,7 @@ test_openpgp_binary (Test *test,
gconstpointer data)
{
GError *error = NULL;
+ EggBytes *bytes;
gchar *binary;
gsize length;
guint seen;
@@ -319,8 +319,8 @@ test_openpgp_binary (Test *test,
g_file_get_contents (test->fixture->filename, &binary, &length, &error);
g_assert_no_error (error);
- seen = _gcr_openpgp_parse (binary, length, test->fixture->flags,
- on_openpgp_packet, test);
+ bytes = egg_bytes_new_take (binary, length);
+ seen = _gcr_openpgp_parse (bytes, test->fixture->flags, on_openpgp_packet, test);
g_assert_cmpuint (seen, >, 0);
if (*(test->at) != NULL) {
@@ -328,7 +328,7 @@ test_openpgp_binary (Test *test,
g_assert_not_reached ();
}
- g_free (binary);
+ egg_bytes_unref (binary);
}
int
diff --git a/gcr/tests/test-openssh.c b/gcr/tests/test-openssh.c
index 81634da..b7742d9 100644
--- a/gcr/tests/test-openssh.c
+++ b/gcr/tests/test-openssh.c
@@ -91,8 +91,7 @@ static void
on_openssh_pub_parse (GckAttributes *attrs,
const gchar *label,
const gchar *options,
- const gchar *outer,
- gsize n_outer,
+ EggBytes *outer,
gpointer user_data)
{
Test *test = user_data;
@@ -104,7 +103,7 @@ on_openssh_pub_parse (GckAttributes *attrs,
g_assert_cmpstr (options, ==, test->expected_options);
/* The block should parse properly */
- keys = _gcr_openssh_pub_parse (outer, n_outer, NULL, NULL);
+ keys = _gcr_openssh_pub_parse (outer, NULL, NULL);
g_assert_cmpuint (keys, ==, 1);
}
@@ -113,14 +112,16 @@ test_parse_v1_rsa (Test *test,
gconstpointer unused)
{
const gchar *data = OPENSSH_PUBLIC_RSA1 EXTRA_LINES_WITHOUT_KEY;
+ EggBytes *bytes;
gint keys;
test->expected_label = "rsa-key example com";
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
+ bytes = egg_bytes_new_static (data, strlen (data));
+ keys = _gcr_openssh_pub_parse (bytes, on_openssh_pub_parse, test);
g_assert_cmpint (keys, ==, 1);
+ egg_bytes_unref (bytes);
}
static void
@@ -128,13 +129,16 @@ test_parse_v2_rsa (Test *test,
gconstpointer unused)
{
const gchar *data = OPENSSH_PUBLIC_RSA2 EXTRA_LINES_WITHOUT_KEY;
+ EggBytes *bytes;
gint keys;
test->expected_label = "rsa-key example com";
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
+ bytes = egg_bytes_new_static (data, strlen (data));
+ keys = _gcr_openssh_pub_parse (bytes, on_openssh_pub_parse, test);
g_assert_cmpint (keys, ==, 1);
+
+ egg_bytes_unref (bytes);
}
static void
@@ -142,13 +146,16 @@ test_parse_v2_dsa (Test *test,
gconstpointer unused)
{
const gchar *data = OPENSSH_PUBLIC_DSA2 EXTRA_LINES_WITHOUT_KEY;
+ EggBytes *bytes;
gint keys;
test->expected_label = "dsa-key example com";
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
+ bytes = egg_bytes_new_static (data, strlen (data));
+ keys = _gcr_openssh_pub_parse (bytes, on_openssh_pub_parse, test);
g_assert_cmpint (keys, ==, 1);
+
+ egg_bytes_unref (bytes);
}
static void
@@ -156,13 +163,16 @@ test_parse_v1_options (Test *test,
gconstpointer unused)
{
const gchar *data = "option1,option2=\"value 2\",option3 " OPENSSH_PUBLIC_RSA1;
+ EggBytes *bytes;
gint keys;
test->expected_options = "option1,option2=\"value 2\",option3";
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
+ bytes = egg_bytes_new_static (data, strlen (data));
+ keys = _gcr_openssh_pub_parse (bytes, on_openssh_pub_parse, test);
g_assert_cmpint (keys, ==, 1);
+
+ egg_bytes_unref (bytes);
}
static void
@@ -170,13 +180,16 @@ test_parse_v2_options (Test *test,
gconstpointer unused)
{
const gchar *data = "option1,option2=\"value 2\",option3 " OPENSSH_PUBLIC_RSA2;
+ EggBytes *bytes;
gint keys;
test->expected_options = "option1,option2=\"value 2\",option3";
- keys = _gcr_openssh_pub_parse (data, strlen (data),
- on_openssh_pub_parse, test);
+ bytes = egg_bytes_new_static (data, strlen (data));
+ keys = _gcr_openssh_pub_parse (bytes, on_openssh_pub_parse, test);
g_assert_cmpint (keys, ==, 1);
+
+ egg_bytes_unref (bytes);
}
int
diff --git a/gcr/tests/test-pkcs11-certificate.c b/gcr/tests/test-pkcs11-certificate.c
index 7c04c07..daf97e1 100644
--- a/gcr/tests/test-pkcs11-certificate.c
+++ b/gcr/tests/test-pkcs11-certificate.c
@@ -53,8 +53,8 @@ setup (Test *test, gconstpointer unused)
GckAttributes *attrs;
CK_FUNCTION_LIST_PTR f;
GckModule *module;
- gconstpointer subject;
- gsize n_subject;
+ EggBytes *subject;
+ EggBytes *bytes;
GNode *asn, *node;
CK_RV rv;
@@ -82,20 +82,24 @@ setup (Test *test, gconstpointer unused)
gcr_pkcs11_set_modules (modules);
gck_list_unref_free (modules);
- asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate",
- test->cert_data, test->n_cert_data);
+ bytes = egg_bytes_new_static (test->cert_data, test->n_cert_data);
+ asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes);
g_assert (asn);
node = egg_asn1x_node (asn, "tbsCertificate", "subject", NULL);
- subject = egg_asn1x_get_raw_element (node, &n_subject);
+ subject = egg_asn1x_get_raw_element (node);
/* Add a certificate to the module */
attrs = gck_attributes_new ();
gck_attributes_add_data (attrs, CKA_VALUE, test->cert_data, test->n_cert_data);
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
gck_attributes_add_ulong (attrs, CKA_CERTIFICATE_TYPE, CKC_X_509);
- gck_attributes_add_data (attrs, CKA_SUBJECT, subject, n_subject);
+ gck_attributes_add_data (attrs, CKA_SUBJECT,
+ egg_bytes_get_data (subject),
+ egg_bytes_get_size (subject));
gck_mock_module_take_object (attrs);
+ egg_bytes_unref (bytes);
+ egg_bytes_unref (subject);
egg_asn1x_destroy (asn);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]