From: Stef Walter Date: Wed, 16 Nov 2011 07:38:44 +0000 (+0100) Subject: gcr: Use GBytes immutable ref counted byte buffers X-Git-Tag: 3.3.3.1~75 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=97cd79171dfbba24394f070f3946b20c2d518d2d;p=platform%2Fupstream%2Fgcr.git 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 --- 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 +#include + 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 +#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-byte-array.c b/egg/egg-byte-array.c deleted file mode 100644 index 6f9f736..0000000 --- a/egg/egg-byte-array.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Collabora Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General License for more details. - * - * You should have received a copy of the GNU Lesser General - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Author: Stef Walter - */ - -#include "egg-byte-array.h" - -#include - -guint -egg_byte_array_hash (gconstpointer v) -{ - const GByteArray *array = v; - const signed char *p; - guint32 h = 0; - gsize i; - - g_assert (array); - g_assert (array->data); - p = (signed char*)array->data; - - /* 31 bit hash function */ - for (i = 0; i < array->len; ++i, ++p) - h = (h << 5) - h + *p; - - return h; -} - -gboolean -egg_byte_array_equal (gconstpointer v1, gconstpointer v2) -{ - const GByteArray *array1 = v1; - const GByteArray *array2 = v2; - - if (array1 == array2) - return TRUE; - if (!array1 || !array2) - return FALSE; - - if (array1->len != array2->len) - return FALSE; - - g_assert (array1->data); - g_assert (array2->data); - - return (memcmp (array1->data, array2->data, array1->len) == 0); -} diff --git a/egg/egg-byte-array.h b/egg/egg-byte-array.h deleted file mode 100644 index f03b34d..0000000 --- a/egg/egg-byte-array.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * gnome-keyring - * - * Copyright (C) 2010 Collabora Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General License for more details. - * - * You should have received a copy of the GNU Lesser General - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - * Author: Stef Walter - */ - -#ifndef EGG_BYTE_ARRAY_H_ -#define EGG_BYTE_ARRAY_H_ - -#include - -guint egg_byte_array_hash (gconstpointer v); - -gboolean egg_byte_array_equal (gconstpointer v1, gconstpointer v2); - -#endif /* EGG_BYTE_ARRAY_H_ */ 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 + */ + +#include "config.h" + +#include "egg-bytes.h" + +#include + +#include + +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 + * Stef Walter + */ + +#ifndef __EGG_BYTES_H__ +#define __EGG_BYTES_H__ + +#include +#include + +/** + * 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 +#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 -int egg_openssl_parse_algo (const gchar *name, int *mode); +#include -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 +#include + 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 #include +#include + 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 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 +#include + 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 +#include + #include 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 +#include + 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 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); }