4 * Copyright (C) 2008 Stefan Walter
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
26 #include "gcr-internal.h"
27 #include "gcr-importer.h"
28 #include "gcr-marshal.h"
30 #include "gcr-parser.h"
31 #include "gcr-types.h"
33 #include "egg/egg-asn1x.h"
34 #include "egg/egg-asn1-defs.h"
35 #include "egg/egg-dn.h"
36 #include "egg/egg-openssl.h"
37 #include "egg/egg-secure-memory.h"
38 #include "egg/egg-symkey.h"
40 #include <glib/gi18n-lib.h>
48 * @short_description: Parser for certificate and key files
50 * A #GcrParser can parse various certificate and key files such as OpenSSL
51 * PEM files, DER encoded certifictes, PKCS\#8 keys and so on. Each various
52 * format is identified by a value in the #GcrDataFormat enumeration.
54 * In order to parse data, a new parser is created with gcr_parser_new() and
55 * then the GcrParser::authenticate and GcrParser::parsed signals should be
56 * connected to. Data is then fed to the parser via gcr_parser_parse_data()
57 * or gcr_parser_parse_stream().
59 * During the GcrParsed::parsed signal the attributes that make up the currently
60 * parsed item can be retrieved using the gcr_parser_get_parsed_attributes()
67 * A parser for parsing various types of files or data.
72 * @parent_class: The parent class
73 * @authenticate: The default handler for the authenticate signal.
74 * @parsed: The default handler for the parsed signal.
76 * The class for #GcrParser
81 * @GCR_FORMAT_INVALID: Not a valid format
82 * @GCR_FORMAT_DER_PRIVATE_KEY: DER encoded private key
83 * @GCR_FORMAT_DER_PRIVATE_KEY_RSA: DER encoded RSA private key
84 * @GCR_FORMAT_DER_PRIVATE_KEY_DSA: DER encoded DSA private key
85 * @GCR_FORMAT_DER_CERTIFICATE_X509: DER encoded X.509 certificate
86 * @GCR_FORMAT_DER_PKCS7: DER encoded PKCS\#7 container file which can contain certificates
87 * @GCR_FORMAT_DER_PKCS8: DER encoded PKCS\#8 file which can contain a key
88 * @GCR_FORMAT_DER_PKCS8_PLAIN: Unencrypted DER encoded PKCS\#8 file which can contain a key
89 * @GCR_FORMAT_DER_PKCS8_ENCRYPTED: Encrypted DER encoded PKCS\#8 file which can contain a key
90 * @GCR_FORMAT_DER_PKCS12: DER encoded PKCS\#12 file which can contain certificates and/or keys
91 * @GCR_FORMAT_PEM: An OpenSSL style PEM file with unspecified contents
92 * @GCR_FORMAT_PEM_PRIVATE_KEY_RSA: An OpenSSL style PEM file with a private RSA key
93 * @GCR_FORMAT_PEM_PRIVATE_KEY_DSA: An OpenSSL style PEM file with a private DSA key
94 * @GCR_FORMAT_PEM_CERTIFICATE_X509: An OpenSSL style PEM file with an X.509 certificate
95 * @GCR_FORMAT_PEM_PKCS7: An OpenSSL style PEM file containing PKCS\#7
96 * @GCR_FORMAT_PEM_PKCS8_PLAIN: Unencrypted OpenSSL style PEM file containing PKCS\#8
97 * @GCR_FORMAT_PEM_PKCS8_ENCRYPTED: Encrypted OpenSSL style PEM file containing PKCS\#8
98 * @GCR_FORMAT_PEM_PKCS12: An OpenSSL style PEM file containing PKCS\#12
100 * The various format identifiers.
106 * A domain for data errors with codes from #GcrDataError
111 * @GCR_ERROR_FAILURE: Failed to parse or serialize the data
112 * @GCR_ERROR_UNRECOGNIZED: The data was unrecognized or unsupported
113 * @GCR_ERROR_CANCELLED: The operation was cancelled
114 * @GCR_ERROR_LOCKED: The data was encrypted or locked and could not be unlocked.
116 * Values responding to error codes for parsing and serializing data.
122 PROP_PARSED_ATTRIBUTES,
123 PROP_PARSED_DESCRIPTION
134 static guint signals[LAST_SIGNAL] = { 0 };
136 struct _GcrParserPrivate {
137 GTree *specific_formats;
138 gboolean normal_formats;
139 GPtrArray *passwords;
141 GckAttributes *parsed_attrs;
142 const gchar *parsed_desc;
144 gconstpointer parsing_block;
145 gsize parsing_n_block;
148 G_DEFINE_TYPE (GcrParser, gcr_parser, G_TYPE_OBJECT);
155 #define PASSWORD_STATE_INIT { 0, 0 }
157 typedef struct _ParserFormat {
159 gint (*function) (GcrParser *self, const guchar *data, gsize n_data);
162 /* Forward declarations */
163 static const ParserFormat parser_normal[];
164 static const ParserFormat parser_formats[];
165 static ParserFormat* parser_format_lookup (gint format_id);
167 EGG_SECURE_DECLARE (parser);
169 /* -----------------------------------------------------------------------------
175 * The xxxxx in: ----- BEGIN xxxxx ------
178 static GQuark PEM_CERTIFICATE;
179 static GQuark PEM_RSA_PRIVATE_KEY;
180 static GQuark PEM_DSA_PRIVATE_KEY;
181 static GQuark PEM_ANY_PRIVATE_KEY;
182 static GQuark PEM_ENCRYPTED_PRIVATE_KEY;
183 static GQuark PEM_PRIVATE_KEY;
184 static GQuark PEM_PKCS7;
185 static GQuark PEM_PKCS12;
190 static volatile gsize quarks_inited = 0;
194 if (g_once_init_enter (&quarks_inited)) {
196 #define QUARK(name, value) \
197 name = g_quark_from_static_string(value)
199 QUARK (PEM_CERTIFICATE, "CERTIFICATE");
200 QUARK (PEM_PRIVATE_KEY, "PRIVATE KEY");
201 QUARK (PEM_RSA_PRIVATE_KEY, "RSA PRIVATE KEY");
202 QUARK (PEM_DSA_PRIVATE_KEY, "DSA PRIVATE KEY");
203 QUARK (PEM_ANY_PRIVATE_KEY, "ANY PRIVATE KEY");
204 QUARK (PEM_ENCRYPTED_PRIVATE_KEY, "ENCRYPTED PRIVATE KEY");
205 QUARK (PEM_PKCS7, "PKCS7");
206 QUARK (PEM_PKCS12, "PKCS12");
210 g_once_init_leave (&quarks_inited, 1);
214 /* -----------------------------------------------------------------------------
219 parsed_asn1_attribute (GcrParser *self, GNode *asn, const guchar *data, gsize n_data,
220 const gchar *part, CK_ATTRIBUTE_TYPE type)
225 g_assert (GCR_IS_PARSER (self));
228 g_assert (self->pv->parsed_attrs);
230 value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, part, NULL), &n_value);
234 /* TODO: Convert to USG FROM STD */
235 gck_attributes_add_data (self->pv->parsed_attrs, type, value, n_value);
240 parsing_begin (GcrParser *self,
241 CK_OBJECT_CLASS klass,
245 g_assert (GCR_IS_PARSER (self));
249 if (self->pv->parsed_attrs)
250 gck_attributes_unref (self->pv->parsed_attrs);
251 if (klass == CKO_PRIVATE_KEY)
252 self->pv->parsed_attrs = gck_attributes_new_full ((GckAllocator)egg_secure_realloc);
254 self->pv->parsed_attrs = gck_attributes_new ();
255 gck_attributes_add_ulong (self->pv->parsed_attrs, CKA_CLASS, klass);
258 case CKO_PRIVATE_KEY:
259 self->pv->parsed_desc = _("Private Key");
261 case CKO_CERTIFICATE:
262 self->pv->parsed_desc = _("Certificate");
265 self->pv->parsed_desc = _("Public Key");
268 self->pv->parsed_desc = NULL;
272 self->pv->parsing_block = block;
273 self->pv->parsing_n_block = n_block;
277 parsed_label (GcrParser *self, const gchar *label)
279 g_free (self->pv->parsed_label);
280 self->pv->parsed_label = g_strdup (label);
284 parsed_attribute (GcrParser *self, CK_ATTRIBUTE_TYPE type, gconstpointer data, gsize n_data)
286 g_assert (GCR_IS_PARSER (self));
287 g_assert (self->pv->parsed_attrs);
288 gck_attributes_add_data (self->pv->parsed_attrs, type, data, n_data);
292 parsing_end (GcrParser *self)
294 g_assert (GCR_IS_PARSER (self));
295 self->pv->parsing_block = NULL;
296 self->pv->parsing_n_block = 0;
297 if (self->pv->parsed_attrs)
298 gck_attributes_unref (self->pv->parsed_attrs);
299 self->pv->parsed_attrs = NULL;
300 g_free (self->pv->parsed_label);
301 self->pv->parsed_label = NULL;
302 self->pv->parsed_desc = NULL;
306 parsed_ulong (GcrParser *self, CK_ATTRIBUTE_TYPE type, gulong value)
308 g_assert (GCR_IS_PARSER (self));
309 g_assert (self->pv->parsed_attrs);
310 gck_attributes_add_ulong (self->pv->parsed_attrs, type, value);
314 parsed_boolean (GcrParser *self, CK_ATTRIBUTE_TYPE type, gboolean value)
316 g_assert (GCR_IS_PARSER (self));
317 g_assert (self->pv->parsed_attrs);
318 gck_attributes_add_boolean (self->pv->parsed_attrs, type, value);
322 enum_next_password (GcrParser *self, PasswordState *state, const gchar **password)
327 * Next passes we look through all the passwords that the parser
328 * has seen so far. This is because different parts of a encrypted
329 * container (such as PKCS#12) often use the same password even
330 * if with different algorithms.
332 * If we didn't do this and the user chooses enters a password,
333 * but doesn't save it, they would get prompted for the same thing
334 * over and over, dumb.
337 /* Look in our list of passwords */
338 if (state->seen < self->pv->passwords->len) {
339 g_assert (state->seen >= 0);
340 *password = g_ptr_array_index (self->pv->passwords, state->seen);
345 /* Fire off all the parsed property signals so anyone watching can update their state */
346 g_object_notify (G_OBJECT (self), "parsed-description");
347 g_object_notify (G_OBJECT (self), "parsed-attributes");
348 g_object_notify (G_OBJECT (self), "parsed-label");
350 g_signal_emit (self, signals[AUTHENTICATE], 0, state->ask_state, &result);
354 return GCR_ERROR_CANCELLED;
356 /* Return any passwords added */
357 if (state->seen < self->pv->passwords->len) {
358 g_assert (state->seen >= 0);
359 *password = g_ptr_array_index (self->pv->passwords, state->seen);
364 return GCR_ERROR_LOCKED;
368 parsed_fire (GcrParser *self)
370 g_object_notify (G_OBJECT (self), "parsed-description");
371 g_object_notify (G_OBJECT (self), "parsed-attributes");
372 g_object_notify (G_OBJECT (self), "parsed-label");
374 g_signal_emit (self, signals[PARSED], 0);
377 /* -----------------------------------------------------------------------------
382 parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
384 gint res = GCR_ERROR_UNRECOGNIZED;
388 asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
392 parsing_begin (self, CKO_PRIVATE_KEY, data, n_data);
393 parsed_ulong (self, CKA_KEY_TYPE, CKK_RSA);
394 parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
395 res = GCR_ERROR_FAILURE;
397 if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
400 /* We only support simple version */
402 res = GCR_ERROR_UNRECOGNIZED;
403 g_message ("unsupported version of RSA key: %lu", version);
407 if (!parsed_asn1_attribute (self, asn, data, n_data, "modulus", CKA_MODULUS) ||
408 !parsed_asn1_attribute (self, asn, data, n_data, "publicExponent", CKA_PUBLIC_EXPONENT) ||
409 !parsed_asn1_attribute (self, asn, data, n_data, "privateExponent", CKA_PRIVATE_EXPONENT) ||
410 !parsed_asn1_attribute (self, asn, data, n_data, "prime1", CKA_PRIME_1) ||
411 !parsed_asn1_attribute (self, asn, data, n_data, "prime2", CKA_PRIME_2) ||
412 !parsed_asn1_attribute (self, asn, data, n_data, "coefficient", CKA_COEFFICIENT))
420 egg_asn1x_destroy (asn);
421 if (res == GCR_ERROR_FAILURE)
422 g_message ("invalid RSA key");
427 /* -----------------------------------------------------------------------------
432 parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
434 gint ret = GCR_ERROR_UNRECOGNIZED;
437 asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
441 parsing_begin (self, CKO_PRIVATE_KEY, data, n_data);
442 parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
443 parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
444 ret = GCR_ERROR_FAILURE;
446 if (!parsed_asn1_attribute (self, asn, data, n_data, "p", CKA_PRIME) ||
447 !parsed_asn1_attribute (self, asn, data, n_data, "q", CKA_SUBPRIME) ||
448 !parsed_asn1_attribute (self, asn, data, n_data, "g", CKA_BASE) ||
449 !parsed_asn1_attribute (self, asn, data, n_data, "priv", CKA_VALUE))
457 egg_asn1x_destroy (asn);
458 if (ret == GCR_ERROR_FAILURE)
459 g_message ("invalid DSA key");
465 parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n_keydata,
466 const guchar *params, gsize n_params)
468 gint ret = GCR_ERROR_UNRECOGNIZED;
469 GNode *asn_params = NULL;
470 GNode *asn_key = NULL;
472 asn_params = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAParameters", params, n_params);
473 asn_key = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivatePart", keydata, n_keydata);
474 if (!asn_params || !asn_key)
477 parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
478 parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
479 ret = GCR_ERROR_FAILURE;
481 if (!parsed_asn1_attribute (self, asn_params, params, n_params, "p", CKA_PRIME) ||
482 !parsed_asn1_attribute (self, asn_params, params, n_params, "q", CKA_SUBPRIME) ||
483 !parsed_asn1_attribute (self, asn_params, params, n_params, "g", CKA_BASE) ||
484 !parsed_asn1_attribute (self, asn_key, keydata, n_keydata, NULL, CKA_VALUE))
491 egg_asn1x_destroy (asn_key);
492 egg_asn1x_destroy (asn_params);
493 if (ret == GCR_ERROR_FAILURE)
494 g_message ("invalid DSA key");
499 /* -----------------------------------------------------------------------------
504 parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
508 res = parse_der_private_key_rsa (self, data, n_data);
509 if (res == GCR_ERROR_UNRECOGNIZED)
510 res = parse_der_private_key_dsa (self, data, n_data);
515 /* -----------------------------------------------------------------------------
520 parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
523 CK_KEY_TYPE key_type;
525 const guchar *keydata;
527 const guchar *params;
531 ret = GCR_ERROR_UNRECOGNIZED;
533 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
537 ret = GCR_ERROR_FAILURE;
538 key_type = GCK_INVALID;
540 key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
543 else if (key_algo == GCR_OID_PKIX1_RSA)
545 else if (key_algo == GCR_OID_PKIX1_DSA)
548 if (key_type == GCK_INVALID) {
549 ret = GCR_ERROR_UNRECOGNIZED;
553 keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
557 params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL), &n_params);
562 if (ret == SUCCESS) {
565 ret = parse_der_private_key_rsa (self, keydata, n_keydata);
568 /* Try the normal sane format */
569 ret = parse_der_private_key_dsa (self, keydata, n_keydata);
571 parsing_begin (self, CKO_PRIVATE_KEY, data, n_data);
572 /* Otherwise try the two part format that everyone seems to like */
573 if (ret == GCR_ERROR_UNRECOGNIZED && params && n_params)
574 ret = parse_der_private_key_dsa_parts (self, keydata, n_keydata,
579 g_message ("invalid or unsupported key type in PKCS#8 key");
580 ret = GCR_ERROR_UNRECOGNIZED;
584 } else if (ret == GCR_ERROR_FAILURE) {
585 g_message ("invalid PKCS#8 key");
588 egg_asn1x_destroy (asn);
593 parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
595 PasswordState pstate = PASSWORD_STATE_INIT;
597 gcry_cipher_hd_t cih = NULL;
601 guchar *crypted = NULL;
602 const guchar *params;
603 gsize n_crypted, n_params;
604 const gchar *password;
607 ret = GCR_ERROR_UNRECOGNIZED;
609 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
613 ret = GCR_ERROR_FAILURE;
615 /* Figure out the type of encryption */
616 scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
620 params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
622 parsing_begin (self, CKO_PRIVATE_KEY, data, n_data);
624 /* Loop to try different passwords */
627 g_assert (cih == NULL);
629 r = enum_next_password (self, &pstate, &password);
635 /* Parse the encryption stuff into a cipher. */
636 if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih))
639 crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted);
643 gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
644 gcry_cipher_close (cih);
648 g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
652 /* Unpad the DER data */
653 l = egg_asn1x_element_length (crypted, n_crypted);
657 /* Try to parse the resulting key */
658 r = parse_der_pkcs8_plain (self, crypted, n_crypted);
659 egg_secure_free (crypted);
662 if (r != GCR_ERROR_UNRECOGNIZED) {
667 /* We assume unrecognized data, is a bad encryption key */
674 gcry_cipher_close (cih);
675 egg_asn1x_destroy (asn);
676 egg_secure_free (crypted);
682 parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
686 ret = parse_der_pkcs8_plain (self, data, n_data);
687 if (ret == GCR_ERROR_UNRECOGNIZED)
688 ret = parse_der_pkcs8_encrypted (self, data, n_data);
693 /* -----------------------------------------------------------------------------
698 parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
703 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
705 return GCR_ERROR_UNRECOGNIZED;
707 parsing_begin (self, CKO_CERTIFICATE, data, n_data);
709 parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
711 if (self->pv->parsed_label == NULL)
712 name = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
714 egg_asn1x_destroy (asn);
717 parsed_label (self, name);
721 parsed_attribute (self, CKA_VALUE, data, n_data);
728 /* -----------------------------------------------------------------------------
733 handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
738 const guchar *certificate;
742 ret = GCR_ERROR_UNRECOGNIZED;
744 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-SignedData", data, n_data);
748 ret = GCR_ERROR_FAILURE;
750 for (i = 0; TRUE; ++i) {
752 node = egg_asn1x_node (asn, "certificates", i + 1, NULL);
754 /* No more certificates? */
758 certificate = egg_asn1x_get_raw_element (node, &n_certificate);
760 ret = parse_der_certificate (self, certificate, n_certificate);
765 /* TODO: Parse out all the CRLs */
770 egg_asn1x_destroy (asn);
775 parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
780 const guchar* content = NULL;
784 ret = GCR_ERROR_UNRECOGNIZED;
786 asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data, n_data);
790 ret = GCR_ERROR_FAILURE;
792 node = egg_asn1x_node (asn, "contentType", NULL);
796 oid = egg_asn1x_get_oid_as_quark (node);
797 g_return_val_if_fail (oid, GCR_ERROR_FAILURE);
799 /* Outer most one must just be plain data */
800 if (oid != GCR_OID_PKCS7_SIGNED_DATA) {
801 g_message ("unsupported outer content type in pkcs7: %s", g_quark_to_string (oid));
805 content = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "content", NULL), &n_content);
809 ret = handle_pkcs7_signed_data (self, content, n_content);
812 egg_asn1x_destroy (asn);
816 /* -----------------------------------------------------------------------------
821 decode_pkcs12_asn1_accepting_invalid_crap (const ASN1_ARRAY_TYPE *defs,
822 const gchar *identifier,
829 * Because PKCS#12 files, the bags specifically, are notorious for
830 * being crappily constructed and are often break rules such as DER
831 * sorting order etc.. we parse the DER in a non-strict fashion.
833 * The rules in DER are designed for X.509 certificates, so there is
834 * only one way to represent a given certificate (although they fail
835 * at that as well). But with PKCS#12 we don't have such high
836 * requirements, and we can slack off on our validation.
839 asn = egg_asn1x_create (defs, identifier);
840 g_return_val_if_fail (asn != NULL, NULL);
842 /* Passing FALSE as the strictness argument */
843 if (!egg_asn1x_decode_no_validate (asn, data, n_data) ||
844 !egg_asn1x_validate (asn, FALSE)) {
845 egg_asn1x_destroy (asn);
853 handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
856 GNode *asn_content = NULL;
857 guchar *certificate = NULL;
858 const guchar *element;
859 gsize n_certificate, n_element;
862 ret = GCR_ERROR_UNRECOGNIZED;
863 asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
869 ret = GCR_ERROR_FAILURE;
871 element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "certValue", NULL), &n_element);
875 asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element, n_element);
879 certificate = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_certificate);
883 ret = parse_der_certificate (self, certificate, n_certificate);
886 egg_asn1x_destroy (asn_content);
887 egg_asn1x_destroy (asn);
888 g_free (certificate);
893 parse_pkcs12_bag_friendly_name (GNode *asn)
898 gconstpointer element;
906 count = egg_asn1x_count (asn);
907 for (i = 1; i <= count; i++) {
908 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "type", NULL));
909 if (oid == GCR_OID_PKCS9_ATTRIBUTE_FRIENDLY) {
910 node = egg_asn1x_node (asn, i, "values", 1, NULL);
912 element = egg_asn1x_get_raw_element (node, &n_element);
913 asn_str = egg_asn1x_create_and_decode (pkix_asn1_tab, "BMPString",
916 result = egg_asn1x_get_bmpstring_as_utf8 (asn_str);
917 egg_asn1x_destroy (asn_str);
928 handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
934 const guchar *element;
939 ret = GCR_ERROR_UNRECOGNIZED;
941 asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
942 "pkcs-12-SafeContents",
947 ret = GCR_ERROR_FAILURE;
949 /* Get the number of elements in this bag */
950 count = egg_asn1x_count (asn);
953 * Now inside each bag are multiple elements. Who comes up
956 for (i = 1; i <= count; i++) {
958 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "bagId", NULL));
962 element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, i, "bagValue", NULL), &n_element);
966 friendly = parse_pkcs12_bag_friendly_name (egg_asn1x_node (asn, i, "bagAttributes", NULL));
967 if (friendly != NULL)
968 parsed_label (self, friendly);
970 /* A normal unencrypted key */
971 if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
972 r = parse_der_pkcs8_plain (self, element, n_element);
974 /* A properly encrypted key */
975 } else if (oid == GCR_OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
976 r = parse_der_pkcs8_encrypted (self, element, n_element);
979 } else if (oid == GCR_OID_PKCS12_BAG_CERTIFICATE) {
980 r = handle_pkcs12_cert_bag (self, element, n_element);
982 /* TODO: GCR_OID_PKCS12_BAG_CRL */
984 r = GCR_ERROR_UNRECOGNIZED;
987 if (friendly != NULL)
988 parsed_label (self, NULL);
990 if (r == GCR_ERROR_FAILURE ||
991 r == GCR_ERROR_CANCELLED ||
992 r == GCR_ERROR_LOCKED) {
1001 egg_asn1x_destroy (asn);
1006 handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
1008 PasswordState pstate = PASSWORD_STATE_INIT;
1010 gcry_cipher_hd_t cih = NULL;
1012 guchar *crypted = NULL;
1013 const guchar *params;
1014 gsize n_params, n_crypted;
1015 const gchar *password;
1020 ret = GCR_ERROR_UNRECOGNIZED;
1022 asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
1023 "pkcs-7-EncryptedData",
1028 ret = GCR_ERROR_FAILURE;
1030 /* Check the encryption schema OID */
1031 scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "algorithm", NULL));
1035 params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL), &n_params);
1039 /* Loop to try different passwords */
1042 g_assert (cih == NULL);
1044 r = enum_next_password (self, &pstate, &password);
1050 /* Parse the encryption stuff into a cipher. */
1051 if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih)) {
1052 ret = GCR_ERROR_FAILURE;
1056 crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedContentInfo", "encryptedContent", NULL),
1057 egg_secure_realloc, &n_crypted);
1061 gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
1062 gcry_cipher_close (cih);
1066 g_warning ("couldn't decrypt pkcs7 data: %s", gcry_strerror (gcry));
1070 /* Unpad the DER data */
1071 l = egg_asn1x_element_length (crypted, n_crypted);
1075 /* Try to parse the resulting key */
1076 r = handle_pkcs12_bag (self, crypted, n_crypted);
1077 egg_secure_free (crypted);
1080 if (r != GCR_ERROR_UNRECOGNIZED) {
1085 /* We assume unrecognized data is a bad encryption key */
1090 gcry_cipher_close (cih);
1091 egg_asn1x_destroy (asn);
1092 egg_secure_free (crypted);
1097 handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
1100 GNode *asn_content = NULL;
1103 guchar *content = NULL;
1104 gsize n_bag, n_content;
1109 ret = GCR_ERROR_UNRECOGNIZED;
1111 asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
1112 "pkcs-12-AuthenticatedSafe",
1117 ret = GCR_ERROR_FAILURE;
1120 * Inside each PKCS12 safe there are multiple bags.
1122 for (i = 0; TRUE; ++i) {
1123 node = egg_asn1x_node (asn, i + 1, "contentType", NULL);
1125 /* All done? no more bags */
1129 oid = egg_asn1x_get_oid_as_quark (node);
1131 node = egg_asn1x_node (asn, i + 1, "content", NULL);
1135 bag = egg_asn1x_get_raw_element (node, &n_bag);
1136 g_return_val_if_fail (bag, ret);
1138 /* A non encrypted bag, just parse */
1139 if (oid == GCR_OID_PKCS7_DATA) {
1141 egg_asn1x_destroy (asn_content);
1142 asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
1149 content = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_content);
1153 r = handle_pkcs12_bag (self, content, n_content);
1155 /* Encrypted data first needs decryption */
1156 } else if (oid == GCR_OID_PKCS7_ENCRYPTED_DATA) {
1157 r = handle_pkcs12_encrypted_bag (self, bag, n_bag);
1159 /* Hmmmm, not sure what this is */
1161 g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
1162 r = GCR_ERROR_UNRECOGNIZED;
1165 if (r == GCR_ERROR_FAILURE ||
1166 r == GCR_ERROR_CANCELLED ||
1167 r == GCR_ERROR_LOCKED) {
1176 egg_asn1x_destroy (asn);
1177 egg_asn1x_destroy (asn_content);
1183 verify_pkcs12_safe (GcrParser *self,
1185 gconstpointer content,
1188 PasswordState pstate = PASSWORD_STATE_INIT;
1189 const gchar *password;
1190 gcry_md_hd_t mdh = NULL;
1191 const guchar *mac_digest;
1193 guchar *digest = NULL;
1197 gconstpointer params;
1201 ret = GCR_ERROR_FAILURE;
1204 * The MAC is optional (and outside the encryption no less). I wonder
1205 * what the designers (ha) of PKCS#12 were trying to achieve
1208 mac_data = egg_asn1x_node (asn, "macData", NULL);
1209 if (mac_data == NULL)
1212 algorithm = egg_asn1x_get_oid_as_quark (egg_asn1x_node (mac_data, "mac",
1213 "digestAlgorithm", "algorithm", NULL));
1217 params = egg_asn1x_get_raw_element (mac_data, &n_params);
1221 digest = egg_asn1x_get_string_as_raw (egg_asn1x_node (mac_data, "mac", "digest", NULL), NULL, &n_digest);
1225 /* Loop to try different passwords */
1227 g_assert (mdh == NULL);
1229 r = enum_next_password (self, &pstate, &password);
1235 /* Parse the encryption stuff into a cipher. */
1236 if (!egg_symkey_read_mac (algorithm, password, -1, params, n_params,
1238 ret = GCR_ERROR_FAILURE;
1242 /* If not the right length, then that's really broken */
1243 if (mac_len != n_digest) {
1244 r = GCR_ERROR_FAILURE;
1247 gcry_md_write (mdh, content, n_content);
1248 mac_digest = gcry_md_read (mdh, 0);
1249 g_return_val_if_fail (mac_digest, GCR_ERROR_FAILURE);
1250 r = memcmp (mac_digest, digest, n_digest) == 0 ? SUCCESS : GCR_ERROR_LOCKED;
1253 gcry_md_close (mdh);
1256 if (r != GCR_ERROR_LOCKED) {
1264 gcry_md_close (mdh);
1271 parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
1274 GNode *asn_content = NULL;
1276 const guchar* element = NULL;
1277 guchar *content = NULL;
1278 gsize n_element, n_content;
1281 ret = GCR_ERROR_UNRECOGNIZED;
1283 asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-12-PFX",
1288 parsing_begin (self, 0, data, n_data);
1290 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
1294 /* Outer most one must just be plain data */
1295 if (oid != GCR_OID_PKCS7_DATA) {
1296 g_message ("unsupported safe content type in pkcs12: %s", g_quark_to_string (oid));
1300 element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "authSafe", "content", NULL), &n_element);
1304 asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-7-Data",
1305 element, n_element);
1309 content = egg_asn1x_get_string_as_raw (asn_content, g_realloc, &n_content);
1313 ret = verify_pkcs12_safe (self, asn, content, n_content);
1315 ret = handle_pkcs12_safe (self, content, n_content);
1321 egg_asn1x_destroy (asn_content);
1322 egg_asn1x_destroy (asn);
1326 /* -----------------------------------------------------------------------------
1331 handle_plain_pem (GcrParser *self, GQuark type, gint subformat,
1332 const guchar *data, gsize n_data)
1334 ParserFormat *format;
1337 if (type == PEM_RSA_PRIVATE_KEY)
1338 format_id = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
1340 else if (type == PEM_DSA_PRIVATE_KEY)
1341 format_id = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
1343 else if (type == PEM_ANY_PRIVATE_KEY)
1344 format_id = GCR_FORMAT_DER_PRIVATE_KEY;
1346 else if (type == PEM_PRIVATE_KEY)
1347 format_id = GCR_FORMAT_DER_PKCS8_PLAIN;
1349 else if (type == PEM_ENCRYPTED_PRIVATE_KEY)
1350 format_id = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
1352 else if (type == PEM_CERTIFICATE)
1353 format_id = GCR_FORMAT_DER_CERTIFICATE_X509;
1355 else if (type == PEM_PKCS7)
1356 format_id = GCR_FORMAT_DER_PKCS7;
1358 else if (type == PEM_PKCS12)
1359 format_id = GCR_FORMAT_DER_PKCS12;
1362 return GCR_ERROR_UNRECOGNIZED;
1364 if (subformat != 0 && subformat != format_id)
1365 return GCR_ERROR_UNRECOGNIZED;
1367 format = parser_format_lookup (format_id);
1369 return GCR_ERROR_UNRECOGNIZED;
1371 return (format->function) (self, data, n_data);
1374 static CK_OBJECT_CLASS
1375 pem_type_to_class (gint type)
1377 if (type == PEM_RSA_PRIVATE_KEY ||
1378 type == PEM_DSA_PRIVATE_KEY ||
1379 type == PEM_ANY_PRIVATE_KEY ||
1380 type == PEM_PRIVATE_KEY ||
1381 type == PEM_ENCRYPTED_PRIVATE_KEY)
1382 return CKO_PRIVATE_KEY;
1384 else if (type == PEM_CERTIFICATE)
1385 return CKO_CERTIFICATE;
1387 else if (type == PEM_PKCS7 ||
1395 handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
1396 GHashTable *headers, const guchar *data, gsize n_data)
1398 PasswordState pstate = PASSWORD_STATE_INIT;
1399 const gchar *password;
1407 g_assert (GCR_IS_PARSER (self));
1411 val = g_hash_table_lookup (headers, "DEK-Info");
1413 g_message ("missing encryption header");
1414 return GCR_ERROR_FAILURE;
1417 res = GCR_ERROR_FAILURE;
1420 res = enum_next_password (self, &pstate, &password);
1427 /* Decrypt, this will result in garble if invalid password */
1428 ret = egg_openssl_decrypt_block (val, password, -1, data, n_data,
1429 &decrypted, &n_decrypted);
1431 res = GCR_ERROR_FAILURE;
1435 g_assert (decrypted);
1437 /* Unpad the DER data */
1438 l = egg_asn1x_element_length (decrypted, n_decrypted);
1443 res = handle_plain_pem (self, type, subformat, decrypted, n_decrypted);
1444 egg_secure_free (decrypted);
1446 /* Unrecognized is a bad password */
1447 if (res != GCR_ERROR_UNRECOGNIZED)
1461 handle_pem_data (GQuark type,
1466 GHashTable *headers,
1469 HandlePemArgs *args = (HandlePemArgs*)user_data;
1470 gint res = GCR_ERROR_FAILURE;
1471 gboolean encrypted = FALSE;
1474 /* Something already failed to parse */
1475 if (args->result == GCR_ERROR_FAILURE)
1478 /* Fill in information necessary for prompting */
1479 parsing_begin (args->parser, pem_type_to_class (type), outer, n_outer);
1481 /* See if it's encrypted PEM all openssl like*/
1483 val = g_hash_table_lookup (headers, "Proc-Type");
1484 if (val && strcmp (val, "4,ENCRYPTED") == 0)
1489 res = handle_encrypted_pem (args->parser, type, args->subformat,
1490 headers, data, n_data);
1492 res = handle_plain_pem (args->parser, type, args->subformat,
1495 parsing_end (args->parser);
1497 if (res != GCR_ERROR_UNRECOGNIZED) {
1498 if (args->result == GCR_ERROR_UNRECOGNIZED)
1500 else if (res > args->result)
1506 handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_data)
1508 HandlePemArgs ctx = { self, GCR_ERROR_UNRECOGNIZED, subformat };
1512 return GCR_ERROR_UNRECOGNIZED;
1514 found = egg_openssl_pem_parse (data, n_data, handle_pem_data, &ctx);
1517 return GCR_ERROR_UNRECOGNIZED;
1524 parse_pem (GcrParser *self, const guchar *data, gsize n_data)
1526 return handle_pem_format (self, 0, data, n_data);
1530 parse_pem_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
1532 return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
1536 parse_pem_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
1538 return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
1542 parse_pem_certificate (GcrParser *self, const guchar *data, gsize n_data)
1544 return handle_pem_format (self, GCR_FORMAT_PEM_CERTIFICATE_X509, data, n_data);
1548 parse_pem_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
1550 return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_PLAIN, data, n_data);
1554 parse_pem_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
1556 return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_ENCRYPTED, data, n_data);
1560 parse_pem_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
1562 return handle_pem_format (self, GCR_FORMAT_PEM_PKCS7, data, n_data);
1566 parse_pem_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
1568 return handle_pem_format (self, GCR_FORMAT_PEM_PKCS12, data, n_data);
1571 /* -----------------------------------------------------------------------------
1575 /* In order of parsing when no formats specified */
1576 static const ParserFormat parser_normal[] = {
1577 { GCR_FORMAT_PEM, parse_pem },
1578 { GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
1579 { GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
1580 { GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
1581 { GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
1582 { GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
1583 { GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
1584 { GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 }
1587 /* Must be in format_id numeric order */
1588 static const ParserFormat parser_formats[] = {
1589 { GCR_FORMAT_DER_PRIVATE_KEY, parse_der_private_key },
1590 { GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
1591 { GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
1592 { GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
1593 { GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
1594 { GCR_FORMAT_DER_PKCS8, parse_der_pkcs8 },
1595 { GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
1596 { GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
1597 { GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
1598 { GCR_FORMAT_PEM, parse_pem },
1599 { GCR_FORMAT_PEM_PRIVATE_KEY_RSA, parse_pem_private_key_rsa },
1600 { GCR_FORMAT_PEM_PRIVATE_KEY_DSA, parse_pem_private_key_dsa },
1601 { GCR_FORMAT_PEM_CERTIFICATE_X509, parse_pem_certificate },
1602 { GCR_FORMAT_PEM_PKCS7, parse_pem_pkcs7 },
1603 { GCR_FORMAT_PEM_PKCS8_PLAIN, parse_pem_pkcs8_plain },
1604 { GCR_FORMAT_PEM_PKCS8_ENCRYPTED, parse_pem_pkcs8_encrypted },
1605 { GCR_FORMAT_PEM_PKCS12, parse_pem_pkcs12 },
1609 compar_id_to_parser_format (const void *a, const void *b)
1611 const gint *format_id = a;
1612 const ParserFormat *format = b;
1614 g_assert (format_id);
1617 if (format->format_id == *format_id)
1619 return (*format_id < format->format_id) ? -1 : 1;
1622 static ParserFormat*
1623 parser_format_lookup (gint format_id)
1625 return bsearch (&format_id, parser_formats, G_N_ELEMENTS (parser_formats),
1626 sizeof (parser_formats[0]), compar_id_to_parser_format);
1630 compare_pointers (gconstpointer a, gconstpointer b)
1634 return a < b ? -1 : 1;
1637 typedef struct _ForeachArgs {
1645 parser_format_foreach (gpointer key, gpointer value, gpointer data)
1647 ForeachArgs *args = data;
1648 ParserFormat *format = key;
1652 g_assert (format->function);
1653 g_assert (GCR_IS_PARSER (args->parser));
1655 result = (format->function) (args->parser, args->data, args->n_data);
1656 if (result != GCR_ERROR_UNRECOGNIZED) {
1657 args->result = result;
1665 /* -----------------------------------------------------------------------------
1671 gcr_parser_constructor (GType type, guint n_props, GObjectConstructParam *props)
1673 GcrParser *self = GCR_PARSER (G_OBJECT_CLASS (gcr_parser_parent_class)->constructor(type, n_props, props));
1674 g_return_val_if_fail (self, NULL);
1676 /* Always try to parse with NULL and empty passwords first */
1677 gcr_parser_add_password (self, NULL);
1678 gcr_parser_add_password (self, "");
1680 return G_OBJECT (self);
1684 gcr_parser_init (GcrParser *self)
1686 self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PARSER, GcrParserPrivate);
1687 self->pv->passwords = g_ptr_array_new ();
1688 self->pv->normal_formats = TRUE;
1692 gcr_parser_dispose (GObject *obj)
1694 GcrParser *self = GCR_PARSER (obj);
1697 if (self->pv->parsed_attrs)
1698 gck_attributes_unref (self->pv->parsed_attrs);
1699 self->pv->parsed_attrs = NULL;
1701 g_free (self->pv->parsed_label);
1702 self->pv->parsed_label = NULL;
1704 for (i = 0; i < self->pv->passwords->len; ++i)
1705 egg_secure_strfree (g_ptr_array_index (self->pv->passwords, i));
1706 g_ptr_array_set_size (self->pv->passwords, 0);
1708 G_OBJECT_CLASS (gcr_parser_parent_class)->dispose (obj);
1712 gcr_parser_finalize (GObject *obj)
1714 GcrParser *self = GCR_PARSER (obj);
1716 g_assert (!self->pv->parsed_attrs);
1717 g_assert (!self->pv->parsed_label);
1719 g_ptr_array_free (self->pv->passwords, TRUE);
1720 self->pv->passwords = NULL;
1722 G_OBJECT_CLASS (gcr_parser_parent_class)->finalize (obj);
1726 gcr_parser_set_property (GObject *obj, guint prop_id, const GValue *value,
1731 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
1737 gcr_parser_get_property (GObject *obj, guint prop_id, GValue *value,
1740 GcrParser *self = GCR_PARSER (obj);
1743 case PROP_PARSED_ATTRIBUTES:
1744 g_value_set_boxed (value, gcr_parser_get_parsed_attributes (self));
1746 case PROP_PARSED_LABEL:
1747 g_value_set_string (value, gcr_parser_get_parsed_label (self));
1749 case PROP_PARSED_DESCRIPTION:
1750 g_value_set_string (value, gcr_parser_get_parsed_description (self));
1753 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
1759 gcr_parser_class_init (GcrParserClass *klass)
1761 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1764 gobject_class->constructor = gcr_parser_constructor;
1765 gobject_class->dispose = gcr_parser_dispose;
1766 gobject_class->finalize = gcr_parser_finalize;
1767 gobject_class->set_property = gcr_parser_set_property;
1768 gobject_class->get_property = gcr_parser_get_property;
1771 * GcrParser:parsed-attributes:
1773 * Get the attributes that make up the currently parsed item. This is
1774 * generally only valid during a #GcrParser::parsed signal.
1776 g_type_class_add_private (gobject_class, sizeof (GcrParserPrivate));
1778 g_object_class_install_property (gobject_class, PROP_PARSED_ATTRIBUTES,
1779 g_param_spec_boxed ("parsed-attributes", "Parsed Attributes", "Parsed PKCS#11 attributes",
1780 GCK_TYPE_ATTRIBUTES, G_PARAM_READABLE));
1783 * GcrParser:parsed-label:
1785 * The label of the currently parsed item. This is generally
1786 * only valid during a #GcrParser::parsed signal.
1788 g_object_class_install_property (gobject_class, PROP_PARSED_LABEL,
1789 g_param_spec_string ("parsed-label", "Parsed Label", "Parsed item label",
1790 "", G_PARAM_READABLE));
1793 * GcrParser:parsed-description:
1795 * The description of the type of the currently parsed item. This is generally
1796 * only valid during a #GcrParser::parsed signal.
1798 g_object_class_install_property (gobject_class, PROP_PARSED_DESCRIPTION,
1799 g_param_spec_string ("parsed-description", "Parsed Description", "Parsed item description",
1800 "", G_PARAM_READABLE));
1803 * GcrParser::authenticate:
1804 * @count: The number of times this item has been authenticated.
1806 * This signal is emitted when an item needs to be unlocked or decrypted before
1807 * it can be parsed. The @count argument specifies the number of times
1808 * the signal has been emitted for a given item. This can be used to
1809 * display a message saying the previous password was incorrect.
1811 * Typically the gcr_parser_add_password() function is called in
1812 * response to this signal.
1814 * If %FALSE is returned, then the authentication was not handled. If
1815 * no handlers return %TRUE then the item is not parsed and an error
1816 * with the code %GCR_ERROR_CANCELLED will be raised.
1818 * Returns: Whether the authentication was handled.
1820 signals[AUTHENTICATE] = g_signal_new ("authenticate", GCR_TYPE_PARSER,
1821 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrParserClass, authenticate),
1822 g_signal_accumulator_true_handled, NULL, _gcr_marshal_BOOLEAN__INT,
1823 G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
1826 * GcrParser::parsed:
1828 * This signal is emitted when an item is sucessfully parsed. To access
1829 * the information about the item use the gcr_parser_get_parsed_label(),
1830 * gcr_parser_get_parsed_attributes() and gcr_parser_get_parsed_description()
1833 signals[PARSED] = g_signal_new ("parsed", GCR_TYPE_PARSER,
1834 G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrParserClass, parsed),
1835 NULL, NULL, g_cclosure_marshal_VOID__VOID,
1839 _gcr_initialize_library ();
1841 /* Check that the format tables are in order */
1842 for (i = 1; i < G_N_ELEMENTS (parser_formats); ++i)
1843 g_assert (parser_formats[i].format_id >= parser_formats[i - 1].format_id);
1846 /* -----------------------------------------------------------------------------
1853 * Create a new #GcrParser
1855 * Returns: A newly allocated #GcrParser
1858 gcr_parser_new (void)
1860 return g_object_new (GCR_TYPE_PARSER, NULL);
1864 * gcr_parser_add_password:
1866 * @password: A password to try
1868 * Add a password to the set of passwords to try when parsing locked or encrypted
1869 * items. This is usually called from the GcrParser::authenticate signal.
1872 gcr_parser_add_password (GcrParser *self, const gchar *password)
1874 g_return_if_fail (GCR_IS_PARSER (self));
1875 g_ptr_array_add (self->pv->passwords, egg_secure_strdup (password));
1879 * gcr_parser_parse_data:
1881 * @data: The data to parse
1882 * @n_data: The length of the data
1883 * @error: A location to raise an error on failure.
1885 * Parse the data. The GcrParser::parsed and GcrParser::authenticate signals
1886 * may fire during the parsing.
1888 * Returns: Whether the data was parsed successfully or not.
1891 gcr_parser_parse_data (GcrParser *self, gconstpointer data,
1892 gsize n_data, GError **error)
1894 ForeachArgs args = { self, data, n_data, GCR_ERROR_UNRECOGNIZED };
1895 const gchar *message = NULL;
1898 g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
1899 g_return_val_if_fail (data || !n_data, FALSE);
1900 g_return_val_if_fail (!error || !*error, FALSE);
1902 if (data && n_data) {
1903 /* Just the specific formats requested */
1904 if (self->pv->specific_formats) {
1905 g_tree_foreach (self->pv->specific_formats, parser_format_foreach, &args);
1907 /* All the 'normal' formats */
1908 } else if (self->pv->normal_formats) {
1909 for (i = 0; i < G_N_ELEMENTS (parser_normal); ++i) {
1910 if (parser_format_foreach ((gpointer)(parser_normal + i),
1911 (gpointer)(parser_normal + i), &args))
1917 switch (args.result) {
1920 case GCR_ERROR_CANCELLED:
1921 message = _("The operation was cancelled");
1923 case GCR_ERROR_UNRECOGNIZED:
1924 message = _("Unrecognized or unsupported data.");
1926 case GCR_ERROR_FAILURE:
1927 message = _("Could not parse invalid or corrupted data.");
1929 case GCR_ERROR_LOCKED:
1930 message = _("The data is locked");
1933 g_assert_not_reached ();
1937 g_set_error_literal (error, GCR_DATA_ERROR, args.result, message);
1942 * gcr_parser_format_enable:
1944 * @format_id: The format identifier
1946 * Enable parsing of the given format. Use -1 to enable all the formats.
1949 gcr_parser_format_enable (GcrParser *self, gint format_id)
1951 const ParserFormat *format;
1954 g_return_if_fail (GCR_IS_PARSER (self));
1956 if (!self->pv->specific_formats)
1957 self->pv->specific_formats = g_tree_new (compare_pointers);
1959 if (format_id != -1) {
1960 format = parser_format_lookup (format_id);
1961 g_return_if_fail (format);
1962 g_tree_insert (self->pv->specific_formats,
1963 (gpointer)format, (gpointer)format);
1965 for (i = 0; i < G_N_ELEMENTS (parser_formats); i++) {
1966 format = &parser_formats[i];
1967 g_tree_insert (self->pv->specific_formats, (gpointer)format,
1974 * gcr_parser_format_disable:
1976 * @format_id: The format identifier
1978 * Disable parsing of the given format. Use -1 to disable all the formats.
1981 gcr_parser_format_disable (GcrParser *self, gint format_id)
1983 ParserFormat *format;
1985 g_return_if_fail (GCR_IS_PARSER (self));
1987 if (format_id == -1) {
1988 if (self->pv->specific_formats)
1989 g_tree_destroy (self->pv->specific_formats);
1990 self->pv->specific_formats = NULL;
1991 self->pv->normal_formats = FALSE;
1994 if (!self->pv->specific_formats)
1997 format = parser_format_lookup (format_id);
1998 g_return_if_fail (format);
2000 g_tree_remove (self->pv->specific_formats, format);
2004 * gcr_parser_format_supported:
2006 * @format_id: The format identifier
2008 * Check whether the given format is supported by the parser.
2010 * Returns: Whether the format is supported.
2013 gcr_parser_format_supported (GcrParser *self, gint format_id)
2015 g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
2016 g_return_val_if_fail (format_id != -1, FALSE);
2017 return parser_format_lookup (format_id) ? TRUE : FALSE;
2021 * gcr_parser_get_parsed_description:
2024 * Get a description for the type of the currently parsed item. This is generally
2025 * only valid during the GcrParser::parsed signal.
2027 * Returns: The description for the current item. This is owned by the parser
2028 * and should not be freed.
2031 gcr_parser_get_parsed_description (GcrParser *self)
2033 g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2034 return self->pv->parsed_desc;
2038 * gcr_parser_get_parsed_attributes:
2041 * Get the attributes which make up the currently parsed item. This is generally
2042 * only valid during the GcrParser::parsed signal.
2044 * Returns: The attributes for the current item. These are owned by the parser
2045 * and should not be freed.
2048 gcr_parser_get_parsed_attributes (GcrParser *self)
2050 g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2051 return self->pv->parsed_attrs;
2055 * gcr_parser_get_parsed_label:
2058 * Get the label of the currently parsed item. This is generally only valid
2059 * during the GcrParser::parsed signal.
2061 * Returns: The label of the currently parsed item. The value is owned by
2062 * the parser and should not be freed.
2065 gcr_parser_get_parsed_label (GcrParser *self)
2067 g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2068 return self->pv->parsed_label;
2072 * gcr_parser_get_parsed_block:
2074 * @n_block: a location to place the size of the block
2076 * Get the raw data block that represents this parsed object. This is only
2077 * valid during the GcrParser::parsed signal.
2079 * Returns: The raw data block of the currently parsed item. The value is
2080 * owned by the parser and should not be freed.
2083 gcr_parser_get_parsed_block (GcrParser *self,
2086 g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2087 g_return_val_if_fail (n_block, NULL);
2088 *n_block = self->pv->parsing_n_block;
2089 return self->pv->parsing_block;
2092 /* ---------------------------------------------------------------------------------
2096 #define GCR_TYPE_PARSING (gcr_parsing_get_type ())
2097 #define GCR_PARSING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PARSING, GcrParsing))
2098 #define GCR_IS_PARSING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PARSING))
2100 typedef struct _GcrParsing {
2101 GObjectClass parent;
2105 GCancellable *cancel;
2107 /* Failure information */
2111 /* Operation state */
2112 GInputStream *input;
2115 /* Async callback stuff */
2116 GAsyncReadyCallback callback;
2121 typedef struct _GcrParsingClass {
2122 GObjectClass parent_class;
2125 /* State forward declarations */
2126 static void state_cancelled (GcrParsing *self, gboolean async);
2127 static void state_failure (GcrParsing *self, gboolean async);
2128 static void state_complete (GcrParsing *self, gboolean async);
2129 static void state_parse_buffer (GcrParsing *self, gboolean async);
2130 static void state_read_buffer (GcrParsing *self, gboolean async);
2132 /* Other forward declarations */
2133 static GType gcr_parsing_get_type (void) G_GNUC_CONST;
2134 static void gcr_parsing_async_result_init (GAsyncResultIface *iface);
2136 G_DEFINE_TYPE_WITH_CODE (GcrParsing, gcr_parsing, G_TYPE_OBJECT,
2137 G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_RESULT, gcr_parsing_async_result_init));
2142 next_state (GcrParsing *self, void (*state) (GcrParsing*, gboolean))
2144 g_assert (GCR_IS_PARSING (self));
2147 if (self->cancel && g_cancellable_is_cancelled (self->cancel))
2148 state = state_cancelled;
2150 (state) (self, self->async);
2154 state_complete (GcrParsing *self, gboolean async)
2156 g_assert (GCR_IS_PARSING (self));
2157 g_assert (!self->complete);
2158 self->complete = TRUE;
2159 if (async && self->callback != NULL)
2160 (self->callback) (G_OBJECT (self->parser), G_ASYNC_RESULT (self), self->user_data);
2164 state_failure (GcrParsing *self, gboolean async)
2166 g_assert (GCR_IS_PARSING (self));
2167 g_assert (self->error);
2168 next_state (self, state_complete);
2172 state_cancelled (GcrParsing *self, gboolean async)
2174 g_assert (GCR_IS_PARSING (self));
2175 if (self->cancel && g_cancellable_is_cancelled (self->cancel))
2176 g_cancellable_cancel (self->cancel);
2178 g_error_free (self->error);
2179 self->error = g_error_new_literal (GCR_DATA_ERROR, GCR_ERROR_CANCELLED, _("The operation was cancelled"));
2180 next_state (self, state_failure);
2184 state_parse_buffer (GcrParsing *self, gboolean async)
2186 GError *error = NULL;
2189 g_assert (GCR_IS_PARSING (self));
2190 g_assert (self->buffer);
2192 ret = gcr_parser_parse_data (self->parser, self->buffer->data, self->buffer->len, &error);
2195 next_state (self, state_complete);
2197 g_propagate_error (&self->error, error);
2198 next_state (self, state_failure);
2203 complete_read_buffer (GcrParsing *self, gssize count, GError *error)
2205 g_assert (GCR_IS_PARSING (self));
2206 g_assert (self->buffer);
2210 g_propagate_error (&self->error, error);
2211 next_state (self, state_failure);
2214 g_return_if_fail (count >= 0 && count <= BLOCK);
2215 g_byte_array_set_size (self->buffer, self->buffer->len - (BLOCK - count));
2217 /* Finished reading */
2219 next_state (self, state_parse_buffer);
2221 /* Read the next block */
2223 next_state (self, state_read_buffer);
2229 on_read_buffer (GObject *obj, GAsyncResult *res, gpointer user_data)
2231 GError *error = NULL;
2234 count = g_input_stream_read_finish (G_INPUT_STREAM (obj), res, &error);
2235 complete_read_buffer (user_data, count, error);
2239 state_read_buffer (GcrParsing *self, gboolean async)
2241 GError *error = NULL;
2245 g_assert (GCR_IS_PARSING (self));
2246 g_assert (G_IS_INPUT_STREAM (self->input));
2249 self->buffer = g_byte_array_sized_new (BLOCK);
2251 at = self->buffer->len;
2252 g_byte_array_set_size (self->buffer, at + BLOCK);
2255 g_input_stream_read_async (self->input, self->buffer->data + at,
2256 BLOCK, G_PRIORITY_DEFAULT, self->cancel,
2257 on_read_buffer, self);
2259 count = g_input_stream_read (self->input, self->buffer->data + at,
2260 BLOCK, self->cancel, &error);
2261 complete_read_buffer (self, count, error);
2266 gcr_parsing_init (GcrParsing *self)
2272 gcr_parsing_finalize (GObject *obj)
2274 GcrParsing *self = GCR_PARSING (obj);
2276 g_object_unref (self->parser);
2277 self->parser = NULL;
2279 g_object_unref (self->input);
2283 g_object_unref (self->cancel);
2284 self->cancel = NULL;
2286 g_clear_error (&self->error);
2289 g_byte_array_free (self->buffer, TRUE);
2290 self->buffer = NULL;
2292 G_OBJECT_CLASS (gcr_parsing_parent_class)->finalize (obj);
2296 gcr_parsing_class_init (GcrParsingClass *klass)
2298 G_OBJECT_CLASS (klass)->finalize = gcr_parsing_finalize;
2302 gcr_parsing_real_get_user_data (GAsyncResult *base)
2304 g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
2305 return GCR_PARSING (base)->user_data;
2309 gcr_parsing_real_get_source_object (GAsyncResult *base)
2311 g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
2312 return G_OBJECT (GCR_PARSING (base)->parser);
2316 gcr_parsing_async_result_init (GAsyncResultIface *iface)
2318 iface->get_source_object = gcr_parsing_real_get_source_object;
2319 iface->get_user_data = gcr_parsing_real_get_user_data;
2323 gcr_parsing_new (GcrParser *parser, GInputStream *input, GCancellable *cancel)
2327 g_assert (GCR_IS_PARSER (parser));
2328 g_assert (G_IS_INPUT_STREAM (input));
2330 self = g_object_new (GCR_TYPE_PARSING, NULL);
2331 self->parser = g_object_ref (parser);
2332 self->input = g_object_ref (input);
2334 self->cancel = g_object_ref (cancel);
2340 * gcr_parser_parse_stream:
2342 * @input: The input stream
2343 * @cancellable: An optional cancellation object
2344 * @error: A location to raise an error on failure
2346 * Parse items from the data in a #GInputStream. This function may block while
2347 * reading from the input stream. Use gcr_parser_parse_stream_async() for
2348 * a non-blocking variant.
2350 * The GcrParser::parsed and GcrParser::authenticate signals
2351 * may fire during the parsing.
2353 * Returns: Whether the parsing completed successfully or not.
2356 gcr_parser_parse_stream (GcrParser *self, GInputStream *input, GCancellable *cancellable,
2359 GcrParsing *parsing;
2361 g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
2362 g_return_val_if_fail (G_IS_INPUT_STREAM (input), FALSE);
2363 g_return_val_if_fail (!error || !*error, FALSE);
2365 parsing = gcr_parsing_new (self, input, cancellable);
2366 parsing->async = FALSE;
2368 next_state (parsing, state_read_buffer);
2369 g_assert (parsing->complete);
2371 return gcr_parser_parse_stream_finish (self, G_ASYNC_RESULT (parsing), error);
2375 * gcr_parser_parse_stream_async:
2377 * @input: The input stream
2378 * @cancellable: An optional cancellation object
2379 * @callback: Called when the operation result is ready.
2380 * @user_data: Data to pass to callback
2382 * Parse items from the data in a #GInputStream. This function completes
2383 * asyncronously and doesn't block.
2385 * The GcrParser::parsed and GcrParser::authenticate signals
2386 * may fire during the parsing.
2389 gcr_parser_parse_stream_async (GcrParser *self, GInputStream *input, GCancellable *cancellable,
2390 GAsyncReadyCallback callback, gpointer user_data)
2392 GcrParsing *parsing;
2394 g_return_if_fail (GCR_IS_PARSER (self));
2395 g_return_if_fail (G_IS_INPUT_STREAM (input));
2397 parsing = gcr_parsing_new (self, input, cancellable);
2398 parsing->async = TRUE;
2399 parsing->callback = callback;
2400 parsing->user_data = user_data;
2402 next_state (parsing, state_read_buffer);
2406 * gcr_parser_parse_stream_finish:
2408 * @result:The operation result
2409 * @error: A location to raise an error on failure
2411 * Complete an operation to parse a stream.
2413 * Returns: Whether the parsing completed successfully or not.
2416 gcr_parser_parse_stream_finish (GcrParser *self, GAsyncResult *result, GError **error)
2418 GcrParsing *parsing;
2420 g_return_val_if_fail (GCR_IS_PARSING (result), FALSE);
2421 g_return_val_if_fail (!error || !*error, FALSE);
2423 parsing = GCR_PARSING (result);
2424 g_return_val_if_fail (parsing->complete, FALSE);
2426 if (parsing->error) {
2427 g_propagate_error (error, parsing->error);