c3d6acf2495c71f44a216d0c0285e3b5d0580353
[platform/upstream/gcr.git] / gcr / gcr-parser.c
1 /*
2  * gnome-keyring
3  *
4  * Copyright (C) 2008 Stefan Walter
5  *
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.
10  *
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.
15  *
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
19  * 02111-1307, USA.
20  */
21
22 #include "config.h"
23
24 #include "gck/gck.h"
25
26 #include "gcr-internal.h"
27 #include "gcr-importer.h"
28 #include "gcr-marshal.h"
29 #include "gcr-oids.h"
30 #include "gcr-parser.h"
31 #include "gcr-types.h"
32
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"
39
40 #include <glib/gi18n-lib.h>
41
42 #include <stdlib.h>
43 #include <gcrypt.h>
44
45 /**
46  * SECTION:gcr-parser
47  * @title: GcrParser
48  * @short_description: Parser for certificate and key files
49  *
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.
53  *
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().
58  *
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()
61  * function.
62  */
63
64 /**
65  * GcrParser:
66  *
67  * A parser for parsing various types of files or data.
68  */
69
70 /**
71  * GcrParserClass:
72  * @parent_class: The parent class
73  * @authenticate: The default handler for the authenticate signal.
74  * @parsed: The default handler for the parsed signal.
75  *
76  * The class for #GcrParser
77  */
78
79 /**
80  * GcrDataFormat:
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
99  *
100  * The various format identifiers.
101  */
102
103 /**
104  * GCR_DATA_ERROR:
105  *
106  * A domain for data errors with codes from #GcrDataError
107  */
108
109 /**
110  * 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.
115  *
116  * Values responding to error codes for parsing and serializing data.
117  */
118
119 enum {
120         PROP_0,
121         PROP_PARSED_LABEL,
122         PROP_PARSED_ATTRIBUTES,
123         PROP_PARSED_DESCRIPTION
124 };
125
126 enum {
127         AUTHENTICATE,
128         PARSED,
129         LAST_SIGNAL
130 };
131
132 #define SUCCESS 0
133
134 static guint signals[LAST_SIGNAL] = { 0 };
135
136 struct _GcrParserPrivate {
137         GTree *specific_formats;
138         gboolean normal_formats;
139         GPtrArray *passwords;
140
141         GckAttributes *parsed_attrs;
142         const gchar *parsed_desc;
143         gchar *parsed_label;
144         gconstpointer parsing_block;
145         gsize parsing_n_block;
146 };
147
148 G_DEFINE_TYPE (GcrParser, gcr_parser, G_TYPE_OBJECT);
149
150 typedef struct {
151         gint ask_state;
152         gint seen;
153 } PasswordState;
154
155 #define PASSWORD_STATE_INIT { 0, 0 }
156
157 typedef struct _ParserFormat {
158         gint format_id;
159         gint (*function) (GcrParser *self, const guchar *data, gsize n_data);
160 } ParserFormat;
161
162 /* Forward declarations */
163 static const ParserFormat parser_normal[];
164 static const ParserFormat parser_formats[];
165 static ParserFormat* parser_format_lookup (gint format_id);
166
167 EGG_SECURE_DECLARE (parser);
168
169 /* -----------------------------------------------------------------------------
170  * QUARK DEFINITIONS
171  */
172
173 /*
174  * PEM STRINGS
175  * The xxxxx in: ----- BEGIN xxxxx ------
176  */
177
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;
186
187 static void
188 init_quarks (void)
189 {
190         static volatile gsize quarks_inited = 0;
191
192         _gcr_oids_init ();
193
194         if (g_once_init_enter (&quarks_inited)) {
195
196                 #define QUARK(name, value) \
197                         name = g_quark_from_static_string(value)
198
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");
207
208                 #undef QUARK
209
210                 g_once_init_leave (&quarks_inited, 1);
211         }
212 }
213
214 /* -----------------------------------------------------------------------------
215  * INTERNAL
216  */
217
218 static gboolean
219 parsed_asn1_attribute (GcrParser *self, GNode *asn, const guchar *data, gsize n_data,
220                        const gchar *part, CK_ATTRIBUTE_TYPE type)
221 {
222         const guchar *value;
223         gsize n_value;
224
225         g_assert (GCR_IS_PARSER (self));
226         g_assert (asn);
227         g_assert (data);
228         g_assert (self->pv->parsed_attrs);
229
230         value = egg_asn1x_get_raw_value (egg_asn1x_node (asn, part, NULL), &n_value);
231         if (value == NULL)
232                 return FALSE;
233
234         /* TODO: Convert to USG FROM STD */
235         gck_attributes_add_data (self->pv->parsed_attrs, type, value, n_value);
236         return TRUE;
237 }
238
239 static void
240 parsing_begin (GcrParser *self,
241                CK_OBJECT_CLASS klass,
242                gconstpointer block,
243                gsize n_block)
244 {
245         g_assert (GCR_IS_PARSER (self));
246         g_assert (block);
247         g_assert (n_block);
248
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);
253         else
254                 self->pv->parsed_attrs = gck_attributes_new ();
255         gck_attributes_add_ulong (self->pv->parsed_attrs, CKA_CLASS, klass);
256
257         switch (klass) {
258         case CKO_PRIVATE_KEY:
259                 self->pv->parsed_desc = _("Private Key");
260                 break;
261         case CKO_CERTIFICATE:
262                 self->pv->parsed_desc = _("Certificate");
263                 break;
264         case CKO_PUBLIC_KEY:
265                 self->pv->parsed_desc = _("Public Key");
266                 break;
267         default:
268                 self->pv->parsed_desc = NULL;
269                 break;
270         }
271
272         self->pv->parsing_block = block;
273         self->pv->parsing_n_block = n_block;
274 }
275
276 static void
277 parsed_label (GcrParser *self, const gchar *label)
278 {
279         g_free (self->pv->parsed_label);
280         self->pv->parsed_label = g_strdup (label);
281 }
282
283 static void
284 parsed_attribute (GcrParser *self, CK_ATTRIBUTE_TYPE type, gconstpointer data, gsize n_data)
285 {
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);
289 }
290
291 static void
292 parsing_end (GcrParser *self)
293 {
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;
303 }
304
305 static void
306 parsed_ulong (GcrParser *self, CK_ATTRIBUTE_TYPE type, gulong value)
307 {
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);
311 }
312
313 static void
314 parsed_boolean (GcrParser *self, CK_ATTRIBUTE_TYPE type, gboolean value)
315 {
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);
319 }
320
321 static gint
322 enum_next_password (GcrParser *self, PasswordState *state, const gchar **password)
323 {
324         gboolean result;
325
326         /*
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.
331          *
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.
335          */
336
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);
341                 ++state->seen;
342                 return SUCCESS;
343         }
344
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");
349
350         g_signal_emit (self, signals[AUTHENTICATE], 0, state->ask_state, &result);
351         ++state->ask_state;
352
353         if (!result)
354                 return GCR_ERROR_CANCELLED;
355
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);
360                 ++state->seen;
361                 return SUCCESS;
362         }
363
364         return GCR_ERROR_LOCKED;
365 }
366
367 static void
368 parsed_fire (GcrParser *self)
369 {
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");
373
374         g_signal_emit (self, signals[PARSED], 0);
375 }
376
377 /* -----------------------------------------------------------------------------
378  * RSA PRIVATE KEY
379  */
380
381 static gint
382 parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
383 {
384         gint res = GCR_ERROR_UNRECOGNIZED;
385         GNode *asn = NULL;
386         gulong version;
387
388         asn = egg_asn1x_create_and_decode (pk_asn1_tab, "RSAPrivateKey", data, n_data);
389         if (!asn)
390                 goto done;
391
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;
396
397         if (!egg_asn1x_get_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), &version))
398                 goto done;
399
400         /* We only support simple version */
401         if (version != 0) {
402                 res = GCR_ERROR_UNRECOGNIZED;
403                 g_message ("unsupported version of RSA key: %lu", version);
404                 goto done;
405         }
406
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))
413                 goto done;
414
415         parsed_fire (self);
416         res = SUCCESS;
417         parsing_end (self);
418
419 done:
420         egg_asn1x_destroy (asn);
421         if (res == GCR_ERROR_FAILURE)
422                 g_message ("invalid RSA key");
423
424         return res;
425 }
426
427 /* -----------------------------------------------------------------------------
428  * DSA PRIVATE KEY
429  */
430
431 static gint
432 parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
433 {
434         gint ret = GCR_ERROR_UNRECOGNIZED;
435         GNode *asn = NULL;
436
437         asn = egg_asn1x_create_and_decode (pk_asn1_tab, "DSAPrivateKey", data, n_data);
438         if (!asn)
439                 goto done;
440
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;
445
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))
450                 goto done;
451
452         parsed_fire (self);
453         ret = SUCCESS;
454         parsing_end (self);
455
456 done:
457         egg_asn1x_destroy (asn);
458         if (ret == GCR_ERROR_FAILURE)
459                 g_message ("invalid DSA key");
460
461         return ret;
462 }
463
464 static gint
465 parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n_keydata,
466                                  const guchar *params, gsize n_params)
467 {
468         gint ret = GCR_ERROR_UNRECOGNIZED;
469         GNode *asn_params = NULL;
470         GNode *asn_key = NULL;
471
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)
475                 goto done;
476
477         parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
478         parsed_boolean (self, CKA_PRIVATE, CK_TRUE);
479         ret = GCR_ERROR_FAILURE;
480
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))
485                 goto done;
486
487         parsed_fire (self);
488         ret = SUCCESS;
489
490 done:
491         egg_asn1x_destroy (asn_key);
492         egg_asn1x_destroy (asn_params);
493         if (ret == GCR_ERROR_FAILURE)
494                 g_message ("invalid DSA key");
495
496         return ret;
497 }
498
499 /* -----------------------------------------------------------------------------
500  * PRIVATE KEY
501  */
502
503 static gint
504 parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
505 {
506         gint res;
507
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);
511
512         return res;
513 }
514
515 /* -----------------------------------------------------------------------------
516  * PKCS8
517  */
518
519 static gint
520 parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
521 {
522         gint ret;
523         CK_KEY_TYPE key_type;
524         GQuark key_algo;
525         const guchar *keydata;
526         gsize n_keydata;
527         const guchar *params;
528         gsize n_params;
529         GNode *asn = NULL;
530
531         ret = GCR_ERROR_UNRECOGNIZED;
532
533         asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo", data, n_data);
534         if (!asn)
535                 goto done;
536
537         ret = GCR_ERROR_FAILURE;
538         key_type = GCK_INVALID;
539
540         key_algo = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL));
541         if (!key_algo)
542                 goto done;
543         else if (key_algo == GCR_OID_PKIX1_RSA)
544                 key_type = CKK_RSA;
545         else if (key_algo == GCR_OID_PKIX1_DSA)
546                 key_type = CKK_DSA;
547
548         if (key_type == GCK_INVALID) {
549                 ret = GCR_ERROR_UNRECOGNIZED;
550                 goto done;
551         }
552
553         keydata = egg_asn1x_get_raw_value (egg_asn1x_node (asn, "privateKey", NULL), &n_keydata);
554         if (!keydata)
555                 goto done;
556
557         params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL), &n_params);
558
559         ret = SUCCESS;
560
561 done:
562         if (ret == SUCCESS) {
563                 switch (key_type) {
564                 case CKK_RSA:
565                         ret = parse_der_private_key_rsa (self, keydata, n_keydata);
566                         break;
567                 case CKK_DSA:
568                         /* Try the normal sane format */
569                         ret = parse_der_private_key_dsa (self, keydata, n_keydata);
570
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,
575                                                                        params, n_params);
576                         parsing_end (self);
577                         break;
578                 default:
579                         g_message ("invalid or unsupported key type in PKCS#8 key");
580                         ret = GCR_ERROR_UNRECOGNIZED;
581                         break;
582                 };
583
584         } else if (ret == GCR_ERROR_FAILURE) {
585                 g_message ("invalid PKCS#8 key");
586         }
587
588         egg_asn1x_destroy (asn);
589         return ret;
590 }
591
592 static gint
593 parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
594 {
595         PasswordState pstate = PASSWORD_STATE_INIT;
596         GNode *asn = NULL;
597         gcry_cipher_hd_t cih = NULL;
598         gcry_error_t gcry;
599         gint ret, r;
600         GQuark scheme;
601         guchar *crypted = NULL;
602         const guchar *params;
603         gsize n_crypted, n_params;
604         const gchar *password;
605         gint l;
606
607         ret = GCR_ERROR_UNRECOGNIZED;
608
609         asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
610         if (!asn)
611                 goto done;
612
613         ret = GCR_ERROR_FAILURE;
614
615         /* Figure out the type of encryption */
616         scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL));
617         if (!scheme)
618                 goto done;
619
620         params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), &n_params);
621
622         parsing_begin (self, CKO_PRIVATE_KEY, data, n_data);
623
624         /* Loop to try different passwords */
625         for (;;) {
626
627                 g_assert (cih == NULL);
628
629                 r = enum_next_password (self, &pstate, &password);
630                 if (r != SUCCESS) {
631                         ret = r;
632                         break;
633                 }
634
635                 /* Parse the encryption stuff into a cipher. */
636                 if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih))
637                         break;
638
639                 crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted);
640                 if (!crypted)
641                         break;
642
643                 gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
644                 gcry_cipher_close (cih);
645                 cih = NULL;
646
647                 if (gcry != 0) {
648                         g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
649                         break;
650                 }
651
652                 /* Unpad the DER data */
653                 l = egg_asn1x_element_length (crypted, n_crypted);
654                 if (l > 0)
655                         n_crypted = l;
656
657                 /* Try to parse the resulting key */
658                 r = parse_der_pkcs8_plain (self, crypted, n_crypted);
659                 egg_secure_free (crypted);
660                 crypted = NULL;
661
662                 if (r != GCR_ERROR_UNRECOGNIZED) {
663                         ret = r;
664                         break;
665                 }
666
667                 /* We assume unrecognized data, is a bad encryption key */
668         }
669
670         parsing_end (self);
671
672 done:
673         if (cih)
674                 gcry_cipher_close (cih);
675         egg_asn1x_destroy (asn);
676         egg_secure_free (crypted);
677
678         return ret;
679 }
680
681 static gint
682 parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
683 {
684         gint ret;
685
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);
689
690         return ret;
691 }
692
693 /* -----------------------------------------------------------------------------
694  * CERTIFICATE
695  */
696
697 static gint
698 parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
699 {
700         gchar *name = NULL;
701         GNode *asn;
702
703         asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", data, n_data);
704         if (asn == NULL)
705                 return GCR_ERROR_UNRECOGNIZED;
706
707         parsing_begin (self, CKO_CERTIFICATE, data, n_data);
708
709         parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
710
711         if (self->pv->parsed_label == NULL)
712                 name = egg_dn_read_part (egg_asn1x_node (asn, "tbsCertificate", "subject", "rdnSequence", NULL), "CN");
713
714         egg_asn1x_destroy (asn);
715
716         if (name != NULL) {
717                 parsed_label (self, name);
718                 g_free (name);
719         }
720
721         parsed_attribute (self, CKA_VALUE, data, n_data);
722         parsed_fire (self);
723
724         parsing_end (self);
725         return SUCCESS;
726 }
727
728 /* -----------------------------------------------------------------------------
729  * PKCS7
730  */
731
732 static gint
733 handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
734 {
735         GNode *asn = NULL;
736         GNode *node;
737         gint ret;
738         const guchar *certificate;
739         gsize n_certificate;
740         int i;
741
742         ret = GCR_ERROR_UNRECOGNIZED;
743
744         asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-SignedData", data, n_data);
745         if (!asn)
746                 goto done;
747
748         ret = GCR_ERROR_FAILURE;
749
750         for (i = 0; TRUE; ++i) {
751
752                 node = egg_asn1x_node (asn, "certificates", i + 1, NULL);
753
754                 /* No more certificates? */
755                 if (node == NULL)
756                         break;
757
758                 certificate = egg_asn1x_get_raw_element (node, &n_certificate);
759
760                 ret = parse_der_certificate (self, certificate, n_certificate);
761                 if (ret != SUCCESS)
762                         goto done;
763         }
764
765         /* TODO: Parse out all the CRLs */
766
767         ret = SUCCESS;
768
769 done:
770         egg_asn1x_destroy (asn);
771         return ret;
772 }
773
774 static gint
775 parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
776 {
777         GNode *asn = NULL;
778         GNode *node;
779         gint ret;
780         const guchar* content = NULL;
781         gsize n_content;
782         GQuark oid;
783
784         ret = GCR_ERROR_UNRECOGNIZED;
785
786         asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-ContentInfo", data, n_data);
787         if (!asn)
788                 goto done;
789
790         ret = GCR_ERROR_FAILURE;
791
792         node = egg_asn1x_node (asn, "contentType", NULL);
793         if (!node)
794                 goto done;
795
796         oid = egg_asn1x_get_oid_as_quark (node);
797         g_return_val_if_fail (oid, GCR_ERROR_FAILURE);
798
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));
802                 goto done;
803         }
804
805         content = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "content", NULL), &n_content);
806         if (!content)
807                 goto done;
808
809         ret = handle_pkcs7_signed_data (self, content, n_content);
810
811 done:
812         egg_asn1x_destroy (asn);
813         return ret;
814 }
815
816 /* -----------------------------------------------------------------------------
817  * PKCS12
818  */
819
820 static GNode *
821 decode_pkcs12_asn1_accepting_invalid_crap (const ASN1_ARRAY_TYPE *defs,
822                                            const gchar *identifier,
823                                            gconstpointer data,
824                                            gsize n_data)
825 {
826         GNode *asn;
827
828         /*
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.
832          *
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.
837          */
838
839         asn = egg_asn1x_create (defs, identifier);
840         g_return_val_if_fail (asn != NULL, NULL);
841
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);
846                 asn = NULL;
847         }
848
849         return asn;
850 }
851
852 static gint
853 handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
854 {
855         GNode *asn = NULL;
856         GNode *asn_content = NULL;
857         guchar *certificate = NULL;
858         const guchar *element;
859         gsize n_certificate, n_element;
860         gint ret;
861
862         ret = GCR_ERROR_UNRECOGNIZED;
863         asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
864                                                          "pkcs-12-CertBag",
865                                                          data, n_data);
866         if (!asn)
867                 goto done;
868
869         ret = GCR_ERROR_FAILURE;
870
871         element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "certValue", NULL), &n_element);
872         if (!element)
873                 goto done;
874
875         asn_content = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-7-Data", element, n_element);
876         if (!asn_content)
877                 goto done;
878
879         certificate = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_certificate);
880         if (!certificate)
881                 goto done;
882
883         ret = parse_der_certificate (self, certificate, n_certificate);
884
885 done:
886         egg_asn1x_destroy (asn_content);
887         egg_asn1x_destroy (asn);
888         g_free (certificate);
889         return ret;
890 }
891
892 static gchar *
893 parse_pkcs12_bag_friendly_name (GNode *asn)
894 {
895         guint count, i;
896         GQuark oid;
897         GNode *node;
898         gconstpointer element;
899         gsize n_element;
900         GNode *asn_str;
901         gchar *result;
902
903         if (asn == NULL)
904                 return NULL;
905
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);
911                         if (node != NULL) {
912                                 element = egg_asn1x_get_raw_element (node, &n_element);
913                                 asn_str = egg_asn1x_create_and_decode (pkix_asn1_tab, "BMPString",
914                                                                        element, n_element);
915                                 if (asn_str) {
916                                         result = egg_asn1x_get_bmpstring_as_utf8 (asn_str);
917                                         egg_asn1x_destroy (asn_str);
918                                         return result;
919                                 }
920                         }
921                 }
922         }
923
924         return NULL;
925 }
926
927 static gint
928 handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
929 {
930         GNode *asn = NULL;
931         gint ret, r;
932         guint count = 0;
933         GQuark oid;
934         const guchar *element;
935         gchar *friendly;
936         gsize n_element;
937         guint i;
938
939         ret = GCR_ERROR_UNRECOGNIZED;
940
941         asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
942                                                          "pkcs-12-SafeContents",
943                                                          data, n_data);
944         if (!asn)
945                 goto done;
946
947         ret = GCR_ERROR_FAILURE;
948
949         /* Get the number of elements in this bag */
950         count = egg_asn1x_count (asn);
951
952         /*
953          * Now inside each bag are multiple elements. Who comes up
954          * with this stuff?
955          */
956         for (i = 1; i <= count; i++) {
957
958                 oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, i, "bagId", NULL));
959                 if (!oid)
960                         goto done;
961
962                 element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, i, "bagValue", NULL), &n_element);
963                 if (!element)
964                         goto done;
965
966                 friendly = parse_pkcs12_bag_friendly_name (egg_asn1x_node (asn, i, "bagAttributes", NULL));
967                 if (friendly != NULL)
968                         parsed_label (self, friendly);
969
970                 /* A normal unencrypted key */
971                 if (oid == GCR_OID_PKCS12_BAG_PKCS8_KEY) {
972                         r = parse_der_pkcs8_plain (self, element, n_element);
973
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);
977
978                 /* A certificate */
979                 } else if (oid == GCR_OID_PKCS12_BAG_CERTIFICATE) {
980                         r = handle_pkcs12_cert_bag (self, element, n_element);
981
982                 /* TODO: GCR_OID_PKCS12_BAG_CRL */
983                 } else {
984                         r = GCR_ERROR_UNRECOGNIZED;
985                 }
986
987                 if (friendly != NULL)
988                         parsed_label (self, NULL);
989
990                 if (r == GCR_ERROR_FAILURE ||
991                     r == GCR_ERROR_CANCELLED ||
992                     r == GCR_ERROR_LOCKED) {
993                         ret = r;
994                         goto done;
995                 }
996         }
997
998         ret = SUCCESS;
999
1000 done:
1001         egg_asn1x_destroy (asn);
1002         return ret;
1003 }
1004
1005 static gint
1006 handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
1007 {
1008         PasswordState pstate = PASSWORD_STATE_INIT;
1009         GNode *asn = NULL;
1010         gcry_cipher_hd_t cih = NULL;
1011         gcry_error_t gcry;
1012         guchar *crypted = NULL;
1013         const guchar *params;
1014         gsize n_params, n_crypted;
1015         const gchar *password;
1016         GQuark scheme;
1017         gint ret, r;
1018         gint l;
1019
1020         ret = GCR_ERROR_UNRECOGNIZED;
1021
1022         asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
1023                                                          "pkcs-7-EncryptedData",
1024                                                          data, n_data);
1025         if (!asn)
1026                 goto done;
1027
1028         ret = GCR_ERROR_FAILURE;
1029
1030         /* Check the encryption schema OID */
1031         scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "algorithm", NULL));
1032         if (!scheme)
1033                 goto done;
1034
1035         params = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "encryptedContentInfo", "contentEncryptionAlgorithm", "parameters", NULL), &n_params);
1036         if (!params)
1037                 goto done;
1038
1039         /* Loop to try different passwords */
1040         for (;;) {
1041
1042                 g_assert (cih == NULL);
1043
1044                 r = enum_next_password (self, &pstate, &password);
1045                 if (r != SUCCESS) {
1046                         ret = r;
1047                         goto done;
1048                 }
1049
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;
1053                         goto done;
1054                 }
1055
1056                 crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedContentInfo", "encryptedContent", NULL),
1057                                                        egg_secure_realloc, &n_crypted);
1058                 if (!crypted)
1059                         goto done;
1060
1061                 gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
1062                 gcry_cipher_close (cih);
1063                 cih = NULL;
1064
1065                 if (gcry != 0) {
1066                         g_warning ("couldn't decrypt pkcs7 data: %s", gcry_strerror (gcry));
1067                         goto done;
1068                 }
1069
1070                 /* Unpad the DER data */
1071                 l = egg_asn1x_element_length (crypted, n_crypted);
1072                 if (l > 0)
1073                         n_crypted = l;
1074
1075                 /* Try to parse the resulting key */
1076                 r = handle_pkcs12_bag (self, crypted, n_crypted);
1077                 egg_secure_free (crypted);
1078                 crypted = NULL;
1079
1080                 if (r != GCR_ERROR_UNRECOGNIZED) {
1081                         ret = r;
1082                         break;
1083                 }
1084
1085                 /* We assume unrecognized data is a bad encryption key */
1086         }
1087
1088 done:
1089         if (cih)
1090                 gcry_cipher_close (cih);
1091         egg_asn1x_destroy (asn);
1092         egg_secure_free (crypted);
1093         return ret;
1094 }
1095
1096 static gint
1097 handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
1098 {
1099         GNode *asn = NULL;
1100         GNode *asn_content = NULL;
1101         gint ret, r;
1102         const guchar *bag;
1103         guchar *content = NULL;
1104         gsize n_bag, n_content;
1105         GQuark oid;
1106         guint i;
1107         GNode *node;
1108
1109         ret = GCR_ERROR_UNRECOGNIZED;
1110
1111         asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
1112                                                          "pkcs-12-AuthenticatedSafe",
1113                                                          data, n_data);
1114         if (!asn)
1115                 goto done;
1116
1117         ret = GCR_ERROR_FAILURE;
1118
1119         /*
1120          * Inside each PKCS12 safe there are multiple bags.
1121          */
1122         for (i = 0; TRUE; ++i) {
1123                 node = egg_asn1x_node (asn, i + 1, "contentType", NULL);
1124
1125                 /* All done? no more bags */
1126                 if (!node)
1127                         break;
1128
1129                 oid = egg_asn1x_get_oid_as_quark (node);
1130
1131                 node = egg_asn1x_node (asn, i + 1, "content", NULL);
1132                 if (!node)
1133                         goto done;
1134
1135                 bag = egg_asn1x_get_raw_element (node, &n_bag);
1136                 g_return_val_if_fail (bag, ret);
1137
1138                 /* A non encrypted bag, just parse */
1139                 if (oid == GCR_OID_PKCS7_DATA) {
1140
1141                         egg_asn1x_destroy (asn_content);
1142                         asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab,
1143                                                                                  "pkcs-7-Data",
1144                                                                                  bag, n_bag);
1145                         if (!asn_content)
1146                                 goto done;
1147
1148                         g_free (content);
1149                         content = egg_asn1x_get_string_as_raw (asn_content, NULL, &n_content);
1150                         if (!content)
1151                                 goto done;
1152
1153                         r = handle_pkcs12_bag (self, content, n_content);
1154
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);
1158
1159                 /* Hmmmm, not sure what this is */
1160                 } else {
1161                         g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
1162                         r = GCR_ERROR_UNRECOGNIZED;
1163                 }
1164
1165                 if (r == GCR_ERROR_FAILURE ||
1166                     r == GCR_ERROR_CANCELLED ||
1167                     r == GCR_ERROR_LOCKED) {
1168                         ret = r;
1169                         goto done;
1170                 }
1171         }
1172
1173         ret = SUCCESS;
1174
1175 done:
1176         egg_asn1x_destroy (asn);
1177         egg_asn1x_destroy (asn_content);
1178         g_free (content);
1179         return ret;
1180 }
1181
1182 static gint
1183 verify_pkcs12_safe (GcrParser *self,
1184                     GNode *asn,
1185                     gconstpointer content,
1186                     gsize n_content)
1187 {
1188         PasswordState pstate = PASSWORD_STATE_INIT;
1189         const gchar *password;
1190         gcry_md_hd_t mdh = NULL;
1191         const guchar *mac_digest;
1192         gsize mac_len;
1193         guchar *digest = NULL;
1194         gsize n_digest;
1195         GQuark algorithm;
1196         GNode *mac_data;
1197         gconstpointer params;
1198         gsize n_params;
1199         int ret, r;
1200
1201         ret = GCR_ERROR_FAILURE;
1202
1203         /*
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
1206          */
1207
1208         mac_data = egg_asn1x_node (asn, "macData", NULL);
1209         if (mac_data == NULL)
1210                 return SUCCESS;
1211
1212         algorithm = egg_asn1x_get_oid_as_quark (egg_asn1x_node (mac_data, "mac",
1213                                                 "digestAlgorithm", "algorithm", NULL));
1214         if (!algorithm)
1215                 goto done;
1216
1217         params = egg_asn1x_get_raw_element (mac_data, &n_params);
1218         if (!params)
1219                 goto done;
1220
1221         digest = egg_asn1x_get_string_as_raw (egg_asn1x_node (mac_data, "mac", "digest", NULL), NULL, &n_digest);
1222         if (!digest)
1223                 goto done;
1224
1225         /* Loop to try different passwords */
1226         for (;;) {
1227                 g_assert (mdh == NULL);
1228
1229                 r = enum_next_password (self, &pstate, &password);
1230                 if (r != SUCCESS) {
1231                         ret = r;
1232                         goto done;
1233                 }
1234
1235                 /* Parse the encryption stuff into a cipher. */
1236                 if (!egg_symkey_read_mac (algorithm, password, -1, params, n_params,
1237                                           &mdh, &mac_len)) {
1238                         ret = GCR_ERROR_FAILURE;
1239                         goto done;
1240                 }
1241
1242                 /* If not the right length, then that's really broken */
1243                 if (mac_len != n_digest) {
1244                         r = GCR_ERROR_FAILURE;
1245
1246                 } else {
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;
1251                 }
1252
1253                 gcry_md_close (mdh);
1254                 mdh = NULL;
1255
1256                 if (r != GCR_ERROR_LOCKED) {
1257                         ret = r;
1258                         break;
1259                 }
1260         }
1261
1262 done:
1263         if (mdh)
1264                 gcry_md_close (mdh);
1265         g_free (digest);
1266         return ret;
1267
1268 }
1269
1270 static gint
1271 parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
1272 {
1273         GNode *asn = NULL;
1274         GNode *asn_content = NULL;
1275         gint ret;
1276         const guchar* element = NULL;
1277         guchar *content = NULL;
1278         gsize n_element, n_content;
1279         GQuark oid;
1280
1281         ret = GCR_ERROR_UNRECOGNIZED;
1282
1283         asn = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-12-PFX",
1284                                                          data, n_data);
1285         if (!asn)
1286                 goto done;
1287
1288         parsing_begin (self, 0, data, n_data);
1289
1290         oid = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "authSafe", "contentType", NULL));
1291         if (!oid)
1292                 goto done;
1293
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));
1297                 goto done;
1298         }
1299
1300         element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "authSafe", "content", NULL), &n_element);
1301         if (!element)
1302                 goto done;
1303
1304         asn_content = decode_pkcs12_asn1_accepting_invalid_crap (pkix_asn1_tab, "pkcs-7-Data",
1305                                                                  element, n_element);
1306         if (!asn_content)
1307                 goto done;
1308
1309         content = egg_asn1x_get_string_as_raw (asn_content, g_realloc, &n_content);
1310         if (!content)
1311                 goto done;
1312
1313         ret = verify_pkcs12_safe (self, asn, content, n_content);
1314         if (ret == SUCCESS)
1315                 ret = handle_pkcs12_safe (self, content, n_content);
1316
1317         parsing_end (self);
1318
1319 done:
1320         g_free (content);
1321         egg_asn1x_destroy (asn_content);
1322         egg_asn1x_destroy (asn);
1323         return ret;
1324 }
1325
1326 /* -----------------------------------------------------------------------------
1327  * PEM PARSING
1328  */
1329
1330 static gint
1331 handle_plain_pem (GcrParser *self, GQuark type, gint subformat,
1332                   const guchar *data, gsize n_data)
1333 {
1334         ParserFormat *format;
1335         gint format_id;
1336
1337         if (type == PEM_RSA_PRIVATE_KEY)
1338                 format_id = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
1339
1340         else if (type == PEM_DSA_PRIVATE_KEY)
1341                 format_id = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
1342
1343         else if (type == PEM_ANY_PRIVATE_KEY)
1344                 format_id = GCR_FORMAT_DER_PRIVATE_KEY;
1345
1346         else if (type == PEM_PRIVATE_KEY)
1347                 format_id = GCR_FORMAT_DER_PKCS8_PLAIN;
1348
1349         else if (type == PEM_ENCRYPTED_PRIVATE_KEY)
1350                 format_id = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
1351
1352         else if (type == PEM_CERTIFICATE)
1353                 format_id = GCR_FORMAT_DER_CERTIFICATE_X509;
1354
1355         else if (type == PEM_PKCS7)
1356                 format_id = GCR_FORMAT_DER_PKCS7;
1357
1358         else if (type == PEM_PKCS12)
1359                 format_id = GCR_FORMAT_DER_PKCS12;
1360
1361         else
1362                 return GCR_ERROR_UNRECOGNIZED;
1363
1364         if (subformat != 0 && subformat != format_id)
1365                 return GCR_ERROR_UNRECOGNIZED;
1366
1367         format = parser_format_lookup (format_id);
1368         if (format == NULL)
1369                 return GCR_ERROR_UNRECOGNIZED;
1370
1371         return (format->function) (self, data, n_data);
1372 }
1373
1374 static CK_OBJECT_CLASS
1375 pem_type_to_class (gint type)
1376 {
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;
1383
1384         else if (type == PEM_CERTIFICATE)
1385                 return CKO_CERTIFICATE;
1386
1387         else if (type == PEM_PKCS7 ||
1388                  type == PEM_PKCS12)
1389                 return 0;
1390
1391         return 0;
1392 }
1393
1394 static gint
1395 handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat,
1396                       GHashTable *headers, const guchar *data, gsize n_data)
1397 {
1398         PasswordState pstate = PASSWORD_STATE_INIT;
1399         const gchar *password;
1400         guchar *decrypted;
1401         gsize n_decrypted;
1402         const gchar *val;
1403         gboolean ret;
1404         gint res;
1405         gint l;
1406
1407         g_assert (GCR_IS_PARSER (self));
1408         g_assert (headers);
1409         g_assert (type);
1410
1411         val = g_hash_table_lookup (headers, "DEK-Info");
1412         if (!val) {
1413                 g_message ("missing encryption header");
1414                 return GCR_ERROR_FAILURE;
1415         }
1416
1417         res = GCR_ERROR_FAILURE;
1418         for (;;) {
1419
1420                 res = enum_next_password (self, &pstate, &password);
1421                 if (res != SUCCESS)
1422                         break;
1423
1424                 decrypted = NULL;
1425                 n_decrypted = 0;
1426
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);
1430                 if (!ret) {
1431                         res = GCR_ERROR_FAILURE;
1432                         break;
1433                 }
1434
1435                 g_assert (decrypted);
1436
1437                 /* Unpad the DER data */
1438                 l = egg_asn1x_element_length (decrypted, n_decrypted);
1439                 if (l > 0)
1440                         n_decrypted = l;
1441
1442                 /* Try to parse */
1443                 res = handle_plain_pem (self, type, subformat, decrypted, n_decrypted);
1444                 egg_secure_free (decrypted);
1445
1446                 /* Unrecognized is a bad password */
1447                 if (res != GCR_ERROR_UNRECOGNIZED)
1448                         break;
1449         }
1450
1451         return res;
1452 }
1453
1454 typedef struct {
1455         GcrParser *parser;
1456         gint result;
1457         gint subformat;
1458 } HandlePemArgs;
1459
1460 static void
1461 handle_pem_data (GQuark type,
1462                  const guchar *data,
1463                  gsize n_data,
1464                  const gchar *outer,
1465                  gsize n_outer,
1466                  GHashTable *headers,
1467                  gpointer user_data)
1468 {
1469         HandlePemArgs *args = (HandlePemArgs*)user_data;
1470         gint res = GCR_ERROR_FAILURE;
1471         gboolean encrypted = FALSE;
1472         const gchar *val;
1473
1474         /* Something already failed to parse */
1475         if (args->result == GCR_ERROR_FAILURE)
1476                 return;
1477
1478         /* Fill in information necessary for prompting */
1479         parsing_begin (args->parser, pem_type_to_class (type), outer, n_outer);
1480
1481         /* See if it's encrypted PEM all openssl like*/
1482         if (headers) {
1483                 val = g_hash_table_lookup (headers, "Proc-Type");
1484                 if (val && strcmp (val, "4,ENCRYPTED") == 0)
1485                         encrypted = TRUE;
1486         }
1487
1488         if (encrypted)
1489                 res = handle_encrypted_pem (args->parser, type, args->subformat,
1490                                             headers, data, n_data);
1491         else
1492                 res = handle_plain_pem (args->parser, type, args->subformat,
1493                                         data, n_data);
1494
1495         parsing_end (args->parser);
1496
1497         if (res != GCR_ERROR_UNRECOGNIZED) {
1498                 if (args->result == GCR_ERROR_UNRECOGNIZED)
1499                         args->result = res;
1500                 else if (res > args->result)
1501                         args->result = res;
1502         }
1503 }
1504
1505 static gint
1506 handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_data)
1507 {
1508         HandlePemArgs ctx = { self, GCR_ERROR_UNRECOGNIZED, subformat };
1509         guint found;
1510
1511         if (n_data == 0)
1512                 return GCR_ERROR_UNRECOGNIZED;
1513
1514         found = egg_openssl_pem_parse (data, n_data, handle_pem_data, &ctx);
1515
1516         if (found == 0)
1517                 return GCR_ERROR_UNRECOGNIZED;
1518
1519         return ctx.result;
1520 }
1521
1522
1523 static gint
1524 parse_pem (GcrParser *self, const guchar *data, gsize n_data)
1525 {
1526         return handle_pem_format (self, 0, data, n_data);
1527 }
1528
1529 static gint
1530 parse_pem_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
1531 {
1532         return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
1533 }
1534
1535 static gint
1536 parse_pem_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
1537 {
1538         return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
1539 }
1540
1541 static gint
1542 parse_pem_certificate (GcrParser *self, const guchar *data, gsize n_data)
1543 {
1544         return handle_pem_format (self, GCR_FORMAT_PEM_CERTIFICATE_X509, data, n_data);
1545 }
1546
1547 static gint
1548 parse_pem_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
1549 {
1550         return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_PLAIN, data, n_data);
1551 }
1552
1553 static gint
1554 parse_pem_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
1555 {
1556         return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_ENCRYPTED, data, n_data);
1557 }
1558
1559 static gint
1560 parse_pem_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
1561 {
1562         return handle_pem_format (self, GCR_FORMAT_PEM_PKCS7, data, n_data);
1563 }
1564
1565 static gint
1566 parse_pem_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
1567 {
1568         return handle_pem_format (self, GCR_FORMAT_PEM_PKCS12, data, n_data);
1569 }
1570
1571 /* -----------------------------------------------------------------------------
1572  * FORMATS
1573  */
1574
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 }
1585 };
1586
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 },
1606 };
1607
1608 static int
1609 compar_id_to_parser_format (const void *a, const void *b)
1610 {
1611         const gint *format_id = a;
1612         const ParserFormat *format = b;
1613
1614         g_assert (format_id);
1615         g_assert (format);
1616
1617         if (format->format_id == *format_id)
1618                 return 0;
1619         return (*format_id < format->format_id) ? -1 : 1;
1620 }
1621
1622 static ParserFormat*
1623 parser_format_lookup (gint format_id)
1624 {
1625         return bsearch (&format_id, parser_formats, G_N_ELEMENTS (parser_formats),
1626                         sizeof (parser_formats[0]), compar_id_to_parser_format);
1627 }
1628
1629 static gint
1630 compare_pointers (gconstpointer a, gconstpointer b)
1631 {
1632         if (a == b)
1633                 return 0;
1634         return a < b ? -1 : 1;
1635 }
1636
1637 typedef struct _ForeachArgs {
1638         GcrParser *parser;
1639         const guchar *data;
1640         gsize n_data;
1641         gint result;
1642 } ForeachArgs;
1643
1644 static gboolean
1645 parser_format_foreach (gpointer key, gpointer value, gpointer data)
1646 {
1647         ForeachArgs *args = data;
1648         ParserFormat *format = key;
1649         gint result;
1650
1651         g_assert (format);
1652         g_assert (format->function);
1653         g_assert (GCR_IS_PARSER (args->parser));
1654
1655         result = (format->function) (args->parser, args->data, args->n_data);
1656         if (result != GCR_ERROR_UNRECOGNIZED) {
1657                 args->result = result;
1658                 return TRUE;
1659         }
1660
1661         /* Keep going */
1662         return FALSE;
1663 }
1664
1665 /* -----------------------------------------------------------------------------
1666  * OBJECT
1667  */
1668
1669
1670 static GObject*
1671 gcr_parser_constructor (GType type, guint n_props, GObjectConstructParam *props)
1672 {
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);
1675
1676         /* Always try to parse with NULL and empty passwords first */
1677         gcr_parser_add_password (self, NULL);
1678         gcr_parser_add_password (self, "");
1679
1680         return G_OBJECT (self);
1681 }
1682
1683 static void
1684 gcr_parser_init (GcrParser *self)
1685 {
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;
1689 }
1690
1691 static void
1692 gcr_parser_dispose (GObject *obj)
1693 {
1694         GcrParser *self = GCR_PARSER (obj);
1695         gsize i;
1696
1697         if (self->pv->parsed_attrs)
1698                 gck_attributes_unref (self->pv->parsed_attrs);
1699         self->pv->parsed_attrs = NULL;
1700
1701         g_free (self->pv->parsed_label);
1702         self->pv->parsed_label = NULL;
1703
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);
1707
1708         G_OBJECT_CLASS (gcr_parser_parent_class)->dispose (obj);
1709 }
1710
1711 static void
1712 gcr_parser_finalize (GObject *obj)
1713 {
1714         GcrParser *self = GCR_PARSER (obj);
1715
1716         g_assert (!self->pv->parsed_attrs);
1717         g_assert (!self->pv->parsed_label);
1718
1719         g_ptr_array_free (self->pv->passwords, TRUE);
1720         self->pv->passwords = NULL;
1721
1722         G_OBJECT_CLASS (gcr_parser_parent_class)->finalize (obj);
1723 }
1724
1725 static void
1726 gcr_parser_set_property (GObject *obj, guint prop_id, const GValue *value,
1727                            GParamSpec *pspec)
1728 {
1729         switch (prop_id) {
1730         default:
1731                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
1732                 break;
1733         }
1734 }
1735
1736 static void
1737 gcr_parser_get_property (GObject *obj, guint prop_id, GValue *value,
1738                          GParamSpec *pspec)
1739 {
1740         GcrParser *self = GCR_PARSER (obj);
1741
1742         switch (prop_id) {
1743         case PROP_PARSED_ATTRIBUTES:
1744                 g_value_set_boxed (value, gcr_parser_get_parsed_attributes (self));
1745                 break;
1746         case PROP_PARSED_LABEL:
1747                 g_value_set_string (value, gcr_parser_get_parsed_label (self));
1748                 break;
1749         case PROP_PARSED_DESCRIPTION:
1750                 g_value_set_string (value, gcr_parser_get_parsed_description (self));
1751                 break;
1752         default:
1753                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
1754                 break;
1755         }
1756 }
1757
1758 static void
1759 gcr_parser_class_init (GcrParserClass *klass)
1760 {
1761         GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1762         gint i;
1763
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;
1769
1770         /**
1771          * GcrParser:parsed-attributes:
1772          *
1773          * Get the attributes that make up the currently parsed item. This is
1774          * generally only valid during a #GcrParser::parsed signal.
1775          */
1776         g_type_class_add_private (gobject_class, sizeof (GcrParserPrivate));
1777
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));
1781
1782         /**
1783          * GcrParser:parsed-label:
1784          *
1785          * The label of the currently parsed item. This is generally
1786          * only valid during a #GcrParser::parsed signal.
1787          */
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));
1791
1792         /**
1793          * GcrParser:parsed-description:
1794          *
1795          * The description of the type of the currently parsed item. This is generally
1796          * only valid during a #GcrParser::parsed signal.
1797          */
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));
1801
1802         /**
1803          * GcrParser::authenticate:
1804          * @count: The number of times this item has been authenticated.
1805          *
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.
1810          *
1811          * Typically the gcr_parser_add_password() function is called in
1812          * response to this signal.
1813          *
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.
1817          *
1818          * Returns: Whether the authentication was handled.
1819          */
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);
1824
1825         /**
1826          * GcrParser::parsed:
1827          *
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()
1831          * functions.
1832          */
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,
1836                                         G_TYPE_NONE, 0);
1837
1838         init_quarks ();
1839         _gcr_initialize_library ();
1840
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);
1844 }
1845
1846 /* -----------------------------------------------------------------------------
1847  * PUBLIC
1848  */
1849
1850 /**
1851  * gcr_parser_new:
1852  *
1853  * Create a new #GcrParser
1854  *
1855  * Returns: A newly allocated #GcrParser
1856  */
1857 GcrParser*
1858 gcr_parser_new (void)
1859 {
1860         return g_object_new (GCR_TYPE_PARSER, NULL);
1861 }
1862
1863 /**
1864  * gcr_parser_add_password:
1865  * @self: The parser
1866  * @password: A password to try
1867  *
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.
1870  */
1871 void
1872 gcr_parser_add_password (GcrParser *self, const gchar *password)
1873 {
1874         g_return_if_fail (GCR_IS_PARSER (self));
1875         g_ptr_array_add (self->pv->passwords, egg_secure_strdup (password));
1876 }
1877
1878 /**
1879  * gcr_parser_parse_data:
1880  * @self: The parser
1881  * @data: The data to parse
1882  * @n_data: The length of the data
1883  * @error: A location to raise an error on failure.
1884  *
1885  * Parse the data. The GcrParser::parsed and GcrParser::authenticate signals
1886  * may fire during the parsing.
1887  *
1888  * Returns: Whether the data was parsed successfully or not.
1889  */
1890 gboolean
1891 gcr_parser_parse_data (GcrParser *self, gconstpointer data,
1892                        gsize n_data, GError **error)
1893 {
1894         ForeachArgs args = { self, data, n_data, GCR_ERROR_UNRECOGNIZED };
1895         const gchar *message = NULL;
1896         gint i;
1897
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);
1901
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);
1906
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))
1912                                         break;
1913                         }
1914                 }
1915         }
1916
1917         switch (args.result) {
1918         case SUCCESS:
1919                 return TRUE;
1920         case GCR_ERROR_CANCELLED:
1921                 message = _("The operation was cancelled");
1922                 break;
1923         case GCR_ERROR_UNRECOGNIZED:
1924                 message = _("Unrecognized or unsupported data.");
1925                 break;
1926         case GCR_ERROR_FAILURE:
1927                 message = _("Could not parse invalid or corrupted data.");
1928                 break;
1929         case GCR_ERROR_LOCKED:
1930                 message = _("The data is locked");
1931                 break;
1932         default:
1933                 g_assert_not_reached ();
1934                 break;
1935         };
1936
1937         g_set_error_literal (error, GCR_DATA_ERROR, args.result, message);
1938         return FALSE;
1939 }
1940
1941 /**
1942  * gcr_parser_format_enable:
1943  * @self: The parser
1944  * @format_id: The format identifier
1945  *
1946  * Enable parsing of the given format. Use -1 to enable all the formats.
1947  */
1948 void
1949 gcr_parser_format_enable (GcrParser *self, gint format_id)
1950 {
1951         const ParserFormat *format;
1952         guint i;
1953
1954         g_return_if_fail (GCR_IS_PARSER (self));
1955
1956         if (!self->pv->specific_formats)
1957                 self->pv->specific_formats = g_tree_new (compare_pointers);
1958
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);
1964         } else {
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,
1968                                        (gpointer)format);
1969                 }
1970         }
1971 }
1972
1973 /**
1974  * gcr_parser_format_disable:
1975  * @self: The parser
1976  * @format_id: The format identifier
1977  *
1978  * Disable parsing of the given format. Use -1 to disable all the formats.
1979  */
1980 void
1981 gcr_parser_format_disable (GcrParser *self, gint format_id)
1982 {
1983         ParserFormat *format;
1984
1985         g_return_if_fail (GCR_IS_PARSER (self));
1986
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;
1992         }
1993
1994         if (!self->pv->specific_formats)
1995                 return;
1996
1997         format = parser_format_lookup (format_id);
1998         g_return_if_fail (format);
1999
2000         g_tree_remove (self->pv->specific_formats, format);
2001 }
2002
2003 /**
2004  * gcr_parser_format_supported:
2005  * @self: The parser
2006  * @format_id: The format identifier
2007  *
2008  * Check whether the given format is supported by the parser.
2009  *
2010  * Returns: Whether the format is supported.
2011  */
2012 gboolean
2013 gcr_parser_format_supported (GcrParser *self, gint format_id)
2014 {
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;
2018 }
2019
2020 /**
2021  * gcr_parser_get_parsed_description:
2022  * @self: The parser
2023  *
2024  * Get a description for the type of the currently parsed item. This is generally
2025  * only valid during the GcrParser::parsed signal.
2026  *
2027  * Returns: The description for the current item. This is owned by the parser
2028  *     and should not be freed.
2029  */
2030 const gchar*
2031 gcr_parser_get_parsed_description (GcrParser *self)
2032 {
2033         g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2034         return self->pv->parsed_desc;
2035 }
2036
2037 /**
2038  * gcr_parser_get_parsed_attributes:
2039  * @self: The parser
2040  *
2041  * Get the attributes which make up the currently parsed item. This is generally
2042  * only valid during the GcrParser::parsed signal.
2043  *
2044  * Returns: The attributes for the current item. These are owned by the parser
2045  *     and should not be freed.
2046  */
2047 GckAttributes*
2048 gcr_parser_get_parsed_attributes (GcrParser *self)
2049 {
2050         g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2051         return self->pv->parsed_attrs;
2052 }
2053
2054 /**
2055  * gcr_parser_get_parsed_label:
2056  * @self: The parser
2057  *
2058  * Get the label of the currently parsed item. This is generally only valid
2059  * during the GcrParser::parsed signal.
2060  *
2061  * Returns: The label of the currently parsed item. The value is owned by
2062  *     the parser and should not be freed.
2063  */
2064 const gchar*
2065 gcr_parser_get_parsed_label (GcrParser *self)
2066 {
2067         g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
2068         return self->pv->parsed_label;
2069 }
2070
2071 /**
2072  * gcr_parser_get_parsed_block:
2073  * @self: a parser
2074  * @n_block: a location to place the size of the block
2075  *
2076  * Get the raw data block that represents this parsed object. This is only
2077  * valid during the GcrParser::parsed signal.
2078  *
2079  * Returns: The raw data block of the currently parsed item. The value is
2080  *      owned by the parser and should not be freed.
2081  */
2082 gconstpointer
2083 gcr_parser_get_parsed_block (GcrParser *self,
2084                              gsize *n_block)
2085 {
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;
2090 }
2091
2092 /* ---------------------------------------------------------------------------------
2093  * STREAM PARSING
2094  */
2095
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))
2099
2100 typedef struct _GcrParsing {
2101         GObjectClass parent;
2102
2103         GcrParser *parser;
2104         gboolean async;
2105         GCancellable *cancel;
2106
2107         /* Failure information */
2108         GError *error;
2109         gboolean complete;
2110
2111         /* Operation state */
2112         GInputStream *input;
2113         GByteArray *buffer;
2114
2115         /* Async callback stuff */
2116         GAsyncReadyCallback callback;
2117         gpointer user_data;
2118
2119 } GcrParsing;
2120
2121 typedef struct _GcrParsingClass {
2122         GObjectClass parent_class;
2123 } GcrParsingClass;
2124
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);
2131
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);
2135
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));
2138
2139 #define BLOCK 4096
2140
2141 static void
2142 next_state (GcrParsing *self, void (*state) (GcrParsing*, gboolean))
2143 {
2144         g_assert (GCR_IS_PARSING (self));
2145         g_assert (state);
2146
2147         if (self->cancel && g_cancellable_is_cancelled (self->cancel))
2148                 state = state_cancelled;
2149
2150         (state) (self, self->async);
2151 }
2152
2153 static void
2154 state_complete (GcrParsing *self, gboolean async)
2155 {
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);
2161 }
2162
2163 static void
2164 state_failure (GcrParsing *self, gboolean async)
2165 {
2166         g_assert (GCR_IS_PARSING (self));
2167         g_assert (self->error);
2168         next_state (self, state_complete);
2169 }
2170
2171 static void
2172 state_cancelled (GcrParsing *self, gboolean async)
2173 {
2174         g_assert (GCR_IS_PARSING (self));
2175         if (self->cancel && g_cancellable_is_cancelled (self->cancel))
2176                 g_cancellable_cancel (self->cancel);
2177         if (self->error)
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);
2181 }
2182
2183 static void
2184 state_parse_buffer (GcrParsing *self, gboolean async)
2185 {
2186         GError *error = NULL;
2187         gboolean ret;
2188
2189         g_assert (GCR_IS_PARSING (self));
2190         g_assert (self->buffer);
2191
2192         ret = gcr_parser_parse_data (self->parser, self->buffer->data, self->buffer->len, &error);
2193
2194         if (ret == TRUE) {
2195                 next_state (self, state_complete);
2196         } else {
2197                 g_propagate_error (&self->error, error);
2198                 next_state (self, state_failure);
2199         }
2200 }
2201
2202 static void
2203 complete_read_buffer (GcrParsing *self, gssize count, GError *error)
2204 {
2205         g_assert (GCR_IS_PARSING (self));
2206         g_assert (self->buffer);
2207
2208         /* A failure */
2209         if (count == -1) {
2210                 g_propagate_error (&self->error, error);
2211                 next_state (self, state_failure);
2212         } else {
2213
2214                 g_return_if_fail (count >= 0 && count <= BLOCK);
2215                 g_byte_array_set_size (self->buffer, self->buffer->len - (BLOCK - count));
2216
2217                 /* Finished reading */
2218                 if (count == 0)
2219                         next_state (self, state_parse_buffer);
2220
2221                 /* Read the next block */
2222                 else
2223                         next_state (self, state_read_buffer);
2224         }
2225
2226 }
2227
2228 static void
2229 on_read_buffer (GObject *obj, GAsyncResult *res, gpointer user_data)
2230 {
2231         GError *error = NULL;
2232         gssize count;
2233
2234         count = g_input_stream_read_finish (G_INPUT_STREAM (obj), res, &error);
2235         complete_read_buffer (user_data, count, error);
2236 }
2237
2238 static void
2239 state_read_buffer (GcrParsing *self, gboolean async)
2240 {
2241         GError *error = NULL;
2242         gssize count;
2243         gsize at;
2244
2245         g_assert (GCR_IS_PARSING (self));
2246         g_assert (G_IS_INPUT_STREAM (self->input));
2247
2248         if (!self->buffer)
2249                 self->buffer = g_byte_array_sized_new (BLOCK);
2250
2251         at = self->buffer->len;
2252         g_byte_array_set_size (self->buffer, at + BLOCK);
2253
2254         if (async) {
2255                 g_input_stream_read_async (self->input, self->buffer->data + at,
2256                                            BLOCK, G_PRIORITY_DEFAULT, self->cancel,
2257                                            on_read_buffer, self);
2258         } else {
2259                 count = g_input_stream_read (self->input, self->buffer->data + at,
2260                                              BLOCK, self->cancel, &error);
2261                 complete_read_buffer (self, count, error);
2262         }
2263 }
2264
2265 static void
2266 gcr_parsing_init (GcrParsing *self)
2267 {
2268
2269 }
2270
2271 static void
2272 gcr_parsing_finalize (GObject *obj)
2273 {
2274         GcrParsing *self = GCR_PARSING (obj);
2275
2276         g_object_unref (self->parser);
2277         self->parser = NULL;
2278
2279         g_object_unref (self->input);
2280         self->input = NULL;
2281
2282         if (self->cancel)
2283                 g_object_unref (self->cancel);
2284         self->cancel = NULL;
2285
2286         g_clear_error (&self->error);
2287
2288         if (self->buffer)
2289                 g_byte_array_free (self->buffer, TRUE);
2290         self->buffer = NULL;
2291
2292         G_OBJECT_CLASS (gcr_parsing_parent_class)->finalize (obj);
2293 }
2294
2295 static void
2296 gcr_parsing_class_init (GcrParsingClass *klass)
2297 {
2298         G_OBJECT_CLASS (klass)->finalize = gcr_parsing_finalize;
2299 }
2300
2301 static gpointer
2302 gcr_parsing_real_get_user_data (GAsyncResult *base)
2303 {
2304         g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
2305         return GCR_PARSING (base)->user_data;
2306 }
2307
2308 static GObject*
2309 gcr_parsing_real_get_source_object (GAsyncResult *base)
2310 {
2311         g_return_val_if_fail (GCR_IS_PARSING (base), NULL);
2312         return G_OBJECT (GCR_PARSING (base)->parser);
2313 }
2314
2315 static void
2316 gcr_parsing_async_result_init (GAsyncResultIface *iface)
2317 {
2318         iface->get_source_object = gcr_parsing_real_get_source_object;
2319         iface->get_user_data = gcr_parsing_real_get_user_data;
2320 }
2321
2322 static GcrParsing*
2323 gcr_parsing_new (GcrParser *parser, GInputStream *input, GCancellable *cancel)
2324 {
2325         GcrParsing *self;
2326
2327         g_assert (GCR_IS_PARSER (parser));
2328         g_assert (G_IS_INPUT_STREAM (input));
2329
2330         self = g_object_new (GCR_TYPE_PARSING, NULL);
2331         self->parser = g_object_ref (parser);
2332         self->input = g_object_ref (input);
2333         if (cancel)
2334                 self->cancel = g_object_ref (cancel);
2335
2336         return self;
2337 }
2338
2339 /**
2340  * gcr_parser_parse_stream:
2341  * @self: The parser
2342  * @input: The input stream
2343  * @cancellable: An optional cancellation object
2344  * @error: A location to raise an error on failure
2345  *
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.
2349  *
2350  * The GcrParser::parsed and GcrParser::authenticate signals
2351  * may fire during the parsing.
2352  *
2353  * Returns: Whether the parsing completed successfully or not.
2354  */
2355 gboolean
2356 gcr_parser_parse_stream (GcrParser *self, GInputStream *input, GCancellable *cancellable,
2357                          GError **error)
2358 {
2359         GcrParsing *parsing;
2360
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);
2364
2365         parsing = gcr_parsing_new (self, input, cancellable);
2366         parsing->async = FALSE;
2367
2368         next_state (parsing, state_read_buffer);
2369         g_assert (parsing->complete);
2370
2371         return gcr_parser_parse_stream_finish (self, G_ASYNC_RESULT (parsing), error);
2372 }
2373
2374 /**
2375  * gcr_parser_parse_stream_async:
2376  * @self: The parser
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
2381  *
2382  * Parse items from the data in a #GInputStream. This function completes
2383  * asyncronously and doesn't block.
2384  *
2385  * The GcrParser::parsed and GcrParser::authenticate signals
2386  * may fire during the parsing.
2387  */
2388 void
2389 gcr_parser_parse_stream_async (GcrParser *self, GInputStream *input, GCancellable *cancellable,
2390                                GAsyncReadyCallback callback, gpointer user_data)
2391 {
2392         GcrParsing *parsing;
2393
2394         g_return_if_fail (GCR_IS_PARSER (self));
2395         g_return_if_fail (G_IS_INPUT_STREAM (input));
2396
2397         parsing = gcr_parsing_new (self, input, cancellable);
2398         parsing->async = TRUE;
2399         parsing->callback = callback;
2400         parsing->user_data = user_data;
2401
2402         next_state (parsing, state_read_buffer);
2403 }
2404
2405 /**
2406  * gcr_parser_parse_stream_finish:
2407  * @self: The parser
2408  * @result:The operation result
2409  * @error: A location to raise an error on failure
2410  *
2411  * Complete an operation to parse a stream.
2412  *
2413  * Returns: Whether the parsing completed successfully or not.
2414  */
2415 gboolean
2416 gcr_parser_parse_stream_finish (GcrParser *self, GAsyncResult *result, GError **error)
2417 {
2418         GcrParsing *parsing;
2419
2420         g_return_val_if_fail (GCR_IS_PARSING (result), FALSE);
2421         g_return_val_if_fail (!error || !*error, FALSE);
2422
2423         parsing = GCR_PARSING (result);
2424         g_return_val_if_fail (parsing->complete, FALSE);
2425
2426         if (parsing->error) {
2427                 g_propagate_error (error, parsing->error);
2428                 return FALSE;
2429         }
2430
2431         return TRUE;
2432 }