[gnome-keyring] gcr: GcrParser now reports current format for block parsed
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: GcrParser now reports current format for block parsed
- Date: Tue, 27 Sep 2011 15:14:57 +0000 (UTC)
commit 10ace51a6d5596691596c3786f99ebe2445d9203
Author: Stef Walter <stefw collabora co uk>
Date: Wed Sep 14 08:34:12 2011 +0200
gcr: GcrParser now reports current format for block parsed
* The current format represents the inner most block
* Refactor GcrParser so that we can accurately track the state of
the parsed items when multiple functions contribute to that state.
docs/reference/gcr/gcr-sections.txt | 1 +
gcr/gcr-base.symbols | 1 +
gcr/gcr-parser.c | 664 +++++++++++++++++++++--------------
gcr/gcr-parser.h | 8 +-
gcr/gcr-types.h | 3 +-
gcr/tests/test-parser.c | 9 +-
6 files changed, 410 insertions(+), 276 deletions(-)
---
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index ea40ee1..fe3419a 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -19,6 +19,7 @@ gcr_parser_get_parsed_label
gcr_parser_get_parsed_description
gcr_parser_get_parsed_attributes
gcr_parser_get_parsed_block
+gcr_parser_get_parsed_format
<SUBSECTION Standard>
GcrParserPrivate
GCR_PARSER
diff --git a/gcr/gcr-base.symbols b/gcr/gcr-base.symbols
index 15f77b0..49b54e8 100644
--- a/gcr/gcr-base.symbols
+++ b/gcr/gcr-base.symbols
@@ -59,6 +59,7 @@ gcr_parser_format_supported
gcr_parser_get_parsed_attributes
gcr_parser_get_parsed_block
gcr_parser_get_parsed_description
+gcr_parser_get_parsed_format
gcr_parser_get_parsed_label
gcr_parser_get_type
gcr_parser_new
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index 8f8b92f..d18034b 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -80,33 +80,6 @@
*/
/**
- * GcrDataFormat:
- * @GCR_FORMAT_INVALID: Not a valid format
- * @GCR_FORMAT_DER_PRIVATE_KEY: DER encoded private key
- * @GCR_FORMAT_DER_PRIVATE_KEY_RSA: DER encoded RSA private key
- * @GCR_FORMAT_DER_PRIVATE_KEY_DSA: DER encoded DSA private key
- * @GCR_FORMAT_DER_CERTIFICATE_X509: DER encoded X.509 certificate
- * @GCR_FORMAT_DER_PKCS7: DER encoded PKCS\#7 container file which can contain certificates
- * @GCR_FORMAT_DER_PKCS8: DER encoded PKCS\#8 file which can contain a key
- * @GCR_FORMAT_DER_PKCS8_PLAIN: Unencrypted DER encoded PKCS\#8 file which can contain a key
- * @GCR_FORMAT_DER_PKCS8_ENCRYPTED: Encrypted DER encoded PKCS\#8 file which can contain a key
- * @GCR_FORMAT_DER_PKCS12: DER encoded PKCS\#12 file which can contain certificates and/or keys
- * @GCR_FORMAT_OPENSSH_PUBLIC: OpenSSH v1 or v2 public key
- * @GCR_FORMAT_OPENPGP_PACKET: OpenPGP key packet(s)
- * @GCR_FORMAT_OPENPGP_ARMOR: OpenPGP public or private key armor encoded data
- * @GCR_FORMAT_PEM: An OpenSSL style PEM file with unspecified contents
- * @GCR_FORMAT_PEM_PRIVATE_KEY_RSA: An OpenSSL style PEM file with a private RSA key
- * @GCR_FORMAT_PEM_PRIVATE_KEY_DSA: An OpenSSL style PEM file with a private DSA key
- * @GCR_FORMAT_PEM_CERTIFICATE_X509: An OpenSSL style PEM file with an X.509 certificate
- * @GCR_FORMAT_PEM_PKCS7: An OpenSSL style PEM file containing PKCS\#7
- * @GCR_FORMAT_PEM_PKCS8_PLAIN: Unencrypted OpenSSL style PEM file containing PKCS\#8
- * @GCR_FORMAT_PEM_PKCS8_ENCRYPTED: Encrypted OpenSSL style PEM file containing PKCS\#8
- * @GCR_FORMAT_PEM_PKCS12: An OpenSSL style PEM file containing PKCS\#12
- *
- * The various format identifiers.
- */
-
-/**
* GCR_DATA_ERROR:
*
* A domain for data errors with codes from #GcrDataError
@@ -139,16 +112,21 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
+typedef struct _GcrParsed {
+ GckAttributes *attrs;
+ const gchar *description;
+ gchar *label;
+ gconstpointer block;
+ gsize n_block;
+ GcrDataFormat format;
+ struct _GcrParsed *next;
+} GcrParsed;
+
struct _GcrParserPrivate {
GTree *specific_formats;
gboolean normal_formats;
GPtrArray *passwords;
-
- GckAttributes *parsed_attrs;
- const gchar *parsed_desc;
- gchar *parsed_label;
- gconstpointer parsing_block;
- gsize parsing_n_block;
+ GcrParsed *parsed;
};
G_DEFINE_TYPE (GcrParser, gcr_parser, G_TYPE_OBJECT);
@@ -226,135 +204,159 @@ init_quarks (void)
* INTERNAL
*/
+static void
+parsed_attribute (GcrParsed *parsed,
+ CK_ATTRIBUTE_TYPE type,
+ gconstpointer data,
+ gsize n_data)
+{
+ g_assert (parsed);
+ g_assert (parsed->attrs);
+ gck_attributes_add_data (parsed->attrs, type, data, n_data);
+}
+
static gboolean
-parsed_asn1_attribute (GcrParser *self, GNode *asn, const guchar *data, gsize n_data,
- const gchar *part, CK_ATTRIBUTE_TYPE type)
+parsed_asn1_attribute (GcrParsed *parsed,
+ GNode *asn,
+ const guchar *data,
+ gsize n_data,
+ const gchar *part,
+ CK_ATTRIBUTE_TYPE type)
{
const guchar *value;
gsize n_value;
-
- g_assert (GCR_IS_PARSER (self));
+
g_assert (asn);
g_assert (data);
- g_assert (self->pv->parsed_attrs);
+ g_assert (parsed);
value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, part, NULL), &n_value);
if (value == NULL)
return FALSE;
/* TODO: Convert to USG FROM STD */
- gck_attributes_add_data (self->pv->parsed_attrs, type, value, n_value);
+ parsed_attribute (parsed, type, value, n_value);
return TRUE;
}
static void
-parsing_begin (GcrParser *self,
+parsed_ulong_attribute (GcrParsed *parsed,
+ CK_ATTRIBUTE_TYPE type,
+ gulong value)
+{
+ g_assert (parsed);
+ g_assert (parsed->attrs);
+ gck_attributes_add_ulong (parsed->attrs, type, value);
+}
+
+static void
+parsed_boolean_attribute (GcrParsed *parsed,
+ CK_ATTRIBUTE_TYPE type,
+ gboolean value)
+{
+ g_assert (parsed);
+ g_assert (parsed->attrs);
+ gck_attributes_add_boolean (parsed->attrs, type, value);
+}
+
+
+static void
+parsing_block (GcrParsed *parsed,
+ gint format,
gconstpointer block,
gsize n_block)
{
- g_assert (GCR_IS_PARSER (self));
+ g_assert (parsed);
g_assert (block);
g_assert (n_block);
+ g_assert (format);
+ g_assert (!parsed->block);
- if (self->pv->parsed_attrs)
- gck_attributes_unref (self->pv->parsed_attrs);
- self->pv->parsed_attrs = NULL;
-
- self->pv->parsing_block = block;
- self->pv->parsing_n_block = n_block;
+ parsed->format = format;
+ parsed->block = block;
+ parsed->n_block = n_block;
}
static void
-parsed_description (GcrParser *self,
+parsed_description (GcrParsed *parsed,
CK_OBJECT_CLASS klass)
{
+ g_assert (parsed);
switch (klass) {
case CKO_PRIVATE_KEY:
- self->pv->parsed_desc = _("Private Key");
+ parsed->description = _("Private Key");
break;
case CKO_CERTIFICATE:
- self->pv->parsed_desc = _("Certificate");
+ parsed->description = _("Certificate");
break;
case CKO_PUBLIC_KEY:
- self->pv->parsed_desc = _("Public Key");
+ parsed->description = _("Public Key");
break;
default:
- self->pv->parsed_desc = NULL;
+ parsed->description = NULL;
break;
}
}
static void
-parsing_object (GcrParser *self,
+parsing_object (GcrParsed *parsed,
CK_OBJECT_CLASS klass)
{
- g_return_if_fail (self->pv->parsed_attrs == NULL);
+ g_assert (parsed);
+ g_assert (!parsed->attrs);
if (klass == CKO_PRIVATE_KEY)
- self->pv->parsed_attrs = gck_attributes_new_full ((GckAllocator)egg_secure_realloc);
+ parsed->attrs = gck_attributes_new_full ((GckAllocator)egg_secure_realloc);
else
- self->pv->parsed_attrs = gck_attributes_new ();
- gck_attributes_add_ulong (self->pv->parsed_attrs, CKA_CLASS, klass);
- parsed_description (self, klass);
+ parsed->attrs = gck_attributes_new ();
+ gck_attributes_add_ulong (parsed->attrs, CKA_CLASS, klass);
+ parsed_description (parsed, klass);
}
static void
-parsed_attributes (GcrParser *self,
+parsed_attributes (GcrParsed *parsed,
GckAttributes *attrs)
{
gulong klass;
- g_return_if_fail (self->pv->parsed_attrs == NULL);
- g_return_if_fail (attrs != NULL);
+ g_assert (parsed);
+ g_assert (attrs);
+ g_assert (!parsed->attrs);
- self->pv->parsed_attrs = gck_attributes_ref (attrs);
+ parsed->attrs = gck_attributes_ref (attrs);
if (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
- parsed_description (self, klass);
+ parsed_description (parsed, klass);
}
static void
-parsed_label (GcrParser *self, const gchar *label)
+parsed_label (GcrParsed *parsed,
+ const gchar *label)
{
- g_free (self->pv->parsed_label);
- self->pv->parsed_label = g_strdup (label);
+ g_assert (parsed);
+ g_assert (!parsed->label);
+ parsed->label = g_strdup (label);
}
-static void
-parsed_attribute (GcrParser *self, CK_ATTRIBUTE_TYPE type, gconstpointer data, gsize n_data)
+static GcrParsed *
+push_parsed (GcrParser *self)
{
- g_assert (GCR_IS_PARSER (self));
- g_assert (self->pv->parsed_attrs);
- gck_attributes_add_data (self->pv->parsed_attrs, type, data, n_data);
+ GcrParsed *parsed = g_new0 (GcrParsed, 1);
+ parsed->next = self->pv->parsed;
+ self->pv->parsed = parsed;
+ return parsed;
}
static void
-parsing_end (GcrParser *self)
+pop_parsed (GcrParser *self,
+ GcrParsed *parsed)
{
- g_assert (GCR_IS_PARSER (self));
- self->pv->parsing_block = NULL;
- self->pv->parsing_n_block = 0;
- if (self->pv->parsed_attrs)
- gck_attributes_unref (self->pv->parsed_attrs);
- self->pv->parsed_attrs = NULL;
- g_free (self->pv->parsed_label);
- self->pv->parsed_label = NULL;
- self->pv->parsed_desc = NULL;
-}
+ g_assert (parsed == self->pv->parsed);
-static void
-parsed_ulong (GcrParser *self, CK_ATTRIBUTE_TYPE type, gulong value)
-{
- g_assert (GCR_IS_PARSER (self));
- g_assert (self->pv->parsed_attrs);
- gck_attributes_add_ulong (self->pv->parsed_attrs, type, value);
-}
+ self->pv->parsed = parsed->next;
-static void
-parsed_boolean (GcrParser *self, CK_ATTRIBUTE_TYPE type, gboolean value)
-{
- g_assert (GCR_IS_PARSER (self));
- g_assert (self->pv->parsed_attrs);
- gck_attributes_add_boolean (self->pv->parsed_attrs, type, value);
+ gck_attributes_unref (parsed->attrs);
+ g_free (parsed->label);
+ g_free (parsed);
}
static gint
@@ -404,8 +406,13 @@ enum_next_password (GcrParser *self, PasswordState *state, const gchar **passwor
}
static void
-parsed_fire (GcrParser *self)
+parsed_fire (GcrParser *self,
+ GcrParsed *parsed)
{
+ g_assert (GCR_IS_PARSER (self));
+ g_assert (parsed);
+ g_assert (parsed == self->pv->parsed);
+
g_object_notify (G_OBJECT (self), "parsed-description");
g_object_notify (G_OBJECT (self), "parsed-attributes");
g_object_notify (G_OBJECT (self), "parsed-label");
@@ -423,15 +430,18 @@ parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
gint res = GCR_ERROR_UNRECOGNIZED;
GNode *asn = NULL;
gulong version;
+ GcrParsed *parsed;
+
+ parsed = push_parsed (self);
asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
if (!asn)
goto done;
- parsing_begin (self, data, n_data);
- parsing_object (self, CKO_PRIVATE_KEY);
- parsed_ulong (self, CKA_KEY_TYPE, CKK_RSA);
- parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
+ parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
+ parsing_object (parsed, CKO_PRIVATE_KEY);
+ parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_RSA);
+ parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
res = GCR_ERROR_FAILURE;
if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
@@ -444,23 +454,23 @@ parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
goto done;
}
- if (!parsed_asn1_attribute (self, asn, data, n_data, "modulus", CKA_MODULUS) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "publicExponent", CKA_PUBLIC_EXPONENT) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "privateExponent", CKA_PRIVATE_EXPONENT) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "prime1", CKA_PRIME_1) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "prime2", CKA_PRIME_2) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "coefficient", CKA_COEFFICIENT))
+ if (!parsed_asn1_attribute (parsed, asn, data, n_data, "modulus", CKA_MODULUS) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "publicExponent", CKA_PUBLIC_EXPONENT) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "privateExponent", CKA_PRIVATE_EXPONENT) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "prime1", CKA_PRIME_1) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "prime2", CKA_PRIME_2) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "coefficient", CKA_COEFFICIENT))
goto done;
-
- parsed_fire (self);
+
+ parsed_fire (self, parsed);
res = SUCCESS;
- parsing_end (self);
done:
egg_asn1x_destroy (asn);
if (res == GCR_ERROR_FAILURE)
g_message ("invalid RSA key");
+ pop_parsed (self, parsed);
return res;
}
@@ -473,32 +483,35 @@ parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
{
gint ret = GCR_ERROR_UNRECOGNIZED;
GNode *asn = NULL;
+ GcrParsed *parsed;
+
+ parsed = push_parsed (self);
asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
if (!asn)
goto done;
- parsing_begin (self, data, n_data);
- parsing_object (self, CKO_PRIVATE_KEY);
- parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
- parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
+ parsing_block (parsed, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
+ parsing_object (parsed, CKO_PRIVATE_KEY);
+ parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
+ parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
ret = GCR_ERROR_FAILURE;
- if (!parsed_asn1_attribute (self, asn, data, n_data, "p", CKA_PRIME) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "q", CKA_SUBPRIME) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "g", CKA_BASE) ||
- !parsed_asn1_attribute (self, asn, data, n_data, "priv", CKA_VALUE))
+ if (!parsed_asn1_attribute (parsed, asn, data, n_data, "p", CKA_PRIME) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "q", CKA_SUBPRIME) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "g", CKA_BASE) ||
+ !parsed_asn1_attribute (parsed, asn, data, n_data, "priv", CKA_VALUE))
goto done;
-
- parsed_fire (self);
+
+ parsed_fire (self, parsed);
ret = SUCCESS;
- parsing_end (self);
done:
egg_asn1x_destroy (asn);
if (ret == GCR_ERROR_FAILURE)
g_message ("invalid DSA key");
+ pop_parsed (self, parsed);
return ret;
}
@@ -509,23 +522,27 @@ parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n
gint ret = GCR_ERROR_UNRECOGNIZED;
GNode *asn_params = NULL;
GNode *asn_key = NULL;
+ GcrParsed *parsed;
+
+ parsed = push_parsed (self);
asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata, n_keydata);
if (!asn_params || !asn_key)
goto done;
- parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
- parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
+ parsing_object (parsed, CKO_PRIVATE_KEY);
+ parsed_ulong_attribute (parsed, CKA_KEY_TYPE, CKK_DSA);
+ parsed_boolean_attribute (parsed, CKA_PRIVATE, CK_TRUE);
ret = GCR_ERROR_FAILURE;
- if (!parsed_asn1_attribute (self, asn_params, params, n_params, "p", CKA_PRIME) ||
- !parsed_asn1_attribute (self, asn_params, params, n_params, "q", CKA_SUBPRIME) ||
- !parsed_asn1_attribute (self, asn_params, params, n_params, "g", CKA_BASE) ||
- !parsed_asn1_attribute (self, asn_key, keydata, n_keydata, NULL, CKA_VALUE))
+ if (!parsed_asn1_attribute (parsed, asn_params, params, n_params, "p", CKA_PRIME) ||
+ !parsed_asn1_attribute (parsed, asn_params, params, n_params, "q", CKA_SUBPRIME) ||
+ !parsed_asn1_attribute (parsed, asn_params, params, n_params, "g", CKA_BASE) ||
+ !parsed_asn1_attribute (parsed, asn_key, keydata, n_keydata, NULL, CKA_VALUE))
goto done;
- parsed_fire (self);
+ parsed_fire (self, parsed);
ret = SUCCESS;
done:
@@ -534,6 +551,7 @@ done:
if (ret == GCR_ERROR_FAILURE)
g_message ("invalid DSA key");
+ pop_parsed (self, parsed);
return ret;
}
@@ -568,13 +586,16 @@ parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
const guchar *params;
gsize n_params;
GNode *asn = NULL;
+ GcrParsed *parsed;
+ parsed = push_parsed (self);
ret = GCR_ERROR_UNRECOGNIZED;
asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
if (!asn)
goto done;
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS8_PLAIN, data, n_data);
ret = GCR_ERROR_FAILURE;
key_type = GCK_INVALID;
@@ -609,15 +630,10 @@ done:
/* Try the normal sane format */
ret = parse_der_private_key_dsa (self, keydata, n_keydata);
- parsing_begin (self, data, n_data);
- parsing_object (self, CKO_PRIVATE_KEY);
-
/* 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);
-
- parsing_end (self);
break;
default:
g_message ("invalid or unsupported key type in PKCS#8 key");
@@ -630,6 +646,7 @@ done:
}
egg_asn1x_destroy (asn);
+ pop_parsed (self, parsed);
return ret;
}
@@ -647,13 +664,16 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
gsize n_crypted, n_params;
const gchar *password;
gint l;
+ GcrParsed *parsed;
+ parsed = push_parsed (self);
ret = GCR_ERROR_UNRECOGNIZED;
asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
if (!asn)
goto done;
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS8_ENCRYPTED, data, n_data);
ret = GCR_ERROR_FAILURE;
/* Figure out the type of encryption */
@@ -663,9 +683,6 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
- parsing_begin (self, data, n_data);
- parsing_object (self, CKO_PRIVATE_KEY);
-
/* Loop to try different passwords */
for (;;) {
@@ -712,14 +729,13 @@ parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
/* We assume unrecognized data, is a bad encryption key */
}
- parsing_end (self);
-
done:
if (cih)
gcry_cipher_close (cih);
egg_asn1x_destroy (asn);
egg_secure_free (crypted);
+ pop_parsed (self, parsed);
return ret;
}
@@ -744,30 +760,32 @@ parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
{
gchar *name = NULL;
GNode *asn;
+ GcrParsed *parsed;
asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
if (asn == NULL)
return GCR_ERROR_UNRECOGNIZED;
- parsing_begin (self, data, n_data);
- parsing_object (self, CKO_CERTIFICATE);
+ parsed = push_parsed (self);
- parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
+ parsing_block (parsed, GCR_FORMAT_DER_CERTIFICATE_X509, data, n_data);
+ parsing_object (parsed, CKO_CERTIFICATE);
+ parsed_ulong_attribute (parsed, CKA_CERTIFICATE_TYPE, CKC_X_509);
- if (self->pv->parsed_label == NULL)
+ if (gcr_parser_get_parsed_label (self) == NULL)
name = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
egg_asn1x_destroy (asn);
if (name != NULL) {
- parsed_label (self, name);
+ parsed_label (parsed, name);
g_free (name);
}
- parsed_attribute (self, CKA_VALUE, data, n_data);
- parsed_fire (self);
+ parsed_attribute (parsed, CKA_VALUE, data, n_data);
+ parsed_fire (self, parsed);
- parsing_end (self);
+ pop_parsed (self, parsed);
return SUCCESS;
}
@@ -826,13 +844,16 @@ parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
const guchar* content = NULL;
gsize n_content;
GQuark oid;
+ GcrParsed *parsed;
+ parsed = push_parsed (self);
ret = GCR_ERROR_UNRECOGNIZED;
asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data, n_data);
if (!asn)
goto done;
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS7, data, n_data);
ret = GCR_ERROR_FAILURE;
node = egg_asn1x_node (asn, "contentType", NULL);
@@ -856,6 +877,7 @@ parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
done:
egg_asn1x_destroy (asn);
+ pop_parsed (self, parsed);
return ret;
}
@@ -981,6 +1003,7 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
gchar *friendly;
gsize n_element;
guint i;
+ GcrParsed *parsed;
ret = GCR_ERROR_UNRECOGNIZED;
@@ -1009,9 +1032,11 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
if (!element)
goto done;
+ parsed = push_parsed (self);
+
friendly = parse_pkcs12_bag_friendly_name (egg_asn1x_node (asn, i, "bagAttributes", NULL));
if (friendly != NULL)
- parsed_label (self, friendly);
+ parsed_label (parsed, friendly);
/* A normal unencrypted key */
if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
@@ -1030,8 +1055,7 @@ handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
r = GCR_ERROR_UNRECOGNIZED;
}
- if (friendly != NULL)
- parsed_label (self, NULL);
+ pop_parsed (self, parsed);
if (r == GCR_ERROR_FAILURE ||
r == GCR_ERROR_CANCELLED ||
@@ -1323,7 +1347,9 @@ parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
guchar *content = NULL;
gsize n_element, n_content;
GQuark oid;
+ GcrParsed *parsed;
+ parsed = push_parsed (self);
ret = GCR_ERROR_UNRECOGNIZED;
asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-12-PFX",
@@ -1331,7 +1357,7 @@ parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
if (!asn)
goto done;
- parsing_begin (self, data, n_data);
+ parsing_block (parsed, GCR_FORMAT_DER_PKCS12, data, n_data);
oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
if (!oid)
@@ -1360,12 +1386,11 @@ parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
if (ret == SUCCESS)
ret = handle_pkcs12_safe (self, content, n_content);
- parsing_end (self);
-
done:
g_free (content);
egg_asn1x_destroy (asn_content);
egg_asn1x_destroy (asn);
+ pop_parsed (self, parsed);
return ret;
}
@@ -1381,12 +1406,15 @@ on_openpgp_packet (GPtrArray *records,
gpointer user_data)
{
GcrParser *self = GCR_PARSER (user_data);
+ GcrParsed *parsed;
+
+ parsed = push_parsed (self);
/* All we can do is the packet bounds */
- parsing_begin (self, outer, n_outer);
- parsing_object (self, CKO_DATA);
- parsed_fire (self);
- parsing_end (self);
+ parsing_block (parsed, GCR_FORMAT_OPENPGP_PACKET, outer, n_outer);
+ parsing_object (parsed, CKO_DATA);
+ parsed_fire (self, parsed);
+ pop_parsed (self, parsed);
}
static gint
@@ -1404,52 +1432,69 @@ parse_openpgp_packets (GcrParser *self,
}
/* -----------------------------------------------------------------------------
- * PEM PARSING
+ * ARMOR PARSING
*/
+static gboolean
+formats_for_armor_type (GQuark armor_type,
+ gint *inner_format,
+ gint *outer_format)
+{
+ gint dummy;
+ if (!inner_format)
+ inner_format = &dummy;
+ if (!outer_format)
+ outer_format = &dummy;
+
+ if (armor_type == PEM_RSA_PRIVATE_KEY) {
+ *inner_format = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
+ *outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_RSA;
+ } else if (armor_type == PEM_DSA_PRIVATE_KEY) {
+ *inner_format = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
+ *outer_format = GCR_FORMAT_PEM_PRIVATE_KEY_DSA;
+ } else if (armor_type == PEM_ANY_PRIVATE_KEY) {
+ *inner_format = GCR_FORMAT_DER_PRIVATE_KEY;
+ *outer_format = GCR_FORMAT_PEM_PRIVATE_KEY;
+ } else if (armor_type == PEM_PRIVATE_KEY) {
+ *inner_format = GCR_FORMAT_DER_PKCS8_PLAIN;
+ *outer_format = GCR_FORMAT_PEM_PKCS8_PLAIN;
+ } else if (armor_type == PEM_ENCRYPTED_PRIVATE_KEY) {
+ *inner_format = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
+ *outer_format = GCR_FORMAT_PEM_PKCS8_ENCRYPTED;
+ } else if (armor_type == PEM_CERTIFICATE) {
+ *inner_format = GCR_FORMAT_DER_CERTIFICATE_X509;
+ *outer_format = GCR_FORMAT_PEM_CERTIFICATE_X509;
+ } else if (armor_type == PEM_PKCS7) {
+ *inner_format = GCR_FORMAT_DER_PKCS7;
+ *outer_format = GCR_FORMAT_PEM_PKCS7;
+ } else if (armor_type == PEM_PKCS12) {
+ *inner_format = GCR_FORMAT_DER_PKCS12;
+ *outer_format = GCR_FORMAT_PEM_PKCS12;
+ } else if (armor_type == ARMOR_PGP_PRIVATE_KEY_BLOCK) {
+ *inner_format = GCR_FORMAT_OPENPGP_PACKET;
+ *outer_format = GCR_FORMAT_OPENPGP_ARMOR;
+ } else if (armor_type == ARMOR_PGP_PUBLIC_KEY_BLOCK) {
+ *inner_format = GCR_FORMAT_OPENPGP_PACKET;
+ *outer_format = GCR_FORMAT_OPENPGP_ARMOR;
+ } else {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static gint
-handle_plain_pem (GcrParser *self, GQuark type, gint subformat,
- const guchar *data, gsize n_data)
+handle_plain_pem (GcrParser *self,
+ gint format_id,
+ gint want_format,
+ const guchar *data,
+ gsize n_data)
{
ParserFormat *format;
- gint format_id;
-
- if (type == PEM_RSA_PRIVATE_KEY)
- format_id = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
-
- else if (type == PEM_DSA_PRIVATE_KEY)
- format_id = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
-
- else if (type == PEM_ANY_PRIVATE_KEY)
- format_id = GCR_FORMAT_DER_PRIVATE_KEY;
-
- else if (type == PEM_PRIVATE_KEY)
- format_id = GCR_FORMAT_DER_PKCS8_PLAIN;
-
- else if (type == PEM_ENCRYPTED_PRIVATE_KEY)
- format_id = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
-
- else if (type == PEM_CERTIFICATE)
- format_id = GCR_FORMAT_DER_CERTIFICATE_X509;
-
- else if (type == PEM_PKCS7)
- format_id = GCR_FORMAT_DER_PKCS7;
-
- else if (type == PEM_PKCS12)
- format_id = GCR_FORMAT_DER_PKCS12;
-
- else if (type == ARMOR_PGP_PRIVATE_KEY_BLOCK)
- format_id = GCR_FORMAT_OPENPGP_PACKET;
- else if (type == ARMOR_PGP_PUBLIC_KEY_BLOCK)
- format_id = GCR_FORMAT_OPENPGP_PACKET;
-
- else
+ if (want_format != 0 && want_format != format_id)
return GCR_ERROR_UNRECOGNIZED;
- if (subformat != 0 && subformat != format_id)
- return GCR_ERROR_UNRECOGNIZED;
-
format = parser_format_lookup (format_id);
if (format == NULL)
return GCR_ERROR_UNRECOGNIZED;
@@ -1457,29 +1502,13 @@ handle_plain_pem (GcrParser *self, GQuark type, gint subformat,
return (format->function) (self, data, n_data);
}
-static CK_OBJECT_CLASS
-pem_type_to_class (gint type)
-{
- if (type == PEM_RSA_PRIVATE_KEY ||
- type == PEM_DSA_PRIVATE_KEY ||
- type == PEM_ANY_PRIVATE_KEY ||
- type == PEM_PRIVATE_KEY ||
- type == PEM_ENCRYPTED_PRIVATE_KEY)
- return CKO_PRIVATE_KEY;
-
- else if (type == PEM_CERTIFICATE)
- return CKO_CERTIFICATE;
-
- else if (type == PEM_PKCS7 ||
- type == PEM_PKCS12)
- return 0;
-
- return 0;
-}
-
static gint
-handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
- GHashTable *headers, const guchar *data, gsize n_data)
+handle_encrypted_pem (GcrParser *self,
+ gint format_id,
+ gint want_format,
+ GHashTable *headers,
+ const guchar *data,
+ gsize n_data)
{
PasswordState pstate = PASSWORD_STATE_INIT;
const gchar *password;
@@ -1489,11 +1518,10 @@ handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
gboolean ret;
gint res;
gint l;
-
+
g_assert (GCR_IS_PARSER (self));
g_assert (headers);
- g_assert (type);
-
+
val = g_hash_table_lookup (headers, "DEK-Info");
if (!val) {
g_message ("missing encryption header");
@@ -1526,7 +1554,8 @@ handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
n_decrypted = l;
/* Try to parse */
- res = handle_plain_pem (self, type, subformat, decrypted, n_decrypted);
+ res = handle_plain_pem (self, format_id, want_format,
+ decrypted, n_decrypted);
egg_secure_free (decrypted);
/* Unrecognized is a bad password */
@@ -1540,7 +1569,7 @@ handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
typedef struct {
GcrParser *parser;
gint result;
- gint subformat;
+ gint want_format;
} HandlePemArgs;
static void
@@ -1556,14 +1585,21 @@ handle_pem_data (GQuark type,
gint res = GCR_ERROR_FAILURE;
gboolean encrypted = FALSE;
const gchar *val;
-
+ gint inner_format;
+ gint outer_format;
+ GcrParsed *parsed;
+
/* Something already failed to parse */
if (args->result == GCR_ERROR_FAILURE)
return;
+ if (!formats_for_armor_type (type, &inner_format, &outer_format))
+ return;
+
+ parsed = push_parsed (args->parser);
+
/* Fill in information necessary for prompting */
- parsing_begin (args->parser, outer, n_outer);
- parsing_object (args->parser, pem_type_to_class (type));
+ parsing_block (parsed, outer_format, outer, n_outer);
/* See if it's encrypted PEM all openssl like*/
if (headers) {
@@ -1573,13 +1609,14 @@ handle_pem_data (GQuark type,
}
if (encrypted)
- res = handle_encrypted_pem (args->parser, type, args->subformat,
- headers, data, n_data);
+ res = handle_encrypted_pem (args->parser, inner_format,
+ args->want_format, headers,
+ data, n_data);
else
- res = handle_plain_pem (args->parser, type, args->subformat,
- data, n_data);
+ res = handle_plain_pem (args->parser, inner_format,
+ args->want_format, data, n_data);
- parsing_end (args->parser);
+ pop_parsed (args->parser, parsed);
if (res != GCR_ERROR_UNRECOGNIZED) {
if (args->result == GCR_ERROR_UNRECOGNIZED)
@@ -1676,12 +1713,14 @@ on_openssh_public_key_parsed (GckAttributes *attrs,
gpointer user_data)
{
GcrParser *self = GCR_PARSER (user_data);
+ GcrParsed *parsed;
- parsing_begin (self, outer, n_outer);
- parsed_attributes (self, attrs);
- parsed_label (self, label);
- parsed_fire (self);
- parsing_end (self);
+ parsed = push_parsed (self);
+ parsing_block (parsed, GCR_FORMAT_OPENSSH_PUBLIC, outer, n_outer);
+ parsed_attributes (parsed, attrs);
+ parsed_label (parsed, label);
+ parsed_fire (self, parsed);
+ pop_parsed (self, parsed);
}
static gint
@@ -1703,6 +1742,34 @@ parse_openssh_public (GcrParser *self,
* FORMATS
*/
+/**
+ * GcrDataFormat:
+ * @GCR_FORMAT_INVALID: Not a valid format
+ * @GCR_FORMAT_DER_PRIVATE_KEY: DER encoded private key
+ * @GCR_FORMAT_DER_PRIVATE_KEY_RSA: DER encoded RSA private key
+ * @GCR_FORMAT_DER_PRIVATE_KEY_DSA: DER encoded DSA private key
+ * @GCR_FORMAT_DER_CERTIFICATE_X509: DER encoded X.509 certificate
+ * @GCR_FORMAT_DER_PKCS7: DER encoded PKCS\#7 container file which can contain certificates
+ * @GCR_FORMAT_DER_PKCS8: DER encoded PKCS\#8 file which can contain a key
+ * @GCR_FORMAT_DER_PKCS8_PLAIN: Unencrypted DER encoded PKCS\#8 file which can contain a key
+ * @GCR_FORMAT_DER_PKCS8_ENCRYPTED: Encrypted DER encoded PKCS\#8 file which can contain a key
+ * @GCR_FORMAT_DER_PKCS12: DER encoded PKCS\#12 file which can contain certificates and/or keys
+ * @GCR_FORMAT_OPENSSH_PUBLIC: OpenSSH v1 or v2 public key
+ * @GCR_FORMAT_OPENPGP_PACKET: OpenPGP key packet(s)
+ * @GCR_FORMAT_OPENPGP_ARMOR: OpenPGP public or private key armor encoded data
+ * @GCR_FORMAT_PEM: An OpenSSL style PEM file with unspecified contents
+ * @GCR_FORMAT_PEM_PRIVATE_KEY: An OpenSSL style PEM file with a private key
+ * @GCR_FORMAT_PEM_PRIVATE_KEY_RSA: An OpenSSL style PEM file with a private RSA key
+ * @GCR_FORMAT_PEM_PRIVATE_KEY_DSA: An OpenSSL style PEM file with a private DSA key
+ * @GCR_FORMAT_PEM_CERTIFICATE_X509: An OpenSSL style PEM file with an X.509 certificate
+ * @GCR_FORMAT_PEM_PKCS7: An OpenSSL style PEM file containing PKCS\#7
+ * @GCR_FORMAT_PEM_PKCS8_PLAIN: Unencrypted OpenSSL style PEM file containing PKCS\#8
+ * @GCR_FORMAT_PEM_PKCS8_ENCRYPTED: Encrypted OpenSSL style PEM file containing PKCS\#8
+ * @GCR_FORMAT_PEM_PKCS12: An OpenSSL style PEM file containing PKCS\#12
+ *
+ * The various format identifiers.
+ */
+
/* In order of parsing when no formats specified */
static const ParserFormat parser_normal[] = {
{ GCR_FORMAT_PEM, parse_pem },
@@ -1830,14 +1897,9 @@ gcr_parser_dispose (GObject *obj)
{
GcrParser *self = GCR_PARSER (obj);
gsize i;
-
- if (self->pv->parsed_attrs)
- gck_attributes_unref (self->pv->parsed_attrs);
- self->pv->parsed_attrs = NULL;
-
- g_free (self->pv->parsed_label);
- self->pv->parsed_label = NULL;
-
+
+ g_assert (!self->pv->parsed);
+
for (i = 0; i < self->pv->passwords->len; ++i)
egg_secure_strfree (g_ptr_array_index (self->pv->passwords, i));
g_ptr_array_set_size (self->pv->passwords, 0);
@@ -1849,9 +1911,8 @@ static void
gcr_parser_finalize (GObject *obj)
{
GcrParser *self = GCR_PARSER (obj);
-
- g_assert (!self->pv->parsed_attrs);
- g_assert (!self->pv->parsed_label);
+
+ g_assert (!self->pv->parsed);
g_ptr_array_free (self->pv->passwords, TRUE);
self->pv->passwords = NULL;
@@ -2078,14 +2139,15 @@ gcr_parser_parse_data (GcrParser *self, gconstpointer data,
/**
* gcr_parser_format_enable:
* @self: The parser
- * @format_id: The format identifier
+ * @format: The format identifier
*
* Enable parsing of the given format. Use -1 to enable all the formats.
*/
void
-gcr_parser_format_enable (GcrParser *self, gint format_id)
+gcr_parser_format_enable (GcrParser *self,
+ GcrDataFormat format)
{
- const ParserFormat *format;
+ const ParserFormat *form;
guint i;
g_return_if_fail (GCR_IS_PARSER (self));
@@ -2093,16 +2155,16 @@ gcr_parser_format_enable (GcrParser *self, gint format_id)
if (!self->pv->specific_formats)
self->pv->specific_formats = g_tree_new (compare_pointers);
- if (format_id != -1) {
- format = parser_format_lookup (format_id);
- g_return_if_fail (format);
+ if (format != -1) {
+ form = parser_format_lookup (format);
+ g_return_if_fail (form);
g_tree_insert (self->pv->specific_formats,
- (gpointer)format, (gpointer)format);
+ (gpointer)form, (gpointer)form);
} else {
for (i = 0; i < G_N_ELEMENTS (parser_formats); i++) {
- format = &parser_formats[i];
- g_tree_insert (self->pv->specific_formats, (gpointer)format,
- (gpointer)format);
+ form = &parser_formats[i];
+ g_tree_insert (self->pv->specific_formats, (gpointer)form,
+ (gpointer)form);
}
}
}
@@ -2110,18 +2172,19 @@ gcr_parser_format_enable (GcrParser *self, gint format_id)
/**
* gcr_parser_format_disable:
* @self: The parser
- * @format_id: The format identifier
+ * @format: The format identifier
*
* Disable parsing of the given format. Use -1 to disable all the formats.
*/
void
-gcr_parser_format_disable (GcrParser *self, gint format_id)
+gcr_parser_format_disable (GcrParser *self,
+ GcrDataFormat format)
{
- ParserFormat *format;
+ ParserFormat *form;
g_return_if_fail (GCR_IS_PARSER (self));
- if (format_id == -1) {
+ if (format == -1) {
if (self->pv->specific_formats)
g_tree_destroy (self->pv->specific_formats);
self->pv->specific_formats = NULL;
@@ -2131,27 +2194,28 @@ gcr_parser_format_disable (GcrParser *self, gint format_id)
if (!self->pv->specific_formats)
return;
- format = parser_format_lookup (format_id);
- g_return_if_fail (format);
+ form = parser_format_lookup (format);
+ g_return_if_fail (form);
- g_tree_remove (self->pv->specific_formats, format);
+ g_tree_remove (self->pv->specific_formats, form);
}
/**
* gcr_parser_format_supported:
* @self: The parser
- * @format_id: The format identifier
+ * @format: The format identifier
*
* Check whether the given format is supported by the parser.
*
* Returns: Whether the format is supported.
*/
gboolean
-gcr_parser_format_supported (GcrParser *self, gint format_id)
+gcr_parser_format_supported (GcrParser *self,
+ GcrDataFormat format)
{
g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
- g_return_val_if_fail (format_id != -1, FALSE);
- return parser_format_lookup (format_id) ? TRUE : FALSE;
+ g_return_val_if_fail (format != -1, FALSE);
+ return parser_format_lookup (format) ? TRUE : FALSE;
}
/**
@@ -2167,8 +2231,16 @@ gcr_parser_format_supported (GcrParser *self, gint format_id)
const gchar*
gcr_parser_get_parsed_description (GcrParser *self)
{
+ GcrParsed *parsed;
+
g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- return self->pv->parsed_desc;
+
+ for (parsed = self->pv->parsed; parsed != NULL; parsed = parsed->next) {
+ if (parsed->description != NULL)
+ return parsed->description;
+ }
+
+ return NULL;
}
/**
@@ -2184,8 +2256,16 @@ gcr_parser_get_parsed_description (GcrParser *self)
GckAttributes*
gcr_parser_get_parsed_attributes (GcrParser *self)
{
+ GcrParsed *parsed;
+
g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- return self->pv->parsed_attrs;
+
+ for (parsed = self->pv->parsed; parsed != NULL; parsed = parsed->next) {
+ if (parsed->attrs != NULL)
+ return parsed->attrs;
+ }
+
+ return NULL;
}
/**
@@ -2201,8 +2281,16 @@ gcr_parser_get_parsed_attributes (GcrParser *self)
const gchar*
gcr_parser_get_parsed_label (GcrParser *self)
{
+ GcrParsed *parsed;
+
g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
- return self->pv->parsed_label;
+
+ for (parsed = self->pv->parsed; parsed != NULL; parsed = parsed->next) {
+ if (parsed->label != NULL)
+ return parsed->label;
+ }
+
+ return NULL;
}
/**
@@ -2220,10 +2308,46 @@ gconstpointer
gcr_parser_get_parsed_block (GcrParser *self,
gsize *n_block)
{
+ GcrParsed *parsed;
+
g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
g_return_val_if_fail (n_block, NULL);
- *n_block = self->pv->parsing_n_block;
- return self->pv->parsing_block;
+
+ for (parsed = self->pv->parsed; parsed != NULL; parsed = parsed->next) {
+ if (parsed->block != NULL) {
+ *n_block = parsed->n_block;
+ return parsed->block;
+ }
+ }
+
+ *n_block = 0;
+ return NULL;
+}
+
+/**
+ * gcr_parser_get_parsed_format:
+ * @self: a parser
+ *
+ * Get the format of the raw data block that represents this parsed object.
+ * This corresponds with the data returned from gcr_parser_get_parsed_block().
+ *
+ * This is only valid during the GcrParser::parsed signal.
+ *
+ * Returns: The data format of the currently parsed item.
+ */
+GcrDataFormat
+gcr_parser_get_parsed_format (GcrParser *self)
+{
+ GcrParsed *parsed;
+
+ g_return_val_if_fail (GCR_IS_PARSER (self), 0);
+
+ for (parsed = self->pv->parsed; parsed != NULL; parsed = parsed->next) {
+ if (parsed->block != NULL)
+ return parsed->format;
+ }
+
+ return 0;
}
/* ---------------------------------------------------------------------------------
diff --git a/gcr/gcr-parser.h b/gcr/gcr-parser.h
index 1887fd4..d6cb1c5 100644
--- a/gcr/gcr-parser.h
+++ b/gcr/gcr-parser.h
@@ -67,13 +67,13 @@ GType gcr_parser_get_type (void);
GcrParser* gcr_parser_new (void);
void gcr_parser_format_enable (GcrParser *self,
- gint format_id);
+ GcrDataFormat format);
void gcr_parser_format_disable (GcrParser *self,
- gint format_id);
+ GcrDataFormat format);
gboolean gcr_parser_format_supported (GcrParser *self,
- gint format_id);
+ GcrDataFormat format);
gboolean gcr_parser_parse_data (GcrParser *self,
gconstpointer data,
@@ -107,6 +107,8 @@ GckAttributes* gcr_parser_get_parsed_attributes (GcrParser *self);
gconstpointer gcr_parser_get_parsed_block (GcrParser *self,
gsize *n_block);
+GcrDataFormat gcr_parser_get_parsed_format (GcrParser *self);
+
G_END_DECLS
#endif /* __GCR_PARSER_H__ */
diff --git a/gcr/gcr-types.h b/gcr/gcr-types.h
index 317e552..1cade80 100644
--- a/gcr/gcr-types.h
+++ b/gcr/gcr-types.h
@@ -83,7 +83,8 @@ typedef enum {
GCR_FORMAT_PEM_PKCS7,
GCR_FORMAT_PEM_PKCS8_PLAIN,
GCR_FORMAT_PEM_PKCS8_ENCRYPTED,
- GCR_FORMAT_PEM_PKCS12
+ GCR_FORMAT_PEM_PKCS12,
+ GCR_FORMAT_PEM_PRIVATE_KEY
} GcrDataFormat;
G_END_DECLS
diff --git a/gcr/tests/test-parser.c b/gcr/tests/test-parser.c
index 199478e..1fa3bc1 100644
--- a/gcr/tests/test-parser.c
+++ b/gcr/tests/test-parser.c
@@ -58,7 +58,8 @@ typedef struct {
} Test;
static void
-ensure_block_can_be_parsed (gconstpointer block,
+ensure_block_can_be_parsed (GcrDataFormat format,
+ gconstpointer block,
gsize n_block)
{
GcrParser *parser;
@@ -69,6 +70,8 @@ ensure_block_can_be_parsed (gconstpointer block,
g_assert (n_block);
parser = gcr_parser_new ();
+ gcr_parser_format_disable (parser, -1);
+ gcr_parser_format_enable (parser, format);
result = gcr_parser_parse_data (parser, block, n_block, &error);
if (!result) {
@@ -89,6 +92,7 @@ parsed_item (GcrParser *par, gpointer user_data)
Test *test = user_data;
gconstpointer block;
gsize n_block;
+ GcrDataFormat format;
g_assert (GCR_IS_PARSER (par));
g_assert (par == test->parser);
@@ -99,7 +103,8 @@ parsed_item (GcrParser *par, gpointer user_data)
description = gcr_parser_get_parsed_description (test->parser);
label = gcr_parser_get_parsed_label (test->parser);
block = gcr_parser_get_parsed_block (test->parser, &n_block);
- ensure_block_can_be_parsed (block, n_block);
+ format = gcr_parser_get_parsed_format (test->parser);
+ ensure_block_can_be_parsed (format, block, n_block);
if (g_test_verbose ())
g_print ("%s: '%s'\n", description, label);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]